Skip to content

Native picker data injection: global boards as native GitHub UI (spec 008, v0.7.0) - #15

Merged
BigLep merged 16 commits into
mainfrom
008-native-picker-data-injection
Aug 21, 2026
Merged

Native picker data injection: global boards as native GitHub UI (spec 008, v0.7.0)#15
BigLep merged 16 commits into
mainfrom
008-native-picker-data-injection

Conversation

@BigLep

@BigLep BigLep commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

Summary

Replaces the custom global-boards picker UI (spec 006) with data-layer interception, so GitHub renders everything itself. Configured global boards (canonically the FilOzone FOC board) appear and behave as native rows in GitHub's own Projects picker and Projects section on repos outside the board's org.

  • Issue pages: full native parity (FR-011). A document_start main-world injector augments the /_ghui/item-pickers/projects feed, seeds GitHub's IndexedDB picker cache for first-open correctness, and commits an enriched membership edge into the page's Relay store. Result: native picker row with correct checked state, native add AND remove via GitHub's own cookie-authenticated mutations (verified accepted cross-org), and a native project card in the Projects section with collapsed Status, expandable field list (fetched by GitHub itself), and native field editing.
  • Legacy PR pages. The picker renders natively via projects_suggestions feed augmentation; because GitHub's legacy toggle endpoint silently ignores cross-org ids, the extension intercepts the form POST and performs add/remove via its existing GraphQL path. The FOC field card remains on PR pages only (GitHub cannot render cross-org boards there) and stays in sync via a membership hint.
  • Same-org boards are out of scope everywhere: skipped at every layer, GitHub handles them natively. FilOzone/* removed from the proactive defaults.
  • Retired: global-boards-picker.ts, the custom dialog section / PR fourth tab, and their CSS (~370 lines deleted); the DOM-anchoring workarounds documented in github-page-layout.md go with them.

Robustness measures (all fail-open to untouched native behavior)

  • Membership hint protocol: GitHub's board-items search index lags mutations by minutes (measured up to ~20 min), so post-mutation state is trusted from the mutation response (per-tab sessionStorage, 30 min TTL) instead of re-queried. The queries that would avoid this do not exist or are cross-org-filtered; documented in specs/008-native-picker-data-injection/research.md.
  • Capture-and-cache for the ProjectItemSectionFieldListQuery persisted-query hash (survives GitHub hash rotation; self-heals on any project card expansion).
  • Retry with backoff for transient config/membership resolution failures (rate-limit bursts), plus dedupe of concurrent membership lookups (one REST scan per page instead of two).

Manifest smoke checklist (constitution I/IV)

  • New content script native-picker.js at document_start matching https://github.com/* — wider than issue/PR patterns because Turbo soft-navigates from issue lists into issue pages in one JS context; justification in specs/008-native-picker-data-injection/plan.md. Loader is dormant off issue/PR pages.
  • New web_accessible_resources entry: native-picker-injector.js (main-world script, same pattern as board-data-injector.js).
  • No new host permissions, API scopes, or OAuth changes. Version bumped to 0.7.0.

Verification

Manual per quickstart (specs/008-native-picker-data-injection/quickstart.md, results recorded inside): V1-V8 pass on the canonical test URLs (docs/canonical-test-urls.md, refreshed in this PR: scenarios 4/6 now use BigLep/.github fixtures with write access; column renamed to "On FOC board"). All test mutations were reverted; board state is canonical. npm run build and npm run typecheck clean.

Docs updated: canonical terminology section and data-layer reference in docs/github-page-layout.md, support matrix and open-issues list in docs/global-boards-picker-status.md, full research trail in specs/008-native-picker-data-injection/.

🤖 Generated with Claude Code

BigLep and others added 16 commits August 19, 2026 13:04
Investigation + PoC (2026-08-19): inject global boards into GitHub's own
picker data feeds instead of rendering custom UI. Issue pages validated
end to end (native render, cross-org native add, native sidebar display);
PR legacy pages render natively but need extension-performed mutations.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… v0.16.5 template

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…uickstart

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…points

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ode)

New document_start content script + main-world injector that augments
GitHub's picker feeds with configured global boards: item-pickers feed
and IssueViewerViewQuery on issues (plus Relay store membership commit
and IndexedDB persister seeding), projects_suggestions and sidebar form
POST delegation on legacy PR pages. Native mutations on injected rows
are observed to keep membership state coherent. All paths fail open.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…tics; docs

Live validation (quickstart V1-V8) on canonical URLs via isolated dev
Chrome: native render, cross-org native add AND delete on issues, Relay
membership commit after reload (with hydration retry), PR picker render
plus delegated add/remove. Fixes from validation: Relay environment
discovery via react-app reactRoot container key with iterative walk;
legacy PR form serializes every listed project with the value carrying
state (on/empty). Custom picker UI (global-boards-picker.ts, CSS block,
issue-sidebar wiring) removed; docs updated (page layout data-layer
section, picker status, AGENT.md).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…rg; drop FilOzone/* from proactive defaults

Same-org invariant now enforced in the injector's config handler (single
choke point) in addition to the content-script filter. FilOzone/* removed
from DEFAULT_TARGET_REPOS: the FOC board lives in that org, so native
GitHub UI already covers membership there.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The committed Relay edge is now enriched with the board's Status field
definition and the item's Status value, fetched via GitHub's own
ProjectItemSectionFieldListQuery (node-by-id, served cross-org over
session cookies). Result: the injected project card renders identically
to same-org boards — collapsed Status row, expandable field list that
GitHub lazily fetches itself, and native field editing
(updateProjectItemFieldValueMutation, verified accepted cross-org with
change+revert on solstice#9).

Cleanups per user direction: FOC field card no longer renders on issue
pages (legacy PR pages keep it, where GitHub cannot show cross-org
boards); IssueViewerViewQuery response augmentation removed in favor of
the single Relay-commit mechanism; canonical terminology section added
to docs/github-page-layout.md (Projects section / project card /
Projects picker / FOC field card).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…n issue/PR pages

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… document fragments-vs-queries rationale

The injector now harvests the current ProjectItemSectionFieldListQuery
hash from GitHub's own requests (fired on any project card expansion,
observed even while dormant) into localStorage, and Status enrichment
tries the cached hash before the hardcoded seed. A rotation therefore
self-heals after one organic card expansion; until then only the
collapsed Status row is omitted, with a console warning.

Docs: research.md gains 'Why the extension must source the collapsed
Status itself', explaining Relay fragment-backed (read-only) vs
query-backed (self-fetching) components and why the spec 007
invalidate-and-refetch trick cannot work here (IssueViewerViewQuery
responses are server-filtered on every request, so a refetch can never
deliver the cross-org edge). Layout doc and status doc updated to match.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… rename column to 'On FOC board'; compact tables

go-fil-commp-hashhash is in filecoin-project and therefore proactive, so
it cannot serve as the scenario 4 fixture, and frisbii is read-only for
the team, so it moves to a dedicated read-only-viewer fixture note.
Scenarios 4 and 6 now use BigLep/.github items (4/5 verified on the FOC
board, 6/7 verified off it). Tables normalized to compact pipes without
column padding; fixes two formatter regressions (corrupted ipld org
name, inverted markdown link).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…otocol); document query limitations

GitHub's REST board-items search (?q=) answers from an eventually
consistent index that lags mutations by minutes in both directions,
and both GraphQL alternatives are unavailable: ProjectV2.items has no
server-side content filter, and the content-side projectItems
connection filters cross-org memberships out (presence proves
membership, absence proves nothing). A full items scan was rejected on
cost (thousands of items, worst case paid on every not-member check).

The delegated picker toggle therefore forwards its mutation result as
an authoritative hint via filoz:boards-changed detail; issue-sidebar
persists it per tab (sessionStorage, 5 min TTL) and passes it to
GET_PANEL_STATE, where the worker skips the REST search and resolves
field values live by item node id. Removal also clears the FOC field
card DOM immediately. Same-org boards ignore the hint: content-side
GraphQL is live and unfiltered there, hence authoritative on its own.

Verified live on filecoin-pin PR#1: add renders the card in ~5s, remove
clears it instantly, and a reload inside the index-lag window no longer
resurrects stale state. Full write-up in research.md ('Membership
resolution: the queries we wish we could run...') and the status doc.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…measured index lag

A global board in the same org as the viewed repo is GitHub's business:
it renders and manages membership natively, so the extension now skips
same-org everywhere instead of special-casing it. Deletes the same-org
GraphQL membership path (QUERY_NODE_PROJECT_ITEMS, matchProjectItem,
NodeWithItems), adds early skips in the card layer and both worker
resolvers, and makes the membership hint unconditional in the remaining
cross-org path. This also makes re-adding FilOzone/* to the proactive
defaults harmless if ever desired.

Hint TTL raised 5 -> 30 minutes: search index convergence was measured
taking up to ~20 minutes, so a couple-of-minutes TTL let stale search
results win again after expiry. Docs updated to match.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…mbership lookups

Opening many tabs at once (the canonical test URL set) can trip
GitHub's secondary rate limit; both the arming path
(GET_NATIVE_PICKER_BOARDS) and membership resolution
(GET_GLOBAL_BOARDS_STATE) were one-shot on failure, leaving a tab
permanently dormant (observed: solstice#9 missing its native FOC card,
BigLep/.github#4 dormant with an unchecked stale picker row). Both now
retry with backoff (15s/30s/45s, budget reset per page), and the worker
dedupes concurrent identical membership lookups so a proactive page
load costs one REST scan instead of two (card layer + picker layer).

Verified live: burst-reloading the open test tabs yields correct state
everywhere; the scenario 4 lazy flow works as designed (picker open
resolves membership, FOC shows checked, native card renders).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings August 21, 2026 21:43
@BigLep
BigLep requested a review from rjan90 as a code owner August 21, 2026 21:43
@FilOzzy FilOzzy added this to FOC Aug 21, 2026
@github-project-automation github-project-automation Bot moved this to 📌 Triage in FOC Aug 21, 2026

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR implements spec 008’s shift from an extension-rendered “global boards” picker UI to data-layer interception so GitHub renders global boards as native rows/cards, and it refreshes Spec Kit workflow assets used to generate and execute specs/plans/tasks. It also bumps the extension/package version to 0.7.0 and updates docs/manual validation guidance accordingly.

Changes:

  • Adds the native-picker injection pipeline (document_start content script + web-accessible main-world injector) and supporting types/caching hooks so GitHub’s own Projects picker/sidebar can display and mutate cross-org boards natively.
  • Retires the previous custom global-boards picker UI and associated CSS; updates sidebar logic to avoid duplicate UI on issue pages.
  • Updates specs/docs and Spec Kit workflow/templates/scripts to match the new “dash-syntax” commands and newer Spec Kit behaviors.

Reviewed changes

Copilot reviewed 73 out of 73 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
specs/008-native-picker-data-injection/tasks.md Task breakdown for spec 008 implementation and validation checkpoints
specs/008-native-picker-data-injection/spec.md Feature requirements, scenarios, and acceptance criteria for native injection
specs/008-native-picker-data-injection/quickstart.md Manual validation steps and recorded results for spec 008
specs/008-native-picker-data-injection/plan.md Technical plan for intercepting feeds/Relay/IDB and retiring custom UI
specs/008-native-picker-data-injection/data-model.md Data entities and cache/edge shapes used by native-picker injection
specs/008-native-picker-data-injection/contracts/messages.md Event/message contracts across isolated world ↔ main world ↔ service worker
specs/008-native-picker-data-injection/contracts/github-feeds.md Documented GitHub endpoints/payloads targeted by the injector
specs/008-native-picker-data-injection/checklists/requirements.md Spec quality checklist for the feature spec
scripts/build.mjs Builds new native-picker bundles into extension/dist/
package.json Version bump to 0.7.0
extension/src/styles/sidebar.css Removes CSS for the retired custom picker UI
extension/src/lib/queries.ts Extends project query fields; removes unused project-items query
extension/src/lib/project-config.ts Removes FilOzone/* from proactive defaults; keeps URL parsing helpers
extension/src/lib/messages.ts Adds types/messages used by native-picker configuration/membership hinting
extension/src/content/native-picker/idb-seeder.ts Seeds GitHub’s IndexedDB cache for first-open picker correctness
extension/src/content/native-picker/feed-shapes.ts Shared payload/type definitions for feed augmentation and events
extension/src/content/issue-sidebar.ts Removes custom picker wiring; adds membership hint support; hides card on issues
extension/src/content/global-boards-picker.ts Deletes retired custom picker implementation
extension/manifest.json Adds native-picker.js content script and native-picker-injector.js WAR entry
docs/global-boards-picker-status.md Updates documentation to reflect native injection behavior and support matrix
docs/canonical-test-urls.md Refreshes canonical URLs and scenario matrix for manual validation
CONTRIBUTING.md Adds guidance for keeping Spec Kit integration files up to date
AGENT.md Expands dev-Chrome/CDP verification workflow and adds worktree-testing notes
.specify/workflows/workflow-registry.json Registers bundled Spec Kit workflow metadata
.specify/workflows/speckit/workflow.yml Adds the multi-step Spec Kit “full SDD cycle” workflow definition
.specify/templates/tasks-template.md Updates tasks template wording and command naming
.specify/templates/spec-template.md Formatting/whitespace cleanups in spec template
.specify/templates/plan-template.md Updates plan template references to dash-syntax commands
.specify/templates/checklist-template.md Updates checklist template semantics and command naming
.specify/scripts/bash/setup-tasks.sh New/updated helper to resolve task template and available docs
.specify/scripts/bash/setup-plan.sh Updates plan setup behavior (skip overwrite; improved template resolution)
.specify/scripts/bash/resolve-template.sh Adds template resolution helper for composed override stacks
.specify/scripts/bash/check-prerequisites.sh Adds --template, --paths-only no-persist behavior, and improved parsing
.specify/integrations/speckit.manifest.json Records installed Spec Kit integration assets/hashes
.specify/integrations/cursor-agent.manifest.json Records Cursor agent skill files/hashes installed by Spec Kit
.specify/integrations/claude.manifest.json Records Claude skill files/hashes installed by Spec Kit
.specify/integration.json Records current default integration configuration
.specify/feature.json Adds feature-directory pointer file (should be machine-local)
.specify/.gitignore Gitignores Spec Kit machine-local state such as feature.json
.cursor/skills/speckit-taskstoissues/SKILL.md Updates Cursor skill definition and workflow for tasks → issues
.cursor/skills/speckit-tasks/SKILL.md Updates Cursor skill definition for tasks generation
.cursor/skills/speckit-plan/SKILL.md Adds Cursor skill for planning workflow
.cursor/skills/speckit-implement/SKILL.md Updates Cursor skill for implementation workflow
.cursor/skills/speckit-constitution/SKILL.md Adds Cursor skill for constitution updates
.cursor/skills/speckit-checklist/SKILL.md Updates Cursor skill for custom checklist generation
.cursor/skills/speckit-analyze/SKILL.md Updates Cursor skill for cross-artifact analysis
.cursor/commands/speckit.taskstoissues.md Removes deprecated Cursor command file (replaced by skills)
.cursor/commands/speckit.plan.md Removes deprecated Cursor command file (replaced by skills)
.cursor/commands/speckit.constitution.md Removes deprecated Cursor command file (replaced by skills)
.claude/skills/speckit-taskstoissues/SKILL.md Adds/updates Claude skill definition for tasks → issues
.claude/skills/speckit-tasks/SKILL.md Adds/updates Claude skill definition for tasks generation
.claude/skills/speckit-plan/SKILL.md Adds Claude skill definition for planning workflow
.claude/skills/speckit-implement/SKILL.md Adds/updates Claude skill definition for implementation workflow
.claude/skills/speckit-constitution/SKILL.md Adds Claude skill definition for constitution updates
.claude/skills/speckit-checklist/SKILL.md Adds/updates Claude skill definition for custom checklist generation
.claude/skills/speckit-analyze/SKILL.md Adds/updates Claude skill definition for cross-artifact analysis
.claude/commands/speckit.taskstoissues.md Removes deprecated Claude command file (replaced by skills)
.claude/commands/speckit.plan.md Removes deprecated Claude command file (replaced by skills)
.claude/commands/speckit.constitution.md Removes deprecated Claude command file (replaced by skills)

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.


- Whether the repo lives in the **FilOzone** org (same org as the global FOC Projects v2 board).
- Whether the issue/PR is a **member of the global FOC project** on that board.
- Whether the issue/PR is a item is **on the global FOC board**.
## V4: Member issue, read-only correctness (cross-org, member)

1. Open `ipld/frisbii#170` (member; viewer may lack repo write access).
2. Expect: if GitHub shows no picker (no write access), the extension adds none; membership remains visible via the FOC card as today. No false checked/unchecked flash anywhere (FR-010).
Comment thread .specify/feature.json
Comment on lines +1 to +3
{
"feature_directory": "specs/008-native-picker-data-injection"
}
@BigLep BigLep closed this Aug 21, 2026
@github-project-automation github-project-automation Bot moved this from 📌 Triage to 🎉 Done in FOC Aug 21, 2026
@BigLep BigLep reopened this Aug 21, 2026
@github-project-automation github-project-automation Bot moved this from 🎉 Done to ⌨️ In Progress in FOC Aug 21, 2026
@BigLep
BigLep merged commit 7f8e23a into main Aug 21, 2026
4 checks passed
@github-project-automation github-project-automation Bot moved this from ⌨️ In Progress to 🎉 Done in FOC Aug 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: 🎉 Done

Development

Successfully merging this pull request may close these issues.

3 participants