feat(console): live operator console for watching and steering agents#4
Conversation
Add `agent-sync console`: a live, interactive view of the coordination layer. A streaming feed tails activity, inter-agent messages, presence changes and lock events, while an `operator>` prompt lets a human act as a first-class participant — send messages/directives, lock files to stop edits immediately, drive the task board, and record decisions. Console details: - New `agent_sync.console` module. The pure logic (sanitize_terminal, parse_command, poll_events, execute_command, format_status) is import- clean and unit-tested without the TUI dependency; only `run()` touches prompt_toolkit, imported lazily. - Reserved `operator` identity registers as active (so its locks are enforced and its messages reach agents) but is filtered out of the "active agents" count in the renderers. - `messages.recent_messages()` provides the global feed; `sanitize_terminal()` strips control/ANSI bytes from agent-authored text before it reaches the human's terminal (terminal-injection defense). - Optional `[tui]` extra (prompt_toolkit); the core stays dependency-free. Graceful fallbacks when the extra is missing or there is no TTY. - Docs: README "Live console" section + commands/roadmap/safety updates, examples/CLAUDE.md operator note, and a console section in the dev smoke test. Bundled pre-existing working-tree changes (committed together to keep the tree green and tests passing): - Live-messaging push: UserPromptSubmit (gentle) and Stop (forceful) hooks deliver undelivered messages into agent context, tracked by a new `message_deliveries` table; `render_pushed_messages` framing. - Naming/positioning + CI/meta pass: CITATION.cff, LICENSE/__init__ wording, and a PyPI-publish guard in the release workflow. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: cdf322bbf2
ℹ️ 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".
| lines.append(f"locks ({len(live)}):") | ||
| for lk in live: | ||
| reason = f" — {sanitize_terminal(lk.reason)}" if lk.reason else "" | ||
| lines.append(f" {sanitize_terminal(lk.file_path)} → {_resolve_name(conn, lk.owner_agent_id)}{reason}") |
There was a problem hiding this comment.
Sanitize owner names in console status
If an agent registers a name containing terminal control bytes and then owns a live lock, format_status() prints the resolved owner directly here, bypassing sanitize_terminal(). Running agent-sync console or the console status command will therefore emit raw escape sequences despite the new terminal-injection defense; sanitize the resolved owner before appending it.
Useful? React with 👍 / 👎.
| } | ||
| ] | ||
| } | ||
| ] |
There was a problem hiding this comment.
Add SessionEnd to the skill-path hook sample
This no-PATH settings sample ends the hook list after Stop, unlike the PATH sample and installer output that include SessionEnd. Users who copy this variant will never call hook_session_end, so a closed Claude session remains active until the stale timeout and its locks/tasks can continue blocking other agents for that window.
Useful? React with 👍 / 👎.
cdf322b to
11e60f5
Compare
Summary
Adds
agent-sync console— a live, interactive view of the coordination layer. A streaming feed tails activity, inter-agent messages, presence changes, and lock events, while anoperator>prompt lets a human act as a first-class participant: send messages/directives, lock files to stop edits immediately, drive the task board, and record decisions.What's included
agent_sync.consolemodule. Pure logic (sanitize_terminal,parse_command,poll_events,execute_command,format_status) is import-clean and unit-tested without the TUI dependency; onlyrun()touchesprompt_toolkit, imported lazily.operatoridentity registers as active (so its locks are enforced and its messages reach agents) but is filtered out of the "active agents" count in the renderers.UserPromptSubmit(gentle) andStop(forceful) deliver undelivered messages into agent context, tracked by a newmessage_deliveriestable;render_pushed_messagesframing.sanitize_terminal()strips control/ANSI bytes from agent-authored text before it reaches the human's terminal.[tui]extra (prompt_toolkit); the core stays dependency-free, with graceful fallbacks when the extra is missing or there is no TTY.examples/CLAUDE.mdoperator note,examples/settings.jsonwired with the new hooks, and a console section in the dev smoke test.CITATION.cff, LICENSE/__init__wording, and a PyPI-publish guard in the release workflow.Testing
pytest— 112 passed (incl.test_console.py,test_hooks_stop.py,test_hooks_user_prompt_submit.py).🤖 Generated with Claude Code