Skip to content

TUI: init command without inline prompt does not accept follow-up message as project description #216

Closed

Description

@williamhallatt

Summary

When running npx @bradygaster/squad-cli in a fresh repo (no .squad/team.md), the init command two-step flow is broken:

  1. User types /init (no args) → TUI shows guidance: "To cast your Squad team, just type what you want to build."
  2. User types their project description → TUI responds with ⚠ No Squad team found. Run /init to create your team first.

The init state is never persisted between the command and the follow-up message.

Steps to Reproduce

npx @bradygaster/squad-cli
> /init
# guidance shown
> We need markdown specialists and an architect for...
# ⚠ No Squad team found. Run /init to create your team first.

Root Cause

Three-part gap across:

  • commands.ts — handleInit(): When called with no args, returns { handled: true, output: "guidance text" } only. No state flag is set to indicate the shell is awaiting an init prompt.
  • App.tsx: No awaitingInitPrompt state is tracked after the no-args init command output is displayed.
  • index.ts — handleDispatch() (line ~1023): The team-file existence guard runs unconditionally before any init check. Since team.md doesn't exist, it shows the error and returns early — even when the user was responding to the init guidance.

Expected Behaviour

After the no-args init command shows guidance, the TUI should enter a "waiting for init prompt" state. The user's next message should bypass the team-file guard and be routed directly to handleInitCast as the project description.

Fix Outline

  1. commands.ts — Add awaitInitPrompt?: boolean to CommandResult; set it on the no-args init path.
  2. App.tsx — Track an awaitingInitPrompt ref; on next non-slash-command dispatch, set skipCastConfirmation: true on the parsed input and clear the ref.
  3. index.ts — In handleDispatch, when parsed.skipCastConfirmation is true and team.md does not exist, skip the team-file guard and go straight to handleInitCast.

Activity

  1. williamhallatt commented on Mar 6, 2026

    @williamhallatt
    ContributorAuthor

    Update: Second root cause found and fixed

    While smoke-testing the original fix, a second bug was found in the init flow:

    New bug: createTeam silently skips creating team.md in fresh projects

    Root cause: packages/squad-cli/src/cli/core/cast.ts — createTeam() only ran the if (existsSync(teamPath)) update path for both team.md and routing.md. In a completely fresh project (no .squad/ directory at all), neither file exists, so both were silently skipped.

    Observed UX:

    ✅ Team hired! 7 members created.
    📌 Routing your message to the team now...
    Squad: This project doesn't have a Squad team yet. (3.8s)
    

    Fix: Added else branches to both team.md and routing.md creation in createTeam — when the files don't exist they are created from scratch with the full structure. The ## Members table is populated with data rows so hasRosterEntries() returns true and the coordinator enters Team Mode correctly on the next dispatch.

    Tests added: 9 new integration tests in test/cast-parser.test.ts covering:

    • Fresh project creates team.md with ## Members data rows
    • Fresh project creates routing.md
    • Project description included in header
    • hasRosterEntries() passes after createTeam (coordinator regression guard)
    • Built-in Scribe and Ralph added automatically
    • Agent charter and history files created for each member
    • Existing project Members section updated without clobbering surrounding content
  2. bradygaster commented on Mar 7, 2026

    @bradygaster
    Collaborator

    ✅ Fixed by PR #217 (merged commit 20970f9) — init no-args behavior corrected.

    Closed as part of v0.8.21 release wave cleanup.

  3. bradygaster commented on Mar 7, 2026

    @bradygaster
    Collaborator

    Great UX catch, @williamhallatt! The init flow breaking when users try to provide their project description (instead of flags) is a classic onboarding gap. Your fix outline (track awaitInitPrompt state, skip the team-file guard) is clean. Looking forward to getting this in! 🎯

    — McManus 📝, on behalf of the Squad

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    release:nextTargeted for next release

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions