@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.
- package/.turbo/turbo-build.log +4 -0
- package/.turbo/turbo-lint.log +498 -0
- package/.turbo/turbo-test.log +21 -0
- package/.turbo/turbo-typecheck.log +4 -0
- package/dist/__tests__/compatibility-scorer.test.d.ts +2 -0
- package/dist/__tests__/compatibility-scorer.test.d.ts.map +1 -0
- package/dist/__tests__/compatibility-scorer.test.js +226 -0
- package/dist/__tests__/compatibility-scorer.test.js.map +1 -0
- package/dist/__tests__/rules-engine.test.d.ts +2 -0
- package/dist/__tests__/rules-engine.test.d.ts.map +1 -0
- package/dist/__tests__/rules-engine.test.js +161 -0
- package/dist/__tests__/rules-engine.test.js.map +1 -0
- package/dist/__tests__/scaffold-orchestrator.test.d.ts +2 -0
- package/dist/__tests__/scaffold-orchestrator.test.d.ts.map +1 -0
- package/dist/__tests__/scaffold-orchestrator.test.js +149 -0
- package/dist/__tests__/scaffold-orchestrator.test.js.map +1 -0
- package/dist/__tests__/stack-engine.test.d.ts +2 -0
- package/dist/__tests__/stack-engine.test.d.ts.map +1 -0
- package/dist/__tests__/stack-engine.test.js +278 -0
- package/dist/__tests__/stack-engine.test.js.map +1 -0
- package/dist/db/database.d.ts +9 -0
- package/dist/db/database.d.ts.map +1 -0
- package/dist/db/database.js +106 -0
- package/dist/db/database.js.map +1 -0
- package/dist/db/index.d.ts +2 -0
- package/dist/db/index.d.ts.map +1 -0
- package/dist/db/index.js +2 -0
- package/dist/db/index.js.map +1 -0
- package/dist/engine/compatibility-scorer.d.ts +37 -0
- package/dist/engine/compatibility-scorer.d.ts.map +1 -0
- package/dist/engine/compatibility-scorer.js +178 -0
- package/dist/engine/compatibility-scorer.js.map +1 -0
- package/dist/engine/compose-generator.d.ts +35 -0
- package/dist/engine/compose-generator.d.ts.map +1 -0
- package/dist/engine/compose-generator.js +95 -0
- package/dist/engine/compose-generator.js.map +1 -0
- package/dist/engine/cost-estimator.d.ts +22 -0
- package/dist/engine/cost-estimator.d.ts.map +1 -0
- package/dist/engine/cost-estimator.js +451 -0
- package/dist/engine/cost-estimator.js.map +1 -0
- package/dist/engine/env-analyzer.d.ts +36 -0
- package/dist/engine/env-analyzer.d.ts.map +1 -0
- package/dist/engine/env-analyzer.js +111 -0
- package/dist/engine/env-analyzer.js.map +1 -0
- package/dist/engine/health-checker.d.ts +20 -0
- package/dist/engine/health-checker.d.ts.map +1 -0
- package/dist/engine/health-checker.js +377 -0
- package/dist/engine/health-checker.js.map +1 -0
- package/dist/engine/index.d.ts +11 -0
- package/dist/engine/index.d.ts.map +1 -0
- package/dist/engine/index.js +7 -0
- package/dist/engine/index.js.map +1 -0
- package/dist/engine/infra-generator.d.ts +26 -0
- package/dist/engine/infra-generator.d.ts.map +1 -0
- package/dist/engine/infra-generator.js +751 -0
- package/dist/engine/infra-generator.js.map +1 -0
- package/dist/engine/migration-planner.d.ts +34 -0
- package/dist/engine/migration-planner.d.ts.map +1 -0
- package/dist/engine/migration-planner.js +427 -0
- package/dist/engine/migration-planner.js.map +1 -0
- package/dist/engine/performance-profiler.d.ts +22 -0
- package/dist/engine/performance-profiler.d.ts.map +1 -0
- package/dist/engine/performance-profiler.js +292 -0
- package/dist/engine/performance-profiler.js.map +1 -0
- package/dist/engine/plugin-loader.d.ts +36 -0
- package/dist/engine/plugin-loader.d.ts.map +1 -0
- package/dist/engine/plugin-loader.js +157 -0
- package/dist/engine/plugin-loader.js.map +1 -0
- package/dist/engine/preferences.d.ts +24 -0
- package/dist/engine/preferences.d.ts.map +1 -0
- package/dist/engine/preferences.js +62 -0
- package/dist/engine/preferences.js.map +1 -0
- package/dist/engine/rules-engine.d.ts +31 -0
- package/dist/engine/rules-engine.d.ts.map +1 -0
- package/dist/engine/rules-engine.js +179 -0
- package/dist/engine/rules-engine.js.map +1 -0
- package/dist/engine/runtime-manager.d.ts +65 -0
- package/dist/engine/runtime-manager.d.ts.map +1 -0
- package/dist/engine/runtime-manager.js +181 -0
- package/dist/engine/runtime-manager.js.map +1 -0
- package/dist/engine/scaffold-orchestrator.d.ts +103 -0
- package/dist/engine/scaffold-orchestrator.d.ts.map +1 -0
- package/dist/engine/scaffold-orchestrator.js +934 -0
- package/dist/engine/scaffold-orchestrator.js.map +1 -0
- package/dist/engine/stack-detector.d.ts +21 -0
- package/dist/engine/stack-detector.d.ts.map +1 -0
- package/dist/engine/stack-detector.js +313 -0
- package/dist/engine/stack-detector.js.map +1 -0
- package/dist/engine/stack-differ.d.ts +26 -0
- package/dist/engine/stack-differ.d.ts.map +1 -0
- package/dist/engine/stack-differ.js +80 -0
- package/dist/engine/stack-differ.js.map +1 -0
- package/dist/engine/stack-engine.d.ts +54 -0
- package/dist/engine/stack-engine.d.ts.map +1 -0
- package/dist/engine/stack-engine.js +186 -0
- package/dist/engine/stack-engine.js.map +1 -0
- package/dist/engine/stack-serializer.d.ts +32 -0
- package/dist/engine/stack-serializer.d.ts.map +1 -0
- package/dist/engine/stack-serializer.js +75 -0
- package/dist/engine/stack-serializer.js.map +1 -0
- package/dist/engine/standards-linter.d.ts +34 -0
- package/dist/engine/standards-linter.d.ts.map +1 -0
- package/dist/engine/standards-linter.js +162 -0
- package/dist/engine/standards-linter.js.map +1 -0
- package/dist/engine/tech-installer.d.ts +37 -0
- package/dist/engine/tech-installer.d.ts.map +1 -0
- package/dist/engine/tech-installer.js +508 -0
- package/dist/engine/tech-installer.js.map +1 -0
- package/dist/index.d.ts +39 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +25 -0
- package/dist/index.js.map +1 -0
- package/dist/types/index.d.ts +6 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/project.d.ts +33 -0
- package/dist/types/project.d.ts.map +1 -0
- package/dist/types/project.js +6 -0
- package/dist/types/project.js.map +1 -0
- package/dist/types/stack.d.ts +29 -0
- package/dist/types/stack.d.ts.map +1 -0
- package/dist/types/stack.js +6 -0
- package/dist/types/stack.js.map +1 -0
- package/dist/types/technology.d.ts +47 -0
- package/dist/types/technology.d.ts.map +1 -0
- package/dist/types/technology.js +6 -0
- package/dist/types/technology.js.map +1 -0
- package/dist/types/template.d.ts +34 -0
- package/dist/types/template.d.ts.map +1 -0
- package/dist/types/template.js +6 -0
- package/dist/types/template.js.map +1 -0
- package/dist/types/validation.d.ts +20 -0
- package/dist/types/validation.d.ts.map +1 -0
- package/dist/types/validation.js +5 -0
- package/dist/types/validation.js.map +1 -0
- package/package.json +39 -0
- package/src/__tests__/compatibility-scorer.test.ts +264 -0
- package/src/__tests__/rules-engine.test.ts +170 -0
- package/src/__tests__/scaffold-orchestrator.test.ts +161 -0
- package/src/__tests__/stack-engine.test.ts +328 -0
- package/src/db/database.ts +112 -0
- package/src/db/index.ts +1 -0
- package/src/engine/compatibility-scorer.ts +222 -0
- package/src/engine/compose-generator.ts +134 -0
- package/src/engine/cost-estimator.ts +498 -0
- package/src/engine/env-analyzer.ts +156 -0
- package/src/engine/health-checker.ts +421 -0
- package/src/engine/index.ts +17 -0
- package/src/engine/infra-generator.ts +837 -0
- package/src/engine/migration-planner.ts +496 -0
- package/src/engine/performance-profiler.ts +354 -0
- package/src/engine/plugin-loader.ts +216 -0
- package/src/engine/preferences.ts +85 -0
- package/src/engine/rules-engine.ts +204 -0
- package/src/engine/runtime-manager.ts +207 -0
- package/src/engine/scaffold-orchestrator.ts +1052 -0
- package/src/engine/stack-detector.ts +345 -0
- package/src/engine/stack-differ.ts +118 -0
- package/src/engine/stack-engine.ts +258 -0
- package/src/engine/stack-serializer.ts +95 -0
- package/src/engine/standards-linter.ts +210 -0
- package/src/engine/tech-installer.ts +650 -0
- package/src/index.ts +78 -0
- package/src/types/index.ts +10 -0
- package/src/types/project.ts +36 -0
- package/src/types/stack.ts +32 -0
- package/src/types/technology.ts +58 -0
- package/src/types/template.ts +37 -0
- package/src/types/validation.ts +22 -0
- package/tsconfig.json +10 -0
- 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 @@
|
|
|
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 @@
|
|
|
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 @@
|
|
|
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 @@
|
|
|
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 @@
|
|
|
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
|
+
});
|