Skip to content

Conversation

@ryoppippi
Copy link
Owner

@ryoppippi ryoppippi commented Sep 16, 2025

Summary by CodeRabbit

  • Chores

    • Migrated repo to a PNPM workspace; CI and release workflows now use pnpm for install, test, lint, typecheck, and publish. Top-level package.json converted to monorepo (private) and pnpm pinned; added pnpm-workspace.yaml.
  • Documentation

    • Docs build/dev and API generation moved to pnpm; schema paths and docs tooling adjusted; VitePress/TypeDoc integration updated; many docs/README examples switched to pnpm; added CLAUDE.md and package docs LICENSE/README.
  • Refactor

    • Introduced packages/ccusage as a dedicated package with its own manifest, exports, scripts, tooling, and license.

@coderabbitai
Copy link

coderabbitai bot commented Sep 16, 2025

Caution

Review failed

The pull request is closed.

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Migrates the repository from Bun to PNPM across CI, release, docs, and scripts; introduces a packages/ccusage workspace with its own package.json, schema generation now copies to the repo-root docs/public path, updates docs tooling to Node/PNPM, and applies workspace/config and minor formatting edits.

Changes

Cohort / File(s) Summary
CI & Release workflows
.github/workflows/ci.yaml, .github/workflows/release.yaml
Replace Bun setup/commands with PNPM equivalents for install/lint/typecheck/test/publish; add PACKAGE_DIR=packages/ccusage; set working-directory for publish and schema generation to the package; use pnpm dlx for pkg-pr publish.
Root monorepo manifest & workspace
package.json, pnpm-workspace.yaml
Convert root to private pnpm monorepo (ccusage-monorepo), change workspaces to packages/* + docs, add packageManager, devEngines, lint-staged, and replace scripts/devDependencies with pnpm-focused tooling; add pnpm-workspace config and catalogs.
Package manifest & package configs
packages/ccusage/package.json, packages/ccusage/eslint.config.js, packages/ccusage/vitest.config.ts
Add new packages/ccusage package.json (exports, scripts, engines, files, devDeps); add package ESLint config; relax Vitest plugin typing (cast to any).
Docs tooling & configs
docs/package.json, docs/tsconfig.json, docs/typedoc.config.mjs, docs/wrangler.jsonc, docs/update-api-index.ts, docs/.vitepress/config.ts
Switch docs build/dev/type generation to pnpm/Node, point TypeDoc/tsconfig entrypoints to package/module paths, rewrite update-api-index to Node fs/child_process and invoke typedoc via pnpm, load typedoc sidebar at runtime in VitePress, remove mermaid wrapper.
Schema generation script
packages/ccusage/scripts/generate-json-schema.ts
Replace Result pipeline with awaited steps: compute git root and copy schema to ${gitRoot}/docs/public/...; remove Result-based logging and explicit Result handling (exceptions propagate).
Docs content & small docs edits
docs/package.json (scripts), docs/.vitepress/config.ts, docs/guide/index.md, CLAUDE.md, .lsmcp/memories/symbol_index_status.md, docs/wrangler.jsonc
Update docs command prefixes to pnpm, remove an embedded mermaid diagram, adjust VitePress config and sidebar loading, and sync build/dev commands to pnpm.
MCP & local dev config
.mcp.json, .lsmcp/...
Replace Bun invocations with npx --no-install for MCP entries and adjust args; update local testing commands to use pnpm run.
Package assets & metadata
packages/ccusage/LICENSE, packages/ccusage/README.md, AGENTS.md, .gitignore, .npmrc
Add package LICENSE and README, add AGENTS.md (removed from .gitignore), remove a scoped registry line from .npmrc.
Small source edits / formatting
packages/ccusage/src/data-loader.ts, packages/ccusage/src/debug.ts, packages/ccusage/src/pricing-fetcher.ts, packages/ccusage/vitest.config.ts
Minor whitespace/indentation or typing-cast changes; no behavioral changes.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor Dev
  participant CI as CI Workflow
  participant PNPM as PNPM Setup
  participant Pkg as packages/ccusage
  participant Docs as docs

  Dev->>CI: push / PR
  CI->>PNPM: setup pnpm, install (--frozen-lockfile)
  CI->>Pkg: pnpm lint / pnpm typecheck / pnpm run test
  CI->>Pkg: pnpm run generate:schema (wd: packages/ccusage)
  CI->>Docs: compare packages/ccusage/config-schema.json vs docs/public/config-schema.json
  alt schema differs
    CI->>CI: fail schema up-to-date check
  else up-to-date
    CI->>CI: continue
  end
  CI->>Pkg: pnpm dlx pkg-pr-new publish --pnpm './packages/*'
Loading
sequenceDiagram
  autonumber
  actor Dev
  participant Script as generate-json-schema.ts
  participant Git as git
  participant FS as File System
  participant Docs as docs/public

  Dev->>Script: pnpm run generate:schema
  Script->>Git: git rev-parse --show-toplevel
  Git-->>Script: gitRoot
  Script->>FS: write packages/ccusage/config-schema.json
  Script->>FS: copy to {gitRoot}/docs/public/config-schema.json
  Note over Script,Docs: Errors propagate via exceptions (no Result wrapper)
Loading
sequenceDiagram
  autonumber
  actor Dev
  participant Node as update-api-index.ts
  participant TypeDoc as pnpm typedoc
  participant FS as File System

  Dev->>Node: pnpm run docs:api
  Node->>TypeDoc: generate API docs for packages/ccusage
  TypeDoc-->>Node: docs output
  Node->>FS: read docs index and module pages
  Node->>FS: update module descriptions and _consts note
  Node->>FS: write updated docs files
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Poem

A rabbit swaps Bun shoes for PNPM paws,
Hops schemas home and tweaks the workflow laws.
Workspaces bloom, docs chatter, scripts run neat,
CI hums a tune and packages all meet.
Thump—packages built, the repo smells like carrots! 🥕

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title "feat: monorepo" concisely and accurately summarizes the primary change: conversion of the repository to a monorepo (pnpm workspace, new packages/ccusage package, workspace config, and CI/release workflow updates to use pnpm). It is short, conventional-commit style, and clear enough for a teammate scanning history to understand the main intent of the changeset.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d808d87 and 21e682e.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (8)
  • .github/workflows/release.yaml (3 hunks)
  • CLAUDE.md (4 hunks)
  • docs/package.json (1 hunks)
  • eslint.config.js (1 hunks)
  • package.json (1 hunks)
  • packages/ccusage/eslint.config.js (1 hunks)
  • packages/ccusage/package.json (1 hunks)
  • pnpm-workspace.yaml (1 hunks)

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.

@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Sep 16, 2025

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 21e682e Commit Preview URL

Branch Preview URL
Sep 17 2025, 12:58 AM

Copy link
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.

Summary of Changes

Hello @ryoppippi, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces a significant architectural change by migrating the project to a monorepo setup. The primary goal is to enhance project organization and maintainability by clearly separating the main application logic from documentation and potentially other future sub-packages. This refactoring involved extensive file relocation and updates to build configurations and scripts to ensure all components function correctly within the new workspace environment.

Highlights

  • Monorepo Structure: The project has been refactored into a monorepo, with the core ccusage package now residing in a dedicated packages/ccusage directory and the docs remaining as a separate workspace.
  • Dependency Management: The bun.lock file has been updated to reflect the new monorepo structure and includes numerous dependency version changes, with some packages being upgraded and others downgraded.
  • Configuration and Scripts: Root-level package.json scripts have been streamlined to manage workspaces, and various configuration files (docs/package.json, docs/tsconfig.json, docs/typedoc.config.mjs, eslint.config.js, scripts/generate-json-schema.ts, vitest.config.ts) have been updated to correctly reference paths within the new monorepo layout.
  • Bun Configuration: A new bunfig.toml file has been added to enforce isolated linker mode for Bun installations, ensuring consistent dependency resolution.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
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 successfully refactors the project into a monorepo structure, moving the ccusage package into a packages directory and setting up workspaces with Bun. The configuration files and scripts have been updated accordingly to reflect the new file structure. My review focuses on the changes to the build and quality-check scripts. I've identified a couple of areas where the refactoring might have unintentionally removed important pre-commit and pre-release checks. My suggestions aim to restore these quality gates to ensure code integrity. Overall, this is a solid refactoring that sets up the project for better scalability.

Comment on lines 9 to 25
"scripts": {
"build": "bun run generate:schema && tsdown",
"docs:build": "cd docs && bun run build",
"docs:deploy": "cd docs && bun run deploy",
"docs:dev": "cd docs && bun run dev",
"docs:preview": "cd docs && bun run preview",
"format": "bun run lint --fix",
"generate:schema": "bun run scripts/generate-json-schema.ts",
"build": "bun run --filter '*' build",
"docs:dev": "bun run --cwd docs dev",
"format": "bun run --filter '*' format",
"preinstall": "npx only-allow bun",
"lint": "eslint --cache .",
"mcp": "bunx @modelcontextprotocol/inspector bun run start mcp",
"prepack": "bun run build && bun clean-pkg-json -r scripts.preinstall",
"prepare": "git config --local core.hooksPath .githooks && bun run generate:schema && ln -s ./CLAUDE.md ./AGENTS.md || true",
"release": "bun lint && bun typecheck && vitest && bun run build && bumpp",
"start": "bun run ./src/index.ts",
"test": "TZ=UTC vitest",
"test:statusline": "cat test/statusline-test.json | bun run start statusline",
"test:statusline:all": "echo 'Testing Sonnet 4:' && bun run test:statusline:sonnet4 && echo 'Testing Opus 4.1:' && bun run test:statusline:opus4 && echo 'Testing Sonnet 4.1:' && bun run test:statusline:sonnet41",
"test:statusline:opus4": "cat test/statusline-test-opus4.json | bun run start statusline --offline",
"test:statusline:sonnet4": "cat test/statusline-test-sonnet4.json | bun run start statusline --offline",
"test:statusline:sonnet41": "cat test/statusline-test-sonnet41.json | bun run start statusline --offline",
"typecheck": "tsgo --noEmit"
},
"devDependencies": {
"@antfu/utils": "^9.2.0",
"@hono/mcp": "^0.1.4",
"@hono/node-server": "^1.19.2",
"@mizchi/lsmcp": "^0.10.0",
"@modelcontextprotocol/sdk": "^1.17.3",
"@oxc-project/runtime": "^0.82.3",
"@praha/byethrow": "^0.6.3",
"@praha/byethrow-mcp": "^0.1.2",
"@ryoppippi/eslint-config": "^0.3.7",
"@ryoppippi/limo": "npm:@jsr/ryoppippi__limo@^0.2.2",
"@std/async": "npm:@jsr/std__async@^1.0.14",
"@types/bun": "^1.2.20",
"@typescript/native-preview": "^7.0.0-dev.20250821.1",
"ansi-escapes": "^7.0.0",
"bumpp": "^10.2.3",
"clean-pkg-json": "^1.3.0",
"cli-table3": "^0.6.5",
"consola": "^3.4.2",
"es-toolkit": "^1.39.10",
"eslint": "^9.33.0",
"eslint-plugin-format": "^1.0.1",
"fast-sort": "^3.4.1",
"fs-fixture": "^2.8.1",
"get-stdin": "^9.0.0",
"gunshi": "^0.26.3",
"hono": "^4.9.2",
"lint-staged": "^16.1.5",
"nano-spawn": "^1.0.2",
"p-limit": "^7.1.0",
"path-type": "^6.0.0",
"picocolors": "^1.1.1",
"pretty-ms": "^9.2.0",
"publint": "^0.3.12",
"sort-package-json": "^3.4.0",
"string-width": "^7.2.0",
"tinyglobby": "^0.2.14",
"tsdown": "^0.14.1",
"type-fest": "^4.41.0",
"unplugin-macros": "^0.18.0",
"unplugin-unused": "^0.5.2",
"vitest": "^3.2.4",
"xdg-basedir": "^5.1.0",
"zod": "^3.25.67"
"lint": "bun run --filter '*' lint",
"prepare": "git config --local core.hooksPath .githooks && (ln -s ./CLAUDE.md ./AGENTS.md || true)",
"release": "bun bumpp -r"
},
"lint-staged": {
"*": [
"eslint --cache --fix",
"bun run generate:schema",
"bun vitest --passWithNoTests"
"bun run format"
],
"package.json": [
"sort-package-json"
"bun sort-package-json"
]
},
Copy link
Contributor

Choose a reason for hiding this comment

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

high

This refactoring simplifies the release and lint-staged scripts at the root level. However, this simplification removes several important quality gates that were previously in place.

  • The release script no longer runs lint, typecheck, vitest, and build before bumping the version. This could lead to releasing versions with bugs, type errors, or linting issues.
  • The lint-staged configuration for * files now only runs format (which triggers lint --fix). It no longer runs generate:schema or vitest. This means schema generation and tests are not run on pre-commit, which could lead to inconsistencies or broken commits.

Was it intentional to move these checks to a different part of the development workflow, like a CI pipeline? If not, I'd recommend re-adding these checks to maintain code quality. For example, the release script could be:

"release": "bun run --filter '*' lint && bun run --filter '*' typecheck && bun run --filter '*' test && bun run --filter '*' build && bun bumpp -r"

And for lint-staged, you might want to add back the schema generation and test runs for relevant files.

Comment on lines 99 to 108
"lint-staged": {
"*": [
"eslint --cache --fix",
"bun run generate:schema",
"bun vitest --passWithNoTests"
],
"package.json": [
"sort-package-json"
]
}
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

lint-staged is typically configured in the root package.json of a repository. Since you've already configured it in the monorepo root, this lint-staged block within the ccusage package is likely redundant and will not be used if lint-staged is run from the root. To avoid confusion and keep a single source of truth for pre-commit hooks, I recommend removing this block.

Copy link

@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)
.github/workflows/ci.yaml (1)

67-81: Fix schema generation location and use git diff --no-index

Run the generator from packages/ccusage (script lives in packages/ccusage/package.json) and use --no-index because docs/public/config-schema.json is ignored/untracked.

Apply this diff:

-      - name: Generate schema files
-        run: bun run generate:schema
+      - name: Generate schema files
+        run: bun run generate:schema
+        working-directory: packages/ccusage
@@
-          if git diff --exit-code packages/ccusage/config-schema.json docs/public/config-schema.json; then
+          if git diff --no-index --exit-code packages/ccusage/config-schema.json docs/public/config-schema.json; then
@@
-            git diff --name-only packages/ccusage/config-schema.json docs/public/config-schema.json
+            git diff --no-index --name-only packages/ccusage/config-schema.json docs/public/config-schema.json
@@
-            git diff packages/ccusage/config-schema.json docs/public/config-schema.json
+            git diff --no-index packages/ccusage/config-schema.json docs/public/config-schema.json
🧹 Nitpick comments (12)
docs/tsconfig.json (1)

3-8: Enable .ts import extensions to match repo guideline

Guideline says “Use .ts extensions for local imports,” which requires "allowImportingTsExtensions": true under TS 5 + bundler resolution. It’s currently false here.

Apply this diff:

  "compilerOptions": {
-   "allowImportingTsExtensions": false,
+   "allowImportingTsExtensions": true,
    "allowJs": true,
    "noEmit": true,
    "skipLibCheck": true
  },
packages/ccusage/vitest.config.ts (1)

13-14: Avoid any and follow double‑quote style

Cast to Vite’s PluginOption instead of any, and switch to double quotes per repo style.

Apply this diff:

-import Macros from 'unplugin-macros/vite';
-import { defineConfig } from 'vitest/config';
+import Macros from "unplugin-macros/vite";
+import { defineConfig } from "vitest/config";
+import type { PluginOption } from "vite";
@@
-    Macros({
-      include: ['src/index.ts', 'src/pricing-fetcher.ts'],
-    }) as any, // vitest bundles its own vite types, so relax plugin typing here
+    (Macros({
+      include: ["src/index.ts", "src/pricing-fetcher.ts"],
+    }) as unknown as PluginOption), // explicit cast; Vitest bundles Vite types
docs/package.json (1)

8-11: Cross‑platform copy for schema

Using cp can break on Windows. Consider a Node copy to avoid shell differences, or delegate to the generator script.

Two options:

-    "build": "bun run docs:api && cp ../packages/ccusage/config-schema.json public/config-schema.json && vitepress build",
+    "build": "bun run docs:api && node -e \"require('fs').copyFileSync('../packages/ccusage/config-schema.json','public/config-schema.json')\" && vitepress build",
@@
-    "dev": "bun run docs:api && cp ../packages/ccusage/config-schema.json public/config-schema.json && vitepress dev",
+    "dev": "bun run docs:api && node -e \"require('fs').copyFileSync('../packages/ccusage/config-schema.json','public/config-schema.json')\" && vitepress dev",

Or add a docs:schema script in packages/ccusage and call it from here.

packages/ccusage/scripts/generate-json-schema.ts (2)

219-234: Replace shell cp with fs APIs and ensure target dir exists

cp is non‑portable and can fail if docs/public doesn’t exist. Use fs/promises instead.

Apply this diff:

-import { fileURLToPath } from 'node:url';
+import { fileURLToPath } from "node:url";
+import { cp, mkdir } from "node:fs/promises";
@@
 async function copySchemaToDocsPublic() {
 	const sourcePath = path.join(process.cwd(), SCHEMA_FILENAME);
 	const targetPath = path.join(DOCS_PUBLIC_DIR, SCHEMA_FILENAME);
 
-	return Result.pipe(
-		Result.try({
-			try: $`cp ${sourcePath} ${targetPath}`,
-			catch: error => error,
-		}),
-		Result.inspectError((error) => {
-			logger.error(`Failed to copy to docs/public/${SCHEMA_FILENAME}:`, error);
-			process.exit(1);
-		}),
-		Result.inspect(() => logger.info(`✓ Copied to docs/public/${SCHEMA_FILENAME}`)),
-	);
+	await Result.pipe(
+		Result.try({ try: () => mkdir(DOCS_PUBLIC_DIR, { recursive: true }), safe: true })(),
+		Result.inspectError((error) => {
+			logger.error("Failed to create docs/public directory:", error);
+			process.exit(1);
+		}),
+	);
+	return Result.pipe(
+		Result.try({ try: () => cp(sourcePath, targetPath), catch: (error) => error }),
+		Result.inspectError((error) => {
+			logger.error(`Failed to copy to docs/public/${SCHEMA_FILENAME}:`, error);
+			process.exit(1);
+		}),
+		Result.inspect(() => logger.info(`✓ Copied to docs/public/${SCHEMA_FILENAME}`)),
+	);
 }

271-283: Minor: make Result.try uniform (pass a thunk)

For consistency with other uses, wrap writeFile in a function.

Apply this diff:

-		Result.try({
-			try: writeFile(SCHEMA_FILENAME, schemaJson),
-			safe: true,
-		}),
+		Result.try({
+			try: () => writeFile(SCHEMA_FILENAME, schemaJson),
+			safe: true,
+		}),
packages/ccusage/package.json (4)

45-45: Use bun run for scripts to avoid ambiguity.

Prefer bun run <script> over bun <script>.

Apply:

-    "release": "bun lint && bun typecheck && vitest && bun run build && bumpp",
+    "release": "bun run lint && bun run typecheck && vitest && bun run build && bumpp",

27-29: Minor: module is redundant with exports.

Since you provide an exports map and "type": "module", the module field is typically unnecessary. Safe to drop unless a specific bundler requires it.


99-104: Make lint-staged invocations repo-agnostic.

bun vitest relies on PATH resolution. Use script or bun x to avoid workspace/CWD issues.

-      "bun vitest --passWithNoTests"
+      "bun run test -- --passWithNoTests"

35-37: Update Node engine constraint to a valid/latest 20.x LTS

Node v20.19.4 exists (released Jul 15, 2025), but the latest 20.x LTS as of Sep 16, 2025 is v20.19.5 (released Sep 3, 2025). Update packages/ccusage/package.json engines to either "node": ">=20.19.5" (pin to current patch) or broaden to "node": ">=20" (accept any 20.x LTS).

package.json (3)

10-12: CI runs should target workspaces explicitly.

To avoid calling workspace-local scripts from the repo root, prefer filtered invocations in workflows: bun run --filter ccusage build, lint, test, etc. This also prevents the generate:schema not found error reported in CI.

Also applies to: 14-16


15-15: Cross‑platform symlink in prepare.

ln -s is non‑portable (Windows). Make it idempotent and OS‑aware, or move to a dev-only script.

-    "prepare": "git config --local core.hooksPath .githooks && (ln -s ./CLAUDE.md ./AGENTS.md || true)",
+    "prepare": "git config --local core.hooksPath .githooks && (ln -sf ./CLAUDE.md ./AGENTS.md || true)"

Optionally gate by shell: use a tiny Node script to create the link when possible.


33-34: Update engines.node to a real Node LTS

File: package.json Lines: 33–34

		"node": ">=20.19.4"

As of Sep 16, 2025 Node 20 latest patch is 20.19.5 (maintenance LTS) and active LTS is v22 (22.19.0). Change engines.node to one of:

  • ">=20.19.5" (or ">=20" to allow future 20.x patches) if you intend to support v20; or
  • ">=22.19.0" (or ">=22") to target the active LTS.
    If Bun is only needed for dev tooling, add a separate "bun" engine for repo tasks and do not require it for published package consumers.
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a03cce7 and 3b338e4.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (11)
  • .github/workflows/ci.yaml (2 hunks)
  • .github/workflows/release.yaml (1 hunks)
  • bunfig.toml (1 hunks)
  • docs/package.json (1 hunks)
  • docs/tsconfig.json (1 hunks)
  • docs/typedoc.config.mjs (1 hunks)
  • package.json (1 hunks)
  • packages/ccusage/eslint.config.js (0 hunks)
  • packages/ccusage/package.json (1 hunks)
  • packages/ccusage/scripts/generate-json-schema.ts (3 hunks)
  • packages/ccusage/vitest.config.ts (1 hunks)
💤 Files with no reviewable changes (1)
  • packages/ccusage/eslint.config.js
🧰 Additional context used
📓 Path-based instructions (2)
**/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.ts: Use ESLint formatting with tab indentation and double quotes
TypeScript code must be compatible with strict mode and bundler module resolution
Do not use console.log; use logger.ts instead (only allow if explicitly eslint-disabled)
Always use Node.js path utilities for file paths (cross-platform compatibility)
Use .ts extensions for local imports (e.g., import { foo } from './utils.ts')
Prefer @praha/byethrow Result type over try-catch for error handling
Use Result.try() to wrap operations that may throw (e.g., JSON parsing)
Use Result.isFailure()/Result.isSuccess() type guards and prefer early returns
Keep try-catch only for complex file I/O or hard-to-refactor legacy code
Variables use camelCase; Types use PascalCase; Constants may use UPPER_SNAKE_CASE
Only export constants, functions, and types that are used by other modules
Use in-source testing blocks guarded by if (import.meta.vitest != null) instead of separate test files
Vitest globals are enabled: use describe, it, expect without imports
Never use dynamic imports (await import()) anywhere, especially in tests
Mock file-system data with fs-fixture createFixture() in tests
Tests must use current Claude 4 model names (Sonnet and Opus) with exact LiteLLM matches
Ensure test coverage includes both claude-sonnet-4-20250514 and claude-opus-4-20250514
Follow model naming convention: claude-{model-type}-{generation}-{date} (e.g., claude-sonnet-4-20250514)
Before adding model-related tests, verify model exists in LiteLLM pricing database

Files:

  • packages/ccusage/vitest.config.ts
  • packages/ccusage/scripts/generate-json-schema.ts
package.json

📄 CodeRabbit inference engine (CLAUDE.md)

Add new dependencies as devDependencies unless explicitly requested otherwise

Files:

  • package.json
🧠 Learnings (2)
📚 Learning: 2025-09-02T11:24:24.075Z
Learnt from: CR
PR: ryoppippi/ccusage#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-02T11:24:24.075Z
Learning: Applies to **/*.ts : Use .ts extensions for local imports (e.g., import { foo } from './utils.ts')

Applied to files:

  • docs/tsconfig.json
📚 Learning: 2025-09-02T11:24:24.075Z
Learnt from: CR
PR: ryoppippi/ccusage#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-02T11:24:24.075Z
Learning: Applies to **/*.ts : TypeScript code must be compatible with strict mode and bundler module resolution

Applied to files:

  • docs/tsconfig.json
🪛 GitHub Actions: CI
docs/package.json

[error] 1-1: Script not found 'generate:schema' (attempted via 'bun run generate:schema').


[error] 1-1: Script 'prepare' exited with code 1.

packages/ccusage/package.json

[error] 1-1: Script not found 'generate:schema' (attempted via 'bun run generate:schema').


[error] 1-1: Script 'prepare' exited with code 1.

package.json

[error] 1-1: Script not found 'generate:schema' (attempted via 'bun run generate:schema').


[error] 1-1: Script 'prepare' exited with code 1.

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Socket Security: Pull Request Alerts
  • GitHub Check: Workers Builds: ccusage-guide
🔇 Additional comments (8)
bunfig.toml (1)

1-2: Confirm isolated linker for workspaces

linker = "isolated" disables hoisting/symlinking. In a monorepo this can increase install size and break implicit workspace linking. If isolation isn’t required, consider "hoisted" or "symlink". Otherwise, confirm all workflows run from the correct package dirs.

docs/tsconfig.json (1)

2-2: Docs TS config now extends package config — looks good

Path updated to the package tsconfig aligns docs with the monorepo structure.

.github/workflows/release.yaml (1)

8-10: LGTM: central env for package dir

Using env.PACKAGE_DIR and setting working-directory on the publish step is clean and consistent with the monorepo move.

docs/typedoc.config.mjs (1)

6-14: LGTM: source, excludes, and tsconfig paths moved to package

The Typedoc inputs now track the package sources correctly.

Also applies to: 21-21

packages/ccusage/scripts/generate-json-schema.ts (2)

29-30: Good: absolute docs/public resolution

Using fileURLToPath(new URL(..., import.meta.url)) avoids CWD issues in monorepos.


1-383: Style: enforce double quotes + tab indentation for TS files

Run the project's linter/formatter to convert single quotes to double quotes and apply tab indentation for packages/ccusage/scripts/generate-json-schema.ts.

Run:
bun run lint --fix packages/ccusage/scripts/generate-json-schema.ts

If bun is unavailable locally (bun: command not found), run the repo lint script with your package manager:
npm run lint -- --fix packages/ccusage/scripts/generate-json-schema.ts
or
pnpm run lint -- --fix packages/ccusage/scripts/generate-json-schema.ts

After committing the formatted file, re-run verification.

packages/ccusage/package.json (2)

41-41: Confirmed — generate:schema script file exists
packages/ccusage/scripts/generate-json-schema.ts is present in the workspace; no action required.


30-30: CLI shebang check.

packages/ccusage/package.json sets "bin": "./dist/index.js" but packages/ccusage/dist/index.js is not present in the repo — ensure your build emits packages/ccusage/dist/index.js with the POSIX shebang "#!/usr/bin/env node" on line 1 so the CLI is executable; after building verify with: head -n1 packages/ccusage/dist/index.js

Comment on lines 55 to 98
"devDependencies": {
"@antfu/utils": "^9.2.0",
"@hono/mcp": "^0.1.4",
"@hono/node-server": "^1.19.2",
"@mizchi/lsmcp": "^0.10.0",
"@modelcontextprotocol/sdk": "^1.17.3",
"@oxc-project/runtime": "^0.82.3",
"@praha/byethrow": "^0.6.3",
"@praha/byethrow-mcp": "^0.1.2",
"@ryoppippi/eslint-config": "^0.3.7",
"@ryoppippi/limo": "npm:@jsr/ryoppippi__limo@^0.2.2",
"@std/async": "npm:@jsr/std__async@^1.0.14",
"@types/bun": "^1.2.20",
"@typescript/native-preview": "^7.0.0-dev.20250821.1",
"ansi-escapes": "^7.0.0",
"bumpp": "^10.2.3",
"clean-pkg-json": "^1.3.0",
"cli-table3": "^0.6.5",
"consola": "^3.4.2",
"es-toolkit": "^1.39.10",
"eslint": "^9.33.0",
"eslint-plugin-format": "^1.0.1",
"fast-sort": "^3.4.1",
"fs-fixture": "^2.8.1",
"get-stdin": "^9.0.0",
"gunshi": "^0.26.3",
"hono": "^4.9.2",
"nano-spawn": "^1.0.2",
"p-limit": "^7.1.0",
"path-type": "^6.0.0",
"picocolors": "^1.1.1",
"pretty-ms": "^9.2.0",
"publint": "^0.3.12",
"sort-package-json": "^3.4.0",
"string-width": "^7.2.0",
"tinyglobby": "^0.2.14",
"tsdown": "^0.14.1",
"type-fest": "^4.41.0",
"unplugin-macros": "^0.18.0",
"unplugin-unused": "^0.5.2",
"vitest": "^3.2.4",
"xdg-basedir": "^5.1.0",
"zod": "^3.25.67"
},
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

🧩 Analysis chain

Runtime vs dev dependency audit for the published package.

All deps are under devDependencies. If the CLI or library imports any of these at runtime (e.g., hono, @modelcontextprotocol/sdk, @hono/*, consola, picocolors), they must live in dependencies to be installed for consumers.


🏁 Script executed:

#!/bin/bash
# List bare module imports used at runtime in ccusage
rg -nP --type=ts --type=tsx -C0 'from\s+[\'"]([^\.\/][^\'"]*)[\'"]|require\([\'"]([^\.\/][^\'"]*)[\'"]\)' packages/ccusage/src \
  | sed -n '1,120p'
# Show current dep buckets
jq '{dependencies, devDependencies}' packages/ccusage/package.json

Length of output: 215


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "SEARCH_NON_RELATIVE_IMPORTS"
python3 - <<'PY'
import os, re, json, sys
root = 'packages/ccusage/src'
if not os.path.isdir(root):
    print("MISSING_SRC_DIR")
    sys.exit(0)
pat = re.compile(r"""(?:from\s+['"](?P<from>[^'"]+)['"])|(?:require\(\s*['"](?P<req>[^'"]+)['"]\s*\))""")
res = {}
for dp, _, fns in os.walk(root):
    for fn in fns:
        if not fn.endswith(('.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs')):
            continue
        path = os.path.join(dp, fn)
        try:
            with open(path, 'r', encoding='utf-8') as fh:
                for i, l in enumerate(fh, 1):
                    for m in pat.finditer(l):
                        mod = (m.group('from') or m.group('req') or '').strip()
                        if not mod or mod.startswith('.') or mod.startswith('/'):
                            continue
                        res.setdefault(mod, []).append(f"{path}:{i}:{l.strip()}")
        except Exception as e:
            print("ERR_FILE", path, str(e))
print(json.dumps(res, indent=2))
PY

echo "SHOW_PACKAGE_JSON"
python3 - <<'PY'
import json, sys
p = 'packages/ccusage/package.json'
try:
    with open(p, 'r', encoding='utf-8') as f:
        j = json.load(f)
    print(json.dumps({'dependencies': j.get('dependencies', {}), 'devDependencies': j.get('devDependencies', {})}, indent=2))
except Exception as e:
    print("ERR_PACKAGE_JSON", str(e))
PY

Length of output: 11136


Move runtime imports from devDependencies → dependencies

packages/ccusage/package.json currently lists all externals as devDependencies but packages/ccusage/src imports many of them at runtime; move the following packages into "dependencies" in packages/ccusage/package.json so consumers get them:

  • @antfu/utils
  • @hono/mcp
  • @hono/node-server
  • hono
  • @modelcontextprotocol/sdk
  • @praha/byethrow
  • fs-fixture
  • xdg-basedir
  • fast-sort
  • nano-spawn
  • p-limit
  • @std/async
  • ansi-escapes
  • picocolors
  • pretty-ms
  • string-width
  • es-toolkit
  • gunshi
  • cli-table3
  • consola
  • @ryoppippi/limo
  • get-stdin
  • path-type
  • tinyglobby
  • zod

Keep Node builtins (node:*) and purely type-only imports (e.g., type-fest, picocolors/types) in devDependencies. Update packages/ccusage/package.json accordingly.

🤖 Prompt for AI Agents
packages/ccusage/package.json lines 55-98: devDependencies currently contains
many packages that are imported at runtime from packages/ccusage/src; move the
listed runtime packages into "dependencies" so consumers receive them:
@antfu/utils, @hono/mcp, @hono/node-server, hono, @modelcontextprotocol/sdk,
@praha/byethrow, fs-fixture, xdg-basedir, fast-sort, nano-spawn, p-limit,
@std/async, ansi-escapes, picocolors, pretty-ms, string-width, es-toolkit,
gunshi, cli-table3, consola, @ryoppippi/limo, get-stdin, path-type, tinyglobby,
zod — remove them from devDependencies and add them under dependencies with the
same versions; keep Node builtins (node:*) and purely type-only packages (e.g.,
type-fest, @types/*, picocolors/types) in devDependencies and run a quick
install and test to ensure the package-lock/yarn.lock is updated.

Copy link

@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: 0

♻️ Duplicate comments (1)
package.json (1)

9-20: Quality gates removed from release workflow.

The previous review comment from gemini-code-assist[bot] highlighted that important quality checks (lint, typecheck, test, build) were removed from the release script. This creates a risk of releasing versions with bugs or type errors.

Given the learning that suggests running bun run format, bun typecheck, and bun run test after code changes, consider adding these checks back to the release script.

Consider updating the release script to include quality gates:

-    "release": "bun bumpp -r",
+    "release": "bun run --filter '*' lint && bun run --filter '*' typecheck && bun run --filter '*' test && bun run --filter '*' build && bun bumpp -r",
🧹 Nitpick comments (1)
package.json (1)

30-34: Lint-staged configuration simplified but may miss important checks.

The lint-staged configuration now only runs format, but previously included schema generation and tests. This could lead to commits with outdated schemas or failing tests.

Consider adding back schema generation for relevant file patterns:

  "lint-staged": {
-    "*": [
-      "bun run format"
-    ]
+    "*": [
+      "bun run format"
+    ],
+    "packages/ccusage/src/**/*.ts": [
+      "bun run --filter ccusage generate:schema"
+    ]
  }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3b338e4 and 0edcc11.

📒 Files selected for processing (3)
  • .github/workflows/ci.yaml (2 hunks)
  • package.json (1 hunks)
  • packages/ccusage/package.json (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/ccusage/package.json
🧰 Additional context used
📓 Path-based instructions (1)
package.json

📄 CodeRabbit inference engine (CLAUDE.md)

Add new dependencies as devDependencies unless explicitly requested otherwise

Files:

  • package.json
🧠 Learnings (1)
📚 Learning: 2025-09-02T11:24:24.075Z
Learnt from: CR
PR: ryoppippi/ccusage#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-02T11:24:24.075Z
Learning: After code changes, always run: bun run format, bun typecheck, bun run test

Applied to files:

  • .github/workflows/ci.yaml
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Workers Builds: ccusage-guide
🔇 Additional comments (7)
.github/workflows/ci.yaml (3)

46-46: LGTM: Package path correctly updated for monorepo structure.

The --bun argument now correctly points to the specific package directory within the monorepo structure.


66-68: Schema generation correctly scoped to package directory.

The working directory specification ensures the schema generation command runs in the correct package context within the monorepo.


71-71: Schema file paths correctly updated for monorepo layout.

All references to the schema file now properly use the monorepo package path packages/ccusage/config-schema.json, maintaining consistency across the diff checks.

Also applies to: 77-77, 80-80

package.json (4)

2-3: LGTM: Proper monorepo package configuration.

The name change to ccusage-monorepo and the private: true flag correctly reflect the new monorepo structure where this is now the root orchestration package.


5-8: LGTM: Workspaces correctly configured.

The workspaces array properly includes the packages directory and docs, enabling Bun's workspace management.


21-25: Dev dependencies correctly scoped to root tooling.

The devDependencies are appropriately limited to monorepo management tools (bumpp, lint-staged, sort-package-json) since package-specific dependencies are now handled in individual workspace packages.


26-26: Package manager version pinned appropriately.

The packageManager field ensures consistent Bun version across the monorepo, which is good practice for reproducible builds.

Add pnpm-workspace.yaml to configure monorepo workspace structure.
This replaces Bun workspaces with pnpm for better package management,
dependency resolution, and CI/CD integration.

The configuration includes:
- Package workspace definition for packages/* and docs
- Build optimization settings for native dependencies (esbuild, sharp, workerd)

This is part of the comprehensive migration from Bun to pnpm to improve
development workflow and leverage pnpm's superior workspace management
capabilities.
Update root package.json to use pnpm instead of Bun for package management:

- Change packageManager from bun to [email protected]
- Add preinstall script to enforce pnpm usage with only-allow
- Update all scripts to use pnpm run with workspace filters
- Add devEngines configuration for Node.js v24.4.0 runtime
- Move MCP server dependencies to root for shared access
- Update lint-staged configuration to use pnpm run format

This establishes the foundation for the pnpm monorepo structure,
enabling better dependency management, workspace coordination,
and development workflow consistency across all packages.

The migration includes specific pnpm workspace commands:
- `pnpm run --filter '*'` for running scripts across all packages
- `pnpm bumpp -r` for recursive release management
- Proper workspace dependency resolution through pnpm's hoisting
Update CI/CD workflows to use pnpm instead of Bun:

CI workflow (.github/workflows/ci.yaml):
- Replace oven-sh/setup-bun with pnpm/[email protected]
- Update all install/run commands to use pnpm equivalents
- Change `bunx pkg-pr-new` to `pnpm dlx pkg-pr-new` for package publishing
- Update error messages to reference pnpm commands
- Remove bun-version configuration (not applicable to pnpm)

Release workflow (.github/workflows/release.yaml):
- Add pnpm/action-setup step before Node.js setup
- Update setup-node action to v5.0.0 for better pnpm compatibility
- Change `bun install` to `pnpm install --frozen-lockfile`
- Keep changelogithub using bunx since it's independent of project package manager

These changes ensure CI/CD processes align with the new pnpm-based
development environment while maintaining all existing functionality
including linting, testing, type checking, and automated publishing.
Update package.json files and scripts in workspace packages:

docs/package.json:
- Change all bun commands to pnpm equivalents
- Update scripts to use pnpm run for cross-package execution
- Maintain existing functionality with pnpm workspace commands

packages/ccusage/package.json:
- Replace bun-specific scripts with pnpm/node alternatives
- Update test scripts to use pnpm instead of bun run
- Change package execution from bun to node for direct runs

TypeScript script updates:
- docs/update-api-index.ts: Replace Bun.spawnSync with Node.js child_process
- packages/ccusage/scripts/generate-json-schema.ts: Migrate from Bun APIs to Node.js
- docs/wrangler.jsonc: Update build command to use pnpm

These changes maintain all existing functionality while migrating
from Bun runtime to Node.js with pnpm package management. Scripts
now use standard Node.js APIs for better compatibility and tooling
support across different development environments.
Update .mcp.json to use npx instead of bun for MCP server execution:

- Change lsmcp command from 'bun' to 'npx --no-install'
- Update @praha/byethrow MCP server to use npx --no-install
- Update gunshi-doc MCP server to use npx --no-install
- Replace 'bun x' with 'npx --no-install' for consistency

These changes ensure MCP servers work correctly in the pnpm environment
while maintaining compatibility with Claude Desktop integration. The
--no-install flag prevents npx from attempting package installation,
assuming dependencies are already available through pnpm workspaces.

MCP dependencies have been moved to the root package.json devDependencies
to ensure they are available globally across the monorepo workspace.
Update project documentation to reflect the migration from Bun to pnpm:

CLAUDE.md updates:
- Replace all 'bun run' commands with 'pnpm run' equivalents
- Update development commands and usage examples
- Change direct execution from 'bun run ./src/index.ts' to 'node ./src/index.ts'
- Update environment variable examples to use pnpm
- Maintain all existing functionality descriptions with new command syntax
- Update testing commands and post-code change workflow instructions

.lsmcp/memories/symbol_index_status.md updates:
- Update testing command examples from 'bun run' to 'pnpm run'
- Maintain all test target definitions with new pnpm syntax

These documentation updates ensure that all development instructions,
examples, and automated tooling references align with the new pnpm-based
development environment while preserving all functional information
and workflow guidance for contributors and CI systems.
Remove Bun configuration and lock files as part of migration to pnpm:

- Delete bun.lock - Bun's lockfile replaced by pnpm-lock.yaml
- Delete bunfig.toml - Bun configuration file no longer needed

These files are specific to Bun package manager and are not compatible
with pnpm. The pnpm equivalent (pnpm-lock.yaml) will be added separately
to maintain clean git history and ensure proper dependency resolution
in the new pnpm-based development environment.

This cleanup removes approximately 2,188 lines of Bun-specific lock data
and configuration that would otherwise conflict with pnpm workspace
management and dependency resolution mechanisms.
Add pnpm-lock.yaml to establish deterministic dependency resolution
for the pnpm-based monorepo workspace.

This lockfile ensures:
- Consistent dependency versions across all development environments
- Reproducible builds in CI/CD pipelines
- Proper workspace dependency linking and hoisting
- Security and integrity verification of installed packages

The lockfile was generated after migrating all package.json files
to use pnpm commands and establishing the pnpm workspace configuration.
This completes the transition from Bun's dependency management to
pnpm's superior workspace and dependency resolution capabilities.

Generated with [email protected] using workspace configuration defined
in pnpm-workspace.yaml covering packages/* and docs directories.
@socket-security
Copy link

socket-security bot commented Sep 16, 2025

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Added@​ryoppippi/​vite-plugin-cloudflare-redirect@​1.1.2631008587100
Addedsitemcp@​0.5.9761009992100
Addedxdg-basedir@​5.1.01001008977100
Addedvitest@​3.2.4981007999100
Addedunplugin-macros@​0.18.28010010097100
Addedunplugin-unused@​0.5.38710010091100
Addedtype-fest@​4.41.010010010091100
Addedtsdown@​0.14.2981009296100
Addedzod@​3.25.7610010010096100

View full report

@pkg-pr-new
Copy link

pkg-pr-new bot commented Sep 16, 2025

Open in StackBlitz

npm i https://pkg.pr.new/ryoppippi/ccusage@631

commit: 21e682e

Copy link

@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

♻️ Duplicate comments (4)
package.json (2)

19-19: Run quality gates before version bump.

Currently release only bumps versions. Consider chaining prerelease checks to prevent releasing broken builds.

-    "release": "pnpm bumpp -r",
+    "release": "pnpm run prerelease && pnpm bumpp -r",

23-30: Make lint-staged operate on staged files, not whole workspace.

"pnpm run format" invokes package scripts and may reformat unrelated files. Prefer calling eslint (or prettier) directly on the staged set.

-  "lint-staged": {
-    "*": [
-      "pnpm run format"
-    ],
-    "./**/package.json": [
-      "sort-package-json"
-    ]
-  },
+  "lint-staged": {
+    "*.{js,ts,tsx,md,json,yml,yaml}": [
+      "pnpm -w exec eslint --fix --cache --"
+    ],
+    "**/package.json": [
+      "sort-package-json"
+    ]
+  },
packages/ccusage/package.json (2)

44-45: Avoid running prepare on consumers’ install.

prepare still runs during npm/pnpm/yarn install for consumers. Even with || true, it increases install time and may surprise users. Prefer generating schema in build/prepack only.

-    "prepare": "pnpm run generate:schema || true",
+    // generate:schema already runs in build/prepack; no prepare hook

58-99: Move runtime imports from devDependencies → dependencies.

This package is published/consumed; modules imported at runtime must be in dependencies so consumers install them. Right now all externals are under devDependencies.

+  "dependencies": {
+    "@antfu/utils": "^9.2.0",
+    "@hono/mcp": "^0.1.4",
+    "@hono/node-server": "^1.19.2",
+    "@modelcontextprotocol/sdk": "^1.17.3",
+    "@praha/byethrow": "^0.6.3",
+    "ansi-escapes": "^7.0.0",
+    "cli-table3": "^0.6.5",
+    "consola": "^3.4.2",
+    "es-toolkit": "^1.39.10",
+    "fast-sort": "^3.4.1",
+    "fs-fixture": "^2.8.1",
+    "get-stdin": "^9.0.0",
+    "gunshi": "^0.26.3",
+    "hono": "^4.9.2",
+    "nano-spawn": "^1.0.2",
+    "p-limit": "^7.1.0",
+    "path-type": "^6.0.0",
+    "picocolors": "^1.1.1",
+    "pretty-ms": "^9.2.0",
+    "string-width": "^7.2.0",
+    "tinyglobby": "^0.2.14",
+    "xdg-basedir": "^5.1.0",
+    "zod": "^3.25.67"
+  },
   "devDependencies": {
-    "@antfu/utils": "^9.2.0",
-    "@hono/mcp": "^0.1.4",
-    "@hono/node-server": "^1.19.2",
-    "@modelcontextprotocol/sdk": "^1.17.3",
-    "@praha/byethrow": "^0.6.3",
-    "@ryoppippi/limo": "jsr:^0.2.2",
-    "@std/async": "jsr:^1.0.14",
-    "ansi-escapes": "^7.0.0",
-    "cli-table3": "^0.6.5",
-    "consola": "^3.4.2",
-    "es-toolkit": "^1.39.10",
-    "fast-sort": "^3.4.1",
-    "fs-fixture": "^2.8.1",
-    "get-stdin": "^9.0.0",
-    "gunshi": "^0.26.3",
-    "hono": "^4.9.2",
-    "nano-spawn": "^1.0.2",
-    "p-limit": "^7.1.0",
-    "path-type": "^6.0.0",
-    "picocolors": "^1.1.1",
-    "pretty-ms": "^9.2.0",
-    "string-width": "^7.2.0",
-    "tinyglobby": "^0.2.14",
-    "xdg-basedir": "^5.1.0",
-    "zod": "^3.25.67",
+    "@ryoppippi/limo": "jsr:^0.2.2",
+    "@std/async": "jsr:^1.0.14",
     ...
   }

Note: Keep type-only deps and tooling in devDependencies. Adjust the exact list based on actual runtime imports.

🧹 Nitpick comments (6)
packages/ccusage/README.md (2)

18-19: Add alt text for the screenshot image (MD045).

The <img> at Line 18 lacks alt. Add a concise description for accessibility and markdownlint.

-    <img src="https://cdn.jsdelivr.net/gh/ryoppippi/ccusage@main/docs/public/screenshot.png">
+    <img src="https://cdn.jsdelivr.net/gh/ryoppippi/ccusage@main/docs/public/screenshot.png" alt="ccusage CLI screenshot">

124-128: Add alt text for sponsors image (MD045).

Provide alt text on the sponsors SVG for a11y and lint compliance.

-        <img src="https://cdn.jsdelivr.net/gh/ryoppippi/sponsors@main/sponsors.svg">
+        <img src="https://cdn.jsdelivr.net/gh/ryoppippi/sponsors@main/sponsors.svg" alt="GitHub sponsors of @ryoppippi">
docs/package.json (1)

8-13: Make schema copy cross‑platform.

cp breaks on Windows shells. Consider a Node one‑liner so contributors on Windows can run docs locally.

-    "build": "pnpm run docs:api && cp ../packages/ccusage/config-schema.json public/config-schema.json && vitepress build",
-    "dev": "pnpm run docs:api && cp ../packages/ccusage/config-schema.json public/config-schema.json && vitepress dev",
+    "build": "pnpm run docs:api && node -e \"require('node:fs').copyFileSync('../packages/ccusage/config-schema.json','public/config-schema.json')\" && vitepress build",
+    "dev": "pnpm run docs:api && node -e \"require('node:fs').copyFileSync('../packages/ccusage/config-schema.json','public/config-schema.json')\" && vitepress dev",
docs/tsconfig.json (1)

2-10: Fragile extend path.

Extending ./node_modules/ccusage/tsconfig.json works in the monorepo, but that file isn’t in the package’s "files" list, so it won’t exist when installed from the registry. Consider a shared root tsconfig.base.json and extends: ../tsconfig.base.json instead.

docs/.vitepress/config.ts (2)

17-18: Don’t blanket-ignore dead links in CI.

Let CI catch broken docs links while keeping local DX lenient.

-  cleanUrls: true,
-  ignoreDeadLinks: true,
+  cleanUrls: true,
+  ignoreDeadLinks: process.env.CI ? false : true,

6-7: Replace as any with proper Vite type.

Tighten typing for the plugin to avoid masking real type issues.

@@
-import type { DefaultTheme } from 'vitepress';
+import type { DefaultTheme } from 'vitepress';
+import type { PluginOption } from 'vite';
@@
-        }) as any,
+        }) as PluginOption,

Also applies to: 145-154

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 90d6ba6 and d808d87.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (18)
  • .github/workflows/ci.yaml (2 hunks)
  • .gitignore (0 hunks)
  • .npmrc (0 hunks)
  • AGENTS.md (1 hunks)
  • LICENSE (0 hunks)
  • LICENSE (1 hunks)
  • README.md (0 hunks)
  • README.md (1 hunks)
  • docs/.vitepress/config.ts (3 hunks)
  • docs/guide/index.md (0 hunks)
  • docs/package.json (1 hunks)
  • docs/tsconfig.json (1 hunks)
  • docs/typedoc.config.mjs (1 hunks)
  • package.json (1 hunks)
  • packages/ccusage/LICENSE (1 hunks)
  • packages/ccusage/README.md (1 hunks)
  • packages/ccusage/package.json (1 hunks)
  • pnpm-workspace.yaml (1 hunks)
💤 Files with no reviewable changes (3)
  • .gitignore
  • docs/guide/index.md
  • .npmrc
✅ Files skipped from review due to trivial changes (6)
  • packages/ccusage/LICENSE
  • AGENTS.md
  • README.md
  • LICENSE
  • LICENSE
  • README.md
🚧 Files skipped from review as they are similar to previous changes (2)
  • .github/workflows/ci.yaml
  • docs/typedoc.config.mjs
🧰 Additional context used
📓 Path-based instructions (1)
package.json

📄 CodeRabbit inference engine (CLAUDE.md)

Add new dependencies as devDependencies unless explicitly requested otherwise

Files:

  • package.json
🧠 Learnings (1)
📚 Learning: 2025-09-02T11:24:24.075Z
Learnt from: CR
PR: ryoppippi/ccusage#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-02T11:24:24.075Z
Learning: Applies to **/*.ts : Use .ts extensions for local imports (e.g., import { foo } from './utils.ts')

Applied to files:

  • docs/tsconfig.json
🪛 markdownlint-cli2 (0.17.2)
packages/ccusage/README.md

18-18: Images should have alternate text (alt text)

(MD045, no-alt-text)


126-126: Images should have alternate text (alt text)

(MD045, no-alt-text)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Socket Security: Pull Request Alerts
  • GitHub Check: Workers Builds: ccusage-guide
🔇 Additional comments (6)
pnpm-workspace.yaml (1)

1-10: Workspace layout LGTM; caution on pre/post scripts.

The workspace globs and onlyBuiltDependencies look fine. Enabling pre/post scripts globally can execute arbitrary install scripts from deps. If you want stricter CI, set PNPM_CONFIG_ENABLE_PRE_POST_SCRIPTS=false in CI or scope scripts to trusted packages only.

docs/package.json (2)

12-13: Confirm tsgo availability.

typecheck uses tsgo. Ensure it resolves in this package’s PATH (via workspace exec or a local devDependency). If not, either add it here or swap to tsc --noEmit.


16-27: Deps bucket looks correct.

ccusage is referenced via workspace:^ in devDependencies, aligning with the monorepo docs usage.

packages/ccusage/package.json (2)

39-42: Bun usage in scripts is fine; confirm devEngines covers it.

You already specify Bun in devEngines. Good. Just ensure CI sets PNPM to respect devEngines.onFail so Bun auto-download works.


30-31: CLI bin: ensure shebang in built file.

packages/ccusage/package.json sets "bin": "./dist/index.js", but packages/ccusage/dist/index.js is missing from the repo so I couldn't verify; ensure the built ./dist/index.js starts with #!/usr/bin/env node (or supply a small wrapper) so global installs execute correctly.

docs/.vitepress/config.ts (1)

100-106: API sidebar injection LGTM.

Runtime composition with ...typedocSidebar is clean and keeps the manual “Overview” entry intact.

Comment on lines 1 to +3
import { defineConfig } from 'vitepress';
import * as path from 'node:path';
import * as fs from 'node:fs';
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

🧩 Analysis chain

Fix ESM path resolution and guard missing TypeDoc sidebar (prevents docs build crashes).

import.meta.dirname requires newer Node and will throw on Node ≤18. Also, an absent or malformed docs/api/typedoc-sidebar.json will crash the dev server/build. Resolve __dirname via fileURLToPath, read with 'utf8', and fall back to an empty sidebar with a warning.

Apply this diff:

@@
-import * as fs from 'node:fs';
+import * as fs from 'node:fs';
+import { fileURLToPath } from 'node:url';
@@
-const typedocSidebarJson = fs.readFileSync(path.join(import.meta.dirname, '../api/typedoc-sidebar.json'))
-const typedocSidebar = JSON.parse(typedocSidebarJson.toString()) as DefaultTheme.SidebarItem[];
+const __dirname = path.dirname(fileURLToPath(import.meta.url));
+const typedocJsonPath = path.join(__dirname, '../api/typedoc-sidebar.json');
+let typedocSidebar: DefaultTheme.SidebarItem[] = [];
+try {
+  const json = fs.readFileSync(typedocJsonPath, 'utf8');
+  typedocSidebar = JSON.parse(json) as DefaultTheme.SidebarItem[];
+} catch {
+  console.warn(`[docs] typedoc sidebar not found or invalid at ${typedocJsonPath}; continuing without API items.`);
+  typedocSidebar = [];
+}

Run to verify Node/tooling versions and file presence:

Also applies to: 10-12


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Node version pins in CI/workflows:"
rg -nP -C2 'setup-node@|node-version:' .github/workflows || true

echo -e "\nEngine/volta pins:"
rg -nP -C2 '"(engines|volta)"\s*:' -g 'package.json' -g 'docs/package.json' || true

echo -e "\nVitePress version(s):"
rg -nP '"vitepress"\s*:\s*".*"' -g 'package.json' -g 'docs/package.json' || true

echo -e "\nTypedoc sidebar presence:"
fd -a typedoc-sidebar.json docs || true
[ -f docs/api/typedoc-sidebar.json ] && head -n 20 docs/api/typedoc-sidebar.json || echo "docs/api/typedoc-sidebar.json not found"

Length of output: 1052


Fix ESM path resolution and guard missing TypeDoc sidebar (prevents docs build crashes). Replace import.meta.dirname with fileURLToPath(import.meta.url); read docs/api/typedoc-sidebar.json with fs.readFileSync(..., 'utf8') inside try/catch, fall back to an empty DefaultTheme.SidebarItem[] and console.warn. File: docs/.vitepress/config.ts (imports + typedoc read).

🤖 Prompt for AI Agents
In docs/.vitepress/config.ts around lines 1 to 3, the current imports and use of
import.meta.dirname are incompatible with ESM and the typedoc sidebar read can
crash the build; update top imports to include fileURLToPath from 'url' and
replace import.meta.dirname with fileURLToPath(import.meta.url) for correct path
resolution, and when reading docs/api/typedoc-sidebar.json use
fs.readFileSync(..., 'utf8') inside a try/catch that on error assigns an empty
DefaultTheme.SidebarItem[] fallback and console.warns the missing sidebar file
and the error details so the docs build doesn't crash.

package.json Outdated
Comment on lines 11 to 22
"build": "pnpm run --filter '*' build",
"docs:dev": "pnpm run --filter docs dev",
"format": "pnpm run --filter '*' format",
"preinstall": "npx only-allow pnpm",
"lint": "pnpm run --filter '*' lint",
"prepare": "pnpm run /^prepare:/",
"prepare:git": "git config --local core.hooksPath .githooks",
"prerelease": "pnpm run --filter '*' prerelease",
"release": "pnpm bumpp -r",
"test": "pnpm run --filter '*' test",
"typecheck": "pnpm run --filter '*' typecheck"
},
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Guard cross‑workspace scripts with --if-present.

Running pnpm run --filter '*' <script> fails if any package lacks that script (e.g., docs may not have format, prerelease, test). Add --if-present to avoid false failures.

-    "build": "pnpm run --filter '*' build",
-    "docs:dev": "pnpm run --filter docs dev",
-    "format": "pnpm run --filter '*' format",
+    "build": "pnpm run --filter '*' --if-present build",
+    "docs:dev": "pnpm run --filter docs dev",
+    "format": "pnpm run --filter '*' --if-present format",
-    "lint": "pnpm run --filter '*' lint",
+    "lint": "pnpm run --filter '*' --if-present lint",
-    "prerelease": "pnpm run --filter '*' prerelease",
+    "prerelease": "pnpm run --filter '*' --if-present prerelease",
-    "test": "pnpm run --filter '*' test",
-    "typecheck": "pnpm run --filter '*' typecheck"
+    "test": "pnpm run --filter '*' --if-present test",
+    "typecheck": "pnpm run --filter '*' --if-present typecheck"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"build": "pnpm run --filter '*' build",
"docs:dev": "pnpm run --filter docs dev",
"format": "pnpm run --filter '*' format",
"preinstall": "npx only-allow pnpm",
"lint": "pnpm run --filter '*' lint",
"prepare": "pnpm run /^prepare:/",
"prepare:git": "git config --local core.hooksPath .githooks",
"prerelease": "pnpm run --filter '*' prerelease",
"release": "pnpm bumpp -r",
"test": "pnpm run --filter '*' test",
"typecheck": "pnpm run --filter '*' typecheck"
},
"build": "pnpm run --filter '*' --if-present build",
"docs:dev": "pnpm run --filter docs dev",
"format": "pnpm run --filter '*' --if-present format",
"preinstall": "npx only-allow pnpm",
"lint": "pnpm run --filter '*' --if-present lint",
"prepare": "pnpm run /^prepare:/",
"prepare:git": "git config --local core.hooksPath .githooks",
"prerelease": "pnpm run --filter '*' --if-present prerelease",
"release": "pnpm bumpp -r",
"test": "pnpm run --filter '*' --if-present test",
"typecheck": "pnpm run --filter '*' --if-present typecheck"
},
🤖 Prompt for AI Agents
package.json lines 11-22: several pnpm invocations use "pnpm run --filter '*'
<script>" which fails if a workspace package lacks that script; update those
invocations to include --if-present after --filter '*' so pnpm ignores missing
scripts. Specifically, modify the build, format, lint, prerelease, test and
typecheck commands to use "pnpm run --filter '*' --if-present <script>" (leave
release, docs:dev, prepare and prepare:git as-is).

@ryoppippi ryoppippi changed the title feat: monorepo feat: monorepo(bun -> pnpm) Sep 17, 2025
@ryoppippi ryoppippi merged commit 4d8b2e1 into main Sep 17, 2025
16 of 17 checks passed
@ryoppippi ryoppippi deleted the monorepo branch September 17, 2025 01:00
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.

2 participants