@stackweld/core 0.2.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 (172) hide show
  1. package/.turbo/turbo-build.log +4 -0
  2. package/.turbo/turbo-lint.log +498 -0
  3. package/.turbo/turbo-test.log +21 -0
  4. package/.turbo/turbo-typecheck.log +4 -0
  5. package/dist/__tests__/compatibility-scorer.test.d.ts +2 -0
  6. package/dist/__tests__/compatibility-scorer.test.d.ts.map +1 -0
  7. package/dist/__tests__/compatibility-scorer.test.js +226 -0
  8. package/dist/__tests__/compatibility-scorer.test.js.map +1 -0
  9. package/dist/__tests__/rules-engine.test.d.ts +2 -0
  10. package/dist/__tests__/rules-engine.test.d.ts.map +1 -0
  11. package/dist/__tests__/rules-engine.test.js +161 -0
  12. package/dist/__tests__/rules-engine.test.js.map +1 -0
  13. package/dist/__tests__/scaffold-orchestrator.test.d.ts +2 -0
  14. package/dist/__tests__/scaffold-orchestrator.test.d.ts.map +1 -0
  15. package/dist/__tests__/scaffold-orchestrator.test.js +149 -0
  16. package/dist/__tests__/scaffold-orchestrator.test.js.map +1 -0
  17. package/dist/__tests__/stack-engine.test.d.ts +2 -0
  18. package/dist/__tests__/stack-engine.test.d.ts.map +1 -0
  19. package/dist/__tests__/stack-engine.test.js +278 -0
  20. package/dist/__tests__/stack-engine.test.js.map +1 -0
  21. package/dist/db/database.d.ts +9 -0
  22. package/dist/db/database.d.ts.map +1 -0
  23. package/dist/db/database.js +106 -0
  24. package/dist/db/database.js.map +1 -0
  25. package/dist/db/index.d.ts +2 -0
  26. package/dist/db/index.d.ts.map +1 -0
  27. package/dist/db/index.js +2 -0
  28. package/dist/db/index.js.map +1 -0
  29. package/dist/engine/compatibility-scorer.d.ts +37 -0
  30. package/dist/engine/compatibility-scorer.d.ts.map +1 -0
  31. package/dist/engine/compatibility-scorer.js +178 -0
  32. package/dist/engine/compatibility-scorer.js.map +1 -0
  33. package/dist/engine/compose-generator.d.ts +35 -0
  34. package/dist/engine/compose-generator.d.ts.map +1 -0
  35. package/dist/engine/compose-generator.js +95 -0
  36. package/dist/engine/compose-generator.js.map +1 -0
  37. package/dist/engine/cost-estimator.d.ts +22 -0
  38. package/dist/engine/cost-estimator.d.ts.map +1 -0
  39. package/dist/engine/cost-estimator.js +451 -0
  40. package/dist/engine/cost-estimator.js.map +1 -0
  41. package/dist/engine/env-analyzer.d.ts +36 -0
  42. package/dist/engine/env-analyzer.d.ts.map +1 -0
  43. package/dist/engine/env-analyzer.js +111 -0
  44. package/dist/engine/env-analyzer.js.map +1 -0
  45. package/dist/engine/health-checker.d.ts +20 -0
  46. package/dist/engine/health-checker.d.ts.map +1 -0
  47. package/dist/engine/health-checker.js +377 -0
  48. package/dist/engine/health-checker.js.map +1 -0
  49. package/dist/engine/index.d.ts +11 -0
  50. package/dist/engine/index.d.ts.map +1 -0
  51. package/dist/engine/index.js +7 -0
  52. package/dist/engine/index.js.map +1 -0
  53. package/dist/engine/infra-generator.d.ts +26 -0
  54. package/dist/engine/infra-generator.d.ts.map +1 -0
  55. package/dist/engine/infra-generator.js +751 -0
  56. package/dist/engine/infra-generator.js.map +1 -0
  57. package/dist/engine/migration-planner.d.ts +34 -0
  58. package/dist/engine/migration-planner.d.ts.map +1 -0
  59. package/dist/engine/migration-planner.js +427 -0
  60. package/dist/engine/migration-planner.js.map +1 -0
  61. package/dist/engine/performance-profiler.d.ts +22 -0
  62. package/dist/engine/performance-profiler.d.ts.map +1 -0
  63. package/dist/engine/performance-profiler.js +292 -0
  64. package/dist/engine/performance-profiler.js.map +1 -0
  65. package/dist/engine/plugin-loader.d.ts +36 -0
  66. package/dist/engine/plugin-loader.d.ts.map +1 -0
  67. package/dist/engine/plugin-loader.js +157 -0
  68. package/dist/engine/plugin-loader.js.map +1 -0
  69. package/dist/engine/preferences.d.ts +24 -0
  70. package/dist/engine/preferences.d.ts.map +1 -0
  71. package/dist/engine/preferences.js +62 -0
  72. package/dist/engine/preferences.js.map +1 -0
  73. package/dist/engine/rules-engine.d.ts +31 -0
  74. package/dist/engine/rules-engine.d.ts.map +1 -0
  75. package/dist/engine/rules-engine.js +179 -0
  76. package/dist/engine/rules-engine.js.map +1 -0
  77. package/dist/engine/runtime-manager.d.ts +65 -0
  78. package/dist/engine/runtime-manager.d.ts.map +1 -0
  79. package/dist/engine/runtime-manager.js +181 -0
  80. package/dist/engine/runtime-manager.js.map +1 -0
  81. package/dist/engine/scaffold-orchestrator.d.ts +103 -0
  82. package/dist/engine/scaffold-orchestrator.d.ts.map +1 -0
  83. package/dist/engine/scaffold-orchestrator.js +934 -0
  84. package/dist/engine/scaffold-orchestrator.js.map +1 -0
  85. package/dist/engine/stack-detector.d.ts +21 -0
  86. package/dist/engine/stack-detector.d.ts.map +1 -0
  87. package/dist/engine/stack-detector.js +313 -0
  88. package/dist/engine/stack-detector.js.map +1 -0
  89. package/dist/engine/stack-differ.d.ts +26 -0
  90. package/dist/engine/stack-differ.d.ts.map +1 -0
  91. package/dist/engine/stack-differ.js +80 -0
  92. package/dist/engine/stack-differ.js.map +1 -0
  93. package/dist/engine/stack-engine.d.ts +54 -0
  94. package/dist/engine/stack-engine.d.ts.map +1 -0
  95. package/dist/engine/stack-engine.js +186 -0
  96. package/dist/engine/stack-engine.js.map +1 -0
  97. package/dist/engine/stack-serializer.d.ts +32 -0
  98. package/dist/engine/stack-serializer.d.ts.map +1 -0
  99. package/dist/engine/stack-serializer.js +75 -0
  100. package/dist/engine/stack-serializer.js.map +1 -0
  101. package/dist/engine/standards-linter.d.ts +34 -0
  102. package/dist/engine/standards-linter.d.ts.map +1 -0
  103. package/dist/engine/standards-linter.js +162 -0
  104. package/dist/engine/standards-linter.js.map +1 -0
  105. package/dist/engine/tech-installer.d.ts +37 -0
  106. package/dist/engine/tech-installer.d.ts.map +1 -0
  107. package/dist/engine/tech-installer.js +508 -0
  108. package/dist/engine/tech-installer.js.map +1 -0
  109. package/dist/index.d.ts +39 -0
  110. package/dist/index.d.ts.map +1 -0
  111. package/dist/index.js +25 -0
  112. package/dist/index.js.map +1 -0
  113. package/dist/types/index.d.ts +6 -0
  114. package/dist/types/index.d.ts.map +1 -0
  115. package/dist/types/index.js +2 -0
  116. package/dist/types/index.js.map +1 -0
  117. package/dist/types/project.d.ts +33 -0
  118. package/dist/types/project.d.ts.map +1 -0
  119. package/dist/types/project.js +6 -0
  120. package/dist/types/project.js.map +1 -0
  121. package/dist/types/stack.d.ts +29 -0
  122. package/dist/types/stack.d.ts.map +1 -0
  123. package/dist/types/stack.js +6 -0
  124. package/dist/types/stack.js.map +1 -0
  125. package/dist/types/technology.d.ts +47 -0
  126. package/dist/types/technology.d.ts.map +1 -0
  127. package/dist/types/technology.js +6 -0
  128. package/dist/types/technology.js.map +1 -0
  129. package/dist/types/template.d.ts +34 -0
  130. package/dist/types/template.d.ts.map +1 -0
  131. package/dist/types/template.js +6 -0
  132. package/dist/types/template.js.map +1 -0
  133. package/dist/types/validation.d.ts +20 -0
  134. package/dist/types/validation.d.ts.map +1 -0
  135. package/dist/types/validation.js +5 -0
  136. package/dist/types/validation.js.map +1 -0
  137. package/package.json +39 -0
  138. package/src/__tests__/compatibility-scorer.test.ts +264 -0
  139. package/src/__tests__/rules-engine.test.ts +170 -0
  140. package/src/__tests__/scaffold-orchestrator.test.ts +161 -0
  141. package/src/__tests__/stack-engine.test.ts +328 -0
  142. package/src/db/database.ts +112 -0
  143. package/src/db/index.ts +1 -0
  144. package/src/engine/compatibility-scorer.ts +222 -0
  145. package/src/engine/compose-generator.ts +134 -0
  146. package/src/engine/cost-estimator.ts +498 -0
  147. package/src/engine/env-analyzer.ts +156 -0
  148. package/src/engine/health-checker.ts +421 -0
  149. package/src/engine/index.ts +17 -0
  150. package/src/engine/infra-generator.ts +837 -0
  151. package/src/engine/migration-planner.ts +496 -0
  152. package/src/engine/performance-profiler.ts +354 -0
  153. package/src/engine/plugin-loader.ts +216 -0
  154. package/src/engine/preferences.ts +85 -0
  155. package/src/engine/rules-engine.ts +204 -0
  156. package/src/engine/runtime-manager.ts +207 -0
  157. package/src/engine/scaffold-orchestrator.ts +1052 -0
  158. package/src/engine/stack-detector.ts +345 -0
  159. package/src/engine/stack-differ.ts +118 -0
  160. package/src/engine/stack-engine.ts +258 -0
  161. package/src/engine/stack-serializer.ts +95 -0
  162. package/src/engine/standards-linter.ts +210 -0
  163. package/src/engine/tech-installer.ts +650 -0
  164. package/src/index.ts +78 -0
  165. package/src/types/index.ts +10 -0
  166. package/src/types/project.ts +36 -0
  167. package/src/types/stack.ts +32 -0
  168. package/src/types/technology.ts +58 -0
  169. package/src/types/template.ts +37 -0
  170. package/src/types/validation.ts +22 -0
  171. package/tsconfig.json +10 -0
  172. package/tsconfig.tsbuildinfo +1 -0
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Project Instance — A stack materialized on disk.
3
+ * Created by the Scaffold Orchestrator.
4
+ */
5
+ export interface ProjectInstance {
6
+ id: string;
7
+ stackId: string;
8
+ name: string;
9
+ path: string;
10
+ createdAt: string;
11
+ lastOpenedAt?: string;
12
+ templateId?: string;
13
+ }
14
+ /**
15
+ * Runtime State — Live state of a running project.
16
+ * Containers, ports, health checks, processes.
17
+ */
18
+ export interface ServiceStatus {
19
+ name: string;
20
+ technologyId: string;
21
+ containerId?: string;
22
+ status: "running" | "healthy" | "unhealthy" | "exited" | "stopped" | "not_started";
23
+ port?: number;
24
+ healthCheck?: "passing" | "failing" | "none";
25
+ uptime?: number;
26
+ }
27
+ export interface RuntimeState {
28
+ projectId: string;
29
+ services: ServiceStatus[];
30
+ composePath?: string;
31
+ lastChecked: string;
32
+ }
33
+ //# sourceMappingURL=project.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project.d.ts","sourceRoot":"","sources":["../../src/types/project.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;GAGG;AAEH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,GAAG,SAAS,GAAG,aAAa,CAAC;IACnF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,SAAS,GAAG,SAAS,GAAG,MAAM,CAAC;IAC7C,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;CACrB"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Project Instance — A stack materialized on disk.
3
+ * Created by the Scaffold Orchestrator.
4
+ */
5
+ export {};
6
+ //# sourceMappingURL=project.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project.js","sourceRoot":"","sources":["../../src/types/project.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Stack Definition — Abstract definition of a development stack.
3
+ * Not yet a project on disk.
4
+ */
5
+ export interface StackTechnology {
6
+ technologyId: string;
7
+ version: string;
8
+ port?: number;
9
+ config?: Record<string, unknown>;
10
+ }
11
+ export type StackProfile = "rapid" | "standard" | "production" | "enterprise" | "lightweight";
12
+ export interface StackDefinition {
13
+ id: string;
14
+ name: string;
15
+ description: string;
16
+ profile: StackProfile;
17
+ technologies: StackTechnology[];
18
+ createdAt: string;
19
+ updatedAt: string;
20
+ version: number;
21
+ tags: string[];
22
+ }
23
+ export interface StackVersion {
24
+ version: number;
25
+ timestamp: string;
26
+ changelog: string;
27
+ snapshot: StackDefinition;
28
+ }
29
+ //# sourceMappingURL=stack.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stack.d.ts","sourceRoot":"","sources":["../../src/types/stack.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,eAAe;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAED,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,UAAU,GAAG,YAAY,GAAG,YAAY,GAAG,aAAa,CAAC;AAE9F,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,YAAY,CAAC;IACtB,YAAY,EAAE,eAAe,EAAE,CAAC;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,eAAe,CAAC;CAC3B"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Stack Definition — Abstract definition of a development stack.
3
+ * Not yet a project on disk.
4
+ */
5
+ export {};
6
+ //# sourceMappingURL=stack.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stack.js","sourceRoot":"","sources":["../../src/types/stack.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Technology — Atomic unit of the registry catalog.
3
+ * Each technology is deeply modeled with versions, ports, rules, and metadata.
4
+ */
5
+ export type TechnologyCategory =
6
+ | "runtime"
7
+ | "frontend"
8
+ | "backend"
9
+ | "database"
10
+ | "orm"
11
+ | "auth"
12
+ | "styling"
13
+ | "service"
14
+ | "devops";
15
+ export interface TechnologyVersion {
16
+ version: string;
17
+ eol?: string;
18
+ lts?: boolean;
19
+ }
20
+ export interface HealthCheckConfig {
21
+ command?: string;
22
+ endpoint?: string;
23
+ interval?: string;
24
+ timeout?: string;
25
+ retries?: number;
26
+ }
27
+ export interface Technology {
28
+ id: string;
29
+ name: string;
30
+ category: TechnologyCategory;
31
+ description: string;
32
+ website: string;
33
+ versions: TechnologyVersion[];
34
+ defaultVersion: string;
35
+ defaultPort?: number;
36
+ requires: string[];
37
+ incompatibleWith: string[];
38
+ suggestedWith: string[];
39
+ officialScaffold?: string;
40
+ dockerImage?: string;
41
+ healthCheck?: HealthCheckConfig;
42
+ envVars: Record<string, string>;
43
+ configFiles: string[];
44
+ lastVerified: string;
45
+ tags: string[];
46
+ }
47
+ //# sourceMappingURL=technology.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"technology.d.ts","sourceRoot":"","sources":["../../src/types/technology.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,MAAM,kBAAkB,GAC1B,SAAS,GACT,UAAU,GACV,SAAS,GACT,UAAU,GACV,KAAK,GACL,MAAM,GACN,SAAS,GACT,SAAS,GACT,QAAQ,CAAC;AAEb,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAC9B,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IAGrB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,aAAa,EAAE,MAAM,EAAE,CAAC;IAGxB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,iBAAiB,CAAC;IAGhC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,WAAW,EAAE,MAAM,EAAE,CAAC;IAGtB,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Technology — Atomic unit of the registry catalog.
3
+ * Each technology is deeply modeled with versions, ports, rules, and metadata.
4
+ */
5
+ export {};
6
+ //# sourceMappingURL=technology.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"technology.js","sourceRoot":"","sources":["../../src/types/technology.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Template / Blueprint — Preconfigured recipe based on a stack.
3
+ * Templates delegate to official tools and only fill gaps.
4
+ */
5
+ export interface ScaffoldStep {
6
+ name: string;
7
+ command: string;
8
+ workingDir?: string;
9
+ condition?: string;
10
+ }
11
+ export interface TemplateOverride {
12
+ path: string;
13
+ content: string;
14
+ condition?: string;
15
+ }
16
+ export interface TemplateHook {
17
+ timing: "pre-scaffold" | "post-scaffold" | "pre-up" | "post-up";
18
+ name: string;
19
+ command: string;
20
+ description: string;
21
+ requiresConfirmation: boolean;
22
+ }
23
+ export interface Template {
24
+ id: string;
25
+ name: string;
26
+ description: string;
27
+ technologyIds: string[];
28
+ profile: string;
29
+ scaffoldSteps: ScaffoldStep[];
30
+ overrides: TemplateOverride[];
31
+ hooks: TemplateHook[];
32
+ variables: Record<string, string>;
33
+ }
34
+ //# sourceMappingURL=template.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template.d.ts","sourceRoot":"","sources":["../../src/types/template.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,cAAc,GAAG,eAAe,GAAG,QAAQ,GAAG,SAAS,CAAC;IAChE,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,oBAAoB,EAAE,OAAO,CAAC;CAC/B;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,YAAY,EAAE,CAAC;IAC9B,SAAS,EAAE,gBAAgB,EAAE,CAAC;IAC9B,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACnC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Template / Blueprint — Preconfigured recipe based on a stack.
3
+ * Templates delegate to official tools and only fill gaps.
4
+ */
5
+ export {};
6
+ //# sourceMappingURL=template.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template.js","sourceRoot":"","sources":["../../src/types/template.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Validation — Results from the rules engine.
3
+ */
4
+ export type ValidationSeverity = "error" | "warning" | "info";
5
+ export interface ValidationIssue {
6
+ severity: ValidationSeverity;
7
+ code: string;
8
+ message: string;
9
+ technologyId?: string;
10
+ relatedTechnologyId?: string;
11
+ autoFixable: boolean;
12
+ suggestedFix?: string;
13
+ }
14
+ export interface ValidationResult {
15
+ valid: boolean;
16
+ issues: ValidationIssue[];
17
+ resolvedDependencies: string[];
18
+ portAssignments: Record<string, number>;
19
+ }
20
+ //# sourceMappingURL=validation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/types/validation.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,MAAM,kBAAkB,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;AAE9D,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,WAAW,EAAE,OAAO,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,oBAAoB,EAAE,MAAM,EAAE,CAAC;IAC/B,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACzC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Validation — Results from the rules engine.
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=validation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/types/validation.ts"],"names":[],"mappings":"AAAA;;GAEG"}
package/package.json ADDED
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "@stackweld/core",
3
+ "version": "0.2.0",
4
+ "description": "Core engine for Stackweld — rules, scaffold orchestrator, runtime manager, tech installer, and SQLite persistence.",
5
+ "license": "MIT",
6
+ "author": "Orlando Fernandez <hello@xplustechnologies.com>",
7
+ "homepage": "https://github.com/mundowise/Stackweld",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "https://github.com/mundowise/Stackweld.git",
11
+ "directory": "packages/core"
12
+ },
13
+ "type": "module",
14
+ "main": "./dist/index.js",
15
+ "types": "./dist/index.d.ts",
16
+ "exports": {
17
+ ".": "./dist/index.js",
18
+ "./*": "./dist/*.js"
19
+ },
20
+ "scripts": {
21
+ "build": "tsc -b",
22
+ "dev": "tsc -b --watch",
23
+ "test": "vitest run --passWithNoTests",
24
+ "typecheck": "tsc --noEmit",
25
+ "lint": "biome check src/",
26
+ "clean": "rm -rf dist .turbo"
27
+ },
28
+ "dependencies": {
29
+ "ajv": "^8.17.0",
30
+ "better-sqlite3": "^11.0.0",
31
+ "yaml": "^2.7.0"
32
+ },
33
+ "devDependencies": {
34
+ "@biomejs/biome": "^2.0.0",
35
+ "@types/better-sqlite3": "^7.6.0",
36
+ "typescript": "^5.9.0",
37
+ "vitest": "^4.1.2"
38
+ }
39
+ }
@@ -0,0 +1,264 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { scoreCompatibility, scoreStack } from "../engine/compatibility-scorer.js";
3
+ import type { Technology } from "../types/index.js";
4
+
5
+ // ─── Test fixtures ────────────────────────────────────
6
+
7
+ function makeTech(
8
+ overrides: Partial<Technology> & Pick<Technology, "id" | "name" | "category">,
9
+ ): Technology {
10
+ return {
11
+ description: "",
12
+ website: "",
13
+ versions: [{ version: "1" }],
14
+ defaultVersion: "1",
15
+ requires: [],
16
+ incompatibleWith: [],
17
+ suggestedWith: [],
18
+ envVars: {},
19
+ configFiles: [],
20
+ lastVerified: "2026-03-22",
21
+ tags: [],
22
+ ...overrides,
23
+ };
24
+ }
25
+
26
+ const nodejs = makeTech({
27
+ id: "nodejs",
28
+ name: "Node.js",
29
+ category: "runtime",
30
+ defaultPort: 3000,
31
+ suggestedWith: ["typescript"],
32
+ });
33
+
34
+ const nextjs = makeTech({
35
+ id: "nextjs",
36
+ name: "Next.js",
37
+ category: "frontend",
38
+ defaultPort: 3000,
39
+ requires: ["nodejs", "react"],
40
+ incompatibleWith: ["nuxt", "sveltekit", "remix", "astro", "angular", "qwik", "solidjs"],
41
+ suggestedWith: ["typescript", "tailwindcss", "prisma"],
42
+ });
43
+
44
+ const nuxt = makeTech({
45
+ id: "nuxt",
46
+ name: "Nuxt",
47
+ category: "frontend",
48
+ defaultPort: 3000,
49
+ requires: ["nodejs"],
50
+ incompatibleWith: ["nextjs"],
51
+ });
52
+
53
+ const react = makeTech({
54
+ id: "react",
55
+ name: "React",
56
+ category: "frontend",
57
+ defaultPort: 3000,
58
+ requires: ["nodejs"],
59
+ suggestedWith: ["tailwindcss"],
60
+ });
61
+
62
+ const tailwindcss = makeTech({
63
+ id: "tailwindcss",
64
+ name: "Tailwind CSS",
65
+ category: "styling",
66
+ requires: ["nodejs"],
67
+ suggestedWith: ["react", "nextjs", "vue"],
68
+ });
69
+
70
+ const prisma = makeTech({
71
+ id: "prisma",
72
+ name: "Prisma ORM",
73
+ category: "orm",
74
+ requires: ["nodejs"],
75
+ incompatibleWith: ["typeorm", "drizzle", "mongoose"],
76
+ suggestedWith: ["postgresql", "nextjs", "typescript"],
77
+ });
78
+
79
+ const express = makeTech({
80
+ id: "express",
81
+ name: "Express",
82
+ category: "backend",
83
+ defaultPort: 3001,
84
+ requires: ["nodejs"],
85
+ incompatibleWith: ["nestjs", "hono", "fastify"],
86
+ suggestedWith: ["typescript", "postgresql"],
87
+ });
88
+
89
+ const fastify = makeTech({
90
+ id: "fastify",
91
+ name: "Fastify",
92
+ category: "backend",
93
+ defaultPort: 3001,
94
+ requires: ["nodejs"],
95
+ incompatibleWith: ["nestjs", "hono", "express"],
96
+ suggestedWith: ["typescript", "postgresql", "prisma"],
97
+ });
98
+
99
+ const postgresql = makeTech({
100
+ id: "postgresql",
101
+ name: "PostgreSQL",
102
+ category: "database",
103
+ defaultPort: 5432,
104
+ suggestedWith: ["prisma", "drizzle", "sqlalchemy"],
105
+ });
106
+
107
+ const redis = makeTech({
108
+ id: "redis",
109
+ name: "Redis",
110
+ category: "database",
111
+ defaultPort: 6379,
112
+ });
113
+
114
+ const typescript = makeTech({
115
+ id: "typescript",
116
+ name: "TypeScript",
117
+ category: "devops",
118
+ requires: [],
119
+ });
120
+
121
+ // ─── Tests ────────────────────────────────────────────
122
+
123
+ describe("scoreCompatibility", () => {
124
+ it("scores nextjs + prisma high (suggested pairing, shared runtime, complementary)", () => {
125
+ const result = scoreCompatibility(nextjs, prisma);
126
+ // +25 suggested (nextjs suggests prisma OR prisma suggests nextjs)
127
+ // +15 shared runtime (both require nodejs)
128
+ // +10 complementary (frontend + orm)
129
+ expect(result.score).toBeGreaterThanOrEqual(75);
130
+ expect(["S", "A"]).toContain(result.grade);
131
+ expect(result.factors.some((f) => f.label === "Suggested pairing")).toBe(true);
132
+ expect(result.factors.some((f) => f.label === "Shared runtime")).toBe(true);
133
+ expect(result.factors.some((f) => f.label === "Complementary categories")).toBe(true);
134
+ });
135
+
136
+ it("scores nextjs + nuxt as 0 (incompatible)", () => {
137
+ const result = scoreCompatibility(nextjs, nuxt);
138
+ expect(result.score).toBe(0);
139
+ expect(result.grade).toBe("F");
140
+ expect(result.factors.some((f) => f.label === "Incompatible")).toBe(true);
141
+ expect(result.recommendation).toContain("Incompatible");
142
+ });
143
+
144
+ it("scores react + tailwindcss high (suggested, complementary)", () => {
145
+ const result = scoreCompatibility(react, tailwindcss);
146
+ // +25 suggested (both suggest each other)
147
+ // +15 shared runtime (both require nodejs)
148
+ // +10 complementary (frontend + styling)
149
+ expect(result.score).toBeGreaterThanOrEqual(75);
150
+ expect(["S", "A"]).toContain(result.grade);
151
+ expect(result.factors.some((f) => f.label === "Suggested pairing")).toBe(true);
152
+ });
153
+
154
+ it("scores express + fastify low (incompatible, same category, same runtime, same port)", () => {
155
+ const result = scoreCompatibility(express, fastify);
156
+ // -50 incompatible, -15 same category+runtime, -5 same port
157
+ expect(result.score).toBe(0); // clamped to 0
158
+ expect(result.grade).toBe("F");
159
+ expect(result.factors.some((f) => f.label === "Incompatible")).toBe(true);
160
+ expect(result.factors.some((f) => f.label === "Same category and runtime")).toBe(true);
161
+ expect(result.factors.some((f) => f.label === "Port conflict")).toBe(true);
162
+ });
163
+
164
+ it("scores postgresql + redis as neutral (both databases, different ports, no runtime overlap)", () => {
165
+ const result = scoreCompatibility(postgresql, redis);
166
+ // baseline 50, no shared runtime (neither requires a runtime), no suggested
167
+ // no incompatibility, no same runtime => no -15 penalty
168
+ expect(result.score).toBe(50);
169
+ expect(result.grade).toBe("C");
170
+ });
171
+
172
+ it("never exceeds 100", () => {
173
+ // Artificial case: two techs that suggest each other, share runtime, complementary
174
+ const techA = makeTech({
175
+ id: "superA",
176
+ name: "Super A",
177
+ category: "frontend",
178
+ requires: ["nodejs"],
179
+ suggestedWith: ["superB"],
180
+ });
181
+ const techB = makeTech({
182
+ id: "superB",
183
+ name: "Super B",
184
+ category: "backend",
185
+ requires: ["nodejs"],
186
+ suggestedWith: ["superA"],
187
+ });
188
+ const result = scoreCompatibility(techA, techB);
189
+ // 50 + 25 + 15 + 10 = 100
190
+ expect(result.score).toBeLessThanOrEqual(100);
191
+ expect(result.score).toBe(100);
192
+ expect(result.grade).toBe("S");
193
+ });
194
+
195
+ it("never goes below 0", () => {
196
+ const result = scoreCompatibility(express, fastify);
197
+ expect(result.score).toBeGreaterThanOrEqual(0);
198
+ });
199
+
200
+ it("returns correct grade boundaries", () => {
201
+ // S: 90-100 — test with a score of exactly 90
202
+ // We use nextjs + prisma which should give 50+25+15+10 = 100
203
+ const sResult = scoreCompatibility(nextjs, prisma);
204
+ expect(sResult.score).toBeGreaterThanOrEqual(90);
205
+ expect(sResult.grade).toBe("S");
206
+ });
207
+
208
+ it("includes a human-readable recommendation", () => {
209
+ const result = scoreCompatibility(nextjs, prisma);
210
+ expect(typeof result.recommendation).toBe("string");
211
+ expect(result.recommendation.length).toBeGreaterThan(0);
212
+ });
213
+ });
214
+
215
+ describe("scoreStack", () => {
216
+ it("returns perfect score for single technology", () => {
217
+ const result = scoreStack([nextjs]);
218
+ expect(result.overall).toBe(100);
219
+ expect(result.grade).toBe("S");
220
+ expect(result.pairs).toHaveLength(0);
221
+ });
222
+
223
+ it("scores a full stack with 5+ technologies", () => {
224
+ const stack = [nodejs, nextjs, prisma, postgresql, tailwindcss, typescript];
225
+ const result = scoreStack(stack);
226
+
227
+ // Should produce C(6,2) = 15 pairs
228
+ expect(result.pairs).toHaveLength(15);
229
+
230
+ // Overall should be the average of all pair scores
231
+ const expectedAvg = Math.round(
232
+ result.pairs.reduce((s, p) => s + p.score, 0) / result.pairs.length,
233
+ );
234
+ expect(result.overall).toBe(expectedAvg);
235
+
236
+ // Should have a valid grade
237
+ expect(["S", "A", "B", "C", "D", "F"]).toContain(result.grade);
238
+ });
239
+
240
+ it("reflects bad pairings in overall score", () => {
241
+ // Include incompatible pair: nextjs + nuxt
242
+ const stack = [nodejs, nextjs, nuxt, postgresql];
243
+ const result = scoreStack(stack);
244
+
245
+ // The nextjs+nuxt pair should drag down the overall
246
+ const badPair = result.pairs.find(
247
+ (p) => (p.a === "nextjs" && p.b === "nuxt") || (p.a === "nuxt" && p.b === "nextjs"),
248
+ );
249
+ expect(badPair).toBeDefined();
250
+ expect(badPair?.score).toBe(0);
251
+
252
+ // Overall should be lower than a stack without incompatible techs
253
+ const goodStack = [nodejs, nextjs, postgresql];
254
+ const goodResult = scoreStack(goodStack);
255
+ expect(goodResult.overall).toBeGreaterThan(result.overall);
256
+ });
257
+
258
+ it("pair entries contain correct tech IDs", () => {
259
+ const result = scoreStack([express, postgresql]);
260
+ expect(result.pairs).toHaveLength(1);
261
+ expect(result.pairs[0].a).toBe("express");
262
+ expect(result.pairs[0].b).toBe("postgresql");
263
+ });
264
+ });