feat(inlay): named profiles + auto-sync#8
Merged
Conversation
|
Warning You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again! |
552b871 to
2ebf6ad
Compare
kfrrst
added a commit
that referenced
this pull request
May 21, 2026
- Add InlayProfile and InlayProfileStore types with version "1" - loadProfileStore() migrates legacy tessellate:inlay:rules key into a "Default" profile on first run; subsequent loads read INLAY_PROFILES_KEY - saveProfileStore(), getActiveProfile(), syncProfileIfStale() with 4h TTL - loadActiveManifest() replaces loadInlayManifest() throughout; syncs stale profiles transparently before returning the active profile's rules - inlay-configure opens with inlay:profiles-hydrate (store + activeProfile) instead of inlay:hydrate; font list sent in same open burst - Message handlers: inlay:save-profile (update rules+syncUrl on named profile), inlay:new-profile, inlay:duplicate-profile, inlay:delete-profile, inlay:rename-profile, inlay:set-active-profile, inlay:sync-now - inlay-switch-profile command: 400×320 panel with list-select + Activate button - generateId() uses Math.random hex — no crypto.randomUUID() (sandbox compat) - manifest.json: "Switch profile…" added between separator and Configure - UI: profile-bar (select + New/Duplicate/Delete), profile-name-bar (rename), sync-bar (URL + ↺ Sync + last-sync timestamp); #inlay-switch panel for the switch-profile command; inlay:profiles-hydrate and inlay:sync-result handlers
5adad46 to
5cf044f
Compare
kfrrst
added a commit
that referenced
this pull request
May 21, 2026
## What - Size-aware `minSize?/maxSize?` on `InlayRule` — Inter Bold can now map to different targets based on font size (Bloomber S6 requirement). - `buildForwardResolver` with sorted-bucket, tightest-range-wins priority replaces the old `buildInlayLookup`/`lookupReplacement`. - `getStyledTextSegments(["fontName", "fontSize"])` so the resolver can act on segment size. - `InlayRuleResult` + `byRule[]` on `InlayResult` → per-rule swap counts in the Apply notification when 2+ rules are active. - `formatInlayResult` appends a rule breakdown for multi-rule applies. - UI: 7-column grid with Min pt / Max pt inputs per rule row. - **Fix**: `resolveFont` null case now falls back to raw target font name instead of recording an error and skipping. `loadFontAsync` handles the true failure case. - **Fix**: test mock `availableFonts` expanded to cover all Klim / Newsreader fonts referenced as substitution targets in tests. ## Closes Part of the S6 font-substitution Inlay v2 series (PRs #6–#8).
2ebf6ad to
cf22c62
Compare
kfrrst
added a commit
that referenced
this pull request
May 21, 2026
- Add InlayProfile and InlayProfileStore types with version "1" - loadProfileStore() migrates legacy tessellate:inlay:rules key into a "Default" profile on first run; subsequent loads read INLAY_PROFILES_KEY - saveProfileStore(), getActiveProfile(), syncProfileIfStale() with 4h TTL - loadActiveManifest() replaces loadInlayManifest() throughout; syncs stale profiles transparently before returning the active profile's rules - inlay-configure opens with inlay:profiles-hydrate (store + activeProfile) instead of inlay:hydrate; font list sent in same open burst - Message handlers: inlay:save-profile (update rules+syncUrl on named profile), inlay:new-profile, inlay:duplicate-profile, inlay:delete-profile, inlay:rename-profile, inlay:set-active-profile, inlay:sync-now - inlay-switch-profile command: 400×320 panel with list-select + Activate button - generateId() uses Math.random hex — no crypto.randomUUID() (sandbox compat) - manifest.json: "Switch profile…" added between separator and Configure - UI: profile-bar (select + New/Duplicate/Delete), profile-name-bar (rename), sync-bar (URL + ↺ Sync + last-sync timestamp); #inlay-switch panel for the switch-profile command; inlay:profiles-hydrate and inlay:sync-result handlers
5cf044f to
8133999
Compare
kfrrst
added a commit
that referenced
this pull request
May 21, 2026
- Test 9: use tessellate:inlay:profiles with syncUrl+empty rules to trigger remote fetch, matching loadActiveManifest's new profile-first code path - Test 10: look for inlay:profiles-hydrate (store+activeProfile) instead of the removed inlay:hydrate (manifest+config); verify migrated rules land in activeProfile.rules - Test 11: check tessellate:inlay:profiles for saved rules instead of the legacy tessellate:inlay:rules key that inlay:save no longer writes
kfrrst
added a commit
that referenced
this pull request
May 21, 2026
## What - `preflightFonts()` → `PreflightResult`: checks which rule targets are actually installed before applying. - `runInlayDryRun()` → `InlayDryRunResult`: scans the current page and reports what would swap, without writing. - `inlay-dryrun-page` command + "Dry run (preview) current page…" menu item. - Auto-preflight fires on configure open so the UI can surface a warning banner for any missing target fonts. - UI: `#inlay-dryrun` section with "Preview current page" button and inline `<details>` result; `#preflight-status` warning banner. Part of the Inlay v2 series (PRs #6–#8).
- Add InlayProfile and InlayProfileStore types with version "1" - loadProfileStore() migrates legacy tessellate:inlay:rules key into a "Default" profile on first run; subsequent loads read INLAY_PROFILES_KEY - saveProfileStore(), getActiveProfile(), syncProfileIfStale() with 4h TTL - loadActiveManifest() replaces loadInlayManifest() throughout; syncs stale profiles transparently before returning the active profile's rules - inlay-configure opens with inlay:profiles-hydrate (store + activeProfile) instead of inlay:hydrate; font list sent in same open burst - Message handlers: inlay:save-profile (update rules+syncUrl on named profile), inlay:new-profile, inlay:duplicate-profile, inlay:delete-profile, inlay:rename-profile, inlay:set-active-profile, inlay:sync-now - inlay-switch-profile command: 400×320 panel with list-select + Activate button - generateId() uses Math.random hex — no crypto.randomUUID() (sandbox compat) - manifest.json: "Switch profile…" added between separator and Configure - UI: profile-bar (select + New/Duplicate/Delete), profile-name-bar (rename), sync-bar (URL + ↺ Sync + last-sync timestamp); #inlay-switch panel for the switch-profile command; inlay:profiles-hydrate and inlay:sync-result handlers
- Test 9: use tessellate:inlay:profiles with syncUrl+empty rules to trigger remote fetch, matching loadActiveManifest's new profile-first code path - Test 10: look for inlay:profiles-hydrate (store+activeProfile) instead of the removed inlay:hydrate (manifest+config); verify migrated rules land in activeProfile.rules - Test 11: check tessellate:inlay:profiles for saved rules instead of the legacy tessellate:inlay:rules key that inlay:save no longer writes
f8f7757 to
5dc72da
Compare
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.
Summary
InlayProfileStore(version"1") holds a list ofInlayProfileobjects, each withid,name,rules[],syncUrl,lastSyncedAt,createdAt,updatedAt. Replaces the flattessellate:inlay:rulesclientStorage key.loadProfileStore()detects a legacyINLAY_RULES_KEYvalue on first run and migrates it into a "Default" profile automatically. Old key is cleared after migration.syncProfileIfStale()checks iflastSyncedAtis older than 4 hours; if so, fetchessyncUrl(must return anInlayManifest), updatesrulesandlastSyncedAt, saves. Transparent to the caller —loadActiveManifest()calls it before returning the manifest.inlay:new-profile,inlay:duplicate-profile,inlay:delete-profile(guard: must have >1 profile),inlay:rename-profile,inlay:set-active-profile— each responds withinlay:profiles-hydrate.inlay:sync-now { profileId }force-syncs regardless of TTL; respondsinlay:sync-result { ok, count, syncedAt, error }.inlay-switch-profilecommand: narrow 400×320 panel with a<select size="6">list of all profiles and an Activate button. Sets active profile and closes.#inlay-switchsection for the standalone switcher. Save button sendsinlay:save-profile { profileId, rules, syncUrl }.generateId()usesMath.random()hex — nocrypto.randomUUID()for sandbox compat.Sandbox safety
scripts/check-sandbox-safety.mjspasses.Test plan