Full Code of dinerojs/dinero.js for AI

main 78b9d443cec6 cached
573 files
1.2 MB
349.9k tokens
653 symbols
1 requests
Download .txt
Showing preview only (1,371K chars total). Download the full file or copy to clipboard to get everything.
Repository: dinerojs/dinero.js
Branch: main
Commit: 78b9d443cec6
Files: 573
Total size: 1.2 MB

Directory structure:
gitextract_430igyon/

├── .agents/
│   └── skills/
│       ├── dinero-best-practices/
│       │   ├── SKILL.md
│       │   └── rules/
│       │       ├── arithmetic-allocate-not-divide.md
│       │       ├── arithmetic-immutability.md
│       │       ├── arithmetic-percentages.md
│       │       ├── arithmetic-scaled-amounts.md
│       │       ├── creation-from-floats.md
│       │       ├── creation-minor-units.md
│       │       ├── creation-zero-exponent.md
│       │       ├── imports-bigint-currencies.md
│       │       ├── imports-tree-shaking.md
│       │       ├── precision-bigint.md
│       │       ├── precision-crypto.md
│       │       └── precision-trim-scale.md
│       ├── dinero-currency-patterns/
│       │   ├── SKILL.md
│       │   └── rules/
│       │       ├── convert-reusable.md
│       │       ├── convert-scaled-rates.md
│       │       ├── payment-services.md
│       │       ├── storage-database.md
│       │       ├── storage-no-money-type.md
│       │       ├── types-as-const.md
│       │       ├── types-currency-mismatch.md
│       │       └── types-lookup-validation.md
│       ├── dinero-formatting/
│       │   ├── SKILL.md
│       │   └── rules/
│       │       ├── display-no-currency-symbols.md
│       │       ├── display-to-decimal.md
│       │       ├── locale-intl-formatter.md
│       │       ├── locale-multilingual.md
│       │       ├── nondecimal-to-units.md
│       │       ├── serialization-bigint-json.md
│       │       └── serialization-snapshot.md
│       ├── tsdown/
│       │   ├── SKILL.md
│       │   └── references/
│       │       ├── advanced-ci.md
│       │       ├── advanced-hooks.md
│       │       ├── advanced-plugins.md
│       │       ├── advanced-programmatic.md
│       │       ├── advanced-rolldown-options.md
│       │       ├── guide-getting-started.md
│       │       ├── guide-migrate-from-tsup.md
│       │       ├── option-cjs-default.md
│       │       ├── option-cleaning.md
│       │       ├── option-config-file.md
│       │       ├── option-css.md
│       │       ├── option-dependencies.md
│       │       ├── option-dts.md
│       │       ├── option-entry.md
│       │       ├── option-lint.md
│       │       ├── option-log-level.md
│       │       ├── option-minification.md
│       │       ├── option-output-directory.md
│       │       ├── option-output-format.md
│       │       ├── option-package-exports.md
│       │       ├── option-platform.md
│       │       ├── option-shims.md
│       │       ├── option-sourcemap.md
│       │       ├── option-target.md
│       │       ├── option-tree-shaking.md
│       │       ├── option-unbundle.md
│       │       ├── option-watch-mode.md
│       │       ├── recipe-react.md
│       │       ├── recipe-vue.md
│       │       ├── recipe-wasm.md
│       │       └── reference-cli.md
│       ├── vercel-composition-patterns/
│       │   ├── AGENTS.md
│       │   ├── README.md
│       │   ├── SKILL.md
│       │   └── rules/
│       │       ├── architecture-avoid-boolean-props.md
│       │       ├── architecture-compound-components.md
│       │       ├── patterns-children-over-render-props.md
│       │       ├── patterns-explicit-variants.md
│       │       ├── react19-no-forwardref.md
│       │       ├── state-context-interface.md
│       │       ├── state-decouple-implementation.md
│       │       └── state-lift-state.md
│       ├── vercel-react-best-practices/
│       │   ├── AGENTS.md
│       │   ├── README.md
│       │   ├── SKILL.md
│       │   └── rules/
│       │       ├── advanced-event-handler-refs.md
│       │       ├── advanced-init-once.md
│       │       ├── advanced-use-latest.md
│       │       ├── async-api-routes.md
│       │       ├── async-defer-await.md
│       │       ├── async-dependencies.md
│       │       ├── async-parallel.md
│       │       ├── async-suspense-boundaries.md
│       │       ├── bundle-barrel-imports.md
│       │       ├── bundle-conditional.md
│       │       ├── bundle-defer-third-party.md
│       │       ├── bundle-dynamic-imports.md
│       │       ├── bundle-preload.md
│       │       ├── client-event-listeners.md
│       │       ├── client-localstorage-schema.md
│       │       ├── client-passive-event-listeners.md
│       │       ├── client-swr-dedup.md
│       │       ├── js-batch-dom-css.md
│       │       ├── js-cache-function-results.md
│       │       ├── js-cache-property-access.md
│       │       ├── js-cache-storage.md
│       │       ├── js-combine-iterations.md
│       │       ├── js-early-exit.md
│       │       ├── js-hoist-regexp.md
│       │       ├── js-index-maps.md
│       │       ├── js-length-check-first.md
│       │       ├── js-min-max-loop.md
│       │       ├── js-set-map-lookups.md
│       │       ├── js-tosorted-immutable.md
│       │       ├── rendering-activity.md
│       │       ├── rendering-animate-svg-wrapper.md
│       │       ├── rendering-conditional-render.md
│       │       ├── rendering-content-visibility.md
│       │       ├── rendering-hoist-jsx.md
│       │       ├── rendering-hydration-no-flicker.md
│       │       ├── rendering-hydration-suppress-warning.md
│       │       ├── rendering-svg-precision.md
│       │       ├── rendering-usetransition-loading.md
│       │       ├── rerender-defer-reads.md
│       │       ├── rerender-dependencies.md
│       │       ├── rerender-derived-state-no-effect.md
│       │       ├── rerender-derived-state.md
│       │       ├── rerender-functional-setstate.md
│       │       ├── rerender-lazy-state-init.md
│       │       ├── rerender-memo-with-default-value.md
│       │       ├── rerender-memo.md
│       │       ├── rerender-move-effect-to-event.md
│       │       ├── rerender-simple-expression-in-memo.md
│       │       ├── rerender-transitions.md
│       │       ├── rerender-use-ref-transient-values.md
│       │       ├── server-after-nonblocking.md
│       │       ├── server-auth-actions.md
│       │       ├── server-cache-lru.md
│       │       ├── server-cache-react.md
│       │       ├── server-dedup-props.md
│       │       ├── server-parallel-fetching.md
│       │       └── server-serialization.md
│       └── web-design-guidelines/
│           └── SKILL.md
├── .browserslistrc
├── .claude/
│   ├── docs/
│   │   ├── architecture.md
│   │   ├── git-workflow.md
│   │   └── linear.md
│   └── skills/
│       └── commit/
│           └── SKILL.md
├── .editorconfig
├── .gitattributes
├── .github/
│   ├── CODEOWNERS
│   ├── ISSUE_TEMPLATE/
│   │   └── BUG.yml
│   ├── semantic.yml
│   └── workflows/
│       ├── ci.yml
│       └── release.yml
├── .gitignore
├── .husky/
│   └── pre-commit
├── .npmrc
├── .nvmrc
├── .oxlintrc.json
├── .prettierignore
├── .prettierrc
├── .size-limit.json
├── .vscode/
│   ├── launch.json
│   └── settings.json
├── CHANGELOG.md
├── CLAUDE.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── docs/
│   ├── .vitepress/
│   │   ├── config.ts
│   │   └── theme/
│   │       ├── HomeFeatures.vue
│   │       ├── HomeHero.vue
│   │       ├── NotFound.vue
│   │       ├── index.ts
│   │       └── style.css
│   ├── about.md
│   ├── agent-skills.md
│   ├── api/
│   │   ├── comparisons/
│   │   │   ├── compare.md
│   │   │   ├── equal.md
│   │   │   ├── greater-than-or-equal.md
│   │   │   ├── greater-than.md
│   │   │   ├── has-sub-units.md
│   │   │   ├── have-same-amount.md
│   │   │   ├── have-same-currency.md
│   │   │   ├── is-negative.md
│   │   │   ├── is-positive.md
│   │   │   ├── is-zero.md
│   │   │   ├── less-than-or-equal.md
│   │   │   ├── less-than.md
│   │   │   ├── maximum.md
│   │   │   └── minimum.md
│   │   ├── conversions/
│   │   │   ├── convert.md
│   │   │   ├── normalize-scale.md
│   │   │   ├── transform-scale.md
│   │   │   └── trim-scale.md
│   │   ├── currencies.md
│   │   ├── dinero.md
│   │   ├── formatting/
│   │   │   ├── to-decimal.md
│   │   │   ├── to-snapshot.md
│   │   │   └── to-units.md
│   │   ├── mutations/
│   │   │   ├── add.md
│   │   │   ├── allocate.md
│   │   │   ├── multiply.md
│   │   │   └── subtract.md
│   │   └── rounding/
│   │       ├── down.md
│   │       ├── half-away-from-zero.md
│   │       ├── half-down.md
│   │       ├── half-even.md
│   │       ├── half-odd.md
│   │       ├── half-towards-zero.md
│   │       ├── half-up.md
│   │       └── up.md
│   ├── build-examples.sh
│   ├── core-concepts/
│   │   ├── amount.md
│   │   ├── comparisons.md
│   │   ├── currency.md
│   │   ├── formatting.md
│   │   ├── mutations.md
│   │   └── scale.md
│   ├── demos.md
│   ├── faq/
│   │   ├── can-i-multiply-by-a-decimal.md
│   │   ├── how-to-look-up-a-currency-by-code.md
│   │   ├── why-cant-i-use-currencies-with-bigint.md
│   │   ├── why-functions-instead-of-methods.md
│   │   └── why-no-currency-formatting.md
│   ├── getting-started/
│   │   ├── compatibility.md
│   │   ├── optimizing-for-production.md
│   │   ├── quick-start.md
│   │   └── upgrade-guide.md
│   ├── guides/
│   │   ├── calculating-percentages.md
│   │   ├── creating-from-floats.md
│   │   ├── cryptocurrencies.md
│   │   ├── currency-type-safety.md
│   │   ├── formatting-in-a-multilingual-site.md
│   │   ├── formatting-non-decimal-currencies.md
│   │   ├── integrating-with-payment-services.md
│   │   ├── precision-and-large-numbers.md
│   │   ├── storing-in-a-database.md
│   │   └── transporting-and-restoring.md
│   ├── index.md
│   ├── package.json
│   └── vercel.json
├── examples/
│   ├── cart-react/
│   │   ├── .gitignore
│   │   ├── README.md
│   │   ├── index.html
│   │   ├── package.json
│   │   ├── postcss.config.js
│   │   ├── src/
│   │   │   ├── App.tsx
│   │   │   ├── components/
│   │   │   │   ├── cart-line.tsx
│   │   │   │   └── order-summary.tsx
│   │   │   ├── data/
│   │   │   │   ├── index.ts
│   │   │   │   ├── items.json
│   │   │   │   └── shipping.json
│   │   │   ├── index.css
│   │   │   ├── lib/
│   │   │   │   └── money.ts
│   │   │   ├── main.tsx
│   │   │   └── types/
│   │   │       └── index.ts
│   │   ├── tsconfig.json
│   │   └── vite.config.ts
│   ├── cart-vue/
│   │   ├── .gitignore
│   │   ├── README.md
│   │   ├── env.d.ts
│   │   ├── index.html
│   │   ├── package.json
│   │   ├── postcss.config.js
│   │   ├── src/
│   │   │   ├── App.vue
│   │   │   ├── components/
│   │   │   │   ├── CartLine.vue
│   │   │   │   └── OrderSummary.vue
│   │   │   ├── data/
│   │   │   │   ├── index.ts
│   │   │   │   ├── items.json
│   │   │   │   └── shipping.json
│   │   │   ├── index.css
│   │   │   ├── lib/
│   │   │   │   └── money.ts
│   │   │   ├── main.ts
│   │   │   └── types/
│   │   │       └── index.ts
│   │   ├── tsconfig.app.json
│   │   ├── tsconfig.json
│   │   └── vite.config.ts
│   ├── expense-splitter/
│   │   ├── .gitignore
│   │   ├── README.md
│   │   ├── index.html
│   │   ├── package.json
│   │   ├── postcss.config.js
│   │   ├── src/
│   │   │   ├── App.tsx
│   │   │   ├── components/
│   │   │   │   ├── add-expense.tsx
│   │   │   │   ├── add-person.tsx
│   │   │   │   ├── balances.tsx
│   │   │   │   ├── expense-list.tsx
│   │   │   │   ├── index.ts
│   │   │   │   ├── person-list.tsx
│   │   │   │   └── settlements.tsx
│   │   │   ├── index.css
│   │   │   ├── lib/
│   │   │   │   └── money.ts
│   │   │   ├── main.tsx
│   │   │   ├── types/
│   │   │   │   └── index.ts
│   │   │   └── vite-env.d.ts
│   │   ├── tsconfig.json
│   │   └── vite.config.ts
│   ├── invoice-builder/
│   │   ├── .gitignore
│   │   ├── README.md
│   │   ├── index.html
│   │   ├── package.json
│   │   ├── postcss.config.js
│   │   ├── src/
│   │   │   ├── App.tsx
│   │   │   ├── components/
│   │   │   │   ├── editor-panel.tsx
│   │   │   │   └── preview-panel.tsx
│   │   │   ├── hooks/
│   │   │   │   └── use-invoice.ts
│   │   │   ├── index.css
│   │   │   ├── lib/
│   │   │   │   ├── invoice-types.ts
│   │   │   │   └── money.ts
│   │   │   ├── main.tsx
│   │   │   └── vite-env.d.ts
│   │   ├── tsconfig.json
│   │   └── vite.config.ts
│   ├── portfolio-tracker/
│   │   ├── README.md
│   │   ├── index.html
│   │   ├── package.json
│   │   ├── postcss.config.js
│   │   ├── src/
│   │   │   ├── App.tsx
│   │   │   ├── components/
│   │   │   │   ├── breakdown-bar.tsx
│   │   │   │   ├── dashboard.tsx
│   │   │   │   ├── exchange-rates.tsx
│   │   │   │   ├── holding-card.tsx
│   │   │   │   ├── holdings-editor.tsx
│   │   │   │   ├── holdings-table.tsx
│   │   │   │   └── summary-cards.tsx
│   │   │   ├── hooks/
│   │   │   │   └── use-portfolio.ts
│   │   │   ├── index.css
│   │   │   ├── lib/
│   │   │   │   ├── money.ts
│   │   │   │   └── types.ts
│   │   │   └── main.tsx
│   │   ├── tsconfig.json
│   │   └── vite.config.ts
│   └── pricing-react/
│       ├── .gitignore
│       ├── README.md
│       ├── index.html
│       ├── package.json
│       ├── postcss.config.js
│       ├── src/
│       │   ├── App.tsx
│       │   ├── components/
│       │   │   ├── pricing-toggle.tsx
│       │   │   ├── seat-slider.tsx
│       │   │   └── tier-card.tsx
│       │   ├── data/
│       │   │   ├── index.ts
│       │   │   └── items.json
│       │   ├── index.css
│       │   ├── lib/
│       │   │   └── money.ts
│       │   ├── main.tsx
│       │   └── types/
│       │       └── index.ts
│       ├── tsconfig.json
│       └── vite.config.ts
├── global.d.ts
├── lint-staged.config.cjs
├── package.json
├── packages/
│   └── dinero.js/
│       ├── README.md
│       ├── package.json
│       ├── src/
│       │   ├── __tests__/
│       │   │   ├── currency-safety.typetest.ts
│       │   │   └── dinero.test.ts
│       │   ├── api/
│       │   │   ├── __tests__/
│       │   │   │   ├── add.test.ts
│       │   │   │   ├── allocate.test.ts
│       │   │   │   ├── compare.test.ts
│       │   │   │   ├── convert.test.ts
│       │   │   │   ├── equal.test.ts
│       │   │   │   ├── greaterThan.test.ts
│       │   │   │   ├── greaterThanOrEqual.test.ts
│       │   │   │   ├── hasSubUnits.test.ts
│       │   │   │   ├── haveSameAmount.test.ts
│       │   │   │   ├── haveSameCurrency.test.ts
│       │   │   │   ├── isNegative.test.ts
│       │   │   │   ├── isPositive.test.ts
│       │   │   │   ├── isZero.test.ts
│       │   │   │   ├── lessThan.test.ts
│       │   │   │   ├── lessThanOrEqual.test.ts
│       │   │   │   ├── maximum.test.ts
│       │   │   │   ├── minimum.test.ts
│       │   │   │   ├── multiply.test.ts
│       │   │   │   ├── normalizeScale.test.ts
│       │   │   │   ├── subtract.test.ts
│       │   │   │   ├── toDecimal.test.ts
│       │   │   │   ├── toSnapshot.test.ts
│       │   │   │   ├── toUnits.test.ts
│       │   │   │   ├── transformScale.test.ts
│       │   │   │   └── trimScale.test.ts
│       │   │   ├── add.ts
│       │   │   ├── allocate.ts
│       │   │   ├── compare.ts
│       │   │   ├── convert.ts
│       │   │   ├── equal.ts
│       │   │   ├── greaterThan.ts
│       │   │   ├── greaterThanOrEqual.ts
│       │   │   ├── hasSubUnits.ts
│       │   │   ├── haveSameAmount.ts
│       │   │   ├── haveSameCurrency.ts
│       │   │   ├── index.ts
│       │   │   ├── isNegative.ts
│       │   │   ├── isPositive.ts
│       │   │   ├── isZero.ts
│       │   │   ├── lessThan.ts
│       │   │   ├── lessThanOrEqual.ts
│       │   │   ├── maximum.ts
│       │   │   ├── minimum.ts
│       │   │   ├── multiply.ts
│       │   │   ├── normalizeScale.ts
│       │   │   ├── subtract.ts
│       │   │   ├── toDecimal.ts
│       │   │   ├── toSnapshot.ts
│       │   │   ├── toUnits.ts
│       │   │   ├── transformScale.ts
│       │   │   └── trimScale.ts
│       │   ├── bigint/
│       │   │   ├── currencies/
│       │   │   │   ├── index.ts
│       │   │   │   └── iso4217.ts
│       │   │   ├── dinero.ts
│       │   │   └── index.ts
│       │   ├── calculator/
│       │   │   ├── bigint/
│       │   │   │   ├── api/
│       │   │   │   │   ├── __tests__/
│       │   │   │   │   │   ├── add.test.ts
│       │   │   │   │   │   ├── compare.test.ts
│       │   │   │   │   │   ├── decrement.test.ts
│       │   │   │   │   │   ├── increment.test.ts
│       │   │   │   │   │   ├── integerDivide.test.ts
│       │   │   │   │   │   ├── modulo.test.ts
│       │   │   │   │   │   ├── multiply.test.ts
│       │   │   │   │   │   ├── power.test.ts
│       │   │   │   │   │   ├── subtract.test.ts
│       │   │   │   │   │   └── zero.test.ts
│       │   │   │   │   ├── add.ts
│       │   │   │   │   ├── compare.ts
│       │   │   │   │   ├── decrement.ts
│       │   │   │   │   ├── increment.ts
│       │   │   │   │   ├── index.ts
│       │   │   │   │   ├── integerDivide.ts
│       │   │   │   │   ├── modulo.ts
│       │   │   │   │   ├── multiply.ts
│       │   │   │   │   ├── power.ts
│       │   │   │   │   ├── subtract.ts
│       │   │   │   │   └── zero.ts
│       │   │   │   ├── calculator.ts
│       │   │   │   └── index.ts
│       │   │   └── number/
│       │   │       ├── api/
│       │   │       │   ├── __tests__/
│       │   │       │   │   ├── add.test.ts
│       │   │       │   │   ├── compare.test.ts
│       │   │       │   │   ├── decrement.test.ts
│       │   │       │   │   ├── increment.test.ts
│       │   │       │   │   ├── integerDivide.test.ts
│       │   │       │   │   ├── modulo.test.ts
│       │   │       │   │   ├── multiply.test.ts
│       │   │       │   │   ├── power.test.ts
│       │   │       │   │   ├── subtract.test.ts
│       │   │       │   │   └── zero.test.ts
│       │   │       │   ├── add.ts
│       │   │       │   ├── compare.ts
│       │   │       │   ├── decrement.ts
│       │   │       │   ├── increment.ts
│       │   │       │   ├── index.ts
│       │   │       │   ├── integerDivide.ts
│       │   │       │   ├── modulo.ts
│       │   │       │   ├── multiply.ts
│       │   │       │   ├── power.ts
│       │   │       │   ├── subtract.ts
│       │   │       │   └── zero.ts
│       │   │       ├── calculator.ts
│       │   │       └── index.ts
│       │   ├── core/
│       │   │   ├── api/
│       │   │   │   ├── add.ts
│       │   │   │   ├── allocate.ts
│       │   │   │   ├── compare.ts
│       │   │   │   ├── convert.ts
│       │   │   │   ├── equal.ts
│       │   │   │   ├── greaterThan.ts
│       │   │   │   ├── greaterThanOrEqual.ts
│       │   │   │   ├── hasSubUnits.ts
│       │   │   │   ├── haveSameAmount.ts
│       │   │   │   ├── haveSameCurrency.ts
│       │   │   │   ├── index.ts
│       │   │   │   ├── isNegative.ts
│       │   │   │   ├── isPositive.ts
│       │   │   │   ├── isZero.ts
│       │   │   │   ├── lessThan.ts
│       │   │   │   ├── lessThanOrEqual.ts
│       │   │   │   ├── maximum.ts
│       │   │   │   ├── minimum.ts
│       │   │   │   ├── multiply.ts
│       │   │   │   ├── normalizeScale.ts
│       │   │   │   ├── subtract.ts
│       │   │   │   ├── toDecimal.ts
│       │   │   │   ├── toSnapshot.ts
│       │   │   │   ├── toUnits.ts
│       │   │   │   ├── transformScale.ts
│       │   │   │   └── trimScale.ts
│       │   │   ├── checks/
│       │   │   │   ├── index.ts
│       │   │   │   └── messages.ts
│       │   │   ├── divide/
│       │   │   │   ├── __tests__/
│       │   │   │   │   ├── down.test.ts
│       │   │   │   │   ├── halfAwayFromZero.test.ts
│       │   │   │   │   ├── halfDown.test.ts
│       │   │   │   │   ├── halfEven.test.ts
│       │   │   │   │   ├── halfOdd.test.ts
│       │   │   │   │   ├── halfTowardsZero.test.ts
│       │   │   │   │   ├── halfUp.test.ts
│       │   │   │   │   └── up.test.ts
│       │   │   │   ├── down.ts
│       │   │   │   ├── halfAwayFromZero.ts
│       │   │   │   ├── halfDown.ts
│       │   │   │   ├── halfEven.ts
│       │   │   │   ├── halfOdd.ts
│       │   │   │   ├── halfTowardsZero.ts
│       │   │   │   ├── halfUp.ts
│       │   │   │   ├── index.ts
│       │   │   │   └── up.ts
│       │   │   ├── helpers/
│       │   │   │   ├── __tests__/
│       │   │   │   │   └── assert.test.ts
│       │   │   │   ├── assert.ts
│       │   │   │   ├── createDinero.ts
│       │   │   │   └── index.ts
│       │   │   ├── index.ts
│       │   │   ├── types/
│       │   │   │   ├── Dinero.ts
│       │   │   │   ├── DineroBinaryOperation.ts
│       │   │   │   ├── DineroCalculator.ts
│       │   │   │   ├── DineroDivideOperation.ts
│       │   │   │   ├── DineroFactory.ts
│       │   │   │   ├── DineroFormatter.ts
│       │   │   │   ├── DineroOptions.ts
│       │   │   │   ├── DineroRates.ts
│       │   │   │   ├── DineroScaledAmount.ts
│       │   │   │   ├── DineroSnapshot.ts
│       │   │   │   ├── DineroTransformer.ts
│       │   │   │   ├── DineroUnaryOperation.ts
│       │   │   │   └── index.ts
│       │   │   └── utils/
│       │   │       ├── __tests__/
│       │   │       │   ├── absolute.test.ts
│       │   │       │   ├── compare.test.ts
│       │   │       │   ├── computeBase.test.ts
│       │   │       │   ├── countTrailingZeros.test.ts
│       │   │       │   ├── distribute.test.ts
│       │   │       │   ├── equal.test.ts
│       │   │       │   ├── getAmountAndScale.test.ts
│       │   │       │   ├── getDivisors.test.ts
│       │   │       │   ├── greaterThan.test.ts
│       │   │       │   ├── greaterThanOrEqual.test.ts
│       │   │       │   ├── isArray.test.ts
│       │   │       │   ├── isEven.test.ts
│       │   │       │   ├── isHalf.test.ts
│       │   │       │   ├── isScaledAmount.test.ts
│       │   │       │   ├── lessThan.test.ts
│       │   │       │   ├── lessThanOrEqual.test.ts
│       │   │       │   ├── maximum.test.ts
│       │   │       │   ├── minimum.test.ts
│       │   │       │   └── sign.test.ts
│       │   │       ├── absolute.ts
│       │   │       ├── compare.ts
│       │   │       ├── computeBase.ts
│       │   │       ├── countTrailingZeros.ts
│       │   │       ├── distribute.ts
│       │   │       ├── equal.ts
│       │   │       ├── getAmountAndScale.ts
│       │   │       ├── getDivisors.ts
│       │   │       ├── greaterThan.ts
│       │   │       ├── greaterThanOrEqual.ts
│       │   │       ├── index.ts
│       │   │       ├── isArray.ts
│       │   │       ├── isEven.ts
│       │   │       ├── isHalf.ts
│       │   │       ├── isScaledAmount.ts
│       │   │       ├── lessThan.ts
│       │   │       ├── lessThanOrEqual.ts
│       │   │       ├── maximum.ts
│       │   │       ├── minimum.ts
│       │   │       └── sign.ts
│       │   ├── currencies/
│       │   │   ├── index.ts
│       │   │   ├── iso4217.ts
│       │   │   └── types/
│       │   │       ├── DineroCurrency.ts
│       │   │       └── index.ts
│       │   ├── dinero.ts
│       │   └── index.ts
│       ├── tsconfig.json
│       └── tsdown.config.ts
├── renovate.json
├── ship.config.cjs
├── skills-lock.json
├── test/
│   └── utils/
│       ├── castToBigintCurrency.ts
│       ├── castToBigjsCurrency.ts
│       ├── createBigintDinero.ts
│       ├── createBigjsDinero.ts
│       ├── createNumberDinero.ts
│       └── index.ts
├── tsconfig.json
├── turbo.json
└── vitest.config.ts

================================================
FILE CONTENTS
================================================

================================================
FILE: .agents/skills/dinero-best-practices/SKILL.md
================================================
---
name: dinero-best-practices
description: >
  Core best practices for the Dinero.js money library. Use when writing,
  reviewing, or refactoring code that creates Dinero objects, performs
  arithmetic on monetary values, or handles money in JavaScript/TypeScript.
  Triggers on imports from 'dinero.js', monetary calculations, or price/cost
  handling logic.
license: MIT
metadata:
  author: dinerojs
  version: '1.0.0'
---

# Dinero.js Best Practices

Core rules for working with [Dinero.js](https://v2.dinerojs.com), the JavaScript/TypeScript library for creating, calculating, and formatting money safely. Contains rules across 4 categories, prioritized by impact.

## When to Apply

Reference these guidelines when:

- Creating Dinero objects from user input, API responses, or database values
- Performing arithmetic on monetary values (adding, splitting, multiplying)
- Choosing between `number` and `bigint` calculators
- Importing from `dinero.js`, `dinero.js/currencies`, or `dinero.js/bigint`
- Working with prices, costs, taxes, or any financial calculation

## Rule Categories by Priority

| Priority | Category        | Impact   | Prefix        |
| -------- | --------------- | -------- | ------------- |
| 1        | Object Creation | CRITICAL | `creation-`   |
| 2        | Arithmetic      | CRITICAL | `arithmetic-` |
| 3        | Precision       | HIGH     | `precision-`  |
| 4        | Imports         | MEDIUM   | `imports-`    |

## Quick Reference

### 1. Object Creation (CRITICAL)

- `creation-minor-units` - Always pass amounts as integers in minor currency units
- `creation-from-floats` - Use a helper to convert float inputs to minor units
- `creation-zero-exponent` - Currencies with exponent 0 (e.g., JPY) take major units directly

### 2. Arithmetic (CRITICAL)

- `arithmetic-immutability` - All operations return new objects; capture the return value
- `arithmetic-allocate-not-divide` - Use `allocate` for splitting money, not manual division
- `arithmetic-scaled-amounts` - Never multiply by a raw decimal; use scaled amounts
- `arithmetic-percentages` - Calculate percentages with `allocate` or scaled `multiply`

### 3. Precision (HIGH)

- `precision-bigint` - Use `dinero.js/bigint` for amounts exceeding `Number.MAX_SAFE_INTEGER`
- `precision-crypto` - Cryptocurrencies require bigint due to high exponents
- `precision-trim-scale` - Use `trimScale` to remove trailing zeros after chained operations

### 4. Imports (MEDIUM)

- `imports-tree-shaking` - Import only what you use; standalone functions enable tree-shaking
- `imports-bigint-currencies` - Match calculator type: use `dinero.js/bigint/currencies` with `dinero.js/bigint`

## How to Use

Read individual rule files for detailed explanations and code examples:

```
rules/creation-minor-units.md
rules/arithmetic-allocate-not-divide.md
```

Each rule file contains:

- Brief explanation of why it matters
- Incorrect code example with explanation
- Correct code example with explanation
- Additional context and references


================================================
FILE: .agents/skills/dinero-best-practices/rules/arithmetic-allocate-not-divide.md
================================================
---
title: Use allocate for Splitting Money, Not Manual Division
impact: CRITICAL
impactDescription: prevents lost cents from rounding
tags: arithmetic, allocate, division, remainder
---

## Use allocate for Splitting Money, Not Manual Division

When splitting money between parties, use `allocate` instead of dividing manually. `allocate` distributes remainders so no money is lost.

**Incorrect (manual division loses money):**

```js
import { dinero, multiply } from 'dinero.js';
import { USD } from 'dinero.js/currencies';

const total = dinero({ amount: 1003, currency: USD }); // $10.03

// Splitting three ways: 1003 / 3 = 334.33... — where does the extra cent go?
const share = multiply(total, { amount: 1, scale: 0 }); // No good way to split evenly
```

**Correct (allocate distributes remainders):**

```js
import { dinero, allocate } from 'dinero.js';
import { USD } from 'dinero.js/currencies';

const total = dinero({ amount: 1003, currency: USD }); // $10.03

const shares = allocate(total, [1, 1, 1]);
// [$3.35, $3.34, $3.34] — extra cent goes to the first share
```

The ratios in `allocate` are relative. `[1, 1, 1]` splits evenly. `[70, 20, 10]` splits 70%/20%/10%.

Reference: https://v2.dinerojs.com/api/mutations/allocate


================================================
FILE: .agents/skills/dinero-best-practices/rules/arithmetic-immutability.md
================================================
---
title: Capture Return Values — Dinero Objects Are Immutable
impact: CRITICAL
impactDescription: prevents silently lost calculations
tags: arithmetic, immutability, pure-functions
---

## Capture Return Values — Dinero Objects Are Immutable

All Dinero.js operations are pure functions that return new objects. The original objects are never modified. Discarding the return value means losing your calculation.

**Incorrect (discarding the return value):**

```js
import { dinero, add } from 'dinero.js';
import { USD } from 'dinero.js/currencies';

const price = dinero({ amount: 1000, currency: USD });
const tax = dinero({ amount: 100, currency: USD });

add(price, tax); // Return value discarded — price is unchanged
```

**Correct (capturing the result):**

```js
import { dinero, add } from 'dinero.js';
import { USD } from 'dinero.js/currencies';

const price = dinero({ amount: 1000, currency: USD });
const tax = dinero({ amount: 100, currency: USD });

const total = add(price, tax); // $11.00
```

This applies to all operations: `add`, `subtract`, `multiply`, `allocate`, `convert`, `trimScale`, `transformScale`, and `normalizeScale`.

Reference: https://v2.dinerojs.com/core-concepts/mutations


================================================
FILE: .agents/skills/dinero-best-practices/rules/arithmetic-percentages.md
================================================
---
title: Calculate Percentages with allocate or Scaled multiply
impact: HIGH
impactDescription: prevents precision loss and thrown errors on percentage calculations
tags: arithmetic, percentages, tax, discount
---

## Calculate Percentages with allocate or Scaled multiply

There are two safe ways to calculate percentages of a monetary value: `allocate` (for splitting into complementary parts) and `multiply` with a scaled amount (for extracting a percentage).

**Incorrect (float percentage):**

```js
import { dinero, multiply } from 'dinero.js';
import { USD } from 'dinero.js/currencies';

const subtotal = dinero({ amount: 5000, currency: USD });
const tax = multiply(subtotal, 0.15); // Risky: may throw if result is non-integer
```

**Correct (allocate for complementary parts):**

```js
import { dinero, allocate } from 'dinero.js';
import { USD } from 'dinero.js/currencies';

const subtotal = dinero({ amount: 5000, currency: USD });
const [tax, net] = allocate(subtotal, [15, 85]); // 15% tax, 85% net
```

**Correct (scaled multiply for a single percentage):**

```js
import { dinero, multiply } from 'dinero.js';
import { USD } from 'dinero.js/currencies';

const subtotal = dinero({ amount: 5000, currency: USD });
const tax = multiply(subtotal, { amount: 15, scale: 2 }); // 15/100 = 15%
```

Use `allocate` when you need both parts (e.g., tax and net) to guarantee they sum to the original. Use `multiply` when you only need one part.

Reference: https://v2.dinerojs.com/guides/calculating-percentages


================================================
FILE: .agents/skills/dinero-best-practices/rules/arithmetic-scaled-amounts.md
================================================
---
title: Never Multiply by a Raw Decimal — Use Scaled Amounts
impact: CRITICAL
impactDescription: prevents throws from non-integer intermediate results
tags: arithmetic, multiply, scaled-amounts, decimals
---

## Never Multiply by a Raw Decimal — Use Scaled Amounts

Dinero.js uses integer arithmetic. Multiplying by a decimal that produces a non-integer result will throw. Use scaled amounts instead: `{ amount, scale }` represents `amount / (base ^ scale)`.

**Incorrect (raw decimal multiplier):**

```js
import { dinero, multiply } from 'dinero.js';
import { USD } from 'dinero.js/currencies';

const price = dinero({ amount: 1001, currency: USD });
multiply(price, 0.5); // Throws: 1001 * 0.5 = 500.5 (not an integer)
```

**Correct (scaled amount):**

```js
import { dinero, multiply } from 'dinero.js';
import { USD } from 'dinero.js/currencies';

const price = dinero({ amount: 1001, currency: USD });
multiply(price, { amount: 5, scale: 1 }); // 5/10 = 0.5, result: amount 5005, scale 3
```

Common scaled amounts:

| Decimal | Scaled amount              |
| ------- | -------------------------- |
| 0.5     | `{ amount: 5, scale: 1 }`  |
| 0.1     | `{ amount: 1, scale: 1 }`  |
| 0.15    | `{ amount: 15, scale: 2 }` |
| 1.5     | `{ amount: 15, scale: 1 }` |

Reference: https://v2.dinerojs.com/faq/can-i-multiply-by-a-decimal


================================================
FILE: .agents/skills/dinero-best-practices/rules/creation-from-floats.md
================================================
---
title: Convert Float Inputs to Minor Units with a Helper
impact: CRITICAL
impactDescription: prevents throws and precision bugs from float inputs
tags: creation, floats, conversion, external-input
---

## Convert Float Inputs to Minor Units with a Helper

When receiving float values from external sources (APIs, user input, databases), convert them to integer minor units before creating a Dinero object. Never pass floats directly.

**Incorrect (passing a float directly):**

```js
import { dinero } from 'dinero.js';
import { USD } from 'dinero.js/currencies';

const priceFromApi = 19.99;
const d = dinero({ amount: priceFromApi, currency: USD }); // Throws
```

**Correct (converting with a helper):**

```js
import { dinero } from 'dinero.js';
import { USD } from 'dinero.js/currencies';

function dineroFromFloat({ amount: float, currency, scale }) {
  const factor = currency.base ** (scale ?? currency.exponent);
  const amount = Math.round(float * factor);

  return dinero({ amount, currency, scale });
}

const priceFromApi = 19.99;
const d = dineroFromFloat({ amount: priceFromApi, currency: USD }); // $19.99
```

`Math.round` is necessary to avoid floating-point artifacts (e.g., `19.99 * 100` evaluates to `1998.9999999999998` in JavaScript).

Reference: https://v2.dinerojs.com/guides/creating-from-floats


================================================
FILE: .agents/skills/dinero-best-practices/rules/creation-minor-units.md
================================================
---
title: Always Pass Amounts as Integers in Minor Currency Units
impact: CRITICAL
impactDescription: prevents silent off-by-100x errors
tags: creation, amount, minor-units, cents
---

## Always Pass Amounts as Integers in Minor Currency Units

Dinero.js represents money in the smallest subdivision of a currency. For USD (exponent 2), the amount is in cents. Passing a major-unit value silently creates the wrong amount.

**Incorrect (passing major units or floats):**

```js
import { dinero } from 'dinero.js';
import { USD } from 'dinero.js/currencies';

// Wrong: 50 cents, not 50 dollars
const d = dinero({ amount: 50, currency: USD });

// Wrong: throws on non-integer
const d = dinero({ amount: 19.99, currency: USD });
```

**Correct (minor units as integers):**

```js
import { dinero } from 'dinero.js';
import { USD } from 'dinero.js/currencies';

const d1 = dinero({ amount: 5000, currency: USD }); // $50.00
const d2 = dinero({ amount: 1999, currency: USD }); // $19.99
```

Reference: https://v2.dinerojs.com/core-concepts/amount


================================================
FILE: .agents/skills/dinero-best-practices/rules/creation-zero-exponent.md
================================================
---
title: Currencies with Exponent 0 Take Major Units Directly
impact: HIGH
impactDescription: prevents wrong amounts for JPY, KRW, and similar currencies
tags: creation, exponent, jpy, zero-decimal
---

## Currencies with Exponent 0 Take Major Units Directly

Currencies like JPY and KRW have no minor units (exponent 0). The amount you pass is in major units directly.

**Incorrect (treating JPY like USD):**

```js
import { dinero } from 'dinero.js';
import { JPY } from 'dinero.js/currencies';

// Wrong: this is 500,000 yen, not 5,000 yen
const d = dinero({ amount: 500000, currency: JPY });
```

**Correct (major units for zero-exponent currencies):**

```js
import { dinero } from 'dinero.js';
import { JPY } from 'dinero.js/currencies';

// JPY has exponent 0, so 5000 means 5,000 yen
const d = dinero({ amount: 5000, currency: JPY });
```

Check a currency's `exponent` property to determine the expected unit. USD has exponent 2 (cents), BHD has exponent 3 (fils), JPY has exponent 0 (yen).

Reference: https://v2.dinerojs.com/core-concepts/amount


================================================
FILE: .agents/skills/dinero-best-practices/rules/imports-bigint-currencies.md
================================================
---
title: Match Calculator Type — Use Matching Currency Imports
impact: HIGH
impactDescription: prevents TypeError from mixing number and bigint arithmetic
tags: imports, bigint, currencies, type-mismatch
---

## Match Calculator Type — Use Matching Currency Imports

Currency definitions from `dinero.js/currencies` use `number` for `base` and `exponent`. Currency definitions from `dinero.js/bigint/currencies` use `bigint`. Mixing them throws a `TypeError`.

**Incorrect (mixing number currencies with bigint calculator):**

```js
import { dinero } from 'dinero.js/bigint';
import { USD } from 'dinero.js/currencies'; // number-typed

// TypeError: Cannot mix BigInt and other types
const d = dinero({ amount: 500n, currency: USD });
```

**Correct (matching imports):**

```js
// Number calculator + number currencies
import { dinero } from 'dinero.js';
import { USD } from 'dinero.js/currencies';
const d = dinero({ amount: 500, currency: USD });

// Bigint calculator + bigint currencies
import { dinero } from 'dinero.js/bigint';
import { USD } from 'dinero.js/bigint/currencies';
const d = dinero({ amount: 500n, currency: USD });
```

Reference: https://v2.dinerojs.com/faq/why-cant-i-use-currencies-with-bigint


================================================
FILE: .agents/skills/dinero-best-practices/rules/imports-tree-shaking.md
================================================
---
title: Import Only What You Use — Standalone Functions Enable Tree-Shaking
impact: MEDIUM
impactDescription: reduces bundle size by excluding unused operations
tags: imports, tree-shaking, bundle-size, functions
---

## Import Only What You Use — Standalone Functions Enable Tree-Shaking

Dinero.js exports standalone functions instead of methods on objects. This means bundlers can eliminate unused code. Import only the functions you need.

**How it works:**

```js
// Only add, toDecimal, and dinero are included in your bundle
import { dinero, add, toDecimal } from 'dinero.js';
import { USD } from 'dinero.js/currencies';

const total = add(
  dinero({ amount: 1000, currency: USD }),
  dinero({ amount: 500, currency: USD }),
);

toDecimal(total); // "15.00"
```

Functions like `multiply`, `allocate`, `compare`, `greaterThan`, etc. are not shipped if you don't import them.

Note: Dinero.js uses standalone functions, not methods. Write `add(d1, d2)`, not `d1.add(d2)`.

Reference: https://v2.dinerojs.com/faq/why-functions-instead-of-methods


================================================
FILE: .agents/skills/dinero-best-practices/rules/precision-bigint.md
================================================
---
title: Use bigint for Amounts Exceeding Number.MAX_SAFE_INTEGER
impact: HIGH
impactDescription: prevents silent precision loss on large monetary values
tags: precision, bigint, large-amounts, safe-integer
---

## Use bigint for Amounts Exceeding Number.MAX_SAFE_INTEGER

JavaScript `number` silently loses precision beyond `Number.MAX_SAFE_INTEGER` (9,007,199,254,740,991). For large monetary values, use the bigint entry point.

**Incorrect (large amount with number calculator):**

```js
import { dinero } from 'dinero.js';
import { USD } from 'dinero.js/currencies';

// 25800000000000000 exceeds safe integer range — silently wrong
const d = dinero({ amount: 25800000000000000, currency: USD });
```

**Correct (bigint calculator):**

```js
import { dinero } from 'dinero.js/bigint';
import { USD } from 'dinero.js/bigint/currencies';

const d = dinero({ amount: 25800000000000000n, currency: USD });
```

Note: `dinero.js/bigint` uses its own currency definitions where `base` and `exponent` are bigint values. Always import currencies from `dinero.js/bigint/currencies` when using the bigint calculator.

Reference: https://v2.dinerojs.com/guides/precision-and-large-numbers


================================================
FILE: .agents/skills/dinero-best-practices/rules/precision-crypto.md
================================================
---
title: Cryptocurrencies Require bigint Due to High Exponents
impact: HIGH
impactDescription: prevents overflow on crypto amounts (e.g., 1 ETH = 10^18 wei)
tags: precision, bigint, cryptocurrency, ethereum, bitcoin
---

## Cryptocurrencies Require bigint Due to High Exponents

Cryptocurrencies like ETH (exponent 18) and BTC (exponent 8) produce amounts that exceed the safe integer range even for small values. Always use the bigint calculator for crypto.

**Incorrect (number calculator for ETH):**

```js
import { dinero } from 'dinero.js';

const ETH = { code: 'ETH', base: 10, exponent: 18 };
// 1 ETH = 1000000000000000000 wei — exceeds Number.MAX_SAFE_INTEGER
const d = dinero({ amount: 1000000000000000000, currency: ETH });
```

**Correct (bigint calculator):**

```js
import { dinero } from 'dinero.js/bigint';

const ETH = { code: 'ETH', base: 10n, exponent: 18n };
const d = dinero({ amount: 1000000000000000000n, currency: ETH });
```

Avoid naming files after cryptocurrency ticker codes (e.g., `xbt.js`, `xmr.js`). Ad blockers may flag these file names as crypto mining scripts and block them from loading.

Reference: https://v2.dinerojs.com/guides/cryptocurrencies


================================================
FILE: .agents/skills/dinero-best-practices/rules/precision-trim-scale.md
================================================
---
title: Use trimScale to Remove Trailing Zeros After Chained Operations
impact: MEDIUM
impactDescription: prevents unnecessary scale growth from chained operations
tags: precision, scale, trim, chained-operations
---

## Use trimScale to Remove Trailing Zeros After Chained Operations

Dinero.js automatically promotes to the highest scale when combining objects with different scales. Over many operations, scale can grow unnecessarily. Use `trimScale` to drop trailing zeros.

**Before trimming:**

```js
import { dinero, add, trimScale } from 'dinero.js';
import { USD } from 'dinero.js/currencies';

const d1 = dinero({ amount: 100, currency: USD });
const d2 = dinero({ amount: 2000000, currency: USD, scale: 6 });

const result = add(d1, d2); // amount: 3000000, scale: 6
```

**After trimming:**

```js
const trimmed = trimScale(result); // amount: 300, scale: 2
```

This is especially useful before serialization (storing or transporting) where compact representation matters.

Reference: https://v2.dinerojs.com/api/conversions/trim-scale


================================================
FILE: .agents/skills/dinero-currency-patterns/SKILL.md
================================================
---
name: dinero-currency-patterns
description: >
  Currency handling patterns for the Dinero.js money library. Use when working
  with multiple currencies, converting between currencies, defining custom
  currencies, storing monetary values in databases, or integrating with payment
  services like Stripe or PayPal. Triggers on currency conversion, database
  schema design for money, or payment API integration with Dinero objects.
license: MIT
metadata:
  author: dinerojs
  version: '1.0.0'
---

# Dinero.js Currency Patterns

Patterns for handling currencies with [Dinero.js](https://v2.dinerojs.com): type safety, conversions, custom currencies, database storage, and payment service integration.

## When to Apply

Reference these guidelines when:

- Converting between currencies with `convert`
- Defining custom currencies (e.g., cryptocurrencies, loyalty points)
- Looking up currencies dynamically from external input
- Storing monetary values in a database
- Integrating with payment services (Stripe, PayPal, Square)

## Rule Categories by Priority

| Priority | Category            | Impact | Prefix     |
| -------- | ------------------- | ------ | ---------- |
| 1        | Type Safety         | HIGH   | `types-`   |
| 2        | Conversion          | HIGH   | `convert-` |
| 3        | Storage             | HIGH   | `storage-` |
| 4        | Payment Integration | MEDIUM | `payment-` |

## Quick Reference

### 1. Type Safety (HIGH)

- `types-as-const` - Define custom currencies with `as const satisfies` for compile-time safety
- `types-currency-mismatch` - TypeScript catches currency mismatches in operations at compile time
- `types-lookup-validation` - Validate currency codes from external sources at runtime

### 2. Conversion (HIGH)

- `convert-scaled-rates` - Use scaled amounts for fractional exchange rates, not floats
- `convert-reusable` - Build reusable converter functions with higher-order patterns

### 3. Storage (HIGH)

- `storage-database` - Store amount, currency code, and scale as separate columns
- `storage-no-money-type` - Avoid PostgreSQL's `money` type for multi-currency applications

### 4. Payment Integration (MEDIUM)

- `payment-services` - Map Dinero objects to payment service formats with dedicated helpers

## How to Use

Read individual rule files for detailed explanations and code examples:

```
rules/types-as-const.md
rules/convert-scaled-rates.md
```

Each rule file contains:

- Brief explanation of why it matters
- Incorrect code example with explanation
- Correct code example with explanation
- Additional context and references


================================================
FILE: .agents/skills/dinero-currency-patterns/rules/convert-reusable.md
================================================
---
title: Build Reusable Converter Functions
impact: MEDIUM
impactDescription: eliminates repeated rate passing across conversion call sites
tags: convert, reusable, higher-order, pattern
---

## Build Reusable Converter Functions

When converting many objects with the same rates, wrap `convert` in a higher-order function to avoid passing rates every time.

**Correct (reusable converter):**

```js
import { dinero, convert } from 'dinero.js';
import { USD, EUR } from 'dinero.js/currencies';

function createConverter(rates) {
  return function converter(dineroObject, newCurrency) {
    return convert(dineroObject, newCurrency, rates);
  };
}

const rates = { EUR: { amount: 89, scale: 2 } };
const convertWithRates = createConverter(rates);

const price = dinero({ amount: 500, currency: USD });
convertWithRates(price, EUR); // Dinero object in EUR
```

This pattern works well when rates are fetched once per request or session and reused across multiple conversions.

Reference: https://v2.dinerojs.com/api/conversions/convert


================================================
FILE: .agents/skills/dinero-currency-patterns/rules/convert-scaled-rates.md
================================================
---
title: Use Scaled Amounts for Fractional Exchange Rates, Not Floats
impact: HIGH
impactDescription: prevents precision loss from floating-point exchange rates
tags: convert, rates, scaled-amounts, exchange-rate
---

## Use Scaled Amounts for Fractional Exchange Rates, Not Floats

When converting between currencies, fractional exchange rates should be passed as scaled amounts (`{ amount, scale }`) instead of floats. This avoids floating-point precision issues.

**Incorrect (float rate):**

```js
import { dinero, convert } from 'dinero.js';
import { USD, EUR } from 'dinero.js/currencies';

const rates = { EUR: 0.89 }; // Float — imprecise
const d = dinero({ amount: 500, currency: USD });
convert(d, EUR, rates);
```

**Correct (scaled rate):**

```js
import { dinero, convert } from 'dinero.js';
import { USD, EUR } from 'dinero.js/currencies';

const rates = { EUR: { amount: 89, scale: 2 } }; // 89/100 = 0.89 — precise
const d = dinero({ amount: 500, currency: USD });
convert(d, EUR, rates); // Dinero object with amount 44500, scale 4
```

Integer rates can be passed directly without scaling:

```js
const rates = { IQD: 1199 }; // 1 USD = 1199 IQD (integer, no scaling needed)
convert(d, IQD, rates);
```

Reference: https://v2.dinerojs.com/api/conversions/convert


================================================
FILE: .agents/skills/dinero-currency-patterns/rules/payment-services.md
================================================
---
title: Map Dinero Objects to Payment Service Formats with Dedicated Helpers
impact: MEDIUM
impactDescription: prevents payment API errors from wrong amount/currency formats
tags: payment, stripe, paypal, square, integration
---

## Map Dinero Objects to Payment Service Formats with Dedicated Helpers

Each payment service expects a different money format. Build dedicated helper functions to convert Dinero objects to the right shape.

**Stripe (minor units, lowercase currency):**

```js
import { toSnapshot } from 'dinero.js';

function toStripeMoney(dineroObject) {
  const { amount, currency } = toSnapshot(dineroObject);

  return {
    amount,
    currency: currency.code.toLowerCase(),
  };
}

// { amount: 1999, currency: 'usd' }
```

**PayPal (decimal string, uppercase currency):**

```js
import { toSnapshot, toDecimal } from 'dinero.js';

function toPaypalMoney(dineroObject) {
  const { currency } = toSnapshot(dineroObject);

  return {
    value: toDecimal(dineroObject),
    currency_code: currency.code,
  };
}

// { value: '19.99', currency_code: 'USD' }
```

**Square (BigInt amount, uppercase currency):**

```js
import { toSnapshot } from 'dinero.js';

function toSquareMoney(dineroObject) {
  const { amount, currency } = toSnapshot(dineroObject);

  return {
    amount: BigInt(amount),
    currency: currency.code,
  };
}

// { amount: 1999n, currency: 'USD' }
```

Keep these helpers in a single module (e.g., `lib/money.js`) so format changes only need updating in one place.

Reference: https://v2.dinerojs.com/guides/integrating-with-payment-services


================================================
FILE: .agents/skills/dinero-currency-patterns/rules/storage-database.md
================================================
---
title: Store Amount, Currency Code, and Scale as Separate Columns
impact: HIGH
impactDescription: prevents data loss and enables correct restoration of Dinero objects
tags: storage, database, schema, columns, restoration
---

## Store Amount, Currency Code, and Scale as Separate Columns

Store each component of a Dinero object separately. This is portable across databases and preserves all information needed for reconstruction.

**Correct (SQL schema):**

```sql
CREATE TABLE products (
  id SERIAL PRIMARY KEY,
  name VARCHAR(255) NOT NULL,
  price_amount BIGINT NOT NULL,
  price_currency VARCHAR(3) NOT NULL,
  price_scale INTEGER NOT NULL DEFAULT 2
);
```

**Correct (restoration from database row):**

```js
import { dinero } from 'dinero.js';
import { getCurrency } from './currencies'; // Your validation helper

function dineroFromRow(row) {
  const currency = getCurrency(row.price_currency);

  return dinero({
    amount: row.price_amount,
    currency,
    scale: row.price_scale,
  });
}
```

Always store the `scale`, not just the currency exponent. If a Dinero object was created with a custom scale (e.g., from a `multiply` with a scaled amount), restoring with just the exponent produces the wrong value.

Reference: https://v2.dinerojs.com/guides/storing-in-a-database


================================================
FILE: .agents/skills/dinero-currency-patterns/rules/storage-no-money-type.md
================================================
---
title: Avoid PostgreSQL's money Type for Multi-Currency Applications
impact: HIGH
impactDescription: prevents locale-dependent bugs and precision loss
tags: storage, database, postgresql, money-type
---

## Avoid PostgreSQL's money Type for Multi-Currency Applications

PostgreSQL's `money` type has no currency information, is locale-dependent, and has fixed 2-decimal precision. It fails for currencies with 0 decimals (JPY), 3 decimals (BHD), or multi-currency support.

**Incorrect (PostgreSQL money type):**

```sql
CREATE TABLE products (
  id SERIAL PRIMARY KEY,
  price MONEY NOT NULL -- No currency info, locale-dependent, fixed precision
);
```

**Correct (separate columns):**

```sql
CREATE TABLE products (
  id SERIAL PRIMARY KEY,
  price_amount BIGINT NOT NULL,
  price_currency VARCHAR(3) NOT NULL,
  price_scale INTEGER NOT NULL DEFAULT 2
);
```

The same advice applies to other database-specific money types. Use standard integer and string columns for maximum portability and control.

Reference: https://v2.dinerojs.com/guides/storing-in-a-database


================================================
FILE: .agents/skills/dinero-currency-patterns/rules/types-as-const.md
================================================
---
title: Define Custom Currencies with as const satisfies for Type Safety
impact: HIGH
impactDescription: enables compile-time currency mismatch detection
tags: types, currency, typescript, as-const, custom-currency
---

## Define Custom Currencies with as const satisfies for Type Safety

When defining custom currencies (e.g., cryptocurrencies, loyalty points), use `as const satisfies` to get a literal type for the `code` property. Without it, TypeScript infers `string`, losing compile-time currency mismatch detection.

**Incorrect (code inferred as string):**

```ts
import type { Currency } from 'dinero.js';

const BTC = { code: 'BTC', base: 10, exponent: 8 };
// typeof BTC.code is string, not 'BTC'
```

**Correct (literal type with as const satisfies):**

```ts
import type { Currency } from 'dinero.js';

const BTC = {
  code: 'BTC',
  base: 10,
  exponent: 8,
} as const satisfies Currency<number, 'BTC'>;
// typeof BTC.code is 'BTC'
```

With literal types, TypeScript catches mistakes like adding BTC and USD at compile time:

```ts
const btcAmount = dinero({ amount: 100000000, currency: BTC });
const usdAmount = dinero({ amount: 500, currency: USD });
add(btcAmount, usdAmount); // Type error: 'USD' is not assignable to 'BTC'
```

All built-in currencies from `dinero.js/currencies` already have literal types.

Reference: https://v2.dinerojs.com/guides/currency-type-safety


================================================
FILE: .agents/skills/dinero-currency-patterns/rules/types-currency-mismatch.md
================================================
---
title: TypeScript Catches Currency Mismatches at Compile Time
impact: HIGH
impactDescription: prevents adding, subtracting, or comparing different currencies
tags: types, currency, mismatch, compile-time, typescript
---

## TypeScript Catches Currency Mismatches at Compile Time

When using typed currencies, TypeScript prevents operations between different currencies. This catches bugs that would otherwise only fail at runtime.

**Caught at compile time:**

```ts
import { dinero, add, subtract, equal } from 'dinero.js';
import { USD, EUR } from 'dinero.js/currencies';

const price = dinero({ amount: 500, currency: USD }); // Dinero<number, 'USD'>
const tax = dinero({ amount: 100, currency: EUR }); // Dinero<number, 'EUR'>

add(price, tax); // Type error: 'EUR' is not assignable to 'USD'
subtract(price, tax); // Type error
equal(price, tax); // Type error
```

**Currency type preserved through operations:**

```ts
import { dinero, multiply, convert } from 'dinero.js';
import { USD, EUR } from 'dinero.js/currencies';

const price = dinero({ amount: 500, currency: USD });
const doubled = multiply(price, 2); // Dinero<number, 'USD'> — preserved
const converted = convert(price, EUR, rates); // Dinero<number, 'EUR'> — changed

add(doubled, converted); // Type error: 'EUR' is not assignable to 'USD'
```

Unary operations (`multiply`, `allocate`, `trimScale`) preserve the currency type. `convert` changes it to the target currency.

Reference: https://v2.dinerojs.com/guides/currency-type-safety


================================================
FILE: .agents/skills/dinero-currency-patterns/rules/types-lookup-validation.md
================================================
---
title: Validate Currency Codes from External Sources at Runtime
impact: HIGH
impactDescription: prevents undefined currency errors from invalid or unknown codes
tags: types, validation, runtime, lookup, external-input
---

## Validate Currency Codes from External Sources at Runtime

Currency codes from APIs, databases, or user input may be invalid. Always validate before looking up a currency definition.

**Incorrect (direct lookup without validation):**

```ts
import * as currencies from 'dinero.js/currencies';

function createPrice(amount: number, code: string) {
  const currency = currencies[code]; // May be undefined
  return dinero({ amount, currency }); // Runtime error
}
```

**Correct (validate before lookup):**

```ts
import { dinero } from 'dinero.js';
import * as currencies from 'dinero.js/currencies';

function getCurrency(code: string) {
  if (!(code in currencies)) {
    throw new Error(`Unknown currency code: ${code}`);
  }

  return currencies[code as keyof typeof currencies];
}

function createPrice(amount: number, code: string) {
  const currency = getCurrency(code);
  return dinero({ amount, currency });
}
```

Currency codes may also change between Dinero.js versions, as the library tracks ISO 4217 amendments. Pin your package version if you need stability.

Reference: https://v2.dinerojs.com/faq/how-to-look-up-a-currency-by-code


================================================
FILE: .agents/skills/dinero-formatting/SKILL.md
================================================
---
name: dinero-formatting
description: >
  Formatting patterns for the Dinero.js money library. Use when displaying
  monetary values to users, formatting prices with currency symbols, handling
  locale-specific number formats, or working with non-decimal currencies.
  Triggers on toDecimal, toUnits, toSnapshot calls, or Intl.NumberFormat
  usage with Dinero objects.
license: MIT
metadata:
  author: dinerojs
  version: '1.0.0'
---

# Dinero.js Formatting

Patterns for formatting [Dinero.js](https://v2.dinerojs.com) monetary values for display. Covers currency symbols, locale-aware formatting, non-decimal currencies, and serialization.

## When to Apply

Reference these guidelines when:

- Displaying prices, totals, or monetary values in a UI
- Adding currency symbols or locale-specific formatting
- Formatting non-decimal currencies (e.g., historical currencies with non-base-10 subdivisions)
- Serializing Dinero objects for APIs, databases, or transport
- Building reusable formatting utilities

## Rule Categories by Priority

| Priority | Category      | Impact   | Prefix           |
| -------- | ------------- | -------- | ---------------- |
| 1        | Display       | CRITICAL | `display-`       |
| 2        | Locale        | HIGH     | `locale-`        |
| 3        | Serialization | HIGH     | `serialization-` |
| 4        | Non-Decimal   | MEDIUM   | `nondecimal-`    |

## Quick Reference

### 1. Display (CRITICAL)

- `display-to-decimal` - Use `toDecimal` for display strings, not `toSnapshot`
- `display-no-currency-symbols` - Dinero.js does not format currency symbols; compose with `Intl.NumberFormat`

### 2. Locale (HIGH)

- `locale-intl-formatter` - Build reusable formatters with `Intl.NumberFormat`
- `locale-multilingual` - Create locale-parameterized formatters for multilingual sites

### 3. Serialization (HIGH)

- `serialization-snapshot` - Use `toSnapshot` for transport and storage, not display
- `serialization-bigint-json` - BigInt Dinero objects require a custom JSON replacer

### 4. Non-Decimal (MEDIUM)

- `nondecimal-to-units` - Use `toUnits` for non-decimal currencies, not `toDecimal`

## How to Use

Read individual rule files for detailed explanations and code examples:

```
rules/display-no-currency-symbols.md
rules/locale-intl-formatter.md
```

Each rule file contains:

- Brief explanation of why it matters
- Incorrect code example with explanation
- Correct code example with explanation
- Additional context and references


================================================
FILE: .agents/skills/dinero-formatting/rules/display-no-currency-symbols.md
================================================
---
title: Dinero.js Does Not Format Currency Symbols — Compose with Intl.NumberFormat
impact: CRITICAL
impactDescription: prevents missing currency symbols in UI
tags: display, currency-symbols, intl, numberformat
---

## Dinero.js Does Not Format Currency Symbols — Compose with Intl.NumberFormat

`toDecimal` returns a plain decimal string like `"19.99"`, not `"$19.99"`. This is by design: currency formatting varies by locale (`$19.99` in en-US, `19,99 $US` in fr-CA, `19,99 $` in fr-FR). Use `toDecimal` with a transformer to add locale-aware formatting.

**Incorrect (expecting currency symbols from toDecimal):**

```js
import { dinero, toDecimal } from 'dinero.js';
import { USD } from 'dinero.js/currencies';

const price = dinero({ amount: 1999, currency: USD });
toDecimal(price); // "19.99" — no currency symbol
```

**Correct (composing with Intl.NumberFormat):**

```js
import { dinero, toDecimal } from 'dinero.js';
import { USD } from 'dinero.js/currencies';

const price = dinero({ amount: 1999, currency: USD });

toDecimal(price, ({ value, currency }) => {
  return Number(value).toLocaleString('en-US', {
    style: 'currency',
    currency: currency.code,
  });
}); // "$19.99"
```

Reference: https://v2.dinerojs.com/faq/why-no-currency-formatting


================================================
FILE: .agents/skills/dinero-formatting/rules/display-to-decimal.md
================================================
---
title: Use toDecimal for Display Strings, Not toSnapshot
impact: CRITICAL
impactDescription: prevents displaying raw minor-unit amounts to users
tags: display, toDecimal, toSnapshot, formatting
---

## Use toDecimal for Display Strings, Not toSnapshot

`toDecimal` returns a human-readable decimal string (e.g., `"19.99"`). `toSnapshot` returns the raw internal representation in minor units (e.g., `{ amount: 1999, ... }`). Use the right one for the right job.

**Incorrect (using toSnapshot for display):**

```js
import { dinero, toSnapshot } from 'dinero.js';
import { USD } from 'dinero.js/currencies';

const price = dinero({ amount: 1999, currency: USD });
const { amount } = toSnapshot(price);
display.textContent = `$${amount}`; // Shows "$1999" — wrong
```

**Correct (using toDecimal for display):**

```js
import { dinero, toDecimal } from 'dinero.js';
import { USD } from 'dinero.js/currencies';

const price = dinero({ amount: 1999, currency: USD });
toDecimal(price); // "19.99"
```

`toSnapshot` is for serialization (APIs, databases, transport). `toDecimal` is for rendering to users.

Reference: https://v2.dinerojs.com/core-concepts/formatting


================================================
FILE: .agents/skills/dinero-formatting/rules/locale-intl-formatter.md
================================================
---
title: Build Reusable Formatters with Intl.NumberFormat
impact: HIGH
impactDescription: eliminates duplicated formatting logic across the codebase
tags: locale, formatter, intl, reusable, higher-order
---

## Build Reusable Formatters with Intl.NumberFormat

Instead of inlining `Intl.NumberFormat` at every call site, build a reusable formatter function.

**Correct (reusable formatter):**

```js
import { toDecimal } from 'dinero.js';

function intlFormat(dineroObject, locale, options = {}) {
  function transformer({ value, currency }) {
    return Number(value).toLocaleString(locale, {
      ...options,
      style: 'currency',
      currency: currency.code,
    });
  }

  return toDecimal(dineroObject, transformer);
}

intlFormat(price, 'en-US'); // "$19.99"
intlFormat(price, 'fr-FR'); // "19,99 $US"
intlFormat(price, 'ja-JP'); // "$19.99"
```

You can also create a higher-order function that bakes in the locale:

```js
function createFormatter(locale, options = {}) {
  return function format(dineroObject) {
    return intlFormat(dineroObject, locale, options);
  };
}

const formatUSD = createFormatter('en-US');
formatUSD(price); // "$19.99"
```

Reference: https://v2.dinerojs.com/guides/formatting-in-a-multilingual-site


================================================
FILE: .agents/skills/dinero-formatting/rules/locale-multilingual.md
================================================
---
title: Parameterize Locale for Multilingual Sites
impact: HIGH
impactDescription: prevents hardcoded locale strings in formatting logic
tags: locale, multilingual, i18n, internationalization
---

## Parameterize Locale for Multilingual Sites

In multilingual applications, pass the locale as a parameter rather than hardcoding it. This lets you format the same Dinero object differently depending on the user's language.

**Incorrect (hardcoded locale):**

```js
function formatPrice(dineroObject) {
  return toDecimal(dineroObject, ({ value, currency }) => {
    return Number(value).toLocaleString('en-US', {
      style: 'currency',
      currency: currency.code,
    });
  });
}
```

**Correct (locale as parameter):**

```js
function formatPrice(dineroObject, locale) {
  return toDecimal(dineroObject, ({ value, currency }) => {
    return Number(value).toLocaleString(locale, {
      style: 'currency',
      currency: currency.code,
    });
  });
}

formatPrice(price, 'en-US'); // "$19.99"
formatPrice(price, 'de-DE'); // "19,99 $"
formatPrice(price, 'ja-JP'); // "$19.99"
```

In React, you can get the locale from your i18n context (e.g., `next-intl`, `react-intl`, `react-i18next`) and pass it to your formatter.

Reference: https://v2.dinerojs.com/guides/formatting-in-a-multilingual-site


================================================
FILE: .agents/skills/dinero-formatting/rules/nondecimal-to-units.md
================================================
---
title: Use toUnits for Non-Decimal Currencies, Not toDecimal
impact: MEDIUM
impactDescription: prevents wrong output for currencies with non-base-10 subdivisions
tags: nondecimal, toUnits, formatting, historical-currencies
---

## Use toUnits for Non-Decimal Currencies, Not toDecimal

`toDecimal` assumes a decimal (base 10) currency. For currencies with non-decimal subdivisions (e.g., base 6, base 12, or multi-base like pre-decimal GBP), use `toUnits`.

**Incorrect (toDecimal on non-decimal currency):**

```js
import { dinero, toDecimal } from 'dinero.js';

const GRD = { code: 'GRD', base: 6, exponent: 1 };
const d = dinero({ amount: 9, currency: GRD });

toDecimal(d); // Throws or produces meaningless output
```

**Correct (toUnits with a custom transformer):**

```js
import { dinero, toUnits } from 'dinero.js';

const GRD = { code: 'GRD', base: 6, exponent: 1 };
const d = dinero({ amount: 9, currency: GRD });
const labels = ['drachma', 'obol'];

toUnits(d, ({ value }) =>
  value
    .filter((v) => v > 0)
    .map((v, i) => `${v} ${labels[i]}`)
    .join(', '),
); // "1 drachma, 3 obols"
```

`toUnits` returns an array of unit values, one per subdivision level. It works with any base, including array bases like `[20, 12]` for pre-decimal GBP (pounds, shillings, pence).

Reference: https://v2.dinerojs.com/guides/formatting-non-decimal-currencies


================================================
FILE: .agents/skills/dinero-formatting/rules/serialization-bigint-json.md
================================================
---
title: BigInt Dinero Objects Require a Custom JSON Replacer
impact: HIGH
impactDescription: prevents TypeError when serializing bigint Dinero objects
tags: serialization, bigint, json, stringify, replacer
---

## BigInt Dinero Objects Require a Custom JSON Replacer

`JSON.stringify` throws a `TypeError` on bigint values. When using the bigint calculator, provide a custom replacer.

**Incorrect (stringify without replacer):**

```js
import { dinero, toSnapshot } from 'dinero.js/bigint';
import { USD } from 'dinero.js/bigint/currencies';

const price = dinero({ amount: 500n, currency: USD });
JSON.stringify(toSnapshot(price)); // TypeError: Do not know how to serialize a BigInt
```

**Correct (with replacer):**

```js
import { dinero, toSnapshot } from 'dinero.js/bigint';
import { USD } from 'dinero.js/bigint/currencies';

const price = dinero({ amount: 500n, currency: USD });

JSON.stringify(toSnapshot(price), (key, value) => {
  if (typeof value === 'bigint') {
    return String(value);
  }
  return value;
});
```

When restoring, convert string values back to bigint:

```js
const data = JSON.parse(json, (key, value) => {
  if (typeof value === 'string' && /^\d+$/.test(value)) {
    return BigInt(value);
  }
  return value;
});
const restored = dinero(data.price);
```

Reference: https://v2.dinerojs.com/guides/transporting-and-restoring


================================================
FILE: .agents/skills/dinero-formatting/rules/serialization-snapshot.md
================================================
---
title: Use toSnapshot for Transport and Storage, Not Display
impact: HIGH
impactDescription: prevents data loss from using display-oriented functions for serialization
tags: serialization, toSnapshot, transport, storage, json
---

## Use toSnapshot for Transport and Storage, Not Display

`toSnapshot` returns the full internal representation as a plain object, suitable for JSON serialization. Use it for APIs, databases, and transport. Use `toDecimal` for user-facing display.

**Correct (serialization with toSnapshot):**

```js
import { dinero, toSnapshot } from 'dinero.js';
import { USD } from 'dinero.js/currencies';

const price = dinero({ amount: 1999, currency: USD });
const snapshot = toSnapshot(price);
// { amount: 1999, currency: { code: 'USD', base: 10, exponent: 2 }, scale: 2 }

// Send to API
await fetch('/api/products', {
  method: 'POST',
  body: JSON.stringify({ price: snapshot }),
});
```

**Correct (restoring from snapshot):**

```js
import { dinero } from 'dinero.js';

// The snapshot can be passed directly to dinero()
const restored = dinero(data.price);
```

Snapshots are plain objects with no methods, making them safe for `JSON.stringify`, database columns, and cross-service communication.

Reference: https://v2.dinerojs.com/guides/transporting-and-restoring


================================================
FILE: .agents/skills/tsdown/SKILL.md
================================================
---
name: tsdown
description: Bundle TypeScript and JavaScript libraries with blazing-fast speed powered by Rolldown. Use when building libraries, generating type declarations, bundling for multiple formats, or migrating from tsup.
---

# tsdown - The Elegant Library Bundler

Blazing-fast bundler for TypeScript/JavaScript libraries powered by Rolldown and Oxc.

## When to Use

- Building TypeScript/JavaScript libraries for npm
- Generating TypeScript declaration files (.d.ts)
- Bundling for multiple formats (ESM, CJS, IIFE, UMD)
- Optimizing bundles with tree shaking and minification
- Migrating from tsup with minimal changes
- Building React, Vue, Solid, or Svelte component libraries

## Quick Start

```bash
# Install
pnpm add -D tsdown

# Basic usage
npx tsdown

# With config file
npx tsdown --config tsdown.config.ts

# Watch mode
npx tsdown --watch

# Migrate from tsup
npx tsdown-migrate
```

## Basic Configuration

```ts
import { defineConfig } from 'tsdown'

export default defineConfig({
  entry: ['./src/index.ts'],
  format: ['esm', 'cjs'],
  dts: true,
  clean: true,
})
```

## Core References

| Topic | Description | Reference |
|-------|-------------|-----------|
| Getting Started | Installation, first bundle, CLI basics | [guide-getting-started](references/guide-getting-started.md) |
| Configuration File | Config file formats, multiple configs, workspace | [option-config-file](references/option-config-file.md) |
| CLI Reference | All CLI commands and options | [reference-cli](references/reference-cli.md) |
| Migrate from tsup | Migration guide and compatibility notes | [guide-migrate-from-tsup](references/guide-migrate-from-tsup.md) |
| Plugins | Rolldown, Rollup, Unplugin support | [advanced-plugins](references/advanced-plugins.md) |
| Hooks | Lifecycle hooks for custom logic | [advanced-hooks](references/advanced-hooks.md) |
| Programmatic API | Build from Node.js scripts | [advanced-programmatic](references/advanced-programmatic.md) |
| Rolldown Options | Pass options directly to Rolldown | [advanced-rolldown-options](references/advanced-rolldown-options.md) |
| CI Environment | CI detection, `'ci-only'` / `'local-only'` values | [advanced-ci](references/advanced-ci.md) |

## Build Options

| Option | Usage | Reference |
|--------|-------|-----------|
| Entry points | `entry: ['src/*.ts', '!**/*.test.ts']` | [option-entry](references/option-entry.md) |
| Output formats | `format: ['esm', 'cjs', 'iife', 'umd']` | [option-output-format](references/option-output-format.md) |
| Output directory | `outDir: 'dist'`, `outExtensions` | [option-output-directory](references/option-output-directory.md) |
| Type declarations | `dts: true`, `dts: { sourcemap, compilerOptions, vue }` | [option-dts](references/option-dts.md) |
| Target environment | `target: 'es2020'`, `target: 'esnext'` | [option-target](references/option-target.md) |
| Platform | `platform: 'node'`, `platform: 'browser'` | [option-platform](references/option-platform.md) |
| Tree shaking | `treeshake: true`, custom options | [option-tree-shaking](references/option-tree-shaking.md) |
| Minification | `minify: true`, `minify: 'dce-only'` | [option-minification](references/option-minification.md) |
| Source maps | `sourcemap: true`, `'inline'`, `'hidden'` | [option-sourcemap](references/option-sourcemap.md) |
| Watch mode | `watch: true`, watch options | [option-watch-mode](references/option-watch-mode.md) |
| Cleaning | `clean: true`, clean patterns | [option-cleaning](references/option-cleaning.md) |
| Log level | `logLevel: 'silent'`, `failOnWarn: 'ci-only'` | [option-log-level](references/option-log-level.md) |

## Dependency Handling

| Feature | Usage | Reference |
|---------|-------|-----------|
| External deps | `external: ['react', /^@myorg\//]` | [option-dependencies](references/option-dependencies.md) |
| Inline deps | `noExternal: ['dep-to-bundle']` | [option-dependencies](references/option-dependencies.md) |
| Auto external | Automatic peer/dependency externalization | [option-dependencies](references/option-dependencies.md) |

## Output Enhancement

| Feature | Usage | Reference |
|---------|-------|-----------|
| Shims | `shims: true` - Add ESM/CJS compatibility | [option-shims](references/option-shims.md) |
| CJS default | `cjsDefault: true` (default) / `false` | [option-cjs-default](references/option-cjs-default.md) |
| Package exports | `exports: true` - Auto-generate exports field | [option-package-exports](references/option-package-exports.md) |
| CSS handling | **[experimental]** Still in development | [option-css](references/option-css.md) |
| Unbundle mode | `unbundle: true` - Preserve directory structure | [option-unbundle](references/option-unbundle.md) |
| Package validation | `publint: true`, `attw: true` - Validate package | [option-lint](references/option-lint.md) |

## Framework & Runtime Support

| Framework | Guide | Reference |
|-----------|-------|-----------|
| React | JSX transform, Fast Refresh | [recipe-react](references/recipe-react.md) |
| Vue | SFC support, JSX | [recipe-vue](references/recipe-vue.md) |
| WASM | WebAssembly modules via `rolldown-plugin-wasm` | [recipe-wasm](references/recipe-wasm.md) |

## Common Patterns

### Basic Library Bundle

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  format: ['esm', 'cjs'],
  dts: true,
  clean: true,
})
```

### Multiple Entry Points

```ts
export default defineConfig({
  entry: {
    index: 'src/index.ts',
    utils: 'src/utils.ts',
    cli: 'src/cli.ts',
  },
  format: ['esm', 'cjs'],
  dts: true,
})
```

### Browser Library (IIFE/UMD)

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  format: ['iife'],
  globalName: 'MyLib',
  platform: 'browser',
  minify: true,
})
```

### React Component Library

```ts
export default defineConfig({
  entry: ['src/index.tsx'],
  format: ['esm', 'cjs'],
  dts: true,
  external: ['react', 'react-dom'],
  plugins: [
    // React Fast Refresh support
  ],
})
```

### Preserve Directory Structure

```ts
export default defineConfig({
  entry: ['src/**/*.ts', '!**/*.test.ts'],
  unbundle: true, // Preserve file structure
  format: ['esm'],
  dts: true,
})
```

### CI-Aware Configuration

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  format: ['esm', 'cjs'],
  dts: true,
  failOnWarn: 'ci-only',
  publint: 'ci-only',
  attw: 'ci-only',
})
```

### WASM Support

```ts
import { wasm } from 'rolldown-plugin-wasm'
import { defineConfig } from 'tsdown'

export default defineConfig({
  entry: ['src/index.ts'],
  plugins: [wasm()],
})
```

### Advanced with Hooks

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  format: ['esm', 'cjs'],
  dts: true,
  hooks: {
    'build:before': async (context) => {
      console.log('Building...')
    },
    'build:done': async (context) => {
      console.log('Build complete!')
    },
  },
})
```

## Configuration Features

### Multiple Configs

Export an array for multiple build configurations:

```ts
export default defineConfig([
  {
    entry: ['src/index.ts'],
    format: ['esm', 'cjs'],
    dts: true,
  },
  {
    entry: ['src/cli.ts'],
    format: ['esm'],
    platform: 'node',
  },
])
```

### Conditional Config

Use functions for dynamic configuration:

```ts
export default defineConfig((options) => {
  const isDev = options.watch
  return {
    entry: ['src/index.ts'],
    format: ['esm', 'cjs'],
    minify: !isDev,
    sourcemap: isDev,
  }
})
```

### Workspace/Monorepo

Use glob patterns to build multiple packages:

```ts
export default defineConfig({
  workspace: 'packages/*',
  entry: ['src/index.ts'],
  format: ['esm', 'cjs'],
  dts: true,
})
```

## CLI Quick Reference

```bash
# Basic commands
tsdown                          # Build once
tsdown --watch                  # Watch mode
tsdown --config custom.ts       # Custom config
npx tsdown-migrate              # Migrate from tsup

# Output options
tsdown --format esm,cjs        # Multiple formats
tsdown --outDir lib            # Custom output directory
tsdown --minify                # Enable minification
tsdown --dts                   # Generate declarations

# Entry options
tsdown src/index.ts            # Single entry
tsdown src/*.ts                # Glob patterns
tsdown src/a.ts src/b.ts       # Multiple entries

# Development
tsdown --watch                 # Watch mode
tsdown --sourcemap             # Generate source maps
tsdown --clean                 # Clean output directory
```

## Best Practices

1. **Always generate type declarations** for TypeScript libraries:
   ```ts
   { dts: true }
   ```

2. **Externalize dependencies** to avoid bundling unnecessary code:
   ```ts
   { external: [/^react/, /^@myorg\//] }
   ```

3. **Use tree shaking** for optimal bundle size:
   ```ts
   { treeshake: true }
   ```

4. **Enable minification** for production builds:
   ```ts
   { minify: true }
   ```

5. **Add shims** for better ESM/CJS compatibility:
   ```ts
   { shims: true }  // Adds __dirname, __filename, etc.
   ```

6. **Auto-generate package.json exports**:
   ```ts
   { exports: true }  // Creates proper exports field
   ```

7. **Use watch mode** during development:
   ```bash
   tsdown --watch
   ```

8. **Preserve structure** for utilities with many files:
   ```ts
   { unbundle: true }  // Keep directory structure
   ```

9. **Validate packages** in CI before publishing:
   ```ts
   { publint: 'ci-only', attw: 'ci-only' }
   ```

## Resources

- Documentation: https://tsdown.dev
- GitHub: https://github.com/rolldown/tsdown
- Rolldown: https://rolldown.rs
- Migration Guide: https://tsdown.dev/guide/migrate-from-tsup


================================================
FILE: .agents/skills/tsdown/references/advanced-ci.md
================================================
# CI Environment Support

Automatically detect CI environments and toggle features based on local vs CI builds.

## Overview

tsdown uses the [`is-in-ci`](https://www.npmjs.com/package/is-in-ci) package to detect CI environments. This covers GitHub Actions, GitLab CI, Jenkins, CircleCI, Travis CI, and more.

## CI-Aware Values

Several options accept CI-aware string values:

| Value | Behavior |
|-------|----------|
| `true` | Always enabled |
| `false` | Always disabled |
| `'ci-only'` | Enabled only in CI, disabled locally |
| `'local-only'` | Enabled only locally, disabled in CI |

## Supported Options

These options accept CI-aware values:

- `dts` - TypeScript declaration file generation
- `publint` - Package lint validation
- `attw` - "Are the types wrong" validation
- `report` - Bundle size reporting
- `exports` - Auto-generate `package.json` exports
- `unused` - Unused dependency check
- `devtools` - DevTools integration
- `failOnWarn` - Fail on warnings (defaults to `'ci-only'`)

## Usage

### String Form

```ts
export default defineConfig({
  dts: 'local-only',        // Skip DTS in CI for faster builds
  publint: 'ci-only',       // Only run publint in CI
  failOnWarn: 'ci-only',    // Fail on warnings in CI only (default)
})
```

### Object Form

When an option takes a configuration object, set `enabled` to a CI-aware value:

```ts
export default defineConfig({
  publint: {
    enabled: 'ci-only',
    level: 'error',
  },
  attw: {
    enabled: 'ci-only',
    profile: 'node16',
  },
})
```

### Config Function

The config function receives a `ci` boolean in its context:

```ts
export default defineConfig((_, { ci }) => ({
  minify: ci,
  sourcemap: !ci,
}))
```

## Typical CI Configuration

```ts
export default defineConfig({
  entry: 'src/index.ts',
  format: ['esm', 'cjs'],
  dts: true,
  failOnWarn: 'ci-only',
  publint: 'ci-only',
  attw: 'ci-only',
})
```

## Related Options

- [Package Validation](option-lint.md) - publint and attw configuration
- [Log Level](option-log-level.md) - `failOnWarn` option details


================================================
FILE: .agents/skills/tsdown/references/advanced-hooks.md
================================================
# Lifecycle Hooks

Extend the build process with lifecycle hooks.

## Overview

Hooks provide a way to inject custom logic at specific stages of the build lifecycle. Inspired by [unbuild](https://github.com/unjs/unbuild).

**Recommendation:** Use [plugins](advanced-plugins.md) for most extensions. Use hooks for simple custom tasks or Rolldown plugin injection.

## Usage Patterns

### Object Syntax

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  hooks: {
    'build:prepare': async (context) => {
      console.log('Build starting...')
    },
    'build:done': async (context) => {
      console.log('Build complete!')
    },
  },
})
```

### Function Syntax

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  hooks(hooks) {
    hooks.hook('build:prepare', () => {
      console.log('Preparing build...')
    })

    hooks.hook('build:before', (context) => {
      console.log(`Building format: ${context.format}`)
    })
  },
})
```

## Available Hooks

### `build:prepare`

Called before the build process starts.

**When:** Once per build session

**Context:**
```ts
{
  options: ResolvedConfig,
  hooks: Hookable
}
```

**Use cases:**
- Setup tasks
- Validation
- Environment preparation

**Example:**
```ts
hooks: {
  'build:prepare': async (context) => {
    console.log('Starting build for:', context.options.entry)
    await cleanOldFiles()
  },
}
```

### `build:before`

Called before each Rolldown build.

**When:** Once per format (ESM, CJS, etc.)

**Context:**
```ts
{
  options: ResolvedConfig,
  buildOptions: BuildOptions,
  hooks: Hookable
}
```

**Use cases:**
- Modify build options per format
- Inject plugins dynamically
- Format-specific setup

**Example:**
```ts
hooks: {
  'build:before': async (context) => {
    console.log(`Building ${context.buildOptions.format} format...`)

    // Add format-specific plugin
    if (context.buildOptions.format === 'iife') {
      context.buildOptions.plugins.push(browserPlugin())
    }
  },
}
```

### `build:done`

Called after the build completes.

**When:** Once per build session

**Context:**
```ts
{
  options: ResolvedConfig,
  chunks: RolldownChunk[],
  hooks: Hookable
}
```

**Use cases:**
- Post-processing
- Asset copying
- Notifications
- Deployment

**Example:**
```ts
hooks: {
  'build:done': async (context) => {
    console.log(`Built ${context.chunks.length} chunks`)

    // Copy additional files
    await copyAssets()

    // Send notification
    notifyBuildComplete()
  },
}
```

## Common Patterns

### Build Notifications

```ts
export default defineConfig({
  hooks: {
    'build:prepare': () => {
      console.log('🚀 Starting build...')
    },
    'build:done': (context) => {
      const size = context.chunks.reduce((sum, c) => sum + c.code.length, 0)
      console.log(`✅ Build complete! Total size: ${size} bytes`)
    },
  },
})
```

### Conditional Plugin Injection

```ts
export default defineConfig({
  hooks(hooks) {
    hooks.hook('build:before', (context) => {
      // Add minification only for production
      if (process.env.NODE_ENV === 'production') {
        context.buildOptions.plugins.push(minifyPlugin())
      }
    })
  },
})
```

### Custom File Copy

```ts
import { copyFile } from 'fs/promises'

export default defineConfig({
  hooks: {
    'build:done': async (context) => {
      // Copy README to dist
      await copyFile('README.md', `${context.options.outDir}/README.md`)
    },
  },
})
```

### Build Metrics

```ts
export default defineConfig({
  hooks: {
    'build:prepare': (context) => {
      context.startTime = Date.now()
    },
    'build:done': (context) => {
      const duration = Date.now() - context.startTime
      console.log(`Build took ${duration}ms`)

      // Log chunk sizes
      context.chunks.forEach((chunk) => {
        console.log(`${chunk.fileName}: ${chunk.code.length} bytes`)
      })
    },
  },
})
```

### Format-Specific Logic

```ts
export default defineConfig({
  format: ['esm', 'cjs', 'iife'],
  hooks: {
    'build:before': (context) => {
      const format = context.buildOptions.format

      if (format === 'iife') {
        // Browser-specific setup
        context.buildOptions.globalName = 'MyLib'
      } else if (format === 'cjs') {
        // Node-specific setup
        context.buildOptions.platform = 'node'
      }
    },
  },
})
```

### Deployment Hook

```ts
export default defineConfig({
  hooks: {
    'build:done': async (context) => {
      if (process.env.DEPLOY === 'true') {
        console.log('Deploying to CDN...')
        await deployToCDN(context.options.outDir)
      }
    },
  },
})
```

## Advanced Usage

### Multiple Hooks

```ts
export default defineConfig({
  hooks(hooks) {
    // Register multiple hooks
    hooks.hook('build:prepare', setupEnvironment)
    hooks.hook('build:prepare', validateConfig)

    hooks.hook('build:before', injectPlugins)
    hooks.hook('build:before', logFormat)

    hooks.hook('build:done', generateManifest)
    hooks.hook('build:done', notifyComplete)
  },
})
```

### Async Hooks

```ts
export default defineConfig({
  hooks: {
    'build:prepare': async (context) => {
      await fetchRemoteConfig()
      await initializeDatabase()
    },
    'build:done': async (context) => {
      await uploadToS3(context.chunks)
      await invalidateCDN()
    },
  },
})
```

### Error Handling

```ts
export default defineConfig({
  hooks: {
    'build:done': async (context) => {
      try {
        await riskyOperation()
      } catch (error) {
        console.error('Hook failed:', error)
        // Don't throw - allow build to complete
      }
    },
  },
})
```

## Hookable API

tsdown uses [hookable](https://github.com/unjs/hookable) for hooks. Additional methods:

```ts
export default defineConfig({
  hooks(hooks) {
    // Register hook
    hooks.hook('build:done', handler)

    // Register hook once
    hooks.hookOnce('build:prepare', handler)

    // Remove hook
    hooks.removeHook('build:done', handler)

    // Clear all hooks for event
    hooks.removeHooks('build:done')

    // Call hooks manually
    await hooks.callHook('build:done', context)
  },
})
```

## Tips

1. **Use plugins** for most extensions
2. **Hooks for simple tasks** like notifications or file copying
3. **Async hooks supported** for I/O operations
4. **Don't throw errors** unless you want to fail the build
5. **Context is mutable** in `build:before` for advanced use cases
6. **Multiple hooks allowed** for the same event

## Troubleshooting

### Hook Not Called

- Verify hook name is correct
- Check hook is registered in config
- Ensure async hooks are awaited

### Build Fails in Hook

- Add try/catch for error handling
- Don't throw unless intentional
- Log errors for debugging

### Context Undefined

- Check which hook you're using
- Verify context properties available for that hook

## Related

- [Plugins](advanced-plugins.md) - Plugin system
- [Rolldown Options](advanced-rolldown-options.md) - Build options
- [Watch Mode](option-watch-mode.md) - Development workflow


================================================
FILE: .agents/skills/tsdown/references/advanced-plugins.md
================================================
# Plugins

Extend tsdown with plugins from multiple ecosystems.

## Overview

tsdown, built on Rolldown, supports plugins from multiple ecosystems to extend and customize the bundling process.

## Supported Ecosystems

### 1. Rolldown Plugins

Native plugins designed for Rolldown:

```ts
import RolldownPlugin from 'rolldown-plugin-something'

export default defineConfig({
  plugins: [RolldownPlugin()],
})
```

**Compatibility:** ✅ Full support

### 2. Unplugin

Universal plugins that work across bundlers:

```ts
import UnpluginPlugin from 'unplugin-something'

export default defineConfig({
  plugins: [UnpluginPlugin.rolldown()],
})
```

**Compatibility:** ✅ Most unplugin-* plugins work

**Examples:**
- `unplugin-vue-components`
- `unplugin-auto-import`
- `unplugin-icons`

### 3. Rollup Plugins

Most Rollup plugins work with tsdown:

```ts
import RollupPlugin from '@rollup/plugin-something'

export default defineConfig({
  plugins: [RollupPlugin()],
})
```

**Compatibility:** ✅ High compatibility

**Type Issues:** May cause TypeScript errors - use type casting:

```ts
import RollupPlugin from 'rollup-plugin-something'

export default defineConfig({
  plugins: [
    // @ts-expect-error Rollup plugin type mismatch
    RollupPlugin(),
    // Or cast to any
    RollupPlugin() as any,
  ],
})
```

### 4. Vite Plugins

Some Vite plugins may work:

```ts
import VitePlugin from 'vite-plugin-something'

export default defineConfig({
  plugins: [
    // @ts-expect-error Vite plugin type mismatch
    VitePlugin(),
  ],
})
```

**Compatibility:** ⚠️ Limited - only if not using Vite-specific APIs

**Note:** Improved support planned for future releases.

## Usage

### Basic Plugin Usage

```ts
import { defineConfig } from 'tsdown'
import SomePlugin from 'some-plugin'

export default defineConfig({
  entry: ['src/index.ts'],
  plugins: [SomePlugin()],
})
```

### Multiple Plugins

```ts
import PluginA from 'plugin-a'
import PluginB from 'plugin-b'
import PluginC from 'plugin-c'

export default defineConfig({
  entry: ['src/index.ts'],
  plugins: [
    PluginA(),
    PluginB({ option: true }),
    PluginC(),
  ],
})
```

### Conditional Plugins

```ts
export default defineConfig((options) => ({
  entry: ['src/index.ts'],
  plugins: [
    SomePlugin(),
    options.watch && DevPlugin(),
    !options.watch && ProdPlugin(),
  ].filter(Boolean),
}))
```

## Common Plugin Patterns

### JSON Import

```ts
import json from '@rollup/plugin-json'

export default defineConfig({
  plugins: [json()],
})
```

### Node Resolve

```ts
import { nodeResolve } from '@rollup/plugin-node-resolve'

export default defineConfig({
  plugins: [nodeResolve()],
})
```

### CommonJS

```ts
import commonjs from '@rollup/plugin-commonjs'

export default defineConfig({
  plugins: [commonjs()],
})
```

### Replace

```ts
import replace from '@rollup/plugin-replace'

export default defineConfig({
  plugins: [
    replace({
      'process.env.NODE_ENV': JSON.stringify('production'),
      __VERSION__: JSON.stringify('1.0.0'),
    }),
  ],
})
```

### Auto Import

```ts
import AutoImport from 'unplugin-auto-import/rolldown'

export default defineConfig({
  plugins: [
    AutoImport({
      imports: ['vue', 'vue-router'],
      dts: 'src/auto-imports.d.ts',
    }),
  ],
})
```

### Vue Components

```ts
import Components from 'unplugin-vue-components/rolldown'

export default defineConfig({
  plugins: [
    Components({
      dts: 'src/components.d.ts',
    }),
  ],
})
```

## Framework-Specific Plugins

### React

```ts
import react from '@vitejs/plugin-react'

export default defineConfig({
  entry: ['src/index.tsx'],
  plugins: [
    // @ts-expect-error Vite plugin
    react(),
  ],
})
```

### Vue

```ts
import vue from '@vitejs/plugin-vue'

export default defineConfig({
  entry: ['src/index.ts'],
  plugins: [
    // @ts-expect-error Vite plugin
    vue(),
  ],
})
```

### Solid

```ts
import solid from 'vite-plugin-solid'

export default defineConfig({
  entry: ['src/index.tsx'],
  plugins: [
    // @ts-expect-error Vite plugin
    solid(),
  ],
})
```

### Svelte

```ts
import { svelte } from '@sveltejs/vite-plugin-svelte'

export default defineConfig({
  entry: ['src/index.ts'],
  plugins: [
    // @ts-expect-error Vite plugin
    svelte(),
  ],
})
```

## Writing Custom Plugins

Follow Rolldown's plugin development guide:

### Basic Plugin Structure

```ts
import type { Plugin } from 'rolldown'

function myPlugin(): Plugin {
  return {
    name: 'my-plugin',

    // Transform hook
    transform(code, id) {
      if (id.endsWith('.custom')) {
        return {
          code: transformCode(code),
          map: null,
        }
      }
    },

    // Other hooks...
  }
}
```

### Using Custom Plugin

```ts
import { myPlugin } from './my-plugin'

export default defineConfig({
  plugins: [myPlugin()],
})
```

## Plugin Configuration

### Plugin-Specific Options

Refer to each plugin's documentation for configuration options.

### Plugin Order

Plugins run in the order they're defined:

```ts
export default defineConfig({
  plugins: [
    PluginA(),  // Runs first
    PluginB(),  // Runs second
    PluginC(),  // Runs last
  ],
})
```

## Troubleshooting

### Type Errors with Rollup/Vite Plugins

Use type casting:

```ts
plugins: [
  // Option 1: @ts-expect-error
  // @ts-expect-error Plugin type mismatch
  SomePlugin(),

  // Option 2: as any
  SomePlugin() as any,
]
```

### Plugin Not Working

1. **Check compatibility** - Verify plugin supports your bundler
2. **Read documentation** - Follow plugin's setup instructions
3. **Check plugin order** - Some plugins depend on execution order
4. **Enable debug mode** - Use `--debug` flag

### Vite Plugin Fails

Vite plugins may rely on Vite-specific APIs:

1. **Find Rollup equivalent** - Look for Rollup version of plugin
2. **Use Unplugin version** - Check for `unplugin-*` alternative
3. **Wait for support** - Vite plugin support improving

## Resources

- [Rolldown Plugin Development](https://rolldown.rs/guide/plugin-development)
- [Unplugin Documentation](https://unplugin.unjs.io/)
- [Rollup Plugins](https://github.com/rollup/plugins)
- [Vite Plugins](https://vitejs.dev/plugins/)

## Tips

1. **Prefer Rolldown plugins** for best compatibility
2. **Use Unplugin** for cross-bundler support
3. **Cast types** for Rollup/Vite plugins
4. **Test thoroughly** when using cross-ecosystem plugins
5. **Check plugin docs** for specific configuration
6. **Write custom plugins** for unique needs

## Related

- [Hooks](advanced-hooks.md) - Lifecycle hooks
- [Rolldown Options](advanced-rolldown-options.md) - Advanced Rolldown config
- [React Recipe](recipe-react.md) - React setup with plugins
- [Vue Recipe](recipe-vue.md) - Vue setup with plugins


================================================
FILE: .agents/skills/tsdown/references/advanced-programmatic.md
================================================
# Programmatic Usage

Use tsdown from JavaScript/TypeScript code.

## Overview

tsdown can be imported and used programmatically in your Node.js scripts, custom build tools, or automation workflows.

## Basic Usage

### Simple Build

```ts
import { build } from 'tsdown'

await build({
  entry: ['src/index.ts'],
  format: ['esm', 'cjs'],
  dts: true,
})
```

### With Options

```ts
import { build } from 'tsdown'

await build({
  entry: ['src/index.ts'],
  format: ['esm', 'cjs'],
  outDir: 'dist',
  dts: true,
  minify: true,
  sourcemap: true,
  clean: true,
})
```

## API Reference

### build()

Main function to run a build.

```ts
import { build } from 'tsdown'

await build(options)
```

**Parameters:**
- `options` - Build configuration object (same as config file)

**Returns:**
- `Promise<void>` - Resolves when build completes

**Throws:**
- Build errors if compilation fails

## Configuration Object

All config file options are available:

```ts
import { build, defineConfig } from 'tsdown'

const config = defineConfig({
  entry: ['src/index.ts'],
  format: ['esm', 'cjs'],
  dts: true,
  minify: true,
  sourcemap: true,
  external: ['react', 'react-dom'],
  plugins: [/* plugins */],
  hooks: {
    'build:done': async () => {
      console.log('Build complete!')
    },
  },
})

await build(config)
```

See [Config Reference](option-config-file.md) for all options.

## Common Patterns

### Custom Build Script

```ts
// scripts/build.ts
import { build } from 'tsdown'

async function main() {
  console.log('Building library...')

  await build({
    entry: ['src/index.ts'],
    format: ['esm', 'cjs'],
    dts: true,
    clean: true,
  })

  console.log('Build complete!')
}

main().catch(console.error)
```

Run with:
```bash
tsx scripts/build.ts
```

### Multiple Builds

```ts
import { build } from 'tsdown'

// Build main library
await build({
  entry: ['src/index.ts'],
  format: ['esm', 'cjs'],
  outDir: 'dist',
  dts: true,
})

// Build CLI tool
await build({
  entry: ['src/cli.ts'],
  format: ['esm'],
  outDir: 'dist/bin',
  platform: 'node',
  shims: true,
})
```

### Conditional Build

```ts
import { build } from 'tsdown'

const isDev = process.env.NODE_ENV === 'development'

await build({
  entry: ['src/index.ts'],
  format: ['esm', 'cjs'],
  minify: !isDev,
  sourcemap: isDev,
  clean: !isDev,
})
```

### With Error Handling

```ts
import { build } from 'tsdown'

try {
  await build({
    entry: ['src/index.ts'],
    format: ['esm', 'cjs'],
    dts: true,
  })
  console.log('✅ Build successful')
} catch (error) {
  console.error('❌ Build failed:', error)
  process.exit(1)
}
```

### Automated Workflow

```ts
import { build } from 'tsdown'
import { execSync } from 'child_process'

async function release() {
  // Clean
  console.log('Cleaning...')
  execSync('rm -rf dist')

  // Build
  console.log('Building...')
  await build({
    entry: ['src/index.ts'],
    format: ['esm', 'cjs'],
    dts: true,
    minify: true,
  })

  // Test
  console.log('Testing...')
  execSync('npm test')

  // Publish
  console.log('Publishing...')
  execSync('npm publish')
}

release().catch(console.error)
```

### Build with Post-Processing

```ts
import { build } from 'tsdown'
import { copyFileSync } from 'fs'

await build({
  entry: ['src/index.ts'],
  format: ['esm', 'cjs'],
  dts: true,
  hooks: {
    'build:done': async () => {
      // Copy additional files
      copyFileSync('README.md', 'dist/README.md')
      copyFileSync('LICENSE', 'dist/LICENSE')
      console.log('Copied additional files')
    },
  },
})
```

## Watch Mode

Unfortunately, watch mode is not directly exposed in the programmatic API. Use the CLI for watch mode:

```ts
// Use CLI for watch mode
import { spawn } from 'child_process'

spawn('tsdown', ['--watch'], {
  stdio: 'inherit',
  shell: true,
})
```

## Integration Examples

### With Task Runner

```ts
// gulpfile.js
import { build } from 'tsdown'
import gulp from 'gulp'

gulp.task('build', async () => {
  await build({
    entry: ['src/index.ts'],
    format: ['esm', 'cjs'],
    dts: true,
  })
})

gulp.task('watch', () => {
  return gulp.watch('src/**/*.ts', gulp.series('build'))
})
```

### With Custom CLI

```ts
// scripts/cli.ts
import { build } from 'tsdown'
import { Command } from 'commander'

const program = new Command()

program
  .command('build')
  .option('--prod', 'Production build')
  .action(async (options) => {
    await build({
      entry: ['src/index.ts'],
      format: ['esm', 'cjs'],
      minify: options.prod,
      sourcemap: !options.prod,
    })
  })

program.parse()
```

### With CI/CD

```ts
// .github/scripts/build.ts
import { build } from 'tsdown'

const isCI = process.env.CI === 'true'

await build({
  entry: ['src/index.ts'],
  format: ['esm', 'cjs'],
  dts: true,
  minify: isCI,
  clean: true,
})

// Upload to artifact storage
if (isCI) {
  // Upload dist/ to S3, etc.
}
```

## TypeScript Support

```ts
// scripts/build.ts
import { build, type UserConfig } from 'tsdown'

const config: UserConfig = {
  entry: ['src/index.ts'],
  format: ['esm', 'cjs'],
  dts: true,
}

await build(config)
```

## Tips

1. **Use TypeScript** for type safety
2. **Handle errors** properly
3. **Use hooks** for custom logic
4. **Log progress** for visibility
5. **Use CLI for watch** mode
6. **Exit on error** in scripts

## Troubleshooting

### Import Errors

Ensure tsdown is installed:
```bash
pnpm add -D tsdown
```

### Type Errors

Import types:
```ts
import type { UserConfig } from 'tsdown'
```

### Build Fails Silently

Add error handling:
```ts
try {
  await build(config)
} catch (error) {
  console.error(error)
  process.exit(1)
}
```

### Options Not Working

Check spelling and types:
```ts
// ✅ Correct
{ format: ['esm', 'cjs'] }

// ❌ Wrong
{ formats: ['esm', 'cjs'] }
```

## Related

- [Config File](option-config-file.md) - Configuration options
- [Hooks](advanced-hooks.md) - Lifecycle hooks
- [CLI](reference-cli.md) - Command-line interface
- [Plugins](advanced-plugins.md) - Plugin system


================================================
FILE: .agents/skills/tsdown/references/advanced-rolldown-options.md
================================================
# Customizing Rolldown Options

Pass options directly to the underlying Rolldown bundler.

## Overview

tsdown uses [Rolldown](https://rolldown.rs) as its core bundling engine. You can override Rolldown's input and output options directly for fine-grained control.

**Warning:** You should be familiar with Rolldown's behavior before overriding options. Refer to the [Rolldown Config Options](https://rolldown.rs/options/input) documentation.

## Input Options

### Using an Object

```ts
export default defineConfig({
  inputOptions: {
    cwd: './custom-directory',
  },
})
```

### Using a Function

Dynamically modify options based on the output format:

```ts
export default defineConfig({
  inputOptions(inputOptions, format) {
    inputOptions.cwd = './custom-directory'
    return inputOptions
  },
})
```

## Output Options

### Using an Object

```ts
export default defineConfig({
  outputOptions: {
    legalComments: 'inline',
  },
})
```

### Using a Function

```ts
export default defineConfig({
  outputOptions(outputOptions, format) {
    if (format === 'esm') {
      outputOptions.legalComments = 'inline'
    }
    return outputOptions
  },
})
```

## Common Use Cases

### Preserve Legal Comments

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  outputOptions: {
    legalComments: 'inline',
  },
})
```

### Custom Working Directory

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  inputOptions: {
    cwd: './packages/my-lib',
  },
})
```

### Format-Specific Options

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  format: ['esm', 'cjs'],
  outputOptions(outputOptions, format) {
    if (format === 'esm') {
      outputOptions.legalComments = 'inline'
    }
    return outputOptions
  },
})
```

## When to Use

- When tsdown doesn't expose a specific Rolldown option
- For format-specific Rolldown customizations
- For advanced bundling scenarios

## Tips

1. **Read Rolldown docs** before overriding options
2. **Use functions** for format-specific customization
3. **Test thoroughly** when overriding defaults
4. **Prefer tsdown options** when available (e.g., use `minify` instead of setting it via `outputOptions`)

## Related

- [Plugins](advanced-plugins.md) - Plugin system
- [Hooks](advanced-hooks.md) - Lifecycle hooks
- [Config File](option-config-file.md) - Configuration options


================================================
FILE: .agents/skills/tsdown/references/guide-getting-started.md
================================================
# Getting Started

Quick guide to installing and using tsdown for the first time.

## Installation

Install tsdown as a development dependency:

```bash
pnpm add -D tsdown

# Optionally install TypeScript if not using isolatedDeclarations
pnpm add -D typescript
```

**Requirements:**
- Node.js 20.19 or higher
- Experimental support for Deno and Bun

## Quick Start Templates

Use `create-tsdown` CLI for instant setup:

```bash
pnpm create tsdown@latest
```

Provides templates for:
- Pure TypeScript libraries
- React component libraries
- Vue component libraries
- Ready-to-use configurations

## First Bundle

### 1. Create Source Files

```ts
// src/index.ts
import { hello } from './hello.ts'
hello()

// src/hello.ts
export function hello() {
  console.log('Hello tsdown!')
}
```

### 2. Create Config File

```ts
// tsdown.config.ts
import { defineConfig } from 'tsdown'

export default defineConfig({
  entry: ['./src/index.ts'],
})
```

### 3. Run Build

```bash
./node_modules/.bin/tsdown
```

Output: `dist/index.mjs`

### 4. Test Output

```bash
node dist/index.mjs
# Output: Hello tsdown!
```

## Add to npm Scripts

```json
{
  "scripts": {
    "build": "tsdown"
  }
}
```

Run with:

```bash
pnpm build
```

## CLI Commands

```bash
# Check version
tsdown --version

# View help
tsdown --help

# Build with watch mode
tsdown --watch

# Build with specific format
tsdown --format esm,cjs

# Generate type declarations
tsdown --dts
```

## Basic Configurations

### TypeScript Library (ESM + CJS)

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  format: ['esm', 'cjs'],
  dts: true,
  clean: true,
})
```

### Browser Library (IIFE)

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  format: ['iife'],
  globalName: 'MyLib',
  platform: 'browser',
  minify: true,
})
```

### Multiple Entry Points

```ts
export default defineConfig({
  entry: {
    index: 'src/index.ts',
    utils: 'src/utils.ts',
    cli: 'src/cli.ts',
  },
  format: ['esm', 'cjs'],
  dts: true,
})
```

## Using Plugins

Add Rolldown, Rollup, or Unplugin plugins:

```ts
import SomePlugin from 'some-plugin'

export default defineConfig({
  entry: ['src/index.ts'],
  plugins: [SomePlugin()],
})
```

## Watch Mode

Enable automatic rebuilds on file changes:

```bash
tsdown --watch
# or
tsdown -w
```

## Next Steps

- Configure [entry points](option-entry.md) with glob patterns
- Set up [multiple output formats](option-output-format.md)
- Enable [type declaration generation](option-dts.md)
- Explore [plugins](advanced-plugins.md) for extended functionality
- Read [migration guide](guide-migrate-from-tsup.md) if coming from tsup


================================================
FILE: .agents/skills/tsdown/references/guide-migrate-from-tsup.md
================================================
# Migrate from tsup

Migration guide for switching from tsup to tsdown.

## Overview

tsdown is built on Rolldown (Rust-based) vs tsup's esbuild, providing faster and more powerful bundling while maintaining compatibility.

## Automatic Migration

### Single Package

```bash
npx tsdown-migrate
```

### Monorepo

```bash
# Using glob patterns
npx tsdown-migrate packages/*

# Multiple directories
npx tsdown-migrate packages/foo packages/bar
```

### Migration Options

- `[...dirs]` - Directories to migrate (supports globs)
- `--dry-run` or `-d` - Preview changes without modifying files

**Important:** Commit your changes before running migration.

## Key Differences

### Default Values

| Option | tsup | tsdown |
|--------|------|--------|
| `format` | `['cjs']` | `['esm']` |
| `clean` | `false` | `true` |
| `dts` | `false` | Auto-enabled if `types`/`typings` in package.json |
| `target` | Manual | Auto-read from `engines.node` in package.json |

### New Features in tsdown

#### Node Protocol Control

```ts
export default defineConfig({
  nodeProtocol: true,      // Add node: prefix (fs → node:fs)
  nodeProtocol: 'strip',   // Remove node: prefix (node:fs → fs)
  nodeProtocol: false,     // Keep as-is (default)
})
```

#### Better Workspace Support

```ts
export default defineConfig({
  workspace: 'packages/*',  // Build all packages
})
```

## Migration Checklist

1. **Backup your code** - Commit all changes
2. **Run migration tool** - `npx tsdown-migrate`
3. **Review changes** - Check modified config files
4. **Update scripts** - Change `tsup` to `tsdown` in package.json
5. **Test build** - Run `pnpm build` to verify
6. **Adjust config** - Fine-tune based on your needs

## Common Migration Patterns

### Basic Library

**Before (tsup):**
```ts
export default defineConfig({
  entry: ['src/index.ts'],
  format: ['cjs', 'esm'],
  dts: true,
})
```

**After (tsdown):**
```ts
export default defineConfig({
  entry: ['src/index.ts'],
  format: ['esm', 'cjs'],  // ESM now default
  dts: true,
  clean: true,  // Now enabled by default
})
```

### With Custom Target

**Before (tsup):**
```ts
export default defineConfig({
  entry: ['src/index.ts'],
  target: 'es2020',
})
```

**After (tsdown):**
```ts
export default defineConfig({
  entry: ['src/index.ts'],
  // target auto-reads from package.json engines.node
  // Or override explicitly:
  target: 'es2020',
})
```

### CLI Scripts

**Before (package.json):**
```json
{
  "scripts": {
    "build": "tsup",
    "dev": "tsup --watch"
  }
}
```

**After (package.json):**
```json
{
  "scripts": {
    "build": "tsdown",
    "dev": "tsdown --watch"
  }
}
```

## Feature Compatibility

### Supported tsup Features

Most tsup features are supported:
- ✅ Multiple entry points
- ✅ Multiple formats (ESM, CJS, IIFE, UMD)
- ✅ TypeScript declarations
- ✅ Source maps
- ✅ Minification
- ✅ Watch mode
- ✅ External dependencies
- ✅ Tree shaking
- ✅ Shims
- ✅ Plugins (Rollup compatible)

### Missing Features

Some tsup features are not yet available. Check [GitHub issues](https://github.com/rolldown/tsdown/issues) for status and request features.

## Troubleshooting

### Build Fails After Migration

1. **Check Node.js version** - Requires Node.js 20.19+
2. **Install TypeScript** - Required for DTS generation
3. **Review config changes** - Ensure format and options are correct
4. **Check dependencies** - Verify all dependencies are installed

### Different Output

- **Format order** - tsdown defaults to ESM first
- **Clean behavior** - tsdown cleans outDir by default
- **Target** - tsdown auto-detects from package.json

### Performance Issues

tsdown should be faster than tsup. If not:
1. Enable `isolatedDeclarations` for faster DTS generation
2. Check for large dependencies being bundled
3. Use `skipNodeModulesBundle` if needed

## Getting Help

- [GitHub Issues](https://github.com/rolldown/tsdown/issues) - Report bugs or request features
- [Documentation](https://tsdown.dev) - Full documentation
- [Migration Tool](https://github.com/rolldown/tsdown/tree/main/packages/tsdown-migrate) - Source code

## Acknowledgements

tsdown is heavily inspired by tsup and incorporates parts of its codebase. Thanks to [@egoist](https://github.com/egoist) and the tsup community.


================================================
FILE: .agents/skills/tsdown/references/option-cjs-default.md
================================================
# CJS Default Export

Control how default exports are handled in CommonJS output.

## Overview

The `cjsDefault` option improves compatibility when generating CommonJS modules. When enabled (default), modules with only a single default export use `module.exports = ...` instead of `exports.default = ...`.

## Type

```ts
cjsDefault?: boolean  // default: true
```

## Basic Usage

### Enabled (Default)

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  format: ['cjs'],
  cjsDefault: true,  // default behavior
})
```

### Disabled

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  format: ['cjs'],
  cjsDefault: false,
})
```

## How It Works

### With `cjsDefault: true` (Default)

When your module has **only a single default export**, tsdown transforms:

**Source:**
```ts
// src/index.ts
export default function greet() {
  console.log('Hello, world!')
}
```

**Generated CJS:**
```js
// dist/index.cjs
function greet() {
  console.log('Hello, world!')
}
module.exports = greet
```

**Generated Declaration:**
```ts
// dist/index.d.cts
declare function greet(): void
export = greet
```

This allows consumers to use `const greet = require('your-module')` directly.

### With `cjsDefault: false`

The default export stays as `exports.default`:

```js
// dist/index.cjs
function greet() {
  console.log('Hello, world!')
}
exports.default = greet
```

Consumers need `require('your-module').default`.

## When to Disable

- When your module has both default and named exports
- When you need consistent `exports.default` behavior
- When consumers always use ESM imports

## Tips

1. **Leave enabled** for most libraries (default `true`)
2. **Disable** if you have both default and named exports and need consistent behavior
3. **Test CJS consumers** to verify compatibility

## Related Options

- [Output Format](option-output-format.md) - Module formats
- [Shims](option-shims.md) - ESM/CJS compatibility


================================================
FILE: .agents/skills/tsdown/references/option-cleaning.md
================================================
# Output Directory Cleaning

Control how the output directory is cleaned before builds.

## Overview

By default, tsdown **cleans the output directory** before each build to remove stale files from previous builds.

## Basic Usage

### CLI

```bash
# Clean enabled (default)
tsdown

# Disable cleaning
tsdown --no-clean
```

### Config File

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  clean: true,  // Default
})
```

## Behavior

### With Cleaning (Default)

Before each build:
1. All files in `outDir` are removed
2. Fresh build starts with empty directory
3. Only current build outputs remain

**Benefits:**
- No stale files
- Predictable output
- Clean slate each build

### Without Cleaning

Build outputs are added to existing files:

```ts
export default defineConfig({
  clean: false,
})
```

**Use when:**
- Multiple builds to same directory
- Incremental builds
- Preserving other files
- Watch mode (faster rebuilds)

## Common Patterns

### Production Build

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  format: ['esm', 'cjs'],
  clean: true,  // Ensure clean output
  minify: true,
})
```

### Development Mode

```ts
export default defineConfig((options) => ({
  entry: ['src/index.ts'],
  clean: !options.watch,  // Don't clean in watch mode
  sourcemap: options.watch,
}))
```

### Multiple Builds

```ts
export default defineConfig([
  {
    entry: ['src/index.ts'],
    outDir: 'dist',
    clean: true,  // Clean once
  },
  {
    entry: ['src/cli.ts'],
    outDir: 'dist',
    clean: false,  // Don't clean, add to same dir
  },
])
```

### Monorepo Package

```ts
export default defineConfig({
  workspace: 'packages/*',
  entry: ['src/index.ts'],
  clean: true,  // Clean each package's dist
})
```

### Preserve Static Files

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  clean: false,  // Keep manually added files
  outDir: 'dist',
})

// Manually copy files first
// Then run tsdown --no-clean
```

## Clean Patterns

### Selective Cleaning

```ts
import { rmSync } from 'fs'

export default defineConfig({
  clean: false,  // Disable auto clean
  hooks: {
    'build:prepare': () => {
      // Custom cleaning logic
      rmSync('dist/*.js', { force: true })
      // Keep other files
    },
  },
})
```

### Clean Specific Directories

```ts
export default defineConfig({
  clean: false,
  hooks: {
    'build:prepare': async () => {
      const { rm } = await import('fs/promises')
      // Only clean specific subdirectories
      await rm('dist/esm', { recursive: true, force: true })
      await rm('dist/cjs', { recursive: true, force: true })
      // Keep dist/types
    },
  },
})
```

## Watch Mode Behavior

In watch mode, cleaning behavior is important:

### Clean on First Build Only

```ts
export default defineConfig((options) => ({
  entry: ['src/index.ts'],
  watch: options.watch,
  clean: !options.watch,  // Only clean initial build
}))
```

**Result:**
- First build: Clean
- Subsequent rebuilds: Incremental

### Always Clean

```ts
export default defineConfig({
  watch: true,
  clean: true,  // Clean every rebuild
})
```

**Trade-off:** Slower rebuilds, but always fresh output.

## Tips

1. **Leave enabled** for production builds
2. **Disable in watch mode** for faster rebuilds
3. **Use multiple configs** carefully with cleaning
4. **Custom clean logic** via hooks if needed
5. **Be cautious** - cleaning removes ALL files in outDir
6. **Test cleaning** - ensure no important files are lost

## Troubleshooting

### Important Files Deleted

- Don't put non-build files in outDir
- Use separate directory for static files
- Disable cleaning and manage manually

### Stale Files in Output

- Enable cleaning: `clean: true`
- Or manually remove before build

### Slow Rebuilds in Watch

- Disable cleaning in watch mode
- Use incremental builds

## CLI Examples

```bash
# Default (clean enabled)
tsdown

# Disable cleaning
tsdown --no-clean

# Watch mode without cleaning
tsdown --watch --no-clean

# Multiple formats with cleaning
tsdown --format esm,cjs --clean
```

## Examples

### Safe Production Build

```bash
# Clean before build
rm -rf dist
tsdown --clean
```

### Incremental Development

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  watch: true,
  clean: false,  // Faster rebuilds
  sourcemap: true,
})
```

### Multi-Stage Build

```ts
// Stage 1: Clean and build main
export default defineConfig([
  {
    entry: ['src/index.ts'],
    outDir: 'dist',
    clean: true,
  },
  {
    entry: ['src/utils.ts'],
    outDir: 'dist',
    clean: false,  // Add to same directory
  },
])
```

## Related Options

- [Output Directory](option-output-directory.md) - Configure outDir
- [Watch Mode](option-watch-mode.md) - Development workflow
- [Hooks](advanced-hooks.md) - Custom clean logic
- [Entry](option-entry.md) - Entry points


================================================
FILE: .agents/skills/tsdown/references/option-config-file.md
================================================
# Configuration File

Centralize and manage build settings with a configuration file.

## Overview

tsdown searches for config files automatically in the current directory and parent directories.

## Supported File Names

tsdown looks for these files (in order):
- `tsdown.config.ts`
- `tsdown.config.mts`
- `tsdown.config.cts`
- `tsdown.config.js`
- `tsdown.config.mjs`
- `tsdown.config.cjs`
- `tsdown.config.json`
- `tsdown.config`
- `package.json` (in `tsdown` field)

## Basic Configuration

### TypeScript Config

```ts
// tsdown.config.ts
import { defineConfig } from 'tsdown'

export default defineConfig({
  entry: ['src/index.ts'],
  format: ['esm', 'cjs'],
  dts: true,
  clean: true,
})
```

### JavaScript Config

```js
// tsdown.config.js
export default {
  entry: ['src/index.ts'],
  format: ['esm', 'cjs'],
  dts: true,
}
```

### JSON Config

```json
// tsdown.config.json
{
  "entry": ["src/index.ts"],
  "format": ["esm", "cjs"],
  "dts": true
}
```

### Package.json Config

```json
// package.json
{
  "name": "my-library",
  "tsdown": {
    "entry": ["src/index.ts"],
    "format": ["esm", "cjs"],
    "dts": true
  }
}
```

## Multiple Configurations

Build multiple outputs with different settings:

```ts
export default defineConfig([
  {
    entry: 'src/index.ts',
    format: ['esm', 'cjs'],
    platform: 'node',
    dts: true,
  },
  {
    entry: 'src/browser.ts',
    format: ['iife'],
    platform: 'browser',
    globalName: 'MyLib',
    minify: true,
  },
])
```

Each configuration runs as a separate build.

## Dynamic Configuration

Use a function for conditional config:

```ts
export default defineConfig((options) => {
  const isDev = options.watch

  return {
    entry: ['src/index.ts'],
    format: ['esm', 'cjs'],
    minify: !isDev,
    sourcemap: isDev,
    clean: !isDev,
  }
})
```

Available options:
- `watch` - Whether watch mode is enabled
- Other CLI flags passed to config

## Config Loaders

Control how TypeScript config files are loaded:

### Auto Loader (Default)

Uses native TypeScript support if available, otherwise falls back to `unrun`:

```bash
tsdown # Uses auto loader
```

### Native Loader

Uses runtime's native TypeScript support (Node.js 23+, Bun, Deno):

```bash
tsdown --config-loader native
```

### Unrun Loader

Uses [unrun](https://gugustinette.github.io/unrun/) library for loading:

```bash
tsdown --config-loader unrun
```

**Tip:** Use `unrun` loader if you need to load TypeScript configs without file extensions in Node.js.

## Custom Config Path

Specify a custom config file location:

```bash
tsdown --config ./configs/build.config.ts
# or
tsdown -c custom-config.ts
```

## Disable Config File

Ignore config files and use CLI options only:

```bash
tsdown --no-config src/index.ts --format esm
```

## Extend Vite/Vitest Config (Experimental)

Reuse existing Vite or Vitest configurations:

```bash
# Extend vite.config.*
tsdown --from-vite

# Extend vitest.config.*
tsdown --from-vite vitest
```

**Note:** Only specific options like `resolve` and `plugins` are reused. Test thoroughly as this feature is experimental.

## Workspace / Monorepo

Build multiple packages with a single config:

```ts
export default defineConfig({
  workspace: 'packages/*',
  entry: ['src/index.ts'],
  format: ['esm', 'cjs'],
  dts: true,
})
```

Each package directory matching the glob pattern will be built with the same configuration.

## Common Patterns

### Library with Multiple Builds

```ts
export default defineConfig([
  // Node.js build
  {
    entry: ['src/index.ts'],
    format: ['esm', 'cjs'],
    platform: 'node',
    dts: true,
  },
  // Browser build
  {
    entry: ['src/browser.ts'],
    format: ['iife'],
    platform: 'browser',
    globalName: 'MyLib',
  },
])
```

### Development vs Production

```ts
export default defineConfig((options) => ({
  entry: ['src/index.ts'],
  format: ['esm', 'cjs'],
  minify: !options.watch,
  sourcemap: options.watch ? true : false,
  clean: !options.watch,
}))
```

### Monorepo Root Config

```ts
// Root tsdown.config.ts
export default defineConfig({
  workspace: 'packages/*',
  entry: ['src/index.ts'],
  format: ['esm', 'cjs'],
  dts: true,
  clean: true,
  // Shared config for all packages
})
```

### Per-Package Override

```ts
// packages/special/tsdown.config.ts
export default defineConfig({
  entry: ['src/index.ts'],
  format: ['esm'], // Override: only ESM
  platform: 'browser', // Override: browser only
})
```

## Config Precedence

When multiple configs exist:

1. CLI options (highest priority)
2. Config file specified with `--config`
3. Auto-discovered config files
4. Package.json `tsdown` field
5. Default values

## Tips

1. **Use TypeScript config** for type checking and autocomplete
2. **Use defineConfig** helper for better DX
3. **Export arrays** for multiple build configurations
4. **Use functions** for dynamic/conditional configs
5. **Keep configs simple** - prefer convention over configuration
6. **Use workspace** for monorepo builds
7. **Test experimental features** thoroughly before production use

## Related Options

- [Entry](option-entry.md) - Configure entry points
- [Output Format](option-output-format.md) - Output formats
- [Watch Mode](option-watch-mode.md) - Watch mode configuration


================================================
FILE: .agents/skills/tsdown/references/option-css.md
================================================
# CSS Support

**Status: Experimental — still in active development.**

CSS handling in tsdown is not yet stable. The API and capabilities may change significantly in future releases.

Avoid relying on CSS-related options in production builds until the feature is marked as stable.


================================================
FILE: .agents/skills/tsdown/references/option-dependencies.md
================================================
# Dependencies

Control how dependencies are bundled or externalized.

## Overview

tsdown intelligently handles dependencies to keep your library lightweight while ensuring all necessary code is included.

## Default Behavior

### Auto-Externalized

These are **NOT bundled** by default:

- **`dependencies`** - Installed automatically with your package
- **`peerDependencies`** - User must install manually

### Conditionally Bundled

These are **bundled ONLY if imported**:

- **`devDependencies`** - Only if actually used in source code
- **Phantom dependencies** - In node_modules but not in package.json

## Configuration Options

### `external`

Mark dependencies as external (not bundled):

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  external: [
    'react',              // Single package
    'react-dom',
    /^@myorg\//,         // Regex pattern (all @myorg/* packages)
    /^lodash/,           // All lodash packages
  ],
})
```

### `noExternal`

Force dependencies to be bundled:

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  noExternal: [
    'some-package',      // Bundle this even if in dependencies
    'vendor-lib',
  ],
})
```

### `skipNodeModulesBundle`

Skip resolving and bundling ALL node_modules:

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  skipNodeModulesBundle: true,
})
```

**Result:** No dependencies from node_modules are parsed or bundled.

## Common Patterns

### React Component Library

```ts
export default defineConfig({
  entry: ['src/index.tsx'],
  format: ['esm', 'cjs'],
  external: [
    'react',
    'react-dom',
    /^react\//,          // react/jsx-runtime, etc.
  ],
  dts: true,
})
```

### Utility Library with Shared Deps

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  format: ['esm', 'cjs'],
  // Bundle lodash utilities
  noExternal: ['lodash-es'],
  dts: true,
})
```

### Monorepo Package

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  format: ['esm', 'cjs'],
  external: [
    /^@mycompany\//,     // Don't bundle other workspace packages
  ],
  dts: true,
})
```

### CLI Tool (Bundle Everything)

```ts
export default defineConfig({
  entry: ['src/cli.ts'],
  format: ['esm'],
  platform: 'node',
  // Bundle all dependencies for standalone CLI
  noExternal: [/.*/],
  shims: true,
})
```

### Library with Specific Externals

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  format: ['esm', 'cjs'],
  external: [
    'vue',
    '@vue/runtime-core',
    '@vue/reactivity',
  ],
  dts: true,
})
```

## Declaration Files

Dependency handling for `.d.ts` files follows the same rules as JavaScript.

### Complex Type Resolution

Use TypeScript resolver for complex third-party types:

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  dts: {
    resolver: 'tsc',     // Use TypeScript resolver instead of Oxc
  },
})
```

**When to use `tsc` resolver:**
- Types in `@types/*` packages with non-standard naming (e.g., `@types/babel__generator`)
- Complex type dependencies
- Issues with default Oxc resolver

**Trade-off:** `tsc` is slower but more compatible.

## CLI Usage

### External

```bash
tsdown --external react --external react-dom
tsdown --external '/^@myorg\/.*/'
```

### No External

```bash
tsdown --no-external some-package
```

## Examples by Use Case

### Framework Component

```ts
// Don't bundle framework
export default defineConfig({
  external: ['vue', 'react', 'solid-js', 'svelte'],
})
```

### Standalone App

```ts
// Bundle everything
export default defineConfig({
  noExternal: [/.*/],
  skipNodeModulesBundle: false,
})
```

### Shared Library

```ts
// Bundle only specific utils
export default defineConfig({
  external: [/.*/],        // External by default
  noExternal: ['tiny-utils'], // Except this one
})
```

### Monorepo Package

```ts
// External workspace packages, bundle utilities
export default defineConfig({
  external: [
    /^@workspace\//,     // Other workspace packages
    'react',
    'react-dom',
  ],
  noExternal: [
    'lodash-es',         // Bundle utility libraries
  ],
})
```

## Troubleshooting

### Dependency Bundled Unexpectedly

Check if it's in `devDependencies` and imported. Move to `dependencies`:

```json
{
  "dependencies": {
    "should-be-external": "^1.0.0"
  }
}
```

Or explicitly externalize:

```ts
export default defineConfig({
  external: ['should-be-external'],
})
```

### Missing Dependency at Runtime

Ensure it's in `dependencies` or `peerDependencies`:

```json
{
  "dependencies": {
    "needed-package": "^1.0.0"
  }
}
```

Or bundle it:

```ts
export default defineConfig({
  noExternal: ['needed-package'],
})
```

### Type Resolution Errors

Use TypeScript resolver for complex types:

```ts
export default defineConfig({
  dts: {
    resolver: 'tsc',
  },
})
```

## Summary

**Default behavior:**
- `dependencies` & `peerDependencies` → External
- `devDependencies` & phantom deps → Bundled if imported

**Override:**
- `external` → Force external
- `noExternal` → Force bundled
- `skipNodeModulesBundle` → Skip all node_modules

**Declaration files:**
- Same bundling logic as JavaScript
- Use `resolver: 'tsc'` for complex types

## Tips

1. **Keep dependencies external** for libraries
2. **Bundle everything** for standalone CLIs
3. **Use regex patterns** for namespaced packages
4. **Check bundle size** to verify external/bundled split
5. **Test with fresh install** to catch missing dependencies
6. **Use tsc resolver** only when needed (slower)

## Related Options

- [External](option-dependencies.md) - This page
- [Platform](option-platform.md) - Runtime environment
- [Output Format](option-output-format.md) - Module formats
- [DTS](option-dts.md) - Type declarations


================================================
FILE: .agents/skills/tsdown/references/option-dts.md
================================================
# TypeScript Declaration Files

Generate `.d.ts` type declaration files for your library.

## Overview

tsdown uses [rolldown-plugin-dts](https://github.com/sxzz/rolldown-plugin-dts) to generate and bundle TypeScript declaration files.

**Requirements:**
- TypeScript must be installed in your project

## Enabling DTS Generation

### Auto-Enabled

DTS generation is **automatically enabled** if `package.json` contains:
- `types` field, or
- `typings` field

### Manual Enable

#### CLI

```bash
tsdown --dts
```

#### Config File

```ts
export default defineConfig({
  dts: true,
})
```

## Performance

### With `isolatedDeclarations` (Recommended)

**Extremely fast** - uses oxc-transform for generation.

```json
// tsconfig.json
{
  "compilerOptions": {
    "isolatedDeclarations": true
  }
}
```

### Without `isolatedDeclarations`

Falls back to TypeScript compiler. Reliable but slower.

## Declaration Maps

Map `.d.ts` files back to original `.ts` sources (useful for monorepos).

### Enable in tsconfig.json

```json
{
  "compilerOptions": {
    "declarationMap": true
  }
}
```

### Enable in tsdown Config

```ts
export default defineConfig({
  dts: {
    sourcemap: true,
  },
})
```

## Advanced Options

### Custom Compiler Options

Override TypeScript compiler options:

```ts
export default defineConfig({
  dts: {
    compilerOptions: {
      removeComments: false,
    },
  },
})
```

## Build Process

- **ESM format**: `.js` and `.d.ts` files generated in same build
- **CJS format**: Separate build process for `.d.ts` files

## Common Patterns

### Basic Library

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  format: ['esm', 'cjs'],
  dts: true,
})
```

Output:
- `dist/index.mjs`
- `dist/index.cjs`
- `dist/index.d.ts`

### Multiple Entry Points

```ts
export default defineConfig({
  entry: {
    index: 'src/index.ts',
    utils: 'src/utils.ts',
  },
  format: ['esm', 'cjs'],
  dts: true,
})
```

Output:
- `dist/index.mjs`, `dist/index.cjs`, `dist/index.d.ts`
- `dist/utils.mjs`, `dist/utils.cjs`, `dist/utils.d.ts`

### With Monorepo Support

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  format: ['esm', 'cjs'],
  dts: {
    sourcemap: true, // Enable declaration maps
  },
})
```

### Fast Build (Isolated Declarations)

```json
// tsconfig.json
{
  "compilerOptions": {
    "isolatedDeclarations": true,
    "declaration": true,
    "declarationMap": true
  }
}
```

```ts
// tsdown.config.ts
export default defineConfig({
  entry: ['src/index.ts'],
  format: ['esm', 'cjs'],
  dts: true, // Will use fast oxc-transform
})
```

## Troubleshooting

### Missing Types

Ensure TypeScript is installed:

```bash
pnpm add -D typescript
```

### Slow Generation

Enable `isolatedDeclarations` in `tsconfig.json` for faster builds.

### Declaration Errors

Check that all exports have explicit types (required for `isolatedDeclarations`).

### Report Issues

For DTS-specific issues, report to [rolldown-plugin-dts](https://github.com/sxzz/rolldown-plugin-dts/issues).

### Vue Support

Enable Vue component type generation (requires `vue-tsc`):

```ts
export default defineConfig({
  dts: {
    vue: true,
  },
})
```

### Oxc Transform

Control Oxc usage for declaration generation:

```ts
export default defineConfig({
  dts: {
    oxc: true,  // Use oxc-transform (fast, requires isolatedDeclarations)
  },
})
```

### Custom TSConfig

Specify a different tsconfig for DTS generation:

```ts
export default defineConfig({
  dts: {
    tsconfig: './tsconfig.build.json',
  },
})
```

## Available DTS Options

| Option | Type | Description |
|--------|------|-------------|
| `sourcemap` | `boolean` | Generate declaration source maps |
| `compilerOptions` | `object` | Override TypeScript compiler options |
| `vue` | `boolean` | Enable Vue type generation (requires vue-tsc) |
| `oxc` | `boolean` | Use oxc-transform for fast generation |
| `tsconfig` | `string` | Path to tsconfig file |
| `resolver` | `'oxc' \| 'tsc'` | Module resolver: `'oxc'` (default, fast) or `'tsc'` (more compatible) |
| `cjsDefault` | `boolean` | CJS default export handling |
| `sideEffects` | `boolean` | Preserve side effects in declarations |

## Tips

1. **Always enable DTS** for TypeScript libraries
2. **Use isolatedDeclarations** for fast builds
3. **Enable declaration maps** in monorepos
4. **Ensure explicit types** for all exports
5. **Install TypeScript** as dev dependency

## Related Options

- [Entry](option-entry.md) - Configure entry points
- [Output Format](option-output-format.md) - Multiple output formats
- [Target](option-target.md) - JavaScript version


================================================
FILE: .agents/skills/tsdown/references/option-entry.md
================================================
# Entry Points

Configure which files to bundle as entry points.

## Overview

Entry points are the starting files for the bundling process. Each entry point generates a separate bundle.

## Usage Patterns

### CLI

```bash
# Single entry
tsdown src/index.ts

# Multiple entries
tsdown src/index.ts src/cli.ts

# Glob patterns
tsdown 'src/*.ts'
```

### Config File

#### Single Entry

```ts
export default defineConfig({
  entry: 'src/index.ts',
})
```

#### Multiple Entries (Array)

```ts
export default defineConfig({
  entry: ['src/entry1.ts', 'src/entry2.ts'],
})
```

#### Named Entries (Object)

```ts
export default defineConfig({
  entry: {
    main: 'src/index.ts',
    utils: 'src/utils.ts',
    cli: 'src/cli.ts',
  },
})
```

Output files will match the keys:
- `dist/main.mjs`
- `dist/utils.mjs`
- `dist/cli.mjs`

## Glob Patterns

Match multiple files dynamically using glob patterns:

### All TypeScript Files

```ts
export default defineConfig({
  entry: 'src/**/*.ts',
})
```

### Exclude Test Files

```ts
export default defineConfig({
  entry: ['src/*.ts', '!src/*.test.ts'],
})
```

### Object Entries with Glob Patterns

Use glob wildcards (`*`) in both keys and values. The `*` in the key acts as a placeholder replaced with the matched file name (without extension):

```ts
export default defineConfig({
  entry: {
    // Maps src/foo.ts → dist/lib/foo.js, src/bar.ts → dist/lib/bar.js
    'lib/*': 'src/*.ts',
  },
})
```

#### Negation Patterns in Object Entries

Values can be an array with negation patterns (`!`):

```ts
export default defineConfig({
  entry: {
    'hooks/*': ['src/hooks/*.ts', '!src/hooks/index.ts'],
  },
})
```

Multiple positive and negation patterns:

```ts
export default defineConfig({
  entry: {
    'utils/*': [
      'src/utils/*.ts',
      'src/utils/*.tsx',
      '!src/utils/index.ts',
      '!src/utils/internal.ts',
    ],
  },
})
```

**Warning:** Multiple positive patterns in an array value must share the same base directory.

### Mixed Entries

Mix strings, glob patterns, and object entries in an array:

```ts
export default defineConfig({
  entry: [
    'src/*',
    '!src/foo.ts',
    { main: 'index.ts' },
    { 'lib/*': ['src/*.ts', '!src/bar.ts'] },
  ],
})
```

Object entries take precedence when output names conflict.

### Windows Compatibility

Use forward slashes `/` instead of backslashes `\` on Windows:

```ts
// ✅ Correct
entry: 'src/utils/*.ts'

// ❌ Wrong on Windows
entry: 'src\\utils\\*.ts'
```

## Common Patterns

### Library with Main Export

```ts
export default defineConfig({
  entry: 'src/index.ts',
  format: ['esm', 'cjs'],
  dts: true,
})
```

### Library with Multiple Exports

```ts
export default defineConfig({
  entry: {
    index: 'src/index.ts',
    client: 'src/client.ts',
    server: 'src/server.ts',
  },
  format: ['esm', 'cjs'],
  dts: true,
})
```

### CLI Tool

```ts
export default defineConfig({
  entry: {
    cli: 'src/cli.ts',
  },
  format: ['esm'],
  platform: 'node',
})
```

### Preserve Directory Structure

Use with `unbundle: true` to keep file structure:

```ts
export default defineConfig({
  entry: ['src/**/*.ts', '!**/*.test.ts'],
  unbundle: true,
  format: ['esm'],
  dts: true,
})
```

This will output files matching the source structure:
- `src/index.ts` → `dist/index.mjs`
- `src/utils/helper.ts` → `dist/utils/helper.mjs`

## Tips

1. **Use glob patterns** for multiple related files
2. **Use object syntax** for custom output names
3. **Exclude test files** with negation patterns `!**/*.test.ts`
4. **Combine with unbundle** to preserve directory structure
5. **Use named entries** for better control over output filenames


================================================
FILE: .agents/skills/tsdown/references/option-lint.md
================================================
# Package Validation (publint & attw)

Validate your package configuration and type declarations before publishing.

## Overview

tsdown integrates with [publint](https://publint.dev/) and [Are the types wrong?](https://arethetypeswrong.github.io/) (attw) to catch common packaging issues. Both are optional dependencies.

## Installation

```bash
# publint only
npm install -D publint

# attw only
npm install -D @arethetypeswrong/core

# both
npm install -D publint @arethetypeswrong/core
```

## publint

Checks that `package.json` fields (`exports`, `main`, `module`, `types`) match your actual output files.

### Enable

```ts
export default defineConfig({
  publint: true,
})
```

### Configuration

```ts
export default defineConfig({
  publint: {
    level: 'error', // 'warning' | 'error' | 'suggestion'
  },
})
```

### CLI

```bash
tsdown --publint
```

## attw (Are the types wrong?)

Verifies TypeScript declarations are correct across different module resolution strategies (`node10`, `node16`, `bundler`).

### Enable

```ts
export default defineConfig({
  attw: true,
})
```

### Configuration

```ts
export default defineConfig({
  attw: {
    profile: 'node16',   // 'strict' | 'node16' | 'esm-only'
    level: 'error',       // 'warn' | 'error'
    ignoreRules: ['false-cjs', 'cjs-resolves-to-esm'],
  },
})
```

### Profiles

| Profile | Description |
|---------|-------------|
| `strict` | Requires all resolutions to pass (default) |
| `node16` | Ignores `node10` resolution failures |
| `esm-only` | Ignores `node10` and `node16-cjs` resolution failures |

### Ignore Rules

Suppress specific problem types with `ignoreRules`:

| Rule | Description |
|------|-------------|
| `no-resolution` | Module could not be resolved |
| `untyped-resolution` | Resolution succeeded but has no types |
| `false-cjs` | Types indicate CJS but implementation is ESM |
| `false-esm` | Types indicate ESM but implementation is CJS |
| `cjs-resolves-to-esm` | CJS resolution points to an ESM module |
| `fallback-condition` | A fallback/wildcard condition was used |
| `cjs-only-exports-default` | CJS module only exports a default |
| `named-exports` | Named exports mismatch between types and implementation |
| `false-export-default` | Types declare a default export that doesn't exist |
| `missing-export-equals` | Types are missing `export =` for CJS |
| `unexpected-module-syntax` | File uses unexpected module syntax |
| `internal-resolution-error` | Internal resolution error in type checking |

### CLI

```bash
tsdown --attw
```

## CI Integration

Both tools support CI-aware options:

```ts
export default defineConfig({
  publint: 'ci-only',
  attw: {
    enabled: 'ci-only',
    profile: 'node16',
    level: 'error',
  },
})
```

Both tools require a `package.json` in your project directory.

## Related Options

- [CI Environment](advanced-ci.md) - CI-aware option details
- [Package Exports](option-package-exports.md) - Auto-generate exports field


================================================
FILE: .agents/skills/tsdown/references/option-log-level.md
================================================
# Log Level

Control the verbosity of build output.

## Overview

The `logLevel` option controls how much information tsdown displays during the build process.

## Type

```ts
logLevel?: 'silent' | 'error' | 'warn' | 'info'
```

**Default:** `'info'`

## Basic Usage

### CLI

```bash
# Suppress all output
tsdown --log-level silent

# Only show errors
tsdown --log-level error

# Show warnings and errors
tsdown --log-level warn

# Show all info (default)
tsdown --log-level info
```

### Config File

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  logLevel: 'error',
})
```

## Available Levels

| Level | Shows | Use Case |
|-------|-------|----------|
| `silent` | Nothing | CI/CD pipelines, scripting |
| `error` | Errors only | Minimal output |
| `warn` | Warnings + errors | Standard CI/CD |
| `info` | All messages | Development (default) |

## Common Patterns

### CI/CD Pipeline

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  logLevel: 'error',  // Only show errors in CI
})
```

### Scripting

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  logLevel: 'silent',  // No output for automation
})
```

## Fail on Warnings

The `failOnWarn` option controls whether warnings cause the build to exit with a non-zero code. Defaults to `'ci-only'` — warnings fail the build in CI but not locally.

```ts
export default defineConfig({
  failOnWarn: 'ci-only', // Default: fail on warnings only in CI
  // failOnWarn: true,   // Always fail on warnings
  // failOnWarn: false,  // Never fail on warnings
})
```

See [CI Environment](advanced-ci.md) for more about CI-aware options.

## Related Options

- [CI Environment](advanced-ci.md) - CI-aware option details
- [CLI Reference](reference-cli.md) - All CLI options
- [Config File](option-config-file.md) - Configuration setup


================================================
FILE: .agents/skills/tsdown/references/option-minification.md
================================================
# Minification

Compress code to reduce bundle size.

## Overview

Minification removes unnecessary characters (whitespace, comments) and optimizes code for production, reducing bundle size and improving load times.

**Note:** Uses [Oxc minifier](https://oxc.rs/docs/contribute/minifier) internally. The minifier is currently in alpha.

## Type

```ts
minify?: boolean | 'dce-only' | MinifyOptions
```

- `true` — Enable full minification (whitespace removal, mangling, compression)
- `false` — Disable minification (default)
- `'dce-only'` — Only perform dead code elimination without full minification
- `MinifyOptions` — Pass detailed options to the Oxc minifier

## Basic Usage

### CLI

```bash
# Enable minification
tsdown --minify

# Disable minification
tsdown --no-minify
```

**Note:** The CLI `--minify` flag is a boolean toggle. For `'dce-only'` mode or advanced options, use the config file.

### Config File

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  minify: true,
})
```

### DCE-Only Mode

Remove dead code without full minification (keeps readable output):

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  minify: 'dce-only',
})
```

## Example Output

### Without Minification

```js
// dist/index.mjs
const x = 1

function hello(x$1) {
  console.log('Hello World')
  console.log(x$1)
}

hello(x)
```

### With Minification

```js
// dist/index.mjs
const e=1;function t(e){console.log(`Hello World`),console.log(e)}t(e);
```

## Common Patterns

### Production Build

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  format: ['esm', 'cjs'],
  minify: true,
  clean: true,
})
```

### Conditional Minification

```ts
export default defineConfig((options) => ({
  entry: ['src/index.ts'],
  format: ['esm'],
  minify: !options.watch,  // Only minify in production
}))
```

### Browser Library

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  format: ['iife'],
  platform: 'browser',
  globalName: 'MyLib',
  minify: true,
})
```

### Multiple Builds

```ts
export default defineConfig([
  // Development build
  {
    entry: ['src/index.ts'],
    format: ['esm'],
    minify: false,
    outDir: 'dist/dev',
  },
  // Production build
  {
    entry: ['src/index.ts'],
    format: ['esm'],
    minify: true,
    outDir: 'dist/prod',
  },
])
```

## CLI Examples

```bash
# Production build with minification
tsdown --minify --clean

# Multiple formats with minification
tsdown --format esm --format cjs --minify

# Conditional minification (only when not watching)
tsdown --minify  # Or omit --watch
```

## Tips

1. **Use `minify: true`** for production builds
2. **Use `'dce-only'`** to remove dead code while keeping output readable
3. **Skip minification** during development for faster rebuilds
4. **Combine with tree shaking** for best results
5. **Test minified output** thoroughly (Oxc minifier is in alpha)

## Troubleshooting

### Minified Code Has Bugs

Oxc minifier is in alpha and may have issues:

1. **Use DCE-only mode**: `minify: 'dce-only'`
2. **Report bug** to [Oxc project](https://github.com/oxc-project/oxc/issues)
3. **Disable minification**: `minify: false`

### Unexpected Output

- **Test unminified** first to isolate issue
- **Check source maps** for debugging
- **Verify target compatibility**

## Related Options

- [Tree Shaking](option-tree-shaking.md) - Remove unused code
- [Target](option-target.md) - Syntax transformations
- [Output Format](option-output-format.md) - Module formats
- [Sourcemap](option-sourcemap.md) - Debug information


================================================
FILE: .agents/skills/tsdown/references/option-output-directory.md
================================================
# Output Directory

Configure the output directory for bundled files.

## Overview

By default, tsdown outputs bundled files to the `dist` directory. You can customize this location using the `outDir` option.

## Basic Usage

### CLI

```bash
# Default output to dist/
tsdown

# Custom output directory
tsdown --out-dir build
tsdown -d lib
```

### Config File

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  outDir: 'build',
})
```

## Common Patterns

### Standard Library

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  format: ['esm', 'cjs'],
  outDir: 'dist',  // Default
  dts: true,
})
```

**Output:**
```
dist/
├── index.mjs
├── index.cjs
└── index.d.ts
```

### Separate Directories by Format

```ts
export default defineConfig([
  {
    entry: ['src/index.ts'],
    format: ['esm'],
    outDir: 'dist/esm',
  },
  {
    entry: ['src/index.ts'],
    format: ['cjs'],
    outDir: 'dist/cjs',
  },
])
```

**Output:**
```
dist/
├── esm/
│   └── index.js
└── cjs/
    └── index.js
```

### Monorepo Package

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  outDir: 'lib',  // Custom directory
  clean: true,
})
```

### Build to Root

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  outDir: '.',  // Output to project root (not recommended)
  clean: false,  // Don't clean root!
})
```

**Warning:** Be careful when outputting to root to avoid deleting important files.

## Output Extensions

### Custom Extensions

Use `outExtensions` to control file extensions:

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  format: ['esm', 'cjs'],
  outDir: 'dist',
  outExtensions({ format }) {
    return {
      js: format === 'esm' ? '.mjs' : '.cjs',
    }
  },
})
```

### Default Extensions

| Format | Default Extension | With `type: "module"` |
|--------|-------------------|----------------------|
| `esm` | `.mjs` | `.js` |
| `cjs` | `.cjs` | `.js` |
| `iife` | `.global.js` | `.global.js` |
| `umd` | `.umd.js` | `.umd.js` |

### ESM with .js Extension

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  format: ['esm'],
  outExtensions: () => ({ js: '.js' }),
})
```

Requires `"type": "module"` in package.json.

## File Naming

### Entry Names

Control output filenames based on entry names:

```ts
export default defineConfig({
  entry: {
    index: 'src/index.ts',
    utils: 'src/utils.ts',
  },
  outDir: 'dist',
})
```

**Output:**
```
dist/
├── index.mjs
└── utils.mjs
```

### Glob Entry

```ts
export default defineConfig({
  entry: ['src/**/*.ts', '!**/*.test.ts'],
  outDir: 'dist',
  unbundle: true,  // Preserve structure
})
```

**Output:**
```
dist/
├── index.mjs
├── utils/
│   └── helper.mjs
└── components/
    └── button.mjs
```

## Multiple Builds

### Same Output Directory

```ts
export default defineConfig([
  {
    entry: ['src/index.ts'],
    outDir: 'dist',
    clean: true,  // Clean first
  },
  {
    entry: ['src/cli.ts'],
    outDir: 'dist',
    clean: false,  // Don't clean again
  },
])
```

### Different Output Directories

```ts
export default defineConfig([
  {
    entry: ['src/index.ts'],
    format: ['esm', 'cjs'],
    outDir: 'dist/lib',
  },
  {
    entry: ['src/cli.ts'],
    format: ['esm'],
    outDir: 'dist/bin',
  },
])
```

## CLI Examples

```bash
# Default
tsdown

# Custom directory
tsdown --out-dir build
tsdown -d lib

# Nested directory
tsdown --out-dir dist/lib

# With other options
tsdown --out-dir build --format esm,cjs --dts
```

## Tips

1. **Use default `dist`** for standard projects
2. **Be careful with root** - avoid `outDir: '.'`
3. **Clean before build** - use `clean: true`
4. **Consistent naming** - match your project conventions
5. **Separate by format** if needed for clarity
6. **Check .gitignore** - ensure output dir is ignored

## Troubleshooting

### Files Not in Expected Location

- Check `outDir` config
- Verify build completed successfully
- Look for typos in path

### Files Deleted Unexpectedly

- Check if `clean: true`
- Ensure outDir doesn't overlap with source
- Don't use root as outDir

### Permission Errors

- Check write permissions
- Ensure directory isn't locked
- Try different location

## Related Options

- [Cleaning](option-cleaning.md) - Clean output directory
- [Entry](option-entry.md) - Entry points
- [Output Format](option-output-format.md) - Module formats
- [Unbundle](option-unbundle.md) - Preserve structure


================================================
FILE: .agents/skills/tsdown/references/option-output-format.md
================================================
# Output Format

Configure the module format(s) for generated bundles.

## Overview

tsdown can generate bundles in multiple formats. Default is ESM.

## Available Formats

| Format | Description | Use Case |
|--------|-------------|----------|
| `esm` | ECMAScript Module (default) | Modern Node.js, browsers, Deno |
| `cjs` | CommonJS | Legacy Node.js, require() |
| `iife` | Immediately Invoked Function Expression | Browser `<script>` tags |
| `umd` | Universal Module Definition | AMD, CommonJS, and globals |

## Usage

### CLI

```bash
# Single format
tsdown --format esm

# Multiple formats
tsdown --format esm --format cjs

# Or comma-separated
tsdown --format esm,cjs
```

### Config File

#### Single Format

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  format: 'esm',
})
```

#### Multiple Formats

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  format: ['esm', 'cjs'],
})
```

## Per-Format Configuration

Override options for specific formats:

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  format: {
    esm: {
      target: ['es2015'],
    },
    cjs: {
      target: ['node20'],
    },
  },
})
```

This allows different targets, platforms, or other settings per format.

## Common Patterns

### Modern Library (ESM + CJS)

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  format: ['esm', 'cjs'],
  dts: true,
})
```

Output:
- `dist/index.mjs` (ESM)
- `dist/index.cjs` (CJS)
- `dist/index.d.ts` (Types)

### Browser Library (IIFE)

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  format: ['iife'],
  globalName: 'MyLib',
  platform: 'browser',
  minify: true,
})
```

Output: `dist/index.global.js` (IIFE with global `MyLib`)

### Universal Library (UMD)

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  format: ['umd'],
  globalName: 'MyLib',
  platform: 'neutral',
})
```

Works with AMD, CommonJS, and browser globals.

### Node.js Package (CJS + ESM)

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  format: ['esm', 'cjs'],
  platform: 'node',
  dts: true,
  shims: true, // Add __dirname, __filename for CJS compat
})
```

### Framework Component Library

```ts
export default defineConfig({
  entry: ['src/index.tsx'],
  format: ['esm', 'cjs'],
  external: ['react', 'react-dom'], // Don't bundle dependencies
  dts: true,
})
```

## Format-Specific Outputs

### File Extensions

| Format | Extension |
|--------|-----------|
| ESM | `.mjs` or `.js` (with `"type": "module"`) |
| CJS | `.cjs` or `.js` (without `"type": "module"`) |
| IIFE | `.global.js` |
| UMD | `.umd.js` |

### Customize Extensions

Use `outExtensions` to override:

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  format: ['esm', 'cjs'],
  outExtensions: ({ format }) => ({
    js: format === 'esm' ? '.js' : '.cjs',
  }),
})
```

## Tips

1. **Use ESM + CJS** for maximum compatibility
2. **Use IIFE** for browser-only libraries
3. **Use UMD** for universal compatibility (less common now)
4. **Externalize dependencies** to avoid bundling framework code
5. **Add shims** for CJS compatibility when using Node.js APIs
6. **Set globalName** for IIFE/UMD formats

## Related Options

- [Target](option-target.md) - Set JavaScript version
- [Platform](option-platform.md) - Set platform (node, browser, neutral)
- [Shims](option-shims.md) - Add ESM/CJS compatibility
- [Output Directory](option-output-directory.md) - Customize output paths


================================================
FILE: .agents/skills/tsdown/references/option-package-exports.md
================================================
# Auto-Generate Package Exports

Automatically generate package.json exports field from build output.

## Overview

tsdown can automatically infer and generate the `exports`, `main`, `module`, and `types` fields in your `package.json` based on your build outputs.

**Status:** Experimental - review before publishing.

## Basic Usage

### CLI

```bash
tsdown --exports
```

### Config File

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  format: ['esm', 'cjs'],
  dts: true,
  exports: true,
})
```

## What Gets Generated

### Single Entry

**Config:**
```ts
export default defineConfig({
  entry: ['src/index.ts'],
  format: ['esm', 'cjs'],
  dts: true,
  exports: true,
})
```

**Generated in package.json:**
```json
{
  "main": "./dist/index.cjs",
  "module": "./dist/index.mjs",
  "types": "./dist/index.d.ts",
  "exports": {
    ".": {
      "types": "./dist/index.d.ts",
      "import": "./dist/index.mjs",
      "require": "./dist/index.cjs"
    }
  }
}
```

### Multiple Entries

**Config:**
```ts
export default defineConfig({
  entry: {
    index: 'src/index.ts',
    utils: 'src/utils.ts',
  },
  format: ['esm', 'cjs'],
  dts: true,
  exports: true,
})
```

**Generated in package.json:**
```json
{
  "main": "./dist/index.cjs",
  "module": "./dist/index.mjs",
  "types": "./dist/index.d.ts",
  "exports": {
    ".": {
      "types": "./dist/index.d.ts",
      "import": "./dist/index.mjs",
      "require": "./dist/index.cjs"
    },
    "./utils": {
      "types": "./dist/utils.d.ts",
      "import": "./dist/utils.mjs",
      "require": "./dist/utils.cjs"
    }
  }
}
```

## Export All Files

Include all output files, not just entry points:

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  format: ['esm', 'cjs'],
  exports: {
    all: true,
  },
})
```

**Result:** All `.mjs`, `.cjs`, and `.d.ts` files will be added to exports.

## Dev-Time Source Linking

### Dev Exports

Link to source files during development:

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  format: ['esm', 'cjs'],
  exports: {
    devExports: true,
  },
})
```

**Generated:**
```json
{
  "exports": {
    ".": "./src/index.ts"  // Points to source
  },
  "publishConfig": {
    "exports": {
      ".": {
        "import": "./dist/index.mjs",
        "require": "./dist/index.cjs"
      }
    }
  }
}
```

**Note:** Supported by pnpm/yarn, not npm.

### Conditional Dev Exports

Use specific condition for dev exports:

```ts
export default defineConfig({
  exports: {
    devExports: 'development',
  },
})
```

**Generated:**
```json
{
  "exports": {
    ".": {
      "development": "./src/index.ts",
      "import": "./dist/index.mjs",
      "require": "./dist/index.cjs"
    }
  }
}
```

**Use with TypeScript customConditions:**
```json
// tsconfig.json
{
  "compilerOptions": {
    "customConditions": ["development"]
  }
}
```

## Custom Exports

Add custom export mappings:

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  exports: {
    customExports(pkg, context) {
      // Add custom export
      pkg['./foo'] = './dist/foo.js'

      // Add package.json export
      pkg['./package.json'] = './package.json'

      return pkg
    },
  },
})
```

## Common Patterns

### Complete Library Setup

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  format: ['esm', 'cjs'],
  dts: true,
  exports: true,
  clean: true,
})
```

### Multiple Exports with Dev Mode

```ts
export default defineConfig({
  entry: {
    index: 'src/index.ts',
    client: 'src/client.ts',
    server: 'src/server.ts',
  },
  format: ['esm', 'cjs'],
  dts: true,
  exports: {
    all: false,  // Only entries
    devExports: 'development',
  },
})
```

### Monorepo Package

```ts
export default defineConfig({
  workspace: 'packages/*',
  entry: ['src/index.ts'],
  format: ['esm', 'cjs'],
  dts: true,
  exports: true,  // Generate for each package
})
```

## Validation

### Enable Publint

Validate generated exports:

```bash
tsdown --exports --publint
```

Or in config:

```ts
export default defineConfig({
  exports: true,
  publint: true,  // Validate exports
})
```

## Tips

1. **Review before publishing** - Check generated fields
2. **Use with publint** - Validate exports field
3. **Enable for libraries** - Especially with multiple exports
4. **Use devExports** - Better DX during development
5. **Test exports** - Verify imports work correctly

## Troubleshooting

### Exports Not Generated

- Ensure `exports: true` is set
- Check build completed successfully
- Verify output files exist

### Wrong Export Paths

- Check `outDir` configuration
- Verify entry names match expectations
- Review `format` settings

### Dev Exports Not Working

- Only supported by pnpm/yarn
- Check package manager
- Use `publishConfig` for publishing

### Types Not Exported

- Enable `dts: true`
- Ensure TypeScript is installed
- Check `.d.ts` files are generated

## CLI Examples

```bash
# Generate exports
tsdown --exports

# With publint validation
tsdown --exports --publint

# Export all files
tsdown --exports

# With dev exports
tsdown --exports
```

## Related Options

- [Entry](option-entry.md) - Configure entry points
- [Output Format](option-output-format.md) - Module formats
- [DTS](option-dts.md) - Type declarations


================================================
FILE: .agents/skills/tsdown/references/option-platform.md
================================================
# Platform

Target runtime environment for bundled code.

## Overview

Platform determines the runtime environment and affects module resolution, built-in handling, and optimizations.

## Available Platforms

| Platform | Runtime | Built-ins | Use Case |
|----------|---------|-----------|----------|
| `node` | Node.js (default) | Resolved automatically | Server-side, CLIs, tooling |
| `browser` | Web browsers | Warning if used | Front-end applications |
| `neutral` | Platform-agnostic | No assumptions | Universal libraries |

## Usage

### CLI

```bash
tsdown --platform node     # Default
tsdown --platform browser
tsdown --platform neutral
```

### Config File

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  platform: 'browser',
})
```

## Platform Details

### Node Platform

**Default platform** for server-side and tooling.

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  platform: 'node',
})
```

**Characteristics:**
- Node.js built-ins (fs, path, etc.) resolved automatically
- Optimized for Node.js runtime
- Compatible with Deno and Bun
- Default mainFields: `['main', 'module']`

### Browser Platform

For web applications running in browsers.

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  platform: 'browser',
  format: ['esm'],
})
```

**Characteristics:**
- Warnings if Node.js built-ins are used
- May require polyfills for Node APIs
- Optimized for browser environments
- Default mainFields: `['browser', 'module', 'main']`

### Neutral Platform

Platform-agnostic for universal libraries.

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  platform: 'neutral',
  format: ['esm'],
})
```

**Characteristics:**
- No runtime assumptions
- No automatic built-in resolution
- Relies on `exports` field only
- Default mainFields: `[]`
- Full control over runtime behavior

## CJS Format Limitation

**CJS format always uses `node` platform** and cannot be changed.

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  format: ['cjs'],
  platform: 'browser',  // Ignored for CJS
})
```

See [rolldown PR #4693](https://github.com/rolldown/rolldown/pull/4693#issuecomment-2912229545) for details.

## Module Resolution

### Main Fields

Different platforms check different `package.json` fields:

| Platform | mainFields | Priority |
|----------|------------|----------|
| `node` | `['main', 'module']` | main → module |
| `browser` | `['browser', 'module', 'main']` | browser → module → main |
| `neutral` | `[]` | Only `exports` field |

### Neutral Platform Resolution

When using `neutral`, packages without `exports` field may fail to resolve:

```
Help: The "main" field here was ignored. Main fields must be configured
explicitly when using the "neutral" platform.
```

**Solution:** Configure mainFields explicitly:

```ts
export default defineConfig({
  platform: 'neutral',
  inputOptions: {
    resolve: {
      mainFields: ['module', 'main'],
    },
  },
})
```

## Common Patterns

### Node.js CLI Tool

```ts
export default defineConfig({
  entry: ['src/cli.ts'],
  format: ['esm'],
  platform: 'node',
  shims: true,
})
```

### Browser Library (IIFE)

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  format: ['iife'],
  platform: 'browser',
  globalName: 'MyLib',
  minify: true,
})
```

### Universal Library

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  format: ['esm'],
  platform: 'neutral',
  inputOptions: {
    resolve: {
      mainFields: ['module', 'main'],
    },
  },
})
```

### React Component Library

```ts
export default defineConfig({
  entry: ['src/index.tsx'],
  format: ['esm', 'cjs'],
  platform: 'browser',
  external: ['react', 'react-dom'],
})
```

### Node.js + Browser Builds

```ts
export default defineConfig([
  {
    entry: ['src/index.ts'],
    format: ['esm', 'cjs'],
    platform: 'node',
  },
  {
    entry: ['src/browser.ts'],
    format: ['esm'],
    platform: 'browser',
  },
])
```

## Troubleshooting

### Node Built-in Warnings (Browser)

When using Node.js APIs in browser builds:

```
Warning: Module "fs" has been externalized for browser compatibility
```

**Solutions:**
1. Use platform: 'node' if not browser-only
2. Add polyfills for Node APIs
3. Avoid Node.js built-ins in browser code
4. Use platform: 'neutral' with careful dependency management

### Module Resolution Issues (Neutral)

When packages don't resolve with `neutral`:

```ts
export default defineConfig({
  platform: 'neutral',
  inputOptions: {
    resolve: {
      mainFields: ['module', 'browser', 'main'],
      conditions: ['import', 'require'],
    },
  },
})
```

## Tips

1. **Use `node`** for server-side and CLIs (default)
2. **Use `browser`** for front-end applications
3. **Use `neutral`** for universal libraries
4. **Configure mainFields** when using neutral platform
5. **CJS is always node** - use ESM for other platforms
6. **Test in target environment** to verify compatibility

## Related Options

- [Output Format](option-output-format.md) - Module formats
- [Target](option-target.md) - JavaScript version
- [Shims](option-shims.md) - ESM/CJS compatibility
- [Dependencies](option-dependencies.md) - External packages


================================================
FILE: .agents/skills/tsdown/references/option-shims.md
================================================
# Shims

Add compatibility between ESM and CommonJS module systems.

## Overview

Shims provide small pieces of code that bridge the gap between CommonJS (CJS) and ECMAScript Modules (ESM), enabling cross-module-system compatibility.

## What Shims Provide

### ESM Output (when enabled)

With `shims: true`, adds CommonJS variables to ESM:

- `__dirname` - Current directory path
- `__filename` - Current file path

### ESM Output (automatic)

Always added when using `require` in ESM on Node.js:

- `require` function via `createRequire(import.meta.url)`

### CJS Output (automatic)

Always added to CommonJS output:

- `import.meta.url`
- `import.meta.dirname`
- `import.meta.filename`

## Usage

### CLI

```bash
tsdown --shims
```

### Config File

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  format: ['esm'],
  shims: true,
})
```

## Generated Code

### ESM with Shims

**Source:**
```ts
console.log(__dirname)
console.log(__filename)
```

**Output (shims: true):**
```js
import { fileURLToPath } from 'node:url'
import { dirname } from 'node:path'

const __filename = fileURLToPath(import.meta.url)
const __dirname = dirname(__filename)

console.log(__dirname)
console.log(__filename)
```

### ESM with require

**Source:**
```ts
const mod = require('some-module')
```

**Output (automatic on Node.js):**
```js
import { createRequire } from 'node:module'
const require = createRequire(import.meta.url)

const mod = require('some-module')
```

### CJS with import.meta

**Source:**
```ts
console.log(import.meta.url)
console.log(import.meta.dirname)
```

**Output (automatic):**
```js
const import_meta = {
  url: require('url').pathToFileURL(__filename).toString(),
  dirname: __dirname,
  filename: __filename
}

console.log(import_meta.url)
console.log(import_meta.dirname)
```

## Common Patterns

### Node.js CLI Tool

```ts
export default defineConfig({
  entry: ['src/cli.ts'],
  format: ['esm'],
  platform: 'node',
  shims: true,  // Add __dirname, __filename
})
```

### Dual Format Library

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  format: ['esm', 'cjs'],
  platform: 'node',
  shims: true,  // ESM gets __dirname/__filename
                // CJS gets import.meta.* (automatic)
})
```

### Server-Side Code

```ts
export default defineConfig({
  entry: ['src/server.ts'],
  format: ['esm'],
  platform: 'node',
  shims: true,
  external: [/.*/],  // External all deps
})
```

### File System Operations

```ts
// Source code
import { readFileSync } from 'fs'
import { join } from 'path'

// Read file relative to current module
const content = readFileSync(join(__dirname, 'data.json'), 'utf-8')
```

```ts
// tsdown config
export default defineConfig({
  entry: ['src/index.ts'],
  format: ['esm'],
  shims: true,  // Enables __dirname
})
```

## When to Use Shims

### Use `shims: true` when:

- ✅ Building Node.js tools/CLIs
- ✅ Code uses `__dirname` or `__filename`
- ✅ Need file system operations relative to module
- ✅ Migrating from CommonJS to ESM
- ✅ Need cross-format compatibility

### Don't need shims when:

- ❌ Browser-only code
- ❌ No file system operations
- ❌ Using only `import.meta.url`
- ❌ Pure ESM without CJS variables

## Performance Impact

### Runtime Overhead

Shims add minimal runtime overhead:

```js
// Added to output when shims enabled
import { fileURLToPath } from 'node:url'
import { dirname } from 'node:path'

const __filename = fileURLToPath(import.meta.url)
const __dirname = dirname(__filename)
```

### Tree Shaking

If `__dirname` or `__filename` are not used, they're automatically removed during bundling (no overhead).

## Platform Considerations

### Node.js Platform

```ts
export default defineConfig({
  platform: 'node',
  format: ['esm'],
  shims: true,  // Recommended for Node.js
})
```

- `require` shim added automatically
- `__dirname` and `__filename` available with `shims: true`

### Browser Platform

```ts
export default defineConfig({
  platform: 'browser',
  format: ['esm'],
  shims: false,  // Not needed for browser
})
```

- Shims not needed (no Node.js variables)
- Will cause warnings if Node.js APIs used

### Neutral Platform

```ts
export default defineConfig({
  platform: 'neutral',
  format: ['esm'],
  shims: false,  // Avoid platform-specific code
})
```

- Avoid shims for maximum portability

## CLI Examples

```bash
# Enable shims
tsdown --shims

# ESM with shims for Node.js
tsdown --format esm --platform node --shims

# Dual format with shims
tsdown --format esm --format cjs --shims
```

## Troubleshooting

### `__dirname is not defined`

Enable shims:

```ts
export default defineConfig({
  shims: true,
})
```

### `require is not defined` in ESM

Automatic on Node.js platform. If not working:

```ts
export default defineConfig({
  platform: 'node',  // Ensure Node.js platform
})
```

### Import.meta not working in CJS

Automatic - no configuration needed. If still failing, check output format:

```ts
export default defineConfig({
  format: ['cjs'],  // Shims added automatically
})
```

## Tips

1. **Enable for Node.js tools** - Use `shims: true` for CLIs and servers
2. **Skip for browsers** - Not needed for browser code
3. **No overhead if unused** - Automatically tree-shaken
4. **Automatic require shim** - No config needed for `require` in ESM
5. **CJS shims automatic** - `import.meta.*` always available in CJS

## Related Options

- [Platform](option-platform.md) - Runtime environment
- [Output Format](option-output-format.md) - Module formats
- [Target](option-target.md) - Syntax transformations


================================================
FILE: .agents/skills/tsdown/references/option-sourcemap.md
================================================
# Source Maps

Generate source maps for debugging bundled code.

## Overview

Source maps map minified/bundled code back to original source files, making debugging significantly easier by showing original line numbers and variable names.

## Basic Usage

### CLI

```bash
tsdown --sourcemap

# Or inline
tsdown --sourcemap inline
```

### Config File

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  sourcemap: true,
})
```

## Source Map Types

### External (default)

Generates separate `.map` files:

```ts
export default defineConfig({
  sourcemap: true,  // or 'external'
})
```

**Output:**
- `dist/index.mjs`
- `dist/index.mjs.map`

**Pros:**
- Smaller bundle size
- Can be excluded from production
- Faster parsing

### Inline

Embeds source maps in the bundle:

```ts
export default defineConfig({
  sourcemap: 'inline',
})
```

**Output:**
- `dist/index.mjs` (includes source map as data URL)

**Pros:**
- Single file deployment
- Guaranteed to be available

**Cons:**
- Larger bundle size
- Exposed in production

### Hidden

Generates map files without reference comment:

```ts
export default defineConfig({
  sourcemap: 'hidden',
})
```

**Output:**
- `dist/index.mjs` (no `//# sourceMappingURL` comment)
- `dist/index.mjs.map`

**Use when:**
- You want maps for error reporting tools
- But don't want them exposed to users

## Auto-Enable Scenarios

### Declaration Maps

If `declarationMap` is enabled in `tsconfig.json`, source maps are automatically enabled:

```json
// tsconfig.json
{
  "compilerOptions": {
    "declarationMap": true
  }
}
```

This also generates `.d.ts.map` files for TypeScript declarations.

## Common Patterns

### Development Build

```ts
export default defineConfig((options) => ({
  entry: ['src/index.ts'],
  sourcemap: options.watch,  // Only in dev
  minify: !options.watch,
}))
```

### Production with External Maps

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  format: ['esm', 'cjs'],
  sourcemap: true,  // External maps
  minify: true,
})
```

Deploy maps to separate error reporting service.

### Always Inline (Development Tool)

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  format: ['esm'],
  sourcemap: 'inline',
})
```

### Per-Format Source Maps

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  format: {
    esm: {
      sourcemap: true,
    },
    iife: {
      sourcemap: 'inline',  // Inline for browser
    },
  },
})
```

### TypeScript Library with Declaration Maps

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  format: ['esm', 'cjs'],
  sourcemap: true,
  dts: {
    sourcemap: true,  // Enable declaration maps
  },
})
```

**Output:**
- `dist/index.mjs` + `dist/index.mjs.map`
- `dist/index.cjs` + `dist/index.cjs.map`
- `dist/index.d.ts` + `dist/index.d.ts.map`

## Benefits

### For Development

- **Faster debugging** - See original code in debugger
- **Better error messages** - Stack traces show original lines
- **Easier breakpoints** - Set breakpoints on source code

### For Production

- **Error reporting** - Send accurate error locations to services
- **Monitoring** - Track errors back to source
- **Support** - Help users report issues accurately

## Performance Impact

| Type | Bundle Size | Parse Speed | Debugging |
|------|-------------|-------------|-----------|
| None | Smallest | Fastest | Hard |
| External | Small | Fast | Easy |
| Inline | Largest | Slower | Easy |
| Hidden | Small | Fast | Tools only |

## CLI Examples

```bash
# Enable source maps
tsdown --sourcemap

# Inline source maps
tsdown --sourcemap inline

# Hidden source maps
tsdown --sourcemap hidden

# Development with source maps
tsdown --watch --sourcemap

# Production with external maps
tsdown --minify --sourcemap

# No source maps
tsdown --no-sourcemap
```

## Use Cases

### Local Development

```ts
export default defineConfig({
  sourcemap: true,
  minify: false,
})
```

### Production Build

```ts
export default defineConfig({
  sourcemap: 'external',  // Upload to error service
  minify: true,
})
```

### Browser Library

```ts
export default defineConfig({
  format: ['iife'],
  platform: 'browser',
  sourcemap: 'inline',  // Self-contained
  globalName: 'MyLib',
})
```

### Node.js CLI Tool

```ts
export default defineConfig({
  format: ['esm'],
  platform: 'node',
  sourcemap: true,
  shims: true,
})
```

## Troubleshooting

### Source Maps Not Working

1. **Check output** - Verify `.map` files are generated
2. **Check reference** - Look for `//# sourceMappingURL=` comment
3. **Check paths** - Ensure relative paths are correct
4. **Check tool** - Verify debugger/browser supports source maps

### Large Bundle Size

Use external source maps instead of inline:

```ts
export default defineConfig({
  sourcemap: true,  // Not 'inline'
})
```

### Source Not Found

- Ensure source files are accessible relative to map
- Check `sourceRoot` in generated map
- Verify paths in `sources` array

## Tips

1. **Use external maps** for production (smaller bundles)
2. **Use inline maps** for single-file tools
3. **Enable in development** for better DX
4. **Upload to error services** for production debugging
5. **Use hidden maps** when you want them for tools only
6. **Enable declaration maps** for TypeScript libraries

## Related Options

- [Minification](option-minification.md) - Code compression
- [DTS](option-dts.md) - TypeScript declarations
- [Watch Mode](option-watch-mode.md) - Development workflow
- [Target](option-target.md) - Syntax transformations


================================================
FILE: .agents/skills/tsdown/references/option-target.md
================================================
# Target Environment

Configure JavaScript syntax transformations for target environments.

## Overview

The `target` option controls which JavaScript features are downleveled (transformed to older syntax) for compatibility.

**Important:** Only affects syntax transformations, not runtime polyfills.

## Default Behavior

tsdown auto-reads from `package.json`:

```json
// package.json
{
  "engines": {
    "node": ">=18.0.0"
  }
}
```

Automatically sets `target` to `node18.0.0`.

If no `engines.node` field exists, behaves as if `target: false` (no transformations).

## Disabling Transformations

Set to `false` to preserve modern syntax:

```ts
export default defineConfig({
  target: false,
})
```

**Result:**
- No JavaScript downleveling
- Modern features preserved (optional chaining `?.`, nullish coalescing `??`, etc.)

**Use when:**
- Targeting modern environments
- Handling transformations elsewhere
- Building libraries for further processing

## Setting Target

### CLI

```bash
# Single target
tsdown --target es2020
tsdown --target node20

# Multiple targets
tsdown --target chrome100 --target node20.18

# Disable
tsdown --no-target
```

### Config File

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  target: 'es2020',
})
```

### Multiple Targets

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  target: ['chrome100', 'safari15', 'node18'],
})
```

## Supported Targets

### ECMAScript Versions

- `es2015`, `es2016`, `es2017`, `es2018`, `es2019`, `es2020`, `es2021`, `es2022`, `es2023`, `esnext`

### Browser Versions

- `chrome100`, `safari18`, `firefox110`, `edge100`, etc.

### Node.js Versions

- `node16`, `node18`, `node20`, `node20.18`, etc.

## Examples

### Modern Browsers

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  format: ['esm'],
  target: ['chrome100', 'safari15', 'firefox100'],
})
```

### Node.js Library

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  format: ['esm', 'cjs'],
  target: 'node18',
})
```

### Legacy Support

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  format: ['esm'],
  target: 'es2015',  // Maximum compatibility
})
```

### Per-Format Targets

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  format: {
    esm: {
      target: 'es2020',
    },
    cjs: {
      target: 'node16',
    },
  },
})
```

## Decorators

### Legacy Decorators (Stage 2)

Enable in `tsconfig.json`:

```json
{
  "compilerOptions": {
    "experimentalDecorators": true
  }
}
```

### Stage 3 Decorators

**Not currently supported** by tsdown/Rolldown/Oxc.

See [oxc issue #9170](https://github.com/oxc-project/oxc/issues/9170).

## Common Patterns

### Universal Library

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  format: ['esm', 'cjs'],
  target: 'es2020',  // Wide compatibility
})
```

### Modern-Only Library

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  format: ['esm'],
  target: false,  // No transformations
})
```

### Browser Component

```ts
export default defineConfig({
  entry: ['src/index.tsx'],
  format: ['esm'],
  target: ['chrome100', 'safari15', 'firefox100'],
  platform: 'browser',
})
```

## Tips

1. **Let tsdown auto-detect** from package.json when possible
2. **Use `false`** for modern-only builds
3. **Specify multiple targets** for broader compatibility
4. **Use legacy decorators** with `experimentalDecorators`
6. **Test output** in target environments

## Related Options

- [Platform](option-platform.md) - Runtime environment
- [Output Format](option-output-format.md) - Module formats
- [Minification](option-minification.md) - Code optimization


================================================
FILE: .agents/skills/tsdown/references/option-tree-shaking.md
================================================
# Tree Shaking

Remove unused code from bundles.

## Overview

Tree shaking eliminates dead code (unused exports) from your final bundle, reducing size and improving performance.

**Default:** Enabled

## Basic Usage

### CLI

```bash
# Tree shaking enabled (default)
tsdown

# Disable tree shaking
tsdown --no-treeshake
```

### Config File

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  treeshake: true,  // Default
})
```

## How It Works

### With Tree Shaking

**Source:**
```ts
// src/util.ts
export function unused() {
  console.log("I'm unused")
}

export function hello(x: number) {
  console.log('Hello World', x)
}

// src/index.ts
import { hello } from './util'
hello(1)
```

**Output:**
```js
// dist/index.mjs
function hello(x) {
  console.log('Hello World', x)
}
hello(1)
```

`unused()` function is removed because it's never imported.

### Without Tree Shaking

**Output:**
```js
// dist/index.mjs
function unused() {
  console.log("I'm unused")
}

function hello(x) {
  console.log('Hello World', x)
}
hello(1)
```

All code is included, even if unused.

## Advanced Configuration

### Enable (Default)

```ts
export default defineConfig({
  treeshake: true,
})
```

Uses Rolldown's default tree shaking.

### Custom Options

```ts
export default defineConfig({
  treeshake: {
    moduleSideEffects: false,
    propertyReadSideEffects: false,
    unknownGlobalSideEffects: false,
  },
})
```

See [Rolldown docs](https://rolldown.rs/reference/config-options#treeshake) for all options.

### Disable

```ts
export default defineConfig({
  treeshake: false,
})
```

## Side Effects

### Package.json sideEffects

Declare side effects in your package:

```json
{
  "sideEffects": false
}
```

Or specify files with side effects:

```json
{
  "sideEffects": ["*.css", "src/polyfills.ts"]
}
```

### Module Side Effects

```ts
export default defineConfig({
  treeshake: {
    moduleSideEffects: (id) => {
      // Preserve side effects for polyfills
      return id.includes('polyfill')
    },
  },
})
```

## Common Patterns

### Production Build

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  format: ['esm', 'cjs'],
  treeshake: true,
  minify: true,
})
```

### Development Build

```ts
export default defineConfig((options) => ({
  entry: ['src/index.ts'],
  treeshake: !options.watch,  // Disable in dev
}))
```

### Library with Side Effects

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  treeshake: {
    moduleSideEffects: (id) => {
      return (
        id.includes('.css') ||
        id.includes('polyfill') ||
        id.includes('side-effect')
      )
    },
  },
})
```

### Utilities Library

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  format: ['esm'],
  treeshake: true,
  dts: true,
})
```

Users can import only what they need:
```ts
import { onlyWhatINeed } from 'my-utils'
```

## Benefits

### Smaller Bundles

- Only includes imported code
- Removes unused functions, classes, variables
- Reduces download size

### Better Performance

- Less code to parse
- Faster execution
- Improved loading times

### Cleaner Output

- No dead code in production
- Easier to debug
- Better maintainability

## When to Disable

### Debugging

During development to see all code:

```ts
export default defineConfig((options) => ({
  treeshake: !options.watch,
}))
```

### Side Effect Code

Code with global side effects:

```ts
// This has side effects
window.myGlobal = {}

export function setup() {
  // ...
}
```

Disable tree shaking or mark side effects:

```json
{
  "sideEffects": true
}
```

### Testing

Include all code for coverage:

```ts
export default defineConfig({
  treeshake: false,
})
```

## Tips

1. **Leave enabled** for production builds
2. **Mark side effects** in package.json
3. **Use with minification** for best results
4. **Test tree shaking** - verify unused code is removed
5. **Disable for debugging** if needed
6. **Pure functions** are easier to tree shake

## Troubleshooting

### Code Still Included

- Check for side effects
- Verify imports are ES modules
- Ensure code is actually unused
- Check `sideEffects` in package.json

### Missing Code at Runtime

- Code has side effects but marked as none
- Set `sideEffects: true` or list specific files

### Unexpected Behavior

- Module has side effects not declared
- Try disabling tree shaking to isolate issue

## Examples

### Pure Utility Functions

```ts
// utils.ts - perfect for tree shaking
export function add(a, b) {
  return a + b
}

export function multiply(a, b) {
  return a * b
}

// Only 'add' imported = only 'add' bundled
import { add } from './utils'
```

### With Side Effects

```ts
// polyfill.ts - has side effects
if (!Array.prototype.at) {
  Array.prototype.at = function(index) {
    // polyfill implementation
  }
}

export {} // Need to export something
```

```json
{
  "sideEffects": ["src/polyfill.ts"]
}
```

## Related Options

- [Minification](option-minification.md) - Code compression
- [Target](option-target.md) - Syntax transformations
- [Dependencies](option-dependencies.md) - External packages
- [Output Format](option-output-format.md) - Module formats


================================================
FILE: .agents/skills/tsdown/references/option-unbundle.md
================================================
# Unbundle Mode

Preserve source directory structure in output.

## Overview

Unbundle mode (also called "bundleless" or "transpile-only") outputs files that mirror your source structure, rather than bundling everything into single files. Each source file is compiled individually with a one-to-one mapping.

## Basic Usage

### CLI

```bash
tsdown --unbundle
```

### Config File

```ts
export default defineConfig({
  entry: ['src/**/*.ts', '!**/*.test.ts'],
  unbundle: true,
})
```

## How It Works

### Source Structure

```
src/
├── index.ts
├── utils/
│   ├── helper.ts
│   └── format.ts
└── components/
    └── button.ts
```

### With Unbundle

**Config:**
```ts
export default defineConfig({
  entry: ['src/index.ts'],
  unbundle: true,
})
```

**Output:**
```
dist/
├── index.mjs
├── utils/
│   ├── helper.mjs
│   └── format.mjs
└── components/
    └── button.mjs
```

All imported files are output individually, preserving structure.

### Without Unbundle (Default)

**Output:**
```
dist/
└── index.mjs  (all code bundled together)
```

## When to Use

### Use Unbundle When:

✅ Building monorepo packages with shared utilities
✅ Users need to import individual modules
✅ Want clear source-to-output mapping
✅ Library with many independent utilities
✅ Debugging requires tracing specific files
✅ Incremental builds for faster development

### Use Standard Bundling When:

❌ Single entry point application
❌ Want to optimize bundle size
❌ Need aggressive tree shaking
❌ Creating IIFE/UMD bundles
❌ Deploying to browsers directly

## Common Patterns

### Utility Library

```ts
export default defineConfig({
  entry: ['src/**/*.ts', '!**/*.test.ts'],
  format: ['esm', 'cjs'],
  unbundle: true,
  dts: true,
})
```

**Benefits:**
- Users import only what they need
- Tree shaking still works at user's build
- Clear module boundaries

**Usage:**
```ts
// Users can import specific utilities
import { helper } from 'my-lib/utils/helper'
import { Button } from 'my-lib/components/button'
```

### Monorepo Shared Package

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  format: ['esm'],
  unbundle: true,
  outDir: 'dist',
})
```

### TypeScript Compilation Only

```ts
export default defineConfig({
  entry: ['src/**/*.ts'],
  format: ['esm'],
  unbundle: true,
  minify: false,
  treeshake: false,
  dts: true,
})
```

Pure TypeScript to JavaScript transformation.

### Development Mode

```ts
export default defineConfig((options) => ({
  entry: ['src/**/*.ts'],
  unbundle: options.watch,  // Unbundle in dev only
  minify: !options.watch,
}))
```

Fast rebuilds during development, optimized for production.

## With Entry Patterns

### Include/Exclude

```ts
export default defineConfig({
  entry: [
    'src/**/*.ts',
    '!**/*.test.ts',
    '!**/*.spec.ts',
    '!**/fixtures/**',
  ],
  unbundle: true,
})
```

### Multiple Entry Points

```ts
export default defineConfig({
  entry: {
    index: 'src/index.ts',
    cli: 'src/cli.ts',
  },
  unbundle: true,
})
```

Both entry files and all imports preserved.

## Output Control

### Custom Extension

```ts
export default defineConfig({
  entry: ['src/**/*.ts'],
  unbundle: true,
  outExtensions: () => ({ js: '.js' }),
})
```

### Preserve Directory

```ts
export default defineConfig({
  entry: ['src/**/*.ts'],
  unbundle: true,
  outDir: 'lib',
})
```

**Output:**
```
lib/
├── index.js
├── utils/
│   └── helper.js
└── components/
    └── button.js
```

## Package.json Setup

```json
{
  "name": "my-library",
  "type": "module",
  "main": "./dist/index.js",
  "types": "./dist/index.d.ts",
  "exports": {
    ".": "./dist/index.js",
    "./utils/*": "./dist/utils/*.js",
    "./components/*": "./dist/components/*.js"
  },
  "files": ["dist"]
}
```

Or use `exports: true` to auto-generate.

## Comparison

| Feature | Bundled | Unbundled |
|---------|---------|-----------|
| Output files | Few | Many |
| File size | Smaller | Larger |
| Build speed | Slower | Faster |
| Tree shaking | Build time | User's build |
| Source mapping | Complex | Simple |
| Module imports | Entry only | Any module |
| Dev rebuilds | Slower | Faster |

## Performance

### Build Speed

Unbundle is typically faster:
- No bundling overhead
- Parallel file processing
- Incremental builds possible

### Bundle Size

Unbundle produces larger output:
- Each file has its own overhead
- No cross-module optimizations
- User's bundler handles final optimization

## Tips

1. **Use with glob patterns** for multiple files
2. **Enable in development** for faster rebuilds
3. **Let users bundle** for production optimization
4. **Preserve structure** for utilities/components
5. **Combine with DTS** for type definitions
6. **Use with monorepos** for shared code

## Troubleshooting

### Too Many Files

- Adjust entry patterns
- Exclude unnecessary files
- Use specific entry points

### Missing Files

- Check entry patterns
- Verify files are imported
- Look for excluded patterns

### Import Paths Wrong

- Check relative paths
- Verify output structure
- Update package.json exports

## CLI Examples

```bash
# Enable unbundle
tsdown --unbundle

# With specific entry
tsdown src/**/*.ts --unbundle

# With other options
tsdown --unbundle --format esm --dts
```

## Related Options

- [Entry](option-entry.md) - Entry patterns
- [Output Directory](option-output-directory.md) - Output location
- [Output Format](option-output-format.md) - Module formats
- [DTS](option-dts.md) - Type declarations


================================================
FILE: .agents/skills/tsdown/references/option-watch-mode.md
================================================
# Watch Mode

Automatically rebuild when files change.

## Overview

Watch mode monitors your source files and rebuilds automatically on changes, streamlining the development workflow.

## Basic Usage

### CLI

```bash
# Watch all project files
tsdown --watch

# Or use short flag
tsdown -w

# Watch specific directory
tsdown --watch ./src

# Watch specific file
tsdown --watch ./src/index.ts
```

### Config File

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  watch: true,
})
```

## Watch Options

### Ignore Paths

Ignore specific paths in watch mode:

```bash
tsdown --watch --ignore-watch test --ignore-watch '**/*.test.ts'
```

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  watch: {
    exclude: ['test/**', '**/*.test.ts'],
  },
})
```

### On Success Command

Run command after successful build:

```bash
tsdown --watch --on-success "echo Build complete!"
tsdown --watch --on-success "node dist/index.mjs"
```

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  watch: true,
  onSuccess: 'node dist/index.mjs',
})
```

## Watch Behavior

### Default Watch Targets

By default, tsdown watches:
- All entry files
- All imported files
- Config file (triggers restart)

### File Change Handling

- **Source files** - Incremental rebuild
- **Config file** - Full restart with cache clear
- **Dependencies** - Rebuild if imported

### Keyboard Shortcuts

During watch mode:
- `r` - Manual rebuild
- `q` - Quit watch mode

## Common Patterns

### Development Mode

```ts
export default defineConfig((options) => ({
  entry: ['src/index.ts'],
  format: ['esm'],
  watch: options.watch,
  sourcemap: options.watch,
  minify: !options.watch,
}))
```

### With Post-Build Script

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  watch: true,
  onSuccess: 'npm run test',
})
```

### Multiple Entry Points

```ts
export default defineConfig({
  entry: {
    main: 'src/index.ts',
    cli: 'src/cli.ts',
  },
  watch: true,
  clean: false,  // Don't clean on each rebuild
})
```

### Test Runner Integration

```bash
# Watch and run tests on change
tsdown --watch --on-success "vitest run"

# Watch and start dev server
tsdown --watch --on-success "node dist/server.mjs"
```

### Monorepo Package

```ts
export default defineConfig({
  workspace: 'packages/*',
  entry: ['src/index.ts'],
  watch: true,
  watch: {
    exclude: ['**/test/**', '**/*.spec.ts'],
  },
})
```

## Advanced Configuration

### Custom Watch Options

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  watch: {
    include: ['src/**'],
    exclude: ['**/*.test.ts', '**/fixtures/**'],
    skipWrite: false,
  },
})
```

### Conditional Watch

```ts
export default defineConfig((options) => {
  const isDev = options.watch

  return {
    entry: ['src/index.ts'],
    format: ['esm'],
    dts: !isDev,        // Skip DTS in watch mode
    sourcemap: isDev,
    clean: !isDev,
  }
})
```

## CLI Examples

```bash
# Basic watch
tsdown -w

# Watch with source maps
tsdown -w --sourcemap

# Watch without cleaning
tsdown -w --no-clean

# Watch and run on success
tsdown -w --on-success "npm test"

# Watch specific format
tsdown -w --format esm

# Watch with minification
tsdown -w --minify

# Watch and ignore test files
tsdown -w --ignore-watch '**/*.test.ts'
```

## Tips

1. **Use watch mode** for active development
2. **Skip DTS generation** in watch for faster rebuilds
3. **Disable clean** to avoid unnecessary file operations
4. **Use onSuccess** for post-build tasks
5. **Ignore test files** to avoid unnecessary rebuilds
6. **Use keyboard shortcuts** for manual control

## Troubleshooting

### Watch Not Detecting Changes

- Check file is in entry or imported chain
- Verify path is not in `exclude` patterns
- Ensure file system supports watching

### Too Many Rebuilds

Add ignore patterns:

```ts
export default defineConfig({
  watch: {
    exclude: [
      '**/node_modules/**',
      '**/.git/**',
      '**/dist/**',
      '**/*.test.ts',
    ],
  },
})
```

### Slow Rebuilds

- Skip DTS in watch mode: `dts: !options.watch`
- Disable minification: `minify: false`
- Use smaller entry set during development

### Config Changes Not Applied

Config file changes trigger full restart automatically.

### Why Not Stub Mode?

tsdown does not support stub mode. Watch mode is the recommended alternative for rapid development, providing instant rebuilds without the drawbacks of stub mode.

## Related Options

- [On Success](reference-cli.md#on-success-command) - Post-build commands
- [Sourcemap](option-sourcemap.md) - Debug information
- [Clean](option-cleaning.md) - Output directory cleaning


================================================
FILE: .agents/skills/tsdown/references/recipe-react.md
================================================
# React Support

Build React component libraries with tsdown.

## Overview

tsdown provides first-class support for React libraries. Rolldown natively supports JSX/TSX, so no additional plugins are required for basic React components.

## Quick Start

### Use Starter Template

```bash
# Basic React library
npx create-tsdown@latest -t react

# With React Compiler
npx create-tsdown@latest -t react-compiler
```

## Basic Configuration

### Minimal Setup

```ts
// tsdown.config.ts
export default defineConfig({
  entry: ['./src/index.ts'],
  format: ['esm', 'cjs'],
  platform: 'neutral',
  external: ['react', 'react-dom'],
  dts: true,
})
```

### Component Example

```tsx
// src/MyButton.tsx
import React from 'react'

interface MyButtonProps {
  type?: 'primary' | 'secondary'
  onClick?: () => void
}

export const MyButton: React.FC<MyButtonProps> = ({ type = 'primary', onClick }) => {
  return (
    <button className={`btn btn-${type}`} onClick={onClick}>
      Click me
    </button>
  )
}
```

```ts
// src/index.ts
export { MyButton } from './MyButton'
```

## JSX Transform

### Automatic (Default)

Modern JSX transform (React 17+):

```ts
export default defineConfig({
  entry: ['src/index.tsx'],
  // Automatic JSX is default
})
```

**Characteristics:**
- No `import React` needed
- Smaller bundle size
- React 17+ required

### Classic

Legacy JSX transform:

```ts
export default defineConfig({
  entry: ['src/index.tsx'],
  inputOptions: {
    transform: {
      jsx: 'react',  // Classic transform
    },
  },
})
```

**Characteristics:**
- Requires `import React from 'react'`
- Compatible with older React versions

## React Compiler

React Compiler automatically optimizes React code at build time.

### Install Dependencies

```bash
pnpm add -D @rollup/plugin-babel babel-plugin-react-compiler
```

### Configure

```ts
import pluginBabel from '@rollup/plugin-babel'

export default defineConfig({
  entry: ['src/index.tsx'],
  format: ['esm', 'cjs'],
  external: ['react', 'react-dom'],
  plugins: [
    pluginBabel({
      babelHelpers: 'bundled',
      parserOpts: {
        sourceType: 'module',
        plugins: ['jsx', 'typescript'],
      },
      plugins: ['babel-plugin-react-compiler'],
      extensions: ['.js', '.jsx', '.ts', '.tsx'],
    }),
  ],
  dts: true,
})
```

## Common Patterns

### Component Library

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  format: ['esm', 'cjs'],
  platform: 'neutral',
  external: [
    'react',
    'react-dom',
    /^react\//,  // react/jsx-runtime, etc.
  ],
  dts: true,
  clean: true,
})
```

### Multiple Components

```ts
export default defineConfig({
  entry: {
    index: 'src/index.ts',
    Button: 'src/Button.tsx',
    Input: 'src/Input.tsx',
    Modal: 'src/Modal.tsx',
  },
  format: ['esm', 'cjs'],
  external: ['react', 'react-dom'],
  dts: true,
})
```

### Hooks Library

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  format: ['esm', 'cjs'],
  platform: 'neutral',
  external: ['react'],  // Only React needed
  dts: true,
  treeshake: true,
})
```

### Monorepo React Packages

```ts
export default defineConfig({
  workspace: 'packages/*',
  entry: ['src/index.ts'],
  format: ['esm', 'cjs'],
  external: [
    'react',
    'react-dom',
    /^@mycompany\//,  // Other workspace packages
  ],
  dts: true,
})
```

## TypeScript Configuration

### Recommended tsconfig.json

```json
{
  "compilerOptions": {
    "target": "ES2020",
    "module": "ESNext",
    "lib": ["ES2020", "DOM", "DOM.Iterable"],
    "jsx": "react-jsx",  // or "react" for classic
    "moduleResolution": "bundler",
    "allowImportingTsExtensions": true,
    "strict": true,
    "isolatedDeclarations": true,  // Fast DTS generation
    "skipLibCheck": true
  },
  "include": ["src"]
}
```

## Package.json Configuration

```json
{
  "name": "my-react-library",
  "version": "1.0.0",
  "type": "module",
  "main": "./dist/index.cjs",
  "module": "./dist/index.mjs",
  "types": "./dist/index.d.ts",
  "exports": {
    ".": {
      "types": "./dist/index.d.ts",
      "import": "./dist/index.mjs",
      "require": "./dist/index.cjs"
    }
  },
  "files": ["dist"],
  "peerDependencies": {
    "react": "^18.0.0",
    "react-dom": "^18.0.0"
  },
  "devDependencies": {
    "@types/react": "^18.0.0",
    "@types/react-dom": "^18.0.0",
    "react": "^18.0.0",
    "react-dom": "^18.0.0",
    "tsdown": "^0.9.0",
    "typescript": "^5.0.0"
  }
}
```

## Advanced Patterns

### With Fast Refresh (Development)

```ts
import react from '@vitejs/plugin-react'

export default defineConfig((options) => ({
  entry: ['src/index.ts'],
  format: ['esm'],
  external: ['react', 'react-dom'],
  plugins: options.watch
    ? [
        // @ts-expect-error Vite plugin
        react({ fastRefresh: true }),
      ]
    : [],
}))
```

## Tips

1. **Always externalize React** - Don't bundle React/ReactDOM
2. **Use automatic JSX** - Smaller bundles with React 17+
3. **Enable DTS generation** - TypeScript support essential
4. **Use platform: 'neutral'** - For maximum compatibility
5. **Add peer dependencies** - Let users provide React
6. **Enable tree shaking** - Reduce bundle size
7. **Use React Compiler** - Better runtime performance

## Troubleshooting

### React Hook Errors

Ensure React is externalized:

```ts
external: ['react', 'react-dom', /^react\//]
```

### Type Errors with JSX

Check `tsconfig.json`:

```json
{
  "compilerOptions": {
    "jsx": "react-jsx"  // or "react"
  }
}
```

### Duplicate React

Add to external patterns:

```ts
external: [
  'react',
  'react-dom',
  'react/jsx-runtime',
  'react/jsx-dev-runtime',
]
```

## Related

- [Plugins](advanced-plugins.md) - Extend functionality
- [Dependencies](option-dependencies.md) - External packages
- [DTS](option-dts.md) - Type declarations
- [Vue Recipe](recipe-vue.md) - Vue component libraries


================================================
FILE: .agents/skills/tsdown/references/recipe-vue.md
================================================
# Vue Support

Build Vue component libraries with tsdown.

## Overview

tsdown provides first-class support for Vue libraries through integration with `unplugin-vue` and `rolldown-plugin-dts` for type generation.

## Quick Start

### Use Starter Template

```bash
npx create-tsdown@latest -t vue
```

## Basic Configuration

### Install Dependencies

```bash
pnpm add -D unplugin-vue vue-tsc
```

### Minimal Setup

```ts
// tsdown.config.ts
import { defineConfig } from 'tsdown'
import Vue from 'unplugin-vue/rolldown'

export default defineConfig({
  entry: ['./src/index.ts'],
  format: ['esm', 'cjs'],
  platform: 'neutral',
  external: ['vue'],
  plugins: [
    Vue({ isProduction: true }),
  ],
  dts: {
    vue: true,  // Enable Vue type generation
  },
})
```

## How It Works

### unplugin-vue

Compiles `.vue` single-file components:
- Transforms template to render functions
- Handles scoped styles
- Processes script setup

### vue-tsc

Generates TypeScript declarations:
- Type-checks Vue components
- Creates `.d.ts` files
- Preserves component props types
- Exports component types

## Component Example

### Single File Component

```vue
<!-- src/Button.vue -->
<script setup lang="ts">
interface Props {
  type?: 'primary' | 'secondary'
  disabled?: boolean
}

defineProps<Props>()
defineEmits<{
  click: []
}>()
</script>

<template>
  <button
    :class="['btn', `btn-${type}`]"
    :disabled="disabled"
    @click="$emit('click')"
  >
    <slot />
  </button>
</template>

<style scoped>
.btn {
  padding: 8px 16px;
  border-radius: 4px;
}

.btn-primary {
  background: blue;
  color: white;
}
</style>
```

### Export Components

```ts
// src/index.ts
export { default as Button } from './Button.vue'
export { default as Input } from './Input.vue'
export { default as Modal } from './Modal.vue'

// Re-export types
export type { ButtonProps } from './Button.vue'
```

## Common Patterns

### Component Library

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  format: ['esm', 'cjs'],
  platform: 'neutral',
  external: ['vue'],
  plugins: [
    Vue({
      isProduction: true,
      style: {
        trim: true,
      },
    }),
  ],
  dts: {
    vue: true,
  },
  clean: true,
})
```

### Multiple Components

```ts
export default defineConfig({
  entry: {
    index: 'src/index.ts',
    Button: 'src/Button.vue',
    Input: 'src/Input.vue',
    Modal: 'src/Modal.vue',
  },
  format: ['esm', 'cjs'],
  external: ['vue'],
  plugins: [Vue({ isProduction: true })],
  dts: { vue: true },
})
```

### With Composition Utilities

```ts
// src/composables/useCounter.ts
import { ref } from 'vue'

export function useCounter(initial = 0) {
  const count = ref(initial)
  const increment = () => count.value++
  const decrement = () => count.value--
  return { count, increment, decrement }
}
```

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  format: ['esm', 'cjs'],
  external: ['vue'],
  plugins: [Vue({ isProduction: true })],
  dts: { vue: true },
})
```

### TypeScript Configuration

```json
// tsconfig.json
{
  "compilerOptions": {
    "target": "ES2020",
    "module": "ESNext",
    "lib": ["ES2020", "DOM", "DOM.Iterable"],
    "jsx": "preserve",
    "moduleResolution": "bundler",
    "allowImportingTsExtensions": true,
    "strict": true,
    "isolatedDeclarations": true,
    "skipLibCheck": true
  },
  "include": ["src"],
  "exclude": ["node_modules", "dist"]
}
```

### Package.json Configuration

```json
{
  "name": "my-vue-library",
  "version": "1.0.0",
  "type": "module",
  "main": "./dist/index.cjs",
  "module": "./dist/index.mjs",
  "types": "./dist/index.d.ts",
  "exports": {
    ".": {
      "types": "./dist/index.d.ts",
      "import": "./dist/index.mjs",
      "require": "./dist/index.cjs"
    },
  },
  "files": ["dist"],
  "peerDependencies": {
    "vue": "^3.0.0"
  },
  "devDependencies": {
    "tsdown": "^0.9.0",
    "typescript": "^5.0.0",
    "unplugin-vue": "^5.0.0",
    "vue": "^3.4.0",
    "vue-tsc": "^2.0.0"
  }
}
```

## Advanced Patterns

### With Vite Plugins

Some Vite Vue plugins may work:

```ts
import Vue from 'unplugin-vue/rolldown'
import Components from 'unplugin-vue-components/rolldown'

export default defineConfig({
  entry: ['src/index.ts'],
  external: ['vue'],
  plugins: [
    Vue({ isProduction: true }),
    Components({
      dts: 'src/components.d.ts',
    }),
  ],
  dts: { vue: true },
})
```

### JSX Support

```ts
export default defineConfig({
  entry: ['src/index.ts'],
  format: ['esm', 'cjs'],
  external: ['vue'],
  plugins: [
    Vue({
      isProduction: true,
      script: {
        propsDestructure: true,
      },
    }),
  ],
  inputOptions: {
    transform: {
      jsx: 'automatic',
      jsxImportSource: 'vue',
    },
  },
  dts: { vue: true },
})
```

### Monorepo Vue Packages

```ts
export default defineConfig({
  workspace: 'packages/*',
  entry: ['src/index.ts'],
  format: ['esm', 'cjs'],
  external: ['vue', /^@mycompany\//],
  plugins: [Vue({ isProduction: true })],
  dts: { vue: true },
})
```

## Plugin Options

### unplugin-vue Options

```ts
Vue({
  isProduction: true,
  script: {
    defineModel: true,
    propsDestructure: true,
  },
  style: {
    trim: true,
  },
  template: {
    compilerOptions: {
      isCustomElement: (tag) => tag.startsWith('custom-'),
    },
  },
})
```

## Tips

1. **Always externalize Vue** - Don't bundle Vue itself
2. **Enable vue: true in dts** - For proper type generation
3. **Use platform: 'neutral'** - Maximum compatibility
4. **Install vue-tsc** - Required for type generation
5. **Set isProduction: true** - Optimize for production
6. **Add peer dependency** - Vue as peer dependency

## Troubleshooting

### Type Generation Fails

Ensure vue-tsc is installed:
```bash
pnpm add -D vue-tsc
```

Enable in config:
```ts
dts: { vue: true }
```

### Component Types Missing

Check TypeScript config:
```json
{
  "compilerOptions": {
    "jsx": "preserve",
    "moduleResolution": "bundler"
  }
}
```

### Vue Not Externalized

Add to external:
```ts
external: ['vue']
```

### SFC Compilation Errors

Check unplugin-vue version:
```bash
pnpm add -D unplugin-vue@latest
```

## Related

- [Plugins](advanced-plugins.md) - Plugin system
- [Dependencies](option-dependencies.md) - External packages
- [DTS](option-dts.md) - Type declarations
- [React Recipe](recipe-react.md) - React component libraries


================================================
FILE: .agents/skills/tsdown/references/recipe-wasm.md
================================================
# WASM Support

Bundle WebAssembly modules in your TypeScript/JavaScript project.

## Overview

tsdown supports WASM through [`rolldown-plugin-wasm`](https://github.com/sxzz/rolldown-plugin-wasm), enabling direct `.wasm` imports with synchronous and asynchronous instantiation.

## Setup

### Install

```bash
pnpm add -D rolldown-plugin-wasm
```

### Configure

```ts
import { wasm } from 'rolldown-plugin-wasm'
import { defineConfig } from 'tsdown'

export default defineConfig({
  entry: ['./src/index.ts'],
  plugins: [wasm()],
})
```

### TypeScript Support

Add type declarations to `tsconfig.json`:

```jsonc
{
  "compilerOptions": {
    "types": ["rolldown-plugin-wasm/types"]
  }
}
```

## Importing WASM Modules

### Direct Import

```ts
import { add } from './add.wasm'
add(1, 2)
```

### Async Init

Use `?init` query for async initialization:

```ts
import init from './add.wasm?init'
const instance = await init(imports) // imports optional
instance.exports.add(1, 2)
```

### Sync Init

Use `?init&sync` query for synchronous initialization:

```ts
import initSync from './add.wasm?init&sync'
const instance = initSync(imports) // imports optional
instance.exports.add(1, 2)
```

## wasm-bindgen Support

### Target `bundler` (Recommended)

```ts
import { add } from 'some-pkg'
add(1, 2)
```

### Target `web` (Node.js)

```ts
import { readFile } from 'node:fs/promises'
import init, { add } from 'some-pkg'
import wasmUrl from 'some-pkg/add_bg.wasm?url'

await init({
  module_or_path: readFile(new URL(wasmUrl, import.meta.url)),
})
add(1, 2)
```

### Target `web` (Browser)

```ts
import init, { add } from 'some-pkg/add.js'
import wasmUrl from 'some-pkg/add_bg.wasm?url'

await init({ module_or_path: wasmUrl })
add(1, 2)
```

`nodejs` and `no-modules` wasm-bindgen targets are not supported.

## Plugin Options

```ts
wasm({
  maxFileSize: 14 * 1024, // Max size for inline (default: 14KB)
  fileName: '[hash][extname]', // Output file name pattern
  publicPath: '',         // Prefix for non-inlined file paths
  targetEnv: 'auto',      // 'auto' | 'auto-inline' | 'browser' | 'node'
})
```

| Option | Default | Description |
|--------|---------|-------------|
| `maxFileSize` | `14 * 1024` | Max file size for inlining. Set to `0` to always copy. |
| `fileName` | `'[hash][extname]'` | Pattern for emitted WASM files |
| `publicPath` | — | Prefix for non-inlined WASM file paths |
| `targetEnv` | `'auto'` | `'auto'` detects at runtime; `'browser'` omits Node builtins; `'node'` omits fetch |

## Related Options

- [Plugins](advanced-plugins.md) - Plugin system overview
- [Platform](option-platform.md) - Target platform configuration


================================================
FILE: .agents/skills/tsdown/references/reference-cli.md
================================================
# CLI Reference

Complete reference for tsdown command-line interface.

## Overview

All CLI flags can also be set in the config file. CLI flags override config file options.

## Flag Patterns

CLI flag mapping rules:
- `--foo` sets `foo: true`
- `--no-foo` sets `foo: false`
- `--foo.bar` sets `foo: { bar: true }`
- `--format esm --format cjs` sets `format: ['esm', 'cjs']`

CLI flags support both camelCase and kebab-case. For example, `--outDir` and `--out-dir` are equivalent.

## Basic Commands

### Build

```bash
# Build with default config
tsdown

# Build specific files
tsdown src/index.ts src/cli.ts

# Build with watch mode
tsdown --watch
```

## Configuration

### `--config, -c <filename>`

Specify custom config file:

```bash
tsdown --config build.config.ts
tsdown -c custom-config.js
```

### `--no-config`

Disable config file loading:

```bash
tsdown --no-config src/index.ts
```

### `--config-loader <loader>`

Choose config loader (`auto`, `native`, `unrun`):

```bash
tsdown --config-loader unrun
```

### `--tsconfig <file>`

Specify TypeScript config file:

```bash
tsdown --tsconfig tsconfig.build.json
```

## Entry Points

### `[...files]`

Specify entry files as arguments:

```bash
tsdown src/index.ts src/utils.ts
```

## Output Options

### `--format <format>`

Output format (`esm`, `cjs`, `iife`, `umd`):

```bash
tsdown --format esm
tsdown --format esm --format cjs
```

### `--out-dir, -d <dir>`

Output directory:

```bash
tsdown --out-dir lib
tsdown -d dist
```

### `--dts`

Generate TypeScript declarations:

```bash
tsdown --dts
```

### `--clean`

Clean output directory before build:

```bash
tsdown --clean
```

## Build Options

### `--target <target>`

JavaScript target version:

```bash
tsdown --target es2020
tsdown --target node18
tsdown --target chrome100
tsdown --no-target  # Disable transformations
```

### `--platform <platform>`

Target platform (`node`, `browser`, `neutral`):

```bash
tsdown --platform node
tsdown --platform browser
```

### `--minify`

Enable minification:

```bash
tsdown --minify
tsdown --no-minify
```

### `--sourcemap`

Generate source maps:

```bash
tsdown --sourcemap
tsdown --sourcemap inline
```

### `--treeshake`

Enable/disable tree shaking:

```bash
tsdown --treeshake
tsdown --no-treeshake
```

## Dependencies

### `--external <module>`

Mark module as external (not bundled):

```bash
tsdown --external react --external react-dom
```

### `--shims`

Add ESM/CJS compatibility shims:

```bash
tsdown --shims
```

## Development

### `--watch, -w [path]`

Enable watch mode:

```bash
tsdown --watch
tsdown -w
tsdown --watch src  # Watch specific directory
```

### `--ignore-watch <path>`

Ignore paths in watch mode:

```bash
tsdown --watch --ignore-watch test
```

### `--on-success <command>`

Run command after successful build:

```bash
tsdown --watch --on-success "echo Build complete!"
```

## Environment Variables

### `--env.* <value>`

Set compile-time environment variables:

```bash
tsdown --env.NODE_ENV=production --env.API_URL=https://api.example.com
```

Access as `import.meta.env.*` or `process.env.*`.

### `--env-file <file>`

Load environment variables from file:

```bash
tsdown --env-file .env.production
```

### `--env-prefix <prefix>`

Filter environment variables by prefix (default: `TSDOWN_`):

```bash
tsdown --env-file .env --env-prefix APP_ --env-prefix TSDOWN_
```

## Assets

### `--copy <dir>`

Copy directory to output:

```bash
tsdown --copy public
tsdown --copy assets --copy static
```

## Package Management

### `--exports`

Auto-generate package.json exports field:

```bash
tsdown --exports
```

### `--publint`

Enable package validation:

```bash
tsdown --publint
```

### `--attw`

Enable "Are the types wrong" validation:

```bash
tsdown --attw
```

### `--unused`

Check for unused dependencies:

```bash
tsdown --unused
```

## Logging

### `--log-level <level>`

Set logging verbosity (`silent`, `error`, `warn`, `info`):

```bash
tsdown --log-level error
tsdown --log-level warn
```

### `--report` / `--no-report`

Enable/disable build report:

```bash
tsdown --no-report  # Disable size report
tsdown --report     # Enable (default)
```

### `--debug [feat]`

Show debug logs:

```bash
tsdown --debug
tsdown --debug rolldown  # Debug specific feature
```

## Integration

### `--from-vite [vitest]`

Extend Vite or Vitest config:

```bash
tsdown --from-vite         # Use vite.config.*
tsdown --from-vite vitest  # Use vitest.config.*
```

## Common Usage Patterns

### Basic Build

```bash
tsdown
```

### Library (ESM + CJS + Types)

```bash
tsdown --format esm --format cjs --dts --clean
```

### Production Build

```bash
tsdown --minify --clean --no-report
```

### Development (Watch)

```bash
tsdown --watch --sourcemap
```

### Browser Bundle (IIFE)

```bash
tsdown --format iife --platform browser --minify
```

### Node.js CLI Tool

```bash
tsdown --format esm --platform node --shims
```

### Monorepo Package

```bash
tsdown --clean --dts --exports --publint
```

### With Environment Variables

```bash
tsdown --env-file .env.production --env.BUILD_TIME=$(date +%s)
```

### Copy Assets

```bash
tsdown --copy public --copy assets --clean
```

## Tips

1. **Use config file** for complex setups
2. **CLI flags override** config file options
3. **Chain multiple formats** for multi-target builds
4. **Use --clean** to avoid stale files
5. **Enable --dts** for TypeScript libraries
6. **Use --watch** during development
7. **Add --on-success** for post-build tasks
8. **Use --exports** to auto-generate package.json fields

## Related Documentation

- [Config File](option-config-file.md) - Configuration file options
- [Entry](option-entry.md) - Entry point configuration
- [Output Format](option-output-format.md) - Format options
- [Watch Mode](option-watch-mode.md) - Watch mode details


================================================
FILE: .agents/skills/vercel-composition-patterns/AGENTS.md
================================================
# React Composition Patterns

**Version 1.0.0**  
Engineering  
January 2026

> **Note:**  
> This document is mainly for agents and LLMs to follow when maintaining,  
> generating, or refactoring React codebases using composition. Humans  
> may also find it useful, but guidance here is optimized for automation  
> and consistency by AI-assisted workflows.

---

## Abstract

Composition patterns for building flexible, maintainable React components. Avoid boolean prop proliferation by using compound components, lifting state, and composing internals. These patterns make codebases easier for both humans and AI agents to work with as they scale.

---

## Table of Contents

1. [Component Architecture](#1-component-architecture) — **HIGH**
   - 1.1 [Avoid Boolean Prop Proliferation](#11-avoid-boolean-prop-proliferation)
   - 1.2 [Use Compound Components](#12-use-compound-components)
2. [State Management](#2-state-management) — **MEDIUM**
   - 2.1 [Decouple State Management from UI](#21-decouple-state-management-from-ui)
   - 2.2 [Define Generic Context Interfaces for Dependency Injection](#22-define-generic-context-interfaces-for-dependency-injection)
   - 2.3 [Lift State into Provider Components](#23-lift-state-into-provider-components)
3. [Implementation Patterns](#3-implementation-patterns) — **MEDIUM**
   - 3.1 [Create Explicit Component Variants](#31-create-explicit-component-variants)
   - 3.2 [Prefer Composing Children Over Render Props](#32-prefer-composing-children-over-render-props)
4. [React 19 APIs](#4-react-19-apis) — **MEDIUM**
   - 4.1 [React 19 API Changes](#41-react-19-api-changes)

---

## 1. Component Architecture

**Impact: HIGH**

Fundamental patterns for structuring components to avoid prop
proliferation and enable flexible composition.

### 1.1 Avoid Boolean Prop Proliferation

**Impact: CRITICAL (prevents unmaintainable component variants)**

Don't add boolean props like `isThread`, `isEditing`, `isDMThread` to customize

component behavior. Each boolean doubles possible states and creates

unmaintainable conditional logic. Use composition instead.

**Incorrect: boolean props create exponential complexity**

```tsx
function Composer({
  onSubmit,
  isThread,
  channelId,
  isDMThread,
  dmId,
  isEditing,
  isForwarding,
}: Props) {
  return (
    <form>
      <Header />
      <Input />
      {isDMThread ? (
        <AlsoSendToDMField id={dmId} />
      ) : isThread ? (
        <AlsoSendToChannelField id={channelId} />
      ) : null}
      {isEditing ? (
        <EditActions />
      ) : isForwarding ? (
        <ForwardActions />
 
Download .txt
gitextract_430igyon/

├── .agents/
│   └── skills/
│       ├── dinero-best-practices/
│       │   ├── SKILL.md
│       │   └── rules/
│       │       ├── arithmetic-allocate-not-divide.md
│       │       ├── arithmetic-immutability.md
│       │       ├── arithmetic-percentages.md
│       │       ├── arithmetic-scaled-amounts.md
│       │       ├── creation-from-floats.md
│       │       ├── creation-minor-units.md
│       │       ├── creation-zero-exponent.md
│       │       ├── imports-bigint-currencies.md
│       │       ├── imports-tree-shaking.md
│       │       ├── precision-bigint.md
│       │       ├── precision-crypto.md
│       │       └── precision-trim-scale.md
│       ├── dinero-currency-patterns/
│       │   ├── SKILL.md
│       │   └── rules/
│       │       ├── convert-reusable.md
│       │       ├── convert-scaled-rates.md
│       │       ├── payment-services.md
│       │       ├── storage-database.md
│       │       ├── storage-no-money-type.md
│       │       ├── types-as-const.md
│       │       ├── types-currency-mismatch.md
│       │       └── types-lookup-validation.md
│       ├── dinero-formatting/
│       │   ├── SKILL.md
│       │   └── rules/
│       │       ├── display-no-currency-symbols.md
│       │       ├── display-to-decimal.md
│       │       ├── locale-intl-formatter.md
│       │       ├── locale-multilingual.md
│       │       ├── nondecimal-to-units.md
│       │       ├── serialization-bigint-json.md
│       │       └── serialization-snapshot.md
│       ├── tsdown/
│       │   ├── SKILL.md
│       │   └── references/
│       │       ├── advanced-ci.md
│       │       ├── advanced-hooks.md
│       │       ├── advanced-plugins.md
│       │       ├── advanced-programmatic.md
│       │       ├── advanced-rolldown-options.md
│       │       ├── guide-getting-started.md
│       │       ├── guide-migrate-from-tsup.md
│       │       ├── option-cjs-default.md
│       │       ├── option-cleaning.md
│       │       ├── option-config-file.md
│       │       ├── option-css.md
│       │       ├── option-dependencies.md
│       │       ├── option-dts.md
│       │       ├── option-entry.md
│       │       ├── option-lint.md
│       │       ├── option-log-level.md
│       │       ├── option-minification.md
│       │       ├── option-output-directory.md
│       │       ├── option-output-format.md
│       │       ├── option-package-exports.md
│       │       ├── option-platform.md
│       │       ├── option-shims.md
│       │       ├── option-sourcemap.md
│       │       ├── option-target.md
│       │       ├── option-tree-shaking.md
│       │       ├── option-unbundle.md
│       │       ├── option-watch-mode.md
│       │       ├── recipe-react.md
│       │       ├── recipe-vue.md
│       │       ├── recipe-wasm.md
│       │       └── reference-cli.md
│       ├── vercel-composition-patterns/
│       │   ├── AGENTS.md
│       │   ├── README.md
│       │   ├── SKILL.md
│       │   └── rules/
│       │       ├── architecture-avoid-boolean-props.md
│       │       ├── architecture-compound-components.md
│       │       ├── patterns-children-over-render-props.md
│       │       ├── patterns-explicit-variants.md
│       │       ├── react19-no-forwardref.md
│       │       ├── state-context-interface.md
│       │       ├── state-decouple-implementation.md
│       │       └── state-lift-state.md
│       ├── vercel-react-best-practices/
│       │   ├── AGENTS.md
│       │   ├── README.md
│       │   ├── SKILL.md
│       │   └── rules/
│       │       ├── advanced-event-handler-refs.md
│       │       ├── advanced-init-once.md
│       │       ├── advanced-use-latest.md
│       │       ├── async-api-routes.md
│       │       ├── async-defer-await.md
│       │       ├── async-dependencies.md
│       │       ├── async-parallel.md
│       │       ├── async-suspense-boundaries.md
│       │       ├── bundle-barrel-imports.md
│       │       ├── bundle-conditional.md
│       │       ├── bundle-defer-third-party.md
│       │       ├── bundle-dynamic-imports.md
│       │       ├── bundle-preload.md
│       │       ├── client-event-listeners.md
│       │       ├── client-localstorage-schema.md
│       │       ├── client-passive-event-listeners.md
│       │       ├── client-swr-dedup.md
│       │       ├── js-batch-dom-css.md
│       │       ├── js-cache-function-results.md
│       │       ├── js-cache-property-access.md
│       │       ├── js-cache-storage.md
│       │       ├── js-combine-iterations.md
│       │       ├── js-early-exit.md
│       │       ├── js-hoist-regexp.md
│       │       ├── js-index-maps.md
│       │       ├── js-length-check-first.md
│       │       ├── js-min-max-loop.md
│       │       ├── js-set-map-lookups.md
│       │       ├── js-tosorted-immutable.md
│       │       ├── rendering-activity.md
│       │       ├── rendering-animate-svg-wrapper.md
│       │       ├── rendering-conditional-render.md
│       │       ├── rendering-content-visibility.md
│       │       ├── rendering-hoist-jsx.md
│       │       ├── rendering-hydration-no-flicker.md
│       │       ├── rendering-hydration-suppress-warning.md
│       │       ├── rendering-svg-precision.md
│       │       ├── rendering-usetransition-loading.md
│       │       ├── rerender-defer-reads.md
│       │       ├── rerender-dependencies.md
│       │       ├── rerender-derived-state-no-effect.md
│       │       ├── rerender-derived-state.md
│       │       ├── rerender-functional-setstate.md
│       │       ├── rerender-lazy-state-init.md
│       │       ├── rerender-memo-with-default-value.md
│       │       ├── rerender-memo.md
│       │       ├── rerender-move-effect-to-event.md
│       │       ├── rerender-simple-expression-in-memo.md
│       │       ├── rerender-transitions.md
│       │       ├── rerender-use-ref-transient-values.md
│       │       ├── server-after-nonblocking.md
│       │       ├── server-auth-actions.md
│       │       ├── server-cache-lru.md
│       │       ├── server-cache-react.md
│       │       ├── server-dedup-props.md
│       │       ├── server-parallel-fetching.md
│       │       └── server-serialization.md
│       └── web-design-guidelines/
│           └── SKILL.md
├── .browserslistrc
├── .claude/
│   ├── docs/
│   │   ├── architecture.md
│   │   ├── git-workflow.md
│   │   └── linear.md
│   └── skills/
│       └── commit/
│           └── SKILL.md
├── .editorconfig
├── .gitattributes
├── .github/
│   ├── CODEOWNERS
│   ├── ISSUE_TEMPLATE/
│   │   └── BUG.yml
│   ├── semantic.yml
│   └── workflows/
│       ├── ci.yml
│       └── release.yml
├── .gitignore
├── .husky/
│   └── pre-commit
├── .npmrc
├── .nvmrc
├── .oxlintrc.json
├── .prettierignore
├── .prettierrc
├── .size-limit.json
├── .vscode/
│   ├── launch.json
│   └── settings.json
├── CHANGELOG.md
├── CLAUDE.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── docs/
│   ├── .vitepress/
│   │   ├── config.ts
│   │   └── theme/
│   │       ├── HomeFeatures.vue
│   │       ├── HomeHero.vue
│   │       ├── NotFound.vue
│   │       ├── index.ts
│   │       └── style.css
│   ├── about.md
│   ├── agent-skills.md
│   ├── api/
│   │   ├── comparisons/
│   │   │   ├── compare.md
│   │   │   ├── equal.md
│   │   │   ├── greater-than-or-equal.md
│   │   │   ├── greater-than.md
│   │   │   ├── has-sub-units.md
│   │   │   ├── have-same-amount.md
│   │   │   ├── have-same-currency.md
│   │   │   ├── is-negative.md
│   │   │   ├── is-positive.md
│   │   │   ├── is-zero.md
│   │   │   ├── less-than-or-equal.md
│   │   │   ├── less-than.md
│   │   │   ├── maximum.md
│   │   │   └── minimum.md
│   │   ├── conversions/
│   │   │   ├── convert.md
│   │   │   ├── normalize-scale.md
│   │   │   ├── transform-scale.md
│   │   │   └── trim-scale.md
│   │   ├── currencies.md
│   │   ├── dinero.md
│   │   ├── formatting/
│   │   │   ├── to-decimal.md
│   │   │   ├── to-snapshot.md
│   │   │   └── to-units.md
│   │   ├── mutations/
│   │   │   ├── add.md
│   │   │   ├── allocate.md
│   │   │   ├── multiply.md
│   │   │   └── subtract.md
│   │   └── rounding/
│   │       ├── down.md
│   │       ├── half-away-from-zero.md
│   │       ├── half-down.md
│   │       ├── half-even.md
│   │       ├── half-odd.md
│   │       ├── half-towards-zero.md
│   │       ├── half-up.md
│   │       └── up.md
│   ├── build-examples.sh
│   ├── core-concepts/
│   │   ├── amount.md
│   │   ├── comparisons.md
│   │   ├── currency.md
│   │   ├── formatting.md
│   │   ├── mutations.md
│   │   └── scale.md
│   ├── demos.md
│   ├── faq/
│   │   ├── can-i-multiply-by-a-decimal.md
│   │   ├── how-to-look-up-a-currency-by-code.md
│   │   ├── why-cant-i-use-currencies-with-bigint.md
│   │   ├── why-functions-instead-of-methods.md
│   │   └── why-no-currency-formatting.md
│   ├── getting-started/
│   │   ├── compatibility.md
│   │   ├── optimizing-for-production.md
│   │   ├── quick-start.md
│   │   └── upgrade-guide.md
│   ├── guides/
│   │   ├── calculating-percentages.md
│   │   ├── creating-from-floats.md
│   │   ├── cryptocurrencies.md
│   │   ├── currency-type-safety.md
│   │   ├── formatting-in-a-multilingual-site.md
│   │   ├── formatting-non-decimal-currencies.md
│   │   ├── integrating-with-payment-services.md
│   │   ├── precision-and-large-numbers.md
│   │   ├── storing-in-a-database.md
│   │   └── transporting-and-restoring.md
│   ├── index.md
│   ├── package.json
│   └── vercel.json
├── examples/
│   ├── cart-react/
│   │   ├── .gitignore
│   │   ├── README.md
│   │   ├── index.html
│   │   ├── package.json
│   │   ├── postcss.config.js
│   │   ├── src/
│   │   │   ├── App.tsx
│   │   │   ├── components/
│   │   │   │   ├── cart-line.tsx
│   │   │   │   └── order-summary.tsx
│   │   │   ├── data/
│   │   │   │   ├── index.ts
│   │   │   │   ├── items.json
│   │   │   │   └── shipping.json
│   │   │   ├── index.css
│   │   │   ├── lib/
│   │   │   │   └── money.ts
│   │   │   ├── main.tsx
│   │   │   └── types/
│   │   │       └── index.ts
│   │   ├── tsconfig.json
│   │   └── vite.config.ts
│   ├── cart-vue/
│   │   ├── .gitignore
│   │   ├── README.md
│   │   ├── env.d.ts
│   │   ├── index.html
│   │   ├── package.json
│   │   ├── postcss.config.js
│   │   ├── src/
│   │   │   ├── App.vue
│   │   │   ├── components/
│   │   │   │   ├── CartLine.vue
│   │   │   │   └── OrderSummary.vue
│   │   │   ├── data/
│   │   │   │   ├── index.ts
│   │   │   │   ├── items.json
│   │   │   │   └── shipping.json
│   │   │   ├── index.css
│   │   │   ├── lib/
│   │   │   │   └── money.ts
│   │   │   ├── main.ts
│   │   │   └── types/
│   │   │       └── index.ts
│   │   ├── tsconfig.app.json
│   │   ├── tsconfig.json
│   │   └── vite.config.ts
│   ├── expense-splitter/
│   │   ├── .gitignore
│   │   ├── README.md
│   │   ├── index.html
│   │   ├── package.json
│   │   ├── postcss.config.js
│   │   ├── src/
│   │   │   ├── App.tsx
│   │   │   ├── components/
│   │   │   │   ├── add-expense.tsx
│   │   │   │   ├── add-person.tsx
│   │   │   │   ├── balances.tsx
│   │   │   │   ├── expense-list.tsx
│   │   │   │   ├── index.ts
│   │   │   │   ├── person-list.tsx
│   │   │   │   └── settlements.tsx
│   │   │   ├── index.css
│   │   │   ├── lib/
│   │   │   │   └── money.ts
│   │   │   ├── main.tsx
│   │   │   ├── types/
│   │   │   │   └── index.ts
│   │   │   └── vite-env.d.ts
│   │   ├── tsconfig.json
│   │   └── vite.config.ts
│   ├── invoice-builder/
│   │   ├── .gitignore
│   │   ├── README.md
│   │   ├── index.html
│   │   ├── package.json
│   │   ├── postcss.config.js
│   │   ├── src/
│   │   │   ├── App.tsx
│   │   │   ├── components/
│   │   │   │   ├── editor-panel.tsx
│   │   │   │   └── preview-panel.tsx
│   │   │   ├── hooks/
│   │   │   │   └── use-invoice.ts
│   │   │   ├── index.css
│   │   │   ├── lib/
│   │   │   │   ├── invoice-types.ts
│   │   │   │   └── money.ts
│   │   │   ├── main.tsx
│   │   │   └── vite-env.d.ts
│   │   ├── tsconfig.json
│   │   └── vite.config.ts
│   ├── portfolio-tracker/
│   │   ├── README.md
│   │   ├── index.html
│   │   ├── package.json
│   │   ├── postcss.config.js
│   │   ├── src/
│   │   │   ├── App.tsx
│   │   │   ├── components/
│   │   │   │   ├── breakdown-bar.tsx
│   │   │   │   ├── dashboard.tsx
│   │   │   │   ├── exchange-rates.tsx
│   │   │   │   ├── holding-card.tsx
│   │   │   │   ├── holdings-editor.tsx
│   │   │   │   ├── holdings-table.tsx
│   │   │   │   └── summary-cards.tsx
│   │   │   ├── hooks/
│   │   │   │   └── use-portfolio.ts
│   │   │   ├── index.css
│   │   │   ├── lib/
│   │   │   │   ├── money.ts
│   │   │   │   └── types.ts
│   │   │   └── main.tsx
│   │   ├── tsconfig.json
│   │   └── vite.config.ts
│   └── pricing-react/
│       ├── .gitignore
│       ├── README.md
│       ├── index.html
│       ├── package.json
│       ├── postcss.config.js
│       ├── src/
│       │   ├── App.tsx
│       │   ├── components/
│       │   │   ├── pricing-toggle.tsx
│       │   │   ├── seat-slider.tsx
│       │   │   └── tier-card.tsx
│       │   ├── data/
│       │   │   ├── index.ts
│       │   │   └── items.json
│       │   ├── index.css
│       │   ├── lib/
│       │   │   └── money.ts
│       │   ├── main.tsx
│       │   └── types/
│       │       └── index.ts
│       ├── tsconfig.json
│       └── vite.config.ts
├── global.d.ts
├── lint-staged.config.cjs
├── package.json
├── packages/
│   └── dinero.js/
│       ├── README.md
│       ├── package.json
│       ├── src/
│       │   ├── __tests__/
│       │   │   ├── currency-safety.typetest.ts
│       │   │   └── dinero.test.ts
│       │   ├── api/
│       │   │   ├── __tests__/
│       │   │   │   ├── add.test.ts
│       │   │   │   ├── allocate.test.ts
│       │   │   │   ├── compare.test.ts
│       │   │   │   ├── convert.test.ts
│       │   │   │   ├── equal.test.ts
│       │   │   │   ├── greaterThan.test.ts
│       │   │   │   ├── greaterThanOrEqual.test.ts
│       │   │   │   ├── hasSubUnits.test.ts
│       │   │   │   ├── haveSameAmount.test.ts
│       │   │   │   ├── haveSameCurrency.test.ts
│       │   │   │   ├── isNegative.test.ts
│       │   │   │   ├── isPositive.test.ts
│       │   │   │   ├── isZero.test.ts
│       │   │   │   ├── lessThan.test.ts
│       │   │   │   ├── lessThanOrEqual.test.ts
│       │   │   │   ├── maximum.test.ts
│       │   │   │   ├── minimum.test.ts
│       │   │   │   ├── multiply.test.ts
│       │   │   │   ├── normalizeScale.test.ts
│       │   │   │   ├── subtract.test.ts
│       │   │   │   ├── toDecimal.test.ts
│       │   │   │   ├── toSnapshot.test.ts
│       │   │   │   ├── toUnits.test.ts
│       │   │   │   ├── transformScale.test.ts
│       │   │   │   └── trimScale.test.ts
│       │   │   ├── add.ts
│       │   │   ├── allocate.ts
│       │   │   ├── compare.ts
│       │   │   ├── convert.ts
│       │   │   ├── equal.ts
│       │   │   ├── greaterThan.ts
│       │   │   ├── greaterThanOrEqual.ts
│       │   │   ├── hasSubUnits.ts
│       │   │   ├── haveSameAmount.ts
│       │   │   ├── haveSameCurrency.ts
│       │   │   ├── index.ts
│       │   │   ├── isNegative.ts
│       │   │   ├── isPositive.ts
│       │   │   ├── isZero.ts
│       │   │   ├── lessThan.ts
│       │   │   ├── lessThanOrEqual.ts
│       │   │   ├── maximum.ts
│       │   │   ├── minimum.ts
│       │   │   ├── multiply.ts
│       │   │   ├── normalizeScale.ts
│       │   │   ├── subtract.ts
│       │   │   ├── toDecimal.ts
│       │   │   ├── toSnapshot.ts
│       │   │   ├── toUnits.ts
│       │   │   ├── transformScale.ts
│       │   │   └── trimScale.ts
│       │   ├── bigint/
│       │   │   ├── currencies/
│       │   │   │   ├── index.ts
│       │   │   │   └── iso4217.ts
│       │   │   ├── dinero.ts
│       │   │   └── index.ts
│       │   ├── calculator/
│       │   │   ├── bigint/
│       │   │   │   ├── api/
│       │   │   │   │   ├── __tests__/
│       │   │   │   │   │   ├── add.test.ts
│       │   │   │   │   │   ├── compare.test.ts
│       │   │   │   │   │   ├── decrement.test.ts
│       │   │   │   │   │   ├── increment.test.ts
│       │   │   │   │   │   ├── integerDivide.test.ts
│       │   │   │   │   │   ├── modulo.test.ts
│       │   │   │   │   │   ├── multiply.test.ts
│       │   │   │   │   │   ├── power.test.ts
│       │   │   │   │   │   ├── subtract.test.ts
│       │   │   │   │   │   └── zero.test.ts
│       │   │   │   │   ├── add.ts
│       │   │   │   │   ├── compare.ts
│       │   │   │   │   ├── decrement.ts
│       │   │   │   │   ├── increment.ts
│       │   │   │   │   ├── index.ts
│       │   │   │   │   ├── integerDivide.ts
│       │   │   │   │   ├── modulo.ts
│       │   │   │   │   ├── multiply.ts
│       │   │   │   │   ├── power.ts
│       │   │   │   │   ├── subtract.ts
│       │   │   │   │   └── zero.ts
│       │   │   │   ├── calculator.ts
│       │   │   │   └── index.ts
│       │   │   └── number/
│       │   │       ├── api/
│       │   │       │   ├── __tests__/
│       │   │       │   │   ├── add.test.ts
│       │   │       │   │   ├── compare.test.ts
│       │   │       │   │   ├── decrement.test.ts
│       │   │       │   │   ├── increment.test.ts
│       │   │       │   │   ├── integerDivide.test.ts
│       │   │       │   │   ├── modulo.test.ts
│       │   │       │   │   ├── multiply.test.ts
│       │   │       │   │   ├── power.test.ts
│       │   │       │   │   ├── subtract.test.ts
│       │   │       │   │   └── zero.test.ts
│       │   │       │   ├── add.ts
│       │   │       │   ├── compare.ts
│       │   │       │   ├── decrement.ts
│       │   │       │   ├── increment.ts
│       │   │       │   ├── index.ts
│       │   │       │   ├── integerDivide.ts
│       │   │       │   ├── modulo.ts
│       │   │       │   ├── multiply.ts
│       │   │       │   ├── power.ts
│       │   │       │   ├── subtract.ts
│       │   │       │   └── zero.ts
│       │   │       ├── calculator.ts
│       │   │       └── index.ts
│       │   ├── core/
│       │   │   ├── api/
│       │   │   │   ├── add.ts
│       │   │   │   ├── allocate.ts
│       │   │   │   ├── compare.ts
│       │   │   │   ├── convert.ts
│       │   │   │   ├── equal.ts
│       │   │   │   ├── greaterThan.ts
│       │   │   │   ├── greaterThanOrEqual.ts
│       │   │   │   ├── hasSubUnits.ts
│       │   │   │   ├── haveSameAmount.ts
│       │   │   │   ├── haveSameCurrency.ts
│       │   │   │   ├── index.ts
│       │   │   │   ├── isNegative.ts
│       │   │   │   ├── isPositive.ts
│       │   │   │   ├── isZero.ts
│       │   │   │   ├── lessThan.ts
│       │   │   │   ├── lessThanOrEqual.ts
│       │   │   │   ├── maximum.ts
│       │   │   │   ├── minimum.ts
│       │   │   │   ├── multiply.ts
│       │   │   │   ├── normalizeScale.ts
│       │   │   │   ├── subtract.ts
│       │   │   │   ├── toDecimal.ts
│       │   │   │   ├── toSnapshot.ts
│       │   │   │   ├── toUnits.ts
│       │   │   │   ├── transformScale.ts
│       │   │   │   └── trimScale.ts
│       │   │   ├── checks/
│       │   │   │   ├── index.ts
│       │   │   │   └── messages.ts
│       │   │   ├── divide/
│       │   │   │   ├── __tests__/
│       │   │   │   │   ├── down.test.ts
│       │   │   │   │   ├── halfAwayFromZero.test.ts
│       │   │   │   │   ├── halfDown.test.ts
│       │   │   │   │   ├── halfEven.test.ts
│       │   │   │   │   ├── halfOdd.test.ts
│       │   │   │   │   ├── halfTowardsZero.test.ts
│       │   │   │   │   ├── halfUp.test.ts
│       │   │   │   │   └── up.test.ts
│       │   │   │   ├── down.ts
│       │   │   │   ├── halfAwayFromZero.ts
│       │   │   │   ├── halfDown.ts
│       │   │   │   ├── halfEven.ts
│       │   │   │   ├── halfOdd.ts
│       │   │   │   ├── halfTowardsZero.ts
│       │   │   │   ├── halfUp.ts
│       │   │   │   ├── index.ts
│       │   │   │   └── up.ts
│       │   │   ├── helpers/
│       │   │   │   ├── __tests__/
│       │   │   │   │   └── assert.test.ts
│       │   │   │   ├── assert.ts
│       │   │   │   ├── createDinero.ts
│       │   │   │   └── index.ts
│       │   │   ├── index.ts
│       │   │   ├── types/
│       │   │   │   ├── Dinero.ts
│       │   │   │   ├── DineroBinaryOperation.ts
│       │   │   │   ├── DineroCalculator.ts
│       │   │   │   ├── DineroDivideOperation.ts
│       │   │   │   ├── DineroFactory.ts
│       │   │   │   ├── DineroFormatter.ts
│       │   │   │   ├── DineroOptions.ts
│       │   │   │   ├── DineroRates.ts
│       │   │   │   ├── DineroScaledAmount.ts
│       │   │   │   ├── DineroSnapshot.ts
│       │   │   │   ├── DineroTransformer.ts
│       │   │   │   ├── DineroUnaryOperation.ts
│       │   │   │   └── index.ts
│       │   │   └── utils/
│       │   │       ├── __tests__/
│       │   │       │   ├── absolute.test.ts
│       │   │       │   ├── compare.test.ts
│       │   │       │   ├── computeBase.test.ts
│       │   │       │   ├── countTrailingZeros.test.ts
│       │   │       │   ├── distribute.test.ts
│       │   │       │   ├── equal.test.ts
│       │   │       │   ├── getAmountAndScale.test.ts
│       │   │       │   ├── getDivisors.test.ts
│       │   │       │   ├── greaterThan.test.ts
│       │   │       │   ├── greaterThanOrEqual.test.ts
│       │   │       │   ├── isArray.test.ts
│       │   │       │   ├── isEven.test.ts
│       │   │       │   ├── isHalf.test.ts
│       │   │       │   ├── isScaledAmount.test.ts
│       │   │       │   ├── lessThan.test.ts
│       │   │       │   ├── lessThanOrEqual.test.ts
│       │   │       │   ├── maximum.test.ts
│       │   │       │   ├── minimum.test.ts
│       │   │       │   └── sign.test.ts
│       │   │       ├── absolute.ts
│       │   │       ├── compare.ts
│       │   │       ├── computeBase.ts
│       │   │       ├── countTrailingZeros.ts
│       │   │       ├── distribute.ts
│       │   │       ├── equal.ts
│       │   │       ├── getAmountAndScale.ts
│       │   │       ├── getDivisors.ts
│       │   │       ├── greaterThan.ts
│       │   │       ├── greaterThanOrEqual.ts
│       │   │       ├── index.ts
│       │   │       ├── isArray.ts
│       │   │       ├── isEven.ts
│       │   │       ├── isHalf.ts
│       │   │       ├── isScaledAmount.ts
│       │   │       ├── lessThan.ts
│       │   │       ├── lessThanOrEqual.ts
│       │   │       ├── maximum.ts
│       │   │       ├── minimum.ts
│       │   │       └── sign.ts
│       │   ├── currencies/
│       │   │   ├── index.ts
│       │   │   ├── iso4217.ts
│       │   │   └── types/
│       │   │       ├── DineroCurrency.ts
│       │   │       └── index.ts
│       │   ├── dinero.ts
│       │   └── index.ts
│       ├── tsconfig.json
│       └── tsdown.config.ts
├── renovate.json
├── ship.config.cjs
├── skills-lock.json
├── test/
│   └── utils/
│       ├── castToBigintCurrency.ts
│       ├── castToBigjsCurrency.ts
│       ├── createBigintDinero.ts
│       ├── createBigjsDinero.ts
│       ├── createNumberDinero.ts
│       └── index.ts
├── tsconfig.json
├── turbo.json
└── vitest.config.ts
Download .txt
SYMBOL INDEX (653 symbols across 135 files)

FILE: examples/cart-react/src/App.tsx
  constant CURRENCY_OPTIONS (line 16) | const CURRENCY_OPTIONS: Array<{ code: CurrencyCode; symbol: string }> = [
  constant VAT_RATE (line 21) | const VAT_RATE = 20;
  constant LOGO (line 23) | const LOGO = (
  function App (line 63) | function App() {

FILE: examples/cart-react/src/components/cart-line.tsx
  type CartLineProps (line 7) | interface CartLineProps {
  function CartLine (line 19) | function CartLine({

FILE: examples/cart-react/src/components/order-summary.tsx
  type OrderSummaryProps (line 7) | interface OrderSummaryProps {
  function OrderSummary (line 21) | function OrderSummary({

FILE: examples/cart-react/src/lib/money.ts
  constant CURRENCIES_MAP (line 7) | const CURRENCIES_MAP = { USD, EUR } as const;
  constant CURRENCY_LOCALES (line 9) | const CURRENCY_LOCALES: Record<CurrencyCode, string> = {
  function currencyFor (line 14) | function currencyFor<TCode extends CurrencyCode>(
  function zero (line 20) | function zero(code: CurrencyCode): Dinero<number> {
  function fromMinorUnits (line 24) | function fromMinorUnits(
  function convertCurrency (line 31) | function convertCurrency(
  function formatMoney (line 44) | function formatMoney(

FILE: examples/cart-react/src/types/index.ts
  type CurrencyCode (line 1) | type CurrencyCode = 'USD' | 'EUR';
  type CartItem (line 3) | interface CartItem {
  type ShippingOption (line 11) | interface ShippingOption {

FILE: examples/cart-vue/src/lib/money.ts
  constant CURRENCIES_MAP (line 7) | const CURRENCIES_MAP = { USD, EUR } as const;
  constant CURRENCY_LOCALES (line 9) | const CURRENCY_LOCALES: Record<CurrencyCode, string> = {
  function currencyFor (line 14) | function currencyFor<TCode extends CurrencyCode>(
  function zero (line 20) | function zero(code: CurrencyCode): Dinero<number> {
  function fromMinorUnits (line 24) | function fromMinorUnits(
  function convertCurrency (line 31) | function convertCurrency(
  function formatMoney (line 44) | function formatMoney(

FILE: examples/cart-vue/src/types/index.ts
  type CurrencyCode (line 1) | type CurrencyCode = 'USD' | 'EUR';
  type CartItem (line 3) | interface CartItem {
  type ShippingOption (line 11) | interface ShippingOption {

FILE: examples/expense-splitter/src/App.tsx
  type StoredExpense (line 15) | interface StoredExpense {
  constant LOGO (line 25) | const LOGO = (
  constant DEFAULT_PEOPLE (line 65) | const DEFAULT_PEOPLE: Person[] = [
  constant DEFAULT_EXPENSES (line 72) | const DEFAULT_EXPENSES: StoredExpense[] = [
  function App (line 115) | function App() {
  function serializeExpenses (line 293) | function serializeExpenses(expenses: Expense[]): StoredExpense[] {
  function deserializeExpenses (line 305) | function deserializeExpenses(stored: StoredExpense[]): Expense[] {

FILE: examples/expense-splitter/src/components/add-expense.tsx
  type AddExpenseProps (line 7) | interface AddExpenseProps {
  function AddExpense (line 12) | function AddExpense({ people, onAdd }: AddExpenseProps) {

FILE: examples/expense-splitter/src/components/add-person.tsx
  type AddPersonProps (line 6) | interface AddPersonProps {
  function AddPerson (line 10) | function AddPerson({ onAdd }: AddPersonProps) {

FILE: examples/expense-splitter/src/components/balances.tsx
  type BalancesProps (line 13) | interface BalancesProps {
  function Balances (line 18) | function Balances({ expenses, people }: BalancesProps) {

FILE: examples/expense-splitter/src/components/expense-list.tsx
  type ExpenseListProps (line 6) | interface ExpenseListProps {
  function ExpenseList (line 12) | function ExpenseList({ expenses, people, onRemove }: ExpenseListProps) {

FILE: examples/expense-splitter/src/components/person-list.tsx
  type PersonListProps (line 5) | interface PersonListProps {
  function PersonList (line 10) | function PersonList({ people, onRemove }: PersonListProps) {

FILE: examples/expense-splitter/src/components/settlements.tsx
  type SettlementsProps (line 6) | interface SettlementsProps {
  function Settlements (line 11) | function Settlements({ expenses, people }: SettlementsProps) {

FILE: examples/expense-splitter/src/lib/money.ts
  function zero (line 27) | function zero(): Dinero<number> {
  function fromAmount (line 31) | function fromAmount(amount: number): Dinero<number> {
  function toMinorUnits (line 38) | function toMinorUnits(value: string): number {
  function snapshot (line 42) | function snapshot(amount: Dinero<number>): number {
  function formatMoney (line 46) | function formatMoney(amount: Dinero<number>): string {
  function negate (line 54) | function negate(amount: Dinero<number>): Dinero<number> {
  function calculateShares (line 61) | function calculateShares(
  function calculateNetBalances (line 108) | function calculateNetBalances(
  function calculateSettlements (line 138) | function calculateSettlements(

FILE: examples/expense-splitter/src/types/index.ts
  type SplitType (line 3) | type SplitType = 'equal' | 'percentage';
  type Person (line 5) | interface Person {
  type ExpenseShare (line 10) | interface ExpenseShare {
  type Expense (line 15) | interface Expense {
  type Settlement (line 25) | interface Settlement {

FILE: examples/invoice-builder/src/App.tsx
  constant LOGO (line 5) | const LOGO = (
  function App (line 45) | function App() {

FILE: examples/invoice-builder/src/components/editor-panel.tsx
  type EditorPanelProps (line 22) | type EditorPanelProps = {
  constant CURRENCIES (line 39) | const CURRENCIES: { value: CurrencyCode; label: string }[] = [
  function EditorPanel (line 46) | function EditorPanel({
  type FieldLabelProps (line 291) | type FieldLabelProps = {
  function FieldLabel (line 295) | function FieldLabel({ htmlFor, children }: FieldLabelProps) {
  type TextInputProps (line 306) | type TextInputProps = {
  function TextInput (line 317) | function TextInput({
  type LineItemRowProps (line 342) | type LineItemRowProps = {
  function LineItemRow (line 351) | function LineItemRow({
  type CollapsibleSectionProps (line 438) | type CollapsibleSectionProps = {
  function CollapsibleSection (line 447) | function CollapsibleSection({

FILE: examples/invoice-builder/src/components/preview-panel.tsx
  type PreviewPanelProps (line 12) | interface PreviewPanelProps {
  function PreviewPanel (line 16) | function PreviewPanel({ invoice }: PreviewPanelProps) {
  function formatDate (line 305) | function formatDate(value: string): string {

FILE: examples/invoice-builder/src/hooks/use-invoice.ts
  function useInvoice (line 9) | function useInvoice() {
  function generateInvoiceNumber (line 72) | function generateInvoiceNumber(): string {
  function todayISO (line 81) | function todayISO(): string {
  function dueDateISO (line 85) | function dueDateISO(): string {
  function createEmptyLineItem (line 92) | function createEmptyLineItem(): LineItem {
  function createInitialInvoice (line 101) | function createInitialInvoice(): InvoiceData {

FILE: examples/invoice-builder/src/lib/invoice-types.ts
  type CurrencyCode (line 1) | type CurrencyCode = 'USD' | 'EUR' | 'GBP' | 'JPY';
  type LineItem (line 3) | interface LineItem {
  type DiscountType (line 10) | type DiscountType = 'percentage' | 'fixed';
  type InvoiceData (line 12) | interface InvoiceData {

FILE: examples/invoice-builder/src/lib/money.ts
  constant CURRENCIES (line 14) | const CURRENCIES = {
  constant CURRENCY_LOCALES (line 21) | const CURRENCY_LOCALES: Record<CurrencyCode, string> = {
  constant NON_NUMERIC (line 28) | const NON_NUMERIC = /[^0-9.-]/g;
  function toMinorUnits (line 34) | function toMinorUnits<TCurrency extends CurrencyCode>(
  function minorUnitsToInputString (line 54) | function minorUnitsToInputString<TCurrency extends CurrencyCode>(
  function lineTotal (line 74) | function lineTotal<TCurrency extends CurrencyCode>(
  function invoiceSubtotal (line 89) | function invoiceSubtotal<TCurrency extends CurrencyCode>(
  function percentageRatios (line 103) | function percentageRatios(percentage: number): [number, number] {
  function discountAmount (line 112) | function discountAmount<TCurrency extends CurrencyCode>(
  function taxAmount (line 134) | function taxAmount<TCurrency extends CurrencyCode>(
  function grandTotal (line 153) | function grandTotal<TCurrency extends CurrencyCode>(
  function formatMoney (line 164) | function formatMoney<TCurrency extends CurrencyCode>(
  function formatCents (line 181) | function formatCents<TCurrency extends CurrencyCode>(
  function zero (line 190) | function zero<TCurrency extends CurrencyCode>(
  function currencyFor (line 196) | function currencyFor<TCurrency extends CurrencyCode>(

FILE: examples/portfolio-tracker/src/App.tsx
  constant LOGO (line 5) | const LOGO = (
  function App (line 45) | function App() {

FILE: examples/portfolio-tracker/src/components/breakdown-bar.tsx
  type BreakdownItem (line 3) | interface BreakdownItem {
  type BreakdownBarProps (line 10) | interface BreakdownBarProps {
  function formatValue (line 16) | function formatValue(amount: number, currency: CurrencyCode): string {
  function BreakdownBar (line 26) | function BreakdownBar({

FILE: examples/portfolio-tracker/src/components/dashboard.tsx
  type DashboardProps (line 9) | interface DashboardProps {
  function Dashboard (line 29) | function Dashboard({

FILE: examples/portfolio-tracker/src/components/exchange-rates.tsx
  type ExchangeRatesCardProps (line 7) | interface ExchangeRatesCardProps {
  function ExchangeRatesCard (line 11) | function ExchangeRatesCard({ baseCurrency }: ExchangeRatesCardProps) {

FILE: examples/portfolio-tracker/src/components/holding-card.tsx
  type HoldingCardProps (line 7) | interface HoldingCardProps {
  function HoldingCard (line 13) | function HoldingCard({ holding, onUpdate, onRemove }: HoldingCardProps) {

FILE: examples/portfolio-tracker/src/components/holdings-editor.tsx
  type HoldingsEditorProps (line 8) | interface HoldingsEditorProps {
  function HoldingsEditor (line 17) | function HoldingsEditor({

FILE: examples/portfolio-tracker/src/components/holdings-table.tsx
  type HoldingRow (line 5) | interface HoldingRow {
  type HoldingsTableProps (line 17) | interface HoldingsTableProps {
  function HoldingsTable (line 23) | function HoldingsTable({
  function formatQuantity (line 156) | function formatQuantity(num: number): string {

FILE: examples/portfolio-tracker/src/components/summary-cards.tsx
  type SummaryCardsProps (line 5) | interface SummaryCardsProps {
  function SummaryCards (line 14) | function SummaryCards({
  function formatChangeAmount (line 140) | function formatChangeAmount(amount: number, currency: CurrencyCode): str...

FILE: examples/portfolio-tracker/src/hooks/use-portfolio.ts
  constant DEFAULT_HOLDINGS (line 13) | const DEFAULT_HOLDINGS: Holding[] = [
  constant MOCK_CHANGES (line 48) | const MOCK_CHANGES: Record<string, number> = {
  type HoldingWithValue (line 57) | interface HoldingWithValue extends Holding {
  function usePortfolio (line 65) | function usePortfolio() {

FILE: examples/portfolio-tracker/src/lib/money.ts
  constant CURRENCIES_MAP (line 7) | const CURRENCIES_MAP = { USD, EUR, GBP, JPY } as const;
  constant CURRENCY_LOCALES (line 9) | const CURRENCY_LOCALES: Record<CurrencyCode, string> = {
  constant NON_NUMERIC (line 16) | const NON_NUMERIC = /[^0-9.-]/g;
  constant BASE_RATES_FROM_USD (line 22) | const BASE_RATES_FROM_USD: Record<CurrencyCode, number> = {
  function currencyFor (line 29) | function currencyFor<TCode extends CurrencyCode>(
  function scaleFor (line 35) | function scaleFor(code: CurrencyCode): number {
  function toMinorUnits (line 44) | function toMinorUnits(value: string, code: CurrencyCode): number {
  function minorUnitsToInputString (line 57) | function minorUnitsToInputString(
  function zero (line 74) | function zero<TCode extends CurrencyCode>(
  function fromMinorUnits (line 80) | function fromMinorUnits<TCode extends CurrencyCode>(
  function countDecimals (line 90) | function countDecimals(n: number): number {
  function holdingValue (line 102) | function holdingValue<TCode extends CurrencyCode>(
  function buildRates (line 116) | function buildRates<TFrom extends CurrencyCode, TTo extends CurrencyCode>(
  function convertToBase (line 139) | function convertToBase<
  function sumDineros (line 153) | function sumDineros<TCode extends CurrencyCode>(
  function getRate (line 163) | function getRate(from: CurrencyCode, to: CurrencyCode): number {
  function getRateDisplay (line 176) | function getRateDisplay(from: CurrencyCode, to: CurrencyCode): string {
  function formatMoney (line 186) | function formatMoney<TCode extends CurrencyCode>(
  function formatCents (line 203) | function formatCents<TCode extends CurrencyCode>(

FILE: examples/portfolio-tracker/src/lib/types.ts
  type CurrencyCode (line 1) | type CurrencyCode = 'USD' | 'EUR' | 'GBP' | 'JPY';
  type Category (line 3) | type Category =
  type Holding (line 11) | interface Holding {
  constant CURRENCIES (line 20) | const CURRENCIES: CurrencyCode[] = ['USD', 'EUR', 'GBP', 'JPY'];
  constant CATEGORIES (line 22) | const CATEGORIES: Category[] = [
  constant CATEGORY_COLORS (line 31) | const CATEGORY_COLORS: Record<Category, string> = {
  constant CURRENCY_COLORS (line 40) | const CURRENCY_COLORS: Record<CurrencyCode, string> = {

FILE: examples/pricing-react/src/App.tsx
  constant LOGO (line 9) | const LOGO = (
  function App (line 49) | function App() {

FILE: examples/pricing-react/src/components/pricing-toggle.tsx
  constant DISCOUNT_RATE (line 1) | const DISCOUNT_RATE = 10;
  type PricingToggleProps (line 3) | interface PricingToggleProps {
  function PricingToggle (line 8) | function PricingToggle({

FILE: examples/pricing-react/src/components/seat-slider.tsx
  type SeatSliderProps (line 1) | interface SeatSliderProps {
  function SeatSlider (line 6) | function SeatSlider({ seats, onChange }: SeatSliderProps) {

FILE: examples/pricing-react/src/components/tier-card.tsx
  constant DISCOUNT_RATE (line 6) | const DISCOUNT_RATE = 10;
  type TierCardProps (line 8) | interface TierCardProps {
  function TierCard (line 18) | function TierCard({
  function MonthlyPrice (line 70) | function MonthlyPrice({ price }: { price: Dinero<number> }) {
  function YearlyPrice (line 83) | function YearlyPrice({ price }: { price: Dinero<number> }) {

FILE: examples/pricing-react/src/lib/money.ts
  function fromMinorUnits (line 12) | function fromMinorUnits(amount: number): Dinero<number> {
  function formatMoney (line 16) | function formatMoney(amount: Dinero<number>): string {

FILE: examples/pricing-react/src/types/index.ts
  type PricingTier (line 1) | interface PricingTier {

FILE: packages/dinero.js/src/api/__tests__/transformScale.test.ts
  constant ABC (line 23) | const ABC = { code: 'ABC', base: 6, exponent: 1 };
  type DineroDivideOperation (line 25) | type DineroDivideOperation = Parameters<typeof transformScale>[2];

FILE: packages/dinero.js/src/api/add.ts
  function add (line 14) | function add<TAmount, TCurrency extends string>(

FILE: packages/dinero.js/src/api/allocate.ts
  function allocate (line 14) | function allocate<TAmount, TCurrency extends string>(

FILE: packages/dinero.js/src/api/compare.ts
  function compare (line 14) | function compare<TAmount, TCurrency extends string>(

FILE: packages/dinero.js/src/api/convert.ts
  function convert (line 15) | function convert<

FILE: packages/dinero.js/src/api/equal.ts
  function equal (line 14) | function equal<TAmount, TCurrency extends string>(

FILE: packages/dinero.js/src/api/greaterThan.ts
  function greaterThan (line 14) | function greaterThan<TAmount, TCurrency extends string>(

FILE: packages/dinero.js/src/api/greaterThanOrEqual.ts
  function greaterThanOrEqual (line 14) | function greaterThanOrEqual<TAmount, TCurrency extends string>(

FILE: packages/dinero.js/src/api/hasSubUnits.ts
  function hasSubUnits (line 13) | function hasSubUnits<TAmount>(

FILE: packages/dinero.js/src/api/haveSameAmount.ts
  function haveSameAmount (line 13) | function haveSameAmount<TAmount, TCurrency extends string>(

FILE: packages/dinero.js/src/api/isNegative.ts
  function isNegative (line 13) | function isNegative<TAmount>(

FILE: packages/dinero.js/src/api/isPositive.ts
  function isPositive (line 13) | function isPositive<TAmount>(

FILE: packages/dinero.js/src/api/isZero.ts
  function isZero (line 13) | function isZero<TAmount>(...[dineroObject]: IsZeroParams<TAmount>) {

FILE: packages/dinero.js/src/api/lessThan.ts
  function lessThan (line 14) | function lessThan<TAmount, TCurrency extends string>(

FILE: packages/dinero.js/src/api/lessThanOrEqual.ts
  function lessThanOrEqual (line 14) | function lessThanOrEqual<TAmount, TCurrency extends string>(

FILE: packages/dinero.js/src/api/maximum.ts
  function maximum (line 13) | function maximum<TAmount, TCurrency extends string>(

FILE: packages/dinero.js/src/api/minimum.ts
  function minimum (line 13) | function minimum<TAmount, TCurrency extends string>(

FILE: packages/dinero.js/src/api/multiply.ts
  function multiply (line 14) | function multiply<TAmount, TCurrency extends string>(

FILE: packages/dinero.js/src/api/normalizeScale.ts
  function normalizeScale (line 13) | function normalizeScale<TAmount, TCurrency extends string>(

FILE: packages/dinero.js/src/api/subtract.ts
  function subtract (line 14) | function subtract<TAmount, TCurrency extends string>(

FILE: packages/dinero.js/src/api/toDecimal.ts
  function toDecimal (line 23) | function toDecimal<TAmount, TOutput, TCurrency extends string>(

FILE: packages/dinero.js/src/api/toUnits.ts
  function toUnits (line 28) | function toUnits<TAmount, TOutput, TCurrency extends string>(

FILE: packages/dinero.js/src/api/transformScale.ts
  function transformScale (line 15) | function transformScale<TAmount, TCurrency extends string>(

FILE: packages/dinero.js/src/api/trimScale.ts
  function trimScale (line 13) | function trimScale<TAmount, TCurrency extends string>(

FILE: packages/dinero.js/src/bigint/currencies/iso4217.ts
  constant AED (line 15) | const AED: DineroCurrency<bigint> = {
  constant AFN (line 24) | const AFN: DineroCurrency<bigint> = {
  constant ALL (line 33) | const ALL: DineroCurrency<bigint> = {
  constant AMD (line 42) | const AMD: DineroCurrency<bigint> = {
  constant AOA (line 51) | const AOA: DineroCurrency<bigint> = {
  constant ARS (line 60) | const ARS: DineroCurrency<bigint> = {
  constant AUD (line 69) | const AUD: DineroCurrency<bigint> = {
  constant AWG (line 78) | const AWG: DineroCurrency<bigint> = {
  constant AZN (line 87) | const AZN: DineroCurrency<bigint> = {
  constant BAM (line 96) | const BAM: DineroCurrency<bigint> = {
  constant BBD (line 105) | const BBD: DineroCurrency<bigint> = {
  constant BDT (line 114) | const BDT: DineroCurrency<bigint> = {
  constant BGN (line 123) | const BGN: DineroCurrency<bigint> = {
  constant BHD (line 132) | const BHD: DineroCurrency<bigint> = {
  constant BIF (line 141) | const BIF: DineroCurrency<bigint> = {
  constant BMD (line 150) | const BMD: DineroCurrency<bigint> = {
  constant BND (line 159) | const BND: DineroCurrency<bigint> = {
  constant BOB (line 168) | const BOB: DineroCurrency<bigint> = {
  constant BOV (line 177) | const BOV: DineroCurrency<bigint> = {
  constant BRL (line 186) | const BRL: DineroCurrency<bigint> = {
  constant BSD (line 195) | const BSD: DineroCurrency<bigint> = {
  constant BTN (line 204) | const BTN: DineroCurrency<bigint> = {
  constant BWP (line 213) | const BWP: DineroCurrency<bigint> = {
  constant BYN (line 222) | const BYN: DineroCurrency<bigint> = {
  constant BZD (line 231) | const BZD: DineroCurrency<bigint> = {
  constant CAD (line 240) | const CAD: DineroCurrency<bigint> = {
  constant CDF (line 249) | const CDF: DineroCurrency<bigint> = {
  constant CHE (line 258) | const CHE: DineroCurrency<bigint> = {
  constant CHF (line 267) | const CHF: DineroCurrency<bigint> = {
  constant CHW (line 276) | const CHW: DineroCurrency<bigint> = {
  constant CLF (line 285) | const CLF: DineroCurrency<bigint> = {
  constant CLP (line 294) | const CLP: DineroCurrency<bigint> = {
  constant CNY (line 303) | const CNY: DineroCurrency<bigint> = {
  constant COP (line 312) | const COP: DineroCurrency<bigint> = {
  constant COU (line 321) | const COU: DineroCurrency<bigint> = {
  constant CRC (line 330) | const CRC: DineroCurrency<bigint> = {
  constant CUP (line 339) | const CUP: DineroCurrency<bigint> = {
  constant CVE (line 348) | const CVE: DineroCurrency<bigint> = {
  constant CZK (line 357) | const CZK: DineroCurrency<bigint> = {
  constant DJF (line 366) | const DJF: DineroCurrency<bigint> = {
  constant DKK (line 375) | const DKK: DineroCurrency<bigint> = {
  constant DOP (line 384) | const DOP: DineroCurrency<bigint> = {
  constant DZD (line 393) | const DZD: DineroCurrency<bigint> = {
  constant EGP (line 402) | const EGP: DineroCurrency<bigint> = {
  constant ERN (line 411) | const ERN: DineroCurrency<bigint> = {
  constant ETB (line 420) | const ETB: DineroCurrency<bigint> = {
  constant EUR (line 429) | const EUR: DineroCurrency<bigint> = {
  constant FJD (line 438) | const FJD: DineroCurrency<bigint> = {
  constant FKP (line 447) | const FKP: DineroCurrency<bigint> = {
  constant GBP (line 456) | const GBP: DineroCurrency<bigint> = {
  constant GEL (line 465) | const GEL: DineroCurrency<bigint> = {
  constant GHS (line 474) | const GHS: DineroCurrency<bigint> = {
  constant GIP (line 483) | const GIP: DineroCurrency<bigint> = {
  constant GMD (line 492) | const GMD: DineroCurrency<bigint> = {
  constant GNF (line 501) | const GNF: DineroCurrency<bigint> = {
  constant GTQ (line 510) | const GTQ: DineroCurrency<bigint> = {
  constant GYD (line 519) | const GYD: DineroCurrency<bigint> = {
  constant HKD (line 528) | const HKD: DineroCurrency<bigint> = {
  constant HNL (line 537) | const HNL: DineroCurrency<bigint> = {
  constant HTG (line 546) | const HTG: DineroCurrency<bigint> = {
  constant HUF (line 555) | const HUF: DineroCurrency<bigint> = {
  constant IDR (line 564) | const IDR: DineroCurrency<bigint> = {
  constant ILS (line 573) | const ILS: DineroCurrency<bigint> = {
  constant INR (line 582) | const INR: DineroCurrency<bigint> = {
  constant IQD (line 591) | const IQD: DineroCurrency<bigint> = {
  constant IRR (line 600) | const IRR: DineroCurrency<bigint> = {
  constant ISK (line 609) | const ISK: DineroCurrency<bigint> = {
  constant JMD (line 618) | const JMD: DineroCurrency<bigint> = {
  constant JOD (line 627) | const JOD: DineroCurrency<bigint> = {
  constant JPY (line 636) | const JPY: DineroCurrency<bigint> = {
  constant KES (line 645) | const KES: DineroCurrency<bigint> = {
  constant KGS (line 654) | const KGS: DineroCurrency<bigint> = {
  constant KHR (line 663) | const KHR: DineroCurrency<bigint> = {
  constant KMF (line 672) | const KMF: DineroCurrency<bigint> = {
  constant KPW (line 681) | const KPW: DineroCurrency<bigint> = {
  constant KRW (line 690) | const KRW: DineroCurrency<bigint> = {
  constant KWD (line 699) | const KWD: DineroCurrency<bigint> = {
  constant KYD (line 708) | const KYD: DineroCurrency<bigint> = {
  constant KZT (line 717) | const KZT: DineroCurrency<bigint> = {
  constant LAK (line 726) | const LAK: DineroCurrency<bigint> = {
  constant LBP (line 735) | const LBP: DineroCurrency<bigint> = {
  constant LKR (line 744) | const LKR: DineroCurrency<bigint> = {
  constant LRD (line 753) | const LRD: DineroCurrency<bigint> = {
  constant LSL (line 762) | const LSL: DineroCurrency<bigint> = {
  constant LYD (line 771) | const LYD: DineroCurrency<bigint> = {
  constant MAD (line 780) | const MAD: DineroCurrency<bigint> = {
  constant MDL (line 789) | const MDL: DineroCurrency<bigint> = {
  constant MGA (line 798) | const MGA: DineroCurrency<bigint> = {
  constant MKD (line 807) | const MKD: DineroCurrency<bigint> = {
  constant MMK (line 816) | const MMK: DineroCurrency<bigint> = {
  constant MNT (line 825) | const MNT: DineroCurrency<bigint> = {
  constant MOP (line 834) | const MOP: DineroCurrency<bigint> = {
  constant MRU (line 843) | const MRU: DineroCurrency<bigint> = {
  constant MUR (line 852) | const MUR: DineroCurrency<bigint> = {
  constant MVR (line 861) | const MVR: DineroCurrency<bigint> = {
  constant MWK (line 870) | const MWK: DineroCurrency<bigint> = {
  constant MXN (line 879) | const MXN: DineroCurrency<bigint> = {
  constant MXV (line 888) | const MXV: DineroCurrency<bigint> = {
  constant MYR (line 897) | const MYR: DineroCurrency<bigint> = {
  constant MZN (line 906) | const MZN: DineroCurrency<bigint> = {
  constant NAD (line 915) | const NAD: DineroCurrency<bigint> = {
  constant NGN (line 924) | const NGN: DineroCurrency<bigint> = {
  constant NIO (line 933) | const NIO: DineroCurrency<bigint> = {
  constant NOK (line 942) | const NOK: DineroCurrency<bigint> = {
  constant NPR (line 951) | const NPR: DineroCurrency<bigint> = {
  constant NZD (line 960) | const NZD: DineroCurrency<bigint> = {
  constant OMR (line 969) | const OMR: DineroCurrency<bigint> = {
  constant PAB (line 978) | const PAB: DineroCurrency<bigint> = {
  constant PEN (line 987) | const PEN: DineroCurrency<bigint> = {
  constant PGK (line 996) | const PGK: DineroCurrency<bigint> = {
  constant PHP (line 1005) | const PHP: DineroCurrency<bigint> = {
  constant PKR (line 1014) | const PKR: DineroCurrency<bigint> = {
  constant PLN (line 1023) | const PLN: DineroCurrency<bigint> = {
  constant PYG (line 1032) | const PYG: DineroCurrency<bigint> = {
  constant QAR (line 1041) | const QAR: DineroCurrency<bigint> = {
  constant RON (line 1050) | const RON: DineroCurrency<bigint> = {
  constant RSD (line 1059) | const RSD: DineroCurrency<bigint> = {
  constant RUB (line 1068) | const RUB: DineroCurrency<bigint> = {
  constant RWF (line 1077) | const RWF: DineroCurrency<bigint> = {
  constant SAR (line 1086) | const SAR: DineroCurrency<bigint> = {
  constant SBD (line 1095) | const SBD: DineroCurrency<bigint> = {
  constant SCR (line 1104) | const SCR: DineroCurrency<bigint> = {
  constant SDG (line 1113) | const SDG: DineroCurrency<bigint> = {
  constant SEK (line 1122) | const SEK: DineroCurrency<bigint> = {
  constant SGD (line 1131) | const SGD: DineroCurrency<bigint> = {
  constant SHP (line 1140) | const SHP: DineroCurrency<bigint> = {
  constant SLE (line 1149) | const SLE: DineroCurrency<bigint> = {
  constant SOS (line 1158) | const SOS: DineroCurrency<bigint> = {
  constant SRD (line 1167) | const SRD: DineroCurrency<bigint> = {
  constant SSP (line 1176) | const SSP: DineroCurrency<bigint> = {
  constant STN (line 1185) | const STN: DineroCurrency<bigint> = {
  constant SVC (line 1194) | const SVC: DineroCurrency<bigint> = {
  constant SYP (line 1203) | const SYP: DineroCurrency<bigint> = {
  constant SZL (line 1212) | const SZL: DineroCurrency<bigint> = {
  constant THB (line 1221) | const THB: DineroCurrency<bigint> = {
  constant TJS (line 1230) | const TJS: DineroCurrency<bigint> = {
  constant TMT (line 1239) | const TMT: DineroCurrency<bigint> = {
  constant TND (line 1248) | const TND: DineroCurrency<bigint> = {
  constant TOP (line 1257) | const TOP: DineroCurrency<bigint> = {
  constant TRY (line 1266) | const TRY: DineroCurrency<bigint> = {
  constant TTD (line 1275) | const TTD: DineroCurrency<bigint> = {
  constant TWD (line 1284) | const TWD: DineroCurrency<bigint> = {
  constant TZS (line 1293) | const TZS: DineroCurrency<bigint> = {
  constant UAH (line 1302) | const UAH: DineroCurrency<bigint> = {
  constant UGX (line 1311) | const UGX: DineroCurrency<bigint> = {
  constant USD (line 1320) | const USD: DineroCurrency<bigint> = {
  constant USN (line 1329) | const USN: DineroCurrency<bigint> = {
  constant UYI (line 1338) | const UYI: DineroCurrency<bigint> = {
  constant UYU (line 1347) | const UYU: DineroCurrency<bigint> = {
  constant UYW (line 1356) | const UYW: DineroCurrency<bigint> = {
  constant UZS (line 1365) | const UZS: DineroCurrency<bigint> = {
  constant VED (line 1374) | const VED: DineroCurrency<bigint> = {
  constant VES (line 1383) | const VES: DineroCurrency<bigint> = {
  constant VND (line 1392) | const VND: DineroCurrency<bigint> = {
  constant VUV (line 1401) | const VUV: DineroCurrency<bigint> = {
  constant WST (line 1410) | const WST: DineroCurrency<bigint> = {
  constant XAD (line 1419) | const XAD: DineroCurrency<bigint> = {
  constant XAF (line 1428) | const XAF: DineroCurrency<bigint> = {
  constant XCD (line 1437) | const XCD: DineroCurrency<bigint> = {
  constant XCG (line 1446) | const XCG: DineroCurrency<bigint> = {
  constant XOF (line 1455) | const XOF: DineroCurrency<bigint> = {
  constant XPF (line 1464) | const XPF: DineroCurrency<bigint> = {
  constant YER (line 1473) | const YER: DineroCurrency<bigint> = {
  constant ZAR (line 1482) | const ZAR: DineroCurrency<bigint> = {
  constant ZMW (line 1491) | const ZMW: DineroCurrency<bigint> = {
  constant ZWG (line 1500) | const ZWG: DineroCurrency<bigint> = {

FILE: packages/dinero.js/src/calculator/bigint/api/zero.ts
  function zero (line 6) | function zero() {

FILE: packages/dinero.js/src/calculator/number/api/zero.ts
  function zero (line 6) | function zero() {

FILE: packages/dinero.js/src/core/api/add.ts
  type AddParams (line 8) | type AddParams<TAmount, TCurrency extends string = string> = readonly [
  function unsafeAdd (line 13) | function unsafeAdd<TAmount>(calculator: DineroCalculator<TAmount>) {
  function safeAdd (line 30) | function safeAdd<TAmount>(calculator: DineroCalculator<TAmount>) {

FILE: packages/dinero.js/src/core/api/allocate.ts
  type UnsafeAllocateParams (line 15) | type UnsafeAllocateParams<
  function unsafeAllocate (line 23) | function unsafeAllocate<TAmount>(calculator: DineroCalculator<TAmount>) {
  type AllocateParams (line 44) | type AllocateParams<
  function safeAllocate (line 52) | function safeAllocate<TAmount>(calculator: DineroCalculator<TAmount>) {

FILE: packages/dinero.js/src/core/api/compare.ts
  type CompareParams (line 9) | type CompareParams<
  function unsafeCompare (line 17) | function unsafeCompare<TAmount>(calculator: DineroCalculator<TAmount>) {
  function safeCompare (line 35) | function safeCompare<TAmount>(calculator: DineroCalculator<TAmount>) {

FILE: packages/dinero.js/src/core/api/convert.ts
  type ConvertParams (line 10) | type ConvertParams<
  function convert (line 20) | function convert<TAmount>(calculator: DineroCalculator<TAmount>) {

FILE: packages/dinero.js/src/core/api/equal.ts
  type EqualParams (line 6) | type EqualParams<TAmount, TCurrency extends string = string> = readonly [
  function equal (line 11) | function equal<TAmount>(calculator: DineroCalculator<TAmount>) {

FILE: packages/dinero.js/src/core/api/greaterThan.ts
  type GreaterThanParams (line 9) | type GreaterThanParams<
  function unsafeGreaterThan (line 17) | function unsafeGreaterThan<TAmount>(calculator: DineroCalculator<TAmount...
  function safeGreaterThan (line 35) | function safeGreaterThan<TAmount>(

FILE: packages/dinero.js/src/core/api/greaterThanOrEqual.ts
  type GreaterThanOrEqualParams (line 9) | type GreaterThanOrEqualParams<
  function unsafeGreaterThanOrEqual (line 17) | function unsafeGreaterThanOrEqual<TAmount>(
  function safeGreaterThanOrEqual (line 37) | function safeGreaterThanOrEqual<TAmount>(

FILE: packages/dinero.js/src/core/api/hasSubUnits.ts
  type HasSubUnitsParams (line 4) | type HasSubUnitsParams<TAmount> = readonly [
  function hasSubUnits (line 8) | function hasSubUnits<TAmount>(calculator: DineroCalculator<TAmount>) {

FILE: packages/dinero.js/src/core/api/haveSameAmount.ts
  type HaveSameAmountParams (line 6) | type HaveSameAmountParams<
  function haveSameAmount (line 16) | function haveSameAmount<TAmount>(calculator: DineroCalculator<TAmount>) {

FILE: packages/dinero.js/src/core/api/haveSameCurrency.ts
  function haveSameCurrency (line 4) | function haveSameCurrency<TAmount>(

FILE: packages/dinero.js/src/core/api/isNegative.ts
  type IsNegativeParams (line 4) | type IsNegativeParams<TAmount> = readonly [
  function isNegative (line 8) | function isNegative<TAmount>(calculator: DineroCalculator<TAmount>) {

FILE: packages/dinero.js/src/core/api/isPositive.ts
  type IsPositiveParams (line 4) | type IsPositiveParams<TAmount> = readonly [
  function isPositive (line 8) | function isPositive<TAmount>(calculator: DineroCalculator<TAmount>) {

FILE: packages/dinero.js/src/core/api/isZero.ts
  type IsZeroParams (line 4) | type IsZeroParams<TAmount> = readonly [dineroObject: Dinero<TAmount>];
  function isZero (line 6) | function isZero<TAmount>(calculator: DineroCalculator<TAmount>) {

FILE: packages/dinero.js/src/core/api/lessThan.ts
  type LessThanParams (line 9) | type LessThanParams<
  function unsafeLessThan (line 17) | function unsafeLessThan<TAmount>(calculator: DineroCalculator<TAmount>) {
  function safeLessThan (line 35) | function safeLessThan<TAmount>(calculator: DineroCalculator<TAmount>) {

FILE: packages/dinero.js/src/core/api/lessThanOrEqual.ts
  type LessThanOrEqualParams (line 9) | type LessThanOrEqualParams<
  function unsafeLessThanOrEqual (line 17) | function unsafeLessThanOrEqual<TAmount>(calculator: DineroCalculator<TAm...
  function safeLessThanOrEqual (line 35) | function safeLessThanOrEqual<TAmount>(

FILE: packages/dinero.js/src/core/api/maximum.ts
  type MaximumParams (line 9) | type MaximumParams<
  function unsafeMaximum (line 19) | function unsafeMaximum<TAmount>(calculator: DineroCalculator<TAmount>) {
  function safeMaximum (line 44) | function safeMaximum<TAmount>(calculator: DineroCalculator<TAmount>) {

FILE: packages/dinero.js/src/core/api/minimum.ts
  type MinimumParams (line 9) | type MinimumParams<
  function unsafeMinimum (line 19) | function unsafeMinimum<TAmount>(calculator: DineroCalculator<TAmount>) {
  function safeMinimum (line 44) | function safeMinimum<TAmount>(calculator: DineroCalculator<TAmount>) {

FILE: packages/dinero.js/src/core/api/multiply.ts
  type MultiplyParams (line 6) | type MultiplyParams<
  function multiply (line 14) | function multiply<TAmount>(calculator: DineroCalculator<TAmount>) {

FILE: packages/dinero.js/src/core/api/normalizeScale.ts
  type NormalizeScaleParams (line 6) | type NormalizeScaleParams<
  function normalizeScale (line 16) | function normalizeScale<TAmount>(calculator: DineroCalculator<TAmount>) {

FILE: packages/dinero.js/src/core/api/subtract.ts
  type SubtractParams (line 8) | type SubtractParams<
  function unsafeSubtract (line 16) | function unsafeSubtract<TAmount>(calculator: DineroCalculator<TAmount>) {
  function safeSubtract (line 33) | function safeSubtract<TAmount>(calculator: DineroCalculator<TAmount>) {

FILE: packages/dinero.js/src/core/api/toDecimal.ts
  type ToDecimalParams (line 13) | type ToDecimalParams<
  function toDecimal (line 22) | function toDecimal<TAmount, TOutput>(
  function getDecimal (line 57) | function getDecimal<TAmount>(

FILE: packages/dinero.js/src/core/api/toSnapshot.ts
  function toSnapshot (line 3) | function toSnapshot<TAmount, TCurrency extends string>(

FILE: packages/dinero.js/src/core/api/toUnits.ts
  type ToUnitsParams (line 4) | type ToUnitsParams<
  function toUnits (line 18) | function toUnits<TAmount, TOutput>(

FILE: packages/dinero.js/src/core/api/transformScale.ts
  type TransformScaleParams (line 5) | type TransformScaleParams<
  function transformScale (line 14) | function transformScale<TAmount>(calculator: DineroCalculator<TAmount>) {

FILE: packages/dinero.js/src/core/api/trimScale.ts
  type TrimScaleParams (line 6) | type TrimScaleParams<
  function trimScale (line 11) | function trimScale<TAmount>(calculator: DineroCalculator<TAmount>) {

FILE: packages/dinero.js/src/core/checks/messages.ts
  constant INVALID_AMOUNT_MESSAGE (line 1) | const INVALID_AMOUNT_MESSAGE = 'Amount is invalid.';
  constant INVALID_SCALE_MESSAGE (line 2) | const INVALID_SCALE_MESSAGE = 'Scale is invalid.';
  constant INVALID_RATIOS_MESSAGE (line 3) | const INVALID_RATIOS_MESSAGE = 'Ratios are invalid.';
  constant UNEQUAL_SCALES_MESSAGE (line 4) | const UNEQUAL_SCALES_MESSAGE = 'Objects must have the same scale.';
  constant UNEQUAL_CURRENCIES_MESSAGE (line 5) | const UNEQUAL_CURRENCIES_MESSAGE =
  constant NON_DECIMAL_CURRENCY_MESSAGE (line 7) | const NON_DECIMAL_CURRENCY_MESSAGE = 'Currency is not decimal.';
  constant MISMATCHED_BASES_MESSAGE (line 8) | const MISMATCHED_BASES_MESSAGE =

FILE: packages/dinero.js/src/core/helpers/assert.ts
  function assert (line 9) | function assert(condition: boolean, message: string) {

FILE: packages/dinero.js/src/core/helpers/createDinero.ts
  type CreateDineroOptions (line 10) | type CreateDineroOptions<TAmount> = {
  function createDinero (line 16) | function createDinero<TAmount>({

FILE: packages/dinero.js/src/core/types/Dinero.ts
  type Dinero (line 8) | type Dinero<TAmount, TCurrency extends string = string> = {

FILE: packages/dinero.js/src/core/types/DineroBinaryOperation.ts
  type DineroBinaryOperation (line 1) | type DineroBinaryOperation<TInput, TOutput = TInput> = (

FILE: packages/dinero.js/src/core/types/DineroCalculator.ts
  type DineroComparisonOperator (line 3) | enum DineroComparisonOperator {
  type DineroCalculator (line 9) | type DineroCalculator<TInput> = {

FILE: packages/dinero.js/src/core/types/DineroDivideOperation.ts
  type DineroDivideOperation (line 3) | type DineroDivideOperation = <TAmount>(

FILE: packages/dinero.js/src/core/types/DineroFactory.ts
  type DineroFactory (line 3) | type DineroFactory<TAmount> = <TCurrency extends string>({

FILE: packages/dinero.js/src/core/types/DineroFormatter.ts
  type DineroFormatter (line 1) | type DineroFormatter<TAmount> = {

FILE: packages/dinero.js/src/core/types/DineroOptions.ts
  type DineroOptions (line 3) | type DineroOptions<TAmount, TCurrency extends string = string> = {

FILE: packages/dinero.js/src/core/types/DineroRates.ts
  type DineroRate (line 3) | type DineroRate<TAmount> = DineroScaledAmount<TAmount> | TAmount;
  type DineroRates (line 5) | type DineroRates<TAmount> = Record<string, DineroRate<TAmount>>;

FILE: packages/dinero.js/src/core/types/DineroScaledAmount.ts
  type DineroScaledAmount (line 1) | type DineroScaledAmount<TAmount> = {

FILE: packages/dinero.js/src/core/types/DineroSnapshot.ts
  type DineroSnapshot (line 3) | type DineroSnapshot<TAmount, TCurrency extends string = string> = {

FILE: packages/dinero.js/src/core/types/DineroTransformer.ts
  type TransformerOptions (line 3) | type TransformerOptions<
  type DineroTransformer (line 12) | type DineroTransformer<

FILE: packages/dinero.js/src/core/types/DineroUnaryOperation.ts
  type DineroUnaryOperation (line 1) | type DineroUnaryOperation<TInput, TOutput = TInput> = (

FILE: packages/dinero.js/src/core/utils/absolute.ts
  function absolute (line 6) | function absolute<TAmount>(calculator: DineroCalculator<TAmount>) {

FILE: packages/dinero.js/src/core/utils/compare.ts
  type ComparisonCalculator (line 3) | type ComparisonCalculator<TAmount> = DineroCalculator<TAmount>;
  function compare (line 12) | function compare<TAmount>(calculator: ComparisonCalculator<TAmount>) {

FILE: packages/dinero.js/src/core/utils/computeBase.ts
  function computeBase (line 5) | function computeBase<TAmount>(calculator: DineroCalculator<TAmount>) {

FILE: packages/dinero.js/src/core/utils/countTrailingZeros.ts
  type CountTrailingZerosCalculator (line 5) | type CountTrailingZerosCalculator<TAmount> = DineroCalculator<TAmount>;
  function countTrailingZeros (line 7) | function countTrailingZeros<TAmount>(

FILE: packages/dinero.js/src/core/utils/distribute.ts
  type DistributeCalculator (line 8) | type DistributeCalculator<TAmount> = DineroCalculator<TAmount>;
  function distribute (line 17) | function distribute<TAmount>(calculator: DistributeCalculator<TAmount>) {

FILE: packages/dinero.js/src/core/utils/equal.ts
  type EqualCalculator (line 4) | type EqualCalculator<TAmount> = DineroCalculator<TAmount>;
  function equal (line 13) | function equal<TAmount>(calculator: EqualCalculator<TAmount>) {

FILE: packages/dinero.js/src/core/utils/getAmountAndScale.ts
  function getAmountAndScale (line 5) | function getAmountAndScale<TAmount>(

FILE: packages/dinero.js/src/core/utils/getDivisors.ts
  function getDivisors (line 3) | function getDivisors<TAmount>(calculator: DineroCalculator<TAmount>) {

FILE: packages/dinero.js/src/core/utils/greaterThan.ts
  type GreaterThanCalculator (line 4) | type GreaterThanCalculator<TAmount> = DineroCalculator<TAmount>;
  function greaterThan (line 13) | function greaterThan<TAmount>(

FILE: packages/dinero.js/src/core/utils/greaterThanOrEqual.ts
  type GreaterThanOrEqualCalculator (line 6) | type GreaterThanOrEqualCalculator<TAmount> = DineroCalculator<TAmount>;
  function greaterThanOrEqual (line 15) | function greaterThanOrEqual<TAmount>(

FILE: packages/dinero.js/src/core/utils/isArray.ts
  function isArray (line 1) | function isArray<TType>(

FILE: packages/dinero.js/src/core/utils/isEven.ts
  function isEven (line 5) | function isEven<TAmount>(calculator: DineroCalculator<TAmount>) {

FILE: packages/dinero.js/src/core/utils/isHalf.ts
  function isHalf (line 5) | function isHalf<TAmount>(calculator: DineroCalculator<TAmount>) {

FILE: packages/dinero.js/src/core/utils/isScaledAmount.ts
  function isScaledAmount (line 3) | function isScaledAmount<TAmount>(

FILE: packages/dinero.js/src/core/utils/lessThan.ts
  type LessThanCalculator (line 4) | type LessThanCalculator<TAmount> = DineroCalculator<TAmount>;
  function lessThan (line 13) | function lessThan<TAmount>(calculator: LessThanCalculator<TAmount>) {

FILE: packages/dinero.js/src/core/utils/lessThanOrEqual.ts
  type LessThanOrEqualCalculator (line 6) | type LessThanOrEqualCalculator<TAmount> = DineroCalculator<TAmount>;
  function lessThanOrEqual (line 15) | function lessThanOrEqual<TAmount>(

FILE: packages/dinero.js/src/core/utils/maximum.ts
  type MaximumCalculator (line 5) | type MaximumCalculator<TAmount> = DineroCalculator<TAmount>;
  function maximum (line 14) | function maximum<TAmount>(calculator: MaximumCalculator<TAmount>) {

FILE: packages/dinero.js/src/core/utils/minimum.ts
  type MinimumCalculator (line 5) | type MinimumCalculator<TAmount> = DineroCalculator<TAmount>;
  function minimum (line 14) | function minimum<TAmount>(calculator: MinimumCalculator<TAmount>) {

FILE: packages/dinero.js/src/core/utils/sign.ts
  function sign (line 6) | function sign<TAmount>(calculator: DineroCalculator<TAmount>) {

FILE: packages/dinero.js/src/currencies/iso4217.ts
  constant AED (line 15) | const AED = {
  constant AFN (line 24) | const AFN = {
  constant ALL (line 33) | const ALL = {
  constant AMD (line 42) | const AMD = {
  constant AOA (line 51) | const AOA = {
  constant ARS (line 60) | const ARS = {
  constant AUD (line 69) | const AUD = {
  constant AWG (line 78) | const AWG = {
  constant AZN (line 87) | const AZN = {
  constant BAM (line 96) | const BAM = {
  constant BBD (line 105) | const BBD = {
  constant BDT (line 114) | const BDT = {
  constant BGN (line 123) | const BGN = {
  constant BHD (line 132) | const BHD = {
  constant BIF (line 141) | const BIF = {
  constant BMD (line 150) | const BMD = {
  constant BND (line 159) | const BND = {
  constant BOB (line 168) | const BOB = {
  constant BOV (line 177) | const BOV = {
  constant BRL (line 186) | const BRL = {
  constant BSD (line 195) | const BSD = {
  constant BTN (line 204) | const BTN = {
  constant BWP (line 213) | const BWP = {
  constant BYN (line 222) | const BYN = {
  constant BZD (line 231) | const BZD = {
  constant CAD (line 240) | const CAD = {
  constant CDF (line 249) | const CDF = {
  constant CHE (line 258) | const CHE = {
  constant CHF (line 267) | const CHF = {
  constant CHW (line 276) | const CHW = {
  constant CLF (line 285) | const CLF = {
  constant CLP (line 294) | const CLP = {
  constant CNY (line 303) | const CNY = {
  constant COP (line 312) | const COP = {
  constant COU (line 321) | const COU = {
  constant CRC (line 330) | const CRC = {
  constant CUP (line 339) | const CUP = {
  constant CVE (line 348) | const CVE = {
  constant CZK (line 357) | const CZK = {
  constant DJF (line 366) | const DJF = {
  constant DKK (line 375) | const DKK = {
  constant DOP (line 384) | const DOP = {
  constant DZD (line 393) | const DZD = {
  constant EGP (line 402) | const EGP = {
  constant ERN (line 411) | const ERN = {
  constant ETB (line 420) | const ETB = {
  constant EUR (line 429) | const EUR = {
  constant FJD (line 438) | const FJD = {
  constant FKP (line 447) | const FKP = {
  constant GBP (line 456) | const GBP = {
  constant GEL (line 465) | const GEL = {
  constant GHS (line 474) | const GHS = {
  constant GIP (line 483) | const GIP = {
  constant GMD (line 492) | const GMD = {
  constant GNF (line 501) | const GNF = {
  constant GTQ (line 510) | const GTQ = {
  constant GYD (line 519) | const GYD = {
  constant HKD (line 528) | const HKD = {
  constant HNL (line 537) | const HNL = {
  constant HTG (line 546) | const HTG = {
  constant HUF (line 555) | const HUF = {
  constant IDR (line 564) | const IDR = {
  constant ILS (line 573) | const ILS = {
  constant INR (line 582) | const INR = {
  constant IQD (line 591) | const IQD = {
  constant IRR (line 600) | const IRR = {
  constant ISK (line 609) | const ISK = {
  constant JMD (line 618) | const JMD = {
  constant JOD (line 627) | const JOD = {
  constant JPY (line 636) | const JPY = {
  constant KES (line 645) | const KES = {
  constant KGS (line 654) | const KGS = {
  constant KHR (line 663) | const KHR = {
  constant KMF (line 672) | const KMF = {
  constant KPW (line 681) | const KPW = {
  constant KRW (line 690) | const KRW = {
  constant KWD (line 699) | const KWD = {
  constant KYD (line 708) | const KYD = {
  constant KZT (line 717) | const KZT = {
  constant LAK (line 726) | const LAK = {
  constant LBP (line 735) | const LBP = {
  constant LKR (line 744) | const LKR = {
  constant LRD (line 753) | const LRD = {
  constant LSL (line 762) | const LSL = {
  constant LYD (line 771) | const LYD = {
  constant MAD (line 780) | const MAD = {
  constant MDL (line 789) | const MDL = {
  constant MGA (line 798) | const MGA = {
  constant MKD (line 807) | const MKD = {
  constant MMK (line 816) | const MMK = {
  constant MNT (line 825) | const MNT = {
  constant MOP (line 834) | const MOP = {
  constant MRU (line 843) | const MRU = {
  constant MUR (line 852) | const MUR = {
  constant MVR (line 861) | const MVR = {
  constant MWK (line 870) | const MWK = {
  constant MXN (line 879) | const MXN = {
  constant MXV (line 888) | const MXV = {
  constant MYR (line 897) | const MYR = {
  constant MZN (line 906) | const MZN = {
  constant NAD (line 915) | const NAD = {
  constant NGN (line 924) | const NGN = {
  constant NIO (line 933) | const NIO = {
  constant NOK (line 942) | const NOK = {
  constant NPR (line 951) | const NPR = {
  constant NZD (line 960) | const NZD = {
  constant OMR (line 969) | const OMR = {
  constant PAB (line 978) | const PAB = {
  constant PEN (line 987) | const PEN = {
  constant PGK (line 996) | const PGK = {
  constant PHP (line 1005) | const PHP = {
  constant PKR (line 1014) | const PKR = {
  constant PLN (line 1023) | const PLN = {
  constant PYG (line 1032) | const PYG = {
  constant QAR (line 1041) | const QAR = {
  constant RON (line 1050) | const RON = {
  constant RSD (line 1059) | const RSD = {
  constant RUB (line 1068) | const RUB = {
  constant RWF (line 1077) | const RWF = {
  constant SAR (line 1086) | const SAR = {
  constant SBD (line 1095) | const SBD = {
  constant SCR (line 1104) | const SCR = {
  constant SDG (line 1113) | const SDG = {
  constant SEK (line 1122) | const SEK = {
  constant SGD (line 1131) | const SGD = {
  constant SHP (line 1140) | const SHP = {
  constant SLE (line 1149) | const SLE = {
  constant SOS (line 1158) | const SOS = {
  constant SRD (line 1167) | const SRD = {
  constant SSP (line 1176) | const SSP = {
  constant STN (line 1185) | const STN = {
  constant SVC (line 1194) | const SVC = {
  constant SYP (line 1203) | const SYP = {
  constant SZL (line 1212) | const SZL = {
  constant THB (line 1221) | const THB = {
  constant TJS (line 1230) | const TJS = {
  constant TMT (line 1239) | const TMT = {
  constant TND (line 1248) | const TND = {
  constant TOP (line 1257) | const TOP = {
  constant TRY (line 1266) | const TRY = {
  constant TTD (line 1275) | const TTD = {
  constant TWD (line 1284) | const TWD = {
  constant TZS (line 1293) | const TZS = {
  constant UAH (line 1302) | const UAH = {
  constant UGX (line 1311) | const UGX = {
  constant USD (line 1320) | const USD = {
  constant USN (line 1329) | const USN = {
  constant UYI (line 1338) | const UYI = {
  constant UYU (line 1347) | const UYU = {
  constant UYW (line 1356) | const UYW = {
  constant UZS (line 1365) | const UZS = {
  constant VED (line 1374) | const VED = {
  constant VES (line 1383) | const VES = {
  constant VND (line 1392) | const VND = {
  constant VUV (line 1401) | const VUV = {
  constant WST (line 1410) | const WST = {
  constant XAD (line 1419) | const XAD = {
  constant XAF (line 1428) | const XAF = {
  constant XCD (line 1437) | const XCD = {
  constant XCG (line 1446) | const XCG = {
  constant XOF (line 1455) | const XOF = {
  constant XPF (line 1464) | const XPF = {
  constant YER (line 1473) | const YER = {
  constant ZAR (line 1482) | const ZAR = {
  constant ZMW (line 1491) | const ZMW = {
  constant ZWG (line 1500) | const ZWG = {

FILE: packages/dinero.js/src/currencies/types/DineroCurrency.ts
  type DineroCurrency (line 1) | type DineroCurrency<TAmount, TCurrency extends string = string> = {

FILE: packages/dinero.js/src/dinero.ts
  method onCreate (line 22) | onCreate({ amount, scale }) {

FILE: packages/dinero.js/tsdown.config.ts
  function getBanner (line 8) | function getBanner() {

FILE: ship.config.cjs
  method publishCommand (line 8) | publishCommand({ tag }) {
  method installCommand (line 11) | installCommand() {
  method shouldPrepare (line 15) | shouldPrepare({ releaseType, commitNumbersPerType }) {
  method beforeCommitChanges (line 20) | beforeCommitChanges({ exec }) {

FILE: test/utils/castToBigintCurrency.ts
  function castToBigintCurrency (line 3) | function castToBigintCurrency<TCurrency extends string>(

FILE: test/utils/castToBigjsCurrency.ts
  function castToBigjsCurrency (line 5) | function castToBigjsCurrency<TCurrency extends string>(

FILE: test/utils/createBigintDinero.ts
  function createBigintDinero (line 4) | function createBigintDinero<TCurrency extends string>(

FILE: test/utils/createBigjsDinero.ts
  function createBigjsDinero (line 21) | function createBigjsDinero<TCurrency extends string>(

FILE: test/utils/createNumberDinero.ts
  function createNumberDinero (line 4) | function createNumberDinero<TCurrency extends string>(
Condensed preview — 573 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,355K chars).
[
  {
    "path": ".agents/skills/dinero-best-practices/SKILL.md",
    "chars": 3024,
    "preview": "---\nname: dinero-best-practices\ndescription: >\n  Core best practices for the Dinero.js money library. Use when writing,\n"
  },
  {
    "path": ".agents/skills/dinero-best-practices/rules/arithmetic-allocate-not-divide.md",
    "chars": 1245,
    "preview": "---\ntitle: Use allocate for Splitting Money, Not Manual Division\nimpact: CRITICAL\nimpactDescription: prevents lost cents"
  },
  {
    "path": ".agents/skills/dinero-best-practices/rules/arithmetic-immutability.md",
    "chars": 1212,
    "preview": "---\ntitle: Capture Return Values — Dinero Objects Are Immutable\nimpact: CRITICAL\nimpactDescription: prevents silently lo"
  },
  {
    "path": ".agents/skills/dinero-best-practices/rules/arithmetic-percentages.md",
    "chars": 1522,
    "preview": "---\ntitle: Calculate Percentages with allocate or Scaled multiply\nimpact: HIGH\nimpactDescription: prevents precision los"
  },
  {
    "path": ".agents/skills/dinero-best-practices/rules/arithmetic-scaled-amounts.md",
    "chars": 1341,
    "preview": "---\ntitle: Never Multiply by a Raw Decimal — Use Scaled Amounts\nimpact: CRITICAL\nimpactDescription: prevents throws from"
  },
  {
    "path": ".agents/skills/dinero-best-practices/rules/creation-from-floats.md",
    "chars": 1327,
    "preview": "---\ntitle: Convert Float Inputs to Minor Units with a Helper\nimpact: CRITICAL\nimpactDescription: prevents throws and pre"
  },
  {
    "path": ".agents/skills/dinero-best-practices/rules/creation-minor-units.md",
    "chars": 1046,
    "preview": "---\ntitle: Always Pass Amounts as Integers in Minor Currency Units\nimpact: CRITICAL\nimpactDescription: prevents silent o"
  },
  {
    "path": ".agents/skills/dinero-best-practices/rules/creation-zero-exponent.md",
    "chars": 1059,
    "preview": "---\ntitle: Currencies with Exponent 0 Take Major Units Directly\nimpact: HIGH\nimpactDescription: prevents wrong amounts f"
  },
  {
    "path": ".agents/skills/dinero-best-practices/rules/imports-bigint-currencies.md",
    "chars": 1222,
    "preview": "---\ntitle: Match Calculator Type — Use Matching Currency Imports\nimpact: HIGH\nimpactDescription: prevents TypeError from"
  },
  {
    "path": ".agents/skills/dinero-best-practices/rules/imports-tree-shaking.md",
    "chars": 1055,
    "preview": "---\ntitle: Import Only What You Use — Standalone Functions Enable Tree-Shaking\nimpact: MEDIUM\nimpactDescription: reduces"
  },
  {
    "path": ".agents/skills/dinero-best-practices/rules/precision-bigint.md",
    "chars": 1185,
    "preview": "---\ntitle: Use bigint for Amounts Exceeding Number.MAX_SAFE_INTEGER\nimpact: HIGH\nimpactDescription: prevents silent prec"
  },
  {
    "path": ".agents/skills/dinero-best-practices/rules/precision-crypto.md",
    "chars": 1186,
    "preview": "---\ntitle: Cryptocurrencies Require bigint Due to High Exponents\nimpact: HIGH\nimpactDescription: prevents overflow on cr"
  },
  {
    "path": ".agents/skills/dinero-best-practices/rules/precision-trim-scale.md",
    "chars": 1052,
    "preview": "---\ntitle: Use trimScale to Remove Trailing Zeros After Chained Operations\nimpact: MEDIUM\nimpactDescription: prevents un"
  },
  {
    "path": ".agents/skills/dinero-currency-patterns/SKILL.md",
    "chars": 2598,
    "preview": "---\nname: dinero-currency-patterns\ndescription: >\n  Currency handling patterns for the Dinero.js money library. Use when"
  },
  {
    "path": ".agents/skills/dinero-currency-patterns/rules/convert-reusable.md",
    "chars": 1037,
    "preview": "---\ntitle: Build Reusable Converter Functions\nimpact: MEDIUM\nimpactDescription: eliminates repeated rate passing across "
  },
  {
    "path": ".agents/skills/dinero-currency-patterns/rules/convert-scaled-rates.md",
    "chars": 1283,
    "preview": "---\ntitle: Use Scaled Amounts for Fractional Exchange Rates, Not Floats\nimpact: HIGH\nimpactDescription: prevents precisi"
  },
  {
    "path": ".agents/skills/dinero-currency-patterns/rules/payment-services.md",
    "chars": 1584,
    "preview": "---\ntitle: Map Dinero Objects to Payment Service Formats with Dedicated Helpers\nimpact: MEDIUM\nimpactDescription: preven"
  },
  {
    "path": ".agents/skills/dinero-currency-patterns/rules/storage-database.md",
    "chars": 1295,
    "preview": "---\ntitle: Store Amount, Currency Code, and Scale as Separate Columns\nimpact: HIGH\nimpactDescription: prevents data loss"
  },
  {
    "path": ".agents/skills/dinero-currency-patterns/rules/storage-no-money-type.md",
    "chars": 1074,
    "preview": "---\ntitle: Avoid PostgreSQL's money Type for Multi-Currency Applications\nimpact: HIGH\nimpactDescription: prevents locale"
  },
  {
    "path": ".agents/skills/dinero-currency-patterns/rules/types-as-const.md",
    "chars": 1397,
    "preview": "---\ntitle: Define Custom Currencies with as const satisfies for Type Safety\nimpact: HIGH\nimpactDescription: enables comp"
  },
  {
    "path": ".agents/skills/dinero-currency-patterns/rules/types-currency-mismatch.md",
    "chars": 1514,
    "preview": "---\ntitle: TypeScript Catches Currency Mismatches at Compile Time\nimpact: HIGH\nimpactDescription: prevents adding, subtr"
  },
  {
    "path": ".agents/skills/dinero-currency-patterns/rules/types-lookup-validation.md",
    "chars": 1376,
    "preview": "---\ntitle: Validate Currency Codes from External Sources at Runtime\nimpact: HIGH\nimpactDescription: prevents undefined c"
  },
  {
    "path": ".agents/skills/dinero-formatting/SKILL.md",
    "chars": 2487,
    "preview": "---\nname: dinero-formatting\ndescription: >\n  Formatting patterns for the Dinero.js money library. Use when displaying\n  "
  },
  {
    "path": ".agents/skills/dinero-formatting/rules/display-no-currency-symbols.md",
    "chars": 1271,
    "preview": "---\ntitle: Dinero.js Does Not Format Currency Symbols — Compose with Intl.NumberFormat\nimpact: CRITICAL\nimpactDescriptio"
  },
  {
    "path": ".agents/skills/dinero-formatting/rules/display-to-decimal.md",
    "chars": 1167,
    "preview": "---\ntitle: Use toDecimal for Display Strings, Not toSnapshot\nimpact: CRITICAL\nimpactDescription: prevents displaying raw"
  },
  {
    "path": ".agents/skills/dinero-formatting/rules/locale-intl-formatter.md",
    "chars": 1245,
    "preview": "---\ntitle: Build Reusable Formatters with Intl.NumberFormat\nimpact: HIGH\nimpactDescription: eliminates duplicated format"
  },
  {
    "path": ".agents/skills/dinero-formatting/rules/locale-multilingual.md",
    "chars": 1306,
    "preview": "---\ntitle: Parameterize Locale for Multilingual Sites\nimpact: HIGH\nimpactDescription: prevents hardcoded locale strings "
  },
  {
    "path": ".agents/skills/dinero-formatting/rules/nondecimal-to-units.md",
    "chars": 1372,
    "preview": "---\ntitle: Use toUnits for Non-Decimal Currencies, Not toDecimal\nimpact: MEDIUM\nimpactDescription: prevents wrong output"
  },
  {
    "path": ".agents/skills/dinero-formatting/rules/serialization-bigint-json.md",
    "chars": 1363,
    "preview": "---\ntitle: BigInt Dinero Objects Require a Custom JSON Replacer\nimpact: HIGH\nimpactDescription: prevents TypeError when "
  },
  {
    "path": ".agents/skills/dinero-formatting/rules/serialization-snapshot.md",
    "chars": 1300,
    "preview": "---\ntitle: Use toSnapshot for Transport and Storage, Not Display\nimpact: HIGH\nimpactDescription: prevents data loss from"
  },
  {
    "path": ".agents/skills/tsdown/SKILL.md",
    "chars": 9651,
    "preview": "---\nname: tsdown\ndescription: Bundle TypeScript and JavaScript libraries with blazing-fast speed powered by Rolldown. Us"
  },
  {
    "path": ".agents/skills/tsdown/references/advanced-ci.md",
    "chars": 2063,
    "preview": "# CI Environment Support\n\nAutomatically detect CI environments and toggle features based on local vs CI builds.\n\n## Over"
  },
  {
    "path": ".agents/skills/tsdown/references/advanced-hooks.md",
    "chars": 7046,
    "preview": "# Lifecycle Hooks\n\nExtend the build process with lifecycle hooks.\n\n## Overview\n\nHooks provide a way to inject custom log"
  },
  {
    "path": ".agents/skills/tsdown/references/advanced-plugins.md",
    "chars": 6753,
    "preview": "# Plugins\n\nExtend tsdown with plugins from multiple ecosystems.\n\n## Overview\n\ntsdown, built on Rolldown, supports plugin"
  },
  {
    "path": ".agents/skills/tsdown/references/advanced-programmatic.md",
    "chars": 6032,
    "preview": "# Programmatic Usage\n\nUse tsdown from JavaScript/TypeScript code.\n\n## Overview\n\ntsdown can be imported and used programm"
  },
  {
    "path": ".agents/skills/tsdown/references/advanced-rolldown-options.md",
    "chars": 2368,
    "preview": "# Customizing Rolldown Options\n\nPass options directly to the underlying Rolldown bundler.\n\n## Overview\n\ntsdown uses [Rol"
  },
  {
    "path": ".agents/skills/tsdown/references/guide-getting-started.md",
    "chars": 2655,
    "preview": "# Getting Started\n\nQuick guide to installing and using tsdown for the first time.\n\n## Installation\n\nInstall tsdown as a "
  },
  {
    "path": ".agents/skills/tsdown/references/guide-migrate-from-tsup.md",
    "chars": 4257,
    "preview": "# Migrate from tsup\n\nMigration guide for switching from tsup to tsdown.\n\n## Overview\n\ntsdown is built on Rolldown (Rust-"
  },
  {
    "path": ".agents/skills/tsdown/references/option-cjs-default.md",
    "chars": 1941,
    "preview": "# CJS Default Export\n\nControl how default exports are handled in CommonJS output.\n\n## Overview\n\nThe `cjsDefault` option "
  },
  {
    "path": ".agents/skills/tsdown/references/option-cleaning.md",
    "chars": 4871,
    "preview": "# Output Directory Cleaning\n\nControl how the output directory is cleaned before builds.\n\n## Overview\n\nBy default, tsdown"
  },
  {
    "path": ".agents/skills/tsdown/references/option-config-file.md",
    "chars": 5267,
    "preview": "# Configuration File\n\nCentralize and manage build settings with a configuration file.\n\n## Overview\n\ntsdown searches for "
  },
  {
    "path": ".agents/skills/tsdown/references/option-css.md",
    "chars": 282,
    "preview": "# CSS Support\n\n**Status: Experimental — still in active development.**\n\nCSS handling in tsdown is not yet stable. The AP"
  },
  {
    "path": ".agents/skills/tsdown/references/option-dependencies.md",
    "chars": 5767,
    "preview": "# Dependencies\n\nControl how dependencies are bundled or externalized.\n\n## Overview\n\ntsdown intelligently handles depende"
  },
  {
    "path": ".agents/skills/tsdown/references/option-dts.md",
    "chars": 4628,
    "preview": "# TypeScript Declaration Files\n\nGenerate `.d.ts` type declaration files for your library.\n\n## Overview\n\ntsdown uses [rol"
  },
  {
    "path": ".agents/skills/tsdown/references/option-entry.md",
    "chars": 3664,
    "preview": "# Entry Points\n\nConfigure which files to bundle as entry points.\n\n## Overview\n\nEntry points are the starting files for t"
  },
  {
    "path": ".agents/skills/tsdown/references/option-lint.md",
    "chars": 2972,
    "preview": "# Package Validation (publint & attw)\n\nValidate your package configuration and type declarations before publishing.\n\n## "
  },
  {
    "path": ".agents/skills/tsdown/references/option-log-level.md",
    "chars": 1834,
    "preview": "# Log Level\n\nControl the verbosity of build output.\n\n## Overview\n\nThe `logLevel` option controls how much information ts"
  },
  {
    "path": ".agents/skills/tsdown/references/option-minification.md",
    "chars": 3562,
    "preview": "# Minification\n\nCompress code to reduce bundle size.\n\n## Overview\n\nMinification removes unnecessary characters (whitespa"
  },
  {
    "path": ".agents/skills/tsdown/references/option-output-directory.md",
    "chars": 4433,
    "preview": "# Output Directory\n\nConfigure the output directory for bundled files.\n\n## Overview\n\nBy default, tsdown outputs bundled f"
  },
  {
    "path": ".agents/skills/tsdown/references/option-output-format.md",
    "chars": 3476,
    "preview": "# Output Format\n\nConfigure the module format(s) for generated bundles.\n\n## Overview\n\ntsdown can generate bundles in mult"
  },
  {
    "path": ".agents/skills/tsdown/references/option-package-exports.md",
    "chars": 5296,
    "preview": "# Auto-Generate Package Exports\n\nAutomatically generate package.json exports field from build output.\n\n## Overview\n\ntsdo"
  },
  {
    "path": ".agents/skills/tsdown/references/option-platform.md",
    "chars": 5205,
    "preview": "# Platform\n\nTarget runtime environment for bundled code.\n\n## Overview\n\nPlatform determines the runtime environment and a"
  },
  {
    "path": ".agents/skills/tsdown/references/option-shims.md",
    "chars": 5568,
    "preview": "# Shims\n\nAdd compatibility between ESM and CommonJS module systems.\n\n## Overview\n\nShims provide small pieces of code tha"
  },
  {
    "path": ".agents/skills/tsdown/references/option-sourcemap.md",
    "chars": 5542,
    "preview": "# Source Maps\n\nGenerate source maps for debugging bundled code.\n\n## Overview\n\nSource maps map minified/bundled code back"
  },
  {
    "path": ".agents/skills/tsdown/references/option-target.md",
    "chars": 3672,
    "preview": "# Target Environment\n\nConfigure JavaScript syntax transformations for target environments.\n\n## Overview\n\nThe `target` op"
  },
  {
    "path": ".agents/skills/tsdown/references/option-tree-shaking.md",
    "chars": 5184,
    "preview": "# Tree Shaking\n\nRemove unused code from bundles.\n\n## Overview\n\nTree shaking eliminates dead code (unused exports) from y"
  },
  {
    "path": ".agents/skills/tsdown/references/option-unbundle.md",
    "chars": 5468,
    "preview": "# Unbundle Mode\n\nPreserve source directory structure in output.\n\n## Overview\n\nUnbundle mode (also called \"bundleless\" or"
  },
  {
    "path": ".agents/skills/tsdown/references/option-watch-mode.md",
    "chars": 4660,
    "preview": "# Watch Mode\n\nAutomatically rebuild when files change.\n\n## Overview\n\nWatch mode monitors your source files and rebuilds "
  },
  {
    "path": ".agents/skills/tsdown/references/recipe-react.md",
    "chars": 5868,
    "preview": "# React Support\n\nBuild React component libraries with tsdown.\n\n## Overview\n\ntsdown provides first-class support for Reac"
  },
  {
    "path": ".agents/skills/tsdown/references/recipe-vue.md",
    "chars": 6398,
    "preview": "# Vue Support\n\nBuild Vue component libraries with tsdown.\n\n## Overview\n\ntsdown provides first-class support for Vue libr"
  },
  {
    "path": ".agents/skills/tsdown/references/recipe-wasm.md",
    "chars": 2660,
    "preview": "# WASM Support\n\nBundle WebAssembly modules in your TypeScript/JavaScript project.\n\n## Overview\n\ntsdown supports WASM thr"
  },
  {
    "path": ".agents/skills/tsdown/references/reference-cli.md",
    "chars": 5848,
    "preview": "# CLI Reference\n\nComplete reference for tsdown command-line interface.\n\n## Overview\n\nAll CLI flags can also be set in th"
  },
  {
    "path": ".agents/skills/vercel-composition-patterns/AGENTS.md",
    "chars": 22604,
    "preview": "# React Composition Patterns\n\n**Version 1.0.0**  \nEngineering  \nJanuary 2026\n\n> **Note:**  \n> This document is mainly fo"
  },
  {
    "path": ".agents/skills/vercel-composition-patterns/README.md",
    "chars": 2132,
    "preview": "# React Composition Patterns\n\nA structured repository for React composition patterns that scale. These\npatterns help avo"
  },
  {
    "path": ".agents/skills/vercel-composition-patterns/SKILL.md",
    "chars": 2882,
    "preview": "---\nname: vercel-composition-patterns\ndescription:\n  React composition patterns that scale. Use when refactoring compone"
  },
  {
    "path": ".agents/skills/vercel-composition-patterns/rules/architecture-avoid-boolean-props.md",
    "chars": 2267,
    "preview": "---\ntitle: Avoid Boolean Prop Proliferation\nimpact: CRITICAL\nimpactDescription: prevents unmaintainable component varian"
  },
  {
    "path": ".agents/skills/vercel-composition-patterns/rules/architecture-compound-components.md",
    "chars": 2600,
    "preview": "---\ntitle: Use Compound Components\nimpact: HIGH\nimpactDescription: enables flexible composition without prop drilling\nta"
  },
  {
    "path": ".agents/skills/vercel-composition-patterns/rules/patterns-children-over-render-props.md",
    "chars": 1886,
    "preview": "---\ntitle: Prefer Composing Children Over Render Props\nimpact: MEDIUM\nimpactDescription: cleaner composition, better rea"
  },
  {
    "path": ".agents/skills/vercel-composition-patterns/rules/patterns-explicit-variants.md",
    "chars": 2395,
    "preview": "---\ntitle: Create Explicit Component Variants\nimpact: MEDIUM\nimpactDescription: self-documenting code, no hidden conditi"
  },
  {
    "path": ".agents/skills/vercel-composition-patterns/rules/react19-no-forwardref.md",
    "chars": 949,
    "preview": "---\ntitle: React 19 API Changes\nimpact: MEDIUM\nimpactDescription: cleaner component definitions and context usage\ntags: "
  },
  {
    "path": ".agents/skills/vercel-composition-patterns/rules/state-context-interface.md",
    "chars": 4970,
    "preview": "---\ntitle: Define Generic Context Interfaces for Dependency Injection\nimpact: HIGH\nimpactDescription: enables dependency"
  },
  {
    "path": ".agents/skills/vercel-composition-patterns/rules/state-decouple-implementation.md",
    "chars": 2697,
    "preview": "---\ntitle: Decouple State Management from UI\nimpact: MEDIUM\nimpactDescription: enables swapping state implementations wi"
  },
  {
    "path": ".agents/skills/vercel-composition-patterns/rules/state-lift-state.md",
    "chars": 3219,
    "preview": "---\ntitle: Lift State into Provider Components\nimpact: HIGH\nimpactDescription: enables state sharing outside component b"
  },
  {
    "path": ".agents/skills/vercel-react-best-practices/AGENTS.md",
    "chars": 81669,
    "preview": "# React Best Practices\n\n**Version 1.0.0**  \nVercel Engineering  \nJanuary 2026\n\n> **Note:**  \n> This document is mainly f"
  },
  {
    "path": ".agents/skills/vercel-react-best-practices/README.md",
    "chars": 3360,
    "preview": "# React Best Practices\n\nA structured repository for creating and maintaining React Best Practices optimized for agents a"
  },
  {
    "path": ".agents/skills/vercel-react-best-practices/SKILL.md",
    "chars": 6165,
    "preview": "---\nname: vercel-react-best-practices\ndescription: React and Next.js performance optimization guidelines from Vercel Eng"
  },
  {
    "path": ".agents/skills/vercel-react-best-practices/rules/advanced-event-handler-refs.md",
    "chars": 1483,
    "preview": "---\ntitle: Store Event Handlers in Refs\nimpact: LOW\nimpactDescription: stable subscriptions\ntags: advanced, hooks, refs,"
  },
  {
    "path": ".agents/skills/vercel-react-best-practices/rules/advanced-init-once.md",
    "chars": 958,
    "preview": "---\ntitle: Initialize App Once, Not Per Mount\nimpact: LOW-MEDIUM\nimpactDescription: avoids duplicate init in development"
  },
  {
    "path": ".agents/skills/vercel-react-best-practices/rules/advanced-use-latest.md",
    "chars": 1072,
    "preview": "---\ntitle: useEffectEvent for Stable Callback Refs\nimpact: LOW\nimpactDescription: prevents effect re-runs\ntags: advanced"
  },
  {
    "path": ".agents/skills/vercel-react-best-practices/rules/async-api-routes.md",
    "chars": 1124,
    "preview": "---\ntitle: Prevent Waterfall Chains in API Routes\nimpact: CRITICAL\nimpactDescription: 2-10× improvement\ntags: api-routes"
  },
  {
    "path": ".agents/skills/vercel-react-best-practices/rules/async-defer-await.md",
    "chars": 2028,
    "preview": "---\ntitle: Defer Await Until Needed\nimpact: HIGH\nimpactDescription: avoids blocking unused code paths\ntags: async, await"
  },
  {
    "path": ".agents/skills/vercel-react-best-practices/rules/async-dependencies.md",
    "chars": 1292,
    "preview": "---\ntitle: Dependency-Based Parallelization\nimpact: CRITICAL\nimpactDescription: 2-10× improvement\ntags: async, paralleli"
  },
  {
    "path": ".agents/skills/vercel-react-best-practices/rules/async-parallel.md",
    "chars": 653,
    "preview": "---\ntitle: Promise.all() for Independent Operations\nimpact: CRITICAL\nimpactDescription: 2-10× improvement\ntags: async, p"
  },
  {
    "path": ".agents/skills/vercel-react-best-practices/rules/async-suspense-boundaries.md",
    "chars": 2508,
    "preview": "---\ntitle: Strategic Suspense Boundaries\nimpact: HIGH\nimpactDescription: faster initial paint\ntags: async, suspense, str"
  },
  {
    "path": ".agents/skills/vercel-react-best-practices/rules/bundle-barrel-imports.md",
    "chars": 2370,
    "preview": "---\ntitle: Avoid Barrel File Imports\nimpact: CRITICAL\nimpactDescription: 200-800ms import cost, slow builds\ntags: bundle"
  },
  {
    "path": ".agents/skills/vercel-react-best-practices/rules/bundle-conditional.md",
    "chars": 949,
    "preview": "---\ntitle: Conditional Module Loading\nimpact: HIGH\nimpactDescription: loads large data only when needed\ntags: bundle, co"
  },
  {
    "path": ".agents/skills/vercel-react-best-practices/rules/bundle-defer-third-party.md",
    "chars": 920,
    "preview": "---\ntitle: Defer Non-Critical Third-Party Libraries\nimpact: MEDIUM\nimpactDescription: loads after hydration\ntags: bundle"
  },
  {
    "path": ".agents/skills/vercel-react-best-practices/rules/bundle-dynamic-imports.md",
    "chars": 791,
    "preview": "---\ntitle: Dynamic Imports for Heavy Components\nimpact: CRITICAL\nimpactDescription: directly affects TTI and LCP\ntags: b"
  },
  {
    "path": ".agents/skills/vercel-react-best-practices/rules/bundle-preload.md",
    "chars": 1149,
    "preview": "---\ntitle: Preload Based on User Intent\nimpact: MEDIUM\nimpactDescription: reduces perceived latency\ntags: bundle, preloa"
  },
  {
    "path": ".agents/skills/vercel-react-best-practices/rules/client-event-listeners.md",
    "chars": 1969,
    "preview": "---\ntitle: Deduplicate Global Event Listeners\nimpact: LOW\nimpactDescription: single listener for N components\ntags: clie"
  },
  {
    "path": ".agents/skills/vercel-react-best-practices/rules/client-localstorage-schema.md",
    "chars": 1950,
    "preview": "---\ntitle: Version and Minimize localStorage Data\nimpact: MEDIUM\nimpactDescription: prevents schema conflicts, reduces s"
  },
  {
    "path": ".agents/skills/vercel-react-best-practices/rules/client-passive-event-listeners.md",
    "chars": 1644,
    "preview": "---\ntitle: Use Passive Event Listeners for Scrolling Performance\nimpact: MEDIUM\nimpactDescription: eliminates scroll del"
  },
  {
    "path": ".agents/skills/vercel-react-best-practices/rules/client-swr-dedup.md",
    "chars": 1159,
    "preview": "---\ntitle: Use SWR for Automatic Deduplication\nimpact: MEDIUM-HIGH\nimpactDescription: automatic deduplication\ntags: clie"
  },
  {
    "path": ".agents/skills/vercel-react-best-practices/rules/js-batch-dom-css.md",
    "chars": 3266,
    "preview": "---\ntitle: Avoid Layout Thrashing\nimpact: MEDIUM\nimpactDescription: prevents forced synchronous layouts and reduces perf"
  },
  {
    "path": ".agents/skills/vercel-react-best-practices/rules/js-cache-function-results.md",
    "chars": 1949,
    "preview": "---\ntitle: Cache Repeated Function Calls\nimpact: MEDIUM\nimpactDescription: avoid redundant computation\ntags: javascript,"
  },
  {
    "path": ".agents/skills/vercel-react-best-practices/rules/js-cache-property-access.md",
    "chars": 531,
    "preview": "---\ntitle: Cache Property Access in Loops\nimpact: LOW-MEDIUM\nimpactDescription: reduces lookups\ntags: javascript, loops,"
  },
  {
    "path": ".agents/skills/vercel-react-best-practices/rules/js-cache-storage.md",
    "chars": 1651,
    "preview": "---\ntitle: Cache Storage API Calls\nimpact: LOW-MEDIUM\nimpactDescription: reduces expensive I/O\ntags: javascript, localSt"
  },
  {
    "path": ".agents/skills/vercel-react-best-practices/rules/js-combine-iterations.md",
    "chars": 753,
    "preview": "---\ntitle: Combine Multiple Array Iterations\nimpact: LOW-MEDIUM\nimpactDescription: reduces iterations\ntags: javascript, "
  },
  {
    "path": ".agents/skills/vercel-react-best-practices/rules/js-early-exit.md",
    "chars": 1133,
    "preview": "---\ntitle: Early Return from Functions\nimpact: LOW-MEDIUM\nimpactDescription: avoids unnecessary computation\ntags: javasc"
  },
  {
    "path": ".agents/skills/vercel-react-best-practices/rules/js-hoist-regexp.md",
    "chars": 1028,
    "preview": "---\ntitle: Hoist RegExp Creation\nimpact: LOW-MEDIUM\nimpactDescription: avoids recreation\ntags: javascript, regexp, optim"
  },
  {
    "path": ".agents/skills/vercel-react-best-practices/rules/js-index-maps.md",
    "chars": 834,
    "preview": "---\ntitle: Build Index Maps for Repeated Lookups\nimpact: LOW-MEDIUM\nimpactDescription: 1M ops to 2K ops\ntags: javascript"
  },
  {
    "path": ".agents/skills/vercel-react-best-practices/rules/js-length-check-first.md",
    "chars": 1747,
    "preview": "---\ntitle: Early Length Check for Array Comparisons\nimpact: MEDIUM-HIGH\nimpactDescription: avoids expensive operations w"
  },
  {
    "path": ".agents/skills/vercel-react-best-practices/rules/js-min-max-loop.md",
    "chars": 2290,
    "preview": "---\ntitle: Use Loop for Min/Max Instead of Sort\nimpact: LOW\nimpactDescription: O(n) instead of O(n log n)\ntags: javascri"
  },
  {
    "path": ".agents/skills/vercel-react-best-practices/rules/js-set-map-lookups.md",
    "chars": 532,
    "preview": "---\ntitle: Use Set/Map for O(1) Lookups\nimpact: LOW-MEDIUM\nimpactDescription: O(n) to O(1)\ntags: javascript, set, map, d"
  },
  {
    "path": ".agents/skills/vercel-react-best-practices/rules/js-tosorted-immutable.md",
    "chars": 1782,
    "preview": "---\ntitle: Use toSorted() Instead of sort() for Immutability\nimpact: MEDIUM-HIGH\nimpactDescription: prevents mutation bu"
  },
  {
    "path": ".agents/skills/vercel-react-best-practices/rules/rendering-activity.md",
    "chars": 564,
    "preview": "---\ntitle: Use Activity Component for Show/Hide\nimpact: MEDIUM\nimpactDescription: preserves state/DOM\ntags: rendering, a"
  },
  {
    "path": ".agents/skills/vercel-react-best-practices/rules/rendering-animate-svg-wrapper.md",
    "chars": 1185,
    "preview": "---\ntitle: Animate SVG Wrapper Instead of SVG Element\nimpact: LOW\nimpactDescription: enables hardware acceleration\ntags:"
  },
  {
    "path": ".agents/skills/vercel-react-best-practices/rules/rendering-conditional-render.md",
    "chars": 980,
    "preview": "---\ntitle: Use Explicit Conditional Rendering\nimpact: LOW\nimpactDescription: prevents rendering 0 or NaN\ntags: rendering"
  },
  {
    "path": ".agents/skills/vercel-react-best-practices/rules/rendering-content-visibility.md",
    "chars": 814,
    "preview": "---\ntitle: CSS content-visibility for Long Lists\nimpact: HIGH\nimpactDescription: faster initial render\ntags: rendering, "
  },
  {
    "path": ".agents/skills/vercel-react-best-practices/rules/rendering-hoist-jsx.md",
    "chars": 1039,
    "preview": "---\ntitle: Hoist Static JSX Elements\nimpact: LOW\nimpactDescription: avoids re-creation\ntags: rendering, jsx, static, opt"
  },
  {
    "path": ".agents/skills/vercel-react-best-practices/rules/rendering-hydration-no-flicker.md",
    "chars": 2308,
    "preview": "---\ntitle: Prevent Hydration Mismatch Without Flickering\nimpact: MEDIUM\nimpactDescription: avoids visual flicker and hyd"
  },
  {
    "path": ".agents/skills/vercel-react-best-practices/rules/rendering-hydration-suppress-warning.md",
    "chars": 870,
    "preview": "---\ntitle: Suppress Expected Hydration Mismatches\nimpact: LOW-MEDIUM\nimpactDescription: avoids noisy hydration warnings "
  },
  {
    "path": ".agents/skills/vercel-react-best-practices/rules/rendering-svg-precision.md",
    "chars": 588,
    "preview": "---\ntitle: Optimize SVG Precision\nimpact: LOW\nimpactDescription: reduces file size\ntags: rendering, svg, optimization, s"
  },
  {
    "path": ".agents/skills/vercel-react-best-practices/rules/rendering-usetransition-loading.md",
    "chars": 2074,
    "preview": "---\ntitle: Use useTransition Over Manual Loading States\nimpact: LOW\nimpactDescription: reduces re-renders and improves c"
  },
  {
    "path": ".agents/skills/vercel-react-best-practices/rules/rerender-defer-reads.md",
    "chars": 973,
    "preview": "---\ntitle: Defer State Reads to Usage Point\nimpact: MEDIUM\nimpactDescription: avoids unnecessary subscriptions\ntags: rer"
  },
  {
    "path": ".agents/skills/vercel-react-best-practices/rules/rerender-dependencies.md",
    "chars": 824,
    "preview": "---\ntitle: Narrow Effect Dependencies\nimpact: LOW\nimpactDescription: minimizes effect re-runs\ntags: rerender, useEffect,"
  },
  {
    "path": ".agents/skills/vercel-react-best-practices/rules/rerender-derived-state-no-effect.md",
    "chars": 1201,
    "preview": "---\ntitle: Calculate Derived State During Rendering\nimpact: MEDIUM\nimpactDescription: avoids redundant renders and state"
  },
  {
    "path": ".agents/skills/vercel-react-best-practices/rules/rerender-derived-state.md",
    "chars": 728,
    "preview": "---\ntitle: Subscribe to Derived State\nimpact: MEDIUM\nimpactDescription: reduces re-render frequency\ntags: rerender, deri"
  },
  {
    "path": ".agents/skills/vercel-react-best-practices/rules/rerender-functional-setstate.md",
    "chars": 2958,
    "preview": "---\ntitle: Use Functional setState Updates\nimpact: MEDIUM\nimpactDescription: prevents stale closures and unnecessary cal"
  },
  {
    "path": ".agents/skills/vercel-react-best-practices/rules/rerender-lazy-state-init.md",
    "chars": 2016,
    "preview": "---\ntitle: Use Lazy State Initialization\nimpact: MEDIUM\nimpactDescription: wasted computation on every render\ntags: reac"
  },
  {
    "path": ".agents/skills/vercel-react-best-practices/rules/rerender-memo-with-default-value.md",
    "chars": 1173,
    "preview": "---\n\ntitle: Extract Default Non-primitive Parameter Value from Memoized Component to Constant\nimpact: MEDIUM\nimpactDescr"
  },
  {
    "path": ".agents/skills/vercel-react-best-practices/rules/rerender-memo.md",
    "chars": 1148,
    "preview": "---\ntitle: Extract to Memoized Components\nimpact: MEDIUM\nimpactDescription: enables early returns\ntags: rerender, memo, "
  },
  {
    "path": ".agents/skills/vercel-react-best-practices/rules/rerender-move-effect-to-event.md",
    "chars": 1268,
    "preview": "---\ntitle: Put Interaction Logic in Event Handlers\nimpact: MEDIUM\nimpactDescription: avoids effect re-runs and duplicate"
  },
  {
    "path": ".agents/skills/vercel-react-best-practices/rules/rerender-simple-expression-in-memo.md",
    "chars": 1018,
    "preview": "---\ntitle: Do not wrap a simple expression with a primitive result type in useMemo\nimpact: LOW-MEDIUM\nimpactDescription:"
  },
  {
    "path": ".agents/skills/vercel-react-best-practices/rules/rerender-transitions.md",
    "chars": 1055,
    "preview": "---\ntitle: Use Transitions for Non-Urgent Updates\nimpact: MEDIUM\nimpactDescription: maintains UI responsiveness\ntags: re"
  },
  {
    "path": ".agents/skills/vercel-react-best-practices/rules/rerender-use-ref-transient-values.md",
    "chars": 1742,
    "preview": "---\ntitle: Use useRef for Transient Values\nimpact: MEDIUM\nimpactDescription: avoids unnecessary re-renders on frequent u"
  },
  {
    "path": ".agents/skills/vercel-react-best-practices/rules/server-after-nonblocking.md",
    "chars": 2012,
    "preview": "---\ntitle: Use after() for Non-Blocking Operations\nimpact: MEDIUM\nimpactDescription: faster response times\ntags: server,"
  },
  {
    "path": ".agents/skills/vercel-react-best-practices/rules/server-auth-actions.md",
    "chars": 2647,
    "preview": "---\ntitle: Authenticate Server Actions Like API Routes\nimpact: CRITICAL\nimpactDescription: prevents unauthorized access "
  },
  {
    "path": ".agents/skills/vercel-react-best-practices/rules/server-cache-lru.md",
    "chars": 1353,
    "preview": "---\ntitle: Cross-Request LRU Caching\nimpact: HIGH\nimpactDescription: caches across requests\ntags: server, cache, lru, cr"
  },
  {
    "path": ".agents/skills/vercel-react-best-practices/rules/server-cache-react.md",
    "chars": 2228,
    "preview": "---\ntitle: Per-Request Deduplication with React.cache()\nimpact: MEDIUM\nimpactDescription: deduplicates within request\nta"
  },
  {
    "path": ".agents/skills/vercel-react-best-practices/rules/server-dedup-props.md",
    "chars": 2053,
    "preview": "---\ntitle: Avoid Duplicate Serialization in RSC Props\nimpact: LOW\nimpactDescription: reduces network payload by avoiding"
  },
  {
    "path": ".agents/skills/vercel-react-best-practices/rules/server-parallel-fetching.md",
    "chars": 1554,
    "preview": "---\ntitle: Parallel Data Fetching with Component Composition\nimpact: CRITICAL\nimpactDescription: eliminates server-side "
  },
  {
    "path": ".agents/skills/vercel-react-best-practices/rules/server-serialization.md",
    "chars": 996,
    "preview": "---\ntitle: Minimize Serialization at RSC Boundaries\nimpact: HIGH\nimpactDescription: reduces data transfer size\ntags: ser"
  },
  {
    "path": ".agents/skills/web-design-guidelines/SKILL.md",
    "chars": 1231,
    "preview": "---\nname: web-design-guidelines\ndescription: Review UI code for Web Interface Guidelines compliance. Use when asked to \""
  },
  {
    "path": ".browserslistrc",
    "chars": 24,
    "preview": "last 2 versions\nie >= 9\n"
  },
  {
    "path": ".claude/docs/architecture.md",
    "chars": 1562,
    "preview": "# Architecture\n\n## Project Structure\n\n```\npackages/\n└── dinero.js/            # Single consolidated package\n    └── src/"
  },
  {
    "path": ".claude/docs/git-workflow.md",
    "chars": 386,
    "preview": "# Git Workflow\n\n## Branches\n\n- Always branch from `main` (unless doing a stacked PR, in which case branch from the targe"
  },
  {
    "path": ".claude/docs/linear.md",
    "chars": 353,
    "preview": "# Linear Integration\n\nThis project uses Linear for project management (project: **Dinero.js v2.0.0 Stable Release**).\n\nU"
  },
  {
    "path": ".claude/skills/commit/SKILL.md",
    "chars": 2666,
    "preview": "---\nname: commit\ndescription: Create a git commit with optional automatic Linear issue linking. Use when the user asks t"
  },
  {
    "path": ".editorconfig",
    "chars": 147,
    "preview": "root = true\n\n[*]\ncharset = utf-8\nindent_size = 2\nend_of_line = lf\nindent_style = space\ninsert_final_newline = true\ntrim_"
  },
  {
    "path": ".gitattributes",
    "chars": 39,
    "preview": "* text=auto\n\n*.png binary\n*.jpg binary\n"
  },
  {
    "path": ".github/CODEOWNERS",
    "chars": 12,
    "preview": "@sarahdayan\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/BUG.yml",
    "chars": 1788,
    "preview": "name: Bug Report\ndescription: File a bug report\ntitle: '[Bug]: '\nlabels: [bug]\nassignees:\n  - sarahdayan\nbody:\n  - type:"
  },
  {
    "path": ".github/semantic.yml",
    "chars": 179,
    "preview": "titleOnly: true\nallowMergeCommits: false\nallowRevertCommits: false\ntypes:\n  - feat\n  - fix\n  - docs\n  - style\n  - refact"
  },
  {
    "path": ".github/workflows/ci.yml",
    "chars": 2931,
    "preview": "name: CI\n\non:\n  pull_request:\n    branches: [main]\n\nconcurrency:\n  group: ${{ github.workflow }}-${{ github.ref }}\n  can"
  },
  {
    "path": ".github/workflows/release.yml",
    "chars": 4271,
    "preview": "name: Release\n\non:\n  push:\n    branches: [main]\n\nconcurrency:\n  group: ${{ github.workflow }}-${{ github.ref }}\n  cancel"
  },
  {
    "path": ".gitignore",
    "chars": 87,
    "preview": "node_modules\ncoverage\ndist\ntemp\n*.tsbuildinfo\n.DS_Store\n.env\n.turbo\n*/.vitepress/cache\n"
  },
  {
    "path": ".husky/pre-commit",
    "chars": 16,
    "preview": "npx lint-staged\n"
  },
  {
    "path": ".npmrc",
    "chars": 22,
    "preview": "legacy-peer-deps=true\n"
  },
  {
    "path": ".nvmrc",
    "chars": 3,
    "preview": "24\n"
  },
  {
    "path": ".oxlintrc.json",
    "chars": 837,
    "preview": "{\n  \"$schema\": \"./node_modules/oxlint/configuration_schema.json\",\n  \"plugins\": [\"import\", \"promise\", \"vitest\", \"typescri"
  },
  {
    "path": ".prettierignore",
    "chars": 50,
    "preview": "coverage\nnode_modules\ndist\nbuild\n**/*.md\n**/*.mdx\n"
  },
  {
    "path": ".prettierrc",
    "chars": 76,
    "preview": "{\n  \"proseWrap\": \"never\",\n  \"singleQuote\": true,\n  \"trailingComma\": \"es5\"\n}\n"
  },
  {
    "path": ".size-limit.json",
    "chars": 198,
    "preview": "[\n  {\n    \"path\": \"packages/dinero.js/dist/umd/index.production.js\",\n    \"limit\": \"4.5 KB\"\n  },\n  {\n    \"path\": \"package"
  },
  {
    "path": ".vscode/launch.json",
    "chars": 874,
    "preview": "{\n  \"version\": \"0.2.0\",\n  \"configurations\": [\n    {\n      \"type\": \"node\",\n      \"request\": \"launch\",\n      \"name\": \"Test"
  },
  {
    "path": ".vscode/settings.json",
    "chars": 88,
    "preview": "{\n  \"path-intellisense.mappings\": {\n    \"@dinero.js\": \"${workspaceRoot}/packages\"\n  }\n}\n"
  },
  {
    "path": "CHANGELOG.md",
    "chars": 18281,
    "preview": "## [2.0.2](https://github.com/dinerojs/dinero.js/compare/v2.0.1...v2.0.2) (2026-03-13)\n\n\n### Bug Fixes\n\n* **dinero.js:**"
  },
  {
    "path": "CLAUDE.md",
    "chars": 816,
    "preview": "# CLAUDE.md\n\nDinero.js: a JavaScript/TypeScript money library. npm workspaces + Turborepo monorepo.\n\n## Commands\n\n```bas"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "chars": 3344,
    "preview": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, w"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 4606,
    "preview": "<p align=\"center\">\n  <a href=\"https://dinerojs.com\">\n    <img alt=\"Dinero.js\" src=\".github/banner.png\">\n  </a>\n</p>\n\n# C"
  },
  {
    "path": "LICENSE",
    "chars": 1086,
    "preview": "The MIT License (MIT)\n\nCopyright (c) 2018-present Sarah Dayan\n\nPermission is hereby granted, free of charge, to any pers"
  },
  {
    "path": "README.md",
    "chars": 7807,
    "preview": "<p align=\"center\">\n  <a href=\"https://dinerojs.com\">\n    <img alt=\"Dinero.js\" src=\"https://raw.githubusercontent.com/din"
  },
  {
    "path": "docs/.vitepress/config.ts",
    "chars": 10897,
    "preview": "import { defineConfig } from 'vitepress';\nimport { version } from '../package.json';\n\nexport default defineConfig({\n  ti"
  },
  {
    "path": "docs/.vitepress/theme/HomeFeatures.vue",
    "chars": 1670,
    "preview": "<script setup lang=\"ts\">\nconst features = [\n  {\n    title: 'Immutable & safe',\n    details:\n      'All operations return"
  },
  {
    "path": "docs/.vitepress/theme/HomeHero.vue",
    "chars": 4499,
    "preview": "<script setup lang=\"ts\">\nimport { withBase } from 'vitepress';\n</script>\n\n<template>\n  <section class=\"home-hero\">\n    <"
  },
  {
    "path": "docs/.vitepress/theme/NotFound.vue",
    "chars": 1347,
    "preview": "<script setup>\nimport { useRouter } from 'vitepress';\n\nconst router = useRouter();\n\nfunction goHome() {\n  router.go('/')"
  },
  {
    "path": "docs/.vitepress/theme/index.ts",
    "chars": 527,
    "preview": "import { h } from 'vue';\nimport type { Theme } from 'vitepress';\nimport DefaultTheme from 'vitepress/theme';\nimport NotF"
  },
  {
    "path": "docs/.vitepress/theme/style.css",
    "chars": 6225,
    "preview": "/**\n * Dinero.js docs theme\n * Near-black dark mode, restrained color, subtle interactions.\n */\n\n/* Custom fonts */\n@imp"
  },
  {
    "path": "docs/about.md",
    "chars": 720,
    "preview": "---\ntitle: About\ndescription: Dinero.js is an open-source library by Sarah Dayan and contributors.\n---\n\n# About\n\nDinero."
  },
  {
    "path": "docs/agent-skills.md",
    "chars": 2269,
    "preview": "---\ntitle: Agent Skills\ndescription: Teach your AI coding agent Dinero.js best practices with installable skills.\n---\n\n#"
  },
  {
    "path": "docs/api/comparisons/compare.md",
    "chars": 2257,
    "preview": "---\ntitle: compare\ndescription: Compare the value of a Dinero object relative to another.\nreturns: number\n---\n\n# compare"
  },
  {
    "path": "docs/api/comparisons/equal.md",
    "chars": 1790,
    "preview": "---\ntitle: equal\ndescription: Check whether the value of a Dinero object is equal to another.\nreturns: boolean\n---\n\n# eq"
  },
  {
    "path": "docs/api/comparisons/greater-than-or-equal.md",
    "chars": 1680,
    "preview": "---\ntitle: greaterThanOrEqual\ndescription: Check whether the value of a Dinero object is greater than or equal another.\n"
  },
  {
    "path": "docs/api/comparisons/greater-than.md",
    "chars": 1334,
    "preview": "---\ntitle: greaterThan\ndescription: Check whether the value of a Dinero object is greater than another.\nreturns: boolean"
  },
  {
    "path": "docs/api/comparisons/has-sub-units.md",
    "chars": 1060,
    "preview": "---\ntitle: hasSubUnits\ndescription: Check whether a Dinero object has minor currency units.\nreturns: boolean\n---\n\n# hasS"
  },
  {
    "path": "docs/api/comparisons/have-same-amount.md",
    "chars": 1312,
    "preview": "---\ntitle: haveSameAmount\ndescription: Check whether a set of Dinero objects have the same amount.\nreturns: boolean\n---\n"
  },
  {
    "path": "docs/api/comparisons/have-same-currency.md",
    "chars": 1004,
    "preview": "---\ntitle: haveSameCurrency\ndescription: Check whether a set of Dinero objects have the same currency.\nreturns: boolean\n"
  },
  {
    "path": "docs/api/comparisons/is-negative.md",
    "chars": 966,
    "preview": "---\ntitle: isNegative\ndescription: Check whether a Dinero object is negative.\nreturns: boolean\n---\n\n# isNegative\n\nCheck "
  },
  {
    "path": "docs/api/comparisons/is-positive.md",
    "chars": 966,
    "preview": "---\ntitle: isPositive\ndescription: Check whether a Dinero object is positive.\nreturns: boolean\n---\n\n# isPositive\n\nCheck "
  },
  {
    "path": "docs/api/comparisons/is-zero.md",
    "chars": 751,
    "preview": "---\ntitle: isZero\ndescription: Check whether the value of a Dinero object is zero.\nreturns: boolean\n---\n\n# isZero\n\nCheck"
  },
  {
    "path": "docs/api/comparisons/less-than-or-equal.md",
    "chars": 1660,
    "preview": "---\ntitle: lessThanOrEqual\ndescription: Check whether the value of a Dinero object is lesser than or equal to another.\nr"
  },
  {
    "path": "docs/api/comparisons/less-than.md",
    "chars": 1314,
    "preview": "---\ntitle: lessThan\ndescription: Check whether the value of a Dinero object is lesser than another.\nreturns: boolean\n---"
  },
  {
    "path": "docs/api/comparisons/maximum.md",
    "chars": 1291,
    "preview": "---\ntitle: maximum\ndescription: Get the greatest of the passed Dinero objects.\nreturns: Dinero<TAmount, TCurrency>\n---\n\n"
  },
  {
    "path": "docs/api/comparisons/minimum.md",
    "chars": 1282,
    "preview": "---\ntitle: minimum\ndescription: Get the lowest of the passed Dinero objects.\nreturns: Dinero<TAmount, TCurrency>\n---\n\n# "
  },
  {
    "path": "docs/api/conversions/convert.md",
    "chars": 2670,
    "preview": "---\ntitle: convert\ndescription: Create a Dinero object converter.\nreturns: Dinero<TAmount, TNewCurrency>\n---\n\n# convert\n"
  },
  {
    "path": "docs/api/conversions/normalize-scale.md",
    "chars": 1122,
    "preview": "---\ntitle: normalizeScale\ndescription: Normalize a set of Dinero objects to the highest scale of the set.\nreturns: Diner"
  },
  {
    "path": "docs/api/conversions/transform-scale.md",
    "chars": 1765,
    "preview": "---\ntitle: transformScale\ndescription: Transform a Dinero object to a new scale.\nreturns: Dinero<TAmount, TCurrency>\n---"
  },
  {
    "path": "docs/api/conversions/trim-scale.md",
    "chars": 1019,
    "preview": "---\ntitle: trimScale\ndescription: Trim a Dinero object's scale as much as possible, down to the currency exponent.\nretur"
  },
  {
    "path": "docs/api/currencies.md",
    "chars": 7694,
    "preview": "---\ntitle: Currencies\ndescription: ISO 4217 currency objects available in dinero.js/currencies.\n---\n\n# Currencies\n\nDiner"
  },
  {
    "path": "docs/api/dinero.md",
    "chars": 1974,
    "preview": "---\ntitle: dinero\ndescription: Create a Dinero object.\nreturns: Dinero<TAmount, TCurrency>\n---\n\n# dinero\n\nCreate a Diner"
  },
  {
    "path": "docs/api/formatting/to-decimal.md",
    "chars": 1502,
    "preview": "---\ntitle: toDecimal\ndescription: Get the amount of a Dinero object in decimal format.\nreturns: TOutput = string\n---\n\n# "
  },
  {
    "path": "docs/api/formatting/to-snapshot.md",
    "chars": 892,
    "preview": "---\ntitle: toSnapshot\ndescription: Get a snapshot of a Dinero object.\nreturns: DineroSnapshot<TAmount, TCurrency>\n---\n\n#"
  },
  {
    "path": "docs/api/formatting/to-units.md",
    "chars": 2051,
    "preview": "---\ntitle: toUnits\ndescription: Get the amount of a Dinero object in units.\nreturns: TOutput = TAmount[]\n---\n\n# toUnits\n"
  },
  {
    "path": "docs/api/mutations/add.md",
    "chars": 1732,
    "preview": "---\ntitle: add\ndescription: Adding up two Dinero objects.\nreturns: Dinero<TAmount, TCurrency>\n---\n\n# add\n\nAdd up two Din"
  },
  {
    "path": "docs/api/mutations/allocate.md",
    "chars": 3072,
    "preview": "---\ntitle: allocate\ndescription: Distribute the amount of a Dinero object across a list of ratios.\nreturns: Dinero<TAmou"
  },
  {
    "path": "docs/api/mutations/multiply.md",
    "chars": 1235,
    "preview": "---\ntitle: multiply\ndescription: Multiply a Dinero object.\nreturns: Dinero<TAmount, TCurrency>\n---\n\n# multiply\n\nMultiply"
  },
  {
    "path": "docs/api/mutations/subtract.md",
    "chars": 1739,
    "preview": "---\ntitle: subtract\ndescription: Subtracting two Dinero objects.\nreturns: Dinero<TAmount, TCurrency>\n---\n\n# subtract\n\nSu"
  },
  {
    "path": "docs/api/rounding/down.md",
    "chars": 1261,
    "preview": "---\ntitle: down\ndescription: Divide and round towards negative infinity.\n---\n\n# down\n\nDivide and round towards negative "
  },
  {
    "path": "docs/api/rounding/half-away-from-zero.md",
    "chars": 1380,
    "preview": "---\ntitle: halfAwayFromZero\ndescription: Divide and round half away from zero.\n---\n\n# halfAwayFromZero\n\nDivide and round"
  },
  {
    "path": "docs/api/rounding/half-down.md",
    "chars": 1314,
    "preview": "---\ntitle: halfDown\ndescription: Divide and round half towards negative infinity.\n---\n\n# halfDown\n\nDivide and round towa"
  }
]

// ... and 373 more files (download for full content)

About this extraction

This page contains the full source code of the dinerojs/dinero.js GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 573 files (1.2 MB), approximately 349.9k tokens, and a symbol index with 653 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!