Skip to content

feat: add the graph-web PWA - #39

Merged
Mearman merged 14 commits into
mainfrom
feat/graph-web
Oct 11, 2026
Merged

Mearman merged 14 commits into
mainfrom
feat/graph-web

Conversation

@Mearman

@Mearman Mearman commented Oct 11, 2026 •

Copy link
Copy Markdown
Member

Adds graph-web, the PWA target from phase 5 of the plan: a Vite app that wires the GitHub issues source (in the page, through the source contract's in-process oRPC client) to the SQLite wasm store (its own worker on OPFS opfs-sahpool, through the store contract's message-port client). It is a private workspace package and changes no release configuration.

The app picks scopes across organisations, syncs them page by page with progress, cancel and resume from a checkpoint kept on the device, and shows the model in every view through ProcessView, with the ready, blocked, critical path, hand-off, cycle and problem lists, the selected element's why, blockers and impact, filters, run state controls, a form for the command line's add, and expansion of the scope to a repository a dependency leads to. The address carries the view state (scope, view, list, select, status, actor, source, subject, step), so a link reproduces the view; the package README has the grammar.

The token is kept in local storage on the device, read only when a sync starts and sent only to api.github.com. The service worker precaches the shell and the SQLite wasm; a new version waits for the person to reload. Icons are rendered from one SVG at build time by build/icons.ts, so none is committed.

Two changes to the UI packages came out of building it: useGraphSelection and ProcessFlow take a selected the owner keeps, so the canvas, the lists and the address share one selection, and useModel shows a model the store does not have yet as missing and keeps following it, so the first sync of a scope appears without a reload.

The Playwright suite runs against vite preview of the production build, with GitHub's GraphQL API answered by a local fixture server that the browser's requests to api.github.com are routed to. It covers sync and the graph, the token reaching no other host, installability (Chromium's installability report, manifest, active service worker) without cross-origin isolation, an offline reload showing the last sync, a write in one tab showing in another, expansion on demand and a rate limit's reset time. CI runs it in the test job, in the Chromium already installed for the SQLite wasm browser tests.

With the GitHub source's Projects v2 scopes and scope listings from #38, a pasted board link becomes a github:owner/projects/N scope, and with a token the scope picker suggests the viewer's account, organisations and, on request, an owner's repositories.

Closes #40

@Mearman
Mearman marked this pull request as ready for review October 11, 2026 02:39
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 11, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
🔒 Security Review ✅ Completed 2026-10-11T04:36:43.553878Z f56e964 Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@Mearman

Mearman commented Oct 11, 2026

Copy link
Copy Markdown
Member Author

@codex security review

@chatgpt-codex-connector

Copy link
Copy Markdown

🛡️ Codex Security Review

Security review completed. No security issues were found in this pull request.

Reviewed commit: 9947750325

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

@Mearman

Mearman commented Oct 11, 2026

Copy link
Copy Markdown
Member Author

@codex security review

@chatgpt-codex-connector

Copy link
Copy Markdown

🛡️ Codex Security Review

Security review completed. No security issues were found in this pull request.

Reviewed commit: 9947750325

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

@Mearman

Mearman commented Oct 11, 2026

Copy link
Copy Markdown
Member Author

@codex security review

@chatgpt-codex-connector

Copy link
Copy Markdown

🛡️ Codex Security Review

Security review completed. No security issues were found in this pull request.

Reviewed commit: adf287939d

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

useGraphSelection takes a `selected` option: when the key is present the
hook reads the selection from it, keeps none of its own and only reports
through onChange what a click or key asks for. Several views of one model,
such as a canvas and a list, can then share one selection held by their
owner.
ProcessFlow, and so ProcessView, takes a `selected` prop passed to
useGraphSelection's option of the same name, so the canvas highlights the
selection an app holds in its address or shares with other views, and
reports the changes a click or key asks for through onSelect.
useModel shows a model whose load answers NOT_FOUND as `missing` and keeps
following it, so the write that creates it, such as the first sync of a
scope, or a save after a delete, loads it. Any other error still ends in
`failed`.
The web app, as a Vite PWA and a composition root: the GitHub issues source
runs in the page and the SQLite wasm store in its own worker on the origin
private file system, both reached through their contracts' oRPC clients.

It picks scopes across organisations, syncs them page by page with progress,
cancelling and resuming from a checkpoint kept on the device, and shows the
model in each view with the ready, blocked, critical path, hand-off, cycle
and problem lists, the selected element's why, blockers and impact, filters,
run state controls, a form to add records by hand and expansion of the scope
to a repository a dependency leads to. The address carries the view state,
so a link reproduces the view.

The token is kept in local storage on the device and sent only to GitHub's
API. The service worker precaches the shell and the SQLite wasm, so the last
sync renders offline, and a new version waits for the person to reload. The
icons are rendered from one SVG at build time, so none is committed.
Playwright drives the production build under vite preview, with GitHub's
GraphQL API answered by a local fixture server that the browser's requests
to api.github.com are routed to. The tests sync organisations across their
repositories, check the token reaches no other host, check installability
and the absence of cross-origin isolation, reload offline, write in one tab
and see it in another, expand the scope on demand and show a rate limit.

The root test:e2e script runs them through turbo after the build, and the CI
test job runs it in the Chromium it already installs for the SQLite wasm
store's browser tests.
Knip finds the page's module from index.html through its Vite plugin, so the
graph-web workspace names only the store's worker, the build script and the
Playwright suite as entries of their own.
The screen tests render the app with Testing Library over the store
contract's fake store and the source contract's fake source, each called
through its oRPC client, laid out by a stub engine: the token, scope, sync
(progress, cancel, resume from the device's record), notices, theme, view,
lists, details, filters, adding by hand and a model with an illegal cycle.
The sync, the browser ports and the icon renderer have their own tests.
A link can select an element that is not in the model, because the scope is
not synced yet or the issue has gone. The reasoning hooks throw on an
unknown element, so the details panel is only drawn for an element the model
declares, and the app says the selection is missing otherwise.
@Mearman

Mearman commented Oct 11, 2026

Copy link
Copy Markdown
Member Author

@codex security review

1 similar comment
@Mearman

Mearman commented Oct 11, 2026

Copy link
Copy Markdown
Member Author

@codex security review

@chatgpt-codex-connector

Copy link
Copy Markdown

🛡️ Codex Security Review

Security review completed. No security issues were found in this pull request.

Reviewed commit: 63a37d380e

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

The source now selects `blocking` beside `blockedBy` on every issue, lists
issues by state, label and order variables, selects each repository's
description, URL and archived flag, and reads Projects v2 items and the
viewer's organisations. The fixture still answered the older shapes, so the
source refused the owner listing at its own parse and every sync stopped
before its first page. The fixture now answers every query the source
sends, with `blocking` as the inverse of `blockedBy` and the listing
narrowed by the states it is asked for.
A github.com/orgs/<owner>/projects/<n> or /users/<owner>/projects/<n>
address, with any view after it, becomes the source's
github:<owner>/projects/<n> scope, and owner/projects/<n> is read as one too.

Closes #40
With a token saved and the page online, the scope picker offers the
viewer's account and organisations from the source's scopes.roots, and an
owner's repositories from scopes.children, a page at a time and only when
asked for, marking archived ones and leaving out scopes already chosen. The
token is read for each listing and handed straight to the source, as a sync
does.

The end-to-end suite also syncs a Projects v2 board pasted as its link.
@Mearman

Mearman commented Oct 11, 2026

Copy link
Copy Markdown
Member Author

@codex security review

1 similar comment
@Mearman

Mearman commented Oct 11, 2026

Copy link
Copy Markdown
Member Author

@codex security review

@chatgpt-codex-connector

Copy link
Copy Markdown

🛡️ Codex Security Review

Security review completed. No security issues were found in this pull request.

Reviewed commit: f56e964e4d

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

@Mearman
Mearman merged commit d43f601 into main Oct 11, 2026
@Mearman
Mearman deleted the feat/graph-web branch October 11, 2026 05:02
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.

Read GitHub Projects v2 boards as a source scope

1 participant