Skip to content

Release commander#2801

Open
rinatkhaziev wants to merge 26 commits intotrunkfrom
next
Open

Release commander#2801
rinatkhaziev wants to merge 26 commits intotrunkfrom
next

Conversation

@rinatkhaziev
Copy link
Copy Markdown
Contributor

Description

This pull request introduces a comprehensive workflow and tooling for building, signing, and distributing a standalone SEA (Single Executable Application) version of the VIP CLI across macOS, Linux, Windows, and WSL environments. It adds automation via GitHub Actions, a dedicated build script, supporting documentation, and updates the codebase to support and document the new packaging approach. Additionally, it removes the legacy args CLI parser in favor of commander, documents the migration, and updates dependencies accordingly.

The most important changes are:

SEA Build & Signing Automation

  • Added .github/workflows/sea-build-sign.yml workflow to automate building, optional signing, and artifact upload for SEA executables on all major platforms, including WSL-mediated Windows builds.
  • Introduced helpers/build-sea.js, a script that bundles the CLI, packages dependencies, and produces a self-contained executable using Node 22 SEA, with platform-specific post-processing (codesign, blob injection, etc.).
  • Added build:sea npm script and new dependencies (esbuild, postject, commander) in package.json to support SEA builds and CLI migration. [1] [2] [3]

Documentation & Developer Guidance

  • Added docs/SEA-BUILD-SIGNING.md, a detailed runbook for building and signing SEA executables on each platform, including prerequisites, step-by-step instructions, and release checklists.
  • Updated AGENTS.md and CLAUDE.md to reference the new SEA build/signing runbook and clarify SEA packaging requirements and pitfalls. [1] [2]

CLI Parser Migration

  • Removed the legacy args CLI parser and migrated to commander, updating all relevant imports and documentation. Added docs/COMMANDER-MIGRATION.md to describe the migration, compatibility, and next steps. [1] [2] [3]

Codebase Cleanups and Type Improvements

  • Changed direct imports of Lando to type-only imports in src/commands/dev-env-sync-sql.ts to support SEA bundling and improve type safety. [1] [2]

These changes collectively enable robust, repeatable, and secure distribution of the VIP CLI as a single-file executable, while modernizing the CLI parsing infrastructure and providing clear guidance for future development and releases.

Changelog Description

Changed

  • We've changed underlying CLI library to Commander

Pull request checklist

New release checklist

Steps to Test

Outline the steps to test and verify the PR here.

Example:

  1. Check out PR.
  2. Run npm run build
  3. Run ./dist/bin/vip-cookies.js nom
  4. Verify cookies are delicious.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 22, 2026

Dependency Review

The following issues were found:
  • ✅ 0 vulnerable package(s)
  • ✅ 0 package(s) with incompatible licenses
  • ✅ 0 package(s) with invalid SPDX license definitions
  • ⚠️ 4 package(s) with unknown licenses.
See the Details below.

License Issues

.github/workflows/sea-build-sign.yml

PackageVersionLicenseIssue Type
actions/checkout6.*.*NullUnknown License
actions/setup-node6.*.*NullUnknown License
actions/upload-artifact4.*.*NullUnknown License

package.json

PackageVersionLicenseIssue Type
commander^14.0.3NullUnknown License

OpenSSF Scorecard

PackageVersionScoreDetails
actions/actions/checkout 6.*.* 🟢 5.7
Details
CheckScoreReason
Binary-Artifacts🟢 10no binaries found in the repo
Maintained⚠️ 00 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Code-Review🟢 10all changesets reviewed
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Fuzzing⚠️ 0project is not fuzzed
Packaging⚠️ -1packaging workflow not detected
License🟢 10license file detected
Signed-Releases⚠️ -1no releases found
Pinned-Dependencies🟢 3dependency not pinned by hash detected -- score normalized to 3
Security-Policy🟢 9security policy file detected
Branch-Protection🟢 5branch protection is not maximal on development and all release branches
SAST🟢 8SAST tool detected but not run on all commits
actions/actions/setup-node 6.*.* 🟢 5.7
Details
CheckScoreReason
Maintained🟢 68 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 6
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Code-Review🟢 10all changesets reviewed
Packaging⚠️ -1packaging workflow not detected
Binary-Artifacts🟢 9binaries present in source code
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Pinned-Dependencies⚠️ 0dependency not pinned by hash detected -- score normalized to 0
Fuzzing⚠️ 0project is not fuzzed
License🟢 10license file detected
Signed-Releases⚠️ -1no releases found
Security-Policy🟢 9security policy file detected
Branch-Protection⚠️ 1branch protection is not maximal on development and all release branches
SAST🟢 9SAST tool is not run on all commits -- score normalized to 9
actions/actions/upload-artifact 4.*.* 🟢 6
Details
CheckScoreReason
Maintained🟢 88 commit(s) and 2 issue activity found in the last 90 days -- score normalized to 8
Binary-Artifacts🟢 10no binaries found in the repo
Code-Review🟢 10all changesets reviewed
Dangerous-Workflow🟢 10no dangerous workflow patterns detected
Packaging⚠️ -1packaging workflow not detected
CII-Best-Practices⚠️ 0no effort to earn an OpenSSF best practices badge detected
Token-Permissions⚠️ 0detected GitHub workflow tokens with excessive permissions
Pinned-Dependencies⚠️ 1dependency not pinned by hash detected -- score normalized to 1
Fuzzing⚠️ 0project is not fuzzed
License🟢 10license file detected
Signed-Releases⚠️ -1no releases found
Security-Policy🟢 9security policy file detected
Branch-Protection⚠️ 0branch protection not enabled on development/release branches
SAST🟢 10SAST tool is run on all commits
npm/commander ^14.0.3 UnknownUnknown
npm/esbuild ^0.27.3 UnknownUnknown
npm/postject ^1.0.0-alpha.6 UnknownUnknown

Scanned Files

  • .github/workflows/sea-build-sign.yml
  • package.json

@sonarqubecloud
Copy link
Copy Markdown

❌ The last analysis has failed.

See analysis details on SonarQube Cloud

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds a cross-platform build/signing workflow for distributing VIP CLI as a Node SEA (single executable), introduces a small SEA runtime filesystem/bootstrap layer for dependencies/assets, and migrates the CLI parser from args to a Commander-backed compatibility wrapper.

Changes:

  • Add SEA build tooling (helpers/build-sea.js), runtime bootstrap/dispatch code, and a GitHub Actions workflow to build/sign/upload SEA artifacts.
  • Migrate CLI parsing from args to a Commander-based compatibility wrapper while preserving existing command(opts).option(...).argv(...) call sites.
  • Update dev-env/Lando integration to support SEA runtime dependency resolution and improve startup/readiness checks.

Reviewed changes

Copilot reviewed 19 out of 23 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
.github/workflows/sea-build-sign.yml New workflow to build SEA artifacts on macOS/Linux/Windows + WSL and optionally sign them.
helpers/build-sea.js New Node 22 SEA bundling + blob injection script (esbuild + postject) and embeds runtime assets.
src/lib/dev-environment/lando-loader.ts New helper to require() Lando from SEA runtime filesystem when present.
src/lib/dev-environment/dev-environment-lando.ts Switch Lando imports to runtime-loading + add runtime mode info to logging banner.
src/lib/dev-environment/dev-environment-core.ts Load lando/lib/utils via runtime loader; add SEA asset template rendering + readiness polling on start.
src/lib/dev-environment/dev-environment-cli.ts Load Lando formatters through runtime loader to support SEA packaging.
src/lib/cli/sea-runtime.js New SEA bootstrap to extract embedded node_modules archive and adjust module resolution.
src/lib/cli/sea-dispatch.js New argv-to-internal-bin resolver/rewriter for SEA single-binary dispatch.
src/lib/cli/runtime-mode.ts New helper to detect/label SEA vs node-script runtime.
src/lib/cli/internal-bin-loader.js New dynamic loader for internal bins in SEA mode.
src/lib/cli/exit.ts Include runtime mode in debug footer output.
src/lib/cli/config.ts Fallback to bundled publish config when SEA build lacks on-disk config files.
src/lib/cli/command.js Replace args with Commander-backed compatibility wrapper + SEA-aware subcommand dispatch.
src/commands/dev-env-sync-sql.ts Convert Lando import to type-only.
src/bin/vip.js Add SEA target-bin execution path and refactor login flow into a helper.
src/bin/vip-sea.js New SEA entrypoint that prepares runtime filesystem then loads the main CLI.
src/bin/vip-dev-env-exec.js Add bounded readiness polling before treating env as down.
package.json Add build:sea, add commander, esbuild, postject, remove args, fix prettier glob.
npm-shrinkwrap.json Lockfile updates reflecting dependency changes for Commander/SEA tooling.
docs/SEA-BUILD-SIGNING.md New runbook for SEA build/signing across platforms and CI workflow notes.
docs/COMMANDER-MIGRATION.md New migration notes, preserved behaviors, and follow-up work items.
CLAUDE.md Link to SEA build/signing runbook.
AGENTS.md Add SEA packaging notes and pitfalls for future contributors/agents.
Files not reviewed (1)
  • npm-shrinkwrap.json: Language not supported

Comment on lines +151 to +155
if ( sea?.isSea?.() && sea.getAsset ) {
const template = sea.getAsset( assetKey, 'utf8' );
if ( typeof template === 'string' ) {
return ejs.render( template, templateData );
}
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

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

renderTemplateFile() treats SEA assets as usable only when sea.getAsset() returns a string, but your SeaModule type allows ArrayBuffer. If getAsset() returns an ArrayBuffer here, the code falls back to ejs.renderFile(filePath), which will fail in SEA when templates aren’t on disk. Convert ArrayBuffer/Buffer to a UTF-8 string and render it instead.

Copilot uses AI. Check for mistakes.
Comment thread src/lib/cli/command.js
const childScriptPath = extension
? `${ baseScriptPath }-${ subcommand }${ extension }`
: `${ baseScriptPath }-${ subcommand }`;
const aliasFromRawArgv = argv.slice( 2 ).find( arg => isAlias( arg ) );
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

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

executeSubcommand() searches for an env alias with argv.slice(2).find(isAlias) without respecting the -- boundary. This differs from parseEnvAliasFromArgv() (which ignores aliases after --) and can incorrectly treat positional args like -- ... @foo as an alias. Limit the alias search to args before -- when constructing childArgs.

Suggested change
const aliasFromRawArgv = argv.slice( 2 ).find( arg => isAlias( arg ) );
const doubleDashIndex = argv.indexOf( '--' );
const rawArgsBeforeDoubleDash =
doubleDashIndex === -1 ? argv.slice( 2 ) : argv.slice( 2, doubleDashIndex );
const aliasFromRawArgv = rawArgsBeforeDoubleDash.find( arg => isAlias( arg ) );

Copilot uses AI. Check for mistakes.
Comment thread src/lib/cli/command.js
Comment on lines +110 to +114

let flags = `--${ normalizedLongName }`;
if ( usesOptionalValue ) {
flags += ' [value]';
}
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

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

Non-boolean options are defined as --name [value] (optional value). In Commander, passing the flag without a value sets the option to true, which can leak into downstream logic (e.g. --format becomes boolean and isn’t currently validated). Use a required value (<value>) for non-boolean options (matching historical args behavior) and/or add validation for opts.format similar to opts.app/opts.env.

Copilot uses AI. Check for mistakes.
Comment on lines +2 to +62
vip: () => import( '../../bin/vip' ),
'vip-app': () => import( '../../bin/vip-app' ),
'vip-app-deploy': () => import( '../../bin/vip-app-deploy' ),
'vip-app-deploy-validate': () => import( '../../bin/vip-app-deploy-validate' ),
'vip-app-list': () => import( '../../bin/vip-app-list' ),
'vip-backup': () => import( '../../bin/vip-backup' ),
'vip-backup-db': () => import( '../../bin/vip-backup-db' ),
'vip-cache': () => import( '../../bin/vip-cache' ),
'vip-cache-purge-url': () => import( '../../bin/vip-cache-purge-url' ),
'vip-config': () => import( '../../bin/vip-config' ),
'vip-config-envvar': () => import( '../../bin/vip-config-envvar' ),
'vip-config-envvar-delete': () => import( '../../bin/vip-config-envvar-delete' ),
'vip-config-envvar-get': () => import( '../../bin/vip-config-envvar-get' ),
'vip-config-envvar-get-all': () => import( '../../bin/vip-config-envvar-get-all' ),
'vip-config-envvar-list': () => import( '../../bin/vip-config-envvar-list' ),
'vip-config-envvar-set': () => import( '../../bin/vip-config-envvar-set' ),
'vip-config-software': () => import( '../../bin/vip-config-software' ),
'vip-config-software-get': () => import( '../../bin/vip-config-software-get' ),
'vip-config-software-update': () => import( '../../bin/vip-config-software-update' ),
'vip-db': () => import( '../../bin/vip-db' ),
'vip-db-phpmyadmin': () => import( '../../bin/vip-db-phpmyadmin' ),
'vip-dev-env': () => import( '../../bin/vip-dev-env' ),
'vip-dev-env-create': () => import( '../../bin/vip-dev-env-create' ),
'vip-dev-env-destroy': () => import( '../../bin/vip-dev-env-destroy' ),
'vip-dev-env-envvar': () => import( '../../bin/vip-dev-env-envvar' ),
'vip-dev-env-envvar-delete': () => import( '../../bin/vip-dev-env-envvar-delete' ),
'vip-dev-env-envvar-get': () => import( '../../bin/vip-dev-env-envvar-get' ),
'vip-dev-env-envvar-get-all': () => import( '../../bin/vip-dev-env-envvar-get-all' ),
'vip-dev-env-envvar-list': () => import( '../../bin/vip-dev-env-envvar-list' ),
'vip-dev-env-envvar-set': () => import( '../../bin/vip-dev-env-envvar-set' ),
'vip-dev-env-exec': () => import( '../../bin/vip-dev-env-exec' ),
'vip-dev-env-import': () => import( '../../bin/vip-dev-env-import' ),
'vip-dev-env-import-media': () => import( '../../bin/vip-dev-env-import-media' ),
'vip-dev-env-import-sql': () => import( '../../bin/vip-dev-env-import-sql' ),
'vip-dev-env-info': () => import( '../../bin/vip-dev-env-info' ),
'vip-dev-env-list': () => import( '../../bin/vip-dev-env-list' ),
'vip-dev-env-logs': () => import( '../../bin/vip-dev-env-logs' ),
'vip-dev-env-purge': () => import( '../../bin/vip-dev-env-purge' ),
'vip-dev-env-shell': () => import( '../../bin/vip-dev-env-shell' ),
'vip-dev-env-start': () => import( '../../bin/vip-dev-env-start' ),
'vip-dev-env-stop': () => import( '../../bin/vip-dev-env-stop' ),
'vip-dev-env-sync': () => import( '../../bin/vip-dev-env-sync' ),
'vip-dev-env-sync-sql': () => import( '../../bin/vip-dev-env-sync-sql' ),
'vip-dev-env-update': () => import( '../../bin/vip-dev-env-update' ),
'vip-export': () => import( '../../bin/vip-export' ),
'vip-export-sql': () => import( '../../bin/vip-export-sql' ),
'vip-import': () => import( '../../bin/vip-import' ),
'vip-import-media': () => import( '../../bin/vip-import-media' ),
'vip-import-media-abort': () => import( '../../bin/vip-import-media-abort' ),
'vip-import-media-status': () => import( '../../bin/vip-import-media-status' ),
'vip-import-sql': () => import( '../../bin/vip-import-sql' ),
'vip-import-sql-status': () => import( '../../bin/vip-import-sql-status' ),
'vip-import-validate-files': () => import( '../../bin/vip-import-validate-files' ),
'vip-import-validate-sql': () => import( '../../bin/vip-import-validate-sql' ),
'vip-logout': () => import( '../../bin/vip-logout' ),
'vip-logs': () => import( '../../bin/vip-logs' ),
'vip-search-replace': () => import( '../../bin/vip-search-replace' ),
'vip-slowlogs': () => import( '../../bin/vip-slowlogs' ),
'vip-sync': () => import( '../../bin/vip-sync' ),
'vip-whoami': () => import( '../../bin/vip-whoami' ),
'vip-wp': () => import( '../../bin/vip-wp' ),
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

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

internal-bin-loader uses relative dynamic imports without file extensions (e.g. import('../../bin/vip')). Node’s import() uses ESM-style resolution for relative specifiers, which typically requires explicit extensions; this can break if this codepath is ever executed outside the esbuild-bundled SEA context. Consider adding explicit .js extensions (or using new URL(..., import.meta.url)) to make the loader robust in plain Node execution too.

Suggested change
vip: () => import( '../../bin/vip' ),
'vip-app': () => import( '../../bin/vip-app' ),
'vip-app-deploy': () => import( '../../bin/vip-app-deploy' ),
'vip-app-deploy-validate': () => import( '../../bin/vip-app-deploy-validate' ),
'vip-app-list': () => import( '../../bin/vip-app-list' ),
'vip-backup': () => import( '../../bin/vip-backup' ),
'vip-backup-db': () => import( '../../bin/vip-backup-db' ),
'vip-cache': () => import( '../../bin/vip-cache' ),
'vip-cache-purge-url': () => import( '../../bin/vip-cache-purge-url' ),
'vip-config': () => import( '../../bin/vip-config' ),
'vip-config-envvar': () => import( '../../bin/vip-config-envvar' ),
'vip-config-envvar-delete': () => import( '../../bin/vip-config-envvar-delete' ),
'vip-config-envvar-get': () => import( '../../bin/vip-config-envvar-get' ),
'vip-config-envvar-get-all': () => import( '../../bin/vip-config-envvar-get-all' ),
'vip-config-envvar-list': () => import( '../../bin/vip-config-envvar-list' ),
'vip-config-envvar-set': () => import( '../../bin/vip-config-envvar-set' ),
'vip-config-software': () => import( '../../bin/vip-config-software' ),
'vip-config-software-get': () => import( '../../bin/vip-config-software-get' ),
'vip-config-software-update': () => import( '../../bin/vip-config-software-update' ),
'vip-db': () => import( '../../bin/vip-db' ),
'vip-db-phpmyadmin': () => import( '../../bin/vip-db-phpmyadmin' ),
'vip-dev-env': () => import( '../../bin/vip-dev-env' ),
'vip-dev-env-create': () => import( '../../bin/vip-dev-env-create' ),
'vip-dev-env-destroy': () => import( '../../bin/vip-dev-env-destroy' ),
'vip-dev-env-envvar': () => import( '../../bin/vip-dev-env-envvar' ),
'vip-dev-env-envvar-delete': () => import( '../../bin/vip-dev-env-envvar-delete' ),
'vip-dev-env-envvar-get': () => import( '../../bin/vip-dev-env-envvar-get' ),
'vip-dev-env-envvar-get-all': () => import( '../../bin/vip-dev-env-envvar-get-all' ),
'vip-dev-env-envvar-list': () => import( '../../bin/vip-dev-env-envvar-list' ),
'vip-dev-env-envvar-set': () => import( '../../bin/vip-dev-env-envvar-set' ),
'vip-dev-env-exec': () => import( '../../bin/vip-dev-env-exec' ),
'vip-dev-env-import': () => import( '../../bin/vip-dev-env-import' ),
'vip-dev-env-import-media': () => import( '../../bin/vip-dev-env-import-media' ),
'vip-dev-env-import-sql': () => import( '../../bin/vip-dev-env-import-sql' ),
'vip-dev-env-info': () => import( '../../bin/vip-dev-env-info' ),
'vip-dev-env-list': () => import( '../../bin/vip-dev-env-list' ),
'vip-dev-env-logs': () => import( '../../bin/vip-dev-env-logs' ),
'vip-dev-env-purge': () => import( '../../bin/vip-dev-env-purge' ),
'vip-dev-env-shell': () => import( '../../bin/vip-dev-env-shell' ),
'vip-dev-env-start': () => import( '../../bin/vip-dev-env-start' ),
'vip-dev-env-stop': () => import( '../../bin/vip-dev-env-stop' ),
'vip-dev-env-sync': () => import( '../../bin/vip-dev-env-sync' ),
'vip-dev-env-sync-sql': () => import( '../../bin/vip-dev-env-sync-sql' ),
'vip-dev-env-update': () => import( '../../bin/vip-dev-env-update' ),
'vip-export': () => import( '../../bin/vip-export' ),
'vip-export-sql': () => import( '../../bin/vip-export-sql' ),
'vip-import': () => import( '../../bin/vip-import' ),
'vip-import-media': () => import( '../../bin/vip-import-media' ),
'vip-import-media-abort': () => import( '../../bin/vip-import-media-abort' ),
'vip-import-media-status': () => import( '../../bin/vip-import-media-status' ),
'vip-import-sql': () => import( '../../bin/vip-import-sql' ),
'vip-import-sql-status': () => import( '../../bin/vip-import-sql-status' ),
'vip-import-validate-files': () => import( '../../bin/vip-import-validate-files' ),
'vip-import-validate-sql': () => import( '../../bin/vip-import-validate-sql' ),
'vip-logout': () => import( '../../bin/vip-logout' ),
'vip-logs': () => import( '../../bin/vip-logs' ),
'vip-search-replace': () => import( '../../bin/vip-search-replace' ),
'vip-slowlogs': () => import( '../../bin/vip-slowlogs' ),
'vip-sync': () => import( '../../bin/vip-sync' ),
'vip-whoami': () => import( '../../bin/vip-whoami' ),
'vip-wp': () => import( '../../bin/vip-wp' ),
vip: () => import( '../../bin/vip.js' ),
'vip-app': () => import( '../../bin/vip-app.js' ),
'vip-app-deploy': () => import( '../../bin/vip-app-deploy.js' ),
'vip-app-deploy-validate': () => import( '../../bin/vip-app-deploy-validate.js' ),
'vip-app-list': () => import( '../../bin/vip-app-list.js' ),
'vip-backup': () => import( '../../bin/vip-backup.js' ),
'vip-backup-db': () => import( '../../bin/vip-backup-db.js' ),
'vip-cache': () => import( '../../bin/vip-cache.js' ),
'vip-cache-purge-url': () => import( '../../bin/vip-cache-purge-url.js' ),
'vip-config': () => import( '../../bin/vip-config.js' ),
'vip-config-envvar': () => import( '../../bin/vip-config-envvar.js' ),
'vip-config-envvar-delete': () => import( '../../bin/vip-config-envvar-delete.js' ),
'vip-config-envvar-get': () => import( '../../bin/vip-config-envvar-get.js' ),
'vip-config-envvar-get-all': () => import( '../../bin/vip-config-envvar-get-all.js' ),
'vip-config-envvar-list': () => import( '../../bin/vip-config-envvar-list.js' ),
'vip-config-envvar-set': () => import( '../../bin/vip-config-envvar-set.js' ),
'vip-config-software': () => import( '../../bin/vip-config-software.js' ),
'vip-config-software-get': () => import( '../../bin/vip-config-software-get.js' ),
'vip-config-software-update': () => import( '../../bin/vip-config-software-update.js' ),
'vip-db': () => import( '../../bin/vip-db.js' ),
'vip-db-phpmyadmin': () => import( '../../bin/vip-db-phpmyadmin.js' ),
'vip-dev-env': () => import( '../../bin/vip-dev-env.js' ),
'vip-dev-env-create': () => import( '../../bin/vip-dev-env-create.js' ),
'vip-dev-env-destroy': () => import( '../../bin/vip-dev-env-destroy.js' ),
'vip-dev-env-envvar': () => import( '../../bin/vip-dev-env-envvar.js' ),
'vip-dev-env-envvar-delete': () => import( '../../bin/vip-dev-env-envvar-delete.js' ),
'vip-dev-env-envvar-get': () => import( '../../bin/vip-dev-env-envvar-get.js' ),
'vip-dev-env-envvar-get-all': () => import( '../../bin/vip-dev-env-envvar-get-all.js' ),
'vip-dev-env-envvar-list': () => import( '../../bin/vip-dev-env-envvar-list.js' ),
'vip-dev-env-envvar-set': () => import( '../../bin/vip-dev-env-envvar-set.js' ),
'vip-dev-env-exec': () => import( '../../bin/vip-dev-env-exec.js' ),
'vip-dev-env-import': () => import( '../../bin/vip-dev-env-import.js' ),
'vip-dev-env-import-media': () => import( '../../bin/vip-dev-env-import-media.js' ),
'vip-dev-env-import-sql': () => import( '../../bin/vip-dev-env-import-sql.js' ),
'vip-dev-env-info': () => import( '../../bin/vip-dev-env-info.js' ),
'vip-dev-env-list': () => import( '../../bin/vip-dev-env-list.js' ),
'vip-dev-env-logs': () => import( '../../bin/vip-dev-env-logs.js' ),
'vip-dev-env-purge': () => import( '../../bin/vip-dev-env-purge.js' ),
'vip-dev-env-shell': () => import( '../../bin/vip-dev-env-shell.js' ),
'vip-dev-env-start': () => import( '../../bin/vip-dev-env-start.js' ),
'vip-dev-env-stop': () => import( '../../bin/vip-dev-env-stop.js' ),
'vip-dev-env-sync': () => import( '../../bin/vip-dev-env-sync.js' ),
'vip-dev-env-sync-sql': () => import( '../../bin/vip-dev-env-sync-sql.js' ),
'vip-dev-env-update': () => import( '../../bin/vip-dev-env-update.js' ),
'vip-export': () => import( '../../bin/vip-export.js' ),
'vip-export-sql': () => import( '../../bin/vip-export-sql.js' ),
'vip-import': () => import( '../../bin/vip-import.js' ),
'vip-import-media': () => import( '../../bin/vip-import-media.js' ),
'vip-import-media-abort': () => import( '../../bin/vip-import-media-abort.js' ),
'vip-import-media-status': () => import( '../../bin/vip-import-media-status.js' ),
'vip-import-sql': () => import( '../../bin/vip-import-sql.js' ),
'vip-import-sql-status': () => import( '../../bin/vip-import-sql-status.js' ),
'vip-import-validate-files': () => import( '../../bin/vip-import-validate-files.js' ),
'vip-import-validate-sql': () => import( '../../bin/vip-import-validate-sql.js' ),
'vip-logout': () => import( '../../bin/vip-logout.js' ),
'vip-logs': () => import( '../../bin/vip-logs.js' ),
'vip-search-replace': () => import( '../../bin/vip-search-replace.js' ),
'vip-slowlogs': () => import( '../../bin/vip-slowlogs.js' ),
'vip-sync': () => import( '../../bin/vip-sync.js' ),
'vip-whoami': () => import( '../../bin/vip-whoami.js' ),
'vip-wp': () => import( '../../bin/vip-wp.js' ),

Copilot uses AI. Check for mistakes.
Comment on lines +75 to +79
if ( ! existsSync( runtimeReadyPath ) || ! existsSync( runtimeNodeModulesPath ) ) {
const archiveAsset = sea.getAsset( RUNTIME_ARCHIVE_KEY );
const archiveBuffer = Buffer.isBuffer( archiveAsset )
? archiveAsset
: Buffer.from( archiveAsset );
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

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

SEA runtime extraction wires a user-writable node_modules directory into module resolution (NODE_PATH) based only on existence checks. A tampered runtime directory could cause the SEA executable to load attacker-controlled JS. Consider validating .ready contents and verifying an embedded checksum/signature for the archive (and/or using atomic extraction + restrictive permissions) before trusting the extracted directory.

Copilot uses AI. Check for mistakes.
Comment thread src/lib/cli/command.js
Comment on lines +128 to +132
class CommanderArgsCompat {
constructor( opts ) {
this.details = {
commands: [],
};
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

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

There are existing unit tests for src/lib/cli/command.js, but the new Commander compatibility layer isn’t covered. Add tests around option parsing, alias handling with --, and subcommand dispatch to prevent regressions in the args -> commander migration.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants