From 464ff6859184a62bdd4d05731a7f7594cd7621c1 Mon Sep 17 00:00:00 2001 From: Michael Blaess Date: Mon, 12 Oct 2026 21:52:52 +0200 Subject: [PATCH] fonts: add a system setting that skips Google Fonts A new `fonts` setting (and spec field) takes `google` (default, unchanged) or `system`. With `system` the page and the folder index leave the Google Fonts stylesheet and preconnects out, so a generated diagram references no other host, and SVG export makes no font request. --- PRIVACY.md | 1 + README.md | 2 +- skills/seecode/references/settings.md | 1 + skills/seecode/references/spec.md | 2 + skills/seecode/schemas/common.schema.json | 7 +++ skills/seecode/scripts/lib/config/config.mjs | 4 ++ skills/seecode/scripts/lib/export/fonts.mjs | 3 +- skills/seecode/scripts/lib/folder.mjs | 8 +-- skills/seecode/scripts/lib/page.mjs | 7 ++- skills/seecode/scripts/lib/tokens.mjs | 6 ++ .../scripts/lib/viewer/viewer.client.js | 3 +- test/fonts.test.mjs | 59 +++++++++++++++++++ 12 files changed, 93 insertions(+), 10 deletions(-) create mode 100644 test/fonts.test.mjs diff --git a/PRIVACY.md b/PRIVACY.md index f2af82f..201601b 100644 --- a/PRIVACY.md +++ b/PRIVACY.md @@ -46,6 +46,7 @@ Diagrams, specs and exports are written where you or your agent choose. Settings ## Your controls - Delete generated files, settings and profiles at any time; they are ordinary files. +- Set `fonts` to `system` (`config set fonts system`, or `"fonts": "system"` in a spec) and generated pages no longer link to Google Fonts; SVG export then makes no font request either. Fonts from a brand profile are separate and still load from where the profile points. - Open a diagram offline and it falls back to system fonts. Export SVG without network access and the fonts aren't embedded; the SVG still works. - Export GIF and MP4 from the command line instead of the Export menu to avoid the jsDelivr request. - Uninstall the skill or plugin from your agent at any time. diff --git a/README.md b/README.md index 081e41a..22386c1 100644 --- a/README.md +++ b/README.md @@ -394,7 +394,7 @@ Issues, pull requests and new diagram types are welcome. Start with the [contrib ## Privacy -SeeCode has no server, accounts or telemetry. Generated diagrams load their fonts from Google Fonts, and the in-page GIF/MP4 export loads its encoders from jsDelivr. [PRIVACY.md](PRIVACY.md) lists every request. +SeeCode has no server, accounts or telemetry. Generated diagrams load their fonts from Google Fonts (turn that off with `config set fonts system`), and the in-page GIF/MP4 export loads its encoders from jsDelivr. [PRIVACY.md](PRIVACY.md) lists every request. ## Acknowledgements diff --git a/skills/seecode/references/settings.md b/skills/seecode/references/settings.md index 8357adc..a8c98a6 100644 --- a/skills/seecode/references/settings.md +++ b/skills/seecode/references/settings.md @@ -15,6 +15,7 @@ | `duration` | `auto` | GIF/MP4 length: `auto` (reveal plus one token loop) or a number of seconds | | `outputDir` | `diagrams` | Where specs and HTML are written | | `profile` | `null` | A brand profile slug from `~/.seecode/profiles/.json` | +| `fonts` | `google` | `google` loads Fraunces and IBM Plex from Google Fonts; `system` leaves that request out and uses system fonts (for offline or restricted networks) | | `watermark` | `true` | SeeCode logo in each diagram's bottom-right corner; `false` removes it (only when the user asks) | **Commands** diff --git a/skills/seecode/references/spec.md b/skills/seecode/references/spec.md index 0788d52..844282b 100644 --- a/skills/seecode/references/spec.md +++ b/skills/seecode/references/spec.md @@ -26,4 +26,6 @@ - Arrays of objects with `id` patch by id: `{"nodes":{"api":{"row":2},"old":null,"new":{"label":"New","row":0,"col":4}}}`. - Tuple arrays add or remove items: `{"edges":{"add":[["a","b","label"]],"remove":["c>d"]}}`. `remove` also accepts indexes. +**Fonts:** `"fonts": "system"` leaves the Google Fonts stylesheet out of the page, so it makes no font request and shows system fonts. Use it when the user asks for a diagram without external requests; the `fonts` setting does the same for every diagram. + **Watermark:** every diagram carries the SeeCode logo in its bottom-right corner, in all formats. The lettering takes the diagram's text colour, so it stays visible on any background. Keep it unless the user asks to remove it; then set `"watermark": false` in the spec, or `SC config set watermark false` for all diagrams. diff --git a/skills/seecode/schemas/common.schema.json b/skills/seecode/schemas/common.schema.json index 8247377..1bf71be 100644 --- a/skills/seecode/schemas/common.schema.json +++ b/skills/seecode/schemas/common.schema.json @@ -142,6 +142,13 @@ "type": "boolean", "description": "SeeCode logo in the bottom-right corner (default true). Set false only when the user asks to remove it." }, + "fonts": { + "enum": [ + "google", + "system" + ], + "description": "Where the typefaces come from (default google). system leaves the Google Fonts stylesheet out and uses the system fallbacks." + }, "lang": { "type": "string", "pattern": "^[A-Za-z]{2,3}(-[A-Za-z0-9]{1,8})*$", diff --git a/skills/seecode/scripts/lib/config/config.mjs b/skills/seecode/scripts/lib/config/config.mjs index dc8a4f3..03b7872 100644 --- a/skills/seecode/scripts/lib/config/config.mjs +++ b/skills/seecode/scripts/lib/config/config.mjs @@ -16,8 +16,11 @@ export const DEFAULTS = { outputDir: 'diagrams', profile: null, watermark: true, + fonts: 'google', }; +const FONTS = ['google', 'system']; + const KNOWN = new Set(Object.keys(DEFAULTS).concat(['brand'])); export function globalDir() { @@ -147,6 +150,7 @@ function coerce(v) { export function set(cwd, key, value, { global = false } = {}) { if (!KNOWN.has(key)) throw new Error(`unknown setting "${key}" (known: ${[...KNOWN].join(', ')})`); + if (key === 'fonts' && !FONTS.includes(value)) throw new Error(`fonts must be one of: ${FONTS.join(', ')}`); const p = paths(cwd); const file = global ? p.global : p.project; let cur = readJson(file) || (global ? { ...DEFAULTS } : {}); diff --git a/skills/seecode/scripts/lib/export/fonts.mjs b/skills/seecode/scripts/lib/export/fonts.mjs index 8fc1bee..1730c52 100644 --- a/skills/seecode/scripts/lib/export/fonts.mjs +++ b/skills/seecode/scripts/lib/export/fonts.mjs @@ -45,7 +45,8 @@ export async function embedFonts(svg) { faces.push(block.replace(/src:[^;]+;/, `src:url(${await toData(src)}) format('woff2');`)); } } - if (!faces.length) return { ok: false, svg, error: 'no font faces returned' }; + // nothing to fetch when the page was built with fonts: 'system' + if (!faces.length && googleFamilies(svg).length) return { ok: false, svg, error: 'no font faces returned' }; let out = svg.replace(/@import url\('https:\/\/fonts\.googleapis\.com\/[^']*'\);/g, ''); out = out.replace(/(` : ''}