Skip to content

Conversation

@jurgenwerk
Copy link
Contributor

@jurgenwerk jurgenwerk commented Jan 20, 2026

This PR addresses a user experience issue where:

  1. User is in interact mode and opens the AI assistant and tells it to generate something (e.g. "make me a tic tac toe game")
  2. The assistant will switch to code mode and open the index card, then proceed with ai generation and once user accepts the patch to create file(s) nothing happens, they still see the index card.

This PR adds an optional boolean param createFile to switch mode command where it will create the file the assistant is about to generate. The user will be transitioned to code mode, seeing a blank file until the AI assistant is done generating the code.

The changes in this PR alone don't fix the mentioned issue yet - there will be another PR in the skills repo to teach the LLM when to use createFile parameter (I have it almost ready and confirm it works with all of the above).


Note

Introduces a file-creation path when switching to code mode and centralizes non-conflicting filename handling.

  • Adds createFile to SwitchSubmodeInput and new SwitchSubmodeResult; creates an empty file on switch from interact→code when requested, reusing blank files or picking a non-conflicting filename; updates UI to not render result cards for switch-submode commands
  • Enhances WriteTextFileCommand to return FileUrlCard, support useNonConflictingFilename, use CardService.saveSource, and avoid overwriting existing content unless requested
  • Refactors non-conflicting filename logic into utils/file-name.ts and updates patch-code to use it when inserting into non-empty files
  • Extends base command schema to include new fields/classes and adds comprehensive tests for new behaviors

Written by Cursor Bugbot for commit 8bee425. This will update automatically on new commits. Configure here.

@github-actions
Copy link

Preview deployments

@github-actions
Copy link

github-actions bot commented Jan 20, 2026

Host Test Results

    1 files  ±0      1 suites  ±0   1h 44m 47s ⏱️ + 2m 44s
1 909 tests +6  1 892 ✅ +6  17 💤 ±0  0 ❌ ±0 
1 924 runs  +6  1 907 ✅ +6  17 💤 ±0  0 ❌ ±0 

Results for commit 8bee425. ± Comparison against base commit e8ef4e1.

♻️ This comment has been updated with latest results.

@jurgenwerk jurgenwerk force-pushed the cs-9640-when-trying-to-create-a-new-card-with-ai-it-will-sometimes branch from 76b1b4d to 2cbf92e Compare January 20, 2026 12:13
@jurgenwerk jurgenwerk requested a review from Copilot January 20, 2026 12:42
Copy link
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 enhances the AI assistant's user experience by adding a createFile parameter to the switch-submode command. When switching from interact mode to code mode, the assistant can now create a blank file immediately, allowing users to see an empty file instead of an index card while the AI generates code.

Changes:

  • Added createFile boolean parameter to SwitchSubmodeInput and introduced SwitchSubmodeResult card definition for handling filename conflicts
  • Implemented file creation logic in switch-submode command with automatic conflict resolution when target files already exist
  • Extracted filename conflict resolution logic to a reusable utility function and refactored patch-code command to use it

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
packages/base/command.gts Added createFile field to SwitchSubmodeInput and defined SwitchSubmodeResult card for communicating filename changes
packages/host/app/commands/switch-submode.ts Implemented file creation logic with conflict resolution when switching from interact to code mode
packages/host/app/utils/file-name.ts New utility function for finding non-conflicting filenames
packages/host/app/commands/patch-code.ts Refactored to use shared filename conflict resolution utility
packages/runtime-common/ai/prompt.ts Added instruction generation for AI when filename conflicts occur
packages/host/app/components/matrix/room-message-command.gts Hide result cards for switch-submode commands in the UI
packages/host/tests/integration/commands/switch-submode-test.gts Added tests for file creation and conflict resolution scenarios
packages/ai-bot/tests/prompt-construction-test.ts Added test for AI instruction when filename conflicts occur

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

jurgenwerk and others added 3 commits January 20, 2026 13:56
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@jurgenwerk jurgenwerk marked this pull request as ready for review January 20, 2026 13:45
@jurgenwerk jurgenwerk requested a review from a team January 20, 2026 13:57
@jurgenwerk jurgenwerk changed the title Add createFile param to switch submode command Add createFile param to the switch submode command Jan 20, 2026
@jurgenwerk
Copy link
Contributor Author

jurgenwerk commented Jan 21, 2026

Accompanying PR: cardstack/boxel-skills#44

Comment on lines 71 to 83
let { status, content } = await this.cardService.getSource(codeUrl);
if (status === 404) {
await this.cardService.saveSource(codeUrl, '', 'create-file');
} else if (status === 200) {
if (content.trim() !== '') {
let nonConflictingUrl = await findNonConflictingFilename(
codeUrl.href,
(candidateUrl) => this.fileExists(candidateUrl),
);
let newCodeUrl = new URL(nonConflictingUrl);
await this.cardService.saveSource(newCodeUrl, '', 'create-file');
finalCodeUrl = newCodeUrl;

Copy link
Contributor

Choose a reason for hiding this comment

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

It might be elegant to delegate to a separate command to accomplish this.

Copy link
Contributor Author

@jurgenwerk jurgenwerk Jan 23, 2026

Choose a reason for hiding this comment

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

I'll check if I can use WriteTextFileCommand for this

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I adjusted WriteTextFileCommand to fit this case and used it in this command

content = [content, switchSubmodeInstruction]
.filter(Boolean)
.join('\n\n');
}
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not enthusiastic about having command-specific code in the ai prompt generation. Is this necessary?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

My intent was to not add more text to the skills prompt since this should be a rare case. I checked and we can achieve this by adding a line to the development skill and drop this new logic in the ai bot

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ai bot logic removed, and I added some extra instructions in the development skill: cardstack/boxel-skills@2719575#r2721123671

cursor[bot]

This comment was marked as outdated.

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

@jurgenwerk jurgenwerk force-pushed the cs-9640-when-trying-to-create-a-new-card-with-ai-it-will-sometimes branch from 5084d41 to 8bee425 Compare January 23, 2026 14:39
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.

3 participants