@hstm-labs/forge-infra-generator 0.1.11

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/README.md ADDED
@@ -0,0 +1,40 @@
1
+ # @hstm-labs/forge-infra-generator
2
+
3
+ Infrastructure configuration generation stage for Forge — produces Dockerfiles, compose configs, CI pipelines, database scripts, environment files, and configuration from architecture output.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @hstm-labs/forge-infra-generator
9
+ ```
10
+
11
+ ## Public API
12
+
13
+ ### Types
14
+
15
+ - `InfraArtifact` — complete infrastructure output
16
+ - `InfraContainer` — Dockerfile definition
17
+ - `InfraComposeConfig` — Docker Compose configuration
18
+ - `InfraCiPipeline` — CI/CD pipeline definition
19
+ - `InfraDatabaseScript` — database migration/init scripts
20
+ - `InfraEnvFile` — environment variable file
21
+ - `InfraConfigFile` — application config file
22
+
23
+ ### Classes
24
+
25
+ - `InfraGenerateStage` — pipeline stage implementing `PipelineStage` interface
26
+ - `InfraOutputValidator` — validates LLM-produced infrastructure output
27
+
28
+ ## Usage
29
+
30
+ ```typescript
31
+ import { InfraGenerateStage } from '@hstm-labs/forge-infra-generator';
32
+
33
+ const stage = new InfraGenerateStage();
34
+ const result = await stage.execute(input);
35
+ // result.data contains InfraArtifact
36
+ ```
37
+
38
+ ## License
39
+
40
+ [MIT](../../LICENSE)
@@ -0,0 +1,4 @@
1
+ export type { InfraArtifact, InfraContainer, InfraComposeConfig, InfraCiPipeline, InfraDatabaseScript, InfraEnvFile, InfraConfigFile, } from './types.js';
2
+ export { InfraGenerateStage } from './infra-generate-stage.js';
3
+ export { InfraOutputValidator } from './validator.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,YAAY,EACV,aAAa,EACb,cAAc,EACd,kBAAkB,EAClB,eAAe,EACf,mBAAmB,EACnB,YAAY,EACZ,eAAe,GAChB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ export { InfraGenerateStage } from './infra-generate-stage.js';
2
+ export { InfraOutputValidator } from './validator.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Infrastructure generation pipeline stage.
3
+ *
4
+ * Produces Dockerfiles, compose configs, CI/CD pipeline definitions,
5
+ * database scripts, environment files, and additional config files
6
+ * from architecture, profile, and specification. Follows the stage
7
+ * implementation pattern established by {@link ArchitectStage} and
8
+ * {@link ServicesGenerateStage}.
9
+ *
10
+ * In API mode, renders prompt templates, calls the LLM via
11
+ * {@link ApiStageExecutor}, validates the output, unpacks individual
12
+ * files, and returns the parsed {@link InfraArtifact} in the stage
13
+ * output data.
14
+ *
15
+ * In agent mode, the pipeline runner intercepts before calling
16
+ * `execute()` and exports a prompt via {@link AgentStageExecutor}.
17
+ */
18
+ import type { StageName } from '@hstm-labs/forge-common';
19
+ import type { PipelineStage, PipelineStageInput, PipelineStageOutput, PipelineContext, AgentPromptContext } from '@hstm-labs/forge-core';
20
+ /**
21
+ * Pipeline stage that generates infrastructure configuration.
22
+ *
23
+ * Produces an {@link InfraArtifact} containing Dockerfiles, compose
24
+ * configuration, CI/CD pipeline, database scripts, environment files,
25
+ * and additional config files. Each element is written as a separate
26
+ * file artifact, preserving directory structure from file names.
27
+ *
28
+ * @example
29
+ * ```ts
30
+ * const stage = new InfraGenerateStage();
31
+ * const output = await stage.execute(input, context);
32
+ * const infra = output.data?.infra as InfraArtifact;
33
+ * ```
34
+ */
35
+ export declare class InfraGenerateStage implements PipelineStage {
36
+ readonly name: StageName;
37
+ readonly dependsOn: StageName[];
38
+ readonly requiresLLM = true;
39
+ /**
40
+ * Return rendered agent-mode prompt context using `infra-generate-agent.hbs`.
41
+ *
42
+ * @param input - Input from prior stages
43
+ * @param context - Pipeline context with config, workspace, and runId
44
+ * @returns Agent prompt context with rendered template and output schema
45
+ */
46
+ getAgentContext(input: PipelineStageInput, context: PipelineContext): AgentPromptContext;
47
+ /**
48
+ * Execute the infrastructure generation stage.
49
+ *
50
+ * @param input - Input from prior stages (expects validate + architect output)
51
+ * @param context - Pipeline context with config, workspace, and adapter
52
+ * @returns Stage output with infra artifacts and parsed InfraArtifact in data
53
+ * @throws {ForgeError} FORGE-PIPE-003 if dependency stage output is missing
54
+ * @throws {ForgeError} FORGE-PIPE-001 if adapter is missing
55
+ * @throws {ForgeError} FORGE-GEN-003 if max retries exhausted
56
+ */
57
+ execute(input: PipelineStageInput, context: PipelineContext): Promise<PipelineStageOutput>;
58
+ }
59
+ //# sourceMappingURL=infra-generate-stage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"infra-generate-stage.d.ts","sourceRoot":"","sources":["../src/infra-generate-stage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAIH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAEzD,OAAO,KAAK,EACV,aAAa,EACb,kBAAkB,EAClB,mBAAmB,EACnB,eAAe,EAEf,kBAAkB,EACnB,MAAM,uBAAuB,CAAC;AAU/B;;;;;;;;;;;;;;GAcG;AACH,qBAAa,kBAAmB,YAAW,aAAa;IACtD,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAoB;IAC5C,QAAQ,CAAC,SAAS,EAAE,SAAS,EAAE,CAAiB;IAChD,QAAQ,CAAC,WAAW,QAAQ;IAE5B;;;;;;OAMG;IACH,eAAe,CACb,KAAK,EAAE,kBAAkB,EACzB,OAAO,EAAE,eAAe,GACvB,kBAAkB;IAwCrB;;;;;;;;;OASG;IACG,OAAO,CACX,KAAK,EAAE,kBAAkB,EACzB,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,mBAAmB,CAAC;CA6KhC"}
@@ -0,0 +1,195 @@
1
+ /**
2
+ * Infrastructure generation pipeline stage.
3
+ *
4
+ * Produces Dockerfiles, compose configs, CI/CD pipeline definitions,
5
+ * database scripts, environment files, and additional config files
6
+ * from architecture, profile, and specification. Follows the stage
7
+ * implementation pattern established by {@link ArchitectStage} and
8
+ * {@link ServicesGenerateStage}.
9
+ *
10
+ * In API mode, renders prompt templates, calls the LLM via
11
+ * {@link ApiStageExecutor}, validates the output, unpacks individual
12
+ * files, and returns the parsed {@link InfraArtifact} in the stage
13
+ * output data.
14
+ *
15
+ * In agent mode, the pipeline runner intercepts before calling
16
+ * `execute()` and exports a prompt via {@link AgentStageExecutor}.
17
+ */
18
+ import { join, dirname } from 'node:path';
19
+ import { writeFileSync, mkdirSync } from 'node:fs';
20
+ import { ForgeError, ErrorCodes, hashContent } from '@hstm-labs/forge-common';
21
+ import { ApiStageExecutor } from '@hstm-labs/forge-core';
22
+ import { loadProfile } from '@hstm-labs/forge-profiles';
23
+ import { loadTemplate, renderTemplate } from '@hstm-labs/forge-templates';
24
+ import { InfraOutputValidator } from './validator.js';
25
+ /**
26
+ * Pipeline stage that generates infrastructure configuration.
27
+ *
28
+ * Produces an {@link InfraArtifact} containing Dockerfiles, compose
29
+ * configuration, CI/CD pipeline, database scripts, environment files,
30
+ * and additional config files. Each element is written as a separate
31
+ * file artifact, preserving directory structure from file names.
32
+ *
33
+ * @example
34
+ * ```ts
35
+ * const stage = new InfraGenerateStage();
36
+ * const output = await stage.execute(input, context);
37
+ * const infra = output.data?.infra as InfraArtifact;
38
+ * ```
39
+ */
40
+ export class InfraGenerateStage {
41
+ name = 'infra-generate';
42
+ dependsOn = ['architect'];
43
+ requiresLLM = true;
44
+ /**
45
+ * Return rendered agent-mode prompt context using `infra-generate-agent.hbs`.
46
+ *
47
+ * @param input - Input from prior stages
48
+ * @param context - Pipeline context with config, workspace, and runId
49
+ * @returns Agent prompt context with rendered template and output schema
50
+ */
51
+ getAgentContext(input, context) {
52
+ const parsedSpec = input['validate']?.data?.['parsedSpec'];
53
+ const architecture = input['architect']?.data?.['architecture'];
54
+ const profile = loadProfile(context.config.profileName, context.workspace.rootDir);
55
+ const outputDir = join(context.workspace.forgeDir, 'runs', context.runId, 'stages', 'infra-generate', 'artifacts');
56
+ const agentTemplate = loadTemplate('infra-generate-agent', context.workspace.rootDir);
57
+ const rendered = renderTemplate(agentTemplate, {
58
+ spec: (parsedSpec ?? {}),
59
+ profile: profile,
60
+ architecture: (architecture ?? {}),
61
+ stage: { outputDir },
62
+ });
63
+ return {
64
+ prompt: rendered.content,
65
+ outputSchema: { format: 'json' },
66
+ };
67
+ }
68
+ /**
69
+ * Execute the infrastructure generation stage.
70
+ *
71
+ * @param input - Input from prior stages (expects validate + architect output)
72
+ * @param context - Pipeline context with config, workspace, and adapter
73
+ * @returns Stage output with infra artifacts and parsed InfraArtifact in data
74
+ * @throws {ForgeError} FORGE-PIPE-003 if dependency stage output is missing
75
+ * @throws {ForgeError} FORGE-PIPE-001 if adapter is missing
76
+ * @throws {ForgeError} FORGE-GEN-003 if max retries exhausted
77
+ */
78
+ async execute(input, context) {
79
+ // 1. Get parsed spec from validate stage output
80
+ const validateOutput = input['validate'];
81
+ if (validateOutput === undefined) {
82
+ throw new ForgeError(ErrorCodes.PIPE.DEPENDENCY_UNMET, "Infra generate stage requires 'validate' stage output, but it was not found. " +
83
+ 'Ensure the validate stage runs before the infra-generate stage.');
84
+ }
85
+ const parsedSpec = validateOutput.data?.['parsedSpec'];
86
+ if (parsedSpec === undefined) {
87
+ throw new ForgeError(ErrorCodes.PIPE.STAGE_FAILURE, 'Validate stage did not produce a parsed specification in its output data. ' +
88
+ 'Ensure the validate stage includes parsedSpec in its data output.');
89
+ }
90
+ // 2. Get architecture from architect stage output
91
+ const architectOutput = input['architect'];
92
+ if (architectOutput === undefined) {
93
+ throw new ForgeError(ErrorCodes.PIPE.DEPENDENCY_UNMET, "Infra generate stage requires 'architect' stage output, but it was not found. " +
94
+ 'Ensure the architect stage runs before the infra-generate stage.');
95
+ }
96
+ const architecture = architectOutput.data?.['architecture'];
97
+ if (architecture === undefined) {
98
+ throw new ForgeError(ErrorCodes.PIPE.STAGE_FAILURE, 'Architect stage did not produce an architecture in its output data. ' +
99
+ 'Ensure the architect stage includes architecture in its data output.');
100
+ }
101
+ // 3. Load profile, determine infra flags
102
+ const profile = loadProfile(context.config.profileName, context.workspace.rootDir);
103
+ const infraSection = profile['infrastructure'] ?? {};
104
+ const hasOrchestration = typeof infraSection['orchestration'] === 'string' && infraSection['orchestration'].length > 0;
105
+ const hasCi = typeof infraSection['ci'] === 'string' && infraSection['ci'].length > 0;
106
+ // 4. Compute output directory
107
+ const outputDir = join(context.workspace.forgeDir, 'runs', context.runId, 'stages', 'infra-generate', 'artifacts');
108
+ // 5. Load and render templates
109
+ const systemTemplate = loadTemplate('infra-generate-system', context.workspace.rootDir);
110
+ const userTemplate = loadTemplate('infra-generate-user', context.workspace.rootDir);
111
+ const templateContext = {
112
+ spec: parsedSpec,
113
+ profile: profile,
114
+ architecture: architecture,
115
+ stage: {
116
+ outputDir,
117
+ },
118
+ };
119
+ const systemPrompt = renderTemplate(systemTemplate, templateContext);
120
+ const userPrompt = renderTemplate(userTemplate, templateContext);
121
+ // 6. Execute via API mode StageExecutor
122
+ if (context.adapter === undefined) {
123
+ throw new ForgeError(ErrorCodes.PIPE.STAGE_FAILURE, 'Infra generate stage requires an LLM adapter in API mode, but none was provided. ' +
124
+ 'Configure an LLM provider in forge.config.json or use agent mode.');
125
+ }
126
+ const validator = new InfraOutputValidator(hasOrchestration, hasCi);
127
+ const executor = new ApiStageExecutor({
128
+ adapter: context.adapter,
129
+ validator,
130
+ retryPolicy: {
131
+ maxRetries: 3,
132
+ backoffMs: 1000,
133
+ includeErrorInRetry: true,
134
+ },
135
+ });
136
+ const result = await executor.execute({
137
+ prompt: userPrompt.content,
138
+ systemPrompt: systemPrompt.content,
139
+ stageName: 'infra-generate',
140
+ outputDir,
141
+ runId: context.runId,
142
+ mode: 'api',
143
+ outputSchema: { format: 'json' },
144
+ });
145
+ // 7. Parse InfraArtifact from LLM output
146
+ const rawContent = result.artifacts[0]?.content ?? '';
147
+ const infraArtifact = JSON.parse(rawContent);
148
+ // 8. Write individual files to artifacts directory
149
+ const artifacts = [];
150
+ // Helper to write a file, creating intermediate directories as needed
151
+ const writeArtifact = (filePath, content) => {
152
+ const fullPath = join(outputDir, filePath);
153
+ mkdirSync(dirname(fullPath), { recursive: true });
154
+ writeFileSync(fullPath, content, 'utf-8');
155
+ artifacts.push({
156
+ filePath,
157
+ content,
158
+ contentHash: hashContent(content),
159
+ sizeBytes: Buffer.byteLength(content, 'utf-8'),
160
+ });
161
+ };
162
+ // Containers (Dockerfiles)
163
+ for (const container of infraArtifact.containers) {
164
+ writeArtifact(container.fileName, container.content);
165
+ }
166
+ // Compose config
167
+ if (infraArtifact.compose !== undefined && infraArtifact.compose !== null) {
168
+ writeArtifact(infraArtifact.compose.fileName, infraArtifact.compose.content);
169
+ }
170
+ // CI pipeline
171
+ if (infraArtifact.ciPipeline !== undefined && infraArtifact.ciPipeline !== null) {
172
+ writeArtifact(infraArtifact.ciPipeline.fileName, infraArtifact.ciPipeline.content);
173
+ }
174
+ // Database scripts
175
+ for (const script of infraArtifact.databaseScripts) {
176
+ writeArtifact(script.fileName, script.content);
177
+ }
178
+ // Environment files
179
+ for (const envFile of infraArtifact.envFiles) {
180
+ writeArtifact(envFile.fileName, envFile.content);
181
+ }
182
+ // Additional config files
183
+ for (const configFile of infraArtifact.configFiles) {
184
+ writeArtifact(configFile.fileName, configFile.content);
185
+ }
186
+ // 9. Return PipelineStageOutput with all artifacts and data
187
+ return {
188
+ artifacts,
189
+ data: {
190
+ infra: infraArtifact,
191
+ },
192
+ };
193
+ }
194
+ }
195
+ //# sourceMappingURL=infra-generate-stage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"infra-generate-stage.js","sourceRoot":"","sources":["../src/infra-generate-stage.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Infrastructure artifact type definitions for the Forge infrastructure generation stage.
3
+ *
4
+ * Defines the output schema produced by the infra generation stage,
5
+ * including containers, compose config, CI/CD pipelines, database
6
+ * scripts, environment files, and additional config files.
7
+ */
8
+ /** Complete infrastructure output produced by the infra-generate stage. */
9
+ export interface InfraArtifact {
10
+ /** Container definitions (Dockerfiles). */
11
+ containers: InfraContainer[];
12
+ /** Compose/orchestration configuration. */
13
+ compose: InfraComposeConfig | undefined;
14
+ /** CI/CD pipeline definition. */
15
+ ciPipeline: InfraCiPipeline | undefined;
16
+ /** Database migration or initialization scripts. */
17
+ databaseScripts: InfraDatabaseScript[];
18
+ /** Environment configuration files. */
19
+ envFiles: InfraEnvFile[];
20
+ /** Additional config files (nginx, etc.). */
21
+ configFiles: InfraConfigFile[];
22
+ }
23
+ /** A Dockerfile definition for a service. */
24
+ export interface InfraContainer {
25
+ /** Service name (e.g., "backend", "frontend", "database"). */
26
+ service: string;
27
+ /** Dockerfile file name (e.g., "Dockerfile.backend"). */
28
+ fileName: string;
29
+ /** Dockerfile content. */
30
+ content: string;
31
+ /** Base image. */
32
+ baseImage: string;
33
+ /** Exposed ports. */
34
+ ports: number[];
35
+ }
36
+ /** Docker Compose or orchestration configuration. */
37
+ export interface InfraComposeConfig {
38
+ /** File name (e.g., "docker-compose.yml"). */
39
+ fileName: string;
40
+ /** File content (YAML). */
41
+ content: string;
42
+ /** Service names defined in the compose file. */
43
+ services: string[];
44
+ }
45
+ /** CI/CD pipeline definition. */
46
+ export interface InfraCiPipeline {
47
+ /** CI platform (e.g., "GitHub Actions", "GitLab CI"). */
48
+ platform: string;
49
+ /** File name (e.g., ".github/workflows/ci.yml"). */
50
+ fileName: string;
51
+ /** File content (YAML). */
52
+ content: string;
53
+ /** Pipeline stages defined. */
54
+ stages: string[];
55
+ }
56
+ /** A database initialization or migration script. */
57
+ export interface InfraDatabaseScript {
58
+ /** Script purpose (e.g., "init", "migration", "seed-schema"). */
59
+ purpose: string;
60
+ /** File name. */
61
+ fileName: string;
62
+ /** File content (SQL or migration script). */
63
+ content: string;
64
+ }
65
+ /** An environment configuration file. */
66
+ export interface InfraEnvFile {
67
+ /** Environment name (e.g., "development", "production", "test"). */
68
+ environment: string;
69
+ /** File name (e.g., ".env.example", ".env.development"). */
70
+ fileName: string;
71
+ /** File content (KEY=value pairs with placeholder secrets). */
72
+ content: string;
73
+ }
74
+ /** An additional configuration file (nginx, eslint, prettier, etc.). */
75
+ export interface InfraConfigFile {
76
+ /** Config purpose (e.g., "nginx", "eslint", "prettier"). */
77
+ purpose: string;
78
+ /** File name. */
79
+ fileName: string;
80
+ /** File content. */
81
+ content: string;
82
+ }
83
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,2EAA2E;AAC3E,MAAM,WAAW,aAAa;IAC5B,2CAA2C;IAC3C,UAAU,EAAE,cAAc,EAAE,CAAC;IAC7B,2CAA2C;IAC3C,OAAO,EAAE,kBAAkB,GAAG,SAAS,CAAC;IACxC,iCAAiC;IACjC,UAAU,EAAE,eAAe,GAAG,SAAS,CAAC;IACxC,oDAAoD;IACpD,eAAe,EAAE,mBAAmB,EAAE,CAAC;IACvC,uCAAuC;IACvC,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,6CAA6C;IAC7C,WAAW,EAAE,eAAe,EAAE,CAAC;CAChC;AAMD,6CAA6C;AAC7C,MAAM,WAAW,cAAc;IAC7B,8DAA8D;IAC9D,OAAO,EAAE,MAAM,CAAC;IAChB,yDAAyD;IACzD,QAAQ,EAAE,MAAM,CAAC;IACjB,0BAA0B;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,kBAAkB;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,qBAAqB;IACrB,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAMD,qDAAqD;AACrD,MAAM,WAAW,kBAAkB;IACjC,8CAA8C;IAC9C,QAAQ,EAAE,MAAM,CAAC;IACjB,2BAA2B;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,iDAAiD;IACjD,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAMD,iCAAiC;AACjC,MAAM,WAAW,eAAe;IAC9B,yDAAyD;IACzD,QAAQ,EAAE,MAAM,CAAC;IACjB,oDAAoD;IACpD,QAAQ,EAAE,MAAM,CAAC;IACjB,2BAA2B;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,+BAA+B;IAC/B,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAMD,qDAAqD;AACrD,MAAM,WAAW,mBAAmB;IAClC,iEAAiE;IACjE,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,8CAA8C;IAC9C,OAAO,EAAE,MAAM,CAAC;CACjB;AAMD,yCAAyC;AACzC,MAAM,WAAW,YAAY;IAC3B,oEAAoE;IACpE,WAAW,EAAE,MAAM,CAAC;IACpB,4DAA4D;IAC5D,QAAQ,EAAE,MAAM,CAAC;IACjB,+DAA+D;IAC/D,OAAO,EAAE,MAAM,CAAC;CACjB;AAMD,wEAAwE;AACxE,MAAM,WAAW,eAAe;IAC9B,4DAA4D;IAC5D,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,oBAAoB;IACpB,OAAO,EAAE,MAAM,CAAC;CACjB"}
package/dist/types.js ADDED
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Infrastructure artifact type definitions for the Forge infrastructure generation stage.
3
+ *
4
+ * Defines the output schema produced by the infra generation stage,
5
+ * including containers, compose config, CI/CD pipelines, database
6
+ * scripts, environment files, and additional config files.
7
+ */
8
+ export {};
9
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Infrastructure output validator for the Forge infra generation stage.
3
+ *
4
+ * Validates LLM-generated infrastructure output against the
5
+ * {@link InfraArtifact} schema with structural, semantic, and
6
+ * security checks.
7
+ */
8
+ import type { OutputValidator, OutputSchema, ValidationResult } from '@hstm-labs/forge-core';
9
+ /**
10
+ * Validator for infrastructure generation stage output.
11
+ *
12
+ * Performs the following checks:
13
+ * 1. JSON parse validation
14
+ * 2. Required top-level keys
15
+ * 3. Non-empty containers with required fields
16
+ * 4. Non-empty envFiles (at least one)
17
+ * 5. Security: scan content for hardcoded secrets (best-effort)
18
+ * 6. Compose validation (when present)
19
+ * 7. CI pipeline validation (when present)
20
+ *
21
+ * @example
22
+ * ```ts
23
+ * const validator = new InfraOutputValidator(true, true);
24
+ * const result = validator.validate(llmOutput, { format: 'json' });
25
+ * ```
26
+ */
27
+ export declare class InfraOutputValidator implements OutputValidator {
28
+ private readonly hasOrchestration;
29
+ private readonly hasCi;
30
+ /**
31
+ * @param hasOrchestration - Whether the profile specifies orchestration
32
+ * @param hasCi - Whether the profile specifies CI
33
+ */
34
+ constructor(hasOrchestration: boolean, hasCi: boolean);
35
+ /**
36
+ * Validate infrastructure output against the InfraArtifact schema.
37
+ *
38
+ * @param output - Raw LLM output text
39
+ * @param _schema - Output schema (format expected to be 'json')
40
+ * @returns Validation result with descriptive errors
41
+ */
42
+ validate(output: string, _schema: OutputSchema): ValidationResult;
43
+ /**
44
+ * Recursively scan all string fields for hardcoded secret patterns.
45
+ * This is a best-effort check, not exhaustive.
46
+ */
47
+ private scanForSecrets;
48
+ }
49
+ //# sourceMappingURL=validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../src/validator.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EACV,eAAe,EACf,YAAY,EACZ,gBAAgB,EAEjB,MAAM,uBAAuB,CAAC;AA4B/B;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,oBAAqB,YAAW,eAAe;IAC1D,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAU;IAC3C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAU;IAEhC;;;OAGG;gBACS,gBAAgB,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO;IAKrD;;;;;;OAMG;IAEH,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,GAAG,gBAAgB;IAmJjE;;;OAGG;IACH,OAAO,CAAC,cAAc;CA2BvB"}
@@ -0,0 +1,233 @@
1
+ /**
2
+ * Infrastructure output validator for the Forge infra generation stage.
3
+ *
4
+ * Validates LLM-generated infrastructure output against the
5
+ * {@link InfraArtifact} schema with structural, semantic, and
6
+ * security checks.
7
+ */
8
+ // ---------------------------------------------------------------------------
9
+ // Constants
10
+ // ---------------------------------------------------------------------------
11
+ const REQUIRED_TOP_LEVEL_KEYS = [
12
+ 'containers',
13
+ 'compose',
14
+ 'ciPipeline',
15
+ 'databaseScripts',
16
+ 'envFiles',
17
+ 'configFiles',
18
+ ];
19
+ /**
20
+ * Best-effort regex patterns to detect hardcoded secrets in content.
21
+ * Matches values that look like real credentials rather than placeholders.
22
+ */
23
+ const HARDCODED_SECRET_PATTERNS = [
24
+ // password=<non-placeholder> (not ${...} or <...> or CHANGEME etc.)
25
+ /(?:password|passwd|secret|api_key|apikey|token|auth)\s*[=:]\s*["']?(?!(\$\{|<|CHANGEME|changeme|placeholder|your_|TODO|xxx))[A-Za-z0-9!@#$%^&*]{8,}["']?/i,
26
+ ];
27
+ // ---------------------------------------------------------------------------
28
+ // Implementation
29
+ // ---------------------------------------------------------------------------
30
+ /**
31
+ * Validator for infrastructure generation stage output.
32
+ *
33
+ * Performs the following checks:
34
+ * 1. JSON parse validation
35
+ * 2. Required top-level keys
36
+ * 3. Non-empty containers with required fields
37
+ * 4. Non-empty envFiles (at least one)
38
+ * 5. Security: scan content for hardcoded secrets (best-effort)
39
+ * 6. Compose validation (when present)
40
+ * 7. CI pipeline validation (when present)
41
+ *
42
+ * @example
43
+ * ```ts
44
+ * const validator = new InfraOutputValidator(true, true);
45
+ * const result = validator.validate(llmOutput, { format: 'json' });
46
+ * ```
47
+ */
48
+ export class InfraOutputValidator {
49
+ hasOrchestration;
50
+ hasCi;
51
+ /**
52
+ * @param hasOrchestration - Whether the profile specifies orchestration
53
+ * @param hasCi - Whether the profile specifies CI
54
+ */
55
+ constructor(hasOrchestration, hasCi) {
56
+ this.hasOrchestration = hasOrchestration;
57
+ this.hasCi = hasCi;
58
+ }
59
+ /**
60
+ * Validate infrastructure output against the InfraArtifact schema.
61
+ *
62
+ * @param output - Raw LLM output text
63
+ * @param _schema - Output schema (format expected to be 'json')
64
+ * @returns Validation result with descriptive errors
65
+ */
66
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
67
+ validate(output, _schema) {
68
+ const errors = [];
69
+ // 1. Parse as JSON
70
+ let parsed;
71
+ try {
72
+ parsed = JSON.parse(output);
73
+ }
74
+ catch {
75
+ errors.push({
76
+ message: 'Infrastructure output is not valid JSON. Ensure the LLM produces only raw JSON without markdown fences or explanatory text.',
77
+ severity: 'error',
78
+ });
79
+ return { valid: false, errors };
80
+ }
81
+ if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {
82
+ errors.push({
83
+ message: 'Infrastructure output must be a JSON object, not an array or primitive.',
84
+ severity: 'error',
85
+ });
86
+ return { valid: false, errors };
87
+ }
88
+ const obj = parsed;
89
+ // 2. Verify required top-level keys
90
+ for (const key of REQUIRED_TOP_LEVEL_KEYS) {
91
+ if (!(key in obj)) {
92
+ errors.push({
93
+ message: `Missing required top-level key: '${key}'.`,
94
+ path: key,
95
+ severity: 'error',
96
+ });
97
+ }
98
+ }
99
+ if (errors.length > 0) {
100
+ return { valid: false, errors };
101
+ }
102
+ // 3. Verify containers is non-empty array with required fields
103
+ const containers = obj['containers'];
104
+ if (!Array.isArray(containers) || containers.length === 0) {
105
+ errors.push({
106
+ message: "Key 'containers' must be a non-empty array of container definitions.",
107
+ path: 'containers',
108
+ severity: 'error',
109
+ });
110
+ }
111
+ else {
112
+ for (let i = 0; i < containers.length; i++) {
113
+ const c = containers[i];
114
+ if (c === undefined || typeof c !== 'object' || c === null) {
115
+ errors.push({
116
+ message: `containers[${String(i)}] is not a valid object.`,
117
+ path: `containers[${String(i)}]`,
118
+ severity: 'error',
119
+ });
120
+ continue;
121
+ }
122
+ for (const field of ['service', 'fileName', 'content', 'baseImage']) {
123
+ if (typeof c[field] !== 'string' || c[field].length === 0) {
124
+ errors.push({
125
+ message: `containers[${String(i)}] is missing required field '${field}'.`,
126
+ path: `containers[${String(i)}].${field}`,
127
+ severity: 'error',
128
+ });
129
+ }
130
+ }
131
+ }
132
+ }
133
+ // 4. Verify envFiles is non-empty
134
+ const envFiles = obj['envFiles'];
135
+ if (!Array.isArray(envFiles) || envFiles.length === 0) {
136
+ errors.push({
137
+ message: "Key 'envFiles' must be a non-empty array — at least one environment file (.env.example) is required.",
138
+ path: 'envFiles',
139
+ severity: 'error',
140
+ });
141
+ }
142
+ // 5. Security check: scan all content fields for hardcoded secrets
143
+ this.scanForSecrets(obj, errors);
144
+ // 6. Compose validation (when present and non-null)
145
+ const compose = obj['compose'];
146
+ if (compose !== null && compose !== undefined) {
147
+ if (typeof compose !== 'object' || Array.isArray(compose)) {
148
+ errors.push({
149
+ message: "Key 'compose' must be an object or null.",
150
+ path: 'compose',
151
+ severity: 'error',
152
+ });
153
+ }
154
+ else {
155
+ const c = compose;
156
+ if (typeof c['content'] !== 'string' || c['content'].length === 0) {
157
+ errors.push({
158
+ message: "Compose config is missing required field 'content'.",
159
+ path: 'compose.content',
160
+ severity: 'error',
161
+ });
162
+ }
163
+ if (!Array.isArray(c['services']) || c['services'].length === 0) {
164
+ errors.push({
165
+ message: "Compose config 'services' must be a non-empty array.",
166
+ path: 'compose.services',
167
+ severity: 'error',
168
+ });
169
+ }
170
+ }
171
+ }
172
+ // 7. CI pipeline validation (when present and non-null)
173
+ const ciPipeline = obj['ciPipeline'];
174
+ if (ciPipeline !== null && ciPipeline !== undefined) {
175
+ if (typeof ciPipeline !== 'object' || Array.isArray(ciPipeline)) {
176
+ errors.push({
177
+ message: "Key 'ciPipeline' must be an object or null.",
178
+ path: 'ciPipeline',
179
+ severity: 'error',
180
+ });
181
+ }
182
+ else {
183
+ const ci = ciPipeline;
184
+ if (typeof ci['content'] !== 'string' || ci['content'].length === 0) {
185
+ errors.push({
186
+ message: "CI pipeline is missing required field 'content'.",
187
+ path: 'ciPipeline.content',
188
+ severity: 'error',
189
+ });
190
+ }
191
+ if (!Array.isArray(ci['stages']) || ci['stages'].length === 0) {
192
+ errors.push({
193
+ message: "CI pipeline 'stages' must be a non-empty array.",
194
+ path: 'ciPipeline.stages',
195
+ severity: 'error',
196
+ });
197
+ }
198
+ }
199
+ }
200
+ return { valid: errors.length === 0, errors };
201
+ }
202
+ /**
203
+ * Recursively scan all string fields for hardcoded secret patterns.
204
+ * This is a best-effort check, not exhaustive.
205
+ */
206
+ scanForSecrets(obj, errors) {
207
+ for (const [key, value] of Object.entries(obj)) {
208
+ if (typeof value === 'string') {
209
+ for (const pattern of HARDCODED_SECRET_PATTERNS) {
210
+ if (pattern.test(value)) {
211
+ errors.push({
212
+ message: `Potential hardcoded secret detected in field '${key}'. Use environment variable placeholders instead.`,
213
+ path: key,
214
+ severity: 'error',
215
+ });
216
+ break;
217
+ }
218
+ }
219
+ }
220
+ else if (Array.isArray(value)) {
221
+ for (const item of value) {
222
+ if (typeof item === 'object' && item !== null && !Array.isArray(item)) {
223
+ this.scanForSecrets(item, errors);
224
+ }
225
+ }
226
+ }
227
+ else if (typeof value === 'object' && value !== null) {
228
+ this.scanForSecrets(value, errors);
229
+ }
230
+ }
231
+ }
232
+ }
233
+ //# sourceMappingURL=validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validator.js","sourceRoot":"","sources":["../src/validator.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,26 @@
1
+ {
2
+ "name": "@hstm-labs/forge-infra-generator",
3
+ "version": "0.1.11",
4
+ "type": "module",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "files": [
8
+ "dist"
9
+ ],
10
+ "publishConfig": {
11
+ "access": "public"
12
+ },
13
+ "scripts": {
14
+ "build": "tsc",
15
+ "test": "vitest run",
16
+ "prepublishOnly": "npm run build"
17
+ },
18
+ "dependencies": {
19
+ "@hstm-labs/forge-common": "0.1.11",
20
+ "@hstm-labs/forge-core": "0.1.11",
21
+ "@hstm-labs/forge-architect": "0.1.11",
22
+ "@hstm-labs/forge-spec-parser": "0.1.11",
23
+ "@hstm-labs/forge-profiles": "0.1.11",
24
+ "@hstm-labs/forge-templates": "0.1.11"
25
+ }
26
+ }