Skip to content

[Feature] Add --ci or --non-interactive-env option for opencode/shuvcode direct prompt #19

@renekris

Description

@renekris

Problem Statement

Currently, ghwt opens shuvcode with only a directory path, but doesn't pass the generated WT-TASK.md prompt to the agent. This means users must manually copy/paste the task instructions or re-type them, which is inefficient and error-prone.

In CI/CD environments or automated workflows, this manual step is impossible.

Context

Both opencode and shuvcode (a fork) already support direct prompt passing through their CLI:

opencode/shuvcode CLI Prompt Methods:

1. Non-interactive run command:

shuvcode run "your prompt here"

2. TUI with initial prompt:

shuvcode --prompt "your prompt"

3. Piped stdin:

echo "prompt" | shuvcode run

Current ghwt Implementation:

# worktree_creator.py:484
subprocess.run(["shuvcode", str(worktree_path)], check=True)

Only passes directory path - no prompt content.

Proposed Solution

Enhance ghwt to pass WT-TASK.md content to shuvcode using its native prompt flags.

Option 1: Use --prompt flag (Recommended)

Modify _open_shuvcode() to read WT-TASK.md and pass it:

def _open_shuvcode(self, worktree_path: Path) -> None:
    """Open shuvcode on worktree with task prompt."""
    task_md_path = worktree_path / "WT-TASK.md"
    
    if task_md_path.exists():
        # Read WT-TASK.md content
        prompt_content = task_md_path.read_text()
        
        subprocess.run([
            "shuvcode",
            str(worktree_path),
            "--prompt",
            prompt_content
        ], check=True)
    else:
        # Fallback to directory-only mode
        subprocess.run(
            ["shuvcode", str(worktree_path)],
            check=True
        )

Usage:

# Interactive mode - passes WT-TASK.md automatically
ghwt 42 --issue
# Opens shuvcode with WT-TASK.md content pre-loaded as prompt

Option 2: Use run command with prompt

subprocess.run([
    "shuvcode", "run",
    "--file", str(worktree_path / "WT-TASK.md"),
    "Read WT-TASK.md and execute the task"
], cwd=str(worktree_path))

Option 3: Add --agent-prompt flag for custom prompts

@main.command()
@click.option("--agent-prompt", type=str, help="Custom prompt to pass to agent")
@click.pass_context
def main(ctx, agent_prompt=None, ...):
    # ...
    worktree_creator.open_shuvcode(prompt=agent_prompt)

Usage:

# Custom prompt overrides WT-TASK.md
ghwt 42 --issue --agent-prompt "/ralph-loop Read WT-TASK.md and execute"

# No prompt passed (current behavior)
ghwt 42 --issue --no-prompt

Option 4: Environment Variable for CI/CD

Add support for GHWT_AGENT_INIT_PROMPT:

# config.py
class Settings(BaseSettings):
    agent_init_prompt: str | None = Field(default=None, env="GHWT_AGENT_INIT_PROMPT")

# worktree_creator.py
prompt = self.config.agent_init_prompt or task_md_path.read_text()

Usage:

# CI/CD mode
export GHWT_AGENT_INIT_PROMPT="/ralph-loop Read WT-TASK.md and execute"
ghwt 42 --issue

Option 5: Prompt Presets

Add preset system for common workflows:

# config.py
class Settings(BaseSettings):
    agent_init_preset: str | None = Field(default=None, env="GHWT_AGENT_INIT_PRESET")

PRESETS = {
    "ralph-loop": "/ralph-loop Read WT-TASK.md and consult @oracle immediately...",
    "standard-ootl": "Read WT-TASK.md and execute the task...",
    "minimal": "Quick review of WT-TASK.md task..."
}

# Usage
export GHWT_AGENT_INIT_PRESET="ralph-loop"
ghwt 42 --issue

Tasks:

  • Modify _open_shuvcode() to read WT-TASK.md content
  • Add --agent-prompt CLI flag to main.py
  • Add GHWT_AGENT_INIT_PROMPT environment variable to config
  • Add GHWT_AGENT_INIT_PRESET environment variable for preset selection
  • Implement prompt presets configuration
  • Add --no-prompt flag to skip prompt passing (current behavior)
  • Add tests for prompt passing to shuvcode
  • Update documentation with usage examples
  • Add CI/CD integration examples

CLI Examples:

# Default: Pass WT-TASK.md content automatically
ghwt 42 --issue

# Custom prompt
ghwt 42 --issue --agent-prompt "Implement feature X with these constraints..."

# No prompt (current behavior)
ghwt 42 --issue --no-prompt

# CI/CD with environment variable
export GHWT_AGENT_INIT_PROMPT="/ralph-loop Execute WT-TASK.md task"
ghwt 42 --issue

# CI/CD with preset
export GHWT_AGENT_INIT_PRESET="ralph-loop"
ghwt 42 --issue

# Combined with other flags
ghwt 123 --pr --agent-prompt "/plan Review PR and create tests" --verbose

CI/CD Integration Examples:

GitHub Actions:

- name: Create worktree and start agent
  env:
    GHWT_AGENT_INIT_PRESET: "ralph-loop"
  run: |
    ghwt ${{ github.event.pull_request.number }} --pr

GitLab CI:

variables:
  GHWT_AGENT_INIT_PROMPT: "/ralph-loop Execute WT-TASK.md task"

create_worktree:
  script:
    - ghwt $CI_MERGE_REQUEST_IID --pr

Acceptance Criteria:

  • WT-TASK.md content is automatically passed to shuvcode on worktree creation
  • --agent-prompt flag overrides WT-TASK.md content
  • --no-prompt flag disables prompt passing (current behavior)
  • GHWT_AGENT_INIT_PROMPT environment variable is respected
  • GHWT_AGENT_INIT_PRESET environment variable selects predefined preset
  • Shuvcode opens with prompt pre-loaded using --prompt flag
  • Tests verify prompt passing to shuvcode subprocess
  • Documentation includes all usage patterns and CI/CD examples
  • Error handling for missing WT-TASK.md (graceful fallback)

Alternative Approaches:

  • Use shuvcode run instead of TUI mode with --prompt
  • Pipe WT-TASK.md content via stdin: cat WT-TASK.md | shuvcode run
  • Use file attachment: shuvcode run --file WT-TASK.md "Read and execute"

Related Issues:

Research Notes:

Both opencode and shuvcode support these prompt methods:

  • shuvcode --prompt "prompt" - Start TUI with initial prompt
  • shuvcode run "prompt" - Non-interactive execution
  • stdin piping support

Reference: https://opencode.ai/docs/cli/

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