Skip to content

FE-737: Web shell over the same host (M3)#147

Open
lunelson wants to merge 36 commits into
ln/fe-736-jsonl-session-viabilityfrom
ln/fe-737-web-shell
Open

FE-737: Web shell over the same host (M3)#147
lunelson wants to merge 36 commits into
ln/fe-736-jsonl-session-viabilityfrom
ln/fe-737-web-shell

Conversation

@lunelson
Copy link
Copy Markdown
Contributor

FE-737: Start web shell frontier

FE-737 reject non-linear transcript JSONL

FE-737 fail fast on non-linear session RPC

FE-737 block TUI branch flows

Copy link
Copy Markdown
Contributor Author

lunelson commented May 21, 2026

Warning

This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
Learn more

This stack of pull requests is managed by Graphite. Learn more about stacking.

Comment thread src/web-host.ts Outdated
}

function websocketHandshakeResponse(key: string): string {
const accept = createHash("sha1")
Copy link
Copy Markdown

@semgrep-code-hashintel semgrep-code-hashintel Bot May 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The use of a weak cryptographic algorithm (e.g., SHA-1 or MD5) has been identified. These algorithms are considered insecure due to vulnerabilities that make them susceptible to collision attacks, allowing attackers to compromise data integrity or security. Replace SHA-1 or MD5 with secure hashing algorithms, such as: SHA-256 or higher (e.g., SHA-3).

Fixed in commit ec2f985

@lunelson lunelson changed the title FE-737: Start web shell frontier FE-737: Web shell over the same host (M3) May 27, 2026
@lunelson lunelson marked this pull request as ready for review May 27, 2026 16:30
@cursor
Copy link
Copy Markdown

cursor Bot commented May 27, 2026

PR Summary

Medium Risk
Introduces a new browser transport and session-projection contract that many clients will depend on; mistakes in binding/linearity or RPC params could mis-route reads, though scope stays read-only POC with broad automated coverage.

Overview
Delivers M3 (web-shell): brunch --mode web runs a local HTTP host that serves the Vite-built React shell and exposes the same JSON-RPC handlers over WebSocket /rpc (no REST product reads). The browser stack adds React 19, TanStack Router/Query, dist-web in the build, and a minimal index.html entry.

Transcript and session reads are centralized on a canonical Brunch session envelope (readBrunchSessionEnvelope): one Pi header, one brunch.session_binding, strict entry shape, and fail-fast linearity (no branch-derived sessions, branch summaries, or multi-child graphs). Active-branch JSONL projection is removed; elicitation and display paths go through linear loaders with an allowlisted set of prompt-side custom entry types and new session.transcriptDisplay RPC alongside session.elicitationExchanges, including optional explicit { sessionId, specId } targets and a -32002 error for non-linear transcripts. The TUI extension cancels Pi session_before_tree / session_before_fork with a stable warning.

Shared json-rpc-protocol helpers factor parse/dispatch out of transports; fixture capture and tests are updated for the linear model. SPEC/PLAN mark web-shell complete, document D33-L (connections are client attachments, one-writer/many-observer POC), and advance the active frontier to graph-data-plane. Also adds the ln-judo-review agent skill and minor workflow doc tweaks (Graphite frontier setup, dist-web gitignore).

Reviewed by Cursor Bugbot for commit eab91df. Bugbot is set up for automated code reviews on this repo. Configure here.

Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit eab91df. Configure here.


function hasRequiredSessionEntryShape(value: unknown): value is SessionEntry {
return isTranscriptEntry(value) && hasStringOrNullParentId(value)
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Identical function duplicated within same file

Low Severity

hasRequiredSessionEntryShape and isSessionEntry in brunch-session-envelope.ts have identical implementations — both return isTranscriptEntry(value) && hasStringOrNullParentId(value). One of them is unnecessary and risks diverging silently if only one is updated in the future.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit eab91df. Configure here.

(value as { parentId?: unknown }).parentId === null ||
typeof (value as { parentId?: unknown }).parentId === "string"
)
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Transcript entry helpers duplicated across two files

Low Severity

isTranscriptEntry, isSessionEntry, and hasStringOrNullParentId are identically copy-pasted as private functions in both brunch-session-envelope.ts and elicitation-exchange.ts. Since elicitation-exchange.ts already imports from brunch-session-envelope.ts, these helpers could be shared rather than duplicated, reducing the risk of future divergence.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit eab91df. Configure here.

@augmentcode
Copy link
Copy Markdown

augmentcode Bot commented May 27, 2026

🤖 Augment PR Summary

Summary: This PR introduces the M3 “web shell” as a native React UI served by the Brunch host, using a single WebSocket-backed JSON-RPC transport (no REST read model).

Changes:

  • Adds --mode web CLI support and a Node HTTP host that serves built web assets plus /rpc WebSocket JSON-RPC.
  • Introduces a typed JSON-RPC protocol helper module to centralize parsing/dispatch and standard error frames.
  • Adds a browser WebSocket RPC client with request multiplexing and protocol-failure hardening.
  • Builds the initial React dashboard using TanStack Router + Query to render workspace chrome and a read-only transcript display.
  • Adds a canonical “Brunch session envelope” reader that validates session self-description (brunch.session_binding) and enforces linear transcript constraints.
  • Hardens projection/RPC paths to reject non-linear transcripts and to require explicit session/spec targets for durable reads.
  • Blocks Pi branch flows (/tree, /fork) in the TUI with a stable user-facing warning.
  • Wires Vite build output to dist-web and updates packaging/tsconfig accordingly.

Technical Notes: Session-consuming reads now treat transport connections as ephemeral attachments; explicit { sessionId, specId } targeting is used for web projections, and non-linear Pi JSONL shapes fail fast.

🤖 Was this summary useful? React with 👍 or 👎

Copy link
Copy Markdown

@augmentcode augmentcode Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review completed. 1 suggestion posted.

Fix All in Augment

Comment augment review to trigger a new review at any time.

Comment thread src/fixture-capture.ts

const response = JSON.parse(chunks.join("")) as JsonRpcResponse<T>
if (response.error) {
if ("error" in response) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

src/fixture-capture.ts:164 — Since response comes from JSON.parse without runtime validation, a malformed frame that lacks both error and result will now fall through and return undefined, which can mask protocol failures during fixture capture.

Severity: medium

Generating Fix in Augment link...

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant