Surface streamed chat errors in the chat UI#7
Open
jakimoai wants to merge 1 commit into
Open
Conversation
This was referenced Jul 11, 2026
jakimoai
marked this pull request as ready for review
July 12, 2026 05:24
jjang-ai
pushed a commit
that referenced
this pull request
Jul 14, 2026
NetworkHostEntry already carried .signing and .shares (populated by
netexec/nxc ingestion) but the row rendered only ip/hostname/os/status.
The signing state ("signed", "not required", "required") and enumerated
share list often determine the next attack path, so hiding them behind
Copy-only context menus made critical evidence undiscoverable.
Added an info button per host row that opens NetworkHostDetailSheet with:
- Header: ip + optional hostname + status pill (Pwn3d! red / else green)
- Metadata grid: ip, hostname, os, smb signing, shares, status, likely tool
- Likely-tool heuristic: snmpwalk for status=="snmp"; netexec/nxc when
signing or shares populated; otherwise nmap + netexec/nxc
- Scrollable selectable raw-output tail from ResultsStore.rawResults
matched by tool name
Same shape as ReconResultDetailSheet (37ef439). Web #11 and Creds #7 land
next iter.
jjang-ai
pushed a commit
that referenced
this pull request
Jul 14, 2026
Batch resolves the visible pieces of the Codex UX-affordance audit
that were left over from B's handoff. All demo-critical for the 5
conference topics tomorrow (Model Risk Management, Supply Chain,
Compliance Audits, Docs & Auditability, Future-Proofing Compliance).
New shared file: Views/Findings/VulnDetailSheet.swift
Three reusable sheets so every tab shows finding depth consistently
instead of eight bespoke layouts:
- VulnDetailSheet: severity + CVSS + source + CVE + tags +
description + tool raw-output tail + Send-to-Web/Exploit intents.
- CVEDetailSheet: everything CVE has (vector, KEV, exploit
availability, vendor, product, version range, published, sources,
description, clickable NSWorkspace references) + Search-Metasploit
intent.
- ExploitModuleDetailSheet: full metasploit output beyond the
lineLimit(20) card, with auto-extracted CVE refs and copy.
- DetailActionButton: consistent pill-button used by all three.
Per-tab wiring
--------------
UX #1 SupplyChainTabView: secrets/deps/SBOM lifecyclePanel now renders
actual VulnEntry results below the command templates (previously
command list only, results only visible in Activity Feed). Rows
open VulnDetailSheet with target/CVE/tags/tool tail.
UX #7 CredsTabView: all 4 subtabs (Cracking, Online Brute, Secrets,
Vault) — every row is click-to-detail with contextMenu "Open
details…" mirror. Tooltip on hover.
UX #9 ExploitTabView: metasploit result cards now click through to
ExploitModuleDetailSheet with full output + detected-CVE
extraction + copy actions.
UX #12 OSINTTabView: found URLs are now real buttons — click opens in
browser via NSWorkspace when scheme://, otherwise opens
OSINTDetailSheet. Context menu adds "Open URL in browser" and
"Open details…". Non-URL results (e.g., theHarvester emails)
still land in the detail sheet.
UX #15 ReconTabView: detail sheet gains a "send to next phase" row
(Web recon / Exploit search / Network scan). Emits a chat-ready
prompt so autopilot picks up the discovered target without the
user retyping — moves from find→exploit in one click.
UX #16 SupplyChainTabView: CVE Intel rows open CVEDetailSheet with
clickable NSWorkspace references, KEV/exploit badges,
version-range display, source attribution, and
Search-Metasploit intent.
UX #17 ToolSettingsView: adds error-status summary chip, click-to-
filter (installed/missing/error), tool-name filter query,
error rows get "Retry" instead of "Install", tool status dot
now colored red for .error. Makes the 40+ tool list scannable.
UX #18 TabBarView readiness pill: shows selected-vs-loaded model
divergence. If engineConfig.modelPath (user's picked model) !=
engineManager.loadedModel (what the engine actually announced),
renders in amber with an arrow.left.arrow.right glyph and a
tooltip explaining the mismatch. Model Risk Management demo
needs this — "what is answering vs what did I ask for" is the
whole point of the topic.
Release script (script/package_release.sh)
------------------------------------------
- Default version bumped 0.1.0-beta → 1.0.0. No more "beta" branding.
- DMG output renamed release/ExploitBot-beta.dmg → release/ExploitBot.dmg.
- Volume label renamed "ExploitBot Beta" → "ExploitBot".
- App notarize-zip renamed to plain ExploitBot-app.zip.
Codex adversarial UX-audit findings still open (deferred, non-blocking
for demo):
#4 ResultProvenance data-contract refactor (largest, structural).
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.
Summary
Surfaces top-level streamed chat errors in the current assistant message instead of leaving a blank response.
Problem
When the engine emits an SSE chunk containing a top-level
errorobject, the chat UI leaves the assistant response blank. The backend failure is present on the wire, but the user sees no output.Root Cause
The Swift streaming loop handles warning and usage chunks, then expects
choices[].delta. Top-level stream errors do not includechoices, so they were discarded before reaching visible chat state.Fix
error.messageanderror.detailpayloads.errorpayloads.errorfinish reason.No engine, model launch, cache, or runtime behavior changes.
Visual Proof
The same local mock SSE request was captured before and after the change:
choices[].delta.contentstream still displays its response.Proven Live on the Dev App
origin/mainFollow-up / Out of Scope
Related PRs
Tests
swift build --package-path ExploitBot.