(MOT-4257) feat(github,console): github page as injectable activity view - #609
Conversation
Move the github page from console-native to the github worker's ui/,
following the injectable-console-ui SOP (state/database precedent). The
page now ships into every running console at runtime as #/ext/github and
appears in the nav whenever the github worker is connected, via the same
ext-pages mechanism the database and iii-directory workers already use.
github/ui/:
- page.tsx setup(host) registers the github page (owner/name input plus
the pull-requests, issues, runs, releases, and search panels). Panels
read github::* over host.iii.trigger and unwrap the worker's { value }
envelope; function ids and payloads are kept verbatim from the console
wrappers. Components are named imports from @iii-dev/console-ui; icons
are hand-drawn inline SVG (no lucide-react); the segmented control is a
local ModeToggle.
- styles.css scopes every rule under [data-iii-ui="github"] and colors
from the console design tokens.
- build.mjs / package.json / tsconfig.json esbuild scaffold with the five
shared specifiers external (react family + @iii-dev/console-ui).
github worker (Rust):
- src/ui.rs registers the two assets through the iii-console-ui crate
(ConsoleUi::new("github")), embedded via include_str! and called from
main.rs after the github::* functions register.
- build.rs builds ui/ (respects SKIP_UI_BUILD=1); iii-console-ui path dep
added to Cargo.toml; the client is Arc-wrapped for the UI watcher.
console cleanup:
- delete src/pages/Github/, lib/github.ts, and use-github-status (the
presence hook only served the page).
- remove the github nav entry, hash route, and githubAvailable plumbing
from App.tsx, nav-options, use-hash-route, and conversations-context.
- chat function-call renderers are untouched (none exist on this branch).
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
skill-check — worker0 verified, 49 skipped (no docs/).
Four for four. Nicely done. |
|
Warning Review limit reached
Next review available in: 44 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (5)
📝 WalkthroughWalkthroughThe legacy console GitHub route and availability plumbing are removed. The GitHub worker now builds and registers an injectable UI with a live call-event feed, git graph, expandable result previews, and scoped styling. ChangesGitHub UI migration
Estimated code review effort: 4 (Complex) | ~60 minutes Possibly related PRs
Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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 |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@github/build.rs`:
- Around line 13-24: Add SKIP_UI_BUILD to the Cargo rerun inputs in main, using
cargo:rerun-if-env-changed alongside the existing rerun directives so changes to
that environment variable rerun the build script and refresh embedded UI assets.
In `@github/ui/src/page/index.tsx`:
- Around line 38-41: Stop using the refresh counter to force-remount the active
panel via the key in the page render flow. Thread a refresh signal or callback
from the refresh control through the panel components, including SearchPanel,
PrsPanel, and IssuesPanel, and invoke each panel’s useGithubRead refresh()
closure so data refetches while preserving query, filter, and expanded-row
state.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 7f3cac6f-6a76-47e3-9052-4783ac378b7e
⛔ Files ignored due to path filters (2)
github/Cargo.lockis excluded by!**/*.lockpnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (31)
console/web/src/App.tsxconsole/web/src/hooks/use-github-status.test.tsconsole/web/src/hooks/use-github-status.tsconsole/web/src/hooks/use-hash-route.tsconsole/web/src/lib/conversations-context.tsxconsole/web/src/lib/github.test.tsconsole/web/src/lib/nav-options.test.tsconsole/web/src/lib/nav-options.tsconsole/web/src/pages/Github/index.tsxgithub/Cargo.tomlgithub/build.rsgithub/src/lib.rsgithub/src/main.rsgithub/src/ui.rsgithub/ui/build.mjsgithub/ui/package.jsongithub/ui/page.tsxgithub/ui/src/page/IssuesPanel.tsxgithub/ui/src/page/ModeToggle.tsxgithub/ui/src/page/PanelShell.tsxgithub/ui/src/page/PrsPanel.tsxgithub/ui/src/page/ReleasesPanel.tsxgithub/ui/src/page/RunsPanel.tsxgithub/ui/src/page/SearchPanel.tsxgithub/ui/src/page/github-data.tsgithub/ui/src/page/icons.tsxgithub/ui/src/page/index.tsxgithub/ui/src/page/useGithubRead.tsgithub/ui/styles.cssgithub/ui/tsconfig.jsonpnpm-workspace.yaml
💤 Files with no reviewable changes (7)
- console/web/src/hooks/use-github-status.test.ts
- console/web/src/pages/Github/index.tsx
- console/web/src/hooks/use-github-status.ts
- console/web/src/lib/nav-options.ts
- console/web/src/lib/github.test.ts
- console/web/src/lib/conversations-context.tsx
- console/web/src/hooks/use-hash-route.ts
|
@coderabbitai review |
✅ Action performedReview finished.
|
There was a problem hiding this comment.
Actionable comments posted: 6
🧹 Nitpick comments (3)
github/ui/src/page/index.tsx (1)
137-179: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win
<tr role="button">overrides native row semantics.The row keeps
<td>children but overrides its implicit "row" role to "button," which can break table navigation semantics for screen readers. Consider keeping the row's native role and moving the interactive semantics to a focusable element inside a cell (e.g., a full-width button in the first<td>), while the<tr>retainsrole="row".🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@github/ui/src/page/index.tsx` around lines 137 - 179, Update ActivityRow so the <tr> retains native table semantics (role="row" or no explicit role) and is not itself focusable or interactive. Move the click, keyboard, focus, and expanded-state behavior to a focusable full-width button inside the first cell, preserving onToggle behavior and the existing row contents.github/ui/src/page/GitGraph.tsx (2)
424-451: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick winUnbounded
git showdiff rendered without a size cap.
CommitDetailfeeds a raw, un-truncated (beyond the shell worker's own general cap) diff intoDiffView, which renders one<div>per line with no cap — a large commit could produce a very large DOM. Shares one root cause withresult-views.tsxDiffView; see the consolidated comment.Also applies to: 462-469
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@github/ui/src/page/GitGraph.tsx` around lines 424 - 451, Cap the git show output before CommitDetail passes it to DiffView, using the existing truncation handling and a defined maximum size so large commits cannot create an unbounded DOM. Update the success path in the useEffect around host.trigger and the corresponding CommitDetail rendering path, while preserving status, error, and truncated-result behavior.
424-469: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick winUnbounded
git showdiff rendered through a renderer sized for small, budgeted previews.DiffViewwas designed for the worker's small,PREVIEW_MAX_BYTES-cappedresult_preview(perresult-views.tsx's file header), butGitGraph.tsx'sCommitDetailis the only caller feeding it a rawgit show --stat --patchdiff bounded only by the shell worker's own general truncation — a large commit could render thousands of uncapped<div>lines.
github/ui/src/page/GitGraph.tsx#L424-L469: cap or truncatetextclient-side (e.g., first N lines) before passing it toResultView, or request a smaller/paginated diff from the shell worker.github/ui/src/page/result-views.tsx#L195-L211: add a defensive line cap insideDiffViewitself (with a "…truncated" marker, mirroring the existingtruncatedflag handling) so any caller is protected regardless of input size.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@github/ui/src/page/GitGraph.tsx` around lines 424 - 469, Cap the raw git show output in CommitDetail before passing it to ResultView, and add a defensive line cap in DiffView with a visible “…truncated” marker while preserving the existing truncated flag behavior. Apply the caller change in github/ui/src/page/GitGraph.tsx at lines 424-469 and the renderer safeguard in github/ui/src/page/result-views.tsx at lines 195-211.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@github/src/events.rs`:
- Around line 339-347: Update preview_list and the related preview handling
around the referenced lines to enforce PREVIEW_MAX_BYTES as an aggregate
serialized-byte budget, stopping before adding another projected item once the
budget is exhausted. Preserve the total count and existing item projection
rules, while ensuring the returned list preview remains within the documented 6
KB limit.
- Around line 157-186: Detach the fan-out from the real call in run_and_emit by
spawning emit without awaiting it, and return result immediately. Preserve
emit’s existing subscriber discovery, serialization, and warning behavior;
ensure the detached task owns the event/emitter data it needs so slow or wedged
subscribers cannot delay or fail the caller.
- Around line 584-623: Update summarize_args to recognize inline-value forms for
--body=, --body-file=, --input=, --field=, --raw-field=, and --json= before the
fallback arm, preserving field keys while redacting values and redacting
body/input values entirely. Update repo_from_args to return the suffix from
--repo= using strip_prefix, while preserving existing separate-argument
handling.
In `@github/ui/src/page/GitGraph.tsx`:
- Around line 369-386: Update the keydown handlers in CommitRow in
github/ui/src/page/GitGraph.tsx (lines 369-386) and the corresponding handler in
github/ui/src/page/index.tsx (lines 137-153) to use the native DOM KeyboardEvent
type, or explicitly import React’s event type with a type-only import. Keep the
existing Enter and Space handling unchanged.
In `@github/ui/styles.css`:
- Around line 208-211: Replace the deprecated word-break: break-word
declarations in the .gh-rv-title and the other flagged GitHub UI selectors with
the supported overflow-wrap: anywhere behavior, preserving the existing
text-wrapping intent.
- Around line 90-96: Update the `.gh-feed-args` and `.gh-feed-status` table-cell
styles to retain `display: table-cell` (or the existing table-cell behavior)
instead of `display: flex`; move the flex layout properties to inner wrapper
elements around each cell’s contents, preserving the existing alignment, gap,
and overflow behavior.
---
Nitpick comments:
In `@github/ui/src/page/GitGraph.tsx`:
- Around line 424-451: Cap the git show output before CommitDetail passes it to
DiffView, using the existing truncation handling and a defined maximum size so
large commits cannot create an unbounded DOM. Update the success path in the
useEffect around host.trigger and the corresponding CommitDetail rendering path,
while preserving status, error, and truncated-result behavior.
- Around line 424-469: Cap the raw git show output in CommitDetail before
passing it to ResultView, and add a defensive line cap in DiffView with a
visible “…truncated” marker while preserving the existing truncated flag
behavior. Apply the caller change in github/ui/src/page/GitGraph.tsx at lines
424-469 and the renderer safeguard in github/ui/src/page/result-views.tsx at
lines 195-211.
In `@github/ui/src/page/index.tsx`:
- Around line 137-179: Update ActivityRow so the <tr> retains native table
semantics (role="row" or no explicit role) and is not itself focusable or
interactive. Move the click, keyboard, focus, and expanded-state behavior to a
focusable full-width button inside the first cell, preserving onToggle behavior
and the existing row contents.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 9afe3857-4e17-4a63-b1a0-56c767cd1f9d
⛔ Files ignored due to path filters (1)
github/Cargo.lockis excluded by!**/*.lock
📒 Files selected for processing (19)
github/Cargo.tomlgithub/build.rsgithub/src/events.rsgithub/src/functions/mod.rsgithub/src/functions/passthrough.rsgithub/src/lib.rsgithub/src/main.rsgithub/src/ui.rsgithub/ui/page.tsxgithub/ui/src/page/GitGraph.tsxgithub/ui/src/page/GithubPage.tsxgithub/ui/src/page/events.tsgithub/ui/src/page/format.tsgithub/ui/src/page/graph-layout.test.tsgithub/ui/src/page/graph-layout.tsgithub/ui/src/page/icons.tsxgithub/ui/src/page/index.tsxgithub/ui/src/page/result-views.tsxgithub/ui/styles.css
🚧 Files skipped from review as they are similar to previous changes (5)
- github/Cargo.toml
- github/src/lib.rs
- github/ui/page.tsx
- github/src/ui.rs
- github/build.rs
…e-ui # Conflicts: # console/web/src/App.tsx # console/web/src/hooks/use-hash-route.ts # console/web/src/lib/nav-options.test.ts # console/web/src/lib/nav-options.ts # pnpm-lock.yaml # pnpm-workspace.yaml
|
@coderabbitai review |
✅ Action performedReview finished.
|
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@console/web/src/hooks/use-hash-route.ts`:
- Around line 141-146: Move the normalizeExtHash/replaceHash logic from the
mount-only path into the hashchange handler so every navigation event rewrites
legacy hashes such as `#/github` to the corresponding `#/ext/`<id> URL. Preserve the
existing normalized view-state resolution and avoid relying solely on the
initial mount normalization.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 11180496-174b-4f94-8b1f-7a772d195791
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (7)
console/web/src/App.tsxconsole/web/src/hooks/use-hash-route.test.tsconsole/web/src/hooks/use-hash-route.tsconsole/web/src/lib/conversations-context.tsxconsole/web/src/lib/nav-options.test.tsconsole/web/src/lib/nav-options.tspnpm-workspace.yaml
💤 Files with no reviewable changes (1)
- console/web/src/lib/conversations-context.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
- pnpm-workspace.yaml
- console/web/src/App.tsx
| // Rewrite a legacy migrated hash (`#/worktrees`, `#/memory`, `#/browser`, | ||
| // `#/github`) to its `#/ext/<id>` form so the URL bar matches the resolved | ||
| // page. The view | ||
| // state already used the normalized hash, so this is cosmetic. | ||
| const normalized = normalizeExtHash(window.location.hash) | ||
| if (normalized !== window.location.hash) replaceHash(normalized) |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Normalize migrated hashes on every hash change.
The rewrite runs only on mount. Later navigation to #/github resolves the ext view but leaves the legacy hash in the URL bar. Move normalization into the hashchange handler too.
Proposed fix
useEffect(() => {
- const normalized = normalizeExtHash(window.location.hash)
- if (normalized !== window.location.hash) replaceHash(normalized)
- const handle = () => {
- const next = routeFromHash(window.location.hash)
+ const handle = () => {
+ const normalized = normalizeExtHash(window.location.hash)
+ if (normalized !== window.location.hash) replaceHash(normalized)
+ const next = routeFromHash(normalized)
if (next !== null && next !== viewRef.current) setView(next)
}
+ handle()
window.addEventListener('hashchange', handle)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| // Rewrite a legacy migrated hash (`#/worktrees`, `#/memory`, `#/browser`, | |
| // `#/github`) to its `#/ext/<id>` form so the URL bar matches the resolved | |
| // page. The view | |
| // state already used the normalized hash, so this is cosmetic. | |
| const normalized = normalizeExtHash(window.location.hash) | |
| if (normalized !== window.location.hash) replaceHash(normalized) | |
| const handle = () => { | |
| const normalized = normalizeExtHash(window.location.hash) | |
| if (normalized !== window.location.hash) replaceHash(normalized) | |
| const next = routeFromHash(normalized) | |
| if (next !== null && next !== viewRef.current) setView(next) | |
| } | |
| handle() |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@console/web/src/hooks/use-hash-route.ts` around lines 141 - 146, Move the
normalizeExtHash/replaceHash logic from the mount-only path into the hashchange
handler so every navigation event rewrites legacy hashes such as `#/github` to the
corresponding `#/ext/`<id> URL. Preserve the existing normalized view-state
resolution and avoid relying solely on the initial mount normalization.
Address CodeRabbit review on PR #609: redact inline --flag=value args (body/field/input) and recognize --repo= inline; enforce an aggregate byte budget on list previews; cap DiffView rendering at 500 lines; use type-only KeyboardEvent imports; move flex off table cells to inner wrappers; replace deprecated word-break: break-word with overflow-wrap: anywhere.
What
Moves the github page to an injectable UI shipped by the github worker (per
docs/sops/injectable-console-ui.md, state worker as the reference), and reworks it from the standalone owner/name browsing into a live activity feed of what the agent actually does with github. First of the console injectable-UI migration (MOT-4256): the console becomes a thin host with no per-worker UI.Worker:
github::calledeventsgithub/src/events.rs: after every github function runs, the worker fires a fire-and-forgetgithub::calledevent (registered as a trigger type viaregister_trigger_type+ aSubscriberSet, matching theiii-directory/browserevent pattern). PayloadCalledEvent { function_id, args_summary, repo, ok, duration_ms, result_summary, timestamp }.summarize(function_id, result)derives a short human result (e.g. "3 pull requests", "exit 0, 1.2 KB out", a created URL, "N B diff"), bounded to 512 chars.args_summaryechoes the gh argv with--body/--input/-fvalues redacted (the auth token never rides argv).run_and_emitthreads through the three generic register helpers + passthrough, so all 32 functions are wrapped with no per-handler edits and no behavior/response change. 9 unit tests (summarize variants, arg redaction, and that emission preserves the wrapped return).Injectable page: activity feed
Prs/Issues/Runs/Releases/Search/PanelShell,github-data.ts,useGithubRead.ts,ModeToggle).src/page/index.tsxrewritten: one tab-scopedgithub::calledsubscription (registerTrigger({ type, function_id: EVENTS_FN::browserId }) + on(...), the state-worker idiom), a bounded newest-first list (cap 200), a row per call (function-id badge, arg echo + repo, ok/error + duration, relative timestamp; click to expand the result summary), plus clear + live/paused.@iii-dev/console-uicomponents only.styles.cssrescoped to the activity classes under[data-iii-ui="github"].Verification
tsc -bexit 0. Console purged of the github page (pages/Github/,lib/github.ts,use-github-status, nav/routing all removed).cargo:rerun-if-env-changed=SKIP_UI_BUILDinbuild.rs.Follow-up
Repo diffs via the shell worker (show a fetched repo's diff in the feed) land as a fast-follow. Closes MOT-4257.
Summary by CodeRabbit