Add configuration file support for CLI#566
Conversation
Summary of ChangesHello @sij411, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request significantly enhances the Fedify CLI by introducing a robust configuration system. Users can now define default settings for various commands through TOML files, which are loaded hierarchically to provide flexible and predictable behavior. This change streamlines the user experience by reducing the need for repetitive command-line arguments and improves the CLI's maintainability by centralizing configuration logic and removing a global state file. Highlights
Changelog
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request introduces configuration file support for the CLI, which is a great enhancement for usability. The implementation uses @optique/config to bind command-line options to values from TOML configuration files loaded from system, user, and project locations. The code is well-structured, with a new config.ts for schemas and refactoring of global options into a dedicated options.ts file.
A key point of confusion is the discrepancy between the pull request description, which states support for fedify.config.jsonc and fedify.config.json files, and the actual implementation and documentation which use the TOML format. It would be beneficial to update the PR description to accurately reflect that TOML is the supported format to avoid misleading future contributors or users.
I've added one suggestion to improve error handling when loading configuration files, which should enhance the user experience by providing feedback on malformed configs.
There was a problem hiding this comment.
Pull request overview
Adds unified configuration-file support to the Fedify CLI using Optique, enabling CLI options across commands to be defaulted from a hierarchical config (plus --config / --ignore-config) and removing the old globals.ts in favor of shared modules.
Changes:
- Introduce CLI config context + schema and load TOML config from system/user/project/custom locations via
runWithConfig. - Bind command options (webfinger/lookup/inbox/nodeinfo/relay/tunnel/global) to config values using
bindConfig. - Update CLI docs/changelog and adjust CLI tests for new config-binding behavior; bump Optique dependencies.
Reviewed changes
Copilot reviewed 26 out of 28 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| pnpm-lock.yaml | Updates lockfile for new Optique/config + TOML/schema deps. |
| deno.lock | Updates Deno lock for new Optique/config + TOML/schema deps and transitive bumps. |
| packages/webfinger/deno.json | Formatting change to publish exclude list. |
| packages/vocab/deno.json | Formatting change to publish exclude list. |
| packages/vocab-tools/deno.json | Formatting change to publish exclude list. |
| packages/vocab-runtime/deno.json | Formatting change to publish exclude list. |
| packages/relay/deno.json | Formatting change to publish exclude list. |
| packages/lint/deno.json | Formatting change to publish exclude list. |
| packages/fresh/deno.json | Formatting change to publish exclude list. |
| packages/elysia/deno.json | Formatting change to publish exclude list. |
| packages/cli/src/config.ts | Adds config schema + config context + TOML loader helper. |
| packages/cli/src/options.ts | Centralizes shared options and binds them to config. |
| packages/cli/src/mod.ts | Switches CLI entrypoint to runWithConfig and implements config loading/merging. |
| packages/cli/src/webfinger/command.ts | Binds webfinger options to config; uses shared options module. |
| packages/cli/src/webfinger/mod.test.ts | Updates webfinger command parsing tests for new defaults/binding. |
| packages/cli/src/lookup.ts | Binds lookup options to config and adds shared user-agent option. |
| packages/cli/src/lookup.test.ts | Updates lookup option parsing tests to run with config context/binding. |
| packages/cli/src/inbox.tsx | Binds inbox options to config; uses new tunnel option factory + logging module. |
| packages/cli/src/nodeinfo.ts | Binds nodeinfo options to config; uses shared user-agent/debug options. |
| packages/cli/src/relay.ts | Binds relay options to config and uses new tunnel option factory + logging module. |
| packages/cli/src/tunnel.ts | Moves debug/logging imports to new modules. |
| packages/cli/src/log.ts | Adds configureLogging() and keeps shared LogTape setup/recording sink. |
| packages/cli/src/init/command.ts | Updates debug option import to new shared options module. |
| packages/cli/src/globals.ts | Removes legacy globals module (debug option + logging config). |
| packages/cli/package.json | Adds Optique/config + TOML/schema deps and adjusts package metadata. |
| packages/cli/deno.json | Adds Optique/config + TOML/schema deps for Deno and updates Optique versions. |
| docs/cli.md | Documents TOML config format, locations, and available settings. |
| CHANGES.md | Adds changelog entry for CLI config support. |
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces a unified configuration file system for the Fedify CLI, which is a great enhancement for usability and customization. The implementation uses Optique and Valibot for hierarchical TOML configuration loading, which is well-structured. The refactoring of command options to use bindConfig is consistent and clean. I have a suggestion to improve user experience.
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces comprehensive configuration file support for the Fedify CLI, which is a great enhancement for usability and managing complex setups. The changes are well-structured, leveraging @optique/config and valibot to create a robust and type-safe configuration system with hierarchical loading (system, user, project, and custom). The refactoring of global options into dedicated modules like options.ts and log.ts improves code organization and maintainability. The documentation in docs/cli.md is clear and thorough. Overall, this is a solid implementation of a significant new feature. The minor suggestion to correct a comment in a test file is valid and has been retained.
70e8e43 to
251f04f
Compare
The globals.ts file mixed unrelated concerns: CLI option definitions and
logging configuration. This refactoring improves code organization by moving
each piece to its natural home:
- debugOption moved to options.ts, where all other CLI options are defined
- configureLogging() moved to log.ts, where recordingSink and other logging
utilities already reside
This eliminates globals.ts entirely and makes the codebase easier to navigate
by grouping related functionality together.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Introduce config.ts that consolidates configuration handling:
- Valibot schemas for validating config structure (global debug option,
command-specific sections for webfinger, lookup, inbox, relay, nodeinfo)
- TOML parsing via smol-toml library
- Hierarchical config loading from system (/etc/fedify/config.toml),
user (~/.config/fedify/config.toml), and project (.fedify.toml) levels
- Recursive merging where later configs override earlier ones
This lays the groundwork for issue fedify-dev#265.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Introduce configOption with two mutually exclusive flags:
- -c, --config PATH: loads an additional configuration file on top of the
standard hierarchy (system, user, project)
- -I, --ignore-config: skips all configuration files entirely, useful for
CI environments requiring reproducible behavior
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The config module now delegates file loading and merging to @optique/config instead of implementing custom logic. This removes: - Manual config file path resolution - Multi-file loading and merging logic - Custom TOML parsing with error handling The configOption now uses withDefault() to properly handle the case when neither --ignore-config nor --config is specified. Also removed short flags (-I, -c) to keep only long flags (--ignore-config, --config) for clarity. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implement config file loading that merges multiple sources in order: 1. /etc/fedify/config.toml (system-wide, silently skipped if missing) 2. ~/.config/fedify/config.toml (user config) 3. ./.fedify.toml (project config) 4. --config PATH (custom, throws on error if specified but missing) Use Optique's runWithConfig with load callback for two-pass parsing, and es-toolkit's merge for deep merging config objects. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Integrate Optique's bindConfig() to allow CLI options to fall back to config file values. Uses type assertion on the key function return type to properly narrow types when defaults are provided. Commands updated: - relay: protocol, port, name - inbox: actorName, actorSummary, authorizedFetch - webfinger: userAgent, allowPrivateAddress, maxRedirection - lookup: userAgent, timeout - nodeinfo: userAgent Also fixes version mismatches across workspace packages (1.10.3). Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add tunnel section to config schema and wrap the service option with bindConfig() to allow tunnel service to be configured via config file. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add missing fields to config schema: - lookup: firstKnock, defaultFormat, separator - relay: persistent, acceptFollow, rejectFollow - nodeinfo: raw, bestEffort, noFavicon, metadata Add bindConfig() for: - lookup: separator - relay: persistent Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Extend config file support for more CLI options: - lookup: authorizedFetch, traverse, suppressErrors, format (defaultFormat) - nodeinfo: raw, bestEffort, noFavicon, metadata The nodeinfo options were restructured from an or() discriminated union to a flat object structure to enable bindConfig integration. This simplifies the runtime checks from `"raw" in command && command.raw` to `command.raw`. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Upgrade @optique/config, @optique/core, @optique/run to 0.10.0-dev.348 which fixes a bug where bindConfig.complete crashed with undefined state when no CLI args were consumed. Update test expectations to reflect bindConfig behavior: - userAgent now returns default value instead of undefined - Invalid option values fall back to default instead of failing See: dahlia/optique#94 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The noFavicon option was incorrectly reading showFavicon from config. When showFavicon was true, noFavicon would also be true, which is inverted. Changed to use strict equality check (=== false) so noFavicon is only true when showFavicon is explicitly set to false. Also updated CHANGES.md to include inbox and nodeinfo in the list of commands with configuration support. Additionally simplified some bindConfig key functions: - Removed redundant type assertion in lookup.ts firstKnock - Removed redundant nullish coalescing in determineSpec - Changed `as number` to `?? default` for port and maxRedirection Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Resolved issues raised by reviewers:
- Improved error handling in tryLoadToml() to print warnings for parsing
errors instead of silently ignoring all errors (only ENOENT is silent)
- Fixed package.json files array to include dist/ instead of non-existent
src/*.mjs files
- Fixed typo in engines field: denp → deno
- Fixed relay.ts persistent option to wrap optional() outside bindConfig()
so config file fallback works correctly
- Removed unused logFile from config schema
- Updated CHANGES.md to document full config precedence chain
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Instead of showing a raw stack trace when the file specified with --config is missing or malformed, display a clean error message using printError and exit gracefully. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The lookup command was broken due to incorrect Optique combinator usage:
- Changed suppressErrors from option() to flag() since it takes no value
- Changed format flags (-r, -C, -e) from option() to flag()
- Wrapped format or() in optional() so bindConfig can provide default
when no format flag is specified
- Wrapped timeout bindConfig() in optional() since it has no default
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Update system-wide and user-level config paths to follow XDG Base Directory Specification on Linux/macOS and use appropriate Windows directories: - System config: `$XDG_CONFIG_DIRS` (default: /etc/xdg) on Linux/macOS, `%ProgramData%` on Windows - User config: `$XDG_CONFIG_HOME` (default: ~/.config) on Linux/macOS, `%APPDATA%` on Windows - Cache: `$XDG_CACHE_HOME` (default: ~/.cache) on Linux/macOS, `%LOCALAPPDATA%` on Windows This replaces the env-paths dependency with inline XDG-compliant logic. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove env-paths from dependencies (replaced with XDG-compliant logic) - Remove redundant es-toolkit from deno.json (already in package.json catalog) - Use JSR specifier for valibot in deno.json - Fix incorrect test comment about default value (5, not 0) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Combine debugOption and configOption into a single globalOptions object for a unified "Global options" group in CLI help output. - Commands using command.debug (lookup, tunnel, relay, inbox) now use GlobalOptions type intersection - Commands not using debug (nodeinfo, webfinger, init, generate-vocab) no longer include debugOption - Updated tests to reflect the new option structure Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
251f04f to
7fc8e74
Compare
The previous version (v0.10.0-dev.355) had a bug where `withDefault(or(...))` inside a nested `merge()` would silently lose parsed values during `runWithConfig`'s two-pass parsing. This caused `--config PATH` to always be `undefined` in the `load` callback after the globalOptions refactoring. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
7fc8e74 to
f5776d6
Compare
Without this, parse errors (unknown options, missing arguments) would print an error message but continue execution, causing confusing behavior. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces comprehensive configuration file support for the Fedify CLI, which is a significant enhancement. The changes are well-structured, leveraging Optique and Valibot for a robust and type-safe configuration system. I appreciate the hierarchical loading of configuration files (system, user, project, and custom path), which provides great flexibility for users. The refactoring to centralize option definitions in options.ts and remove globals.ts improves the codebase's modularity and maintainability. The documentation and tests have been updated thoroughly to reflect these new features. Overall, this is an excellent contribution. I have one minor suggestion for improving the accuracy of the changelog.
Summary
/etc/fedify/config.toml~/.config/fedify/config.toml(or $XDG_CONFIG_HOME/fedify/config.toml).fedify.tomlin current directory--config(highest precedence)--ignore-configoption to skip all config file loadinginbox,lookup,webfinger,nodeinfo,tunnel,relay) with configvalues
globals.tsand relocate its contents to appropriate modulesCloses #265
Test plan
--configoption loads custom config file--ignore-configskips config loading🤖 Generated with Claude Code