AGENTS.md@packages/chat-gateway/src/client · git:20260919.9482906 · 2026-09-19 · sha256 6c62fd946d68dc80

AGENTS.md@packages/chat-gateway/src/client git:20260919.9482906A

Immutable. This exact content is served forever at /api/v1/blob/6c62fd946d68dc80.

# DOX — packages/chat-gateway/src/client

Files in this directory. One row per source file. See change: add-chat-gateway.

| File | Purpose |
|------|---------|
| `index.tsx` | Settings-section client entry, claimed by `pi-dashboard-plugin.claims[]` as `ChatGatewaySettings`. Edits config (enabled, token, `allowedRoots`, `defaultCwd`, `fixedMap`, `allowlist`, `admins`, `groupChannels`, `steerPrefix`) and persists via `usePluginSend()`+`plugin_config_write`; a BLANK token is omitted so a save cannot erase the stored secret. Reads the read-only bindings/pairing/status view from `GET /api/chat-gateway/bindings`. The bot token NEVER arrives here: it is `writeOnly` in `configSchema.json` and stripped host-side by `redactWriteOnly`. Renders `<TeamControlsPanel />` below the gateway fields (`teamControls` is edited there, not here, because only that lane can await the platform). Tested in `__tests__/ChatGatewaySettings.test.tsx` (jsdom) — note its `configWrites()` helper: the nested panel sends its own surface request on mount, so a raw `sendMock` call count is no longer 1:1 with a config write. |
| `team-controls-panel.tsx` | `TeamControlsPanel` — the team-controls configuration surface (tasks 8.1-8.4), a PURE RENDERER of `TeamSurfaceView` that decides nothing. Renders per binding: principals, role map with the delegation disclosure, ceiling, mirror level, provisioned channel, provisioning problem, and folders with the inert ones marked. Shows the live disarm state plus a Re-arm control when disarmed. Reads/writes ride the plugin's browser-handler lane (`TEAM_SURFACE_MESSAGE` / `TEAM_CONFIG_MESSAGE`, no new HTTP route); re-arm WRITES config rather than issuing a chat verb, which is exactly the dashboard-only asymmetry the spec requires. The delegation disclosure renders `unavailable` as "missing permission: X" and an empty roster as "Nobody can assign this role" — the two states must never collapse, or a role looks safe precisely when the platform declined to say who holds it. Tested in `__tests__/team-controls-panel.test.tsx` (jsdom). |