[
  {
    "path": ".changeset/README.md",
    "content": "# Changesets\n\nHello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works\nwith multi-package repos, or single-package repos to help you version and publish your code. You can\nfind the full documentation for it [in our repository](https://github.com/changesets/changesets)\n\nWe have a quick list of common questions to get you started engaging with this project in\n[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md)\n"
  },
  {
    "path": ".changeset/config.json",
    "content": "{\n  \"$schema\": \"https://unpkg.com/@changesets/config@3.0.0/schema.json\",\n  \"changelog\": [\n    \"@changesets/changelog-github\",\n    { \"repo\": \"jaredpalmer/tsdx\" }\n  ],\n  \"commit\": false,\n  \"fixed\": [],\n  \"linked\": [],\n  \"access\": \"public\",\n  \"baseBranch\": \"main\",\n  \"updateInternalDependencies\": \"patch\",\n  \"ignore\": []\n}\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "content": "---\nname: Bug report\nabout: Create a report to help us improve\ntitle: ''\nlabels: bug\nassignees: ''\n\n---\n\n### Describe the Bug\n\nA clear and concise description of what the bug is.\n\n### Steps to Reproduce\n\n1. Run `tsdx create mylib`\n2. ...\n3. See error\n\n### Expected Behavior\n\nWhat you expected to happen.\n\n### Actual Behavior\n\nWhat actually happened.\n\n### Screenshots/Logs\n\nIf applicable, add screenshots or error logs.\n\n```\nPaste error output here\n```\n\n### Environment\n\n```\nTSDX version:\nNode version:\nBun version:\nOS:\nTemplate used:\n```\n\nRun this to get versions:\n```bash\necho \"TSDX: $(bunx tsdx --version 2>/dev/null || echo 'not installed')\"\necho \"Node: $(node --version)\"\necho \"Bun: $(bun --version)\"\necho \"OS: $(uname -a)\"\n```\n\n### Additional Context\n\nAdd any other context about the problem here.\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/config.yml",
    "content": "blank_issues_enabled: false\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.md",
    "content": "---\nname: Feature request\nabout: Suggest an idea for this project\ntitle: ''\nlabels: enhancement\nassignees: ''\n\n---\n\n### Problem Statement\n\nWhat problem are you trying to solve? What's the current behavior?\n\n### Proposed Solution\n\nDescribe the solution you'd like. Be specific about the API or behavior.\n\n### Alternatives Considered\n\nWhat alternative solutions or features have you considered?\n\n### Who Benefits?\n\nWho is this for? All users? Specific use cases?\n\n### Additional Context\n\nAdd any other context, screenshots, or examples about the feature request here.\n"
  },
  {
    "path": ".github/dependabot.yml",
    "content": "version: 2\n\nupdates:\n  - package-ecosystem: npm\n    directory: '/'\n    schedule:\n      interval: weekly\n    commit-message:\n      prefix: 'deps:'\n    versioning-strategy: increase-if-necessary\n    allow:\n      - dependency-name: '*'\n        dependency-type: production\n    open-pull-requests-limit: 5\n"
  },
  {
    "path": ".github/stale.yml",
    "content": "# Number of days of inactivity before an issue becomes stale\ndaysUntilStale: 60\n# Number of days of inactivity before a stale issue is closed\ndaysUntilClose: 3600\n# Issues with these labels will never be considered stale\nexemptLabels:\n  - enhancement\n  - pinned\n  - RFC\n  - bug\n  - in progress\n  - 2.0\n# Label to use when marking an issue as stale\nstaleLabel: stale\n# Comment to post when marking an issue as stale. Set to `false` to disable\nmarkComment: false\n# Comment to post when closing a stale issue. Set to `false` to disable\ncloseComment: false\n"
  },
  {
    "path": ".github/workflows/nodejs.yml",
    "content": "name: CI\n\non:\n  push:\n    branches: [main, master]\n  pull_request:\n    branches: [main, master]\n\njobs:\n  build:\n    name: Build, lint, and test on Node ${{ matrix.node }} and ${{ matrix.os }}\n    runs-on: ${{ matrix.os }}\n    strategy:\n      matrix:\n        node: ['20', '22']\n        os: [ubuntu-latest, windows-latest, macos-latest]\n\n    steps:\n      - name: Checkout repo\n        uses: actions/checkout@v4\n\n      - name: Setup Bun\n        uses: oven-sh/setup-bun@v2\n        with:\n          bun-version: latest\n\n      - name: Setup Node.js ${{ matrix.node }}\n        uses: actions/setup-node@v4\n        with:\n          node-version: ${{ matrix.node }}\n\n      - name: Install dependencies\n        run: bun install\n\n      - name: Lint\n        run: bun run lint\n\n      - name: Type check\n        run: bun run typecheck\n\n      - name: Build\n        run: bun run build\n\n      - name: Test\n        run: bun run test\n"
  },
  {
    "path": ".github/workflows/release.yml",
    "content": "name: Release\n\non:\n  push:\n    branches:\n      - master\n\nconcurrency: ${{ github.workflow }}-${{ github.ref }}\n\njobs:\n  release:\n    name: Release\n    runs-on: ubuntu-latest\n    permissions:\n      contents: write\n      pull-requests: write\n      id-token: write\n    steps:\n      - name: Checkout repo\n        uses: actions/checkout@v4\n\n      - name: Setup Bun\n        uses: oven-sh/setup-bun@v2\n        with:\n          bun-version: latest\n\n      - name: Setup Node.js\n        uses: actions/setup-node@v4\n        with:\n          node-version: 20\n          registry-url: 'https://registry.npmjs.org'\n\n      - name: Install dependencies\n        run: bun install\n\n      - name: Build\n        run: bun run build\n\n      - name: Create Release Pull Request or Publish\n        id: changesets\n        uses: changesets/action@v1\n        with:\n          version: bun run changeset version\n          publish: bun run release\n          title: 'chore: release package'\n          commit: 'chore: release package'\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}\n          NPM_CONFIG_PROVENANCE: true\n"
  },
  {
    "path": ".gitignore",
    "content": "# Dependencies\nnode_modules\n.pnp\n.pnp.js\n\n# Build output\ndist\n*.tsbuildinfo\n\n# Bun\nbun.lockb\n\n# IDE\n.idea\n.vscode\n*.swp\n*.swo\n\n# OS\n.DS_Store\nThumbs.db\n\n# Logs\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n\n# Testing\ncoverage\n\n# Misc\n.env\n.env.local\n.netlify\n\n# Test directories\ntester\ntester-react\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "# tsdx\n\n## 2.0.0\n\n### Major Changes\n\n- [#1202](https://github.com/jaredpalmer/tsdx/pull/1202) [`6fcfef1`](https://github.com/jaredpalmer/tsdx/commit/6fcfef1dcb1c1d7f9f2c04969ee208a702876140) Thanks [@jaredpalmer](https://github.com/jaredpalmer)! - Initial 2.0.0 release - complete rewrite with modern Rust-based tooling\n\n  - Bundling with bunchee\n  - Testing with vitest\n  - Linting with oxlint\n  - Formatting with oxfmt\n  - Project scaffolding with basic and react templates\n"
  },
  {
    "path": "CLAUDE.md",
    "content": "# CLAUDE.md\n\nThis file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.\n\n## Project Overview\n\nTSDX is a zero-config CLI for TypeScript package development. Version 2.0 is a complete rewrite using modern Rust-based tooling: bunchee (bundling), vitest (testing), oxlint (linting), and oxfmt (formatting).\n\n## Development Commands\n\n```bash\nbun install              # Install dependencies\nbun run build            # Build CLI with bunchee\nbun run dev              # Watch mode (rebuilds on changes)\nbun run test             # Run all tests with vitest\nbun run test:watch       # Run tests in watch mode\nbun run test test/cli.test.ts   # Run a specific test file\nbun run lint             # Lint with oxlint\nbun run typecheck        # TypeScript type checking\nbun run format           # Format with oxfmt\nbun run format:check     # Check formatting\n```\n\n## Testing Notes\n\nTests require a build first since they test the compiled CLI:\n```bash\nbun run build && bun run test\n```\n\nThe e2e tests create projects in temp directories and have longer timeouts (60s).\n\n## Architecture\n\n**Single CLI Entry Point**: `src/index.ts` contains all CLI commands using Commander.js:\n- `create` - scaffolds projects from templates, installs deps with bun\n- `build/dev` - wraps bunchee\n- `test` - wraps vitest\n- `lint` - wraps oxlint\n- `format` - wraps oxfmt\n- `typecheck` - wraps tsc\n- `init` - adds tsdx config to existing project\n\n**Templates**: `templates/basic/` and `templates/react/` are copied directly during `create`. Template `gitignore` files are renamed to `.gitignore` post-copy. `<year>` and `<author>` placeholders in LICENSE are replaced.\n\n## Adding a New Template\n\n1. Create directory in `templates/`\n2. Register in `src/index.ts` in the `templates` object\n3. Include: package.json, tsconfig.json, vitest.config.ts, src/, test/, gitignore (not .gitignore), LICENSE with `<year>` and `<author>` placeholders\n\n## Documentation Website\n\nThe documentation site is in `./website/` and built with:\n- **Next.js 16** - React framework\n- **Fumadocs** - Documentation framework (fumadocs-core, fumadocs-mdx, fumadocs-ui)\n- **Tailwind CSS v4** - CSS-first configuration\n- **IBM Plex Sans/Mono** - Typography via next/font/google\n\n### Website Commands\n\n```bash\ncd website\nbun install              # Install dependencies\nbun run dev              # Start dev server\nbun run build            # Build for production\n```\n\n### Content Structure\n\n- `content/docs/` - MDX documentation files\n- `content/docs/meta.json` - Sidebar navigation structure\n- `app/` - Next.js App Router pages\n- `app/layout.config.tsx` - Navigation and logo configuration\n\n### Adding Documentation Pages\n\n1. Create `.mdx` file in `content/docs/`\n2. Add frontmatter with `title` and `description`\n3. Add page to `content/docs/meta.json` in desired position\n4. Use `---Section Name---` syntax in meta.json for sidebar sections\n\n## Commit Convention\n\nUses Conventional Commits: `feat:`, `fix:`, `docs:`, `test:`, `refactor:`, `chore:`\n\n## Release Process\n\nUses [changesets](https://github.com/changesets/changesets) for version management and npm publishing.\n\n### Creating a Changeset\n\nWhen making changes that should be released:\n```bash\nbun run changeset\n```\nFollow the prompts to select version bump type (patch/minor/major) and describe the change.\n\n### Release Workflow\n\n1. Create a changeset with your PR\n2. Merge PR to main\n3. GitHub Action creates a \"Release\" PR with version bumps\n4. Merge the Release PR to publish to npm\n\n### Manual Release\n\n```bash\nbun run changeset version  # Apply version bumps from changesets\nbun run release            # Build and publish to npm\n```\n"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "content": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, we as\ncontributors and maintainers pledge to making participation in our project and\nour community a harassment-free experience for everyone, regardless of age, body\nsize, disability, ethnicity, sex characteristics, gender identity and expression,\nlevel of experience, education, socio-economic status, nationality, personal\nappearance, race, religion, or sexual identity and orientation.\n\n## Our Standards\n\nExamples of behavior that contributes to creating a positive environment\ninclude:\n\n* Using welcoming and inclusive language\n* Being respectful of differing viewpoints and experiences\n* Gracefully accepting constructive criticism\n* Focusing on what is best for the community\n* Showing empathy towards other community members\n\nExamples of unacceptable behavior by participants include:\n\n* The use of sexualized language or imagery and unwelcome sexual attention or\n advances\n* Trolling, insulting/derogatory comments, and personal or political attacks\n* Public or private harassment\n* Publishing others' private information, such as a physical or electronic\n address, without explicit permission\n* Other conduct which could reasonably be considered inappropriate in a\n professional setting\n\n## Our Responsibilities\n\nProject maintainers are responsible for clarifying the standards of acceptable\nbehavior and are expected to take appropriate and fair corrective action in\nresponse to any instances of unacceptable behavior.\n\nProject maintainers have the right and responsibility to remove, edit, or\nreject comments, commits, code, wiki edits, issues, and other contributions\nthat are not aligned to this Code of Conduct, or to ban temporarily or\npermanently any contributor for other behaviors that they deem inappropriate,\nthreatening, offensive, or harmful.\n\n## Scope\n\nThis Code of Conduct applies both within project spaces and in public spaces\nwhen an individual is representing the project or its community. Examples of\nrepresenting a project or community include using an official project e-mail\naddress, posting via an official social media account, or acting as an appointed\nrepresentative at an online or offline event. Representation of a project may be\nfurther defined and clarified by project maintainers.\n\n## Enforcement\n\nInstances of abusive, harassing, or otherwise unacceptable behavior may be\nreported by contacting the project team at hello@formium.io. All\ncomplaints will be reviewed and investigated and will result in a response that\nis deemed necessary and appropriate to the circumstances. The project team is\nobligated to maintain confidentiality with regard to the reporter of an incident.\nFurther details of specific enforcement policies may be posted separately.\n\nProject maintainers who do not follow or enforce the Code of Conduct in good\nfaith may face temporary or permanent repercussions as determined by other\nmembers of the project's leadership.\n\n## Attribution\n\nThis Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,\navailable at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html\n\n[homepage]: https://www.contributor-covenant.org\n\nFor answers to common questions about this code of conduct, see\nhttps://www.contributor-covenant.org/faq\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# Contributing to TSDX\n\nThanks for your interest in TSDX! Contributions are welcome.\n\nIf you're proposing a new feature, please [open an issue](https://github.com/jaredpalmer/tsdx/issues/new/choose) first to discuss it.\n\n## Prerequisites\n\n- [Node.js](https://nodejs.org/) 20+ (LTS)\n- [Bun](https://bun.sh/) (latest version)\n\n### Installing Bun\n\n```bash\n# macOS/Linux\ncurl -fsSL https://bun.sh/install | bash\n\n# Windows\npowershell -c \"irm bun.sh/install.ps1 | iex\"\n```\n\n## Setup\n\n1. Fork this repository to your own GitHub account and clone it:\n\n   ```bash\n   git clone https://github.com/your-username/tsdx.git\n   cd tsdx\n   ```\n\n2. Install dependencies:\n\n   ```bash\n   bun install\n   ```\n\n3. Build the CLI:\n\n   ```bash\n   bun run build\n   ```\n\n4. Link for local development:\n\n   ```bash\n   bun link\n   ```\n\n   Now you can use `tsdx` commands globally and they'll run your local version.\n\n## Development Workflow\n\n### Building\n\n```bash\n# Build once\nbun run build\n\n# Watch mode (rebuilds on changes)\nbun run dev\n```\n\n### Testing\n\n```bash\n# Run all tests\nbun run test\n\n# Watch mode\nbun run test:watch\n\n# Run specific test file\nbun run test test/cli.test.ts\n```\n\n### Linting\n\n```bash\n# Lint the codebase\nbun run lint\n\n# Auto-fix issues\nbun run lint --fix\n```\n\n### Type Checking\n\n```bash\nbun run typecheck\n```\n\n### Formatting\n\n```bash\n# Format all files\nbun run format\n\n# Check formatting\nbun run format:check\n```\n\n## Testing Your Changes\n\n### Testing the CLI\n\nAfter building, test your changes by creating a new project:\n\n```bash\n# Create a test project\ncd /tmp\ntsdx create test-project --template basic\ncd test-project\n\n# Verify it works\nbun run build\nbun run test\n```\n\n### Testing Templates\n\nTemplates are in the `templates/` directory. After modifying a template:\n\n1. Build tsdx: `bun run build`\n2. Create a new project: `tsdx create test-project --template <template-name>`\n3. Verify the generated project works correctly\n\n## Project Structure\n\n```\ntsdx/\n├── src/\n│   └── index.ts          # CLI entry point\n├── templates/\n│   ├── basic/            # Basic TypeScript template\n│   └── react/            # React component template\n├── test/\n│   ├── cli.test.ts       # CLI unit tests\n│   └── e2e.test.ts       # End-to-end tests\n├── package.json\n├── tsconfig.json\n└── vitest.config.ts\n```\n\n## Submitting a PR\n\n1. Create a feature branch:\n   ```bash\n   git checkout -b feature/my-feature\n   ```\n\n2. Make your changes\n\n3. Run all checks:\n   ```bash\n   bun run lint\n   bun run typecheck\n   bun run test\n   bun run build\n   ```\n\n4. Commit your changes with a descriptive message:\n   ```bash\n   git commit -m \"feat: add new feature\"\n   ```\n\n5. Push and create a pull request:\n   ```bash\n   git push origin feature/my-feature\n   ```\n\n### Commit Message Guidelines\n\nWe follow [Conventional Commits](https://www.conventionalcommits.org/):\n\n- `feat:` - New features\n- `fix:` - Bug fixes\n- `docs:` - Documentation changes\n- `test:` - Test changes\n- `refactor:` - Code refactoring\n- `chore:` - Maintenance tasks\n\n## Adding a New Template\n\n1. Create a new directory in `templates/`:\n   ```bash\n   mkdir templates/my-template\n   ```\n\n2. Add the template files (use `basic` as reference)\n\n3. Register the template in `src/index.ts`:\n   ```typescript\n   const templates = {\n     basic: { ... },\n     react: { ... },\n     'my-template': {\n       name: 'my-template',\n       description: 'Description of my template',\n     },\n   };\n   ```\n\n4. Add tests for the new template\n\n5. Update the README to document the new template\n\n## Questions?\n\nFeel free to [open an issue](https://github.com/jaredpalmer/tsdx/issues) if you have questions or need help.\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2019 Jared Palmer https://jaredpalmer.com\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE."
  },
  {
    "path": "MIGRATION.md",
    "content": "# Migration Guide: TSDX v0.x to v2.0\n\nThis guide helps you migrate from the original TSDX (v0.x) to the modern TSDX 2.0.\n\n## What's Changed\n\nTSDX 2.0 is a complete rewrite that replaces the original toolchain with modern, high-performance alternatives:\n\n| Old (v0.x) | New (v2.0) | Why |\n|------------|------------|-----|\n| Rollup + Babel | [bunchee](https://github.com/huozhi/bunchee) | Zero-config, SWC-powered, faster |\n| Jest | [vitest](https://vitest.dev/) | Vite-native, faster, Jest-compatible |\n| ESLint | [oxlint](https://oxc.rs/) | 50-100x faster, Rust-powered |\n| Prettier | [oxfmt](https://oxc.rs/) | 35x faster, Rust-powered |\n| yarn/npm | [bun](https://bun.sh/) | Faster installs and execution |\n| Node 10+ | Node 20+ | LTS only |\n\n## Quick Migration\n\nFor most projects, follow these steps:\n\n### 1. Install Bun\n\n```bash\n# macOS/Linux\ncurl -fsSL https://bun.sh/install | bash\n\n# Windows\npowershell -c \"irm bun.sh/install.ps1 | iex\"\n```\n\n### 2. Update package.json\n\nReplace your scripts:\n\n```json\n{\n  \"scripts\": {\n    \"dev\": \"tsdx dev\",\n    \"build\": \"tsdx build\",\n    \"test\": \"tsdx test\",\n    \"lint\": \"tsdx lint\",\n    \"format\": \"tsdx format\",\n    \"typecheck\": \"tsdx typecheck\",\n    \"prepublishOnly\": \"bun run build\"\n  }\n}\n```\n\n### 3. Update Dependencies\n\nRemove old dependencies and add new ones:\n\n```bash\n# Remove old dependencies\nbun remove tsdx rollup @rollup/plugin-* babel-* @babel/* jest ts-jest eslint @typescript-eslint/* prettier husky lint-staged\n\n# Add new tsdx\nbun add -D tsdx typescript\n```\n\n### 4. Replace Jest with Vitest\n\nCreate `vitest.config.ts`:\n\n```typescript\nimport { defineConfig } from 'vitest/config';\n\nexport default defineConfig({\n  test: {\n    globals: true,\n    environment: 'node', // or 'jsdom' for React/DOM testing\n  },\n});\n```\n\nUpdate test files:\n- Change `import { describe, it, expect } from 'jest'` to `import { describe, it, expect } from 'vitest'`\n- Or use `globals: true` in vitest.config.ts to avoid imports\n\n**Jest to Vitest Cheatsheet:**\n\n| Jest | Vitest |\n|------|--------|\n| `jest.fn()` | `vi.fn()` |\n| `jest.mock()` | `vi.mock()` |\n| `jest.spyOn()` | `vi.spyOn()` |\n| `jest.useFakeTimers()` | `vi.useFakeTimers()` |\n| `beforeAll/afterAll` | Same |\n| `beforeEach/afterEach` | Same |\n| `describe/it/test` | Same |\n| `expect()` | Same |\n\n### 5. Remove Old Config Files\n\nDelete these files (they're no longer needed):\n\n```bash\nrm -f tsdx.config.js\nrm -f jest.config.js\nrm -f .babelrc babel.config.js babel.config.json\nrm -f .eslintrc .eslintrc.js .eslintrc.json .eslintignore\nrm -f .prettierrc .prettierrc.js .prettierrc.json .prettierignore\nrm -f rollup.config.js\nrm -f yarn.lock package-lock.json\n```\n\n### 6. Update tsconfig.json\n\nUpdate to modern settings:\n\n```json\n{\n  \"compilerOptions\": {\n    \"target\": \"ES2022\",\n    \"module\": \"ESNext\",\n    \"moduleResolution\": \"bundler\",\n    \"lib\": [\"ES2022\", \"DOM\"],\n    \"strict\": true,\n    \"esModuleInterop\": true,\n    \"skipLibCheck\": true,\n    \"forceConsistentCasingInFileNames\": true,\n    \"declaration\": true,\n    \"declarationMap\": true,\n    \"outDir\": \"./dist\",\n    \"rootDir\": \"./src\",\n    \"resolveJsonModule\": true,\n    \"isolatedModules\": true,\n    \"noEmit\": true\n  },\n  \"include\": [\"src\"],\n  \"exclude\": [\"node_modules\", \"dist\"]\n}\n```\n\n### 7. Update package.json Exports\n\nEnsure your package.json has modern exports:\n\n```json\n{\n  \"type\": \"module\",\n  \"main\": \"./dist/index.cjs\",\n  \"module\": \"./dist/index.js\",\n  \"types\": \"./dist/index.d.ts\",\n  \"exports\": {\n    \".\": {\n      \"import\": {\n        \"types\": \"./dist/index.d.ts\",\n        \"default\": \"./dist/index.js\"\n      },\n      \"require\": {\n        \"types\": \"./dist/index.d.cts\",\n        \"default\": \"./dist/index.cjs\"\n      }\n    },\n    \"./package.json\": \"./package.json\"\n  },\n  \"files\": [\"dist\", \"src\"],\n  \"engines\": {\n    \"node\": \">=20\"\n  }\n}\n```\n\n### 8. Install and Test\n\n```bash\n# Install dependencies\nbun install\n\n# Run tests\nbun run test\n\n# Build\nbun run build\n\n# Lint\nbun run lint\n```\n\n## Detailed Migration\n\n### Build Configuration\n\n**Old TSDX (tsdx.config.js):**\n```javascript\nmodule.exports = {\n  rollup(config, options) {\n    // Custom rollup config\n    return config;\n  },\n};\n```\n\n**New TSDX:** No configuration needed! bunchee reads your `package.json` exports field.\n\nFor advanced customization, create `bunchee.config.ts`:\n```typescript\nimport { BuncheeConfig } from 'bunchee';\n\nexport default {\n  // See bunchee documentation\n} satisfies BuncheeConfig;\n```\n\n### Testing\n\n**Old Jest test:**\n```typescript\nimport { sum } from './index';\n\ndescribe('sum', () => {\n  it('adds numbers', () => {\n    expect(sum(1, 2)).toBe(3);\n  });\n});\n```\n\n**New Vitest test (same syntax!):**\n```typescript\nimport { describe, it, expect } from 'vitest';\nimport { sum } from './index';\n\ndescribe('sum', () => {\n  it('adds numbers', () => {\n    expect(sum(1, 2)).toBe(3);\n  });\n});\n```\n\nOr with `globals: true` in vitest.config.ts:\n```typescript\nimport { sum } from './index';\n\ndescribe('sum', () => {\n  it('adds numbers', () => {\n    expect(sum(1, 2)).toBe(3);\n  });\n});\n```\n\n### React Testing\n\n**Old (enzyme/react-testing-library with Jest):**\n```typescript\nimport { render, screen } from '@testing-library/react';\nimport { MyComponent } from './MyComponent';\n\ntest('renders', () => {\n  render(<MyComponent />);\n  expect(screen.getByText('Hello')).toBeInTheDocument();\n});\n```\n\n**New (same, just with Vitest!):**\n```typescript\nimport { describe, it, expect } from 'vitest';\nimport { render, screen } from '@testing-library/react';\nimport { MyComponent } from './MyComponent';\n\ndescribe('MyComponent', () => {\n  it('renders', () => {\n    render(<MyComponent />);\n    expect(screen.getByText('Hello')).toBeDefined();\n  });\n});\n```\n\nNote: Replace `toBeInTheDocument()` with `toBeDefined()` or add `@testing-library/jest-dom` and configure in vitest setup.\n\n### Linting\n\n**Old ESLint (.eslintrc.js):**\n```javascript\nmodule.exports = {\n  extends: ['react-app', 'prettier'],\n  rules: {\n    'no-unused-vars': 'warn',\n  },\n};\n```\n\n**New oxlint (.oxlintrc.json) - optional:**\n```json\n{\n  \"rules\": {\n    \"no-unused-vars\": \"warn\"\n  }\n}\n```\n\nMost ESLint rules have equivalents in oxlint. Check [oxlint rules documentation](https://oxc.rs/docs/guide/usage/linter/rules.html).\n\n### Formatting\n\n**Old Prettier (.prettierrc):**\n```json\n{\n  \"semi\": true,\n  \"singleQuote\": true,\n  \"tabWidth\": 2\n}\n```\n\n**New oxfmt (.oxfmtrc.json) - optional:**\n```json\n{\n  \"indentWidth\": 2,\n  \"lineWidth\": 100\n}\n```\n\n### GitHub Actions\n\n**Old workflow:**\n```yaml\njobs:\n  build:\n    runs-on: ubuntu-latest\n    strategy:\n      matrix:\n        node: [12, 14, 16]\n    steps:\n      - uses: actions/checkout@v3\n      - uses: actions/setup-node@v3\n        with:\n          node-version: ${{ matrix.node }}\n      - run: yarn install\n      - run: yarn build\n      - run: yarn test\n```\n\n**New workflow:**\n```yaml\njobs:\n  build:\n    runs-on: ${{ matrix.os }}\n    strategy:\n      matrix:\n        node: ['20', '22']\n        os: [ubuntu-latest, windows-latest, macos-latest]\n    steps:\n      - uses: actions/checkout@v4\n      - uses: oven-sh/setup-bun@v2\n        with:\n          bun-version: latest\n      - uses: actions/setup-node@v4\n        with:\n          node-version: ${{ matrix.node }}\n      - run: bun install\n      - run: bun run lint\n      - run: bun run typecheck\n      - run: bun run build\n      - run: bun run test\n```\n\n## Breaking Changes\n\n### Removed Features\n\n1. **Storybook template** - Use [Storybook CLI](https://storybook.js.org/docs/get-started/install) directly\n2. **Custom Rollup config** - Use bunchee config or raw rollup if needed\n3. **tsdx lint** - Now wraps oxlint instead of ESLint\n4. **Node.js < 20** - Only Node.js 20+ (LTS) is supported\n\n### Changed Behavior\n\n1. **Build output** - Slightly different but compatible\n2. **Watch mode** - Now uses bunchee's watch, may have different behavior\n3. **Test runner** - Vitest instead of Jest (mostly compatible API)\n4. **Default branch** - Uses `main` instead of `master` in templates\n\n## Compatibility\n\n### Your Library Consumers\n\n**No changes needed!** The build output format is compatible:\n- ESM and CommonJS dual publish\n- TypeScript declarations\n- Same export patterns\n\n### Your Development Workflow\n\n| Task | Old Command | New Command |\n|------|-------------|-------------|\n| Create project | `npx tsdx create mylib` | `bunx tsdx create mylib` |\n| Development | `yarn start` | `bun run dev` |\n| Build | `yarn build` | `bun run build` |\n| Test | `yarn test` | `bun run test` |\n| Lint | `yarn lint` | `bun run lint` |\n| Format | `yarn prettier --write .` | `bun run format` |\n\n## Troubleshooting\n\n### \"bun: command not found\"\n\nInstall bun:\n```bash\ncurl -fsSL https://bun.sh/install | bash\n```\n\n### Tests fail with \"vi is not defined\"\n\nAdd vitest imports:\n```typescript\nimport { describe, it, expect, vi } from 'vitest';\n```\n\nOr enable globals in `vitest.config.ts`:\n```typescript\nexport default defineConfig({\n  test: {\n    globals: true,\n  },\n});\n```\n\n### TypeScript errors with moduleResolution\n\nUpdate tsconfig.json:\n```json\n{\n  \"compilerOptions\": {\n    \"moduleResolution\": \"bundler\"\n  }\n}\n```\n\n### ESM/CJS interop issues\n\nEnsure your package.json has:\n```json\n{\n  \"type\": \"module\"\n}\n```\n\n### \"Cannot find module\" in tests\n\nCheck your vitest.config.ts has correct paths:\n```typescript\nexport default defineConfig({\n  test: {\n    include: ['test/**/*.test.ts'],\n  },\n});\n```\n\n## Getting Help\n\n- [TSDX GitHub Issues](https://github.com/jaredpalmer/tsdx/issues)\n- [Vitest Documentation](https://vitest.dev/)\n- [bunchee Documentation](https://github.com/huozhi/bunchee)\n- [oxlint Documentation](https://oxc.rs/docs/guide/usage/linter.html)\n- [Bun Documentation](https://bun.sh/docs)\n"
  },
  {
    "path": "README.md",
    "content": "# TSDX\n\nZero-config CLI for TypeScript package development.\n\n[![CI](https://github.com/jaredpalmer/tsdx/actions/workflows/nodejs.yml/badge.svg)](https://github.com/jaredpalmer/tsdx/actions/workflows/nodejs.yml)\n[![npm](https://img.shields.io/npm/v/tsdx.svg)](https://www.npmjs.com/package/tsdx)\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)\n\nModern TypeScript library development, simplified. TSDX provides a zero-config CLI that helps you develop, test, and publish TypeScript packages with ease.\n\n> **TSDX 2.0** is a complete rewrite using modern, high-performance Rust-based tooling. See the [Migration Guide](./MIGRATION.md) if upgrading from v0.x\n\n## Features\n\n- **Zero config** - Sensible defaults, just start coding\n- **Modern tooling** - Built on [bunchee](https://github.com/huozhi/bunchee), [vitest](https://vitest.dev/), [oxlint](https://oxc.rs/docs/guide/usage/linter.html), and [oxfmt](https://oxc.rs/docs/guide/usage/formatter)\n- **Dual ESM/CJS** - Automatic dual module builds with proper exports\n- **TypeScript first** - Full TypeScript support with declaration generation\n- **Lightning fast** - Rust-powered linting (50-100x faster than ESLint) and formatting (35x faster than Prettier)\n- **Bun-native** - Uses bun for package management\n- **Modern Node.js** - Supports Node.js 20+ (LTS)\n\n## Quick Start\n\n```bash\n# Create a new package\nbunx tsdx create mylib\n\n# Navigate to the project\ncd mylib\n\n# Start development\nbun run dev\n```\n\nThat's it! Start editing `src/index.ts` and build your library.\n\n## Installation\n\n### Global Installation (recommended for creating projects)\n\n```bash\nbun add -g tsdx\n```\n\n### Per-Project Installation\n\n```bash\nbun add -D tsdx\n```\n\n## Commands\n\n### `tsdx create <name>`\n\nCreate a new TypeScript package from a template.\n\n```bash\n# Interactive template selection\nbunx tsdx create mylib\n\n# Specify template directly\nbunx tsdx create mylib --template react\n```\n\n**Available Templates:**\n\n| Template | Description |\n|----------|-------------|\n| `basic` | A basic TypeScript library with vitest |\n| `react` | A React component library with Testing Library |\n\n### `tsdx build`\n\nBuild the package for production using [bunchee](https://github.com/huozhi/bunchee).\n\n```bash\ntsdx build\n\n# Skip cleaning dist folder\ntsdx build --no-clean\n```\n\nOutputs ESM and CommonJS formats with TypeScript declarations.\n\n### `tsdx dev` / `tsdx watch`\n\nStart development mode with file watching.\n\n```bash\ntsdx dev\n```\n\nRebuilds automatically when files change.\n\n### `tsdx test`\n\nRun tests using [vitest](https://vitest.dev/).\n\n```bash\n# Run tests once\ntsdx test\n\n# Watch mode\ntsdx test --watch\n\n# With coverage\ntsdx test --coverage\n\n# Update snapshots\ntsdx test --update\n```\n\n### `tsdx lint`\n\nLint the codebase using [oxlint](https://oxc.rs/docs/guide/usage/linter.html).\n\n```bash\n# Lint src and test directories (default)\ntsdx lint\n\n# Lint specific paths\ntsdx lint src lib\n\n# Auto-fix issues\ntsdx lint --fix\n\n# Use custom config\ntsdx lint --config .oxlintrc.json\n```\n\n### `tsdx format`\n\nFormat the codebase using [oxfmt](https://oxc.rs/docs/guide/usage/formatter).\n\n```bash\n# Format all files\ntsdx format\n\n# Check formatting without changes\ntsdx format --check\n\n# Format specific paths\ntsdx format src test\n```\n\n### `tsdx typecheck`\n\nRun TypeScript type checking.\n\n```bash\ntsdx typecheck\n\n# Watch mode\ntsdx typecheck --watch\n```\n\n### `tsdx init`\n\nInitialize tsdx configuration in an existing project.\n\n```bash\nbunx tsdx init\n```\n\nThis adds the necessary configuration to your `package.json`, creates `tsconfig.json` and `vitest.config.ts` if they don't exist.\n\n## Project Structure\n\nProjects created with tsdx follow this structure:\n\n```\nmylib/\n├── src/\n│   └── index.ts          # Library entry point\n├── test/\n│   └── index.test.ts     # Tests (vitest)\n├── dist/                  # Build output (generated)\n│   ├── index.js          # ESM\n│   ├── index.cjs         # CommonJS\n│   └── index.d.ts        # TypeScript declarations\n├── .github/\n│   └── workflows/        # CI/CD workflows\n├── package.json\n├── tsconfig.json\n├── vitest.config.ts\n├── LICENSE\n└── README.md\n```\n\n### React Template Additional Structure\n\n```\nmylib/\n├── src/\n│   └── index.tsx         # React component entry\n├── test/\n│   └── index.test.tsx    # Tests with Testing Library\n├── example/              # Demo app (Vite-powered)\n│   ├── index.tsx\n│   ├── index.html\n│   ├── package.json\n│   └── vite.config.ts\n└── ...\n```\n\n## Module Formats\n\nTSDX outputs both ESM and CommonJS formats:\n\n| File | Format | Usage |\n|------|--------|-------|\n| `dist/index.js` | ESM | Modern bundlers, Node.js with `type: \"module\"` |\n| `dist/index.cjs` | CommonJS | Legacy Node.js, older bundlers |\n| `dist/index.d.ts` | TypeScript | Type definitions |\n| `dist/index.d.cts` | TypeScript | CJS type definitions |\n\nThe `package.json` exports field is configured automatically:\n\n```json\n{\n  \"type\": \"module\",\n  \"main\": \"./dist/index.cjs\",\n  \"module\": \"./dist/index.js\",\n  \"types\": \"./dist/index.d.ts\",\n  \"exports\": {\n    \".\": {\n      \"import\": {\n        \"types\": \"./dist/index.d.ts\",\n        \"default\": \"./dist/index.js\"\n      },\n      \"require\": {\n        \"types\": \"./dist/index.d.cts\",\n        \"default\": \"./dist/index.cjs\"\n      }\n    },\n    \"./package.json\": \"./package.json\"\n  }\n}\n```\n\n## Tool Stack\n\nTSDX 2.0 uses modern, high-performance tools:\n\n| Tool | Purpose | Performance |\n|------|---------|-------------|\n| [bunchee](https://github.com/huozhi/bunchee) | Bundling | Zero-config, built on Rollup + SWC |\n| [vitest](https://vitest.dev/) | Testing | Vite-native, Jest-compatible API |\n| [oxlint](https://oxc.rs/docs/guide/usage/linter.html) | Linting | 50-100x faster than ESLint |\n| [oxfmt](https://oxc.rs/docs/guide/usage/formatter) | Formatting | 35x faster than Prettier |\n| [bun](https://bun.sh/) | Package Management | Native speed, npm-compatible |\n\n## Configuration\n\n### TypeScript (`tsconfig.json`)\n\nTSDX creates a modern TypeScript configuration:\n\n```json\n{\n  \"compilerOptions\": {\n    \"target\": \"ES2022\",\n    \"module\": \"ESNext\",\n    \"moduleResolution\": \"bundler\",\n    \"strict\": true,\n    \"declaration\": true,\n    \"declarationMap\": true\n  }\n}\n```\n\n### Vitest (`vitest.config.ts`)\n\nDefault test configuration:\n\n```typescript\nimport { defineConfig } from 'vitest/config';\n\nexport default defineConfig({\n  test: {\n    globals: true,\n    environment: 'node', // or 'jsdom' for React\n  },\n});\n```\n\n### Linting (`.oxlintrc.json`)\n\nOptional oxlint configuration:\n\n```json\n{\n  \"rules\": {\n    \"no-unused-vars\": \"warn\"\n  }\n}\n```\n\n### Formatting (`.oxfmtrc.json`)\n\nOptional oxfmt configuration:\n\n```json\n{\n  \"indentWidth\": 2,\n  \"lineWidth\": 100\n}\n```\n\n## Requirements\n\n- **Node.js**: 20+ (LTS)\n- **Bun**: Latest version\n\n### Installing Bun\n\n```bash\n# macOS/Linux\ncurl -fsSL https://bun.sh/install | bash\n\n# Windows\npowershell -c \"irm bun.sh/install.ps1 | iex\"\n\n# npm (alternative)\nnpm install -g bun\n```\n\n## Migrating from TSDX v0.x\n\nSee the [Migration Guide](./MIGRATION.md) for detailed instructions on upgrading from the original TSDX.\n\n**Quick summary:**\n1. Install bun\n2. Update `package.json` scripts to use tsdx commands\n3. Replace Jest with vitest\n4. Replace ESLint with oxlint (optional)\n5. Replace Prettier with oxfmt (optional)\n6. Run `bun install`\n\n## Publishing\n\n```bash\n# Build the package\nbun run build\n\n# Publish to npm\nnpm publish\n```\n\nWe recommend using [np](https://github.com/sindresorhus/np) or [changesets](https://github.com/changesets/changesets) for publishing.\n\n## FAQ\n\n### Why bun?\n\nBun provides significantly faster package installation and script execution. It's compatible with npm packages and the Node.js ecosystem.\n\n### Can I still use npm/yarn/pnpm?\n\nThe generated projects use bun for package management, but the built packages are compatible with any package manager. Your library consumers can use npm, yarn, pnpm, or bun.\n\n### Why oxlint instead of ESLint?\n\noxlint is 50-100x faster than ESLint while catching the most important issues. For comprehensive linting, you can still use ESLint alongside oxlint.\n\n### Is this compatible with the old TSDX?\n\nThe build output format is fully compatible. Your library consumers won't notice any difference. However, the development workflow and configuration are different.\n\n## Contributing\n\nContributions are welcome! Please see [CONTRIBUTING.md](./CONTRIBUTING.md) for guidelines.\n\n## Acknowledgments\n\nTSDX 2.0 is built on the shoulders of giants:\n\n- [bunchee](https://github.com/huozhi/bunchee) by Jiachi Liu\n- [vitest](https://vitest.dev/) by the Vitest team\n- [oxc](https://oxc.rs/) by the OXC team\n- [bun](https://bun.sh/) by the Bun team\n\n## Author\n\n- [Jared Palmer](https://twitter.com/jaredpalmer)\n\n## License\n\n[MIT](./LICENSE)\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"tsdx\",\n  \"version\": \"2.0.0\",\n  \"author\": \"Jared Palmer <jared@palmer.net>\",\n  \"description\": \"Zero-config TypeScript package development\",\n  \"license\": \"MIT\",\n  \"homepage\": \"https://github.com/jaredpalmer/tsdx\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/jaredpalmer/tsdx.git\"\n  },\n  \"keywords\": [\n    \"typescript\",\n    \"bundle\",\n    \"bunchee\",\n    \"vitest\",\n    \"oxlint\"\n  ],\n  \"bugs\": {\n    \"url\": \"https://github.com/jaredpalmer/tsdx/issues\"\n  },\n  \"type\": \"module\",\n  \"bin\": {\n    \"tsdx\": \"./dist/index.js\"\n  },\n  \"exports\": {\n    \".\": {\n      \"import\": \"./dist/index.js\",\n      \"types\": \"./dist/index.d.ts\"\n    }\n  },\n  \"scripts\": {\n    \"build\": \"bunchee\",\n    \"dev\": \"bunchee --watch\",\n    \"lint\": \"oxlint\",\n    \"format\": \"oxfmt --write .\",\n    \"format:check\": \"oxfmt --check .\",\n    \"test\": \"vitest run\",\n    \"test:watch\": \"vitest\",\n    \"typecheck\": \"tsc --noEmit\",\n    \"prepare\": \"bun run build\",\n    \"changeset\": \"changeset\",\n    \"release\": \"bun run build && changeset publish\"\n  },\n  \"files\": [\n    \"dist\",\n    \"templates\"\n  ],\n  \"engines\": {\n    \"node\": \">=20\"\n  },\n  \"dependencies\": {\n    \"commander\": \"^13.0.0\",\n    \"enquirer\": \"^2.4.1\",\n    \"execa\": \"^9.5.2\",\n    \"fs-extra\": \"^11.2.0\",\n    \"ora\": \"^8.1.1\",\n    \"picocolors\": \"^1.1.1\"\n  },\n  \"devDependencies\": {\n    \"@changesets/changelog-github\": \"^0.5.2\",\n    \"@changesets/cli\": \"^2.29.8\",\n    \"@types/fs-extra\": \"^11.0.4\",\n    \"@types/node\": \"^22.10.2\",\n    \"bunchee\": \"^6.4.0\",\n    \"oxlint\": \"^0.16.0\",\n    \"typescript\": \"^5.7.2\",\n    \"vitest\": \"^2.1.8\"\n  }\n}\n"
  },
  {
    "path": "src/index.ts",
    "content": "#!/usr/bin/env node\n\nimport { program } from 'commander';\nimport pc from 'picocolors';\nimport fs from 'fs-extra';\nimport path from 'path';\nimport { execa, execaCommand } from 'execa';\nimport ora from 'ora';\nimport Enquirer from 'enquirer';\n\nconst { Select, Input } = Enquirer as unknown as {\n  Select: new (options: { message: string; choices: { name: string; message: string }[] }) => { run: () => Promise<string> };\n  Input: new (options: { message: string; initial?: string }) => { run: () => Promise<string> };\n};\n\n// Read package.json for version\nconst pkgPath = path.resolve(__dirname, '../package.json');\nconst pkg = fs.readJSONSync(pkgPath);\n\n// Path constants\nconst paths = {\n  appRoot: process.cwd(),\n  appPackageJson: path.resolve(process.cwd(), 'package.json'),\n  appDist: path.resolve(process.cwd(), 'dist'),\n  appSrc: path.resolve(process.cwd(), 'src'),\n};\n\n// Template definitions\nconst templates = {\n  basic: {\n    name: 'basic',\n    description: 'A basic TypeScript library',\n  },\n  react: {\n    name: 'react',\n    description: 'A React component library',\n  },\n} as const;\n\ntype TemplateName = keyof typeof templates;\n\n// ASCII banner\nconst banner = `\n${pc.cyan('████████╗███████╗██████╗ ██╗  ██╗')}\n${pc.cyan('╚══██╔══╝██╔════╝██╔══██╗╚██╗██╔╝')}\n${pc.cyan('   ██║   ███████╗██║  ██║ ╚███╔╝ ')}\n${pc.cyan('   ██║   ╚════██║██║  ██║ ██╔██╗ ')}\n${pc.cyan('   ██║   ███████║██████╔╝██╔╝ ██╗')}\n${pc.cyan('   ╚═╝   ╚══════╝╚═════╝ ╚═╝  ╚═╝')}\n${pc.dim('Zero-config TypeScript package development')}\n${pc.dim('Powered by bunchee, oxlint, vitest')}\n`;\n\nprogram\n  .name('tsdx')\n  .description('Zero-config TypeScript package development')\n  .version(pkg.version);\n\n// CREATE command\nprogram\n  .command('create <name>')\n  .description('Create a new TypeScript package')\n  .option('-t, --template <template>', 'Template to use (basic, react)')\n  .action(async (name: string, options: { template?: string }) => {\n    console.log(banner);\n\n    const spinner = ora();\n\n    try {\n      // Check if folder exists\n      const projectPath = path.resolve(process.cwd(), name);\n      if (await fs.pathExists(projectPath)) {\n        console.log(pc.red(`Error: Directory \"${name}\" already exists`));\n        process.exit(1);\n      }\n\n      // Select template\n      let templateName: TemplateName;\n      if (options.template && options.template in templates) {\n        templateName = options.template as TemplateName;\n      } else {\n        const prompt = new Select({\n          message: 'Choose a template',\n          choices: Object.entries(templates).map(([key, val]) => ({\n            name: key,\n            message: `${key} - ${val.description}`,\n          })),\n        });\n        templateName = (await prompt.run()) as TemplateName;\n      }\n\n      spinner.start(`Creating ${pc.green(name)}...`);\n\n      // Copy template\n      const templatePath = path.resolve(__dirname, `../templates/${templateName}`);\n      await fs.copy(templatePath, projectPath);\n\n      // Rename gitignore\n      const gitignorePath = path.resolve(projectPath, 'gitignore');\n      if (await fs.pathExists(gitignorePath)) {\n        await fs.move(gitignorePath, path.resolve(projectPath, '.gitignore'));\n      }\n\n      // Get author name\n      let author = '';\n      try {\n        const { stdout } = await execa('git', ['config', '--global', 'user.name']);\n        author = stdout.trim();\n      } catch {\n        // Ignore if git config fails\n      }\n\n      if (!author) {\n        spinner.stop();\n        const authorPrompt = new Input({\n          message: 'Who is the package author?',\n          initial: '',\n        });\n        author = await authorPrompt.run();\n        spinner.start();\n      }\n\n      // Update package.json\n      const pkgJsonPath = path.resolve(projectPath, 'package.json');\n      const pkgJson = await fs.readJSON(pkgJsonPath);\n      pkgJson.name = name;\n      pkgJson.author = author;\n      await fs.writeJSON(pkgJsonPath, pkgJson, { spaces: 2 });\n\n      // Update LICENSE\n      const licensePath = path.resolve(projectPath, 'LICENSE');\n      if (await fs.pathExists(licensePath)) {\n        let license = await fs.readFile(licensePath, 'utf-8');\n        license = license.replace(/<year>/g, new Date().getFullYear().toString());\n        license = license.replace(/<author>/g, author);\n        await fs.writeFile(licensePath, license);\n      }\n\n      spinner.succeed(`Created ${pc.green(name)}`);\n\n      // Install dependencies\n      spinner.start('Installing dependencies with bun...');\n      process.chdir(projectPath);\n      await execa('bun', ['install']);\n      spinner.succeed('Installed dependencies');\n\n      // Success message\n      console.log(`\n${pc.green('Success!')} Created ${pc.cyan(name)} at ${pc.dim(projectPath)}\n\nInside that directory, you can run:\n\n  ${pc.cyan('bun run dev')}      Start the dev server\n  ${pc.cyan('bun run build')}    Build for production\n  ${pc.cyan('bun run test')}     Run tests\n  ${pc.cyan('bun run lint')}     Lint the codebase\n  ${pc.cyan('bun run format')}   Format the codebase\n\nWe suggest that you begin by typing:\n\n  ${pc.cyan('cd')} ${name}\n  ${pc.cyan('bun run dev')}\n`);\n    } catch (error) {\n      spinner.fail('Failed to create project');\n      console.error(error);\n      process.exit(1);\n    }\n  });\n\n// BUILD command\nprogram\n  .command('build')\n  .description('Build the package for production')\n  .option('--no-clean', 'Skip cleaning the dist folder')\n  .action(async (options: { clean: boolean }) => {\n    const spinner = ora();\n\n    try {\n      if (options.clean) {\n        spinner.start('Cleaning dist folder...');\n        await fs.remove(paths.appDist);\n        spinner.succeed('Cleaned dist folder');\n      }\n\n      spinner.start('Building with bunchee...');\n      await execaCommand('bunchee', { stdio: 'inherit' });\n      spinner.succeed('Build complete');\n    } catch (error) {\n      spinner.fail('Build failed');\n      console.error(error);\n      process.exit(1);\n    }\n  });\n\n// DEV/WATCH command\nprogram\n  .command('dev')\n  .alias('watch')\n  .description('Start development mode with watch')\n  .action(async () => {\n    console.log(pc.cyan('Starting development mode...'));\n    try {\n      await execaCommand('bunchee --watch', { stdio: 'inherit' });\n    } catch {\n      console.error(pc.red('Development mode failed'));\n      process.exit(1);\n    }\n  });\n\n// TEST command\nprogram\n  .command('test')\n  .description('Run tests with vitest')\n  .option('-w, --watch', 'Run in watch mode')\n  .option('-c, --coverage', 'Run with coverage')\n  .option('-u, --update', 'Update snapshots')\n  .allowUnknownOption(true)\n  .action(async (options: { watch?: boolean; coverage?: boolean; update?: boolean }, command) => {\n    const args = ['vitest'];\n\n    if (!options.watch) {\n      args.push('run');\n    }\n\n    if (options.coverage) {\n      args.push('--coverage');\n    }\n\n    if (options.update) {\n      args.push('--update');\n    }\n\n    // Pass through any additional arguments\n    const extraArgs = command.args || [];\n    args.push(...extraArgs);\n\n    try {\n      await execa('bunx', args, { stdio: 'inherit' });\n    } catch (error: unknown) {\n      // Vitest exits with non-zero on test failure, which is expected\n      const exitCode = (error as { exitCode?: number }).exitCode ?? 1;\n      process.exit(exitCode);\n    }\n  });\n\n// LINT command\nprogram\n  .command('lint')\n  .description('Lint the codebase with oxlint')\n  .option('-f, --fix', 'Auto-fix fixable issues')\n  .option('--config <path>', 'Path to config file')\n  .argument('[paths...]', 'Paths to lint', ['src', 'test'])\n  .action(async (lintPaths: string[], options: { fix?: boolean; config?: string }) => {\n    const args = ['oxlint'];\n\n    // Filter to existing paths\n    const existingPaths = lintPaths.filter((p) => fs.existsSync(path.resolve(process.cwd(), p)));\n\n    if (existingPaths.length === 0) {\n      console.log(pc.yellow('No valid paths to lint'));\n      return;\n    }\n\n    args.push(...existingPaths);\n\n    if (options.fix) {\n      args.push('--fix');\n    }\n\n    if (options.config) {\n      args.push('--config', options.config);\n    }\n\n    try {\n      await execa('bunx', args, { stdio: 'inherit' });\n      console.log(pc.green('Linting complete'));\n    } catch (error: unknown) {\n      const exitCode = (error as { exitCode?: number }).exitCode ?? 1;\n      process.exit(exitCode);\n    }\n  });\n\n// FORMAT command\nprogram\n  .command('format')\n  .description('Format the codebase with oxfmt')\n  .option('-c, --check', 'Check if files are formatted')\n  .argument('[paths...]', 'Paths to format', ['.'])\n  .action(async (formatPaths: string[], options: { check?: boolean }) => {\n    const args = ['oxfmt'];\n\n    if (options.check) {\n      args.push('--check');\n    } else {\n      args.push('--write');\n    }\n\n    args.push(...formatPaths);\n\n    try {\n      await execa('bunx', args, { stdio: 'inherit' });\n      if (options.check) {\n        console.log(pc.green('All files are formatted'));\n      } else {\n        console.log(pc.green('Formatting complete'));\n      }\n    } catch (error: unknown) {\n      const exitCode = (error as { exitCode?: number }).exitCode ?? 1;\n      process.exit(exitCode);\n    }\n  });\n\n// TYPECHECK command\nprogram\n  .command('typecheck')\n  .description('Run TypeScript type checking')\n  .option('-w, --watch', 'Run in watch mode')\n  .action(async (options: { watch?: boolean }) => {\n    const args = ['tsc', '--noEmit'];\n\n    if (options.watch) {\n      args.push('--watch');\n    }\n\n    try {\n      await execa('bunx', args, { stdio: 'inherit' });\n      console.log(pc.green('Type checking complete'));\n    } catch (error: unknown) {\n      const exitCode = (error as { exitCode?: number }).exitCode ?? 1;\n      process.exit(exitCode);\n    }\n  });\n\n// INIT command - initialize tsdx in an existing project\nprogram\n  .command('init')\n  .description('Initialize tsdx configuration in an existing project')\n  .action(async () => {\n    const spinner = ora();\n\n    try {\n      // Check if package.json exists\n      if (!(await fs.pathExists(paths.appPackageJson))) {\n        console.log(pc.red('No package.json found. Run this command in a project directory.'));\n        process.exit(1);\n      }\n\n      spinner.start('Initializing tsdx configuration...');\n\n      // Read current package.json\n      const pkgJson = await fs.readJSON(paths.appPackageJson);\n\n      // Add/update exports field for bunchee\n      if (!pkgJson.exports) {\n        pkgJson.exports = {\n          '.': {\n            import: './dist/index.js',\n            require: './dist/index.cjs',\n            types: './dist/index.d.ts',\n          },\n          './package.json': './package.json',\n        };\n      }\n\n      // Add main/module/types\n      pkgJson.main = './dist/index.cjs';\n      pkgJson.module = './dist/index.js';\n      pkgJson.types = './dist/index.d.ts';\n      pkgJson.type = 'module';\n\n      // Add scripts\n      pkgJson.scripts = {\n        ...pkgJson.scripts,\n        dev: 'bunchee --watch',\n        build: 'bunchee',\n        test: 'vitest run',\n        'test:watch': 'vitest',\n        lint: 'oxlint',\n        format: 'oxfmt --write .',\n        'format:check': 'oxfmt --check .',\n        typecheck: 'tsc --noEmit',\n      };\n\n      await fs.writeJSON(paths.appPackageJson, pkgJson, { spaces: 2 });\n\n      // Create tsconfig.json if it doesn't exist\n      const tsconfigPath = path.resolve(process.cwd(), 'tsconfig.json');\n      if (!(await fs.pathExists(tsconfigPath))) {\n        const tsconfig = {\n          compilerOptions: {\n            target: 'ES2022',\n            module: 'ESNext',\n            moduleResolution: 'bundler',\n            lib: ['ES2022', 'DOM'],\n            strict: true,\n            esModuleInterop: true,\n            skipLibCheck: true,\n            forceConsistentCasingInFileNames: true,\n            declaration: true,\n            declarationMap: true,\n            outDir: './dist',\n            rootDir: './src',\n            resolveJsonModule: true,\n            isolatedModules: true,\n            noEmit: true,\n          },\n          include: ['src'],\n          exclude: ['node_modules', 'dist'],\n        };\n        await fs.writeJSON(tsconfigPath, tsconfig, { spaces: 2 });\n      }\n\n      // Create vitest.config.ts if it doesn't exist\n      const vitestConfigPath = path.resolve(process.cwd(), 'vitest.config.ts');\n      if (!(await fs.pathExists(vitestConfigPath))) {\n        const vitestConfig = `import { defineConfig } from 'vitest/config';\n\nexport default defineConfig({\n  test: {\n    globals: true,\n    environment: 'node',\n  },\n});\n`;\n        await fs.writeFile(vitestConfigPath, vitestConfig);\n      }\n\n      spinner.succeed('Initialized tsdx configuration');\n\n      console.log(`\n${pc.green('Configuration added!')}\n\nInstall the required dev dependencies:\n\n  ${pc.cyan('bun add -D bunchee vitest typescript')}\n  ${pc.cyan('bun add -D oxlint')}\n\nThen you can run:\n\n  ${pc.cyan('bun run dev')}      Start development mode\n  ${pc.cyan('bun run build')}    Build for production\n  ${pc.cyan('bun run test')}     Run tests\n  ${pc.cyan('bun run lint')}     Lint the codebase\n`);\n    } catch (error) {\n      spinner.fail('Failed to initialize');\n      console.error(error);\n      process.exit(1);\n    }\n  });\n\nprogram.parse();\n"
  },
  {
    "path": "templates/basic/.github/workflows/main.yml",
    "content": "name: CI\n\non:\n  push:\n    branches: [main, master]\n  pull_request:\n    branches: [main, master]\n\njobs:\n  build:\n    name: Build, lint, and test on Node ${{ matrix.node }} and ${{ matrix.os }}\n    runs-on: ${{ matrix.os }}\n    strategy:\n      matrix:\n        node: ['20', '22']\n        os: [ubuntu-latest, windows-latest, macos-latest]\n\n    steps:\n      - name: Checkout repo\n        uses: actions/checkout@v4\n\n      - name: Setup Bun\n        uses: oven-sh/setup-bun@v2\n        with:\n          bun-version: latest\n\n      - name: Setup Node.js ${{ matrix.node }}\n        uses: actions/setup-node@v4\n        with:\n          node-version: ${{ matrix.node }}\n\n      - name: Install dependencies\n        run: bun install\n\n      - name: Lint\n        run: bun run lint\n\n      - name: Type check\n        run: bun run typecheck\n\n      - name: Test\n        run: bun run test\n\n      - name: Build\n        run: bun run build\n"
  },
  {
    "path": "templates/basic/.github/workflows/size.yml",
    "content": "name: Size\n\non:\n  pull_request:\n    branches: [main, master]\n\njobs:\n  size:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout repo\n        uses: actions/checkout@v4\n\n      - name: Setup Bun\n        uses: oven-sh/setup-bun@v2\n        with:\n          bun-version: latest\n\n      - name: Install dependencies\n        run: bun install\n\n      - name: Build\n        run: bun run build\n\n      - name: Check bundle size\n        run: |\n          echo \"📦 Bundle size:\"\n          du -sh dist/*\n"
  },
  {
    "path": "templates/basic/LICENSE",
    "content": "MIT License\n\nCopyright (c) <year> <author>\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE."
  },
  {
    "path": "templates/basic/README.md",
    "content": "# TSDX Library\n\nZero-config TypeScript package development powered by modern tools.\n\n## Quick Start\n\n```bash\n# Install dependencies\nbun install\n\n# Start development mode\nbun run dev\n\n# Build for production\nbun run build\n\n# Run tests\nbun run test\n\n# Lint code\nbun run lint\n\n# Format code\nbun run format\n```\n\n## Project Structure\n\n```\n/src\n  index.ts        # Your library entry point\n/test\n  index.test.ts   # Tests using Vitest\n.gitignore\npackage.json\nREADME.md\ntsconfig.json\nvitest.config.ts\n```\n\n## Scripts\n\n| Script | Description |\n|--------|-------------|\n| `bun run dev` | Start development mode with watch |\n| `bun run build` | Build for production |\n| `bun run test` | Run tests |\n| `bun run test:watch` | Run tests in watch mode |\n| `bun run lint` | Lint code |\n| `bun run format` | Format code |\n| `bun run format:check` | Check if code is formatted |\n| `bun run typecheck` | Run TypeScript type checking |\n\n## Tools\n\nTSDX wraps these modern, high-performance tools:\n\n- **[Bunchee](https://github.com/huozhi/bunchee)** - Zero-config bundler for npm packages\n- **[Vitest](https://vitest.dev/)** - Next-generation testing framework\n- **[Oxlint](https://oxc.rs/docs/guide/usage/linter.html)** - Rust-powered linter (50-100x faster than ESLint)\n- **[Oxfmt](https://oxc.rs/docs/guide/usage/formatter)** - Rust-powered formatter (35x faster than Prettier)\n- **[TypeScript](https://www.typescriptlang.org/)** - Type safety\n\n## Module Formats\n\nThis library exports both ESM and CommonJS formats, with full TypeScript support:\n\n- `dist/index.js` - ESM\n- `dist/index.cjs` - CommonJS\n- `dist/index.d.ts` - TypeScript declarations\n\n## Publishing\n\n```bash\n# Build the package\nbun run build\n\n# Publish to npm\nnpm publish\n```\n\nWe recommend using [np](https://github.com/sindresorhus/np) for publishing.\n\n## License\n\nMIT\n"
  },
  {
    "path": "templates/basic/gitignore",
    "content": "# Dependencies\nnode_modules\n.pnp\n.pnp.js\n\n# Build output\ndist\n*.tsbuildinfo\n\n# IDE\n.idea\n.vscode\n*.swp\n*.swo\n\n# OS\n.DS_Store\nThumbs.db\n\n# Logs\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n\n# Testing\ncoverage\n\n# Misc\n.env\n.env.local\n"
  },
  {
    "path": "templates/basic/package.json",
    "content": "{\n  \"name\": \"package-name\",\n  \"version\": \"0.1.0\",\n  \"license\": \"MIT\",\n  \"author\": \"\",\n  \"type\": \"module\",\n  \"main\": \"./dist/index.cjs\",\n  \"module\": \"./dist/index.js\",\n  \"types\": \"./dist/index.d.ts\",\n  \"exports\": {\n    \".\": {\n      \"import\": {\n        \"types\": \"./dist/index.d.ts\",\n        \"default\": \"./dist/index.js\"\n      },\n      \"require\": {\n        \"types\": \"./dist/index.d.cts\",\n        \"default\": \"./dist/index.cjs\"\n      }\n    },\n    \"./package.json\": \"./package.json\"\n  },\n  \"files\": [\n    \"dist\",\n    \"src\"\n  ],\n  \"engines\": {\n    \"node\": \">=20\"\n  },\n  \"scripts\": {\n    \"dev\": \"tsdx dev\",\n    \"build\": \"tsdx build\",\n    \"test\": \"tsdx test\",\n    \"test:watch\": \"tsdx test --watch\",\n    \"lint\": \"tsdx lint\",\n    \"format\": \"tsdx format\",\n    \"format:check\": \"tsdx format --check\",\n    \"typecheck\": \"tsdx typecheck\",\n    \"prepublishOnly\": \"bun run build\"\n  },\n  \"devDependencies\": {\n    \"@types/node\": \"^22.10.2\",\n    \"tsdx\": \"^1.0.0\",\n    \"typescript\": \"^5.7.2\"\n  }\n}\n"
  },
  {
    "path": "templates/basic/src/index.ts",
    "content": "/**\n * Adds two numbers together.\n */\nexport const sum = (a: number, b: number): number => {\n  return a + b;\n};\n"
  },
  {
    "path": "templates/basic/test/index.test.ts",
    "content": "import { describe, it, expect } from 'vitest';\nimport { sum } from '../src';\n\ndescribe('sum', () => {\n  it('adds two numbers together', () => {\n    expect(sum(1, 1)).toBe(2);\n  });\n\n  it('handles negative numbers', () => {\n    expect(sum(-1, 1)).toBe(0);\n  });\n\n  it('handles zero', () => {\n    expect(sum(0, 0)).toBe(0);\n  });\n});\n"
  },
  {
    "path": "templates/basic/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"target\": \"ES2022\",\n    \"module\": \"ESNext\",\n    \"moduleResolution\": \"bundler\",\n    \"lib\": [\"ES2022\", \"DOM\"],\n    \"strict\": true,\n    \"esModuleInterop\": true,\n    \"skipLibCheck\": true,\n    \"forceConsistentCasingInFileNames\": true,\n    \"declaration\": true,\n    \"declarationMap\": true,\n    \"outDir\": \"./dist\",\n    \"rootDir\": \"./src\",\n    \"resolveJsonModule\": true,\n    \"isolatedModules\": true,\n    \"noEmit\": true,\n    \"noUnusedLocals\": true,\n    \"noUnusedParameters\": true,\n    \"noFallthroughCasesInSwitch\": true,\n    \"noImplicitReturns\": true\n  },\n  \"include\": [\"src\"],\n  \"exclude\": [\"node_modules\", \"dist\"]\n}\n"
  },
  {
    "path": "templates/basic/vitest.config.ts",
    "content": "import { defineConfig } from 'vitest/config';\n\nexport default defineConfig({\n  test: {\n    globals: true,\n    environment: 'node',\n    include: ['test/**/*.test.ts'],\n  },\n});\n"
  },
  {
    "path": "templates/react/.github/workflows/main.yml",
    "content": "name: CI\n\non:\n  push:\n    branches: [main, master]\n  pull_request:\n    branches: [main, master]\n\njobs:\n  build:\n    name: Build, lint, and test on Node ${{ matrix.node }} and ${{ matrix.os }}\n    runs-on: ${{ matrix.os }}\n    strategy:\n      matrix:\n        node: ['20', '22']\n        os: [ubuntu-latest, windows-latest, macos-latest]\n\n    steps:\n      - name: Checkout repo\n        uses: actions/checkout@v4\n\n      - name: Setup Bun\n        uses: oven-sh/setup-bun@v2\n        with:\n          bun-version: latest\n\n      - name: Setup Node.js ${{ matrix.node }}\n        uses: actions/setup-node@v4\n        with:\n          node-version: ${{ matrix.node }}\n\n      - name: Install dependencies\n        run: bun install\n\n      - name: Lint\n        run: bun run lint\n\n      - name: Type check\n        run: bun run typecheck\n\n      - name: Test\n        run: bun run test\n\n      - name: Build\n        run: bun run build\n"
  },
  {
    "path": "templates/react/.github/workflows/size.yml",
    "content": "name: Size\n\non:\n  pull_request:\n    branches: [main, master]\n\njobs:\n  size:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout repo\n        uses: actions/checkout@v4\n\n      - name: Setup Bun\n        uses: oven-sh/setup-bun@v2\n        with:\n          bun-version: latest\n\n      - name: Install dependencies\n        run: bun install\n\n      - name: Build\n        run: bun run build\n\n      - name: Check bundle size\n        run: |\n          echo \"📦 Bundle size:\"\n          du -sh dist/*\n"
  },
  {
    "path": "templates/react/LICENSE",
    "content": "MIT License\n\nCopyright (c) <year> <author>\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE."
  },
  {
    "path": "templates/react/README.md",
    "content": "# TSDX React Component Library\n\nZero-config React component library development powered by modern tools.\n\n## Quick Start\n\n```bash\n# Install dependencies\nbun install\n\n# Start development mode\nbun run dev\n\n# Build for production\nbun run build\n\n# Run tests\nbun run test\n\n# Lint code\nbun run lint\n\n# Format code\nbun run format\n```\n\n## Project Structure\n\n```\n/src\n  index.tsx       # Your component entry point\n/test\n  index.test.tsx  # Tests using Vitest + Testing Library\n/example\n  index.tsx       # Demo app using Vite\n.gitignore\npackage.json\nREADME.md\ntsconfig.json\nvitest.config.ts\n```\n\n## Scripts\n\n| Script | Description |\n|--------|-------------|\n| `bun run dev` | Start development mode with watch |\n| `bun run build` | Build for production |\n| `bun run test` | Run tests |\n| `bun run test:watch` | Run tests in watch mode |\n| `bun run lint` | Lint code |\n| `bun run format` | Format code |\n| `bun run format:check` | Check if code is formatted |\n| `bun run typecheck` | Run TypeScript type checking |\n\n## Tools\n\nTSDX wraps these modern, high-performance tools:\n\n- **[Bunchee](https://github.com/huozhi/bunchee)** - Zero-config bundler for npm packages\n- **[Vitest](https://vitest.dev/)** - Next-generation testing framework\n- **[Testing Library](https://testing-library.com/)** - React testing utilities\n- **[Oxlint](https://oxc.rs/docs/guide/usage/linter.html)** - Rust-powered linter (50-100x faster than ESLint)\n- **[Oxfmt](https://oxc.rs/docs/guide/usage/formatter)** - Rust-powered formatter (35x faster than Prettier)\n- **[TypeScript](https://www.typescriptlang.org/)** - Type safety\n\n## Development with Example\n\nTo test your component in a real React app:\n\n```bash\n# In one terminal, start the library in watch mode\nbun run dev\n\n# In another terminal, run the example app\ncd example\nbun install\nbun run dev\n```\n\n## Module Formats\n\nThis library exports both ESM and CommonJS formats, with full TypeScript support:\n\n- `dist/index.js` - ESM\n- `dist/index.cjs` - CommonJS\n- `dist/index.d.ts` - TypeScript declarations\n\n## Publishing\n\n```bash\n# Build the package\nbun run build\n\n# Publish to npm\nnpm publish\n```\n\nWe recommend using [np](https://github.com/sindresorhus/np) for publishing.\n\n## License\n\nMIT\n"
  },
  {
    "path": "templates/react/example/index.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"UTF-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n    <title>Component Demo</title>\n  </head>\n  <body>\n    <div id=\"root\"></div>\n    <script type=\"module\" src=\"./index.tsx\"></script>\n  </body>\n</html>\n"
  },
  {
    "path": "templates/react/example/index.tsx",
    "content": "import { StrictMode } from 'react';\nimport { createRoot } from 'react-dom/client';\nimport { Thing } from '../src';\n\nconst App = () => {\n  return (\n    <div style={{ padding: '2rem', fontFamily: 'system-ui, sans-serif' }}>\n      <h1>Component Demo</h1>\n      <Thing />\n      <Thing>Custom content!</Thing>\n    </div>\n  );\n};\n\nconst root = document.getElementById('root');\nif (root) {\n  createRoot(root).render(\n    <StrictMode>\n      <App />\n    </StrictMode>\n  );\n}\n"
  },
  {
    "path": "templates/react/example/package.json",
    "content": "{\n  \"name\": \"example\",\n  \"version\": \"1.0.0\",\n  \"private\": true,\n  \"type\": \"module\",\n  \"scripts\": {\n    \"dev\": \"vite\",\n    \"build\": \"vite build\",\n    \"preview\": \"vite preview\"\n  },\n  \"dependencies\": {\n    \"react\": \"^18.3.1\",\n    \"react-dom\": \"^18.3.1\"\n  },\n  \"devDependencies\": {\n    \"@types/react\": \"^18.3.17\",\n    \"@types/react-dom\": \"^18.3.5\",\n    \"@vitejs/plugin-react\": \"^4.3.4\",\n    \"typescript\": \"^5.7.2\",\n    \"vite\": \"^6.0.5\"\n  }\n}\n"
  },
  {
    "path": "templates/react/example/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"target\": \"ES2022\",\n    \"module\": \"ESNext\",\n    \"moduleResolution\": \"bundler\",\n    \"lib\": [\"ES2022\", \"DOM\", \"DOM.Iterable\"],\n    \"jsx\": \"react-jsx\",\n    \"strict\": true,\n    \"esModuleInterop\": true,\n    \"skipLibCheck\": true,\n    \"forceConsistentCasingInFileNames\": true,\n    \"noEmit\": true\n  },\n  \"include\": [\".\"]\n}\n"
  },
  {
    "path": "templates/react/example/vite.config.ts",
    "content": "import { defineConfig } from 'vite';\nimport react from '@vitejs/plugin-react';\n\nexport default defineConfig({\n  plugins: [react()],\n});\n"
  },
  {
    "path": "templates/react/gitignore",
    "content": "# Dependencies\nnode_modules\n.pnp\n.pnp.js\n\n# Build output\ndist\n*.tsbuildinfo\n\n# IDE\n.idea\n.vscode\n*.swp\n*.swo\n\n# OS\n.DS_Store\nThumbs.db\n\n# Logs\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n\n# Testing\ncoverage\n\n# Misc\n.env\n.env.local\n.cache\n"
  },
  {
    "path": "templates/react/package.json",
    "content": "{\n  \"name\": \"package-name\",\n  \"version\": \"0.1.0\",\n  \"license\": \"MIT\",\n  \"author\": \"\",\n  \"type\": \"module\",\n  \"main\": \"./dist/index.cjs\",\n  \"module\": \"./dist/index.js\",\n  \"types\": \"./dist/index.d.ts\",\n  \"exports\": {\n    \".\": {\n      \"import\": {\n        \"types\": \"./dist/index.d.ts\",\n        \"default\": \"./dist/index.js\"\n      },\n      \"require\": {\n        \"types\": \"./dist/index.d.cts\",\n        \"default\": \"./dist/index.cjs\"\n      }\n    },\n    \"./package.json\": \"./package.json\"\n  },\n  \"files\": [\n    \"dist\",\n    \"src\"\n  ],\n  \"engines\": {\n    \"node\": \">=20\"\n  },\n  \"scripts\": {\n    \"dev\": \"tsdx dev\",\n    \"build\": \"tsdx build\",\n    \"test\": \"tsdx test\",\n    \"test:watch\": \"tsdx test --watch\",\n    \"lint\": \"tsdx lint\",\n    \"format\": \"tsdx format\",\n    \"format:check\": \"tsdx format --check\",\n    \"typecheck\": \"tsdx typecheck\",\n    \"prepublishOnly\": \"bun run build\"\n  },\n  \"peerDependencies\": {\n    \"react\": \">=18\",\n    \"react-dom\": \">=18\"\n  },\n  \"devDependencies\": {\n    \"@testing-library/react\": \"^16.1.0\",\n    \"@types/node\": \"^22.10.2\",\n    \"@types/react\": \"^18.3.17\",\n    \"@types/react-dom\": \"^18.3.5\",\n    \"jsdom\": \"^25.0.1\",\n    \"react\": \"^18.3.1\",\n    \"react-dom\": \"^18.3.1\",\n    \"tsdx\": \"^1.0.0\",\n    \"typescript\": \"^5.7.2\"\n  }\n}\n"
  },
  {
    "path": "templates/react/src/index.tsx",
    "content": "import type { ReactNode } from 'react';\n\nexport interface ThingProps {\n  children?: ReactNode;\n}\n\nexport const Thing = ({ children }: ThingProps) => {\n  return (\n    <div>\n      {children ?? 'the snozzberries taste like snozzberries'}\n    </div>\n  );\n};\n"
  },
  {
    "path": "templates/react/test/index.test.tsx",
    "content": "import { describe, it, expect } from 'vitest';\nimport { render, screen } from '@testing-library/react';\nimport { Thing } from '../src';\n\ndescribe('Thing', () => {\n  it('renders without crashing', () => {\n    render(<Thing />);\n    expect(screen.getByText(/snozzberries/)).toBeDefined();\n  });\n\n  it('renders children when provided', () => {\n    render(<Thing>Hello World</Thing>);\n    expect(screen.getByText('Hello World')).toBeDefined();\n  });\n});\n"
  },
  {
    "path": "templates/react/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"target\": \"ES2022\",\n    \"module\": \"ESNext\",\n    \"moduleResolution\": \"bundler\",\n    \"lib\": [\"ES2022\", \"DOM\", \"DOM.Iterable\"],\n    \"jsx\": \"react-jsx\",\n    \"strict\": true,\n    \"esModuleInterop\": true,\n    \"skipLibCheck\": true,\n    \"forceConsistentCasingInFileNames\": true,\n    \"declaration\": true,\n    \"declarationMap\": true,\n    \"outDir\": \"./dist\",\n    \"rootDir\": \"./src\",\n    \"resolveJsonModule\": true,\n    \"isolatedModules\": true,\n    \"noEmit\": true,\n    \"noUnusedLocals\": true,\n    \"noUnusedParameters\": true,\n    \"noFallthroughCasesInSwitch\": true,\n    \"noImplicitReturns\": true\n  },\n  \"include\": [\"src\"],\n  \"exclude\": [\"node_modules\", \"dist\", \"example\"]\n}\n"
  },
  {
    "path": "templates/react/vitest.config.ts",
    "content": "import { defineConfig } from 'vitest/config';\n\nexport default defineConfig({\n  test: {\n    globals: true,\n    environment: 'jsdom',\n    include: ['test/**/*.test.{ts,tsx}'],\n  },\n});\n"
  },
  {
    "path": "test/cli.test.ts",
    "content": "import { describe, it, expect } from 'vitest';\nimport { execSync } from 'child_process';\nimport path from 'path';\n\nconst CLI_PATH = path.resolve(__dirname, '../dist/index.js');\n\ndescribe('tsdx CLI', () => {\n  it('should display help', () => {\n    const output = execSync(`node ${CLI_PATH} --help`, { encoding: 'utf-8' });\n    expect(output).toContain('Zero-config TypeScript package development');\n  });\n\n  it('should display version', () => {\n    const output = execSync(`node ${CLI_PATH} --version`, { encoding: 'utf-8' });\n    expect(output).toMatch(/\\d+\\.\\d+\\.\\d+/);\n  });\n\n  it('should list commands', () => {\n    const output = execSync(`node ${CLI_PATH} --help`, { encoding: 'utf-8' });\n    expect(output).toContain('create');\n    expect(output).toContain('build');\n    expect(output).toContain('dev');\n    expect(output).toContain('test');\n    expect(output).toContain('lint');\n    expect(output).toContain('format');\n  });\n});\n"
  },
  {
    "path": "test/e2e.test.ts",
    "content": "import { describe, it, expect, beforeAll, afterAll, beforeEach, afterEach } from 'vitest';\nimport { execSync, spawn, ChildProcess } from 'child_process';\nimport path from 'path';\nimport fs from 'fs-extra';\nimport os from 'os';\n\n// Path to the built CLI\nconst CLI_PATH = path.resolve(__dirname, '../dist/index.js');\nconst TEMPLATES_PATH = path.resolve(__dirname, '../templates');\n\n// Timeout for long-running operations\nconst LONG_TIMEOUT = 60000;\n\n// Helper to run CLI commands\nfunction runCLI(args: string, options: { cwd?: string; timeout?: number } = {}): string {\n  const { cwd = process.cwd(), timeout = 30000 } = options;\n  return execSync(`node ${CLI_PATH} ${args}`, {\n    encoding: 'utf-8',\n    cwd,\n    timeout,\n    env: { ...process.env, FORCE_COLOR: '0' },\n  });\n}\n\n// Helper to run CLI and get exit code\nfunction runCLIWithExitCode(\n  args: string,\n  options: { cwd?: string; timeout?: number } = {}\n): { stdout: string; stderr: string; exitCode: number } {\n  const { cwd = process.cwd(), timeout = 30000 } = options;\n  try {\n    const stdout = execSync(`node ${CLI_PATH} ${args}`, {\n      encoding: 'utf-8',\n      cwd,\n      timeout,\n      env: { ...process.env, FORCE_COLOR: '0' },\n      stdio: ['pipe', 'pipe', 'pipe'],\n    });\n    return { stdout, stderr: '', exitCode: 0 };\n  } catch (error: unknown) {\n    const execError = error as { stdout?: string; stderr?: string; status?: number };\n    return {\n      stdout: execError.stdout || '',\n      stderr: execError.stderr || '',\n      exitCode: execError.status ?? 1,\n    };\n  }\n}\n\n// Helper to create a temp directory\nfunction createTempDir(prefix: string): string {\n  return fs.mkdtempSync(path.join(os.tmpdir(), `tsdx-test-${prefix}-`));\n}\n\n// ============================================================================\n// CLI BASIC TESTS\n// ============================================================================\n\ndescribe('CLI Basics', () => {\n  it('should display help with --help flag', () => {\n    const output = runCLI('--help');\n    expect(output).toContain('Zero-config TypeScript package development');\n    expect(output).toContain('Usage:');\n    expect(output).toContain('Commands:');\n  });\n\n  it('should display help with -h flag', () => {\n    const output = runCLI('-h');\n    expect(output).toContain('Zero-config TypeScript package development');\n  });\n\n  it('should display version with --version flag', () => {\n    const output = runCLI('--version');\n    expect(output.trim()).toMatch(/^\\d+\\.\\d+\\.\\d+$/);\n  });\n\n  it('should display version with -V flag', () => {\n    const output = runCLI('-V');\n    expect(output.trim()).toMatch(/^\\d+\\.\\d+\\.\\d+$/);\n  });\n\n  it('should list all available commands', () => {\n    const output = runCLI('--help');\n    expect(output).toContain('create');\n    expect(output).toContain('build');\n    expect(output).toContain('dev');\n    expect(output).toContain('test');\n    expect(output).toContain('lint');\n    expect(output).toContain('format');\n    expect(output).toContain('typecheck');\n    expect(output).toContain('init');\n  });\n\n  it('should show command-specific help for create', () => {\n    const output = runCLI('create --help');\n    expect(output).toContain('Create a new TypeScript package');\n    expect(output).toContain('--template');\n    expect(output).toContain('-t');\n  });\n\n  it('should show command-specific help for build', () => {\n    const output = runCLI('build --help');\n    expect(output).toContain('Build the package for production');\n    expect(output).toContain('--no-clean');\n  });\n\n  it('should show command-specific help for test', () => {\n    const output = runCLI('test --help');\n    expect(output).toContain('Run tests with vitest');\n    expect(output).toContain('--watch');\n    expect(output).toContain('--coverage');\n    expect(output).toContain('--update');\n  });\n\n  it('should show command-specific help for lint', () => {\n    const output = runCLI('lint --help');\n    expect(output).toContain('Lint the codebase with oxlint');\n    expect(output).toContain('--fix');\n    expect(output).toContain('--config');\n  });\n\n  it('should show command-specific help for format', () => {\n    const output = runCLI('format --help');\n    expect(output).toContain('Format the codebase with oxfmt');\n    expect(output).toContain('--check');\n  });\n\n  it('should show command-specific help for typecheck', () => {\n    const output = runCLI('typecheck --help');\n    expect(output).toContain('Run TypeScript type checking');\n    expect(output).toContain('--watch');\n  });\n\n  it('should show command-specific help for init', () => {\n    const output = runCLI('init --help');\n    expect(output).toContain('Initialize tsdx configuration');\n  });\n\n  it('should show dev command with watch alias', () => {\n    const output = runCLI('dev --help');\n    expect(output).toContain('Start development mode with watch');\n  });\n});\n\n// ============================================================================\n// CREATE COMMAND TESTS\n// ============================================================================\n\ndescribe('Create Command', () => {\n  let tempDir: string;\n\n  beforeEach(() => {\n    tempDir = createTempDir('create');\n  });\n\n  afterEach(async () => {\n    await fs.remove(tempDir);\n  });\n\n  describe('Basic Template', () => {\n    it('should create project directory structure', () => {\n      const projectName = 'my-lib';\n      const projectPath = path.join(tempDir, projectName);\n\n      // Run create with --template to skip interactive prompt\n      // Note: This will fail at bun install in CI, but the files should be created\n      try {\n        runCLI(`create ${projectName} --template basic`, { cwd: tempDir, timeout: LONG_TIMEOUT });\n      } catch {\n        // Expected to fail at bun install in CI environment\n      }\n\n      // Verify project structure was created\n      expect(fs.existsSync(projectPath)).toBe(true);\n      expect(fs.existsSync(path.join(projectPath, 'package.json'))).toBe(true);\n      expect(fs.existsSync(path.join(projectPath, 'tsconfig.json'))).toBe(true);\n      expect(fs.existsSync(path.join(projectPath, 'src', 'index.ts'))).toBe(true);\n      expect(fs.existsSync(path.join(projectPath, 'test', 'index.test.ts'))).toBe(true);\n      expect(fs.existsSync(path.join(projectPath, 'vitest.config.ts'))).toBe(true);\n    });\n\n    it('should set project name in package.json when git author is available', () => {\n      const projectName = 'my-awesome-lib';\n      const projectPath = path.join(tempDir, projectName);\n\n      try {\n        runCLI(`create ${projectName} --template basic`, { cwd: tempDir, timeout: LONG_TIMEOUT });\n      } catch {\n        // Expected to fail at bun install or author prompt in non-TTY\n      }\n\n      const pkgJson = fs.readJSONSync(path.join(projectPath, 'package.json'));\n      // In CI without TTY, the author prompt may fail before package.json is updated\n      // So we check that either the name was updated OR the template default is present\n      expect(['package-name', projectName]).toContain(pkgJson.name);\n    });\n\n    it('should rename gitignore to .gitignore', () => {\n      const projectName = 'gitignore-test';\n      const projectPath = path.join(tempDir, projectName);\n\n      try {\n        runCLI(`create ${projectName} --template basic`, { cwd: tempDir, timeout: LONG_TIMEOUT });\n      } catch {\n        // Expected to fail at bun install\n      }\n\n      expect(fs.existsSync(path.join(projectPath, '.gitignore'))).toBe(true);\n      expect(fs.existsSync(path.join(projectPath, 'gitignore'))).toBe(false);\n    });\n\n    it('should include tsdx scripts in package.json', () => {\n      const projectName = 'scripts-test';\n      const projectPath = path.join(tempDir, projectName);\n\n      try {\n        runCLI(`create ${projectName} --template basic`, { cwd: tempDir, timeout: LONG_TIMEOUT });\n      } catch {\n        // Expected to fail at bun install\n      }\n\n      const pkgJson = fs.readJSONSync(path.join(projectPath, 'package.json'));\n      expect(pkgJson.scripts.dev).toBe('tsdx dev');\n      expect(pkgJson.scripts.build).toBe('tsdx build');\n      expect(pkgJson.scripts.test).toBe('tsdx test');\n      expect(pkgJson.scripts.lint).toBe('tsdx lint');\n      expect(pkgJson.scripts.format).toBe('tsdx format');\n      expect(pkgJson.scripts.typecheck).toBe('tsdx typecheck');\n    });\n\n    it('should have tsdx as devDependency', () => {\n      const projectName = 'deps-test';\n      const projectPath = path.join(tempDir, projectName);\n\n      try {\n        runCLI(`create ${projectName} --template basic`, { cwd: tempDir, timeout: LONG_TIMEOUT });\n      } catch {\n        // Expected to fail at bun install\n      }\n\n      const pkgJson = fs.readJSONSync(path.join(projectPath, 'package.json'));\n      expect(pkgJson.devDependencies.tsdx).toBeDefined();\n    });\n\n    it('should have correct exports configuration', () => {\n      const projectName = 'exports-test';\n      const projectPath = path.join(tempDir, projectName);\n\n      try {\n        runCLI(`create ${projectName} --template basic`, { cwd: tempDir, timeout: LONG_TIMEOUT });\n      } catch {\n        // Expected to fail at bun install\n      }\n\n      const pkgJson = fs.readJSONSync(path.join(projectPath, 'package.json'));\n      expect(pkgJson.type).toBe('module');\n      expect(pkgJson.main).toBe('./dist/index.cjs');\n      expect(pkgJson.module).toBe('./dist/index.js');\n      expect(pkgJson.types).toBe('./dist/index.d.ts');\n      expect(pkgJson.exports['.']).toBeDefined();\n    });\n\n    it('should include LICENSE file', () => {\n      const projectName = 'license-test';\n      const projectPath = path.join(tempDir, projectName);\n      const currentYear = new Date().getFullYear().toString();\n\n      try {\n        runCLI(`create ${projectName} --template basic`, { cwd: tempDir, timeout: LONG_TIMEOUT });\n      } catch {\n        // Expected to fail at bun install or author prompt in non-TTY\n      }\n\n      expect(fs.existsSync(path.join(projectPath, 'LICENSE'))).toBe(true);\n      const license = fs.readFileSync(path.join(projectPath, 'LICENSE'), 'utf-8');\n      // In CI without TTY, the author prompt may fail before LICENSE is updated\n      // So we check that either the year was updated OR the template placeholder is present\n      expect(license).toMatch(new RegExp(`(${currentYear}|<year>)`));\n    });\n\n    it('should include README.md', () => {\n      const projectName = 'readme-test';\n      const projectPath = path.join(tempDir, projectName);\n\n      try {\n        runCLI(`create ${projectName} --template basic`, { cwd: tempDir, timeout: LONG_TIMEOUT });\n      } catch {\n        // Expected to fail at bun install\n      }\n\n      expect(fs.existsSync(path.join(projectPath, 'README.md'))).toBe(true);\n      const readme = fs.readFileSync(path.join(projectPath, 'README.md'), 'utf-8');\n      expect(readme).toContain('TSDX');\n    });\n\n    it('should include GitHub workflows', () => {\n      const projectName = 'workflows-test';\n      const projectPath = path.join(tempDir, projectName);\n\n      try {\n        runCLI(`create ${projectName} --template basic`, { cwd: tempDir, timeout: LONG_TIMEOUT });\n      } catch {\n        // Expected to fail at bun install\n      }\n\n      expect(fs.existsSync(path.join(projectPath, '.github', 'workflows', 'main.yml'))).toBe(true);\n      expect(fs.existsSync(path.join(projectPath, '.github', 'workflows', 'size.yml'))).toBe(true);\n    });\n  });\n\n  describe('React Template', () => {\n    it('should create project with React structure', () => {\n      const projectName = 'my-react-lib';\n      const projectPath = path.join(tempDir, projectName);\n\n      try {\n        runCLI(`create ${projectName} --template react`, { cwd: tempDir, timeout: LONG_TIMEOUT });\n      } catch {\n        // Expected to fail at bun install\n      }\n\n      // Verify React-specific structure\n      expect(fs.existsSync(projectPath)).toBe(true);\n      expect(fs.existsSync(path.join(projectPath, 'src', 'index.tsx'))).toBe(true);\n      expect(fs.existsSync(path.join(projectPath, 'test', 'index.test.tsx'))).toBe(true);\n    });\n\n    it('should have React peer dependencies', () => {\n      const projectName = 'react-peers-test';\n      const projectPath = path.join(tempDir, projectName);\n\n      try {\n        runCLI(`create ${projectName} --template react`, { cwd: tempDir, timeout: LONG_TIMEOUT });\n      } catch {\n        // Expected to fail at bun install\n      }\n\n      const pkgJson = fs.readJSONSync(path.join(projectPath, 'package.json'));\n      expect(pkgJson.peerDependencies.react).toBeDefined();\n      expect(pkgJson.peerDependencies['react-dom']).toBeDefined();\n    });\n\n    it('should have React dev dependencies', () => {\n      const projectName = 'react-deps-test';\n      const projectPath = path.join(tempDir, projectName);\n\n      try {\n        runCLI(`create ${projectName} --template react`, { cwd: tempDir, timeout: LONG_TIMEOUT });\n      } catch {\n        // Expected to fail at bun install\n      }\n\n      const pkgJson = fs.readJSONSync(path.join(projectPath, 'package.json'));\n      expect(pkgJson.devDependencies.react).toBeDefined();\n      expect(pkgJson.devDependencies['react-dom']).toBeDefined();\n      expect(pkgJson.devDependencies['@types/react']).toBeDefined();\n      expect(pkgJson.devDependencies['@testing-library/react']).toBeDefined();\n    });\n\n    it('should have jsdom for React testing', () => {\n      const projectName = 'react-jsdom-test';\n      const projectPath = path.join(tempDir, projectName);\n\n      try {\n        runCLI(`create ${projectName} --template react`, { cwd: tempDir, timeout: LONG_TIMEOUT });\n      } catch {\n        // Expected to fail at bun install\n      }\n\n      const pkgJson = fs.readJSONSync(path.join(projectPath, 'package.json'));\n      expect(pkgJson.devDependencies.jsdom).toBeDefined();\n    });\n\n    it('should include example app', () => {\n      const projectName = 'react-example-test';\n      const projectPath = path.join(tempDir, projectName);\n\n      try {\n        runCLI(`create ${projectName} --template react`, { cwd: tempDir, timeout: LONG_TIMEOUT });\n      } catch {\n        // Expected to fail at bun install\n      }\n\n      expect(fs.existsSync(path.join(projectPath, 'example'))).toBe(true);\n      expect(fs.existsSync(path.join(projectPath, 'example', 'package.json'))).toBe(true);\n      expect(fs.existsSync(path.join(projectPath, 'example', 'index.tsx'))).toBe(true);\n      expect(fs.existsSync(path.join(projectPath, 'example', 'index.html'))).toBe(true);\n      expect(fs.existsSync(path.join(projectPath, 'example', 'vite.config.ts'))).toBe(true);\n    });\n  });\n\n  describe('Error Handling', () => {\n    it('should fail if directory already exists', () => {\n      const projectName = 'existing-dir';\n      const projectPath = path.join(tempDir, projectName);\n\n      // Create the directory first\n      fs.mkdirSync(projectPath);\n\n      const result = runCLIWithExitCode(`create ${projectName} --template basic`, {\n        cwd: tempDir,\n        timeout: LONG_TIMEOUT,\n      });\n\n      expect(result.exitCode).not.toBe(0);\n    });\n  });\n});\n\n// ============================================================================\n// INIT COMMAND TESTS\n// ============================================================================\n\ndescribe('Init Command', () => {\n  let tempDir: string;\n\n  beforeEach(() => {\n    tempDir = createTempDir('init');\n  });\n\n  afterEach(async () => {\n    await fs.remove(tempDir);\n  });\n\n  it('should fail if no package.json exists', () => {\n    const result = runCLIWithExitCode('init', { cwd: tempDir });\n    expect(result.exitCode).not.toBe(0);\n  });\n\n  it('should add tsdx configuration to existing package.json', () => {\n    // Create a minimal package.json\n    const pkgJson = {\n      name: 'existing-project',\n      version: '1.0.0',\n      scripts: {\n        existing: 'echo existing',\n      },\n    };\n    fs.writeJSONSync(path.join(tempDir, 'package.json'), pkgJson, { spaces: 2 });\n\n    runCLI('init', { cwd: tempDir });\n\n    const updatedPkgJson = fs.readJSONSync(path.join(tempDir, 'package.json'));\n\n    // Should have new scripts\n    expect(updatedPkgJson.scripts.dev).toBe('bunchee --watch');\n    expect(updatedPkgJson.scripts.build).toBe('bunchee');\n    expect(updatedPkgJson.scripts.test).toBe('vitest run');\n    expect(updatedPkgJson.scripts.lint).toBe('oxlint');\n    expect(updatedPkgJson.scripts.format).toBe('oxfmt --write .');\n    expect(updatedPkgJson.scripts.typecheck).toBe('tsc --noEmit');\n\n    // Should preserve existing scripts\n    expect(updatedPkgJson.scripts.existing).toBe('echo existing');\n  });\n\n  it('should add ESM configuration', () => {\n    fs.writeJSONSync(path.join(tempDir, 'package.json'), { name: 'test' }, { spaces: 2 });\n\n    runCLI('init', { cwd: tempDir });\n\n    const pkgJson = fs.readJSONSync(path.join(tempDir, 'package.json'));\n    expect(pkgJson.type).toBe('module');\n    expect(pkgJson.main).toBe('./dist/index.cjs');\n    expect(pkgJson.module).toBe('./dist/index.js');\n    expect(pkgJson.types).toBe('./dist/index.d.ts');\n  });\n\n  it('should add exports field', () => {\n    fs.writeJSONSync(path.join(tempDir, 'package.json'), { name: 'test' }, { spaces: 2 });\n\n    runCLI('init', { cwd: tempDir });\n\n    const pkgJson = fs.readJSONSync(path.join(tempDir, 'package.json'));\n    expect(pkgJson.exports['.']).toBeDefined();\n    expect(pkgJson.exports['.'].import).toBe('./dist/index.js');\n    expect(pkgJson.exports['.'].require).toBe('./dist/index.cjs');\n    expect(pkgJson.exports['./package.json']).toBe('./package.json');\n  });\n\n  it('should create tsconfig.json if it does not exist', () => {\n    fs.writeJSONSync(path.join(tempDir, 'package.json'), { name: 'test' }, { spaces: 2 });\n\n    runCLI('init', { cwd: tempDir });\n\n    expect(fs.existsSync(path.join(tempDir, 'tsconfig.json'))).toBe(true);\n\n    const tsconfig = fs.readJSONSync(path.join(tempDir, 'tsconfig.json'));\n    expect(tsconfig.compilerOptions.target).toBe('ES2022');\n    expect(tsconfig.compilerOptions.module).toBe('ESNext');\n    expect(tsconfig.compilerOptions.strict).toBe(true);\n    expect(tsconfig.compilerOptions.declaration).toBe(true);\n  });\n\n  it('should not overwrite existing tsconfig.json', () => {\n    const existingTsconfig = {\n      compilerOptions: {\n        target: 'ES2020',\n        custom: 'option',\n      },\n    };\n    fs.writeJSONSync(path.join(tempDir, 'package.json'), { name: 'test' }, { spaces: 2 });\n    fs.writeJSONSync(path.join(tempDir, 'tsconfig.json'), existingTsconfig, { spaces: 2 });\n\n    runCLI('init', { cwd: tempDir });\n\n    const tsconfig = fs.readJSONSync(path.join(tempDir, 'tsconfig.json'));\n    expect(tsconfig.compilerOptions.target).toBe('ES2020');\n    expect(tsconfig.compilerOptions.custom).toBe('option');\n  });\n\n  it('should create vitest.config.ts if it does not exist', () => {\n    fs.writeJSONSync(path.join(tempDir, 'package.json'), { name: 'test' }, { spaces: 2 });\n\n    runCLI('init', { cwd: tempDir });\n\n    expect(fs.existsSync(path.join(tempDir, 'vitest.config.ts'))).toBe(true);\n\n    const vitestConfig = fs.readFileSync(path.join(tempDir, 'vitest.config.ts'), 'utf-8');\n    expect(vitestConfig).toContain('defineConfig');\n    expect(vitestConfig).toContain('globals: true');\n  });\n\n  it('should not overwrite existing vitest.config.ts', () => {\n    const existingConfig = 'export default { custom: true };';\n    fs.writeJSONSync(path.join(tempDir, 'package.json'), { name: 'test' }, { spaces: 2 });\n    fs.writeFileSync(path.join(tempDir, 'vitest.config.ts'), existingConfig);\n\n    runCLI('init', { cwd: tempDir });\n\n    const vitestConfig = fs.readFileSync(path.join(tempDir, 'vitest.config.ts'), 'utf-8');\n    expect(vitestConfig).toBe(existingConfig);\n  });\n\n  it('should not overwrite existing exports field', () => {\n    const pkgJson = {\n      name: 'test',\n      exports: {\n        '.': './custom-entry.js',\n      },\n    };\n    fs.writeJSONSync(path.join(tempDir, 'package.json'), pkgJson, { spaces: 2 });\n\n    runCLI('init', { cwd: tempDir });\n\n    const updatedPkgJson = fs.readJSONSync(path.join(tempDir, 'package.json'));\n    expect(updatedPkgJson.exports['.']).toBe('./custom-entry.js');\n  });\n});\n\n// ============================================================================\n// TEMPLATE STRUCTURE VALIDATION\n// ============================================================================\n\ndescribe('Template Validation', () => {\n  describe('Basic Template', () => {\n    const templatePath = path.join(TEMPLATES_PATH, 'basic');\n\n    it('should have valid package.json', () => {\n      const pkgJson = fs.readJSONSync(path.join(templatePath, 'package.json'));\n      expect(pkgJson.type).toBe('module');\n      expect(pkgJson.scripts).toBeDefined();\n      expect(pkgJson.devDependencies).toBeDefined();\n    });\n\n    it('should have valid tsconfig.json', () => {\n      const tsconfig = fs.readJSONSync(path.join(templatePath, 'tsconfig.json'));\n      expect(tsconfig.compilerOptions).toBeDefined();\n      expect(tsconfig.compilerOptions.strict).toBe(true);\n    });\n\n    it('should have valid vitest.config.ts', () => {\n      expect(fs.existsSync(path.join(templatePath, 'vitest.config.ts'))).toBe(true);\n    });\n\n    it('should have source entry point', () => {\n      expect(fs.existsSync(path.join(templatePath, 'src', 'index.ts'))).toBe(true);\n    });\n\n    it('should have test file', () => {\n      expect(fs.existsSync(path.join(templatePath, 'test', 'index.test.ts'))).toBe(true);\n    });\n\n    it('should have gitignore (to be renamed)', () => {\n      expect(fs.existsSync(path.join(templatePath, 'gitignore'))).toBe(true);\n    });\n\n    it('should have LICENSE template', () => {\n      expect(fs.existsSync(path.join(templatePath, 'LICENSE'))).toBe(true);\n      const license = fs.readFileSync(path.join(templatePath, 'LICENSE'), 'utf-8');\n      expect(license).toContain('<year>');\n      expect(license).toContain('<author>');\n    });\n\n    it('should have README.md', () => {\n      expect(fs.existsSync(path.join(templatePath, 'README.md'))).toBe(true);\n    });\n\n    it('should have GitHub workflows', () => {\n      expect(fs.existsSync(path.join(templatePath, '.github', 'workflows', 'main.yml'))).toBe(true);\n      expect(fs.existsSync(path.join(templatePath, '.github', 'workflows', 'size.yml'))).toBe(true);\n    });\n\n    it('source code should export a function', () => {\n      const source = fs.readFileSync(path.join(templatePath, 'src', 'index.ts'), 'utf-8');\n      expect(source).toContain('export');\n    });\n\n    it('tests should import from source', () => {\n      const test = fs.readFileSync(path.join(templatePath, 'test', 'index.test.ts'), 'utf-8');\n      expect(test).toContain(\"from '../src'\");\n    });\n  });\n\n  describe('React Template', () => {\n    const templatePath = path.join(TEMPLATES_PATH, 'react');\n\n    it('should have valid package.json with React dependencies', () => {\n      const pkgJson = fs.readJSONSync(path.join(templatePath, 'package.json'));\n      expect(pkgJson.peerDependencies.react).toBeDefined();\n      expect(pkgJson.devDependencies.react).toBeDefined();\n      expect(pkgJson.devDependencies['@testing-library/react']).toBeDefined();\n    });\n\n    it('should have valid tsconfig.json with JSX support', () => {\n      const tsconfig = fs.readJSONSync(path.join(templatePath, 'tsconfig.json'));\n      expect(tsconfig.compilerOptions.jsx).toBeDefined();\n    });\n\n    it('should have vitest.config.ts with jsdom', () => {\n      const config = fs.readFileSync(path.join(templatePath, 'vitest.config.ts'), 'utf-8');\n      expect(config).toContain('jsdom');\n    });\n\n    it('should have TSX source entry point', () => {\n      expect(fs.existsSync(path.join(templatePath, 'src', 'index.tsx'))).toBe(true);\n    });\n\n    it('should have TSX test file', () => {\n      expect(fs.existsSync(path.join(templatePath, 'test', 'index.test.tsx'))).toBe(true);\n    });\n\n    it('source should export a React component', () => {\n      const source = fs.readFileSync(path.join(templatePath, 'src', 'index.tsx'), 'utf-8');\n      expect(source).toContain('export');\n      expect(source).toMatch(/React|ReactNode|<\\w+/);\n    });\n\n    it('tests should use Testing Library', () => {\n      const test = fs.readFileSync(path.join(templatePath, 'test', 'index.test.tsx'), 'utf-8');\n      expect(test).toContain('@testing-library/react');\n      expect(test).toContain('render');\n    });\n\n    it('should have example app with Vite', () => {\n      const examplePath = path.join(templatePath, 'example');\n      expect(fs.existsSync(path.join(examplePath, 'package.json'))).toBe(true);\n      expect(fs.existsSync(path.join(examplePath, 'vite.config.ts'))).toBe(true);\n      expect(fs.existsSync(path.join(examplePath, 'index.html'))).toBe(true);\n      expect(fs.existsSync(path.join(examplePath, 'index.tsx'))).toBe(true);\n    });\n\n    it('example app should have vite dependency', () => {\n      const examplePkgJson = fs.readJSONSync(path.join(templatePath, 'example', 'package.json'));\n      expect(examplePkgJson.devDependencies.vite).toBeDefined();\n    });\n  });\n});\n\n// ============================================================================\n// BUILD COMMAND TESTS (using templates directory)\n// ============================================================================\n\ndescribe('Build Command', () => {\n  let tempDir: string;\n\n  beforeEach(() => {\n    tempDir = createTempDir('build');\n  });\n\n  afterEach(async () => {\n    await fs.remove(tempDir);\n  });\n\n  it('should show help for build command', () => {\n    const output = runCLI('build --help');\n    expect(output).toContain('Build the package for production');\n    expect(output).toContain('--no-clean');\n  });\n\n  it('should fail gracefully without bunchee installed', () => {\n    // Create minimal project structure\n    fs.writeJSONSync(\n      path.join(tempDir, 'package.json'),\n      {\n        name: 'test',\n        type: 'module',\n        exports: { '.': './dist/index.js' },\n      },\n      { spaces: 2 }\n    );\n    fs.mkdirSync(path.join(tempDir, 'src'));\n    fs.writeFileSync(path.join(tempDir, 'src', 'index.ts'), 'export const x = 1;');\n\n    const result = runCLIWithExitCode('build', { cwd: tempDir });\n    // Should fail because bunchee is not installed\n    expect(result.exitCode).not.toBe(0);\n  });\n\n  it('should clean dist folder by default (when it exists)', () => {\n    // Create a project with an existing dist folder\n    fs.writeJSONSync(\n      path.join(tempDir, 'package.json'),\n      { name: 'test', type: 'module' },\n      { spaces: 2 }\n    );\n    fs.mkdirSync(path.join(tempDir, 'dist'));\n    fs.writeFileSync(path.join(tempDir, 'dist', 'old-file.js'), 'old content');\n    fs.mkdirSync(path.join(tempDir, 'src'));\n    fs.writeFileSync(path.join(tempDir, 'src', 'index.ts'), 'export const x = 1;');\n\n    // Build will fail because bunchee isn't installed, but dist should be cleaned first\n    runCLIWithExitCode('build', { cwd: tempDir });\n\n    // Dist folder should be cleaned\n    expect(fs.existsSync(path.join(tempDir, 'dist', 'old-file.js'))).toBe(false);\n  });\n});\n\n// ============================================================================\n// TEST COMMAND TESTS\n// ============================================================================\n\ndescribe('Test Command', () => {\n  it('should show help for test command', () => {\n    const output = runCLI('test --help');\n    expect(output).toContain('Run tests with vitest');\n    expect(output).toContain('-w, --watch');\n    expect(output).toContain('-c, --coverage');\n    expect(output).toContain('-u, --update');\n  });\n});\n\n// ============================================================================\n// LINT COMMAND TESTS\n// ============================================================================\n\ndescribe('Lint Command', () => {\n  let tempDir: string;\n\n  beforeEach(() => {\n    tempDir = createTempDir('lint');\n  });\n\n  afterEach(async () => {\n    await fs.remove(tempDir);\n  });\n\n  it('should show help for lint command', () => {\n    const output = runCLI('lint --help');\n    expect(output).toContain('Lint the codebase with oxlint');\n    expect(output).toContain('-f, --fix');\n    expect(output).toContain('--config');\n  });\n\n  it('should handle missing paths gracefully', () => {\n    // Create a project without src or test directories\n    fs.writeJSONSync(path.join(tempDir, 'package.json'), { name: 'test' }, { spaces: 2 });\n\n    // Should not error, just report no valid paths\n    const output = runCLI('lint', { cwd: tempDir });\n    expect(output).toContain('No valid paths to lint');\n  });\n\n  it('should lint existing directories', () => {\n    fs.writeJSONSync(path.join(tempDir, 'package.json'), { name: 'test' }, { spaces: 2 });\n    fs.mkdirSync(path.join(tempDir, 'src'));\n    fs.writeFileSync(path.join(tempDir, 'src', 'index.ts'), 'export const x = 1;');\n\n    // Should succeed with valid TypeScript code\n    const result = runCLIWithExitCode('lint', { cwd: tempDir });\n    // oxlint should run successfully (may return 0 for clean code or non-zero for issues)\n    // The key is that it doesn't crash - it runs the linter\n    expect(result.exitCode).toBeDefined();\n  });\n\n  it('should accept custom paths', () => {\n    fs.writeJSONSync(path.join(tempDir, 'package.json'), { name: 'test' }, { spaces: 2 });\n    fs.mkdirSync(path.join(tempDir, 'lib'));\n    fs.writeFileSync(path.join(tempDir, 'lib', 'index.ts'), 'export const x = 1;');\n\n    // Should run lint on the custom path\n    const result = runCLIWithExitCode('lint lib', { cwd: tempDir });\n    expect(result.exitCode).toBeDefined();\n  });\n});\n\n// ============================================================================\n// FORMAT COMMAND TESTS\n// ============================================================================\n\ndescribe('Format Command', () => {\n  it('should show help for format command', () => {\n    const output = runCLI('format --help');\n    expect(output).toContain('Format the codebase with oxfmt');\n    expect(output).toContain('-c, --check');\n  });\n});\n\n// ============================================================================\n// TYPECHECK COMMAND TESTS\n// ============================================================================\n\ndescribe('Typecheck Command', () => {\n  it('should show help for typecheck command', () => {\n    const output = runCLI('typecheck --help');\n    expect(output).toContain('Run TypeScript type checking');\n    expect(output).toContain('-w, --watch');\n  });\n});\n\n// ============================================================================\n// DEV COMMAND TESTS\n// ============================================================================\n\ndescribe('Dev Command', () => {\n  it('should show help for dev command', () => {\n    const output = runCLI('dev --help');\n    expect(output).toContain('Start development mode with watch');\n  });\n\n  it('should have watch as alias', () => {\n    const output = runCLI('watch --help');\n    expect(output).toContain('Start development mode with watch');\n  });\n});\n\n// ============================================================================\n// INTEGRATION TESTS - Full Workflow\n// ============================================================================\n\ndescribe('Integration: Full Workflow', () => {\n  let tempDir: string;\n\n  beforeAll(() => {\n    tempDir = createTempDir('integration');\n  });\n\n  afterAll(async () => {\n    await fs.remove(tempDir);\n  });\n\n  it('should create a complete project structure', () => {\n    const projectName = 'integration-test';\n    const projectPath = path.join(tempDir, projectName);\n\n    try {\n      runCLI(`create ${projectName} --template basic`, { cwd: tempDir, timeout: LONG_TIMEOUT });\n    } catch {\n      // Expected to fail at bun install\n    }\n\n    // Verify complete structure\n    const expectedFiles = [\n      'package.json',\n      'tsconfig.json',\n      'vitest.config.ts',\n      'README.md',\n      'LICENSE',\n      '.gitignore',\n      'src/index.ts',\n      'test/index.test.ts',\n      '.github/workflows/main.yml',\n      '.github/workflows/size.yml',\n    ];\n\n    for (const file of expectedFiles) {\n      expect(fs.existsSync(path.join(projectPath, file))).toBe(true);\n    }\n  });\n\n  it('package.json should have all required fields', () => {\n    const projectPath = path.join(tempDir, 'integration-test');\n    const pkgJson = fs.readJSONSync(path.join(projectPath, 'package.json'));\n\n    // Verify essential fields (name may not be updated if author prompt fails in non-TTY)\n    expect(['package-name', 'integration-test']).toContain(pkgJson.name);\n    expect(pkgJson.type).toBe('module');\n    expect(pkgJson.main).toBeDefined();\n    expect(pkgJson.module).toBeDefined();\n    expect(pkgJson.types).toBeDefined();\n    expect(pkgJson.exports).toBeDefined();\n    expect(pkgJson.scripts).toBeDefined();\n    expect(pkgJson.devDependencies).toBeDefined();\n    expect(pkgJson.engines).toBeDefined();\n    expect(pkgJson.files).toBeDefined();\n  });\n\n  it('tsconfig.json should have modern settings', () => {\n    const projectPath = path.join(tempDir, 'integration-test');\n    const tsconfig = fs.readJSONSync(path.join(projectPath, 'tsconfig.json'));\n\n    expect(tsconfig.compilerOptions.target).toBeDefined();\n    expect(tsconfig.compilerOptions.module).toBeDefined();\n    expect(tsconfig.compilerOptions.strict).toBe(true);\n    expect(tsconfig.compilerOptions.declaration).toBe(true);\n  });\n\n  it('source file should be valid TypeScript', () => {\n    const projectPath = path.join(tempDir, 'integration-test');\n    const source = fs.readFileSync(path.join(projectPath, 'src', 'index.ts'), 'utf-8');\n\n    // Should have typed exports\n    expect(source).toContain('export');\n    expect(source).toMatch(/: \\w+/); // Type annotation\n  });\n\n  it('test file should import from source', () => {\n    const projectPath = path.join(tempDir, 'integration-test');\n    const test = fs.readFileSync(path.join(projectPath, 'test', 'index.test.ts'), 'utf-8');\n\n    expect(test).toContain(\"from '../src'\");\n    expect(test).toContain('describe');\n    expect(test).toContain('expect');\n  });\n});\n\n// ============================================================================\n// EDGE CASES AND ERROR HANDLING\n// ============================================================================\n\ndescribe('Edge Cases', () => {\n  let tempDir: string;\n\n  beforeEach(() => {\n    tempDir = createTempDir('edge');\n  });\n\n  afterEach(async () => {\n    await fs.remove(tempDir);\n  });\n\n  it('should handle project names with special characters', () => {\n    const projectName = 'my-awesome_lib.test';\n    const projectPath = path.join(tempDir, projectName);\n\n    try {\n      runCLI(`create \"${projectName}\" --template basic`, { cwd: tempDir, timeout: LONG_TIMEOUT });\n    } catch {\n      // Expected to fail at bun install or author prompt in non-TTY\n    }\n\n    expect(fs.existsSync(projectPath)).toBe(true);\n    const pkgJson = fs.readJSONSync(path.join(projectPath, 'package.json'));\n    // Name may not be updated if author prompt fails in non-TTY\n    expect(['package-name', projectName]).toContain(pkgJson.name);\n  });\n\n  it('should handle scoped package names', () => {\n    // Create as directory name (scoped names need special handling)\n    const dirName = 'scoped-pkg';\n    const projectPath = path.join(tempDir, dirName);\n\n    try {\n      runCLI(`create ${dirName} --template basic`, { cwd: tempDir, timeout: LONG_TIMEOUT });\n    } catch {\n      // Expected to fail at bun install\n    }\n\n    expect(fs.existsSync(projectPath)).toBe(true);\n  });\n});\n\n// ============================================================================\n// VITEST CONFIG VALIDATION\n// ============================================================================\n\ndescribe('Vitest Configuration', () => {\n  it('basic template vitest config should be valid', () => {\n    const config = fs.readFileSync(path.join(TEMPLATES_PATH, 'basic', 'vitest.config.ts'), 'utf-8');\n    expect(config).toContain('defineConfig');\n    expect(config).toContain('test');\n  });\n\n  it('react template vitest config should include jsdom', () => {\n    const config = fs.readFileSync(path.join(TEMPLATES_PATH, 'react', 'vitest.config.ts'), 'utf-8');\n    expect(config).toContain('defineConfig');\n    expect(config).toContain('jsdom');\n  });\n});\n\n// ============================================================================\n// GITHUB WORKFLOWS VALIDATION\n// ============================================================================\n\ndescribe('GitHub Workflows', () => {\n  describe('Basic Template Workflows', () => {\n    it('main.yml should have correct structure', () => {\n      const workflow = fs.readFileSync(\n        path.join(TEMPLATES_PATH, 'basic', '.github', 'workflows', 'main.yml'),\n        'utf-8'\n      );\n      expect(workflow).toContain('name: CI');\n      expect(workflow).toContain('push:');\n      expect(workflow).toContain('pull_request:');\n      expect(workflow).toContain('bun install');\n      expect(workflow).toContain('bun run lint');\n      expect(workflow).toContain('bun run test');\n      expect(workflow).toContain('bun run build');\n    });\n\n    it('size.yml should check bundle size', () => {\n      const workflow = fs.readFileSync(\n        path.join(TEMPLATES_PATH, 'basic', '.github', 'workflows', 'size.yml'),\n        'utf-8'\n      );\n      expect(workflow).toContain('Size');\n      expect(workflow).toContain('bun run build');\n    });\n  });\n\n  describe('React Template Workflows', () => {\n    it('main.yml should have correct structure', () => {\n      const workflow = fs.readFileSync(\n        path.join(TEMPLATES_PATH, 'react', '.github', 'workflows', 'main.yml'),\n        'utf-8'\n      );\n      expect(workflow).toContain('name: CI');\n      expect(workflow).toContain('bun install');\n      expect(workflow).toContain('bun run lint');\n      expect(workflow).toContain('bun run test');\n      expect(workflow).toContain('bun run build');\n    });\n  });\n});\n"
  },
  {
    "path": "tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"target\": \"ES2022\",\n    \"module\": \"ESNext\",\n    \"moduleResolution\": \"bundler\",\n    \"lib\": [\"ES2022\"],\n    \"strict\": true,\n    \"esModuleInterop\": true,\n    \"skipLibCheck\": true,\n    \"forceConsistentCasingInFileNames\": true,\n    \"declaration\": true,\n    \"declarationMap\": true,\n    \"outDir\": \"./dist\",\n    \"rootDir\": \"./src\",\n    \"resolveJsonModule\": true,\n    \"isolatedModules\": true,\n    \"noEmit\": true,\n    \"noUnusedLocals\": true,\n    \"noUnusedParameters\": true,\n    \"noFallthroughCasesInSwitch\": true,\n    \"noImplicitReturns\": true\n  },\n  \"include\": [\"src\"],\n  \"exclude\": [\"node_modules\", \"dist\", \"templates\"]\n}\n"
  },
  {
    "path": "vitest.config.ts",
    "content": "import { defineConfig } from 'vitest/config';\n\nexport default defineConfig({\n  test: {\n    globals: true,\n    environment: 'node',\n    include: ['test/**/*.test.ts'],\n    testTimeout: 60000,\n    hookTimeout: 60000,\n  },\n});\n"
  },
  {
    "path": "website/.gitignore",
    "content": "# Dependencies\nnode_modules/\n.pnp\n.pnp.js\n\n# Build\n.next/\nout/\n.source/\ndist/\n\n# Testing\ncoverage/\n\n# Misc\n.DS_Store\n*.pem\nThumbs.db\n\n# Debug\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n\n# Local env files\n.env*.local\n.env\n\n# Vercel\n.vercel\n\n# TypeScript\n*.tsbuildinfo\nnext-env.d.ts\n"
  },
  {
    "path": "website/app/(home)/layout.tsx",
    "content": "import type { ReactNode } from 'react';\nimport { HomeLayout } from 'fumadocs-ui/layouts/home';\nimport { baseOptions } from '@/app/layout.config';\n\nexport default function Layout({ children }: { children: ReactNode }) {\n  return <HomeLayout {...baseOptions}>{children}</HomeLayout>;\n}\n"
  },
  {
    "path": "website/app/(home)/page.tsx",
    "content": "import Link from 'next/link';\n\nconst features = [\n  {\n    title: 'Zero Config',\n    description: 'Sensible defaults, just start coding. No complex setup required.',\n    icon: (\n      <svg\n        xmlns=\"http://www.w3.org/2000/svg\"\n        width={24}\n        height={24}\n        viewBox=\"0 0 24 24\"\n        fill=\"none\"\n        stroke=\"currentColor\"\n        strokeWidth={2}\n        strokeLinecap=\"round\"\n        strokeLinejoin=\"round\"\n      >\n        <polyline points=\"4 17 10 11 4 5\" />\n        <line x1={12} y1={19} x2={20} y2={19} />\n      </svg>\n    ),\n  },\n  {\n    title: 'Modern Tooling',\n    description: 'Built on bunchee, vitest, oxlint, and oxfmt for blazing fast development.',\n    icon: (\n      <svg\n        width=\"24\"\n        height=\"24\"\n        fill=\"none\"\n        stroke=\"currentColor\"\n        strokeLinecap=\"round\"\n        strokeLinejoin=\"round\"\n        strokeWidth=\"1.5\"\n        viewBox=\"0 0 24 24\"\n      >\n        <path d=\"M13 2L3 14h9l-1 8 10-12h-9l1-8z\"></path>\n      </svg>\n    ),\n  },\n  {\n    title: 'Dual ESM/CJS',\n    description: 'Automatic dual module builds with proper exports configuration.',\n    icon: (\n      <svg\n        width=\"24\"\n        height=\"24\"\n        fill=\"none\"\n        stroke=\"currentColor\"\n        strokeLinecap=\"round\"\n        strokeLinejoin=\"round\"\n        strokeWidth=\"1.5\"\n        viewBox=\"0 0 24 24\"\n      >\n        <path d=\"M16.5 9.4l-9-5.19M21 16V8a2 2 0 00-1-1.73l-7-4a2 2 0 00-2 0l-7 4A2 2 0 003 8v8a2 2 0 001 1.73l7 4a2 2 0 002 0l7-4A2 2 0 0021 16z\"></path>\n        <path d=\"M3.27 6.96L12 12.01l8.73-5.05M12 22.08V12\"></path>\n      </svg>\n    ),\n  },\n  {\n    title: 'TypeScript First',\n    description: 'Full TypeScript support with automatic declaration generation.',\n    icon: (\n      <svg fill=\"none\" height=\"24\" viewBox=\"0 0 27 26\" width=\"24\" xmlns=\"http://www.w3.org/2000/svg\">\n        <path\n          clipRule=\"evenodd\"\n          d=\"m.98608 0h24.32332c.5446 0 .9861.436522.9861.975v24.05c0 .5385-.4415.975-.9861.975h-24.32332c-.544597 0-.98608-.4365-.98608-.975v-24.05c0-.538478.441483-.975.98608-.975zm13.63142 13.8324v-2.1324h-9.35841v2.1324h3.34111v9.4946h2.6598v-9.4946zm1.0604 9.2439c.4289.2162.9362.3784 1.5218.4865.5857.1081 1.2029.1622 1.8518.1622.6324 0 1.2331-.0595 1.8023-.1784.5691-.1189 1.0681-.3149 1.497-.5879s.7685-.6297 1.0187-1.0703.3753-.9852.3753-1.6339c0-.4703-.0715-.8824-.2145-1.2365-.1429-.3541-.3491-.669-.6186-.9447-.2694-.2757-.5925-.523-.9692-.7419s-.8014-.4257-1.2743-.6203c-.3465-.1406-.6572-.2771-.9321-.4095-.275-.1324-.5087-.2676-.7011-.4054-.1925-.1379-.3409-.2838-.4454-.4379-.1045-.154-.1567-.3284-.1567-.523 0-.1784.0467-.3392.1402-.4824.0935-.1433.2254-.2663.3959-.369s.3794-.1824.6269-.2392c.2474-.0567.5224-.0851.8248-.0851.22 0 .4523.0162.697.0486.2447.0325.4908.0825.7382.15.2475.0676.4881.1527.7218.2555.2337.1027.4495.2216.6475.3567v-2.4244c-.4015-.1514-.84-.2636-1.3157-.3365-.4756-.073-1.0214-.1095-1.6373-.1095-.6268 0-1.2207.0662-1.7816.1987-.5609.1324-1.0544.3392-1.4806.6203s-.763.6392-1.0104 1.0743c-.2475.4352-.3712.9555-.3712 1.5609 0 .7731.2268 1.4326.6805 1.9785.4537.546 1.1424 1.0082 2.0662 1.3866.363.146.7011.2892 1.0146.4298.3134.1405.5842.2865.8124.4378.2282.1514.4083.3162.5403.4946s.198.3811.198.6082c0 .1676-.0413.323-.1238.4662-.0825.1433-.2076.2676-.3753.373s-.3766.1879-.6268.2473c-.2502.0595-.5431.0892-.8785.0892-.5719 0-1.1383-.0986-1.6992-.2959-.5608-.1973-1.0805-.4933-1.5589-.8879z\"\n          fill=\"currentColor\"\n          fillRule=\"evenodd\"\n        ></path>\n      </svg>\n    ),\n  },\n  {\n    title: 'Lightning Fast',\n    description: 'Rust-powered linting (50-100x faster) and formatting (35x faster).',\n    icon: (\n      <svg\n        xmlns=\"http://www.w3.org/2000/svg\"\n        width=\"24\"\n        height=\"24\"\n        viewBox=\"0 0 24 24\"\n        fill=\"none\"\n        stroke=\"currentColor\"\n        strokeWidth=\"2\"\n        strokeLinecap=\"round\"\n        strokeLinejoin=\"round\"\n      >\n        <circle cx=\"12\" cy=\"12\" r=\"10\"></circle>\n        <polyline points=\"12 6 12 12 16 14\"></polyline>\n      </svg>\n    ),\n  },\n  {\n    title: 'Bun Native',\n    description: 'Uses bun for package management with native speed.',\n    icon: (\n      <svg\n        xmlns=\"http://www.w3.org/2000/svg\"\n        width={24}\n        height={24}\n        viewBox=\"0 0 24 24\"\n        fill=\"none\"\n        stroke=\"currentColor\"\n        strokeWidth={2}\n        strokeLinecap=\"round\"\n        strokeLinejoin=\"round\"\n      >\n        <path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\" />\n        <polyline points=\"14 2 14 8 20 8\" />\n        <line x1={12} y1={18} x2={12} y2={12} />\n        <line x1={9} y1={15} x2={15} y2={15} />\n      </svg>\n    ),\n  },\n];\n\nexport default function HomePage() {\n  return (\n    <main className=\"flex flex-col min-h-screen\">\n      {/* Hero Section */}\n      <section className=\"relative flex flex-col items-center justify-center px-6 py-24 text-center bg-gradient-to-b from-fd-background to-fd-secondary/20\">\n        <div className=\"max-w-4xl mx-auto\">\n          {/* Logo - Light mode */}\n          <div className=\"flex justify-center mb-8\">\n            <svg\n              height={80}\n              viewBox=\"0 0 441 254\"\n              fill=\"none\"\n              xmlns=\"http://www.w3.org/2000/svg\"\n              className=\"dark:hidden\"\n            >\n              <path d=\"M0 127V254H127H254V127V8.28505e-06H127H0V127Z\" fill=\"#007ACC\" />\n              <path\n                d=\"M56.0802 127.508L56 137.925H72.4369H88.8739L88.8739 184.962V232H100.5H112.126V184.962L112.126 137.925H128.563H145V127.71C145 122.057 144.88 117.333 144.719 117.212C144.599 117.051 124.594 116.97 100.34 117.01L56.2004 117.131L56.0802 127.508Z\"\n                fill=\"white\"\n              />\n              <path\n                d=\"M204.89 117.051C211.339 118.673 216.256 121.551 220.77 126.254C223.107 128.768 226.573 133.349 226.855 134.444C226.936 134.768 215.893 142.228 209.203 146.403C208.961 146.566 207.994 145.512 206.905 143.89C203.641 139.106 200.215 137.038 194.976 136.673C187.278 136.146 182.32 140.201 182.361 146.971C182.361 148.958 182.643 150.133 183.449 151.755C185.142 155.282 188.285 157.39 198.16 161.688C216.336 169.553 224.115 174.742 228.951 182.121C234.352 190.351 235.561 203.486 231.893 213.257C227.863 223.879 217.868 231.095 203.802 233.487C199.449 234.257 189.132 234.136 184.457 233.284C174.26 231.46 164.587 226.392 158.622 219.744C156.285 217.149 151.73 210.378 152.013 209.892C152.133 209.73 153.181 209.081 154.35 208.392C155.479 207.743 159.751 205.27 163.781 202.919L171.076 198.662L172.607 200.932C174.744 204.216 179.419 208.716 182.24 210.216C190.341 214.514 201.464 213.905 206.946 208.959C209.283 206.811 210.251 204.581 210.251 201.297C210.251 198.337 209.888 197.04 208.356 194.81C206.381 191.972 202.351 189.58 190.905 184.594C177.807 178.918 172.164 175.391 167.005 169.796C164.023 166.553 161.202 161.363 160.033 157.025C159.066 153.417 158.824 144.376 159.59 140.728C162.29 127.998 171.842 119.119 185.625 116.484C190.099 115.632 200.497 115.957 204.89 117.051Z\"\n                fill=\"white\"\n              />\n              <path\n                d=\"M305.321 211.872C301.475 211.872 298.425 208.551 298.425 200.183C298.425 186.767 306.648 169.233 315.269 169.233C317.656 169.233 321.767 169.897 326.277 171.358L320.043 203.769C314.871 208.419 309.168 211.872 305.321 211.872ZM350.945 222.1L349.487 212.271C338.478 214.662 337.948 214.529 339.009 208.817L355.19 125L335.03 126.461L329.99 152.629C328.133 152.363 326.409 152.363 324.818 152.363C295.64 152.363 278 179.86 278 206.293C278 222.897 285.295 231 294.048 231C301.74 231 310.892 224.757 318.849 216.92C318.186 231.797 325.481 236.446 350.945 222.1Z\"\n                fill=\"black\"\n              />\n              <path\n                d=\"M404.129 229.406L426.941 228.742L409.965 191.815L441 154.356H419.514L400.548 179.727L390.071 154.09L367.259 154.887L383.97 191.682L352.935 229.14H374.553L393.519 203.769L404.129 229.406Z\"\n                fill=\"black\"\n              />\n            </svg>\n            {/* Logo - Dark mode */}\n            <svg\n              height={80}\n              viewBox=\"0 0 441 254\"\n              fill=\"none\"\n              xmlns=\"http://www.w3.org/2000/svg\"\n              className=\"hidden dark:block\"\n            >\n              <path d=\"M0 127V254H127H254V127V8.28505e-06H127H0V127Z\" fill=\"#007ACC\" />\n              <path\n                d=\"M56.0802 127.508L56 137.925H72.4369H88.8739L88.8739 184.962V232H100.5H112.126V184.962L112.126 137.925H128.563H145V127.71C145 122.057 144.88 117.333 144.719 117.212C144.599 117.051 124.594 116.97 100.34 117.01L56.2004 117.131L56.0802 127.508Z\"\n                fill=\"white\"\n              />\n              <path\n                d=\"M204.89 117.051C211.339 118.673 216.256 121.551 220.77 126.254C223.107 128.768 226.573 133.349 226.855 134.444C226.936 134.768 215.893 142.228 209.203 146.403C208.961 146.566 207.994 145.512 206.905 143.89C203.641 139.106 200.215 137.038 194.976 136.673C187.278 136.146 182.32 140.201 182.361 146.971C182.361 148.958 182.643 150.133 183.449 151.755C185.142 155.282 188.285 157.39 198.16 161.688C216.336 169.553 224.115 174.742 228.951 182.121C234.352 190.351 235.561 203.486 231.893 213.257C227.863 223.879 217.868 231.095 203.802 233.487C199.449 234.257 189.132 234.136 184.457 233.284C174.26 231.46 164.587 226.392 158.622 219.744C156.285 217.149 151.73 210.378 152.013 209.892C152.133 209.73 153.181 209.081 154.35 208.392C155.479 207.743 159.751 205.27 163.781 202.919L171.076 198.662L172.607 200.932C174.744 204.216 179.419 208.716 182.24 210.216C190.341 214.514 201.464 213.905 206.946 208.959C209.283 206.811 210.251 204.581 210.251 201.297C210.251 198.337 209.888 197.04 208.356 194.81C206.381 191.972 202.351 189.58 190.905 184.594C177.807 178.918 172.164 175.391 167.005 169.796C164.023 166.553 161.202 161.363 160.033 157.025C159.066 153.417 158.824 144.376 159.59 140.728C162.29 127.998 171.842 119.119 185.625 116.484C190.099 115.632 200.497 115.957 204.89 117.051Z\"\n                fill=\"white\"\n              />\n              <path\n                d=\"M305.321 211.872C301.475 211.872 298.425 208.551 298.425 200.183C298.425 186.767 306.648 169.233 315.269 169.233C317.656 169.233 321.767 169.897 326.277 171.358L320.043 203.769C314.871 208.419 309.168 211.872 305.321 211.872ZM350.945 222.1L349.487 212.271C338.478 214.662 337.948 214.529 339.009 208.817L355.19 125L335.03 126.461L329.99 152.629C328.133 152.363 326.409 152.363 324.818 152.363C295.64 152.363 278 179.86 278 206.293C278 222.897 285.295 231 294.048 231C301.74 231 310.892 224.757 318.849 216.92C318.186 231.797 325.481 236.446 350.945 222.1Z\"\n                fill=\"white\"\n              />\n              <path\n                d=\"M404.129 229.406L426.941 228.742L409.965 191.815L441 154.356H419.514L400.548 179.727L390.071 154.09L367.259 154.887L383.97 191.682L352.935 229.14H374.553L393.519 203.769L404.129 229.406Z\"\n                fill=\"white\"\n              />\n            </svg>\n          </div>\n\n          <h1 className=\"text-4xl font-bold tracking-tight sm:text-6xl text-fd-foreground mb-4\">\n            Zero-config TypeScript Package Development\n          </h1>\n\n          <p className=\"mt-6 text-lg leading-8 text-fd-muted-foreground max-w-2xl mx-auto\">\n            TSDX helps you develop, test, and publish modern TypeScript packages with ease.\n            Built on modern, high-performance Rust-based tooling.\n          </p>\n\n          {/* CTA Buttons */}\n          <div className=\"mt-10 flex items-center justify-center gap-x-6\">\n            <Link\n              href=\"/docs\"\n              className=\"rounded-lg bg-primary px-6 py-3 text-sm font-semibold text-white shadow-sm hover:bg-primary-600 transition-colors\"\n            >\n              Get Started\n            </Link>\n            <a\n              href=\"https://github.com/jaredpalmer/tsdx\"\n              target=\"_blank\"\n              rel=\"noopener noreferrer\"\n              className=\"rounded-lg border border-fd-border px-6 py-3 text-sm font-semibold text-fd-foreground hover:bg-fd-secondary transition-colors flex items-center gap-2\"\n            >\n              <svg\n                className=\"w-5 h-5\"\n                fill=\"currentColor\"\n                viewBox=\"0 0 24 24\"\n                aria-hidden=\"true\"\n              >\n                <path\n                  fillRule=\"evenodd\"\n                  d=\"M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.943.359.309.678.92.678 1.855 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z\"\n                  clipRule=\"evenodd\"\n                />\n              </svg>\n              GitHub\n            </a>\n          </div>\n\n          {/* Quick Install */}\n          <div className=\"mt-12 flex justify-center\">\n            <div className=\"relative\">\n              <pre className=\"rounded-lg bg-fd-secondary px-6 py-4 text-sm text-fd-foreground font-mono\">\n                bunx tsdx create mylib\n              </pre>\n            </div>\n          </div>\n        </div>\n      </section>\n\n      {/* Features Section */}\n      <section className=\"py-24 px-6\">\n        <div className=\"max-w-6xl mx-auto\">\n          <div className=\"text-center mb-16\">\n            <h2 className=\"text-3xl font-bold tracking-tight text-fd-foreground sm:text-4xl\">\n              Everything you need to build TypeScript packages\n            </h2>\n            <p className=\"mt-4 text-lg text-fd-muted-foreground\">\n              Modern tooling. Zero configuration. Maximum productivity.\n            </p>\n          </div>\n\n          <div className=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8\">\n            {features.map((feature) => (\n              <div\n                key={feature.title}\n                className=\"relative p-6 rounded-xl border border-fd-border bg-fd-card hover:border-primary/50 transition-colors\"\n              >\n                <div className=\"w-12 h-12 rounded-lg bg-primary/10 flex items-center justify-center text-primary mb-4\">\n                  {feature.icon}\n                </div>\n                <h3 className=\"text-lg font-semibold text-fd-foreground mb-2\">{feature.title}</h3>\n                <p className=\"text-fd-muted-foreground\">{feature.description}</p>\n              </div>\n            ))}\n          </div>\n        </div>\n      </section>\n\n      {/* Tool Stack Section */}\n      <section className=\"py-24 px-6 bg-fd-secondary/30\">\n        <div className=\"max-w-4xl mx-auto text-center\">\n          <h2 className=\"text-3xl font-bold tracking-tight text-fd-foreground sm:text-4xl mb-8\">\n            Powered by Modern Tools\n          </h2>\n          <p className=\"text-lg text-fd-muted-foreground mb-12\">\n            TSDX 2.0 is built on the fastest, most modern tools in the ecosystem.\n          </p>\n\n          <div className=\"grid grid-cols-2 md:grid-cols-4 gap-6\">\n            {[\n              { name: 'bunchee', description: 'Bundling', url: 'https://github.com/huozhi/bunchee' },\n              { name: 'vitest', description: 'Testing', url: 'https://vitest.dev/' },\n              { name: 'oxlint', description: 'Linting', url: 'https://oxc.rs/' },\n              { name: 'bun', description: 'Package Mgmt', url: 'https://bun.sh/' },\n            ].map((tool) => (\n              <a\n                key={tool.name}\n                href={tool.url}\n                target=\"_blank\"\n                rel=\"noopener noreferrer\"\n                className=\"p-4 rounded-lg border border-fd-border bg-fd-card hover:border-primary/50 transition-colors\"\n              >\n                <div className=\"font-semibold text-fd-foreground\">{tool.name}</div>\n                <div className=\"text-sm text-fd-muted-foreground\">{tool.description}</div>\n              </a>\n            ))}\n          </div>\n        </div>\n      </section>\n\n      {/* Footer */}\n      <footer className=\"py-12 px-6 border-t border-fd-border\">\n        <div className=\"max-w-6xl mx-auto flex flex-col md:flex-row justify-between items-center gap-4\">\n          <div className=\"flex items-center gap-2 text-fd-muted-foreground\">\n            <span>A</span>\n            <a\n              href=\"https://jaredpalmer.com\"\n              target=\"_blank\"\n              rel=\"noopener noreferrer\"\n              className=\"font-semibold text-fd-foreground hover:text-primary transition-colors\"\n            >\n              Jared Palmer\n            </a>\n            <span>Project</span>\n          </div>\n          <div className=\"flex items-center gap-6\">\n            <a\n              href=\"https://github.com/jaredpalmer/tsdx\"\n              target=\"_blank\"\n              rel=\"noopener noreferrer\"\n              className=\"text-fd-muted-foreground hover:text-fd-foreground transition-colors\"\n            >\n              GitHub\n            </a>\n            <a\n              href=\"https://twitter.com/jaredpalmer\"\n              target=\"_blank\"\n              rel=\"noopener noreferrer\"\n              className=\"text-fd-muted-foreground hover:text-fd-foreground transition-colors\"\n            >\n              Twitter\n            </a>\n          </div>\n        </div>\n      </footer>\n    </main>\n  );\n}\n"
  },
  {
    "path": "website/app/docs/[[...slug]]/page.tsx",
    "content": "import { source } from '@/lib/source';\nimport { DocsPage, DocsBody } from 'fumadocs-ui/page';\nimport { notFound } from 'next/navigation';\nimport defaultMdxComponents from 'fumadocs-ui/mdx';\nimport { Tab, Tabs } from 'fumadocs-ui/components/tabs';\n\nexport default async function Page(props: {\n  params: Promise<{ slug?: string[] }>;\n}) {\n  const params = await props.params;\n  const page = source.getPage(params.slug);\n  if (!page) notFound();\n\n  const MDX = page.data.body;\n\n  return (\n    <DocsPage toc={page.data.toc} full={page.data.full}>\n      <DocsBody>\n        <MDX components={{ ...defaultMdxComponents, Tab, Tabs }} />\n      </DocsBody>\n    </DocsPage>\n  );\n}\n\nexport async function generateStaticParams() {\n  return source.generateParams();\n}\n\nexport async function generateMetadata(props: {\n  params: Promise<{ slug?: string[] }>;\n}) {\n  const params = await props.params;\n  const page = source.getPage(params.slug);\n  if (!page) notFound();\n\n  return {\n    title: page.data.title,\n    description: page.data.description,\n  };\n}\n"
  },
  {
    "path": "website/app/docs/layout.tsx",
    "content": "import { DocsLayout } from 'fumadocs-ui/layouts/docs';\nimport type { ReactNode } from 'react';\nimport { baseOptions } from '@/app/layout.config';\nimport { source } from '@/lib/source';\n\nexport default function Layout({ children }: { children: ReactNode }) {\n  return (\n    <DocsLayout tree={source.pageTree} {...baseOptions}>\n      {children}\n    </DocsLayout>\n  );\n}\n"
  },
  {
    "path": "website/app/global.css",
    "content": "@import 'tailwindcss';\n@import 'fumadocs-ui/css/neutral.css';\n@import 'fumadocs-ui/css/preset.css';\n\n@source '../node_modules/fumadocs-ui/dist/**/*.js';\n\n/* Custom theme overrides */\n@theme {\n  --color-primary: #007ACC;\n  --color-fd-primary: #007ACC;\n  --font-sans: var(--font-ibm-plex-sans), ui-sans-serif, system-ui, sans-serif;\n  --font-mono: var(--font-ibm-plex-mono), ui-monospace, monospace;\n}\n"
  },
  {
    "path": "website/app/layout.config.tsx",
    "content": "import type { BaseLayoutProps } from 'fumadocs-ui/layouts/shared';\n\nexport const baseOptions: BaseLayoutProps = {\n  nav: {\n    title: (\n      <div className=\"flex items-center gap-2\">\n        <svg height={24} viewBox=\"0 0 441 254\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n          <path d=\"M0 127V254H127H254V127V8.28505e-06H127H0V127Z\" fill=\"#007ACC\" />\n          <path\n            d=\"M56.0802 127.508L56 137.925H72.4369H88.8739L88.8739 184.962V232H100.5H112.126V184.962L112.126 137.925H128.563H145V127.71C145 122.057 144.88 117.333 144.719 117.212C144.599 117.051 124.594 116.97 100.34 117.01L56.2004 117.131L56.0802 127.508Z\"\n            fill=\"white\"\n          />\n          <path\n            d=\"M204.89 117.051C211.339 118.673 216.256 121.551 220.77 126.254C223.107 128.768 226.573 133.349 226.855 134.444C226.936 134.768 215.893 142.228 209.203 146.403C208.961 146.566 207.994 145.512 206.905 143.89C203.641 139.106 200.215 137.038 194.976 136.673C187.278 136.146 182.32 140.201 182.361 146.971C182.361 148.958 182.643 150.133 183.449 151.755C185.142 155.282 188.285 157.39 198.16 161.688C216.336 169.553 224.115 174.742 228.951 182.121C234.352 190.351 235.561 203.486 231.893 213.257C227.863 223.879 217.868 231.095 203.802 233.487C199.449 234.257 189.132 234.136 184.457 233.284C174.26 231.46 164.587 226.392 158.622 219.744C156.285 217.149 151.73 210.378 152.013 209.892C152.133 209.73 153.181 209.081 154.35 208.392C155.479 207.743 159.751 205.27 163.781 202.919L171.076 198.662L172.607 200.932C174.744 204.216 179.419 208.716 182.24 210.216C190.341 214.514 201.464 213.905 206.946 208.959C209.283 206.811 210.251 204.581 210.251 201.297C210.251 198.337 209.888 197.04 208.356 194.81C206.381 191.972 202.351 189.58 190.905 184.594C177.807 178.918 172.164 175.391 167.005 169.796C164.023 166.553 161.202 161.363 160.033 157.025C159.066 153.417 158.824 144.376 159.59 140.728C162.29 127.998 171.842 119.119 185.625 116.484C190.099 115.632 200.497 115.957 204.89 117.051Z\"\n            fill=\"white\"\n          />\n          <path\n            d=\"M305.321 211.872C301.475 211.872 298.425 208.551 298.425 200.183C298.425 186.767 306.648 169.233 315.269 169.233C317.656 169.233 321.767 169.897 326.277 171.358L320.043 203.769C314.871 208.419 309.168 211.872 305.321 211.872ZM350.945 222.1L349.487 212.271C338.478 214.662 337.948 214.529 339.009 208.817L355.19 125L335.03 126.461L329.99 152.629C328.133 152.363 326.409 152.363 324.818 152.363C295.64 152.363 278 179.86 278 206.293C278 222.897 285.295 231 294.048 231C301.74 231 310.892 224.757 318.849 216.92C318.186 231.797 325.481 236.446 350.945 222.1Z\"\n            fill=\"currentColor\"\n          />\n          <path\n            d=\"M404.129 229.406L426.941 228.742L409.965 191.815L441 154.356H419.514L400.548 179.727L390.071 154.09L367.259 154.887L383.97 191.682L352.935 229.14H374.553L393.519 203.769L404.129 229.406Z\"\n            fill=\"currentColor\"\n          />\n        </svg>\n        <span className=\"sr-only\">TSDX</span>\n      </div>\n    ),\n  },\n  links: [\n    {\n      text: 'Documentation',\n      url: '/docs',\n      active: 'nested-url',\n    },\n    {\n      text: 'GitHub',\n      url: 'https://github.com/jaredpalmer/tsdx',\n      external: true,\n    },\n  ],\n  githubUrl: 'https://github.com/jaredpalmer/tsdx',\n};\n"
  },
  {
    "path": "website/app/layout.tsx",
    "content": "import './global.css';\nimport { RootProvider } from 'fumadocs-ui/provider/next';\nimport type { Metadata } from 'next';\nimport { IBM_Plex_Sans, IBM_Plex_Mono } from 'next/font/google';\n\nconst ibmPlexSans = IBM_Plex_Sans({\n  subsets: ['latin'],\n  weight: ['400', '500', '600', '700'],\n  variable: '--font-ibm-plex-sans',\n});\n\nconst ibmPlexMono = IBM_Plex_Mono({\n  subsets: ['latin'],\n  weight: ['400', '500', '600'],\n  variable: '--font-ibm-plex-mono',\n});\n\nexport const metadata: Metadata = {\n  title: {\n    template: '%s | TSDX',\n    default: 'TSDX - Zero-config TypeScript Package Development',\n  },\n  description:\n    'Zero-config CLI for TypeScript package development. Build production-ready TypeScript packages with modern tooling.',\n  metadataBase: new URL('https://tsdx.io'),\n  openGraph: {\n    title: 'TSDX - Zero-config TypeScript Package Development',\n    description:\n      'Zero-config CLI for TypeScript package development. Build production-ready TypeScript packages with modern tooling.',\n    url: 'https://tsdx.io',\n    siteName: 'TSDX',\n    images: [\n      {\n        url: '/og_image.jpg',\n        width: 1200,\n        height: 630,\n      },\n    ],\n    locale: 'en_US',\n    type: 'website',\n  },\n  twitter: {\n    card: 'summary_large_image',\n    title: 'TSDX - Zero-config TypeScript Package Development',\n    description:\n      'Zero-config CLI for TypeScript package development. Build production-ready TypeScript packages with modern tooling.',\n    images: ['/og_image.jpg'],\n    creator: '@jaredpalmer',\n  },\n  icons: {\n    icon: '/favicon.png',\n    apple: '/favicon/apple-touch-icon.png',\n  },\n  manifest: '/favicon/site.webmanifest',\n};\n\nexport default function Layout({ children }: { children: React.ReactNode }) {\n  return (\n    <html\n      lang=\"en\"\n      className={`${ibmPlexSans.variable} ${ibmPlexMono.variable}`}\n      suppressHydrationWarning\n    >\n      <body className=\"flex flex-col min-h-screen font-sans\">\n        <RootProvider>{children}</RootProvider>\n      </body>\n    </html>\n  );\n}\n"
  },
  {
    "path": "website/content/docs/commands.mdx",
    "content": "---\ntitle: Commands\ndescription: Complete reference for all TSDX CLI commands\n---\n\n# Commands\n\nTSDX provides a set of commands to help you develop, test, and build your TypeScript packages.\n\n## tsdx create\n\nCreate a new TypeScript package from a template.\n\n```bash\ntsdx create <name> [options]\n```\n\n### Options\n\n| Option | Description |\n|--------|-------------|\n| `-t, --template <template>` | Template to use (basic, react) |\n\n### Examples\n\n```bash\n# Interactive template selection\nbunx tsdx create mylib\n\n# Specify template directly\nbunx tsdx create mylib --template react\n```\n\n---\n\n## tsdx build\n\nBuild the package for production using [bunchee](https://github.com/huozhi/bunchee).\n\n```bash\ntsdx build [options]\n```\n\n### Options\n\n| Option | Description |\n|--------|-------------|\n| `--no-clean` | Skip cleaning the dist folder before building |\n\n### Examples\n\n```bash\n# Standard build\ntsdx build\n\n# Build without cleaning dist\ntsdx build --no-clean\n```\n\n### Output\n\nThe build command outputs:\n- `dist/index.js` - ESM module\n- `dist/index.cjs` - CommonJS module\n- `dist/index.d.ts` - TypeScript declarations\n- `dist/index.d.cts` - CJS TypeScript declarations\n\n---\n\n## tsdx dev / tsdx watch\n\nStart development mode with file watching. Rebuilds automatically when files change.\n\n```bash\ntsdx dev\n# or\ntsdx watch\n```\n\n### Examples\n\n```bash\n# Start development mode\ntsdx dev\n```\n\n---\n\n## tsdx test\n\nRun tests using [vitest](https://vitest.dev/).\n\n```bash\ntsdx test [options]\n```\n\n### Options\n\n| Option | Description |\n|--------|-------------|\n| `-w, --watch` | Run in watch mode |\n| `-c, --coverage` | Run with coverage |\n| `-u, --update` | Update snapshots |\n\nAll additional options are passed through to vitest.\n\n### Examples\n\n```bash\n# Run tests once\ntsdx test\n\n# Watch mode\ntsdx test --watch\n\n# With coverage\ntsdx test --coverage\n\n# Update snapshots\ntsdx test --update\n\n# Run specific test file\ntsdx test src/utils.test.ts\n```\n\n---\n\n## tsdx lint\n\nLint the codebase using [oxlint](https://oxc.rs/docs/guide/usage/linter.html).\n\n```bash\ntsdx lint [paths...] [options]\n```\n\n### Options\n\n| Option | Description |\n|--------|-------------|\n| `-f, --fix` | Auto-fix fixable issues |\n| `--config <path>` | Path to config file |\n\n### Arguments\n\n| Argument | Description | Default |\n|----------|-------------|---------|\n| `paths` | Paths to lint | `src test` |\n\n### Examples\n\n```bash\n# Lint src and test directories (default)\ntsdx lint\n\n# Lint specific paths\ntsdx lint src lib\n\n# Auto-fix issues\ntsdx lint --fix\n\n# Use custom config\ntsdx lint --config .oxlintrc.json\n```\n\n---\n\n## tsdx format\n\nFormat the codebase using [oxfmt](https://oxc.rs/docs/guide/usage/formatter).\n\n```bash\ntsdx format [paths...] [options]\n```\n\n### Options\n\n| Option | Description |\n|--------|-------------|\n| `-c, --check` | Check if files are formatted without making changes |\n\n### Arguments\n\n| Argument | Description | Default |\n|----------|-------------|---------|\n| `paths` | Paths to format | `.` |\n\n### Examples\n\n```bash\n# Format all files\ntsdx format\n\n# Check formatting without changes\ntsdx format --check\n\n# Format specific paths\ntsdx format src test\n```\n\n---\n\n## tsdx typecheck\n\nRun TypeScript type checking.\n\n```bash\ntsdx typecheck [options]\n```\n\n### Options\n\n| Option | Description |\n|--------|-------------|\n| `-w, --watch` | Run in watch mode |\n\n### Examples\n\n```bash\n# Type check once\ntsdx typecheck\n\n# Watch mode\ntsdx typecheck --watch\n```\n\n---\n\n## tsdx init\n\nInitialize TSDX configuration in an existing project.\n\n```bash\ntsdx init\n```\n\nThis command:\n- Updates `package.json` with tsdx scripts and exports configuration\n- Creates `tsconfig.json` if it doesn't exist\n- Creates `vitest.config.ts` if it doesn't exist\n\n### Examples\n\n```bash\n# Initialize in existing project\nbunx tsdx init\n```\n\nAfter running `tsdx init`, install the required dependencies:\n\n```bash\nbun add -D bunchee vitest typescript oxlint\n```\n"
  },
  {
    "path": "website/content/docs/configuration.mdx",
    "content": "---\ntitle: Configuration\ndescription: Configuring TSDX and its underlying tools\n---\n\n# Configuration\n\nTSDX is designed to be zero-config, but you can customize the underlying tools when needed.\n\n## TypeScript\n\nTSDX creates a modern TypeScript configuration in `tsconfig.json`:\n\n```json\n{\n  \"compilerOptions\": {\n    \"target\": \"ES2022\",\n    \"module\": \"ESNext\",\n    \"moduleResolution\": \"bundler\",\n    \"lib\": [\"ES2022\", \"DOM\"],\n    \"strict\": true,\n    \"esModuleInterop\": true,\n    \"skipLibCheck\": true,\n    \"forceConsistentCasingInFileNames\": true,\n    \"declaration\": true,\n    \"declarationMap\": true,\n    \"outDir\": \"./dist\",\n    \"rootDir\": \"./src\",\n    \"resolveJsonModule\": true,\n    \"isolatedModules\": true,\n    \"noEmit\": true\n  },\n  \"include\": [\"src\"],\n  \"exclude\": [\"node_modules\", \"dist\"]\n}\n```\n\nYou can modify this file to adjust TypeScript behavior for your project.\n\n---\n\n## Vitest\n\nTest configuration is in `vitest.config.ts`:\n\n```typescript\nimport { defineConfig } from 'vitest/config';\n\nexport default defineConfig({\n  test: {\n    globals: true,\n    environment: 'node', // or 'jsdom' for React/DOM testing\n  },\n});\n```\n\n### Common Configurations\n\n<Tabs items={['Node Environment', 'JSDOM (React)', 'With Coverage']}>\n\n<Tab value=\"Node Environment\">\n```typescript\nimport { defineConfig } from 'vitest/config';\n\nexport default defineConfig({\n  test: {\n    globals: true,\n    environment: 'node',\n  },\n});\n```\n</Tab>\n\n<Tab value=\"JSDOM (React)\">\n```typescript\nimport { defineConfig } from 'vitest/config';\n\nexport default defineConfig({\n  test: {\n    globals: true,\n    environment: 'jsdom',\n    setupFiles: ['./test/setup.ts'],\n  },\n});\n```\n</Tab>\n\n<Tab value=\"With Coverage\">\n```typescript\nimport { defineConfig } from 'vitest/config';\n\nexport default defineConfig({\n  test: {\n    globals: true,\n    environment: 'node',\n    coverage: {\n      provider: 'v8',\n      reporter: ['text', 'json', 'html'],\n    },\n  },\n});\n```\n</Tab>\n\n</Tabs>\n\nSee the [Vitest documentation](https://vitest.dev/config/) for all options.\n\n---\n\n## Linting (oxlint)\n\nCreate `.oxlintrc.json` in your project root for custom lint rules:\n\n```json\n{\n  \"rules\": {\n    \"no-unused-vars\": \"warn\",\n    \"no-console\": \"off\"\n  }\n}\n```\n\nSee the [oxlint documentation](https://oxc.rs/docs/guide/usage/linter/rules.html) for available rules.\n\n---\n\n## Formatting (oxfmt)\n\nCreate `.oxfmtrc.json` in your project root for custom formatting:\n\n```json\n{\n  \"indentWidth\": 2,\n  \"lineWidth\": 100\n}\n```\n\nSee the [oxfmt documentation](https://oxc.rs/docs/guide/usage/formatter) for available options.\n\n---\n\n## Bundling (bunchee)\n\nBunchee reads your `package.json` exports field to determine build output. The default configuration is:\n\n```json\n{\n  \"type\": \"module\",\n  \"main\": \"./dist/index.cjs\",\n  \"module\": \"./dist/index.js\",\n  \"types\": \"./dist/index.d.ts\",\n  \"exports\": {\n    \".\": {\n      \"import\": {\n        \"types\": \"./dist/index.d.ts\",\n        \"default\": \"./dist/index.js\"\n      },\n      \"require\": {\n        \"types\": \"./dist/index.d.cts\",\n        \"default\": \"./dist/index.cjs\"\n      }\n    },\n    \"./package.json\": \"./package.json\"\n  }\n}\n```\n\nFor advanced customization, create `bunchee.config.ts`:\n\n```typescript\nimport { BuncheeConfig } from 'bunchee';\n\nexport default {\n  // See bunchee documentation\n} satisfies BuncheeConfig;\n```\n\nSee the [bunchee documentation](https://github.com/huozhi/bunchee) for all options.\n\n---\n\n## GitHub Actions\n\nTSDX templates include a GitHub Actions workflow in `.github/workflows/main.yml`:\n\n```yaml\nname: CI\n\non:\n  push:\n    branches: [main]\n  pull_request:\n    branches: [main]\n\njobs:\n  build:\n    runs-on: ${{ matrix.os }}\n    strategy:\n      matrix:\n        node: ['20', '22']\n        os: [ubuntu-latest, windows-latest, macos-latest]\n\n    steps:\n      - uses: actions/checkout@v4\n\n      - uses: oven-sh/setup-bun@v2\n        with:\n          bun-version: latest\n\n      - uses: actions/setup-node@v4\n        with:\n          node-version: ${{ matrix.node }}\n\n      - run: bun install\n      - run: bun run lint\n      - run: bun run typecheck\n      - run: bun run build\n      - run: bun run test\n```\n\nYou can customize this workflow to fit your needs.\n"
  },
  {
    "path": "website/content/docs/index.mdx",
    "content": "---\ntitle: Introduction\ndescription: Zero-config CLI for TypeScript package development\n---\n\n# TSDX\n\n**TSDX is a zero-config CLI that helps you develop, test, and publish modern TypeScript packages** with ease—so you can focus on your awesome new library and not waste another afternoon on configuration.\n\n<Callout type=\"info\" title=\"TSDX 2.0\">\n  TSDX 2.0 is a complete rewrite using modern, high-performance Rust-based tooling. See the [Migration Guide](/docs/migration) if upgrading from v0.x.\n</Callout>\n\n## Features\n\n- **Zero config** - Sensible defaults, just start coding\n- **Modern tooling** - Built on [bunchee](https://github.com/huozhi/bunchee), [vitest](https://vitest.dev/), [oxlint](https://oxc.rs/docs/guide/usage/linter.html), and [oxfmt](https://oxc.rs/docs/guide/usage/formatter)\n- **Dual ESM/CJS** - Automatic dual module builds with proper exports\n- **TypeScript first** - Full TypeScript support with declaration generation\n- **Lightning fast** - Rust-powered linting (50-100x faster than ESLint) and formatting (35x faster than Prettier)\n- **Bun-native** - Uses bun for package management\n- **Modern Node.js** - Supports Node.js 20+ (LTS)\n\n## Tool Stack\n\nTSDX 2.0 uses modern, high-performance tools:\n\n| Tool | Purpose | Performance |\n|------|---------|-------------|\n| [bunchee](https://github.com/huozhi/bunchee) | Bundling | Zero-config, built on Rollup + SWC |\n| [vitest](https://vitest.dev/) | Testing | Vite-native, Jest-compatible API |\n| [oxlint](https://oxc.rs/docs/guide/usage/linter.html) | Linting | 50-100x faster than ESLint |\n| [oxfmt](https://oxc.rs/docs/guide/usage/formatter) | Formatting | 35x faster than Prettier |\n| [bun](https://bun.sh/) | Package Management | Native speed, npm-compatible |\n\n## Requirements\n\n- **Node.js**: 20+ (LTS)\n- **Bun**: Latest version\n\n## Quick Example\n\n```bash\n# Create a new package\nbunx tsdx create mylib\n\n# Navigate to the project\ncd mylib\n\n# Start development\nbun run dev\n```\n\nThat's it! Start editing `src/index.ts` and build your library.\n"
  },
  {
    "path": "website/content/docs/installation.mdx",
    "content": "---\ntitle: Installation\ndescription: How to install TSDX and its dependencies\n---\n\n# Installation\n\n## Prerequisites\n\nBefore installing TSDX, you need to have **bun** installed.\n\n### Installing Bun\n\n<Tabs items={['macOS/Linux', 'Windows', 'npm']}>\n\n<Tab value=\"macOS/Linux\">\n```bash\ncurl -fsSL https://bun.sh/install | bash\n```\n</Tab>\n\n<Tab value=\"Windows\">\n```powershell\npowershell -c \"irm bun.sh/install.ps1 | iex\"\n```\n</Tab>\n\n<Tab value=\"npm\">\n```bash\nnpm install -g bun\n```\n</Tab>\n\n</Tabs>\n\n## Installing TSDX\n\n### Global Installation (recommended for creating projects)\n\n```bash\nbun add -g tsdx\n```\n\nAfter installing globally, you can create new projects from anywhere:\n\n```bash\ntsdx create mylib\n```\n\n### Per-Project Installation\n\n```bash\nbun add -D tsdx\n```\n\nWhen installed per-project, use `bunx` to run commands:\n\n```bash\nbunx tsdx create mylib\n```\n\n### One-off Usage (no installation)\n\nYou can use `bunx` to run TSDX without installing it:\n\n```bash\nbunx tsdx create mylib\n```\n\n## Verifying Installation\n\nCheck that TSDX is installed correctly:\n\n```bash\ntsdx --version\n```\n\nOr with bunx:\n\n```bash\nbunx tsdx --version\n```\n\n## Next Steps\n\nOnce installed, you're ready to [create your first project](/docs/quick-start).\n"
  },
  {
    "path": "website/content/docs/meta.json",
    "content": "{\n  \"title\": \"Documentation\",\n  \"pages\": [\n    \"index\",\n    \"---Getting Started---\",\n    \"installation\",\n    \"quick-start\",\n    \"---Usage---\",\n    \"commands\",\n    \"templates\",\n    \"---Configuration---\",\n    \"configuration\",\n    \"project-structure\",\n    \"---Migration---\",\n    \"migration\"\n  ]\n}\n"
  },
  {
    "path": "website/content/docs/migration.mdx",
    "content": "---\ntitle: Migration Guide\ndescription: Migrating from TSDX v0.x to v2.0\n---\n\n# Migration Guide\n\nThis guide helps you migrate from the original TSDX (v0.x) to the modern TSDX 2.0.\n\n## What's Changed\n\nTSDX 2.0 is a complete rewrite that replaces the original toolchain with modern, high-performance alternatives:\n\n| Old (v0.x) | New (v2.0) | Why |\n|------------|------------|-----|\n| Rollup + Babel | [bunchee](https://github.com/huozhi/bunchee) | Zero-config, SWC-powered, faster |\n| Jest | [vitest](https://vitest.dev/) | Vite-native, faster, Jest-compatible |\n| ESLint | [oxlint](https://oxc.rs/) | 50-100x faster, Rust-powered |\n| Prettier | [oxfmt](https://oxc.rs/) | 35x faster, Rust-powered |\n| yarn/npm | [bun](https://bun.sh/) | Faster installs and execution |\n| Node 10+ | Node 20+ | LTS only |\n\n---\n\n## Quick Migration\n\n### 1. Install Bun\n\n<Tabs items={['macOS/Linux', 'Windows']}>\n\n<Tab value=\"macOS/Linux\">\n```bash\ncurl -fsSL https://bun.sh/install | bash\n```\n</Tab>\n\n<Tab value=\"Windows\">\n```powershell\npowershell -c \"irm bun.sh/install.ps1 | iex\"\n```\n</Tab>\n\n</Tabs>\n\n### 2. Update package.json Scripts\n\nReplace your scripts:\n\n```json\n{\n  \"scripts\": {\n    \"dev\": \"tsdx dev\",\n    \"build\": \"tsdx build\",\n    \"test\": \"tsdx test\",\n    \"lint\": \"tsdx lint\",\n    \"format\": \"tsdx format\",\n    \"typecheck\": \"tsdx typecheck\",\n    \"prepublishOnly\": \"bun run build\"\n  }\n}\n```\n\n### 3. Update Dependencies\n\n```bash\n# Remove old dependencies\nbun remove tsdx rollup @rollup/plugin-* babel-* @babel/* jest ts-jest eslint @typescript-eslint/* prettier husky lint-staged\n\n# Add new tsdx\nbun add -D tsdx typescript\n```\n\n### 4. Replace Jest with Vitest\n\nCreate `vitest.config.ts`:\n\n```typescript\nimport { defineConfig } from 'vitest/config';\n\nexport default defineConfig({\n  test: {\n    globals: true,\n    environment: 'node', // or 'jsdom' for React/DOM testing\n  },\n});\n```\n\n### 5. Remove Old Config Files\n\nDelete these files (they're no longer needed):\n\n```bash\nrm -f tsdx.config.js\nrm -f jest.config.js\nrm -f .babelrc babel.config.js babel.config.json\nrm -f .eslintrc .eslintrc.js .eslintrc.json .eslintignore\nrm -f .prettierrc .prettierrc.js .prettierrc.json .prettierignore\nrm -f rollup.config.js\nrm -f yarn.lock package-lock.json\n```\n\n### 6. Update tsconfig.json\n\n```json\n{\n  \"compilerOptions\": {\n    \"target\": \"ES2022\",\n    \"module\": \"ESNext\",\n    \"moduleResolution\": \"bundler\",\n    \"lib\": [\"ES2022\", \"DOM\"],\n    \"strict\": true,\n    \"esModuleInterop\": true,\n    \"skipLibCheck\": true,\n    \"forceConsistentCasingInFileNames\": true,\n    \"declaration\": true,\n    \"declarationMap\": true,\n    \"outDir\": \"./dist\",\n    \"rootDir\": \"./src\",\n    \"resolveJsonModule\": true,\n    \"isolatedModules\": true,\n    \"noEmit\": true\n  },\n  \"include\": [\"src\"],\n  \"exclude\": [\"node_modules\", \"dist\"]\n}\n```\n\n### 7. Update package.json Exports\n\n```json\n{\n  \"type\": \"module\",\n  \"main\": \"./dist/index.cjs\",\n  \"module\": \"./dist/index.js\",\n  \"types\": \"./dist/index.d.ts\",\n  \"exports\": {\n    \".\": {\n      \"import\": {\n        \"types\": \"./dist/index.d.ts\",\n        \"default\": \"./dist/index.js\"\n      },\n      \"require\": {\n        \"types\": \"./dist/index.d.cts\",\n        \"default\": \"./dist/index.cjs\"\n      }\n    },\n    \"./package.json\": \"./package.json\"\n  },\n  \"files\": [\"dist\", \"src\"],\n  \"engines\": {\n    \"node\": \">=20\"\n  }\n}\n```\n\n### 8. Install and Test\n\n```bash\nbun install\nbun run test\nbun run build\nbun run lint\n```\n\n---\n\n## Jest to Vitest Migration\n\nMost Jest tests work with Vitest without changes. Here's a quick reference:\n\n| Jest | Vitest |\n|------|--------|\n| `jest.fn()` | `vi.fn()` |\n| `jest.mock()` | `vi.mock()` |\n| `jest.spyOn()` | `vi.spyOn()` |\n| `jest.useFakeTimers()` | `vi.useFakeTimers()` |\n| `beforeAll/afterAll` | Same |\n| `beforeEach/afterEach` | Same |\n| `describe/it/test` | Same |\n| `expect()` | Same |\n\nIf using globals (`globals: true` in vitest.config.ts), you don't need imports. Otherwise:\n\n```typescript\nimport { describe, it, expect, vi } from 'vitest';\n```\n\n---\n\n## Breaking Changes\n\n### Removed Features\n\n1. **Storybook template** - Use [Storybook CLI](https://storybook.js.org/docs/get-started/install) directly\n2. **Custom Rollup config** (`tsdx.config.js`) - Use bunchee config or raw rollup if needed\n3. **UMD builds** - Modern tooling focuses on ESM and CJS\n4. **Error extraction** - This feature has been removed\n5. **Node.js < 20** - Only Node.js 20+ (LTS) is supported\n\n### Changed Behavior\n\n1. **Build output** - Slightly different but compatible\n2. **Watch mode** - Now uses bunchee's watch\n3. **Test runner** - Vitest instead of Jest (mostly compatible API)\n4. **Default branch** - Uses `main` instead of `master` in templates\n\n---\n\n## Compatibility\n\n### Your Library Consumers\n\n**No changes needed!** The build output format is compatible:\n- ESM and CommonJS dual publish\n- TypeScript declarations\n- Same export patterns\n\n### Command Changes\n\n| Task | Old Command | New Command |\n|------|-------------|-------------|\n| Create project | `npx tsdx create mylib` | `bunx tsdx create mylib` |\n| Development | `yarn start` | `bun run dev` |\n| Build | `yarn build` | `bun run build` |\n| Test | `yarn test` | `bun run test` |\n| Lint | `yarn lint` | `bun run lint` |\n| Format | `yarn prettier --write .` | `bun run format` |\n\n---\n\n## Troubleshooting\n\n### \"bun: command not found\"\n\nInstall bun:\n\n```bash\ncurl -fsSL https://bun.sh/install | bash\n```\n\n### Tests fail with \"vi is not defined\"\n\nAdd vitest imports or enable globals:\n\n```typescript\n// Option 1: Add imports\nimport { describe, it, expect, vi } from 'vitest';\n\n// Option 2: Enable globals in vitest.config.ts\nexport default defineConfig({\n  test: { globals: true },\n});\n```\n\n### TypeScript errors with moduleResolution\n\nUpdate tsconfig.json:\n\n```json\n{\n  \"compilerOptions\": {\n    \"moduleResolution\": \"bundler\"\n  }\n}\n```\n\n### ESM/CJS interop issues\n\nEnsure your package.json has:\n\n```json\n{\n  \"type\": \"module\"\n}\n```\n\n---\n\n## Getting Help\n\n- [TSDX GitHub Issues](https://github.com/jaredpalmer/tsdx/issues)\n- [Vitest Documentation](https://vitest.dev/)\n- [bunchee Documentation](https://github.com/huozhi/bunchee)\n- [oxlint Documentation](https://oxc.rs/docs/guide/usage/linter.html)\n- [Bun Documentation](https://bun.sh/docs)\n"
  },
  {
    "path": "website/content/docs/project-structure.mdx",
    "content": "---\ntitle: Project Structure\ndescription: Understanding the structure of TSDX projects\n---\n\n# Project Structure\n\nProjects created with TSDX follow a consistent, well-organized structure.\n\n## Basic Template Structure\n\n```\nmylib/\n├── src/\n│   └── index.ts          # Library entry point\n├── test/\n│   └── index.test.ts     # Tests (vitest)\n├── dist/                  # Build output (generated)\n│   ├── index.js          # ESM\n│   ├── index.cjs         # CommonJS\n│   ├── index.d.ts        # TypeScript declarations\n│   └── index.d.cts       # CJS TypeScript declarations\n├── .github/\n│   └── workflows/\n│       └── main.yml      # CI/CD workflow\n├── package.json\n├── tsconfig.json\n├── vitest.config.ts\n├── LICENSE\n└── README.md\n```\n\n## React Template Structure\n\nThe React template includes everything from the basic template plus:\n\n```\nmylib/\n├── src/\n│   └── index.tsx         # React component entry\n├── test/\n│   └── index.test.tsx    # Tests with Testing Library\n├── example/              # Demo app (Vite-powered)\n│   ├── index.tsx         # Example app entry\n│   ├── index.html        # HTML template\n│   ├── package.json      # Example app dependencies\n│   └── vite.config.ts    # Vite configuration\n├── dist/\n├── .github/\n├── package.json\n├── tsconfig.json\n├── vitest.config.ts\n├── LICENSE\n└── README.md\n```\n\n---\n\n## Key Files\n\n### `src/index.ts` (or `src/index.tsx`)\n\nThe main entry point of your library. This is what gets exported when users import your package.\n\n```typescript\n// Basic library\nexport const sum = (a: number, b: number): number => {\n  return a + b;\n};\n\n// React component library\nexport { MyComponent } from './MyComponent';\nexport type { MyComponentProps } from './MyComponent';\n```\n\n### `package.json`\n\nContains your package configuration, dependencies, and scripts:\n\n```json\n{\n  \"name\": \"mylib\",\n  \"version\": \"0.1.0\",\n  \"type\": \"module\",\n  \"main\": \"./dist/index.cjs\",\n  \"module\": \"./dist/index.js\",\n  \"types\": \"./dist/index.d.ts\",\n  \"exports\": {\n    \".\": {\n      \"import\": {\n        \"types\": \"./dist/index.d.ts\",\n        \"default\": \"./dist/index.js\"\n      },\n      \"require\": {\n        \"types\": \"./dist/index.d.cts\",\n        \"default\": \"./dist/index.cjs\"\n      }\n    },\n    \"./package.json\": \"./package.json\"\n  },\n  \"files\": [\"dist\", \"src\"],\n  \"scripts\": {\n    \"dev\": \"tsdx dev\",\n    \"build\": \"tsdx build\",\n    \"test\": \"tsdx test\",\n    \"lint\": \"tsdx lint\",\n    \"format\": \"tsdx format\",\n    \"typecheck\": \"tsdx typecheck\",\n    \"prepublishOnly\": \"bun run build\"\n  }\n}\n```\n\n### `tsconfig.json`\n\nTypeScript configuration:\n\n```json\n{\n  \"compilerOptions\": {\n    \"target\": \"ES2022\",\n    \"module\": \"ESNext\",\n    \"moduleResolution\": \"bundler\",\n    \"strict\": true,\n    \"declaration\": true,\n    \"declarationMap\": true\n  }\n}\n```\n\n### `vitest.config.ts`\n\nTest configuration:\n\n```typescript\nimport { defineConfig } from 'vitest/config';\n\nexport default defineConfig({\n  test: {\n    globals: true,\n    environment: 'node',\n  },\n});\n```\n\n---\n\n## Module Formats\n\nTSDX outputs both ESM and CommonJS formats:\n\n| File | Format | Usage |\n|------|--------|-------|\n| `dist/index.js` | ESM | Modern bundlers, Node.js with `type: \"module\"` |\n| `dist/index.cjs` | CommonJS | Legacy Node.js, older bundlers |\n| `dist/index.d.ts` | TypeScript | ESM type definitions |\n| `dist/index.d.cts` | TypeScript | CJS type definitions |\n\n---\n\n## Adding More Entry Points\n\nYou can add multiple entry points by updating your `package.json` exports:\n\n```json\n{\n  \"exports\": {\n    \".\": {\n      \"import\": \"./dist/index.js\",\n      \"require\": \"./dist/index.cjs\"\n    },\n    \"./utils\": {\n      \"import\": \"./dist/utils.js\",\n      \"require\": \"./dist/utils.cjs\"\n    }\n  }\n}\n```\n\nThen create corresponding source files:\n\n```\nsrc/\n├── index.ts\n└── utils.ts\n```\n\nBunchee will automatically build all entry points defined in your exports.\n\n---\n\n## Best Practices\n\n1. **Keep `src/` focused** - Only include source code that should be bundled\n2. **Separate tests** - Keep tests in the `test/` directory\n3. **Use TypeScript** - Take advantage of type safety and declaration generation\n4. **Export types** - Always export TypeScript types alongside your code\n5. **Document with JSDoc** - Add JSDoc comments for better IDE support\n"
  },
  {
    "path": "website/content/docs/quick-start.mdx",
    "content": "---\ntitle: Quick Start\ndescription: Create your first TypeScript package in seconds\n---\n\n# Quick Start\n\nWith TSDX, you can quickly bootstrap a new TypeScript project in seconds, instead of hours.\n\n## Create a New Project\n\nOpen your terminal and run:\n\n```bash\nbunx tsdx create mylib\n```\n\nYou'll be prompted to choose from one of the available templates:\n\n| Template | Description |\n|----------|-------------|\n| `basic` | A basic TypeScript library with vitest |\n| `react` | A React component library with Testing Library |\n\nAfter you select one, TSDX will create a folder with the project template and install all dependencies.\n\n## Specifying a Template\n\nYou can skip the prompt by specifying the template directly:\n\n```bash\nbunx tsdx create mylib --template basic\n# or\nbunx tsdx create mylib --template react\n```\n\n## Start Developing\n\nOnce your project is created, navigate to the project folder:\n\n```bash\ncd mylib\n```\n\nStart the development server:\n\n```bash\nbun run dev\n```\n\nNow edit `src/index.ts` (or `src/index.tsx` for React) and see your changes rebuild automatically!\n\n## Available Commands\n\nInside your new project, you can run:\n\n```bash\nbun run dev       # Start development mode with watch\nbun run build     # Build for production\nbun run test      # Run tests with vitest\nbun run lint      # Lint with oxlint\nbun run format    # Format with oxfmt\nbun run typecheck # Type check with TypeScript\n```\n\n## Building for Production\n\nWhen you're ready to publish your package:\n\n```bash\nbun run build\n```\n\nThis outputs:\n- `dist/index.js` - ESM bundle\n- `dist/index.cjs` - CommonJS bundle\n- `dist/index.d.ts` - TypeScript declarations\n\n## Publishing\n\n```bash\n# Build the package\nbun run build\n\n# Publish to npm\nnpm publish\n```\n\nWe recommend using [np](https://github.com/sindresorhus/np) or [changesets](https://github.com/changesets/changesets) for a better publishing workflow.\n\n## Next Steps\n\n- Learn about all available [Commands](/docs/commands)\n- Explore [Project Templates](/docs/templates)\n- Understand the [Project Structure](/docs/project-structure)\n- Configure your project in [Configuration](/docs/configuration)\n"
  },
  {
    "path": "website/content/docs/templates.mdx",
    "content": "---\ntitle: Templates\ndescription: Available project templates in TSDX\n---\n\n# Templates\n\nTSDX provides project templates to help you get started quickly with different types of TypeScript packages.\n\n## Available Templates\n\n| Template | Description |\n|----------|-------------|\n| `basic` | A basic TypeScript library with vitest |\n| `react` | A React component library with Testing Library |\n\n## Basic Template\n\nThe basic template is perfect for any TypeScript library that doesn't require React.\n\n```bash\nbunx tsdx create mylib --template basic\n```\n\n### What's Included\n\n- TypeScript configuration\n- Vitest for testing\n- oxlint for linting\n- oxfmt for formatting\n- GitHub Actions CI workflow\n- MIT License\n- README with usage instructions\n\n### Project Structure\n\n```\nmylib/\n├── src/\n│   └── index.ts          # Library entry point\n├── test/\n│   └── index.test.ts     # Tests (vitest)\n├── dist/                  # Build output (generated)\n├── .github/\n│   └── workflows/        # CI/CD workflows\n├── package.json\n├── tsconfig.json\n├── vitest.config.ts\n├── LICENSE\n└── README.md\n```\n\n### Example Code\n\n```typescript\n// src/index.ts\nexport const sum = (a: number, b: number): number => {\n  return a + b;\n};\n```\n\n```typescript\n// test/index.test.ts\nimport { describe, expect, it } from 'vitest';\nimport { sum } from '../src';\n\ndescribe('sum', () => {\n  it('should add two numbers', () => {\n    expect(sum(1, 2)).toBe(3);\n  });\n});\n```\n\n---\n\n## React Template\n\nThe React template is designed for building React component libraries.\n\n```bash\nbunx tsdx create mylib --template react\n```\n\n### What's Included\n\nEverything from the basic template, plus:\n- React and React DOM\n- @testing-library/react for component testing\n- jsdom environment for vitest\n- Example Vite-powered playground\n\n### Project Structure\n\n```\nmylib/\n├── src/\n│   └── index.tsx         # React component entry\n├── test/\n│   └── index.test.tsx    # Tests with Testing Library\n├── example/              # Demo app (Vite-powered)\n│   ├── index.tsx\n│   ├── index.html\n│   ├── package.json\n│   └── vite.config.ts\n├── dist/                  # Build output (generated)\n├── package.json\n├── tsconfig.json\n├── vitest.config.ts\n├── LICENSE\n└── README.md\n```\n\n### Example Code\n\n```tsx\n// src/index.tsx\nimport React from 'react';\n\nexport interface MyComponentProps {\n  text: string;\n}\n\nexport const MyComponent: React.FC<MyComponentProps> = ({ text }) => {\n  return <div className=\"my-component\">{text}</div>;\n};\n```\n\n```tsx\n// test/index.test.tsx\nimport { describe, expect, it } from 'vitest';\nimport { render, screen } from '@testing-library/react';\nimport { MyComponent } from '../src';\n\ndescribe('MyComponent', () => {\n  it('renders text', () => {\n    render(<MyComponent text=\"Hello\" />);\n    expect(screen.getByText('Hello')).toBeDefined();\n  });\n});\n```\n\n### Running the Example\n\nThe React template includes a Vite-powered example app for developing and testing your components:\n\n```bash\ncd example\nbun install\nbun run dev\n```\n\nThis starts a development server where you can see your components in action.\n\n---\n\n## Creating Custom Templates\n\nWhile TSDX doesn't support custom templates out of the box, you can:\n\n1. Create a project with an existing template\n2. Customize it to your needs\n3. Use it as a boilerplate for future projects\n\nAlternatively, you can use `tsdx init` to add TSDX configuration to any existing project.\n"
  },
  {
    "path": "website/lib/source.ts",
    "content": "import { docs, meta } from 'fumadocs-mdx:collections/server';\nimport { toFumadocsSource } from 'fumadocs-mdx/runtime/server';\nimport { loader } from 'fumadocs-core/source';\n\nexport const source = loader({\n  baseUrl: '/docs',\n  source: toFumadocsSource(docs, meta),\n});\n"
  },
  {
    "path": "website/mdx-components.tsx",
    "content": "import type { MDXComponents } from 'mdx/types';\nimport defaultComponents from 'fumadocs-ui/mdx';\n\nexport function useMDXComponents(components: MDXComponents): MDXComponents {\n  return {\n    ...defaultComponents,\n    ...components,\n  };\n}\n"
  },
  {
    "path": "website/next.config.mjs",
    "content": "import { createMDX } from 'fumadocs-mdx/next';\n\nconst withMDX = createMDX();\n\n/** @type {import('next').NextConfig} */\nconst config = {\n  reactStrictMode: true,\n  experimental: {\n    turbopackUseSystemTlsCerts: true,\n  },\n};\n\nexport default withMDX(config);\n"
  },
  {
    "path": "website/package.json",
    "content": "{\n  \"name\": \"tsdx-docs\",\n  \"version\": \"1.0.0\",\n  \"private\": true,\n  \"scripts\": {\n    \"dev\": \"next dev\",\n    \"build\": \"next build\",\n    \"start\": \"next start\"\n  },\n  \"dependencies\": {\n    \"@tailwindcss/postcss\": \"^4.1.18\",\n    \"fumadocs-core\": \"^16.4.1\",\n    \"fumadocs-mdx\": \"^14.2.3\",\n    \"fumadocs-ui\": \"^16.4.1\",\n    \"next\": \"^16.1.1\",\n    \"react\": \"^19.2.3\",\n    \"react-dom\": \"^19.2.3\"\n  },\n  \"devDependencies\": {\n    \"@types/mdx\": \"^2.0.13\",\n    \"@types/node\": \"^22.10.2\",\n    \"@types/react\": \"^19.2.7\",\n    \"@types/react-dom\": \"^19.2.3\",\n    \"autoprefixer\": \"^10.4.20\",\n    \"postcss\": \"^8.4.49\",\n    \"tailwindcss\": \"^4.1.18\",\n    \"typescript\": \"^5.7.2\"\n  }\n}\n"
  },
  {
    "path": "website/postcss.config.js",
    "content": "module.exports = {\n  plugins: {\n    '@tailwindcss/postcss': {},\n  },\n};\n"
  },
  {
    "path": "website/public/favicon/site.webmanifest",
    "content": "{\n  \"name\": \"TSDX\",\n  \"short_name\": \"TSDX\",\n  \"icons\": [\n    {\n      \"src\": \"/android-chrome-192x192.png\",\n      \"sizes\": \"192x192\",\n      \"type\": \"image/png\"\n    },\n    {\n      \"src\": \"/android-chrome-512x512.png\",\n      \"sizes\": \"512x512\",\n      \"type\": \"image/png\"\n    }\n  ],\n  \"theme_color\": \"#ffffff\",\n  \"background_color\": \"#ffffff\",\n  \"display\": \"standalone\"\n}\n"
  },
  {
    "path": "website/source.config.ts",
    "content": "import { defineConfig, defineDocs } from 'fumadocs-mdx/config';\n\nexport const { docs, meta } = defineDocs({\n  dir: 'content/docs',\n});\n\nexport default defineConfig();\n"
  },
  {
    "path": "website/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"lib\": [\n      \"dom\",\n      \"dom.iterable\",\n      \"esnext\"\n    ],\n    \"allowJs\": true,\n    \"skipLibCheck\": true,\n    \"strict\": true,\n    \"noEmit\": true,\n    \"esModuleInterop\": true,\n    \"module\": \"esnext\",\n    \"moduleResolution\": \"bundler\",\n    \"resolveJsonModule\": true,\n    \"isolatedModules\": true,\n    \"jsx\": \"react-jsx\",\n    \"incremental\": true,\n    \"plugins\": [\n      {\n        \"name\": \"next\"\n      }\n    ],\n    \"paths\": {\n      \"@/*\": [\n        \"./*\"\n      ],\n      \"fumadocs-mdx:collections/*\": [\n        \"./.source/*\"\n      ]\n    },\n    \"target\": \"ES2017\"\n  },\n  \"include\": [\n    \"next-env.d.ts\",\n    \"**/*.ts\",\n    \"**/*.tsx\",\n    \".next/types/**/*.ts\",\n    \".source/**/*.ts\",\n    \".next/dev/types/**/*.ts\"\n  ],\n  \"exclude\": [\n    \"node_modules\"\n  ]\n}\n"
  },
  {
    "path": "website/vercel.json",
    "content": "{\n  \"framework\": \"nextjs\",\n  \"installCommand\": \"bun install\",\n  \"buildCommand\": \"bun run build\"\n}\n"
  }
]