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.
Files changed (27) hide show
  1. package/.aios-core/development/tasks/analyze-brownfield.md +456 -456
  2. package/.aios-core/development/tasks/setup-project-docs.md +440 -444
  3. package/.aios-core/infrastructure/scripts/documentation-integrity/brownfield-analyzer.js +501 -501
  4. package/.aios-core/infrastructure/scripts/documentation-integrity/config-generator.js +368 -329
  5. package/.aios-core/infrastructure/scripts/documentation-integrity/deployment-config-loader.js +308 -282
  6. package/.aios-core/infrastructure/scripts/documentation-integrity/doc-generator.js +331 -331
  7. package/.aios-core/infrastructure/scripts/documentation-integrity/gitignore-generator.js +312 -312
  8. package/.aios-core/infrastructure/scripts/documentation-integrity/index.js +74 -74
  9. package/.aios-core/infrastructure/scripts/documentation-integrity/mode-detector.js +389 -358
  10. package/.aios-core/infrastructure/scripts/llm-routing/install-llm-routing.js +6 -6
  11. package/.aios-core/infrastructure/templates/core-config/core-config-brownfield.tmpl.yaml +176 -182
  12. package/.aios-core/infrastructure/templates/core-config/core-config-greenfield.tmpl.yaml +127 -127
  13. package/.aios-core/infrastructure/templates/project-docs/coding-standards-tmpl.md +346 -346
  14. package/.aios-core/infrastructure/templates/project-docs/source-tree-tmpl.md +177 -177
  15. package/.aios-core/infrastructure/templates/project-docs/tech-stack-tmpl.md +267 -267
  16. package/package.json +1 -1
  17. package/packages/installer/src/config/templates/env-template.js +2 -2
  18. package/packages/installer/src/wizard/wizard.js +1 -1
  19. package/packages/installer/tests/integration/environment-configuration.test.js +2 -1
  20. package/packages/installer/tests/unit/env-template.test.js +3 -2
  21. package/src/wizard/index.js +2 -2
  22. package/.aios-core/development/tasks/validate-structure.md +0 -243
  23. package/.aios-core/infrastructure/scripts/source-tree-guardian/index.js +0 -375
  24. package/.aios-core/infrastructure/scripts/source-tree-guardian/manifest-generator.js +0 -410
  25. package/.aios-core/infrastructure/scripts/source-tree-guardian/rules/naming-rules.yaml +0 -285
  26. package/.aios-core/infrastructure/scripts/source-tree-guardian/rules/placement-rules.yaml +0 -262
  27. package/.aios-core/infrastructure/scripts/source-tree-guardian/validator.js +0 -468
@@ -1,312 +1,312 @@
1
- /**
2
- * Gitignore Generator Module
3
- *
4
- * Generates .gitignore files based on detected tech stack.
5
- * Supports brownfield merge mode to preserve existing ignores.
6
- *
7
- * @module documentation-integrity/gitignore-generator
8
- * @version 1.0.0
9
- * @story 6.9
10
- */
11
-
12
- const fs = require('fs');
13
- const path = require('path');
14
-
15
- // Template directory
16
- const TEMPLATES_DIR = path.join(__dirname, '..', '..', 'templates', 'gitignore');
17
-
18
- /**
19
- * Template file names
20
- * @enum {string}
21
- */
22
- const GitignoreTemplates = {
23
- AIOS_BASE: 'gitignore-aios-base.tmpl',
24
- NODE: 'gitignore-node.tmpl',
25
- PYTHON: 'gitignore-python.tmpl',
26
- BROWNFIELD_MERGE: 'gitignore-brownfield-merge.tmpl',
27
- };
28
-
29
- /**
30
- * Tech stack identifiers
31
- * @enum {string}
32
- */
33
- const TechStack = {
34
- NODE: 'node',
35
- PYTHON: 'python',
36
- GO: 'go',
37
- RUST: 'rust',
38
- };
39
-
40
- /**
41
- * Loads a gitignore template
42
- *
43
- * @param {string} templateName - Template file name
44
- * @returns {string} Template content
45
- * @throws {Error} If template not found
46
- */
47
- function loadGitignoreTemplate(templateName) {
48
- const templatePath = path.join(TEMPLATES_DIR, templateName);
49
-
50
- if (!fs.existsSync(templatePath)) {
51
- throw new Error(`Gitignore template not found: ${templatePath}`);
52
- }
53
-
54
- return fs.readFileSync(templatePath, 'utf8');
55
- }
56
-
57
- /**
58
- * Detects tech stack from project markers
59
- *
60
- * @param {Object} markers - Detected project markers
61
- * @returns {string[]} List of detected tech stacks
62
- */
63
- function detectTechStacks(markers) {
64
- const stacks = [];
65
-
66
- if (markers.hasPackageJson) stacks.push(TechStack.NODE);
67
- if (markers.hasPythonProject) stacks.push(TechStack.PYTHON);
68
- if (markers.hasGoMod) stacks.push(TechStack.GO);
69
- if (markers.hasCargoToml) stacks.push(TechStack.RUST);
70
-
71
- return stacks;
72
- }
73
-
74
- /**
75
- * Gets gitignore templates for detected tech stacks
76
- *
77
- * @param {string[]} techStacks - Detected tech stacks
78
- * @returns {string[]} List of template names to use
79
- */
80
- function getTemplatesForStacks(techStacks) {
81
- const templates = [GitignoreTemplates.AIOS_BASE];
82
-
83
- for (const stack of techStacks) {
84
- switch (stack) {
85
- case TechStack.NODE:
86
- templates.push(GitignoreTemplates.NODE);
87
- break;
88
- case TechStack.PYTHON:
89
- templates.push(GitignoreTemplates.PYTHON);
90
- break;
91
- // Go and Rust would have their own templates
92
- // Add when implemented
93
- }
94
- }
95
-
96
- return templates;
97
- }
98
-
99
- /**
100
- * Generates a complete .gitignore file
101
- *
102
- * @param {Object} markers - Detected project markers
103
- * @param {Object} [options] - Generation options
104
- * @param {string} [options.projectName] - Project name for header
105
- * @returns {string} Generated gitignore content
106
- */
107
- function generateGitignore(markers, options = {}) {
108
- const techStacks = detectTechStacks(markers);
109
- const templates = getTemplatesForStacks(techStacks);
110
-
111
- const sections = [];
112
-
113
- // Add project header
114
- const projectName = options.projectName || 'Project';
115
- sections.push(`# ${projectName} .gitignore`);
116
- sections.push('# Generated by AIOS Documentation Integrity System');
117
- sections.push(`# Date: ${new Date().toISOString().split('T')[0]}`);
118
- sections.push(`# Tech Stack: ${techStacks.join(', ') || 'Generic'}`);
119
- sections.push('');
120
-
121
- // Load and append each template
122
- for (const templateName of templates) {
123
- try {
124
- const content = loadGitignoreTemplate(templateName);
125
- sections.push(content);
126
- sections.push(''); // Add blank line between sections
127
- } catch (error) {
128
- console.warn(`Warning: Could not load template ${templateName}: ${error.message}`);
129
- }
130
- }
131
-
132
- return sections.join('\n').trim() + '\n';
133
- }
134
-
135
- /**
136
- * Merges AIOS ignores with existing .gitignore
137
- *
138
- * @param {string} existingContent - Existing .gitignore content
139
- * @param {Object} [options] - Merge options
140
- * @returns {string} Merged gitignore content
141
- */
142
- function mergeGitignore(existingContent, _options = {}) {
143
- // Check if AIOS section already exists
144
- if (existingContent.includes('AIOS Integration Section')) {
145
- console.log('AIOS section already exists in .gitignore, skipping merge');
146
- return existingContent;
147
- }
148
-
149
- // Load merge template
150
- let mergeSection;
151
- try {
152
- mergeSection = loadGitignoreTemplate(GitignoreTemplates.BROWNFIELD_MERGE);
153
- } catch {
154
- // Fallback to minimal section
155
- mergeSection = `
156
- # ========================================
157
- # AIOS Integration Section
158
- # ========================================
159
-
160
- # AIOS Local Configuration
161
- .aios-core/local/
162
- .aios-core/*.local.yaml
163
- .aios-core/logs/
164
- .aios-core/cache/
165
-
166
- # ========================================
167
- # End of AIOS Integration Section
168
- # ========================================
169
- `;
170
- }
171
-
172
- // Replace date placeholder
173
- mergeSection = mergeSection.replace(
174
- '{{GENERATED_DATE}}',
175
- new Date().toISOString().split('T')[0],
176
- );
177
-
178
- // Append to existing content
179
- const merged = existingContent.trimEnd() + '\n\n' + mergeSection.trim() + '\n';
180
-
181
- return merged;
182
- }
183
-
184
- /**
185
- * Generates or merges .gitignore for a project
186
- *
187
- * @param {string} targetDir - Target directory
188
- * @param {Object} markers - Detected project markers
189
- * @param {Object} [options] - Generation options
190
- * @param {boolean} [options.dryRun] - Don't write file, just return content
191
- * @param {boolean} [options.merge] - Merge with existing instead of replace
192
- * @param {string} [options.projectName] - Project name for header
193
- * @returns {Object} Generation result
194
- */
195
- function generateGitignoreFile(targetDir, markers, options = {}) {
196
- const gitignorePath = path.join(targetDir, '.gitignore');
197
- const existingPath = fs.existsSync(gitignorePath);
198
-
199
- let content;
200
- let mode;
201
-
202
- if (existingPath && options.merge !== false) {
203
- // Brownfield mode - merge with existing
204
- const existing = fs.readFileSync(gitignorePath, 'utf8');
205
- content = mergeGitignore(existing, options);
206
- mode = 'merged';
207
- } else {
208
- // Greenfield mode - generate new
209
- content = generateGitignore(markers, options);
210
- mode = existingPath ? 'replaced' : 'created';
211
- }
212
-
213
- const result = {
214
- success: true,
215
- path: gitignorePath,
216
- content,
217
- mode,
218
- techStacks: detectTechStacks(markers),
219
- };
220
-
221
- if (!options.dryRun) {
222
- try {
223
- fs.writeFileSync(gitignorePath, content, 'utf8');
224
- } catch (error) {
225
- result.success = false;
226
- result.error = error.message;
227
- }
228
- }
229
-
230
- return result;
231
- }
232
-
233
- /**
234
- * Checks if a .gitignore file has AIOS integration
235
- *
236
- * @param {string} targetDir - Target directory
237
- * @returns {boolean} True if AIOS section exists
238
- */
239
- function hasAiosIntegration(targetDir) {
240
- const gitignorePath = path.join(targetDir, '.gitignore');
241
-
242
- if (!fs.existsSync(gitignorePath)) {
243
- return false;
244
- }
245
-
246
- const content = fs.readFileSync(gitignorePath, 'utf8');
247
- return content.includes('AIOS Integration Section') || content.includes('.aios-core/');
248
- }
249
-
250
- /**
251
- * Parses an existing .gitignore into sections
252
- *
253
- * @param {string} content - .gitignore content
254
- * @returns {Object} Parsed sections
255
- */
256
- function parseGitignore(content) {
257
- const lines = content.split('\n');
258
- const sections = {
259
- header: [],
260
- patterns: [],
261
- aiosSection: null,
262
- comments: [],
263
- };
264
-
265
- let aiosStart = -1;
266
- let aiosEnd = -1;
267
-
268
- for (let i = 0; i < lines.length; i++) {
269
- const line = lines[i];
270
-
271
- if (line.includes('AIOS Integration Section')) {
272
- if (aiosStart === -1) {
273
- aiosStart = i;
274
- }
275
- }
276
-
277
- if (line.includes('End of AIOS Integration Section')) {
278
- aiosEnd = i;
279
- }
280
-
281
- if (line.startsWith('#') && !line.includes('AIOS')) {
282
- sections.comments.push({ line: i, content: line });
283
- }
284
-
285
- if (!line.startsWith('#') && line.trim()) {
286
- sections.patterns.push({ line: i, pattern: line.trim() });
287
- }
288
- }
289
-
290
- if (aiosStart !== -1) {
291
- sections.aiosSection = {
292
- start: aiosStart,
293
- end: aiosEnd !== -1 ? aiosEnd : lines.length - 1,
294
- };
295
- }
296
-
297
- return sections;
298
- }
299
-
300
- module.exports = {
301
- loadGitignoreTemplate,
302
- detectTechStacks,
303
- getTemplatesForStacks,
304
- generateGitignore,
305
- mergeGitignore,
306
- generateGitignoreFile,
307
- hasAiosIntegration,
308
- parseGitignore,
309
- GitignoreTemplates,
310
- TechStack,
311
- TEMPLATES_DIR,
312
- };
1
+ /**
2
+ * Gitignore Generator Module
3
+ *
4
+ * Generates .gitignore files based on detected tech stack.
5
+ * Supports brownfield merge mode to preserve existing ignores.
6
+ *
7
+ * @module documentation-integrity/gitignore-generator
8
+ * @version 1.0.0
9
+ * @story 6.9
10
+ */
11
+
12
+ const fs = require('fs');
13
+ const path = require('path');
14
+
15
+ // Template directory
16
+ const TEMPLATES_DIR = path.join(__dirname, '..', '..', 'templates', 'gitignore');
17
+
18
+ /**
19
+ * Template file names
20
+ * @enum {string}
21
+ */
22
+ const GitignoreTemplates = {
23
+ AIOS_BASE: 'gitignore-aios-base.tmpl',
24
+ NODE: 'gitignore-node.tmpl',
25
+ PYTHON: 'gitignore-python.tmpl',
26
+ BROWNFIELD_MERGE: 'gitignore-brownfield-merge.tmpl',
27
+ };
28
+
29
+ /**
30
+ * Tech stack identifiers
31
+ * @enum {string}
32
+ */
33
+ const TechStack = {
34
+ NODE: 'node',
35
+ PYTHON: 'python',
36
+ GO: 'go',
37
+ RUST: 'rust',
38
+ };
39
+
40
+ /**
41
+ * Loads a gitignore template
42
+ *
43
+ * @param {string} templateName - Template file name
44
+ * @returns {string} Template content
45
+ * @throws {Error} If template not found
46
+ */
47
+ function loadGitignoreTemplate(templateName) {
48
+ const templatePath = path.join(TEMPLATES_DIR, templateName);
49
+
50
+ if (!fs.existsSync(templatePath)) {
51
+ throw new Error(`Gitignore template not found: ${templatePath}`);
52
+ }
53
+
54
+ return fs.readFileSync(templatePath, 'utf8');
55
+ }
56
+
57
+ /**
58
+ * Detects tech stack from project markers
59
+ *
60
+ * @param {Object} markers - Detected project markers
61
+ * @returns {string[]} List of detected tech stacks
62
+ */
63
+ function detectTechStacks(markers) {
64
+ const stacks = [];
65
+
66
+ if (markers.hasPackageJson) stacks.push(TechStack.NODE);
67
+ if (markers.hasPythonProject) stacks.push(TechStack.PYTHON);
68
+ if (markers.hasGoMod) stacks.push(TechStack.GO);
69
+ if (markers.hasCargoToml) stacks.push(TechStack.RUST);
70
+
71
+ return stacks;
72
+ }
73
+
74
+ /**
75
+ * Gets gitignore templates for detected tech stacks
76
+ *
77
+ * @param {string[]} techStacks - Detected tech stacks
78
+ * @returns {string[]} List of template names to use
79
+ */
80
+ function getTemplatesForStacks(techStacks) {
81
+ const templates = [GitignoreTemplates.AIOS_BASE];
82
+
83
+ for (const stack of techStacks) {
84
+ switch (stack) {
85
+ case TechStack.NODE:
86
+ templates.push(GitignoreTemplates.NODE);
87
+ break;
88
+ case TechStack.PYTHON:
89
+ templates.push(GitignoreTemplates.PYTHON);
90
+ break;
91
+ // Go and Rust would have their own templates
92
+ // Add when implemented
93
+ }
94
+ }
95
+
96
+ return templates;
97
+ }
98
+
99
+ /**
100
+ * Generates a complete .gitignore file
101
+ *
102
+ * @param {Object} markers - Detected project markers
103
+ * @param {Object} [options] - Generation options
104
+ * @param {string} [options.projectName] - Project name for header
105
+ * @returns {string} Generated gitignore content
106
+ */
107
+ function generateGitignore(markers, options = {}) {
108
+ const techStacks = detectTechStacks(markers);
109
+ const templates = getTemplatesForStacks(techStacks);
110
+
111
+ const sections = [];
112
+
113
+ // Add project header
114
+ const projectName = options.projectName || 'Project';
115
+ sections.push(`# ${projectName} .gitignore`);
116
+ sections.push('# Generated by AIOS Documentation Integrity System');
117
+ sections.push(`# Date: ${new Date().toISOString().split('T')[0]}`);
118
+ sections.push(`# Tech Stack: ${techStacks.join(', ') || 'Generic'}`);
119
+ sections.push('');
120
+
121
+ // Load and append each template
122
+ for (const templateName of templates) {
123
+ try {
124
+ const content = loadGitignoreTemplate(templateName);
125
+ sections.push(content);
126
+ sections.push(''); // Add blank line between sections
127
+ } catch (error) {
128
+ console.warn(`Warning: Could not load template ${templateName}: ${error.message}`);
129
+ }
130
+ }
131
+
132
+ return sections.join('\n').trim() + '\n';
133
+ }
134
+
135
+ /**
136
+ * Merges AIOS ignores with existing .gitignore
137
+ *
138
+ * @param {string} existingContent - Existing .gitignore content
139
+ * @param {Object} [options] - Merge options
140
+ * @returns {string} Merged gitignore content
141
+ */
142
+ function mergeGitignore(existingContent, _options = {}) {
143
+ // Check if AIOS section already exists
144
+ if (existingContent.includes('AIOS Integration Section')) {
145
+ console.log('AIOS section already exists in .gitignore, skipping merge');
146
+ return existingContent;
147
+ }
148
+
149
+ // Load merge template
150
+ let mergeSection;
151
+ try {
152
+ mergeSection = loadGitignoreTemplate(GitignoreTemplates.BROWNFIELD_MERGE);
153
+ } catch {
154
+ // Fallback to minimal section
155
+ mergeSection = `
156
+ # ========================================
157
+ # AIOS Integration Section
158
+ # ========================================
159
+
160
+ # AIOS Local Configuration
161
+ .aios-core/local/
162
+ .aios-core/*.local.yaml
163
+ .aios-core/logs/
164
+ .aios-core/cache/
165
+
166
+ # ========================================
167
+ # End of AIOS Integration Section
168
+ # ========================================
169
+ `;
170
+ }
171
+
172
+ // Replace date placeholder
173
+ mergeSection = mergeSection.replace(
174
+ '{{GENERATED_DATE}}',
175
+ new Date().toISOString().split('T')[0],
176
+ );
177
+
178
+ // Append to existing content
179
+ const merged = existingContent.trimEnd() + '\n\n' + mergeSection.trim() + '\n';
180
+
181
+ return merged;
182
+ }
183
+
184
+ /**
185
+ * Generates or merges .gitignore for a project
186
+ *
187
+ * @param {string} targetDir - Target directory
188
+ * @param {Object} markers - Detected project markers
189
+ * @param {Object} [options] - Generation options
190
+ * @param {boolean} [options.dryRun] - Don't write file, just return content
191
+ * @param {boolean} [options.merge] - Merge with existing instead of replace
192
+ * @param {string} [options.projectName] - Project name for header
193
+ * @returns {Object} Generation result
194
+ */
195
+ function generateGitignoreFile(targetDir, markers, options = {}) {
196
+ const gitignorePath = path.join(targetDir, '.gitignore');
197
+ const existingPath = fs.existsSync(gitignorePath);
198
+
199
+ let content;
200
+ let mode;
201
+
202
+ if (existingPath && options.merge !== false) {
203
+ // Brownfield mode - merge with existing
204
+ const existing = fs.readFileSync(gitignorePath, 'utf8');
205
+ content = mergeGitignore(existing, options);
206
+ mode = 'merged';
207
+ } else {
208
+ // Greenfield mode - generate new
209
+ content = generateGitignore(markers, options);
210
+ mode = existingPath ? 'replaced' : 'created';
211
+ }
212
+
213
+ const result = {
214
+ success: true,
215
+ path: gitignorePath,
216
+ content,
217
+ mode,
218
+ techStacks: detectTechStacks(markers),
219
+ };
220
+
221
+ if (!options.dryRun) {
222
+ try {
223
+ fs.writeFileSync(gitignorePath, content, 'utf8');
224
+ } catch (error) {
225
+ result.success = false;
226
+ result.error = error.message;
227
+ }
228
+ }
229
+
230
+ return result;
231
+ }
232
+
233
+ /**
234
+ * Checks if a .gitignore file has AIOS integration
235
+ *
236
+ * @param {string} targetDir - Target directory
237
+ * @returns {boolean} True if AIOS section exists
238
+ */
239
+ function hasAiosIntegration(targetDir) {
240
+ const gitignorePath = path.join(targetDir, '.gitignore');
241
+
242
+ if (!fs.existsSync(gitignorePath)) {
243
+ return false;
244
+ }
245
+
246
+ const content = fs.readFileSync(gitignorePath, 'utf8');
247
+ return content.includes('AIOS Integration Section') || content.includes('.aios-core/');
248
+ }
249
+
250
+ /**
251
+ * Parses an existing .gitignore into sections
252
+ *
253
+ * @param {string} content - .gitignore content
254
+ * @returns {Object} Parsed sections
255
+ */
256
+ function parseGitignore(content) {
257
+ const lines = content.split('\n');
258
+ const sections = {
259
+ header: [],
260
+ patterns: [],
261
+ aiosSection: null,
262
+ comments: [],
263
+ };
264
+
265
+ let aiosStart = -1;
266
+ let aiosEnd = -1;
267
+
268
+ for (let i = 0; i < lines.length; i++) {
269
+ const line = lines[i];
270
+
271
+ if (line.includes('AIOS Integration Section')) {
272
+ if (aiosStart === -1) {
273
+ aiosStart = i;
274
+ }
275
+ }
276
+
277
+ if (line.includes('End of AIOS Integration Section')) {
278
+ aiosEnd = i;
279
+ }
280
+
281
+ if (line.startsWith('#') && !line.includes('AIOS')) {
282
+ sections.comments.push({ line: i, content: line });
283
+ }
284
+
285
+ if (!line.startsWith('#') && line.trim()) {
286
+ sections.patterns.push({ line: i, pattern: line.trim() });
287
+ }
288
+ }
289
+
290
+ if (aiosStart !== -1) {
291
+ sections.aiosSection = {
292
+ start: aiosStart,
293
+ end: aiosEnd !== -1 ? aiosEnd : lines.length - 1,
294
+ };
295
+ }
296
+
297
+ return sections;
298
+ }
299
+
300
+ module.exports = {
301
+ loadGitignoreTemplate,
302
+ detectTechStacks,
303
+ getTemplatesForStacks,
304
+ generateGitignore,
305
+ mergeGitignore,
306
+ generateGitignoreFile,
307
+ hasAiosIntegration,
308
+ parseGitignore,
309
+ GitignoreTemplates,
310
+ TechStack,
311
+ TEMPLATES_DIR,
312
+ };