Skip to content

feat: Implement CLI (Cobra/BubbleTea) & PendingActionScheduler#14

Merged
Kavirubc merged 5 commits intomainfrom
update/0.0.2v-cli
Feb 2, 2026
Merged

feat: Implement CLI (Cobra/BubbleTea) & PendingActionScheduler#14
Kavirubc merged 5 commits intomainfrom
update/0.0.2v-cli

Conversation

@Kavirubc
Copy link
Copy Markdown
Contributor

@Kavirubc Kavirubc commented Feb 2, 2026

Overview

This PR completes the v0.0.2v CLI implementation phases.

Changes

  • Phase 7: PendingActionScheduler: Added step to handle deferred actions (e.g., transfers).
  • Phase 8: CLI (Cobra + Bubble Tea):
    • Refactored to use Cobra.
    • Implemented command.
    • Added Bubble Tea TUI for interactive pipeline status.
  • Phase 9: Wiring: Connected CLI to steps and clients.
  • Phase 10: E2E Testing: Added to verify plumbing.
  • Docs: Updated with CLI usage.

Verification

  • Unit tests added for .
  • Integration test passed.
  • verified locally.

Closes #5, #6

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR implements the v0.0.2 CLI functionality for Simili-Bot, adding a Cobra-based command structure with a BubbleTea interactive TUI, and introducing the PendingActionScheduler step to handle deferred actions like issue transfers.

Changes:

  • Added PendingActionScheduler step to record pending actions to a local state directory when transfers cannot be executed immediately
  • Implemented CLI using Cobra framework with a process command to run the pipeline on individual issues
  • Added interactive TUI using BubbleTea to display real-time pipeline execution status
  • Integrated E2E tests to verify the full pipeline execution flow

Reviewed changes

Copilot reviewed 11 out of 12 changed files in this pull request and generated 15 comments.

Show a summary per file
File Description
internal/steps/pending_action_scheduler.go Implements step to schedule deferred actions like transfers
internal/steps/pending_action_scheduler_test.go Unit tests for the PendingActionScheduler step
internal/steps/register.go Registers the new pending_action_scheduler step with the pipeline
cmd/simili/main.go Refactored to use Cobra command framework
cmd/simili/commands/root.go Cobra root command with global flags
cmd/simili/commands/process.go Implements the process command for running pipelines on issues
cmd/simili/commands/pipeline_runner.go Pipeline execution logic with status reporting wrapper
internal/tui/model.go BubbleTea TUI model for interactive pipeline status display
tests/integration/e2e_test.go End-to-end integration test for pipeline execution
go.mod Added dependencies for Cobra and BubbleTea frameworks
go.sum Updated dependency checksums
DOCS/0.0.2v/README.md Documentation updates with CLI usage examples

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread tests/integration/e2e_test.go Outdated
Comment on lines +18 to +36
// Mock mocks the pipeline.Step interface.
type MockStep struct {
NameFunc func() string
RunFunc func(ctx *pipeline.Context) error
}

func (m *MockStep) Name() string {
if m.NameFunc != nil {
return m.NameFunc()
}
return "mock_step"
}

func (m *MockStep) Run(ctx *pipeline.Context) error {
if m.RunFunc != nil {
return m.RunFunc(ctx)
}
return nil
}
Copy link

Copilot AI Feb 2, 2026

Choose a reason for hiding this comment

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

The MockStep struct is defined in the e2e_test.go file but is not used in the test. The test only uses real pipeline steps. Consider either using the MockStep in the test or removing it if it's not needed. If it's intended for future test scenarios, add a comment explaining its purpose.

Copilot uses AI. Check for mistakes.
Comment thread cmd/simili/commands/pipeline_runner.go Outdated

func (s *statusReportingStep) Run(ctx *pipeline.Context) error {
s.statusChan <- tui.PipelineStatusMsg{Step: s.Name(), Status: "started", Message: "Starting..."}
time.Sleep(100 * time.Millisecond) // Artificial delay for visual effect
Copy link

Copilot AI Feb 2, 2026

Choose a reason for hiding this comment

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

An artificial delay of 100ms is added for visual effect on every step execution. While this might improve the user experience during demos, it significantly slows down pipeline execution in production. Consider making this delay configurable (e.g., via a flag or environment variable) so it can be disabled in production or CI/CD environments.

Copilot uses AI. Check for mistakes.
Comment thread cmd/simili/commands/process.go Outdated
}()

if _, err := p.Run(); err != nil {
fmt.Printf("Alas, there's been an error: %v", err)
Copy link

Copilot AI Feb 2, 2026

Choose a reason for hiding this comment

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

The error message uses informal language ("Alas, there's been an error") which is inconsistent with the rest of the codebase's error messages. Consider using a more standard format like "Error running TUI: %v" to maintain consistency.

Suggested change
fmt.Printf("Alas, there's been an error: %v", err)
fmt.Printf("Error running TUI: %v\n", err)

Copilot uses AI. Check for mistakes.
Comment on lines +24 to +28
func NewPendingActionScheduler(deps *pipeline.Dependencies) *PendingActionScheduler {
// For now, we use a local directory for state. In the future, this could be a git branch.
return &PendingActionScheduler{
stateDir: ".simili/pending",
}
Copy link

Copilot AI Feb 2, 2026

Choose a reason for hiding this comment

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

The hardcoded state directory path ".simili/pending" could lead to issues in different deployment environments. Consider making this configurable through the Dependencies struct or environment variables, especially for production deployments where state should be persisted in a well-defined location.

Copilot uses AI. Check for mistakes.
Comment on lines +57 to +60
// Verify content
content, _ := os.ReadFile(expectedFile)
var action PendingAction
json.Unmarshal(content, &action)
Copy link

Copilot AI Feb 2, 2026

Choose a reason for hiding this comment

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

The test doesn't verify error handling in the json.Unmarshal call. If unmarshaling fails, the test will silently continue with a zero-value action, which could lead to misleading test results. Consider adding error checking after unmarshaling to ensure the test validates the actual content written to the file.

Copilot uses AI. Check for mistakes.
Comment on lines +46 to +48
r.Register("pending_action_scheduler", func(deps *pipeline.Dependencies) (pipeline.Step, error) {
return NewPendingActionScheduler(deps), nil
})
Copy link

Copilot AI Feb 2, 2026

Choose a reason for hiding this comment

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

The newly registered "pending_action_scheduler" step is not included in any of the workflow presets (issue-triage, similarity-only, index-only). According to the PR description, this step handles deferred actions like transfers, which should logically be part of the "issue-triage" workflow after the "action_executor" step. Consider adding it to the appropriate workflow presets, particularly "issue-triage".

Copilot uses AI. Check for mistakes.
Comment on lines +53 to +54
ctx := context.Background()
pCtx := pipeline.NewContext(ctx, issue, cfg)
Copy link

Copilot AI Feb 2, 2026

Choose a reason for hiding this comment

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

The pipeline uses context.Background() without any cancellation support. If a user presses Ctrl+C or quits the TUI, the pipeline goroutine will continue running in the background. Consider using a cancellable context and passing it through to support graceful shutdown when the user quits the TUI.

Copilot uses AI. Check for mistakes.
Comment thread internal/tui/model.go

return m, m.waitForActivity()

case ResultMsg:
Copy link

Copilot AI Feb 2, 2026

Choose a reason for hiding this comment

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

When receiving a ResultMsg, the TUI immediately quits without displaying the final result output to the user. The View() method returns an empty string when quitting, so users won't see the pipeline's final result. Consider keeping the TUI visible for a moment to display the final output, or printing it to stdout before quitting.

Suggested change
case ResultMsg:
case ResultMsg:
// Print the final output before quitting so the user can see the result.
if msg.Output != "" {
fmt.Println(msg.Output)
}

Copilot uses AI. Check for mistakes.
Comment thread internal/tui/model.go Outdated
prefix = "✗ "
style = errorStepStyle
case "skipped":
prefix = "- "
Copy link

Copilot AI Feb 2, 2026

Choose a reason for hiding this comment

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

The View() method renders different prefixes based on step status, but when a step is "skipped", it uses "- " as the prefix which is the same visual indicator used for steps that haven't started yet (due to the default prefix being " " for non-current steps). This could be confusing. Consider using a different prefix for skipped steps (e.g., "○ " or "⊘ ") to clearly distinguish them from pending steps.

Suggested change
prefix = "- "
prefix = " "

Copilot uses AI. Check for mistakes.
Comment thread cmd/simili/commands/pipeline_runner.go Outdated
}

// Marshal result to JSON
resultBytes, _ := json.MarshalIndent(pCtx.Result, "", " ")
Copy link

Copilot AI Feb 2, 2026

Choose a reason for hiding this comment

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

Error from json.MarshalIndent is silently ignored. While marshaling a Result struct is unlikely to fail, it's better to handle the error explicitly, especially since this is the final output being sent to the user. If marshaling fails, the user will receive an empty output without any indication of what went wrong.

Suggested change
resultBytes, _ := json.MarshalIndent(pCtx.Result, "", " ")
resultBytes, err := json.MarshalIndent(pCtx.Result, "", " ")
if err != nil {
p.Send(tui.ResultMsg{Success: false, Output: err.Error()})
return
}

Copilot uses AI. Check for mistakes.
This commit fixes CI lint failures and addresses code quality issues
identified in PR #14 review:

- Fix unchecked json.Unmarshal error in pending_action_scheduler_test.go
- Fix unchecked json.MarshalIndent error in pipeline_runner.go
- Add timeout support to TUI waitForActivity to prevent hanging
- Display final pipeline result before TUI quits
- Make UI delay configurable via SIMILI_NO_UI_DELAY env var
- Make pending action state directory configurable via env var
- Add pending_action_scheduler to issue-triage workflow preset
- Improve error logging for client initialization failures
- Update error message for consistency
- Improve visual distinction for skipped steps (○ instead of -)
- Add documentation to MockStep explaining its purpose
- Remove incomplete comment from process.go

All tests pass and code builds successfully.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@Kavirubc Kavirubc merged commit cc6a91b into main Feb 2, 2026
3 checks passed
@Kavirubc Kavirubc linked an issue Feb 2, 2026 that may be closed by this pull request
@Kavirubc Kavirubc deleted the update/0.0.2v-cli branch February 2, 2026 07:27
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.

[v0.0.2] CLI: Implement 'process' command [v0.0.2] Implement PendingActionScheduler step

2 participants