Skip to content
6 changes: 5 additions & 1 deletion SPECS/ARCHIVE/INDEX.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
# mcpbridge-wrapper Tasks Archive

**Last Updated:** 2026-03-07 (P1-T12 archived)
**Last Updated:** 2026-03-07 (REVIEW_broker_runtime_status_surface archived)

## Archived Tasks

| Task ID | Folder | Archived | Verdict |
|---------|--------|----------|---------|
| P6-T1 | [P6-T1_Add_explicit_broker_runtime_status_surface_for_frontend_consumers/](P6-T1_Add_explicit_broker_runtime_status_surface_for_frontend_consumers/) | 2026-03-07 | PASS |
| P1-T12 | [P1-T12_Improve_troubleshooting_docs_for_Zed_broker_startup_timeouts/](P1-T12_Improve_troubleshooting_docs_for_Zed_broker_startup_timeouts/) | 2026-03-07 | PASS |
| P5-T2 | [P5-T2_Release_0.4.1_to_PyPI_and_MCP_Registry/](P5-T2_Release_0.4.1_to_PyPI_and_MCP_Registry/) | 2026-03-06 | PASS |
| BUG-T9 | [BUG-T9_Fix_broker_daemon_not_sending_notifications_initialized_before_tools_list_probe/](BUG-T9_Fix_broker_daemon_not_sending_notifications_initialized_before_tools_list_probe/) | 2026-03-06 | PASS |
Expand Down Expand Up @@ -193,6 +194,7 @@

| File | Description |
|------|-------------|
| [REVIEW_broker_runtime_status_surface.md](_Historical/REVIEW_broker_runtime_status_surface.md) | Review report for P6-T1 |
| [REVIEW_p1_t12_zed_timeout_docs.md](_Historical/REVIEW_p1_t12_zed_timeout_docs.md) | Review report for P1-T12 |
| [REVIEW_P4-T2_broker_readiness_cache.md](_Historical/REVIEW_P4-T2_broker_readiness_cache.md) | Review report for P4-T2 |
| [REVIEW_P1-T11_readme_coverage_badge.md](_Historical/REVIEW_P1-T11_readme_coverage_badge.md) | Review report for P1-T11 |
Expand Down Expand Up @@ -329,6 +331,8 @@

| Date | Task ID | Action |
|------|---------|--------|
| 2026-03-07 | P6-T1 | Archived REVIEW_broker_runtime_status_surface report |
| 2026-03-07 | P6-T1 | Archived task artifacts and validation report |
| 2026-03-07 | P1-T12 | Archived task artifacts and validation report |
| 2026-03-06 | P5-T2 | Archived Release_0.4.1_to_PyPI_and_MCP_Registry (PASS) |
| 2026-03-06 | P5-T2 | Archived REVIEW_release-0.4.1 report |
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# P6-T1 — Add explicit broker runtime status surface for frontend consumers

## Objective Summary

The broker already has internal lifecycle state and the Web UI already exposes
basic control metadata, but operators still have to infer real daemon health
from PID files, `--broker-status`, and raw log lines. This task adds one
explicit runtime status surface that frontend consumers can trust. The result
must make it obvious whether the dedicated broker host is healthy, reconnecting,
missing an upstream process, or serving active client sessions.

This task does not implement the TUI itself. It delivers the structured runtime
contract that a TUI or other explicit frontend can consume without log parsing.

## Deliverables

- Extend broker runtime status payloads to include operator-facing fields beyond
the current `state` / `pid` / `upstream_pid` / `version` tuple.
- Expose that payload through the Web UI server in a dedicated API route rather
than overloading `/api/control`.
- Cover ready, degraded, and reconnecting status states with automated tests.

## Success Criteria

- A dedicated broker host exposes structured status including broker state,
daemon PID, upstream PID when present, version, and connected client count.
- The payload clearly distinguishes healthy vs reconnecting / not-ready states.
- Frontend consumers can detect whether upstream initialization has completed
without reading `broker.log`.
- Existing control endpoints remain backward-compatible.

## Test-First Plan

1. Add Web UI server tests for a new broker-status endpoint and assert the JSON
schema in both default/no-runtime and broker-runtime-backed modes.
2. Add or extend broker daemon tests for richer `status()` payloads, including
connected session count and readiness indicators.
3. Implement the production changes only after the expected payload shape is
fixed in tests.
4. Run full quality gates after implementation: `pytest`, `ruff check src/`,
`mypy src/`, and `pytest --cov`.

## Execution Plan

### Phase 1: Define the runtime contract

Inputs:
- Existing `BrokerDaemon.status()` behavior
- Existing `/api/control`, `/api/config`, and `/api/sessions` routes

Outputs:
- Final status schema for frontend consumers
- Decision on how broker runtime is injected into the Web UI app

Verification:
- The schema is stable enough to power a future TUI without additional parsing
- Backward-compatible control API behavior is preserved

### Phase 2: Implement daemon + Web UI wiring

Inputs:
- `src/mcpbridge_wrapper/broker/daemon.py`
- `src/mcpbridge_wrapper/webui/server.py`
- broker-daemon startup path in `src/mcpbridge_wrapper/__main__.py`

Outputs:
- Enriched daemon status payload
- Dedicated Web UI broker-status route
- Broker daemon startup passes a runtime status provider/callback into the UI

Verification:
- A running dedicated host returns live daemon/runtime details via HTTP
- Non-broker or dashboard-only runtimes fail gracefully with a clear empty or
unavailable status response instead of crashing

### Phase 3: Lock the behavior with tests and validation

Inputs:
- New endpoint implementation
- Existing server and broker daemon test suites

Outputs:
- Unit tests for the endpoint and status payload
- Validation report with quality gate results

Verification:
- Tests cover healthy and degraded states
- Coverage remains at or above project threshold

## Acceptance Tests

- `pytest tests/unit/test_broker_daemon.py -k status`
- `pytest tests/unit/webui/test_server.py -k broker`
- `pytest`
- `ruff check src/`
- `mypy src/`
- `pytest --cov`

## Decision Points

- The status endpoint should report runtime data through a dedicated API route
such as `/api/broker/status`, not by mutating `/api/control`, because control
and observability are separate concerns.
- Session count should come from the transport/runtime object when available so
the value reflects live attached clients rather than historical audit sessions.
- Readiness should be explicit. A frontend needs to know whether the daemon is
merely alive or whether upstream initialization is complete.

## Notes

- If the Web UI needs a small refactor to accept an optional runtime status
provider, keep that refactor scoped and test-covered.
- Docs updates for using this new surface belong in `P6-T3`, unless a tiny
endpoint mention is required inline for immediate correctness.
- Review subject name for this task: `broker_runtime_status_surface`.

---
**Archived:** 2026-03-07
**Verdict:** PASS
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# P6-T1 Validation Report

**Task:** P6-T1 — Add explicit broker runtime status surface for frontend consumers
**Date:** 2026-03-07
**Verdict:** PASS

## Summary

Implemented a dedicated broker runtime status surface for frontend consumers by:

- enriching `BrokerDaemon.status()` with operator-facing fields
- exposing `GET /api/broker/status` in the Web UI server
- wiring a broker-status provider into broker-daemon Web UI startup
- extending unit tests for daemon status, Web UI status API, and main wiring

## Files Validated

- `src/mcpbridge_wrapper/broker/daemon.py`
- `src/mcpbridge_wrapper/webui/server.py`
- `src/mcpbridge_wrapper/__main__.py`
- `tests/unit/test_broker_daemon.py`
- `tests/unit/webui/test_server.py`
- `tests/unit/test_main.py`

## Targeted Verification

```bash
PYTHONPATH=src pytest tests/unit/test_broker_daemon.py -k status
```

- Result: `3 passed`

```bash
PYTHONPATH=src pytest tests/unit/webui/test_server.py -k 'broker_status or control'
```

- Result: `6 passed`

```bash
PYTHONPATH=src pytest tests/unit/test_main.py -k 'broker_daemon_webui'
```

- Result: `3 passed`

## Required Quality Gates

```bash
PYTHONPATH=src pytest
```

- Result: `787 passed, 5 skipped in 8.02s`

```bash
ruff check src/
```

- Result: `All checks passed!`

```bash
mypy src/
```

- Result: `Success: no issues found in 18 source files`

```bash
PYTHONPATH=src pytest --cov
```

- Result: `787 passed, 5 skipped in 8.94s`
- Coverage: `90.64%`

## Notes

- `PYTHONPATH=src` was required for `pytest` in the current local shell because the package is not installed into that interpreter environment.
- Coverage remains above the repository threshold of `90%`.
- Remaining warnings are pre-existing dependency deprecations from `websockets`/`uvicorn`, not regressions introduced by this task.
47 changes: 47 additions & 0 deletions SPECS/ARCHIVE/_Historical/REVIEW_broker_runtime_status_surface.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
## REVIEW REPORT — Broker Runtime Status Surface

**Scope:** `origin/main..HEAD`
**Files:** 11

### Summary Verdict
- [x] Approve
- [ ] Approve with comments
- [ ] Request changes
- [ ] Block

### Critical Issues

None.

### Secondary Issues

None.

### Architectural Notes

- The new broker runtime status surface is correctly separated from control
concerns by adding `GET /api/broker/status` instead of mutating
`/api/control`.
- `BrokerDaemon.status()` now exposes enough operator-facing state for an
explicit frontend to distinguish healthy, reconnecting, and not-ready broker
states without reading pid files or parsing logs.
- Broker-daemon Web UI startup keeps the new status surface optional, so
non-broker and dashboard-only runtimes remain backward-compatible.

### Tests

- Validation report confirms:
- `PYTHONPATH=src pytest` -> `787 passed, 5 skipped`
- `ruff check src/` -> pass
- `mypy src/` -> pass
- `PYTHONPATH=src pytest --cov` -> `90.64%`
- Targeted status-path tests cover daemon status payloads, Web UI endpoint
responses, and broker-daemon wiring in `__main__.py`.
- Re-ran focused review checks on this branch:
- `PYTHONPATH=src pytest tests/unit/test_broker_daemon.py -k status -q` -> `3 passed`
- `PYTHONPATH=src pytest tests/unit/webui/test_server.py -k broker_status -q` -> `2 passed`

### Next Steps

- FOLLOW-UP skipped: no actionable review findings.
- Proceed to `ARCHIVE-REVIEW` and start planning `P6-T2`.
25 changes: 12 additions & 13 deletions SPECS/INPROGRESS/next.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
# Next Task: Noneall tracked tasks completed
# Next Task: P6-T2Build a terminal frontend for broker daemon monitoring and control

**Priority:** —
**Phase:** —
**Effort:** —
**Dependencies:** —
**Status:** All done
**Priority:** P1
**Phase:** Phase 6: Explicit Broker Frontend
**Dependencies:** P6-T1
**Status:** Ready

## Description

Implement a terminal-first operator interface for the broker daemon so users can explicitly see whether the daemon is running, whether upstream Xcode connectivity is healthy, which clients are attached, and what recent reconnect/error events occurred. The interface should give a clearer operational model than auto-spawn alone.

## Recently Archived

- **P1-T12** (2026-03-07): Improve troubleshooting docs for Zed broker startup timeouts — PASS
- **P5-T2** (2026-03-06): Release 0.4.1 to PyPI and MCP Registry — PASS
- **BUG-T9** (2026-03-06): Fix broker daemon not sending notifications/initialized before tools/list probe — PASS
- **P5-T1** (2026-03-06): Release 0.4.0 to PyPI and MCP Registry — PASS
- `P6-T1` — Add explicit broker runtime status surface for frontend consumers (`PASS`, archived 2026-03-07)

## Description
## Next Step

All tasks in `SPECS/Workplan.md` have been completed. No next task is available.
To add new work, use the `workplan-task-ops` skill or edit `SPECS/Workplan.md` directly.
Run the PLAN command for `P6-T2` and define the TUI scope, entrypoint, and control flow against the new broker runtime status API.
46 changes: 46 additions & 0 deletions SPECS/Workplan.md
Original file line number Diff line number Diff line change
Expand Up @@ -419,3 +419,49 @@ Add new tasks using the canonical template in [TASK_TEMPLATE.md](TASK_TEMPLATE.m
- [ ] MCP Registry entry reflects `0.4.0` (auto-triggered by tag push via CI/CD)
- [ ] README version badge displays `v0.4.0` after PyPI publish propagates (auto after tag push)
- [x] All quality gates pass on the tagged commit (`pytest` 785 tests, 90.91% coverage, `ruff`, `mypy`, DocC sync, package assets check)

### Phase 6: Explicit Broker Frontend

#### ✅ P6-T1: Add explicit broker runtime status surface for frontend consumers
- **Status:** ✅ Completed (2026-03-07)
- **Description:** Add a structured runtime status surface for the persistent broker so explicit frontends do not need to infer daemon health from pid files and log parsing alone. The surface should expose broker lifecycle state, upstream pid/availability, client session counts, and other operator-facing details that explain whether the daemon is healthy, reconnecting, or awaiting approval.
- **Priority:** P1
- **Dependencies:** none
- **Parallelizable:** yes
- **Outputs/Artifacts:**
- `src/mcpbridge_wrapper/broker/daemon.py` runtime status payload extended with readiness, upstream-health, and connected-client details
- `src/mcpbridge_wrapper/webui/server.py` new `GET /api/broker/status` endpoint for frontend consumers
- `src/mcpbridge_wrapper/__main__.py` broker-daemon Web UI wiring updated to publish live runtime status
- `tests/unit/test_broker_daemon.py`, `tests/unit/webui/test_server.py`, and `tests/unit/test_main.py` covering healthy and degraded runtime status flows
- **Acceptance Criteria:**
- [x] Dedicated broker host exposes structured runtime status including broker state, daemon pid, upstream pid (when present), version, and connected client count
- [x] Status makes reconnecting/not-ready states explicit so a frontend can distinguish them from a healthy shared daemon
- [x] Automated tests cover both healthy and degraded broker runtime status responses

#### ⬜️ P6-T2: Build a terminal frontend for broker daemon monitoring and control
- **Description:** Implement a terminal-first operator interface for the broker daemon so users can explicitly see whether the daemon is running, whether upstream Xcode connectivity is healthy, which clients are attached, and what recent reconnect/error events occurred. The interface should give a clearer operational model than auto-spawn alone.
- **Priority:** P1
- **Dependencies:** P6-T1
- **Parallelizable:** no
- **Outputs/Artifacts:**
- `src/mcpbridge_wrapper/` TUI entrypoint/module for broker monitoring and control
- Tests covering the TUI status rendering and control integration where practical
- CLI/docs wiring for launching the TUI
- **Acceptance Criteria:**
- [ ] Users can launch a terminal UI from the wrapper package to inspect broker runtime state without tailing logs manually
- [ ] The TUI shows at minimum broker state, daemon/upstream PIDs, connected client count, and recent broker events or reconnect indicators
- [ ] The TUI exposes at least one explicit control action for the daemon lifecycle (for example stop or restart)

#### ⬜️ P6-T3: Document the explicit dedicated-host frontend workflow
- **Description:** Update the operator docs so the recommended path for multi-editor setups is an explicit dedicated broker host plus a single monitoring frontend. The docs should explain when to prefer a dedicated host over implicit auto-spawn, how to verify that both editors share one daemon, and how the new frontend fits into that workflow.
- **Priority:** P2
- **Dependencies:** P6-T1, P6-T2
- **Parallelizable:** yes
- **Outputs/Artifacts:**
- `README.md` dedicated-host guidance updated to mention the explicit frontend
- `docs/broker-mode.md` and related docs updated with the recommended monitoring/control workflow
- Any new frontend usage documentation added under `docs/`
- **Acceptance Criteria:**
- [ ] README explains the dedicated-host + frontend workflow for users who want explicit visibility into daemon health
- [ ] Broker docs describe how to confirm that multiple editors are attached to one shared daemon
- [ ] Frontend launch and troubleshooting steps are documented in a user-facing guide
7 changes: 7 additions & 0 deletions src/mcpbridge_wrapper/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -618,6 +618,12 @@ def main() -> int:
metrics = None
audit = None

def get_broker_status() -> Optional[Dict[str, Any]]:
"""Return live broker runtime status for explicit frontend consumers."""
if daemon is None:
return None
return daemon.status()

if web_ui_enabled:
runtime = _prepare_webui_runtime(
web_ui_port=web_ui_port,
Expand Down Expand Up @@ -656,6 +662,7 @@ def request_broker_shutdown() -> None:
audit,
service_name="broker-daemon",
request_stop=request_broker_shutdown,
broker_status_provider=get_broker_status,
)
print(
f"Web UI dashboard started at http://{config.host}:{config.port}",
Expand Down
Loading