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,243 +0,0 @@
|
|
|
1
|
-
# validate-structure
|
|
2
|
-
|
|
3
|
-
**Task ID:** validate-structure
|
|
4
|
-
**Version:** 1.0.0
|
|
5
|
-
**Agent:** @architect (Aria)
|
|
6
|
-
**Story:** 6.8 - Source-Tree Guardian
|
|
7
|
-
|
|
8
|
-
---
|
|
9
|
-
|
|
10
|
-
## Purpose
|
|
11
|
-
|
|
12
|
-
Validate file placement decisions against AIOS source-tree standards before implementation begins.
|
|
13
|
-
|
|
14
|
-
**This task is MANDATORY for all stories that create new files.**
|
|
15
|
-
|
|
16
|
-
---
|
|
17
|
-
|
|
18
|
-
## When to Use
|
|
19
|
-
|
|
20
|
-
- Before starting implementation of any story
|
|
21
|
-
- When planning new modules or features
|
|
22
|
-
- During architecture review
|
|
23
|
-
- Before PR submission
|
|
24
|
-
|
|
25
|
-
---
|
|
26
|
-
|
|
27
|
-
## Prerequisites
|
|
28
|
-
|
|
29
|
-
- Story file exists with implementation plan
|
|
30
|
-
- Source-tree-guardian module installed
|
|
31
|
-
- Access to `docs/architecture/source-tree.md`
|
|
32
|
-
|
|
33
|
-
---
|
|
34
|
-
|
|
35
|
-
## Execution
|
|
36
|
-
|
|
37
|
-
### Step 1: List New Files
|
|
38
|
-
|
|
39
|
-
List all files that will be created in this story:
|
|
40
|
-
|
|
41
|
-
| File | Purpose | Category |
|
|
42
|
-
|------|---------|----------|
|
|
43
|
-
| {path} | {purpose} | {agent/task/script/test/etc} |
|
|
44
|
-
|
|
45
|
-
### Step 2: Validate Each File
|
|
46
|
-
|
|
47
|
-
For each file, run placement validation:
|
|
48
|
-
|
|
49
|
-
```bash
|
|
50
|
-
npm run validate:structure -- --check "{file_path}"
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
Or validate all planned files at once:
|
|
54
|
-
|
|
55
|
-
```bash
|
|
56
|
-
npm run validate:structure -- --files "{glob_pattern}"
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
### Step 3: Document Decisions
|
|
60
|
-
|
|
61
|
-
Add the following section to the story file:
|
|
62
|
-
|
|
63
|
-
```markdown
|
|
64
|
-
## Structure Validation
|
|
65
|
-
|
|
66
|
-
| File | Validated Location | Approved |
|
|
67
|
-
|------|-------------------|----------|
|
|
68
|
-
| {file} | {location} | ✅/❌ |
|
|
69
|
-
|
|
70
|
-
**Validated by:** @architect (Aria)
|
|
71
|
-
**Date:** {YYYY-MM-DD}
|
|
72
|
-
**Violations:** {count}
|
|
73
|
-
**Notes:** {any special decisions}
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
### Step 4: Handle Violations
|
|
77
|
-
|
|
78
|
-
If violations exist:
|
|
79
|
-
|
|
80
|
-
1. **Review the violation message** - Understand why the location is flagged
|
|
81
|
-
2. **Propose correct location** - Use suggested location or justify alternative
|
|
82
|
-
3. **Get PO approval** - If deviation from standard is needed
|
|
83
|
-
4. **Document reasoning** - Create ADR if significant deviation
|
|
84
|
-
5. **Update story** - Mark as resolved or approved exception
|
|
85
|
-
|
|
86
|
-
---
|
|
87
|
-
|
|
88
|
-
## Task Definition (YAML)
|
|
89
|
-
|
|
90
|
-
```yaml
|
|
91
|
-
task: validateStructure()
|
|
92
|
-
responsável: Aria (Architect)
|
|
93
|
-
responsavel_type: Agente
|
|
94
|
-
atomic_layer: Molecule
|
|
95
|
-
elicit: true
|
|
96
|
-
|
|
97
|
-
Entrada:
|
|
98
|
-
- campo: story_files
|
|
99
|
-
tipo: array
|
|
100
|
-
origem: Story implementation plan
|
|
101
|
-
obrigatório: true
|
|
102
|
-
descrição: List of files to be created/modified
|
|
103
|
-
|
|
104
|
-
- campo: story_path
|
|
105
|
-
tipo: string
|
|
106
|
-
origem: User input or context
|
|
107
|
-
obrigatório: true
|
|
108
|
-
descrição: Path to the story file
|
|
109
|
-
|
|
110
|
-
Saída:
|
|
111
|
-
- campo: placement_report
|
|
112
|
-
tipo: object
|
|
113
|
-
destino: Story file (## Structure Validation section)
|
|
114
|
-
persistido: true
|
|
115
|
-
|
|
116
|
-
- campo: violations
|
|
117
|
-
tipo: array
|
|
118
|
-
destino: Console output
|
|
119
|
-
persistido: false
|
|
120
|
-
|
|
121
|
-
Elicitation:
|
|
122
|
-
- prompt: "What files will be created in this story?"
|
|
123
|
-
type: list
|
|
124
|
-
required: true
|
|
125
|
-
help: "List each file with its full path"
|
|
126
|
-
|
|
127
|
-
- prompt: "For each file, what is its purpose?"
|
|
128
|
-
type: text
|
|
129
|
-
required: true
|
|
130
|
-
help: "Brief description of what each file does"
|
|
131
|
-
|
|
132
|
-
- prompt: "What category does each file belong to?"
|
|
133
|
-
type: select
|
|
134
|
-
options:
|
|
135
|
-
- agent
|
|
136
|
-
- task
|
|
137
|
-
- script
|
|
138
|
-
- template
|
|
139
|
-
- checklist
|
|
140
|
-
- test
|
|
141
|
-
- documentation
|
|
142
|
-
- configuration
|
|
143
|
-
- other
|
|
144
|
-
required: true
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
---
|
|
148
|
-
|
|
149
|
-
## Checklist
|
|
150
|
-
|
|
151
|
-
Use this checklist to ensure complete validation:
|
|
152
|
-
|
|
153
|
-
- [ ] All new files have been listed
|
|
154
|
-
- [ ] Each file has been validated against source-tree.md
|
|
155
|
-
- [ ] Placement decisions are documented in story
|
|
156
|
-
- [ ] Any violations have been resolved or approved
|
|
157
|
-
- [ ] @architect sign-off is complete
|
|
158
|
-
- [ ] Story "Structure Validation" section is populated
|
|
159
|
-
|
|
160
|
-
---
|
|
161
|
-
|
|
162
|
-
## CLI Commands Reference
|
|
163
|
-
|
|
164
|
-
```bash
|
|
165
|
-
# Full validation
|
|
166
|
-
npm run validate:structure
|
|
167
|
-
|
|
168
|
-
# Check single file
|
|
169
|
-
npm run validate:structure -- --check "path/to/file.js"
|
|
170
|
-
|
|
171
|
-
# Check multiple files with glob
|
|
172
|
-
npm run validate:structure -- --files "src/**/*.js"
|
|
173
|
-
|
|
174
|
-
# Generate manifest
|
|
175
|
-
npm run validate:structure -- --generate-manifest
|
|
176
|
-
|
|
177
|
-
# Show suggestions for violations
|
|
178
|
-
npm run validate:structure -- --fix
|
|
179
|
-
|
|
180
|
-
# JSON output for automation
|
|
181
|
-
npm run validate:structure -- --json
|
|
182
|
-
|
|
183
|
-
# Verbose output
|
|
184
|
-
npm run validate:structure -- --verbose
|
|
185
|
-
```
|
|
186
|
-
|
|
187
|
-
---
|
|
188
|
-
|
|
189
|
-
## Common Violations & Resolutions
|
|
190
|
-
|
|
191
|
-
### Scripts at Root Level
|
|
192
|
-
|
|
193
|
-
**Violation:** `Scripts at root level are not allowed`
|
|
194
|
-
|
|
195
|
-
**Resolution:**
|
|
196
|
-
- Move to `.aios-core/infrastructure/scripts/{category}/`
|
|
197
|
-
- Example: `scripts/foo.js` → `.aios-core/infrastructure/scripts/foo.js`
|
|
198
|
-
|
|
199
|
-
### Tools at Root Level
|
|
200
|
-
|
|
201
|
-
**Violation:** `Tool definitions at root level are not allowed`
|
|
202
|
-
|
|
203
|
-
**Resolution:**
|
|
204
|
-
- Move to `.aios-core/infrastructure/tools/cli/` for CLI tools
|
|
205
|
-
- Move to `.aios-core/infrastructure/tools/mcp/` for MCP tools
|
|
206
|
-
|
|
207
|
-
### Agents in Wrong Location
|
|
208
|
-
|
|
209
|
-
**Violation:** `Agent files at root level are not allowed`
|
|
210
|
-
|
|
211
|
-
**Resolution:**
|
|
212
|
-
- Move to `.aios-core/development/agents/`
|
|
213
|
-
- Ensure naming follows kebab-case: `{agent-name}.md`
|
|
214
|
-
|
|
215
|
-
### Tasks in Wrong Location
|
|
216
|
-
|
|
217
|
-
**Violation:** `Task files at root level are not allowed`
|
|
218
|
-
|
|
219
|
-
**Resolution:**
|
|
220
|
-
- Move to `.aios-core/development/tasks/`
|
|
221
|
-
- Ensure naming follows kebab-case: `{task-name}.md`
|
|
222
|
-
|
|
223
|
-
---
|
|
224
|
-
|
|
225
|
-
## Integration Points
|
|
226
|
-
|
|
227
|
-
- **Pre-commit Hook:** Runs automatically on `git commit`
|
|
228
|
-
- **CI/CD Pipeline:** Can be integrated with `npm run validate:structure -- --json`
|
|
229
|
-
- **Story Workflow:** Executed by @architect before @dev implementation
|
|
230
|
-
|
|
231
|
-
---
|
|
232
|
-
|
|
233
|
-
## Related Resources
|
|
234
|
-
|
|
235
|
-
- [Source Tree Structure](../../docs/architecture/source-tree.md)
|
|
236
|
-
- [Coding Standards](../../docs/architecture/coding-standards.md)
|
|
237
|
-
- [Story 6.8: Source-Tree Guardian](../../docs/stories/v2.1/sprint-6/story-6.8-source-tree-guardian.md)
|
|
238
|
-
|
|
239
|
-
---
|
|
240
|
-
|
|
241
|
-
**Created:** 2025-12-14
|
|
242
|
-
**Author:** @architect (Aria)
|
|
243
|
-
**Story:** 6.8 - Source-Tree Guardian
|
|
@@ -1,375 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* Source-Tree Guardian - Main Entry Point
|
|
4
|
-
*
|
|
5
|
-
* CLI tool and module exports for source-tree validation.
|
|
6
|
-
*
|
|
7
|
-
* @module source-tree-guardian
|
|
8
|
-
* @version 1.0.0
|
|
9
|
-
* @story 6.8
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
const path = require('path');
|
|
13
|
-
const fs = require('fs').promises;
|
|
14
|
-
|
|
15
|
-
// Import core modules
|
|
16
|
-
const {
|
|
17
|
-
SourceTreeValidator,
|
|
18
|
-
normalizePath,
|
|
19
|
-
validateNamingConvention,
|
|
20
|
-
matchesPattern,
|
|
21
|
-
loadRules,
|
|
22
|
-
shouldExclude,
|
|
23
|
-
validateFilePlacement,
|
|
24
|
-
getStagedFiles,
|
|
25
|
-
Severity,
|
|
26
|
-
} = require('./validator');
|
|
27
|
-
|
|
28
|
-
const {
|
|
29
|
-
ManifestGenerator,
|
|
30
|
-
generateTree,
|
|
31
|
-
countFilesByCategory,
|
|
32
|
-
getFileStats,
|
|
33
|
-
FILE_CATEGORIES,
|
|
34
|
-
DEFAULT_EXCLUSIONS,
|
|
35
|
-
} = require('./manifest-generator');
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* CLI argument parser
|
|
39
|
-
* @param {string[]} args - Command line arguments
|
|
40
|
-
* @returns {Object} Parsed options
|
|
41
|
-
*/
|
|
42
|
-
function parseArgs(args) {
|
|
43
|
-
const options = {
|
|
44
|
-
help: false,
|
|
45
|
-
version: false,
|
|
46
|
-
files: null,
|
|
47
|
-
stagedOnly: false,
|
|
48
|
-
generateManifest: false,
|
|
49
|
-
diff: false,
|
|
50
|
-
fix: false,
|
|
51
|
-
json: false,
|
|
52
|
-
verbose: false,
|
|
53
|
-
force: false,
|
|
54
|
-
reason: null,
|
|
55
|
-
config: null,
|
|
56
|
-
check: null,
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
for (let i = 0; i < args.length; i++) {
|
|
60
|
-
const arg = args[i];
|
|
61
|
-
|
|
62
|
-
switch (arg) {
|
|
63
|
-
case '-h':
|
|
64
|
-
case '--help':
|
|
65
|
-
options.help = true;
|
|
66
|
-
break;
|
|
67
|
-
case '-v':
|
|
68
|
-
case '--version':
|
|
69
|
-
options.version = true;
|
|
70
|
-
break;
|
|
71
|
-
case '--files':
|
|
72
|
-
options.files = args[++i];
|
|
73
|
-
break;
|
|
74
|
-
case '--staged-only':
|
|
75
|
-
options.stagedOnly = true;
|
|
76
|
-
break;
|
|
77
|
-
case '--generate-manifest':
|
|
78
|
-
options.generateManifest = true;
|
|
79
|
-
break;
|
|
80
|
-
case '--diff':
|
|
81
|
-
options.diff = true;
|
|
82
|
-
break;
|
|
83
|
-
case '--fix':
|
|
84
|
-
options.fix = true;
|
|
85
|
-
break;
|
|
86
|
-
case '--json':
|
|
87
|
-
options.json = true;
|
|
88
|
-
break;
|
|
89
|
-
case '--verbose':
|
|
90
|
-
options.verbose = true;
|
|
91
|
-
break;
|
|
92
|
-
case '--force':
|
|
93
|
-
options.force = true;
|
|
94
|
-
break;
|
|
95
|
-
case '--reason':
|
|
96
|
-
options.reason = args[++i];
|
|
97
|
-
break;
|
|
98
|
-
case '--config':
|
|
99
|
-
options.config = args[++i];
|
|
100
|
-
break;
|
|
101
|
-
case '--check':
|
|
102
|
-
options.check = args[++i];
|
|
103
|
-
break;
|
|
104
|
-
default:
|
|
105
|
-
if (!arg.startsWith('-')) {
|
|
106
|
-
options.files = arg;
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
return options;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* Prints help message
|
|
116
|
-
*/
|
|
117
|
-
function printHelp() {
|
|
118
|
-
console.log(`
|
|
119
|
-
Source-Tree Guardian - Structure Validation System
|
|
120
|
-
Version: 1.0.0 | Story: 6.8
|
|
121
|
-
|
|
122
|
-
USAGE:
|
|
123
|
-
node index.js [options]
|
|
124
|
-
npm run validate:structure [-- options]
|
|
125
|
-
|
|
126
|
-
OPTIONS:
|
|
127
|
-
-h, --help Show this help message
|
|
128
|
-
-v, --version Show version information
|
|
129
|
-
--files <glob> Validate specific files (glob pattern)
|
|
130
|
-
--staged-only Only validate git staged files
|
|
131
|
-
--generate-manifest Generate source-tree-manifest.json
|
|
132
|
-
--diff Show drift from previous manifest
|
|
133
|
-
--fix Show auto-fix suggestions
|
|
134
|
-
--json Output in JSON format
|
|
135
|
-
--verbose Enable verbose output
|
|
136
|
-
--force Bypass validation (requires --reason)
|
|
137
|
-
--reason <text> Justification for --force (logged)
|
|
138
|
-
--config <path> Custom rules file location
|
|
139
|
-
--check <path> Check a single file
|
|
140
|
-
|
|
141
|
-
EXAMPLES:
|
|
142
|
-
# Validate all files
|
|
143
|
-
npm run validate:structure
|
|
144
|
-
|
|
145
|
-
# Validate specific files
|
|
146
|
-
npm run validate:structure -- --files "src/**/*.js"
|
|
147
|
-
|
|
148
|
-
# Validate staged files only (pre-commit)
|
|
149
|
-
npm run validate:structure -- --staged-only
|
|
150
|
-
|
|
151
|
-
# Generate manifest
|
|
152
|
-
npm run validate:structure -- --generate-manifest
|
|
153
|
-
|
|
154
|
-
# Show drift from previous manifest
|
|
155
|
-
npm run validate:structure -- --diff
|
|
156
|
-
|
|
157
|
-
# JSON output for CI
|
|
158
|
-
npm run validate:structure -- --json
|
|
159
|
-
|
|
160
|
-
# Force bypass with reason
|
|
161
|
-
npm run validate:structure -- --force --reason "Hotfix deployment"
|
|
162
|
-
`);
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
/**
|
|
166
|
-
* Prints version information
|
|
167
|
-
*/
|
|
168
|
-
function printVersion() {
|
|
169
|
-
console.log('Source-Tree Guardian v1.0.0');
|
|
170
|
-
console.log('Story: 6.8 - Source-Tree Guardian - Structure Validation System');
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
/**
|
|
174
|
-
* Logs force bypass with reason
|
|
175
|
-
* @param {string} reason - Justification for bypass
|
|
176
|
-
* @param {string} projectRoot - Project root directory
|
|
177
|
-
*/
|
|
178
|
-
async function logForceBypass(reason, projectRoot) {
|
|
179
|
-
const logDir = path.join(projectRoot, '.ai');
|
|
180
|
-
const logFile = path.join(logDir, 'force-bypass-log.md');
|
|
181
|
-
|
|
182
|
-
await fs.mkdir(logDir, { recursive: true });
|
|
183
|
-
|
|
184
|
-
const entry = `\n## Force Bypass - ${new Date().toISOString()}\n\n**Reason:** ${reason}\n\n---\n`;
|
|
185
|
-
|
|
186
|
-
try {
|
|
187
|
-
await fs.appendFile(logFile, entry);
|
|
188
|
-
console.log(`⚠️ Force bypass logged to ${logFile}`);
|
|
189
|
-
} catch (error) {
|
|
190
|
-
console.warn(`Warning: Could not log force bypass: ${error.message}`);
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
/**
|
|
195
|
-
* Main CLI entry point
|
|
196
|
-
* @param {string[]} args - Command line arguments
|
|
197
|
-
* @returns {Promise<number>} Exit code
|
|
198
|
-
*/
|
|
199
|
-
async function main(args = process.argv.slice(2)) {
|
|
200
|
-
const options = parseArgs(args);
|
|
201
|
-
const projectRoot = process.cwd();
|
|
202
|
-
|
|
203
|
-
// Handle help and version
|
|
204
|
-
if (options.help) {
|
|
205
|
-
printHelp();
|
|
206
|
-
return 0;
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
if (options.version) {
|
|
210
|
-
printVersion();
|
|
211
|
-
return 0;
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
// Handle force bypass
|
|
215
|
-
if (options.force) {
|
|
216
|
-
if (!options.reason) {
|
|
217
|
-
console.error('❌ --force requires --reason to be specified');
|
|
218
|
-
return 1;
|
|
219
|
-
}
|
|
220
|
-
await logForceBypass(options.reason, projectRoot);
|
|
221
|
-
console.log('✅ Validation bypassed');
|
|
222
|
-
return 0;
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
// Handle manifest generation
|
|
226
|
-
if (options.generateManifest) {
|
|
227
|
-
const generator = new ManifestGenerator({ projectRoot });
|
|
228
|
-
console.log('📊 Generating source-tree manifest...');
|
|
229
|
-
|
|
230
|
-
const manifest = await generator.generate();
|
|
231
|
-
const outputPath = await generator.save(manifest);
|
|
232
|
-
|
|
233
|
-
if (options.json) {
|
|
234
|
-
console.log(JSON.stringify(manifest, null, 2));
|
|
235
|
-
} else {
|
|
236
|
-
console.log(`✅ Manifest generated: ${outputPath}`);
|
|
237
|
-
console.log(` Files: ${manifest.summary.totalFiles}`);
|
|
238
|
-
console.log(` Directories: ${manifest.summary.totalDirectories}`);
|
|
239
|
-
console.log(` Duration: ${manifest.duration}ms`);
|
|
240
|
-
}
|
|
241
|
-
return 0;
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
// Handle diff
|
|
245
|
-
if (options.diff) {
|
|
246
|
-
const generator = new ManifestGenerator({ projectRoot });
|
|
247
|
-
console.log('📊 Comparing with previous manifest...');
|
|
248
|
-
|
|
249
|
-
try {
|
|
250
|
-
const oldManifest = await generator.load();
|
|
251
|
-
const newManifest = await generator.generate();
|
|
252
|
-
const diff = generator.compare(oldManifest, newManifest);
|
|
253
|
-
|
|
254
|
-
if (options.json) {
|
|
255
|
-
console.log(JSON.stringify(diff, null, 2));
|
|
256
|
-
} else {
|
|
257
|
-
console.log(generator.formatDiffReport(diff));
|
|
258
|
-
}
|
|
259
|
-
} catch (error) {
|
|
260
|
-
if (error.code === 'ENOENT') {
|
|
261
|
-
console.log('⚠️ No previous manifest found. Generate one first with --generate-manifest');
|
|
262
|
-
return 1;
|
|
263
|
-
}
|
|
264
|
-
throw error;
|
|
265
|
-
}
|
|
266
|
-
return 0;
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
// Handle single file check
|
|
270
|
-
if (options.check) {
|
|
271
|
-
const validator = new SourceTreeValidator({
|
|
272
|
-
projectRoot,
|
|
273
|
-
rulesPath: options.config,
|
|
274
|
-
verbose: options.verbose,
|
|
275
|
-
});
|
|
276
|
-
|
|
277
|
-
const result = await validator.validateFile(options.check);
|
|
278
|
-
|
|
279
|
-
if (options.json) {
|
|
280
|
-
console.log(JSON.stringify(result, null, 2));
|
|
281
|
-
} else {
|
|
282
|
-
if (result.isValid) {
|
|
283
|
-
console.log(`✅ ${options.check}: Valid placement`);
|
|
284
|
-
} else {
|
|
285
|
-
console.log(`❌ ${options.check}: Invalid placement`);
|
|
286
|
-
for (const v of result.violations) {
|
|
287
|
-
console.log(` ${v.message}`);
|
|
288
|
-
if (v.suggestedLocation) {
|
|
289
|
-
console.log(` Suggested: ${v.suggestedLocation}`);
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
return result.isValid ? 0 : 1;
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
// Main validation
|
|
299
|
-
const validator = new SourceTreeValidator({
|
|
300
|
-
projectRoot,
|
|
301
|
-
rulesPath: options.config,
|
|
302
|
-
verbose: options.verbose,
|
|
303
|
-
});
|
|
304
|
-
|
|
305
|
-
console.log('🔍 Validating source-tree structure...');
|
|
306
|
-
|
|
307
|
-
const report = await validator.validate({
|
|
308
|
-
files: options.files,
|
|
309
|
-
stagedOnly: options.stagedOnly,
|
|
310
|
-
});
|
|
311
|
-
|
|
312
|
-
// Output report
|
|
313
|
-
if (options.json) {
|
|
314
|
-
console.log(validator.formatJsonReport(report));
|
|
315
|
-
} else {
|
|
316
|
-
console.log(validator.formatReport(report, { showFixHint: !options.fix }));
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
// Show fix suggestions if requested
|
|
320
|
-
if (options.fix && report.violations.length > 0) {
|
|
321
|
-
console.log('\n📋 FIX SUGGESTIONS:\n');
|
|
322
|
-
const suggestions = validator.generateFixSuggestions(report.violations);
|
|
323
|
-
for (const suggestion of suggestions) {
|
|
324
|
-
console.log(`File: ${suggestion.file}`);
|
|
325
|
-
console.log(` Current: ${suggestion.currentLocation}`);
|
|
326
|
-
console.log(` Suggested: ${suggestion.suggestedLocation}`);
|
|
327
|
-
if (suggestion.command) {
|
|
328
|
-
console.log(` Command: ${suggestion.command}`);
|
|
329
|
-
}
|
|
330
|
-
console.log('');
|
|
331
|
-
}
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
// Return exit code based on errors
|
|
335
|
-
return report.summary.errors > 0 ? 1 : 0;
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
// Export modules
|
|
339
|
-
module.exports = {
|
|
340
|
-
// Validator exports
|
|
341
|
-
SourceTreeValidator,
|
|
342
|
-
normalizePath,
|
|
343
|
-
validateNamingConvention,
|
|
344
|
-
matchesPattern,
|
|
345
|
-
loadRules,
|
|
346
|
-
shouldExclude,
|
|
347
|
-
validateFilePlacement,
|
|
348
|
-
getStagedFiles,
|
|
349
|
-
Severity,
|
|
350
|
-
// Manifest exports
|
|
351
|
-
ManifestGenerator,
|
|
352
|
-
generateTree,
|
|
353
|
-
countFilesByCategory,
|
|
354
|
-
getFileStats,
|
|
355
|
-
FILE_CATEGORIES,
|
|
356
|
-
DEFAULT_EXCLUSIONS,
|
|
357
|
-
// CLI exports
|
|
358
|
-
main,
|
|
359
|
-
parseArgs,
|
|
360
|
-
};
|
|
361
|
-
|
|
362
|
-
// Run CLI if executed directly
|
|
363
|
-
if (require.main === module) {
|
|
364
|
-
main()
|
|
365
|
-
.then((exitCode) => {
|
|
366
|
-
process.exit(exitCode);
|
|
367
|
-
})
|
|
368
|
-
.catch((error) => {
|
|
369
|
-
console.error('❌ Error:', error.message);
|
|
370
|
-
if (process.env.DEBUG) {
|
|
371
|
-
console.error(error.stack);
|
|
372
|
-
}
|
|
373
|
-
process.exit(1);
|
|
374
|
-
});
|
|
375
|
-
}
|