* ✨ Feature(gui): configure server upload secret in settings
PicGo Core already supports authenticating `POST /upload` with a shared secret (`Authorization: Bearer <secret>`, `X-PicGo-Secret` or `?secret=`), resolved from `PICGO_SERVER_SECRET` or `settings.server.secret`, but the GUI offered no way to set it. Add a masked secret field with a show/hide toggle to the PicGo Server dialog, next to host and port.
The dialog saves the trimmed value as `settings.server.secret`; an empty value disables authentication. Saving already restarts the server, and Core reads the secret from config on `listen()`, so the main process needs no change and `PICGO_SERVER_SECRET` still takes precedence. The secret value is never added to the settings search index.
* 🐛 Fix(gui): keep server secret when normalizing settings
normalizeSettingsConfig only copied host, port and enable from `settings.server`, so after a reload the renderer state had no secret: the server dialog reopened with an empty secret field, and saving it again (e.g. after changing the port) would have silently cleared the secret and disabled authentication. Keep `secret` (falling back to an empty string) and cover it with a test.
* 📝 Docs: document renderer config normalizer whitelist in AGENTS.md
The server secret was dropped from renderer state because normalizeSettingsConfig only copies listed fields, and the server dialog re-saves the whole object. Record the rule for future changes: when adding a persisted config field, update the shared types, renderer state type, default value and normalizer, and add a round-trip normalizer test. Also give `settings.server.secret` an explicit empty default to follow that rule.
* 📝 Docs: require English PRs and squash merges in AGENTS.md
Mode is hydrated synchronously, but Verbosity / API version only show the saved values after the async refreshConfigSchema call resolves with the advanced-state choices. Both tests waited for Mode and then asserted the dependent fields synchronously, so on a slow CI runner they could still see the placeholder ("verbosity▼"). Move those assertions into waitFor.
Forward per-upload Core options through the GUI HTTP server, isolate upload task window state, scope rename listener cleanup, and align uploader fallbacks with PicGo Cloud. Add regression coverage and PR/mainline commitlint and test checks.
* ✨ Feature: rebuild picgo.app when a release is published
The download page on picgo.app reads the installer list from the GitHub API at
build time, so a new release does not appear there until the site rebuilds.
Fires on `release: published` rather than on the tag push, because releases are
created as drafts here -- at tag time `releases/latest` still points at the
previous version, so the rebuild would pick up stale installers.
Needs a HOMEPAGE_DISPATCH_TOKEN secret with workflow scope on the homepage
repository; the existing GH_TOKEN is not reused so the two can be revoked
independently.
* 📦 Chore: allow builds for the native dependencies
pnpm 11 gates build scripts behind an explicit allowlist, so a fresh install
stopped partway and asked for `pnpm approve-builds`, which breaks any
non-interactive run including the husky pre-commit hook.
Records the approvals that were already implied by onlyBuiltDependencies. The
spacing change in supportedArchitectures is pnpm rewriting the file.
3.0.0 ships as ESM and renamed the configs it exposes to consumers, so
the cz-customizable and commitlint paths gain their .cjs extensions.
It also stopped shipping contributor tooling as runtime dependencies,
which this repo was relying on: @commitlint/cli reached the commitlint
script only as a transitive dependency of bump-version 2, so the upgrade
would have removed the binary the commit-msg hook needs. It is now a
direct devDependency.
Drops the "husky" field, which has been dead config since c84d542 moved
this repo to husky 9 — v9 reads .husky/ and ignores it entirely. The
circular-dependency check it used to declare has been unhooked ever
since, so lint:dpdm moves to .husky/pre-commit where it actually runs.
Confirmed it both passes on the current tree and fails on a deliberately
introduced cycle, so it is a real gate rather than a no-op.
#1435 removed `backgroundThrottling: false` from `defaultWebPreferences`, but
`IBrowserWindowOptions.webPreferences` still declared the field as required, so
`tsc` failed on all five window definitions.
Mark it optional rather than dropping it: omitting the field keeps Electron's
default (throttle when hidden), which is what #1435 intended, while individual
windows can still opt out explicitly if they ever need full-speed background
rendering.