Skip to content

refactor!: rewamp cli#175

Merged
pi0 merged 6 commits into
mainfrom
refactor/cli-serve
Feb 3, 2026
Merged

refactor!: rewamp cli#175
pi0 merged 6 commits into
mainfrom
refactor/cli-serve

Conversation

@pi0

@pi0 pi0 commented Feb 3, 2026

Copy link
Copy Markdown
Member

The CLI codebase had been growing without maintenance. This PR adds a clear srvx serve new command with backward compatibility.

(still releasing as major since there might be slight behavior changes for args)

Summary by CodeRabbit

  • Documentation

    • Reorganized CLI guide with a unified "srvx serve" workflow, updated serve/fetch examples, and clearer common/serve option groups.
  • New Features

    • Enhanced CLI: improved serve and fetch workflows, robust fetch (stdin/body handling, streaming, verbose output) and richer usage/help text.
    • Added structured CLI option typing and exposed loader defaults for configurable entry resolution.
  • Refactor

    • Modularized CLI internals and moved implementations into dedicated modules for clearer public surface.

@coderabbitai

coderabbitai Bot commented Feb 3, 2026

Copy link
Copy Markdown

Caution

Review failed

The pull request is closed.

📝 Walkthrough

Walkthrough

Refactors CLI by extracting in-file logic into modular src/cli/* modules (main, serve, fetch, types, usage), updates call sites and import paths, exposes loader defaults, updates docs and the bin entry invocation, and adds typed CLI option shapes and usage generation. No public API signatures beyond new re-exports/types were widened.

Changes

Cohort / File(s) Summary
CLI surface & re-exports
src/cli.ts
Removed large in-file CLI implementation; now re-exports main, cliFetch, and CLI types from ./cli/* modules.
New CLI modules
src/cli/main.ts, src/cli/serve.ts, src/cli/fetch.ts
Added orchestration (main), server launcher (cliServe, NO_ENTRY_ERROR), and fetch CLI (cliFetch) with request/streaming, child-process and lifecycle handling.
Types & usage text
src/cli/types.ts, src/cli/usage.ts
Introduced typed CLIOptions and MainOptions, global __srvx__, and usage(mainOpts) generator (usage moved under mainOpts.usage).
Loader exports
src/loader.ts
Exported defaultExts and defaultEntries; updated defaultEntries list (replaced .output/server/index with server/server).
Import path updates
src/_plugins.ts, src/log.ts, automd.config.ts
Redirected imports from ./_color.ts/./src/cli.js to ./cli/_utils.ts and ./src/cli/usage.ts respectively.
Bin & invocation
bin/srvx.mjs
Sets globalThis.__srvxMain__ = import.meta.url; wraps usage fields as { usage: { ... } } when calling main.
Docs
docs/1.guide/8.cli.md
Rewrote CLI docs: unified srvx serve workflow, reorganized option groups (COMMON / SERVE / FETCH OPTIONS), updated examples and flags.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • OskarLebuda

Poem

🐰 Hopped from one file to many with cheer,

main, serve, and fetch now appear,
Types tucked neatly in a single nest,
Docs rewrote the serve-and-fetch quest,
Rabbit thumps once — modular and clear. 🥕

🚥 Pre-merge checks | ✅ 1 | ❌ 2
❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'refactor!: rewamp cli' contains a typo ('rewamp' instead of 'revamp') and uses vague language that doesn't clearly convey the scope of changes. While it indicates a CLI refactor, it doesn't specify that this is a significant restructuring involving extraction of CLI logic into separate modules and introduction of new serve/fetch/main handlers. Consider revising to 'refactor!: restructure cli into modular architecture' or 'refactor!: extract and modularize cli handlers' to better reflect the architectural changes, and fix the typo.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

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

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch refactor/cli-serve

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.

@pkg-pr-new

pkg-pr-new Bot commented Feb 3, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/h3js/srvx@175

commit: 55610e1

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🤖 Fix all issues with AI agents
In `@src/cli/fetch.ts`:
- Around line 58-62: The URL construction missed including cliOpts.port so
requests always use default ports; update the base used for new URL in the fetch
logic to include the port when provided (e.g., build the origin as
`http${cliOpts.tls ? "s" : ""}://${cliOpts.host || "localhost"}${cliOpts.port ?
`:${cliOpts.port}` : ""}`) and keep using cliOpts.url for the path; adjust the
code around the URL creation (the const url assignment that references cliOpts,
cliOpts.tls, cliOpts.host, and cliOpts.url) to conditionally append
`:${cliOpts.port}` only when cliOpts.port is set.

In `@src/cli/main.ts`:
- Around line 16-20: The child-process branch runs setupProcessErrorHandlers()
and awaits cliServe(cliOpts) but then continues executing parent logic; add an
early return immediately after the awaited cliServe(cliOpts) call so the child
path exits (e.g., return or process.exit) to prevent the child from falling
through into the parent flow; update the block containing process.send,
setupProcessErrorHandlers, and cliServe(cliOpts) accordingly.

In `@src/cli/serve.ts`:
- Around line 38-70: The code unconditionally sets port: cliOpts.port when
calling srvxServe, which overwrites any port exported in serverOptions; change
this to only set the port when cliOpts.port is provided (e.g., conditionally
include port from cliOpts or merge cliOpts after serverOptions), so
serverOptions.port (from the entry module) remains effective unless the user
passed --port; update the srvxServe call where serverOptions and port:
cliOpts.port are combined to apply the conditional logic (symbols:
serverOptions, cliOpts.port, srvxServe).
- Around line 85-99: The dev error page currently injects raw error text into
the HTML (see the html string building in serve.ts inside the cliOpts.prod
branch where the template includes <pre>${error instanceof Error ? error.stack
|| error.message : String(error)}</pre>); fix this by HTML-escaping the error
content before interpolation (create/use an escapeHtml helper that replaces &,
<, >, ", ' and backticks) and replace the direct interpolation with the escaped
value (e.g., escapedError = escapeHtml(error instanceof Error ? error.stack ||
error.message : String(error)) and use <pre>${escapedError}</pre>); ensure the
helper is used consistently for both Error stack and message cases.
🧹 Nitpick comments (3)
src/cli/usage.ts (1)

2-2: Remove unused import CLIOptions.

CLIOptions is imported but not referenced in this file. Only MainOptions is used.

🧹 Suggested fix
-import type { CLIOptions, MainOptions } from "./types.ts";
+import type { MainOptions } from "./types.ts";
automd.config.ts (1)

20-20: Consider typing _ctx more precisely if automd exports context types.

Using any works but loses type safety. If the automd library exports a context type, consider using it instead.

src/cli/fetch.ts (1)

172-189: Consider expanding binary content-type detection.

The isBinary check covers common cases but misses some binary types like application/x-tar, application/x-7z-compressed, font/*, and model/*. This is a minor gap since unknown types default to text handling, which is generally safe.

Comment thread src/cli/fetch.ts
Comment thread src/cli/main.ts Outdated
Comment thread src/cli/serve.ts
Comment thread src/cli/serve.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🤖 Fix all issues with AI agents
In `@src/cli/main.ts`:
- Around line 86-91: The exit handler currently only accepts `code` and calls
`process.exit(code)`, which misbehaves when a child is killed by a signal (code
=== null). Update the listener signature to (code, signal) in the
child.on("exit", ...) handler, then: if code !== null use process.exit(code);
else if signal != null propagate the signal to the current process (e.g.,
process.kill(process.pid, signal)); otherwise handle as a non-zero failure
(process.exit(1)). This avoids calling process.exit(null) and correctly
propagates signal-based termination.
- Around line 160-165: The call to statSync(maybeEntryOrDir) can throw if the
path doesn't exist; wrap the statSync call in a try-catch around the block that
sets values.dir / values.entry, catch ENOENT (and other FS errors) and surface a
user-friendly error message (or throw a controlled error) instead of letting the
raw stack trace propagate; modify the logic around statSync, maybeEntryOrDir,
and the assignments to values.dir / values.entry to handle missing paths
gracefully and log a clear message indicating the provided positional argument
was not found.
- Around line 70-78: The Node version check that pushes
"--experimental-strip-types" should be narrowed so it only applies to Node 22
(where the flag is still experimental); update the condition around
runtimeArgs.push("--experimental-strip-types") to require major === "22" (and
+minor >= 6 if you want the minor guard), or alternately explicitly skip for
major >= "23". Locate the block that reads process.versions.node and the symbols
isNode, runtimeArgs and adjust the if condition so Node 23+ does not receive the
experimental flag.

In `@src/cli/serve.ts`:
- Line 53: The TLS config currently sets tls: cliOpts.tls ? { cert:
cliOpts.cert, key: cliOpts.key } : undefined which can pass undefined cert/key
when --tls is set without files; update the logic in the serve initialization to
validate that when cliOpts.tls is truthy both cliOpts.cert and cliOpts.key are
present (or else throw/exit with a clear error or print a warning), and only
then set tls: { cert: cliOpts.cert, key: cliOpts.key }; otherwise set tls to
undefined (or abort). Reference cliOpts.tls, cliOpts.cert, cliOpts.key and the
tls property in the serve setup to locate and change the code.
🧹 Nitpick comments (1)
src/cli/main.ts (1)

24-24: Redundant ternary; simplify to process.exit(0).

Since we're inside the if (cliOpts.help) block, cliOpts.help is always truthy here, making the ternary unnecessary.

✨ Suggested fix
-    process.exit(cliOpts.help ? 0 : 1);
+    process.exit(0);

Comment thread src/cli/main.ts
Comment thread src/cli/main.ts
Comment thread src/cli/main.ts
Comment thread src/cli/serve.ts
@pi0 pi0 changed the title refactor: rewamp cli refactor!: rewamp cli Feb 3, 2026
@pi0
pi0 merged commit 3414ca1 into main Feb 3, 2026
11 of 13 checks passed
@pi0
pi0 deleted the refactor/cli-serve branch February 3, 2026 14:24
@coderabbitai coderabbitai Bot mentioned this pull request Jul 6, 2026
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.

1 participant