From 0bfcf2ea323e9ac089966967eb6d567bd0c46e90 Mon Sep 17 00:00:00 2001 From: "autohub-codex[bot]" <334634853+autohub-codex[bot]@users.noreply.github.com> Date: Sun, 8 Nov 2026 08:25:39 +0100 Subject: [PATCH] docs(command): document the command-center checkpoint --- .superpowers/sdd/town-trades-art-report.md | 11 ++ .superpowers/sdd/town-trades-panel-report.md | 11 ++ README.md | 73 +++++++++- docs/COMMAND_CENTER_EXPLORATION.md | 129 ++++++++++++++++++ docs/COTTAGE_FEED.md | 124 +++++++++++++++-- .../plans/2026-11-04-command-center.md | 88 ++++++++++++ .../2026-11-04-town-command-integration.md | 75 ++++++++++ .../specs/2026-11-04-command-center-design.md | 67 +++++++++ .../2026-11-04-town-command-integration.md | 13 ++ .../specs/2026-11-05-living-town.md | 21 +++ 10 files changed, 603 insertions(+), 9 deletions(-) create mode 100644 .superpowers/sdd/town-trades-art-report.md create mode 100644 .superpowers/sdd/town-trades-panel-report.md create mode 100644 docs/COMMAND_CENTER_EXPLORATION.md create mode 100644 docs/superpowers/plans/2026-11-04-command-center.md create mode 100644 docs/superpowers/plans/2026-11-04-town-command-integration.md create mode 100644 docs/superpowers/specs/2026-11-04-command-center-design.md create mode 100644 docs/superpowers/specs/2026-11-04-town-command-integration.md create mode 100644 docs/superpowers/specs/2026-11-05-living-town.md diff --git a/.superpowers/sdd/town-trades-art-report.md b/.superpowers/sdd/town-trades-art-report.md new file mode 100644 index 0000000..70f47e5 --- /dev/null +++ b/.superpowers/sdd/town-trades-art-report.md @@ -0,0 +1,11 @@ +# Town trades art + +Implemented `src/trade-art.mjs` with pure `drawTradeLife(ctx, options)` and shared `tradeSites(options)` geometry. No state, dependencies, polling, world mutation or invented routes. + +- Miners use exact resident, roommate or child IDs and occupy the household side yard. One compact site per household avoids overlapping miners. A small timber mine, visible ore, helmet lamp and timed pick sparks make the read/search role legible. +- Roadmenders prefer a visible recorded destination, then the recorded source. They occupy the nearest supplied road rectangle; no street rectangle means no roadmender. Paving, a low striped barrier, stacked stone and a lifting mallet remain inside the existing road. +- Garden work yards fit the lower district margin and avoid cottages/branch signs. They include a potting bench, up to six seedlings, a wheelbarrow and gardener. Growing gardens gently haul; growth spurts pause with a hand at the brow. The visual seedling cap does not change actual arrival data. +- Every site returns `{role, taskId, town, x, y, w, h, evidence, clip}`. Roles are `miner`, `road`, `gardener`. The host can use actual painted bounds and direct evidence for explanatory click targets. Garden task IDs are limited to visible recorded households. +- Site clipping and outer/per-site `save`/`restore` protect the host canvas, including exceptions. Reduced motion and stale force identical paint calls across clocks. Town filtering and supplied visible plots control scope. + +Verification: `node --test test/trade-art.test.mjs` — seven tests pass. Tests cover exact household attribution, existing-road geometry, town and visible-plot scope, garden margin fit, bounded seedlings, time-invariant stillness, active animation, input nonmutation, clipping and canvas restoration on paint failure. Parent owns integrated browser verification and the full suite. diff --git a/.superpowers/sdd/town-trades-panel-report.md b/.superpowers/sdd/town-trades-panel-report.md new file mode 100644 index 0000000..ec3b303 --- /dev/null +++ b/.superpowers/sdd/town-trades-panel-report.md @@ -0,0 +1,11 @@ +# Village activity panel + +Added `src/trade-panel.mjs`, integrated into `src/command-center.mjs`, and styled in `src/command-styles.mjs`. + +The compact, collapsed-by-default Village activity ribbon counts miners, explicit road crews and actual arrivals in the selected town. Expanding exposes keyboard-accessible evidence buttons and a selected story. The story renders current recorded title/reason/time and offers Inspect cottage only for an exact supported task ID. All source strings and attributes are escaped. + +The host passes `options.trades` to each command-center update and may call `commandCenter.inspectTrade(site)` for a painted trade. Supported roles are `miner`, `road`, `gardener`; matching uses current story role/town/task identity (or exact event ID). Missing matches open the ribbon without inventing an explanation. Expired/out-of-scope stories close automatically on update. Source changes clear selection and discard previous trades if no replacement was supplied. + +`onRehearseGrowth` is a new createCommandCenter callback. The Rehearse growth button appears only when builtInDemo/publicDemo is true, and the click handler rechecks that flag. Field guide text explains real read/search tools, unknown missing evidence, new explicit links, first observed arrivals over ten minutes, and the gardener pause's growth meaning. + +Verification: five new pure helper tests pass, plus 42 existing command-center/model/workbench tests. No browser run in this slice; parent owns host integration and browser verification. diff --git a/README.md b/README.md index 5b09437..1c7d6ee 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ Click the map to give it keyboard focus. | + / − or zoom buttons | Zoom the Townmap between 50% and 200% | | 0 / percentage button | Reset to the initial map scale (100%) | | Overview | Frame working and blocked cottages, including active roommates and shed residents | -| Details / Close | Show or hide the floating inspector in fullscreen | +| Evidence / Close | Show or hide the shared inspector in any view | | Click a cottage or its roster button | Open its inspector without walking there | | Enter cottage / Leave cottage | Visit or exit using buttons | | Click a resident / Talk to agent | Open their conversation and recorded activity | @@ -116,6 +116,77 @@ and no longer create false input alerts. Use **Follow from bench** to keep one cottage selected as its work updates. The noticeboard lists changes observed since the previous visit. The scrapbook stores up to 1,600 milestones per feed in this browser, including result snippets and artifact links. Replay steps through that recorded history; it cannot reconstruct unobserved work or expired source logs. +## 🧭 Oversee the village + +Townmap remains the playable home. Its **attention strip** shows the actual question +or recorded blocker and cycles through work that needs attention. The **Village, +Attention, Time, Delivery, and Owner lenses** annotate existing plots without +moving cottages. Choose Village for the original scenery. + +**Dispatch** is a compact ledger of tasks, public activity, owner/harness, clocks, +and delivery. **Threads** follows recorded issues, parent/child tasks, +dependencies, and shared PRs; narrow screens show a readable cottage trace. +Missing relationships stay missing. PR badges open a preview on hover or keyboard +focus and the existing PR desk on click. + +All views share the same evidence inspector, journal, and reply composer. +Switching views preserves Jack, the camera, the occupied room, and the selected +work. Dispatch and Threads open beneath the playable town; the balance slider +gives either surface more room. Walking continues with a workbench open. +Choose a project in the heartbeat rail to scope the evidence and frame its +cottages. Overview can fit below the ordinary manual zoom range for distant annexes. +**Visit activity** brings you to an active or attention cottage in that project +at normal street zoom, including when you start inside a room. Project pulses +show both attention and ready shipments when a neighbourhood has each. + +The **Village activity** ribbon explains the small work yards in the scene. +Click a worker or choose its accessible story button: + +- **Miners** gather material beside cottages with a read/search tool observed in + the last two minutes, while the canonical task is working. Generic shell tools + and task prose do not imply mining. This is recent tool evidence, not proof + that the individual call is still running. +- **Workshops** light a small workbench beside working cottages with other + recent tool use, including shell calls. They use the same two-minute evidence + window and do not infer what a command does. +- **Roadmenders** work on existing streets for three minutes after a newly + observed explicit parent/dependency link or a recent recorded handoff. +- **Gardeners** gain seedlings for residents first observed in the last ten + minutes. Three arrivals make a growth spurt: more pots and a pause beside the + full bench. The initial snapshot establishes a baseline, without an arrival + parade. A calm garden does not imply idle agents. + +Unknown tool coverage stays unknown. Stale feeds and reduced motion stop the +moving trade cues. Source changes clear observations; view changes do not invent +arrivals. In `/?demo=1`, **Rehearse growth** adds three illustrative residents, +recorded read/search tools, and a parent link without contacting real agents. +Expand the ribbon to compare recent, older/stale, and unreported tool evidence +for the selected project, and inspect a working cottage's exact tool name and +observation age. A fresh feed check does not make an older tool event recent. + +| Key | Action | +|---|---| +| `1` / `2` / `3` | Townmap / Dispatch / Threads | +| `Cmd/Ctrl+K` | Find a cottage by name, task, town, owner, PR, or recorded issue | +| `J` / `K` in command views | Inspect next / previous visible task | +| `↑` / `↓` / `Enter` in search | Choose and inspect a match | +| `Escape` in command views | Close search/preview first, then return to the same place in town | + +Task age includes waiting; recorded execution, session age, last observation, and +last progress are separate evidence. Quiet means at least 15 minutes since explicit +progress, not a confirmed stall. Unknown harnesses and clocks are labeled honestly. +Shared PR counts and states are reconciled across the fleet before filtering. +The header's recorded cost is a partial subtotal of visible live/recent task +records, not spend during a time interval. Running usage and unpriced sources +may be missing; a healthy tool feed does not imply complete cost coverage. +Hub verification remains authoritative through an outage; local staleness cannot +turn an unverified standalone PR green. + +Only an explicit Send uses a supported message route. The client rechecks the +latest task, question revision, status, and route, and persists a receipt before +transport. Uncertain delivery stays locked across reloads instead of retrying. +Draft text survives view changes and polling, but not a page reload. + ## 🔌 Cottage feed `npm start` serves the townmap and `GET /agents`. The connect box defaults to that URL. Drop in any other endpoint that speaks the [cottage feed](docs/COTTAGE_FEED.md) shape. diff --git a/docs/COMMAND_CENTER_EXPLORATION.md b/docs/COMMAND_CENTER_EXPLORATION.md new file mode 100644 index 0000000..988313a --- /dev/null +++ b/docs/COMMAND_CENTER_EXPLORATION.md @@ -0,0 +1,129 @@ +# A command center that still feels like CottageCode + +2026-11-04 · local exploration · branch `feat/command-center-lab` + +## Recommendation + +Keep the town. Give it a working attention desk and an evidence ledger. Three perspectives should be three ways of looking at the same work, with selection preserved: Townwatch for recognition, Dispatch for deciding, Threads for understanding relationships. A person should be able to answer a current question or inspect a PR without walking anywhere. + +The first production increment should be the attention strip, readable task titles, independent task/session clocks, and the selected-cottage evidence drawer. Fold the useful parts of these prototypes into the existing renderer. Keep the original village interactions, rather than replacing the whole product with a table. + +## What belongs in sight + +| Question | At a glance | On focus or click | +| --- | --- | --- | +| What needs me? | Unanswered-input count, precise attention symbol | Exact source question, age, choices, owner and supported reply route | +| What can ship? | Unique ready PR count | Source state, current/reviewed head, CI, review, remaining manual verification and dependency evidence | +| Is anything stuck? | Explicit blocked state; separately a quiet-progress hint | Last real progress, active tool/wait, heartbeat health, expected next event; unknown when not instrumented | +| What is it doing? | Short meaningful task title and latest public action | Original ask, public journal, structured checklist | +| How long? | Time lens | Separate task age, session age, recorded duration and observation freshness | +| Who owns this? | Harness name/mark when supplied | Controller/orchestrator, full provider/model, parent and exact source destination | +| What work is this part of? | Selected connections | Issue, planned work item, attempts, related PR stack and required landing order | +| What changed while I was away? | Locally observed transition count | Bounded since-last-visit digest; never invented historical progress | + +Counts are scoped and labelled. PR counts deduplicate shared identities. Current execution, pending input, PR readiness and telemetry freshness remain independent: an agent can be idle while its PR waits on CI; a working agent can have a question on a separate attempt; a finished response does not make an issue complete. + +## A visual language with one job per signal + +- Windows and smoke indicate working execution. Night scenery never changes source state. +- A letter/diamond identifies a recorded input or attention report. Reading it is not resolving it. +- A parcel/PR badge shows delivery state independently of execution. Mint means canonical ready; coral means blocked; lavender means review; a hollow shape means unknown. +- Harness is a neutral monogram/wordmark. Do not consume the warning colours to distinguish models. +- Time appears on demand. Separate “task 42m”, “session 2h”, “observed 8s ago” and “progress 6m ago”. An observation heartbeat cannot reset the progress clock. +- Motion celebrates actual transitions and helps locate selection. Polling is silent. No persistent flashing, no racing timer labels, and reduced-motion users get the same information. +- Connections appear only around the selected work, and only for recorded relationships. Town positions stay stable across lens changes. + +## Your actual workflow changes the design + +The merged AutoHub Todoist work explicitly keeps intentionally planned tasks on the AutoJack Tasks board and non-board dispatches in mission control. CottageCode should join their evidence when a relationship exists. It should not manufacture a Todoist task for every cottage or become a second planning backlog. Sources: [#2393](https://github.com/verygoodplugins/autohub/pull/2393), [#2394](https://github.com/verygoodplugins/autohub/pull/2394), [#2395](https://github.com/verygoodplugins/autohub/pull/2395). + +The November 3 [Pulse dataset](https://pulse.automem.ai/activity-data.json) records 2,576 commits over 25 repositories in its trailing 30-day window, versus 72 over six in its last seven days. This is a bounded set of local repos and selected authors, and commits are not outcomes. The product implication is to reduce context-switch cost across a bursty portfolio, not reward more movement with a productivity score. + +Your actual issue graph already crosses task and repository boundaries. [AutoApp #320](https://github.com/verygoodplugins/AutoApp/issues/320) has a [foundation PR](https://github.com/verygoodplugins/AutoApp/pull/464) and a [dependent fix](https://github.com/verygoodplugins/AutoApp/pull/465); the foundation alone does not resolve the issue. [AutoMem evals #78](https://github.com/verygoodplugins/automem-evals/pull/78) verifies [AutoMem #273](https://github.com/verygoodplugins/automem/pull/273). These are reasons to model explicit edges, rather than drawing attractive but guessed lines between cottages. + +Recent chat summaries also include repeated nightly runs, decision holds and physical-device verification. Eventually the feed should supply a durable workflow/work-item id so repeated runs can expand beneath one objective. Grouping by similar titles would hide distinct work and is not a valid substitute. + +## What the current feed can and cannot promise + +The initial live capture had 216 records: 37 current/recent and 179 settled. Nine records carried input requests, but only one exposed a supported response route. Some “questions” were blocker reports. The UI must show the actual text and capability reason instead of inventing a question or an enabled Answer button. + +All six working records in that capture were external sessions with no explicit task start. They did have session time. Their updatedAt observations were near the latest feed refresh, so this timestamp cannot prove meaningful progress. A running timer derived from the wrong field would look reassuring while being false. + +The existing model flag and red attention signal are also overloaded visually: roof pennants represent normalized model family; the raised red mailbox means a blocked task or blocked PR; the red exclamation marks have task/parcel-specific meanings. They do not detect stalls. Tooltips and explicit labels fix the immediate ambiguity, while independent state channels improve the larger system. + +## Upstream additions that unlock the full experience + +These are proposed additive fields, not existing capabilities: + +```json +{ + "workItem": {"id": "stable-source-id", "url": "https://tracker.example/task/42", "source": "todoist"}, + "attemptId": "attempt-3", + "harness": {"name": "codex", "provider": "openai", "model": "full-model-id", "controller": "autohub"}, + "telemetry": { + "progressAt": "2026-11-04T10:00:00Z", + "observedAt": "2026-11-04T10:01:00Z", + "heartbeatAt": "2026-11-04T10:00:55Z", + "waitingFor": {"kind": "ci", "since": "2026-11-04T09:58:00Z", "nextCheckAt": "2026-11-04T10:03:00Z"} + }, + "sourceLinks": [{"kind": "session", "url": "https://supported-source.example/sessions/known-id"}], + "issues": [{"url": "https://github.com/example/project/issues/42", "title": "Explicitly linked outcome"}] +} +``` + +Add typed relationships such as `implements`, `depends_on`, `reviews`, `verifies`, `attempt_of` and `handoff`. The producer supplies canonical source identity and provenance; the browser does not mine prose for these. A real stall classification requires source health, expected waits and meaningful-progress telemetry. No universal “15 minutes = stalled” rule is credible across coding, CI, music generation and device checks. + +The reply path also needs a producer-owned contract: current question revision, supported actions, exact destination and durable receipt. The prototype retains the existing CottageCode/Hub mechanism. Native provider permissions should route to the native interface unless the provider explicitly supports remote authorization. + +## What to borrow + +[Anthropic's April 14 desktop redesign](https://claude.com/resources/articles/claude-code-desktop-redesign) emphasizes status/project/environment filtering, session navigation, PR lifecycle and adjustable verbosity. Borrow progressive detail, not a permanent wall of transcripts. + +[cmux notifications](https://cmux.com/docs/notifications) offer persistent attention and direct navigation. Keep “seen” separate from “resolved”. Its [generic-waiting issue](https://github.com/manaflow-ai/cmux/issues/4506) captures the precise failure to avoid: an alert without identity, reason or actual question. + +[Conductor's workflow](https://www.conductor.build/docs/concepts/workflow) separates workspace execution from PR integration. Treat a PR as a shared object, not property duplicated into five independent green counts. + +The [Reddit Brain showcase](https://www.reddit.com/r/ClaudeCode/comments/1ww6hvj/i_run_15_claude_code_sessions_in_parallel_and/) makes oldest-wait-first triage and exact questions compelling. This is a builder's anecdote, not evidence of widespread adoption. The [official Claude hook reference](https://code.claude.com/docs/en/hooks) reinforces the important distinction: a finished response or idle notification does not establish a genuine human-input requirement. + +## Deliberately outside this experiment + +No automatic merges, retries, restarts, approvals or dispatches. No universal chat transport invented for providers that only expose observation. No new planning backlog. No productivity leaderboard. No inference that green CI, a closed agent turn or lively animation means an outcome safely shipped. + +## Implemented exploration and acceptance + +The isolated lab runs at `http://127.0.0.1:8790/`. It defaults to the existing live feed; `?view=townwatch|dispatch|threads&scenario=1` selects the visibly fictional scenario. The original app on port 8787 and its production source files are unchanged. Start commands and interaction details are in [the lab README](../experiments/command-center/README.md). + +The final core suite passed 382 tests. Independent task reviews and a whole-branch Astra review completed; their findings were fixed and re-reviewed. Browser acceptance covered all three views, fixed cottage coordinates across lens changes, keyboard search and selection, PR focus previews, shared-PR counts, exact-question choices and local-only reply receipts, narrow layouts without horizontal overflow, both directions of the dependency trace, live/scenario switching, and live ready-PR filtering. Stopping and restarting only the lab server verified last-snapshot retention, an explicit outage banner, paused messaging and recovery. A temporary unsent draft survived live polling and was cleared. No live messages were sent. + +Live verification exposed two lifecycle distinctions now handled explicitly: a resumed task can retain a historical end timestamp, and Hub's recorded execution duration excludes subsequent waiting. Current nonterminal state controls the live clock and reply eligibility; task age comes from the explicit task start, while recorded execution has its own drawer label. For example, the observed AutoHub #2384 task was about six days old with 22m 14s of recorded execution. + +Remaining prototype limits: public journals render supplied inline events but do not yet lazily fetch the existing activity endpoint; drafts survive polling and view changes but not page reload; the responsive district grid guarantees stable lens positions and ordering, rather than the original renderer's fixed world coordinates across every viewport. The live feed currently lacks structured harness and issue relationships for these records. Those omissions remain visible instead of being inferred from model names or prose. + +## Original-town integration + +The next approved iteration brings attention, lenses, Dispatch and Threads into +`src/town.html` and the original canvas. The integrated preview is at +`http://127.0.0.1:8791/` (`?demo=1` for fictional data). The original process on +8787 remains running from its separate checkout. The standalone lab is retained +as design history, not the replacement home. + +The shared inspector now separates the task being read from the cottage being +visited. It keeps the existing paginated journal, room objects and local demo +responses. View changes suspend movement without reseeding rooms or moving plots; +explicit spatial actions return to Townmap. Keyboard search includes names and +recorded issue links. Threads allocates only populated lanes and uses a vertical +trace where a fleet graph would be too crowded. + +Verification covers actual WASD doorway entry/exit, E addressing the physical +host after inspecting another task, an approached duck swimming to its pond, +room/position preservation, suspended movement, local practice replies, live +unsent draft continuity, source-change clearing, stale messaging suppression and +recovery, PR previews, fullscreen drawer space and narrow layouts. No messages +were sent to real agents. The live feed still omits structured harness names and +issue links; the interface displays that absence. + +Final integrated validation: 414 Node tests pass, including static public-demo +bundling and network restrictions. Independent task reviews and the final Astra +review are clean. Browser checks also confirmed paused-feed clock agreement, +stable native lens selectors, PR previews surviving updates, and a single +recorded PR state across map markers, lenses, lists and the drawer. diff --git a/docs/COTTAGE_FEED.md b/docs/COTTAGE_FEED.md index 154764d..8d990a0 100644 --- a/docs/COTTAGE_FEED.md +++ b/docs/COTTAGE_FEED.md @@ -29,7 +29,15 @@ Optional envelope fields: An empty custom feed stays empty. The bundled same-origin `/agents` endpoint has an onboarding exception: an empty snapshot with `source: "none"` opens the demo until local agents appear. Demo history uses its own namespace. -The browser polls every 1.5 seconds. HTTP failures keep the last snapshot from the same endpoint, marked stale; they never substitute another feed. The Node adapters refresh every 2 seconds. GitHub enrichment runs on its own slower cache. +The bundled browser feed subscribes to same-origin `GET /agents/events` for immediate +refresh notifications. Each `event: change` carries only `{ "revision": number | null }`; +it is sent after the normalized `/agents` cache has been committed. A connection or +reconnection sends a notification with a null revision to request a fresh snapshot. +The stream never forwards raw upstream events or credentials. Arbitrary custom JSON +feeds are not assumed to implement this route. Pause closes the subscription; +resume reconnects and refreshes immediately. Endpoint changes fence off old notifications. + +The browser also polls every 1.5 seconds as a fallback. HTTP failures keep the last snapshot from the same endpoint, marked stale; they never substitute another feed. The Node adapters refresh every 2 seconds. GitHub enrichment runs on its own slower cache. CORS: the browser fetches the URL entered in the connect box. Serve `Access-Control-Allow-Origin: *` (or the CottageCode origin) for feeds and activity endpoints on another host. The bundled server defaults to `127.0.0.1:8787` and permits its `/agents` and activity routes only to a Townmap loaded from that same origin; it does not provide CORS access to its local agent data. To use a separately hosted Townmap, point it at a separate feed/activity service that allows the Townmap origin, or host that service and the Townmap together. Message writes require this server's own origin, JSON, and the explicit message header described below. @@ -57,7 +65,7 @@ Full shape (everything else is optional): | `role` | string | Fallback for `town` if `town` is missing. | | `status` | string | One of `working` `idle` `blocked` `done` `offline`. | | `occupancy` | string | `live` `recent` `settled`. Optional. If omitted, the townmap classifies from `status` + timestamps (done ages out after ~2h). | -| `inventoryScope` | string | Optional canonical Hub membership: `dashboard` keeps Live + recent tasks visible; `history` keeps older tasks settled, including those with historical PR links. Omit for standalone/custom classification. | +| `inventoryScope` | string | Optional Hub membership: `dashboard` keeps Live + recent roots visible; `family` includes canonically fresh active external sessions with an explicit parent chain to a dashboard root; `history` keeps other tasks settled, including those with historical PR links. Omit for standalone/custom classification. | | `parent` | string \| null | Id of the parent cottage. Kids render as sheds in the yard. | | `task` | string | Short description of the current work. Separate from the original request. | | `taskId` | string \| null | Explicit task/run identity. Changes reset the room and activity cache for that cottage. | @@ -83,16 +91,22 @@ Full shape (everything else is optional): | `lastLine` | string | Latest log line / thought bubble fodder. | | `attention` | string | Why it's blocked. Shows up in Jack's letter pile. | | `handoffUrl` | string | Optional https handoff link. | -| `model` | string | `opus` `sonnet` `haiku` `gpt` `local` `mlx` (or a string containing those). Roof flag color. | +| `model` | string | Full source model identifier, retained in evidence. Known `opus` `sonnet` `haiku` `gpt` `local` `mlx` substrings choose roof flag color. | +| `harness` | string | Explicit execution harness, such as Claude Code or Codex. Never inferred from the model. `execution.harness` is also accepted. | +| `owner` | string | Optional explicit responsible party; otherwise command views show the supplied harness or Unknown. | +| `lastProgressAt` | number \| null | Last meaningful progress reported by the producer; `telemetry.progressAt` is also accepted. Observation time does not substitute. | +| `durationMs` | number \| null | Recorded execution duration, independent from wall-clock task age and waits. | +| `issues` | array | Explicit `{url, title?, number?}` issue links. HTTP/HTTPS only. Used by Threads and search; never parsed from prose. | | `dispatchedBy` | string | Who sent it. | | `taskStartedAt` | number \| null | Start of the identified task, in epoch milliseconds. | | `sessionStartedAt` | number \| null | Start of the enclosing session, in epoch milliseconds. | +| `turnStartedAt` | number \| null | Latest explicitly observed turn start within a persistent session, in epoch milliseconds. | | `startedAt` | number \| null | Legacy start value, still accepted for occupancy. It does not replace the explicit task/session clocks. | | `endedAt` | number \| null | Known completion time. The task clock uses it to stop elapsed time for terminal tasks. | | `terminal` | boolean | Optional. Set when a terminal source record is presented as `blocked` for attention; the task clock stops at `endedAt`. | | `updatedAt` | number \| null | Time of the last signal. | -| `tokens` | number | | -| `cost` | number | USD for this run. | +| `tokens` | number or null | Recorded run total; missing measurements stay null. | +| `cost` | number or null | Recorded USD for this run; missing pricing stays null. | | `pr` | object | PR identity, state, and review evidence. See [Pull requests](#pull-requests). | | `interiorTheme` | string | Optional `hub`, `app`, `memory`, `vault`, or `neutral` furniture theme. `theme` is an accepted alias. | @@ -100,6 +114,12 @@ Full shape (everything else is optional): Supply `taskId` and `taskStartedAt` only when the source identifies a task. A recent assistant response or file modification is not a new task start. Missing or invalid clocks show **Unavailable**; they are never filled with the current time. +The Codex desktop rollout observer's canonical `startedAt` is the latest turn +boundary. CottageCode maps it to `turnStartedAt`, shown as **Current turn age / +Current turn started**. It does not infer the persistent session's creation time +from that value; session clocks stay unavailable without an explicit session +start. A turn boundary alone also does not establish a separate logical task. + The local transcript adapter preserves the first genuine user request, excluding tool replies, runtime metadata, and compaction summaries. Explicit `taskId`/`runId` records establish task boundaries. Without them, `taskId` and `taskStartedAt` remain null, and `originalAskSource: "session"` labels the pinned note as the first request in that session. Assistant updates populate activity instead of replacing the request. ### Activity @@ -448,8 +468,24 @@ npx --yes http-server . -p 9999 --cors ### Shared Hub inventory mode -The Node process caches dashboard reads for five seconds and history for one -minute, using up to 500 tasks per page. It allows 45 seconds for a Hub request +The Node process keeps one authenticated connection to Hub's shared +`GET /v1/agent-events/stream`. A canonical `task_updated` notification wakes inventory +hydration immediately, including new children, lifecycle changes, and explicit parent +links. Event payloads are invalidation hints; canonical task detail remains the +authority for status, ancestry, readiness, and permissions. New snapshots reach the +browser through the local notification stream and use the existing layout/path logic. +The stream does not claim user presence or send messages to agents. + +Fallback reads cache dashboard data for five seconds and history for one +minute, using up to 500 tasks per page. Task-change notifications bypass those delays; +tool and usage notifications update telemetry without repaging all history. Reconnect, +cursor reset, and reported telemetry gaps force canonical resynchronization. A global +`task_updated` hint with `payload.resync: true` also resynchronizes inventory when a +canonical task or parent ID cannot fit telemetry's bounded identifier vocabulary. +Invalidations +received during a read schedule another pass, so an older response cannot consume a newer +notification. A missing or disconnected stream leaves ordinary polling available. +It allows 45 seconds for a Hub request to finish during database contention instead of abandoning and requeuing it. It follows all cursor pages for both `history` and `dashboard` before replacing a snapshot. @@ -481,4 +517,76 @@ Hub cottages also expose `executionStatus`, `version`, `finalization` (`status`, Hub PR observations carry `authority: "hub"`: `reviewState` comes from canonical finalization, while raw `labels` remain evidence. The browser preserves that verified state during an outage and marks its evidence stale. It does not infer readiness from a stale ready label or overrule Hub's head-change blocker. Standalone observations retain conservative freshness-based classification. -Hub `durationMs` is the recorded execution time; review and merge waits do not inflate elapsed time. Hub also owns PR freshness, including immutable merged observations. Once cleanup is `removed`, the historical worktree path remains copyable but no longer offers an open action. +Hub `durationMs` is recorded execution time. The command center labels it separately from task age, which includes review and merge waits. Hub also owns PR freshness, including immutable merged observations. Once cleanup is `removed`, the historical worktree path remains copyable but no longer offers an open action. + +### Recorded work relationships in Threads + +The command center accepts typed `relationships` whose `from` and `to` refer to +known nodes: `task:`, `pr://#` +(for example, `pr:github.com/example/project#42`), or +`issue:`. PR repository keys are lowercase. Kinds such as `depends-on` are shown with the arrow +from prerequisite to dependent. It also creates typed links from supplied +`parent`, `issues`, and PR evidence. Shared PRs have one node. Town-to-town paths +continue using the existing town relationship contract; they do not imply task +or issue dependencies. Missing issue links have an explicit empty explanation. + +### Optional Hub tool telemetry + +Hub-backed inventory refreshes make one shared, authenticated server-side +`GET /v1/agent-events/snapshot?limit=200` request. It shares the inventory cache +and concurrent reads, runs alongside canonical inventory reads, and has an +independent 3 second timeout. Missing endpoints, errors and partial telemetry +never change task membership, lifecycle, PR readiness, permissions or input. +The browser does not poll this endpoint. + +A cottage may carry `toolActivity: null` or the small allowlisted object: + +```json +{"name":"read_file","state":"started","at":1793880000000,"callId":"call-1","source":"hub:agent-events","stale":false} +``` + +States preserve Hub's `started`, `succeeded`, `failed`, or `cancelled` spelling. +`at` is Unix milliseconds from the explicit tool fact. Names and optional call +IDs are bounded to 120 identifier characters; malformed facts are unavailable. +Facts older than two minutes or from canonically stale inventory have +`stale: true`. A timestamp more than 30 seconds in the future is rejected. + +`toolCoverage: {available, reason}` distinguishes a valid fact (reason `null`, +or `partial` for an incomplete Hub snapshot) from unavailable evidence +(`unavailable`, `missing_task`, `ambiguous_task`, `missing_scope`, +`ambiguous_scope`, `stale_scope`, `missing_tool`, or `invalid_tool`). +It does not claim complete event history or infer that no tool was used. +An attempt with no retained scope, or an observed session absent from the +snapshot, reports `missing_scope`; conflicting or non-unique matches remain +`ambiguous_scope`. Neither condition permits falling back to another identity. + +Telemetry joins exact `cottage.taskId` to projected `taskId`. Managed tasks use +only the uniquely marked `currentAttempt`; old or conflicting attempts cannot +supply tools. With no attempt scopes, observed telemetry requires a single exact +known cottage session and exact `s:` scope. Unknown or ambiguous +sessions remain unavailable. Cached historical cottages retain their existing +session identity for this check. The adapter exports neither full scopes nor +arguments, outputs, progress text, authentication or unrelated fields. + +The same identity check may also attach `usage` and `contextUsage`, independently +of whether a tool fact exists. `usage` preserves the explicit `session` or +`attempt` scope, a `tokens` object (`inputTokens`, `outputTokens`, +`cacheReadTokens`, `cacheWriteTokens`, `totalTokens`), `incompleteFields`, +`lowerBound`, and `cost: {usd, sources, complete}`. Values are finite nonnegative +numbers or null; zero is a measurement. `usageCoverage: {available, reason}` +reports missing, conflicting, partial, or superseded evidence. Observer aliases +owned by managed tasks do not expose duplicate usage totals. + +Session usage is cumulative across that session, never task or interval spend. +It does not replace the top-level run counters or enter the town's recorded +cost sum. In particular, cached input is not added again to a reported total. +Missing cost is not estimated. `measuredAt` stays null because Hub's projection +does not yet export a usage-specific timestamp; a subsequent tool event cannot +make an older usage total appear newly measured. `coverageComplete` preserves +the snapshot's known completeness. + +`contextUsage` contains `scope`, `usedTokens`, `windowTokens`, `usedRatio`, `at`, +`stale`, and the same `hub:agent-events` source. Its own explicit timestamp owns +freshness (two minutes or canonical staleness), independently of tool activity. +The inspector labels cumulative observations as **Session tokens / Session +cost**, and leaves unavailable values visible as unavailable. diff --git a/docs/superpowers/plans/2026-11-04-command-center.md b/docs/superpowers/plans/2026-11-04-command-center.md new file mode 100644 index 0000000..02a8840 --- /dev/null +++ b/docs/superpowers/plans/2026-11-04-command-center.md @@ -0,0 +1,88 @@ +# Command center prototype implementation plan + +Use subagent-driven-development. User already chose autonomous implementation and local experiments. + +**Goal:** A polished, useful, truthful three-perspective command center at http://127.0.0.1:8790, using the existing local feed and a clearly separate illustrative scenario. + +**Architecture:** Experimental modules in experiments/command-center, with a tiny Node loopback server. Reuse source contract helpers; keep the original product untouched. One data/policy task, followed by one UI task. Parent integrates and performs browser verification. Each task gets an independent review; whole branch gets an Astra review. + +**Tech stack:** Node 24, ES modules, HTML/CSS/SVG, no dependencies. Node executable is /Users/jgarturo/.nvm/versions/node/v24.15.0/bin/node; prefix PATH for npm in this worktree. + +## Global Constraints + +- Product name CottageCode. Spatial view named Townmap; Townwatch is the perspective, not a replacement logo. +- Zero dependencies; no production-source modifications needed. +- Task and session clocks stay separate; missing stays unavailable; updatedAt is observed, not progress. +- Quiet requires explicit progress telemetry and is not a stall diagnosis. +- Reuse normalizePr/prStage/prCi, inputRequestVersion/normalizeInputRequest and conversationCapability. +- Hub readiness remains authoritative; standalone stale/conflicting evidence cannot be ready. +- Shared PRs count once; only explicit graph edges. +- Live and illustrative data must be visibly separate; no live fallback to fixtures. +- Explicit Send only; latest task/question/capability preflight; uncertain sends persistently locked; no automatic retry; upstream validation retained. +- Tests never send to real agents. Proxy binds loopback and only permits exact known routes to fixed upstream. +- Keep existing town and untracked user .cursor files untouched. Work on feat/command-center-lab in this isolated worktree. +- HTML content escaping, safe URL handling, reduced motion, responsive keyboard/mouse parity. + +### Task 1: Truthful data model, scenario and local harness + +Files owned: experiments/command-center/model.mjs, scenario.mjs, server.mjs, replies.mjs, test/command-center.test.mjs, test/command-center-server.test.mjs. Implement and commit as one coherent contract. Do not create UI files. + +Interfaces: + +```js +// model.mjs +export function durationLabel(milliseconds) {} // null -> 'Unavailable'; compact d/h/m/s +export function taskView(agent, {now=Date.now(), stale=false, endpoint='http://127.0.0.1:8790/agents'}={}) {} +export function fleetView(snapshot, options={}) {} +// taskView returns {id, raw, title, project, town, harness, model, status, +// taskAgeMs, sessionAgeMs, observedAgeMs, progressAgeMs, quiet, +// input, capability, pr, prKey, prStage, ci, attention, activity, +// issues, parent, sourceStale}. Raw is retained for existing validators. +// fleetView returns {tasks, projects, prs, edges, counts, stale, checkedAt} +// counts: {tasks, working, attention, answerable, quiet, ready, blockedPr, settled} +// projects: [{id,name,count,working,attention}], prs: [{key,pr,stage,taskIds}] +// edges: [{from,to,kind}] with typed ids task:, issue:, pr:. +// Include non-settled records only. Parent/task/issue/PR edges are explicit. + +// scenario.mjs +export function createScenario(now=Date.now()) {} // feed-shaped snapshot, illustrative:true + +// server.mjs +export function createLabServer({upstream='http://127.0.0.1:8787', fetchImpl=fetch}={}) {} +// CLI node experiments/command-center/server.mjs --port 8790 +// / -> index.html; /model.mjs,/scenario.mjs,/replies.mjs,/app.mjs,/style.css +// /src/.mjs -> existing src helpers. +// /agents and /agents/:id/activity GET, /agents/:id/messages POST proxy only. +// Fixed upstream constructor injectable for local tests, never from HTTP input. + +// replies.mjs +export function createReplyClient({endpoint, fetchImpl=fetch, storage=localStorage, now=Date.now}={}) {} +// returns {state(taskId), send(agent, message)}; state gives phase + notice. +// send fetches latest /agents, compares task and current input id/version, checks +// conversationCapability, persists request id before POST, returns receipt state. +// Transport ambiguous outcome locks retry across reload; do not silently retry. +``` + +Implement tests before core logic. Cover: missing task start with session time, terminal clocks frozen, observation not quiet, progress heuristic explicit, canonical Hub ready retained through outage, stale standalone ready rejected, shared PR dedup, explicit graph only, unsafe URL rejected, source-specific harness unknown, stale/changed-input send refused, uncertain send survives client recreation. Server tests use ephemeral loopback stub endpoints and reject cross-origin writes, arbitrary proxy paths, methods and oversized payloads. No integration calls to real message endpoints. + +Scenario: approximately 12 tasks across HubTown, MemTown, AppTown, FusionTown, VaultTown. Clear fictional issue/PR ids; no actionable live links. Include two exact questions (one answerable, one source-only), working tasks with different harnesses, quiet task with progress timestamp, shared PR, blocked dependent PR, ready PR, unknown evidence, recently ended work. Use concise plausible activities connected to user's actual domains. No copied private live payload in fixtures. + +Run focused tests, then commit owned files. Report public interfaces and test evidence to .superpowers/sdd/task-1-report.md. + +### Task 2: Three-perspective interface + +Files owned: experiments/command-center/index.html, style.css, app.mjs, README.md. Read the spec and Task 1 report before implementation. May request interface changes through parent. Do not alter model/server tests without coordination. + +Use taskView/fleetView/createScenario/createReplyClient. Build a complete beautiful application with Townwatch, Dispatch and Threads, a shared detail drawer, global search/project filtering, rich PR preview, attention navigation, explicit live/scenario switch and readable source freshness. Live polls every five seconds, retains last snapshot with stale banner on failure; protects focused draft and selection across polls. Illustrative scenario never polls or sends remotely. Demo Send produces explicit local-only receipt without altering source status as fact. + +Townwatch: CSS/SVG pixel cottages in stable district cards, dark desaturated midnight scene, subtle grid/stars/plants/roads, warm windows only for working tasks. Spacious typography, restrained coral/amber/mint/lavender state system with shapes and text. A slim attention strip puts exact next actions within one click. Lenses Attention/Time/Delivery/Owner change labels without repositioning cottages. + +Dispatch: compact readable task rows grouped or filtered by useful attention states, independently show state/activity, provider/model, task/session age, observation and PR. Order stable across refresh except explicit resort/filter. Counts dedup PRs via fleet model. Search is typed across title/project/task id/PR. Selected row and drawer remain bound to identity. + +Threads: explicit issue/task/PR cards arranged left to right with labelled connectors/relationships and selected-path emphasis. Support shared PR and dependencies. Live missing issue links gets clear explanation, still shows known task/parent/PR edges. No fabricated graph. + +Drawer: title and project, exact public activity, task/session/observation/progress clocks, source, pending request with full expandable original and options, current reply capability or exact unavailable reason, request text, PR evidence (stage, source, checks, checkedAt, current/reviewed head, reason, labels), safe original links. Live Send uses createReplyClient only; no automatic messages. Scenario Send is local with explicit label. No merge controls. + +Interactions: perspective keys 1/2/3, Cmd/Ctrl+K palette/search, j/k task selection, Escape closes overlay. Ignore shortcuts in editable controls. Buttons remain available. Click/focus PR badges opens preview; hover can use title/preview but must not be essential. At narrow widths collapse rail, use list layout and drawer below/overlay without horizontal overflow. Preserve draft on polling, warn if request changes. Respect reduced motion. + +README covers start command, ports, shortcuts, live vs illustrative, data limitations and safety. Verify JS syntax and full npm test; parent does real browser journeys then supplies fixes. Commit owned files and write .superpowers/sdd/task-2-report.md. Browser screenshots go outside git. diff --git a/docs/superpowers/plans/2026-11-04-town-command-integration.md b/docs/superpowers/plans/2026-11-04-town-command-integration.md new file mode 100644 index 0000000..0b7736f --- /dev/null +++ b/docs/superpowers/plans/2026-11-04-town-command-integration.md @@ -0,0 +1,75 @@ +# Original-town command center implementation plan + +> Use subagent-driven-development with independent file ownership and parent integration. User already authorized execution. + +**Goal:** Integrate the lab's visibility into the original playable CottageCode town. +**Architecture:** town.mjs retains polling and canvas; observatory retains room state, inspector, journal and composer; a presentation-only coordinator renders attention, search, Dispatch, Threads and plot lenses. Promote reviewed pure model/reply helpers to src, keeping lab re-exports. +**Tech:** Zero-dependency Node/ESM, canvas, DOM/CSS. Node /Users/jgarturo/.nvm/versions/node/v24.15.0/bin/node. + +## Global Constraints +- Original pixel world, WASD/doors/E, residents, wildlife, lighting, optional sound/music remain intact; music and sound start off. +- No view/lens change resets world layout, camera, player, occupied room, visited-room seed or selected task. Explicit Locate/Enter/Leave actions may change world context. +- One poll owner (town.mjs); command coordinator never fetches or sends. One inspector/composer (observatory). +- Keep task/session/execution/observation/progress clocks separate; unknown stays unknown. Harness is explicit, not guessed from model. +- Hub readiness remains canonical during outages; stale standalone cannot be ready. Shared PR counts dedup; edges require explicit evidence. +- Exact input/version/identity/capability/latest preflight and durable uncertainty lock precede explicit live Send. No real agent test messages. Demo answers local. +- Source changes clear old evidence. Public demo bundles only static src modules and denies network connections. +- All dynamic HTML escaped, safe URLs, keyboard parity, reduced motion, responsive layouts. CSS fullscreen only. +- Parent owns integration and final browser/full-suite checks. Workers own disjoint files and do not revert others. No child delegation. + +### Task 3: Shared model and host integration (parent) +Ownership: src/command-model.mjs, src/command-replies.mjs, src/town.mjs, src/town.html, src/map-display.mjs, src/feed-client.mjs, experiments/command-center/{model,replies,server}.mjs, test/command-integration.test.mjs, test/public-demo.test.mjs, docs. +- Promote reviewed lab model/replies to src with local relative imports; lab re-exports preserve existing tests and experiment. +- Add commandSnapshot(agents,meta,{stale=false}) to merge accepted raw evidence by id with normalized ids/town/occupancy/PR. Raw unknown terminal stays unknown; exact model/status preserved. Include raw relationships. Never merge mismatched IDs. fleetView option includeSettled makes explicit settled toggle work. +- Preserve checkedAt/timestamp in feedEnvelope. +- Mount DOM #command-bar, #command-attention, #command-view. Wrap existing #map-viewport in #perspective-stage; alternate view absolutely fills wrapper and scrolls independently. Original viewport remains mounted/measurable and becomes inert/visually hidden in alternate modes. Keep the wrapper's original/fullscreen sizing. +- Wire coordinator update after accepted feed updates and original filters; inspect callback invokes new observatory inspectCottage. Locate is explicit focusCottage. getEvidence(id) returns accepted raw/normalized join. setView suspends observatory and calls mapDisplay.syncZoom; selection sync calls coordinator.select(id) without recursion. +- Map draw passes existing plot coordinates to coordinator.drawLens after night treatment; no relayout. Add hover context using existing hit/hover, not new walk physics. +- mapDisplay receives getWorkspaceView and focusWorkspace; close details focuses visible view, zoom keys ignore hidden town. Details can be closed/reopened in normal layout as a real evidence drawer; changing visibility must preserve camera. +- Add --town preview mode to lab server at8791: serve original town.html and src modules/static audio with existing restricted live feed proxy. Keep port8787 unchanged. +- Focused tests cover snapshot exact model/status/terminal, stale authority, settled inclusion, no mismatched evidence; public demo includes new src modules. Full suite after integration. + +### Task 4: Shared evidence inspector and suspended walking +Ownership: src/observatory.mjs and test/observatory.test.mjs (may add test/command-observatory.test.mjs). Report .superpowers/sdd/integration-inspector-report.md. +Consumes src/command-model.mjs taskView/durationLabel, src/command-replies.mjs createReplyClient/isTerminalForMessage; parent creates these before implementation. New optional api.getEvidence(id) returns the raw-preserving agent (fallback byId). Existing api.select/showDetails/etc remain. +Produces: +```js +observatory.inspectCottage(id,{tab='overview'}={}); // select/read only; no camera/player/room change +observatory.setSuspended(boolean); // clear keys; gate world input/movement/follow, preserve all physical state +``` +- Keep selected evidence target independent from interiorId. All inspector/composer/tab/action handlers operate on the currently inspected task, while physical E/room-object/door interactions explicitly select the physical host. Do not accidentally send to interiorId after a different task was inspected. +- renderPanel must not force room host over requested evidence. Preserve existing draft/focus/activity pagination/room caches. Continue lastFrame update while suspended; do not move or follow camera. Return suspended in state for browser verification. +- Upgrade original overview into legible evidence: task title/public activity, explicit harness and full source model, clocks from taskView including conditional recorded execution, input question excerpt+open Talk, PR stage/reason/checks/head/freshness (existing prSnapshotHtml), original request. Existing tabs/journal/todos/objects stay available. Distinguish observation from progress. +- Promote live Send to ONE createReplyClient per endpoint/source using raw evidence snapshot, latest preflight and persistent state. Preserve request-version draft guard; mapping uncertain -> existing unconfirmed UI must stay locked after reload/source revisit. Demo branch stays local and never instantiates remote write. Inspect existing tests/handlers before patching; do not weaken locks for usability. +- Add focused behavioral tests for pure helpers/eligibility where useful. Parent browser tests actual room/selection/composer journey; don't build mock-only DOM tests that mirror implementation. +- Run focused observatory tests and syntax; commit only owned files, report interfaces and concerns. Do not run entire suite while other workers changing code. + +### Task 5: Presentation coordinator, lenses and alternate views +Ownership: src/command-center.mjs, src/command-styles.mjs (CSS string installed by coordinator), optionally src/command-render.mjs and test/command-center-ui.test.mjs. Report .superpowers/sdd/integration-ui-report.md. +Consumes src/command-model.mjs fleetView/taskView/durationLabel/safeUrl. Reference lab app for rendering, not bootstrap or second drawer. Parent supplies DOM ids #command-bar,#command-attention,#command-view, all under #map-shell. #perspective-stage wraps still-mounted #map-viewport. Existing evidence #details-shell/#panel. +Produces: +```js +createCommandCenter({root,onInspect,onLocate,onViewChange,onTownFilter}) +// root = #map-shell; callbacks onInspect(id,tab), onLocate(id), onViewChange(view), onTownFilter(town) +// returns: +.update({snapshot,endpoint,sourceKey,builtInDemo,publicDemo,stale,selectedId,townFilter,showSettled}) +.select(id) // selection sync; no callback recursion +.setView('town'|'dispatch'|'threads') +.drawLens(ctx,plots,{selectedId,hoverId,townFilter,visible,time,reduce}) +.state // serializable view,lens,selectedId,filter,counts,sourceKey +``` +- Defaults Townmap, lens Village/off. Toolbar 1 Townmap,2 Dispatch,3 Threads, search. Attention strip exact input excerpt or blocked PR reason, counts scoped; answerable inputs first, next-item cycle; click onInspect(id,'talk' or 'review' or 'overview'). Explain stale/illustrative state in compact copy. +- Lenses Village,Attention,Time,Delivery,Owner annotate EXISTING plot coordinates without changing layout/positions. Canvas text small/simple; focus/hover provides richer readable context. Pixel colors/labels harmonize original warm/night palette. Reduce visual noise with single lens. drawLens restores canvas state and respects town/PR dimming. Parent paints after night palette; marker labels should not blanket sprites. Handle roommates/kids honestly. +- Dispatch compact ledger shows title/activity, independent status/owner/model/time/PR, filters all/attention/working/quiet/ready. Original townFilter and showSettled context apply. OnInspect updates shared inspector, never creates a drawer or sends. One Show in town action on selected work invokes onLocate. SharedPR counts once. +- Threads reuses explicit typed graph contract (task,issue,PR,parent,depends-on) with dedup PR nodes. At narrow width or insufficient graph space, selected-task trace. Same selected task. No issue edges -> useful honest empty note plus known edges. Dependency direction prerequisite -> dependent. Safe links only. +- Hover/focus PR receipt tooltip, click invokes onInspect(id,'review'). Global search Command/Ctrl+K, arrows/Enter/Escape;1/2/3 views;J/K only alternateviews;WASD/E untouched. Ignore shortcuts editing/dialogs; Escape closes search/preview then returns alternate view to town without also leaving a room. Keep game focus when returning. Coordinator never fetch/POST/poll. +- Scope styles to cc classes/root state; don't replace original theme/globalfonts. New view surface gets readable typography, warm paper/brass accents, restrained lines. Mobile drawer original semantics parent handles; alternate table/trace no horizontal overflow. Mount global dialog inside map-shell for fullscreen inert support. +- Preserve focused controls through feed updates, redraw graph on width change, avoid resetting alternate scroll. Source change clears search/selection/lens data as appropriate. No duplicate attention notifications on poll. +- Syntax and focused tests; commit ownedfiles; report. Parent browser verification and independent task review follow. + +## Integration verification +- Node full suite, static demo build checks and syntax. +- Real browser at8791/?demo=1: WASD door entry/exit, E conversation and workbench, duck startle; Townmap↔Dispatch↔Threads while inside and outside preserves position/room/camera; lenses preserve plots. +- Inspect different task while in a room; verify drawer identity and supported demo response target, then return to unchanged physical room. Never send live messages. +- PR preview, search, ready unique count, settled/town filters, source/stale recovery, fullscreen/zoom and narrow viewport. +- Independent task reviews and final broad Astra review; fix important findings and scoped re-review. Save screenshots outside git and leave integrated preview running. diff --git a/docs/superpowers/specs/2026-11-04-command-center-design.md b/docs/superpowers/specs/2026-11-04-command-center-design.md new file mode 100644 index 0000000..59467c5 --- /dev/null +++ b/docs/superpowers/specs/2026-11-04-command-center-design.md @@ -0,0 +1,67 @@ +# CottageCode command center exploration + +Date: 2026-11-04. Status: experimental, locally runnable; not a production replacement. + +Jack explicitly authorized autonomous design choices, prototypes, browser experiments and worktrees. That authorization supersedes the brainstorming skill's repeated approval pauses for this exploration. Existing town on port 8787 stays available. Build one coherent experimental application on port 8790 with three inspectable perspectives, rather than three incompatible data models. + +## Direction + +The village is a memorable place to recognize work. Add an attention desk that makes the next human action obvious, and an evidence drawer that explains whether work can ship. Preserve charm through pixel cottages, quiet motion, warm window light, carefully composed night colours and little arrival/focus feedback. Use clean readable typography for work, not pixel text for paragraphs. + +Three perspectives share search, project filter, task selection, evidence drawer and keyboard commands: + +1. **Townwatch**: spatial project districts, stable cottage positions, compact task titles. Attention/Time/Delivery/Owner lenses alter labels and emphasis, never task placement. No need to walk to do operational work. +2. **Dispatch**: a fast operational list with independently readable execution, pending input, task/session age, last observation, PR state and ownership. Filters for Attention, Working, Quiet, Ready and All. Ready counts unique PR identities, not cottages. +3. **Threads**: explicit issue → task → PR relationships, selected-path emphasis, shared PR objects and dependency reasons. No guessed lines from prose/title similarity. Missing issue instrumentation is an honest empty state in live mode. + +Default to the live local feed. A conspicuous **Illustrative scenario** switch exercises the richer design: actual multi-provider names, progress clocks, structured issue links, shared PR, dependency wait, exact question and a simulated reply. Every illustrative view is marked; scenario replies remain local. Live mode never falls back to invented data. + +## What we learned + +The initial feed snapshot has 216 records, 37 current/recent, 179 settled, nine recorded pending inputs and one supported reply route. The red mailbox means a blocked task or blocked PR; it does not detect inactivity. Some recorded inputs are terminal blocker reports rather than questions. All six working external sessions lack explicit task starts. updatedAt can reflect inventory observation, not meaningful progress. Full harness/model identity and issue edges are missing from most live records. + +GitHub confirms the November 3 Todoist board PRs #2393–2395 merged. Todoist owns intentionally tracked planning; non-board Hub dispatches are intentionally not mirrored. CottageCode adds oversight, not another backlog. Pulse's November 3 dataset includes 2,576 commit records across 25 repositories over its trailing 30 days; these are bounded artifact counts, not effort or outcomes. Recurring nightly runs should eventually collapse under a stable workflow identity supplied upstream. + +Anthropic's session filters and verbosity levels, cmux's attention lifecycle and jump-to-source, and Conductor's separation of agent workspaces from shared PRs inform this design. Reddit showcases support exact-question triage as a useful qualitative idea, not proven popularity. + +## Data and safety constraints + +- Zero dependencies. Reuse existing PR interpretation, input normalization/version and conversation-capability validation. +- Task start and session start are separate. Missing values remain unavailable. Task age includes waiting; do not call it compute time. Ended work uses endedAt/duration rather than a growing clock. +- updatedAt is an observation signal. Quiet is only a labelled heuristic from an explicit lastProgressAt/telemetry.progressAt, never from a heartbeat. Never claim a detected stall. +- Keep execution, input, review and feed freshness as separate states. Raw babysit labels do not override Hub authority or head validation. +- Stable cottage identity and coordinates across filter/lens/selection changes. Shared PR counts deduplicate canonical URL identity. +- Use only explicit relationships. Show unknown harness separately from model family; source Hub is not proof of Claude/Codex ownership. +- Live content is text, not executable HTML. Safe URL schemes only. No private thinking. +- Replies require explicit user Send and a current supported capability. Recheck exact task, question content version and route before sending. Preserve upstream durable receipt handling, locally lock uncertain sends across reload, never retry automatically. Test only stubbed transports or the illustrative scenario. +- A local development server proxies only known /agents read/activity/message routes to fixed 127.0.0.1:8787. It binds loopback, checks Origin for messages and forwards to the existing server, which remains responsible for authoritative validation and durable delivery receipts. It never exposes arbitrary proxy targets. +- No automatic messaging, merge, restart, approval, task creation or remote changes. Opening links and copying context are direct user gestures. +- No audio by default. Respect prefers-reduced-motion. Mouse, keyboard and narrow layouts must expose the same evidence. + +## Interaction + +The header carries live/scenario provenance and last successful refresh. A summary strip offers attention, working and ready filters. A left project rail makes the current scope explicit. Main view holds Townwatch/Dispatch/Threads; a right drawer shows selected title, exact public activity, two clocks, original request, source capability, pending input, PR checks/head/reason and recorded relationships. + +PR badges open a rich preview on focus/click; hover may enhance it but is never the only route. Command/search palette via Cmd/Ctrl+K, perspectives via 1/2/3, j/k to move selection, Escape to dismiss. Do not intercept typing. Readiness is inspectable and links to the source PR; no merge button in this prototype. + +For unavailable messaging show the exact supplied reason and available source links. A question is not an actionable approval simply because it is red. When no route exists, do not render an enabled composer. + +## Verification and scope + +Baseline: 348 Node tests passing. Add focused tests for truthful timestamps, quiet eligibility, canonical PR preservation and deduplication, explicit graph edges, proxy restrictions and reply identity/uncertainty handling. Verify all three perspectives, live/scenario switching, filters/search, PR preview, keyboard and narrow viewport in real browser. No real test messages. + +This prototype demonstrates information architecture and interactions. Upstream work still needed: full harness/provider/controller identity, last meaningful progress, tool wait/heartbeat health, issue and PR-stack edges, workflow grouping and verified provider deep links. Display current gaps instead of pretending the browser can recover absent telemetry. + +## Sources + +- https://claude.com/resources/articles/claude-code-desktop-redesign +- https://cmux.com/docs/notifications +- https://github.com/manaflow-ai/cmux/issues/4506 +- https://www.conductor.build/docs/concepts/workflow +- https://www.reddit.com/r/ClaudeCode/comments/1ww6hvj/i_run_15_claude_code_sessions_in_parallel_and/ +- https://code.claude.com/docs/en/hooks +- https://pulse.automem.ai/activity-data.json +- https://github.com/verygoodplugins/autohub/pull/2393 +- https://github.com/verygoodplugins/autohub/pull/2394 +- https://github.com/verygoodplugins/autohub/pull/2395 +- https://github.com/verygoodplugins/AutoApp/issues/320 diff --git a/docs/superpowers/specs/2026-11-04-town-command-integration.md b/docs/superpowers/specs/2026-11-04-town-command-integration.md new file mode 100644 index 0000000..f7c45e9 --- /dev/null +++ b/docs/superpowers/specs/2026-11-04-town-command-integration.md @@ -0,0 +1,13 @@ +# Command center in the original town + +Approved by the user on 2026-11-04: bring the attention strip, lenses and evidence drawer into the original town, with Dispatch and Threads as toggleable views; retain walking and charm. This is implementation of the approved direction, not a new approval gate. cmux migration is outside this change. + +The original canvas renderer remains the Townmap. All houses, resident movement, wildlife, paths, interiors, lighting, sound and music retain their owners. One accepted feed refresh drives every view. A compact brass/paper toolbar and attention strip sit above the scene. Townmap lenses annotate existing plots without changing their layout; an off/default Village lens preserves scenery. Attention, Time, Delivery and Owner reveal one kind of information at a time. Selected/hovered work gets readable context without coating the whole world in text. + +Townmap, Dispatch and Threads share the existing inspector as an evidence drawer. Inspector selection is independent of the occupied room: selecting another task in Dispatch does not leave the room or change Jack's location. Switching back returns to the same room/camera. Explicit Locate, Enter, Leave and Follow actions retain their intentional world effects. The inspector exposes full model/harness evidence, distinct wall task age/session age/recorded execution/observation/progress clocks, exact input and source capability, canonical PR receipts, original request, paginated journal, and existing checklist/artifacts. It remains the sole composer, upgraded to the lab's persistent reply/preflight guard. Demo answers remain local. + +Dispatch is a compact HTML ledger. Threads draws only recorded issue/task/PR/parent/dependency edges and shared PRs once, with a narrow vertical trace. Both are separate scroll surfaces over a continuously mounted town viewport. Walking and automatic camera-follow are suspended in alternate views; held keys clear on transitions, while clocks/feed/scenery can continue. View keys 1/2/3, Command/Ctrl+K search, J/K list navigation, direct controls and Escape work without taking WASD/E from the canvas or shortcuts from editable fields. + +One canonical snapshot joins raw public evidence with normalized town identities. Exact model/status and absent terminal evidence survive normalization; raw PR data cannot override normalized freshness or Hub authority. Missing data remains unavailable. Settled visibility and town filtering agree with the original controls. Source changes clear command data and selections; stale same-source data stays visibly stale. No new polling loop and no new autonomous task writes. + +Acceptance: original door walking, E interactions, journals/PR desks, duck startle, music off, night treatment, camera/plot/room stability across view and lens changes, filtering/search/PR preview, shared selection, input safety, stale recovery, public sample network isolation, full Node suite and real browser screenshots. Build a local integrated preview alongside the existing app, not a live runtime migration. diff --git a/docs/superpowers/specs/2026-11-05-living-town.md b/docs/superpowers/specs/2026-11-05-living-town.md new file mode 100644 index 0000000..b1030b4 --- /dev/null +++ b/docs/superpowers/specs/2026-11-05-living-town.md @@ -0,0 +1,21 @@ +# Living town and workbenches + +Jack's refinement on 2026-11-05: high information density and an attractive, living town should coexist. The town needs a heartbeat, with easy project focus and activity visible through its environment. This supersedes the earlier full-surface Dispatch/Threads replacement and suspended-walking choice. + +The original town remains mounted, visible and walkable while Dispatch or Threads opens as a workbench below it. A continuous balance control allocates 30–75% of the shared space to scenery and changes immediately on input. Its DOM node lives outside streamed markup. Escape closes the workbench; selecting a cottage uses the shared evidence drawer. Keyboard movement belongs to the focused canvas. + +The neighbourhood rail summarizes current working, attention and unique ready-PR counts. Choosing a project scopes the ledger and frames all its visible cottages, including resting cottages, without moving plots. When the selected evidence belongs elsewhere, the drawer opens a relevant cottage in the chosen project. All towns restores the wider scope. Ordinary data updates do not reposition the camera. + +The environmental language is grounded: + +- Moving ground dashes mark reported working cottages that are neither stale nor explicitly quiet. Amber lanterns mark attention. These are aggregate signals, not claims of measured throughput. +- Potting benches, loading depots and tiny gardeners/craftsfolk are decorative village inhabitants. Their pace follows the district's working count; they are not additional agents or inferred professions. Resting is allowed. +- A newly observed canonical merged PR creates one labeled cart with one parcel. The parcel means that PR's changes. It does not represent a commit count, file count, deployment or release. Shared PRs count once. +- A newly observed closed PR creates an empty cart travelling home. No agent is fired or removed by the animation. Actual occupancy remains feed-owned. +- Carts run only at the recorded household, never an unrelated cottage. Initial inventories do not generate parades; source changes immediately clear traffic. Lifetimes and remembered identities are bounded. Stale feeds and reduced-motion preferences stop the new movement. + +The field guide explains these meanings and the basic interactions without a first-run modal. Sound and music retain their independent, off-by-default lifecycle. Real messages still require explicit Send through the existing guarded route. + +Validation for this iteration includes controller checks for volume/time, workbench balance input/change/keyboard behavior, PR identity and shipment direction, unavailable households, source resets, unique counts and stable project bounds. Browser acceptance covers the live preview, simultaneous town/workbench, repo focus, desktop and narrow layouts, all three perspectives, range controls and lighting. Private live screenshots stay outside the repository. + +This pass establishes the rhythm. Richer crafts, mining, road building, material inventories or workload stress are future vocabulary; they are not fabricated from task titles or missing telemetry.