CLAUDE.md was a full, drifting duplicate of AGENTS.md. Replace it with a
one-line @AGENTS.md import so AGENTS.md is the single source of truth for
agent context. Removed content was a stale subset (old openconcho:config
key, older rules description) — AGENTS.md already has the current version.
Type docs → no version bump.
Revert the over-engineered linking attempts (provenance: false,
index annotations, dispatch tag input, Dockerfile source LABEL). Our
working repos (e.g. offendingcommit/infra) link GHCR packages with the
plain metadata-action labels + GITHUB_TOKEN push — none of the extras
helped or were needed. Match that.
Package<->repo linking is handled by the one-time Connect Repository
step in package settings.
Type ci → no version bump.
The canonical, build-tool-independent way GHCR links a container package
to its repo is a Dockerfile LABEL baked into the image config — not
buildx/metadata-action annotations. Add it so freshly-created packages
auto-connect.
Note: GHCR evaluates the source at package CREATION, so this links new
packages; an already-orphaned package needs a one-time manual connect
(or delete + re-publish) regardless.
Type build → no version bump.
The publish step passed labels but not annotations, so
org.opencontainers.image.source landed only on per-platform configs, not
the multi-arch index. GHCR reads the source from the index annotation to
auto-link a package to its repo, so the package stayed orphaned.
- Set DOCKER_METADATA_ANNOTATIONS_LEVELS=index + pass annotations to the
build, putting source/url/revision on the index.
- provenance: false keeps the pushed artifact a clean multi-arch index.
- workflow_dispatch now takes a 'tag' input to (re)publish a specific
version; tags derived from the ref so dispatch and release both work.
Type ci → no version bump; republish v0.13.0 via dispatch.
Make the web image drop-in for a Honcho docker-compose stack:
- nginx reverse-proxies /v3 and /health to $HONCHO_UPSTREAM (variable +
Docker resolver so it starts even before the upstream resolves), giving
the SPA a same-origin path to Honcho with no browser CORS.
- Runtime config: an entrypoint writes config.js from
OPENCONCHO_DEFAULT_HONCHO_URL, so one prebuilt image targets any backend
("same-origin" | absolute URL | empty). SPA seeds a first-run default
instance from it (additive; no-op in dev/desktop).
- docker-compose.yml example service + GHCR multi-arch publish workflow on
release.
- nginx.conf -> envsubst template; docs rewritten.
Closes#21. Closes#31.
Two focused Playwright tests, mirroring the existing sidebar.spec
pattern (no backend dependency — instances point at unreachable ports
and we only assert on rendered names + row count, not health):
- Fleet link in the sidebar navigates to /fleet
- /fleet renders one row per configured instance under the table role
Also adds a Fleet link assertion to the existing sidebar.spec so the
nav entry is covered on the dashboard route alongside the other top
links. Both new tests run under the existing `pnpm test:e2e` (not
gated in CI by design — matches the current Compare/Dashboard E2E
posture).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds a new /fleet route that shows a fleet-wide overview of all
configured Honcho instances. Each row renders per-instance metrics
(workspace count, total conclusions, queue activity, last seen, health)
by fanning out scoped fetches via createScopedClient, and aggregates
into top-level metric cards.
Reuses the Phase 2 scoped-client pattern. Extends compareQueries.ts
with useScopedQueueStatus and useScopedConclusionsCount, plus option
builders so useQueries can fan out per-workspace requests inside
FleetRow without duplicating query logic.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Human peers surface as raw ids (WhatsApp `…-lid`, UUIDs). Read an
optional `display_name` from peer metadata and prefer it over the id in
the peer header and breadcrumb, with the raw id kept as a sub-caption.
An inline edit on the header writes `display_name` via useUpdatePeer
(merging existing metadata); blank clears it. Falls back to the id when
unset.
Closes#32.
semantic-release creates the tag via the GitHub Releases API
(@semantic-release/github). API-created tags don't emit the
refs/tags/* push event that 'on: push: tags' listens for, so the
artifact build never auto-ran — every release so far was built by
manual workflow_dispatch.
The PAT-published release does fire 'release: published', so trigger on
that. workflow_dispatch stays as a manual fallback.
Adds @vitest/coverage-v8 (catalog-pinned), a test:coverage script wired
through turbo (inputs + coverage/** output), and coverage thresholds set
to a floor measured on main (lines 18 / funcs 10 / branches 10 / stmts
17 against current 19.3/11.4/11.7/18.9). Ratchet upward as tests grow.
Adapts the coverage config from @BenSheridanEdwards's fork; the multi-job
CI fan-out from that branch was intentionally left out.
Co-authored-by: Ben Sheridan-Edwards <BenSheridanEdwards@users.noreply.github.com>
* feat(desktop): auto-discover Honcho instances on localhost
First-launch and on-demand discovery of running Honcho instances on
127.0.0.1:8000-8100. Desktop-only — the browser can't port-scan due to
CORS, so the scan runs in the Tauri Rust shell.
- New Rust command `discover_honcho_instances(start_port?, end_port?)`
in src-tauri/src/discover.rs: parallel TCP probe of each port with
150ms connect timeout + 250ms total request budget, looking for a
/health endpoint returning `{"status":"ok"}`.
- New TS helper `discoverHonchoInstances()` in src/lib/discovery.ts:
detects Tauri runtime; web build degrades to an empty result.
- `suggestNameForInstance()` fetches the first workspace and derives a
friendly name from its id ("neo-personal" -> "Neo"). Used to seed the
Name field for each discovered instance.
- `DiscoveredInstances` component: list of found instances with
editable suggested names + per-row checkbox + "Add N instances"
button. Rows are pre-checked by default and filter out already-
configured baseUrls.
- Wired into `InstancesManager`:
- First launch (no instances): renders above the connection-type
chooser with autoRun=true. User sees results immediately.
- With instances: adds a "Discover instances" button to the list
view that opens the discovery flow on demand.
- Both paths gate on `isTauri()`; the web build keeps its existing
behaviour unchanged.
Adds tokio (with net + io-util + time + rt + macros) and futures to
the Tauri shell to get async TCP + join_all.
Tests:
- deriveNameFromWorkspaceId handles hyphenated, multi-segment, and
no-hyphen ids
* test(desktop): add probe tests including live Hermes stack integration
- rejects_inverted_port_range
- ignores_ports_with_no_listener
- finds_live_hermes_stacks (#[ignore]d; opt-in with --ignored)
The ignored test exercises discover_honcho_instances against ports
8000-8010, expecting exactly [8001, 8002, 8003, 8004, 8005]. Verified
locally — the probe finds all 5 stacks in <10ms.
---------
Co-authored-by: Agents <agents@Jarviss-Mac-mini.local>
Filed the upstream feature request asking /queue/status to surface
per-work-unit observer/observed, specialist phase, and token telemetry.
Panel now links to the concrete tracking issue instead of a pre-filled
new-issue form. Re-captured the showcase screenshots so the visual
state matches.
Wires up the DEV-only /dream-progress showcase to a Playwright script
that captures idle/active/stalled variants for documentation. Also
regenerates routeTree.gen.ts to include the new queue + showcase routes
and folds in Biome formatter fixes.
Run `node scripts/screenshot-dream-progress.mjs` from packages/web with
the dev server up to refresh the images.
- pickQueueRefetchInterval picks 2.5s when work is active, 10s otherwise
- useStaleQueueDetection only flags after 30 min without forward progress
- stall anchor resets when completed advances or all work finishes
Watching dreams was a 5-15min black box. Now a dedicated
/workspaces/:id/queue route polls /v3/workspaces/:id/queue/status
every 2.5s while work is in-flight (10s when idle) and surfaces a
warning when in-progress work hasn't advanced the completed count
for >30 minutes.
The Honcho API only exposes aggregate counts (no observer/observed
pair, specialist phase, or token telemetry per work-unit), so the
panel links out to an upstream issue for those.
- queries: adaptive refetchInterval via TanStack Query callback form
- hooks/useStaleQueueDetection: client-side stall detection
- routes/workspaces_.\$workspaceId_.queue: dedicated live view
- routes/_dev.dream-progress: DEV-only showcase for screenshots
- WorkspaceDetail: new "Queue & dreams" nav card
Lets users fire one query at every Honcho reasoning level (minimal / low /
medium / high / max) in parallel and compare answers + latency side-by-side
in a 5-column grid.
- New route: /workspaces/:ws/peers/:peer/playground
- New component: DialecticPlayground with per-column state, level checkboxes
to skip expensive levels, and a single Run button that fans out via
Promise.all
- Extends useChat() to accept an optional reasoning_level parameter (was
hardcoded to "low")
- Adds a Playground button next to Chat on the peer detail page
- Tests cover the parallel fan-out (peak concurrency = 5, no serial
awaiting) and per-column latency measurement
- Screenshot Playwright spec (idle / mid-flight / settled) drives the
images in docs/screenshots/ — regen with PLAYWRIGHT_BASE_URL=... pnpm
exec playwright test e2e/playground.screenshots.spec.ts
- packages/web/e2e/dreams.spec.ts: 4 tests covering sidebar entry,
heading/breadcrumb resolution, mocked-API clustering into rows with
count chips, and the premise-tree expansion path. Uses a function
matcher for context.route so the trailing ?page=&page_size= query
string doesn't break a glob.
- docs/screenshots/: dark + light mode list and expanded-detail PNGs
captured at 2880x1800 (retina) via playwright against the dev
server with a tiny mock Honcho.
- DreamList.tsx: add a literal space to CountChip's label fragment so
the rendered text reads "3 explicit" instead of "3explicit" (gap-1
styles the visual layout but doesn't add a text-node space). Better
for screen readers, copy/paste, and assertion via toContainText.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Dreams are currently a black box — to benchmark Tier L models on dreamer
induction quality we need to see what each model produced. This adds a
workspace-scoped /dreams route that surfaces every dream run as a
group of conclusions split into explicit / deductive / inductive
columns, with click-to-expand premise trees.
What's here:
- `lib/dreams.ts`: pure helpers. `clusterConclusionsIntoDreams` groups a
raw conclusions list into per-pair bursts using a configurable time
window (default 60s). `expandPremiseTree` walks `reasoning_tree` first
and falls back to a flat `premises` ID list, with cycle detection and
a depth cap. Defines an `ExtendedConclusion` type that augments the
generated schema with `conclusion_type`, `premises`, and
`reasoning_tree` — Honcho's migration f1a2b3c4d5e6 added those
columns but `schema.d.ts` doesn't expose them yet, so the UI degrades
gracefully (unknown types fall into "explicit").
- `api/queries.ts`: new `useDreams` hook that paginates the conclusions
list endpoint up to a configurable cap (default 400) and hands the
raw list to the UI for clustering. New `dreams` query key.
- `components/dreams/`:
- `DreamList.tsx` — route entry. Shows recent dreams as rows with
timestamp, observer→observed pair, and per-type counts. Selecting
a row expands an inline detail panel above the list.
- `DreamDetail.tsx` — three-column view (explicit / deductive /
inductive). Each inductive conclusion has a "Show premises" button
that expands the reasoning chain.
- `PremiseTree.tsx` — recursive premise renderer with type badges,
cycle indicator, and graceful handling of premises that fall
outside the loaded page.
- Routing: `routes/workspaces_.$workspaceId_.dreams.tsx` registers the
page; routeTree.gen.ts regenerated.
- Sidebar: new "Dreams" entry between Conclusions and Webhooks
(MoonStar icon to distinguish from the dark-mode Moon).
- Breadcrumb: "dreams" added to SECTION_LABELS so the trail resolves.
Tests (vitest, 14 new):
- clustering: empty input; same-pair burst within window; gap exceeds
threshold → split; different pairs don't merge even with overlapping
timestamps; custom gap window; newest-first ordering; counts default
unknown types to explicit.
- premise tree: empty children for no premises; flat list → direct
children; multi-level reasoning_tree recursion; missing premise
flagged (not in loaded page); cycle detection halts recursion;
maxDepth cap; reasoning_tree preferred over flat premises.
Verified manually in the preview: route mounts, sidebar/breadcrumb
resolve, error path renders cleanly, typecheck + lint + dream tests
all clean. The unrelated `app.test.tsx` failure is pre-existing on
main.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Weekly npm (pnpm workspace), cargo (Tauri shell), and github-actions
updates, grouped by family (TanStack, Tauri, React, test stack, build
tooling, semantic-release, commitlint) to keep related bumps in one PR.
Co-authored-by: Ben Sheridan-Edwards <BenSheridanEdwards@users.noreply.github.com>
Phase A of the quality-gate rollout — local + pre-push gates that stop
slop before it leaves the laptop. Preventative controls, per the
architect playbook.
- .husky/pre-commit — adds scripts/secret-scan.sh as the first check
before the existing Biome format/lint. Blocks the commit when a
likely secret is found in staged additions. Existing Biome behaviour
is preserved.
- .husky/pre-push (new) — runs `pnpm check` (lint + typecheck + test)
before the branch leaves the laptop. Mirrors the `check` job in
.github/workflows/ci.yml so PR-blocking issues surface locally first.
Bypassable for genuine emergencies with `git push --no-verify`.
- scripts/secret-scan.sh (new) — regex scan over staged additions for
the common accidents: AWS keys, Anthropic/OpenAI/GitHub/Slack/Google/
Stripe tokens, JWTs, PEM private key blocks, hardcoded password
literals. Validated against synthetic leaks of each type. No external
tool dependency — pure bash + grep, runs in <100ms typical.
- scripts/pr-evidence.sh (new) — drafts a PR_BODY.md from the diff vs
origin/main: file lists (added/modified/deleted), commit summaries,
and the QA checklist. Flags screenshots as REQUIRED when the diff
touches packages/web/src/{components,routes} or packages/desktop.
Wired as `pnpm pr:evidence` so it runs from anywhere in the
workspace.
- .gitignore — adds PR_BODY.md so drafts don't get committed by
accident.
Pre-commit stays fast (<2s typical). Heavy checks (typecheck, full
test run) live in pre-push.
Multi-stage Dockerfile (node:22-alpine + pnpm build -> nginx-unprivileged
serve) producing a non-root image that runs under read-only fs + cap_drop
ALL. nginx.conf does SPA-fallback routing, /healthz, immutable asset cache,
and gzip, plus an opt-in same-origin reverse-proxy block.
docs/docker.md documents build/run and the two ways to handle browser CORS
on the web build (configure Honcho's CORSMiddleware, or the nginx proxy).
The Dockerfile and nginx.conf are adapted from @zmarakjanbangash's fork.
Co-authored-by: zmarakjanbangash <zmarakjanbangash@users.noreply.github.com>