diff --git a/.changeset/add-project-flow.md b/.changeset/add-project-flow.md deleted file mode 100644 index 482cce1..0000000 --- a/.changeset/add-project-flow.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@gemstack/framework": minor ---- - -Add the "Add project(s)" install flow to the dashboard. A `POST /api/projects` (guarded like the other state-changing routes) installs The Framework into a repo, or every git repo directly under a folder, then registers each so it shows up in the Projects list; the daemon wires it to install-core. The Projects sidebar gains an "Add" control with a small path form (single repo or "folder of repos"), shown only when the server enables adding. Also fixes `enumerateGitRepos` to detect repo roots via `git rev-parse --show-prefix` instead of comparing `--show-toplevel` to the path, which failed across a symlink (e.g. macOS `/var` -> `/private/var`) and returned no repos. diff --git a/.changeset/architect-await-gate.md b/.changeset/architect-await-gate.md deleted file mode 100644 index e791dc1..0000000 --- a/.changeset/architect-await-gate.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@gemstack/framework': patch ---- - -Architect turns now honor agent-authored await gates (#356): an architect (or re-architect) turn that stops to ask via `showChoices()` / `showMultiSelect()` resolves through the live dashboard gate and re-prompts with the answer, instead of the question being silently swallowed into a stub fallback plan at the plan-approval gate. Headless runs are unchanged. Bounded at 5 rounds, like the build gate. diff --git a/.changeset/auto-accept-naming-325.md b/.changeset/auto-accept-naming-325.md deleted file mode 100644 index 43ae8fa..0000000 --- a/.changeset/auto-accept-naming-325.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@gemstack/framework': patch ---- - -Untangle the two "autopilot" concepts in the dashboard (#325): the countdown text now reads "Auto accept in 10s" (and "Auto accept canceled" / "Auto accept off"), so "autopilot" is left to mean the mode preset. The checkbox that arms the countdown is labeled "Autopilot", per Rom's call on the issue. diff --git a/.changeset/auto-git-init-add-project-473.md b/.changeset/auto-git-init-add-project-473.md deleted file mode 100644 index 8deacfd..0000000 --- a/.changeset/auto-git-init-add-project-473.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@gemstack/framework": patch ---- - -Adding a project that isn't a git repo now initializes one for you instead of failing with `fatal: not a git repository`. `installProject` detects a non-repo folder and runs `git init` before its usual commit-and-install flow, so a plain directory can be added straight from the dashboard. The install result reports `initialized: true` when it did so. diff --git a/.changeset/bootstrap-system-prompt.md b/.changeset/bootstrap-system-prompt.md deleted file mode 100644 index 6ce341c..0000000 --- a/.changeset/bootstrap-system-prompt.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@gemstack/framework': minor ---- - -Add bootstrap mode (`--bootstrap`, and `StartRunOptions.bootstrap` for the dashboard): starting a brand-new project from an empty directory. It prepends a forceful preamble above the built-in #326 prompt so the first turn stops for a plan (ranked interpretations or a PLAN file) instead of charging ahead and scaffolding code. The #326 template is left byte-identical; the preamble only raises its "Unclear scope" / "Large scope" rules above Claude Code's default decisiveness, which otherwise overrides them on the append path (#297, #448). diff --git a/.changeset/browser-dashboard-toggle-467.md b/.changeset/browser-dashboard-toggle-467.md deleted file mode 100644 index 2d477b1..0000000 --- a/.changeset/browser-dashboard-toggle-467.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@gemstack/framework": minor ---- - -Add a "Browser" toggle to the dashboard Start form so `--browser` (give the agent a real browser via chrome-devtools-mcp, #452) is reachable from daemon/dashboard-started runs, not just the CLI. Mirrors the Post-merge cleanup pref: a `browser` preference flows to `StartRunOptions.browser` and on to the `--browser` flag. diff --git a/.changeset/browser-mcp-452.md b/.changeset/browser-mcp-452.md deleted file mode 100644 index 0cde726..0000000 --- a/.changeset/browser-mcp-452.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@gemstack/framework": minor ---- - -Add `--browser`: give the agent a real browser during the run via chrome-devtools-mcp. When set, the driver writes a temp `--mcp-config` wiring `chrome-devtools-mcp`, so the agent can navigate pages, read console + network output, inspect the DOM, and screenshot while it works instead of flying blind on frontend changes. Off by default; host-side only (no runner change), and the MCP servers merge with the user's own rather than replacing them. The `ClaudeCodeDriver` gains an `mcpServers` option backing this. diff --git a/.changeset/cli-real-version.md b/.changeset/cli-real-version.md deleted file mode 100644 index d3f9d55..0000000 --- a/.changeset/cli-real-version.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@gemstack/framework': patch ---- - -Fix `framework --version` (and the bare-`framework` footer) reporting `0.0.0` instead of the real package version (#312). The version is now read from the package's own `package.json` at runtime, so it always matches what is installed. diff --git a/.changeset/cli-update-check.md b/.changeset/cli-update-check.md deleted file mode 100644 index 00757d3..0000000 --- a/.changeset/cli-update-check.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@gemstack/framework': minor ---- - -Bare `framework` now tells you whether the CLI is up to date (#312): after the version footer it checks npm's `dist-tags.latest` (2.5s cap) and prints "Up to date" or "Update available: vX (you have vY). Run: npm i -g @gemstack/framework". Offline or on any fetch failure it prints nothing. Display only; no auto-update. diff --git a/.changeset/confirmation-gate-358.md b/.changeset/confirmation-gate-358.md deleted file mode 100644 index 143f12f..0000000 --- a/.changeset/confirmation-gate-358.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@gemstack/framework': minor ---- - -Turn-boundary gate for plan approval (`showMarkdown()` + AWAIT): a build turn that ends with an `await-confirmation` block (the #326 large-scope PLAN flow) now pauses the run with a green Approve and a red Decline button on the dashboard. Approve resumes the build; Decline logs "Plan declined, awaiting user instructions." and stops the run cleanly (like the budget cap), so nothing reviews or improves work the user just declined. Headless runs auto-approve, keeping programmatic runs deterministic. Try it offline with `FRAMEWORK_FAKE_AWAIT=confirmation`. diff --git a/.changeset/context-selector.md b/.changeset/context-selector.md deleted file mode 100644 index 6a4c7c0..0000000 --- a/.changeset/context-selector.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@gemstack/framework': minor ---- - -Add the context selector and trust-on-add to the dashboard (#439, part of #314). The Start form gains a "Context" picker — tick the registered repos to focus the agent on, and each becomes one `Context: ` line in the run's system prompt (the agent can still reach every repo; this just narrows where it looks). Threaded through as a repeatable `--context ` CLI flag and `StartRunOptions.context`. Adding a project now asks "do you trust this repository?" first, warning about prompt-injection risk before the agent is given read access. - -Also hardens the daemon's Telefunc mount: a bare `GET /_telefunc` (which a browser tab issues on reconnect) made telefunc throw an unhandled rejection that crashed the daemon; the mount now catches it and returns 400. diff --git a/.changeset/daemon-foreground.md b/.changeset/daemon-foreground.md deleted file mode 100644 index 3a571a3..0000000 --- a/.changeset/daemon-foreground.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@gemstack/framework": minor ---- - -Bare `framework` now runs the dashboard server in the foreground (#456): Ctrl+C stops it, and the server's logs and any errors it throws are visible in the terminal. `framework --daemon` does what bare `framework` used to do, running the dashboard in the background (detached) and returning after printing the convenience commands. If a background daemon is already running, bare `framework` reports its URL and defers instead of fighting for the port. diff --git a/.changeset/daemon-serves-dashboard.md b/.changeset/daemon-serves-dashboard.md deleted file mode 100644 index 97f4072..0000000 --- a/.changeset/daemon-serves-dashboard.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@gemstack/framework": minor ---- - -The daemon can now serve the new Vike + Telefunc dashboard bundle (#405). Opt in with `FRAMEWORK_DASHBOARD=next` (serves the prerendered SPA at `/`, with the legacy `page.ts` at `/legacy`) or `FRAMEWORK_DASHBOARD=legacy` (mounts the Telefunc surface at `/_telefunc` while `page.ts` stays at `/`). Unset keeps today's behavior exactly. The dashboard's read + steer RPCs and the live-event Channel are served in-process at `/_telefunc` (same-origin guarded), backed by a new `@gemstack/framework/dashboard-rpc` subpath; `starting` a run over Telefunc lands next. diff --git a/.changeset/dashboard-actions.md b/.changeset/dashboard-actions.md deleted file mode 100644 index 663a25a..0000000 --- a/.changeset/dashboard-actions.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@gemstack/framework': minor ---- - -Restore the dashboard actions on the new dashboard (#433): the Start form now carries the Global options (autopilot, technical, vanilla, eco) and the run presets (Research, Readability, Maintainability), the interactive choice gate auto-accepts the recommended pick on an autopilot countdown, a Deploy card shows the chosen render + target, and projects can be added from the Projects sidebar over a new `sendAddProject` telefunction. Adds a browser-safe `deployPlan` projection and the preset builders to `@gemstack/framework/client`. diff --git a/.changeset/dashboard-agent-views-441.md b/.changeset/dashboard-agent-views-441.md deleted file mode 100644 index 2ecd045..0000000 --- a/.changeset/dashboard-agent-views-441.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@gemstack/framework": minor ---- - -Let the agent push ad-hoc markdown views into the dashboard right rail. A `show-markdown` block in a turn (non-blocking, unlike a choice gate) becomes a `view` event that renders as a first-class Views tab in the right rail, with a sticky top-nav to jump between views. Re-showing the same title updates that view in place. diff --git a/.changeset/dashboard-browser-notifications.md b/.changeset/dashboard-browser-notifications.md deleted file mode 100644 index e5af5d7..0000000 --- a/.changeset/dashboard-browser-notifications.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@gemstack/framework': minor ---- - -feat(framework): opt-in browser notifications on the dashboard for run-end and choice gates (#317) - -The localhost dashboard can now notify you when a run finishes (or fails/stops) and when a run reaches a `` gate that needs your input (e.g. a PLAN.md approval). Opt in via the header bell; it only nudges when the dashboard tab is backgrounded, so a run you are watching stays quiet. diff --git a/.changeset/dashboard-center-main.md b/.changeset/dashboard-center-main.md deleted file mode 100644 index be7ac55..0000000 --- a/.changeset/dashboard-center-main.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@gemstack/framework': patch ---- - -Center the dashboard's main grid in the content column. `main` had a `max-width: 1100px` cap but no horizontal centering, so on a wide window the panels hugged the left edge next to the runs sidebar. Add `margin: 0 auto` so the capped grid sits centered. diff --git a/.changeset/dashboard-control-channel.md b/.changeset/dashboard-control-channel.md deleted file mode 100644 index 976902f..0000000 --- a/.changeset/dashboard-control-channel.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@gemstack/framework': minor ---- - -Dashboard control channel: the persistent daemon dashboard can now steer any run in its workspace. Its Stop button and choice picks append to `.framework/control.jsonl`; the run tails the file and aborts or resolves its parked gate. Gates now pause whenever a workspace daemon is live, not only when the run owns its own dashboard; headless behavior without a daemon is unchanged. Also fixes the fresh-workspace daemon startup: bare `framework` in a project with no `.framework/` yet used to fail and leave a zombie server on the port. diff --git a/.changeset/dashboard-default-next.md b/.changeset/dashboard-default-next.md deleted file mode 100644 index 5956668..0000000 --- a/.changeset/dashboard-default-next.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@gemstack/framework": minor ---- - -The new Vike + Telefunc dashboard (#405) is now what the daemon serves by default at `/`; the legacy `page.ts` dashboard moves to `/legacy`. Set `FRAMEWORK_DASHBOARD=legacy` to keep `page.ts` at `/` (the escape hatch), and if a build ever ships without the prerendered bundle the daemon falls back to `page.ts` automatically. The `release` flow now runs `bundle:dashboard` so the published package ships the dashboard assets. diff --git a/.changeset/dashboard-document-sidebar.md b/.changeset/dashboard-document-sidebar.md deleted file mode 100644 index d13e429..0000000 --- a/.changeset/dashboard-document-sidebar.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@gemstack/framework': minor ---- - -feat(framework): document sidebar on the dashboard, rendering the run's PLAN.md / TODO.md (#319) - -The localhost dashboard now surfaces the `PLAN.md` and `TODO.md` the agent writes at the workspace root (via the anti-lazy-pill) in a right sidebar, rendered as markdown with a sticky tab nav to jump between them. A new `GET /api/docs` endpoint reads the surfaced docs (fixed filenames, gated on the workspace `cwd` like `/api/runs`); the sidebar polls it so a plan written mid-run appears, and stays hidden when there are no docs. diff --git a/.changeset/dashboard-layout-fill-height.md b/.changeset/dashboard-layout-fill-height.md deleted file mode 100644 index 5eab17f..0000000 --- a/.changeset/dashboard-layout-fill-height.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@gemstack/framework': patch ---- - -Make the dashboard layout fill the viewport height. `#layout` only grew to its content height, so on a short page the runs-sidebar right border stopped partway down instead of reaching the bottom. Give `#layout` a `min-height: calc(100vh - 57px)` (matching the sidebar's existing header-height key) so the stretched sidebar runs full-height. diff --git a/.changeset/dashboard-overview-437.md b/.changeset/dashboard-overview-437.md deleted file mode 100644 index 9e89953..0000000 --- a/.changeset/dashboard-overview-437.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@gemstack/framework": minor ---- - -Add an Overview section to the top of the dashboard's first sidebar. It gives a cross-project glance over a new `onOverview` Telefunc read: what the agent is running right now (from each project's live run meta), the total open TODO count across all projects, and the most recently active projects. Clicking any of them selects the project. diff --git a/.changeset/dashboard-port-4200.md b/.changeset/dashboard-port-4200.md deleted file mode 100644 index e20bcfe..0000000 --- a/.changeset/dashboard-port-4200.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@gemstack/framework': minor ---- - -Default dashboard port is now 4200 (was 4477): easier to remember. Pass `--port` to override. diff --git a/.changeset/dashboard-preferences.md b/.changeset/dashboard-preferences.md deleted file mode 100644 index b47cffb..0000000 --- a/.changeset/dashboard-preferences.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@gemstack/framework': minor ---- - -Persist the dashboard's Global options (Autopilot, Technical, Vanilla, Eco) in the same `the-framework.json` as the project list, read and written daemon-side over Telefunc (`onPreferences` / `savePreferences`), so they survive restarts without localStorage (#410). The registry file becomes an object `{ projects, preferences }`; older bare-array files still read and are migrated on the next write. diff --git a/.changeset/dashboard-preset-routing-narration.md b/.changeset/dashboard-preset-routing-narration.md deleted file mode 100644 index 0d8c9e5..0000000 --- a/.changeset/dashboard-preset-routing-narration.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@gemstack/framework': patch ---- - -fix(framework): narrate the auto-preset routing turn so the dashboard is not blank at the start of a run (#310) - -A preset-less live run first does a real Claude routing turn to auto-select a domain preset. The dashboard was started only after that turn, so its first few seconds looked dead. The dashboard now starts before the routing turn and the turn narrates a log line into it. diff --git a/.changeset/dashboard-project-log-panel.md b/.changeset/dashboard-project-log-panel.md deleted file mode 100644 index 89cf95f..0000000 --- a/.changeset/dashboard-project-log-panel.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@gemstack/framework': minor ---- - -Add a Project log panel to the dashboard (#384). It surfaces the committed `.the-framework/LOGS.md` history (#378/#379) for the workspace: every loop/prompt/build run with its title, status, kind, session link, and a loop's constituent prompts, newest-first. Served by a new `GET /api/logs` endpoint and refreshed on load, on run-end, and on an interval. All fields are escaped and the session link is passed through the page's safe-URL guard, since the log is agent-authored. diff --git a/.changeset/dashboard-queue-438.md b/.changeset/dashboard-queue-438.md deleted file mode 100644 index b5cff1f..0000000 --- a/.changeset/dashboard-queue-438.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@gemstack/framework": minor ---- - -Add a cross-project Queue section to the dashboard's first sidebar. It aggregates the open `TODO.md` items across every registered project over a new `onQueue` Telefunc read, so the whole backlog is visible in one place instead of per-selected-project only. Clicking a project in the queue selects it. diff --git a/.changeset/dashboard-read-model.md b/.changeset/dashboard-read-model.md deleted file mode 100644 index 53a1eb8..0000000 --- a/.changeset/dashboard-read-model.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@gemstack/framework": minor ---- - -Export `readDocs` + the `WorkspaceDoc` type from the package root, so a separate dashboard can read the same surfaced PLAN/TODO docs the daemon serves (#405 phase 2). diff --git a/.changeset/dashboard-run-history.md b/.changeset/dashboard-run-history.md deleted file mode 100644 index 7a0f1e0..0000000 --- a/.changeset/dashboard-run-history.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@gemstack/framework': minor ---- - -feat(framework): browse a project's run history in the dashboard (#303) - -The dashboard now has a left sidebar listing a project's past runs (intent, status, session link); clicking one replays that run's projection in the main view, and "Back to live" returns to the current run. Each finished run is archived under `.framework/runs/.jsonl` + `.framework/runs/.json` (a crash that skips the final flush is archived on the next run), and served over `GET /api/runs` and `GET /api/runs/`. Single project only. Closes #303. diff --git a/.changeset/dashboard-run-view.md b/.changeset/dashboard-run-view.md deleted file mode 100644 index 7f3f07f..0000000 --- a/.changeset/dashboard-run-view.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@gemstack/framework": minor ---- - -Add event-stream projections for the dashboard's run overview: `architectPlan`, `decisionLedger`, `loopStatus`, and `sessionInfo` derive the chosen stack + rationale, the decisions ledger, the production-grade loop status, and the live session from a `FrameworkEvent[]`. They plus `formatFrameworkEvent` are re-exported from a new browser-safe `@gemstack/framework/client` subpath (no Node imports), so the dashboard renders the rich run view — the stack/PROS-CONS card, decisions, loop status, and a human-readable event log instead of raw JSON — across the live view, past-run replay, and the relay watch view. diff --git a/.changeset/dashboard-send-start.md b/.changeset/dashboard-send-start.md deleted file mode 100644 index ba8948b..0000000 --- a/.changeset/dashboard-send-start.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@gemstack/framework": minor ---- - -The new dashboard can now start a run over Telefunc (#405). A `sendStart` telefunction reaches the daemon's own `startRun` closure through the Telefunc request context, so it runs in-process with the one-run-per-project busy guard intact (a second start returns `busy`). Served at `/_telefunc` alongside the read + steer RPCs, same-origin guarded. diff --git a/.changeset/dashboard-start-run.md b/.changeset/dashboard-start-run.md deleted file mode 100644 index 91a51a2..0000000 --- a/.changeset/dashboard-start-run.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@gemstack/framework': minor ---- - -Start runs from the daemon dashboard (#345): a prompt textarea + `POST /api/start` that spawns `framework "" --no-dashboard` as a detached child, with a one-run-at-a-time guard. The started run streams into the page via the tailed event log and is steerable (gates + Stop) through the control channel. diff --git a/.changeset/dashboard-sticky-header-sidebar.md b/.changeset/dashboard-sticky-header-sidebar.md deleted file mode 100644 index 5af808f..0000000 --- a/.changeset/dashboard-sticky-header-sidebar.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@gemstack/framework': patch ---- - -Keep the dashboard header and sidebar in view while scrolling. The header is now sticky at the top (with a background and z-index so content scrolls under it), and the app-running banner and the runs sidebar stick just below it. On a long page you no longer lose the title, stop button, and run list when you scroll down. diff --git a/.changeset/doc-sidebar-session-scoped.md b/.changeset/doc-sidebar-session-scoped.md deleted file mode 100644 index 66c3c24..0000000 --- a/.changeset/doc-sidebar-session-scoped.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@gemstack/framework': patch ---- - -fix(framework): surface session-scoped PLAN/TODO docs in the dashboard sidebar (#323) - -The document sidebar now also surfaces the session-scoped `PLAN_.agent.md` / `TODO_.agent.md` files The Framework writes per run (#323/#326), not just flat `PLAN.md` / `TODO.md`. Flat files stay supported as a fallback for hand-written docs. Names are matched against the workspace root with a fixed slug pattern, so there is still no path traversal. diff --git a/.changeset/eventstream-iterator-cancel.md b/.changeset/eventstream-iterator-cancel.md deleted file mode 100644 index b0a96e5..0000000 --- a/.changeset/eventstream-iterator-cancel.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@gemstack/ai-autopilot': patch ---- - -fix(ai-autopilot): EventStream iterators are now cancellable - -A consumer's async iterator gained a `return()` that drops its waiter from the stream and settles any pending `next()`. Previously a consumer that stopped iterating (e.g. a disconnected SSE client) left its waiter registered until the next `push`/`close`, so many short-lived consumers on an idle stream leaked. Live iteration and history replay are unchanged. diff --git a/.changeset/framework-dashboard-csrf-xss.md b/.changeset/framework-dashboard-csrf-xss.md deleted file mode 100644 index 85435e8..0000000 --- a/.changeset/framework-dashboard-csrf-xss.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@gemstack/framework': patch ---- - -Harden the dashboard against cross-site abuse and event-borne XSS. The state-changing dashboard routes (`/stop`, `/choice`, `/api/start`) now reject any request whose `Origin` is a foreign site, so a page on another origin can no longer drive the localhost dashboard into spawning or steering a run (a non-browser caller that sends no `Origin` is unaffected). The client render pipeline no longer trusts event strings: link URLs (session link, preview URL, run-history link) are scheme-checked so a `javascript:` URL collapses to `#`, and the HTML escaper now escapes quotes so a relay-published event can't break out of an attribute (e.g. a choice option id like `x" autofocus onfocus=...`). diff --git a/.changeset/framework-maintain-sweep.md b/.changeset/framework-maintain-sweep.md deleted file mode 100644 index e6e4f75..0000000 --- a/.changeset/framework-maintain-sweep.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@gemstack/framework": minor ---- - -Add `framework maintain` (#298): a background maintenance sweep. It walks the registered repos, and for each that has grown commits since its last review it runs the maintainability loop on them (`framework prompt`, budget-capped by `--max-cost`, bounded by `--max-repos`). A first-seen repo is baselined (recorded, not reviewed retroactively); per-repo review state lives in `.the-framework/maintenance.json`. `--dry-run` previews the plan. Also exports the maintenance API (`assessRepo`, `planMaintenanceSweep`, `maintainSweep`, review state helpers). diff --git a/.changeset/framework-system-prompt-injection.md b/.changeset/framework-system-prompt-injection.md deleted file mode 100644 index 078fbf8..0000000 --- a/.changeset/framework-system-prompt-injection.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@gemstack/framework': minor ---- - -feat(framework): inject a system prompt into every prompt (anti-lazy-pill + SYSTEM.md) - -Every run is now framed with a built-in system prompt: the validated anti-lazy-pill (#297), which turns unclear scope into a ranked list, a large scope into a `PLAN.md`, and a very large one into a `TODO.md` backlog, so the agent builds a real backend and declares what it descopes instead of silently faking it. Drop a `SYSTEM.md` at the workspace root to add project-specific instructions on top, or set `antiLazyPill: false` in `the-framework.yml` to remove the built-in default. Closes #301. diff --git a/.changeset/gate-refire-after-realternative.md b/.changeset/gate-refire-after-realternative.md deleted file mode 100644 index f4f78a4..0000000 --- a/.changeset/gate-refire-after-realternative.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@gemstack/framework': patch ---- - -fix(framework): re-fire the plan-approval gate after picking an alternative (#324) - -Picking an alternative at the plan-approval gate re-architects the plan, and that fresh plan can differ a lot from the one you rejected. The gate now re-fires on the re-architected plan so you approve the plan you will actually build, not just the first one. Bounded to a few re-architect rounds so a run of alternative-picks can't loop forever. diff --git a/.changeset/global-options-engine-314.md b/.changeset/global-options-engine-314.md deleted file mode 100644 index d427b99..0000000 --- a/.changeset/global-options-engine-314.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@gemstack/framework': minor ---- - -Thread the #314 Global options through the run engine (#370). `POST /api/start` now carries an `options` object which the daemon turns into CLI flags: `--vanilla` removes the built-in #326 system prompt entirely (raw Claude Code), and `--eco-auto-planning` / `--eco-auto-research` / `--eco-auto-maintenance` drop the matching #326 sections to save tokens (Autopilot and Technical keep mapping to modes). `system-prompt.ts` drops the Eco sections at render, so the #343 Prompts panel reflects the toggles live; the #326 template stays byte-identical. The dashboard panel that drives these lands separately (#371); all fields default off, so today's behavior is unchanged. diff --git a/.changeset/global-options-panel-314.md b/.changeset/global-options-panel-314.md deleted file mode 100644 index 7db9f87..0000000 --- a/.changeset/global-options-panel-314.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@gemstack/framework': minor ---- - -Add the #314 Global options panel to the dashboard (#371). Beside the Start box the daemon dashboard now shows persistent toggles: Autopilot (auto-accept, sharing its key with the choice-panel toggle so the two stay in lockstep), Technical control, Vanilla (remove all system prompts, fully transparent), and Eco with Auto planning / Auto research / Auto maintenance to trim the built-in prompt. Each persists in localStorage and rides along in the `POST /api/start` body, so flipping a toggle changes what the run gets (and, with the engine plumbing in #370, what the #343 Prompts panel shows). Vanilla disables Eco, since a removed prompt has nothing left to trim. diff --git a/.changeset/interactive-choices-autopilot.md b/.changeset/interactive-choices-autopilot.md deleted file mode 100644 index 14997e3..0000000 --- a/.changeset/interactive-choices-autopilot.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@gemstack/framework': minor ---- - -feat(framework): interactive plan-approval choice + autopilot in the dashboard (#304) - -The run now pauses at a plan-approval gate right after the architect decides the stack (the AWAIT point of the plan-then-AWAIT flow): the dashboard shows a "Your call" panel with "Proceed" plus each architect alternative as "Use X instead". Accept with the button or Ctrl+Enter, or leave the `[x] autopilot` countdown auto-accept the recommended plan after 10s (moving the mouse cancels it). Picking an alternative re-architects the run around it. New `requestChoice` option on `runFramework`, `choice` / `choice-resolved` events, and a `POST /choice` dashboard route; a headless run with no handler auto-accepts the recommended plan, so nothing else changes. Closes #304. diff --git a/.changeset/lifecycle-signals-326.md b/.changeset/lifecycle-signals-326.md deleted file mode 100644 index 3edc845..0000000 --- a/.changeset/lifecycle-signals-326.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@gemstack/framework": minor ---- - -Add the `setSessionName()` and `setReadyForMerge()` lifecycle signals (#326). Both are non-blocking turn-boundary signals, the same shape as the existing `show-markdown` view: the agent emits a fenced `set-session-name` / `ready-for-merge` block and keeps working, and the framework records it and reflects it in the dashboard. `setSessionName()` labels the run with the `[a-z0-9-]` slug it chose (also its `the-framework/` branch); `setReadyForMerge()` flips the run's status from building to ready-for-review. The dashboard shows the session name and a status dot (amber while building, green once ready) in both the run overview and the cross-project "working now" list. This is the signal the post-merge quality suite will hang off. diff --git a/.changeset/maintainability-preset-361.md b/.changeset/maintainability-preset-361.md deleted file mode 100644 index 19b075b..0000000 --- a/.changeset/maintainability-preset-361.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@gemstack/framework': minor ---- - -New [Maintainability] preset button on the dashboard (#361): prefills the deliberately minimal refactor-for-future-changes prompt ("look for maintainability red flags, and fix them") into the start textarea for review or editing; Start runs the text verbatim as a direct prompt run. The one blank, ``, defaults to `this PR`. diff --git a/.changeset/multi-project-daemon-reads.md b/.changeset/multi-project-daemon-reads.md deleted file mode 100644 index 3a7e145..0000000 --- a/.changeset/multi-project-daemon-reads.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@gemstack/framework": minor ---- - -Make the dashboard multi-project on the read side: `GET /api/projects` lists the registered projects (from the registry) with a per-project summary (name, activated, last activity), and `?project=` on `/api/logs`, `/api/runs`, `/api/runs/`, and `/api/docs` reads that project's data (an absent id keeps the daemon's own workspace, single-project back-compat). The daemon auto-registers its own workspace on boot when it is activated, so the Projects list is populated for the common single-project case. Live event streaming and per-project run start/stop stay single-project for now. Adds `ProjectSummary` / `ProjectsProvider` / `summarizeProject` / `defaultProjectsProvider`. diff --git a/.changeset/multi-project-install-core.md b/.changeset/multi-project-install-core.md deleted file mode 100644 index 87e2466..0000000 --- a/.changeset/multi-project-install-core.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@gemstack/framework": minor ---- - -Add the install-core module: `installProject(cwd)` activates a repo for The Framework by creating the `.the-framework/` marker with a seeded `LOGS.md`, committing any pre-existing dirty changes first (`[The Framework] uncommitted changes`) so the install commit (`[The Framework] install The Framework`) is clean; an already-activated repo is a no-op. Also `enumerateGitRepos(dir)` lists the immediate child directories that are their own git repo roots (for the "add a directory of repos" flow). Pure core over the existing `GitRunner` + `StoreFs` seams; any git failure surfaces as a value, never a throw. No daemon or UI wiring yet. diff --git a/.changeset/multi-project-registry-module.md b/.changeset/multi-project-registry-module.md deleted file mode 100644 index b5e8111..0000000 --- a/.changeset/multi-project-registry-module.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@gemstack/framework": minor ---- - -Add the multi-project registry module: reads and writes the list of projects The Framework is installed into, as a small `{id, path, addedAt}` JSON index under the user's config dir. Exposes `projectId`, `registryPath`, `listProjects`, `addProject`, `removeProject`, and an injectable `RegistryFs` seam with a `nodeRegistryFs()` adapter. No daemon or UI wiring yet. diff --git a/.changeset/multi-select-gate-332.md b/.changeset/multi-select-gate-332.md deleted file mode 100644 index 1748915..0000000 --- a/.changeset/multi-select-gate-332.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@gemstack/framework': minor ---- - -Add a multi-select gate (`showMultiSelect()`): a dashboard checklist with pre-checked defaults that pauses the run and resolves to the selected subset. Built on the existing single-select choice gate (same panel and POST-back resolver), exposed as `requestMultiSelect()`; a headless run auto-accepts the default set. This is the primitive the [Research] preset uses to let the user pick which problems to deep-dive. diff --git a/.changeset/multiselect-turn-boundary-gate.md b/.changeset/multiselect-turn-boundary-gate.md deleted file mode 100644 index a5189e1..0000000 --- a/.changeset/multiselect-turn-boundary-gate.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@gemstack/framework': minor ---- - -feat(framework): turn an agent's showMultiSelect()+AWAIT into a live checklist gate (#339) - -The multi twin of the single-select turn-boundary gate (#337). When a build turn ends on an `await-multiselect` block, the framework shows a checklist on the dashboard (via `requestMultiSelect`, with the agent-marked defaults pre-checked), waits for the selection, and re-prompts the agent to continue from it. This is what the research preset needs to let the user pick which problems to deep-dive. Same safety as #337: a no-op when headless and when the agent just finishes. diff --git a/.changeset/per-project-daemon-393.md b/.changeset/per-project-daemon-393.md deleted file mode 100644 index 859d229..0000000 --- a/.changeset/per-project-daemon-393.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@gemstack/framework": minor ---- - -Per-project daemon runs + one daemon per machine (#393). Dashboard-started runs, Stop, and choice picks now carry the viewed project id, so the daemon spawns each run with that project's `--cwd`, steers it through that project's own control log, and guards one run per project. Daemon liveness moved from a per-workspace `.the-framework/daemon.json` to a single global file beside the registry (`$XDG_CONFIG_HOME/the-framework-daemon.json`), so `framework` and `framework stop` in any repo find the same daemon. Per-project live event streaming is folded in with the dashboard rebuild (#405). diff --git a/.changeset/per-run-new-dashboard.md b/.changeset/per-run-new-dashboard.md deleted file mode 100644 index f0eb61d..0000000 --- a/.changeset/per-run-new-dashboard.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@gemstack/framework": minor ---- - -Serve the new Vike + Telefunc dashboard for per-run foreground runs and `--resume`, not just the daemon. `framework ""` and `framework --resume` now serve the rebuilt dashboard in single-project mode, scoped to that run's workspace without touching the global registry, and the live run steers over its own `.the-framework/control.jsonl` even with no daemon running. Falls back to the legacy `page.ts` when the bundle is absent or `--no-persist` is set. Adds `singleProjectProvider` and `resolveDashboardBundle` to the public surface. diff --git a/.changeset/persistent-dashboard-daemon.md b/.changeset/persistent-dashboard-daemon.md deleted file mode 100644 index a5da1dd..0000000 --- a/.changeset/persistent-dashboard-daemon.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@gemstack/framework': minor ---- - -feat(framework): persistent background dashboard daemon (#302) - -Bare `framework` now ensures a long-lived dashboard process for the workspace and prints its URL plus the convenience commands; `framework stop` shuts it down. The dashboard is a projection of `.framework/events.jsonl`: the detached daemon tails the log and pushes each new event to connected browsers, so it outlives any single run. The tailer also detects an in-place truncation when a fresh run rewrites the log to the same byte length (size unchanged but mtime advanced), and the daemon spawn refuses to re-exec a test entry so a `node --test` run can never fork-bomb itself. diff --git a/.changeset/post-merge-quality-suite-326.md b/.changeset/post-merge-quality-suite-326.md deleted file mode 100644 index d9897a7..0000000 --- a/.changeset/post-merge-quality-suite-326.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@gemstack/framework": minor ---- - -Add the post-merge quality suite (#326): when a run signals `setReadyForMerge()`, optionally fire the maintainability, readability, and security-audit passes over the same workspace. Enabled per run by the new `--post-merge` CLI flag, or from the dashboard's Global options via a "Post-merge cleanup" toggle (persisted as the `postMergeQuality` preference, mapped to `--post-merge` on the spawned run). The three passes run **sequentially** — they edit and commit the same git tree, so concurrent writers would race on the index lock; worktree-isolated parallelism is a follow-up. Each pass is a plain `framework prompt` child carrying no `--post-merge`, so a quality pass never triggers its own suite. Off by default. diff --git a/.changeset/preset-params-330.md b/.changeset/preset-params-330.md deleted file mode 100644 index ccd60ce..0000000 --- a/.changeset/preset-params-330.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@gemstack/framework': minor ---- - -Add preset-prompt param substitution (``), the foundation for prompt-preset buttons. A preset prompt template can carry `` placeholders substituted from supplied values or declared defaults; unfilled params are surfaced so a caller can ask the user to fill the blanks. diff --git a/.changeset/presets-prefill-textarea.md b/.changeset/presets-prefill-textarea.md deleted file mode 100644 index 9ca103d..0000000 --- a/.changeset/presets-prefill-textarea.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@gemstack/framework': minor ---- - -Dashboard presets only prefill the textarea (#353): the [Research] button now loads the full rendered preset prompt for review and editing, and nothing runs until Start / Ctrl+Enter. The edited text is sent verbatim via a new `prompt` start kind and `framework prompt ` subcommand (the direct path: gates honored, no build pipeline). Clearing the box reverts Start to a normal build run. diff --git a/.changeset/project-second-sidebar.md b/.changeset/project-second-sidebar.md deleted file mode 100644 index f04903f..0000000 --- a/.changeset/project-second-sidebar.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@gemstack/framework": minor ---- - -Add the per-project second sidebar and main view. The second sidebar now shows the selected project's loops/prompts (its `.the-framework/LOGS.md`, scoped via `?project=`) with its Runs archive below it, both following the selection. The main view shows the selected or latest loop/prompt claude.ai/code-style (kind, title, status, session link, and a loop's constituent prompts); clicking a loop in the sidebar opens it. On load the most recently active project is auto-selected, so the view is populated immediately. diff --git a/.changeset/projects-sidebar.md b/.changeset/projects-sidebar.md deleted file mode 100644 index 4399e2c..0000000 --- a/.changeset/projects-sidebar.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@gemstack/framework": minor ---- - -Add the Projects sidebar to the dashboard: a leftmost nav with Overview (project count plus the most recently active projects), Projects (every registered project with an activation dot and last-activity, from `/api/projects`), and Queue (the open TODO items aggregated across all projects). Selecting a project re-points the project log to `?project=`. The per-project second sidebar and main view come next. diff --git a/.changeset/readability-preset-360.md b/.changeset/readability-preset-360.md deleted file mode 100644 index 57f1c28..0000000 --- a/.changeset/readability-preset-360.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@gemstack/framework': minor ---- - -New [Readability] preset button on the dashboard (#360): prefills Rom's refactor-for-human-readers prompt (architectural seams, linearity/altitude pass, exhaustive per-function rating lists, one commit per refactor) into the start textarea for review or editing; Start runs the text verbatim as a direct prompt run. The one blank, ``, defaults to `this PR`. diff --git a/.changeset/registry-single-file.md b/.changeset/registry-single-file.md deleted file mode 100644 index 9ed8eac..0000000 --- a/.changeset/registry-single-file.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@gemstack/framework": patch ---- - -Store the multi-project registry as a single file, `.bashrc`-style: `$HOME/.the-framework.json` (or `$XDG_CONFIG_HOME/the-framework.json`) instead of a `projects.json` nested inside a `.the-framework/` directory (#390). diff --git a/.changeset/relay-new-dashboard.md b/.changeset/relay-new-dashboard.md deleted file mode 100644 index 4adf84b..0000000 --- a/.changeset/relay-new-dashboard.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@gemstack/framework": minor ---- - -Serve the new Vike + Telefunc dashboard from the run relay (`--share`), in a read-only watch mode. The relay now serves the prerendered SPA and streams events over the same Telefunc `onEvents` Channel the daemon uses, sourced from its in-memory run instead of a file. Only the live event stream is exposed (an empty projects provider neutralizes the file/registry RPCs on the public host, and no run can be started or steered). The shareable viewer URL moves from `/r/:id/` to `/?run=:id` (old links redirect); ingest stays at `/r/:id/publish`. This removes the relay's dependency on the legacy `page.ts`. Adds `makeTelefuncMount`, `serveClientBundle`, `emptyProjectsProvider`, and the `EventsSource` type to the public surface. diff --git a/.changeset/relay-sandbox-hardening.md b/.changeset/relay-sandbox-hardening.md deleted file mode 100644 index 473cf38..0000000 --- a/.changeset/relay-sandbox-hardening.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -'@gemstack/framework': patch ---- - -fix(framework): harden the run relay and workspace sandbox against resource exhaustion - -- The relay now caps how many runs it holds in memory and evicts the least-recently-used one on overflow. Because it is unauthenticated, an anonymous request to `/r//…` could previously create per-run state that was never freed; run creation is now bounded (`maxRuns`, default 200). -- A disconnected SSE viewer now cancels its stream iterator, releasing its waiter immediately instead of lingering on the stream until the next event (which may never arrive for an idle run). -- `snapshotWorkspace` checks a file's size before reading it, so a large asset in the workspace is skipped without ever being loaded into memory during a `--sandbox docker` sync. -- `relayPublisher`'s POST has a timeout, so a relay that accepts a connection but never responds can no longer hang the CLI on exit (`flush()`). diff --git a/.changeset/research-preset-button.md b/.changeset/research-preset-button.md deleted file mode 100644 index b7c924f..0000000 --- a/.changeset/research-preset-button.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@gemstack/framework': minor ---- - -The [Research] preset (#331): `framework research [what]` and a [Research] button on the daemon dashboard run Rom's problem-variability review as a direct prompt via the new `runPrompt()` path, which honors await gates (showChoices/showMultiSelect) but skips the scope/architect/build scaffolding. The "what" defaults to `this PR`. diff --git a/.changeset/retire-page-ts.md b/.changeset/retire-page-ts.md deleted file mode 100644 index ec5cc23..0000000 --- a/.changeset/retire-page-ts.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@gemstack/framework': minor ---- - -Retire the legacy `page.ts` dashboard and its HTTP routes (#426, part 3). Both consumers are now on the new Vike + Telefunc dashboard (the daemon default, per-run/resume, and the relay), so `startDashboard` now serves only the prerendered SPA plus the `/_telefunc` mount (RPCs + the live-event Channel). Removed: the `dashboardHtml` and `parseStartOptions` exports, the in-process `Dashboard.push`/`Dashboard.stream` (the SPA reads `events.jsonl` over the Channel and steers over `control.jsonl`), and the now-unused `DashboardOptions` fields (`onStop`, `onChoice`, `cwd`, `dashboardMode`) and the `FRAMEWORK_DASHBOARD=legacy` escape hatch. A `--no-persist` foreground run (or an install missing the built bundle) now runs headless rather than falling back to the old page. diff --git a/.changeset/security-audit-preset-461.md b/.changeset/security-audit-preset-461.md deleted file mode 100644 index 566a890..0000000 --- a/.changeset/security-audit-preset-461.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@gemstack/framework": minor ---- - -Add the [Security audit] preset (#461): an exhaustive, direct security pass over a target (defaults to `this PR`), shipped alongside [Research], [Readability], and [Maintainability]. It lists every aspect considered with a per-aspect verdict and fixes each issue in its own commit. Available as a dashboard Start-a-run button and exported as `renderSecurityAuditPrompt`. It is also the third of the post-merge quality prompts #326 fires on `setReadyForMerge()`. diff --git a/.changeset/show-prompts-in-dashboard-476.md b/.changeset/show-prompts-in-dashboard-476.md deleted file mode 100644 index 6833b47..0000000 --- a/.changeset/show-prompts-in-dashboard-476.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@gemstack/framework": minor ---- - -Show the exact prompt sent to the agent each turn. The run feed used to render a turn's start as just `> prompt sent` and drop the text; now the terminal/log formatter shows a one-line preview, and the dashboard event feed renders the full prompt in a collapsible block (click to expand) for both live runs and replays. The prompt was already carried on the driver `start` event and persisted, so this is a display-only change that surfaces it. diff --git a/.changeset/show-real-prompts-343.md b/.changeset/show-real-prompts-343.md deleted file mode 100644 index cdd3419..0000000 --- a/.changeset/show-real-prompts-343.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@gemstack/framework': minor ---- - -Show the real prompts on the dashboard (#343). The framework now emits the exact system prompt it runs the agent under, the #326 block plus any persona / skill / memory framing, as a `system-prompt` event at session start (both the direct-prompt path and the full build path). A new "Prompts sent to Claude Code" panel renders it alongside each turn's user prompt (harvested from the `driver` `start` events already in the stream), so the normally-hidden prompt is fully visible for transparency. Prompt text renders as inert text, never markup. Read-only; nothing is gated on it. diff --git a/.changeset/single-select-gate-primitive.md b/.changeset/single-select-gate-primitive.md deleted file mode 100644 index 8cced42..0000000 --- a/.changeset/single-select-gate-primitive.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@gemstack/framework': minor ---- - -feat(framework): extract a shared single-select gate primitive (`requestChoices`) (#335) - -The single-select choice gate (#304) is now a reusable `requestChoices({ id, title, options, recommended })` export, the twin of `requestMultiSelect` (#332): it emits the `choice` event, parks for the pick, and falls back to the recommended option if the run is headless or aborts. The plan-approval gate builds on it, and it is the primitive the system prompt's `showChoices()` and the research preset need. No behavior change for existing runs. diff --git a/.changeset/start-run-feedback.md b/.changeset/start-run-feedback.md deleted file mode 100644 index 54d80ed..0000000 --- a/.changeset/start-run-feedback.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@gemstack/framework": minor ---- - -Give the dashboard clear feedback when a run is started. A run is spawned detached, so there was a gap between clicking Start and the first event (and a failed launch produced nothing, so the page looked frozen). Now clicking Start shows an immediate "Starting your run..." banner; if no output arrives within ~8s it warns that the run may have failed to start; a run-launch/exit failure surfaces as an error banner; and a rejected Start (a run is already active) shows a clear "busy" banner instead of a tiny note. diff --git a/.changeset/system-prompt-326.md b/.changeset/system-prompt-326.md deleted file mode 100644 index 4be61a5..0000000 --- a/.changeset/system-prompt-326.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@gemstack/framework': minor ---- - -The built-in system prompt is now Rom's #326 text, verbatim, replacing the anti-lazy-pill it grew out of: unclear scope becomes a ranked `showChoices()` list, a large scope a `PLAN_.agent.md` to approve, a very large one also a `TODO_.agent.md` backlog, an alternatives pass rates problem "variability" before code is written, and edits to existing code stay minimal. The prompt is a template (#350): `${{ ... }}` JS fragments render against the run context, so `tf.params.autopilot` relaxes the maintenance stance on autopilot runs and `${{tf.prompt}}` carries the user prompt slot. New exports: `SYSTEM_PROMPT_TEMPLATE`, `renderSystemPrompt`, `renderTemplate`; the `ANTI_LAZY_PILL` export is gone (the `antiLazyPill` config key still toggles the built-in prompt). `--autopilot` now has an effect without a preset. diff --git a/.changeset/the-framework-log-run-completion.md b/.changeset/the-framework-log-run-completion.md deleted file mode 100644 index 10751a9..0000000 --- a/.changeset/the-framework-log-run-completion.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@gemstack/framework': minor ---- - -Record every finished run in the project log `.the-framework/LOGS.md` (#379). When a run ends, the CLI appends an entry with the intent/prompt title, the kind (build or prompt), the final status (done/stopped/failed), and the Claude Code session id and link. Best-effort, so a log write can never break a run. This is what makes the project DB (#378) fill itself; the run-history sidebar in #314 reads from it. diff --git a/.changeset/the-framework-logs-module.md b/.changeset/the-framework-logs-module.md deleted file mode 100644 index 8310dff..0000000 --- a/.changeset/the-framework-logs-module.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@gemstack/framework': minor ---- - -New `.the-framework/LOGS.md` project-log module (#378): `appendLog`/`readLogs` keep a human-readable markdown log of every loop, prompt, and build in a project, with `renderLogEntry`/`parseLogs` as the pure core over the same StoreFs seam as the run store. Parsing is forgiving: a malformed entry is skipped, never thrown. Standalone for now; the run-lifecycle wiring and dashboard UI land in follow-up issues. diff --git a/.changeset/the-framework-project-helpers.md b/.changeset/the-framework-project-helpers.md deleted file mode 100644 index fa9ed3c..0000000 --- a/.changeset/the-framework-project-helpers.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@gemstack/framework': minor ---- - -Add project repo helpers (#380): `isActivated()` checks the `.the-framework/` activation marker via an injectable `ProjectFs`, and `crawlRepoFiles()` lists every tracked + untracked (gitignore-honoring) file via `git ls-files -z` behind an injectable `GitRunner`. Both forgiving: any failure reads as not-activated / an empty list. Building blocks for the #314 sidebars. diff --git a/.changeset/todo-backlog-loop.md b/.changeset/todo-backlog-loop.md deleted file mode 100644 index 1f33d4a..0000000 --- a/.changeset/todo-backlog-loop.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@gemstack/framework': minor ---- - -The backlog loop (#323): after the build settles, the run consumes the agent's own TODO backlog (`TODO_.agent.md`, or the flat `TODO.md`) one entry per turn until it is empty. When a dashboard can answer, the loop gates before each entry ("start the next item?"), so autopilot consumes the backlog unattended and autopilot-off pauses per item. Caps make it safe overnight: the budget/Stop signal ends any turn, `--max-todo-items` bounds the run (default 25), and two no-progress items stop the loop. `--no-todo-loop` opts out. diff --git a/.changeset/turn-boundary-choice-gate.md b/.changeset/turn-boundary-choice-gate.md deleted file mode 100644 index c8de255..0000000 --- a/.changeset/turn-boundary-choice-gate.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@gemstack/framework': minor ---- - -feat(framework): turn an agent's showChoices()+AWAIT into a live gate at the turn boundary (#337) - -The system prompt tells the agent to `showChoices()` and `AWAIT` at unclear-scope / alternatives points, but until now only framework-emitted gates (the plan-approval gate, multi-select) could pause a run. Now when a build turn ends by asking the user, an `await-choices` block, the framework shows the choice on the dashboard, waits for the pick, and re-prompts the agent to continue from that decision. It is the agent-authored counterpart to the plan-approval gate: a no-op when headless and when the agent just finishes instead of asking, so existing runs are unchanged. diff --git a/.changeset/unify-the-framework-dir.md b/.changeset/unify-the-framework-dir.md deleted file mode 100644 index 84b2dc0..0000000 --- a/.changeset/unify-the-framework-dir.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@gemstack/framework": minor ---- - -Keep everything in a single `.the-framework/` directory (#313). The transient run state (`events.jsonl`, `run.json`, `runs/`, `control.jsonl`, `daemon.json`) now lives in `.the-framework/` alongside the committed project log `LOGS.md`, instead of a separate `.framework/` directory. `install` seeds a `.the-framework/.gitignore` that ignores everything except `LOGS.md`, so the run state stays transient and only the log is committed. diff --git a/.changeset/usage-accounting-budget-cap.md b/.changeset/usage-accounting-budget-cap.md deleted file mode 100644 index 023baf4..0000000 --- a/.changeset/usage-accounting-budget-cap.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@gemstack/framework': minor ---- - -feat(framework): track agent spend and add a budget cap (#322) - -The framework now accumulates the token + cost usage the wrapped agent reports each turn, streams a running total as a `usage` event, and shows a live spend readout on the dashboard header. Pass `--max-cost ` to stop a run once it has spent that much: the current turn finishes, then the run stops cleanly (not a failure). Useful for long autopilot runs where you only review the result at the end. diff --git a/.changeset/ux-preset-472.md b/.changeset/ux-preset-472.md deleted file mode 100644 index 93fbc24..0000000 --- a/.changeset/ux-preset-472.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@gemstack/framework": minor ---- - -Add the [UX] preset (#472): a direct, interactive usability review of a target (defaults to `this PR`), shipped alongside [Research], [Readability], [Maintainability], and [Security audit]. It enumerates every finding as a categorized, reference-numbered list of choices via `showChoices()`, stops for the user to accept proposals, then works on the accepted ones. Available as a dashboard Start-a-run button and exported as `renderUxPrompt`. diff --git a/examples/framework-demo/CHANGELOG.md b/examples/framework-demo/CHANGELOG.md index efbf2b2..af6c12e 100644 --- a/examples/framework-demo/CHANGELOG.md +++ b/examples/framework-demo/CHANGELOG.md @@ -1,5 +1,89 @@ # @gemstack/example-framework-demo +## 0.0.7 + +### Patch Changes + +- Updated dependencies [0faa297] +- Updated dependencies [40491ba] +- Updated dependencies [6721c0f] +- Updated dependencies [8c576df] +- Updated dependencies [418a85b] +- Updated dependencies [4788a22] +- Updated dependencies [9e71fc8] +- Updated dependencies [7a94b48] +- Updated dependencies [016fb8d] +- Updated dependencies [87d67c8] +- Updated dependencies [f61a367] +- Updated dependencies [7ca71be] +- Updated dependencies [1dbc02a] +- Updated dependencies [f82e220] +- Updated dependencies [18de94b] +- Updated dependencies [27f522a] +- Updated dependencies [900efbb] +- Updated dependencies [4ed510f] +- Updated dependencies [a345a83] +- Updated dependencies [63b2a73] +- Updated dependencies [48aba07] +- Updated dependencies [3091bc2] +- Updated dependencies [dabdf0f] +- Updated dependencies [c26159d] +- Updated dependencies [8cbff44] +- Updated dependencies [16e86c4] +- Updated dependencies [43d4f50] +- Updated dependencies [90c15bf] +- Updated dependencies [388f3ad] +- Updated dependencies [48f25cd] +- Updated dependencies [4e43d76] +- Updated dependencies [72fb351] +- Updated dependencies [ed25ab8] +- Updated dependencies [131f349] +- Updated dependencies [734da1a] +- Updated dependencies [c05a186] +- Updated dependencies [1f588aa] +- Updated dependencies [5882932] +- Updated dependencies [07f1756] +- Updated dependencies [eec009d] +- Updated dependencies [5d54b64] +- Updated dependencies [1f6a0d3] +- Updated dependencies [b183dc0] +- Updated dependencies [28fff61] +- Updated dependencies [4aaa00a] +- Updated dependencies [f0a024c] +- Updated dependencies [4746188] +- Updated dependencies [f496a54] +- Updated dependencies [e370b41] +- Updated dependencies [7e1ea76] +- Updated dependencies [5709703] +- Updated dependencies [21fe373] +- Updated dependencies [89cedff] +- Updated dependencies [721f539] +- Updated dependencies [d834af8] +- Updated dependencies [5108aea] +- Updated dependencies [32e9d3e] +- Updated dependencies [f736b55] +- Updated dependencies [1e1b4dc] +- Updated dependencies [632f0df] +- Updated dependencies [734da1a] +- Updated dependencies [98f44e2] +- Updated dependencies [aafbb55] +- Updated dependencies [43d7fa0] +- Updated dependencies [8910ed3] +- Updated dependencies [03ca1b0] +- Updated dependencies [34d3ec2] +- Updated dependencies [c72d155] +- Updated dependencies [5c83bc2] +- Updated dependencies [9345476] +- Updated dependencies [59e3707] +- Updated dependencies [6b561fc] +- Updated dependencies [d1202dc] +- Updated dependencies [e4b518a] +- Updated dependencies [bc3586b] +- Updated dependencies [7db5a9c] +- Updated dependencies [5417558] + - @gemstack/framework@0.9.0 + - @gemstack/ai-autopilot@0.9.1 + ## 0.0.6 ### Patch Changes diff --git a/examples/framework-demo/package.json b/examples/framework-demo/package.json index fb4ba9c..34fa323 100644 --- a/examples/framework-demo/package.json +++ b/examples/framework-demo/package.json @@ -1,6 +1,6 @@ { "name": "@gemstack/example-framework-demo", - "version": "0.0.6", + "version": "0.0.7", "private": true, "description": "Showable end-to-end demo of @gemstack/framework: one prompt → scope → architect → build → full-fledged loop → deploy → a real running app, offline and deterministic via the fake driver.", "type": "module", diff --git a/examples/framework-discovery-demo/CHANGELOG.md b/examples/framework-discovery-demo/CHANGELOG.md index f67cc31..3e99be6 100644 --- a/examples/framework-discovery-demo/CHANGELOG.md +++ b/examples/framework-discovery-demo/CHANGELOG.md @@ -1,5 +1,89 @@ # @gemstack/example-framework-discovery +## 0.0.7 + +### Patch Changes + +- Updated dependencies [0faa297] +- Updated dependencies [40491ba] +- Updated dependencies [6721c0f] +- Updated dependencies [8c576df] +- Updated dependencies [418a85b] +- Updated dependencies [4788a22] +- Updated dependencies [9e71fc8] +- Updated dependencies [7a94b48] +- Updated dependencies [016fb8d] +- Updated dependencies [87d67c8] +- Updated dependencies [f61a367] +- Updated dependencies [7ca71be] +- Updated dependencies [1dbc02a] +- Updated dependencies [f82e220] +- Updated dependencies [18de94b] +- Updated dependencies [27f522a] +- Updated dependencies [900efbb] +- Updated dependencies [4ed510f] +- Updated dependencies [a345a83] +- Updated dependencies [63b2a73] +- Updated dependencies [48aba07] +- Updated dependencies [3091bc2] +- Updated dependencies [dabdf0f] +- Updated dependencies [c26159d] +- Updated dependencies [8cbff44] +- Updated dependencies [16e86c4] +- Updated dependencies [43d4f50] +- Updated dependencies [90c15bf] +- Updated dependencies [388f3ad] +- Updated dependencies [48f25cd] +- Updated dependencies [4e43d76] +- Updated dependencies [72fb351] +- Updated dependencies [ed25ab8] +- Updated dependencies [131f349] +- Updated dependencies [734da1a] +- Updated dependencies [c05a186] +- Updated dependencies [1f588aa] +- Updated dependencies [5882932] +- Updated dependencies [07f1756] +- Updated dependencies [eec009d] +- Updated dependencies [5d54b64] +- Updated dependencies [1f6a0d3] +- Updated dependencies [b183dc0] +- Updated dependencies [28fff61] +- Updated dependencies [4aaa00a] +- Updated dependencies [f0a024c] +- Updated dependencies [4746188] +- Updated dependencies [f496a54] +- Updated dependencies [e370b41] +- Updated dependencies [7e1ea76] +- Updated dependencies [5709703] +- Updated dependencies [21fe373] +- Updated dependencies [89cedff] +- Updated dependencies [721f539] +- Updated dependencies [d834af8] +- Updated dependencies [5108aea] +- Updated dependencies [32e9d3e] +- Updated dependencies [f736b55] +- Updated dependencies [1e1b4dc] +- Updated dependencies [632f0df] +- Updated dependencies [734da1a] +- Updated dependencies [98f44e2] +- Updated dependencies [aafbb55] +- Updated dependencies [43d7fa0] +- Updated dependencies [8910ed3] +- Updated dependencies [03ca1b0] +- Updated dependencies [34d3ec2] +- Updated dependencies [c72d155] +- Updated dependencies [5c83bc2] +- Updated dependencies [9345476] +- Updated dependencies [59e3707] +- Updated dependencies [6b561fc] +- Updated dependencies [d1202dc] +- Updated dependencies [e4b518a] +- Updated dependencies [bc3586b] +- Updated dependencies [7db5a9c] +- Updated dependencies [5417558] + - @gemstack/framework@0.9.0 + - @gemstack/ai-autopilot@0.9.1 + ## 0.0.6 ### Patch Changes diff --git a/examples/framework-discovery-demo/package.json b/examples/framework-discovery-demo/package.json index 5698250..333442a 100644 --- a/examples/framework-discovery-demo/package.json +++ b/examples/framework-discovery-demo/package.json @@ -1,6 +1,6 @@ { "name": "@gemstack/example-framework-discovery", - "version": "0.0.6", + "version": "0.0.7", "private": true, "description": "End-to-end proof of The Framework's extension SPI (#190): this project depends on the third-party `framework-hello` package, and the CLI discovers, registers, and composes it into the agent frame - offline and deterministic via the fake driver.", "type": "module", diff --git a/packages/ai-autopilot/CHANGELOG.md b/packages/ai-autopilot/CHANGELOG.md index 2f4d0c2..4c5a34e 100644 --- a/packages/ai-autopilot/CHANGELOG.md +++ b/packages/ai-autopilot/CHANGELOG.md @@ -1,5 +1,13 @@ # @gemstack/ai-autopilot +## 0.9.1 + +### Patch Changes + +- 734da1a: fix(ai-autopilot): EventStream iterators are now cancellable + + A consumer's async iterator gained a `return()` that drops its waiter from the stream and settles any pending `next()`. Previously a consumer that stopped iterating (e.g. a disconnected SSE client) left its waiter registered until the next `push`/`close`, so many short-lived consumers on an idle stream leaked. Live iteration and history replay are unchanged. + ## 0.9.0 ### Minor Changes diff --git a/packages/ai-autopilot/package.json b/packages/ai-autopilot/package.json index 66e6d3a..e9140e5 100644 --- a/packages/ai-autopilot/package.json +++ b/packages/ai-autopilot/package.json @@ -1,6 +1,6 @@ { "name": "@gemstack/ai-autopilot", - "version": "0.9.0", + "version": "0.9.1", "description": "Orchestration for @gemstack/ai-sdk agents: a Supervisor that plans, dispatches subagents (bounded concurrency + budget guardrails), and synthesizes the result.", "keywords": [ "ai", diff --git a/packages/framework-dashboard/CHANGELOG.md b/packages/framework-dashboard/CHANGELOG.md new file mode 100644 index 0000000..bfcf267 --- /dev/null +++ b/packages/framework-dashboard/CHANGELOG.md @@ -0,0 +1,83 @@ +# @gemstack/framework-dashboard + +## 0.0.1 + +### Patch Changes + +- Updated dependencies [0faa297] +- Updated dependencies [40491ba] +- Updated dependencies [6721c0f] +- Updated dependencies [8c576df] +- Updated dependencies [418a85b] +- Updated dependencies [4788a22] +- Updated dependencies [9e71fc8] +- Updated dependencies [7a94b48] +- Updated dependencies [016fb8d] +- Updated dependencies [87d67c8] +- Updated dependencies [f61a367] +- Updated dependencies [7ca71be] +- Updated dependencies [1dbc02a] +- Updated dependencies [f82e220] +- Updated dependencies [18de94b] +- Updated dependencies [27f522a] +- Updated dependencies [900efbb] +- Updated dependencies [4ed510f] +- Updated dependencies [a345a83] +- Updated dependencies [63b2a73] +- Updated dependencies [48aba07] +- Updated dependencies [3091bc2] +- Updated dependencies [dabdf0f] +- Updated dependencies [c26159d] +- Updated dependencies [8cbff44] +- Updated dependencies [16e86c4] +- Updated dependencies [43d4f50] +- Updated dependencies [90c15bf] +- Updated dependencies [388f3ad] +- Updated dependencies [48f25cd] +- Updated dependencies [4e43d76] +- Updated dependencies [72fb351] +- Updated dependencies [ed25ab8] +- Updated dependencies [131f349] +- Updated dependencies [c05a186] +- Updated dependencies [1f588aa] +- Updated dependencies [5882932] +- Updated dependencies [07f1756] +- Updated dependencies [eec009d] +- Updated dependencies [5d54b64] +- Updated dependencies [1f6a0d3] +- Updated dependencies [b183dc0] +- Updated dependencies [28fff61] +- Updated dependencies [4aaa00a] +- Updated dependencies [f0a024c] +- Updated dependencies [4746188] +- Updated dependencies [f496a54] +- Updated dependencies [e370b41] +- Updated dependencies [7e1ea76] +- Updated dependencies [5709703] +- Updated dependencies [21fe373] +- Updated dependencies [89cedff] +- Updated dependencies [721f539] +- Updated dependencies [d834af8] +- Updated dependencies [5108aea] +- Updated dependencies [32e9d3e] +- Updated dependencies [f736b55] +- Updated dependencies [1e1b4dc] +- Updated dependencies [632f0df] +- Updated dependencies [734da1a] +- Updated dependencies [98f44e2] +- Updated dependencies [aafbb55] +- Updated dependencies [43d7fa0] +- Updated dependencies [8910ed3] +- Updated dependencies [03ca1b0] +- Updated dependencies [34d3ec2] +- Updated dependencies [c72d155] +- Updated dependencies [5c83bc2] +- Updated dependencies [9345476] +- Updated dependencies [59e3707] +- Updated dependencies [6b561fc] +- Updated dependencies [d1202dc] +- Updated dependencies [e4b518a] +- Updated dependencies [bc3586b] +- Updated dependencies [7db5a9c] +- Updated dependencies [5417558] + - @gemstack/framework@0.9.0 diff --git a/packages/framework-dashboard/package.json b/packages/framework-dashboard/package.json index 04cb41a..45f1738 100644 --- a/packages/framework-dashboard/package.json +++ b/packages/framework-dashboard/package.json @@ -1,6 +1,6 @@ { "name": "@gemstack/framework-dashboard", - "version": "0.0.0", + "version": "0.0.1", "private": true, "description": "The Framework dashboard (spike): Vike + React + shadcn + Telefunc, a projection of the same .the-framework files the daemon writes (#405/#406).", "license": "MIT", diff --git a/packages/framework/CHANGELOG.md b/packages/framework/CHANGELOG.md index e12c167..3f099db 100644 --- a/packages/framework/CHANGELOG.md +++ b/packages/framework/CHANGELOG.md @@ -1,5 +1,139 @@ # @gemstack/framework +## 0.9.0 + +### Minor Changes + +- 0faa297: Add the "Add project(s)" install flow to the dashboard. A `POST /api/projects` (guarded like the other state-changing routes) installs The Framework into a repo, or every git repo directly under a folder, then registers each so it shows up in the Projects list; the daemon wires it to install-core. The Projects sidebar gains an "Add" control with a small path form (single repo or "folder of repos"), shown only when the server enables adding. Also fixes `enumerateGitRepos` to detect repo roots via `git rev-parse --show-prefix` instead of comparing `--show-toplevel` to the path, which failed across a symlink (e.g. macOS `/var` -> `/private/var`) and returned no repos. +- 418a85b: Add bootstrap mode (`--bootstrap`, and `StartRunOptions.bootstrap` for the dashboard): starting a brand-new project from an empty directory. It prepends a forceful preamble above the built-in #326 prompt so the first turn stops for a plan (ranked interpretations or a PLAN file) instead of charging ahead and scaffolding code. The #326 template is left byte-identical; the preamble only raises its "Unclear scope" / "Large scope" rules above Claude Code's default decisiveness, which otherwise overrides them on the append path (#297, #448). +- 4788a22: Add a "Browser" toggle to the dashboard Start form so `--browser` (give the agent a real browser via chrome-devtools-mcp, #452) is reachable from daemon/dashboard-started runs, not just the CLI. Mirrors the Post-merge cleanup pref: a `browser` preference flows to `StartRunOptions.browser` and on to the `--browser` flag. +- 9e71fc8: Add `--browser`: give the agent a real browser during the run via chrome-devtools-mcp. When set, the driver writes a temp `--mcp-config` wiring `chrome-devtools-mcp`, so the agent can navigate pages, read console + network output, inspect the DOM, and screenshot while it works instead of flying blind on frontend changes. Off by default; host-side only (no runner change), and the MCP servers merge with the user's own rather than replacing them. The `ClaudeCodeDriver` gains an `mcpServers` option backing this. +- 016fb8d: Bare `framework` now tells you whether the CLI is up to date (#312): after the version footer it checks npm's `dist-tags.latest` (2.5s cap) and prints "Up to date" or "Update available: vX (you have vY). Run: npm i -g @gemstack/framework". Offline or on any fetch failure it prints nothing. Display only; no auto-update. +- 87d67c8: Turn-boundary gate for plan approval (`showMarkdown()` + AWAIT): a build turn that ends with an `await-confirmation` block (the #326 large-scope PLAN flow) now pauses the run with a green Approve and a red Decline button on the dashboard. Approve resumes the build; Decline logs "Plan declined, awaiting user instructions." and stops the run cleanly (like the budget cap), so nothing reviews or improves work the user just declined. Headless runs auto-approve, keeping programmatic runs deterministic. Try it offline with `FRAMEWORK_FAKE_AWAIT=confirmation`. +- f61a367: Add the context selector and trust-on-add to the dashboard (#439, part of #314). The Start form gains a "Context" picker — tick the registered repos to focus the agent on, and each becomes one `Context: ` line in the run's system prompt (the agent can still reach every repo; this just narrows where it looks). Threaded through as a repeatable `--context ` CLI flag and `StartRunOptions.context`. Adding a project now asks "do you trust this repository?" first, warning about prompt-injection risk before the agent is given read access. + + Also hardens the daemon's Telefunc mount: a bare `GET /_telefunc` (which a browser tab issues on reconnect) made telefunc throw an unhandled rejection that crashed the daemon; the mount now catches it and returns 400. + +- 7ca71be: Bare `framework` now runs the dashboard server in the foreground (#456): Ctrl+C stops it, and the server's logs and any errors it throws are visible in the terminal. `framework --daemon` does what bare `framework` used to do, running the dashboard in the background (detached) and returning after printing the convenience commands. If a background daemon is already running, bare `framework` reports its URL and defers instead of fighting for the port. +- 1dbc02a: The daemon can now serve the new Vike + Telefunc dashboard bundle (#405). Opt in with `FRAMEWORK_DASHBOARD=next` (serves the prerendered SPA at `/`, with the legacy `page.ts` at `/legacy`) or `FRAMEWORK_DASHBOARD=legacy` (mounts the Telefunc surface at `/_telefunc` while `page.ts` stays at `/`). Unset keeps today's behavior exactly. The dashboard's read + steer RPCs and the live-event Channel are served in-process at `/_telefunc` (same-origin guarded), backed by a new `@gemstack/framework/dashboard-rpc` subpath; `starting` a run over Telefunc lands next. +- f82e220: Restore the dashboard actions on the new dashboard (#433): the Start form now carries the Global options (autopilot, technical, vanilla, eco) and the run presets (Research, Readability, Maintainability), the interactive choice gate auto-accepts the recommended pick on an autopilot countdown, a Deploy card shows the chosen render + target, and projects can be added from the Projects sidebar over a new `sendAddProject` telefunction. Adds a browser-safe `deployPlan` projection and the preset builders to `@gemstack/framework/client`. +- 18de94b: Let the agent push ad-hoc markdown views into the dashboard right rail. A `show-markdown` block in a turn (non-blocking, unlike a choice gate) becomes a `view` event that renders as a first-class Views tab in the right rail, with a sticky top-nav to jump between views. Re-showing the same title updates that view in place. +- 27f522a: feat(framework): opt-in browser notifications on the dashboard for run-end and choice gates (#317) + + The localhost dashboard can now notify you when a run finishes (or fails/stops) and when a run reaches a `` gate that needs your input (e.g. a PLAN.md approval). Opt in via the header bell; it only nudges when the dashboard tab is backgrounded, so a run you are watching stays quiet. + +- 4ed510f: Dashboard control channel: the persistent daemon dashboard can now steer any run in its workspace. Its Stop button and choice picks append to `.framework/control.jsonl`; the run tails the file and aborts or resolves its parked gate. Gates now pause whenever a workspace daemon is live, not only when the run owns its own dashboard; headless behavior without a daemon is unchanged. Also fixes the fresh-workspace daemon startup: bare `framework` in a project with no `.framework/` yet used to fail and leave a zombie server on the port. +- a345a83: The new Vike + Telefunc dashboard (#405) is now what the daemon serves by default at `/`; the legacy `page.ts` dashboard moves to `/legacy`. Set `FRAMEWORK_DASHBOARD=legacy` to keep `page.ts` at `/` (the escape hatch), and if a build ever ships without the prerendered bundle the daemon falls back to `page.ts` automatically. The `release` flow now runs `bundle:dashboard` so the published package ships the dashboard assets. +- 63b2a73: feat(framework): document sidebar on the dashboard, rendering the run's PLAN.md / TODO.md (#319) + + The localhost dashboard now surfaces the `PLAN.md` and `TODO.md` the agent writes at the workspace root (via the anti-lazy-pill) in a right sidebar, rendered as markdown with a sticky tab nav to jump between them. A new `GET /api/docs` endpoint reads the surfaced docs (fixed filenames, gated on the workspace `cwd` like `/api/runs`); the sidebar polls it so a plan written mid-run appears, and stays hidden when there are no docs. + +- 3091bc2: Add an Overview section to the top of the dashboard's first sidebar. It gives a cross-project glance over a new `onOverview` Telefunc read: what the agent is running right now (from each project's live run meta), the total open TODO count across all projects, and the most recently active projects. Clicking any of them selects the project. +- dabdf0f: Default dashboard port is now 4200 (was 4477): easier to remember. Pass `--port` to override. +- c26159d: Persist the dashboard's Global options (Autopilot, Technical, Vanilla, Eco) in the same `the-framework.json` as the project list, read and written daemon-side over Telefunc (`onPreferences` / `savePreferences`), so they survive restarts without localStorage (#410). The registry file becomes an object `{ projects, preferences }`; older bare-array files still read and are migrated on the next write. +- 16e86c4: Add a Project log panel to the dashboard (#384). It surfaces the committed `.the-framework/LOGS.md` history (#378/#379) for the workspace: every loop/prompt/build run with its title, status, kind, session link, and a loop's constituent prompts, newest-first. Served by a new `GET /api/logs` endpoint and refreshed on load, on run-end, and on an interval. All fields are escaped and the session link is passed through the page's safe-URL guard, since the log is agent-authored. +- 43d4f50: Add a cross-project Queue section to the dashboard's first sidebar. It aggregates the open `TODO.md` items across every registered project over a new `onQueue` Telefunc read, so the whole backlog is visible in one place instead of per-selected-project only. Clicking a project in the queue selects it. +- 90c15bf: Export `readDocs` + the `WorkspaceDoc` type from the package root, so a separate dashboard can read the same surfaced PLAN/TODO docs the daemon serves (#405 phase 2). +- 388f3ad: feat(framework): browse a project's run history in the dashboard (#303) + + The dashboard now has a left sidebar listing a project's past runs (intent, status, session link); clicking one replays that run's projection in the main view, and "Back to live" returns to the current run. Each finished run is archived under `.framework/runs/.jsonl` + `.framework/runs/.json` (a crash that skips the final flush is archived on the next run), and served over `GET /api/runs` and `GET /api/runs/`. Single project only. Closes #303. + +- 48f25cd: Add event-stream projections for the dashboard's run overview: `architectPlan`, `decisionLedger`, `loopStatus`, and `sessionInfo` derive the chosen stack + rationale, the decisions ledger, the production-grade loop status, and the live session from a `FrameworkEvent[]`. They plus `formatFrameworkEvent` are re-exported from a new browser-safe `@gemstack/framework/client` subpath (no Node imports), so the dashboard renders the rich run view — the stack/PROS-CONS card, decisions, loop status, and a human-readable event log instead of raw JSON — across the live view, past-run replay, and the relay watch view. +- 4e43d76: The new dashboard can now start a run over Telefunc (#405). A `sendStart` telefunction reaches the daemon's own `startRun` closure through the Telefunc request context, so it runs in-process with the one-run-per-project busy guard intact (a second start returns `busy`). Served at `/_telefunc` alongside the read + steer RPCs, same-origin guarded. +- 72fb351: Start runs from the daemon dashboard (#345): a prompt textarea + `POST /api/start` that spawns `framework "" --no-dashboard` as a detached child, with a one-run-at-a-time guard. The started run streams into the page via the tailed event log and is steerable (gates + Stop) through the control channel. +- 1f588aa: Add `framework maintain` (#298): a background maintenance sweep. It walks the registered repos, and for each that has grown commits since its last review it runs the maintainability loop on them (`framework prompt`, budget-capped by `--max-cost`, bounded by `--max-repos`). A first-seen repo is baselined (recorded, not reviewed retroactively); per-repo review state lives in `.the-framework/maintenance.json`. `--dry-run` previews the plan. Also exports the maintenance API (`assessRepo`, `planMaintenanceSweep`, `maintainSweep`, review state helpers). +- 5882932: feat(framework): inject a system prompt into every prompt (anti-lazy-pill + SYSTEM.md) + + Every run is now framed with a built-in system prompt: the validated anti-lazy-pill (#297), which turns unclear scope into a ranked list, a large scope into a `PLAN.md`, and a very large one into a `TODO.md` backlog, so the agent builds a real backend and declares what it descopes instead of silently faking it. Drop a `SYSTEM.md` at the workspace root to add project-specific instructions on top, or set `antiLazyPill: false` in `the-framework.yml` to remove the built-in default. Closes #301. + +- eec009d: Thread the #314 Global options through the run engine (#370). `POST /api/start` now carries an `options` object which the daemon turns into CLI flags: `--vanilla` removes the built-in #326 system prompt entirely (raw Claude Code), and `--eco-auto-planning` / `--eco-auto-research` / `--eco-auto-maintenance` drop the matching #326 sections to save tokens (Autopilot and Technical keep mapping to modes). `system-prompt.ts` drops the Eco sections at render, so the #343 Prompts panel reflects the toggles live; the #326 template stays byte-identical. The dashboard panel that drives these lands separately (#371); all fields default off, so today's behavior is unchanged. +- 5d54b64: Add the #314 Global options panel to the dashboard (#371). Beside the Start box the daemon dashboard now shows persistent toggles: Autopilot (auto-accept, sharing its key with the choice-panel toggle so the two stay in lockstep), Technical control, Vanilla (remove all system prompts, fully transparent), and Eco with Auto planning / Auto research / Auto maintenance to trim the built-in prompt. Each persists in localStorage and rides along in the `POST /api/start` body, so flipping a toggle changes what the run gets (and, with the engine plumbing in #370, what the #343 Prompts panel shows). Vanilla disables Eco, since a removed prompt has nothing left to trim. +- 1f6a0d3: feat(framework): interactive plan-approval choice + autopilot in the dashboard (#304) + + The run now pauses at a plan-approval gate right after the architect decides the stack (the AWAIT point of the plan-then-AWAIT flow): the dashboard shows a "Your call" panel with "Proceed" plus each architect alternative as "Use X instead". Accept with the button or Ctrl+Enter, or leave the `[x] autopilot` countdown auto-accept the recommended plan after 10s (moving the mouse cancels it). Picking an alternative re-architects the run around it. New `requestChoice` option on `runFramework`, `choice` / `choice-resolved` events, and a `POST /choice` dashboard route; a headless run with no handler auto-accepts the recommended plan, so nothing else changes. Closes #304. + +- b183dc0: Add the `setSessionName()` and `setReadyForMerge()` lifecycle signals (#326). Both are non-blocking turn-boundary signals, the same shape as the existing `show-markdown` view: the agent emits a fenced `set-session-name` / `ready-for-merge` block and keeps working, and the framework records it and reflects it in the dashboard. `setSessionName()` labels the run with the `[a-z0-9-]` slug it chose (also its `the-framework/` branch); `setReadyForMerge()` flips the run's status from building to ready-for-review. The dashboard shows the session name and a status dot (amber while building, green once ready) in both the run overview and the cross-project "working now" list. This is the signal the post-merge quality suite will hang off. +- 28fff61: New [Maintainability] preset button on the dashboard (#361): prefills the deliberately minimal refactor-for-future-changes prompt ("look for maintainability red flags, and fix them") into the start textarea for review or editing; Start runs the text verbatim as a direct prompt run. The one blank, ``, defaults to `this PR`. +- 4aaa00a: Make the dashboard multi-project on the read side: `GET /api/projects` lists the registered projects (from the registry) with a per-project summary (name, activated, last activity), and `?project=` on `/api/logs`, `/api/runs`, `/api/runs/`, and `/api/docs` reads that project's data (an absent id keeps the daemon's own workspace, single-project back-compat). The daemon auto-registers its own workspace on boot when it is activated, so the Projects list is populated for the common single-project case. Live event streaming and per-project run start/stop stay single-project for now. Adds `ProjectSummary` / `ProjectsProvider` / `summarizeProject` / `defaultProjectsProvider`. +- f0a024c: Add the install-core module: `installProject(cwd)` activates a repo for The Framework by creating the `.the-framework/` marker with a seeded `LOGS.md`, committing any pre-existing dirty changes first (`[The Framework] uncommitted changes`) so the install commit (`[The Framework] install The Framework`) is clean; an already-activated repo is a no-op. Also `enumerateGitRepos(dir)` lists the immediate child directories that are their own git repo roots (for the "add a directory of repos" flow). Pure core over the existing `GitRunner` + `StoreFs` seams; any git failure surfaces as a value, never a throw. No daemon or UI wiring yet. +- 4746188: Add the multi-project registry module: reads and writes the list of projects The Framework is installed into, as a small `{id, path, addedAt}` JSON index under the user's config dir. Exposes `projectId`, `registryPath`, `listProjects`, `addProject`, `removeProject`, and an injectable `RegistryFs` seam with a `nodeRegistryFs()` adapter. No daemon or UI wiring yet. +- f496a54: Add a multi-select gate (`showMultiSelect()`): a dashboard checklist with pre-checked defaults that pauses the run and resolves to the selected subset. Built on the existing single-select choice gate (same panel and POST-back resolver), exposed as `requestMultiSelect()`; a headless run auto-accepts the default set. This is the primitive the [Research] preset uses to let the user pick which problems to deep-dive. +- e370b41: feat(framework): turn an agent's showMultiSelect()+AWAIT into a live checklist gate (#339) + + The multi twin of the single-select turn-boundary gate (#337). When a build turn ends on an `await-multiselect` block, the framework shows a checklist on the dashboard (via `requestMultiSelect`, with the agent-marked defaults pre-checked), waits for the selection, and re-prompts the agent to continue from it. This is what the research preset needs to let the user pick which problems to deep-dive. Same safety as #337: a no-op when headless and when the agent just finishes. + +- 7e1ea76: Per-project daemon runs + one daemon per machine (#393). Dashboard-started runs, Stop, and choice picks now carry the viewed project id, so the daemon spawns each run with that project's `--cwd`, steers it through that project's own control log, and guards one run per project. Daemon liveness moved from a per-workspace `.the-framework/daemon.json` to a single global file beside the registry (`$XDG_CONFIG_HOME/the-framework-daemon.json`), so `framework` and `framework stop` in any repo find the same daemon. Per-project live event streaming is folded in with the dashboard rebuild (#405). +- 5709703: Serve the new Vike + Telefunc dashboard for per-run foreground runs and `--resume`, not just the daemon. `framework ""` and `framework --resume` now serve the rebuilt dashboard in single-project mode, scoped to that run's workspace without touching the global registry, and the live run steers over its own `.the-framework/control.jsonl` even with no daemon running. Falls back to the legacy `page.ts` when the bundle is absent or `--no-persist` is set. Adds `singleProjectProvider` and `resolveDashboardBundle` to the public surface. +- 21fe373: feat(framework): persistent background dashboard daemon (#302) + + Bare `framework` now ensures a long-lived dashboard process for the workspace and prints its URL plus the convenience commands; `framework stop` shuts it down. The dashboard is a projection of `.framework/events.jsonl`: the detached daemon tails the log and pushes each new event to connected browsers, so it outlives any single run. The tailer also detects an in-place truncation when a fresh run rewrites the log to the same byte length (size unchanged but mtime advanced), and the daemon spawn refuses to re-exec a test entry so a `node --test` run can never fork-bomb itself. + +- 89cedff: Add the post-merge quality suite (#326): when a run signals `setReadyForMerge()`, optionally fire the maintainability, readability, and security-audit passes over the same workspace. Enabled per run by the new `--post-merge` CLI flag, or from the dashboard's Global options via a "Post-merge cleanup" toggle (persisted as the `postMergeQuality` preference, mapped to `--post-merge` on the spawned run). The three passes run **sequentially** — they edit and commit the same git tree, so concurrent writers would race on the index lock; worktree-isolated parallelism is a follow-up. Each pass is a plain `framework prompt` child carrying no `--post-merge`, so a quality pass never triggers its own suite. Off by default. +- 721f539: Add preset-prompt param substitution (``), the foundation for prompt-preset buttons. A preset prompt template can carry `` placeholders substituted from supplied values or declared defaults; unfilled params are surfaced so a caller can ask the user to fill the blanks. +- d834af8: Dashboard presets only prefill the textarea (#353): the [Research] button now loads the full rendered preset prompt for review and editing, and nothing runs until Start / Ctrl+Enter. The edited text is sent verbatim via a new `prompt` start kind and `framework prompt ` subcommand (the direct path: gates honored, no build pipeline). Clearing the box reverts Start to a normal build run. +- 5108aea: Add the per-project second sidebar and main view. The second sidebar now shows the selected project's loops/prompts (its `.the-framework/LOGS.md`, scoped via `?project=`) with its Runs archive below it, both following the selection. The main view shows the selected or latest loop/prompt claude.ai/code-style (kind, title, status, session link, and a loop's constituent prompts); clicking a loop in the sidebar opens it. On load the most recently active project is auto-selected, so the view is populated immediately. +- 32e9d3e: Add the Projects sidebar to the dashboard: a leftmost nav with Overview (project count plus the most recently active projects), Projects (every registered project with an activation dot and last-activity, from `/api/projects`), and Queue (the open TODO items aggregated across all projects). Selecting a project re-points the project log to `?project=`. The per-project second sidebar and main view come next. +- f736b55: New [Readability] preset button on the dashboard (#360): prefills Rom's refactor-for-human-readers prompt (architectural seams, linearity/altitude pass, exhaustive per-function rating lists, one commit per refactor) into the start textarea for review or editing; Start runs the text verbatim as a direct prompt run. The one blank, ``, defaults to `this PR`. +- 632f0df: Serve the new Vike + Telefunc dashboard from the run relay (`--share`), in a read-only watch mode. The relay now serves the prerendered SPA and streams events over the same Telefunc `onEvents` Channel the daemon uses, sourced from its in-memory run instead of a file. Only the live event stream is exposed (an empty projects provider neutralizes the file/registry RPCs on the public host, and no run can be started or steered). The shareable viewer URL moves from `/r/:id/` to `/?run=:id` (old links redirect); ingest stays at `/r/:id/publish`. This removes the relay's dependency on the legacy `page.ts`. Adds `makeTelefuncMount`, `serveClientBundle`, `emptyProjectsProvider`, and the `EventsSource` type to the public surface. +- 98f44e2: The [Research] preset (#331): `framework research [what]` and a [Research] button on the daemon dashboard run Rom's problem-variability review as a direct prompt via the new `runPrompt()` path, which honors await gates (showChoices/showMultiSelect) but skips the scope/architect/build scaffolding. The "what" defaults to `this PR`. +- aafbb55: Retire the legacy `page.ts` dashboard and its HTTP routes (#426, part 3). Both consumers are now on the new Vike + Telefunc dashboard (the daemon default, per-run/resume, and the relay), so `startDashboard` now serves only the prerendered SPA plus the `/_telefunc` mount (RPCs + the live-event Channel). Removed: the `dashboardHtml` and `parseStartOptions` exports, the in-process `Dashboard.push`/`Dashboard.stream` (the SPA reads `events.jsonl` over the Channel and steers over `control.jsonl`), and the now-unused `DashboardOptions` fields (`onStop`, `onChoice`, `cwd`, `dashboardMode`) and the `FRAMEWORK_DASHBOARD=legacy` escape hatch. A `--no-persist` foreground run (or an install missing the built bundle) now runs headless rather than falling back to the old page. +- 43d7fa0: Add the [Security audit] preset (#461): an exhaustive, direct security pass over a target (defaults to `this PR`), shipped alongside [Research], [Readability], and [Maintainability]. It lists every aspect considered with a per-aspect verdict and fixes each issue in its own commit. Available as a dashboard Start-a-run button and exported as `renderSecurityAuditPrompt`. It is also the third of the post-merge quality prompts #326 fires on `setReadyForMerge()`. +- 8910ed3: Show the exact prompt sent to the agent each turn. The run feed used to render a turn's start as just `> prompt sent` and drop the text; now the terminal/log formatter shows a one-line preview, and the dashboard event feed renders the full prompt in a collapsible block (click to expand) for both live runs and replays. The prompt was already carried on the driver `start` event and persisted, so this is a display-only change that surfaces it. +- 03ca1b0: Show the real prompts on the dashboard (#343). The framework now emits the exact system prompt it runs the agent under, the #326 block plus any persona / skill / memory framing, as a `system-prompt` event at session start (both the direct-prompt path and the full build path). A new "Prompts sent to Claude Code" panel renders it alongside each turn's user prompt (harvested from the `driver` `start` events already in the stream), so the normally-hidden prompt is fully visible for transparency. Prompt text renders as inert text, never markup. Read-only; nothing is gated on it. +- 34d3ec2: feat(framework): extract a shared single-select gate primitive (`requestChoices`) (#335) + + The single-select choice gate (#304) is now a reusable `requestChoices({ id, title, options, recommended })` export, the twin of `requestMultiSelect` (#332): it emits the `choice` event, parks for the pick, and falls back to the recommended option if the run is headless or aborts. The plan-approval gate builds on it, and it is the primitive the system prompt's `showChoices()` and the research preset need. No behavior change for existing runs. + +- c72d155: Give the dashboard clear feedback when a run is started. A run is spawned detached, so there was a gap between clicking Start and the first event (and a failed launch produced nothing, so the page looked frozen). Now clicking Start shows an immediate "Starting your run..." banner; if no output arrives within ~8s it warns that the run may have failed to start; a run-launch/exit failure surfaces as an error banner; and a rejected Start (a run is already active) shows a clear "busy" banner instead of a tiny note. +- 5c83bc2: The built-in system prompt is now Rom's #326 text, verbatim, replacing the anti-lazy-pill it grew out of: unclear scope becomes a ranked `showChoices()` list, a large scope a `PLAN_.agent.md` to approve, a very large one also a `TODO_.agent.md` backlog, an alternatives pass rates problem "variability" before code is written, and edits to existing code stay minimal. The prompt is a template (#350): `${{ ... }}` JS fragments render against the run context, so `tf.params.autopilot` relaxes the maintenance stance on autopilot runs and `${{tf.prompt}}` carries the user prompt slot. New exports: `SYSTEM_PROMPT_TEMPLATE`, `renderSystemPrompt`, `renderTemplate`; the `ANTI_LAZY_PILL` export is gone (the `antiLazyPill` config key still toggles the built-in prompt). `--autopilot` now has an effect without a preset. +- 9345476: Record every finished run in the project log `.the-framework/LOGS.md` (#379). When a run ends, the CLI appends an entry with the intent/prompt title, the kind (build or prompt), the final status (done/stopped/failed), and the Claude Code session id and link. Best-effort, so a log write can never break a run. This is what makes the project DB (#378) fill itself; the run-history sidebar in #314 reads from it. +- 59e3707: New `.the-framework/LOGS.md` project-log module (#378): `appendLog`/`readLogs` keep a human-readable markdown log of every loop, prompt, and build in a project, with `renderLogEntry`/`parseLogs` as the pure core over the same StoreFs seam as the run store. Parsing is forgiving: a malformed entry is skipped, never thrown. Standalone for now; the run-lifecycle wiring and dashboard UI land in follow-up issues. +- 6b561fc: Add project repo helpers (#380): `isActivated()` checks the `.the-framework/` activation marker via an injectable `ProjectFs`, and `crawlRepoFiles()` lists every tracked + untracked (gitignore-honoring) file via `git ls-files -z` behind an injectable `GitRunner`. Both forgiving: any failure reads as not-activated / an empty list. Building blocks for the #314 sidebars. +- d1202dc: The backlog loop (#323): after the build settles, the run consumes the agent's own TODO backlog (`TODO_.agent.md`, or the flat `TODO.md`) one entry per turn until it is empty. When a dashboard can answer, the loop gates before each entry ("start the next item?"), so autopilot consumes the backlog unattended and autopilot-off pauses per item. Caps make it safe overnight: the budget/Stop signal ends any turn, `--max-todo-items` bounds the run (default 25), and two no-progress items stop the loop. `--no-todo-loop` opts out. +- e4b518a: feat(framework): turn an agent's showChoices()+AWAIT into a live gate at the turn boundary (#337) + + The system prompt tells the agent to `showChoices()` and `AWAIT` at unclear-scope / alternatives points, but until now only framework-emitted gates (the plan-approval gate, multi-select) could pause a run. Now when a build turn ends by asking the user, an `await-choices` block, the framework shows the choice on the dashboard, waits for the pick, and re-prompts the agent to continue from that decision. It is the agent-authored counterpart to the plan-approval gate: a no-op when headless and when the agent just finishes instead of asking, so existing runs are unchanged. + +- bc3586b: Keep everything in a single `.the-framework/` directory (#313). The transient run state (`events.jsonl`, `run.json`, `runs/`, `control.jsonl`, `daemon.json`) now lives in `.the-framework/` alongside the committed project log `LOGS.md`, instead of a separate `.framework/` directory. `install` seeds a `.the-framework/.gitignore` that ignores everything except `LOGS.md`, so the run state stays transient and only the log is committed. +- 7db5a9c: feat(framework): track agent spend and add a budget cap (#322) + + The framework now accumulates the token + cost usage the wrapped agent reports each turn, streams a running total as a `usage` event, and shows a live spend readout on the dashboard header. Pass `--max-cost ` to stop a run once it has spent that much: the current turn finishes, then the run stops cleanly (not a failure). Useful for long autopilot runs where you only review the result at the end. + +- 5417558: Add the [UX] preset (#472): a direct, interactive usability review of a target (defaults to `this PR`), shipped alongside [Research], [Readability], [Maintainability], and [Security audit]. It enumerates every finding as a categorized, reference-numbered list of choices via `showChoices()`, stops for the user to accept proposals, then works on the accepted ones. Available as a dashboard Start-a-run button and exported as `renderUxPrompt`. + +### Patch Changes + +- 40491ba: Architect turns now honor agent-authored await gates (#356): an architect (or re-architect) turn that stops to ask via `showChoices()` / `showMultiSelect()` resolves through the live dashboard gate and re-prompts with the answer, instead of the question being silently swallowed into a stub fallback plan at the plan-approval gate. Headless runs are unchanged. Bounded at 5 rounds, like the build gate. +- 6721c0f: Untangle the two "autopilot" concepts in the dashboard (#325): the countdown text now reads "Auto accept in 10s" (and "Auto accept canceled" / "Auto accept off"), so "autopilot" is left to mean the mode preset. The checkbox that arms the countdown is labeled "Autopilot", per Rom's call on the issue. +- 8c576df: Adding a project that isn't a git repo now initializes one for you instead of failing with `fatal: not a git repository`. `installProject` detects a non-repo folder and runs `git init` before its usual commit-and-install flow, so a plain directory can be added straight from the dashboard. The install result reports `initialized: true` when it did so. +- 7a94b48: Fix `framework --version` (and the bare-`framework` footer) reporting `0.0.0` instead of the real package version (#312). The version is now read from the package's own `package.json` at runtime, so it always matches what is installed. +- 900efbb: Center the dashboard's main grid in the content column. `main` had a `max-width: 1100px` cap but no horizontal centering, so on a wide window the panels hugged the left edge next to the runs sidebar. Add `margin: 0 auto` so the capped grid sits centered. +- 48aba07: Make the dashboard layout fill the viewport height. `#layout` only grew to its content height, so on a short page the runs-sidebar right border stopped partway down instead of reaching the bottom. Give `#layout` a `min-height: calc(100vh - 57px)` (matching the sidebar's existing header-height key) so the stretched sidebar runs full-height. +- 8cbff44: fix(framework): narrate the auto-preset routing turn so the dashboard is not blank at the start of a run (#310) + + A preset-less live run first does a real Claude routing turn to auto-select a domain preset. The dashboard was started only after that turn, so its first few seconds looked dead. The dashboard now starts before the routing turn and the turn narrates a log line into it. + +- ed25ab8: Keep the dashboard header and sidebar in view while scrolling. The header is now sticky at the top (with a background and z-index so content scrolls under it), and the app-running banner and the runs sidebar stick just below it. On a long page you no longer lose the title, stop button, and run list when you scroll down. +- 131f349: fix(framework): surface session-scoped PLAN/TODO docs in the dashboard sidebar (#323) + + The document sidebar now also surfaces the session-scoped `PLAN_.agent.md` / `TODO_.agent.md` files The Framework writes per run (#323/#326), not just flat `PLAN.md` / `TODO.md`. Flat files stay supported as a fallback for hand-written docs. Names are matched against the workspace root with a fixed slug pattern, so there is still no path traversal. + +- c05a186: Harden the dashboard against cross-site abuse and event-borne XSS. The state-changing dashboard routes (`/stop`, `/choice`, `/api/start`) now reject any request whose `Origin` is a foreign site, so a page on another origin can no longer drive the localhost dashboard into spawning or steering a run (a non-browser caller that sends no `Origin` is unaffected). The client render pipeline no longer trusts event strings: link URLs (session link, preview URL, run-history link) are scheme-checked so a `javascript:` URL collapses to `#`, and the HTML escaper now escapes quotes so a relay-published event can't break out of an attribute (e.g. a choice option id like `x" autofocus onfocus=...`). +- 07f1756: fix(framework): re-fire the plan-approval gate after picking an alternative (#324) + + Picking an alternative at the plan-approval gate re-architects the plan, and that fresh plan can differ a lot from the one you rejected. The gate now re-fires on the re-architected plan so you approve the plan you will actually build, not just the first one. Bounded to a few re-architect rounds so a run of alternative-picks can't loop forever. + +- 1e1b4dc: Store the multi-project registry as a single file, `.bashrc`-style: `$HOME/.the-framework.json` (or `$XDG_CONFIG_HOME/the-framework.json`) instead of a `projects.json` nested inside a `.the-framework/` directory (#390). +- 734da1a: fix(framework): harden the run relay and workspace sandbox against resource exhaustion + + - The relay now caps how many runs it holds in memory and evicts the least-recently-used one on overflow. Because it is unauthenticated, an anonymous request to `/r//…` could previously create per-run state that was never freed; run creation is now bounded (`maxRuns`, default 200). + - A disconnected SSE viewer now cancels its stream iterator, releasing its waiter immediately instead of lingering on the stream until the next event (which may never arrive for an idle run). + - `snapshotWorkspace` checks a file's size before reading it, so a large asset in the workspace is skipped without ever being loaded into memory during a `--sandbox docker` sync. + - `relayPublisher`'s POST has a timeout, so a relay that accepts a connection but never responds can no longer hang the CLI on exit (`flush()`). + +- Updated dependencies [734da1a] + - @gemstack/ai-autopilot@0.9.1 + ## 0.8.0 ### Minor Changes diff --git a/packages/framework/package.json b/packages/framework/package.json index 6d5fddc..3c3aab7 100644 --- a/packages/framework/package.json +++ b/packages/framework/package.json @@ -1,6 +1,6 @@ { "name": "@gemstack/framework", - "version": "0.8.0", + "version": "0.9.0", "description": "The (AI) Framework: turnkey, zero-config AI orchestration that wraps a coding-agent CLI (Claude Code) as a black box and takes you from an idea to a running app. Vite for AI.", "keywords": [ "ai",