Add GateFlow local CLI and agent creation#11
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 24ceadfb92
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if args.command == "tui": | ||
| return _load_tui().run_interactive(args.root) |
There was a problem hiding this comment.
Handle non-TTY invocation before launching curses TUI
The tui subcommand now unconditionally enters curses.wrapper, which crashes with a traceback when stdin/stdout is not a real TTY (for example CI, redirected execution, or scripted use). Running python3 tools/gateflow_cli.py --plain tui in a non-interactive terminal raises cbreak()/nocbreak() errors instead of returning a controlled message or fallback output, so this command is currently brittle outside interactive terminals.
Useful? React with 👍 / 👎.
| parts = shlex.split(command) | ||
| name = parts[1] if len(parts) > 1 else input("agent name: ").strip() | ||
| role = input("role: ").strip() or "custom GateFlow specialist" | ||
| description = input("description: ").strip() or role | ||
| result = create_agent( |
There was a problem hiding this comment.
Catch create-agent failures in shell loop
The interactive create-agent path in run_shell calls create_agent(...) without exception handling, so common user errors (like reusing an existing agent name or invalid names) terminate the entire shell with a traceback instead of returning an error and keeping the prompt alive. This is user-facing in normal operation (shell mode) and is easy to trigger by running create-agent twice with the same name.
Useful? React with 👍 / 👎.
| parts = shlex.split(command) | ||
| name = parts[1] if len(parts) > 1 else input("agent name: ").strip() | ||
| role = input("role: ").strip() or "custom GateFlow specialist" | ||
| description = input("description: ").strip() or role |
There was a problem hiding this comment.
🟢 Low tools/gateflow_cli.py:287
The create-agent command uses the built-in input() function, which always reads from sys.stdin. When run_shell is called with a custom input_stream (e.g., in tests), the command will block on input() instead of reading from the provided stream.
- name = parts[1] if len(parts) > 1 else input("agent name: ").strip()
+ name = parts[1] if len(parts) > 1 else input_stream.readline().strip()
- role = input("role: ").strip() or "custom GateFlow specialist"
+ print("role: ", end="", file=output, flush=True)
+ role = input_stream.readline().strip() or "custom GateFlow specialist"
- description = input("description: ").strip() or role
+ print("description: ", end="", file=output, flush=True)
+ description = input_stream.readline().strip() or role🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file tools/gateflow_cli.py around lines 287-290:
The `create-agent` command uses the built-in `input()` function, which always reads from `sys.stdin`. When `run_shell` is called with a custom `input_stream` (e.g., in tests), the command will block on `input()` instead of reading from the provided stream.
Evidence trail:
tools/gateflow_cli.py line 262: `def run_shell(root: Path, *, plain: bool, input_stream: TextIO = sys.stdin, output: TextIO = sys.stdout) -> int:` — accepts custom input_stream. Line 267: `line = input_stream.readline()` — main loop correctly uses input_stream. Lines 288-290: `input("agent name: ")`, `input("role: ")`, `input("description: ")` — uses built-in input() which reads from sys.stdin, not from input_stream.
| return agents | ||
|
|
||
|
|
||
| def shell_help() -> str: |
There was a problem hiding this comment.
🟡 Medium tools/gateflow_cli.py:186
The shell_help() text documents agents create NAME as a valid shell command, but run_shell() does not implement it — the function only handles exact matches for "agents" and "agents list" at line 281. When a user types agents create "CDC Reviewer", it falls through to the unknown command error at line 302. Either implement the agents create command or remove it from the help text.
🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file tools/gateflow_cli.py around line 186:
The `shell_help()` text documents `agents create NAME` as a valid shell command, but `run_shell()` does not implement it — the function only handles exact matches for `"agents"` and `"agents list"` at line 281. When a user types `agents create "CDC Reviewer"`, it falls through to the unknown command error at line 302. Either implement the `agents create` command or remove it from the help text.
Evidence trail:
tools/gateflow_cli.py lines 186-201 (shell_help documents `agents create NAME` and gives example at line 199), tools/gateflow_cli.py lines 270-303 (run_shell handles `agents`/`agents list` at line 281, `create-agent` at line 286, but has no handler for `agents create`; falls through to unknown command error at line 302).
Summary
tools/gateflow_cli.pywithstatus,tui,agents list,agents create, andshellato create Claude-compatible agent markdown filesVerification
Note
Add GateFlow local CLI and in-TUI agent creation
status,agents list,agents create,tui, andshellsubcommands; supports JSON and plain-text output with ANSI colors.agents create(and the new'a'hotkey in the TUI) writes agent markdown files toplugins/gateflow/agents/using a consistent schema._terminal_stylesin tools/gateflow_tui.py to use semantic curses color pairs (accent, ok, warn, error, etc.) with 256-color support and safe fallbacks.📊 Macroscope summarized 24ceadf. 11 files reviewed, 4 issues evaluated, 1 issue filtered, 2 comments posted
🗂️ Filtered Issues
tools/gateflow_cli.py — 2 comments posted, 4 evaluated, 1 filtered
NO_COLORenvironment variable check usingos.environ.get("NO_COLOR")is incorrect. Per the NO_COLOR spec, colors should be disabled when the variable is set to any value, including an empty string. However,os.environ.get("NO_COLOR")returns""when set to empty, which is falsy in Python, soplain or ""evaluates toFalseand colors are still emitted. The check should be"NO_COLOR" in os.environoros.environ.get("NO_COLOR") is not None. [ Failed validation ]