Skip to content

Conversation

@kfirstri
Copy link
Contributor

No description provided.

@kfirstri kfirstri self-assigned this Jan 11, 2026
@github-project-automation github-project-automation bot moved this to Backlog in Dev Jan 11, 2026
@github-actions
Copy link
Contributor

github-actions bot commented Jan 11, 2026

🚀 Package Preview Available!


Install this PR's preview build with npm:

npm i @base44-preview/cli@0.0.1-pr.14.3c9bc6f

Prefer not to change any import paths? Install using npm alias so your code still imports base44:

npm i "base44@npm:@base44-preview/cli@0.0.1-pr.14.3c9bc6f"

Or add it to your package.json dependencies:

{
  "dependencies": {
    "base44": "npm:@base44-preview/cli@0.0.1-pr.14.3c9bc6f"
  }
}

Preview published to npm registry — try new features instantly!

@claude
Copy link

claude bot commented Jan 11, 2026

Pull Request Review: Add Create App Command

Summary

This PR adds a new init (alias: create) command to initialize Base44 projects. The implementation creates project structure, config files, and .env.local with the project ID from the API.

🟢 Strengths

Good Architecture

  • Clean separation of concerns: CLI layer (init.ts) → Core logic (init.ts) → API (api.ts)
  • Type safety: Proper TypeScript interfaces and Zod schemas for validation
  • Reusable utilities: New textPrompt and printBanner utilities follow existing patterns
  • Template-based generation: Using EJS templates for config files is maintainable

Code Quality

  • Error handling matches existing patterns (try/catch with proper error messages)
  • Consistent use of existing utilities (runTask, runCommand)
  • Good UX with clear prompts and success messages
  • Proper file/directory checks before creation

🟡 Issues & Concerns

1. CRITICAL: Broken Test Import ⚠️

tests/core/project.test.ts:2 still imports from the old path:

import { readProjectConfig } from "../../src/core/config/project.js";

Should be:

import { readProjectConfig } from "../../src/core/project/config.js";

This will cause test failures and needs to be fixed.

2. Code Duplication: Templates Directory 🔴

Templates exist in two locations:

  • src/core/project/templates/
  • templates/ (root)

The root templates/ directory appears to be duplicated and unused. The tsdown.config.mjs correctly copies from src/core/project/templates, so the root templates should be removed to avoid confusion and maintenance burden.

3. Missing Error Handling in getBase44ClientId() ⚠️

In src/core/utils/httpClient.ts:80, getBase44ClientId() can return undefined, but it's used directly in a template string:

prefixUrl: new URL(`/api/apps/${getBase44ClientId()}/`, getBase44ApiUrl()).href,

This will create an invalid URL like /api/apps/undefined/ if BASE44_CLIENT_ID is not set. The old getAppId() threw an error when the env var wasn't set, which was safer. Consider:

  • Throwing an error in getAppClient() if the client ID is undefined
  • Or documenting that commands requiring the app client must check for project context first

4. Template Path Assumptions

src/core/project/templates/index.ts:7-8 assumes templates are at __dirname/templates after bundling:

const __dirname = dirname(fileURLToPath(import.meta.url));
const TEMPLATES_DIR = join(__dirname, "templates");

This relies on tsdown copying files correctly. Consider:

  • Adding a runtime check that template files exist (with a helpful error if missing)
  • Or documenting this assumption in a comment

5. Missing Newline at End of File

src/cli/utils/index.ts:4 and src/core/project/index.ts:5 are missing trailing newlines (per convention in other files).

6. API Error Response Type Safety

src/core/project/api.ts:8 defaults description to a template string:

user_description: description ?? `Backend for '${projectName}'`,

While this works, consider if the API actually needs a description or if it's optional. If optional, it might be cleaner to omit it entirely when not provided rather than generating a synthetic one.

7. Inconsistent Error Messages

src/core/resources/entity/api.ts:23 has a misleading error message:

throw new Error(`Failed to delete entity: ${errorJson.message}`);

This is in pushEntities, not a delete operation. (Note: This is pre-existing, but surfaced during review)

🔵 Suggestions

Test Coverage

No tests were added for the new init functionality. Consider adding:

  • Unit tests for initProject() function
  • Tests for template rendering
  • Tests for error cases (project already exists, API failures, etc.)
  • Integration test for the full command flow

Security & Validation

  • ✅ Input validation is present (empty name check)
  • ✅ Path resolution is safe (using resolve())
  • ⚠️ Consider validating project name format (alphanumeric, hyphens, etc.) to avoid filesystem issues
  • ⚠️ The .env.local file contains sensitive data (BASE44_CLIENT_ID) - ensure documentation warns against committing it (the template has a comment, which is good)

Performance

No concerns - all operations are appropriately async and will be fast for typical use cases.

UX Improvements

  • The default path is ./ which will create ./base44/ - this is reasonable
  • Consider adding a --yes/-y flag to skip prompts for CI/automation scenarios
  • The banner is a nice touch! 🎨

📋 Action Items

Must Fix Before Merge:

  1. ❗ Update test import in tests/core/project.test.ts
  2. ❗ Remove duplicate templates/ directory from root
  3. ❗ Add error handling for undefined BASE44_CLIENT_ID in getAppClient()

Should Fix:
4. Add trailing newlines to src/cli/utils/index.ts and src/core/project/index.ts
5. Add tests for new init functionality

Nice to Have:
6. Validate project name format
7. Add runtime check for template file existence
8. Consider adding --yes flag for non-interactive mode

Verdict

This is a solid feature implementation with good code organization. However, there are critical issues (broken test import, duplicate templates, missing error handling) that must be addressed before merging. Once these are fixed, this will be a great addition to the CLI.


Review performed by Claude Code

@claude
Copy link

claude bot commented Jan 11, 2026

Pull Request Review: feat(create-app) - Add create app command

Thank you for this contribution! Overall, this is a well-structured implementation with good separation of concerns.

✅ Strengths

  1. Clean architecture with good separation between CLI and core logic
  2. Interactive prompts with validation and helpful error messages
  3. Proper refactoring of consts.ts to config.ts
  4. EJS templates provide flexible file generation
  5. Good error handling throughout

🐛 Critical Issues

1. Inconsistent .env.local location (src/core/project/init.ts:32)

  • Creates .env.local inside base44/ subdirectory
  • But loadProjectEnv() looks for it at project root
  • FIX: Place .env.local at project root, not inside base44/

2. getBase44ClientId() validation missing (src/core/utils/httpClient.ts:80)

  • If getBase44ClientId() returns undefined, creates URL like /api/apps/undefined/
  • FIX: Add validation to throw error if client ID not set

3. Duplicate template files

  • Templates exist in both templates/ (root) and src/core/project/templates/
  • Only src/core/project/templates is copied per tsdown.config.mjs
  • FIX: Remove duplicate templates/ directory at project root

4. Template path resolution (src/core/project/templates/index.ts:7-8)

  • After bundling, templates directory structure might not match expectations
  • FIX: Verify template paths work after bundling, add error handling

🐛 Moderate Issues

  1. Missing newlines at end of files (src/cli/utils/index.ts:4, src/core/index.ts:6, src/core/project/index.ts:5)
  2. Empty description handling - textPrompt can return empty string
  3. Circular dependency workaround with dynamic import in loadProjectEnv()

🔒 Security Concerns (Low Risk)

  • Environment variables in plaintext (acceptable for this use case, good warning in template)
  • User input passed to API without sanitization (API should validate)
  • Full file paths in error messages (consider using relative paths)

⚡ Performance

  • Glob search across patterns - acceptable for typical use
  • Synchronous dotenv loading - unlikely to be an issue
  • Template rendering - negligible for 2 files

🧪 Test Coverage

NO TESTS for new functionality:

  • src/cli/commands/project/init.ts
  • src/core/project/init.ts
  • src/core/project/api.ts
  • Template rendering functions

Recommended: Add tests for project creation, existing project detection, template rendering, error handling, and path resolution.

📋 Code Quality Suggestions

  • Extract magic string baas to constant
  • Add try-catch for template rendering
  • Document looseObject usage in schema
  • Extract banner color to shared constant
  • Ensure all callers handle getBase44ClientId() returning undefined

📦 Dependencies

All appropriate: dotenv@17.2.3, ejs@3.1.10, @types/ejs@3.1.5

🎯 Summary: Approve with Changes Requested

Must fix before merge:

  1. Fix .env.local location mismatch
  2. Add getBase44ClientId() validation in getAppClient()
  3. Remove duplicate template files
  4. Verify template path resolution after bundling

Should fix:
5. Add test coverage
6. Add missing newlines
7. Handle empty descriptions
8. Add template rendering error handling

Great work! Once critical issues are addressed, this will be a solid addition. 🚀

@claude
Copy link

claude bot commented Jan 11, 2026

Pull Request Review: Create App Command

This PR adds a 'base44 init' command to initialize new Base44 projects. The implementation is generally solid with good separation of concerns.

Strengths

  1. Good separation of concerns: CLI layer cleanly separated from core logic
  2. Proper error handling with try-catch blocks and runTask wrapper
  3. Interactive prompts with validation, helpful banner, and clear success messages
  4. Smart refactoring of consts.ts into config.ts with environment variable support
  5. Good use of EJS templates with proper bundling configuration

CRITICAL: Template Path Resolution Issue

Location: src/core/project/templates/index.ts:5-8

After bundling, import.meta.url points to the bundled output, but templates are copied to dist/cli/templates/. The path resolution assumes templates are in a templates/ subdirectory relative to the module location, which may not match the actual bundled structure. This will cause template rendering to FAIL at runtime.

Recommendation: Verify the actual bundled structure and test template resolution. Consider using explicit paths based on the known bundle structure.

Minor Issues

  1. Empty description handling (init.ts:26-28): textPrompt returns empty string, not undefined, when user presses Enter. This gets sent to API instead of being omitted. Add: 'description: description && description.trim() ? description.trim() : undefined'

  2. Missing error context (project/api.ts:4): No try-catch around API call. Add contextual error wrapping.

  3. Missing return type annotation on createProject function

  4. Missing newline at end of src/core/index.ts

Security Concerns

  1. .env.local created inside base44/ subdirectory. Users may not have base44/.env.local in gitignore and could accidentally commit sensitive data. Consider creating in project root or auto-generating .gitignore.

  2. loadProjectEnv() called for ALL commands including init (where no env exists yet). Safe but confusing - needs better documentation.

Test Coverage

Missing tests for new initProject() function. Need tests for:

  • Project already exists scenario
  • API failure scenarios
  • File system permission errors
  • Invalid project names
  • Template rendering failures

Recommendations Before Merge

  1. Fix/verify template path resolution (CRITICAL)
  2. Handle empty description input
  3. Add explicit return type to createProject()
  4. Add error context to API calls

Overall Assessment

Solid implementation following existing patterns. Main concern is template path resolution. Code is readable, well-structured, good UX. Rating: 7.5/10 (9/10 after fixing template path)


Review generated by Claude Code

@claude
Copy link

claude bot commented Jan 11, 2026

PR Review: feat(create-app): add a create app command to init a new base44 project

Overview

This PR adds a base44 init command to initialize new Base44 projects. The implementation creates project structure, makes an API call to register the project, and generates config files from templates. Overall, this is a solid foundation, but there are several issues that should be addressed.

Critical Issues

1. Breaking Change: Function Signature Change

Location: src/core/config.ts:61

The function getAppId() was renamed to getBase44ClientId() and the behavior changed:

  • Old: Throws error if BASE44_CLIENT_ID is not set
  • New: Returns undefined if not set

Location Affected: src/core/utils/httpClient.ts:80

Risk: If getBase44ClientId() returns undefined, the URL becomes /api/apps/undefined/, which will fail silently or with confusing errors.

Recommendation: Add explicit checks before using it in getAppClient().

2. .env.local Placement Inconsistency

Location: src/core/project/init.ts:32

The .env.local file is created inside the base44/ subdirectory but loadProjectEnv() looks for it at the project root (src/core/config.ts:44).

Risk: The created .env.local file will not be found by loadProjectEnv().

Recommendation: Clarify where .env.local should live and make it consistent.

3. Inconsistent Error Handling

Location: src/core/project/init.ts:40-44

The initProject function checks for existing projects before calling the API, but if the API call fails, no rollback occurs. This could leave the user in an inconsistent state.

Recommendation: Add error handling to rollback or provide clearer error messages.

Major Issues

4. Race Condition in loadProjectEnv

Location: src/core/config.ts:35-46

The function does not prevent multiple simultaneous calls. Add a guard variable to ensure it only loads once.

5. Missing Test Coverage

No tests were added for the new functionality. Recommend adding unit tests for initProject(), createProject(), template rendering, and error cases.

6. Missing Validation for Empty Description

Location: src/cli/commands/project/init.ts:26-29

The description prompt allows empty strings. Trim and convert empty strings to undefined.

Minor Issues

7. Security: Template Injection

Location: src/core/project/api.ts:8

The description parameter is interpolated directly without sanitization. Remove quotes from the template string.

8. Potential Path Traversal

Location: src/cli/commands/project/init.ts:39

Add validation to prevent creating projects in system directories.

9. Missing JSDoc

Add documentation for createProject(), renderConfigTemplate(), and renderEnvTemplate().

Positive Aspects

  • Good separation of concerns
  • Template-based approach is flexible and maintainable
  • Polished CLI experience with banner and prompts
  • Reusable textPrompt wrapper with cancellation handling
  • Good use of Zod schemas for API response validation
  • Logical code organization

Recommendations Summary

Must Fix (Before Merge):

  1. Fix breaking change in getBase44ClientId() / getAppClient()
  2. Fix .env.local placement inconsistency
  3. Add error handling for API failures

Should Fix:
4. Add test coverage
5. Add race condition guard for loadProjectEnv()
6. Validate and sanitize user inputs

Great work on this feature! The architecture is solid. Addressing the critical issues will make this ready to merge.

@claude
Copy link

claude bot commented Jan 11, 2026

Pull Request Review: feat(create-app): add a create app command to init a new base44 project

Summary

This PR adds a new base44 init (alias: create) command to bootstrap new Base44 projects. The implementation includes API integration, template-based file generation, and proper environment configuration. Overall, this is a solid addition with good structure, but there are several areas that need attention.

🐛 Critical Issues

1. Template Path Resolution Bug (High Priority)

Location: src/core/project/templates/index.ts:7-8

The template path resolution has a critical bug that will cause runtime failures after bundling. The templates are nested in src/core/project/templates/ but after bundling with tsdown to dist/cli/, the path resolution will break.

Recommendation: Either copy templates to dist/cli/templates/ or embed templates as string constants in the code to avoid path resolution issues.

2. Empty Description Handling

Location: src/cli/commands/project/init.ts:26-29

The textPrompt for description returns an empty string when the user skips, not undefined. This means an empty string gets passed to the API and template.

Recommendation: Add const description = descriptionInput.trim() || undefined; after the prompt.

3. Error Handling: API Call Before File System Operations

Location: src/core/project/init.ts:34-47

The code calls the API to create a project before writing files. If the file write fails after the API call succeeds, you've created an orphaned project on the server with no local configuration.

Recommendation: Add cleanup logic or transaction-like behavior to handle failures gracefully.


(Review continues in next comment...)

@claude
Copy link

claude bot commented Jan 11, 2026

⚠️ Security Concerns

4. EJS Template Injection Risk

Location: src/core/project/templates/config.jsonc.ejs:6-7

User input is directly interpolated into EJS templates without sanitization. If a user enters a project name or description containing double quotes or special characters, this could break the JSON or introduce injection issues.

Recommendation: Don't use EJS for generating JSON. Use JSON.stringify() which automatically handles escaping properly. This is both more secure and more reliable.

5. .env.local Not Added to .gitignore

Location: src/core/project/init.ts

The code creates .env.local with the BASE44_CLIENT_ID, but doesn't ensure this file is added to .gitignore. While the template comments warn about not committing sensitive data, users might accidentally commit this.

Recommendation: Add a .gitignore file to the base44 directory with .env.local in it, or check if a .gitignore exists in the parent and append to it.

@claude
Copy link

claude bot commented Jan 11, 2026

🔍 Code Quality Issues

6. Missing Error Context in fs.ts

Location: src/core/utils/fs.ts:21-30, 64-74, 76-81

The refactored writeFile, writeJsonFile, and deleteFile functions removed error handling that provided helpful context about which file operation failed. If these operations fail, debugging will be harder.

Recommendation: Restore the try-catch blocks with contextual error messages.

7. Redundant Error Handling

Location: src/cli/commands/project/init.ts:64-74

The init command has its own error handling that duplicates the error handling in runCommand. Looking at login.ts:117, other commands just use runCommand without additional try-catch.

Recommendation: Follow the pattern in login.ts and use runCommand(init) directly. However, note that init() already calls printBanner() and loadProjectEnv(), which are also called by runCommand() - you'll need to refactor to avoid duplication.

8. Inconsistent Banner Usage

Location: src/cli/commands/project/init.ts:10

The init function calls printBanner() directly, while runCommand() calls intro(). This creates inconsistency with other commands.

Recommendation: Either use runCommand() consistently and remove the manual printBanner() call, or add a parameter to runCommand() to skip the intro when you want a custom banner.

9. Circular Dependency Risk

Location: src/core/config.ts:4 imports from ./project/index.js, which exports from ./project/init.ts, which imports from ../config.js

This creates a circular dependency: config.tsproject/index.tsproject/init.tsconfig.ts

While this might work in practice due to how ES modules handle cycles, it's fragile and can cause initialization issues.

Recommendation: Move findProjectRoot to a separate utilities file or break the cycle by restructuring imports.

10. Missing Return Type on API Function

Location: src/core/project/api.ts:4

The createProject function should have an explicit return type: Promise<{ projectId: string }>

@claude
Copy link

claude bot commented Jan 11, 2026

📝 Minor Issues & Suggestions

11. Missing Tests

No tests were added for the new functionality. Consider adding tests for:

  • initProject() function with various inputs
  • Template rendering with special characters
  • Error cases (project already exists, API failures, file write failures)
  • Path resolution edge cases

12. Missing Newline at End of File

Location: src/core/index.ts:6 - Missing newline at end of file (minor style issue).

13. Success Message Uses Untrimmed Name

Location: src/cli/commands/project/init.ts:58

Uses name instead of name.trim(), which was passed to initProject. While the name is validated to not be empty after trimming, it's more consistent to use the trimmed version in the message too.

✅ What's Done Well

  1. Good separation of concerns: CLI layer, core logic, and API calls are well separated
  2. Template-based generation: Using EJS templates is a good approach (just needs sanitization fixes)
  3. Proper TypeScript types: Good use of interfaces for options and results
  4. Input validation: Name validation ensures non-empty values
  5. User experience: Clear prompts with placeholders and default values
  6. Documentation: Good JSDoc comments on functions
  7. Path resolution: Using resolve() to handle relative paths correctly

🧪 Test Coverage

Missing test coverage for the new functionality. Consider adding unit tests for initProject(), integration tests for the full command flow, and template rendering tests with edge cases.

Recommendation

Request Changes - The template path resolution bug (issue #1) is critical and will cause runtime failures after bundling. The security issues around template injection (issue #4) and missing .gitignore (issue #5) also need to be addressed before merging.


Happy to discuss any of these points or provide more specific code examples if helpful!

@kfirstri kfirstri merged commit e199c8e into main Jan 11, 2026
5 checks passed
@kfirstri kfirstri deleted the create-app branch January 11, 2026 15:48
@github-project-automation github-project-automation bot moved this from Backlog to Done in Dev Jan 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants