Skip to content

feat(launcher): add a News tab and bundle the player Guide into Help - #540

Merged
Mat4m0 merged 5 commits into
feat/launcher-help-pagefrom
feat/launcher-guide
Nov 4, 2026
Merged

Mat4m0 merged 5 commits into
feat/launcher-help-pagefrom
feat/launcher-guide

Conversation

@Mat4m0

@Mat4m0 Mat4m0 commented Nov 3, 2026 •

Copy link
Copy Markdown
Owner

What changed

  • News tab. Every story opens as a full page in the launcher. The news modal is deleted. Home shows the five newest stories with an "All news" link.

  • Guild Wars Wiki updates load the page source of the five newest Feedback:Game updates/ pages in one request and convert it to Markdown. Before, the API returned full text for only one page per request, so most wiki stories had no body.

  • What's new. The release post whose launcherId matches the installed version is bundled. It opens once in News after an update, but not on a new install.

  • Help is for players who already have the app. The sidebar has two groups:

    • Get help: Known issues, Troubleshooting, Report a problem.
    • Features: Accounts and launcher, Hub and Switch Character, Travel and maps, Chat and trade, Inventory, Timers and readouts, Build templates, Appearance, Performance, Game files and updates.

    The pages are the website's Markdown, bundled at build time, so they match this version and work offline. The install and comparison pages stay on the website.

  • Guide links open a Settings control (settings:<section>/<control>, checked against the settings catalogue), another Guide page, or one of a short list of allowed websites through the new externalOpenUrl IPC.

  • Media placeholders. ::media-placeholder{type="image|video"} blocks mark the screenshots and videos still to make. They render as dashed boxes in the launcher and on the website.

  • Reading styles for Guide pages and articles: lines stop at about 75 characters, emphasis is semibold, link underlines are quieter, and key chips are smaller. Troubleshooting now uses one symptom heading per problem, and each fix starts with the action.

  • 2026.11.0 release notes (draft: true, so hidden on the website and skipped by the news generator until release). They list what changes for Stable users: ⌘R opens the Hub, Xunlai moved to ⌘S, one Settings page, and templates moved to the Build Library.

Why

Many players will move from Stable 2026.8.12 to the new launcher. They need to read what changed and how each feature works inside the app. A modal was the wrong place for long text, and the old Help pointed at an install guide they no longer need.

This change deletes NewsArticle.vue and the hand-written known-issues list in HelpView.vue. The website's 7.known-issues.md is now the only source for that list. News and the Guide share one Markdown subset parser (src/shared/launcher-markdown.ts).

Invariant

  • No address in news or the Guide is trusted. Every link goes through a resolver and becomes an opaque action ID: a main-process news-link-* ID, or guide:, settings: or url: with the origin allowlist re-checked in main by parseLauncherGuideUrl.
  • guide.test.ts fails if any Guide page is missing, or if any of its links or images does not resolve.

Delivery

Stacked on #537; target feat/launcher-help-page. Recommend shipping with 2026.11.0 (Beta, then Stable). Before Stable, remove draft: true from 13.gwonmac-2026-11-0.md.

5.templates.md and the release notes describe Template files in the Build Library. That feature is in #541, which should land in the same release.

Verification

  • pnpm run check passed. After the last change, which only touched reading styles and Troubleshooting copy, the launcher vitest suite (93) and tests/policy/source-ui-system.test.ts passed again.

  • Regression tests that fail without their fix:

    • The wiki body is parsed from page source.
    • A feed copy of the release notes opens its own links, not Guide links. This bug was found while testing this branch.
  • Browser check of the launcher preview at 1280×800 and 800×600:

    • the Help groups and feature pages, placeholders, and a Settings link;
    • the News list and reader, and a wiki article with "Open on Guild Wars Wiki".
  • The eight feature pages were checked against the code. All 83 settings: links resolve, and claims found only in older docs were dropped.

  • Not checked: the website rendering of MediaPlaceholder and ProseA. No live game QA.

  • I kept this pull request focused.

  • I ran the relevant checks.

  • I did not add game binaries, credentials, diagnostics, or private traffic.

  • I updated documentation when behavior or an invariant changed.

🤖 Generated with Claude Code

News is now a tab: every story opens as a full page instead of a modal.
Guild Wars Wiki updates load their full page source, and the installed
version's release notes open once after an update as What's new.

Help shows the website's Known issues, Troubleshooting and eight new
feature pages, bundled at build time so they match this version and work
offline. Guide links open Settings controls, other Guide pages, or an
allowlisted website. A shared Markdown subset parser serves news and the
Guide; ::media-placeholder blocks mark screenshots and videos still to make.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Mat4m0 and others added 4 commits November 3, 2026 13:00
ginko-content's render policy refuses any link that is not https, mailto,
tel, or relative, so every page with a `settings:` link failed to
prerender. Settings are now the inline component
`:setting[Label]{to="section/control"}`, which the launcher's parser reads as
before. Both Guide components are declared in the site's component policy,
mapped through `content.markdown.tags`, and registered globally; the ProseA
override never took effect and is deleted.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With News added, the tabs spilled under the Support pill at 900×640 and
200% zoom, so Help could not be clicked. The brand column now takes the
icon's width, and below 480px the tabs drop their icons; the labels stay.
The layout spec now walks Report a problem and a Guide page too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Mat4m0 added a commit that referenced this pull request Nov 3, 2026
## What changed

- Raise Electron to `^43.8.1`; it resolves to 43.8.6
(GHSA-jr5w-w6x2-84p9). This replaces #536.
- Move the undici overrides to the patched 7.30.1 and 8.12.2.
- Raise happy-dom to `^21.0.4` in the launcher and tools test setups. It
is a test-only DOM, and no app bundle ships it.
- Update the website's lockfile to patched vue-i18n / `@intlify` 11.4.17
and node-forge 1.4.2. These are named lockfile updates, so no new
overrides. The i18n build plugins stay at their current versions:
`@intlify/unplugin-vue-i18n` 11.2.8 breaks the website type check.
- Pin zod 4.6.7 and body-parser 2.4.0 through overrides. Nuxt DevTools
pins zod 4.4.3 exactly, and express keeps body-parser on 2.3.0.
- Remove the node-forge exception GHSA-86w9-cpqp-85rv from the audit
config and its policy test. node-forge 1.4.2 fixes it, which is the
removal condition the exception named.

## Why

Since these advisories were published, `runtime / static` fails at `pnpm
audit --audit-level=high` on `main` and on every open pull request
(#537, #539, #540, #541 and others). No code on `main` changed. Once
this lands, a PR only needs an update from `main`.

## Verification

- `pnpm audit --audit-level=high --ignore-registry-errors` exits 0. The
remaining high and critical findings are only the documented exceptions.
- `pnpm verify:static` passed: check, build, both kernel verifiers,
integration and release tests (1907 unit, 188 policy, 283 tools, 92
launcher, 120 integration, 30 release).
- `pnpm test:website` (type check, build, release-output invariants)
passed on a fresh install of this commit.
- `pnpm test:electron` locally: 182 of 184 passed on the first run. The
2 failures were focus-sensitive specs (`character-switch-background`,
`input-clipboard`) that fought my desktop for focus. On reruns
`input-clipboard` passed, and `character-switch-background` passed 18 of
18 with `--repeat-each=3`. The CI Electron and Hub e2e shards are the
authority here.

## Rollout

The shipped app changes only by the Electron patch release (43.7.6 →
43.8.6, same major). Everything else is test or website tooling. It goes
out with the next release (2026.11.0); no separate Beta is needed.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Mat4m0 added a commit that referenced this pull request Nov 4, 2026
## What changed

- New workflow `Retry runner shortages`
(`.github/workflows/retry-runner-shortage.yml`). When an Application
verification, client canary or client recertification run fails, it
checks why. If every failed or cancelled job was either cancelled with
"not acquired by Runner" or is the `verify / verify` gate that fails as
a result, it reruns the failed jobs. It stops after three attempts in
all.
- A short note under "GitHub enforcement" in
`docs/development-workflow.md`.

## Why

GitHub's macOS arm64 pool is short of machines. A job that waits too
long is cancelled, and `verify / verify` turns red although no test ran.
Since Nov 1 this has hit #539 (three manual reruns), #544, #537, #541,
both main runs (d6d046f, 70cb19f) and the client recertification.
Every case needed a manual `gh run rerun --failed`.

## Safety

- It never reruns a real failure. A failed test, a failed audit, a
failed install, or a cancellation for another reason (such as a newer
push) stops the retry.
- It reads job results and annotations only. It does not check out or
run PR code, so fork PRs are safe. Its permissions are `actions: write`
and `checks: read`.
- Versioned release is not covered; a release rerun stays a manual
decision.

## Verification

- `actionlint` passes. `pnpm test:policy` passes (188 tests).
- The run script was replayed against real runs from today, with the
rerun call replaced by an echo:

| Run | Situation | Result |
|---|---|---|
| 41663036291 (#544) | 3 jobs not acquired | rerun |
| 41622716010 (recertification) | derive not acquired | rerun |
| 41634472759 (#537) | 3 jobs not acquired | rerun |
| 41631535647 (#537) | audit + Electron shard failed | no rerun |
| 41612162024 (#537) | cancelled by a newer push | no rerun |
| 41643011855 (Dependabot) | install failed | no rerun |
| 41635280475 (#540) | audit failed + 1 not acquired | no rerun |
| invalid run ID | API 404 | step fails |

- Not verifiable before merge: a `workflow_run` workflow runs only from
the default branch. The first real shortage after merge is the live
test. If GitHub does not trigger `workflow_run` for a rerun started by
the workflow token, the limit is effectively two attempts instead of
three.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
@Mat4m0
Mat4m0 merged commit 0652047 into feat/launcher-help-page Nov 4, 2026
9 of 12 checks passed
@Mat4m0
Mat4m0 deleted the feat/launcher-guide branch November 4, 2026 14:26
Mat4m0 added a commit that referenced this pull request Nov 5, 2026
…esign system (#537)

This PR now also carries #540 (News tab and the player
Guide in Help), which was stacked on it. Both land as one squash commit
after one CI round. Part 1 is the original #537; part 2 is #540.

# Part 1: Help page and design system

### What changed

The launcher gets one Help page and one design system.

- **Help** replaces Known Issues and Feedback. It lists the open issues
in ArenaNet's official client with what players can do now (⌘Q → Reload
Guild Wars), explains how to tell a Mac issue from a client issue, and
has a feedback form. Main sends the form to Basin and the page confirms
only after Basin accepted it.
- **Funding bar removed.** `src/shared/funding.json` and the remote
fetch are gone. Support is a quiet Ko-fi pill in the title bar on every
page.
- **Design system.** `style.css` names every colour, radius, and type
size once in `:root`; components use only those tokens and one button
vocabulary (`.primary`, `.secondary`, `.quiet`, `.small`,
`.icon-button`, `.chip`). Documented in `DESIGN.md`.
- **Polish.** No eyebrow labels. Nav labels stay visible at narrow
widths. The title bar shows the gwonmac icon and name instead of the
Reforged logo. News rows carry a source mark (Guild Wars helmet, gwonmac
icon, event calendar).
- **Dailies are real.** `src/shared/daily-activities.ts` computes
Zaishen, Shining Blade, Vanguard, and Nicholas Sandford rotations
offline from Guild Wars Wiki anchors, with a 7-day table and a reset
countdown. The placeholder `contentAvailability` flag is deleted.
- **Ended events leave the news.** The hero showed a finished event as
"Upcoming event".
- **Settings sidebar fix.** An unscoped `nav {}` rule from the title bar
laid out the Settings groups side by side.

### Why

Pages used different title sizes, five button styles, ~76 distinct
colours, and square and round corners side by side. Feedback, known
issues, and funding were three surfaces for one job.

### Invariant

- `tests/policy/source-ui-system.test.ts`: launcher shell colours come
only from `:root` tokens, and every custom property it reads is defined.
Both proven to fail on a probe.
- `tests/unit/launcher-news.test.ts`: an event disappears once `endsAt`
has passed (fails without the fix).
- `tests/unit/daily-activities.test.ts`: rotations match the Wiki for
today and 2026-11-23; moving one anchor by a day fails 4 of 5 tests.
- `tests/unit/launcher-feedback.test.ts` and `HelpView.test.ts`: a
report is confirmed only after it was sent, and the text survives a
failed send.

### Delivery

Target `main`. Ships with the next Beta. Installed apps that still fetch
`funding.json` fall back to their bundled figures when the file is gone,
so they keep working; they just stop updating the amount.

### Verification

- `pnpm run check` passed (unit, policy, tools 283, launcher 90).
- Browser preview of the launcher renderer at 1280×800, 1100×720,
800×600 (window minimum), and 420 px, with the production, update,
failed, and offline fixtures; Settings, the article modal, and the Help
form.
- Basin test submission returned HTTP 200.
- Not checked in a packaged app or with a live game session.

# Part 2: News tab and Guide (from #540)

### What changed

- **News tab.** Every story opens as a full page in the launcher. The
news modal is deleted. Home shows the five newest stories with an "All
news" link.
- **Guild Wars Wiki updates** load the page source of the five newest
`Feedback:Game updates/` pages in one request and convert it to
Markdown. Before, the API returned full text for only one page per
request, so most wiki stories had no body.
- **What's new.** The release post whose `launcherId` matches the
installed version is bundled. It opens once in News after an update, but
not on a new install.
- **Help is for players who already have the app.** The sidebar has two
groups:
  - **Get help:** Known issues, Troubleshooting, Report a problem.
- **Features:** Accounts and launcher, Hub and Switch Character, Travel
and maps, Chat and trade, Inventory, Timers and readouts, Build
templates, Appearance, Performance, Game files and updates.

The pages are the website's Markdown, bundled at build time, so they
match this version and work offline. The install and comparison pages
stay on the website.
- **Guide links** open a Settings control
(`settings:<section>/<control>`, checked against the settings
catalogue), another Guide page, or one of a short list of allowed
websites through the new `externalOpenUrl` IPC.
- **Media placeholders.** `::media-placeholder{type="image|video"}`
blocks mark the screenshots and videos still to make. They render as
dashed boxes in the launcher and on the website.
- **Reading styles** for Guide pages and articles: lines stop at about
75 characters, emphasis is semibold, link underlines are quieter, and
key chips are smaller. Troubleshooting now uses one symptom heading per
problem, and each fix starts with the action.
- **2026.11.0 release notes** (`draft: true`, so hidden on the website
and skipped by the news generator until release). They list what changes
for Stable users: ⌘R opens the Hub, Xunlai moved to ⌘S, one Settings
page, and templates moved to the Build Library.

### Why

Many players will move from Stable 2026.8.12 to the new launcher. They
need to read what changed and how each feature works inside the app. A
modal was the wrong place for long text, and the old Help pointed at an
install guide they no longer need.

This change deletes `NewsArticle.vue` and the hand-written known-issues
list in `HelpView.vue`. The website's `7.known-issues.md` is now the
only source for that list. News and the Guide share one Markdown subset
parser (`src/shared/launcher-markdown.ts`).

### Invariant

- No address in news or the Guide is trusted. Every link goes through a
resolver and becomes an opaque action ID: a main-process `news-link-*`
ID, or `guide:`, `settings:` or `url:` with the origin allowlist
re-checked in main by `parseLauncherGuideUrl`.
- `guide.test.ts` fails if any Guide page is missing, or if any of its
links or images does not resolve.

### Delivery

Folded in from #540. Recommend shipping with 2026.11.0
(Beta, then Stable). Before Stable, remove `draft: true` from
`13.gwonmac-2026-11-0.md`.

`5.templates.md` and the release notes describe **Template files** in
the Build Library. That feature is in #541, which should
land in the same release.

### Verification

- `pnpm run check` passed. After the last change, which only touched
reading styles and Troubleshooting copy, the launcher vitest suite (93)
and `tests/policy/source-ui-system.test.ts` passed again.
- Regression tests that fail without their fix:
  - The wiki body is parsed from page source.
- A feed copy of the release notes opens its own links, not Guide links.
This bug was found while testing this branch.
- Browser check of the launcher preview at 1280×800 and 800×600:
- the Help groups and feature pages, placeholders, and a Settings link;
- the News list and reader, and a wiki article with "Open on Guild Wars
Wiki".
- The eight feature pages were checked against the code. All 83
`settings:` links resolve, and claims found only in older docs were
dropped.
- Not checked: the website rendering of `MediaPlaceholder` and `ProseA`.
No live game QA.

### Fold check

- Main (with #538's release-notes backfill) merged in without conflicts.
`check:links`, the launcher vitest suite (93, including `guide.test.ts`)
and `typecheck` passed on the merged tree.

- [x] I kept this pull request focused.
- [x] I ran the relevant checks.
- [x] I did not add game binaries, credentials, diagnostics, or private
traffic.
- [x] I updated documentation when behavior or an invariant changed.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Mat4m0 added a commit that referenced this pull request Nov 5, 2026
…rary (#541)

## What changed

The Build Library's **Builds** tab has a new **Template files** button
next to **Import build**. It opens a dialog with these actions:

- **Folder…** imports a whole Guild Wars Templates folder. **Files…**
imports single `.txt` files.
- The import shows a preview first: how many templates will be added,
and what is skipped and why. **Keep existing** or **Replace** decides
what happens to names already in use. Nothing is written until **Import
N templates** is pressed. The result names Refresh List, because the
client reads its template list once per session.
- **Export all…** saves every skill and equipment template to a folder,
using the existing `templatesExport` IPC.
- **Move to top level** appears only when some templates sit in a
subfolder Guild Wars cannot list.

## Why

Stable 2026.8.12 had all of this in Settings → Templates. 4dacdd3
(#351) removed the old settings host, and the pane went with it. The
store, the format rules and their tests stayed, but nothing called them.
Without this, Stable users would lose a feature in the next release.

This change deletes the pane's DOM binding. `template-pane.ts` becomes
`template-files.ts`: it keeps the tested sentences and adds
`createTemplateFiles(ports)`. The Vue dialog only draws what that port
returns. The `.create-actions--single` style is gone.

Not restored: the "Copied text" import, which took several codes at
once. **Import build** still covers a single skill code.

## Invariant

`tests/unit/template-files.test.ts` covers the import path. Reading
files and previewing write nothing. **Keep existing** never overwrites a
different build with the same name, and **Replace** does. The test fails
if `apply` ignores the chosen policy.

The dialog is gated on the same `gameFileSaving` compatibility check as
Save to Guild Wars.

## Delivery

Target `main`. Recommend shipping with 2026.11.0, Beta first, so it
reaches Stable together with the new launcher. The Guide text for this
feature is in `5.templates.md` on #540.

## Verification

- `pnpm run check` passed.
- Tools vitest: 283 tests passed.
- The new test fails with `apply` forced to `"replace"`.
- Browser check of the dialog in the Tools workbench, using a temporary
stub host (not committed): the start state, the preview, switching
between Keep existing and Replace, the import result, and the return to
the start state.
- **Not verified:** the dialog in a running game window. It still needs
a Beta check: import a real Windows Templates folder, press Refresh List
in the game, and run Export all.

- [x] I kept this pull request focused.
- [x] I ran the relevant checks.
- [x] I did not add game binaries, credentials, diagnostics, or private
traffic.
- [x] I updated documentation when behavior or an invariant changed.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
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.

1 participant