use commander js classes for base44 commands#420
Conversation
🚀 Package Preview Available!Install this PR's preview build with npm: npm i @base44-preview/cli@0.0.45-pr.420.1329187Prefer not to change any import paths? Install using npm alias so your code still imports npm i "base44@npm:@base44-preview/cli@0.0.45-pr.420.1329187"Or add it to your {
"dependencies": {
"base44": "npm:@base44-preview/cli@0.0.45-pr.420.1329187"
}
}
Preview published to npm registry — try new features instantly! |
|
@claude please go over and review this PR, it's a big infra change. try to see if you can find any backward issues or bugs that might arise |
|
Claude finished @kfirstri's task in 6m 37s —— View job PR Review: Commander.js Class Architecture RefactorTasks:
OverviewThis is a clean, well-executed refactoring. The core architecture change — moving from No critical regressions found. A few medium and minor issues below. Issues Found🟠 Medium:
|
| Behavior | Old (runCommand) |
New (Base44Command) |
|---|---|---|
requireAuth default |
false |
true |
requireAppConfig default |
true |
true |
intro() in non-interactive |
Always called | Skipped |
| Upgrade notification in CI | Written via clack note() to stdout |
Written via process.stderr.write |
All existing commands were updated to pass explicit options where old defaults differed. The audit looks complete — login, logout, whoami, create, link, eject all correctly opt out of requireAppConfig: false and/or requireAuth: false where needed.
Test Notes
The version-check test change ("Update available!" → "Update available") is correct. Tests run with CI=true, so the new non-interactive code path fires formatPlainUpgradeMessage() → "Update available: x → y" written to stderr. CLIResultMatcher.toContain() checks stdout + stderr combined, so the test works.
Architecture: No Issues Found
- The
program.hook("preAction", ...)correctly injects context into nestedBase44Commandinstances (Commander fires the rootpreActionfor all nested subcommands withactionCommandpointing to the deepest matching command). - Error re-throws are intentional and consistent with the old code —
index.ts:runCLIhandlesCLIExitErrorvs other errors for the final exit code. Base44Command.action()wrapping is lazy (readsthis.contextat execution time, not registration time), so command construction increateProgram()before the preAction hook runs is safe.- Plain
Commandgroup containers (getAgentsCommand,getConnectorsCommand, etc.) don't needBase44Commandsince they have no actions.
Adapt exec.ts to use the new Base44Command class introduced in main (#420) instead of the removed runCommand utility. Made-with: Cursor
Note
Description
This PR refactors the CLI command architecture by replacing the
runCommand()higher-order function pattern with aBase44Commandclass that extends Commander.js'sCommand. The new approach moves the lifecycle logic (intro/outro, auth check, app config loading, error handling, non-interactive mode) into an OOP-based command wrapper, making command definitions cleaner and eliminating the need to passCLIContextexplicitly to every command factory. TheCLIContextis now injected once via apreActionhook increateProgram().Related Issue
None
Type of Change
Changes Made
Base44Commandclass (packages/cli/src/cli/utils/command/Base44Command.ts) that wraps command actions with the full Base44 lifecycle (intro/outro, auth, app config, error handling, upgrade notification)command/render.ts(showCommandStart,showCommandEnd,showThemedError,showPlainError) and middleware intocommand/middleware.ts(ensureAuth,ensureAppConfig)runCommand.tsand migrated all ~30 command files from therunCommand()HOF pattern tonew Base44Command(name, options).action(...)preActionhook increateProgram(), removing theCLIContextparameter from all command factory functionsRunCommandResulttype fromrunCommand.tstocli/types.tsfor shared accessformatPlainUpgradeMessage()toupgradeNotification.tsfor proper CI/non-interactive upgrade notices written to stderrcreate,deploy,eject,link, andsite deploycommandsdocs/commands.mdto document the newBase44CommandpatternTesting
npm test)Checklist
docs/(AGENTS.md) if I made architectural changesAdditional Notes
The
Base44Commandconstructor defaults are:requireAuth: true,requireAppConfig: true,fullBanner: false— matching the most common command profile. Commands likeloginthat skip auth/config pass explicit overrides. Non-interactive mode (CI/piped output) skips all clack UI and writes errors to stderr as plain text; upgrade notifications also go to stderr in that mode.🤖 Generated by Claude | 2026-03-17 00:00 UTC