Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
87771c5
feat(ccusage): add native Rust CLI
ryoppippi May 11, 2026
f328b8f
chore(ccusage): preserve executable entrypoint
ryoppippi May 11, 2026
704b90d
test(ccusage): extend large JSONL stress timeout
ryoppippi May 11, 2026
854ae14
docs(ccusage): record Rust benchmark
ryoppippi May 11, 2026
6b89cc4
fix(ccusage): align Rust loader with TypeScript output
ryoppippi May 11, 2026
1c631d5
docs(ccusage): refresh Rust benchmark
ryoppippi May 11, 2026
b4b933d
feat(ccusage): align native pricing and terminal output
ryoppippi May 11, 2026
936fdb7
docs(ccusage): update native performance benchmark
ryoppippi May 11, 2026
251137e
perf(ccusage): skip redundant cost reassignment
ryoppippi May 11, 2026
4740961
Revert "perf(ccusage): skip redundant cost reassignment"
ryoppippi May 11, 2026
9d20248
Revert "docs(ccusage): update native performance benchmark"
ryoppippi May 11, 2026
5b85607
Revert "feat(ccusage): align native pricing and terminal output"
ryoppippi May 11, 2026
ea0196c
perf(ccusage): speed up TypeScript usage loading
ryoppippi May 11, 2026
61e12b8
Revert "perf(ccusage): speed up TypeScript usage loading"
ryoppippi May 11, 2026
32c27ca
perf(ccusage): reduce native JSONL parse work
ryoppippi May 11, 2026
bc3ed22
Revert "perf(ccusage): reduce native JSONL parse work"
ryoppippi May 11, 2026
0a2a475
Merge remote-tracking branch 'origin/main' into rust
ryoppippi May 11, 2026
64fcc96
perf(ccusage): speed up TypeScript usage loading
ryoppippi May 11, 2026
946621d
perf(ccusage): reduce native JSONL parse work
ryoppippi May 11, 2026
fa875ed
Merge remote-tracking branch 'origin/main' into rust
ryoppippi May 11, 2026
d10dd61
perf(ccusage): use Bun glob for usage discovery
ryoppippi May 11, 2026
dac83d3
perf(ccusage): avoid trimming JSONL lines
ryoppippi May 11, 2026
a7141da
fix(ccusage): keep complete duplicate usage entries
ryoppippi May 11, 2026
ba13d22
perf(ccusage): read Rust usage data in one pass
ryoppippi May 12, 2026
4392f0f
perf(ccusage): shrink Rust timezone support
ryoppippi May 12, 2026
9ee8501
perf(ccusage): parse Rust usage timestamps once
ryoppippi May 12, 2026
a127b17
perf(ccusage): skip Rust content deserialization
ryoppippi May 12, 2026
5857545
perf(ccusage): share Rust file metadata strings
ryoppippi May 12, 2026
0746159
perf(ccusage): accumulate Rust summaries in one pass
ryoppippi May 12, 2026
80ba182
perf(ccusage): drop chrono clock dependency
ryoppippi May 12, 2026
c63dae7
perf(ccusage): replace anyhow in Rust CLI
ryoppippi May 12, 2026
8bc0603
perf(ccusage): format Rust dates without strftime
ryoppippi May 12, 2026
a46c0b3
perf(ccusage): avoid chrono format parsing in Rust CLI
ryoppippi May 12, 2026
084c59e
perf(ccusage): replace clap in Rust CLI
ryoppippi May 12, 2026
4caad29
perf(ccusage): replace rayon in Rust loader
ryoppippi May 12, 2026
96a2f9f
perf(ccusage): remove chrono from Rust CLI
ryoppippi May 12, 2026
2418e39
feat(ccusage): add Rust pricing fetch and JS-style tables
ryoppippi May 12, 2026
532267c
fix(ccusage): preserve ANSI in Rust table truncation
ryoppippi May 12, 2026
3f82fb1
perf(ccusage): avoid Rust dedupe key allocations
ryoppippi May 12, 2026
ab15264
chore: pin Rust toolchain
ryoppippi May 12, 2026
5d3a213
Merge remote-tracking branch 'origin/main' into rust
ryoppippi May 12, 2026
9e4b979
perf(ccusage): balance Rust workers by file size
ryoppippi May 12, 2026
adb5f62
perf(ccusage): tune Rust release optimization level
ryoppippi May 13, 2026
afbe336
fix(ccusage): remove stale Rust locale option
ryoppippi May 13, 2026
7281959
perf(ccusage): optimize Rust dependencies for size
ryoppippi May 13, 2026
2943cc7
perf(ccusage): skip non-usage JSONL lines earlier
ryoppippi May 13, 2026
f8d6cd3
perf(ccusage): place rust worker results by index
ryoppippi May 13, 2026
38da692
ci(ccusage): compare rust performance against main
ryoppippi May 15, 2026
e0439c0
ci(ccusage): benchmark rust package bin without shell
ryoppippi May 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
66 changes: 66 additions & 0 deletions .github/scripts/upsert-pr-comment.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#!/usr/bin/env bun

type GitHubComment = {
body?: string;
id: number;
user?: {
login?: string;
};
};

function requiredEnv(name: string): string {
const value = Bun.env[name];
if (value == null || value.length === 0) {
throw new Error(`${name} is required`);
}
return value;
}

async function githubRequest<T>(path: string, options: RequestInit = {}): Promise<T> {
const response = await fetch(`https://api.github.com${path}`, {
...options,
headers: {
accept: 'application/vnd.github+json',
authorization: `Bearer ${requiredEnv('GITHUB_TOKEN')}`,
'content-type': 'application/json',
'x-github-api-version': '2022-11-28',
...options.headers,
},
});

if (!response.ok) {
throw new Error(
`${options.method ?? 'GET'} ${path} failed: ${response.status} ${await response.text()}`,
);
}

if (response.status === 204) {
return undefined as T;
}

return response.json() as Promise<T>;
}

const repository = requiredEnv('GITHUB_REPOSITORY');
const prNumber = requiredEnv('PR_NUMBER');
const marker = requiredEnv('COMMENT_MARKER');
const body = await Bun.file(requiredEnv('COMMENT_FILE')).text();

const comments = await githubRequest<GitHubComment[]>(
`/repos/${repository}/issues/${prNumber}/comments?per_page=100`,
);
const existing = comments.find(
(comment) => comment.user?.login === 'github-actions[bot]' && comment.body?.includes(marker),
);

if (existing == null) {
await githubRequest(`/repos/${repository}/issues/${prNumber}/comments`, {
method: 'POST',
body: JSON.stringify({ body }),
});
} else {
await githubRequest(`/repos/${repository}/issues/comments/${existing.id}`, {
method: 'PATCH',
body: JSON.stringify({ body }),
});
}
72 changes: 72 additions & 0 deletions .github/workflows/ccusage-rust-perf.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
name: ccusage rust perf comment

on:
pull_request:
types:
- opened
- reopened
- synchronize

permissions:
contents: read
pull-requests: write
issues: write

jobs:
compare:
runs-on: ubuntu-24.04-arm
timeout-minutes: 15

steps:
- name: Checkout PR
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

- name: Checkout base
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
ref: ${{ github.event.pull_request.base.sha }}
path: base

- name: Setup Nix
uses: ./.github/actions/setup-nix

- name: Build base ccusage
run: nix develop --command pnpm --filter ccusage run build
working-directory: base

- name: Build Rust ccusage
run: nix develop --command pnpm --filter ccusage run build

- name: Generate small ccusage fixture
run: |
nix develop --command pnpm exec bun apps/ccusage/scripts/generate-large-fixture.ts \
--output-dir "$RUNNER_TEMP/ccusage-small-fixture" \
--size-mib 8

- name: Generate large ccusage fixture
run: |
nix develop --command pnpm exec bun apps/ccusage/scripts/generate-large-fixture.ts \
--output-dir "$RUNNER_TEMP/ccusage-large-fixture" \
--size-mib 1024

- name: Compare Rust performance
run: |
nix develop --command pnpm exec bun apps/ccusage/scripts/compare-rust-pr-performance.ts \
--base-dir base \
--head-dir . \
--fixture-dir "$RUNNER_TEMP/ccusage-small-fixture" \
--warmup 2 \
--runs 7 \
--large-fixture-dir "$RUNNER_TEMP/ccusage-large-fixture" \
--large-warmup 0 \
--large-runs 1 \
--output "$RUNNER_TEMP/ccusage-rust-perf-comment.md"

- name: Upsert PR comment
env:
COMMENT_FILE: ${{ runner.temp }}/ccusage-rust-perf-comment.md
COMMENT_MARKER: <!-- ccusage-rust-perf-comment -->
GITHUB_TOKEN: ${{ github.token }}
GITHUB_REPOSITORY: ${{ github.repository }}
PR_NUMBER: ${{ github.event.pull_request.number }}
run: nix develop --command pnpm exec bun .github/scripts/upsert-pr-comment.ts
Loading
Loading