Skip to content

🤖 feat: create new git projects from the getting-started screen - #3923

Merged
ibetitsmike merged 7 commits into
mainfrom
mike/fix-2340-create-project
Aug 22, 2026
Merged

🤖 feat: create new git projects from the getting-started screen#3923
ibetitsmike merged 7 commits into
mainfrom
mike/fix-2340-create-project

Conversation

@ibetitsmike

Copy link
Copy Markdown
Contributor

Fixes #2340

Problem

The getting-started screen (and the Add Project modal) only accepts an existing directory or a repo to clone. When prototyping something new, users want Xum to create the project itself.

Change

  • Backend: projects.create accepts an optional initGit flag. With it set, ProjectService.create rejects an existing non-empty directory, creates the directory if needed, and initializes it as a git repository (git init -b main + an initial empty commit, extracted from the existing gitInit path so worktree/SSH runtimes get a born branch) before registering the project. On git failure, a directory we created is cleaned up.
  • Frontend: ProjectAddForm gains a third mode, "New project" (lucide FolderPlus), reusing ProjectCreateForm with a createNewGitRepo prop. Bare names resolve to the default projects directory via the existing backend resolution; the frontend consumes normalizedPath + projectConfig from the backend response. Surfaced on both the onboarding wizard's projects step and the Add Project modal. Keyboard accessible via the existing ToggleGroup + Enter-to-submit handling.

Testing

  • make static-check
  • bun test src/node/services/projectService.test.ts (initGit success on a new path, existing empty dir, non-empty dir rejection, file-path rejection, git-failure cleanup; red-green verified)
  • bun test src/browser/components/ProjectCreateModal/ProjectCreateModal.cloneAbort.test.tsx
  • Remote dogfood UAT (dev.coder.com) on this exact head passed: new-project creation from the wizard and modal, git repo born on main, worktree workspace creation, non-empty-dir error case, existing modes regression, keyboard-only flow.

Generated with xum • Model: anthropic:claude-fable-5 • Thinking: xhigh

@ibetitsmike

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

This comment has been minimized.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 66f0ce633f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/node/services/projectService.ts
Comment thread src/browser/components/ProjectCreateModal/ProjectCreateModal.tsx
Comment thread src/node/services/projectService.ts
Comment thread src/node/services/projectService.ts
Codex review fixes for #3923:
- reject initGit beneath a registered parent project (nested repo would
  invalidate the sub-project same-repository hierarchy)
- claim the leaf directory with a non-recursive mkdir so concurrent
  creates of the same path cannot delete each other's work
- roll back a .git created in a pre-existing directory when git init or
  the initial commit fails, so retries are not rejected as non-empty
- let the three-mode selector wrap inside narrow dialogs and pin a
  phone-viewport story
@ibetitsmike

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

This comment has been minimized.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 479b5a18c4

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/node/services/projectService.ts
…itGit parent check

- Windows CI: recursive mkdir of the parent throws EEXIST when a path
  component is a file; report it like ENOTDIR instead of misreading it
  as a leaf-creation race
- Codex P2: run the initGit nested-repository rejection against the
  canonical path too, so a symlinked alias into a registered checkout
  cannot bypass it
@ibetitsmike

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

This comment has been minimized.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 058dfac082

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/node/services/projectService.ts
Comment thread src/node/services/projectService.ts
Comment thread src/node/services/projectService.ts
Comment thread src/node/services/projectService.ts Outdated
Codex round-3 fixes for #3923:
- re-check the canonical parent inside the serialized transform so a
  parent registered concurrently (reached via symlink) cannot end up
  owning a nested repository
- serialize git initialization per canonical path so two initGit
  creates of the same pre-existing empty directory cannot interleave
  init and rollback
- verify config persistence after the transform (saveConfig swallows
  write failures) and roll back before reporting an error
- mark .git rollback before running git init so a failing init that
  leaves a partial .git is cleaned up too
@ibetitsmike

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

This comment has been minimized.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6d2271c6a3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/node/services/projectService.ts
The hierarchy-changed-descendant branch deliberately keeps the tree for
the winning descendant, but the .git this losing request created would
wrap the winner's checkout in an unregistered outer repository and make
retries fail the non-empty check. Remove only the .git we created.
@ibetitsmike

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

This comment has been minimized.

@ibetitsmike

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

This comment has been minimized.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5aeb130849

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/node/services/projectService.ts Outdated
Comment thread src/node/services/projectService.ts Outdated
- gitInit (the public banner path) now takes the same per-canonical-path
  claim as create(), so concurrent initializations cannot double-commit
  or delete each other's .git via the failure rollback
- when a plain create registers the same pre-existing directory while an
  initGit create is mid-flight, the losing initGit now strips the .git
  it created instead of leaving the winner's project silently converted
  into a repository
@ibetitsmike

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

This comment has been minimized.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ae9c936ac8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/node/services/projectService.ts Outdated
GIT_DIR/GIT_WORK_TREE in Xum's environment win over -C, redirecting
git init and the initial commit into an unrelated external repository
while the new project registers without a .git. Reuse the backup
feature's GIT_SCOPE_ENV_UNSET for both commands.
@ibetitsmike

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

This comment has been minimized.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. You're on a roll.

Reviewed commit: 9661a63743

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@ibetitsmike
ibetitsmike added this pull request to the merge queue Aug 22, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Aug 22, 2026
@ibetitsmike
ibetitsmike added this pull request to the merge queue Aug 22, 2026
Merged via the queue into main with commit cc633c9 Aug 22, 2026
19 of 20 checks passed
@ibetitsmike
ibetitsmike deleted the mike/fix-2340-create-project branch August 22, 2026 04:49
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.

allow users to create a new project from mux getting started screen

1 participant