Skip to content

Make Gullet globally configurable and publishable - #17

Merged
mlsimon734 merged 4 commits into
mainfrom
feat/vault-override
Aug 3, 2026
Merged

Make Gullet globally configurable and publishable#17
mlsimon734 merged 4 commits into
mainfrom
feat/vault-override

Conversation

@mlsimon734

Copy link
Copy Markdown
Owner

Closes #13.

Summary

  • add XDG-aware global configuration with secret-safe tokenFile and bounded tokenCommand support
  • package the zero-dependency sidecar for bunx tabglutton-gullet and move its tab rendering code inside the Gullet package
  • update client configuration, documentation, CI packaging, and the extension's copyable setup guidance
  • preserve fixed-port setup, enforce 0600 on token-file overwrites, and keep command timeouts active while inherited output pipes drain

Why

Gullet previously depended on a repository-relative shell wrapper and environment file. Clients without a stable working directory or shell interpolation could not configure it, and a published bunx entrypoint had no global place to resolve its token.

Existing CLI and environment configuration remains supported at higher precedence, while global config makes standalone and desktop client setup portable.

Validation

  • bun run check — 398 tests passed
  • bun run package:gullet
  • push hooks: formatting, JSON/YAML checks, oxlint, web-ext lint, typecheck, and tests all passed

Manifest and browser permission declarations are unchanged. The options-page change is setup copy only, so no screenshot is included.

@mlsimon734
mlsimon734 marked this pull request as ready for review August 3, 2026 17:33
Quality cleanup over the global-config work, no behavior change intended.

- Delete `parseConfig`. It had no production caller left — `main` uses
  `loadConfig` — and re-implemented the CLI→env precedence in a second
  idiom, so the rules had two homes and the tested one was not the one
  that shipped. Its assertions now drive `loadConfig` through the
  existing `ConfigRuntime` seam with every file absent.
- Use the shared `errorMessage` and `asRecord` from `bridge-protocol`
  instead of the local `messageOf` / `isRecord` copies.
- Collapse `definedEnv` into `firstDefined`: the `{set, value?}` box
  carried nothing a `!== undefined` check doesn't, and forced three
  `?? ""` fallbacks that could never fire.
- Drop `portSet` / `tokenSet` — `requireValue` throws rather than
  returning undefined, so a set flag always carries a string.
- Drop the conditional spreads in `assembleConfig` and `main`;
  `exactOptionalPropertyTypes` is false, so they guarded an optional
  property that already accepts undefined.
- Fold the twin tokenFile/tokenCommand validation blocks into one local.

`Supervisor.acquireToken` returns `BridgeError | null`, which removes the
unreachable `fault?.code ?? …` fallbacks in `start()` and with them a
second copy of the no-token message. `start()` also stops arming
`retryToken()` when no `resolveToken` is configured: that branch does no
I/O and re-derives a constant, so it was a 1s→30s backoff loop waking the
event loop for the process lifetime — reachable via `--token=` or an
empty TABGLUTTON_TOKEN.

The options page spelled `~/.config/tabglutton/token` as shell text while
`configPaths()` computed it in TS, with nothing enforcing agreement;
renaming either would typecheck cleanly and silently break the only
documented way to install a token. Both now build from CONFIG_DIR_NAME
and DEFAULT_TOKEN_FILE_NAME in `bridge-protocol.ts`, the module the two
halves already share for this class of constant. `bridgeSnippetText`
returns null with no token rather than wrapping a runnable command around
the `<generate or paste a token above>` placeholder — the copy button's
guard never covered selecting the `<pre>` by hand — and the copy handler
now shares that one check.

Verified: bun run check.
One conflict, in gullet/src/main.ts's createToolCaller argument. Both
sides changed adjacent lines for unrelated reasons:

- This branch removed the local `tokenError`, because Supervisor now owns
  token faults and publishes them through `backend.fault()` — so the
  `?? tokenError` fallback has nothing left to fall back to.
- main added `knownObsidianVaults` for the tab_clip vault registry check.

Resolved by keeping both: `startupError: () => backend.fault()` alongside
`knownObsidianVaults`.

Verified: bun run check (408 tests).
@mlsimon734
mlsimon734 merged commit 7423d92 into main Aug 3, 2026
1 check passed
@mlsimon734
mlsimon734 deleted the feat/vault-override branch August 3, 2026 18:08
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.

Gullet: global config file + bunx distribution

1 participant