Skip to content

fix(cli): forward launcher signals to native child - #1667

Merged
ryoppippi merged 2 commits into
mainfrom
codex/fix/cli-signal-forwarding
Aug 30, 2026
Merged

ryoppippi merged 2 commits into
mainfrom
codex/fix/cli-signal-forwarding

Conversation

@ryoppippi

@ryoppippi ryoppippi commented Aug 30, 2026 •

Copy link
Copy Markdown
Member

Addresses #1596\n\nThe npm launcher forwards every catchable termination signal to the native child and removes the forwarding listeners when the child exits or fails to spawn.\n\nThis covers the catchable-signal orphan path. SIGKILL cannot be intercepted by Node, and platform-native parent-death handling remains out of scope, so this PR must not auto-close the issue.\n\nUnix signals: SIGINT, SIGTERM, SIGHUP, SIGQUIT.\nWindows console signals: SIGINT, SIGBREAK, SIGHUP.\n\nValidation:\n- 34 launcher tests passed\n- oxlint passed\n- treefmt passed\n\nThe issue reporter is included as a commit co-author.

Forward catchable launcher termination signals to the native child, ignore duplicate deliveries per signal, and remove the listeners when the child exits or errors. This covers the catchable signal path only; SIGKILL and platform-native parent-death handling remain out of scope.

Co-authored-by: devinsays <[email protected]>
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Aug 30, 2026 •

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
ccusage-guide f9f3ecc Commit Preview URL

Branch Preview URL
Aug 30 2026, 03:32 AM

@coderabbitai

coderabbitai Bot commented Aug 30, 2026 •

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: fb6eacec-5972-4058-a5bb-ad35d3d7ecc8

📥 Commits

Reviewing files that changed from the base of the PR and between e697018 and f9f3ecc.

📒 Files selected for processing (2)
  • apps/ccusage/src/cli.js
  • apps/ccusage/src/cli.test.ts

Included review availability: Your plan provides up to 10 included reviews per hour; 7 remain after this review.


📝 Walkthrough

Walkthrough

The CLI native spawner now accepts injectable dependencies, forwards platform-specific signals to the native child on every occurrence, and removes listeners after exit or error. Tests cover signal selection, repeated forwarding, result handling, and cleanup.

Changes

Native signal forwarding

Layer / File(s) Summary
Native spawner implementation
apps/ccusage/src/cli.js
createNativeSpawner supports injected platform, signal source, and spawn function values. It forwards platform-specific signals with child.kill, cleans up handlers after child completion, and exports the spawner.
Native spawner validation
apps/ccusage/src/cli.test.ts
Tests verify repeated signal forwarding, Windows signal selection, exit and error results, and listener cleanup.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Merge Risk: ⚪ Minimal · up to f9f3e

The npm launcher now forwards catchable termination signals to its native child and cleans up handlers when the child exits or fails to start. This is a localized behavior fix with no actionable merge-blocking risk remaining after normal checks and review.

Sequence Diagram(s)

sequenceDiagram
  participant signalSource
  participant createNativeSpawner
  participant nativeChild
  signalSource->>createNativeSpawner: Emit supported signal
  createNativeSpawner->>nativeChild: Call child.kill(signal)
  nativeChild-->>createNativeSpawner: Exit or error
  createNativeSpawner->>signalSource: Remove signal listeners
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The changes satisfy issue #1596 by forwarding supported Unix and Windows signals, forwarding repeated deliveries, and removing listeners after child error or exit. SIGKILL handling and native parent-d…
Out of Scope Changes check ✅ Passed The code, exports, type definitions, and tests directly support signal forwarding and listener cleanup. No unrelated code changes are identified.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 3 functions across 2 files.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: forwarding launcher signals to the native child process.
Full details: Linked Issues check

Explanation

The changes satisfy issue #1596 by forwarding supported Unix and Windows signals, forwarding repeated deliveries, and removing listeners after child error or exit. SIGKILL handling and native parent-death detection remain correctly out of scope.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/fix/cli-signal-forwarding

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.

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Important

Repeated termination signals can still leave the launcher and native child running when the first signal is handled or ignored.

Reviewed changes

The review covers the new launcher signal forwarding and its lifecycle tests.

  • Signal forwarding: Adds platform-specific termination signal handlers that forward signals to the native child.
  • Listener cleanup: Removes forwarding handlers when the child exits or fails to spawn, with focused tests for both paths.

Pullfrog  | ⚠️ this action is pinned to a commit SHA, which freezes the cleanup step — switch to @v0 or keep the SHA fresh with Dependabot | Fix all ➔ | Fix 👍s ➔ | View workflow run | Using GPT Luna (free via Pullfrog for OSS) | 𝕏

Comment thread apps/ccusage/src/cli.js Resolved
@pkg-pr-new

pkg-pr-new Bot commented Aug 30, 2026 •

Copy link
Copy Markdown

Open in StackBlitz

ccusage

npx https://pkg.pr.new/ccusage@1667

@ccusage/ccusage-darwin-arm64

npx https://pkg.pr.new/@ccusage/ccusage-darwin-arm64@1667

@ccusage/ccusage-darwin-x64

npx https://pkg.pr.new/@ccusage/ccusage-darwin-x64@1667

@ccusage/ccusage-linux-arm64

npx https://pkg.pr.new/@ccusage/ccusage-linux-arm64@1667

@ccusage/ccusage-linux-x64

npx https://pkg.pr.new/@ccusage/ccusage-linux-x64@1667

@ccusage/ccusage-win32-x64

npx https://pkg.pr.new/@ccusage/ccusage-win32-x64@1667

commit: f9f3ecc

@github-actions

Copy link
Copy Markdown
Contributor

ccusage performance comparison

PR SHA: e697018c40ed
Base SHA: 527ec3a9cefa

This compares the Rust PR release binary against the configured base package on the same CI runner.

Package runtime diagnostics

Compares the PR package wrapper, the installed native optional dependency binary, and the workspace release binary on the same large fixture. This identifies whether slow package results come from JavaScript wrapper overhead, the published native binary build, or the Rust core itself.

Fixtures: Claude /home/runner/_work/_temp/ccusage-large-fixture (1.01 GiB, 2597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2597 files)
All rows run --offline --json, measured by hyperfine with 0 warmups and 1 runs. This isolates wrapper overhead from the installed native optional dependency and the workspace release binary built on the runner.

Command Runtime Input Median Throughput Samples
claude --offline --json Package wrapper 1.01 GiB 375.6ms 2.68 GiB/s 1
claude --offline --json Installed native binary 1.01 GiB 304.9ms 3.30 GiB/s 1
codex --offline --json Package wrapper 1.01 GiB 135.0ms 7.46 GiB/s 1
codex --offline --json Installed native binary 1.01 GiB 105.6ms 9.54 GiB/s 1

Committed fixture performance

Committed small fixtures for stable PR-to-PR feedback and explicit Claude/Codex command coverage.

Fixtures: Claude apps/ccusage/test/fixtures/claude (0.00 MiB, 2 files), Codex apps/ccusage/test/fixtures/codex (0.00 MiB, 1 files)
Base runs the published ccusage package from pkg.pr.new, installed before measurement; PR runs the published native ccusage binary from pkg.pr.new, installed before measurement. Both run --offline --json, measured by hyperfine with 2 warmups and 7 runs.
Peak RSS is measured separately with /usr/bin/time using 1 runs. Lower RSS ratios are better.

Command Input Base median PR median PR vs base Base peak RSS PR peak RSS PR/base RSS Base throughput PR throughput
claude daily --offline --json 0.00 MiB 41.1ms 10.8ms 3.80x 55.25 MiB 24.71 MiB 0.45x 0.04 MiB/s 0.14 MiB/s
claude session --offline --json 0.00 MiB 33.2ms 10.4ms 3.19x 55.50 MiB 24.71 MiB 0.45x 0.05 MiB/s 0.15 MiB/s
codex daily --offline --json 0.00 MiB 35.1ms 9.4ms 3.72x 55.25 MiB 24.96 MiB 0.45x 0.02 MiB/s 0.09 MiB/s
codex session --offline --json 0.00 MiB 33.5ms 8.8ms 3.82x 54.75 MiB 24.96 MiB 0.46x 0.03 MiB/s 0.10 MiB/s

Large real-world-shaped fixture performance

Generated fixtures shaped from aggregate local log statistics: thousands of JSONL files, many small sessions, and a long tail of larger sessions. No real prompts, paths, or outputs are stored in the fixtures.

Fixtures: Claude /home/runner/_work/_temp/ccusage-large-fixture (1.01 GiB, 2597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2597 files)
Base runs the published ccusage package from pkg.pr.new, installed before measurement; PR runs the published native ccusage binary from pkg.pr.new, installed before measurement. Both run --offline --json, measured by hyperfine with 0 warmups and 1 runs.
Peak RSS is measured separately with /usr/bin/time using 1 runs. Lower RSS ratios are better.

Command Input Base median PR median PR vs base Base peak RSS PR peak RSS PR/base RSS Base throughput PR throughput
claude --offline --json 1.01 GiB 356.1ms 321.4ms 1.11x 912.84 MiB 958.84 MiB 1.05x 2.83 GiB/s 3.13 GiB/s
codex --offline --json 1.01 GiB 131.0ms 109.0ms 1.20x 435.17 MiB 447.17 MiB 1.03x 7.69 GiB/s 9.24 GiB/s

Artifact size

Artifact Base PR Delta Ratio
packed ccusage-*.tgz 19.20 KiB 19.62 KiB +0.42 KiB 0.98x
installed native package binary 4302.03 KiB 4302.03 KiB +0.00 KiB 1.00x

Lower medians and smaller artifacts are better. CI runner noise still applies; use same-run ratios as directional PR feedback, not release guarantees.

@github-actions

Copy link
Copy Markdown
Contributor

ccusage performance comparison

PR SHA: e697018c40ed
Base SHA: 527ec3a9cefa

This compares the PR package against the configured base package on the same CI runner.

Package runtime diagnostics

Compares the PR package wrapper, the installed native optional dependency binary, and the workspace release binary on the same large fixture. This identifies whether slow package results come from JavaScript wrapper overhead, the published native binary build, or the Rust core itself.

Fixtures: Claude /home/runner/_work/_temp/ccusage-large-fixture (1.01 GiB, 2597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2597 files)
All rows run --offline --json, measured by hyperfine with 0 warmups and 1 runs. This isolates wrapper overhead from the installed native optional dependency and the workspace release binary built on the runner.

Command Runtime Input Median Throughput Samples
claude --offline --json Package wrapper 1.01 GiB 377.6ms 2.67 GiB/s 1
claude --offline --json Installed native binary 1.01 GiB 322.1ms 3.13 GiB/s 1
codex --offline --json Package wrapper 1.01 GiB 136.2ms 7.39 GiB/s 1
codex --offline --json Installed native binary 1.01 GiB 109.1ms 9.22 GiB/s 1

Committed fixture performance

Committed small fixtures for stable PR-to-PR feedback and explicit Claude/Codex command coverage.

Fixtures: Claude apps/ccusage/test/fixtures/claude (0.00 MiB, 2 files), Codex apps/ccusage/test/fixtures/codex (0.00 MiB, 1 files)
Base runs the published ccusage package from pkg.pr.new, installed before measurement; PR runs the published ccusage package from pkg.pr.new, installed before measurement. Both run --offline --json, measured by hyperfine with 2 warmups and 7 runs.
Peak RSS is measured separately with /usr/bin/time using 1 runs. Lower RSS ratios are better.

Command Input Base median PR median PR vs base Base peak RSS PR peak RSS PR/base RSS Base throughput PR throughput
claude daily --offline --json 0.00 MiB 41.6ms 46.2ms 0.90x 55.00 MiB 55.00 MiB 1.00x 0.04 MiB/s 0.03 MiB/s
claude session --offline --json 0.00 MiB 33.5ms 36.2ms 0.93x 55.25 MiB 55.25 MiB 1.00x 0.05 MiB/s 0.04 MiB/s
codex daily --offline --json 0.00 MiB 32.6ms 31.4ms 1.04x 54.75 MiB 55.25 MiB 1.01x 0.03 MiB/s 0.03 MiB/s
codex session --offline --json 0.00 MiB 31.2ms 35.0ms 0.89x 55.25 MiB 55.00 MiB 1.00x 0.03 MiB/s 0.02 MiB/s

Large real-world-shaped fixture performance

Generated fixtures shaped from aggregate local log statistics: thousands of JSONL files, many small sessions, and a long tail of larger sessions. No real prompts, paths, or outputs are stored in the fixtures.

Fixtures: Claude /home/runner/_work/_temp/ccusage-large-fixture (1.01 GiB, 2597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2597 files)
Base runs the published ccusage package from pkg.pr.new, installed before measurement; PR runs the published ccusage package from pkg.pr.new, installed before measurement. Both run --offline --json, measured by hyperfine with 0 warmups and 1 runs.
Peak RSS is measured separately with /usr/bin/time using 1 runs. Lower RSS ratios are better.

Command Input Base median PR median PR vs base Base peak RSS PR peak RSS PR/base RSS Base throughput PR throughput
claude --offline --json 1.01 GiB 362.4ms 328.1ms 1.10x 946.85 MiB 974.85 MiB 1.03x 2.78 GiB/s 3.07 GiB/s
codex --offline --json 1.01 GiB 130.0ms 135.5ms 0.96x 443.16 MiB 443.17 MiB 1.00x 7.75 GiB/s 7.43 GiB/s

Artifact size

Artifact Base PR Delta Ratio
packed ccusage-*.tgz 19.20 KiB 19.62 KiB +0.42 KiB 0.98x
installed native package binary 4302.03 KiB 4302.03 KiB +0.00 KiB 1.00x

Lower medians and smaller artifacts are better. CI runner noise still applies; use same-run ratios as directional PR feedback, not release guarantees.

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

All reported issues were addressed across 2 files

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread apps/ccusage/src/cli.js Resolved
Forward every catchable launcher signal delivery without suppressing repeated deliveries. Use SIGINT, SIGBREAK, and SIGHUP on Windows while retaining the Unix signal set, and cover both behaviors in focused tests.

Co-authored-by: devinsays <[email protected]>

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✅ No new issues found.

Reviewed changes

The review covers the commits added since the prior Pullfrog review, including repeated signal delivery and Windows console signal handling.

  • Removed repeat suppression — Forwarded every supported signal delivery while the native child is running.
  • Added Windows signal coverage — Replaced the unsupported Windows SIGTERM listener with SIGBREAK and SIGHUP, and added focused tests for the platform-specific set.

Pullfrog  | ⚠️ this action is pinned to a commit SHA, which freezes the cleanup step — switch to @v0 or keep the SHA fresh with Dependabot | View workflow run | Using GPT Luna (free via Pullfrog for OSS) | 𝕏

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

1 issue found across 2 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="apps/ccusage/src/cli.js">

<violation number="1" location="apps/ccusage/src/cli.js:168">
P2: On Windows these signals never reach the native child as a catchable signal: Node's `subprocess.kill()` coerces `SIGINT`, `SIGBREAK`, and `SIGHUP` into an abrupt force-terminate (TerminateProcess / SIGKILL-like), so it cannot deliver an interrupt the Rust binary can handle. The win32 test mocks `kill` and therefore does not reflect the real behavior, and a Ctrl+C / console-close during a write leaves no graceful-shutdown path for the child. This is a Windows design limitation rather than a regression (SIGINT was already forwarded this way), but it runs counter to the PR's stated 'catchable-signal' premise, so it's worth confirming the intent before relying on it.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread apps/ccusage/src/cli.js
*/
function getForwardedSignals(platform = process.platform) {
if (platform === 'win32') {
return ['SIGINT', 'SIGBREAK', 'SIGHUP'];

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2: On Windows these signals never reach the native child as a catchable signal: Node's subprocess.kill() coerces SIGINT, SIGBREAK, and SIGHUP into an abrupt force-terminate (TerminateProcess / SIGKILL-like), so it cannot deliver an interrupt the Rust binary can handle. The win32 test mocks kill and therefore does not reflect the real behavior, and a Ctrl+C / console-close during a write leaves no graceful-shutdown path for the child. This is a Windows design limitation rather than a regression (SIGINT was already forwarded this way), but it runs counter to the PR's stated 'catchable-signal' premise, so it's worth confirming the intent before relying on it.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/ccusage/src/cli.js, line 168:

<comment>On Windows these signals never reach the native child as a catchable signal: Node's `subprocess.kill()` coerces `SIGINT`, `SIGBREAK`, and `SIGHUP` into an abrupt force-terminate (TerminateProcess / SIGKILL-like), so it cannot deliver an interrupt the Rust binary can handle. The win32 test mocks `kill` and therefore does not reflect the real behavior, and a Ctrl+C / console-close during a write leaves no graceful-shutdown path for the child. This is a Windows design limitation rather than a regression (SIGINT was already forwarded this way), but it runs counter to the PR's stated 'catchable-signal' premise, so it's worth confirming the intent before relying on it.</comment>

<file context>
@@ -165,7 +165,7 @@ function isMainModule({ argvEntry = process.argv[1], moduleUrl, realpathPath = r
 function getForwardedSignals(platform = process.platform) {
 	if (platform === 'win32') {
-		return ['SIGINT', 'SIGTERM'];
+		return ['SIGINT', 'SIGBREAK', 'SIGHUP'];
 	}
 
</file context>

@github-actions

Copy link
Copy Markdown
Contributor

ccusage performance comparison

PR SHA: f9f3ecc6b700
Base SHA: 527ec3a9cefa

This compares the Rust PR release binary against the configured base package on the same CI runner.

Package runtime diagnostics

Compares the PR package wrapper, the installed native optional dependency binary, and the workspace release binary on the same large fixture. This identifies whether slow package results come from JavaScript wrapper overhead, the published native binary build, or the Rust core itself.

Fixtures: Claude /home/runner/_work/_temp/ccusage-large-fixture (1.01 GiB, 2597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2597 files)
All rows run --offline --json, measured by hyperfine with 0 warmups and 1 runs. This isolates wrapper overhead from the installed native optional dependency and the workspace release binary built on the runner.

Command Runtime Input Median Throughput Samples
claude --offline --json Package wrapper 1.01 GiB 366.1ms 2.75 GiB/s 1
claude --offline --json Installed native binary 1.01 GiB 334.9ms 3.01 GiB/s 1
codex --offline --json Package wrapper 1.01 GiB 124.8ms 8.07 GiB/s 1
codex --offline --json Installed native binary 1.01 GiB 100.5ms 10.02 GiB/s 1

Committed fixture performance

Committed small fixtures for stable PR-to-PR feedback and explicit Claude/Codex command coverage.

Fixtures: Claude apps/ccusage/test/fixtures/claude (0.00 MiB, 2 files), Codex apps/ccusage/test/fixtures/codex (0.00 MiB, 1 files)
Base runs the published ccusage package from pkg.pr.new, installed before measurement; PR runs the published native ccusage binary from pkg.pr.new, installed before measurement. Both run --offline --json, measured by hyperfine with 2 warmups and 7 runs.
Peak RSS is measured separately with /usr/bin/time using 1 runs. Lower RSS ratios are better.

Command Input Base median PR median PR vs base Base peak RSS PR peak RSS PR/base RSS Base throughput PR throughput
claude daily --offline --json 0.00 MiB 35.9ms 15.3ms 2.35x 54.75 MiB 24.71 MiB 0.45x 0.04 MiB/s 0.10 MiB/s
claude session --offline --json 0.00 MiB 33.7ms 7.9ms 4.28x 55.00 MiB 24.71 MiB 0.45x 0.05 MiB/s 0.20 MiB/s
codex daily --offline --json 0.00 MiB 35.2ms 7.9ms 4.46x 55.00 MiB 24.96 MiB 0.45x 0.02 MiB/s 0.11 MiB/s
codex session --offline --json 0.00 MiB 30.3ms 7.7ms 3.92x 55.00 MiB 24.96 MiB 0.45x 0.03 MiB/s 0.11 MiB/s

Large real-world-shaped fixture performance

Generated fixtures shaped from aggregate local log statistics: thousands of JSONL files, many small sessions, and a long tail of larger sessions. No real prompts, paths, or outputs are stored in the fixtures.

Fixtures: Claude /home/runner/_work/_temp/ccusage-large-fixture (1.01 GiB, 2597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2597 files)
Base runs the published ccusage package from pkg.pr.new, installed before measurement; PR runs the published native ccusage binary from pkg.pr.new, installed before measurement. Both run --offline --json, measured by hyperfine with 0 warmups and 1 runs.
Peak RSS is measured separately with /usr/bin/time using 1 runs. Lower RSS ratios are better.

Command Input Base median PR median PR vs base Base peak RSS PR peak RSS PR/base RSS Base throughput PR throughput
claude --offline --json 1.01 GiB 374.0ms 341.7ms 1.09x 976.86 MiB 948.85 MiB 0.97x 2.69 GiB/s 2.95 GiB/s
codex --offline --json 1.01 GiB 123.5ms 103.5ms 1.19x 437.17 MiB 443.18 MiB 1.01x 8.15 GiB/s 9.73 GiB/s

Artifact size

Artifact Base PR Delta Ratio
packed ccusage-*.tgz 19.20 KiB 19.59 KiB +0.39 KiB 0.98x
installed native package binary 4302.03 KiB 4302.16 KiB +0.13 KiB 1.00x

Lower medians and smaller artifacts are better. CI runner noise still applies; use same-run ratios as directional PR feedback, not release guarantees.

@github-actions

Copy link
Copy Markdown
Contributor

ccusage performance comparison

PR SHA: f9f3ecc6b700
Base SHA: 527ec3a9cefa

This compares the PR package against the configured base package on the same CI runner.

Package runtime diagnostics

Compares the PR package wrapper, the installed native optional dependency binary, and the workspace release binary on the same large fixture. This identifies whether slow package results come from JavaScript wrapper overhead, the published native binary build, or the Rust core itself.

Fixtures: Claude /home/runner/_work/_temp/ccusage-large-fixture (1.01 GiB, 2597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2597 files)
All rows run --offline --json, measured by hyperfine with 0 warmups and 1 runs. This isolates wrapper overhead from the installed native optional dependency and the workspace release binary built on the runner.

Command Runtime Input Median Throughput Samples
claude --offline --json Package wrapper 1.01 GiB 471.2ms 2.14 GiB/s 1
claude --offline --json Installed native binary 1.01 GiB 446.9ms 2.25 GiB/s 1
codex --offline --json Package wrapper 1.01 GiB 159.6ms 6.31 GiB/s 1
codex --offline --json Installed native binary 1.01 GiB 127.9ms 7.87 GiB/s 1

Committed fixture performance

Committed small fixtures for stable PR-to-PR feedback and explicit Claude/Codex command coverage.

Fixtures: Claude apps/ccusage/test/fixtures/claude (0.00 MiB, 2 files), Codex apps/ccusage/test/fixtures/codex (0.00 MiB, 1 files)
Base runs the published ccusage package from pkg.pr.new, installed before measurement; PR runs the published ccusage package from pkg.pr.new, installed before measurement. Both run --offline --json, measured by hyperfine with 2 warmups and 7 runs.
Peak RSS is measured separately with /usr/bin/time using 1 runs. Lower RSS ratios are better.

Command Input Base median PR median PR vs base Base peak RSS PR peak RSS PR/base RSS Base throughput PR throughput
claude daily --offline --json 0.00 MiB 40.9ms 36.1ms 1.13x 55.25 MiB 55.00 MiB 1.00x 0.04 MiB/s 0.04 MiB/s
claude session --offline --json 0.00 MiB 40.8ms 32.8ms 1.24x 55.00 MiB 55.25 MiB 1.00x 0.04 MiB/s 0.05 MiB/s
codex daily --offline --json 0.00 MiB 30.9ms 30.5ms 1.01x 55.00 MiB 55.25 MiB 1.00x 0.03 MiB/s 0.03 MiB/s
codex session --offline --json 0.00 MiB 51.6ms 58.5ms 0.88x 55.00 MiB 55.00 MiB 1.00x 0.02 MiB/s 0.01 MiB/s

Large real-world-shaped fixture performance

Generated fixtures shaped from aggregate local log statistics: thousands of JSONL files, many small sessions, and a long tail of larger sessions. No real prompts, paths, or outputs are stored in the fixtures.

Fixtures: Claude /home/runner/_work/_temp/ccusage-large-fixture (1.01 GiB, 2597 files), Codex /home/runner/_work/_temp/ccusage-large-codex-fixture (1.01 GiB, 2597 files)
Base runs the published ccusage package from pkg.pr.new, installed before measurement; PR runs the published ccusage package from pkg.pr.new, installed before measurement. Both run --offline --json, measured by hyperfine with 0 warmups and 1 runs.
Peak RSS is measured separately with /usr/bin/time using 1 runs. Lower RSS ratios are better.

Command Input Base median PR median PR vs base Base peak RSS PR peak RSS PR/base RSS Base throughput PR throughput
claude --offline --json 1.01 GiB 559.3ms 559.8ms 1.00x 954.85 MiB 972.86 MiB 1.02x 1.80 GiB/s 1.80 GiB/s
codex --offline --json 1.01 GiB 171.6ms 161.0ms 1.07x 433.17 MiB 441.17 MiB 1.02x 5.87 GiB/s 6.25 GiB/s

Artifact size

Artifact Base PR Delta Ratio
packed ccusage-*.tgz 19.20 KiB 19.59 KiB +0.39 KiB 0.98x
installed native package binary 4302.03 KiB 4302.16 KiB +0.13 KiB 1.00x

Lower medians and smaller artifacts are better. CI runner noise still applies; use same-run ratios as directional PR feedback, not release guarantees.

@ryoppippi
ryoppippi merged commit ee74244 into main Aug 30, 2026
43 checks passed
@ryoppippi
ryoppippi deleted the codex/fix/cli-signal-forwarding branch August 30, 2026 05:02
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