Skip to content

Fix CLI config fallbacks for Optique 1.0#728

Merged
dahlia merged 5 commits intofedify-dev:mainfrom
dahlia:bugfix/cli
Apr 26, 2026
Merged

Fix CLI config fallbacks for Optique 1.0#728
dahlia merged 5 commits intofedify-dev:mainfrom
dahlia:bugfix/cli

Conversation

@dahlia
Copy link
Copy Markdown
Member

@dahlia dahlia commented Apr 26, 2026

Summary

This fixes Fedify CLI option/config fallback handling after the Optique 1.0 upgrade. The tunnel, inbox, and relay commands could fail with Error: Missing required configuration value. even when required positional arguments were provided, because optional config-bound options were modeled with withDefault(..., undefined) or nested bindConfig(withDefault(...)) patterns.

Changes

  • Replaced the optional tunnel service fallback in packages/cli/src/options.ts with optional(bindConfig(...)).
  • Simplified the tunnel enable/disable option in packages/cli/src/options.ts so bindConfig() owns the default value directly.
  • Updated the recursive lookup depth option in packages/cli/src/lookup.ts so config binding and defaults are expressed in the same layer.
  • Added regression tests in packages/cli/src/tunnel.test.ts for tunnel, inbox, and relay runners with omitted tunnel service config.
  • Updated Optique dependencies to 1.0.2 in deno.json and pnpm-workspace.yaml, then refreshed deno.lock and pnpm-lock.yaml.
  • Added packages/cli/package.json dependency metadata for @standard-schema/spec, which satisfies @optique/config's peer dependency in Node.js and Bun installs.

Rationale

Optique's config file support documentation describes bindConfig() as the layer that handles fallback from CLI arguments to config file values to a default value, and then to an error if none of those sources produce a value. Optique's modifying combinators documentation describes optional() as the way to represent a value that may be genuinely absent.

The previous Fedify CLI patterns mixed those concepts: withDefault(..., undefined) was used to express optional absence, and withDefault() was also nested around or inside config-bound parsers. With Optique 1.0's config parsing model, those compositions can leave bindConfig() with no config value and no real default, which surfaces as Error: Missing required configuration value.

The fix follows the documented shape more directly: use optional(bindConfig(...)) when absence is meaningful, and put concrete defaults such as true or 20 in the bindConfig() options when config fallback should have a real default value.

Verification

  • Ran deno test --allow-all for the tunnel and lookup CLI tests.
  • Ran deno check against the CLI source files.
  • Ran deno lint and deno fmt --check on the touched CLI source and test files.
  • Ran pnpm install, pnpm install --lockfile-only --frozen-lockfile --ignore-scripts, and the repository pre-commit mise run check.

dahlia added 2 commits April 26, 2026 21:11
Use optional parsers for tunnel service configuration so missing
configuration values do not make commands fail during Optique's two-pass
parsing.  Move other config-backed defaults into bindConfig() directly to
avoid relying on wrapper defaults around configuration bindings.

Add regression coverage for tunnel, inbox, and relay command parsing when
no tunnel service is configured.

Assisted-by: Codex:gpt-5.5
Update the Optique packages to 1.0.2 across the Deno and pnpm
workspace manifests and refresh both lockfiles.  Add an explicit
@standard-schema/spec dependency for the CLI package to satisfy
@optique/config's peer dependency under Node.js and Bun installs.

Assisted-by: Codex:gpt-5.5
@dahlia dahlia added this to the Fedify 2.2 milestone Apr 26, 2026
@dahlia dahlia requested a review from Copilot April 26, 2026 12:24
@dahlia dahlia self-assigned this Apr 26, 2026
@dahlia dahlia added type/bug Something isn't working component/cli CLI tools related dependencies Dependency updates and issues labels Apr 26, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 26, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: beb02602-c311-4979-b109-ecbf1cbce7a0

📥 Commits

Reviewing files that changed from the base of the PR and between dcd20e9 and ea162f5.

⛔ Files ignored due to path filters (1)
  • deno.lock is excluded by !**/*.lock
📒 Files selected for processing (2)
  • deno.json
  • packages/cli/src/options.ts

📝 Walkthrough

Walkthrough

Updates dependency pins (JSR and npm) including adding @standard-schema/spec; refactors CLI option/config binding for recurse-depth and tunnel handling; and adds CLI-level tests for tunnel/inbox/relay command behaviors.

Changes

Cohort / File(s) Summary
Dependency Version Updates
deno.json, pnpm-workspace.yaml
Bumps @optique/config, @optique/core, @optique/run from ^1.0.0 to ^1.0.2 and adds @standard-schema/spec@^1.1.0 catalog entry.
CLI Package Manifest
packages/cli/package.json
Adds @standard-schema/spec as a dependency (catalog: resolution).
CLI Config & Option Binding
packages/cli/src/lookup.ts, packages/cli/src/options.ts
Changes default application: --recurse-depth default moved into bindConfig default; tunnel service uses optional(...) instead of withDefault(..., undefined); tunnel boolean logic now derives from noTunnel (explicit undefined vs negation).
CLI Tests
packages/cli/src/tunnel.test.ts
Adds async tests invoking runCli for tunnel, inbox, and relay with --ignore-config, asserting tunnelService/service undefined when omitted and --no-tunnel sets tunnel to false.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested labels

type/enhancement, component/testing

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically summarizes the main change: fixing CLI config fallbacks after an Optique 1.0 upgrade.
Description check ✅ Passed The description is thorough and directly related to the changeset, explaining the problem, changes, rationale, and verification steps.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@dahlia
Copy link
Copy Markdown
Member Author

dahlia commented Apr 26, 2026

@codex review

@issues-auto-labeler issues-auto-labeler Bot added breaking change Requires backward-incompatible change component/build Build system and packaging labels Apr 26, 2026
@dahlia dahlia removed breaking change Requires backward-incompatible change component/build Build system and packaging labels Apr 26, 2026
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates the @optique suite of packages (config, core, run) to version 1.0.2 and adds @standard-schema/spec to the project dependencies. It refactors the CLI's option handling for recursion depth and tunneling to improve how default values and optional configurations are bound. Furthermore, it introduces new unit tests to ensure the CLI correctly handles scenarios where tunnel services are omitted. I have no feedback to provide.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes Fedify CLI option/config fallback behavior after upgrading to Optique 1.0, preventing “Missing required configuration value” errors when positional args are provided and config-backed options are intentionally omitted.

Changes:

  • Adjusted CLI option compositions to align with Optique 1.0’s intended bindConfig() + optional() semantics (notably tunnel service and tunnel enable/disable).
  • Updated lookup recursion depth config binding so defaults are owned by the config-binding layer.
  • Added regression tests for tunnel, inbox, and relay runners when tunnel service config is omitted, and updated Optique-related dependencies/locks (including @standard-schema/spec).

Reviewed changes

Copilot reviewed 6 out of 8 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
pnpm-workspace.yaml Bumps Optique catalog versions and adds @standard-schema/spec to satisfy peer deps.
pnpm-lock.yaml Refreshes lockfile for Optique 1.0.2 and @standard-schema/spec resolution.
packages/cli/src/tunnel.test.ts Adds regression tests ensuring runners parse correctly with omitted tunnel service config.
packages/cli/src/options.ts Fixes tunnel-related option/config fallback modeling using optional(bindConfig(...)) and config-owned defaults.
packages/cli/src/lookup.ts Updates recursion depth config binding/default handling for Optique 1.0 behavior.
packages/cli/package.json Adds explicit @standard-schema/spec dependency metadata for Node/Bun installs.
deno.lock Updates locked JSR Optique versions to 1.0.2 and refreshes integrity entries.
deno.json Updates Optique import mappings to ^1.0.2.
Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported
Comments suppressed due to low confidence (1)

packages/cli/src/options.ts:90

  • In createTunnelOption, key always returns a boolean (it treats an absent config value as false and then negates), and default: true is also specified. This makes the default option effectively unreachable and duplicates the source of truth for the default behavior. Consider returning undefined from key when the config field is absent and keeping default: true as the single fallback mechanism.
      {
        context: configContext,
        key: (config: Config) => !(config[section]?.noTunnel ?? false),
        default: true,
      },

Comment thread packages/cli/src/lookup.ts Outdated
@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. More of your lovely PRs please.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Keep config-bound fallback values in one place by returning raw config
values from key callbacks and relying on bindConfig's default option
for missing values.  This avoids drift between duplicated fallback
expressions for lookup recursion depth and tunnel defaults.

Addresses fedify-dev#728 (comment)
Addresses fedify-dev#728 (review)

Assisted-by: Codex:gpt-5.5
@dahlia
Copy link
Copy Markdown
Member Author

dahlia commented Apr 26, 2026

Also addressed the createTunnelOption fallback note from #728 (review) in dcd20e9 by returning undefined when noTunnel is absent and leaving default: true as the single fallback.

@dahlia
Copy link
Copy Markdown
Member Author

dahlia commented Apr 26, 2026

@codex review

@dahlia
Copy link
Copy Markdown
Member Author

dahlia commented Apr 26, 2026

/gemini review

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 26, 2026

Codecov Report

❌ Patch coverage is 76.92308% with 6 lines in your changes missing coverage. Please review.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
packages/cli/src/options.ts 57.14% 6 Missing ⚠️
Files with missing lines Coverage Δ
packages/cli/src/lookup.ts 71.77% <100.00%> (-0.11%) ⬇️
packages/cli/src/options.ts 94.33% <57.14%> (-5.67%) ⬇️
🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 🚀

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates the @optique dependencies to version 1.0.2 and adds @standard-schema/spec to the project. The CLI configuration logic was refactored to use the default property within bindConfig and the optional utility, replacing several instances of withDefault. Additionally, the tunnel option mapping was updated to explicitly handle nullish values, ensuring the configuration fallback mechanism functions correctly. New test cases were added to verify that the tunnel, inbox, and relay runners handle omitted tunnel services as expected. I have no feedback to provide.

@dahlia dahlia marked this pull request as ready for review April 26, 2026 12:46
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
deno.json (1)

38-79: 🧹 Nitpick | 🔵 Trivial

Consider adding @standard-schema/spec to deno.json imports for consistency with JSR packages.

@standard-schema/spec was added to packages/cli/package.json as a dependency for @optique/config's peer requirements, but no corresponding entry exists in deno.json. The codebase has no direct imports of @standard-schema/spec, so Deno resolves it transitively through @optique/config's JSR metadata. However, for consistency with the convention of explicitly declaring dependencies in both configuration files, consider adding:

"@standard-schema/spec": "jsr:`@standard-schema/spec`@^1.1.0",

The JSR package exists and version 1.1.0 is available.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@deno.json` around lines 38 - 79, The deno.json imports are missing an
explicit JSR entry for the peer dependency "@standard-schema/spec" (which causes
implicit/transitive resolution via `@optique/config`); add an imports entry for
"@standard-schema/spec" in the existing "imports" object using the JSR spec
syntax, e.g. add "@standard-schema/spec": "jsr:`@standard-schema/spec`@^1.1.0" to
the "imports" map so Deno resolves the package explicitly and matches the
package.json dependency.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/cli/src/options.ts`:
- Around line 88-91: Hoist the repeated indexed access by assigning
config[section] to a local (e.g., const sect = config[section]) and then use
that local in the arrow for key to perform the null check and negation (replace
both config[section] uses with sect and use optional chaining on the check as
needed), so the expression becomes: const sect = config[section]; sect?.noTunnel
== null ? undefined : !sect.noTunnel — this ensures safe narrowing and removes
the redundant lookup for functions referencing section and config.

---

Outside diff comments:
In `@deno.json`:
- Around line 38-79: The deno.json imports are missing an explicit JSR entry for
the peer dependency "@standard-schema/spec" (which causes implicit/transitive
resolution via `@optique/config`); add an imports entry for
"@standard-schema/spec" in the existing "imports" object using the JSR spec
syntax, e.g. add "@standard-schema/spec": "jsr:`@standard-schema/spec`@^1.1.0" to
the "imports" map so Deno resolves the package explicitly and matches the
package.json dependency.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 7207b2a1-e132-4319-a3d8-d8f42d4dba22

📥 Commits

Reviewing files that changed from the base of the PR and between 96f2567 and dcd20e9.

⛔ Files ignored due to path filters (2)
  • deno.lock is excluded by !**/*.lock
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (6)
  • deno.json
  • packages/cli/package.json
  • packages/cli/src/lookup.ts
  • packages/cli/src/options.ts
  • packages/cli/src/tunnel.test.ts
  • pnpm-workspace.yaml

Comment thread packages/cli/src/options.ts Outdated
dahlia added 2 commits April 26, 2026 21:57
Hoist the section config lookup before checking noTunnel so the
nullish check and boolean negation share the same narrowed value.
This removes repeated indexed access in the config fallback callback.

Addresses fedify-dev#728 (comment)

Assisted-by: Codex:gpt-5.5
Add @standard-schema/spec to the Deno import map as well as the npm
package metadata so the peer dependency introduced for @optique/config
is declared consistently across runtimes.

Addresses fedify-dev#728 (review)

Assisted-by: Codex:gpt-5.5
@dahlia
Copy link
Copy Markdown
Member Author

dahlia commented Apr 26, 2026

Addressed the @standard-schema/spec Deno manifest note from #728 (review) in ea162f5 by adding the JSR import-map entry and refreshing deno.lock.

@dahlia
Copy link
Copy Markdown
Member Author

dahlia commented Apr 26, 2026

@codex review

@dahlia
Copy link
Copy Markdown
Member Author

dahlia commented Apr 26, 2026

/gemini review

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates the @optique suite of dependencies to version 1.0.2 and introduces @standard-schema/spec version 1.1.0 across the workspace. In the CLI package, the configuration binding logic for recurse-depth and tunnel options was refactored to use the built-in default property within bindConfig and the optional utility, replacing the previous withDefault wrappers. Additionally, new test cases were added to packages/cli/src/tunnel.test.ts to verify that the CLI runners correctly handle omitted tunnel service configurations. I have no feedback to provide.

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Keep them coming!

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@dahlia dahlia requested review from 2chanhaeng and sij411 April 26, 2026 13:08
Copy link
Copy Markdown
Contributor

@sij411 sij411 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me.

@dahlia dahlia merged commit 6e28e6e into fedify-dev:main Apr 26, 2026
16 of 17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

component/cli CLI tools related dependencies Dependency updates and issues type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants