Skip to content

Update @fedify/cli for Optique 1.0.0#677

Merged
dahlia merged 6 commits intofedify-dev:mainfrom
dahlia:chore/optique-1.0.0-cli
Apr 15, 2026
Merged

Update @fedify/cli for Optique 1.0.0#677
dahlia merged 6 commits intofedify-dev:mainfrom
dahlia:chore/optique-1.0.0-cli

Conversation

@dahlia
Copy link
Copy Markdown
Member

@dahlia dahlia commented Apr 15, 2026

Summary

  • Bump the shared Optique dependencies to 1.0.0 in deno.json, pnpm-workspace.yaml, and the lockfiles.
  • Switch packages/cli/src/mod.ts from runWithConfig() to run(), pass contexts and contextOptions, and update the help/completion wiring for Optique 1.0.
  • Adjust CLI parser tests in packages/cli/src/lookup.test.ts, packages/cli/src/tunnel.test.ts, and packages/cli/src/webfinger/mod.test.ts.
  • Fix a runtime issue in packages/init/src/action/configs.ts found during fedify startup smoke tests.

Why

Optique 1.0.0 removes runWithConfig() and replaces it with the finalized runner and context API. This keeps the Fedify CLI compatible with the 1.0 release without changing config loading or shell completion behavior.

Release notes: dahlia/optique#796

Testing

  • deno task -f @fedify/cli test
  • node --test --experimental-transform-types 'src/**/*.test.ts' '!src/init/test/**' in packages/cli
  • pnpm test in packages/init
  • node --disable-warning=ExperimentalWarning dist/mod.js --help in packages/cli
  • node --disable-warning=ExperimentalWarning dist/mod.js completions bash in packages/cli
  • node dist/test/mod.js --help in packages/init
  • node dist/mod.js --help in packages/create

Upgrade the shared Optique packages to 1.0.0 so fedify can use the
stable runner and config-context APIs. This switches the CLI entrypoint
from runWithConfig() to run() with contextOptions, updates parser tests
for the new config annotation flow, and keeps help entrypoints runnable
by removing an outdated @fxts/core helper from @fedify/init.

Assisted-by: OpenCode:gpt-5.4
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 15, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Replaces in-module config wiring with a new CLI runner exporting command, loadConfig, and runCli; tightens tunnel option typing and makes the tunnel service option optional; bumps Optique workspace dependencies to ^1.0.0; moves inbox/relay command schemas into dedicated files; and updates tests to new parsing and runner APIs.

Changes

Cohort / File(s) Summary
Dependency Version Upgrades
deno.json, pnpm-workspace.yaml
Bumped @optique/config, @optique/core, and @optique/run from ^0.10.7^1.0.0.
New CLI runner & entrypoint
packages/cli/src/runner.ts, packages/cli/src/mod.ts
Added runner.ts exporting command, loadConfig, and runCli(args); replaced prior runWithConfig-based entry in mod.ts with runCli(process.argv.slice(2)) and direct dispatch to subcommands.
Config-loading behavior
packages/cli/src/runner.ts
Introduces platform-aware system/user/project config discovery, optional --configPath loading, TOML parsing and deep-merge, and process exit on unreadable custom config.
Command decomposition
packages/cli/src/inbox/command.ts, packages/cli/src/relay/command.ts, packages/cli/src/inbox.tsx, packages/cli/src/relay.ts
Moved inbox and relay option schemas into .../command.ts files; callers now import inferred command types and accept those types in runInbox/runRelay.
Option typing & optionality
packages/cli/src/options.ts, packages/cli/src/lookup.ts
createTunnelServiceOption signature tightened to readonly [OptionName, ...OptionName[]]; authorizedFetchOption now wraps tunnel service option in optional(...), making tunnelService nullable/absent by default.
Tests: parsing & runner API changes
packages/cli/src/lookup.test.ts, packages/cli/src/tunnel.test.ts, packages/cli/src/webfinger/mod.test.ts, packages/init/src/action/configs.test.ts
Removed global active-config helpers; added local parseWithConfig helper; switched some tests to runSync; added CLI runner integration tests using temp FS; added Deno-version-based config tests.
Init config logic
packages/init/src/action/configs.ts
Refactored unstable-temporal detection and version parsing logic; adjusted how unstable field is produced.
New/removed CLI exports and types
packages/cli/src/runner.ts, packages/cli/src/inbox.tsx, packages/cli/src/relay.ts
Added exported command, loadConfig, and runCli; removed in-file inboxCommand/relayCommand exports and replaced usage with imported inferred types.
Test & script tweaks
packages/vocab-tools/package.json, packages/cli/src/tunnel.test.ts
Increased Bun test timeout and adjusted test imports to new APIs and Node temp-path utilities.

Sequence Diagram(s)

sequenceDiagram
    participant User as User CLI
    participant Runner as CLI Runner
    participant Config as Config Loader
    participant Parser as Option Parser
    participant CmdExec as Command Executor

    rect rgba(200, 150, 255, 0.5)
    Note over User,CmdExec: Old Flow (pre-runner)
    User->>Runner: start (old entry)
    Runner->>Config: setActiveConfig()/global config
    Runner->>Parser: parse(args) [reads global active config]
    Parser->>CmdExec: return parsed command
    Runner->>CmdExec: runWithConfig(command, configContext, ...)
    Runner->>Config: clearActiveConfig()
    end

    rect rgba(150, 200, 255, 0.5)
    Note over User,CmdExec: New Flow (runner-based)
    User->>Runner: runCli(args)
    Runner->>Parser: parse(parser, args, { annotations })
    Runner->>Config: loadConfig(parsed) (system/user/project/custom)
    Config-->>Runner: { config, meta } | undefined
    Runner->>CmdExec: dispatch and execute selected command
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

suggested labels: type/test, component/build

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: updating the CLI for Optique 1.0.0 dependency upgrade and API migration.
Description check ✅ Passed The description is directly related to the changeset, detailing the Optique 1.0.0 upgrade, API migration from runWithConfig to run, test adjustments, and bug fixes across multiple files.

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

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

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

@issues-auto-labeler issues-auto-labeler Bot added breaking change Requires backward-incompatible change component/build Build system and packaging component/cli CLI tools related labels Apr 15, 2026
@dahlia dahlia added dependencies Dependency updates and issues and removed breaking change Requires backward-incompatible change component/build Build system and packaging labels Apr 15, 2026
@dahlia dahlia added this to the Fedify 2.2 milestone Apr 15, 2026
@dahlia dahlia self-assigned this Apr 15, 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 dependencies to version 1.0.0 and refactors the CLI and initialization logic to align with the new APIs. Key changes include replacing runWithConfig with the new run function in the main entry point, updating test helpers to use a custom parseWithConfig utility instead of global configuration state, and refactoring functional piping in the project initializer for better clarity. Feedback was provided regarding the parseWithConfig test helper, which relies on internal execution phases and manual type casting that may be brittle.

Comment thread packages/cli/src/lookup.test.ts
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: 3

Caution

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

⚠️ Outside diff range comments (1)
packages/cli/src/lookup.test.ts (1)

2-11: ⚠️ Potential issue | 🟡 Minor

Switch this test file to @fedify/fixture.

It still uses node:test, which skips the repository’s runtime-agnostic wrapper.

As per coding guidelines, **/*.test.{ts,tsx}: Import test from @fedify/fixture for runtime-agnostic tests instead of using environment-specific test APIs.

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

In `@packages/cli/src/lookup.test.ts` around lines 2 - 11, The test file imports
the test runner from node:test which bypasses the repo’s runtime-agnostic
wrapper; replace the import "test from 'node:test'" with importing test from
"@fedify/fixture" (i.e., update the import statement that provides the test
symbol) so all tests use the repository’s fixture wrapper and remain
runtime-agnostic; ensure any usages of the test symbol and related test
utilities remain unchanged after switching the import.
🤖 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/lookup.test.ts`:
- Around line 33-46: The test helper parseWithConfig bypasses the real context
loading, so add at least one runner-level regression test that calls the CLI
entrypoint run(...) (the runner) and exercises --config and --ignore-config
paths using real contextOptions.load behavior; specifically add a test that
invokes run with args including --config and another with --ignore-config,
stubbing or creating a temporary config file and asserting behavior differs as
expected, ensuring you reference and cover the run function in
packages/cli/src/mod.ts and avoid using parseWithConfig for these cases so the
contextOptions.load path is exercised.

In `@packages/cli/src/tunnel.test.ts`:
- Around line 2-4: Replace the environment-specific test import with the repo's
runtime-agnostic fixture: remove "import test from 'node:test'" and import the
test entrypoint from "@fedify/fixture" instead (so existing uses of the test
function in this file—e.g., tests that call test(...)—continue to work); keep
the other imports (runSync, deepEqual, rejects) unchanged and verify any test
options/signatures align with the `@fedify/fixture` test API.

In `@packages/init/src/action/configs.ts`:
- Around line 74-83: The needsUnstableTemporal() logic is inverted: it currently
returns true for Deno >= 2.7.0 but should return true only for Deno < 2.7.0;
update the function so when parseVersion yields an array it uses an "earlier
than" check (or negates isLaterOrEqualThan(TEMPORAL_STABLE_FROM)) to return true
for versions before TEMPORAL_STABLE_FROM, and when version is not an array
return false (omit unstable.temporal). Keep references to
getDenoVersionFromRuntime, getDenoVersionFromCommand, parseVersion and
TEMPORAL_STABLE_FROM when making the change.

---

Outside diff comments:
In `@packages/cli/src/lookup.test.ts`:
- Around line 2-11: The test file imports the test runner from node:test which
bypasses the repo’s runtime-agnostic wrapper; replace the import "test from
'node:test'" with importing test from "@fedify/fixture" (i.e., update the import
statement that provides the test symbol) so all tests use the repository’s
fixture wrapper and remain runtime-agnostic; ensure any usages of the test
symbol and related test utilities remain unchanged after switching the import.
🪄 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: 9e13929a-2ffc-4598-a682-241b3e2efaa5

📥 Commits

Reviewing files that changed from the base of the PR and between fe50936 and c7c209b.

⛔ 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 (9)
  • deno.json
  • packages/cli/src/lookup.test.ts
  • packages/cli/src/lookup.ts
  • packages/cli/src/mod.ts
  • packages/cli/src/options.ts
  • packages/cli/src/tunnel.test.ts
  • packages/cli/src/webfinger/mod.test.ts
  • packages/init/src/action/configs.ts
  • pnpm-workspace.yaml
💤 Files with no reviewable changes (1)
  • packages/cli/src/webfinger/mod.test.ts

Comment thread packages/cli/src/lookup.test.ts
Comment thread packages/cli/src/tunnel.test.ts
Comment thread packages/init/src/action/configs.ts
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 15, 2026

Codecov Report

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

Files with missing lines Patch % Lines
packages/cli/src/runner.ts 84.07% 13 Missing and 5 partials ⚠️
packages/cli/src/relay/command.ts 99.04% 1 Missing ⚠️
packages/init/src/action/configs.ts 90.90% 0 Missing and 1 partial ⚠️
Files with missing lines Coverage Δ
packages/cli/src/inbox/command.ts 100.00% <100.00%> (ø)
packages/cli/src/lookup.ts 68.54% <100.00%> (+0.08%) ⬆️
packages/cli/src/options.ts 100.00% <100.00%> (+19.80%) ⬆️
packages/cli/src/relay/command.ts 99.04% <99.04%> (ø)
packages/init/src/action/configs.ts 69.12% <90.90%> (ø)
packages/cli/src/runner.ts 84.07% <84.07%> (ø)

... and 26 files with indirect coverage changes

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Add runner-level CLI tests for --config and --ignore-config so the
Optique 1.0 load path is exercised instead of only parser annotations.
This also fixes the Deno Temporal version check in @fedify/init and
adds regression tests for versions before and after Deno 2.7.0.

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

dahlia commented Apr 15, 2026

For the outside-diff suggestion in CodeRabbit's review summary about switching packages/cli/src/lookup.test.ts to @fedify/fixture, I kept node:test there as well. The CLI package tests are intentionally Node-specific, the same as in the tunnel test thread.

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: 2

Caution

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

⚠️ Outside diff range comments (1)
packages/cli/src/mod.ts (1)

21-24: ⚠️ Potential issue | 🟠 Major

Missing await on async command handlers.

Both runInbox and runNodeInfo are async functions (per packages/cli/src/nodeinfo.ts:109-111), but they're called without await. This means:

  1. main() completes before these commands finish executing
  2. Any errors thrown will result in unhandled promise rejections
  3. The process exit code won't reflect command failures
🔧 Proposed fix
   } else if (result.command === "inbox") {
-    runInbox(result);
+    await runInbox(result);
   } else if (result.command === "nodeinfo") {
-    runNodeInfo(result);
+    await runNodeInfo(result);
   } else if (result.command === "tunnel") {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/cli/src/mod.ts` around lines 21 - 24, The branches calling the async
command handlers call runInbox(result) and runNodeInfo(result) without awaiting
them, causing main to exit early and unhandled promise rejections; change those
calls in the command dispatch to await runInbox(result) and await
runNodeInfo(result) so main waits for completion and errors propagate correctly
(identify the calls to runInbox and runNodeInfo in the dispatch block and
prepend await).
🤖 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/runner.ts`:
- Around line 122-149: Add a JSDoc comment for the exported function runCli
describing its purpose as the main CLI entry point, document the args parameter
(string[]), and note the return value (the result of run(...), e.g., a Command
runner or Promise if applicable). Place the JSDoc immediately above the runCli
declaration and include short descriptions for the function, the args parameter,
and the return type so callers and generated docs can understand its usage.

In `@packages/init/src/action/configs.test.ts`:
- Around line 1-2: Replace the runtime-specific import of the test runner:
instead of importing test from "node:test" at the top of the file, import test
from "@fedify/fixture" so the test uses the repository's runtime-agnostic
harness; update the import statement that currently references "node:test" to
reference "@fedify/fixture" (leave the assert import and existing test usages
like test(...) unchanged).

---

Outside diff comments:
In `@packages/cli/src/mod.ts`:
- Around line 21-24: The branches calling the async command handlers call
runInbox(result) and runNodeInfo(result) without awaiting them, causing main to
exit early and unhandled promise rejections; change those calls in the command
dispatch to await runInbox(result) and await runNodeInfo(result) so main waits
for completion and errors propagate correctly (identify the calls to runInbox
and runNodeInfo in the dispatch block and prepend await).
🪄 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: 985484aa-ca08-4ea8-93d2-9a5de5871a3c

📥 Commits

Reviewing files that changed from the base of the PR and between c7c209b and 689d861.

📒 Files selected for processing (5)
  • packages/cli/src/lookup.test.ts
  • packages/cli/src/mod.ts
  • packages/cli/src/runner.ts
  • packages/init/src/action/configs.test.ts
  • packages/init/src/action/configs.ts

Comment thread packages/cli/src/runner.ts
Comment thread packages/init/src/action/configs.test.ts
Await the inbox and nodeinfo handlers so the CLI does not exit before
those commands finish and still reports failures through the process
exit status. This also documents the shared runCli() helper now that it
acts as the entrypoint for the Optique 1.0 runner setup.

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

dahlia commented Apr 15, 2026

For CodeRabbit's outside-diff note about missing await in packages/cli/src/mod.ts, I fixed that in 4b28b9a by awaiting both runInbox() and runNodeInfo().

Split the inbox and relay command parsers out of the runtime-heavy
modules so source-level CLI tests do not import .tsx or node:sqlite
under Node and Bun. This also rewrites the Deno version regression
test to replace the global safely and raises the Bun timeout for
vocab-tools so mise test stays green again.

Assisted-by: OpenCode:gpt-5.4
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: 2

🤖 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/inbox/command.ts`:
- Around line 89-91: Update the CLI command help description string (the
description property in the inbox command definition) to correct the grammar:
replace "an one-time actor" with "a one-time actor" so the user-facing message
reads "Spins up an ephemeral server that serves the ActivityPub inbox with a
one-time actor, through a short-lived public DNS with HTTPS. You can monitor the
incoming activities in real-time."

In `@packages/init/src/action/configs.test.ts`:
- Around line 6-43: The test helper createInitData currently uses a double type
cast to InitCommandData which bypasses type safety; replace it by building a
Partial<InitCommandData> (or implement a small builder function like
buildInitCommandData that accepts overrides) and populate all required fields
with sensible defaults (including initializer, kv, mq, env, projectDir, dir,
etc.), then return the constructed object as InitCommandData or merge overrides
into the defaults—this preserves compile-time checks and prevents future silent
breaks in createInitData/InitCommandData usage.
🪄 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: c9f392d9-cf1a-4f48-bede-facd2d4e5c77

📥 Commits

Reviewing files that changed from the base of the PR and between 4b28b9a and 6b2689e.

📒 Files selected for processing (7)
  • packages/cli/src/inbox.tsx
  • packages/cli/src/inbox/command.ts
  • packages/cli/src/relay.ts
  • packages/cli/src/relay/command.ts
  • packages/cli/src/runner.ts
  • packages/init/src/action/configs.test.ts
  • packages/vocab-tools/package.json

Comment thread packages/cli/src/inbox/command.ts
Comment thread packages/init/src/action/configs.test.ts
Fix the inbox help text typo so the extracted command definition keeps
its user-facing wording clean. This also replaces the configs test's
double-cast fixture with a real InitCommandData object, so changes to
that type keep surfacing as compile-time failures.

Assisted-by: Codex:gpt-5.4
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: 2

🤖 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/inbox/command.ts`:
- Around line 53-67: The duplicated default actor strings used in the bindConfig
blocks for actorName and actorSummary should be extracted into constants to
avoid drift; create descriptive constants (e.g., DEFAULT_EPHEMERAL_INBOX_NAME
and DEFAULT_EPHEMERAL_INBOX_SUMMARY) near the top of the module and replace the
repeated literals in both the key fallback expressions and default properties
used by bindConfig/actorName and bindConfig/actorSummary so both the
option("--actor-summary", ...) and the actorName option reference the same
constant values.

In `@packages/init/src/action/configs.test.ts`:
- Around line 74-96: The test title and assertions are mismatched: the first
test's title claims "2.7.0 and newer" but only checks the boundary 2.7.0; either
rename the title to indicate it's a boundary-only check or add an explicit newer
case; to fix, update the test suite either by changing the test title for the
case that calls setDenoVersion({ deno: "2.7.0", ... }) to something like
"loadDenoConfig omits unstable.temporal on Deno 2.7.0 (boundary)" or add a
second test that calls setDenoVersion({ deno: "2.8.0", ... }) and asserts
loadDenoConfig(createInitData()).data.unstable === undefined, using the same
helpers setDenoVersion, restoreDeno, createInitData and the tested function
loadDenoConfig.
🪄 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: b7cb88fe-dc58-404b-9a31-c972b22b8fa0

📥 Commits

Reviewing files that changed from the base of the PR and between 6b2689e and fd47b77.

📒 Files selected for processing (2)
  • packages/cli/src/inbox/command.ts
  • packages/init/src/action/configs.test.ts

Comment thread packages/cli/src/inbox/command.ts Outdated
Comment thread packages/init/src/action/configs.test.ts Outdated
Extract the inbox actor fallback strings into shared constants so the
config defaults stay aligned in one place. This also narrows the Deno
Temporal regression test title to the exact 2.7.0 boundary case that it
asserts, which keeps the test intent precise.

Assisted-by: Codex:gpt-5.4
@dahlia dahlia merged commit 3d1ca85 into fedify-dev:main Apr 15, 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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant