Releases: togo-framework/builder
Release list
v0.3.0
Changelog
- a96b075: docs(security): record SF-001 — a source can never be granted its secret (@fadymondy)
- 717f959: feat(apps): give an app a way to say what goes in the window (@fadymondy)
- f7523fa: feat(connections): build the webhook receiver the schema has been waiting for (@fadymondy)
- 4667d55: feat(integrations): the connection plane, and the actors that run through it (@fadymondy)
- 3dbcf35: feat(sdk): build the shell document, under budget and actually rendering (@fadymondy)
- f9ffe55: feat(sdk): remember where windows were put — on the device, not the account (@fadymondy)
- 040007a: feat(sdk): ship the windowed shell dark, behind mount({ shell }) (@fadymondy)
- 414f504: feat(sdk): the FeedbackOS token layer, in three deliberate layers (@fadymondy)
- d901af8: feat(sdk): the app contract, and apps that actually render in windows (@fadymondy)
- 1d8a1e6: feat(sdk): the issue composer, built on the Initial CTA pattern (@fadymondy)
- b7a184b: feat(sdk): the loader, and the dead-man's switch that makes it safe (@fadymondy)
- 8921baf: feat(sdk): vendor ui-desktop as an embeddable fork, behind one seam (@fadymondy)
- bac392f: feat(setup): declare every environment variable once, and generate the rest (@fadymondy)
- 8eae7b7: feat(setup): generate the wizard's steps from the capability registry (@fadymondy)
- 333b9c9: fix(issues): let a visitor actually file feedback (@fadymondy)
- 37a5af8: fix(mcp): accept a proxied Host, and stop telling operators to lie about APP_ENV (@fadymondy)
- f7ff2a7: fix(sdk): repair four latent bugs the desktop fork inherited (@fadymondy)
- 756482e: fix(sdk): three bugs that only a real host page could reveal (@fadymondy)
- 955e801: fix(sdk): tokenise the chrome and make window controls reachable (@fadymondy)
- 151aebe: perf(sdk): inline the icon set, drop lucide-react from the shell (@fadymondy)
- c2caf95: style(sdk): retire the patterns this sheet had already argued against (@fadymondy)
Install
npx create-togo-builder@latest my-projectThe postinstall verifies the binary's SHA-256 against checksums.txt
before running it.
v0.2.2
Changelog
- 766d0eb: chore(release): 0.2.2 (@fadymondy)
- f1379cc: feat(sdk): rebuild the issue detail against the dashboard's issue page (@fadymondy)
- 064fe0d: fix(runner): send the prompt on stdin, not argv (@fadymondy)
Install
npx create-togo-builder@latest my-projectThe postinstall verifies the binary's SHA-256 against checksums.txt
before running it.
v0.2.0
A feature release. The headline: the plugin now ships its own dashboard, so it works on install rather than after a frontend integration.
The SDK ships its own UI
The plugin used to ship a feedback widget and nothing else — the 23 screens existed only as source, compiled by whichever project the scaffolder had stamped them into. Two bugs followed from that, and both were reported:
builderd, the standalone daemon, served its UI out ofBUILDER_WEB_DIR, defaulting to a sibling development project's build output. On any machine without that checkout built, the daemon came up healthy and served no pages at all.- Installing the plugin into an existing application wired up the whole Go side and every screen 404'd, because the host's own SPA has no
/issuesroute and never will.
web/dist is now embedded with go:embed and carried inside the binary, exactly as sdk/dist already was. Copy the binary anywhere and the screens come with it. BUILDER_WEB_DIR survives as a dev override only.
The screens mount at /builder/* — deliberately not /issues, /agents, /chat. Those are words a host application is likely to have used already, and whose handlers its own router would answer first. One prefix, claimed once, is what makes the bundle safe to drop into somebody else's product. Vite's base and the Go WebMount constant are the same string, so asset URLs and the mount cannot drift — and a test asserts it.
web/src is a symlink to blueprint/_project/web/src: one copy of the 23 screens, not two. A fix to a screen lands in the embedded dashboard and in every scaffolded project at once.
The cost is worth naming: the bundle is a few megabytes and lands in the host application's binary too. That is the price of a plugin that works on install.
builderd hosts several apps in one shell
A product is rarely one origin. BUILDER_TARGETS="app=…,auth=…,dashboard=…" frames them side by side with a switcher. BUILDER_TARGET (singular) still works and renders a byte-identical shell, so no existing deployment changes.
Isolation is the part that had to be right. Each framed document is its own JavaScript realm with its own bridge, buffers and picker. What they share is the parent window, so the shell routes on event.source — the window the browser says sent the message — and not on the origin, because two hosted apps may legitimately share one. Pin and screenshot are refused for any non-active frame.
Every forwarded answer is stamped with the app's identity from the shell's own registry, never from the frame. A compromised product cannot file under its neighbour's name, and the stamp rides into the issue's stored browser context — the difference between "a bug somewhere in the product" and "a bug in auth".
/api/health is answered by the daemon itself now, reporting service: "builderd". It previously polled a route the product registers, took the 404 as "down", and drew "API offline" while running perfectly.
Custom apps
Add a screen without forking the plugin. An app is a directory under apps/<slug> with an app.json and a ui.js, discovered by a boot scan — it gets a tile in the launcher and a route at /apps/<slug>.
Two ways in, one implementation behind them so they cannot drift:
togo-builder app new|list, for a human at a promptcreate_app/list_appsover MCP, so an agent mid-run can add the screen it just decided was needed
The MCP tools live on /mcp/agents, not /mcp/feedback. An app ships an ES module the dashboard imports and executes in an authenticated origin; the feedback token is the one documented as safe to wire into a shared editor, and it must not also be able to put running code in front of an operator. The surface fails closed when auth is unavailable, and no custom app can fail boot.
Semantic recall
Recall was keyword overlap wearing relevance's clothes — HashEmbedder hashes a bag of words, so "the login button is broken" and "authentication fails" embed orthogonally.
Real embeddings (bge-m3, 1024-wide, which migration 0002 already declared) now back it when configured, with reranking on the candidate set where the quality gain lands. Three things make the switch safe:
- The endpoint is probed at boot, not assumed. Configured-but-unreachable used to leave every retain storing a NULL vector with only a warning.
- Vectors are labelled with the model that wrote them (
0018), and recall filters on it. A hash vector and a bge-m3 vector share a column, a width and a distance operator while living in unrelated spaces — a meaningless 0.4 would outrank a real match at 0.5. - Legacy rows are re-embedded in the background. Nothing is dropped; they stay findable by keyword throughout.
HashEmbedder remains the fallback, because this harness has to work on day 0 with nothing else running.
Agent runs happen in tmux
A run was a black box. Runs now spawn inside a deterministic session named builder-issue-<number>-<attempt>, and the issue page shows the attach command.
The name is written to the run row before the process starts, so the mapping survives a crash between the claim and the first byte of output. Every terminal path clears it, because the column means "a session you can attach to right now" — a stale name sends the operator to something tmux has already reaped. Reconcile also reaps the orphaned session, closing a leak of one live shell per crashed run.
UI
The 23 screens rebuilt against the design references — issue board and detail, agent and skill catalogues, dashboard, vault, docs, brain, sources, chat, mcp, terminal — over a shared token and motion layer. EN/AR with RTL throughout.
Fixes
- Fonts never loaded.
@font-facedeclares absolute URLs, and the SPA fallback answered those 404s withindex.html— so the browser got HTML where it expected woff2 and every screen silently fell back to the system stack. - Page headings jumped ~120px between routes, because each screen laid out its own header.
- The brain graph letterboxed in fullscreen instead of filling it, and opened at a scale that had to be fought before it was readable.
tmux new-session -Afailed on the second call from a non-TTY. On the exists branch tmux builds a client, and a client needs a terminal — so from an HTTP handler it died with "open terminal failed: not a terminal". Now check-then-creates viahas-session, which touches no client.
Docs
A rewritten README.md plus 14 pages under docs/: architecture, the two ways to run it, the full environment reference, the HTTP API, the CLI, the brain and its embedders, sources, custom apps, tmux agent runs, and troubleshooting.
Upgrading
Two new migrations, 0017 (tmux session) and 0018 (embedding model), both IF NOT EXISTS and safe to re-apply. Nothing is dropped. Semantic recall is opt-in — set BUILDER_EMBED_URL; unset, the brain behaves exactly as it did.
Changelog
- 01868ed: chore(release): 0.2.0 (@fadymondy)
- bd88f66: feat(apps): custom screens, addable without touching builder's source (@fadymondy)
- d9cb29f: feat(blueprint): mirror the EN/AR pass on issues, sources, brain and chat (@fadymondy)
- 0c11b60: feat(brain): real embeddings and reranking, so recall means something (@fadymondy)
- 3836872: feat(builderd): host several apps in one shell, each reporting as itself (@fadymondy)
- e3817c2: feat(runner): agent runs happen inside tmux, so you can watch them work (@fadymondy)
- 1c6bff2: feat(ui): rebuild the 23 screens against the design references (@fadymondy)
- 09bc597: feat(web): the plugin ships its own dashboard, compiled into the binary (@fadymondy)
Install
npx create-togo-builder@latest my-projectThe postinstall verifies the binary's SHA-256 against checksums.txt
before running it.
v0.1.2
Changelog
- 75cdd42: fix(scaffold): verify the build with GOWORK=off — a workspace above broke it (@fadymondy)
Install
npx create-togo-builder@latest my-projectThe postinstall verifies the binary's SHA-256 against checksums.txt
before running it.
v0.1.1
Changelog
- ac3271e: chore(release): 0.1.1 (@fadymondy)
- 3e55809: docs(rules): batch sessions persist per item and resume — never re-spend (@fadymondy)
- b94c358: feat(setup): break the plan into issues too, opt-in (#57) (@fadymondy)
- c10d84e: feat(setup): generation runs in the background, with a progress bar in the shell (@fadymondy)
- cbcbd65: fix(fleet): generation resumes instead of starting over, and stops timing out (#56) (@fadymondy)
- 544045a: fix(sdk): the shell panel never listened — pin discarded, screenshot black (#55) (@fadymondy)
Install
npx create-togo-builder@latest my-projectThe postinstall verifies the binary's SHA-256 against checksums.txt
before running it.
v0.1.0
Changelog
- e1944ba: Feedback sideover closes on outside click and widens when viewing an issue's detail (feedback-widget-engineer feedback-widget-engineer@agents.local)
- ad5a2b4: Merge #17: feedback slide-over close + detail width (builder builder@togo.local)
- 2752887: Merge #19 via deploy (Fady Mondy info@3x1.io)
- cf10a02: SDK: show thumbnail previews for screenshots/images and flash the pinned element on-page (feedback-widget-engineer feedback-widget-engineer@agents.local)
- 6c0f7d6: builder: day-0 agentic harness — schema, authz, seeder, preflight, vault, SDK, issue plane, wizard, fleet generator (builder builder@togo.local)
- bd124b7: chore(db): renumber the sources migration to 0011, keep the constraint re-runnable (Fady Mondy info@3x1.io)
- e96b34c: chore(fleet): hire the domain expert (Fady Mondy info@3x1.io)
- e47a80c: chore(ui): a crawl config template in the source form (Fady Mondy info@3x1.io)
- c758eb6: feat(blueprint): mirror the design-language pass (Fady Mondy info@3x1.io)
- fc748e8: feat(blueprint): sync the reference app back into the blueprint, and make a generated project build (Fady Mondy info@3x1.io)
- ca32d75: feat(brain): a brain that belongs to no agent, and the webhook source registry (brain-vault-engineer brain-vault-engineer@agents.local)
- 3961b55: feat(brain): a project brain the whole fleet reads (#35) (Fady Mondy info@3x1.io)
- c4ac3c1: feat(brain): a real embedding model behind the seam, configured from .env (#36) (Fady Mondy info@3x1.io)
- 58edf4d: feat(bridge): pin and screenshot taken inside the running product, not the shell (Fady Mondy info@3x1.io)
- 9e812ee: feat(builderd): run the builder as its own process, so it survives the product (Fady Mondy info@3x1.io)
- 197add0: feat(builderd): serve the dashboard too, or there is nothing to look at (Fady Mondy info@3x1.io)
- e4990c2: feat(builderd): the shell — your product framed, the builder outside it (Fady Mondy info@3x1.io)
- 9dd2350: feat(decisions): "Not now" — park an issue without closing it (Fady Mondy info@3x1.io)
- 1b38d11: feat(docs): the reference library, and the caller brain.IngestDocument never had (#37, #38) (Fady Mondy info@3x1.io)
- 1bb4d1b: feat(fleet): brain graph + memory UI, paged activity, unlimited budgets, retry (builder builder@togo.local)
- 89db0ee: feat(fleet): hire agents, and stop refusing a deploy on a dirty tree (builder builder@togo.local)
- cbf4ecc: feat(issues): file an issue by hand from the board (Fady Mondy info@3x1.io)
- f5f1b0d: feat(issues): unblock by replying, and never park without a question (Fady Mondy info@3x1.io)
- 6879c32: feat(mcp): connect any MCP client to this fleet and its memory (Fady Mondy info@3x1.io)
- 9ff8d22: feat(orchestrator): a lead that reads the fleet and hands work to whoever fits (Fady Mondy info@3x1.io)
- 660b92c: feat(orchestrator): agents can delegate to each other, and ask a researcher (Fady Mondy info@3x1.io)
- 626fd1c: feat(sdk): the builder as a layer over the app, not an item in its menu (Fady Mondy info@3x1.io)
- 9f40311: feat(sdk): the report form is a draggable modal, not a section of the panel (Fady Mondy info@3x1.io)
- 3bd2f26: feat(sdk,issues): pin several elements, and get out of the way while doing it (Fady Mondy info@3x1.io)
- 6d4ed1b: feat(skills): make the generator write procedures, and regenerate one at a time (Fady Mondy info@3x1.io)
- caab3d8: feat(skills,brain): skill pages, usage log, and an interrogable graph (Fady Mondy info@3x1.io)
- 9b405d7: feat(sources): a GitHub repository as a brain source, incremental by commit SHA (brain-vault-engineer brain-vault-engineer@agents.local)
- 2796b93: feat(sources): a web crawl connector, and chunking for everything (#41) (Fady Mondy info@3x1.io)
- ca0e3de: feat(sources): join the scheduler to the plugin registry, and fix the loop it exposed (Fady Mondy info@3x1.io)
- dddc26d: feat(sources): mount the registry, start the scheduler, give it a surface (#39) (Fady Mondy info@3x1.io)
- eca7f3f: feat(sources): the source registry, and a SQL query as the first kind (#43) (Fady Mondy info@3x1.io)
- b4c8ae6: feat(term): a tmux terminal in the dashboard (Fady Mondy info@3x1.io)
- 092be8a: feat(triage): a title with no description gets a question, not a guess (Fady Mondy info@3x1.io)
- 8e4d9ab: feat(ui): the Sources and Library apps, and tiles to reach them (#37, #38, #39) (Fady Mondy info@3x1.io)
- 44fd20f: feat: PR publishing (opt-in), brain wired into the loop, routing fixes (builder builder@togo.local)
- 953b468: feat: chat history, a WhatsApp connector, and a PDF that reads any script (Fady Mondy info@3x1.io)
- 1dbd4a9: feat: database search and per-column paging across the board, skills and memories (builder builder@togo.local)
- 1826b41: feat: run reconciler, entity graph, per-agent workdir, deploy gate (builder builder@togo.local)
- 2927466: feat: skills catalogue (#16) and SDK-drafted personas (#15) (builder builder@togo.local)
- 43407d8: feat: the Brain and Chat apps (#47, #46) (Fady Mondy info@3x1.io)
- 2bd989b: fix(autonomy): the migrations deny rule pointed agents at a database wipe (Fady Mondy info@3x1.io)
- b30c12b: fix(blueprint): the generated app was titled BuilderDev (Fady Mondy info@3x1.io)
- ef6c674: fix(brain): one definition of the project namespace, and a guard test that guards (Fady Mondy info@3x1.io)
- 82c360f: fix(caps): measure blast radius by what a run disturbs, not what it writes (Fady Mondy info@3x1.io)
- 1ddc569: fix(ci): pin pnpm, and move to Node 22 (Fady Mondy info@3x1.io)
- 93b3edd: fix(crawl): SSRF via a discovered link, and two robots.txt rules that failed open (Fady Mondy info@3x1.io)
- 1a50d41: fix(orchestrator): a released run left its row open, throttling the fleet (Fady Mondy info@3x1.io)
- 1283f6b: fix(reaper): refund the attempt when the process was killed, not the agent (Fady Mondy info@3x1.io)
- 8106530: fix(rss): say when maxEntries silently loses entries (Fady Mondy info@3x1.io)
- 734b246: fix(sdk): standalone pages — real URL, no host chrome, and a Close that goes back (#51) (Fady Mondy info@3x1.io)
- 75c2e92: fix(sdk): stop offering pin and screenshot where they cannot work (Fady Mondy info@3x1.io)
- 15ef085: fix(sdk): the builder apps are pages now, not an iframe stapled to the host (#51) (Fady Mondy info@3x1.io)
- f4a8d24: fix(sdk): the report modal could not be scrolled, so Submit was unreachable (Fady Mondy info@3x1.io)
- 497749b: fix(skills): give regeneration ten minutes, not five (Fady Mondy info@3x1.io)
- ea5a80f: fix(skills): report the real failure, and let the clock bound the session (Fady Mondy info@3x1.io)
- 7a76d11: fix(skills): strip the preamble models put above the document (Fady Mondy info@3x1.io)
- 597bb0b: fix(term): the terminal was an unauthenticated shell — and ship the icon font (Fady Mondy info@3x1.io)
- d4d01ad: fix(triage): never move an issue without its explanation (Fady Mondy info@3x1.io)
- 00e089e: fix: an agent announces its work before starting, and never moves an issue silently (builder builder@togo.local)
- ddf620e: fix: truncate on character boundaries, not bytes (builder builder@togo.local)
- 506c421: merge issue-38 (Fady Mondy info@3x1.io)
- 61241fe: merge issue-44 (Fady Mondy info@3x1.io)
- c9be3e6: merge issue-47 (Fady Mondy info@3x1.io)
- 7da75b6: test(skills): assert no skill in the catalogue is a stub (Fady Mondy info@3x1.io)
- 6faa841: wip(#35): issue #35 (brain-vault-engineer brain-vault-engineer@agents.local)
- b3d4dc3: wip(#38): issue #38 (brain-vault-engineer <brai...