@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,186 @@
1
+ /**
2
+ * Stack Engine — CRUD operations for stack definitions.
3
+ * Handles creation, validation, versioning, and persistence.
4
+ */
5
+ import { randomUUID } from "node:crypto";
6
+ import { getDatabase } from "../db/database.js";
7
+ export class StackEngine {
8
+ rules;
9
+ constructor(rules) {
10
+ this.rules = rules;
11
+ }
12
+ /**
13
+ * Create a new stack definition.
14
+ * Validates technologies and auto-resolves dependencies.
15
+ */
16
+ create(opts) {
17
+ const validation = this.rules.validate(opts.technologies);
18
+ // Add auto-resolved dependencies
19
+ const allTechs = [...opts.technologies];
20
+ for (const depId of validation.resolvedDependencies) {
21
+ const tech = this.rules.getTechnology(depId);
22
+ if (tech) {
23
+ allTechs.push({
24
+ technologyId: depId,
25
+ version: tech.defaultVersion,
26
+ port: validation.portAssignments[depId],
27
+ });
28
+ }
29
+ }
30
+ // Apply port assignments to existing techs
31
+ for (const t of allTechs) {
32
+ if (validation.portAssignments[t.technologyId]) {
33
+ t.port = validation.portAssignments[t.technologyId];
34
+ }
35
+ }
36
+ const now = new Date().toISOString();
37
+ const stack = {
38
+ id: randomUUID(),
39
+ name: opts.name,
40
+ description: opts.description || "",
41
+ profile: opts.profile || "standard",
42
+ technologies: allTechs,
43
+ createdAt: now,
44
+ updatedAt: now,
45
+ version: 1,
46
+ tags: opts.tags || [],
47
+ };
48
+ if (validation.valid) {
49
+ this.persist(stack);
50
+ }
51
+ return { stack, validation };
52
+ }
53
+ /**
54
+ * Get a stack by ID.
55
+ */
56
+ get(id) {
57
+ const db = getDatabase();
58
+ const row = db.prepare("SELECT * FROM stacks WHERE id = ?").get(id);
59
+ if (!row)
60
+ return null;
61
+ const techRows = db
62
+ .prepare("SELECT * FROM stack_technologies WHERE stack_id = ?")
63
+ .all(id);
64
+ return {
65
+ id: row.id,
66
+ name: row.name,
67
+ description: row.description,
68
+ profile: row.profile,
69
+ version: row.version,
70
+ createdAt: row.created_at,
71
+ updatedAt: row.updated_at,
72
+ tags: JSON.parse(row.tags),
73
+ technologies: techRows.map((t) => ({
74
+ technologyId: t.technology_id,
75
+ version: t.version,
76
+ port: t.port,
77
+ config: JSON.parse(t.config || "{}"),
78
+ })),
79
+ };
80
+ }
81
+ /**
82
+ * List all stacks.
83
+ */
84
+ list() {
85
+ const db = getDatabase();
86
+ const rows = db.prepare("SELECT id FROM stacks ORDER BY updated_at DESC").all();
87
+ return rows.map((r) => this.get(r.id)).filter(Boolean);
88
+ }
89
+ /**
90
+ * Delete a stack.
91
+ */
92
+ delete(id) {
93
+ const db = getDatabase();
94
+ const result = db.prepare("DELETE FROM stacks WHERE id = ?").run(id);
95
+ return result.changes > 0;
96
+ }
97
+ /**
98
+ * Update a stack. Auto-increments version and saves snapshot.
99
+ */
100
+ update(id, changes) {
101
+ const existing = this.get(id);
102
+ if (!existing)
103
+ return null;
104
+ const techs = changes.technologies || existing.technologies;
105
+ const validation = this.rules.validate(techs);
106
+ const now = new Date().toISOString();
107
+ const newVersion = existing.version + 1;
108
+ const db = getDatabase();
109
+ db.prepare(`
110
+ UPDATE stacks SET
111
+ name = ?, description = ?, profile = ?, version = ?,
112
+ updated_at = ?, tags = ?
113
+ WHERE id = ?
114
+ `).run(changes.name || existing.name, changes.description ?? existing.description, changes.profile || existing.profile, newVersion, now, JSON.stringify(changes.tags || existing.tags), id);
115
+ // Replace technologies
116
+ db.prepare("DELETE FROM stack_technologies WHERE stack_id = ?").run(id);
117
+ for (const t of techs) {
118
+ db.prepare(`
119
+ INSERT INTO stack_technologies (stack_id, technology_id, version, port, config)
120
+ VALUES (?, ?, ?, ?, ?)
121
+ `).run(id, t.technologyId, t.version, t.port || null, JSON.stringify(t.config || {}));
122
+ }
123
+ // Save version snapshot
124
+ const updatedStack = this.get(id);
125
+ this.saveVersionSnapshot(updatedStack, `Updated to v${newVersion}`);
126
+ return { stack: updatedStack, validation };
127
+ }
128
+ /**
129
+ * Get version history for a stack.
130
+ */
131
+ getVersionHistory(stackId) {
132
+ const db = getDatabase();
133
+ const rows = db
134
+ .prepare("SELECT * FROM stack_versions WHERE stack_id = ? ORDER BY version DESC")
135
+ .all(stackId);
136
+ return rows.map((r) => ({
137
+ version: r.version,
138
+ timestamp: r.created_at,
139
+ changelog: r.changelog,
140
+ snapshot: JSON.parse(r.snapshot),
141
+ }));
142
+ }
143
+ /**
144
+ * Rollback to a specific version.
145
+ */
146
+ rollback(stackId, targetVersion) {
147
+ const db = getDatabase();
148
+ const versionRow = db
149
+ .prepare("SELECT snapshot FROM stack_versions WHERE stack_id = ? AND version = ?")
150
+ .get(stackId, targetVersion);
151
+ if (!versionRow)
152
+ return null;
153
+ const snapshot = JSON.parse(versionRow.snapshot);
154
+ this.update(stackId, {
155
+ name: snapshot.name,
156
+ description: snapshot.description,
157
+ profile: snapshot.profile,
158
+ technologies: snapshot.technologies,
159
+ tags: snapshot.tags,
160
+ });
161
+ return this.get(stackId);
162
+ }
163
+ // ─── Private ────────────────────────────────────────────
164
+ persist(stack) {
165
+ const db = getDatabase();
166
+ db.prepare(`
167
+ INSERT INTO stacks (id, name, description, profile, version, created_at, updated_at, tags)
168
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?)
169
+ `).run(stack.id, stack.name, stack.description, stack.profile, stack.version, stack.createdAt, stack.updatedAt, JSON.stringify(stack.tags));
170
+ for (const t of stack.technologies) {
171
+ db.prepare(`
172
+ INSERT INTO stack_technologies (stack_id, technology_id, version, port, config)
173
+ VALUES (?, ?, ?, ?, ?)
174
+ `).run(stack.id, t.technologyId, t.version, t.port || null, JSON.stringify(t.config || {}));
175
+ }
176
+ this.saveVersionSnapshot(stack, "Initial creation");
177
+ }
178
+ saveVersionSnapshot(stack, changelog) {
179
+ const db = getDatabase();
180
+ db.prepare(`
181
+ INSERT OR REPLACE INTO stack_versions (stack_id, version, changelog, snapshot)
182
+ VALUES (?, ?, ?, ?)
183
+ `).run(stack.id, stack.version, changelog, JSON.stringify(stack));
184
+ }
185
+ }
186
+ //# sourceMappingURL=stack-engine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stack-engine.js","sourceRoot":"","sources":["../../src/engine/stack-engine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Stack Serializer — Compress/decompress stack definitions into URL-safe strings.
3
+ * Uses zlib deflate + base64url encoding. No server needed.
4
+ */
5
+ export interface ShareableStack {
6
+ name: string;
7
+ profile: string;
8
+ technologies: Array<{
9
+ id: string;
10
+ version?: string;
11
+ port?: number;
12
+ }>;
13
+ }
14
+ /**
15
+ * Compress a stack into a URL-safe base64 string.
16
+ * Flow: JSON → deflate → base64url
17
+ */
18
+ export declare function serializeStack(stack: ShareableStack): string;
19
+ /**
20
+ * Decompress from a base64url string back to a stack definition.
21
+ * Flow: base64url → inflate → JSON
22
+ */
23
+ export declare function deserializeStack(encoded: string): ShareableStack;
24
+ /**
25
+ * Generate a full shareable URL for a stack.
26
+ */
27
+ export declare function generateShareUrl(stack: ShareableStack, baseUrl?: string): string;
28
+ /**
29
+ * Extract the encoded payload from a share URL.
30
+ */
31
+ export declare function extractFromShareUrl(url: string): string;
32
+ //# sourceMappingURL=stack-serializer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stack-serializer.d.ts","sourceRoot":"","sources":["../../src/engine/stack-serializer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACtE;AAID;;;GAGG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,CAc5D;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,cAAc,CAmBhE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,cAAc,EACrB,OAAO,GAAE,MAAyB,GACjC,MAAM,CAER;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAMvD"}
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Stack Serializer — Compress/decompress stack definitions into URL-safe strings.
3
+ * Uses zlib deflate + base64url encoding. No server needed.
4
+ */
5
+ import { deflateSync, inflateSync } from "node:zlib";
6
+ const DEFAULT_BASE_URL = "https://stackweld.dev/s/#";
7
+ /**
8
+ * Compress a stack into a URL-safe base64 string.
9
+ * Flow: JSON → deflate → base64url
10
+ */
11
+ export function serializeStack(stack) {
12
+ const json = JSON.stringify({
13
+ n: stack.name,
14
+ p: stack.profile,
15
+ t: stack.technologies.map((t) => {
16
+ const entry = { i: t.id };
17
+ if (t.version)
18
+ entry.v = t.version;
19
+ if (t.port)
20
+ entry.p = t.port;
21
+ return entry;
22
+ }),
23
+ });
24
+ const compressed = deflateSync(Buffer.from(json, "utf-8"));
25
+ return toBase64Url(compressed);
26
+ }
27
+ /**
28
+ * Decompress from a base64url string back to a stack definition.
29
+ * Flow: base64url → inflate → JSON
30
+ */
31
+ export function deserializeStack(encoded) {
32
+ const buffer = fromBase64Url(encoded);
33
+ const json = inflateSync(buffer).toString("utf-8");
34
+ const data = JSON.parse(json);
35
+ return {
36
+ name: data.n,
37
+ profile: data.p,
38
+ technologies: data.t.map((t) => ({
39
+ id: t.i,
40
+ version: t.v,
41
+ port: t.p,
42
+ })),
43
+ };
44
+ }
45
+ /**
46
+ * Generate a full shareable URL for a stack.
47
+ */
48
+ export function generateShareUrl(stack, baseUrl = DEFAULT_BASE_URL) {
49
+ return `${baseUrl}${serializeStack(stack)}`;
50
+ }
51
+ /**
52
+ * Extract the encoded payload from a share URL.
53
+ */
54
+ export function extractFromShareUrl(url) {
55
+ const hashIndex = url.indexOf("#");
56
+ if (hashIndex === -1) {
57
+ throw new Error("Invalid share URL: no hash fragment found.");
58
+ }
59
+ return url.substring(hashIndex + 1);
60
+ }
61
+ // ─── Base64url helpers ────────────────────────────────
62
+ function toBase64Url(buffer) {
63
+ return buffer.toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
64
+ }
65
+ function fromBase64Url(str) {
66
+ let base64 = str.replace(/-/g, "+").replace(/_/g, "/");
67
+ // Add padding
68
+ const pad = base64.length % 4;
69
+ if (pad === 2)
70
+ base64 += "==";
71
+ else if (pad === 3)
72
+ base64 += "=";
73
+ return Buffer.from(base64, "base64");
74
+ }
75
+ //# sourceMappingURL=stack-serializer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stack-serializer.js","sourceRoot":"","sources":["../../src/engine/stack-serializer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Stack Standards Linter — Validates stacks against team-defined standards.
3
+ * Reads .stackweldrc config and checks compliance.
4
+ */
5
+ import type { StackDefinition } from "../types/index.js";
6
+ export interface StackStandards {
7
+ team?: string;
8
+ allowedTechnologies?: string[];
9
+ blockedTechnologies?: string[];
10
+ requiredTechnologies?: string[];
11
+ minProfile?: string;
12
+ requireDocker?: boolean;
13
+ requireTests?: boolean;
14
+ requireTypeScript?: boolean;
15
+ customRules?: Array<{
16
+ name: string;
17
+ check: string;
18
+ message: string;
19
+ }>;
20
+ }
21
+ export interface LintResult {
22
+ passed: boolean;
23
+ violations: LintViolation[];
24
+ warnings: LintWarning[];
25
+ }
26
+ export interface LintViolation {
27
+ rule: string;
28
+ message: string;
29
+ severity: "error" | "warning";
30
+ }
31
+ export type LintWarning = LintViolation;
32
+ export declare function lintStack(stack: StackDefinition, standards: StackStandards): LintResult;
33
+ export declare function loadStandards(projectPath: string): StackStandards | null;
34
+ //# sourceMappingURL=standards-linter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"standards-linter.d.ts","sourceRoot":"","sources":["../../src/engine/standards-linter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAIzD,MAAM,WAAW,cAAc;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC/B,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC/B,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;IAChC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,WAAW,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACvE;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,EAAE,aAAa,EAAE,CAAC;IAC5B,QAAQ,EAAE,WAAW,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAC;CAC/B;AAED,MAAM,MAAM,WAAW,GAAG,aAAa,CAAC;AAkCxC,wBAAgB,SAAS,CAAC,KAAK,EAAE,eAAe,EAAE,SAAS,EAAE,cAAc,GAAG,UAAU,CA2HvF;AAID,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAaxE"}
@@ -0,0 +1,162 @@
1
+ /**
2
+ * Stack Standards Linter — Validates stacks against team-defined standards.
3
+ * Reads .stackweldrc config and checks compliance.
4
+ */
5
+ import * as fs from "node:fs";
6
+ import * as path from "node:path";
7
+ // ─── Profile Ordering ─────────────────────────────────
8
+ const PROFILE_ORDER = {
9
+ lightweight: 0,
10
+ rapid: 1,
11
+ standard: 2,
12
+ production: 3,
13
+ enterprise: 4,
14
+ };
15
+ function profileLevel(profile) {
16
+ return PROFILE_ORDER[profile] ?? -1;
17
+ }
18
+ // ─── Testing Frameworks ───────────────────────────────
19
+ const TESTING_FRAMEWORKS = new Set([
20
+ "vitest",
21
+ "jest",
22
+ "playwright",
23
+ "cypress",
24
+ "mocha",
25
+ "ava",
26
+ "tap",
27
+ "pytest",
28
+ "unittest",
29
+ "go-test",
30
+ "cargo-test",
31
+ ]);
32
+ // ─── Lint Function ────────────────────────────────────
33
+ export function lintStack(stack, standards) {
34
+ const violations = [];
35
+ const warnings = [];
36
+ const techIds = new Set(stack.technologies.map((t) => t.technologyId));
37
+ // Allowed technologies check
38
+ if (standards.allowedTechnologies && standards.allowedTechnologies.length > 0) {
39
+ const allowed = new Set(standards.allowedTechnologies);
40
+ for (const id of techIds) {
41
+ if (!allowed.has(id)) {
42
+ violations.push({
43
+ rule: "allowedTechnologies",
44
+ message: `Technology "${id}" is not in the allowed list`,
45
+ severity: "error",
46
+ });
47
+ }
48
+ }
49
+ }
50
+ // Blocked technologies check
51
+ if (standards.blockedTechnologies && standards.blockedTechnologies.length > 0) {
52
+ for (const blocked of standards.blockedTechnologies) {
53
+ if (techIds.has(blocked)) {
54
+ violations.push({
55
+ rule: "blockedTechnologies",
56
+ message: `Blocked technology "${blocked}" found — remove it`,
57
+ severity: "error",
58
+ });
59
+ }
60
+ }
61
+ }
62
+ // Required technologies check
63
+ if (standards.requiredTechnologies && standards.requiredTechnologies.length > 0) {
64
+ for (const required of standards.requiredTechnologies) {
65
+ if (!techIds.has(required)) {
66
+ violations.push({
67
+ rule: "requiredTechnologies",
68
+ message: `Required technology "${required}" is missing`,
69
+ severity: "error",
70
+ });
71
+ }
72
+ }
73
+ }
74
+ // Minimum profile check
75
+ if (standards.minProfile) {
76
+ const minLevel = profileLevel(standards.minProfile);
77
+ const currentLevel = profileLevel(stack.profile);
78
+ if (minLevel >= 0 && currentLevel < minLevel) {
79
+ warnings.push({
80
+ rule: "minProfile",
81
+ message: `Profile "${stack.profile}" is below minimum "${standards.minProfile}"`,
82
+ severity: "warning",
83
+ });
84
+ }
85
+ }
86
+ // Require Docker
87
+ if (standards.requireDocker) {
88
+ if (!techIds.has("docker") && !techIds.has("docker-compose")) {
89
+ violations.push({
90
+ rule: "requireDocker",
91
+ message: "Docker is required but not present in the stack",
92
+ severity: "error",
93
+ });
94
+ }
95
+ }
96
+ // Require tests
97
+ if (standards.requireTests) {
98
+ const hasTestFramework = Array.from(techIds).some((id) => TESTING_FRAMEWORKS.has(id));
99
+ if (!hasTestFramework) {
100
+ warnings.push({
101
+ rule: "requireTests",
102
+ message: "No testing framework found (vitest, jest, playwright, cypress, etc.)",
103
+ severity: "warning",
104
+ });
105
+ }
106
+ }
107
+ // Require TypeScript
108
+ if (standards.requireTypeScript) {
109
+ if (!techIds.has("typescript")) {
110
+ violations.push({
111
+ rule: "requireTypeScript",
112
+ message: "TypeScript is required but not present in the stack",
113
+ severity: "error",
114
+ });
115
+ }
116
+ }
117
+ // Custom rules (simple presence/absence checks)
118
+ if (standards.customRules) {
119
+ for (const rule of standards.customRules) {
120
+ if (rule.check === "present") {
121
+ if (!techIds.has(rule.name)) {
122
+ violations.push({
123
+ rule: `custom:${rule.name}`,
124
+ message: rule.message,
125
+ severity: "error",
126
+ });
127
+ }
128
+ }
129
+ else if (rule.check === "absent") {
130
+ if (techIds.has(rule.name)) {
131
+ violations.push({
132
+ rule: `custom:${rule.name}`,
133
+ message: rule.message,
134
+ severity: "error",
135
+ });
136
+ }
137
+ }
138
+ }
139
+ }
140
+ const hasErrors = violations.some((v) => v.severity === "error");
141
+ return {
142
+ passed: !hasErrors,
143
+ violations,
144
+ warnings,
145
+ };
146
+ }
147
+ // ─── Config Loader ────────────────────────────────────
148
+ export function loadStandards(projectPath) {
149
+ const configPath = path.resolve(projectPath, ".stackweldrc");
150
+ if (!fs.existsSync(configPath)) {
151
+ return null;
152
+ }
153
+ try {
154
+ const content = fs.readFileSync(configPath, "utf-8");
155
+ const parsed = JSON.parse(content);
156
+ return parsed;
157
+ }
158
+ catch {
159
+ return null;
160
+ }
161
+ }
162
+ //# sourceMappingURL=standards-linter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"standards-linter.js","sourceRoot":"","sources":["../../src/engine/standards-linter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * TechInstaller — Knows how to install and configure EVERY technology
3
+ * in a project directory. Each category has specific installation logic.
4
+ *
5
+ * Categories handled:
6
+ * - database: Docker service + connection env vars
7
+ * - orm: Initialize schema + connect to selected DB
8
+ * - auth: Install package + config files + env vars
9
+ * - styling: Install + configure (Tailwind, shadcn, etc.)
10
+ * - devops: Create config files (biome, vitest, playwright, etc.)
11
+ * - service: Docker service entry
12
+ *
13
+ * Frontend and Backend scaffolding is handled by the generate command directly.
14
+ */
15
+ import type { Technology } from "../types/index.js";
16
+ export interface InstallContext {
17
+ projectDir: string;
18
+ frontendDir: string | null;
19
+ backendDir: string | null;
20
+ projectName: string;
21
+ isFullStack: boolean;
22
+ allTechs: Technology[];
23
+ runtime: "node" | "python" | "go" | "rust" | "bun" | "deno" | "php" | null;
24
+ }
25
+ export interface InstallResult {
26
+ techId: string;
27
+ success: boolean;
28
+ message: string;
29
+ filesCreated: string[];
30
+ }
31
+ /**
32
+ * Install all selected technologies that have installers.
33
+ * Skips runtimes (already handled), frontends/backends (handled by generate),
34
+ * databases (handled by docker-compose), and services (handled by docker-compose).
35
+ */
36
+ export declare function installTechnologies(ctx: InstallContext): InstallResult[];
37
+ //# sourceMappingURL=tech-installer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tech-installer.d.ts","sourceRoot":"","sources":["../../src/engine/tech-installer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAKH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAIpD,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;IACrB,QAAQ,EAAE,UAAU,EAAE,CAAC;IACvB,OAAO,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,IAAI,CAAC;CAC5E;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAokBD;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,cAAc,GAAG,aAAa,EAAE,CA2BxE"}