fix: insta project create name optional (recommended one-liner was unrunnable)#34
Conversation
… paste-run The console's empty-state onboarding recommended 'curl … | sh && insta project create <app-name>', but the <app-name> placeholder is unrunnable: zsh reads <…> as redirection → 'parse error near \n'. The RECOMMENDED command couldn't be pasted. Name is now optional: explicit arg wins; else prompt with the cwd dir-name default (TTY); else use the dir name (non-TTY/CI). So 'insta project create' runs clean. TDD: slugify + resolver, 4 cases. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GMbAe5K1RfwaAcge5inX7P
|
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
jwfing
left a comment
There was a problem hiding this comment.
Review: fix: insta project create name optional
Summary: Makes the insta project create name argument optional and resolves a safe default (explicit arg → slugified; TTY → prompt with cwd basename default; non-TTY/CI → cwd basename), fixing the unrunnable <app-name> one-liner. The change is well-scoped, tested, and solves the stated problem.
Requirements context: No matching spec/plan found — this repo has no docs/superpowers/ or docs/specs/ directory. Assessed against the PR description and the repo-local developing-insta-cli skill (gates are typecheck + vitest; DI/injected-collaborator test pattern). The injected prompt/cwd params on resolveProjectName follow that pattern nicely.
Findings
Critical
(none)
Suggestion
-
Functionality — explicit-arg path has no empty-slug fallback (
src/commands/project.ts:42).if (nameArg) return slugifyName(nameArg)returnsslugifyName(nameArg)directly, butslugifyNameyields""for all-non-alnum input — e.g.insta project create "!!!"orcreate "---"both producename: "", which is then POSTed to/orgs/:id/projectsand echoed ininfo(...). The TTY branch (:43) andfromDir(:41) both guard with|| fromDir/|| 'app', so only the explicit-arg branch is unguarded. Verified locally:slug("!!!") === "". Suggest applying the same fallback (e.g.return slugifyName(nameArg) || fromDir) so no code path can emit an empty name. Low blast radius (requires pathological input; the no-arg happy path the PR targets is fine), hence Suggestion not Critical. -
Software engineering —
slice(0, 40)runs after the trailing-hyphen trim (src/commands/project.ts:31). Because.slice(0, 40)is the last operation, truncating a name at a hyphen boundary re-introduces a trailing hyphen the earlier.replace(/^-+|-+$/g, '')was meant to remove. Verified:slug("a".repeat(39) + "-bcd")→"aa␣…a-"(ends in-). Reordering to trim after the slice (or.slice(0,40).replace(/-+$/,'')) keeps 40-char names clean. Cosmetic, so Suggestion. -
Software engineering — tests don't cover the two edge cases above.
test/create-name.test.tscovers the happy paths (slugify, explicit arg, TTY prompt + Enter default, non-TTY default) well, but neither the empty-slug fallback nor the >40-char truncation is exercised. Adding a case for each would lock in the fixes and match the "every behavior has a test" convention.
Information
- Windows basename extraction (
src/commands/project.ts:41).cwd.split('/')won't split backslash paths, so on Windows the whole path would slugify into one long name. This mirrors the existing convention insrc/observe/scanner.ts(filePath.split('/').pop()), and the primary onboarding channel iscurl … | sh(unix), so it's consistent with the codebase and not a regression — noting only in case Windows is a target platform for the packaged binaries. - Nice touch: prompting on
stderr(promptName,:8-12) keeps piped stdout clean — good instinct for a CLI.
Security: No security-relevant concerns. New user input (name) is sent as a JSON body param via api.request (parameterized, not string-interpolated into a URL/SQL/shell), and slugifyName further restricts it to [a-z0-9-]. No secrets logged, no auth/authorization changes, no new dependencies.
Performance: No concerns — no loops, queries, or I/O added beyond a single interactive prompt gated on isTTY.
Verdict: approved (informational)
Zero Critical findings. The three Suggestions are worth a quick follow-up but are non-blocking; a human still provides the explicit GitHub approval via the approve flow.
jwfing
left a comment
There was a problem hiding this comment.
Review: fix: insta project create name optional
Summary: Makes the project create name argument optional with a well-designed resolution chain (explicit arg → TTY prompt with cwd default → cwd basename), fixing the unpasteable zsh one-liner; the fix is correct and covered by tests, with a few non-blocking edge-case gaps.
Requirements context
No matching spec/plan found — this repo has no docs/superpowers/ or docs/specs/ directory. Assessed against the PR description, the referenced onboarding bug, and repo conventions in .claude/skills/developing-insta-cli/SKILL.md. The core intent (insta project create runnable with no placeholder arg) is met: the no-arg paths both fall back safely and create [name] is registered in src/index.ts:80.
Findings
Critical
(none)
Suggestion
- Functionality / Testing — explicit-arg path has no empty-slug fallback.
src/commands/project.ts:42—if (nameArg) return slugifyName(nameArg). An all-symbol argument slugifies to""(verified:slugifyName('@#$%') === ''), soinsta project create "@#$"posts{ name: "" }toPOST /orgs/:id/projects. The two no-arg paths (:41,:43) both guard with|| 'app'/|| fromDir, but the explicit-arg path doesn't. Apply the same fallback (e.g.return slugifyName(nameArg) || fromDir) and add a regression test — the current suite doesn't exercise an empty slug. Low blast radius (requires a deliberately garbage arg, and the API likely rejects empty names), hence non-blocking.
Information
- Functionality —
slice(0, 40)can reintroduce a trailing hyphen.src/commands/project.ts:31trims hyphens before truncating, so a 41-char name truncated at a hyphen boundary yields...a-(verified). If the API rejects trailing hyphens, slice-then-trim would be safer. - Behavior change — explicit args are now slugified.
src/commands/project.ts:42— previously the rawnamewas posted verbatim; nowinsta project create "My App"createsmy-app. This is intended per the PR and README examples are already slug-style, so flagging only so it's a conscious decision (assumes the API accepts/expects slugs). - Portability — basename via manual split.
src/commands/project.ts:41usescwd.split('/')rather thannode:pathbasename; on Windows this won't split backslash paths. The CLI targets macOS/Linux (the bug is zsh-specific) so impact is low, butpath.basenamematches the existingnode:pathusage elsewhere in the repo. - Testability —
resolveProjectNamereadsprocess.stdin.isTTYdirectly.src/commands/project.ts:43; the tests mutate that global (restored inafterEach) to reach the TTY branch. Injecting anisTTYflag alongside the already-injectedpromptwould avoid touching globals — the repo skill favors DI over mocking globals — though the restore-in-afterEachapproach here is acceptable.
Security
No security-relevant changes. The resolved name is strictly slugified to [a-z0-9-] before reaching the API request body, so there's no new injection surface; no new dependencies (node:readline/promises is a builtin); no secrets, auth, or authorization touched. The prompt writes to stderr to keep piped stdout clean — a nice touch.
Performance
No concerns — constant-time string work on a short input, no new queries, loops, or blocking I/O in a hot path.
Verdict
approved (no Critical findings). The fix is correct, focused, and tested; the Suggestion and Information items are optional polish. Note: this is the bot's informational verdict — the GitHub green-checkmark approval remains a separate human action.
Ships: optional project-create name (paste-runnable one-liner, #34), next-action Next: hints (#32), insta compute start/stop/suspend/status lifecycle commands, agents.instacloud.com canonical docs (#31). Claude-Session: https://claude.ai/code/session_01GMbAe5K1RfwaAcge5inX7P Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
The recommended onboarding command couldn't be pasted. The console's empty-state showed
curl … | sh && insta project create <app-name>— but zsh parses<app-name>as I/O redirection →zsh: parse error near '\n'(user hit this live). A recommended workflow that errors on paste is the worst onboarding bug.Fix:
nameis now optional (create [name]). Explicit arg wins (slugified); else prompt with the current directory name as the default (TTY, Enter accepts); else use the dir name (non-TTY/CI). Soinsta project createruns clean with no placeholder. TDD:slugifyName+resolveProjectName, 4 cases; full suite green.Frontend empty-state copy drops the
<app-name>placeholder in a companion PR.🤖 Generated with Claude Code
https://claude.ai/code/session_01GMbAe5K1RfwaAcge5inX7P
Summary by cubic
Fixes the paste-and-run onboarding by making the
insta project createname argument optional and resolving a safe default. This removes the zsh redirection error caused by<app-name>.project create [name]: explicit arg is slugified; otherwise prompt with cwd default (TTY) or use cwd (non-TTY/CI).slugifyNameandresolveProjectNamewith tests covering explicit arg, TTY prompt, and non-TTY defaults.Written for commit 13eaf34. Summary will update on new commits.