Skip to content

Commit e5b7cf5

Browse files
authored
fix: allow Pro greenfield validation without package manifest
Treats Pro-created node_modules as valid in greenfield installs that intentionally skipped package.json, and bumps core/installer package versions for publication.
1 parent d3ea190 commit e5b7cf5

6 files changed

Lines changed: 73 additions & 12 deletions

File tree

compat/aiox-core/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "aiox-core",
3-
"version": "5.2.2",
3+
"version": "5.2.3",
44
"description": "Compatibility wrapper for @aiox-squads/core.",
55
"license": "MIT",
66
"bin": {
@@ -15,7 +15,7 @@
1515
"README.md"
1616
],
1717
"dependencies": {
18-
"@aiox-squads/core": "5.2.2"
18+
"@aiox-squads/core": "5.2.3"
1919
},
2020
"engines": {
2121
"node": ">=18"

package-lock.json

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@aiox-squads/core",
3-
"version": "5.2.2",
3+
"version": "5.2.3",
44
"description": "Synkra AIOX: AI-Orchestrated System for Full Stack Development - Core Framework",
55
"bin": {
66
"aiox": "bin/aiox.js",

packages/installer/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@aiox-squads/installer",
3-
"version": "3.3.2",
3+
"version": "3.3.3",
44
"description": "AIOX Installer - Automated setup wizard for AIOX projects (greenfield & brownfield)",
55
"main": "src/index.js",
66
"bin": {

packages/installer/src/wizard/validation/validators/dependency-validator.js

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,15 @@ async function validateDependencies(depsContext = {}) {
4646
// Check node_modules existence
4747
const nodeModulesPath = path.join(projectRoot, 'node_modules');
4848
const packageJsonPath = path.join(projectRoot, 'package.json');
49+
const packageJsonExists = fs.existsSync(packageJsonPath);
50+
const isGreenfieldNoPackageJson =
51+
depsContext.skipped === true &&
52+
depsContext.reason === 'no-package-json' &&
53+
!packageJsonExists;
4954

5055
// For greenfield projects, check if package.json has dependencies
5156
let hasDependencies = false;
52-
if (fs.existsSync(packageJsonPath)) {
57+
if (packageJsonExists) {
5358
try {
5459
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
5560
hasDependencies = !!(
@@ -92,14 +97,31 @@ async function validateDependencies(depsContext = {}) {
9297
message: 'Directory exists',
9398
});
9499

95-
// Validate package.json integrity
96-
await validatePackageJson(results, projectRoot);
100+
if (isGreenfieldNoPackageJson) {
101+
results.checks.push({
102+
component: 'Package Manifest',
103+
file: packageJsonPath,
104+
status: 'skipped',
105+
message: 'No package.json found (greenfield project)',
106+
});
107+
} else {
108+
// Validate package.json integrity
109+
await validatePackageJson(results, projectRoot);
110+
}
97111

98112
// Validate any explicit dependency contract supplied by the caller.
99113
await checkRequiredDependencies(results, projectRoot, depsContext.requiredDependencies);
100114

101-
// Run npm audit (non-blocking - warnings only)
102-
await runSecurityAudit(results, depsContext.packageManager, projectRoot);
115+
if (isGreenfieldNoPackageJson) {
116+
results.checks.push({
117+
component: 'Security Audit',
118+
status: 'skipped',
119+
message: 'No package.json found (greenfield project)',
120+
});
121+
} else {
122+
// Run npm audit (non-blocking - warnings only)
123+
await runSecurityAudit(results, depsContext.packageManager, projectRoot);
124+
}
103125

104126
// Count installed packages
105127
await countInstalledPackages(results, nodeModulesPath);

tests/unit/wizard/validation/dependency-validator.test.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,45 @@ describe('Dependency Validator', () => {
143143
);
144144
});
145145

146+
it('does not fail greenfield validation when Pro creates node_modules without package.json', async () => {
147+
const projectPath = '/tmp/aiox-greenfield-pro';
148+
149+
fs.existsSync.mockImplementation((targetPath) => (
150+
samePath(targetPath, projectFile(projectPath, 'node_modules'))
151+
));
152+
fs.readdirSync.mockReturnValue(['@aiox-squads', '.bin']);
153+
154+
const result = await validateDependencies({
155+
success: true,
156+
skipped: true,
157+
reason: 'no-package-json',
158+
packageManager: 'npm',
159+
projectPath,
160+
});
161+
162+
expect(result.success).toBe(true);
163+
expect(result.errors).toEqual([]);
164+
expect(result.checks).toEqual(
165+
expect.arrayContaining([
166+
expect.objectContaining({
167+
component: 'Dependencies',
168+
status: 'success',
169+
}),
170+
expect.objectContaining({
171+
component: 'Package Manifest',
172+
status: 'skipped',
173+
message: 'No package.json found (greenfield project)',
174+
}),
175+
expect.objectContaining({
176+
component: 'Security Audit',
177+
status: 'skipped',
178+
message: 'No package.json found (greenfield project)',
179+
}),
180+
]),
181+
);
182+
expect(childProcess.exec).not.toHaveBeenCalled();
183+
});
184+
146185
it('fails when package.json declares dependencies but node_modules is missing', async () => {
147186
const projectPath = '/tmp/aiox-broken';
148187

0 commit comments

Comments
 (0)