Skip to content

feat(projects): add "New project" creation (mkdir + git init)#19

Closed
writingdeveloper wants to merge 1 commit into
mainfrom
feat/new-project
Closed

feat(projects): add "New project" creation (mkdir + git init)#19
writingdeveloper wants to merge 1 commit into
mainfrom
feat/new-project

Conversation

@writingdeveloper

Copy link
Copy Markdown
Owner

Summary

Adds a "+ New project" button to the projects toolbar that creates a new project folder under a scan root and git inits it, then opens it in a terminal with the active agent and refreshes the deck.

git init is not cosmetic: the scanner only surfaces folders containing a .git directory, so initialising the repo is what makes the new project appear in the deck.

What's new

  • shared/projectName.ts — pure, shared name validation reused by the main process (authoritative) and the renderer (instant feedback). Allows spaces/dots/hyphens, rejects illegal/reserved/too-long names, returns a trimmed canonical name.
  • main/createProject.tsmkdir + git init, guarded by isAllowedPath (the same guard used by open/openFolder, so a compromised renderer can't mkdir anywhere). Deps injectable for tests.
  • IPC project:create + preload bridge + global.d.ts type.
  • renderer/newProjectModal.ts — small modal: scan-root picker with a browse fallback (a freshly picked dir registers as a scan root), live path preview, inline validation errors. Toolbar button + localized label.
  • i18n ko/en/ja/zh, modal styles, QA harness modal scene.

Decisions

  • Scope: minimal (empty folder + git init) — fits DevDeck's "command deck" identity; no template/scaffold system.
  • Location: created under a scan root so it auto-appears on the next scan (browse fallback registers the picked dir as a root).
  • After create: opens in a terminal with the active agent (claude/codex).

Test plan

  • tsc + renderer bundle clean
  • Unit tests: 162 passing (+16 — projectName 10, createProject 6), incl. guard/validation/dup/git-unavailable paths
  • Playwright QA harness: 0 console / 0 page errors across ko/en/ja/zh; modal default + validation-error states captured
  • Real git init path verified end-to-end in a temp dir (gitInitialized: true, .git created)

🤖 Generated with Claude Code

Add a "+ New project" button to the projects toolbar that opens a small
modal to create a new project folder under a scan root and `git init` it
— git init is what makes the scanner discover the folder. On success the
new project opens in a terminal with the active agent and the deck refreshes.

- shared/projectName.ts: pure, shared name validation reused by main
  (authoritative) and the renderer (live feedback); allows spaces/dots/
  hyphens, rejects illegal/reserved/too-long names, trims canonical name
- main/createProject.ts: mkdir + git init guarded by isAllowedPath (same
  guard as open/openFolder); deps injectable for tests
- IPC project:create, preload bridge, global.d.ts type
- renderer modal (newProjectModal.ts): scan-root picker + browse fallback,
  live path preview, inline validation errors; toolbar button + label
- i18n ko/en/ja/zh, modal styles, QA harness modal scene
- tests +16 (162 total); Playwright QA 0 console/page errors

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

@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: 865ecca255

ℹ️ 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/main/createProject.ts

const check = validateProjectName(rawName);
if (!check.ok) return { ok: false, error: check.reason };
if (!isAllowedPath(folders, parent)) return { ok: false, error: 'parent_not_allowed' };

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Resolve parent symlinks before mkdir

When a configured scan root contains a symlink to another directory, this guard accepts a renderer-supplied parent like <root>/link because isAllowedPath only checks the resolved string prefix, but mkdirSync(join(parent, name)) then follows the symlink and creates the project outside the allowed roots. Since project:create is exposed to the renderer and this path is used for filesystem writes, resolve/realpath the parent or reject symlink parents before creating the directory.

Useful? React with 👍 / 👎.

writingdeveloper added a commit that referenced this pull request Jun 13, 2026
A "+ New project" button in the projects toolbar opens a small modal to
create a new project folder under a scan root and `git init` it — git init
is what makes the scanner discover the folder. On success the project opens
in a terminal with the active agent and the deck refreshes.

- shared/projectName.ts: pure, shared name validation reused by main
  (authoritative) and the renderer (live feedback); allows spaces/dots/
  hyphens, rejects illegal/reserved/too-long names, returns trimmed name
- main/createProject.ts: mkdir + git init guarded by isAllowedPath (same
  guard as open/openFolder); deps injectable for tests
- ipc.ts: project:create; preload + global.d.ts bridge/types
- renderer/newProjectModal.ts: scan-root picker + browse fallback, live
  path preview, inline validation errors; toolbar button + localized label
- locales: proj.new + newproj.* (ko/en/ja/zh); modal styles; QA modal scene
- tests +16 (162 total); Playwright QA 0 console/page errors

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@writingdeveloper writingdeveloper deleted the feat/new-project branch June 13, 2026 21:12
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.

1 participant