aios-core 2.1.4 → 2.1.6
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/.aios-core/development/tasks/analyze-brownfield.md +456 -456
- package/.aios-core/development/tasks/setup-project-docs.md +440 -444
- package/.aios-core/infrastructure/scripts/documentation-integrity/brownfield-analyzer.js +501 -501
- package/.aios-core/infrastructure/scripts/documentation-integrity/config-generator.js +368 -329
- package/.aios-core/infrastructure/scripts/documentation-integrity/deployment-config-loader.js +308 -282
- package/.aios-core/infrastructure/scripts/documentation-integrity/doc-generator.js +331 -331
- package/.aios-core/infrastructure/scripts/documentation-integrity/gitignore-generator.js +312 -312
- package/.aios-core/infrastructure/scripts/documentation-integrity/index.js +74 -74
- package/.aios-core/infrastructure/scripts/documentation-integrity/mode-detector.js +389 -358
- package/.aios-core/infrastructure/scripts/llm-routing/install-llm-routing.js +6 -6
- package/.aios-core/infrastructure/templates/core-config/core-config-brownfield.tmpl.yaml +176 -182
- package/.aios-core/infrastructure/templates/core-config/core-config-greenfield.tmpl.yaml +127 -127
- package/.aios-core/infrastructure/templates/project-docs/coding-standards-tmpl.md +346 -346
- package/.aios-core/infrastructure/templates/project-docs/source-tree-tmpl.md +177 -177
- package/.aios-core/infrastructure/templates/project-docs/tech-stack-tmpl.md +267 -267
- package/package.json +1 -1
- package/packages/installer/src/config/templates/env-template.js +2 -2
- package/packages/installer/src/wizard/wizard.js +1 -1
- package/packages/installer/tests/integration/environment-configuration.test.js +2 -1
- package/packages/installer/tests/unit/env-template.test.js +3 -2
- package/src/wizard/index.js +2 -2
- package/.aios-core/development/tasks/validate-structure.md +0 -243
- package/.aios-core/infrastructure/scripts/source-tree-guardian/index.js +0 -375
- package/.aios-core/infrastructure/scripts/source-tree-guardian/manifest-generator.js +0 -410
- package/.aios-core/infrastructure/scripts/source-tree-guardian/rules/naming-rules.yaml +0 -285
- package/.aios-core/infrastructure/scripts/source-tree-guardian/rules/placement-rules.yaml +0 -262
- package/.aios-core/infrastructure/scripts/source-tree-guardian/validator.js +0 -468
|
@@ -1,329 +1,368 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Config Generator Module
|
|
3
|
-
*
|
|
4
|
-
* Generates project-specific core-config.yaml from templates.
|
|
5
|
-
* Supports greenfield and brownfield modes with deployment configuration.
|
|
6
|
-
*
|
|
7
|
-
* @module documentation-integrity/config-generator
|
|
8
|
-
* @version 1.0.0
|
|
9
|
-
* @story 6.9
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
const fs = require('fs');
|
|
13
|
-
const path = require('path');
|
|
14
|
-
const yaml = require('yaml');
|
|
15
|
-
|
|
16
|
-
// Template directory
|
|
17
|
-
const TEMPLATES_DIR = path.join(__dirname, '..', '..', 'templates', 'core-config');
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Template file names
|
|
21
|
-
* @enum {string}
|
|
22
|
-
*/
|
|
23
|
-
const ConfigTemplates = {
|
|
24
|
-
GREENFIELD: 'core-config-greenfield.tmpl.yaml',
|
|
25
|
-
BROWNFIELD: 'core-config-brownfield.tmpl.yaml',
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Deployment workflow types
|
|
30
|
-
* @enum {string}
|
|
31
|
-
*/
|
|
32
|
-
const DeploymentWorkflow = {
|
|
33
|
-
STAGING_FIRST: 'staging-first',
|
|
34
|
-
DIRECT_TO_MAIN: 'direct-to-main',
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Deployment platform options
|
|
39
|
-
* @enum {string}
|
|
40
|
-
*/
|
|
41
|
-
const DeploymentPlatform = {
|
|
42
|
-
RAILWAY: 'Railway',
|
|
43
|
-
VERCEL: 'Vercel',
|
|
44
|
-
AWS: 'AWS',
|
|
45
|
-
DOCKER: 'Docker',
|
|
46
|
-
NONE: 'None',
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Default deployment configuration
|
|
51
|
-
* @type {Object}
|
|
52
|
-
*/
|
|
53
|
-
const DEFAULT_DEPLOYMENT_CONFIG = {
|
|
54
|
-
workflow: DeploymentWorkflow.STAGING_FIRST,
|
|
55
|
-
stagingBranch: 'staging',
|
|
56
|
-
productionBranch: 'main',
|
|
57
|
-
defaultTarget: 'staging',
|
|
58
|
-
stagingEnvName: 'Staging',
|
|
59
|
-
productionEnvName: 'Production',
|
|
60
|
-
platform: DeploymentPlatform.NONE,
|
|
61
|
-
qualityGates: {
|
|
62
|
-
lint: true,
|
|
63
|
-
typecheck: true,
|
|
64
|
-
tests: true,
|
|
65
|
-
|
|
66
|
-
minCoverage: 50,
|
|
67
|
-
},
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
* @param {string}
|
|
74
|
-
* @
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
//
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
*
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
*
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Config Generator Module
|
|
3
|
+
*
|
|
4
|
+
* Generates project-specific core-config.yaml from templates.
|
|
5
|
+
* Supports greenfield and brownfield modes with deployment configuration.
|
|
6
|
+
*
|
|
7
|
+
* @module documentation-integrity/config-generator
|
|
8
|
+
* @version 1.0.0
|
|
9
|
+
* @story 6.9
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
const fs = require('fs');
|
|
13
|
+
const path = require('path');
|
|
14
|
+
const yaml = require('yaml');
|
|
15
|
+
|
|
16
|
+
// Template directory
|
|
17
|
+
const TEMPLATES_DIR = path.join(__dirname, '..', '..', 'templates', 'core-config');
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Template file names
|
|
21
|
+
* @enum {string}
|
|
22
|
+
*/
|
|
23
|
+
const ConfigTemplates = {
|
|
24
|
+
GREENFIELD: 'core-config-greenfield.tmpl.yaml',
|
|
25
|
+
BROWNFIELD: 'core-config-brownfield.tmpl.yaml',
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Deployment workflow types
|
|
30
|
+
* @enum {string}
|
|
31
|
+
*/
|
|
32
|
+
const DeploymentWorkflow = {
|
|
33
|
+
STAGING_FIRST: 'staging-first',
|
|
34
|
+
DIRECT_TO_MAIN: 'direct-to-main',
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Deployment platform options
|
|
39
|
+
* @enum {string}
|
|
40
|
+
*/
|
|
41
|
+
const DeploymentPlatform = {
|
|
42
|
+
RAILWAY: 'Railway',
|
|
43
|
+
VERCEL: 'Vercel',
|
|
44
|
+
AWS: 'AWS',
|
|
45
|
+
DOCKER: 'Docker',
|
|
46
|
+
NONE: 'None',
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Default deployment configuration
|
|
51
|
+
* @type {Object}
|
|
52
|
+
*/
|
|
53
|
+
const DEFAULT_DEPLOYMENT_CONFIG = {
|
|
54
|
+
workflow: DeploymentWorkflow.STAGING_FIRST,
|
|
55
|
+
stagingBranch: 'staging',
|
|
56
|
+
productionBranch: 'main',
|
|
57
|
+
defaultTarget: 'staging',
|
|
58
|
+
stagingEnvName: 'Staging',
|
|
59
|
+
productionEnvName: 'Production',
|
|
60
|
+
platform: DeploymentPlatform.NONE,
|
|
61
|
+
qualityGates: {
|
|
62
|
+
lint: true,
|
|
63
|
+
typecheck: true,
|
|
64
|
+
tests: true,
|
|
65
|
+
securityScan: false,
|
|
66
|
+
minCoverage: 50,
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Escapes a string for use in YAML double-quoted strings
|
|
72
|
+
*
|
|
73
|
+
* @param {string} str - String to escape
|
|
74
|
+
* @returns {string} Escaped string safe for YAML
|
|
75
|
+
*/
|
|
76
|
+
function escapeYamlString(str) {
|
|
77
|
+
return String(str)
|
|
78
|
+
.replace(/\\/g, '\\\\') // Escape backslashes first
|
|
79
|
+
.replace(/"/g, '\\"') // Escape double quotes
|
|
80
|
+
.replace(/\n/g, '\\n') // Escape newlines
|
|
81
|
+
.replace(/\r/g, '\\r') // Escape carriage returns
|
|
82
|
+
.replace(/\t/g, '\\t'); // Escape tabs
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Formats an array as YAML list string for template substitution
|
|
87
|
+
*
|
|
88
|
+
* @param {Array} arr - Array to format
|
|
89
|
+
* @param {number} [indent=4] - Number of spaces for indentation
|
|
90
|
+
* @returns {string} YAML-formatted array string
|
|
91
|
+
*/
|
|
92
|
+
function formatArrayAsYaml(arr, indent = 4) {
|
|
93
|
+
if (!Array.isArray(arr) || arr.length === 0) {
|
|
94
|
+
return '[]';
|
|
95
|
+
}
|
|
96
|
+
const spaces = ' '.repeat(indent);
|
|
97
|
+
const items = arr.map((item) => `\n${spaces}- "${escapeYamlString(item)}"`).join('');
|
|
98
|
+
return items;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Builds config context from project info and deployment settings
|
|
103
|
+
*
|
|
104
|
+
* @param {string} projectName - Project name
|
|
105
|
+
* @param {string} mode - Installation mode (greenfield/brownfield)
|
|
106
|
+
* @param {Object} deploymentConfig - Deployment configuration
|
|
107
|
+
* @param {Object} [analysisResults] - Brownfield analysis results (if applicable)
|
|
108
|
+
* @returns {Object} Config context for template rendering
|
|
109
|
+
*/
|
|
110
|
+
function buildConfigContext(projectName, mode, deploymentConfig = {}, analysisResults = {}) {
|
|
111
|
+
const config = { ...DEFAULT_DEPLOYMENT_CONFIG, ...deploymentConfig };
|
|
112
|
+
const isStaging = config.workflow === DeploymentWorkflow.STAGING_FIRST;
|
|
113
|
+
|
|
114
|
+
const context = {
|
|
115
|
+
// Basic info
|
|
116
|
+
PROJECT_NAME: projectName,
|
|
117
|
+
GENERATED_DATE: new Date().toISOString().split('T')[0],
|
|
118
|
+
PROJECT_VERSION: analysisResults.version || '0.1.0',
|
|
119
|
+
|
|
120
|
+
// Deployment workflow
|
|
121
|
+
DEPLOYMENT_WORKFLOW: config.workflow,
|
|
122
|
+
|
|
123
|
+
// Branch configuration
|
|
124
|
+
STAGING_BRANCH: isStaging ? config.stagingBranch : 'null',
|
|
125
|
+
PRODUCTION_BRANCH: config.productionBranch,
|
|
126
|
+
// Use symbolic name ('staging'/'production') - deployment-config-loader resolves to actual branch
|
|
127
|
+
DEFAULT_TARGET: isStaging ? 'staging' : 'production',
|
|
128
|
+
|
|
129
|
+
// Environment names
|
|
130
|
+
STAGING_ENV_NAME: config.stagingEnvName,
|
|
131
|
+
PRODUCTION_ENV_NAME: config.productionEnvName,
|
|
132
|
+
|
|
133
|
+
// Platform
|
|
134
|
+
DEPLOYMENT_PLATFORM: config.platform,
|
|
135
|
+
|
|
136
|
+
// Quality gates
|
|
137
|
+
QUALITY_LINT: config.qualityGates.lint,
|
|
138
|
+
QUALITY_TYPECHECK: config.qualityGates.typecheck,
|
|
139
|
+
QUALITY_TESTS: config.qualityGates.tests,
|
|
140
|
+
QUALITY_SECURITY: config.qualityGates.securityScan || false,
|
|
141
|
+
MIN_COVERAGE: config.qualityGates.minCoverage || 50,
|
|
142
|
+
|
|
143
|
+
// Brownfield specific (defaults for greenfield)
|
|
144
|
+
HAS_EXISTING_STRUCTURE: analysisResults.hasExistingStructure || false,
|
|
145
|
+
HAS_EXISTING_WORKFLOWS: analysisResults.hasExistingWorkflows || false,
|
|
146
|
+
HAS_EXISTING_STANDARDS: analysisResults.hasExistingStandards || false,
|
|
147
|
+
MERGE_STRATEGY: analysisResults.mergeStrategy || 'parallel',
|
|
148
|
+
|
|
149
|
+
// Detected configs (brownfield)
|
|
150
|
+
DETECTED_TECH_STACK: JSON.stringify(analysisResults.techStack || []),
|
|
151
|
+
DETECTED_FRAMEWORKS: JSON.stringify(analysisResults.frameworks || []),
|
|
152
|
+
DETECTED_LINTING: analysisResults.linting || 'none',
|
|
153
|
+
DETECTED_FORMATTING: analysisResults.formatting || 'none',
|
|
154
|
+
DETECTED_TESTING: analysisResults.testing || 'none',
|
|
155
|
+
|
|
156
|
+
// Auto deploy settings
|
|
157
|
+
STAGING_AUTO_DEPLOY: config.stagingAutoDeploy !== false,
|
|
158
|
+
PRODUCTION_AUTO_DEPLOY: config.productionAutoDeploy !== false,
|
|
159
|
+
|
|
160
|
+
// PR settings
|
|
161
|
+
AUTO_ASSIGN_REVIEWERS: config.autoAssignReviewers || false,
|
|
162
|
+
DRAFT_BY_DEFAULT: config.draftByDefault || false,
|
|
163
|
+
|
|
164
|
+
// Existing config paths (brownfield)
|
|
165
|
+
ESLINT_CONFIG_PATH: analysisResults.eslintPath || 'null',
|
|
166
|
+
PRETTIER_CONFIG_PATH: analysisResults.prettierPath || 'null',
|
|
167
|
+
TSCONFIG_PATH: analysisResults.tsconfigPath || 'null',
|
|
168
|
+
FLAKE8_CONFIG_PATH: analysisResults.flake8Path || 'null',
|
|
169
|
+
GITHUB_WORKFLOWS_PATH: analysisResults.githubWorkflowsPath || 'null',
|
|
170
|
+
GITLAB_CI_PATH: analysisResults.gitlabCiPath || 'null',
|
|
171
|
+
PACKAGE_JSON_PATH: analysisResults.packageJsonPath || 'null',
|
|
172
|
+
REQUIREMENTS_PATH: analysisResults.requirementsPath || 'null',
|
|
173
|
+
GO_MOD_PATH: analysisResults.goModPath || 'null',
|
|
174
|
+
|
|
175
|
+
// Merge settings
|
|
176
|
+
MERGE_WORKFLOWS: analysisResults.mergeWorkflows || false,
|
|
177
|
+
|
|
178
|
+
// Migration notes (brownfield)
|
|
179
|
+
MIGRATION_SUMMARY: analysisResults.summary || 'No analysis performed',
|
|
180
|
+
MANUAL_REVIEW_ITEMS: analysisResults.manualReviewItems || [],
|
|
181
|
+
CONFLICTS: analysisResults.conflicts || [],
|
|
182
|
+
RECOMMENDATIONS: analysisResults.recommendations || [],
|
|
183
|
+
|
|
184
|
+
// Pre-formatted YAML arrays for template substitution (avoids Handlebars #each)
|
|
185
|
+
MANUAL_REVIEW_ITEMS_YAML: formatArrayAsYaml(analysisResults.manualReviewItems || []),
|
|
186
|
+
CONFLICTS_YAML: formatArrayAsYaml(analysisResults.conflicts || []),
|
|
187
|
+
RECOMMENDATIONS_YAML: formatArrayAsYaml(analysisResults.recommendations || []),
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
return context;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Renders a YAML template with context
|
|
195
|
+
*
|
|
196
|
+
* @param {string} template - Template content
|
|
197
|
+
* @param {Object} context - Context object
|
|
198
|
+
* @returns {string} Rendered YAML content
|
|
199
|
+
*/
|
|
200
|
+
function renderConfigTemplate(template, context) {
|
|
201
|
+
let result = template;
|
|
202
|
+
|
|
203
|
+
// Process {{#each}} blocks
|
|
204
|
+
result = processEachBlocks(result, context);
|
|
205
|
+
|
|
206
|
+
// Replace simple variables {{variable}}
|
|
207
|
+
result = result.replace(/\{\{([^#/}][^}]*)\}\}/g, (match, key) => {
|
|
208
|
+
const value = context[key.trim()];
|
|
209
|
+
if (value === undefined) return match;
|
|
210
|
+
if (typeof value === 'boolean') return value.toString();
|
|
211
|
+
if (typeof value === 'number') return value.toString();
|
|
212
|
+
return String(value);
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
return result;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Process {{#each array}}...{{/each}} blocks
|
|
220
|
+
*
|
|
221
|
+
* @param {string} template - Template string
|
|
222
|
+
* @param {Object} context - Context object
|
|
223
|
+
* @returns {string} Processed template
|
|
224
|
+
*/
|
|
225
|
+
function processEachBlocks(template, context) {
|
|
226
|
+
const eachRegex = /\{\{#each\s+(\w+)\}\}([\s\S]*?)\{\{\/each\}\}/g;
|
|
227
|
+
|
|
228
|
+
return template.replace(eachRegex, (match, arrayName, content) => {
|
|
229
|
+
const array = context[arrayName];
|
|
230
|
+
if (!Array.isArray(array) || array.length === 0) {
|
|
231
|
+
return '';
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
return array
|
|
235
|
+
.map((item) => {
|
|
236
|
+
return content.replace(/\{\{this\}\}/g, String(item));
|
|
237
|
+
})
|
|
238
|
+
.join('');
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Loads a config template
|
|
244
|
+
*
|
|
245
|
+
* @param {string} templateName - Template file name
|
|
246
|
+
* @returns {string} Template content
|
|
247
|
+
* @throws {Error} If template not found
|
|
248
|
+
*/
|
|
249
|
+
function loadConfigTemplate(templateName) {
|
|
250
|
+
const templatePath = path.join(TEMPLATES_DIR, templateName);
|
|
251
|
+
|
|
252
|
+
if (!fs.existsSync(templatePath)) {
|
|
253
|
+
throw new Error(`Config template not found: ${templatePath}`);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
return fs.readFileSync(templatePath, 'utf8');
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Generates core-config.yaml for a project
|
|
261
|
+
*
|
|
262
|
+
* @param {string} targetDir - Target directory
|
|
263
|
+
* @param {string} mode - Installation mode (greenfield/brownfield)
|
|
264
|
+
* @param {Object} context - Config context
|
|
265
|
+
* @param {Object} [options] - Generation options
|
|
266
|
+
* @param {boolean} [options.dryRun] - Don't write file, just return content
|
|
267
|
+
* @returns {Object} Generation result
|
|
268
|
+
*/
|
|
269
|
+
function generateConfig(targetDir, mode, context, options = {}) {
|
|
270
|
+
const templateName =
|
|
271
|
+
mode === 'brownfield' ? ConfigTemplates.BROWNFIELD : ConfigTemplates.GREENFIELD;
|
|
272
|
+
|
|
273
|
+
try {
|
|
274
|
+
const template = loadConfigTemplate(templateName);
|
|
275
|
+
const rendered = renderConfigTemplate(template, context);
|
|
276
|
+
|
|
277
|
+
// Validate YAML syntax
|
|
278
|
+
try {
|
|
279
|
+
yaml.parse(rendered);
|
|
280
|
+
} catch (yamlError) {
|
|
281
|
+
return {
|
|
282
|
+
success: false,
|
|
283
|
+
error: `Generated YAML is invalid: ${yamlError.message}`,
|
|
284
|
+
content: rendered,
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
const configDir = path.join(targetDir, '.aios-core');
|
|
289
|
+
const configPath = path.join(configDir, 'core-config.yaml');
|
|
290
|
+
|
|
291
|
+
if (!options.dryRun) {
|
|
292
|
+
fs.mkdirSync(configDir, { recursive: true });
|
|
293
|
+
fs.writeFileSync(configPath, rendered, 'utf8');
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
return {
|
|
297
|
+
success: true,
|
|
298
|
+
path: configPath,
|
|
299
|
+
content: rendered,
|
|
300
|
+
};
|
|
301
|
+
} catch (error) {
|
|
302
|
+
return {
|
|
303
|
+
success: false,
|
|
304
|
+
error: error.message,
|
|
305
|
+
content: null,
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* Generates deployment config context from user inputs
|
|
312
|
+
*
|
|
313
|
+
* @param {Object} inputs - User inputs from wizard
|
|
314
|
+
* @returns {Object} Deployment configuration
|
|
315
|
+
*/
|
|
316
|
+
function buildDeploymentConfig(inputs = {}) {
|
|
317
|
+
return {
|
|
318
|
+
workflow: inputs.workflow || DeploymentWorkflow.STAGING_FIRST,
|
|
319
|
+
stagingBranch: inputs.stagingBranch || 'staging',
|
|
320
|
+
productionBranch: inputs.productionBranch || 'main',
|
|
321
|
+
stagingEnvName: inputs.stagingEnvName || 'Staging',
|
|
322
|
+
productionEnvName: inputs.productionEnvName || 'Production',
|
|
323
|
+
platform: inputs.platform || DeploymentPlatform.NONE,
|
|
324
|
+
qualityGates: {
|
|
325
|
+
lint: inputs.lint !== false,
|
|
326
|
+
typecheck: inputs.typecheck !== false,
|
|
327
|
+
tests: inputs.tests !== false,
|
|
328
|
+
securityScan: inputs.securityScan || false,
|
|
329
|
+
minCoverage: inputs.minCoverage || 50,
|
|
330
|
+
},
|
|
331
|
+
autoAssignReviewers: inputs.autoAssignReviewers || false,
|
|
332
|
+
draftByDefault: inputs.draftByDefault || false,
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
/**
|
|
337
|
+
* Gets default deployment config for a mode
|
|
338
|
+
*
|
|
339
|
+
* @param {string} mode - Installation mode
|
|
340
|
+
* @returns {Object} Default deployment config
|
|
341
|
+
*/
|
|
342
|
+
function getDefaultDeploymentConfig(mode) {
|
|
343
|
+
if (mode === 'brownfield') {
|
|
344
|
+
// Brownfield might use direct-to-main if solo project
|
|
345
|
+
return {
|
|
346
|
+
...DEFAULT_DEPLOYMENT_CONFIG,
|
|
347
|
+
// Keep staging-first as default, but brownfield analyzer may change this
|
|
348
|
+
};
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
return { ...DEFAULT_DEPLOYMENT_CONFIG };
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
module.exports = {
|
|
355
|
+
buildConfigContext,
|
|
356
|
+
renderConfigTemplate,
|
|
357
|
+
loadConfigTemplate,
|
|
358
|
+
generateConfig,
|
|
359
|
+
buildDeploymentConfig,
|
|
360
|
+
getDefaultDeploymentConfig,
|
|
361
|
+
formatArrayAsYaml,
|
|
362
|
+
escapeYamlString,
|
|
363
|
+
ConfigTemplates,
|
|
364
|
+
DeploymentWorkflow,
|
|
365
|
+
DeploymentPlatform,
|
|
366
|
+
DEFAULT_DEPLOYMENT_CONFIG,
|
|
367
|
+
TEMPLATES_DIR,
|
|
368
|
+
};
|