Skip to content

Commit 3bf17b9

Browse files
authored
Add config page (#41)
1 parent 7c2d158 commit 3bf17b9

11 files changed

Lines changed: 9003 additions & 352 deletions

File tree

‎CHANGELOG.md‎

Lines changed: 101 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,48 @@
1+
## [0.0.18] - 2026-05-25
2+
3+
### Added
4+
5+
- A richer `Capability Packs` section inside `Settings > Configuration`, with cross-pack enablement toggles, always-visible pack cards, guided runtime-backed controls for `Architecture graph`, `Context Guidance`, `Semantic clones`, and `Knowledge pack`, plus a review sheet that separates direct pack edits from supporting dependency changes.
6+
- A strict `Inference config` panel that materializes backend profile and runtime definitions, supports profile/runtime renames with reference rewrites, validates safe names before save, and provides task, driver, runtime, model, and thinking-level controls for Bitloops, Codex, Claude, OpenAI, and Ollama-backed profiles.
7+
- Default-install seeding for missing daemon config files, including runtime CLI version, store paths, telemetry defaults, capability-pack defaults, platform inference profiles, and resolved executable hints for local runtimes.
8+
- Unit and integration coverage for the Configuration-based settings surface, including route aliases, daemon setup persistence, JSON-section compatibility, inference renames, default seeding, stale save responses, and redacted secret saves.
9+
10+
### Changed
11+
12+
- Kept `/settings/configuration` as the canonical settings route while treating `/settings/capability-packs` as a legacy alias that resolves to the same configuration UI.
13+
- Capability pack controls now write directly to runtime config paths while seeding missing backend sections and default profile bindings without rendering duplicated shared/default profile editors inside pack cards.
14+
- Removed the repo setup controls and the duplicate lower advanced runtime config area, keeping daemon setup, inference config, and pack-backed save/review as the main configuration flow.
15+
16+
### Fixed
17+
18+
- The dashboard bundle script now creates the parent cache directory before replacing the bundled app.
19+
- Runtime config saves now accept stale mutation responses when a refetch confirms the submitted patch, and redacted secret values when the backend returns masked saved secrets.
20+
21+
## [0.0.17] - 2026-05-21
22+
23+
### Fixed
24+
25+
- Session play actions now update existing session content instead of leaving stale details behind.
26+
- Session page data updates now avoid the slow refresh path that made existing sessions feel unresponsive.
27+
- Session table rows now preserve the actor value so the actor column no longer appears blank for populated sessions.
28+
29+
## [0.0.16] - 2026-05-18
30+
31+
### Fixed
32+
33+
- Tool-call counts now stay aligned across checkpoint summaries, session detail, token usage displays, and the supporting integration coverage.
34+
35+
## [0.0.15] - 2026-05-18
36+
37+
### Added
38+
39+
- Normalized transcript-entry types, mappers, and tests for dashboard session detail, turn timelines, and tool-use displays.
40+
41+
### Changed
42+
43+
- Dashboard transcript rendering now consumes canonical backend transcript entries from checkpoint session detail and interaction session detail responses instead of reparsing legacy raw-event transcript fragments.
44+
- Turn transcript analysis now builds per-turn sections from per-turn entries or the session-wide transcript stream, with stable ordering and empty-state handling when no canonical entries are available.
45+
146
## [0.0.14] - 2026-05-12
247

348
### Fixed
@@ -22,14 +67,7 @@
2267
- Aborted stale session and checkpoint detail requests when the selection changes or panels unmount, preventing outdated heavy payloads from lingering in memory.
2368
- Reduced duplicate raw-event filtering, sorting, and transcript parsing that caused Chrome RAM spikes on large sessions and checkpoints.
2469

25-
## [0.0.12]
26-
27-
### Fixed
28-
29-
- Restored missing session and checkpoint turn timelines when heavy interaction detail loads on demand, so turn content appears reliably after opening the `Turns` view.
30-
- OpenCode turn model badges now show readable model slugs like `kimi-k2p6` instead of full provider account paths such as `accounts/fireworks/models/kimi-k2p6`.
31-
32-
## [0.0.9]
70+
## [0.0.12] - 2026-05-10
3371

3472
### Added
3573

@@ -38,6 +76,7 @@
3876
- Architecture page with a 3D component-first view of Containers, Components, Deployment Units, Entry Points, flow-derived contract corridors, persistence read/write edges, and toggleable red direct module dependencies.
3977
- Architecture component parent grouping, with path-derived parent frames, group search results, group inspector details, and row-aware component layout so flat component lists can be scanned hierarchically.
4078
- Code Atlas data-source support for a live DevQL snapshot alongside the existing fixture catalogue, with the live source selected by default and `VITE_CODE_CITY_PROJECT_PATH` available for project-scoped CodeCity queries.
79+
- Debug view support for daemon validation, sync status, task tracking, and related troubleshooting details.
4180
- Unit and Playwright coverage for the live CodeCity data shape, including backend-compatible world mapping, render-arc fallback behaviour, live-route network stubs, search, selection, overlay toggles, and canvas rendering.
4281

4382
### Changed
@@ -50,19 +89,70 @@
5089
### Fixed
5190

5291
- Fixed Code Atlas arc visibility so backend world/medium zoom arcs can render without requiring a selected building, while selection-only arcs retain the existing focused behaviour.
53-
- Fixed Code Atlas rendering and lint issues around floor stacking, camera focus dependencies, and React StrictMode live-load retries.
54-
- Improved session compatibility and tool reporting for OpenCode
92+
- Fixed Code Atlas rendering, e2e, lint, and quality issues around floor stacking, camera focus dependencies, and React StrictMode live-load retries.
5593

56-
## [0.0.8]
94+
## [0.0.11] - 2026-05-08
95+
96+
### Fixed
97+
98+
- Restored missing session and checkpoint turn timelines when heavy interaction detail loads on demand, so turn content appears reliably after opening the `Turns` view.
99+
- OpenCode turn model badges now show readable model slugs like `kimi-k2p6` instead of full provider account paths such as `accounts/fireworks/models/kimi-k2p6`.
100+
101+
## [0.0.10] - 2026-05-07
102+
103+
### Added
104+
105+
- A dedicated session tool-use list and trace-pair renderer for pairing tool calls with responses in the session detail experience.
106+
107+
### Changed
108+
109+
- Refined the tool-use tab, chat transcript rendering, checkpoint sheet helpers, and session row mapping around shared tool-use display utilities.
110+
111+
### Fixed
112+
113+
- Improved tool reporting for OpenCode sessions and kept bundle metadata aligned for the `0.0.10` release.
114+
115+
## [0.0.9] - 2026-04-24
116+
117+
### Added
118+
119+
- Checkpoint browsing inside the sessions experience, including a sessions checkpoint table, checkpoint derivation helpers, and tests for the new checkpoint rows.
120+
- Turn timeline rendering and transcript utilities for session detail and checkpoint views.
121+
- WebSocket error handling, table URL-state coverage, JSON viewer theme coverage, and supporting dependency updates.
122+
123+
### Changed
124+
125+
- Updated session variables parsing, dashboard operations, and session defaults so checkpoint queries can share the sessions filtering flow.
126+
- Removed redundant CI `pnpm` version pins.
127+
128+
### Fixed
129+
130+
- Improved session compatibility and tool reporting for OpenCode.
131+
132+
## [0.0.8] - 2026-04-21
57133

58134
### Added
59135

60136
- New sessions page containing explorer and list of sessions.
61137

138+
## [0.0.7] - 2026-04-19
139+
140+
### Added
141+
142+
- Dashboard session rows, columns, detail sidebar, checkpoint summaries, and supporting GraphQL types for the sessions-first dashboard flow.
143+
- Accordion UI support and a DevQL usage skill for local dashboard development.
144+
- Expanded client, dashboard, hook, GraphQL mapper, and integration coverage for session loading and repository selection.
145+
62146
### Changed
63147

148+
- Replaced the dashboard commit-list focus with session-oriented browsing while preserving checkpoint detail access.
149+
- Updated release workflow dependencies, bundle metadata, and the dashboard favicon.
150+
64151
### Fixed
65152

153+
- Dashboard repository auto-selection and session loading now recover correctly when default branch data or repository identity changes.
154+
- Token usage charts are skipped when a checkpoint has no usage data instead of rendering empty chart chrome.
155+
66156
## [0.0.6] - 2026-04-14
67157

68158
### Added

‎bundle_versions.json‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
{
22
"versions": [
3+
{
4+
"version": "0.0.18",
5+
"min_required_cli_version": "0.0.29",
6+
"max_required_cli_version": "latest",
7+
"download_url": "https://github.com/bitloops/local-dashboard/releases/download/v0.0.18/bundle.tar.zst",
8+
"checksum_url": "https://github.com/bitloops/local-dashboard/releases/download/v0.0.18/bundle.tar.zst.sha256"
9+
},
310
{
411
"version": "0.0.17",
512
"min_required_cli_version": "0.0.29",

‎package.json‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
{
22
"name": "local-dashboard",
3-
"version": "0.0.17",
3+
"version": "0.0.18",
44
"license": "Apache-2.0",
55
"type": "module",
66
"scripts": {
77
"dev": "vite",
88
"build": "tsc -b && vite build",
9-
"bundle": "pnpm build && rm -rf ~/Library/Caches/bitloops/dashboard/bundle && mv dist ~/Library/Caches/bitloops/dashboard/bundle",
9+
"bundle": "pnpm build && mkdir -p ~/Library/Caches/bitloops/dashboard && rm -rf ~/Library/Caches/bitloops/dashboard/bundle && mv dist ~/Library/Caches/bitloops/dashboard/bundle",
1010
"format": "prettier . --write",
1111
"format:check": "prettier . --check",
1212
"lint": "eslint .",

‎src/api/runtime/config.test.ts‎

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import { afterEach, describe, expect, it, vi } from 'vitest'
2+
import { updateRuntimeConfig, type RuntimeConfigSnapshot } from './config'
3+
4+
function jsonResponse(payload: unknown, status = 200) {
5+
return new Response(JSON.stringify(payload), {
6+
status,
7+
headers: {
8+
'content-type': 'application/json',
9+
},
10+
})
11+
}
12+
13+
function runtimeConfigSnapshot(
14+
overrides: Partial<RuntimeConfigSnapshot> = {},
15+
): RuntimeConfigSnapshot {
16+
return {
17+
target: {
18+
id: 'target-daemon',
19+
kind: 'daemon',
20+
scope: 'Daemon',
21+
label: 'Daemon config',
22+
group: 'Daemon',
23+
path: '/tmp/bitloops/config.toml',
24+
repoRoot: null,
25+
exists: true,
26+
},
27+
revision: 'rev-2',
28+
valid: true,
29+
validationErrors: [],
30+
restartRequired: true,
31+
reloadRequired: true,
32+
sections: [],
33+
rawValue: {},
34+
effectiveValue: {},
35+
...overrides,
36+
}
37+
}
38+
39+
describe('updateRuntimeConfig', () => {
40+
afterEach(() => {
41+
vi.restoreAllMocks()
42+
})
43+
44+
it('returns the mutation-level reload decision instead of stale snapshot flags', async () => {
45+
vi.spyOn(globalThis, 'fetch').mockResolvedValue(
46+
jsonResponse({
47+
data: {
48+
updateConfig: {
49+
restartRequired: false,
50+
reloadRequired: false,
51+
path: '/tmp/bitloops/config.toml',
52+
message: 'Runtime config saved and hot-reloaded.',
53+
snapshot: runtimeConfigSnapshot(),
54+
},
55+
},
56+
}),
57+
)
58+
59+
const result = await updateRuntimeConfig({
60+
targetId: 'target-daemon',
61+
expectedRevision: 'rev-1',
62+
patches: [
63+
{
64+
path: ['inference', 'profiles', 'summary_llm', 'model'],
65+
value: 'gpt-5.4-mini',
66+
},
67+
],
68+
})
69+
70+
expect(result.restartRequired).toBe(false)
71+
expect(result.reloadRequired).toBe(false)
72+
})
73+
})

‎src/api/runtime/config.ts‎

Lines changed: 46 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,14 @@ export type RuntimeConfigSnapshot = {
128128

129129
export type RuntimeConfigFieldPatch = {
130130
path: string[]
131-
value: unknown
131+
value?: unknown
132+
unset?: boolean
133+
}
134+
135+
export type RuntimeExecutableResolution = {
136+
command: string
137+
path: string | null
138+
found: boolean
132139
}
133140

134141
export type UpdateRuntimeConfigInput = {
@@ -137,6 +144,12 @@ export type UpdateRuntimeConfigInput = {
137144
patches: RuntimeConfigFieldPatch[]
138145
}
139146

147+
type UpdateRuntimeConfigPayload = {
148+
restartRequired: boolean
149+
reloadRequired: boolean
150+
snapshot: RuntimeConfigSnapshot
151+
}
152+
140153
const CONFIG_TARGETS_QUERY = `
141154
query RuntimeConfigTargets {
142155
configTargets {
@@ -258,6 +271,16 @@ const UPDATE_CONFIG_MUTATION = `
258271
}
259272
`
260273

274+
const EXECUTABLE_RESOLUTIONS_QUERY = `
275+
query RuntimeExecutableResolutions($commands: [String!]!) {
276+
runtimeExecutableResolutions(commands: $commands) {
277+
command
278+
path
279+
found
280+
}
281+
}
282+
`
283+
261284
export async function fetchRuntimeConfigTargets(
262285
options?: GraphQLRequestOptions,
263286
): Promise<RuntimeConfigTarget[]> {
@@ -283,19 +306,36 @@ export async function fetchRuntimeConfigSnapshot(
283306
return response.data.configSnapshot
284307
}
285308

309+
export async function fetchRuntimeExecutableResolutions(
310+
commands: string[],
311+
options?: GraphQLRequestOptions,
312+
): Promise<RuntimeExecutableResolution[]> {
313+
if (commands.length === 0) return []
314+
315+
const response = await requestRuntimeGraphQL<{
316+
runtimeExecutableResolutions: RuntimeExecutableResolution[]
317+
}>(EXECUTABLE_RESOLUTIONS_QUERY, { commands }, options)
318+
319+
return response.data?.runtimeExecutableResolutions ?? []
320+
}
321+
286322
export async function updateRuntimeConfig(
287323
input: UpdateRuntimeConfigInput,
288324
options?: GraphQLRequestOptions,
289325
): Promise<RuntimeConfigSnapshot> {
290326
const response = await requestRuntimeGraphQL<{
291-
updateConfig: {
292-
snapshot: RuntimeConfigSnapshot
293-
}
327+
updateConfig: UpdateRuntimeConfigPayload
294328
}>(UPDATE_CONFIG_MUTATION, { input }, options)
295329

296-
if (!response.data?.updateConfig?.snapshot) {
330+
const update = response.data?.updateConfig
331+
332+
if (!update?.snapshot) {
297333
throw new GraphQLRequestError('Runtime config update returned no snapshot.')
298334
}
299335

300-
return response.data.updateConfig.snapshot
336+
return {
337+
...update.snapshot,
338+
restartRequired: update.restartRequired,
339+
reloadRequired: update.reloadRequired,
340+
}
301341
}

‎src/features/settings/components/sidebar-nav.tsx‎

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,11 @@ type SidebarNavProps = React.HTMLAttributes<HTMLElement> & {
2323
export function SidebarNav({ className, items, ...props }: SidebarNavProps) {
2424
const { pathname } = useLocation()
2525
const navigate = useNavigate()
26-
const [val, setVal] = useState(pathname ?? '/settings')
26+
const activePath =
27+
pathname === '/settings/capability-packs'
28+
? '/settings/configuration'
29+
: pathname
30+
const [val, setVal] = useState(activePath ?? '/settings')
2731

2832
const handleSelect = (e: string) => {
2933
setVal(e)
@@ -33,7 +37,7 @@ export function SidebarNav({ className, items, ...props }: SidebarNavProps) {
3337
return (
3438
<>
3539
<div className='p-1 md:hidden'>
36-
<Select value={val} onValueChange={handleSelect}>
40+
<Select value={activePath ?? val} onValueChange={handleSelect}>
3741
<SelectTrigger className='h-12 sm:w-48'>
3842
<SelectValue placeholder='Theme' />
3943
</SelectTrigger>
@@ -68,7 +72,7 @@ export function SidebarNav({ className, items, ...props }: SidebarNavProps) {
6872
to={item.href}
6973
className={cn(
7074
buttonVariants({ variant: 'ghost' }),
71-
pathname === item.href
75+
activePath === item.href
7276
? 'bg-muted hover:bg-accent'
7377
: 'hover:bg-accent hover:underline',
7478
'justify-start',

0 commit comments

Comments
 (0)