Skip to content

Deft Bootstrap CLI with TUI #12

@jsgoecke

Description

@jsgoecke

Feature Specification: Deft Bootstrap CLI with TUI

Status: Draft
Date: 2026-02-20
Inspired by: github/spec-kit specify-cli


Problem Statement

Deft currently has a 2,314-line monolithic Python script (run) on the master branch that provides CLI commands and a Textual TUI. This script:

  • Is not distributable (no pip install / uv tool install path)
  • Lives inside the framework directory itself (users run ./deft/run)
  • Bundles framework content with tooling
  • Has no strategy awareness (master branch doesn't know about beta's strategies system)
  • Has no feature branching automation (the biggest gap vs spec-kit)
  • Has no agent-specific configuration generation

Meanwhile, spec-kit ships a proper Python package (specify-cli) installable via uv tool install with a specify entry point, agent detection for 17+ tools, and shell script automation for branch/directory scaffolding.

Deft needs a standalone, distributable CLI tool that bootstraps projects with the deft framework, supports the strategies system, automates feature branching, and provides both CLI and TUI interfaces.


User Scenarios

User Story 1 — New Project Bootstrap (Priority: P1)

A developer wants to start a new project using the deft framework.

Why this priority: This is the primary entry point for all deft users.

Journey: The developer installs the deft CLI globally, runs deft init my-project, selects a strategy, defines principles, picks their AI agent, and gets a fully scaffolded project ready for specification work.

Independent Test: Run deft init test-project --strategy default --ai claude and verify the output directory structure.

Acceptance Scenarios:

  1. Given the CLI is installed, When the user runs deft init my-project, Then an interactive setup wizard collects project name, strategy, principles, AI agent, and tech stack, and creates a scaffolded project directory.

  2. Given the CLI is installed, When the user runs deft init . --here, Then the framework is installed into the current directory without creating a new subdirectory.

  3. Given the CLI is installed, When the user runs deft init my-project --strategy speckit --ai claude, Then the project is created non-interactively with the speckit strategy and Claude Code agent configuration.

User Story 2 — TUI Wizard Mode (Priority: P1)

A developer prefers a visual, guided experience over remembering CLI flags.

Why this priority: TUI is a differentiator vs spec-kit and already exists in deft master.

Journey: The developer runs deft with no arguments (or deft tui), gets a full-screen terminal interface with menu navigation, form inputs, and step-by-step guidance through bootstrap, project config, and spec generation.

Acceptance Scenarios:

  1. Given the CLI is installed and Textual is available, When the user runs deft with no arguments, Then the TUI wizard launches with a main menu.

  2. Given the TUI is running, When the user selects "New Project", Then a guided form collects project details with strategy selection, principle definition, and AI agent choice.

  3. Given Textual is not installed, When the user runs deft with no arguments, Then the CLI falls back to the standard interactive prompts (rich/readline).

User Story 3 — Feature Branch Creation (Priority: P1)

A developer using the speckit strategy wants to start a new feature with proper branch and directory scaffolding.

Why this priority: This is the single biggest gap vs spec-kit and the primary user request.

Journey: The developer runs deft feature "add user authentication", which auto-generates a branch name, finds the next feature number, creates the branch, and scaffolds the spec directory.

Acceptance Scenarios:

  1. Given a deft project with speckit strategy, When the user runs deft feature "add user authentication", Then the CLI creates branch 001-user-auth, directory specs/001-user-auth/, and copies spec.md template into it.

  2. Given branches 001-user-auth and 002-payment-flow already exist, When the user runs deft feature "analytics dashboard", Then the CLI creates branch 003-analytics-dashboard (auto-incremented).

  3. Given a deft project with default strategy, When the user runs deft feature "...", Then the CLI creates a branch but uses the default strategy's artifact structure (PRD.md + SPECIFICATION.md) instead of speckit's.

User Story 4 — Agent Configuration (Priority: P2)

A developer wants to set up their AI agent's configuration so slash commands and context files work out of the box.

Why this priority: Agent integration is what makes deft actionable vs just documentation.

Journey: The developer runs deft init my-project --ai claude and gets .claude/commands/ populated with strategy-appropriate slash commands, plus a CLAUDE.md that references the deft framework files.

Acceptance Scenarios:

  1. Given the user selects Claude as their AI agent, When project init completes, Then .claude/commands/ contains slash command files derived from the selected strategy's phases.

  2. Given the user selects a different agent (Gemini, Copilot, Cursor, etc.), When project init completes, Then the agent-specific directory is populated with equivalent command files in that agent's format.

  3. Given no AI agent is specified, When project init completes, Then no agent-specific directories are created, but a message suggests running deft agent <name> later.

User Story 5 — Project Health Check (Priority: P2)

A developer wants to verify their deft installation and tools are working.

Why this priority: Reduces support burden and debugging time.

Acceptance Scenarios:

  1. Given the CLI is installed, When the user runs deft check, Then the CLI verifies git, task runner, AI agent CLI tools, and reports status for each.

  2. Given the CLI is installed, When the user runs deft doctor, Then a detailed diagnostic runs including Python version, optional dependencies (rich, textual), framework file integrity, and strategy validation.

User Story 6 — Existing Project Adoption (Priority: P2)

A developer wants to add deft to an existing project that already has code.

Why this priority: Most real adoption happens in existing codebases, not greenfield.

Acceptance Scenarios:

  1. Given an existing project with source code, When the user runs deft init . --here, Then deft is installed without overwriting existing files, .gitignore is appended (not replaced), and existing Taskfile.yml is preserved.

  2. Given deft is already installed, When the user runs deft init . --here, Then the CLI detects the existing installation and offers to update/merge rather than overwrite.

User Story 7 — Strategy Management (Priority: P3)

A developer wants to switch strategies or view available strategies.

Acceptance Scenarios:

  1. Given a deft project, When the user runs deft strategy list, Then available strategies are displayed with descriptions and phase counts.

  2. Given a deft project using default strategy, When the user runs deft strategy set speckit, Then project.md is updated to reference the speckit strategy.


Requirements

Functional Requirements

  • FR-001: CLI MUST be installable via uv tool install and pip install as a standalone package named deft-cli
  • FR-002: CLI MUST provide a deft entry point command accessible from PATH after installation
  • FR-003: deft init <project-name> MUST create a new project directory with full deft framework scaffolding
  • FR-004: deft init . --here MUST install deft into the current directory without creating a subdirectory
  • FR-005: deft init MUST support --strategy flag to select a development strategy (default, speckit, or custom)
  • FR-006: deft init MUST support --ai flag to configure agent-specific files (claude, gemini, copilot, cursor, etc.)
  • FR-007: deft feature "<description>" MUST auto-generate a branch name, find the next feature number, create the branch, and scaffold the spec directory according to the active strategy
  • FR-008: Feature numbering MUST scan remote branches, local branches, and specs/ directories to find the next available number
  • FR-009: TUI mode MUST launch when deft is run with no arguments (if Textual is available)
  • FR-010: TUI MUST provide guided forms for init, feature creation, bootstrap, and project configuration
  • FR-011: CLI MUST fall back gracefully when optional dependencies (rich, textual) are not installed
  • FR-012: deft check MUST verify installed tools (git, task runner, AI agent CLIs) and report status
  • FR-013: deft bootstrap MUST create/update user.md with personal preferences
  • FR-014: deft project MUST create/update project.md with project-specific configuration
  • FR-015: Agent configuration MUST generate slash command files appropriate to the selected strategy's phases
  • FR-016: deft strategy list MUST display available strategies with descriptions
  • FR-017: deft strategy set <name> MUST update project.md to reference the selected strategy
  • FR-018: deft update MUST update the deft framework files to the latest version
  • FR-019: deft validate MUST check framework file integrity and configuration consistency

Non-Functional Requirements

  • NFR-001: Performance — CLI commands MUST complete in under 3 seconds (excluding network operations)
  • NFR-002: Compatibility — MUST support Python 3.10+ on macOS, Linux, and Windows
  • NFR-003: Dependencies — Core functionality MUST work with only typer and standard library; rich and textual are optional enhancements
  • NFR-004: Size — The installed package MUST be under 5MB (framework markdown files included)
  • NFR-005: Offline — All commands except deft update MUST work fully offline
  • NFR-006: Idempotency — Running deft init . --here multiple times MUST NOT corrupt existing project files
  • NFR-007: No data loss — MUST NEVER overwrite user-modified files without explicit --force flag

Architecture Overview

Package Structure

deft-cli/
├── pyproject.toml              # Package metadata, entry point: deft = "deft_cli:main"
├── src/
│   └── deft_cli/
│       ├── __init__.py         # Main app, typer commands
│       ├── tui.py              # Textual TUI screens (optional import)
│       ├── agents.py           # Agent configuration registry + generators
│       ├── branching.py        # Feature branch creation + numbering
│       ├── strategies.py       # Strategy detection, listing, switching
│       ├── scaffold.py         # Directory/file creation for init
│       └── templates/          # Embedded framework files
│           ├── framework/      # Core deft markdown files (main.md, coding/, scm/, etc.)
│           ├── strategies/     # Strategy definitions (default.md, speckit.md)
│           ├── commands/       # Agent command templates per strategy
│           └── project.md.template
├── tests/
│   ├── test_init.py
│   ├── test_feature.py
│   ├── test_agents.py
│   ├── test_branching.py
│   └── test_strategies.py
└── README.md

Command Tree

deft                            # No args: launch TUI (or show help)
deft init <name>                # Create new project
deft init . --here              # Install in current directory
deft feature "<description>"    # Create feature branch + spec scaffold
deft bootstrap                  # Set up user.md
deft project                    # Configure project.md
deft strategy list              # List available strategies
deft strategy set <name>        # Switch strategy
deft agent <name>               # Add/reconfigure AI agent
deft check                      # Verify installed tools
deft doctor                     # Detailed diagnostics
deft validate                   # Check framework integrity
deft update                     # Update framework files
deft version                    # Show version info

Key Design Decisions

1. Typer over Cobra (Go) or Click

The existing deft codebase uses Python. Spec-kit uses Python + Typer. Staying with Python + Typer:

  • Preserves existing TUI code (Textual)
  • Matches spec-kit's packaging model (uv tool install)
  • Keeps the optional dependency pattern (rich, textual as extras)
  • Allows reuse of deft master's 2,314 lines of battle-tested CLI logic

2. Framework Files Embedded in Package

Unlike the current model where run lives inside the framework directory, the new CLI embeds framework files as package data:

Current:  project/deft/run          (script inside framework)
New:      ~/.local/bin/deft          (installed CLI)
          project/deft/              (framework files, copied on init)

This means deft init copies framework files from the installed package into the target project. Updates happen via deft update, which pulls new framework files from the package.

3. Strategy-Aware Feature Branching

The deft feature command adapts its behavior based on the active strategy:

Strategy Branch Pattern Directory Structure Template Files
default NNN-feature-name specs/NNN-feature-name/ PRD.md, SPECIFICATION.md
speckit NNN-feature-name specs/NNN-feature-name/ spec.md, plan.md, tasks.md
rapid NNN-feature-name specs/NNN-feature-name/ SPECIFICATION.md

4. Agent Command Generation

Each strategy defines phases. Each phase maps to a slash command. The CLI generates agent-specific command files based on the intersection of strategy phases and agent format:

Strategy: speckit (5 phases)
Agent: claude

Generates:
  .claude/commands/
    deft-specify.md       # Phase 2: Create spec
    deft-clarify.md       # Between Phase 2-3: Clarify ambiguities
    deft-plan.md          # Phase 3: Generate plan
    deft-tasks.md         # Phase 4: Generate tasks
    deft-implement.md     # Phase 5: Execute tasks
    deft-analyze.md       # Cross-artifact analysis

For other agents, the same content is formatted for their conventions:

  • Gemini: TOML format in .gemini/commands/
  • Copilot: Markdown in .github/agents/
  • Cursor: Markdown in .cursor/commands/
  • Generic: User-specified directory via --ai-commands-dir

Feature Branch Automation Detail

This is the most critical new capability. The flow for deft feature "add user authentication":

1. Read project.md to determine active strategy
2. Parse description → short name: "user-auth"
3. git fetch --all --prune
4. Scan for highest feature number:
   a. Remote branches: git ls-remote --heads origin | grep NNN-*
   b. Local branches: git branch | grep NNN-*
   c. Spec directories: ls specs/ | grep NNN-*
5. Next number = max(all found) + 1, or 1 if none found
6. Create branch: git checkout -b 001-user-auth
7. Create directory: specs/001-user-auth/
8. Copy strategy-appropriate templates into directory
9. Report: branch name, spec path, next command to run

Short Name Generation Rules

  • Extract 2-4 most meaningful keywords from description
  • Use action-noun format when possible
  • Preserve technical terms and acronyms
  • Lowercase, hyphen-separated
  • Examples:
    • "add user authentication" → user-auth
    • "implement OAuth2 for the API" → oauth2-api
    • "fix payment processing timeout" → fix-payment-timeout
    • "create analytics dashboard" → analytics-dashboard

TUI Design

Main Menu

┌─────────────────────────────────────────┐
│              Deft v1.0.0                │
│     Specification-Driven Development    │
├─────────────────────────────────────────┤
│                                         │
│   New Project .... Create from scratch  │
│   Feature ........ Start new feature    │
│   Bootstrap ...... User preferences     │
│   Project ........ Project config       │
│                                         │
│   Strategy ....... View/switch          │
│   Agent .......... Configure AI agent   │
│   Check .......... Verify tools         │
│   Validate ....... Check framework      │
│                                         │
│   README ......... View documentation   │
│   Help ........... Show help            │
│   Exit ........... Quit                 │
│                                         │
└─────────────────────────────────────────┘

New Project Screen

┌─────────────────────────────────────────┐
│           New Project Setup             │
├─────────────────────────────────────────┤
│                                         │
│  Project name:  [________________]      │
│                                         │
│  Strategy:                              │
│    (o) DEFaulT - Interview → PRD → Spec │
│    ( ) SpecKit - 5-phase SDD workflow   │
│    ( ) Rapid   - Quick specification    │
│                                         │
│  AI Agent:                              │
│    ( ) Claude Code                      │
│    ( ) Gemini CLI                       │
│    (o) GitHub Copilot                   │
│    ( ) Cursor                           │
│    ( ) None                             │
│                                         │
│  Principles:                            │
│    [x] Test-First                       │
│    [x] Spec-Driven                      │
│    [ ] Library-First                    │
│    [x] No Premature Abstraction (anti)  │
│    [ ] Custom: [________________]       │
│                                         │
│  Tech stack:    [________________]      │
│  Project type:                          │
│    [x] CLI  [ ] API  [ ] Web  [ ] Lib  │
│                                         │
│  [Submit]                  [Cancel]     │
│                                         │
└─────────────────────────────────────────┘

Feature Branch Screen

┌─────────────────────────────────────────┐
│          New Feature Branch             │
├─────────────────────────────────────────┤
│                                         │
│  Describe the feature:                  │
│  [add user authentication with OAuth2 ] │
│                                         │
│  Generated branch: 003-user-auth-oauth2 │
│  Spec directory:   specs/003-user-auth- │
│                    oauth2/              │
│                                         │
│  Strategy: speckit                      │
│  Templates to create:                   │
│    [x] spec.md                          │
│    [x] plan.md (empty)                  │
│    [x] tasks.md (empty)                 │
│                                         │
│  [Create Branch]           [Cancel]     │
│                                         │
└─────────────────────────────────────────┘

Differences from Spec-Kit's specify CLI

Aspect Spec-Kit specify Deft deft (proposed)
TUI mode None Full Textual TUI with form screens
Strategy selection Implicit (speckit only) Explicit: --strategy default|speckit|rapid
Feature branching Built into /speckit.specify slash command Standalone deft feature CLI command
Principles Via /speckit.constitution slash command Via deft init wizard + deft project
Agent support 17+ agents in AGENT_CONFIG dict Start with top 5 (claude, gemini, copilot, cursor, codex), expand
Slash command generation Copies fixed templates per agent Generates commands dynamically from strategy phases
Framework files Downloads from GitHub on init Embedded in package, copied on init
Offline support Requires network for init (GitHub download) Fully offline (files bundled)
RFC2119 notation Standard prose Compact symbols (!/~//?) in all generated files
Extension system Full RFC + catalog Not in v1.0 scope
Distribution uv tool install specify-cli --from git+https://github.com/... uv tool install deft-cli (PyPI) or --from git+

Output Directory Structure

After running deft init my-project --strategy speckit --ai claude:

my-project/
├── .claude/
│   └── commands/
│       ├── deft-specify.md
│       ├── deft-clarify.md
│       ├── deft-plan.md
│       ├── deft-tasks.md
│       ├── deft-implement.md
│       └── deft-analyze.md
├── CLAUDE.md                   # References deft/ framework files
├── deft/
│   ├── main.md
│   ├── core/
│   │   ├── project.md          # Populated with user's choices
│   │   └── user.md             # If bootstrap was run
│   ├── coding/
│   │   └── coding.md
│   ├── scm/
│   │   ├── git.md
│   │   └── github.md
│   ├── strategies/
│   │   ├── README.md
│   │   ├── default.md
│   │   └── speckit.md
│   ├── templates/
│   │   ├── spec-template.md
│   │   ├── plan-template.md
│   │   └── tasks-template.md
│   └── meta/
│       └── code-field.md
├── specs/                      # Empty, ready for features
├── secrets/
│   └── .gitkeep
├── docs/
├── Taskfile.yml
├── .gitignore
└── README.md

Migration Path

From Existing Deft run Script

Users currently using ./deft/run should be able to:

  1. Install the new CLI: uv tool install deft-cli
  2. Run deft init . --here in their project to upgrade
  3. The old run script is no longer needed (can be deleted)
  4. All existing project.md and user.md files are preserved

From Spec-Kit

Users migrating from spec-kit should be able to:

  1. Install deft CLI: uv tool install deft-cli
  2. Run deft init . --here --strategy speckit --ai claude
  3. Existing specs/ directories are detected and preserved
  4. Feature numbering picks up from existing branch/spec numbers

Success Criteria

  • SC-001: A developer can go from uv tool install deft-cli to a fully scaffolded project with strategy, principles, and agent config in under 5 minutes
  • SC-002: deft feature creates numbered branches with correct spec directories matching the active strategy
  • SC-003: Feature numbering correctly auto-increments across remote branches, local branches, and spec directories with no collisions
  • SC-004: TUI wizard provides equivalent functionality to all CLI commands with guided forms
  • SC-005: Generated slash commands work correctly in the target AI agent (tested with Claude Code at minimum)
  • SC-006: CLI works fully offline for all commands except deft update
  • SC-007: Existing deft run script users can migrate without losing configuration

Assumptions

  • Python 3.10+ is the minimum (aligns with Typer's modern type hint support)
  • uv is the preferred installer but pip must also work
  • The initial agent support targets the top 5 agents; others are added incrementally
  • The extension system (spec-kit's RFC/catalog) is deferred to a future version
  • Custom strategies (user-authored .md files in strategies/) are supported but not validated

Open Questions

  • Q1: Should the package name be deft-cli (to avoid conflicts with any existing deft on PyPI) or just deft?
  • Q2: Should deft feature work outside of a git repository (creating one if needed), or require an existing repo?
  • Q3: Should the TUI be a hard dependency (always installed) or remain optional via deft-cli[tui] extras?

Scope Boundaries

In Scope (v1.0)

  • Distributable Python package with deft entry point
  • init, feature, bootstrap, project, strategy, agent, check, validate, update, version commands
  • TUI wizard mode (optional dependency)
  • Strategy-aware feature branching with auto-numbering
  • Agent configuration for top 5 agents
  • Slash command generation from strategy phases
  • Offline operation (framework files embedded)

Out of Scope (v1.0)

  • Extension/plugin system
  • Tasks-to-Issues automation (GitHub MCP integration)
  • Cross-artifact analysis command
  • Custom strategy authoring wizard
  • CI/CD pipeline generation
  • Multi-language CLI (Go, Rust alternatives)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions