Skip to content

Add GateFlow terminal console and release checks#8

Merged
codejunkie99 merged 1 commit into
mainfrom
codex-gateflow-release-tools
May 20, 2026
Merged

Add GateFlow terminal console and release checks#8
codejunkie99 merged 1 commit into
mainfrom
codex-gateflow-release-tools

Conversation

@codejunkie99
Copy link
Copy Markdown
Owner

@codejunkie99 codejunkie99 commented May 20, 2026

Summary

  • Add /gf-tui plus tools/gateflow_tui.py for an OpenClaw-style local terminal console with interactive, snapshot, and JSON modes.
  • Add /gf-release plus tools/validate_gateflow.py for release-readiness validation.
  • Bump plugin and marketplace metadata to 2.5.0, refresh release notes, docs index, README counts, and complete root mirrors.

Verification

  • python3 -m unittest
  • python3 tools/validate_gateflow.py --version 2.5.0
  • python3 tools/gateflow_tui.py --snapshot --plain
  • python3 tools/gateflow_tui.py --json
  • git diff --check

Note

Add /gf-tui terminal console and /gf-release validation commands to GateFlow plugin

📊 Macroscope summarized bae136f. 17 files reviewed, 7 issues evaluated, 1 issue filtered, 4 comments posted

🗂️ Filtered Issues

tools/gateflow_tui.py — 1 comment posted, 4 evaluated, 1 filtered
  • line 27: importlib.util.spec_from_file_location returns None if the file doesn't exist or cannot be loaded. When validate_gateflow.py is missing, spec will be None, and importlib.util.module_from_spec(spec) will raise a confusing TypeError (or AttributeError on spec.loader). The code should check if spec is None before proceeding. [ Cross-file consolidated ]

@codejunkie99 codejunkie99 merged commit 62c33f1 into main May 20, 2026
1 of 2 checks passed
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: bae136f0f6

ℹ️ 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".

Comment thread tools/gateflow_tui.py
payload = build_payload(root)

def wrapped(stdscr) -> None:
curses.curs_set(0)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Guard cursor hide call for unsupported terminals

The interactive path calls curses.curs_set(0) unconditionally, which raises _curses.error on terminals that do not support cursor visibility changes; in that case /gf-tui exits before rendering any UI. This makes the new interactive console unusable in a non-trivial set of environments (including minimal/remote TTYs), so this should be wrapped in a safe fallback (e.g., try/except curses.error) instead of hard-failing.

Useful? React with 👍 / 👎.

Comment thread tools/gateflow_tui.py
root = root.resolve()
validator = _load_validator()
inventory = validator.discover_inventory(root)
release = validator.run_checks(root, expected_version="2.5.0")
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Remove hardcoded release version from TUI health check

The release health status is computed with a fixed expected version (2.5.0), so after the next version bump the TUI will report release errors even when manifests/docs are correctly synchronized to the new version. Because this value is baked into runtime behavior, the dashboard becomes misleading until code is manually edited for every release; it should derive the expected version from plugin.json (or accept it as an argument).

Useful? React with 👍 / 👎.

Comment on lines +1 to +20
---
name: gf-tui
description: >
GateFlow terminal console inspired by OpenClaw local TUI workflows. Shows
workspace status, component inventory, tool health, map readiness, release
readiness, and command shortcuts from one terminal surface.
user-invocable: true
triggers:
- open GateFlow TUI
- show GateFlow dashboard
- terminal console
- CLI TUI
- OpenClaw-style TUI
---
allowed-tools:
- Bash
- Read

# GF-TUI -- Terminal Console

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟠 High gf-tui/SKILL.md:1

The allowed-tools block on lines 15–17 is placed after the closing --- frontmatter delimiter on line 14, so it renders as Markdown text instead of being parsed as YAML metadata. This causes the skill to not declare its required tool permissions (Bash, Read), which may lead to runtime tool denials or unexpected fallback behavior. Move the allowed-tools: key and its list items above line 14, inside the frontmatter block.

+---
+name: gf-tui
+description: >
+  GateFlow terminal console inspired by OpenClaw local TUI workflows. Shows
+  workspace status, component inventory, tool health, map readiness, release
+  readiness, and command shortcuts from one terminal surface.
+user-invocable: true
+triggers:
+  - open GateFlow TUI
+  - show GateFlow dashboard
+  - terminal console
+  - CLI TUI
+  - OpenClaw-style TUI
+allowed-tools:
+  - Bash
+  - Read
+---
+
+# GF-TUI -- Terminal Console
🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file plugins/gateflow/skills/gf-tui/SKILL.md around lines 1-20:

The `allowed-tools` block on lines 15–17 is placed after the closing `---` frontmatter delimiter on line 14, so it renders as Markdown text instead of being parsed as YAML metadata. This causes the skill to not declare its required tool permissions (`Bash`, `Read`), which may lead to runtime tool denials or unexpected fallback behavior. Move the `allowed-tools:` key and its list items above line 14, inside the frontmatter block.

# GateFlow

**The open-source AI hardware platform.** Design, verify, synthesize, and deploy working RTL from natural language. 20 agents. 25 skills. 8 verified IP blocks. One command.
**The open-source AI hardware platform.** Design, verify, synthesize, release, and deploy working RTL from natural language. 20 agents. 27 skills. 21 commands. 8 verified IP blocks.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Medium gateflow/README.md:3

The header claims 27 skills (line 3) and 27 Skills (line 69), but the table only lists 25 comma-separated skill items (4+3+4+3+4+2+1+1+1+2=25). The count overstates by 2. Consider updating the header and section title to 25 skills / 25 Skills to match the actual table contents.

Suggested change
**The open-source AI hardware platform.** Design, verify, synthesize, release, and deploy working RTL from natural language. 20 agents. 27 skills. 21 commands. 8 verified IP blocks.
**The open-source AI hardware platform.** Design, verify, synthesize, release, and deploy working RTL from natural language. 20 agents. 25 skills. 21 commands. 8 verified IP blocks.
🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file plugins/gateflow/README.md around line 3:

The header claims **27 skills** (line 3) and **27 Skills** (line 69), but the table only lists 25 comma-separated skill items (4+3+4+3+4+2+1+1+1+2=25). The count overstates by 2. Consider updating the header and section title to **25 skills** / **25 Skills** to match the actual table contents.

Comment thread tools/gateflow_tui.py
Comment on lines +203 to +207
def run_interactive(root: Path) -> int:
payload = build_payload(root)

def wrapped(stdscr) -> None:
curses.curs_set(0)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟠 High tools/gateflow_tui.py:203

_draw calls curses.init_pair(..., -1) to use the terminal's default background color, but curses.use_default_colors() is never called first. This causes init_pair() to throw curses.error on terminals where the default color mechanism isn't initialized. Consider calling curses.use_default_colors() at the start of wrapped() before invoking _draw.

 def run_interactive(root: Path) -> int:
     payload = build_payload(root)
 
     def wrapped(stdscr) -> int:
+        curses.use_default_colors()
         curses.curs_set(0)
         stdscr.keypad(True)
🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file tools/gateflow_tui.py around lines 203-207:

`_draw` calls `curses.init_pair(..., -1)` to use the terminal's default background color, but `curses.use_default_colors()` is never called first. This causes `init_pair()` to throw `curses.error` on terminals where the default color mechanism isn't initialized. Consider calling `curses.use_default_colors()` at the start of `wrapped()` before invoking `_draw`.

Evidence trail:
tools/gateflow_tui.py lines 156-159: `curses.init_pair` called with `-1` background. tools/gateflow_tui.py line 206-227: `wrapped` function and `curses.wrapper(wrapped)` call. git_grep for `use_default_colors` in tools/gateflow_tui.py returned no results. Python docs: https://docs.python.org/3/library/curses.html#curses.use_default_colors confirms `-1` requires `use_default_colors()`.

Comment on lines +28 to +35
def discover_inventory(root: Path) -> Inventory:
plugin = root / "plugins" / "gateflow"
agents = sorted(path.stem for path in (plugin / "agents").glob("*.md"))
skills = sorted(path.parent.name for path in (plugin / "skills").glob("*/SKILL.md"))
commands = sorted(path.stem for path in (plugin / "commands").glob("*.md"))
ip_blocks = sorted(path.name for path in (plugin / "ip").iterdir() if path.is_dir())
boards = sorted(path.name for path in (plugin / "boards").iterdir() if path.is_dir())
return Inventory(agents, skills, commands, ip_blocks, boards)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 Low tools/validate_gateflow.py:28

discover_inventory crashes with FileNotFoundError when any plugin subdirectory (agents, skills, commands, ip, or boards) is missing. Both glob() and iterdir() throw when their target directory doesn't exist. Unlike _read_json which appends to an errors list, this function has no error handling and run_checks doesn't catch exceptions. A validation tool should report missing directories as validation errors rather than terminating.

 def discover_inventory(root: Path) -> Inventory:
     plugin = root / "plugins" / "gateflow"
-    agents = sorted(path.stem for path in (plugin / "agents").glob("*.md"))
-    skills = sorted(path.parent.name for path in (plugin / "skills").glob("*/SKILL.md"))
-    commands = sorted(path.stem for path in (plugin / "commands").glob("*.md"))
-    ip_blocks = sorted(path.name for path in (plugin / "ip").iterdir() if path.is_dir())
-    boards = sorted(path.name for path in (plugin / "boards").iterdir() if path.is_dir())
+    agents = sorted(path.stem for path in (plugin / "agents").glob("*.md")) if (plugin / "agents").exists() else []
+    skills = sorted(path.parent.name for path in (plugin / "skills").glob("*/SKILL.md")) if (plugin / "skills").exists() else []
+    commands = sorted(path.stem for path in (plugin / "commands").glob("*.md")) if (plugin / "commands").exists() else []
+    ip_blocks = sorted(path.name for path in (plugin / "ip").iterdir() if path.is_dir()) if (plugin / "ip").exists() else []
+    boards = sorted(path.name for path in (plugin / "boards").iterdir() if path.is_dir()) if (plugin / "boards").exists() else []
     return Inventory(agents, skills, commands, ip_blocks, boards)
Also found in 1 other location(s)

tools/gateflow_tui.py:27

importlib.util.spec_from_file_location returns None if the file doesn't exist or cannot be loaded. When validate_gateflow.py is missing, spec will be None, and importlib.util.module_from_spec(spec) will raise a confusing TypeError (or AttributeError on spec.loader). The code should check if spec is None before proceeding.

🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file tools/validate_gateflow.py around lines 28-35:

`discover_inventory` crashes with `FileNotFoundError` when any plugin subdirectory (`agents`, `skills`, `commands`, `ip`, or `boards`) is missing. Both `glob()` and `iterdir()` throw when their target directory doesn't exist. Unlike `_read_json` which appends to an errors list, this function has no error handling and `run_checks` doesn't catch exceptions. A validation tool should report missing directories as validation errors rather than terminating.

Evidence trail:
tools/validate_gateflow.py lines 28-35 (discover_inventory with no error handling), lines 33-34 (iterdir() calls), lines 135-145 (run_checks with no try/except around discover_inventory), lines 38-46 (_read_json with FileNotFoundError handling). Python docs: Path.iterdir() raises OSError/FileNotFoundError on non-existent directories (https://docs.python.org/3/library/pathlib.html#pathlib.Path.iterdir). Python 3.13 changelog: 'In previous versions, such exceptions [from glob] are suppressed in many cases, but not all.'

Also found in 1 other location(s):
- tools/gateflow_tui.py:27 -- `importlib.util.spec_from_file_location` returns `None` if the file doesn't exist or cannot be loaded. When `validate_gateflow.py` is missing, `spec` will be `None`, and `importlib.util.module_from_spec(spec)` will raise a confusing `TypeError` (or `AttributeError` on `spec.loader`). The code should check if `spec is None` before proceeding.

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.

1 participant