Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .aiox-core/install-manifest.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
# - SHA256 hashes for change detection
# - File types for categorization
#
version: 5.2.8
generated_at: "2026-05-21T00:21:31.048Z"
version: 5.2.9
generated_at: "2026-05-21T01:42:24.351Z"
generator: scripts/generate-install-manifest.js
file_count: 1129
files:
Expand Down Expand Up @@ -3701,7 +3701,7 @@ files:
type: monitor
size: 818
- path: package.json
hash: sha256:bc1bd0eae7c04feb1d1659fb9715a7c908e1cf2bb146341ed3b0d24f630cc9a9
hash: sha256:d8dbe037240a366d545ca4259d2059e705b709706dcf2a18a5a52d9b543b7ed9
type: other
size: 1445
- path: product/checklists/accessibility-wcag-checklist.md
Expand Down
2 changes: 1 addition & 1 deletion .aiox-core/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@aiox-squads/core-internal",
"version": "5.2.8",
"version": "5.2.9",
"description": "Internal package manifest for AIOX framework — declares runtime dependencies consumed by scripts under .aiox-core/. This is NOT published independently; it ships inside @aiox-squads/core (the top-level package). Kept name-distinct from the parent (`-internal` suffix) to avoid npm registry confusion. Version follows the parent package.",
"private": true,
"main": "index.js",
Expand Down
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,19 @@ All notable changes to Synkra AIOX will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [5.2.9] - 2026-05-21

### Fixed

- **Pro artifact install no longer invokes `npx install` when the installer itself runs through `npx`**.
- Root cause: `npm_execpath` can point at `npx-cli.js` during `npx -p @aiox-squads/core aiox install`.
- Fix: the installer now derives the sibling `npm-cli.js` when available and otherwise falls back to `npm`, so Pro artifact extraction keeps running `npm install <tgz> --prefix <target>`.
- This targets Linux installs that authenticated and activated Pro successfully, then failed at content installation with `unexpected argument '--prefix' found`.

### Changed

- `@aiox-squads/installer` bumped to `3.3.8` to ship the Pro artifact extraction fix.

## [5.2.8] - 2026-05-21

### Fixed
Expand Down
4 changes: 2 additions & 2 deletions compat/aiox-core/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "aiox-core",
"version": "5.2.8",
"version": "5.2.9",
"description": "Compatibility wrapper for @aiox-squads/core.",
"license": "MIT",
"bin": {
Expand All @@ -15,7 +15,7 @@
"README.md"
],
"dependencies": {
"@aiox-squads/core": "5.2.8"
"@aiox-squads/core": "5.2.9"
},
"engines": {
"node": ">=18"
Expand Down
6 changes: 3 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@aiox-squads/core",
"version": "5.2.8",
"version": "5.2.9",
"description": "Synkra AIOX: AI-Orchestrated System for Full Stack Development - Core Framework",
"bin": {
"aiox": "bin/aiox.js",
Expand Down
2 changes: 1 addition & 1 deletion packages/installer/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@aiox-squads/installer",
"version": "3.3.7",
"version": "3.3.8",
"description": "AIOX Installer - Automated setup wizard for AIOX projects (greenfield & brownfield)",
"main": "src/index.js",
"bin": {
Expand Down
26 changes: 24 additions & 2 deletions packages/installer/src/wizard/pro-setup.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,39 @@ function stripWrappingQuotes(value) {
return String(value || '').trim().replace(/^"(.*)"$/, '$1');
}

function resolveNpmExecPath(npmExecPath, fileExists = fs.existsSync) {
if (!npmExecPath || !/\.js$/i.test(npmExecPath)) {
return null;
}

const pathApi = npmExecPath.includes('\\') ? path.win32 : path.posix;
const basename = pathApi.basename(npmExecPath).toLowerCase();
if (basename === 'npm-cli.js' && fileExists(npmExecPath)) {
return npmExecPath;
}

if (basename === 'npx-cli.js') {
const npmCliPath = pathApi.join(pathApi.dirname(npmExecPath), 'npm-cli.js');
if (fileExists(npmCliPath)) {
return npmCliPath;
}
}

return null;
}

function resolveNpmInvocation(options = {}) {
const platform = options.platform || process.platform;
const env = options.env || process.env;
const execPath = options.execPath || process.execPath;
const fileExists = options.fileExists || fs.existsSync;
const npmExecPath = stripWrappingQuotes(env.npm_execpath);
const npmCliPath = resolveNpmExecPath(npmExecPath, fileExists);

if (npmExecPath && /\.js$/i.test(npmExecPath) && fileExists(npmExecPath)) {
if (npmCliPath) {
return {
command: execPath,
prefixArgs: [npmExecPath],
prefixArgs: [npmCliPath],
execOptions: {},
};
}
Expand Down
33 changes: 33 additions & 0 deletions tests/installer/pro-setup-auth.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,39 @@ describe('pro-setup npm invocation', () => {
});
});

it('derives npm-cli.js when invoked through npx-cli.js', () => {
const invocation = proSetup._testing.resolveNpmInvocation({
platform: 'linux',
execPath: '/usr/bin/node',
env: {
npm_execpath: '/usr/lib/node_modules/npm/bin/npx-cli.js',
},
fileExists: (candidate) => candidate.endsWith('/npm-cli.js'),
});

expect(invocation).toEqual({
command: '/usr/bin/node',
prefixArgs: ['/usr/lib/node_modules/npm/bin/npm-cli.js'],
execOptions: {},
});
});

it('does not execute npx-cli.js as npm when npm-cli.js cannot be found', () => {
const invocation = proSetup._testing.resolveNpmInvocation({
platform: 'linux',
env: {
npm_execpath: '/usr/lib/node_modules/npm/bin/npx-cli.js',
},
fileExists: () => false,
});

expect(invocation).toEqual({
command: 'npm',
prefixArgs: [],
execOptions: {},
});
});

it('falls back to shell execution for npm.cmd on Windows', () => {
const invocation = proSetup._testing.resolveNpmInvocation({
platform: 'win32',
Expand Down
Loading