Repository navigation
docs: a handover for whoever picks this up - #33
Merged
Merged
Conversation
Eight PRs landed in this stretch and the reasoning behind most of it lives in commit messages nobody reads twice. This is the part a diff cannot carry: why each decision went the way it did, what is still open and why it was deferred, and the traps in this tree that cost real time. The open items are written as work, not as a wish list — each says what it is, why it is not done, where to start, and what needs a human decision. The bookmark rename is blocked on aliasing three external contracts; the SQL table rename is blocked on whether anyone runs mixed versions against one project. The traps section is the part I would most want handed to me. The native-module ABI swap, whose failure mode is unit tests SKIPPING rather than failing. The temporal-dead-zone crash that only appears in the bundled build, which has bitten this codebase three times and which vitest structurally cannot see. The two-tier tables, where most of the corpus lives in the half that gets pruned. The source-scanning guard tests. And two of my own mistakes from this stretch: a scripted edit whose anchor silently missed and stopped capture for three commits, and a `git checkout --` that ate an hour of uncommitted work in the file I was editing. ROADMAP.md gets a staleness banner rather than a rewrite — it was written against v0.9.3, five releases back, and rewriting someone's planning document from the outside is worse than pointing at what is current. The docs index has been claiming v0.11.7; it now says v0.14.3 and leads with the handover. Every relative link and code path in the new page is checked to resolve. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Team Run ID: Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
…is not them The written standard has been in the repo since #29, but two things it names were not: the app-icon masters, and the design canvas itself. The masters are now at design/assets/. The canvas is deliberately not — it is authored in the design project, and a copy in the repo would just be a second truth that drifts. Pulling the masters in surfaced a contradiction worth writing down: §16 says the old logo "was replaced", while resources/icon.svg, resources/logo.svg, resources/tray-icon.svg and the renderer's logo.svg are all still the old one, gradients and glow included, and every .icns/.ico/PNG derives from them. So §16 now carries a ▲ 分歧 saying it describes the design ruling, not what you get when you install the app, and the handover carries the swap as item 7 with the part that makes it more than a file replacement: the macOS tray set is a Template image with two states, and 16px is exactly where the old mark failed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Merged
2 tasks done
guan4tou2
added a commit
that referenced
this pull request
Oct 8, 2026
Seven P1 findings from the UI/UX audit, batched: • #15 HUD auto-collapse now pauses while the pointer is on the overlay (audit was: hard 8s timer, no way to keep it open while reading the topology chain / Reveal button). • #16 Terminal tab labels ("Shell 1", "Shell 2" …) used tabs.length + 1 → duplicated after any close. Now uses a monotonic counter. • #17 Closing a terminal tab kills the PTY silently. Now confirms via ConfirmDialog when the tab is still alive (matches ProjectPicker delete pattern). • #21 Settings CDP test callback had a `const tab = ...` shadowing the outer `tab` state (settings tab name). Renamed to `cdpTab`. • #28-29 EventMarker showed raw enum strings ("info" / "initial_access") for severity + category — now i18n'd (marker.severity.*, marker. category.*). Also added an opt-out "Capture screenshot too" checkbox (default on) so a mark taken over sensitive UI doesn't force a capture. • #30 EventMarker gained role="dialog", aria-modal, aria-label, and an Escape-to-close handler on the backdrop. Autofocus lands on the dialog body so keyboard users have a hook. • #32 App title-bar Mark button title="Ctrl+Shift+M" was hardcoded — Mac users saw the wrong hint. Uses isMac to pick ⌘⇧M vs Ctrl+Shift+M. Deferred (need bigger refactors): #9-14/#49-50 shared IPC store to stop per-event refetches across StatusBar/Sidebar/Dashboard/LootPanel/TargetView/ ScopeStatus; #22-24 sidebar keyboard drag; #25-27 FindingsView/SearchPanel/ LootPanel interactive; #33 uptime should be engagement-scoped not window- scoped; #34 StatusBar record toggle button styling; #37-38 timeline layout constraints. All queued for the next batch. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
guan4tou2
added a commit
that referenced
this pull request
Oct 8, 2026
…ocus • #25 FindingsView CDP poll now backs off from 3s → 10s while the browser isn't running. Was hitting IPC every 3s regardless. • #26 Mark URLs (both the primary and the auto-captured browserUrl) now open in the operator's real browser via app.openExternal — was inert plain text before. New http/https-only openExternal IPC (rejects file: and other schemes so untrusted content can't dispatch side effects). • #27 SearchPanel results are clickable — click jumps to the event on the Timeline via the existing focusEvent flow. Also dropped the q<2 gate to q<1 so single-char IPs/octets work. • #37 Cluster popover now flips ABOVE the cluster when the natural position would drop it off the bottom of the timeline (last-lane clusters). • #39 Recent-project delete ✕ now shows on focus, not only hover — keyboard users can reach it. Also gained a focus ring. • #47 Timeline zoom-reset button gained a ↺ glyph so the click-to-reset behaviour is discoverable (was just the percentage number), plus is disabled at 100% and has aria-label + focus ring. New i18n keys: marks.openUrl, search.openInTimeline (en + zh-TW). Deferred (still queued): #24 already fixed by v0.6.29's shortcut order change; #33 uptime → engagement start; #38 timeline layout with detail panel; #48 MCP UI stdio vs http. Bigger P1s (#9-14, #49-50 shared IPC store) and P2 shared-component extractions still need dedicated design. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
guan4tou2
added a commit
that referenced
this pull request
Oct 8, 2026
• #33 StatusBar uptime is now engagement-scoped: reads project.active() createdAt instead of window-open Date.now(). Closing the app mid-op and reopening no longer resets the counter — the timeline matches what "uptime" says. Also extended the project.active IPC to include createdAt (with a matching env.d.ts type bump). • #41 (partial) Screenshots + Loot cards gained role="button", tabIndex, aria-label, Enter/Space key handlers, and a focus-visible ring. Grid views are keyboard-navigable now. • #30/#40 (screenshot expanded overlay) got role="dialog", aria-modal, aria-label, autofocus, Escape-to-close — was click-only before. TargetView cards still need the same keyboard-nav pass; queued for the next batch alongside StatusBar sep buttons and Overlay ▲/▼/✕. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
guan4tou2
added a commit
that referenced
this pull request
Oct 8, 2026
Second-pass audit (81 findings) shortlisted three P0 bugs. All fixed: • #33 TargetView in-scope / out-of-scope filter always returned empty. Every entry's `inScope` was set to null and never populated; both filter chips compared === true/false, so they always yielded zero results while "All" worked. Compute inScope client-side by matching each target against the current scope config (wildcard subdomains + CIDR + exact). Reclassify when the scope config changes. Also extended the source query from shell-only to all events (audit finding #34) — screenshot / http_navigation / loot events with a detectedTarget now surface here too. • #1 Timeline reveal state was sticky across the session. `revealedEvents` Set only shrank when the user clicked Hide — leaving and coming back kept everything unmasked. Now the set clears on every selectedEvent.id change, so mask-by-default holds. • #2 Copy JSON always dumped raw bytes regardless of what the panel was showing. Now respects the reveal state: masked panel → masked clipboard, revealed panel → raw clipboard. New toast tells the user which they got. • #43 CDP port had TWO controls: a separate FieldGroup with local `cdpPort` state (bypassed auto-save entirely) plus BrowserPanel's `config.browser. cdpPort` field that did save. Users editing one thought they'd changed both. Removed the standalone Field + local state; the Test Connection button now reads from config.browser.cdpPort like everything else. Second-pass audit produced 81 findings across 14 feature areas; these are the three called out as P0. Batches of P1/friction items to follow. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
guan4tou2
added a commit
that referenced
this pull request
Oct 8, 2026
docs: a handover for whoever picks this up
guan4tou2
added a commit
that referenced
this pull request
Oct 8, 2026
…ock counts Spec 034. Settings search matched page names only (#143 had relabelled the box "Filter categories…" to be honest about it). It now matches the text each page renders — group titles, field labels, hints — in the displayed language. Choosing a result opens its page and brings the text into view. The index is generated from the page sources (npm run gen:settings-search) and a test fails when a page renders a key the index lacks. The box says "Search settings…" again, and the IA test now allows that label only while the search is wired. The filter bar named types by storage name (http_navigation, credential_use). It now uses the Timeline's lane names from one shared table (LANE_LABEL_KEYS / agentTypeLabel); the stored name is the tooltip, and a plugin type with no lane keeps its own name. The status-bar clock counts from the project's creation — deliberately, per audit P1 #33 — but next to REC it read as this session's recording time. It keeps its meaning and now says it: tooltip and aria-label name the creation date and "not this session". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
guan4tou2
added a commit
that referenced
this pull request
Oct 8, 2026
Seven P1 findings from the UI/UX audit, batched: • #15 HUD auto-collapse now pauses while the pointer is on the overlay (audit was: hard 8s timer, no way to keep it open while reading the topology chain / Reveal button). • #16 Terminal tab labels ("Shell 1", "Shell 2" …) used tabs.length + 1 → duplicated after any close. Now uses a monotonic counter. • #17 Closing a terminal tab kills the PTY silently. Now confirms via ConfirmDialog when the tab is still alive (matches ProjectPicker delete pattern). • #21 Settings CDP test callback had a `const tab = ...` shadowing the outer `tab` state (settings tab name). Renamed to `cdpTab`. • #28-29 EventMarker showed raw enum strings ("info" / "initial_access") for severity + category — now i18n'd (marker.severity.*, marker. category.*). Also added an opt-out "Capture screenshot too" checkbox (default on) so a mark taken over sensitive UI doesn't force a capture. • #30 EventMarker gained role="dialog", aria-modal, aria-label, and an Escape-to-close handler on the backdrop. Autofocus lands on the dialog body so keyboard users have a hook. • #32 App title-bar Mark button title="Ctrl+Shift+M" was hardcoded — Mac users saw the wrong hint. Uses isMac to pick ⌘⇧M vs Ctrl+Shift+M. Deferred (need bigger refactors): #9-14/#49-50 shared IPC store to stop per-event refetches across StatusBar/Sidebar/Dashboard/LootPanel/TargetView/ ScopeStatus; #22-24 sidebar keyboard drag; #25-27 FindingsView/SearchPanel/ LootPanel interactive; #33 uptime should be engagement-scoped not window- scoped; #34 StatusBar record toggle button styling; #37-38 timeline layout constraints. All queued for the next batch. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
guan4tou2
added a commit
that referenced
this pull request
Oct 8, 2026
…ocus • #25 FindingsView CDP poll now backs off from 3s → 10s while the browser isn't running. Was hitting IPC every 3s regardless. • #26 Mark URLs (both the primary and the auto-captured browserUrl) now open in the operator's real browser via app.openExternal — was inert plain text before. New http/https-only openExternal IPC (rejects file: and other schemes so untrusted content can't dispatch side effects). • #27 SearchPanel results are clickable — click jumps to the event on the Timeline via the existing focusEvent flow. Also dropped the q<2 gate to q<1 so single-char IPs/octets work. • #37 Cluster popover now flips ABOVE the cluster when the natural position would drop it off the bottom of the timeline (last-lane clusters). • #39 Recent-project delete ✕ now shows on focus, not only hover — keyboard users can reach it. Also gained a focus ring. • #47 Timeline zoom-reset button gained a ↺ glyph so the click-to-reset behaviour is discoverable (was just the percentage number), plus is disabled at 100% and has aria-label + focus ring. New i18n keys: marks.openUrl, search.openInTimeline (en + zh-TW). Deferred (still queued): #24 already fixed by v0.6.29's shortcut order change; #33 uptime → engagement start; #38 timeline layout with detail panel; #48 MCP UI stdio vs http. Bigger P1s (#9-14, #49-50 shared IPC store) and P2 shared-component extractions still need dedicated design. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
guan4tou2
added a commit
that referenced
this pull request
Oct 8, 2026
• #33 StatusBar uptime is now engagement-scoped: reads project.active() createdAt instead of window-open Date.now(). Closing the app mid-op and reopening no longer resets the counter — the timeline matches what "uptime" says. Also extended the project.active IPC to include createdAt (with a matching env.d.ts type bump). • #41 (partial) Screenshots + Loot cards gained role="button", tabIndex, aria-label, Enter/Space key handlers, and a focus-visible ring. Grid views are keyboard-navigable now. • #30/#40 (screenshot expanded overlay) got role="dialog", aria-modal, aria-label, autofocus, Escape-to-close — was click-only before. TargetView cards still need the same keyboard-nav pass; queued for the next batch alongside StatusBar sep buttons and Overlay ▲/▼/✕. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
guan4tou2
added a commit
that referenced
this pull request
Oct 8, 2026
Second-pass audit (81 findings) shortlisted three P0 bugs. All fixed: • #33 TargetView in-scope / out-of-scope filter always returned empty. Every entry's `inScope` was set to null and never populated; both filter chips compared === true/false, so they always yielded zero results while "All" worked. Compute inScope client-side by matching each target against the current scope config (wildcard subdomains + CIDR + exact). Reclassify when the scope config changes. Also extended the source query from shell-only to all events (audit finding #34) — screenshot / http_navigation / loot events with a detectedTarget now surface here too. • #1 Timeline reveal state was sticky across the session. `revealedEvents` Set only shrank when the user clicked Hide — leaving and coming back kept everything unmasked. Now the set clears on every selectedEvent.id change, so mask-by-default holds. • #2 Copy JSON always dumped raw bytes regardless of what the panel was showing. Now respects the reveal state: masked panel → masked clipboard, revealed panel → raw clipboard. New toast tells the user which they got. • #43 CDP port had TWO controls: a separate FieldGroup with local `cdpPort` state (bypassed auto-save entirely) plus BrowserPanel's `config.browser. cdpPort` field that did save. Users editing one thought they'd changed both. Removed the standalone Field + local state; the Test Connection button now reads from config.browser.cdpPort like everything else. Second-pass audit produced 81 findings across 14 feature areas; these are the three called out as P0. Batches of P1/friction items to follow. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
guan4tou2
added a commit
that referenced
this pull request
Oct 8, 2026
docs: a handover for whoever picks this up
guan4tou2
added a commit
that referenced
this pull request
Oct 8, 2026
…ock counts Spec 034. Settings search matched page names only (#143 had relabelled the box "Filter categories…" to be honest about it). It now matches the text each page renders — group titles, field labels, hints — in the displayed language. Choosing a result opens its page and brings the text into view. The index is generated from the page sources (npm run gen:settings-search) and a test fails when a page renders a key the index lacks. The box says "Search settings…" again, and the IA test now allows that label only while the search is wired. The filter bar named types by storage name (http_navigation, credential_use). It now uses the Timeline's lane names from one shared table (LANE_LABEL_KEYS / agentTypeLabel); the stored name is the tooltip, and a plugin type with no lane keeps its own name. The status-bar clock counts from the project's creation — deliberately, per audit P1 #33 — but next to REC it read as this session's recording time. It keeps its meaning and now says it: tooltip and aria-label name the creation date and "not this session". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
Eight PRs (#25–#32) landed in this stretch. This adds
docs/HANDOVER-2026-09.md— the part a diff cannot carry.Where main stands, with the exact verification sequence including the native-module ABI swap that has to bracket the e2e run.
What the last eight PRs decided and why — the three core ones expanded: why a marker amendment is a new chained event rather than an UPDATE, why scope withdrawals are computed from the violation records rather than by rescanning (the logged tier is pruned, so a rescan leaves them standing forever), and why every looser unlock predicate in progressive disclosure makes some page lie.
What is still open, ordered by value ÷ risk, each with the reason it was deferred: the bookmark rename (blocked on aliasing three external contracts), bookmarks having no retention sweep at all, the bundle verifier never re-hashing
manifest["files"], the unimplemented scope-aware-lifecycle spec, andenv.d.tsstill being a hand-written mirror.The traps — the section I would most want handed to me. The ABI swap whose failure mode is unit tests skipping rather than failing. The temporal-dead-zone crash that only appears in the bundled build, which has bitten this tree three times and which vitest structurally cannot see. The two-tier tables. The source-scanning guards. And two mistakes of my own from this stretch, written down so the next person does not repeat them.
And the closed direction: PR #8 is archived as a tag, with the recovery commands and the reason it was closed on direction rather than staleness.
ROADMAP.md gets a staleness banner rather than a rewrite — it predates this work by five releases, and rewriting someone's planning document from the outside is worse than pointing at what is current. The docs index had been claiming v0.11.7.
Every relative link and code path in the new page resolves (checked).
🤖 Generated with Claude Code