aios-core 4.4.2 → 4.4.4
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/core/doctor/checks/npm-packages.js +53 -10
- package/.aios-core/data/entity-registry.yaml +863 -785
- package/.aios-core/development/scripts/code-quality-improver.js +29 -12
- package/.aios-core/development/scripts/refactoring-suggester.js +15 -6
- package/.aios-core/install-manifest.yaml +12 -12
- package/.aios-core/package.json +9 -5
- package/README.md +3 -1
- package/bin/utils/validate-publish.js +26 -3
- package/package.json +1 -1
- package/packages/installer/src/installer/aios-core-installer.js +4 -1
- package/packages/installer/src/wizard/i18n.js +3 -0
- package/packages/installer/src/wizard/index.js +36 -21
- package/packages/installer/src/wizard/pro-setup.js +79 -10
- package/packages/installer/tests/unit/doctor/doctor-checks.test.js +1 -1
- package/scripts/validate-aios-core-deps.js +161 -0
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Dependency Graph Validator — .aios-core/package.json completeness
|
|
6
|
+
* Story INS-4.12 (AC1, AC4, AC6)
|
|
7
|
+
*
|
|
8
|
+
* Scans all .js files in .aios-core/development/scripts/ for require() calls,
|
|
9
|
+
* then verifies each non-builtin, non-relative package is declared in
|
|
10
|
+
* .aios-core/package.json dependencies.
|
|
11
|
+
*
|
|
12
|
+
* Exit codes: 0 = PASS, 1 = FAIL (missing deps found)
|
|
13
|
+
* Usage: node scripts/validate-aios-core-deps.js
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
const fs = require('fs');
|
|
17
|
+
const path = require('path');
|
|
18
|
+
const Module = require('module');
|
|
19
|
+
|
|
20
|
+
const PROJECT_ROOT = path.join(__dirname, '..');
|
|
21
|
+
const AIOS_CORE_DIR = path.join(PROJECT_ROOT, '.aios-core');
|
|
22
|
+
const SCRIPTS_DIR = path.join(AIOS_CORE_DIR, 'development', 'scripts');
|
|
23
|
+
const PACKAGE_JSON = path.join(AIOS_CORE_DIR, 'package.json');
|
|
24
|
+
|
|
25
|
+
// Node.js builtin modules
|
|
26
|
+
const BUILTINS = new Set(Module.builtinModules.concat(
|
|
27
|
+
Module.builtinModules.map(m => `node:${m}`),
|
|
28
|
+
));
|
|
29
|
+
|
|
30
|
+
// Optional dev-time packages that should be wrapped in try-catch, not declared as deps
|
|
31
|
+
const ALLOWLIST = new Set([
|
|
32
|
+
'eslint',
|
|
33
|
+
'prettier',
|
|
34
|
+
'jscodeshift',
|
|
35
|
+
'@babel/parser',
|
|
36
|
+
'@babel/traverse',
|
|
37
|
+
'@babel/generator',
|
|
38
|
+
'@babel/types',
|
|
39
|
+
'@jest/globals',
|
|
40
|
+
'jest',
|
|
41
|
+
]);
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Extract require() calls from a JS file using regex.
|
|
45
|
+
* Handles: require('pkg'), require("pkg"), require(`pkg`)
|
|
46
|
+
* Skips: require('./relative'), require('fs'), dynamic require(variable)
|
|
47
|
+
*/
|
|
48
|
+
function extractRequires(filePath) {
|
|
49
|
+
const content = fs.readFileSync(filePath, 'utf8');
|
|
50
|
+
const requires = new Set();
|
|
51
|
+
|
|
52
|
+
// Match require('...') and require("...")
|
|
53
|
+
const pattern = /require\s*\(\s*['"`]([^'"`]+)['"`]\s*\)/g;
|
|
54
|
+
let match;
|
|
55
|
+
while ((match = pattern.exec(content)) !== null) {
|
|
56
|
+
const dep = match[1];
|
|
57
|
+
// Skip relative paths
|
|
58
|
+
if (dep.startsWith('.') || dep.startsWith('/')) continue;
|
|
59
|
+
// Skip template literal expressions (e.g., require('${dep.name}') in code generators)
|
|
60
|
+
if (dep.includes('${') || dep.includes('$')) continue;
|
|
61
|
+
// Skip builtins
|
|
62
|
+
if (BUILTINS.has(dep)) continue;
|
|
63
|
+
|
|
64
|
+
// Extract package name (handle scoped packages like @babel/parser)
|
|
65
|
+
const parts = dep.split('/');
|
|
66
|
+
const pkgName = dep.startsWith('@') ? parts.slice(0, 2).join('/') : parts[0];
|
|
67
|
+
requires.add(pkgName);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return requires;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Recursively find all .js files in a directory
|
|
75
|
+
*/
|
|
76
|
+
function findJsFiles(dir) {
|
|
77
|
+
const files = [];
|
|
78
|
+
if (!fs.existsSync(dir)) return files;
|
|
79
|
+
|
|
80
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
81
|
+
for (const entry of entries) {
|
|
82
|
+
const fullPath = path.join(dir, entry.name);
|
|
83
|
+
if (entry.isDirectory() && entry.name !== 'node_modules') {
|
|
84
|
+
files.push(...findJsFiles(fullPath));
|
|
85
|
+
} else if (entry.isFile() && entry.name.endsWith('.js')) {
|
|
86
|
+
files.push(fullPath);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return files;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function main() {
|
|
93
|
+
console.log('--- .aios-core Dependency Validation (INS-4.12) ---\n');
|
|
94
|
+
|
|
95
|
+
// Read .aios-core/package.json
|
|
96
|
+
if (!fs.existsSync(PACKAGE_JSON)) {
|
|
97
|
+
console.error('FAIL: .aios-core/package.json not found');
|
|
98
|
+
process.exit(1);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const pkg = JSON.parse(fs.readFileSync(PACKAGE_JSON, 'utf8'));
|
|
102
|
+
const declared = new Set(Object.keys(pkg.dependencies || {}));
|
|
103
|
+
|
|
104
|
+
// Find all JS scripts
|
|
105
|
+
const scripts = findJsFiles(SCRIPTS_DIR);
|
|
106
|
+
if (scripts.length === 0) {
|
|
107
|
+
console.log('WARN: No .js files found in .aios-core/development/scripts/');
|
|
108
|
+
process.exit(0);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
console.log(`Scanning ${scripts.length} scripts in .aios-core/development/scripts/\n`);
|
|
112
|
+
|
|
113
|
+
const errors = [];
|
|
114
|
+
const allRequires = new Map(); // pkg -> [files that use it]
|
|
115
|
+
|
|
116
|
+
for (const script of scripts) {
|
|
117
|
+
const requires = extractRequires(script);
|
|
118
|
+
const relPath = path.relative(PROJECT_ROOT, script);
|
|
119
|
+
|
|
120
|
+
for (const pkg of requires) {
|
|
121
|
+
if (!allRequires.has(pkg)) allRequires.set(pkg, []);
|
|
122
|
+
allRequires.get(pkg).push(relPath);
|
|
123
|
+
|
|
124
|
+
if (!declared.has(pkg) && !ALLOWLIST.has(pkg)) {
|
|
125
|
+
errors.push({ script: relPath, package: pkg });
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Report
|
|
131
|
+
console.log(`Found ${allRequires.size} unique external packages across ${scripts.length} scripts`);
|
|
132
|
+
console.log(`Declared in .aios-core/package.json: ${declared.size}`);
|
|
133
|
+
console.log(`Allowlisted (optional/dev-time): ${ALLOWLIST.size}\n`);
|
|
134
|
+
|
|
135
|
+
if (errors.length > 0) {
|
|
136
|
+
console.error(`FAIL: ${errors.length} undeclared dependencies found:\n`);
|
|
137
|
+
|
|
138
|
+
// Group by package
|
|
139
|
+
const byPkg = new Map();
|
|
140
|
+
for (const err of errors) {
|
|
141
|
+
if (!byPkg.has(err.package)) byPkg.set(err.package, []);
|
|
142
|
+
byPkg.get(err.package).push(err.script);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
for (const [pkg, files] of byPkg) {
|
|
146
|
+
console.error(` Missing: "${pkg}"`);
|
|
147
|
+
for (const f of files) {
|
|
148
|
+
console.error(` Used in: ${f}`);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
console.error('\nFix: Add missing packages to .aios-core/package.json dependencies');
|
|
153
|
+
console.error('Or add to ALLOWLIST if they are optional dev-time tools (wrap in try-catch)\n');
|
|
154
|
+
process.exit(1);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
console.log('PASS: All script dependencies are declared in .aios-core/package.json\n');
|
|
158
|
+
process.exit(0);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
main();
|