Ins-48 feat: improve create & link UX — auto-org, subdirectories, next steps#60
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughOrganization auto-selection when exactly one org is returned; interactive directory-name prompt added with basename extraction, sanitization, and validation; created directory is made under the original CWD and Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
…ry, next steps - Skip org selection prompt when user has only one organization - Prompt for directory name and create project files in a subdirectory - Show next steps (cd + npm run dev) and suggested prompts for coding agents - Template projects suggest feature additions; blank projects suggest app ideas Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
ee37706 to
9f27201
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/commands/create.ts (1)
172-193:⚠️ Potential issue | 🟠 MajorMove the JSON-mode error behind the single-org fast path.
Line 177 throws before the new
orgs.length === 1branch runs, socreate --jsonstill fails for accounts that only have one organization. That makes the auto-select behavior interactive-only.Suggested fix
if (!orgId) { const orgs = await listOrganizations(apiUrl); if (orgs.length === 0) { throw new CLIError('No organizations found.'); } - if (json) { - throw new CLIError('Specify --org-id in JSON mode.'); - } if (orgs.length === 1) { orgId = orgs[0].id; - clack.log.info(`Using organization: ${orgs[0].name}`); + if (!json) clack.log.info(`Using organization: ${orgs[0].name}`); } else { + if (json) { + throw new CLIError('Multiple organizations found. Specify --org-id.'); + } const selected = await clack.select({ message: 'Select an organization:', options: orgs.map((o) => ({ value: o.id, label: o.name,🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/commands/create.ts` around lines 172 - 193, The JSON-mode error check is executed before the single-organization fast-path, preventing non-interactive auto-selection; move the check that throws "Specify --org-id in JSON mode." to after the orgs.length === 1 branch so that when orgs.length === 1 you auto-set orgId (using the orgs[0].id and logging via clack.log.info) and only enforce the JSON-mode error when there are multiple orgs and you would need to prompt via clack.select (use clack.isCancel to handle cancels). Ensure you still call listOrganizations(apiUrl) and preserve the existing throw for zero organizations.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/commands/create.ts`:
- Around line 271-287: The current prompt validates the raw input but then
normalizes it into dirName using path.basename(...) which can collapse inputs
like './' back to '.' or an existing folder; update the flow around inputDir,
dirName and projectDir in create.ts so you validate the normalized dirName
(after path.basename and replacement) for empty/invalid values ('.', '..', ''),
and compute projectDir = path.resolve(process.cwd(), dirName) before creating;
then check if projectDir already exists (use fs.stat or fs.access) and if so
abort with an error rather than calling fs.mkdir with { recursive: true }, and
only then call fs.mkdir(projectDir) and process.chdir(projectDir). Ensure
references to inputDir, dirName, projectDir, fs.mkdir and process.chdir are
updated accordingly.
---
Outside diff comments:
In `@src/commands/create.ts`:
- Around line 172-193: The JSON-mode error check is executed before the
single-organization fast-path, preventing non-interactive auto-selection; move
the check that throws "Specify --org-id in JSON mode." to after the orgs.length
=== 1 branch so that when orgs.length === 1 you auto-set orgId (using the
orgs[0].id and logging via clack.log.info) and only enforce the JSON-mode error
when there are multiple orgs and you would need to prompt via clack.select (use
clack.isCancel to handle cancels). Ensure you still call
listOrganizations(apiUrl) and preserve the existing throw for zero
organizations.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: d1f1688b-3d9d-4dfd-8164-7dd56cdd2cb0
📒 Files selected for processing (1)
src/commands/create.ts
…ory validation - Move JSON-mode org error after single-org check so auto-select works in both interactive and JSON modes - Validate directory name after normalization (rejects /, ./, etc.) - Reject existing directories instead of silently reusing them - Add unit tests for org selection logic and directory validation Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…or templates - Template projects: just point users to their coding agent - Blank projects: suggest app ideas (todo, Instagram clone, AI chatbot) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/commands/create.ts (1)
323-329:⚠️ Potential issue | 🟠 MajorTrack template bootstrap success separately from
hasTemplate.
hasTemplateonly reflects the requested template, not whether the scaffold actually landed on disk. BecausedownloadTemplate/downloadGitHubTemplatewarn and return normally on failure, Lines 366-469 can still runnpm install, offer deploy, and printnpm run devinstructions for an empty project directory. Have the download helpers return a success flag and gate the later template-only steps on that.
Based on learnings,downloadTemplateanddownloadGitHubTemplatecatch all errors internally and never rethrow them.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/commands/create.ts` around lines 323 - 329, The current code uses hasTemplate to decide later template-only steps but downloadTemplate and downloadGitHubTemplate swallow errors and return normally; change both downloadTemplate and downloadGitHubTemplate to return a boolean success flag (true when files were actually written) and update the caller in create.ts to await those functions into a new variable (e.g., const templateDownloaded = await downloadGitHubTemplate(...) or await downloadTemplate(...)) and then gate subsequent template-only work (npm install, deploy offer, printing "npm run dev" instructions) on templateDownloaded rather than hasTemplate so you don't run install/print instructions for an empty project; ensure the new boolean is passed/used where projectConfig/projectName/json/apiUrl are currently used.
🧹 Nitpick comments (1)
src/commands/create.test.ts (1)
10-25: Test the real helpers instead of re-implementing them here.These helpers duplicate the branching and normalization from
src/commands/create.ts, so the suite can stay green even if the command behavior drifts. I'd extract the directory/org-selection logic into shared pure functions and import those here, or drive the actual command with mocks.Also applies to: 81-101
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/commands/create.test.ts` around lines 10 - 25, The test currently re-implements the helpers sanitizeDirName, validateDirInput, and isValidNormalizedDir which duplicates logic from src/commands/create.ts; instead, import and use the real helper functions (or refactor create.ts to export shared pure functions for directory/org-selection) in the test so behavior stays in sync, or invoke the actual create command flow with appropriate mocks for filesystem/prompts to exercise the real helpers; update the test to remove the local copies (sanitizeDirName, validateDirInput, isValidNormalizedDir) and reference the exported functions from create.ts (or the new shared module) when asserting behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/commands/create.ts`:
- Around line 290-297: Wrap the setup steps after fs.mkdir(projectDir) and
process.chdir(projectDir) in a try/catch and track that the directory was
created (e.g., a createdDir flag); if any error occurs before the local project
linking step completes, remove the partially created projectDir (using
fs.rm/fs.rmdir) and rethrow the error. Update the block around projectDir,
dirExists, fs.mkdir and process.chdir so cleanup runs only when the directory
was newly created and linking has not succeeded.
---
Outside diff comments:
In `@src/commands/create.ts`:
- Around line 323-329: The current code uses hasTemplate to decide later
template-only steps but downloadTemplate and downloadGitHubTemplate swallow
errors and return normally; change both downloadTemplate and
downloadGitHubTemplate to return a boolean success flag (true when files were
actually written) and update the caller in create.ts to await those functions
into a new variable (e.g., const templateDownloaded = await
downloadGitHubTemplate(...) or await downloadTemplate(...)) and then gate
subsequent template-only work (npm install, deploy offer, printing "npm run dev"
instructions) on templateDownloaded rather than hasTemplate so you don't run
install/print instructions for an empty project; ensure the new boolean is
passed/used where projectConfig/projectName/json/apiUrl are currently used.
---
Nitpick comments:
In `@src/commands/create.test.ts`:
- Around line 10-25: The test currently re-implements the helpers
sanitizeDirName, validateDirInput, and isValidNormalizedDir which duplicates
logic from src/commands/create.ts; instead, import and use the real helper
functions (or refactor create.ts to export shared pure functions for
directory/org-selection) in the test so behavior stays in sync, or invoke the
actual create command flow with appropriate mocks for filesystem/prompts to
exercise the real helpers; update the test to remove the local copies
(sanitizeDirName, validateDirInput, isValidNormalizedDir) and reference the
exported functions from create.ts (or the new shared module) when asserting
behavior.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 8acce66e-ab46-4e89-a7a4-8dd5528f3a8d
📒 Files selected for processing (2)
src/commands/create.test.tssrc/commands/create.ts
If project creation or linking fails after the directory was created, roll back by removing the directory so retries don't hit "already exists". Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- `insforge link` now just links the project in current directory - `insforge link --template <name>` downloads template into a subdirectory - Auto-select org when only one exists (same as create) - Remove isDirEmpty auto-detection and interactive template selection - Show next steps and coding agent nudge Also in create: only prompt for directory when template is selected, blank projects use current directory. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…cise Raw link shows coding agent prompt suggestions; template link shows cd + npm run dev + nudge to add features. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… success - link: only saveProjectConfig in cwd when --template is NOT used (template flow saves in subdirectory instead) - create & link: check for package.json after template download before running npm install, deploy, or showing "npm run dev" instructions - Show warning if template download failed silently Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Summary
createandlink)createwith template prompts for directory name, creates subdirectory, downloads templatecreateblank uses current directory, shows coding agent prompt suggestionslink --template <name>downloads template into a new subdirectory (same UX as create)link(no template) just links in current directory, shows prompt suggestions/,.,..), rejects existing dirs, cleans up on failurecd+npm run dev+ agent nudge; blank/raw link shows app idea promptsTest plan
insforge create --template react— prompts for dir, creates subdir, downloads, shows next stepsinsforge create(blank) — uses cwd, shows prompt suggestionsinsforge link --template nextjs— links project, prompts for dir, downloads templateinsforge link— links in cwd, shows prompt suggestionsnpm run test:unitpasses (16 tests)🤖 Generated with Claude Code
Note
Improve
createandlinkUX with auto-org selection, subdirectory creation, and next stepscreateandlinkcommands now auto-select an organization when the account has exactly one org; in JSON mode with multiple orgs, an error is thrown requiring--org-id.createflows now prompt for a directory name, create a subdirectory under cwd, and run subsequent steps inside it; blank projects use cwd.linkcommand gains a--templateflag that downloads a starter template into a new subdirectory and installs dependencies; without the flag, it saves config in cwd and prints suggested prompts.cd <dir> && npm run dev).createcleans up the newly created directory if project linking fails, and only runsnpm install/ deploy prompts when apackage.jsonis present.linkno longer prompts interactively to choose templates, seeds.env.local, or offers a deploy prompt post-link.Macroscope summarized e8d2d28.