feat: add --watch mode for continuous CLI polling#1
Merged
Conversation
Add global --watch and --interval flags to re-run any read-only CLI command on a polling interval. TTY output clears and reprints each cycle; piped output appends JSON lines for streaming consumption. Supported commands: workflow list/get/count, activity list, event list, insight scan. Write commands (cancel, terminate) and serve are excluded. Includes 3 unit tests for the watch loop and has been live-tested against Temporal Cloud. Co-authored-by: Cursor <cursoragent@cursor.com>
Greptile OverviewGreptile SummaryImplements a polling watch mode for continuous monitoring of Temporal workflows. The Key changes:
Implementation highlights:
Confidence Score: 5/5
|
| Filename | Overview |
|---|---|
| src/watch.rs | New module with clean polling loop implementation and comprehensive tests |
| src/cli.rs | Added --watch and --interval flags, added Clone derives for action enums |
| src/lib.rs | Simple module registration for the new watch module |
| src/main.rs | Integrated watch mode with proper wrapping of read commands, excludes write operations |
Sequence Diagram
sequenceDiagram
participant User
participant CLI as CLI Parser
participant Main as main.rs
participant Watch as watch.rs
participant Commands as Command Handlers
participant Client as Temporal Client
User->>CLI: tpv --watch --interval 30 workflow list
CLI->>Main: Parse args (watch=true, interval=30)
Main->>Main: Build WatchConfig (interval, is_tty)
Main->>Client: create_client()
Client-->>Main: Arc<dyn TemporalClient>
alt Watch mode enabled
Main->>Watch: run_watch_loop(config, task_closure)
loop Every interval seconds
alt TTY mode
Watch->>Watch: Clear screen
Watch->>Watch: Print timestamp header
end
Watch->>Commands: Execute task() closure
Commands->>Client: client.list(filter, limit)
Client-->>Commands: Result<Vec<Workflow>>
Commands->>Commands: print output (table/json)
Commands-->>Watch: Result<()>
alt Error occurred
Watch->>Watch: Print error to stderr
end
Watch->>Watch: tokio::select! sleep or ctrl_c
alt Ctrl+C pressed
Watch->>Watch: Break loop
Watch-->>Main: Ok(())
end
end
else Normal mode
Main->>Commands: handle(action, client, format)
Commands->>Client: client.list(filter, limit)
Client-->>Commands: Result<Vec<Workflow>>
Commands->>Commands: print output
Commands-->>Main: Result<()>
end
Main-->>User: Exit
When --watch is used with piped stdout, only emit output when it changes from the previous cycle. Identical output is suppressed, making watch mode behave like tailing new events rather than reprinting the full dataset every interval. - Refactor output layer: add write_* functions accepting &mut dyn Write - Refactor command handlers: add handle_to() variants with writer param - Watch loop captures output into buffer in pipe mode, diffs vs previous - TTY mode unchanged (clear + full reprint each cycle) - Move InsightsResult summary println to eprintln to avoid capture noise Co-authored-by: Cursor <cursoragent@cursor.com>
First cycle now captures a silent baseline instead of dumping all existing data. Only subsequent cycles that detect a change emit output. This makes --watch behave like tailing new events rather than replaying history on startup. Co-authored-by: Cursor <cursoragent@cursor.com>
Add --sort asc|desc flag (default: desc) to `tpv workflow list`. Sorting is done client-side after fetching results, which works across all Temporal server versions. - asc: oldest first (ascending by start time) - desc: newest first (descending by start time, default) Compatible with --watch and all other flags. Co-authored-by: Cursor <cursoragent@cursor.com>
sushantvema-harper
approved these changes
Feb 7, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a
--watchglobal flag (with configurable--interval <SECONDS>, default 30) that re-runs any read-only CLI command on a polling loop. This enables continuous monitoring of Temporal workflows directly from the terminal or through piped toolchains.[2026-02-06 20:04:05] Refreshing every 30s... (Ctrl+C to stop))jq, alerting scripts, or log aggregationSupported commands
workflow listtpv --watch --interval 10 workflow list --status failedworkflow gettpv --watch workflow get <workflow-id>workflow counttpv --watch --interval 5 workflow count --status runningactivity listtpv --watch activity list <workflow-id>event listtpv --watch event list <workflow-id>insight scantpv --watch --interval 60 insight scan --since 2hWrite commands (
cancel,terminate) andserveare intentionally excluded.Example: streaming critical alerts to jq
Changes
New file:
src/watch.rsWatchConfigstruct (interval, format, is_tty)run_watch_loop()— generic async polling loop that accepts anyFn() -> Future<Result<()>>closuretokio::select!withtokio::signal::ctrl_c()for clean shutdown during the sleep intervalModified:
src/cli.rs--watch(bool) and--interval(u64, default 30) toGlobalArgs#[derive(Clone)]toWorkflowAction,ActivityAction,EventAction,InsightActionso actions can be reused across loop iterationsModified:
src/lib.rspub mod watch;Modified:
src/main.rsWatchConfigfrom CLI flags when--watchis setrun_watch_loopwhen watch mode is activeuse std::io::IsTerminalanduse std::time::DurationimportsTest plan
cargo check— compiles cleanlycargo test --lib— all 155 tests pass (including 3 new watch tests)tpv --watch --interval 3 --limit 2 workflow listagainst Temporal Cloud — polled successfully every 3stpv --watch --interval 3 --output json --limit 1 workflow count— appended JSON lines each cycle--helpoutput shows new--watchand--intervalflags--watchwithinsight scanagainst live dataMade with Cursor