Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
d507c79
Remove globals.ts and relocate its contents to appropriate modules
sij411 Jan 30, 2026
8d0f2f7
Add unified configuration module for CLI
sij411 Jan 30, 2026
dabbb49
Add --config and --ignore-config CLI options
sij411 Jan 30, 2026
5bde9db
Simplify config module to use Optique's config system
sij411 Feb 3, 2026
48fe66c
Add hierarchical config file loading with Optique integration
sij411 Feb 4, 2026
8cb928b
Add bindConfig integration for CLI options
sij411 Feb 5, 2026
14350a8
Add bindConfig integration for tunnel command
sij411 Feb 5, 2026
ac8ef43
Extend config schema and add more bindConfig integrations
sij411 Feb 5, 2026
5a84e7a
Add bindConfig for lookup and nodeinfo command options
sij411 Feb 5, 2026
7037417
Update Optique to 0.10.0-dev.347
sij411 Feb 9, 2026
76c5246
Update CLI config schema to match issue spec
sij411 Feb 9, 2026
71d801d
Bind all inbox command options with config
sij411 Feb 9, 2026
fb7dd38
Bind webfinger command options with config
sij411 Feb 9, 2026
236233c
Refactor userAgentOption
sij411 Feb 9, 2026
e800faa
Bind lookup command options with config
sij411 Feb 9, 2026
bfbaff5
Wrap userAgentOption with object and update usages
sij411 Feb 9, 2026
52928f8
Remove tunnel-specific config binding from tunnel command
sij411 Feb 9, 2026
7cdf585
Bind relay command options with config
sij411 Feb 9, 2026
0b769d5
Add configuration file documentation to CLI docs
sij411 Feb 9, 2026
8f19053
Update CLI tests for bindConfig compatibility
sij411 Feb 10, 2026
aa6b64f
Fix noFavicon config logic and update changelog command list
sij411 Feb 11, 2026
89338f7
Set webfinger command's default value to 5 and test codes
sij411 Feb 11, 2026
270ecb0
Fix package versions to 2.0.0
sij411 Feb 12, 2026
faae49b
Update optique version to dev.355
sij411 Feb 12, 2026
1f4ee9f
Fix unclosed tag in cli.md
sij411 Feb 12, 2026
6e66448
Add change log
sij411 Feb 12, 2026
26d63b9
Address PR review feedback for CLI configuration feature
sij411 Feb 13, 2026
f474b83
Show user-friendly error for invalid --config file
sij411 Feb 13, 2026
4db0707
Fix lookup command option parsing issues
sij411 Feb 13, 2026
0ac37f0
Use XDG-compliant paths for config and cache directories
sij411 Feb 14, 2026
4ce87ed
Address PR review feedback
sij411 Feb 14, 2026
efc2c93
Merge debug and config options into globalOptions
sij411 Feb 14, 2026
f5776d6
Upgrade Optique to v0.10.0-dev.376 to fix nested merge bug
sij411 Feb 14, 2026
53a2390
Add onError handler to runWithConfig to exit on parse errors
sij411 Feb 15, 2026
003ad63
Fix config path on change log
sij411 Feb 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,23 @@ To be released.
to the existing `-s`/`--service` option in `fedify tunnel` for consistency.
[[#525], [#529], [#531] by Jiwon Kwon]

- Added configuration file support for CLI commands. The CLI now loads
settings from configuration files at multiple levels, with a well-defined
precedence chain. [[#555], [#566] by Jiwon Kwon]

- By default, configuration is loaded (in order of increasing precedence)
from a system-wide configuration file (*/etc/xdg/fedify/config.toml*),
a user-level configuration file (*~/.config/fedify/config.toml*),
and *.fedify.toml* in the current directory; later files override
earlier ones.
- Added `--config` option to specify a custom configuration file path;
this file has the highest precedence over all other configuration
sources.
- Added `--ignore-config` option to skip configuration file loading.
- All command options (`inbox`, `lookup`, `webfinger`, `nodeinfo`,
`tunnel`, `relay`) can now be configured via any of the configuration
files.

[Elysia]: https://elysiajs.com/
[#374]: https://github.com/fedify-dev/fedify/issues/374
[#397]: https://github.com/fedify-dev/fedify/issues/397
Expand All @@ -238,6 +255,8 @@ To be released.
[#525]: https://github.com/fedify-dev/fedify/issues/525
[#529]: https://github.com/fedify-dev/fedify/pull/529
[#531]: https://github.com/fedify-dev/fedify/pull/531
[#555]: https://github.com/fedify-dev/fedify/issues/555
[#566]: https://github.com/fedify-dev/fedify/pull/566

### @fedify/debugger

Expand Down
1,093 changes: 584 additions & 509 deletions deno.lock

Large diffs are not rendered by default.

102 changes: 102 additions & 0 deletions docs/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,108 @@ the appropriate executable for your platform and put it in your `PATH`.
[releases]: https://github.com/fedify-dev/fedify/releases


Configuration file
------------------

*This feature is available since Fedify 2.0.0.*

The `fedify` command supports configuration files to set default values for
command options. Configuration files are written in [TOML] format.

[TOML]: https://toml.io/

### Configuration file locations

Configuration files are loaded from the following locations in order, with
later files taking precedence over earlier ones:

1. System-wide configuration directories (see below)
2. *~/.config/fedify/config.toml* (user-level, or
`$XDG_CONFIG_HOME/fedify/config.toml`)
3. *.fedify.toml* in the current working directory (project-level)
4. Custom path specified via `--config` option (highest precedence)

The system-wide and user-level config paths vary by operating system:

- **Linux/macOS (system)**: Directories listed in `$XDG_CONFIG_DIRS`
(default: */etc/xdg/fedify/config.toml*)
- **Linux/macOS (user)**: `$XDG_CONFIG_HOME/fedify/config.toml`
(default: *~/.config/fedify/config.toml*)
- **Windows (system)**: *%ProgramData%\\fedify\\config.toml*
- **Windows (user)**: *%APPDATA%\\fedify\\config.toml*

### `--config`: Load an additional configuration file

You can specify an additional configuration file to load using the `--config`
option:

~~~~ sh
fedify --config ./my-config.toml lookup @user@example.com
~~~~

This file is loaded after all standard configuration files and takes the
highest precedence.

### `--ignore-config`: Ignore all configuration files

The `--ignore-config` option skips loading all configuration files. This is
useful for CI environments or when you want reproducible behavior:

~~~~ sh
fedify --ignore-config lookup @user@example.com
~~~~

### Configuration file structure

Below is an example configuration file showing all available options:

~~~~ toml
# Global settings (apply to all commands)
debug = false
userAgent = "MyApp/1.0"
tunnelService = "localhost.run" # "localhost.run", "serveo.net", or "pinggy.io"

[webfinger]
allowPrivateAddress = false
maxRedirection = 5

[lookup]
authorizedFetch = false
firstKnock = "draft-cavage-http-signatures-12" # or "rfc9421"
traverse = false
suppressErrors = false
defaultFormat = "default" # "default", "raw", "compact", or "expand"
separator = "----"
timeout = 30 # seconds

[inbox]
actorName = "Fedify Ephemeral Actor"
actorSummary = "An ephemeral actor for testing purposes."
authorizedFetch = false
noTunnel = false
follow = ["@user@example.com"]
acceptFollow = ["*"]

[relay]
protocol = "mastodon" # or "litepub"
port = 8000
name = "Fedify Relay"
persistent = "/path/to/relay.db" # optional, uses in-memory if not specified
noTunnel = false
acceptFollow = ["*"]
rejectFollow = []

[nodeinfo]
raw = false
bestEffort = false
showFavicon = true
showMetadata = false
~~~~

All configuration options are optional. Command-line arguments always take
precedence over configuration file values.


`fedify init`: Initializing a Fedify project
--------------------------------------------

Expand Down
38 changes: 30 additions & 8 deletions packages/cli/deno.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,24 @@
"exports": "./src/mod.ts",
"imports": {
"@hongminhee/localtunnel": "jsr:@hongminhee/localtunnel@^0.3.0",
"@inquirer/prompts": "npm:@inquirer/prompts@^7.8.4",
"@jimp/core": "npm:@jimp/core@^1.6.0",
"@jimp/wasm-webp": "npm:@jimp/wasm-webp@^1.6.0",
"@optique/config": "jsr:@optique/config@^0.10.0-dev.376",
"@optique/core": "jsr:@optique/core@^0.10.0-dev.376",
"@optique/run": "jsr:@optique/run@^0.10.0-dev.376",
"@poppanator/http-constants": "npm:@poppanator/http-constants@^1.1.1",
"chalk": "npm:chalk@^5.6.2",
"cli-table3": "npm:cli-table3@^0.6.5",
"env-paths": "npm:env-paths@^3.0.0",
"fetch-mock": "npm:fetch-mock@^12.5.4",
"hono": "jsr:@hono/hono@^4.8.3",
"icojs": "npm:icojs@^0.19.5",
"inquirer-toggle": "npm:inquirer-toggle@^1.0.1",
"ora": "npm:ora@^8.2.0",
"shiki": "npm:shiki@^1.6.4",
"smol-toml": "npm:smol-toml@^1.6.0",
"srvx": "npm:srvx@^0.8.7",
"valibot": "jsr:@valibot/valibot@^1.2.0",
"#kv": "./src/kv.node.ts"
},
"exclude": [
Expand All @@ -25,11 +32,7 @@
"fedify-cli-*.zip"
],
"publish": {
"exclude": [
"**/*.test.ts",
"tsdown.config.ts",
"scripts/"
]
"exclude": ["**/*.test.ts", "tsdown.config.ts", "scripts/"]
},
"tasks": {
"codegen": "deno task -f @fedify/vocab compile",
Expand Down Expand Up @@ -57,8 +60,27 @@
"dependencies": [
"codegen"
]
},
"test-init": {
"command": "FEDIFY_TEST_MODE=true deno run --allow-all src/init/test/mod.ts test-init",
"dependencies": [
"codegen"
]
}
},
"fmt": {},
"lint": {}
"fmt": {
"exclude": [
"src/init/templates/**"
]
},
"lint": {
"exclude": [
"src/init/templates/**"
]
},
"test": {
"exclude": [
"src/init/test/**"
]
}
}
77 changes: 48 additions & 29 deletions packages/cli/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,43 @@
{
"name": "@fedify/cli",
"version": "2.0.0",
"type": "module",
"files": [
"README.md",
"dist/"
],
"bin": {
"fedify": "./dist/mod.js"
},
"scripts": {
"build:self": "tsdown",
"build": "pnpm --filter @fedify/cli... run build:self",
"prepack": "pnpm build",
"prepublish": "pnpm build",
"pretest": "pnpm build",
"test": "node --test --experimental-transform-types 'src/**/*.test.ts' '!src/init/test/**'",
"test-init": "deno task test-init",
"pretest:bun": "pnpm build",
"test:bun": "bun test",
"run": "pnpm build && node dist/mod.js",
"runi": "tsdown && node dist/mod.js",
"run:bun": "pnpm build && bun dist/mod.js",
"runi:bun": "tsdown && bun dist/mod.js"
},
"engines": {
"node": ">=20.0.0",
"bun": ">=1.2.0",
"deno": ">=2.0.0"
},
"os": [
"darwin",
"linux",
"win32"
],
"cpu": [
"x64",
"arm64"
],
"description": "CLI toolchain for Fedify and debugging ActivityPub",
"keywords": [
"fedify",
Expand All @@ -27,15 +64,6 @@
"url": "git+https://github.com/fedify-dev/fedify.git",
"directory": "packages/cli"
},
"type": "module",
"engines": {
"node": ">=20.0.0",
"bun": ">=1.2.0",
"denp": ">=2.0.0"
},
"bin": {
"fedify": "./dist/mod.js"
},
"exports": "./dist/mod.js",
"imports": {
"#kv": {
Expand All @@ -45,7 +73,6 @@
},
"dependencies": {
"@fedify/fedify": "workspace:*",
"@fedify/init": "workspace:*",
"@fedify/relay": "workspace:*",
"@fedify/sqlite": "workspace:*",
"@fedify/vocab": "workspace:*",
Expand All @@ -54,46 +81,38 @@
"@fedify/webfinger": "workspace:*",
"@fxts/core": "catalog:",
"@hongminhee/localtunnel": "^0.3.0",
"@inquirer/prompts": "^7.8.4",
"@jimp/core": "^1.6.0",
"@jimp/wasm-webp": "^1.6.0",
"@js-temporal/polyfill": "catalog:",
"@logtape/file": "catalog:",
"@logtape/logtape": "catalog:",
"@optique/core": "catalog:",
"@optique/run": "catalog:",
"@optique/config": "0.10.0-dev.376",
"@optique/core": "0.10.0-dev.376",
"@optique/run": "0.10.0-dev.376",
"@poppanator/http-constants": "^1.1.1",
"byte-encodings": "catalog:",
"chalk": "catalog:",
"chalk": "^5.6.2",
"cli-highlight": "^2.1.11",
"cli-table3": "^0.6.5",
"env-paths": "^3.0.0",
"enquirer": "^2.4.1",
"es-toolkit": "catalog:",
"fetch-mock": "catalog:",
"hono": "^4.8.3",
"icojs": "^0.19.5",
"inquirer": "^12.9.4",
"inquirer-toggle": "^1.0.1",
"jimp": "^1.6.0",
"ora": "^8.2.0",
"shiki": "^1.6.4",
"srvx": "^0.8.7"
"smol-toml": "^1.6.0",
"srvx": "^0.8.7",
"valibot": "^1.2.0"
},
"devDependencies": {
"@types/bun": "catalog:",
"@types/node": "catalog:",
"tsdown": "catalog:",
"typescript": "catalog:"
},
"scripts": {
"build:self": "tsdown",
"build": "pnpm --filter @fedify/cli... run build:self",
"prepack": "pnpm build",
"prepublish": "pnpm build",
"pretest": "pnpm build",
"test": "node --test --experimental-transform-types 'src/**/*.test.ts' '!src/init/test/**'",
"pretest:bun": "pnpm build",
"test:bun": "bun test",
"run": "pnpm build && node dist/mod.js",
"runi": "tsdown && node dist/mod.js",
"run:bun": "pnpm build && bun dist/mod.js",
"runi:bun": "tsdown && bun dist/mod.js"
}
}
22 changes: 19 additions & 3 deletions packages/cli/src/cache.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,24 @@
import envPaths from "env-paths";
import { mkdir } from "node:fs/promises";
import { homedir } from "node:os";
import { join } from "node:path";
import process from "node:process";

const paths = envPaths("fedify", { suffix: "" });
export const DEFAULT_CACHE_DIR = paths.cache;
/**
* Returns the default cache directory path.
* - Linux/macOS: `$XDG_CACHE_HOME/fedify` (default: ~/.cache/fedify)
* - Windows: `%LOCALAPPDATA%\fedify`
*/
function getDefaultCacheDir(): string {
if (process.platform === "win32") {
const localAppData = process.env.LOCALAPPDATA ||
join(homedir(), "AppData", "Local");
return join(localAppData, "fedify");
}
const xdgCacheHome = process.env.XDG_CACHE_HOME || join(homedir(), ".cache");
return join(xdgCacheHome, "fedify");
}

export const DEFAULT_CACHE_DIR = getDefaultCacheDir();

let currentCacheDir: string = DEFAULT_CACHE_DIR;

Expand Down
Loading
Loading