Read as Markdown

Changelog

What changed between GoodFolder releases.

All notable changes to GoodFolder are recorded here. The format follows Keep a Changelog, and releases carry a v* tag that the published packages and images are built from.

[Unreleased]

  • An event destination that is, or resolves to, an address inside the server's own network is now refused — including IPv4-mapped IPv6 and NAT64 forms, which slipped past before — and the check is repeated before every send. A destination whose name starts answering with a private address fails its delivery with that reason instead of being contacted.
  • The hosted tool endpoint at /mcp refuses a request body over 2 MB before reading it, like every other route already did.
  • Two saves recorded on one folder at the same moment no longer collide; the second one is numbered after the first instead of failing.
  • Lookups the server runs on every request have indexes (infra/migrations/2026-10-08-lookup-indexes.sql, applied by docker compose up -d). The folder list and the write-access check stop scanning tables that grow with other people's accounts.
  • The website's pages load less before they appear: analytics code now loads after the page instead of with it, hashed assets are cached for a year, and the two screenshots in the WebMCP section are a third of their former size.
  • Dependency patches: @modelcontextprotocol/sdk 1.31.0 (the hosted /mcp endpoint and the local server), next 15.5.27, and patched versions of the transitive packages pnpm audit named.
  • A save no longer waits more than a few seconds for its AI label — the plain summary is recorded and the model's label is written in afterwards.
  • Event destinations are now contacted only at the addresses that passed the check.
  • Running the control plane from source (pnpm dev, the services browser check) works again — a single import named the wrong file extension since 2026-09-17.

[0.3.0] - 2026-09-23

  • Every file a save leaves out now says why: goodfolder skipped and the save output name the rule that caught each one — a built-in rule, the folder's own ignore list, or the project's own settings.
  • More credential shapes stay out of a save by default: *.p12, *.pfx, *.keystore, *.jks, and a file named exactly credentials. Names that merely suggest a secret (Passwords.xlsx, Secret plan.txt, server.key.bak) are saved but reported as warnings, in the command's output and in the save result an agent or service reads. A warning now covers files a save changed as well as files it added.
  • goodfolder ignore add | list | remove manages a .goodfolderignore list that travels with the folder. Ignoring changes future saves only; ignore add --remove also stops saving a file that already has history, after asking. Earlier saves are never rewritten.
  • goodfolder save --include-secrets saves credential-shaped files on purpose, after you type include. It needs a person at the keyboard.
  • Save results carry a skipped list — what the saving computer left out, with the rule for each — and GET /api/projects/{id}/exclusions answers which rules a folder stands under.
  • The server now checks every save before it is stored. A save that adds a credential-shaped file, or one on the folder's ignore list, is refused as a whole with the path and the rule named; nothing from it is kept. The command line explains a refusal and takes back the save it just made. Self-hosted installs choose GF_PUSH_GATE=enforce (default), observe, or off. New events: save.flagged and push.refused.
  • The dashboard's key list is called API keys (it was "Services and assistants"), and its create button says what it does.
  • A command that needs your confirmation no longer takes "no" for an answer when there is no terminal to ask in (a script, a pipe, an agent's shell). goodfolder ignore add --remove used to report "Nothing was taken out of the saves" and exit 0; goodfolder undo printed a hint and also exited 0. Both now stop with exit code 1 and print the exact command to re-run with --yes.

[0.2.0] - 2026-09-17

  • Scoped access keys for services and hosted assistants: five access kinds, optional binding to one folder, revocable from the dashboard, with an activity record of every request a key made. Approvable through the existing pairing ceremony or issued from the dashboard.
  • A hosted tool endpoint at /mcp (Model Context Protocol over HTTP) and an OpenAPI 3.1 description at /openapi.json for the same REST surface.
  • Remote folder access for services over the existing transport proxy, with git:read / git:write scopes and save receipts computed from the folder's own tree.
  • Restore and undo for services, recorded as new saves — never a rewrite.
  • Outbound webhooks: signed, retried, with delivery history, for save.created, proposal.created, proposal.reviewed, and the reserved save.requested.
  • A dashboard surface for services and event destinations, a guide at /docs/services, and a runnable integration example.
  • A real browser check for the dashboard's service surface: pnpm --filter @goodfolder/web e2e:services brings up a scratch database, the control plane and the dashboard, then creates, approves, audits and revokes a key in Chromium, keeping screenshots in apps/web/e2e/artifacts/. Not part of pnpm test; run it when the dashboard or the credential routes change.

Decisions (2026-09-17)

  • The integration reference stays its own file. docs/service-protocol.md is not folded into README: README is the front door, and a front-door document does not carry transport paths, header names and scope literals, while the reference exists for whoever builds the integration and is linked from README and docs/services.md. It is site: false and sits on the same side of the vocabulary wall as docs/development.md — a third engine-naming file by decision, not by drift.
  • The access-key scopes are API terms, not copy. git:read and git:write are exempted in tools/vocabulary-gate.mjs as exact literals only; the matcher blanks them out first, so a bare use of the word elsewhere in the same string still fails the gate.

[0.1.2] - 2026-09-13

  • goodfolder --version and goodfolder-mcp --version say which release is installed. The agent server reports the same version to the agents that connect to it.
  • Every part of GoodFolder now carries one version number. The command and the agent server had moved to 0.1.1 ahead of the rest.
  • Self-hosting notes cover moving a port that is already taken, with an override file Compose picks up on its own.
  • The hosted service runs the same schema-upgrade step as a self-hosted install, so both move forward the same way.

[0.1.1] - 2026-09-13

  • The goodfolder command and the goodfolder-mcp agent server are published from the release workflow itself, with no stored credential. No change to what either of them does.

[0.1.0] - 2026-09-13

The first tagged release.

  • The four verbs — Save, Sync, Timeline and Restore — plus Undo, around an ordinary folder of any file type.
  • The goodfolder command (@goodfolder/cli on npm) and the goodfolder-mcp agent server (@goodfolder/mcp), so a compatible local agent can drive the same actions.
  • The dashboard: file browsing and previews, readable history, invitations, Change Proposals, and WebMCP site tools a browser assistant can use.
  • A self-hosted stack from one docker-compose.yml — Postgres, MinIO, the control plane, the large-file service and the dashboard — with prebuilt images on GHCR and tracked schema upgrades that run by themselves.
  • Sign-in by one-time link, which works with no email provider (the link lands in the server log), and approved computers that renew their own access without a key ever being written into the folder.