Skip to content

fix: insta project create name optional (recommended one-liner was unrunnable)#34

Merged
tonychang04 merged 1 commit into
mainfrom
fix/create-optional-name
Jul 15, 2026
Merged

fix: insta project create name optional (recommended one-liner was unrunnable)#34
tonychang04 merged 1 commit into
mainfrom
fix/create-optional-name

Conversation

@tonychang04

@tonychang04 tonychang04 commented Jul 15, 2026

Copy link
Copy Markdown
Member

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: name is 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). So insta project create runs 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 create name argument optional and resolving a safe default. This removes the zsh redirection error caused by <app-name>.

  • Bug Fixes
    • CLI now accepts project create [name]: explicit arg is slugified; otherwise prompt with cwd default (TTY) or use cwd (non-TTY/CI).
    • Added slugifyName and resolveProjectName with tests covering explicit arg, TTY prompt, and non-TTY defaults.
    • API request and output updated to use the resolved name.

Written for commit 13eaf34. Summary will update on new commits.

Review in cubic

… 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
@cursor

cursor Bot commented Jul 15, 2026

Copy link
Copy Markdown

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 jwfing left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM - approved.

@jwfing jwfing left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

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) returns slugifyName(nameArg) directly, but slugifyName yields "" for all-non-alnum input — e.g. insta project create "!!!" or create "---" both produce name: "", which is then POSTed to /orgs/:id/projects and echoed in info(...). The TTY branch (:43) and fromDir (: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.ts covers 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 in src/observe/scanner.ts (filePath.split('/').pop()), and the primary onboarding channel is curl … | 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 jwfing left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM - approved.

@jwfing jwfing left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

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:42if (nameArg) return slugifyName(nameArg). An all-symbol argument slugifies to "" (verified: slugifyName('@#$%') === ''), so insta project create "@#$" posts { name: "" } to POST /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:31 trims 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 raw name was posted verbatim; now insta project create "My App" creates my-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:41 uses cwd.split('/') rather than node:path basename; on Windows this won't split backslash paths. The CLI targets macOS/Linux (the bug is zsh-specific) so impact is low, but path.basename matches the existing node:path usage elsewhere in the repo.
  • Testability — resolveProjectName reads process.stdin.isTTY directly. src/commands/project.ts:43; the tests mutate that global (restored in afterEach) to reach the TTY branch. Injecting an isTTY flag alongside the already-injected prompt would avoid touching globals — the repo skill favors DI over mocking globals — though the restore-in-afterEach approach 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.

@jwfing jwfing left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM - approved.

@tonychang04 tonychang04 merged commit 7507d32 into main Jul 15, 2026
2 checks passed
@tonychang04 tonychang04 mentioned this pull request Jul 15, 2026
tonychang04 added a commit that referenced this pull request Jul 15, 2026
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>
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.

2 participants