Skip to content

fix: resolve Pro package from both @aiox-fullstack/pro and @aios-fullstack/pro [Story 122.1]#623

Open
rafaelscosta wants to merge 7 commits intomainfrom
fix/pro-package-dual-scope-resolution
Open

fix: resolve Pro package from both @aiox-fullstack/pro and @aios-fullstack/pro [Story 122.1]#623
rafaelscosta wants to merge 7 commits intomainfrom
fix/pro-package-dual-scope-resolution

Conversation

@rafaelscosta
Copy link
Copy Markdown
Collaborator

@rafaelscosta rafaelscosta commented Apr 10, 2026

Resolves dual-scope package resolution for AIOX Pro. The canonical name @aiox-fullstack/pro does not yet exist on npm (pending org rename). The active fallback is @aios-fullstack/pro@0.3.0. All Pro-related code now tries canonical first, then fallback. 80/80 Pro tests pass.

Summary by CodeRabbit

  • New Features

    • Added a Pro update command (check/dry-run/force/include-core/skip-scaffold) and optional integration into the main update flow.
  • Bug Fixes

    • Improved Pro detection, install/verify and scaffolding to support two package scopes with automatic fallback and clearer install/repair messaging.
  • Documentation

    • Updated user-facing help, translations, release notes, workflows and submodule references to the alternate package scope.
  • Tests

    • Added/expanded tests for Pro detection, NPM resolution and the Pro updater/scaffolding behavior.

…stack/pro [Story 122.1]

- pro-detector: add npm package resolution with canonical/fallback priority
- pro CLI commands: resolve license path from both scopes
- pro-setup wizard: loadProModule tries both npm scopes
- pro-scaffolder: resolve source dir from both npm scopes
- aiox-pro-cli: isProInstalled checks both scopes
- i18n: update user-facing messages to active package name
- CI: update publish workflow to active package name
- tests: update pro-detector tests for new API (21/21 passing)

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
@vercel
Copy link
Copy Markdown

vercel bot commented Apr 10, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
aiox-core Ready Ready Preview, Comment Apr 11, 2026 0:49am

Request Review

@github-actions github-actions bot added area: agents Agent system related area: workflows Workflow system related squad mcp type: test Test coverage and quality area: core Core framework (.aios-core/core/) area: installer Installer and setup (packages/installer/) area: synapse SYNAPSE context engine area: cli CLI tools (bin/, packages/aios-pro-cli/) area: pro Pro features (pro/) area: health-check Health check system area: docs Documentation (docs/) area: devops CI/CD, GitHub Actions (.github/) labels Apr 10, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 10, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds dual-scope Pro package resolution across CLI, installer, and detection utilities; introduces a new Pro updater module and aiox pro update subcommand; broadens npm-based detection/scaffolding fallbacks; updates i18n, CI and submodule references; and expands tests for the new behaviors.

Changes

Cohort / File(s) Summary
CLI Pro Command & Entrypoint
.aiox-core/cli/commands/pro/index.js, bin/aiox.js
Adds aiox pro update and updateAction; CLI now invokes Pro updater after core updates and handles progress/exit behavior; activation/setup flows prefer canonical package then fallback.
Pro Updater Module
.aiox-core/core/pro/pro-updater.js
New end-to-end Pro update workflow: detect installed Pro, detect package manager, fetch npm metadata, validate peerDependencies, optionally update core, install/update Pro (check/dryRun/force/include-core/skip-scaffold), run scaffolder, and format results. Exposes several helpers.
Pro Detection Utilities & CLI Installer
bin/utils/pro-detector.js, packages/aiox-pro-cli/bin/aiox-pro.js, tests/pro/pro-detector.test.js
Introduce canonical/fallback package names and resolveNpmProPackage(); detection/load/version functions prefer npm packages (canonical then fallback) before bundled submodule; tests updated/expanded for npm-resolution and new exports.
Installer & Scaffolding
packages/installer/src/pro/pro-scaffolder.js, packages/installer/src/wizard/pro-setup.js
Broaden scaffold and license resolution to try both package scopes, add guarded tryRequire behavior, and check both node_modules/.../pro candidates when resolving scaffold source; update error messaging.
i18n / User Messaging
packages/installer/src/wizard/i18n.js, .aiox-core/cli/commands/pro/index.js (messages)
Updated translation and CLI messages to reference @aios-fullstack/pro (and generalized messaging when neither scope is present).
CI / Publish Workflow & Submodule
.github/workflows/publish-pro.yml, .github/workflows/pro-integration.yml, .gitmodules, pro
Updated publish workflow messaging/verification to use @aios-fullstack/pro; changed pro submodule remote URL and bumped recorded submodule revision.
Install Manifest
.aiox-core/install-manifest.yaml
Manifest metadata updated to include new core file entry and updated hashes/sizes for modified files.
Tests: Pro Updater
tests/pro/pro-updater.test.js
New Jest suite covering core-version resolution, peer-range satisfaction, registry fetch behavior, and an update+scaffold failure scenario for updatePro.

Sequence Diagram(s)

sequenceDiagram
  participant CLI as CLI (aiox)
  participant Updater as Pro Updater
  participant Registry as npm Registry (HTTPS)
  participant PM as Package Manager
  participant FS as Filesystem / Scaffolder

  CLI->>Updater: updatePro(projectRoot, options)
  Updater->>Updater: resolveInstalledPro(projectRoot)
  Updater->>Registry: fetchLatestFromNpm(packageName)
  Registry-->>Updater: metadata (version, peerDependencies)
  Updater->>Updater: compare versions & peer deps
  alt includeCore & core incompatible
    Updater->>PM: install/update aiox-core
    PM-->>Updater: install result
  end
  alt should update Pro
    Updater->>PM: install/update Pro (or dry-run plan)
    PM-->>Updater: install result
    Updater->>FS: require scaffolder -> scaffoldProContent(...)
    FS-->>Updater: scaffold result
  else up-to-date
    Updater-->>CLI: formatted up-to-date result
  end
  Updater-->>CLI: formatUpdateResult(result)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • oalanicolas
  • Pedrovaleriolopez
🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 78.13% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main change: implementing dual-scope package resolution for Pro packages, supporting both @aiox-fullstack/pro and @aios-fullstack/pro as fallback options.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/pro-package-dual-scope-resolution

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 10, 2026

📊 Coverage Report

Coverage report not available

📈 Full coverage report available in Codecov


Generated by PR Automation (Story 6.1)

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/installer/src/wizard/i18n.js (1)

124-165: ⚠️ Potential issue | 🟡 Minor

Keep these recovery strings scope-agnostic.

The wizard now resolves @aiox-fullstack/pro first, but these messages tell users to install only @aios-fullstack/pro. Once the canonical package is available, valid installs will be reported with the wrong remediation path. Prefer “AIOX Pro package” or mention both scopes here.

Also applies to: 282-322, 439-479

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/installer/src/wizard/i18n.js` around lines 124 - 165, The i18n
strings reference the hard-coded scope '@aios-fullstack/pro' which is now
ambiguous because the wizard resolves '@aiox-fullstack/pro' first; update all
affected keys (e.g., proModuleNotAvailable, proInstallingPackage,
proPackageInstallFailed, proPackageNotFound, proScaffolderNotAvailable,
proNeedHelp and the other messages in the ranges mentioned) to use
scope-agnostic wording such as "AIOX Pro package" or list both scopes
('@aiox-fullstack/pro' and '@aios-fullstack/pro') in remediation text, ensuring
every message that tells users to install or check the package is updated
consistently.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.aiox-core/cli/commands/pro/index.js:
- Around line 636-659: The loop currently falls back to the next package for any
execSync error; change the catch in the for (const pkg of PRO_PACKAGES) loop to
inspect the thrown error (e.g., capture as err) and only continue to the next
pkg when the error indicates package-not-found (look for stderr/message
containing "404", "Not Found", "ERR! 404" or similar). For any other error
(auth/registry/lockfile/etc.) surface it immediately: log the error details via
console.error and exit (or rethrow) instead of silently trying the fallback;
keep references to PRO_PACKAGES and the execSync call while updating the catch
behavior.

In `@bin/utils/pro-detector.js`:
- Around line 49-63: The resolveNpmProPackage function currently checks only
hardcoded node_modules locations and fails for hoisted/workspace installs;
modify resolveNpmProPackage to attempt resolving each candidate using
require.resolve (e.g., require.resolve(path.join(candidateName, 'package.json'))
or require.resolve(candidateName) inside a try/catch) so Node's resolver is
used, and on success return the same { packagePath, packageName } shape (use
path.dirname of the resolved package.json or module to set packagePath); keep
trying PRO_PACKAGE_CANONICAL then PRO_PACKAGE_FALLBACK and return null if both
fail.

In `@packages/aiox-pro-cli/bin/aiox-pro.js`:
- Around line 25-26: The rename introduced PRO_PACKAGE_CANONICAL and
PRO_PACKAGE_FALLBACK but left references to PRO_PACKAGE in showHelp(),
installPro(), and the “not installed” path, causing a ReferenceError; fix by
restoring a compatibility alias (e.g., define PRO_PACKAGE =
PRO_PACKAGE_CANONICAL) or update every call site to use
PRO_PACKAGE_CANONICAL/PRO_PACKAGE_FALLBACK consistently (ensure showHelp,
installPro, and the not-installed logic reference the new constants).

In `@packages/installer/src/wizard/pro-setup.js`:
- Around line 340-346: The loops over npmScopes currently swallow all require()
errors; change the catch to only fall through when the module is actually
missing for the exact requested path. For each loop (the one using npmScopes and
moduleName and the other similar loop referenced), compute the request string
(e.g. const reqPath = `${scope}/license/${moduleName}`), try require(reqPath),
and in the catch inspect the error: if err.code !== 'MODULE_NOT_FOUND' or the
err.message does not include reqPath then rethrow the error; otherwise continue
to the next scope. This ensures you only fallback on a genuine "module not
found" for that specific path and rethrow initialization or transitive
dependency errors.

In `@tests/pro/pro-detector.test.js`:
- Around line 68-73: Add a targeted test that calls resolveNpmProPackage()
directly with both candidate scopes present and asserts the returned package
string is the canonical '@aiox-fullstack/pro' (i.e., ensure the resolver prefers
'@aiox-fullstack' over the fallback); to implement, mock fs.existsSync to return
true for paths containing both '@aiox-fullstack' and '@aios-fullstack' and then
assert resolveNpmProPackage() === '@aiox-fullstack/pro'; replicate the same
explicit precedence assertion for the similar case mentioned around lines 90-94
so the new resolver ordering is covered.

---

Outside diff comments:
In `@packages/installer/src/wizard/i18n.js`:
- Around line 124-165: The i18n strings reference the hard-coded scope
'@aios-fullstack/pro' which is now ambiguous because the wizard resolves
'@aiox-fullstack/pro' first; update all affected keys (e.g.,
proModuleNotAvailable, proInstallingPackage, proPackageInstallFailed,
proPackageNotFound, proScaffolderNotAvailable, proNeedHelp and the other
messages in the ranges mentioned) to use scope-agnostic wording such as "AIOX
Pro package" or list both scopes ('@aiox-fullstack/pro' and
'@aios-fullstack/pro') in remediation text, ensuring every message that tells
users to install or check the package is updated consistently.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 1ed22e78-c0c2-4bd4-963e-abc24839acf8

📥 Commits

Reviewing files that changed from the base of the PR and between 0df1e25 and 06e2f42.

📒 Files selected for processing (8)
  • .aiox-core/cli/commands/pro/index.js
  • .github/workflows/publish-pro.yml
  • bin/utils/pro-detector.js
  • packages/aiox-pro-cli/bin/aiox-pro.js
  • packages/installer/src/pro/pro-scaffolder.js
  • packages/installer/src/wizard/i18n.js
  • packages/installer/src/wizard/pro-setup.js
  • tests/pro/pro-detector.test.js

- Add pro-updater.js: detect installed Pro, query npm, check compat, update, re-scaffold
- Register 'aiox pro update' subcommand with --check, --dry-run, --force, --include-core, --skip-scaffold
- Add 'aiox update --include-pro' to update core + Pro in one command
- License validation before update (skip on --check/--dry-run)
- Detects package manager (npm/pnpm/yarn/bun) automatically
- Re-scaffolds Pro assets (squads, skills, configs) after package update
- Formatted CLI output with update summary

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

♻️ Duplicate comments (1)
.aiox-core/cli/commands/pro/index.js (1)

643-652: ⚠️ Potential issue | 🟠 Major

Retry the fallback only for “package not found”, and pin the intended fallback version.

This still falls through to @aios-fullstack/pro after any install failure, so auth, registry, or lockfile errors get masked as a scope fallback. It also installs the fallback unpinned even though this story’s contract is @aios-fullstack/pro@0.3.0, which makes setup drift with whatever latest points to at execution time. As per coding guidelines, **/*.js: Verify error handling is comprehensive.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.aiox-core/cli/commands/pro/index.js around lines 643 - 652, The current
loop over PRO_PACKAGES blindly falls back on any install error and installs the
unpinned fallback; change the catch in the loop that calls execSync to inspect
the thrown error (from execSync) and only continue to the next package when the
error indicates "package not found" (npm ERR 404 or similar message/code),
otherwise rethrow or exit with the original error so auth/registry/lockfile
errors are not masked; also update the PRO_PACKAGES entry for the fallback to
use the pinned version "@aios-fullstack/pro@0.3.0" so the intended version is
installed when that specific fallback is chosen (references: PRO_PACKAGES array,
execSync call, and the catch block that sets installed).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.aiox-core/cli/commands/pro/index.js:
- Around line 707-712: The command defines conflicting flags
(.option('--include-core') and .option('--no-core')) so --no-core doesn't negate
includeCore; update the CLI option definitions to use a single boolean flag with
a negation pair (e.g., define .option('--core') and .option('--no-core') or only
.option('--include-core') and remove .option('--no-core')) and ensure the
handler reads the same property passed to updatePro (currently reading
options.includeCore); update the option name or the code that builds the call to
updatePro so options.includeCore correctly reflects the user's --core/--no-core
choice and passes the intended includeCore value into updatePro.

In @.aiox-core/core/pro/pro-updater.js:
- Around line 301-309: The scaffold step currently ignores
scaffoldResult.success and unconditionally sets result.success = true; update
the logic in the block that calls runScaffold (referencing skipScaffold,
updatedPro/installed to compute proPath, runScaffold, and
result.scaffoldResult/result.actions) so that if scaffoldResult.success is false
you set result.success = false (and keep the action marked 'failed') and return
or propagate that failure; also wrap the runScaffold call in a try/catch so any
thrown errors are caught, set result.scaffoldResult to an error/failure object,
push a corresponding failed action into result.actions, and set result.success =
false before returning.
- Around line 119-129: The current satisfiesPeer function incorrectly strips
operators and compares numeric minima; replace its logic to use a real semver
evaluator: import or require the semver package and change
satisfiesPeer(installed, range) to return true when either arg is missing,
otherwise call semver.satisfies(installed, range) (or
semver.satisfies(semver.coerce(installed), range) if installed may be
non-standard), and catch invalid-range errors to conservatively return
true/false per your policy; ensure you update any module imports to include
semver so semver.satisfies is available.

---

Duplicate comments:
In @.aiox-core/cli/commands/pro/index.js:
- Around line 643-652: The current loop over PRO_PACKAGES blindly falls back on
any install error and installs the unpinned fallback; change the catch in the
loop that calls execSync to inspect the thrown error (from execSync) and only
continue to the next package when the error indicates "package not found" (npm
ERR 404 or similar message/code), otherwise rethrow or exit with the original
error so auth/registry/lockfile errors are not masked; also update the
PRO_PACKAGES entry for the fallback to use the pinned version
"@aios-fullstack/pro@0.3.0" so the intended version is installed when that
specific fallback is chosen (references: PRO_PACKAGES array, execSync call, and
the catch block that sets installed).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: dcfbf71d-9874-4c1a-ae37-69cc8d989f90

📥 Commits

Reviewing files that changed from the base of the PR and between 06e2f42 and cebcb91.

📒 Files selected for processing (3)
  • .aiox-core/cli/commands/pro/index.js
  • .aiox-core/core/pro/pro-updater.js
  • bin/aiox.js

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (3)
.aiox-core/core/pro/pro-updater.js (2)

30-35: Consider reusing detectPackageManager from dependency-installer.js.

The same logic exists in packages/installer/src/installer/dependency-installer.js with a data-driven approach using LOCK_FILES. Extracting this to a shared utility would reduce duplication and ensure consistent priority order across the codebase.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.aiox-core/core/pro/pro-updater.js around lines 30 - 35, The
detectPackageManager implementation in pro-updater.js duplicates logic from
dependency-installer.js; extract the lock-file based detection into a shared
utility (e.g., create a new exported function like detectPackageManager in a
common util module) that uses the existing LOCK_FILES data-driven array from
dependency-installer.js (or move LOCK_FILES into the new shared module) and
replace the local detectPackageManager function with an import of that shared
function so both pro-updater.js and dependency-installer.js use the same
implementation and priority order.

215-223: Consider validating projectRoot parameter.

Public API methods like updatePro(), getCoreVersion(), and resolveInstalledPro() don't validate that projectRoot is a non-empty string or an existing directory. Passing undefined or an invalid path would cause cryptic fs errors downstream. As per coding guidelines, .aiox-core/core/**: Check for proper input validation on public API methods.

💡 Example validation
async function updatePro(projectRoot, options = {}) {
  if (typeof projectRoot !== 'string' || !projectRoot) {
    throw new TypeError('projectRoot must be a non-empty string');
  }
  // ... rest of function
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.aiox-core/core/pro/pro-updater.js around lines 215 - 223, Validate the
projectRoot parameter at the start of public API functions (updatePro,
getCoreVersion, resolveInstalledPro): ensure typeof projectRoot === 'string' and
it is not empty, then confirm it points to an existing directory (use fs.stat or
fs.promises.stat and check isDirectory()); throw a clear TypeError for invalid
types/empty string and a descriptive Error if the path does not exist or is not
a directory so downstream fs calls won't produce cryptic errors.
tests/pro/pro-updater.test.js (1)

119-138: jest.doMock without jest.resetModules() may cause flaky tests.

When using jest.doMock for lazy mocking after the module under test is already imported, you should call jest.resetModules() beforehand to clear the require cache. Otherwise, if the scaffolder module was required elsewhere (e.g., in a previous test or during import resolution), the mock won't take effect.

♻️ Suggested fix
+      jest.resetModules();
       jest.doMock(scaffolderPath, () => ({
         scaffoldProContent: jest.fn().mockResolvedValue({
           success: false,
           errors: ['sync failed'],
           copiedFiles: [],
           skippedFiles: [],
           warnings: [],
         }),
       }));
+
+      // Re-require updater to pick up mocked scaffolder
+      const { updatePro: updateProWithMock } = require('../../.aiox-core/core/pro/pro-updater');
 
-      const result = await updatePro(projectRoot, {});
+      const result = await updateProWithMock(projectRoot, {});
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/pro/pro-updater.test.js` around lines 119 - 138, The test uses
jest.doMock(scaffolderPath, ...) after the module under test has likely been
imported, which can lead to flaky behavior; call jest.resetModules() immediately
before jest.doMock to clear the require cache so the mock will be applied, then
re-require or import modules if needed; update the test around the jest.doMock
call that mocks scaffolderPath (and the subsequent updatePro invocation) to add
jest.resetModules() before doMock and ensure jest.dontMock(scaffolderPath)
remains after the assertions.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.aiox-core/core/pro/pro-updater.js:
- Around line 48-62: The response handler currently parses body unconditionally;
update the res.on('end') logic to first check res.statusCode (ensure 2xx, e.g.,
statusCode >= 200 && statusCode < 300) before attempting JSON.parse. If the
status is not OK, do not parse the body—resolve(null) (or reject with a clear
error) and include the statusCode in any logged message; keep the existing
try/catch JSON.parse block only for successful status codes. Target the
res.on('end') callback (the JSON.parse block that builds { version,
peerDependencies }) and the surrounding https.get response handler to implement
this check.
- Around line 391-404: The current brittle relative import built via
scaffolderPath (path.join(...
'packages','installer','src','pro','pro-scaffolder')) and its require that
extracts scaffoldProContent should be replaced with a stable package export or
module alias: add an "exports" entry in packages/installer/package.json that
exposes "src/pro/pro-scaffolder" (or create a tsconfig/webpack module alias for
the installer package), then change the require in pro-updater.js to import from
the package name (e.g., require('installer/pro-scaffolder') or the alias) and
keep using the scaffoldProContent symbol; update any build/tsconfig config so
the new path resolves in dev and CI.

---

Nitpick comments:
In @.aiox-core/core/pro/pro-updater.js:
- Around line 30-35: The detectPackageManager implementation in pro-updater.js
duplicates logic from dependency-installer.js; extract the lock-file based
detection into a shared utility (e.g., create a new exported function like
detectPackageManager in a common util module) that uses the existing LOCK_FILES
data-driven array from dependency-installer.js (or move LOCK_FILES into the new
shared module) and replace the local detectPackageManager function with an
import of that shared function so both pro-updater.js and
dependency-installer.js use the same implementation and priority order.
- Around line 215-223: Validate the projectRoot parameter at the start of public
API functions (updatePro, getCoreVersion, resolveInstalledPro): ensure typeof
projectRoot === 'string' and it is not empty, then confirm it points to an
existing directory (use fs.stat or fs.promises.stat and check isDirectory());
throw a clear TypeError for invalid types/empty string and a descriptive Error
if the path does not exist or is not a directory so downstream fs calls won't
produce cryptic errors.

In `@tests/pro/pro-updater.test.js`:
- Around line 119-138: The test uses jest.doMock(scaffolderPath, ...) after the
module under test has likely been imported, which can lead to flaky behavior;
call jest.resetModules() immediately before jest.doMock to clear the require
cache so the mock will be applied, then re-require or import modules if needed;
update the test around the jest.doMock call that mocks scaffolderPath (and the
subsequent updatePro invocation) to add jest.resetModules() before doMock and
ensure jest.dontMock(scaffolderPath) remains after the assertions.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 7aff28b9-5d29-4de0-b513-ff982f4a8df6

📥 Commits

Reviewing files that changed from the base of the PR and between f1a6d1e and f23f8e7.

📒 Files selected for processing (7)
  • .aiox-core/cli/commands/pro/index.js
  • .aiox-core/core/pro/pro-updater.js
  • .aiox-core/install-manifest.yaml
  • bin/utils/pro-detector.js
  • packages/installer/src/wizard/pro-setup.js
  • tests/pro/pro-detector.test.js
  • tests/pro/pro-updater.test.js
✅ Files skipped from review due to trivial changes (2)
  • .aiox-core/install-manifest.yaml
  • bin/utils/pro-detector.js
🚧 Files skipped from review as they are similar to previous changes (3)
  • packages/installer/src/wizard/pro-setup.js
  • tests/pro/pro-detector.test.js
  • .aiox-core/cli/commands/pro/index.js

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
.aiox-core/core/pro/pro-updater.js (1)

233-242: Consider adding input validation for projectRoot.

The updatePro function is a public API but doesn't validate that projectRoot is a valid, existing directory before proceeding. If called with an invalid path, the failure would occur deep in the flow with a potentially confusing error message.

🛡️ Suggested validation
 async function updatePro(projectRoot, options = {}) {
+  if (!projectRoot || typeof projectRoot !== 'string') {
+    return {
+      success: false,
+      error: 'projectRoot is required and must be a string.',
+      actions: [],
+    };
+  }
+
+  if (!fs.existsSync(projectRoot) || !fs.statSync(projectRoot).isDirectory()) {
+    return {
+      success: false,
+      error: `Project root does not exist or is not a directory: ${projectRoot}`,
+      actions: [],
+    };
+  }
+
   const {
     check = false,

As per coding guidelines, .aiox-core/core/**: Check for proper input validation on public API methods.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.aiox-core/core/pro/pro-updater.js around lines 233 - 242, The
updatePro(public API) is missing validation for its projectRoot parameter; add
an early guard in the updatePro function to ensure projectRoot is a non-empty
string that resolves to an existing directory and throw a clear, descriptive
error (e.g., TypeError or custom Error) if not. Use the Node fs APIs (fs.stat or
fs.promises.stat) to test existence and directory-ness before any async work
begins, normalize the path (e.g., path.resolve) for clearer error messages, and
reference updatePro and the projectRoot parameter in the thrown message so
callers immediately know the input was invalid.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.aiox-core/core/pro/pro-updater.js:
- Around line 348-361: The update block hardcodes 'aiox-core' when calling
buildInstallCmd(pm, 'aiox-core') which can install the wrong package for
projects using the scoped name; add a helper (e.g.,
detectCorePackageName(projectRoot)) that reads package.json and dependencies to
return '@synkra/aiox-core' or 'aiox-core' (or null), call it before the
includeCoreUpdate branch, and use its result as the packageName argument to
buildInstallCmd (falling back to 'aiox-core' if detectCorePackageName returns
null); update the try/catch block in the includeCoreUpdate section to use this
detected package name instead of the hardcoded string.

---

Nitpick comments:
In @.aiox-core/core/pro/pro-updater.js:
- Around line 233-242: The updatePro(public API) is missing validation for its
projectRoot parameter; add an early guard in the updatePro function to ensure
projectRoot is a non-empty string that resolves to an existing directory and
throw a clear, descriptive error (e.g., TypeError or custom Error) if not. Use
the Node fs APIs (fs.stat or fs.promises.stat) to test existence and
directory-ness before any async work begins, normalize the path (e.g.,
path.resolve) for clearer error messages, and reference updatePro and the
projectRoot parameter in the thrown message so callers immediately know the
input was invalid.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 152165d0-7938-44a5-aceb-435dfddbd351

📥 Commits

Reviewing files that changed from the base of the PR and between f23f8e7 and 4f3aa4e.

📒 Files selected for processing (3)
  • .aiox-core/core/pro/pro-updater.js
  • .aiox-core/install-manifest.yaml
  • tests/pro/pro-updater.test.js
🚧 Files skipped from review as they are similar to previous changes (2)
  • .aiox-core/install-manifest.yaml
  • tests/pro/pro-updater.test.js

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: agents Agent system related area: cli CLI tools (bin/, packages/aios-pro-cli/) area: core Core framework (.aios-core/core/) area: devops CI/CD, GitHub Actions (.github/) area: docs Documentation (docs/) area: health-check Health check system area: installer Installer and setup (packages/installer/) area: pro Pro features (pro/) area: synapse SYNAPSE context engine area: workflows Workflow system related mcp squad type: test Test coverage and quality

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants