Skip to content

feat(create-app): Add protocol option and improve CLI scaffolding - #78

Merged
gabrypavanello merged 7 commits into
mainfrom
create-app-ref
Jan 9, 2026
Merged

feat(create-app): Add protocol option and improve CLI scaffolding#78
gabrypavanello merged 7 commits into
mainfrom
create-app-ref

Conversation

@gabe4coding

Copy link
Copy Markdown
Contributor

Summary

  • Add protocol option to CLI: Users can now specify --protocol mcp or --protocol openai when scaffolding new projects, allowing them to target specific platforms
  • Refactor OpenAI adapter: Updated methods for better compatibility with latest OpenAI API (sendFollowUpMessage, openExternal, setWidgetState)
  • Simplify CLI code: Cleaned up argument parsing and project name validation logic
  • Fix test environment: Skip server start during tests to prevent port conflicts
  • Fix flaky tests: Resolved timestamp comparison issues in client contract tests

Test plan

  • All 186 ui package tests pass
  • All 39 create-app package tests pass
  • Typecheck passes for all packages
  • Lint passes for all packages

🤖 Generated with Claude Code

- Replaced `prompts` with `@inquirer/prompts` and updated to version 7.10.1.
- Added `figlet` as a dependency and updated to version 1.9.4.
- Introduced `@inquirer/testing` and `@types/figlet` as devDependencies.
- Refactored CLI to utilize `@inquirer/prompts` for user interactions.
- Enhanced project scaffolding to include testing setup files and dependencies.
- Updated package.json scripts to use npm consistently for installations.
- Added Vitest configuration and initial test setup files for improved testing capabilities.

All changes maintain existing functionality while improving code clarity and structure.
- Introduced a new `protocol` option in the CLI, allowing users to specify either "mcp" or "openai" when creating applications.
- Updated argument parsing to default the protocol to "mcp" if not specified.
- Enhanced interactive prompts to include protocol selection.
- Updated relevant scaffolding functions to handle the new protocol parameter.
- Added tests to ensure proper parsing and validation of the protocol option.

These changes improve flexibility in application setup and enhance user experience during project initialization.
- Replaced `sendMessage` with `sendFollowUpMessage` to align with updated OpenAI API.
- Changed `openLink` to use `openExternal` for better external link handling.
- Updated `setState` to utilize `setWidgetState`, enhancing state management consistency.

These changes ensure compatibility with the latest OpenAI features and improve the overall functionality of the adapter.
- Updated the server start logic to only execute when the NODE_ENV is not set to "test", preventing unnecessary server initialization during testing.
- Enhanced the integration test to check for the presence of the "test:watch" script in package.json, ensuring proper test setup.

These changes improve the testing experience by avoiding server startup in test scenarios.
- Streamlined the `validateProjectName` function by removing unnecessary checks and simplifying the scoped package validation logic.
- Refactored the `parseArgs` function to eliminate the initial result object, directly returning the constructed options, enhancing clarity and reducing code complexity.

These changes improve code readability and maintainability in the CLI package.
@coderabbitai

coderabbitai Bot commented Jan 9, 2026

Copy link
Copy Markdown
Contributor

Caution

Review failed

The pull request is closed.

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Added protocol selection (mcp or openai) during app creation
    • Improved interactive CLI with a visual header and richer prompts
    • Generated projects now include test scaffolding and testing scripts
  • Enhancements

    • Improved OpenAI adapter behavior for messaging, external links, and state handling
  • Chores

    • Updated CLI prompt library and related development tooling dependencies
  • Tests

    • Added integration and unit tests covering scaffolding, CLI protocol parsing, and test setup

✏️ Tip: You can customize this high-level summary in your review settings.

Walkthrough

Adds a new protocol option ("mcp" | "openai") across the create-app CLI and scaffolding, replaces prompts with @inquirer/prompts, adds figlet header rendering, updates generated templates and tests for testing scaffolds, and adjusts openai adapter behaviors.

Changes

Cohort / File(s) Change Summary
Dependencies
packages/create-app/package.json
Swapped prompts for @inquirer/prompts; added figlet; removed @types/prompts; added @inquirer/testing and @types/figlet.
CLI
packages/create-app/src/cli.ts
Replaced prompts with Inquirer prompts; added figlet header; added protocol to CLIOptions; new protocol prompt/validation and propagation; updated interactive flow and messaging.
Scaffolding & Templates
packages/create-app/src/index.ts
Added `protocol?: "mcp"
Create-app Tests
packages/create-app/tests/unit/cli.test.ts, packages/create-app/tests/integration/scaffold.test.ts
Unit tests for protocol parsing and validation; integration tests asserting test setup files, testing deps/scripts, and server export in generated templates.
UI Adapter (openai)
packages/ui/src/adapters/openai.ts
sendMessage rejects non-text and delegates to openai.sendFollowUpMessage({ prompt }); openLink uses openExternal({ href }) with window.open fallback; setState uses setWidgetState if available; simplified getToolOutput wrapping.
Contract Tests
packages/ui/tests/contract/client.test.ts
Tests updated to ignore timestamp field when comparing proxy vs direct results.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant CLI
  participant Scaffolder
  participant TemplateGen
  participant FS
  User->>CLI: run create-app (args or interactive)
  CLI->>User: (if interactive) render figlet header, ask prompts (name, template, protocol, vercel, etc.)
  CLI->>Scaffolder: call scaffoldProject(options with protocol)
  Scaffolder->>TemplateGen: generate template files (pass protocol)
  TemplateGen->>FS: write project files (server, ui, tests, package.json)
  Scaffolder->>FS: run installer messaging (npm) / skip install per options
  Scaffolder->>CLI: return success and final instructions
  CLI->>User: print completion message (includes protocol)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 77.78% 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
Title check ✅ Passed The title accurately summarizes the main changes: adding protocol option to create-app and improving CLI scaffolding, which aligns with the primary changes across packages/create-app files.
Description check ✅ Passed The description provides relevant context covering the main changes: protocol option addition, OpenAI adapter refactoring, CLI simplification, test environment fixes, and flaky test resolution, all of which are reflected in the changeset.

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

✨ Finishing touches
  • 📝 Generate docstrings

📜 Recent review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f62e0cd and 94352c6.

📒 Files selected for processing (1)
  • packages/ui/src/adapters/openai.ts

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.

@claude

claude Bot commented Jan 9, 2026

Copy link
Copy Markdown
Contributor

Code Review

I've reviewed PR #78 and have the following feedback:

Strengths

  1. Well-structured feature addition: The protocol option is cleanly integrated into the CLI and propagated correctly through templates
  2. Good test coverage: Added comprehensive tests for new functionality (91 new lines of integration tests)
  3. Dependency update is justified: Switching from prompts to @inquirer/prompts provides better UX with the new protocol selection
  4. Backward compatibility: Protocol defaults to "mcp", maintaining existing behavior
  5. Consistent patterns: The protocol parameter follows the same patterns as template selection
  6. Good documentation: The figlet header is a nice touch for CLI UX

🔍 Code Quality Issues

1. Potential issue with protocol config

The generated server code includes config.protocol but I don't see evidence that @mcp-apps-kit/core actually supports this option. Please verify that the core package properly handles this config option, or document it as a placeholder for future use.

2. Package manager comment

The comment "Always use npm for standalone projects" could be more detailed to explain why (avoiding workspace conflicts in pnpm monorepo).

3. Minor: Code simplification

The validateProjectName function was simplified but the old version with intermediate variables was arguably more readable. This is subjective though.

🐛 Potential Bugs

1. Test flakiness fix

The timestamp comparison fix is good, but assumes timestamps are the ONLY potentially different values. Consider using a more explicit approach or mocking Date.now() if other time-sensitive data is added.

Performance Considerations

Network calls during scaffolding could be slow. Consider adding a timeout and progress indicator when fetching package versions.

📝 Additional Observations

OpenAI adapter refactoring: Method signature updates look correct and align with latest OpenAI Apps SDK ✅

Template improvements: Better TypeScript typing, integration tests, improved UI styling, and dark mode support are excellent additions ✅

📊 Test Coverage

  • ✅ New CLI tests cover the protocol option
  • ✅ Integration tests scaffold projects successfully
  • ✅ All 186 UI tests pass
  • ✅ All 39 create-app tests pass

🎯 Recommendations

  1. HIGH PRIORITY: Verify config.protocol is supported by core
  2. MEDIUM PRIORITY: Add progress indicator during package version fetching
  3. LOW PRIORITY: Add test verifying protocol value in generated files
  4. LOW PRIORITY: Improve npm vs pnpm comment

Overall Assessment

Solid PR with valuable functionality. Well-structured, tested, and follows conventions. Main concern is verifying the config.protocol support.

Recommendation: ✅ Approve with minor revisions


Review generated by Claude Code

@gabrypavanello gabrypavanello self-assigned this Jan 9, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

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

⚠️ Outside diff range comments (1)
packages/ui/src/adapters/openai.ts (1)

525-533: Fix incorrect type assertion and error handling in openLink method.

The type assertion is incorrect. The OpenAI API openExternal method returns void, not Promise<void>. Remove the await operator and the Promise-based type cast. Additionally, this method must use AppError and ErrorCode from @mcp-apps-kit/core for error handling per the codebase guidelines, rather than throwing generic errors.

Update the method to:

  • Correct the type signature: openai.openExternal({ href: url })
  • Remove the await (the method is synchronous)
  • Add proper error handling using AppError and ErrorCode if needed
🤖 Fix all issues with AI agents
In @packages/create-app/package.json:
- Around line 51-57: Update the dependency version strings in package.json for
the listed packages to the latest stable releases: change "@inquirer/prompts"
from "^7.5.0" to "^7.8.6", change "figlet" from "^1.8.0" to "^1.9.4", and change
"@inquirer/testing" from "^2.1.0" to "^2.1.47" (leave "@types/figlet" as-is
since it's already current); after updating these entries, run your package
manager to refresh the lockfile (e.g., npm install or pnpm install) and run the
test/build scripts to verify nothing breaks.

In @packages/ui/src/adapters/openai.ts:
- Around line 514-521: The sendMessage method's parameter currently declares an
unused property `type`; rename it to `_type` in the signature (change content: {
type: string; text: string } to content: { _type: string; text: string }) so the
unused variable is prefixed with an underscore, and keep the rest of sendMessage
(including the call to openai.sendFollowUpMessage with content.text) unchanged;
if message-type validation is needed instead of ignoring it, mirror the
validation logic from the mcp.ts adapter for `_type` and implement appropriate
handling rather than simply renaming.
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e7468dd and 0f0bb79.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (7)
  • packages/create-app/package.json
  • packages/create-app/src/cli.ts
  • packages/create-app/src/index.ts
  • packages/create-app/tests/integration/scaffold.test.ts
  • packages/create-app/tests/unit/cli.test.ts
  • packages/ui/src/adapters/openai.ts
  • packages/ui/tests/contract/client.test.ts
🧰 Additional context used
📓 Path-based instructions (4)
**/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.ts: Use Strict TypeScript mode: no any types, use unknown and narrow types instead
Remove all unused variables or prefix them with underscore (_)
Use export type for type-only exports

Files:

  • packages/create-app/src/index.ts
  • packages/ui/src/adapters/openai.ts
  • packages/create-app/src/cli.ts
  • packages/create-app/tests/unit/cli.test.ts
  • packages/ui/tests/contract/client.test.ts
  • packages/create-app/tests/integration/scaffold.test.ts
**/index.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Export public API only through index.ts files

Files:

  • packages/create-app/src/index.ts
packages/**/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Use AppError and ErrorCode from @mcp-apps-kit/core for error handling

Files:

  • packages/create-app/src/index.ts
  • packages/ui/src/adapters/openai.ts
  • packages/create-app/src/cli.ts
  • packages/create-app/tests/unit/cli.test.ts
  • packages/ui/tests/contract/client.test.ts
  • packages/create-app/tests/integration/scaffold.test.ts
**/tests/**/*.test.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Place test files in tests/ directory mirroring source structure with subdirectories for unit/, integration/, and contract/ tests

Files:

  • packages/create-app/tests/unit/cli.test.ts
  • packages/ui/tests/contract/client.test.ts
  • packages/create-app/tests/integration/scaffold.test.ts
🧠 Learnings (3)
📚 Learning: 2026-01-09T14:18:43.501Z
Learnt from: CR
Repo: AndurilCode/mcp-apps-kit PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-09T14:18:43.501Z
Learning: Applies to packages/**/*.ts : Use `AppError` and `ErrorCode` from `mcp-apps-kit/core` for error handling

Applied to files:

  • packages/create-app/src/index.ts
  • packages/create-app/tests/integration/scaffold.test.ts
📚 Learning: 2026-01-09T14:18:43.501Z
Learnt from: CR
Repo: AndurilCode/mcp-apps-kit PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-09T14:18:43.501Z
Learning: Applies to **/tests/**/*.test.ts : Place test files in `tests/` directory mirroring source structure with subdirectories for unit/, integration/, and contract/ tests

Applied to files:

  • packages/create-app/src/index.ts
  • packages/create-app/tests/integration/scaffold.test.ts
📚 Learning: 2026-01-09T14:18:43.501Z
Learnt from: CR
Repo: AndurilCode/mcp-apps-kit PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-09T14:18:43.501Z
Learning: Run full checks before PR: `pnpm build && pnpm test && pnpm lint && pnpm typecheck`

Applied to files:

  • packages/create-app/src/index.ts
🧬 Code graph analysis (2)
packages/create-app/tests/unit/cli.test.ts (1)
packages/create-app/src/cli.ts (1)
  • parseArgs (74-133)
packages/create-app/tests/integration/scaffold.test.ts (1)
packages/create-app/src/index.ts (1)
  • scaffoldProject (1195-1258)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: claude-review
  • GitHub Check: test-and-lint
🔇 Additional comments (30)
packages/ui/tests/contract/client.test.ts (1)

139-142: LGTM! Effective fix for flaky timestamp comparisons.

The destructuring approach correctly isolates and ignores the non-deterministic timestamp field while comparing the rest of the result structure. The unused timestamp variables are properly prefixed with underscores per coding guidelines.

Also applies to: 156-159

packages/ui/src/adapters/openai.ts (2)

663-667: LGTM! Cleaner implementation.

The simplified return statement is more concise while maintaining the same functionality of wrapping the output with the tool name when available.


566-572: OpenAI API method implementation is correct.

The code properly calls openai.setWidgetState, which aligns with the official OpenAI ChatGPT Apps SDK. The adapter's setState method correctly wraps the SDK's setWidgetState API and includes appropriate type checking before invocation.

packages/create-app/src/index.ts (13)

18-18: LGTM: Protocol option properly typed.

The optional protocol field with union type "mcp" | "openai" aligns with the PR objectives and provides type safety.


33-33: LGTM: Testing version tracking added.

The testing field is properly added to support the new test scaffolding feature.


77-81: LGTM: Protocol parameter with sensible default.

The protocol parameter with a default value of "mcp" ensures backward compatibility while enabling the new feature.


252-256: LGTM: Server start properly gated for test environment.

Wrapping the server start in if (process.env.NODE_ENV !== "test") prevents port conflicts during tests, aligning with the PR objectives.


258-259: LGTM: App export enables testing.

Exporting the app instance allows the generated test files to import and test the application, which is essential for the new test scaffolding feature.


273-294: LGTM: Tool result handling supports multiple formats.

The code properly handles both wrapped ({ hello: {...} }) and unwrapped result formats with clear type definitions and helpful comments.


522-534: LGTM: Vitest configuration is well-structured.

The test configuration with 30-second timeouts and node environment is appropriate for integration tests.


535-542: LGTM: Test setup file is clean and simple.

The setup file properly initializes Vitest matchers from the testing package.


543-608: LGTM: Integration test template provides comprehensive coverage.

The test template covers server startup, tool listing, tool execution, and response validation. The 100ms delay after server start (line 557) is a reasonable approach for integration tests.


822-861: LGTM: Vanilla template properly handles tool results.

The tool result handling with type definitions and subscription logic mirrors the React template approach appropriately.


1195-1258: LGTM: Scaffolding properly handles protocol and uses npm.

The protocol parameter is correctly defaulted and propagated. Using npm for standalone projects (line 1252) is a good choice to avoid workspace-related issues.


169-171: No action required. The config.protocol field is fully supported by @mcp-apps-kit/core. The protocol field is a documented property in GlobalConfig that accepts "mcp" (default) or "openai" and is properly handled throughout the core package's server initialization and adapter system.


108-108: No changes needed—zod 4.x is the current release line as of January 2026, with 4.0.0 having been released in July 2025. The version specification ^4.0.0 is valid and will not cause installation failures.

Likely an incorrect or invalid review comment.

packages/create-app/tests/unit/cli.test.ts (1)

71-88: LGTM: Comprehensive protocol parsing test coverage.

The test cases properly cover default values, argument parsing (both long and short forms), and validation for the new protocol option.

packages/create-app/tests/integration/scaffold.test.ts (5)

124-140: LGTM: Test setup file verification is thorough.

The test properly verifies that all three test configuration files are generated for the React template.


142-160: LGTM: Testing dependencies and scripts are properly verified.

The test ensures that testing dependencies and npm scripts are correctly added to the generated project.


162-175: LGTM: Server export verification is appropriate.

The test confirms that the generated server file exports the app instance, which is essential for the integration tests.


226-242: LGTM: Vanilla template test setup verification mirrors React.

The test structure is consistent and provides equivalent coverage for the Vanilla template.


244-262: LGTM: Vanilla template testing dependencies are verified.

The test ensures consistent testing infrastructure across both templates.

packages/create-app/src/cli.ts (8)

9-11: LGTM: Inquirer and figlet imports are appropriate.

The specific named imports from @inquirer/prompts and the figlet import align with the dependency changes and CLI enhancements.


22-22: LGTM: Protocol field properly typed in CLIOptions.

The protocol field is correctly defined as a required union type in CLIOptions, which is appropriate since the CLI always provides a default value.


38-59: LGTM: Project name validation refactored cleanly.

The validation logic is simplified with the extracted validateSimpleName helper, making it easier to maintain and understand.


68-105: LGTM: Protocol argument parsing follows established patterns.

The protocol validation and parsing logic is consistent with the existing template option implementation, with proper error handling and defaults.


123-132: LGTM: parseArgs return statement is clean.

The return statement properly constructs the CLIOptions object with all fields, including the new protocol field.


142-154: LGTM: ASCII art header enhances CLI experience.

The printHeader function creates an attractive visual header using figlet and chalk, improving the user experience.


156-222: LGTM: Interactive prompts are well-structured with clear protocol options.

The protocol selection prompt provides helpful descriptions and follows the consistent inquirer pattern. Error handling for cancelled prompts is appropriate.


247-287: LGTM: Protocol properly propagated and displayed.

The protocol is correctly included in the options object and displayed to the user. The simplified npm command suggestions align with the "always use npm for standalone projects" approach.

Comment thread packages/create-app/package.json Outdated
Comment on lines 514 to 521
async sendMessage(content: { type: string; text: string }): Promise<void> {
const openai = this.getOpenAI();
if (openai && typeof openai.sendMessage === "function") {
await (openai.sendMessage as (content: { type: string; text: string }) => Promise<void>)(
content
);
if (openai && typeof openai.sendFollowUpMessage === "function") {
await (openai.sendFollowUpMessage as (opts: { prompt: string }) => Promise<void>)({
prompt: content.text,
});
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# Check if the file exists and examine the context around lines 514-521
fd "openai.ts" packages/ui/src/adapters

Repository: AndurilCode/mcp-apps-kit

Length of output: 102


🏁 Script executed:

# Look for references to sendFollowUpMessage in the codebase
rg "sendFollowUpMessage" --type ts -n

Repository: AndurilCode/mcp-apps-kit

Length of output: 1166


🏁 Script executed:

# Check the file size and read the relevant section
wc -l packages/ui/src/adapters/openai.ts

Repository: AndurilCode/mcp-apps-kit

Length of output: 106


🏁 Script executed:

# Read the sendMessage method and surrounding context
sed -n '510,530p' packages/ui/src/adapters/openai.ts

Repository: AndurilCode/mcp-apps-kit

Length of output: 720


🏁 Script executed:

# Read the type definition to understand the actual API
cat -n packages/ui/src/types.ts | grep -A 2 "sendFollowUpMessage"

Repository: AndurilCode/mcp-apps-kit

Length of output: 167


🏁 Script executed:

# Read the client implementation
sed -n '114,125p' packages/ui/src/client.ts

Repository: AndurilCode/mcp-apps-kit

Length of output: 330


🏁 Script executed:

# Check broader context for error handling and whether content.type should be used
sed -n '490,545p' packages/ui/src/adapters/openai.ts

Repository: AndurilCode/mcp-apps-kit

Length of output: 1844


🏁 Script executed:

# Check what the content parameter's type property should be used for
rg "sendMessage.*type" packages/ui/src -A 2 -B 2 --type ts

Repository: AndurilCode/mcp-apps-kit

Length of output: 2281


🏁 Script executed:

# Check if there are AppError imports or error handling patterns in this file
head -50 packages/ui/src/adapters/openai.ts

Repository: AndurilCode/mcp-apps-kit

Length of output: 1634


🏁 Script executed:

# Check the adapter interface definition for type parameter
cat -n packages/ui/src/adapters/types.ts | grep -A 3 "sendMessage"

Repository: AndurilCode/mcp-apps-kit

Length of output: 192


🏁 Script executed:

# Check if AppError is used in this file or if error handling pattern exists
grep -n "AppError\|ErrorCode\|Error\|throw" packages/ui/src/adapters/openai.ts | head -20

Repository: AndurilCode/mcp-apps-kit

Length of output: 463


🏁 Script executed:

# Check if types are exported as type-only
grep -n "export type\|export interface" packages/ui/src/adapters/openai.ts

Repository: AndurilCode/mcp-apps-kit

Length of output: 112


🏁 Script executed:

# Check if AppError is imported in this file
grep -n "import.*AppError\|import.*ErrorCode" packages/ui/src/adapters/openai.ts

Repository: AndurilCode/mcp-apps-kit

Length of output: 50


🏁 Script executed:

# Compare error handling pattern - check if other adapters use AppError
grep -n "AppError\|ErrorCode" packages/ui/src/adapters/*.ts

Repository: AndurilCode/mcp-apps-kit

Length of output: 728


🏁 Script executed:

# Check the actual type definition in types.ts more carefully
sed -n '400,410p' packages/ui/src/types.ts

Repository: AndurilCode/mcp-apps-kit

Length of output: 281


🏁 Script executed:

# Check what UIError is and where it's imported from
cat -n packages/ui/src/errors.ts | head -30

Repository: AndurilCode/mcp-apps-kit

Length of output: 1046


🏁 Script executed:

# Check if packages/ui is under packages/**/*.ts pattern that requires AppError or UIError
head -20 packages/ui/src/adapters/openai.ts | grep -i "mcp-apps-kit"

Repository: AndurilCode/mcp-apps-kit

Length of output: 50


🏁 Script executed:

# Check if @mcp-apps-kit/core is available and what it exports
fd "package.json" packages/ui | xargs grep -l "@mcp-apps-kit/core" 2>/dev/null || echo "Not found in packages/ui"

Repository: AndurilCode/mcp-apps-kit

Length of output: 92


🏁 Script executed:

# Check the root or core package
cat packages/core/package.json 2>/dev/null | grep -A 5 "\"name\""

Repository: AndurilCode/mcp-apps-kit

Length of output: 274


🏁 Script executed:

# Check what's exported from core
fd "index.ts" packages/core/src | head -5 && grep -n "export.*Error\|export.*AppError" packages/core/src/*.ts 2>/dev/null | head -10

Repository: AndurilCode/mcp-apps-kit

Length of output: 545


🏁 Script executed:

# Check if packages/ui is actually supposed to use AppError or if UIError is the pattern for this package
cat packages/ui/package.json | grep -A 10 "dependencies"

Repository: AndurilCode/mcp-apps-kit

Length of output: 207


🏁 Script executed:

# Review the entire error handling in openai.ts
grep -n "throw\|Error\|async" packages/ui/src/adapters/openai.ts | head -30

Repository: AndurilCode/mcp-apps-kit

Length of output: 1262


🏁 Script executed:

# Check the sendMessage implementation more carefully for potential issues
sed -n '514,525p' packages/ui/src/adapters/openai.ts

Repository: AndurilCode/mcp-apps-kit

Length of output: 465


🏁 Script executed:

# Check how content.type is used in other adapters
grep -A 5 "async sendMessage" packages/ui/src/adapters/mcp.ts | head -10

Repository: AndurilCode/mcp-apps-kit

Length of output: 340


🏁 Script executed:

# Check the mock adapter
grep -A 10 "async sendMessage" packages/ui/src/adapters/mock.ts | head -15

Repository: AndurilCode/mcp-apps-kit

Length of output: 421


🏁 Script executed:

# Check if content.type is used anywhere else in the file
grep -n "content.type" packages/ui/src/adapters/openai.ts

Repository: AndurilCode/mcp-apps-kit

Length of output: 50


The OpenAI API method signature for sendFollowUpMessage is correct, but the content.type parameter should be prefixed with an underscore since it's unused in this method.

Change content: { type: string; text: string } to content: { _type: string; text: string } to comply with the coding guideline: "Remove all unused variables or prefix them with underscore (_)".

Note: The mcp.ts adapter validates content.type, so if this parameter should be used for message type handling, add similar validation.

🤖 Prompt for AI Agents
In @packages/ui/src/adapters/openai.ts around lines 514 - 521, The sendMessage
method's parameter currently declares an unused property `type`; rename it to
`_type` in the signature (change content: { type: string; text: string } to
content: { _type: string; text: string }) so the unused variable is prefixed
with an underscore, and keep the rest of sendMessage (including the call to
openai.sendFollowUpMessage with content.text) unchanged; if message-type
validation is needed instead of ignoring it, mirror the validation logic from
the mcp.ts adapter for `_type` and implement appropriate handling rather than
simply renaming.

- Updated `@inquirer/prompts` from `^7.5.0` to `^7.8.6` in both `package.json` and `pnpm-lock.yaml`.
- Upgraded `figlet` from `^1.8.0` to `^1.9.4` in both `package.json` and `pnpm-lock.yaml`.
- Increased `@inquirer/testing` version from `^2.1.0` to `^2.1.47` in both files.

These updates ensure compatibility with the latest features and improvements in the respective packages.
…penAIAdapter

- Implemented a check in the `sendMessage` method to throw an error if the content type is not "text", ensuring that only supported message types are processed.
- This change enhances the robustness of the OpenAIAdapter by preventing unexpected behavior when unsupported message types are sent.
@claude

claude Bot commented Jan 9, 2026

Copy link
Copy Markdown
Contributor

Code Review: Protocol Option and CLI Improvements

I've completed a thorough review of this PR. Overall, this is a solid enhancement that adds protocol selection to the CLI and makes several improvements. Here's my detailed feedback:


Strengths

1. Well-Structured Protocol Addition

  • The --protocol flag is properly integrated with validation and defaults to mcp
  • Protocol is correctly threaded through from CLI → options → templates
  • Good use of TypeScript const arrays for type safety

2. Improved Developer Experience

  • Migration from prompts to @inquirer/prompts provides better UX
  • ASCII art header adds polish to interactive mode
  • Cleaner error handling for prompt cancellation

3. Excellent Test Coverage

  • New integration tests for scaffolding (91 lines added)
  • Protocol option tests added to CLI tests
  • Tests verify actual file generation and content

4. Testing Infrastructure

  • Added @mcp-apps-kit/testing dependency to generated projects
  • Includes vitest config and test setup
  • Generated projects have integration tests out-of-the-box
  • Server exports app for testability (with NODE_ENV check)

5. OpenAI Adapter Improvements

  • Renamed sendMessagesendFollowUpMessage for clarity
  • Updated openLinkopenExternal with correct API shape
  • Fixed setStatesetWidgetState to match actual OpenAI SDK

⚠️ Issues & Concerns

1. Critical: Package Manager Inconsistency (High Priority)

// Line 83 in index.ts
const packageManager = "npm"; // Always use npm for standalone projects

Problem: The comment says "Always use npm" but the CLI still has logic checking for Vercel to decide package managers. This creates confusion.

Lines 93, 277-280 in cli.ts:

dev: `${packageManager} run build:ui && concurrently ...`
// Later in CLI output:
console.log(chalk.cyan("  npm run dev"));

Issue: You're hardcoding npm everywhere, which is reasonable for standalone projects, but:

  • The project itself is a pnpm monorepo (per CLAUDE.md)
  • Users might prefer pnpm/yarn/bun
  • The Vercel logic remnants suggest this was recently changed

Recommendation: Either:

  1. Keep npm-only and remove all package manager logic/comments about Vercel affecting it
  2. Or add a --package-manager flag if you want flexibility

2. Zod Version Mismatch (Medium Priority)

"zod": "^4.0.0"  // In generated projects

Problem: Zod v4 doesn't exist yet (latest is 3.23.x). This will cause installation failures.

Impact: npm install will fail in generated projects.

Fix: Change to "zod": "^3.22.0" in both template functions.

3. Test Flakiness Fix Incomplete (Low Priority)

// client.test.ts lines 140-142, 157-159
const { timestamp: _t1, ...proxyRest } = proxyResult as Record<string, unknown>;
const { timestamp: _t2, ...directRest } = directResult as Record<string, unknown>;
expect(proxyRest).toEqual(directRest);

Issue: While you fixed the timestamp comparison, the unused variable prefix (_t1, _t2) violates the "no unused variables" rule from CLAUDE.md.

Fix: Either remove them entirely or use a different pattern:

const { timestamp, ...proxyRest } = proxyResult as Record<string, unknown>;
const { timestamp: _timestamp, ...directRest } = directResult as Record<string, unknown>;

4. Dependency Fetching Risk (Medium Priority)

function fetchLatestVersion(packageName: string): string {
  try {
    const result = execSync(`npm view ${packageName} version`, {...}).trim();
    return `^${result}`;
  } catch {
    return "^0.2.0"; // Fallback
  }
}

Concerns:

  • Network calls during scaffolding (slow in CI/offline environments)
  • Silent failure with outdated fallback version
  • No caching between template generations in the same CLI run (you do cache, but only for one getPackageVersions() call)

Recommendations:

  1. Add a --offline flag that uses fallback versions
  2. Log a warning when falling back
  3. Consider reading versions from the CLI's own package.json (if create-app depends on them)

5. Missing Protocol in Config (Low Priority)

The templates add:

config: {
  protocol: "${protocol}",
},

Question: Is this actually used by createApp? I don't see this in the core package API. If it's not used, remove it to avoid confusion.

6. Figlet Dependency (Low Priority)

New dependency figlet adds ~100KB for ASCII art.

Consideration: Is the ASCII banner worth the bundle size increase? It's nice-to-have but not essential. Consider:

  • Making it optional
  • Using a simpler banner (chalk + box-drawing chars)
  • Lazy-loading it only in interactive mode

🔍 Code Quality Observations

Positive:

  • ✅ Proper TypeScript usage with strict types
  • ✅ Error handling for prompt cancellation
  • ✅ Good test coverage (integration + unit tests)
  • ✅ Follows project conventions (exports in index.ts)

Minor Issues:

  1. Line 38 in cli.ts: Simplification removed empty string check but !name already handles it

    if (!name) return false; // Good, handles empty string too
  2. Lines 93-100 in index.ts: dev script now runs build:ui first, which makes the first startup slower but ensures UI is built. Consider documenting this change in the PR.

  3. OpenAI adapter changes: The method renames (sendFollowUpMessage, openExternal, setWidgetState) should be verified against the actual OpenAI SDK documentation to ensure they're correct.


🧪 Testing Notes

Well tested:

  • Protocol parsing and validation
  • File generation for both templates
  • Test infrastructure in generated projects

⚠️ Could improve:

  • No test for protocol actually being used in generated config
  • No test for the NODE_ENV check preventing server start in tests
  • OpenAI adapter changes not covered by new tests (but existing tests pass)

📋 Action Items

Must Fix (Blocking):

  1. ✅ Fix Zod version to ^3.22.0 (or ^3.23.0)
  2. ⚠️ Decide on package manager strategy and clean up inconsistencies

Should Fix (Recommended):

  1. Remove unused variable naming violations (_t1, _t2)
  2. Add logging when version fetching fails
  3. Verify OpenAI adapter method names against SDK docs
  4. Document or remove unused protocol in config

Nice to Have:

  1. Consider offline mode or bundle size optimization for figlet
  2. Test that protocol config is actually used

🎯 Overall Assessment

This is a solid PR that delivers on its goals:

  • ✅ Protocol selection works
  • ✅ CLI improvements are valuable
  • ✅ Testing infrastructure is excellent
  • ✅ Code quality is good

Risk Level: Medium (Zod version will break installs)

Recommendation: Fix the Zod version, clarify package manager strategy, then approve and merge.


📚 Code Quality Checklist (per CLAUDE.md)

  • ✅ Strict TypeScript (no any)
  • ⚠️ Unused variables (fix _t1, _t2)
  • ✅ Public API in index.ts
  • ✅ Tests added
  • ✅ No secrets committed
  • ⚠️ Zod dependency incorrect

Great work overall! The protocol option is a valuable addition and the testing infrastructure will help users. Just fix the Zod version before merging. 🚀

@gabrypavanello
gabrypavanello merged commit d6d004c into main Jan 9, 2026
3 of 4 checks passed
@gabrypavanello
gabrypavanello deleted the create-app-ref branch January 9, 2026 18:32
@claude

claude Bot commented Jan 9, 2026

Copy link
Copy Markdown
Contributor

Code Review for PR #78

This PR adds protocol selection to the CLI scaffolder and includes several quality improvements. All tests pass (186 UI + 39 create-app tests).

✅ Strengths

  1. Protocol Selection Feature - Clean implementation of --protocol flag with mcp/openai options
  2. Improved CLI UX - Migration to @inquirer/prompts with figlet ASCII art header
  3. Test Infrastructure - Excellent test scaffolding with vitest, integration tests, and proper test setup
  4. Refactored Templates - Better TypeScript types, improved CSS with dark mode, exports for testing
  5. Code Quality - Simplified validation, better readability, consistent npm usage

⚠️ Critical Issues

1. Zod Version

Templates use zod ^4.0.0 but Zod v4 doesn't exist yet (latest is 3.x). This will break npm install.
Fix: Change to zod ^3.22.0

2. Express Version

Vercel templates use express ^4.21.0 while CLAUDE.md mentions Express 5.x.
Fix: Use ^5.1.0 consistently or document why v4 is required

3. Unused Protocol Config

Templates add config.protocol but don't use it anywhere.
Fix: Either use it, remove it, or document its future purpose

📝 Medium Priority

  • OpenAI adapter methods look correct (sendFollowUpMessage, openExternal, setWidgetState)
  • Test timestamp fix is good but consider vitest.useFakeTimers() for determinism
  • Dev script builds UI first every time - could slow DX
  • CSS duplication between React/Vanilla templates (200+ lines)

🔒 Security & Performance

✅ No secrets, proper validation, good escaping, .env in .gitignore
✅ Caches package versions
⚠️ Could parallelize version fetching with Promise.all()

🧪 Test Coverage

Excellent coverage with 225 total tests. Missing: protocol-specific behavior tests, Vercel scaffolding tests, npm error cases.

📚 Documentation Needed

  1. When to use mcp vs openai protocol
  2. How to run tests in generated apps
  3. Roadmap for protocol config usage

✅ Verdict: Approve with changes

Solid PR with valuable features and excellent testing! The Zod version is a blocker that needs fixing before merge.

Action Items:

  1. Fix zod version (v4.0.0 → v3.22.0)
  2. Fix Express version or document why v4
  3. Document or remove config.protocol

Great work @gabe4coding! 🚀

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