release: v1.0.5 → main (production) - #2435
Merged
Merged
Conversation
feat(components): kit-change propagation — fan-out decision spine (#2277)
…write-through slice (#2277) The data the propagation fan-out reads: which projects use which kit. Mirrors the project-links store (#2253) end-to-end. Rust — `bsc component usage` (crates/bsc-component): - `usage.rs`: a flat edge store at ~/.base-studio-code/kit-usage.json — load/add/remove over (projectKey, kitId) edges, idempotent by a deterministic `usage_id` ("<projectKey>><kitId>"). - `bsc component usage list [--json] | add <projectKey> <kitId> | remove <id>` (a custom command, not per-record CRUD), registered in the component help. Frontend — the write-through cache: - `kitUsageBridge`: load/push/drop via `bsc component usage …` (null → keeps the cache when unreachable). - `kitUsageId` in propagation.ts — byte-identical to the Rust `usage_id` (one contract). - store `ComponentsSlice`: `kitUsage: KitConsumer[]` + `addKitUsage`/`removeKitUsage` (write-through) + `hydrateKitUsage`; hydrated on boot, persisted as a fast-first-paint cache. `kitUsage` is exactly the `KitConsumer[]` `planPropagation` (the #2291 spine) consumes — so the fan-out now has real consumer data. clippy + typecheck + lint clean; tests: Rust add/idempotent/reject/remove + help, frontend add/dedup/remove(by-id)/hydrate. Part of #2277 — follow-ups: recording the edge at planning (blueprint→kit), `bsc component set` emitting a classified change, and wiring the dispatch plan to the rails. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
feat(components): kit-usage consumer index — bsc component usage + write-through slice (#2277)
…nge + fan-out plan (#2277) Close the change→plan loop: editing a component now produces the propagation plan against the real consumer index. - `setComponent(component, changeOverride?)` — write-through the edit (upsert + `bsc component set`), and when it EDITS an existing component, emit a classified `KitChange` (the #2291 diff/classify), fan it out over `kitUsage` (the #2292 consumer index) via `planPropagation`, and queue the fresh dispatches. A brand-new component isn't a change; an author-declared class overrides the derived one. - `kitDispatches: Dispatch[]` — the pending fan-out (notify-only by default; issue/assign only for breaking + opted-in), deduped by (projectKey, change.id); `dismissKitDispatch` drains one. So: edit a component → additive is notify-only across consumers; a breaking edit queues an issue (dormant) / assign (live) for each opted-in consuming app. typecheck + lint clean; tests cover write-through, breaking→issue, additive→notify, new-component-no-change, dedup + dismiss. Part of #2277 — remaining: auto-record the edge at planning (blueprint→kit), and DELIVER the queued dispatches to the rails (issuer / bsc-issue+bsc-assign / a kit-update GitHub issue). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
feat(components): change origin — setComponent emits a classified change + fan-out plan (#2277)
…-store # Conflicts: # Cargo.toml # crates/bsc-agent/src/main.rs # crates/bsc-util/src/sidecars.rs
RUSTSEC-2026-0194/0195 fire on quick-xml 0.39.4, pulled in transitively via tauri -> plist 1.9.0 -> quick-xml. plist 1.9.0 (latest) pins `quick-xml = "^0.39.2"`; the fix lands in quick-xml >=0.41, an API-breaking bump plist can't take, so neither `cargo update` nor a `[patch]` reaches it without breaking the build. Both are DoS-only via untrusted XML, and plist only parses the app's own bundle Info.plist at build time (not runtime attacker input), so neither is reachable here. Add a scoped `.cargo/audit.toml` ignoring EXACTLY these two IDs, matching the workflow's existing non-blocking-transitive stance. Any other real advisory still fails the audit. Revisit when tauri/plist ship a quick-xml 0.41 bump. Closes #2173 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add SplitView to src/shared/ui/layouts/ — the standardized two-pane split page skeleton (flexing primary + fixed-size, drag-resizable secondary + optional toolbar), matching the MasterDetail/GraphCanvas template idiom. Generalizes the hand-rolled Planner-session terminal/inspector split. - Horizontal (default) or vertical orientation; the secondary is the resized pane (inverted drag), owning size/min/max + the splitter wiring by construction. - Add a `.resize-y` splitter class for the vertical orientation. - Colocated render smoke + layout-behavior tests. Template only — no page migrations here (that is the separate #2213). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
feat(errordb): fault store + `bsc errors` CLI — runtime fault spine (#2260)
fix(ci): scoped-ignore quick-xml DoS advisories in cargo audit (#2173)
feat(ui): SplitView layout template — the two-pane split page skeleton (#2197)
…nce + relationship graph Slice 3 of the graph-core epic (#2214), tight sub-slice: extract the longest-path layer ASSIGNMENT into `shared/lib/graph/layers.ts` (`layerDag`) and adopt it in the two consumers that both compute layers over a precomputed back-edge-exclusion set — Glance's `buildGraph` (was iterative relaxation) and the relationship graph's `buildRelationshipGraph` (was Kahn). Both are the same unique DAG longest-path fixpoint, so the migration is byte-identical: - Glance is a depends-on DAG (dependency sits LOWER), so it hands layerDag its edges reversed. - Relationship passes its ordering edges + DFS back-edge set straight through. Placement stays per-domain (Glance's grid, Relationship's swimlanes). Deliberately left for a follow-up: Org's `layerNodes` (a runtime-cycle-guard memoized DFS feeding a d3-force layout — different cycle semantics, higher layout-shift risk) and the Glance/Org barycenter ordering (not shared by Relationship). Colocated `layers.test.ts` covers longest-path, order-independence, back-edge exclusion, self-loop/unknown-node guards, and the reversed depends-on orientation. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
refactor(graph): shared layerDag — consolidate Glance + Relationship layering (#2214)
Part of the runtime-fault epic (#2258). Adds a small synchronous HTTP receiver, bound to 127.0.0.1 only, started with the app on a background thread. A locally running generated app POSTs a fault/heartbeat envelope (an OTLP-log subset) to `POST /ingest`; the collector validates the per-project ingest token, resolves the project's error.db via `error_db_path`, opens the errordb `Store`, and `record`s the fault (fingerprinting in the store). Heartbeats update an in-memory per-project liveness timestamp (consumed later by #2263). - New module `src-tauri/src/observability/collector.rs`: the `Envelope` wire type, the pure parse/validate/attribute/record `ingest` decision (returns an `Outcome` → HTTP status), a `tiny_http` accept loop on a named thread, the `CollectorState` managed state (port + per-project token/liveness/rate maps), and the `collector_info` Tauri command exposing `{ ingestPort, token }`. - Auth/attribution: unknown project_key → 404, absent/bad token → 401; tokens minted on demand (32 hex chars, in-memory for this slice). - Robustness: oversized bodies rejected (413) without buffering; malformed JSON and message-less faults → 400; per-project fixed-window rate limit (drop-with-count → 429); the accept loop never panics out. - Wired into `app/run.rs`: `.manage(CollectorState::new())`, started in `setup`, `collector_info` registered. - `src-tauri/Cargo.toml`: add `errordb` (path) + `tiny_http = "0.12"`. - Tests (`#[cfg(test)]`): end-to-end record into a temp error.db, 401/404/400, oversized-body, heartbeat-liveness, default-type-is-fault, rate-limit drop-with-count, token stability, context stringify. Verify: `cargo check -p base-studio-code` and `cargo clippy -p base-studio-code --all-targets -- -D warnings` both clean. Deferred: cloud transport seam (#2258), heartbeat/Glance status consumer (#2263), and baking the shim into generation (#2262). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ights page (#2243) Roll the reusable per-card empty/loading pattern (#2234) onto the planner's GitHub board → Insights dashboard. The page kept a full-page "Loading insights…" screen that hid every card while the ProjectV2 query ran, and used bare inline text ("No status field found.", "No open issues.") for empty bodies. Now the card layout ALWAYS renders; each body swaps loading skeleton | compact EmptyState (size="sm") | content: - Stat cards use StatCard `loading`. - Status distribution / Assignee workload / Label frequency: SkeletonRows → CardEmpty → HBars/bars. - Weekly activity: SkeletonChart → CardEmpty → Bars. - `isLoading = loading && issues.length === 0`, so a background refetch keeps the rendered content instead of flashing back to skeletons. - The Label frequency card is now always present (was hidden entirely when empty). Adds Insights.test.tsx covering the three states (loading → skeletons + no page-wide loader + no empty titles; empty → each card's compact EmptyState; content → real charts, no empty states). One slice of the #2243 rollout. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
feat(runtime): localhost fault-ingest collector (OTLP-log → errordb) (#2261)
feat(ui): per-card empty/loading on the Planner Insights dashboard (#2243)
…e apps (#2264) Give an app bsc didn't generate (a brought-in repo, the migration case) best- effort runtime-fault coverage by tapping the dev-server output the console already streams — no injected shim required. - observability/pty_faults.rs: a pure, tested signature extractor (extract_faults) scans a text block for Rust/Go panics, JS/Node stack traces, uncaught/unhandled rejections, and ERROR/FATAL log lines (ANSI-stripped, best-effort grouping of a head line with its frames). Detected faults are fingerprinted (stage runtime) and recorded to the pane's project error.db via the shared errordb::Store, tagged source_hint = "pty-tap" (lower confidence than a shim/OTLP fault). - Side-tap in spawn_emitter (console/pty/pump.rs): a single additive `observe` call that only BORROWS the flushed batch before it's moved into app.emit, so the WebView emit + mobile-tunnel tee are byte-for-byte unchanged. A no-op (one relaxed atomic load) when no pane is tapped. - Gated + rate-limited: off by default per pane. A pane must be explicitly marked an app-runner via the new pty_set_app_runner command; recordings are capped per pane per window. Attribution is the pane's owning project key → error_db_path. - Cargo.toml: add errordb path dependency. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…allback (#2264) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
feat(runtime): best-effort PTY-tap fault fallback for uninstrumented in-pane apps (#2264)
Elevate the per-card content|empty|loading pattern into a property of each component: a content-bearing primitive takes `loading` and renders a skeleton the same shape as itself, via the shared Skeleton/SkeletonText (one shimmer app-wide). Added to Card (skeleton body), Chip (shimmer pill), Text (inline shimmer line), TextField (skeleton input, label kept), Code (shimmer lines in the frame), and FillBar (indeterminate track). StatCard/StatTile already had it. Pure layout (Box/Stack/Row) and interactive controls (Button/Toggle) don't "load" — skipped. Registered the `loading` prop in each component's shared/ui/manifest.ts spec so the design-system registry + the v1.0.5 visual builder know the state. Test covers all six: loading → a shape-matched skeleton, real content hidden. Closes #2302 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
feat(ui): every content component ships a loading state (#2302)
…t-class destination The Component Library UI (`ComponentLibraryPane`, #2269) was reachable ONLY as the planner's optional `test_ui` stage (UI-Kit-blueprint-only), so it was effectively invisible. Promote it to a top-level **Design Studio** Rail workspace that renders the pane directly — it stands alone, reading the global `bsc component` store, so the workspace is just the pane. - registry.ts: add the `design` Workspace (key + "Design Studio" label + Blocks icon), placed after Skills in the library grouping. - lazyWorkspaces.tsx: `DesignWorkspace` lazy export wrapping `ComponentLibraryPane`. - App.tsx: render it in the Suspense screen-switch, in a flex-fill wrapper (the pane fills height:100%). - rail.test.tsx / registry.test.ts: extend the locked rail order + the exhaustive Workspace-union map; add a Design Studio nav test. The planner `test_ui` stage is unchanged. Part of the component-kit arc (#2238). Closes #2303 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
feat(app): Design Studio Rail workspace — Component Library as a first-class destination
…oadmap) (#2248) Bring the two remaining board views up to the #2243 pattern (Insights was already done): cards/columns always render; async bodies show a skeleton while loading and a compact empty state when there's no data — no page-wide blank. - ProjectBoard (Issues): replaced the full-section "Loading board…" overlay with skeleton columns while loading + a real "No board items yet" empty state (gated on items, since the "All items" column fallback means columns is never empty). - Roadmap: stat values shimmer via StatCard `loading` (not "…"); the gantt shows a SkeletonChart while loading + a compact EmptyState when there are no milestones. Tested (ProjectBoard loading/empty/content), mirroring Insights.test. Closes #2248. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
feat(planner): per-card empty/loading on the GitHub board (Issues + Roadmap) (#2248)
The bsc-defer Stop-hook directive was the last inline PROMPT string in the fleet/warden rc surface. Move its prose out of the BSC_DEFER_RC compile-time const into config-dir-overridable data/fleet/defer-directive.md, loaded via config::load_str at rc-assembly time and JSON-escaped into the block-reason fragment. The ALL_BSC_RC const becomes all_bsc_rc() so the config-loaded defer slot can sit in the ordered fragment list; bsc_rc_body() concats it. Output is byte-identical to the old inline const (the escape is a no-op on the current prose), so the #296 trailing-newline contract and the syntax guard hold. Adds bsc_defer_rc_embeds_the_externalized_directive test. Closes #2145 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
refactor(fleet): externalize bsc-defer directive prose to data/ (#2145)
#2303 added the Design Studio Rail workspace but pointed it at `ComponentLibraryPane` — which is the *Kickoff* design that correctly lives in the planner's `test_ui` stage. This builds the distinct, full-page Design Studio (from `design/Component Library Design Studio/Design Studio.dc.html`) and repoints the workspace at it. The planner Kickoff pane is untouched. The page (`DesignStudio.tsx` + `designStudio.css`): - Toolbar — ◆ logo · kit-switcher chips · ⌘K search · Library/Graph toggle · +Kit/+Component - Resizable left rail — collapsible kits→components tree (role dots, ×used) - Center — Library view (live preview + variant/theme/viewport switchers + Source/Props/ Usage tabs + a generate-variants design bar with a candidate strip) ⇄ composition Graph view - Resizable right inspector — title/meta · Props/API · Variants · Composes mini-graph · Guidance - Empty (no kits), generating overlay, and preview-error states Reuses the existing domain (`lib/model`, `renderSpecimen`, the global `bsc component` store) and the shared graph toolkit — `useGraphViewport` (pan/zoom) + `layerDag` (composition layering) + `useDragResize` (the splitters) — so it stays on-architecture. The design-only demo-state switcher is dropped; its states are wired to real signals. Closes #2308 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… + scoped globs) The single-text-node fix exposed the real mismatch: the test asserted the conceptual #219 table (planner code:none), but role-capabilities.json encodes plan-only as code:write + writeGlobs scoped to plan-section files (*.md, prompts/*, ...) — unlike the director, whose commons carve-out is encoded code:none + globs (#851). The data drives real permission wiring, so the test aligns with the model, with the encoding asymmetry documented. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
fix(ci): two born-broken #2420 tests (RoleTierChips text nodes + SectionLabel CSSOM serialization)
…-minor-3d73cdc6eb
feat(console): single Terminal Host — one PTY terminal per agent, re-parented between surfaces (#2378)
feat(design-system): register the Layouts tier in the manifest + Design Studio gallery (#2197 slice 3)
fix(planner): deploy-config instructions were cloud-only + legacy schema (#2392)
fix(publish): don't 404 on a failed/missing GitHub issue — label streams at creation (#2397)
feat(components): kit-change propagation delivery — auto-record edges + drain to rails (#2277)
fix(hotkeys): restore F-key screen navigation off the console page (#2403)
…velop/npm-minor-78585cbe35 chore(deps): bump the npm-minor group with 7 updates
feat(recovery): durable per-project agent-session ledger in plan.db (#2405)
…develop/actions-minor-3d73cdc6eb chore(deps): bump the actions-minor group with 5 updates
…point terminal mock - glance.css: the drill transition moved to the shared .graph-drill-anim (shared/ui/layouts/graphCanvas.css, #2418) and GlanceWorkspace already uses it — dropped this file's now-dead .glance-drill-anim copy; kept the #2401 morph CSS. - GlanceStreamMorph.test.tsx: the dock renders TerminalSlot since the single Terminal Host landed (#2378/#2399), so the old TerminalView mock intercepted nothing — mock the slot, mirroring the dock's test. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
feat(glance): morph a live agent node into its terminal for check-in (#2401)
…argo-minor-8dca6ac8b9 chore(deps): bump the cargo-minor group with 4 updates
fix(planner): resume the Claude conversation on reopen/restart instead of starting fresh (#2396)
…urrent) - New "Milestones — the version system" subsection: milestone = the release an issue ships in; themes are epics/labels, never milestones; Current + next + Backlog are the only open milestones; on each release close the milestone and roll unfinished issues forward. (Matches the board migration done today: 32 stale milestones closed, in-flight issues paired to 1.0.5.) - Roadmap: v1.0.4 + the 1.0.4n line marked Complete; v1.0.5 is Current (maintainer-confirmed — the app version is already 1.0.5). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
docs: milestone version-system policy + v1.0.5 Current roadmap flip
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Promotes the v1.0.5 release (tag v1.0.5, commit 0a9feef) to main. Snapshot includes the frontend consolidation wave (#2416–#2421), Glance/Org designer work, the documentor role, and everything stamped under CHANGELOG [1.0.5] — 2026-07-06.
🤖 Generated with Claude Code