Skip to content

Commit beaf639

Browse files
phodalcodex
andcommitted
feat(studio): discover sessions from project workspaces
Reworks Studio around a Web-selected project workspace and reuses Inspector's in-process multi-provider discovery for Session detail and observational compare views. Adds cross-platform native directory selection and staged loading feedback without exposing the selected path. Implements docs/specs/2026-08-20-harness-studio-local-web-workspace.md. Validated with 118 Harness Studio tests, 15 Playwright flows, and 1412 repository tests. Co-authored-by: Codex (GPT 5.6 Sol) <codex@openai.com>
1 parent 8a35fc5 commit beaf639

14 files changed

Lines changed: 868 additions & 190 deletions

docs/specs/2026-08-20-harness-studio-local-web-workspace.md

Lines changed: 75 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,11 @@
99

1010
Harness Studio is a local Web application, not a collection of views enabled by
1111
startup flags. Launching the server should open an empty workbench. The user
12-
then chooses a local directory in the browser, Studio discovers the supported
13-
sessions inside that directory, and the user can inspect one session or compare
14-
two sessions without restarting the process.
12+
then chooses a project working directory in the Web UI. Studio passes that
13+
absolute local workspace identity to the same in-process discovery capability
14+
used by Harness Inspector, which finds workspace-matching sessions in each
15+
supported host's evidence store. The user does not need to know where a host
16+
stores transcripts or select a Session directory manually.
1517

1618
The product hierarchy is `Workspace -> Sessions -> Session detail / Compare ->
1719
Session artifacts`. CLI arguments may preload data for compatibility and
@@ -20,15 +22,18 @@ surface exists.
2022

2123
## Decisions
2224

23-
- **D-1: the Web workspace is the root aggregate.** A selected directory creates
24-
one replaceable, server-managed workspace session. Session, compare, and
25-
artifact routes resolve through that workspace.
26-
- **D-2: directory selection stays browser-native.** The browser uses a directory
27-
picker and sends relative paths plus bounded file bytes. It never claims that
28-
a browser file picker exposes a portable server-readable absolute path.
29-
- **D-3: adapters own session formats.** The first adapter accepts retained
30-
Harness Studio `run_*.json` records. Additional Qoder, Codex, Claude, or
31-
harness-run layouts must be added through a format adapter, not UI branching.
25+
- **D-1: the project workspace is the root aggregate.** A selected local working
26+
directory creates one replaceable workspace scope. Session, compare, and
27+
artifact routes resolve through the sessions discovered for that scope.
28+
- **D-2: a local server owns directory selection.** A normal browser directory
29+
input cannot reveal a portable absolute path, so it cannot establish the same
30+
workspace identity as Inspector. A same-origin POST asks the loopback server
31+
to open the operating system's directory chooser. No project files are
32+
uploaded or copied into Studio.
33+
- **D-3: reuse Inspector discovery code in process.** Studio calls the existing
34+
multi-provider session-analysis capability with the selected workspace. It
35+
does not invoke an Inspector or session-analysis CLI subprocess and does not
36+
duplicate host path/slug rules in React.
3237
- **D-4: Session Compare is observational.** Comparing two selected sessions
3338
shows retained status, duration boundary, tool calls, messages, and semantic
3439
phase differences. It does not emit a winner or reuse the frozen
@@ -40,18 +45,23 @@ surface exists.
4045
- **D-6: `better-harness web` is a launcher only.** The future public command
4146
locates and starts the packaged Studio application. Selecting or switching a
4247
workspace remains entirely inside the Web UI.
48+
- **D-7: slow discovery reports real stages, not fake percentages.** While an
49+
open request is pending, Studio exposes only the coarse server-owned stage:
50+
waiting for the native directory chooser or discovering workspace-matched
51+
Sessions. The Web UI polls that privacy-safe state and renders an indeterminate
52+
progress indicator with reduced-motion support.
4353

4454
## Acceptance Scenarios
4555

4656
- **AC-1:** Studio starts with no data arguments and presents an enabled
47-
**Open session folder** action on Overview and Sessions.
48-
- **AC-2:** Choosing a directory creates a same-origin, opaque, bounded import
49-
session. Relative paths are portable and confined; the active workspace
50-
changes only after all selected files are accepted and indexed.
51-
- **AC-3:** A directory containing valid retained `run_*.json` records produces
52-
a newest-first Session list with prompt, status, saved time, and tool-call
53-
count. Unsupported and malformed files are reported as omitted and do not
54-
break the workspace.
57+
**Open workspace** action on Overview and Sessions.
58+
- **AC-2:** Choosing a directory is allowed only from a same-origin loopback
59+
request, returns no absolute path to the browser, and does not upload or copy
60+
the project's files. Cancelling leaves the active workspace unchanged.
61+
- **AC-3:** Selecting a project directory runs the Inspector-owned provider
62+
discovery against that workspace and produces a newest-first Session list
63+
with provider, prompt, observed time, and tool-call count. One unavailable or
64+
failed provider does not hide sessions from other providers.
5565
- **AC-4:** Selecting a Session opens its real retained Session Debugger
5666
projection. No sample session is substituted when the workspace has data.
5767
- **AC-5:** The user can select exactly two sessions from the current workspace
@@ -60,8 +70,8 @@ surface exists.
6070
for status, retained event count, tool-call count, message count, and tool
6171
sequence. It labels missing evidence and makes no winner claim.
6272
- **AC-7:** Replacing or disconnecting the workspace clears the prior Session,
63-
Compare, and Artifact selection and removes Studio-owned temporary data. It
64-
never writes into the source directory.
73+
Compare, and Artifact selection. Discovery is read-only and never writes into
74+
the workspace or native host session stores.
6575
- **AC-8:** Empty-state UI copy does not instruct the user to restart with
6676
`--inspector`, `--evidence`, `--harness`, or `--artifacts` for browsing and
6777
comparing retained sessions.
@@ -70,12 +80,16 @@ surface exists.
7080
- **AC-10:** The root CLI contract can later expose `better-harness web` as a
7181
workflow command that starts the same empty Studio server; it does not add
7282
directory-selection flags to the primary Web workflow.
83+
- **AC-11:** During a slow workspace open, the button is disabled, an animated
84+
live status first reports directory selection and then Session discovery, and
85+
completion automatically replaces the intake with the discovered Session
86+
list. No made-up percentage or absolute path is shown.
7387

7488
## Non-goals
7589

7690
- Treating observational Session Compare as an experiment verdict.
77-
- Uploading an entire repository or agent home without a bounded adapter plan.
78-
- Supporting every host transcript layout in the first adapter.
91+
- Uploading an entire repository or agent home to the loopback server.
92+
- Reimplementing host transcript discovery inside the Studio package or UI.
7993
- Editing, replaying, or writing back into imported sessions.
8094
- Shipping the public `better-harness web` package boundary in this first UI
8195
migration; the server and packaged-app ownership must be resolved first.
@@ -84,15 +98,15 @@ surface exists.
8498

8599
### 1. Introduce the workspace session contract
86100

87-
Add bounded create/upload/commit/disconnect routes. Preserve relative paths in
88-
a confined temporary root, index supported records through a format adapter,
89-
and make the committed workspace the dynamic owner for Session routes.
101+
Add same-origin open/disconnect routes around a cross-platform native directory
102+
picker. Keep the absolute path server-side and make the discovered workspace
103+
scope the dynamic owner for Session routes.
90104

91105
### 2. Make Sessions the primary observed-data surface
92106

93-
Replace startup-flag-driven empty states with an Open session folder action,
94-
render the committed Session catalog, and open real retained Session Debugger
95-
data from the selected row.
107+
Replace startup-flag-driven empty states with an Open workspace action, invoke
108+
the Inspector-owned multi-provider collector in process, render its Session
109+
catalog, and open real retained Session evidence from the selected row.
96110

97111
### 3. Add observational Session Compare
98112

@@ -102,9 +116,9 @@ Keep frozen harness-compare evidence as a separate surface.
102116

103117
### 4. Scope Artifact View below Session
104118

105-
Resolve artifacts from the selected Session workspace when the adapter exposes
106-
them. Until then, show an honest session-scoped empty state rather than a loose
107-
global artifact picker.
119+
Resolve artifacts from a Session discovered for the selected project workspace
120+
when the adapter exposes them. Until then, show an honest session-scoped empty
121+
state rather than a loose global artifact picker.
108122

109123
### 5. Prepare the launcher boundary
110124

@@ -114,36 +128,44 @@ package the built Studio runtime so the root command registry can dispatch
114128

115129
## Test and Review Evidence
116130

117-
Implementation evidence captured on 2026-08-20:
118-
119-
- `npm test` in `packages/harness-studio`: 17 files, 115 tests passed.
120-
- `npm run test:browser` in `packages/harness-studio`: 15 Playwright tests
121-
passed, including the folder-to-Session-to-Compare flow and the provisioned
122-
PPTX viewer regression.
123-
- `npx vitest run test/skills-docs/doc-link-graph.test.mjs`: 6 tests passed
124-
after regenerating `docs/better-harness-doc-links.mmd`.
125-
- Wide, compact, and narrow screenshots were captured for workspace intake,
126-
Session browsing, and Session Compare with browser console/page-error and
127-
horizontal-overflow assertions.
128-
129131
- AC-1/AC-8: empty-start model and Playwright assertions for UI copy and actions.
130-
- AC-2/AC-3/AC-7: HTTP tests for transactionality, traversal, limits,
131-
replacement, disconnect, malformed files, and source immutability.
132+
- AC-2/AC-3/AC-7: HTTP tests with an injected picker/provider for same-origin
133+
access, cancellation, atomic replacement, disconnect, provider diagnostics,
134+
path redaction, and read-only discovery.
132135
- AC-4: browser test that selects a retained session and verifies its prompt and
133136
real tool-call projection.
134137
- AC-5/AC-6: model and browser tests selecting two sessions and rendering an
135138
observational comparison with no winner language.
136139
- AC-9: Playwright screenshots, keyboard focus, horizontal overflow, browser
137140
console, and page-error checks at all three required widths.
138141
- AC-10: CLI inventory/dispatch tests belong to the packaging follow-up.
142+
- AC-11: HTTP tests pause the injected chooser and provider to verify the two
143+
status stages; Playwright verifies the live discovery message, progress
144+
indicator, disabled action, and automatic transition to the Session list.
145+
146+
Implementation evidence (2026-08-20):
147+
148+
- `npm test` in `packages/harness-studio`: 18 files, 118 tests passed,
149+
including controlled chooser/discovery stage transitions.
150+
- `npm run test:browser` in `packages/harness-studio`: 15 Playwright tests
151+
passed, including the workspace intake, discovered Session detail, Compare,
152+
animated discovery status, wide/compact/narrow screenshots, keyboard focus,
153+
overflow, console, and page error checks.
154+
- `npm test` at the repository root: 99 files, 1412 tests passed.
155+
- A live in-process discovery smoke against this repository returned the bounded
156+
100-Session catalog: Qoder 79, Codex 16, and Claude 5.
139157

140158
### Risks
141159

142-
- Directory pickers expose relative paths and bytes, not portable absolute
143-
paths. The UI must not imply direct filesystem mounting.
160+
- Browser directory inputs expose relative paths and bytes, not a portable
161+
absolute path. The loopback server therefore owns the native picker and must
162+
never expose the selected absolute path back to the page.
144163
- Session records may contain sensitive prompts or tool output. Imports remain
145164
loopback-only, temporary, bounded, and never leave the local server.
146-
- Host transcript formats differ substantially. UI inference would create false
147-
compatibility; adapter detection must fail closed with omission reasons.
148-
- Large histories can exhaust browser or server memory. The first slice limits
149-
files, per-file bytes, aggregate bytes, depth, and accepted record count.
165+
- Host transcript formats differ substantially. Studio must reuse the bounded
166+
provider discovery and privacy-safe projection already owned by Inspector.
167+
- Native directory chooser availability differs across Windows, macOS, and
168+
Linux. Platform implementations must use fixed commands without a shell and
169+
return an actionable unavailable state when no chooser exists.
170+
- Large histories can exhaust memory. Discovery retains Inspector's global
171+
Session bound and hydrates only selected recent candidates.

0 commit comments

Comments
 (0)