Full Code of ieedan/jsrepo for AI

main aa1753d4a043 cached
459 files
1.1 MB
340.7k tokens
877 symbols
1 requests
Download .txt
Showing preview only (1,220K chars total). Download the full file or copy to clipboard to get everything.
Repository: ieedan/jsrepo
Branch: main
Commit: aa1753d4a043
Files: 459
Total size: 1.1 MB

Directory structure:
gitextract__1f43wdr/

├── .changeset/
│   └── config.json
├── .github/
│   └── workflows/
│       ├── build-example-registries.yml
│       ├── bundle-analyze.yml
│       ├── ci.yml
│       ├── cli-preview.yml
│       ├── publish.yml
│       └── test-external-projects.yml
├── .gitignore
├── .vscode/
│   └── settings.json
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── apps/
│   └── docs/
│       ├── .gitignore
│       ├── README.md
│       ├── biome.json
│       ├── cli.json
│       ├── content/
│       │   └── docs/
│       │       ├── cli/
│       │       │   ├── add.mdx
│       │       │   ├── auth.mdx
│       │       │   ├── build.mdx
│       │       │   ├── config/
│       │       │   │   ├── language.mdx
│       │       │   │   ├── mcp.mdx
│       │       │   │   ├── meta.json
│       │       │   │   ├── provider.mdx
│       │       │   │   └── transform.mdx
│       │       │   ├── meta.json
│       │       │   ├── publish.mdx
│       │       │   └── update.mdx
│       │       ├── create-a-registry.mdx
│       │       ├── index.mdx
│       │       ├── jsrepo-com.mdx
│       │       ├── jsrepo-config.mdx
│       │       ├── languages/
│       │       │   ├── css.mdx
│       │       │   ├── html.mdx
│       │       │   ├── index.mdx
│       │       │   ├── js.mdx
│       │       │   ├── svelte.mdx
│       │       │   └── vue.mdx
│       │       ├── legacy.mdx
│       │       ├── mcp.mdx
│       │       ├── migrate.mdx
│       │       ├── outputs/
│       │       │   ├── distributed.mdx
│       │       │   ├── index.mdx
│       │       │   ├── repository.mdx
│       │       │   └── shadcn.mdx
│       │       ├── providers/
│       │       │   ├── azure.mdx
│       │       │   ├── bitbucket.mdx
│       │       │   ├── fs.mdx
│       │       │   ├── github.mdx
│       │       │   ├── gitlab.mdx
│       │       │   ├── http.mdx
│       │       │   ├── index.mdx
│       │       │   ├── jsrepo.mdx
│       │       │   └── shadcn.mdx
│       │       └── transforms/
│       │           ├── biome.mdx
│       │           ├── filecasing.mdx
│       │           ├── index.mdx
│       │           ├── javascript.mdx
│       │           ├── oxfmt.mdx
│       │           └── prettier.mdx
│       ├── instrumentation-client.js
│       ├── jsrepo.config.mts
│       ├── middleware.ts
│       ├── next.config.mjs
│       ├── og-image.d.ts
│       ├── package.json
│       ├── postcss.config.mjs
│       ├── source.config.ts
│       ├── src/
│       │   ├── app/
│       │   │   ├── (home)/
│       │   │   │   ├── code-block.tsx
│       │   │   │   ├── layout.tsx
│       │   │   │   ├── page.tsx
│       │   │   │   └── providers-section.tsx
│       │   │   ├── api/
│       │   │   │   └── search/
│       │   │   │       └── route.ts
│       │   │   ├── app-client.tsx
│       │   │   ├── docs/
│       │   │   │   ├── [[...slug]]/
│       │   │   │   │   └── page.tsx
│       │   │   │   └── layout.tsx
│       │   │   ├── global.css
│       │   │   ├── layout.tsx
│       │   │   ├── llms-full.txt/
│       │   │   │   └── route.ts
│       │   │   ├── llms.mdx/
│       │   │   │   └── [[...slug]]/
│       │   │   │       └── route.ts
│       │   │   ├── og/
│       │   │   │   ├── docs/
│       │   │   │   │   └── [...slug]/
│       │   │   │   │       └── route.tsx
│       │   │   │   └── route.tsx
│       │   │   └── robots.txt
│       │   ├── components/
│       │   │   ├── PrismaticBurst.tsx
│       │   │   ├── badges-table.tsx
│       │   │   ├── feature-tabs.tsx
│       │   │   ├── files.tsx
│       │   │   ├── language-toggle.tsx
│       │   │   ├── layout/
│       │   │   │   ├── home/
│       │   │   │   │   ├── client.tsx
│       │   │   │   │   └── index.tsx
│       │   │   │   └── shared/
│       │   │   │       ├── client.tsx
│       │   │   │       └── index.tsx
│       │   │   ├── logos/
│       │   │   │   ├── antigravity.tsx
│       │   │   │   ├── azure-devops.tsx
│       │   │   │   ├── biome.tsx
│       │   │   │   ├── bitbucket.tsx
│       │   │   │   ├── claude.tsx
│       │   │   │   ├── css.tsx
│       │   │   │   ├── cursor.tsx
│       │   │   │   ├── github.tsx
│       │   │   │   ├── gitlab.tsx
│       │   │   │   ├── html.tsx
│       │   │   │   ├── index.ts
│       │   │   │   ├── javascript.tsx
│       │   │   │   ├── jsrepo-com.tsx
│       │   │   │   ├── npm.tsx
│       │   │   │   ├── openai.tsx
│       │   │   │   ├── oxfmt.tsx
│       │   │   │   ├── prettier.tsx
│       │   │   │   ├── registry-kit.tsx
│       │   │   │   ├── shadcn.tsx
│       │   │   │   ├── svelte.tsx
│       │   │   │   ├── typescript.tsx
│       │   │   │   ├── vscode.tsx
│       │   │   │   └── vue.tsx
│       │   │   ├── navigation-menu.tsx
│       │   │   ├── page-actions.tsx
│       │   │   ├── registry-index.tsx
│       │   │   ├── registry-kit/
│       │   │   │   ├── demo-example.tsx
│       │   │   │   └── demo.tsx
│       │   │   ├── search-toggle.tsx
│       │   │   ├── sidebar.tsx
│       │   │   ├── theme-toggle.tsx
│       │   │   └── ui/
│       │   │       ├── accordion.tsx
│       │   │       ├── animated-beam.tsx
│       │   │       ├── badge.tsx
│       │   │       ├── button.tsx
│       │   │       ├── collapsible.tsx
│       │   │       ├── field.tsx
│       │   │       ├── github-button.tsx
│       │   │       ├── index.ts
│       │   │       ├── input-group.tsx
│       │   │       ├── input.tsx
│       │   │       ├── item.tsx
│       │   │       ├── label.tsx
│       │   │       ├── popover.tsx
│       │   │       ├── scroll-area.tsx
│       │   │       ├── separator.tsx
│       │   │       ├── sonner.tsx
│       │   │       ├── table.tsx
│       │   │       ├── tabs.tsx
│       │   │       ├── terminal.tsx
│       │   │       ├── textarea.tsx
│       │   │       ├── tooltip.tsx
│       │   │       └── underline-tabs.tsx
│       │   ├── hooks/
│       │   │   ├── use-copy-to-clipboard.tsx
│       │   │   └── use-scroll-to-top.tsx
│       │   ├── lib/
│       │   │   ├── cn.ts
│       │   │   ├── is-active.ts
│       │   │   ├── layout.shared.tsx
│       │   │   ├── og.ts
│       │   │   ├── source.ts
│       │   │   └── utils.ts
│       │   └── mdx-components.tsx
│       └── tsconfig.json
├── biome.json
├── examples/
│   ├── react/
│   │   ├── .gitignore
│   │   ├── README.md
│   │   ├── biome.json
│   │   ├── jsrepo.config.mts
│   │   ├── next.config.ts
│   │   ├── package.json
│   │   ├── postcss.config.mjs
│   │   ├── public/
│   │   │   └── r/
│   │   │       ├── button.json
│   │   │       ├── registry.json
│   │   │       ├── shadcn/
│   │   │       │   ├── button.json
│   │   │       │   ├── registry.json
│   │   │       │   └── utils.json
│   │   │       └── utils.json
│   │   ├── src/
│   │   │   ├── app/
│   │   │   │   ├── demos/
│   │   │   │   │   └── button-demo/
│   │   │   │   │       └── page.tsx
│   │   │   │   ├── globals.css
│   │   │   │   ├── layout.tsx
│   │   │   │   └── page.tsx
│   │   │   └── registry/
│   │   │       ├── lib/
│   │   │       │   └── utils.ts
│   │   │       └── ui/
│   │   │           └── button.tsx
│   │   └── tsconfig.json
│   └── svelte/
│       ├── .gitignore
│       ├── .npmrc
│       ├── README.md
│       ├── biome.json
│       ├── jsrepo.config.ts
│       ├── package.json
│       ├── src/
│       │   ├── app.css
│       │   ├── app.d.ts
│       │   ├── app.html
│       │   ├── lib/
│       │   │   └── registry/
│       │   │       ├── lib/
│       │   │       │   └── utils.ts
│       │   │       └── ui/
│       │   │           └── button/
│       │   │               ├── button.svelte
│       │   │               └── index.ts
│       │   └── routes/
│       │       ├── +layout.svelte
│       │       ├── +page.svelte
│       │       └── demos/
│       │           └── button-demo/
│       │               └── +page.svelte
│       ├── static/
│       │   ├── r/
│       │   │   ├── button.json
│       │   │   ├── registry.json
│       │   │   └── utils.json
│       │   └── robots.txt
│       ├── svelte.config.js
│       ├── tsconfig.json
│       └── vite.config.ts
├── package.json
├── packages/
│   ├── bun/
│   │   ├── CHANGELOG.md
│   │   ├── README.md
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── index.ts
│   │   │   └── workspace.ts
│   │   ├── tests/
│   │   │   ├── bun.test.ts
│   │   │   └── fixtures/
│   │   │       ├── bun-workspace/
│   │   │       │   ├── package.json
│   │   │       │   └── packages/
│   │   │       │       ├── bar/
│   │   │       │       │   └── package.json
│   │   │       │       └── foo/
│   │   │       │           └── package.json
│   │   │       └── bun-workspace-object/
│   │   │           ├── package.json
│   │   │           └── packages/
│   │   │               └── baz/
│   │   │                   └── package.json
│   │   ├── tsconfig.json
│   │   └── tsdown.config.ts
│   ├── jsrepo/
│   │   ├── CHANGELOG.md
│   │   ├── LICENSE
│   │   ├── README.md
│   │   ├── biome.json
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── api/
│   │   │   │   ├── config.ts
│   │   │   │   ├── errors.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── langs/
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── js.ts
│   │   │   │   ├── outputs.ts
│   │   │   │   ├── providers.ts
│   │   │   │   ├── utils.ts
│   │   │   │   └── warnings.ts
│   │   │   ├── bin.ts
│   │   │   ├── cli.ts
│   │   │   ├── commands/
│   │   │   │   ├── add.ts
│   │   │   │   ├── auth.ts
│   │   │   │   ├── build.ts
│   │   │   │   ├── config/
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── language.ts
│   │   │   │   │   ├── mcp.ts
│   │   │   │   │   ├── provider.ts
│   │   │   │   │   └── transform.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── init.ts
│   │   │   │   ├── publish.ts
│   │   │   │   ├── update.ts
│   │   │   │   └── utils.ts
│   │   │   ├── langs/
│   │   │   │   ├── css.ts
│   │   │   │   ├── html.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── js.ts
│   │   │   │   ├── svelte.ts
│   │   │   │   ├── types.ts
│   │   │   │   └── vue.ts
│   │   │   ├── outputs/
│   │   │   │   ├── distributed.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── repository.ts
│   │   │   │   └── types.ts
│   │   │   ├── providers/
│   │   │   │   ├── azure.ts
│   │   │   │   ├── bitbucket.ts
│   │   │   │   ├── fs.ts
│   │   │   │   ├── github.ts
│   │   │   │   ├── gitlab.ts
│   │   │   │   ├── http.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── jsrepo.ts
│   │   │   │   └── types.ts
│   │   │   └── utils/
│   │   │       ├── add.ts
│   │   │       ├── build.ts
│   │   │       ├── casing.ts
│   │   │       ├── compat/
│   │   │       │   └── shadcn.ts
│   │   │       ├── config/
│   │   │       │   ├── index.ts
│   │   │       │   ├── mods/
│   │   │       │   │   ├── add-plugins.ts
│   │   │       │   │   ├── add-registries.ts
│   │   │       │   │   └── update-paths.ts
│   │   │       │   └── utils.ts
│   │   │       ├── diff.ts
│   │   │       ├── env.ts
│   │   │       ├── errors.ts
│   │   │       ├── fs.ts
│   │   │       ├── glob.ts
│   │   │       ├── hooks.ts
│   │   │       ├── json.ts
│   │   │       ├── lines.ts
│   │   │       ├── package.ts
│   │   │       ├── pad.ts
│   │   │       ├── parse-package-name.ts
│   │   │       ├── path.ts
│   │   │       ├── persisted.ts
│   │   │       ├── prompts.ts
│   │   │       ├── roles.ts
│   │   │       ├── strings.ts
│   │   │       ├── token-manager.ts
│   │   │       ├── tsconfig.ts
│   │   │       ├── types.ts
│   │   │       ├── url.ts
│   │   │       ├── utils.ts
│   │   │       ├── validate-npm-package-name.ts
│   │   │       ├── warnings.ts
│   │   │       └── zod.ts
│   │   ├── tests/
│   │   │   ├── __mocks__/
│   │   │   │   ├── fs/
│   │   │   │   │   └── promises.cjs
│   │   │   │   └── fs.cjs
│   │   │   ├── build.test.ts
│   │   │   ├── config.test.ts
│   │   │   ├── fixtures/
│   │   │   │   ├── build/
│   │   │   │   │   ├── .npmignore
│   │   │   │   │   ├── .npmrc
│   │   │   │   │   ├── jsrepo.config.ts
│   │   │   │   │   ├── package.json
│   │   │   │   │   └── src/
│   │   │   │   │       ├── components/
│   │   │   │   │       │   └── ui/
│   │   │   │   │       │       ├── button.tsx
│   │   │   │   │       │       ├── counter.svelte
│   │   │   │   │       │       ├── empty/
│   │   │   │   │       │       │   ├── empty-content.svelte
│   │   │   │   │       │       │   ├── empty.svelte
│   │   │   │   │       │       │   └── index.ts
│   │   │   │   │       │       └── lanyard/
│   │   │   │   │       │           ├── Lanyard.tsx
│   │   │   │   │       │           └── card.glb
│   │   │   │   │       ├── routes/
│   │   │   │   │       │   ├── demo/
│   │   │   │   │       │   │   ├── +page.server.ts
│   │   │   │   │       │   │   └── +page.svelte
│   │   │   │   │       │   └── demos/
│   │   │   │   │       │       ├── button-default.tsx
│   │   │   │   │       │       ├── button-loading.tsx
│   │   │   │   │       │       └── subdir/
│   │   │   │   │       │           ├── button-subdir.tsx
│   │   │   │   │       │           └── nested/
│   │   │   │   │       │               └── button-nested.tsx
│   │   │   │   │       ├── utils/
│   │   │   │   │       │   ├── math/
│   │   │   │   │       │   │   ├── add.test.ts
│   │   │   │   │       │   │   ├── add.ts
│   │   │   │   │       │   │   ├── answer-format.test.ts
│   │   │   │   │       │   │   └── answer-format.ts
│   │   │   │   │       │   ├── shiki.ts
│   │   │   │   │       │   └── stdout.ts
│   │   │   │   │       └── utils.ts
│   │   │   │   ├── config/
│   │   │   │   │   ├── basic/
│   │   │   │   │   │   └── jsrepo.config.ts
│   │   │   │   │   ├── mts/
│   │   │   │   │   │   └── jsrepo.config.mts
│   │   │   │   │   └── nested/
│   │   │   │   │       └── jsrepo.config.ts
│   │   │   │   └── langs/
│   │   │   │       ├── js/
│   │   │   │       │   ├── logger.ts
│   │   │   │       │   ├── math/
│   │   │   │       │   │   ├── add.ts
│   │   │   │       │   │   └── subtract.ts
│   │   │   │       │   ├── print-answer.ts
│   │   │   │       │   └── stdout.ts
│   │   │   │       ├── js-arbitrary-extensions/
│   │   │   │       │   ├── component.svelte
│   │   │   │       │   ├── config.json
│   │   │   │       │   ├── index.ts
│   │   │   │       │   └── svelte-entry.ts
│   │   │   │       ├── js-baseurl-bare-imports/
│   │   │   │       │   ├── package.json
│   │   │   │       │   ├── tsconfig.json
│   │   │   │       │   └── types.ts
│   │   │   │       ├── js-subpath-imports/
│   │   │   │       │   ├── index.ts
│   │   │   │       │   ├── package.json
│   │   │   │       │   └── src/
│   │   │   │       │       ├── meta.ts
│   │   │   │       │       └── utils/
│   │   │   │       │           └── print.ts
│   │   │   │       └── svelte/
│   │   │   │           └── page.svelte
│   │   │   ├── langs/
│   │   │   │   ├── js.test.ts
│   │   │   │   └── svelte.test.ts
│   │   │   ├── providers/
│   │   │   │   ├── azure.test.ts
│   │   │   │   ├── bitbucket.test.ts
│   │   │   │   ├── fs.test.ts
│   │   │   │   ├── github.test.ts
│   │   │   │   ├── gitlab.test.ts
│   │   │   │   └── http.test.ts
│   │   │   └── utils/
│   │   │       ├── add-plugins-to-config.test.ts
│   │   │       ├── add-registries.test.ts
│   │   │       ├── add.test.ts
│   │   │       ├── casing.test.ts
│   │   │       ├── config-mcp.test.ts
│   │   │       ├── config-utils.test.ts
│   │   │       ├── env.test.ts
│   │   │       ├── package.test.ts
│   │   │       ├── parse-package-name.test.ts
│   │   │       ├── roles.test.ts
│   │   │       ├── update-paths.test.ts
│   │   │       └── zod.test.ts
│   │   ├── tsconfig.json
│   │   ├── tsdown.config.ts
│   │   └── vitest.config.ts
│   ├── mcp/
│   │   ├── CHANGELOG.md
│   │   ├── README.md
│   │   ├── biome.json
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── index.ts
│   │   │   ├── server.ts
│   │   │   └── utils.ts
│   │   ├── tests/
│   │   │   └── mcp.test.ts
│   │   ├── tsconfig.json
│   │   └── tsdown.config.ts
│   ├── migrate/
│   │   ├── CHANGELOG.md
│   │   ├── LICENSE
│   │   ├── README.md
│   │   ├── biome.json
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── bin.ts
│   │   │   ├── cli.ts
│   │   │   ├── commands/
│   │   │   │   ├── index.ts
│   │   │   │   ├── utils.ts
│   │   │   │   └── v3.ts
│   │   │   └── utils/
│   │   │       ├── errors.ts
│   │   │       ├── fs.ts
│   │   │       ├── json.ts
│   │   │       ├── package.ts
│   │   │       ├── parse-package-name.ts
│   │   │       ├── path.ts
│   │   │       ├── prompts.ts
│   │   │       ├── strings.ts
│   │   │       ├── types.ts
│   │   │       ├── v2/
│   │   │       │   └── config.ts
│   │   │       └── zod.ts
│   │   ├── tsconfig.json
│   │   └── tsdown.config.ts
│   ├── pnpm/
│   │   ├── CHANGELOG.md
│   │   ├── README.md
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── catalog.ts
│   │   │   ├── index.ts
│   │   │   └── workspace.ts
│   │   ├── tests/
│   │   │   ├── fixtures/
│   │   │   │   └── pnpm-workspace/
│   │   │   │       ├── packages/
│   │   │   │       │   ├── pkg-a/
│   │   │   │       │   │   └── package.json
│   │   │   │       │   ├── pkg-b/
│   │   │   │       │   │   └── package.json
│   │   │   │       │   └── pkg-c/
│   │   │   │       │       └── package.json
│   │   │   │       └── pnpm-workspace.yaml
│   │   │   └── pnpm.test.ts
│   │   ├── tsconfig.json
│   │   └── tsdown.config.ts
│   ├── shadcn/
│   │   ├── CHANGELOG.md
│   │   ├── README.md
│   │   ├── biome.json
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── index.ts
│   │   │   ├── output.ts
│   │   │   ├── provider.ts
│   │   │   └── utils.ts
│   │   ├── tsconfig.json
│   │   └── tsdown.config.ts
│   ├── transform-biome/
│   │   ├── CHANGELOG.md
│   │   ├── README.md
│   │   ├── biome.json
│   │   ├── package.json
│   │   ├── src/
│   │   │   └── index.ts
│   │   ├── tsconfig.json
│   │   └── tsdown.config.ts
│   ├── transform-filecasing/
│   │   ├── CHANGELOG.md
│   │   ├── README.md
│   │   ├── biome.json
│   │   ├── package.json
│   │   ├── src/
│   │   │   └── index.ts
│   │   ├── tests/
│   │   │   └── filecasing.test.ts
│   │   ├── tsconfig.json
│   │   └── tsdown.config.ts
│   ├── transform-javascript/
│   │   ├── CHANGELOG.md
│   │   ├── README.md
│   │   ├── biome.json
│   │   ├── package.json
│   │   ├── src/
│   │   │   └── index.ts
│   │   ├── tests/
│   │   │   └── strip-types.test.ts
│   │   ├── tsconfig.json
│   │   └── tsdown.config.ts
│   ├── transform-oxfmt/
│   │   ├── CHANGELOG.md
│   │   ├── README.md
│   │   ├── biome.json
│   │   ├── package.json
│   │   ├── src/
│   │   │   └── index.ts
│   │   ├── tsconfig.json
│   │   └── tsdown.config.ts
│   └── transform-prettier/
│       ├── CHANGELOG.md
│       ├── README.md
│       ├── biome.json
│       ├── package.json
│       ├── src/
│       │   └── index.ts
│       ├── tsconfig.json
│       └── tsdown.config.ts
├── pnpm-workspace.yaml
└── task.config.json

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

================================================
FILE: .changeset/config.json
================================================
{
	"$schema": "https://unpkg.com/@changesets/config@3.1.1/schema.json",
	"changelog": ["@svitejs/changesets-changelog-github-compact", { "repo": "jsrepojs/jsrepo" }],
	"commit": false,
	"fixed": [],
	"linked": [],
	"access": "public",
	"baseBranch": "main",
	"updateInternalDependencies": "patch",
	"ignore": ["@jsrepo/docs", "@example/react", "@example/svelte"],
	"prettier": false
}


================================================
FILE: .github/workflows/build-example-registries.yml
================================================
name: build-example-registries

on:
    pull_request:
        branches: [main]

jobs:
    build-example-registries:
        runs-on: ubuntu-latest

        steps:
            - uses: actions/checkout@v4
            - uses: pnpm/action-setup@v4
            - uses: actions/setup-node@v4
              with:
                  node-version: "20"
                  cache: pnpm

            - name: Install dependencies
              run: pnpm install

            - name: Build example registries
              run: pnpm build:example-registries

================================================
FILE: .github/workflows/bundle-analyze.yml
================================================
name: Bundle Analyze

on:
    pull_request:
        branches: [next, main]

jobs:
    bundle-analyze:
        runs-on: ubuntu-latest
        permissions:
            pull-requests: write

        steps:
            - uses: actions/checkout@v4
            - uses: pnpm/action-setup@v4
            - uses: actions/setup-node@v4
              with:
                  node-version: "20"
                  cache: pnpm

            - name: Install dependencies
              run: pnpm install

            - name: Build packages
              run: pnpm build:packages

            - name: Bundle Analyze
              run: |
                  pnpm bundle-analyze


================================================
FILE: .github/workflows/ci.yml
================================================
name: CI

on:
    pull_request:
        branches: [main]

jobs:
    CI:
        runs-on: ubuntu-latest

        steps:
            - uses: actions/checkout@v4
            - uses: pnpm/action-setup@v4
            - uses: actions/setup-node@v4
              with:
                  node-version: "20"
                  cache: pnpm

            - name: Install dependencies
              run: pnpm install

            - name: Check Types
              run: pnpm check

            - name: Test
              run: pnpm test

================================================
FILE: .github/workflows/cli-preview.yml
================================================
name: Package Previews
on:
    pull_request:
        branches: [main]
        paths:
            - 'pnpm-lock.yaml'
            - 'packages/**'

jobs:
  release-previews:
    runs-on: ubuntu-latest

    steps:
        - uses: actions/checkout@v4
        - uses: pnpm/action-setup@v4
        - uses: actions/setup-node@v4
          with:
              node-version: "20"
              cache: pnpm

        - name: Install dependencies
          run: pnpm install # packages automatically built on postinstall

        - name: publish preview
          run: pnpm pkg-pr-new publish --pnpm './packages/jsrepo' './packages/mcp' './packages/transform-prettier' './packages/transform-biome' './packages/transform-javascript' './packages/migrate' './packages/transform-oxfmt' './packages/transform-filecasing' --packageManager=pnpm


================================================
FILE: .github/workflows/publish.yml
================================================
name: Publish

on:
    push:
        branches:
            - main

concurrency: ${{ github.workflow }}-${{ github.ref }}

jobs:
    release:
        permissions:
            contents: write # to create release (changesets/action)
            pull-requests: write # to create pull request (changesets/action)
            id-token: write # Required for OIDC
        name: Build & Publish Release
        runs-on: ubuntu-latest

        steps:
            - uses: actions/checkout@v4
              with:
                # This makes Actions fetch all Git history so that Changesets can generate changelogs with the correct commits
                fetch-depth: 0
            - uses: pnpm/action-setup@v4
            - uses: actions/setup-node@v4
              with:
                node-version: 24
                cache: 'pnpm'

            - run: npm install -g npm@latest

            - name: Install dependencies
              run: pnpm install

            - name: Create Release Pull Request or Publish to npm
              id: changesets
              uses: changesets/action@v1
              with:
                commit: "chore(release): version package"
                title: "chore(release): version package"
                publish: pnpm ci:release
              env:
                GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
                NPM_CONFIG_PROVENANCE: true

================================================
FILE: .github/workflows/test-external-projects.yml
================================================
name: Test External Projects

on:
    pull_request:
        branches: [main]

jobs:
    test-external-projects:
        runs-on: ubuntu-latest
        strategy:
            matrix:
                project:
                    - name: shadcn-svelte-extras
                      repo: ieedan/shadcn-svelte-extras
                      pm: pnpm
                      build: pnpm registry:build
                    - name: react-bits
                      repo: DavidHDev/react-bits
                      pm: npm
                      build: npm run registry:build

        steps:
            - name: Checkout jsrepo
              uses: actions/checkout@v4

            - name: Setup pnpm
              uses: pnpm/action-setup@v4

            - name: Setup Node.js
              uses: actions/setup-node@v4
              with:
                  node-version: "20"
                  cache: pnpm

            - name: Install jsrepo dependencies
              run: pnpm install

            - name: Build jsrepo
              run: pnpm build:packages

            - name: Pack jsrepo
              id: pack
              run: |
                  cd packages/jsrepo && pnpm pack
                  TARBALL="$(ls jsrepo-*.tgz)"
                  echo "tarball_path=${{ github.workspace }}/packages/jsrepo/$TARBALL" >> $GITHUB_OUTPUT

            - name: Clone ${{ matrix.project.name }}
              uses: actions/checkout@v4
              with:
                  repository: ${{ matrix.project.repo }}
                  path: external-project

            - name: Cache ${{ matrix.project.name }} dependencies
              uses: actions/cache@v4
              with:
                  path: external-project/node_modules
                  key: ${{ matrix.project.name }}-deps-${{ hashFiles('external-project/package-lock.json', 'external-project/pnpm-lock.yaml') }}

            - name: Install local jsrepo in ${{ matrix.project.name }}
              working-directory: external-project
              env:
                  TARBALL: ${{ steps.pack.outputs.tarball_path }}
              run: |
                  if [ "${{ matrix.project.pm }}" = "pnpm" ]; then
                      pnpm add "jsrepo@file:$TARBALL"
                  else
                      npm install "jsrepo@file:$TARBALL"
                  fi

            - name: Build ${{ matrix.project.name }} registry
              working-directory: external-project
              run: ${{ matrix.project.build }}


================================================
FILE: .gitignore
================================================
node_modules

# out
dist

# testing
temp-test
**/tests/fixtures/**/node_modules
**/tests/fixtures/**/package-lock.json
**/tests/fixtures/**/pnpm-lock.yaml

.DS_Store
# ralphex progress logs
progress*.txt


================================================
FILE: .vscode/settings.json
================================================
{
	"cSpell.words": ["fuzzysort", "onwarn", "packlist"]
}


================================================
FILE: CONTRIBUTING.md
================================================
# Contributing to jsrepo

Looking to contribute to jsrepo? Great! You're in the right place. This guide will help you get started.

## AI Assistance Notice

> [!IMPORTANT]
>
> If you are using **any kind of AI assistance** to contribute to jsrepo,
> it must be disclosed in the pull request.

If you are using any kind of AI assistance while contributing to jsrepo,
**this must be disclosed in the pull request**, along with the extent to
which AI assistance was used (e.g. docs only vs. code generation).
If PR responses are being generated by an AI, disclose that as well.
As a small exception, trivial tab-completion doesn't need to be disclosed,
so long as it is limited to single keywords or short phrases.

An example disclosure:

> This PR was written primarily by Claude Code.

Or a more detailed disclosure:

> I consulted ChatGPT to understand the codebase but the solution
> was fully authored manually by myself.

Failure to disclose this is first and foremost rude to the human operators
on the other end of the pull request, but it also makes it difficult to
determine how much scrutiny to apply to the contribution.

When using AI assistance, we expect contributors to understand the code
that is produced and be able to answer critical questions about it. It
isn't a maintainers job to review a PR so broken that it requires
significant rework to be acceptable.

Please be respectful to maintainers and disclose AI assistance.

## Development

First install dependencies:

```sh
pnpm install
```

Then run the dev script:

```sh
pnpm dev
```

This will start the development server and watch for changes to packages.

The docs are available at [http://localhost:3000](http://localhost:3000).

To run the tests, run the following command:

```sh
pnpm test
```

To test jsrepo manually you can use the playground projects in the [`playground/`](./playground/) directory.

### Project Structure

- `packages/jsrepo` - jsrepo CLI
- `packages/mcp` - MCP server for jsrepo
- `playground/` - Playground projects to manually test jsrepo
- `apps/docs` - Contains the documentation hosted at [https://jsrepo.dev](https://jsrepo.dev).

## Before opening a PR

### Open an issue

If your PR is more than a one line fix please open an issue first to discuss the changes you want to make.

### Checklist

- Run `pnpm format`
- Run `pnpm lint` (Ensure passing)
- Run `pnpm check` (Ensure passing)
- Run `pnpm test` (Ensure passing)
- Run `pnpm changeset` and add a changeset for your changes if it effects any of the released packages (under packages/*)

================================================
FILE: LICENSE
================================================
MIT License

Copyright (c) 2025 jsrepo

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: README.md
================================================
<img width="100%" alt="CleanShot 2025-11-24 at 09 35 57" src="https://github.com/user-attachments/assets/61899098-fbc9-4263-972f-aacdfe0976de" />

[![npm version](https://flat.badgen.net/npm/v/jsrepo?color=yellow)](https://npmjs.com/package/jsrepo)
[![npm downloads](https://flat.badgen.net/npm/dm/jsrepo?color=yellow)](https://npmjs.com/package/jsrepo)

# jsrepo 

The modern registry toolchain. Distribute your code in any language anywhere with one CLI. 

## Get Started

```sh
npx jsrepo init
```


================================================
FILE: apps/docs/.gitignore
================================================
# deps
/node_modules

# generated content
.contentlayer
.content-collections
.source

# test & build
/coverage
/.next/
/out/
/build
*.tsbuildinfo

# misc
.DS_Store
*.pem
/.pnp
.pnp.js
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# others
.env*.local
.vercel
next-env.d.ts

public/registry-kit


================================================
FILE: apps/docs/README.md
================================================
# docs

This is a Next.js application generated with
[Create Fumadocs](https://github.com/fuma-nama/fumadocs).

Run development server:

```bash
npm run dev
# or
pnpm dev
# or
yarn dev
```

Open http://localhost:3000 with your browser to see the result.

## Explore

In the project, you can see:

- `lib/source.ts`: Code for content source adapter, [`loader()`](https://fumadocs.dev/docs/headless/source-api) provides the interface to access your content.
- `lib/layout.shared.tsx`: Shared options for layouts, optional but preferred to keep.

| Route                     | Description                                            |
| ------------------------- | ------------------------------------------------------ |
| `app/(home)`              | The route group for your landing page and other pages. |
| `app/docs`                | The documentation layout and pages.                    |
| `app/api/search/route.ts` | The Route Handler for search.                          |

### Fumadocs MDX

A `source.config.ts` config file has been included, you can customise different options like frontmatter schema.

Read the [Introduction](https://fumadocs.dev/docs/mdx) for further details.

## Learn More

To learn more about Next.js and Fumadocs, take a look at the following
resources:

- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js
  features and API.
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
- [Fumadocs](https://fumadocs.dev) - learn about Fumadocs


================================================
FILE: apps/docs/biome.json
================================================
{
	"root": false,
	"extends": "//",
	"files": {
		"includes": []
	}
}


================================================
FILE: apps/docs/cli.json
================================================
{
  "aliases": {
    "uiDir": "./components/ui",
    "componentsDir": "./components",
    "blockDir": "./components",
    "cssDir": "./styles",
    "libDir": "./lib"
  },
  "baseDir": "src",
  "commands": {}
}

================================================
FILE: apps/docs/content/docs/cli/add.mdx
================================================
---
title: add
description: Add items from registries to your project.
---

```sh
jsrepo add
```

## Usage

Add an item from the registries in your `jsrepo.config` file:

```sh
jsrepo add button
```

If the item exists in multiple registries you will be prompted to select which one you want to add:

```
◆  Multiple registries contain button. Please select one:
│  ● button (@ieedan/shadcn-svelte-extras)
│  ○ button (@ai/elements)
└
```

Add an item from a specific registry:

```sh
jsrepo add @ieedan/shadcn-svelte-extras/button
```

Add all items from a specific registry:

```sh
jsrepo add @ieedan/shadcn-svelte-extras --all
```

Add all items from every registry in your `jsrepo.config` file:

```sh
jsrepo add --all
```

## Options

### `--all`

Add all items from every registry:

```sh
jsrepo add --all
```

### `--cwd`

The current working directory:

```sh
jsrepo add button --cwd ./my-project
```

### `--expand`

Expands the diff so you see the entire file:

```sh
jsrepo add button --expand
```

### `--max-unchanged`

Maximum unchanged lines that will show without being collapsed:

```sh
jsrepo add button --max-unchanged 20
```

### `--overwrite`

Overwrite files without prompting:

```sh
jsrepo add button --overwrite
```

### `--registry`

The registry to add items from:

```sh
jsrepo add button --registry @ieedan/shadcn-svelte-extras
```

### `--verbose`

Include debug logs:

```sh
jsrepo add button --verbose
```

### `--with`

Include files with the given roles:

```sh
jsrepo add --with example test storybook
```

### `--with-docs` (Deprecated)

Use `--with doc`:

```sh
jsrepo add --with-docs
```

### `--with-examples` (Deprecated)

Use `--with example`:

```sh
jsrepo add --with-examples
```

### `--with-tests` (Deprecated)

Use `--with test`:

```sh
jsrepo add --with-tests
```

### `--yes`

Skip the confirmation prompt:

```sh
jsrepo add button --yes
```


================================================
FILE: apps/docs/content/docs/cli/auth.mdx
================================================
---
title: auth
description: Authenticate to a provider or registry.
---

```sh
jsrepo auth
```

## Usage

Authenticate to a provider. You will be prompted to select a provider if multiple are available:

```sh
jsrepo auth
```

Authenticate to a specific provider:

```sh
jsrepo auth github
```

If the provider requires registry-specific authentication, you will be prompted to select a registry:

```
◆  Select a registry to authenticate to.
│  ● @ieedan/shadcn-svelte-extras
│  ○ @ai/elements
│  ○ Other
└
```

Logout from a provider:

```sh
jsrepo auth github --logout
```

If the provider uses registry-specific tokens, you will be prompted to select which registry to logout from:

```
◆  Select a registry to logout of.
│  ● @ieedan/shadcn-svelte-extras
│  ○ @ai/elements
└
```

Authenticate using a token directly:

```sh
jsrepo auth github --token <your-token>
```

Authenticate non-interactively for a specific registry:

```sh
jsrepo auth --registry https://private-registry.example.com --token <your-token>
```

## Options

### `--cwd`

The current working directory:

```sh
jsrepo auth --cwd ./my-project
```

### `--logout`

Execute the logout flow:

```sh
jsrepo auth github --logout
```

### `--registry`

The registry to authenticate to. This is especially useful in non-interactive environments where prompts are unavailable:

```sh
jsrepo auth --registry https://private-registry.example.com --token <your-token>
```

### `--token`

The token to use for authenticating to this provider:

```sh
jsrepo auth github --token <your-token>
```

### `--verbose`

Include debug logs:

```sh
jsrepo auth github --verbose
```



================================================
FILE: apps/docs/content/docs/cli/build.mdx
================================================
---
title: build
description: Build your registry.
---

```sh
jsrepo build
```

## Usage

Build all blocks from the registries in your `jsrepo.config` file:

```sh
jsrepo build
```

Build blocks and watch for changes:

```sh
jsrepo build --watch
```

## Options

### `--cwd`

The current working directory:

```sh
jsrepo build --cwd ./my-project
```

### `--debounce`, `-d`

How long to wait before building again after a change is detected (watch mode only):

```sh
jsrepo build --watch --debounce 200
```

### `--watch`, `-w`

Watch for changes and rebuild automatically:

```sh
jsrepo build --watch
```



================================================
FILE: apps/docs/content/docs/cli/config/language.mdx
================================================
---
title: language
description: Add a language to your config.
---

```sh
jsrepo config language
```

## Usage

Add a language to your config. You will be prompted to install dependencies after adding:

```sh
jsrepo config language jsrepo-language-go
```

Add multiple languages at once:

```sh
jsrepo config language jsrepo-language-go jsrepo-language-rust
```

## Options

### `--cwd`

The current working directory:

```sh
jsrepo config language jsrepo-language-go --cwd ./my-project
```

### `--yes`

Skip the confirmation prompt:

```sh
jsrepo config language jsrepo-language-go --yes
```



================================================
FILE: apps/docs/content/docs/cli/config/mcp.mdx
================================================
---
title: mcp
description: Configure the jsrepo MCP server for your environment.
---

```sh
jsrepo config mcp
```

## Usage

Configure the jsrepo MCP server. You will be prompted to select which clients to configure:

```sh
jsrepo config mcp
```

You will be prompted to select which clients you want to configure:

```
◆  Which clients would you like to configure?
│  ■ Cursor
│  □ Claude Code
│  □ VS Code
│  □ Codex
└
```

Configure a specific client:

```sh
jsrepo config mcp --client cursor
```

Configure multiple clients:

```sh
jsrepo config mcp --client cursor vscode
```

Configure all supported MCP clients:

```sh
jsrepo config mcp --all
```

## Options

### `--all`

Configure all supported MCP clients:

```sh
jsrepo config mcp --all
```

### `--client`

The MCP client(s) to configure. Supported clients: `cursor`, `claude`, `vscode`, `codex`:

```sh
jsrepo config mcp --client cursor
```

Configure multiple clients:

```sh
jsrepo config mcp --client cursor vscode
```

### `--cwd`

The current working directory:

```sh
jsrepo config mcp --cwd ./my-project
```



================================================
FILE: apps/docs/content/docs/cli/config/meta.json
================================================
{
  "title": "config"
}



================================================
FILE: apps/docs/content/docs/cli/config/provider.mdx
================================================
---
title: provider
description: Add a provider to your config.
---

```sh
jsrepo config provider
```

## Usage

Add a provider to your config. You will be prompted to install dependencies after adding:

```sh
jsrepo config provider jsrepo-provider-jsr
```

Add multiple providers at once:

```sh
jsrepo config provider jsrepo-provider-jsr jsrepo-provider-npm
```

## Options

### `--cwd`

The current working directory:

```sh
jsrepo config provider jsrepo-provider-jsr --cwd ./my-project
```

### `--yes`

Skip the confirmation prompt:

```sh
jsrepo config provider jsrepo-provider-jsr --yes
```



================================================
FILE: apps/docs/content/docs/cli/config/transform.mdx
================================================
---
title: transform
description: Add a transform to your config.
---

```sh
jsrepo config transform
```

## Usage

Add a transform to your config. You will be prompted to install dependencies after adding:

```sh
jsrepo config transform @jsrepo/transform-prettier
```

Add multiple transforms at once:

```sh
jsrepo config transform @jsrepo/transform-prettier @jsrepo/transform-biome
```

## Options

### `--cwd`

The current working directory:

```sh
jsrepo config transform @jsrepo/transform-prettier --cwd ./my-project
```

### `--yes`

Skip the confirmation prompt:

```sh
jsrepo config transform @jsrepo/transform-prettier --yes
```



================================================
FILE: apps/docs/content/docs/cli/meta.json
================================================
{
  "title": "CLI"
}



================================================
FILE: apps/docs/content/docs/cli/publish.mdx
================================================
---
title: publish
description: Publish your registry to jsrepo.com.
---

```sh
jsrepo publish
```

## Usage

Publish all registries in your `jsrepo.config` file:

```sh
jsrepo publish
```

Publish a specific registry:

```sh
jsrepo publish @jsrepo/playground
```

Publish in dry run mode:

```sh
jsrepo publish --dry-run
```

## Options

### `--cwd`

The current working directory:

```sh
jsrepo build --cwd ./my-project
```

### `--dry-run`

Publish in dry run mode. This will check with jsrepo.com to see if the registry can be published in it's current state:

```sh
jsrepo publish --dry-run
```

### `--verbose`

Include debug logs:

```sh
jsrepo publish --verbose
```

================================================
FILE: apps/docs/content/docs/cli/update.mdx
================================================
---
title: update
description: Update items in your project.
---

```sh
jsrepo update
```

## Usage

Update an item in your project:

```sh
jsrepo update button
```

Select which items from your project that you want to update:

```sh
jsrepo update
```

```
◆  Which items would you like to update?
│  ■ button
│  □ math
│  □ logger
└
```

Update an item from a specific registry:

```sh
jsrepo update @ieedan/shadcn-svelte-extras/button
```

Update all items in your project:

```sh
jsrepo update --all
```

## Options

### `--all`

Update all items in your project:

```sh
jsrepo update --all
```

### `--cwd`

The current working directory:

```sh
jsrepo update button --cwd ./my-project
```

### `--expand`

Expands the diff so you see the entire file:

```sh
jsrepo update button --expand
```

### `--max-unchanged`

Maximum unchanged lines that will show without being collapsed:

```sh
jsrepo update button --max-unchanged 20
```

### `--overwrite`

Overwrite files without prompting:

```sh
jsrepo update button --overwrite
```

### `--registry`

The registry to update items from:

```sh
jsrepo update button --registry @ieedan/shadcn-svelte-extras
```

### `--verbose`

Include debug logs:

```sh
jsrepo update button --verbose
```

### `--with`

Include files with the given roles:

```sh
jsrepo update --with example test storybook
```

### `--with-docs` (Deprecated)

Use `--with doc`:

```sh
jsrepo update --with-docs
```

### `--with-examples` (Deprecated)

Use `--with example`:

```sh
jsrepo update --with-examples
```

### `--with-tests` (Deprecated)

Use `--with test`:

```sh
jsrepo update --with-tests
```

### `--yes`

Skip the confirmation prompt:

```sh
jsrepo update button --yes
```


================================================
FILE: apps/docs/content/docs/create-a-registry.mdx
================================================
---
title: Create a registry
description: A complete guide to creating your own registry with jsrepo.
---

In this guide we will show you how to setup a registry with **jsrepo**.

## Creating a registry

To create a registry start by running:

```npm
npx jsrepo init
```

This will initialize a blank config in your project and install **jsrepo** as a dev dependency.

Before we continue let's create some items for our registry.

```ts tab="src/stdout.ts"
export function print(msg: string) {
    console.log(msg);
}
```

```ts tab="src/logger.ts"
import { print } from './stdout';
export function createLogger() {
    return {
        log: print,
    }
}
```

Next we can configure the registry with the `registry` key.

Let's start by giving the registry a name:

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";

export default defineConfig({
	registry: {
		name: 'my-first-registry', // [!code ++]
	},
});
```

Next let's add the items we just created to the registry:

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";

export default defineConfig({
	registry: {
        // ...
        items: [ // [!code ++]
            { // [!code ++]
                name: 'logger', // [!code ++]
                type: 'utils', // [!code ++]
                files: [ // [!code ++]
                    { // [!code ++]
                        path: 'src/logger.ts', // [!code ++]
                    }, // [!code ++]
                ] // [!code ++]
            }, // [!code ++]
            { // [!code ++]
                name: 'stdout', // [!code ++]
                type: 'utils', // [!code ++]
                add: 'when-needed', // [!code ++] this will prevent the item from being listed by the `add` command
                files: [ // [!code ++]
                    { // [!code ++]
                        path: 'src/stdout.ts', // [!code ++]
                    }, // [!code ++]
                ] // [!code ++]
            } // [!code ++]
        ], // [!code ++]
    }
});
```

For now we will use the `repository` output for our registry so let's add it to our config:

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";
import { repository } from "jsrepo/outputs"; // [!code ++]

export default defineConfig({
	registry: {
        // ...
		outputs: [repository()], // [!code ++]
	},
});
```

Now we can build our registry with the `jsrepo build` command:

```sh
jsrepo build
```

This will create a `registry.json` file at the root of our project that contains everything we need to start adding items from our registry to other projects.

### Testing the registry

To test our registry locally we can use the `fs` provider. Let's add it to our config:

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";
import { repository } from "jsrepo/outputs";
import { fs } from "jsrepo/providers"; // [!code ++]

export default defineConfig({
    // ...
	providers: [fs()], // [!code ++]
});
```

Now let's initialize our registry with the `jsrepo init` command:   

```sh
jsrepo init fs://./
```

This will add the registry to the `registries` key in our config file:

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";
import { repository } from "jsrepo/outputs";
import { fs } from "jsrepo/providers";

export default defineConfig({
	// ...
	registries: ["fs://./"], // [!code ++]
});
```

Now we can run `jsrepo add` to add an item to our project:

```sh
jsrepo add logger
```

## Deploying your registry

This is the end of the basic guide.

Now that you have a working registry you can deploy it wherever you want! Take a look at the [providers](/docs/providers) docs for the full list of hosting options. 

For more advanced usage you can continue reading below...

## Advanced Usage

Now that we have covered the basics of creating a registry we can start to explore some of the features that make **jsrepo** so powerful.

### Resolving Dependencies

**jsrepo** automatically resolves dependencies both to other items in the registry and to remote packages. This ensures that when building your registry it will work out of the box for end users.

#### Excluding dependencies

Many times you may not want certain dependencies to be installed with your registry items. For instance if you import `useState` from `react` you probably don't want to force users to install `react` with your registry.

For this you can use the `excludeDeps` key of your registry config.

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";

export default defineConfig({
	registry: {
        // ...
		excludeDeps: ["react"], // [!code ++]
	},
});
```

<Callout type="info">
    It's good practice to put your framework in the `excludeDeps` list whether that be `react`, `vue`, `svelte` etc.
</Callout>

#### Opting out of automatic dependency resolution

Occasionally you may want to opt out of automatic dependency resolution for a particular item or file.

To do this you can set the `dependencyResolution` key to `manual` on the item or on specific files within the item:

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";

export default defineConfig({
	registry: {
		items: [
			{
				// ...
				dependencyResolution: "manual", // [!code ++]
			}
		]
	},
});
```

#### Resolving `workspace:` and `catalog:` dependencies

By default `workspace:` and `catalog:` dependencies won't be handled by **jsrepo**, however if you are using `pnpm` or `bun` you can use the `@jsrepo/pnpm` or `@jsrepo/bun` packages to automatically resolve these dependencies.

pnpm:

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";
import { pnpm } from "@jsrepo/pnpm"; // [!code ++]

export default defineConfig({
    // ...
	build: {
		remoteDependencyResolver: pnpm(), // [!code ++]
	},
});
```

bun:

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";
import { bun } from "@jsrepo/bun"; // [!code ++]

export default defineConfig({
    // ...
	build: {
		remoteDependencyResolver: bun(), // [!code ++]
	},
});
```

Now when you build your registry the `workspace:` and `catalog:` dependencies will be resolved to concrete versions.

### Files

We showed you how to include files in the registry earlier by referencing them by their path but there's much more to know!

#### File types

Files can have any type that an item can. If you don't provide a type the file will simply inherit the type from the parent item.

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";

export default defineConfig({
	registry: {
		items: [
			{
				// ...
                files: [
                    {
                        path: "src/example.ts",
                        type: "utils", // [!code ++]
                    }
                ]
			}
		]
	}
});
```

#### File dependencies

Just like items you can set the `dependencyResolution` to `manual` and manually specify the dependencies of a file.

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";

export default defineConfig({
	registry: {
		items: [
			{
				// ...
                files: [
                    {
                        path: "src/example.ts",
                        dependencyResolution: "manual", // [!code ++]
                        dependencies: ["chalk"], // [!code ++]
                    }
                ]
			}
		]
	}
});
```

#### File roles

File roles classify files into different categories that can be optionally installed by the user. The built-in roles are:

- `file` - The default (always installed)
- `example` - An example file
- `doc` - A documentation file
- `test` - A test file
- Custom roles - Any other role you want to give files in your registry

By default only files with the `file` role are included.

Users can include files with specific roles using the `--with <role>` flag:

```sh
jsrepo add --with story doc
```

<Callout type="info">
    These files are also made available to LLMs when using the `@jsrepo/mcp` server.
</Callout>

You can specify the role of a file when you define it on an item:

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";

export default defineConfig({
	registry: {
        // ...
		items: [
			{
				// ...
				files: [
					{
						path: "src/example.ts",
						role: "example", // [!code ++]
					},
				],
			}
		]
	},
});
```

Files with any non-`file` role will only install their dependencies when the file is included.

For example if you have a file with `role: "test"` that depends on `vitest`. `vitest` will only be installed to the user's project when the user provides `--with test`.

Similarly if that same file was to depend on another item in the registry. Then that item will only be installed to the user's project when the test file is added.

This allows you to add **documentation**, **examples**, **tests**, or any other optional role to your registry without forcing the user to install them.

#### Folders

When using frameworks like **Svelte** you are forced to define *one component per file* which will require you to bundle all your files into a folder. In cases like this you need to be able to include folders in your registry.

Doing this is intuitive in **jsrepo**.

Let's take for example, this **Empty** component:

import { Files, Folder, File } from "@/components/files";

<Files>
	<Folder name="src" defaultOpen>
		<Folder name="components" defaultOpen>
			<Folder name="ui" defaultOpen>
				<Folder name="empty" defaultOpen>
					<File name="empty-content.svelte" />
					<File name="empty-description.svelte" />
					<File name="empty-header.svelte" />
					<File name="empty-media.svelte" />
					<File name="empty-title.svelte" />
                    <File name="empty.svelte" />
					<File name="index.ts" />
				</Folder>
			</Folder>
		</Folder>
	</Folder>
</Files>

We can simply reference the folder path and **jsrepo** will automatically include all the files in the folder:

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";

export default defineConfig({
	registry: {
		items: [
			{
				name: 'empty',
				type: 'ui',
				files: [
					{
						path: 'src/components/ui/empty', // [!code ++]
					},
				],
			},
		],
	},
});
```

All the files in the folder will be included in the registry automatically and when users add them they will be added together under the `empty` folder.

If you need to configure the files that are included in a folder you can use the `files` key on folder. This is also useful if you need to change properties like the `role` or `dependencyResolution` of a particular file.

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";

export default defineConfig({
	registry: {
		items: [
			{
				// ...
				files: [
					{
						path: 'src/components/ui/empty', // [!code ++]
                        files: [ // [!code ++]
                            { // [!code ++]
                                // file paths are relative to the parent folder path so this turns into `src/components/ui/empty/empty-content.svelte` // [!code ++]
                                path: 'empty-content.svelte', // [!code ++]
                                // you can also configure other properties like the `role` or `dependencyResolution` of a particular file. // [!code ++]
                                dependencyResolution: 'manual', // [!code ++]
                            }, // [!code ++]
                            { // [!code ++]
                                path: 'empty-description.svelte', // [!code ++]
                            }, // [!code ++]
                            { // [!code ++]
                                path: 'empty-header.svelte', // [!code ++]
                            }, // [!code ++]
                            { // [!code ++]
                                path: 'empty-media.svelte', // [!code ++]
                            }, // [!code ++]
                            { // [!code ++]
                                path: 'empty-title.svelte', // [!code ++]
                            }, // [!code ++]
                            { // [!code ++]
                                path: 'empty.svelte', // [!code ++]
                            }, // [!code ++]
                            { // [!code ++]
                                path: 'index.ts', // [!code ++]
                            }, // [!code ++]
                        ], // [!code ++]
					},
				],
			},
		],
	});
});
```

#### Glob patterns in file paths

You can also use glob patterns in file paths to include all files that match the pattern.

For example lets say I want to include all my demos for the button component as examples:

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";

export default defineConfig({
	registry: {
		items: [
			{
                name: 'button',
                type: 'ui',
				files: [
                    {
                        path: 'src/lib/components/button',
                    },
					{
						path: "src/lib/demos/button-*.svelte", // [!code ++]
                        role: 'example',
                        dependencyResolution: 'manual',
					},
				],
			},
		],
	});
});
```

This will match all files that match the pattern `button-*.svelte` in the `src/lib/demos` directory.

**Recursive glob patterns:**

Match files in subdirectories while preserving the directory structure:

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";

export default defineConfig({
	registry: {
		items: [
			{
                name: 'button',
                type: 'ui',
				files: [
                    {
                        path: 'src/lib/components/button',
                    },
					{
						path: "src/lib/demos/**/button-*.svelte", // [!code ++]
                        role: 'example',
                    },
				],
			},
		],
	});
});
```

This will match all files (including those in subdirectories) that match the pattern `button-*.svelte` while maintaining the directory structure.

For instance:

| Source Path | Path Relative to Item |
|-------------|----------------------|
| `src/lib/demos/button-default.svelte` | `button-default.svelte` |
| `src/lib/demos/variants/button-outlined.svelte` | `variants/button-outlined.svelte` |
| `src/lib/demos/variants/themes/button-dark.svelte` | `variants/themes/button-dark.svelte` |

### Configure when an item is added

We mentioned this briefly above but you can configure when an item is added in the user's project by setting the `add` key an item.

- `"on-init"` - Added on registry init or when it's needed by another item
- `"optionally-on-init"` - Users are prompted to add the item when initializing the registry
- `"when-needed"` - Not listed and only added when another item is added that depends on it
- `"when-added"` - Added when the user selects it to be added

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";

export default defineConfig({
	registry: {
		items: [
			{
				// ...
				add: "when-added", // [!code ++]
			}
		]
	},
});
```

### Configuring the user's project

There are a few common things you may want to automatically configure in the user's project when they first initialize your registry.

#### Default Paths

Default paths are just that, the default locations for which items types or specific items should be added to in the user's project.

You can configure the `defaultPaths` key of your registry config to configure the default paths for items or item types to be added to in the user's project.

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";

export default defineConfig({
	registry: {
        // ...
		defaultPaths: { // [!code ++]
			component: "src/components/ui", // [!code ++]
            // you can of course also configure a specific item by referencing it by `<type>/<name>` // [!code ++]
            "ui/button": "src/components/ui/button", // [!code ++]
		}, // [!code ++]
	},
});
```

#### Plugins

You can configure the `plugins` key to automatically install plugins to the user's project when they initialize your registry.

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";

export default defineConfig({
	registry: {
		plugins: {
            languages: [{ package: "jsrepo-language-go" }], // [!code ++]
            // by setting the optional key to true the user will be prompted to install the plugin if it is not already installed. // [!code ++]
			transforms: [{ package: "@jsrepo/transform-prettier", optional: true }], // [!code ++]
		},
	},
});
```

### Environment Variables

Sometimes your registry items may require environment variables to work.

For this you can define the `envVars` key of that particular item:

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";

export default defineConfig({
	registry: {
        // ...
        items: [
            // ...
            {
                // ...
                name: 'db',
                type: 'lib',
                files: [
                    {
                        path: 'src/db.ts',
                    }
                ],
                envVars: { // [!code ++]
                    DATABASE_URL: "https://example.com/database", // [!code ++]
                    DATABASE_SECRET_TOKEN: "", // [!code ++]
                }, // [!code ++]
            }
        ]
	},
});
```

Environment variables will be added to the users `.env.local` or `.env` file.

If you leave an environment variable blank the user will be prompted to add a value for it.

Values you configure here will ***never*** overwrite existing values in the user's env file.

### Distributing multiple registries

It's become common to distribute multiple registries to allow users to optionally use different variants of your registry for example JavaScript or TypeScript.

However until now there wasn't an easy way to do this.

**jsrepo** solves this by allowing you to define multiple registries in the same config:

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";

export default defineConfig({
	registry: [
        {
            name: '@my-registry/typescript',
            // ...
        },
        {
            name: '@my-registry/javascript',
            // ...
        }
    ]
});
```

You can then use the `outputs` api to define where each registry should be output to:

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";
import { distributed } from "jsrepo/outputs";

export default defineConfig({
	registry: [
        {
            name: '@my-registry/vanilla',
            outputs: [distributed({ dir: "./public/r/v" })], // [!code ++]
            // ...
        },
        {
            name: '@my-registry/tailwind',
            outputs: [distributed({ dir: "./public/r/tw" })], // [!code ++]
            // ...
        }
    ]
});
```

### Dynamically generating registries

You don't always want to have to manually define your entire registry in your config file.

AI has made this less cumbersome but it's still annoying to have a 1k LOC file just to define your registry.

In **jsrepo v2** we automatically generated your registry based on a bunch of complicated options and this wasn't the best experience.

In **jsrepo v3** we are giving the control back to you allowing you to write your own code to generate your registry.

To do this simply pass a function to the `registry` key that returns a registry config:

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";
// define your own custom function
import { getItems } from "./getItems";

export default defineConfig({
	registry: ({ cwd }) => {
        return {
            name: 'my-registry',
            items: getItems(cwd)
        }
    }
});
```

Oh and of course you can also pass an array of functions:

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";
// define your own custom function
import { getItems } from "./getItems";

export default defineConfig({
	registry: [
		({ cwd }) => {
			return {
				name: '@my-registry/typescript',
				items: getItems(path.join(cwd, 'src/registry/ts'))
			}
		},
        ({ cwd }) => {
			return {
				name: '@my-registry/javascript',
				items: getItems(path.join(cwd, 'src/registry/js'))
			}
		}
	]
});
```

<Callout type="info">
    Dynamically generated registries will still work with the `--watch` flag.
</Callout>

### Supporting JavaScript and TypeScript

Thanks to the **jsrepo** transforms API it's extremely straightforward to allow your users to choose between JavaScript and TypeScript when using your registry.

Users can simply initialize your registry with the `--js` flag to use JavaScript:

```sh
jsrepo init @example/registry --js
# or add the javascript plugin at any time
jsrepo config transform javascript
```

Or add the `@jsrepo/transform-javascript` transform to their config manually:

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";
import javascript from "@jsrepo/transform-javascript"; // [!code ++]

export default defineConfig({
	transforms: [javascript()], // [!code ++]
});
```

This will automatically strip the types from TypeScript files and rename them to JavaScript files. You can see the full documentation for the `@jsrepo/transform-javascript` transform [here](/docs/transforms/javascript).

<Callout type="warning">
    This only works for [erasable syntax](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-8.html#the---erasablesyntaxonly-option) if you are expecting for your users to use TypeScript ensure you are using the `--erasableSyntaxOnly` option when writing your TypeScript code.
</Callout>

### Depending on items from other registries

Often times you may want to depend on items from other registries. In `shadcn/ui` you would add the registry URL to the item you are dependent on.

**jsrepo** doesn't support this for a few reasons:

1. You may have made changes to the component in your project that are not tracked by the upstream registry. This can break the users code or cause it to function incorrectly.
2. It's possible that the author of the upstream registry may make changes to the component that break your code in users projects.

For this reason **jsrepo** doesn't support depending on items from other registries. The alternative is to simply copy the components from the upstream registry into your own registry and serve them from your own registry.

We recommend when you do this to follow a few best practices:

1. Credit the upstream registry in some way so users know where those items came from.
2. Ensure to set `add: "when-needed"` on items from external registries to prevent them from being listed by the `add` command.

### Modifying items in your registry before build

Sometimes you may want to modify the content of registry items before they are built to an output.

For example you may want to build multiple different types of your registry for each style you offer.

You can do this with the `build.transforms` option:

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";

export default defineConfig({
	build: {
		transforms: [
			{
				transform: async (content, opts) => {
					return { content: content.replaceAll('{{PROJECT_NAME}}', 'jsrepo') };
				},
			}
		],
	},
});
```

This will run the transform on the content of each file in your registry before it's added to the output. This way you can easily modify the content at build time without needing to write another registry to the filesystem.

================================================
FILE: apps/docs/content/docs/index.mdx
================================================
---
title: Introduction
description: Why we built jsrepo.
---

import Link from "next/link";

[shadcn/ui](https://ui.shadcn.com) proved that distributing code in a way that allows consumers to own the source is an extremely powerful pattern. Since then registries have become a common way to distribute reusable components.

As more and more registries start to emerge it became clear that there was a need for a more powerful toolchain to help manage and distribute these registries. That's where **jsrepo** comes in...

**jsrepo** is a toolchain for distributing your code. It gives powerful tools to both registry owners and consumers. 

**Registry owners...**
- Don't want to have to write their own CLI and build system to distribute their code
- Want to be able to test and verify that their registry will work for their users before they publish it
- Want to be able to host their registries privately without having to write their own hosting solution

**Registry consumers...**
- Want to quickly add items from a registry to their project and start using them without having to even look at the code
- Want to be able to easily update their items with visibility to what as changed
- Want to be able to install and manage code from multiple registries in a single project
- Want an easy way to authenticate to private registries

**jsrepo...**
- Provides a powerful CLI for building and distributing your registry
- Prevents you from publishing broken or unusable registries
- Provides provider adapters to allow you to host your registry publicly or privately anywhere you want
- Automatically resolves dependencies to other items so your items always come ready to use
- Provides an interactive update command to easily update your items with visibility to what as changed
- Allows you to authenticate to private registries with `jsrepo auth`

<Accordion type="single" collapsible>
	<AccordionItem value="q-1">
		<AccordionTrigger>Is this trying to replace npm?</AccordionTrigger>
		<AccordionContent className="flex flex-col gap-4 text-balance">
			No, **jsrepo** won't replace npm, but it's perfect for distributing code like leftPad that probably shouldn't
			be a package but also shouldn't have to be rewritten every time.
		</AccordionContent>
	</AccordionItem>
	<AccordionItem value="q-2">
		<AccordionTrigger>Is this shadcn compatible?</AccordionTrigger>
		<AccordionContent className="flex flex-col gap-4 text-balance">
			Yes **jsrepo** is fully shadcn compatible. You can add and update items from **shadcn** with zero configuration needed.
		</AccordionContent>
	</AccordionItem>
</Accordion>


================================================
FILE: apps/docs/content/docs/jsrepo-com.mdx
================================================
---
title: jsrepo.com
description: A registry for your registries.
---

import { BadgesTable } from "@/components/badges-table";

<BadgeGroup>
	<OfficialBadge />
</BadgeGroup>

[jsrepo.com](https://jsrepo.com) is a centralized source registry for registries. Much like npm is for packages, **jsrepo.com** is for registries.

Like npm, you publish your registry to [jsrepo.com](https://jsrepo.com) with the `jsrepo publish` command and then other developers can add your code to their projects with the `jsrepo add` command.

## The benefits of jsrepo.com

- Semver support - You can publish multiple versions of the same registry (including pre-release versions) just like you would on npm.
- Easy installation - You can add your registry to your project with the simple `@<scope>/<registry>` syntax.
- Private registries - You can easily publish private registries and share them with your team for free.
- Marketplace - You can monetize your registry by selling it on the marketplace.
- Discoverability - Your registry will be discoverable through the **jsrepo.com** website and the jsrepo mcp server.

## Publishing your registry

If you already have a registry that can be built with **jsrepo** then there are only a few steps to publishing it to **jsrepo.com**. If not then checkout the [create a registry](/docs/create-a-registry) guide to get started.

<Steps>

<Step>
    ### Create an account
    Go to [jsrepo.com](https://jsrepo.com) and create an account.
</Step>

<Step>
    ### Claim a scope
    Once you have an account navigate to `/account/scopes/new` to [claim a scope](https://www.jsrepo.com/account/scopes/new). 
    
    Scopes are used to group your registries together and are required to publish your registry.

    When users add your registry the scope will be the first part of the registry name: `@<scope>/<registry>`.
</Step>

<Step>
    ### Authenticate with jsrepo.com
    Run the following command to authenticate with jsrepo.com:

    ```sh
    jsrepo auth jsrepo
    ```

    You will be prompted to finish the sign in in your browser and then you will be authenticated.
</Step>

<Step>
    ### Prepare your registry
    Decide on a name for your registry and add it to your `jsrepo.config.ts` file:

    ```ts title="jsrepo.config.ts"
    import { defineConfig } from "jsrepo";

    export default defineConfig({
        registry: {
            name: "@my-scope/my-registry", // [!code ++]
            // ...
        },
    });
    ```

    Next you need to provide the version or your registry that will be published. If you want **jsrepo** to pull from the version in your `package.json` file just provide `package` as the version:

    ```ts title="jsrepo.config.ts"
    import { defineConfig } from "jsrepo";

    export default defineConfig({
        registry: {
            name: "@my-scope/my-registry",
            version: "1.0.0", // [!code ++]
            // or take the version from the `package.json` file
            version: "package", // [!code ++]
            // ...
        },
    });
    ```

    (Optional) Now is also a good time to add any other metadata you want to your registry:

    ```ts title="jsrepo.config.ts"
    import { defineConfig } from "jsrepo";

    export default defineConfig({
        registry: {
            name: "@my-scope/my-registry",
            description: "My first registry", // [!code ++]
            homepage: "https://my-registry.com", // [!code ++]
            repository: "https://github.com/my-scope/my-registry", // [!code ++]
            bugs: "https://github.com/my-scope/my-registry/issues", // [!code ++]
            authors: ["Aidan Bleser"], // [!code ++]
            tags: ["first-registry"], // [!code ++]
            // ...
        },
    });
    ```

    (Optional) By default your registry will be published as public so anyone can see and use it. You can change the access level to `"private"` or `"marketplace"` by setting the `access` property:

    ```ts title="jsrepo.config.ts"
    import { defineConfig } from "jsrepo";

    export default defineConfig({
        registry: {
            name: "@my-scope/my-registry",
            access: "private", // [!code ++]
        },
    });
    ```
</Step>

<Step>
    ### Publish your registry
    Run the following command to publish your registry:

    ```sh
    jsrepo publish
    ```
</Step>

<Step>
    ### Start adding items to your project
    Run the following command to add items to your project:

    ```sh
    jsrepo add --registry @my-scope/my-registry
    # or 
    jsrepo init @my-scope/my-registry
    ```
</Step>

</Steps>

## Badges

<BadgesTable
	badges={[
		{
			alt: 'jsrepo latest version',
			hrefTemplate: 'https://jsrepo.com/badges/{{registry}}'
		},
		{
			alt: 'jsrepo downloads weekly',
			hrefTemplate: 'https://jsrepo.com/badges/{{registry}}/dm'
		},
		{
			alt: 'jsrepo downloads monthly',
			hrefTemplate: 'https://jsrepo.com/badges/{{registry}}/dw'
		},
		{
			alt: 'jsrepo downloads yearly',
			hrefTemplate: 'https://jsrepo.com/badges/{{registry}}/dy'
		},
		{
			alt: 'jsrepo registry rating',
			hrefTemplate: 'https://jsrepo.com/badges/{{registry}}/rating'
		}
	]}
	defaultRegistry="@ieedan/std"
/>

================================================
FILE: apps/docs/content/docs/jsrepo-config.mdx
================================================
---
title: jsrepo.config
description: The configuration file for jsrepo.
---

The `jsrepo.config.(ts|js|mts|mjs)` file is used to configure **jsrepo** projects and registries.

Having a js based config allows you far more flexibility when configuring your project or registry allowing you to abstract out the reusable parts of your config.

## Creating a config

To create a new config in your project you can run the following command or copy the code below:

```sh
jsrepo init
```

This will initialize a blank config in your project.

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";

export default defineConfig({
	// configure where stuff comes from here
	registries: [],
	// configure where stuff goes here
	paths: {},
});
```

<Callout type="info">
	We default to `.mts` to prevent errors when you don't have `"type": "module"` in your `package.json`. But you can
	rename this to `.ts` if you prefer.
</Callout>

### Create with a registry

To create your config with a registry you can run the following command:

```sh
jsrepo init [registry]
```

Let's look at an example...

You might run:

```sh
jsrepo init https://example.com/registry
```

First you will be prompted to install any plugins specified by the registry author:

```plaintext
┌   jsrepo
│
◆  Would you like to add the @jsrepo/transform-prettier transform plugin?
│  ● Yes / ○ No
```

Next you can configure the paths for the items you want to add. (These are the types of the items you can add from the registry)

```plaintext
◆  Which paths would you like to configure?
│  ◻ block (Default: src/components)
│  ◻ component
│  ◻ lib
└
```

Once you have configured the paths any items that were specified by the registry author to add upon initialization will be added to your project. And the resulting config should look like this:

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";
import prettier from "@jsrepo/transform-prettier";

export default defineConfig({
	registries: ["https://example.com/registry"],
	transforms: [prettier()],
	paths: {
		block: "src/components",
		component: "src/components/ui",
		lib: "src/lib",
	},
});
```

## Adding plugins

Plugins are a big part of what makes jsrepo so powerful but having to manually add them to your config kinda sucks. So we've added a way to automatically install and add plugins to your config.

To add a plugin run the following command:

```sh
# add a transform plugin
jsrepo config transform @jsrepo/transform-prettier
# add a provider plugin
jsrepo config provider jsrepo-provider-<provider>
# add a language plugin
jsrepo config language jsrepo-language-<language>
```

This will automatically install the plugin and add it to your config:

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";
import prettier from "@jsrepo/transform-prettier"; // [!code ++]

export default defineConfig({
	registries: ["https://example.com/registry"],
	transforms: [prettier()], // [!code ++]
	paths: {
		block: "src/components",
		component: "src/components/ui",
		lib: "src/lib",
	},
});
```

As your config grows this will continue to work (so long as you don't use some really contrived syntax for your config).

## Options

### languages

Languages are how **jsrepo** knows how to parse and transform code. You can read more about the supported languages [here](/docs/languages).

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";
import { js } from "jsrepo/languages";

export default defineConfig({
	languages: [js()], // [!code highlight]
});
```

### paths

Paths are how **jsrepo** knows where to put items in your project. Paths can either reference a type of item or a specific item.

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";

export default defineConfig({
	paths: { // [!code highlight]
		block: "src/components", // [!code highlight]
		// control where a specific item goes by referencing it by `<type>/<name>` // [!code highlight]
		"ui/button": "src/components/ui/button", // [!code highlight]
	}, // [!code highlight]
});
```

### providers

Providers are how **jsrepo** knows where to fetch items from. You can read more about providers [here](/docs/providers).

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";
import { fs } from "jsrepo/providers";

export default defineConfig({
	providers: [fs()], // [!code highlight]
});
```

### registries

Registries are the default locations that items will be fetched from when you run **jsrepo** commands.

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";

export default defineConfig({
	registries: ["https://example.com/registry"], // [!code highlight]
});
```

### registry

The `registry` option allows you to define your own registry or registries. You can learn more about creating your own registry [here](/docs/create-a-registry).

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";

export default defineConfig({
	registry: ..., // [!code highlight]
});
```

### transforms

Transforms allow you to make modifications to code before it is added to your project this is where you might add formatting, and other code modifications. You can read more about transforms [here](/docs/transforms).

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";
import prettier from "@jsrepo/transform-prettier";

export default defineConfig({
	transforms: [prettier()], // [!code highlight]
});
```

### onwarn

<Callout type="warning">
**Deprecated:** The top-level `onwarn` option is deprecated. Use [`build.onwarn`](#buildonwarn) instead.
</Callout>

### build.onwarn

The `build.onwarn` option allows you to customize how warnings are handled during the build process. You can suppress specific warnings, transform them, or use the default logging behavior.

The handler receives two arguments:
- `warning`: The warning instance (extends the base `Warning` class)
- `handler`: A function to log the warning using the default format

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";
import { InvalidImportWarning, LanguageNotFoundWarning } from "jsrepo/warnings";

export default defineConfig({
	// ...
	build: {
		onwarn: (warning, handler) => { // [!code highlight]
			// Suppress warnings for SvelteKit internal imports
			if (warning instanceof InvalidImportWarning) { // [!code highlight]
				if (['$app/server', '$app/navigation'].includes(warning.specifier)) { // [!code highlight]
					return; // Don't log this warning // [!code highlight]
				}
			}
			// Suppress language warnings for specific file types
			if (warning instanceof LanguageNotFoundWarning) { // [!code highlight]
				if (warning.path.endsWith('.glb') || warning.path.endsWith('.png')) { // [!code highlight]
					return; // Don't log this warning // [!code highlight]
				}
			}
			// Log all other warnings using the default handler
			handler(warning); // [!code highlight]
		},
	},
});
```

Available warning types:
- `InvalidImportWarning`: Triggered when an import is skipped because it's not a valid package name or path alias
- `LanguageNotFoundWarning`: Triggered when a language cannot be found to resolve dependencies for a file
- `UnresolvableDynamicImportWarning`: Triggered when a dynamic import cannot be resolved due to unresolvable syntax

All warnings extend the base `Warning` class which has a `message` property. Each specific warning type includes additional properties relevant to that warning type.

### build.remoteDependencyResolver

The `build.remoteDependencyResolver` option lets you rewrite each detected remote dependency before it is added to the built registry output.

This is useful when your source `package.json` uses version protocols like `workspace:*` or `catalog:` and you want to replace them with concrete versions during build.

For pnpm workspaces (workspace and catalog protocols), use `@jsrepo/pnpm`:

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";
import { pnpm } from "@jsrepo/pnpm";

export default defineConfig({
	build: {
		remoteDependencyResolver: pnpm(),
	},
});
```

For bun workspaces, use `@jsrepo/bun`:

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";
import { bun } from "@jsrepo/bun";

export default defineConfig({
	build: {
		remoteDependencyResolver: bun(),
	},
});
```

Or implement a custom resolver:

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";

export default defineConfig({
	build: {
		remoteDependencyResolver: async (dep) => {
			if (dep.version === "workspace:*") {
				return { ...dep, version: "1.2.3" };
			}
			if (dep.version === "catalog:") {
				return { ...dep, version: "^4.0.0" };
			}
			return dep;
		},
	},
});
```

### build.transforms

The `build.transforms` option allows you to transform the content of files before they are added to your project.

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";

export default defineConfig({
	build: {
		transforms: [
			{
				transform: async (content, opts) => {
					return { content: content.replaceAll('{{PROJECT_NAME}}', 'jsrepo') };
				},
			}
		],
	},
});
```

### hooks

Hooks allow you to run custom logic before and after CLI commands.

- `before` hooks run before the command executes.
- `after` hooks run after the command completes.

Hooks can be a function, a shell command string, or an array of either.

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";

export default defineConfig({
	hooks: {
		before: ({ command }) => {
			console.log(`Running ${command}...`);
		},
		after: "echo done",
	},
});
```

Function hooks receive typed arguments with a `command` discriminant. Use it to narrow and access command-specific data:

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";

export default defineConfig({
	hooks: {
		after: (args) => {
			if (args.command === "add") {
				console.log(`Added ${args.result.items.length} items`);
			}
		},
	},
});
```

You can also use an array of hooks:

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";

export default defineConfig({
	hooks: {
		before: [
			({ command }) => console.log(`Starting ${command}...`),
			"echo 'before hook done'",
		],
	},
});
```


================================================
FILE: apps/docs/content/docs/languages/css.mdx
================================================
---
title: css
description: CSS language support for jsrepo.
---

<BadgeGroup>
	<SourceBadge path="packages/jsrepo/src/langs/css.ts" />
	<OfficialBadge />
	<DefaultBadge />
</BadgeGroup>

The `css` language plugin supports dependency resolution for CSS, SCSS, and Sass files as well as installing dependencies with `ecosystem: "js"`.

## Supported syntax

The CSS plugin uses the [css-dependency](https://www.npmjs.com/package/css-dependency) library under the hood to detect dependencies. So it supports all the following syntax:

-   `@import` statements
-   `@plugin` statements (if `allowTailwindDirectives` is `true`)
-   `@config` statements (if `allowTailwindDirectives` is `true`)
-   `@reference` statements (if `allowTailwindDirectives` is `true`)

By default `allowTailwindDirectives` is `true` so it will also detect Tailwind directives as imports. To opt out of this behavior you can set `allowTailwindDirectives` to `false`.

```ts
import { defineConfig } from "jsrepo";
import { css } from "jsrepo/langs";

export default defineConfig({
	languages: [css({ allowTailwindDirectives: false })], // [!code ++]
});
```
## Supported File Extensions

The CSS language plugin supports the following file extensions:

| Extension |
| --------- |
| `.css`    |
| `.scss`   |
| `.sass`   |

================================================
FILE: apps/docs/content/docs/languages/html.mdx
================================================
---
title: html
description: HTML language support for jsrepo.
---

<BadgeGroup>
	<SourceBadge path="packages/jsrepo/src/langs/html.ts" />
	<OfficialBadge />
	<DefaultBadge />
</BadgeGroup>

The `html` language plugin supports dependency resolution for HTML files as well as installing dependencies with `ecosystem: "js"`.

## Supported syntax

The HTML plugin will detect dependencies from the following syntax:

-   `script` tags with `src` attributes
-   `script` tags with inline code
-   `link` tags with `href` attributes

For example the following code:

```html
<!DOCTYPE html>
<html>
	<head>
		<link rel="stylesheet" href="./app.css">
	</head>
	<!-- Doesn't resolve remote deps -->
	<script src="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19"></script>
	<script>
		import { print } from "@/utils/stdout";
		print("Hello, world!");
	</script>
</html>
```

Will result in the following dependencies:

-   `./app.css` - From `link` tag
-   `@/utils/stdout` - From `script` tag with inline code

## Supported File Extensions

The HTML language plugin supports the following file extensions:

| Extension |
| --------- |
| `.html`   |

================================================
FILE: apps/docs/content/docs/languages/index.mdx
================================================
---
title: Languages
description: Language support for jsrepo.
---

**jsrepo** uses languages to determine the dependencies of registry items when you run the `build` command and also how to add and install dependencies.

<Callout type="info">
	**jsrepo** can distribute code of any language or file type but these are the languages that support [dependency
	resolution](#what-is-dependency-resolution).
</Callout>

## Available Languages

By default **jsrepo** supports the following languages:

<Cards>
	<Card href="/docs/languages/js" icon={<JavaScriptLogo />} title="JavaScript">
		Support for `*.js`, `*.ts`, `*.jsx`, `*.tsx`, `*.mjs`, `*.mts` files.
	</Card>
	<Card href="/docs/languages/svelte" icon={<SvelteLogo />} title="Svelte">
		Support for `*.svelte` files.
	</Card>
	<Card href="/docs/languages/vue" icon={<VueLogo />} title="Vue">
		Support for `*.vue` files.
	</Card>
	<Card href="/docs/languages/css" icon={<CSSLogo />} title="CSS">
		Support for `*.css`, `*.scss`, `*.sass` files.
	</Card>
	<Card href="/docs/languages/html" icon={<HTML5Logo />} title="HTML">
		Support for `*.html` files.
	</Card>
</Cards>

## What is dependency resolution?

Dependency resolution is the process of determining the dependencies of a registry item. This process ensures that when you add a registry item that all of it's dependencies are also added.

Without dependency resolution you need to manually specify dependencies of a registry item which is cumbersome and error prone.

### How to manually specify dependencies

If your language of choice doesn't support dependency resolution or your registry items have dependencies that cannot be automatically detected you can manually specify them like so:

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";
import { js } from "jsrepo/langs";

export default defineConfig({
	registry: {
		items: [
			{
				name: "button",
				type: "component",
				files: [
					{
						path: "src/components/button.tsx",
					},
				],
				registryDependencies: ["utils"], // [!code ++]
				dependencies: [
					// [!code ++]
					{
						// [!code ++]
						ecosystem: "js", // [!code ++]
						name: "radix-ui", // [!code ++]
						version: "1.4.3", // [!code ++]
					}, // [!code ++]
				], // [!code ++]
			},
		],
	},
});
```

### How to prevent automatic dependency resolution

If you want to opt out of automatic dependency resolution you can do so by setting the `dependencyResolution` option to `manual` on the registry item or on the file itself.

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";
import { js } from "jsrepo/langs";

export default defineConfig({
	registry: {
		items: [
			{
				name: "button",
				type: "component",
				// for the entire item
				dependencyResolution: "manual", // [!code ++]
				files: [
					{
						path: "src/components/button.tsx",
						// for individual files
						dependencyResolution: "manual", // [!code ++]
					},
				],
			},
		],
	},
});
```

### Strict mode

By default **jsrepo** will error if it cannot resolve all dependencies of a registry item. You can opt out of this behavior by setting the `strict` option to `false`.

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";
import { js } from "jsrepo/langs";

export default defineConfig({
	registry: {
		items: [
			{
				name: "button",
				type: "component",
				strict: false, // [!code ++]
			},
		],
	},
});
```


================================================
FILE: apps/docs/content/docs/languages/js.mdx
================================================
---
title: js
description: JavaScript language support for jsrepo.
---

<BadgeGroup>
	<SourceBadge path="packages/jsrepo/src/langs/js.ts" />
	<OfficialBadge />
	<DefaultBadge />
</BadgeGroup>

The `js` language plugin supports dependency resolution for both JavaScript and TypeScript files as well as installing dependencies with `ecosystem: "js"`.

## Supported syntax

The JavaScript plugin will detect dependencies from the following syntax:

- Static imports
- Dynamic imports
- Export from statements

For example the following code:

```ts
import 'dotenv/config';
import { print } from "@/utils/stdout";

async function printDynamic() {
	const data = await import("./data.json", { with: { type: "json" } });
	print(data.message);
}

export { logger } from "@/utils/logger";
```

Will result in the following dependencies:

-   `dotenv` - From side effect import
-   `@/utils/stdout` - From static import
-   `./data.json` - From dynamic import
-   `@/utils/logger` - From export from statement

## Supported File Extensions

The JavaScript language plugin supports the following file extensions:

| Extension |
| --------- |
| `.js`     |
| `.ts`     |
| `.jsx`    |
| `.tsx`    |
| `.mjs`    |
| `.mts`    |


================================================
FILE: apps/docs/content/docs/languages/svelte.mdx
================================================
---
title: svelte
description: Svelte language support for jsrepo.
---

<BadgeGroup>
	<SourceBadge path="packages/jsrepo/src/langs/svelte.ts" />
	<OfficialBadge />
	<DefaultBadge />
</BadgeGroup>

The `svelte` language plugin supports dependency resolution for Svelte files as well as installing dependencies with `ecosystem: "js"`.

<Callout type="warning">
	This language plugin requires `svelte` to be installed in your project.
</Callout>

## Supported syntax

The Svelte plugin parses all script tags and passes the code to the [JavaScript plugin](/docs/languages/js) to resolve dependencies so all the same syntax is supported.

## Supported File Extensions

The JavaScript language plugin supports the following file extensions:

| Extension |
| --------- |
| `.svelte` |


================================================
FILE: apps/docs/content/docs/languages/vue.mdx
================================================
---
title: vue
description: Vue language support for jsrepo.
---

<BadgeGroup>
	<SourceBadge path="packages/jsrepo/src/langs/vue.ts" />
	<OfficialBadge />
	<DefaultBadge />
</BadgeGroup>

The `vue` language plugin supports dependency resolution for Vue files as well as installing dependencies with `ecosystem: "js"`.

<Callout type="warning">
	This language plugin requires `vue` to be installed in your project.
</Callout>

## Supported syntax

The Vue plugin parses all script tags and passes the code to the [JavaScript plugin](/docs/languages/js) to resolve dependencies so all the same syntax is supported.

## Supported File Extensions

The Vue language plugin supports the following file extensions:

| Extension |
| --------- |
| `.vue`    |

================================================
FILE: apps/docs/content/docs/legacy.mdx
================================================
---
title: Legacy Docs
description: Legacy documentation for jsrepo.
---

All documentation for older versions of **jsrepo** can be found below:

<Cards>
	<Card href="https://v2.jsrepo.dev" icon={<BookIcon />} title="jsrepo v2">
		Legacy documentation for jsrepo v2.
	</Card>
</Cards>

================================================
FILE: apps/docs/content/docs/mcp.mdx
================================================
---
title: MCP Server
description: The jsrepo MCP server.
---

<BadgeGroup>
	<SourceBadge path="packages/mcp" />
	<OfficialBadge />
    <NpmBadge packageName="@jsrepo/mcp" />
</BadgeGroup>

The **jsrepo** MCP server has been built alongside the **jsrepo** CLI to ensure agents have first class support for interacting with jsrepo registries.

<Callout type="info">
    The **jsrepo** MCP ships separate to the **jsrepo** CLI to reduce the overall size of the CLI and can be found on npm as `@jsrepo/mcp`.
</Callout>

All **jsrepo** registries are supported out of the box by the MCP server, including registries hosted on custom providers (provided the custom provider is present in your `jsrepo.config`).

## Configuration

<UnderlineTabs defaultValue="cursor">
	<UnderlineTabsList>
		<UnderlineTabsTrigger value="cursor"><CursorLogo /> Cursor</UnderlineTabsTrigger>
		<UnderlineTabsTrigger value="claude"><ClaudeLogo /> Claude Code </UnderlineTabsTrigger>
		<UnderlineTabsTrigger value="vs-code"><VSCodeLogo /> VS Code</UnderlineTabsTrigger>
		<UnderlineTabsTrigger value="codex"><OpenAILogo /> Codex</UnderlineTabsTrigger>
		<UnderlineTabsTrigger value="antigravity"><AntigravityLogo /> Antigravity</UnderlineTabsTrigger>
	</UnderlineTabsList>
	<UnderlineTabsContent value="cursor">
        You can quickly configure the MCP server for Cursor by running the following command:

		```sh
        jsrepo config mcp --client cursor
        ```

        This will automatically configure the MCP server for Cursor in the correct file:

        ```json title=".cursor/mcp.json"
        {
            "mcpServers": {
                "jsrepo": {
                    "command": "npx",
                    "args": ["@jsrepo/mcp"]
                }
            }
        }
        ```
	</UnderlineTabsContent>
	<UnderlineTabsContent value="claude">
        You can quickly configure the MCP server for Claude Code by running the following command:

		```sh
        jsrepo config mcp --client claude
        ```

        This will automatically configure the MCP server for Claude Code in the correct file:

        ```json title=".mcp.json"
        {
            "mcpServers": {
                "jsrepo": {
                    "command": "npx",
                    "args": ["@jsrepo/mcp"]
                }
            }
        }
        ```
    </UnderlineTabsContent>
	<UnderlineTabsContent value="vs-code">
        You can quickly configure the MCP server for VSCode by running the following command:

		```sh
        jsrepo config mcp --client vscode
        ```

        This will automatically configure the MCP server for VSCode in the correct file:

        ```json title=".vscode/mcp.json"
        {
            "servers": {
                "jsrepo": {
                    "command": "npx",
                    "args": ["@jsrepo/mcp"]
                }
            }
        }
        ```
    </UnderlineTabsContent>
	<UnderlineTabsContent value="codex">
        You can quickly configure the MCP server for Codex by running the following command:

		```sh
        jsrepo config mcp --client codex
        ```

        This will automatically configure the MCP server for Codex in the correct file:

        ```toml title="~/.codex/config.toml"
        [mcp_servers.jsrepo]
        command = "npx"
        args = ["@jsrepo/mcp"]
        ```
    </UnderlineTabsContent>
    <UnderlineTabsContent value="antigravity">
        You can quickly configure the MCP server for Antigravity by running the following command:

		```sh
        jsrepo config mcp --client antigravity
        ```

        This will automatically configure the MCP server for Antigravity in the correct file:

        ```json title="~/.gemini/antigravity/mcp_config.json"
        {
            "mcpServers": {
                "jsrepo": {
                    "command": "npx",
                    "args": ["@jsrepo/mcp"]
                }
            }
        }
        ```
    </UnderlineTabsContent>
</UnderlineTabs>

## Tools

The jsrepo MCP server provides the following tools:

| Tool | Description |
|------|-------------|
| `add_item_to_project` | Add a registry item or items directly to the users project |
| `view_registry_item` | View the code and information about a registry item |
| `list_items_in_registry` | List registry items in one or more registries and optionally fuzzy search |

## Registry Authors

Your registry will automatically be compatible with the **jsrepo** MCP server, but here are a few tips to improve the agents usage of your registry:

- include all the registry metadata in your `jsrepo.config` to allow agents to find your registry more easily when searching
- include a `description` with each item in your registry
- include files with `role: "example"` that show how to use each item
- include files with `role: "doc"` that document each item


================================================
FILE: apps/docs/content/docs/migrate.mdx
================================================
---
title: Migration
description: Migrate from jsrepo v2 to jsrepo v3.
---

**jsrepo** v3 is a complete rewrite of the **jsrepo** CLI and we haven't been shy about making breaking changes. 

If you're coming from **jsrepo** v2 and want to quickly get started with **jsrepo** v3 you can run the following command in your existing **jsrepo** project:

```sh
pnpm dlx @jsrepo/migrate v3
```

The migration tool will:
- Migrate your `jsrepo-build-config.json` and `jsrepo.json` files into the new `jsrepo.config.ts` file.
- Install `jsrepo` and the correct formatting transform (if you were using one)
- Build your registry using both v2 and v3 to ensure compatibility

<Callout type="info">
    You can put this in your upgrade guide for your users.
</Callout>

## Breaking changes

### 1. A new js based config

In **jsrepo** v2 you used a `jsrepo-build-config.json` file to configure your registry and a `jsrepo.json` file to configure your project. This wasn't great for obvious reasons.

In **jsrepo** v3 we use a `jsrepo.config.ts` file to configure your registry and project: 

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";

export default defineConfig({
	// ...
});
```

This affords us more flexibility and allows us to support plugins.

<Callout type="info">
    If you're like me you may be worried about having to automatically make modifications to a js based config. Not to worry! The blood, sweat, and (mostly) tears have been shed to make it as seamless as possible.
</Callout>

### 2. No more categories

In **jsrepo** v2 we had item categories. This allowed you to group items together and add them by running `jsrepo add <category>/<item>`.

In **jsrepo** v3 you can add items by running `jsrepo add <item>`.

"categories" are now the `type` of the item. The type of an item is used to determine the path that the item will be added to in the user's project:

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";

export default defineConfig({
	registry: {
		items: [
			{
				name: "button",
				type: "component", // instead of category now it's type // [!code highlight]
				files: [
					{
						path: "src/components/button.tsx",
					},
				],
			},
		],
	},
});
```

### 3. No backwards compatibility with v2 registries

You probably could've guessed this by some of the changes we have already mentioned but unfortunately we don't support adding items from v2 registries from the v3 CLI.

If you still want to use a v2 registry you can of course continue to use the v2 CLI to add items to your project:

```sh
pnpm dlx jsrepo@2 add ui/button
```

### 4. Deprecated commands

The following commands have been deprecated in **jsrepo** v3:

- `jsrepo test`
- `jsrepo execute`
- `jsrepo tokens` - Now all auth functions are handled by the `jsrepo auth` command.
- `jsrepo mcp` - The MCP server has been moved to the `@jsrepo/mcp` package.

### 5. No more `Update with AI`

While we were excited by the `Update with AI` feature it didn't feel worth the added bundle cost. We'll likely explore ways to improve the workflow of updating items with AI without the added bundle cost.

### 6. Formatting functionality has been externalized

In **jsrepo** v2 you could format code before it was added to your project by configuring the formatter in your `jsrepo.json` file.

With **jsrepo** v3 we introduced the concept of "transforms" and in so doing we realized that the formatting functionality should be externalized to reduce the bundle size of the CLI and allow for more flexibility for users.

You can now configure formatting for your project by adding one of the officially supported transforms to your config:

```sh
# prettier
jsrepo config transform prettier
# biome
jsrepo config transform biome
```

### 7. Output configuration changes

In **jsrepo** v2, registries could specify an `outputDir` in their build config. In **jsrepo** v3, this has been replaced with output plugins:

- Registries that had an `outputDir` are migrated to use the [distributed](/docs/outputs/distributed) output
- Registries without an `outputDir` use the [repository](/docs/outputs/repository) output by default

### 8. Removed peer dependencies

Right now this is just a choice to reduce API surface for language plugins. If this becomes something the community wants we can add it back in the future.

## The wins

Now let's talk about the reasons we are so excited to break everyone's code for **jsrepo** v3.

### Plugins

In **jsrepo** v3 we have introduced plugins. There are currently three types of plugins:

- [Languages](/docs/languages) - Extend jsrepo dependency resolution support to include additional languages.
- [Outputs](/docs/outputs) - Customize the way your registry is distributed.
- [Providers](/docs/providers) - Allow users to install items from a custom source.
- [Transforms](/docs/transforms) - Modify code before it's added to your project.

### Shadcn compatibility

**jsrepo** v3 is now **shadcn** compatible. You can now add and update items from **shadcn** meaning **jsrepo** now has access to an entire ecosystem of **shadcn** registries.

Try it out by running:

```sh
pnpm jsrepo add --registry https://ui.shadcn.com/r/styles/new-york-v4
```

### Greatly improved MCP responses

Thanks to adopting the more manual approach for defining a registry it's now possible to add metadata to your registry items greatly improving the responses you will get when using the **jsrepo** MCP server.

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";

export default defineConfig({
	registry: {
		items: [
			{
				name: "button",
                title: "Button", // [!code ++]
                description: "A button component", // [!code ++]
                files: [
                    {
                        path: "src/components/button.tsx",
                    },
                    // add examples for LLMs to use
                    { // [!code ++]
                        path: 'src/demos/button-demo.tsx', // [!code ++]
                        role: 'example', // [!code ++]
                    } // [!code ++]
                ]
			},
		],
	},
});
```


================================================
FILE: apps/docs/content/docs/outputs/distributed.mdx
================================================
---
title: Distributed
description: Output your registry as json files in a directory.
---

import { Files, Folder, File } from "@/components/files";

<BadgeGroup>
	<SourceBadge path="packages/jsrepo/src/outputs/distributed.ts" />
	<OfficialBadge />
</BadgeGroup>

The `distributed` output is used for maximizing performance when serving your registry as a static asset.

## Usage

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";
import { distributed } from "jsrepo/outputs"; // [!code ++]

export default defineConfig({
	registry: {
		outputs: [distributed({ dir: "./public/r" })], // [!code ++]
	},
});
```

Now running `jsrepo build` will output your registry to the `./public/r` directory.

Unlike the `repository` output, the `distributed` output will output each item as a separate json file. For example:

<Files>
	<Folder name="public" defaultOpen>
		<Folder name="r" defaultOpen>
			<File name="registry.json" />
			<File name="button.json" />
			<File name="utils.json" />
		</Folder>
	</Folder>
</Files>

Since each item file contains all the code for all the files required for that item this is much more performant, and portable than the `repository` output.

================================================
FILE: apps/docs/content/docs/outputs/index.mdx
================================================
---
title: Outputs
description: Output your registry however you want.
---

Outputs allow you to customize the way your registry is distributed, or (more generally) what to do with the registry after it's built.

This isn't limited into building your registry into a format that **jsrepo** can understand you could use it to output documentation or a manifest for your own CLI application.

By default **jsrepo** ships with two output types:

- [Distributed](/docs/outputs/distributed) - Output your registry as json files in a directory.
- [Repository](/docs/outputs/repository) - Output your registry as a single json file in the root of your repository.

Here are all the officially available outputs:

<Cards>
	<Card href="/docs/outputs/distributed" icon={<SplitIcon />} title="Distributed">
		Output your registry as json files in a directory.
	</Card>
	<Card href="/docs/outputs/repository" icon={<FolderIcon />} title="Repository">
		Output your registry as a single json file in the root of your repository.
	</Card>
    <Card href="/docs/outputs/shadcn" icon={<ShadcnLogo />} title="shadcn">
		Output your registry as a shadcn registry.
	</Card>
</Cards>

## Creating a custom output

You can create your own output either inline in your config file or as a standalone package.

For this example we will create a standalone package that outputs your registry as a markdown file called `REGISTRY.md`.

Let's create our `output.ts` file and import the `Output` type from `jsrepo/outputs`:

```ts
import type { Output } from "jsrepo/outputs";

export function output(): Output {
    return {
        
    }
}
```

Next let's define the `output` key to define how the registry should be output:

```ts title="src/output.ts"
import type { Output } from "jsrepo/outputs";

export const OUTPUT_FILE = "REGISTRY.md";

export function output(): Output {
    return {
        output: async (buildResult, { cwd }) => { // [!code ++]
            let content = `# ${buildResult.name}\n\n`; // [!code ++]
            // [!code ++]
            for (const item of buildResult.items) { // [!code ++]
                content += `## ${item.name}\n\n${item.description}\n\n`; // [!code ++]
            } // [!code ++]
            // [!code ++]
            fs.writeFileSync(path.join(cwd, OUTPUT_FILE), content); // [!code ++]
        }, // [!code ++]
    }
}
```

<Callout type="info">
    The `buildResult` object contains a bunch of useful information about the registry. You can find the full type [here](https://github.com/jsrepojs/jsrepo/blob/next/packages/jsrepo/src/utils/build.ts#L31).
</Callout>

Finally we can define the `clean` key to define how to remove the output file before the next build:

```ts title="src/output.ts"
import type { Output } from "jsrepo/outputs";

export const OUTPUT_FILE = "REGISTRY.md";

export function output(): Output {
    return {
        output: async (buildResult, { cwd }) => {
            let content = `# ${buildResult.name}\n\n`;

            for (const item of buildResult.items) {
                content += `## ${item.name}\n\n${item.description}\n\n`;
            }

            fs.writeFileSync(path.join(cwd, OUTPUT_FILE), content);
        },
        clean: async ({ cwd }) => { // [!code ++]
            const manifestPath = path.join(cwd, OUTPUT_FILE); // [!code ++]
            if (!fs.existsSync(manifestPath)) return; // [!code ++]
            fs.rmSync(manifestPath); // [!code ++]
        }, // [!code ++]
    }
}
```

Now we can use the output in our config file:

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";
import { output } from "./src/output";

export default defineConfig({
    registry: {
        name: "my-registry",
        outputs: [output()],
        // ...
    }
});
```

And the result should look like this:

```markdown title="REGISTRY.md"
# my-registry

## button

A button component.

```

================================================
FILE: apps/docs/content/docs/outputs/repository.mdx
================================================
---
title: Repository
description: Output your registry as a single json file in the root of your repository.
---

<BadgeGroup>
	<SourceBadge path="packages/jsrepo/src/outputs/distributed.ts" />
	<OfficialBadge />
</BadgeGroup>

The `repository` output is used when you are serving your registry from a repository and want to minimize code duplication and tracked files.

## Usage

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";
import { repository } from "jsrepo/outputs"; // [!code ++]

export default defineConfig({
	registry: {
		outputs: [repository()], // [!code ++]
	},
});
```

Now running `jsrepo build` will output a `registry.json` file to the root of your repository.

================================================
FILE: apps/docs/content/docs/outputs/shadcn.mdx
================================================
---
title: shadcn
description: Output your registry as a shadcn registry.
---

<BadgeGroup>
	<SourceBadge path="packages/shadcn/src/output.ts" />
	<OfficialBadge />
	<NpmBadge packageName="@jsrepo/shadcn" />
</BadgeGroup>

The `@jsrepo/shadcn` is a package that helps you distribute your jsrepo registry as a shadcn registry.

## Usage

To get started install the package:

```npm
npm install @jsrepo/shadcn -D
```

Next let's add the output to our config file:

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";
import { output } from "@jsrepo/shadcn/output";

export default defineConfig({
	registry: {
        // ...
		outputs: [output({ dir: "./public/r/shadcn" })], // [!code ++]
	},
});
```

Now running `jsrepo build` will output a **shadcn** registry to the `./public/r/shadcn` directory.

## defineShadcnRegistry

**shadcn** registries are defined a bit differently than **jsrepo** registries, generally this plugin should correctly resolve those differences or warn you if it is unable to. 

However if you are only distributing your registry as a **shadcn** registry and don't care about the other features of **jsrepo** you can use the `defineShadcnRegistry` function to define your registry the *"shadcn"* way.

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";
import { defineShadcnRegistry, output } from "@jsrepo/shadcn";

export default defineConfig({
	registry: defineShadcnRegistry({
		// make sure you still include the output
		outputs: [output({ dir: "./public/r/shadcn" })],
	}),
});
```

<Callout type="info">
    When using the `defineShadcnRegistry` function it's be possible to just paste the contents of the **shadcn** `registry.json` file into your config file and start building your registry with **jsrepo**.
</Callout>

## Outputting jsrepo registries alongside shadcn registries

Currently the **jsrepo** and **shadcn** outputs are not compatible to be used in the same directory. Because of this you will need to serve each registry from a different URL.

The preferred way to avoid this conflict would be to publish your registry to [jsrepo.com](https://jsrepo.com) (which also has it's own benefits).

In absence of that, the easiest way to do this and our recommendation is to postfix the **shadcn** registry output `dir` option with `/shadcn`.

For example:

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";
import { distributed } from "jsrepo/outputs";
import { output } from "@jsrepo/shadcn/output";

export default defineConfig({
	registry: {
		outputs: [
            distributed({ dir: "./public/r" }), 
            output({ dir: "./public/r" }) // [!code --]
            output({ dir: "./public/r/shadcn" }) // [!code ++]
        ],
	},
});
```

================================================
FILE: apps/docs/content/docs/providers/azure.mdx
================================================
---
title: azure
description: Download and add registry items from an Azure DevOps repository.
---

<BadgeGroup>
	<SourceBadge path="packages/jsrepo/src/providers/azure.ts" />
	<OfficialBadge />
	<DefaultBadge />
</BadgeGroup>

## Usage

To start adding registry items from an Azure DevOps repository you can run the following command:

```sh
jsrepo add azure/<org>/<project>/<repo>
```

The Azure provider understands refs as either branches or tags:

```sh
jsrepo add azure/<org>/<project>/<repo>/heads/<ref>
jsrepo add azure/<org>/<project>/<repo>/tags/<ref>
```

### Custom base urls

By default the Azure provider will use `https://dev.azure.com` as the base url. You can configure this behavior by configuring `azure` in your `jsrepo.config` file:

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";
import { azure } from "jsrepo/providers";

export default defineConfig({
	providers: [azure({ baseUrl: "https://dev.azure.com" })], // [!code highlight]
});
```

Alternatively you can use the `azure:https://<url>` shorthand to use a custom base url without having to touch your config file:

```sh
jsrepo add azure:https://dev.azure.com/<org>/<project>/<repo>/heads/<ref>
```

This syntax tells the Azure provider that it can resolve this URL as an Azure DevOps repository.

## Deploying your registry to Azure DevOps

When deploying your registry to Azure DevOps you will want to use the `repository` output type:

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";
import { repository } from "jsrepo/outputs"; // [!code ++]

export default defineConfig({
	registry: {
		// ...
		outputs: [repository()], // [!code ++]
	},
});
```

This will create a `registry.json` file that will contain everything users need to use your registry.

<Callout type="warning">
	The `registry.json` file must be at the **root** of your repository otherwise users won't be able to use your registry.
</Callout>

## Authentication

To authenticate with Azure DevOps you can run the following command:

```sh
jsrepo auth azure
```

You can logout of your account by running:

```sh
jsrepo auth azure --logout
```

### Environment Variable

If you prefer to use an environment variable or are in an environment where you can't use the `jsrepo auth` command you can provide the token via the `AZURE_TOKEN` environment variable.

```sh
AZURE_TOKEN=... jsrepo add 
```

## Options

<TypeTable
	type={{
		baseUrl: {
			description: "The base url to use.",
			type: "string",
			default: "https://dev.azure.com",
		},
	}}
/>

================================================
FILE: apps/docs/content/docs/providers/bitbucket.mdx
================================================
---
title: bitbucket
description: Download and add registry items from a Bitbucket repository.
---

<BadgeGroup>
	<SourceBadge path="packages/jsrepo/src/providers/bitbucket.ts" />
	<OfficialBadge />
	<DefaultBadge />
</BadgeGroup>

## Usage

To start adding registry items from a Bitbucket repository you can run the following command:

```sh
jsrepo add https://bitbucket.org/<owner>/<repo>/<item-name>
```

The Bitbucket provider can parse Bitbucket URLs so that you can just copy and paste a link to a Bitbucket repository and it will just work:

```sh
jsrepo add https://bitbucket.org/<owner>/<repo>/<item-name>
jsrepo add https://bitbucket.org/<owner>/<repo>/src/<ref>
```

### The `bitbucket/` shorthand

You can also just use the `bitbucket/` shorthand in place of `https://bitbucket.org/`.

```sh
jsrepo add bitbucket/<owner>/<repo>/<item-name>
jsrepo add bitbucket/<owner>/<repo>/src/<ref>
```

<Callout type="info">
	If you configured a custom `baseUrl` in your `jsrepo.config` file then using the `bitbucket/` shorthand will use your
	custom base url instead of `https://bitbucket.org/`.
</Callout>

### Custom base urls

By default the Bitbucket provider will use `https://bitbucket.org` as the base url for the `bitbucket/` shorthand. You can configure this behavior by configuring `bitbucket` in your `jsrepo.config` file:

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";
import { bitbucket } from "jsrepo/providers";

export default defineConfig({
	providers: [bitbucket()], // [!code ++]
});
```

Alternatively you can use the `bitbucket:https://<url>` shorthand to use a custom base url without having to touch your config file:

```sh
jsrepo add bitbucket:https://bitbucket.org/<owner>/<repo>/src/<ref>
```

This syntax tells the Bitbucket provider that it can resolve this URL as a Bitbucket repository.

## Deploying your registry to Bitbucket

When deploying your registry to Bitbucket you will want to use the `repository` output type:

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";
import { repository } from "jsrepo/outputs"; // [!code ++]

export default defineConfig({
	registry: {
		// ...
		outputs: [repository()], // [!code ++]
	},
});
```

This will create a `registry.json` file that will contain everything users need to use your registry.

<Callout type="warning">
	The `registry.json` file must be at the **root** of your repository otherwise users won't be able to use your registry.
</Callout>

## Authentication

To authenticate with Bitbucket you can run the following command:

```sh
jsrepo auth bitbucket
```

You can logout of your account by running:

```sh
jsrepo auth bitbucket --logout
```

### Environment Variable

If you prefer to use an environment variable or are in an environment where you can't use the `jsrepo auth` command you can provide the token via the `BITBUCKET_TOKEN` environment variable.

```sh
BITBUCKET_TOKEN=... jsrepo add 
```

## Options

<TypeTable
	type={{
		baseUrl: {
			description: "The base url to use when using the bitbucket/ shorthand.",
			type: "string",
			default: "https://bitbucket.org",
		},
	}}
/>

================================================
FILE: apps/docs/content/docs/providers/fs.mdx
================================================
---
title: fs
description: Download and add registry items from your local filesystem.
---

<BadgeGroup>
	<SourceBadge path="packages/jsrepo/src/providers/fs.ts" />
	<OfficialBadge />
</BadgeGroup>

The `fs` provider allows you to distribute code from your local filesystem. This is useful when you want to test out how your registries behave without having to deploy them somewhere first.

## Usage

To start adding registry items from your local filesystem you first need to configure the provider in your `jsrepo.config` file:

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";
import { fs } from "jsrepo/providers"; // [!code ++]

export default defineConfig({
	providers: [fs()], // [!code ++]
});
```

Now you can start adding registry items from your local filesystem:

```sh
jsrepo add fs://../registries/my-registry
```

You may also want to supply a base directory to the provider:

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";
import { fs } from "jsrepo/providers";

export default defineConfig({
	providers: [fs({ baseDir: "../registries" })], // [!code highlight]
});
```

Now your commands will be relative to the base directory you defined:

```sh
jsrepo add fs://./my-registry
```

## Options

<TypeTable
	type={{
		baseDir: {
			description: "All paths will be relative to this directory.",
			type: "string",
		},
	}}
/>

================================================
FILE: apps/docs/content/docs/providers/github.mdx
================================================
---
title: github
description: Download and add registry items from a GitHub repository.
---

<BadgeGroup>
	<SourceBadge path="packages/jsrepo/src/providers/github.ts" />
	<OfficialBadge />
    <DefaultBadge />
</BadgeGroup>

## Usage

To start adding registry items from a GitHub repository you can run the following command:

```sh
jsrepo add https://github.com/<owner>/<repo>/<item-name>
```

The GitHub provider can parse GitHub URLs so that you can just copy and paste a link to a GitHub repository and it will just work:

```sh
jsrepo add https://github.com/<owner>/<repo>/<item-name>
jsrepo add https://github.com/<owner>/<repo>/tree/<ref>
```

### The `github/` shorthand

You can also just use the `github/` shorthand in place of `https://github.com/`.

```sh
jsrepo add github/<owner>/<repo>/<item-name>
jsrepo add github/<owner>/<repo>/tree/<ref>
```

<Callout type="info">
	If you configured a custom `baseUrl` in your `jsrepo.config` file then using the `github/` shorthand will use your
	custom base url instead of `https://github.com/`.
</Callout>

### Custom base urls

By default the GitHub provider will use `https://github.com` as the base url for the `github/` shorthand. You can configure this behavior by configuring `github` in your `jsrepo.config` file:

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";
import { github } from "jsrepo/providers";

export default defineConfig({
	providers: [github({ baseUrl: "https://my-github-instance.com" })], // [!code highlight]
});
```

Alternatively you can use the `github:https://<url>` shorthand to use a custom base url without having to touch your config file:

```sh
jsrepo add github:https://my-github-instance.com/<owner>/<repo>/<item-name>
```

This syntax tells the GitHub provider that it can resolve this URL as a GitHub repository.

## Authentication

To authenticate with GitHub you can run the following command:

```sh
jsrepo auth github
```

You can logout of your account by running:

```sh
jsrepo auth github --logout
```

### Environment Variable

If you prefer to use an environment variable or are in an environment where you can't use the `jsrepo auth` command you can provide the token via the `GITHUB_TOKEN` environment variable.

```sh
GITHUB_TOKEN=... jsrepo add 
```

## Deploying your registry to GitHub

When deploying your registry to GitHub you will want to use the `repository` output type:

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";
import { repository } from "jsrepo/outputs"; // [!code ++]

export default defineConfig({
	registry: {
        // ...
		outputs: [repository()], // [!code ++]
	},
});
```

This will create a `registry.json` file that will contain everything users need to use your registry.

<Callout type="warning">
	The `registry.json` file must be at the **root** of your repository otherwise users won't be able to use your registry.
</Callout>

### Workflow

If you want to use GitHub Actions to automatically build your registry when you push changes you can use this workflow:

```yml title=".github/workflows/build-registry.yml"
name: build-registry
on:
  push:
    branches:
      - main
permissions:
  contents: write
  pull-requests: write
  id-token: write
jobs:
  build:
    runs-on: ubuntu-latest
    permissions:
      contents: write
      pull-requests: write
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
      - name: Install dependencies
        run: npm install
      - name: Build registry.json
        run: jsrepo build
      - name: Create pull request with changes
        uses: peter-evans/create-pull-request@v7
        with:
          title: 'chore: update `registry.json`'
          body: |
            - Update `registry.json`
            ---
            This PR was auto generated
          branch: build-registry
          commit-message: build `registry.json`
```

## Options

<TypeTable
	type={{
		baseUrl: {
			description: "The base url to use when using the github/ shorthand.",
			type: "string",
			default: "https://github.com",
		},
	}}
/>


================================================
FILE: apps/docs/content/docs/providers/gitlab.mdx
================================================
---
title: gitlab
description: Download and add registry items from a GitLab repository.
---

<BadgeGroup>
	<SourceBadge path="packages/jsrepo/src/providers/gitlab.ts" />
	<OfficialBadge />
	<DefaultBadge />
</BadgeGroup>


## Usage

To start adding registry items from a GitLab repository you can run the following command:

```sh
jsrepo add https://gitlab.com/<group>/<project>/<item-name>
```

The GitLab provider can parse GitLab URLs so that you can just copy and paste a link to a GitLab repository and it will just work:

```sh
jsrepo add https://gitlab.com/<group>/<project>/<item-name>
jsrepo add https://gitlab.com/<group>/<project>/-/tree/<ref>
```

### The `gitlab/` shorthand

You can also just use the `gitlab/` shorthand in place of `https://gitlab.com/`.

```sh
jsrepo add gitlab/<group>/<project>/<item-name>
jsrepo add gitlab/<group>/<subgroup>/<project>/-/tree/<ref>
```

<Callout type="info">
	If you configured a custom `baseUrl` in your `jsrepo.config` file then using the `gitlab/` shorthand will use your
	custom base url instead of `https://gitlab.com/`.
</Callout>

### Custom base urls

By default the GitLab provider will use `https://gitlab.com` as the base url for the `gitlab/` shorthand. You can configure this behavior by configuring `gitlab` in your `jsrepo.config` file:

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";
import { gitlab } from "jsrepo/providers";

export default defineConfig({
	providers: [gitlab({ baseUrl: "https://my-gitlab-instance.com" })], // [!code highlight]
});
```

Alternatively you can use the `gitlab:https://<url>` shorthand to use a custom base url without having to touch your config file:

```sh
jsrepo add gitlab:https://my-gitlab-instance.com/<group>/<project>/<item-name>
```

This syntax tells the GitLab provider that it can resolve this URL as a GitLab repository.

## Deploying your registry to GitLab

When deploying your registry to GitLab you will want to use the `repository` output type:

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";
import { repository } from "jsrepo/outputs"; // [!code ++]

export default defineConfig({
	registry: {
		// ...
		outputs: [repository()], // [!code ++]
	},
});
```

This will create a `registry.json` file that will contain everything users need to use your registry.

<Callout type="warning">
	The `registry.json` file must be at the **root** of your repository otherwise users won't be able to use your registry.
</Callout>

## Authentication

To authenticate with GitLab you can run the following command:

```sh
jsrepo auth gitlab
```

You can logout of your account by running:

```sh
jsrepo auth gitlab --logout
```

### Environment Variable

If you prefer to use an environment variable or are in an environment where you can't use the `jsrepo auth` command you can provide the token via the `GITLAB_TOKEN` environment variable.

```sh
GITLAB_TOKEN=... jsrepo add 
```

## Options

<TypeTable
	type={{
		baseUrl: {
			description: "The base url to use when using the gitlab/ shorthand.",
			type: "string",
			default: "https://gitlab.com",
		},
	}}
/>



================================================
FILE: apps/docs/content/docs/providers/http.mdx
================================================
---
title: http
description: Download and add registry items from an arbitrary HTTP endpoint.
---

import { Files, Folder, File } from "@/components/files";

<BadgeGroup>
	<SourceBadge path="packages/jsrepo/src/providers/http.ts" />
	<OfficialBadge />
	<DefaultBadge />
</BadgeGroup>

The http provider is the simplest provider by far. To add registry items simply provide the base url of the `registry.json` file:

```sh
jsrepo add https://example.com/registry
```

**jsrepo** will then find the `registry.json` file from `https://example.com/registry/registry.json`.

## Deploying a registry to your own website

When deploying a registry to your own website you will want to use the `distributed` output type:

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";
import { distributed } from "jsrepo/outputs"; // [!code ++]

export default defineConfig({
	// `dir` is the directory to output the files to
	outputs: [distributed({ dir: "./public/r" })], // [!code ++]
});
```

This will output your registry to the `public/r` directory which might look something like this:

<Files>
	<Folder name="public" defaultOpen>
		<Folder name="r" defaultOpen>
			<File name="registry.json" />
			<File name="button.json" />
			<File name="utils.json" />
		</Folder>
	</Folder>
</Files>

Users will then be able to add registry items to their project by running:

```sh
jsrepo add https://your-website.com/r
```

## Authentication

To authenticate with the http provider you can run the following command:

```sh
jsrepo auth http
```

You will then be prompted to select or enter the name of a registry to authenticate to.

Once authenticated that token will continue to be used for that registry until you logout.

You can logout of your account by running:

```sh
jsrepo auth http --logout
```

## Options

### `baseUrl`

The `baseUrl` option allows you to configure what registries this provider will match. 

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";
import { http } from "jsrepo/providers";

export default defineConfig({
	// only use this provider for registries starting with https://myregistry.com
	providers: [
		http({ 
			baseUrl: "https://myregistry.com" // [!code ++]
		})
	],
});
```

### `authHeader`

The `authHeader` function allows you to set headers for every request using the provided token. This is useful for when you need to authenticate to a registry that doesn't support the Bearer token format.

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";
import { http } from "jsrepo/providers";

export default defineConfig({
	providers: [
		http({ 
			// set your custom headers here
			authHeader: (token) => ({ 'X-API-Key': token }) // [!code ++]
		})
	],
});
```

### `headers`

You can set custom headers on every request by providing the `headers` option:

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";
import { http } from "jsrepo/providers";

export default defineConfig({
	providers: [
		http({
			headers: {  // [!code ++]
				'X-Custom-Header': 'custom value' // [!code ++]
			} // [!code ++]
		})
	],
});
```

One way you might use headers is by providing an authorization token via an environment variable:

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";
import { http } from "jsrepo/providers";

export default defineConfig({
	providers: [
		http({
			baseUrl: "https://myregistry.com", // [!code ++]
			headers: {  // [!code ++]
				Authorization: `Bearer ${process.env.MYREGISTRY_TOKEN}` // [!code ++]
			} // [!code ++]
		})
	],
});
```

Now anyone running `jsrepo add` will have the `Authorization` header set to the value of the `MYREGISTRY_TOKEN` environment variable when making requests to `https://myregistry.com/registry`.

================================================
FILE: apps/docs/content/docs/providers/index.mdx
================================================
---
title: Providers
description: Host your code anywhere with jsrepo.
---

Providers are how **jsrepo** knows where to find registry items. When you provide a registry identifier to a **jsrepo** command the provider is responsible for resolving that to a usable URL.

For example you might run the following command:

```sh
jsrepo init github/ieedan/std
```

In this case the `github` provider will be used to resolve the path to the `registry.json` file which might look something like this:

```plaintext
https://api.github.com/repos/ieedan/std/contents/registry.json?ref=main
```

This makes **jsrepo** more flexible than any other registry because you can host your registry anywhere.

## Available providers

<Cards>
	<Card href="/docs/providers/jsrepo" icon={<JsrepoLogo />} title="jsrepo">
		Download and add registry items from jsrepo.com
	</Card>
	<Card href="/docs/providers/github" icon={<GitHubLogo />} title="GitHub">
		Download and add registry items from a GitHub repository.
	</Card>
	<Card href="/docs/providers/gitlab" icon={<GitLabLogo />} title="GitLab">
		Download and add registry items from a GitLab repository.
	</Card>
	<Card href="/docs/providers/bitbucket" icon={<BitbucketLogo />} title="Bitbucket">
		Download and add registry items from a Bitbucket repository.
	</Card>
	<Card href="/docs/providers/azure" icon={<AzureDevopsLogo />} title="AzureDevops">
		Download and add registry items from an Azure DevOps repository.
	</Card>
	<Card href="/docs/providers/http" icon={<GlobeIcon />} title="Your Website">
		Download and add registry items from your own website.
	</Card>
	<Card href="/docs/providers/fs" icon={<FolderIcon />} title="Local Filesystem">
		Download and add registry items from your local filesystem.
	</Card>
</Cards>

You can customize the providers that **jsrepo** uses by adding them to your `jsrepo.config` file.

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";
import { github } from "jsrepo/providers"; // [!code ++]

export default defineConfig({
	providers: [github()], // [!code ++]
});
```

## Provider plugins

Provider plugins are a way to add support for additional providers to **jsrepo**.

### Adding provider plugins

You can add provider plugins by running the following command:

```sh
jsrepo config provider <plugin>
```

This will automatically install the plugin and add it to your config file:

```ts title="jsrepo.config.ts"
import { defineConfig, DEFAULT_PROVIDERS } from "jsrepo"; // [!code ++]
import myProvider from "jsrepo-provider-myprovider"; // [!code ++]

export default defineConfig({
	providers: [...DEFAULT_PROVIDERS, myProvider()], // [!code ++]
});
```

<Callout type="info">
	You will notice the addition of the `DEFAULT_PROVIDERS` object in the example above. This way you can continue to
	use all other providers alongside your provider plugin.
</Callout>


================================================
FILE: apps/docs/content/docs/providers/jsrepo.mdx
================================================
---
title: jsrepo
description: Download and add registry items from jsrepo.com
---

<BadgeGroup>
	<SourceBadge path="packages/jsrepo/src/providers/jsrepo.ts" />
	<OfficialBadge />
	<DefaultBadge />
</BadgeGroup>

**jsrepo.com** is a centralized source registry for registries. Much like npm is for packages, **jsrepo.com** is for registries.

**jsrepo.com** comes with a few added benefits over other registry providers:

-   Semver support
-   First class support for private registries with the `jsrepo auth` command
-   Discoverability of your registry through the **jsrepo.com** website (also by the jsrepo mcp agent)
-   Easier installation for your users with simple `@<scope>/<registry>` syntax

## Usage

To start adding registry items from **jsrepo.com** you can run the following command:

```sh
jsrepo add @<scope>/<registry>
```

You can also add registries at a specific version:

```sh
jsrepo add @<scope>/<registry>@1.0.0
```

## Authentication

To authenticate with jsrepo.com you can run the following command:

```sh
jsrepo auth jsrepo
```

Once authenticated you will have access to all registries associated with your account public and private as well as the ability to publish registries.

You can logout of your account by running:

```sh
jsrepo auth jsrepo --logout
```

### Environment Variable

If you prefer to use an environment variable or are in an environment where you can't use the `jsrepo auth` command you can provide the token via the `JSREPO_TOKEN` environment variable.

```sh
JSREPO_TOKEN=... jsrepo publish 
```

## Publishing your registry to jsrepo.com

Once you have authenticated you can publish your registry with the `publish` command:

```sh
jsrepo publish
```

For a more detailed guide on publishing your registry to jsrepo.com checkout the guide [here](/docs/jsrepo-com#publishing-your-registry).



================================================
FILE: apps/docs/content/docs/providers/shadcn.mdx
================================================
---
title: shadcn
description: Download and add items from the shadcn registry index.
---

import { RegistryDirectory } from "@/components/registry-index";

<BadgeGroup>
	<SourceBadge path="packages/shadcn/src/provider.ts" />
	<OfficialBadge />
</BadgeGroup>

## Usage

The **shadcn** registry index is a nice way to shorten shadcn registry urls. If you are making use of shadcn registries in your project you can use this provider to use registries by their shortened name.

Since this doesn't come by default you will need to add it to your `jsrepo.config.ts` file. You can do this with a command:

```sh
jsrepo config provider @jsrepo/shadcn
```

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";
import shadcn from "@jsrepo/shadcn"; // [!code ++]

export default defineConfig({
	providers: [shadcn()], // [!code ++]
});
```

Now you can simply use the `shadcn:` prefix followed by the registry namespace:

```sh
jsrepo add --registry shadcn:@react-bits
```

## Options

<TypeTable
	type={{
		registryIndexUrl: {
			description: "The base url of the registry index.",
			type: "string",
			default: "https://ui.shadcn.com/r/registries.json",
		},
	}}
/>

## Registry Directory

All of these registries are available to use with the **shadcn** provider.

<RegistryDirectory />

================================================
FILE: apps/docs/content/docs/transforms/biome.mdx
================================================
---
title: Biome
description: Format code before it's added to your project using Biome.
---

<BadgeGroup>
	<SourceBadge path="packages/transform-biome/src/index.ts" />
	<OfficialBadge />
	<NpmBadge packageName="@jsrepo/transform-biome" />
</BadgeGroup>

The [@jsrepo/transform-biome](https://npmjs.com/package/@jsrepo/transform-biome) package is a transform plugin for **jsrepo** that formats code using your local biome configuration before it's added to your project using [Biome](https://biomejs.dev).

<Callout type="info">
    This is especially useful when you are making use of the `jsrepo update` command as it will format the code the same way as it is in your project preventing any formatting changes from being shown in the diff.
</Callout>

## Installation

To add the **@jsrepo/transform-biome** transform to your config run the following command:

```sh
jsrepo config transform biome
```

This will automatically install the transform and add it to your config:

```ts
import { defineConfig } from "jsrepo";
import biome from "@jsrepo/transform-biome"; // [!code ++]

export default defineConfig({
	transforms: [biome()], // [!code ++]
});
```

================================================
FILE: apps/docs/content/docs/transforms/filecasing.mdx
================================================
---
title: File Casing
description: Transform file and folder names to different case formats before adding them to your project.
---

<BadgeGroup>
	<SourceBadge path="packages/transform-filecasing/src/index.ts" />
	<OfficialBadge />
	<NpmBadge packageName="@jsrepo/transform-filecasing" />
</BadgeGroup>

The [@jsrepo/transform-filecasing](https://npmjs.com/package/@jsrepo/transform-filecasing) package is a transform plugin for **jsrepo** that transforms file and folder names to different case formats before adding them to your project.

<Callout type="info">
    This is useful when your project follows a specific file or folder naming convention and you want registry items to automatically conform to it.
</Callout>

<Callout type="info">
    The transform only affects the item's relative path, not the base path configured in your jsrepo.config. For example, if your config specifies `src/lib/components/ui` as the path for components, and you add a button component, only the part after that base path is transformed: `button/index.ts` → `Button/Index.ts`, resulting in `src/lib/components/ui/Button/Index.ts`.
</Callout>

## Installation

To add the **@jsrepo/transform-filecasing** transform to your config run the following command:

```sh
jsrepo config transform filecasing
```

This will automatically install the transform and add it to your config:

```ts
import { defineConfig } from "jsrepo";
import fileCasing from "@jsrepo/transform-filecasing"; // [!code ++]

export default defineConfig({
	transforms: [fileCasing({ to: "camel" })], // [!code ++]
});
```

Now when a file is added to your project its file and folder names will be transformed to the target case format. Note that only the item's relative path is transformed, not the base path from your config:

```ts title="Config path: 'src/lib/components/ui', Item: 'button/index.ts' → Result: 'src/lib/components/ui/Button/Index.ts'"
// Config path: 'src/lib/components/ui'
// Item path: 'button/index.ts'
// Result: 'src/lib/components/ui/Button/Index.ts'
```

## Configuration

The transform accepts an options object with the following properties:

| Option | Type | Description |
|--------|------|-------------|
| `to` | `"kebab" \| "camel" \| "snake" \| "pascal"` | The target case format for file and folder names |
| `transformDirectories` | `boolean` | Whether to transform directory segments in the path. When `false`, only the filename baseName is transformed. Defaults to `true` |

### Transform Directories and Filenames (Default)

By default, both directory segments and filenames are transformed:

```ts
import { defineConfig } from "jsrepo";
import fileCasing from "@jsrepo/transform-filecasing";

export default defineConfig({
	// Config path: 'src/lib/components/ui'
	transforms: [fileCasing({ to: "pascal" })],
});
```

This will transform the item's relative path:
- Item: `button/index.ts` → Result: `src/lib/components/ui/Button/Index.ts`
- Item: `my-components/use-hook.ts` → Result: `src/lib/components/ui/MyComponents/UseHook.ts`

Note that the config path (`src/lib/components/ui`) is never transformed.

### Transform Only Filenames

To preserve directory names and only transform filenames, set `transformDirectories` to `false`:

```ts
import { defineConfig } from "jsrepo";
import fileCasing from "@jsrepo/transform-filecasing";

export default defineConfig({
	transforms: [fileCasing({ to: "camel", transformDirectories: false })],
});
```

This will transform only the filename in the item's relative path:
- Item: `my-components/use-hook.ts` → Result: `src/lib/components/ui/my-components/useHook.ts`
- Item: `button/index.ts` → Result: `src/lib/components/ui/button/index.ts`

Note that directory names in the item path are preserved, and the config path is never transformed.

<Callout type="info">
    This only transforms directories and files within added items and will never rename existing files or directories in your project.
</Callout>


================================================
FILE: apps/docs/content/docs/transforms/index.mdx
================================================
---
title: Transforms
description: Modify code before it is added to your project.
---

Transforms are a way to modify code before it's added to your project. You can use transforms to format code, add comments, or any other code modification you can think of.

Transforms are also pluggable so you can create your own and share them with the community. Here are a few of the officially supported transforms:
<Cards>
	<Card href="/docs/transforms/prettier" icon={<PrettierLogo />} title="@jsrepo/transform-prettier">
		Format code before it's added to your project using **Prettier**.
	</Card>
	<Card href="/docs/transforms/biome" icon={<BiomeLogo />} title="@jsrepo/transform-biome">
		Format code before it's added to your project using **Biome**.
	</Card>
	<Card href="/docs/transforms/oxfmt" icon={<OxfmtLogo />} title="@jsrepo/transform-oxfmt">
		Format code before it's added to your project using **oxfmt**.
	</Card>
	<Card href="/docs/transforms/javascript" icon={<JavaScriptLogo />} title="@jsrepo/transform-javascript">
		Transform TypeScript registry items into JavaScript before adding them to your project.
	</Card>
	<Card href="/docs/transforms/filecasing" title="@jsrepo/transform-filecasing">
		Transform file and folder names to different case formats before adding them to your project.
	</Card>
</Cards>

## Adding transforms

You can add transforms to your config by running the following command:

```sh
jsrepo config transform jsrepo-transform-my-transform
```

This will automatically install the transform and add it to your config:

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";
import myTransform from "jsrepo-transform-my-transform"; // [!code ++]

export default defineConfig({
	transforms: [myTransform()], // [!code ++]
});
```

## Transform authors

When creating transforms we recommend you follow a few rules:

1. Name your transform package with the following naming convention: `jsrepo-transform-<name>` or `@<org>/jsrepo-transform-<name>`
2. Export the transform as the `default` export

The name of your transform in the config will be the name of your package without the `jsrepo-transform-` prefix converted to camel case.

For example:

```plaintext
jsrepo-transform-my-transform -> myTransform
@my-org/jsrepo-transform-my-transform -> myTransform
```

Official plugins are an exception to this rule to prevent having to name packages like `@jsrepo/jsrepo-transform-prettier`. 

For instance:

```plaintext
@jsrepo/transform-prettier -> prettier
@jsrepo/transform-faster-prettier -> fasterPrettier
```

## Creating your own transform

To demonstrate the power of transforms let's create a simple transform that adds a comment at the top of each file letting the user know what registry the item was added from.

```ts title="src/transform.ts"
import type { Transform } from "jsrepo";

export default function(): Transform {
	return {
		transform: async (code, fileName, { registryUrl }) => {
			if (fileName.endsWith('.ts') || fileName.endsWith('.js')) {
				return { code: `// Added from ${registryUrl}\n\n${code}` };
			}

			// return nothing since no changes were made
			return { };
		},
	};
}
```

Now we can use the transform in our config:

```ts title="jsrepo.config.ts"
import { defineConfig } from "jsrepo";
import addComment from "./src/transform"; // [!code ++]

export default defineConfig({
	transforms: [addComment()], // [!code ++]
});
```

Now when users add items from the registry they will include the comment at the top of the file letting them know what registry the item was added from:

```ts title="src/math/add.ts"
// Added from https://example.com/registry // [!code highlight]

export function add(a: number, b: number): number {
	return a + b;
}
```


================================================
FILE: apps/docs/content/docs/transforms/javascript.mdx
================================================
---
title: JavaScript
description: Transform TypeScript registry items into JavaScript before adding them to your project.
---

<BadgeGroup>
	<SourceBadge path="packages/transform-javascript/src/index.ts" />
	<OfficialBadge />
	<NpmBadge packageName="@jsrepo/transform-javascript" />
</BadgeGroup>

The [@jsrepo/transform-javascript](https://npmjs.com/package/@jsrepo/transform-javascript) package is a transform plugin for **jsrepo** that converts TypeScript registry items into JavaScript before adding them to your project.

<Callout type="warning">
    This only works for [erasable syntax](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-8.html#the---erasablesyntaxonly-option).
</Callout>

## Installation

```sh
jsrepo config transform javascript
# or initialize any jsrepo project with the --js flag
jsrepo init @ieedan/std --js
```

This will automatically install the transform and add it to your config:

```ts
import { defineConfig } from "jsrepo";
import javascript from "@jsrepo/transform-javascript"; // [!code ++]

export default defineConfig({
	// ...
	transforms: [javascript()], // [!code ++]
});
```

This plugin will then transform any registry items written in TypeScript into JavaScript before adding them to your project.

**Before:**

```ts title="math/add.ts"
export function add(a: number, b: number): number {
	return a + b;
}
```

**After:**

```ts title="math/add.js"
export function add(a: number, b: number): number { // [!code --]
export function add(a, b) { // [!code ++]
	return a + b;
}
```

## Supported Languages

If your language of choice is not supported here feel free to contribute it!

- ✅ Full support
- ⚠️ Partial support
- ❌ No support


| Language   | Support |
|------------|---------|
| TypeScript | ✅      |
| Svelte     | ✅      |


================================================
FILE: apps/docs/content/docs/transforms/oxfmt.mdx
================================================
---
title: oxfmt
description: Format code before it's added to your project using oxfmt.
---

<BadgeGroup>
	<SourceBadge path="packages/transform-oxfmt/src/index.ts" />
	<OfficialBadge />
	<NpmBadge packageName="@jsrepo/transform-oxfmt" />
</BadgeGroup>

The [@jsrepo/transform-oxfmt](https://npmjs.com/package/@jsrepo/transform-oxfmt) package is a transform plugin for **jsrepo** that formats code using [oxfmt](https://github.com/oxc-project/oxfmt) before it's added to your project.

<Callout type="info">
    This is especially useful when you are making use of the `jsrepo update` command as it will format the code the same way as it is in your project preventing any formatting changes from being shown in the diff.
</Callout>

## Installation

To add the **@jsrepo/transform-oxfmt** transform to your config run the following command:

```sh
jsrepo config transform oxfmt
```

This will automatically install the transform and add it to your config:

```ts
import { defineConfig } from "jsrepo";
import oxfmt from "@jsrepo/transform-oxfmt"; // [!code ++]

export default defineConfig({
	transforms: [oxfmt()], // [!code ++]
});
```


================================================
FILE: apps/docs/content/docs/transforms/prettier.mdx
================================================
---
title: Prettier
description: Format code before it's added to your project using Prettier.
---

<BadgeGroup>
	<SourceBadge path="packages/transform-prettier/src/index.ts" />
	<OfficialBadge />
	<NpmBadge packageName="@jsrepo/transform-prettier" />
</BadgeGroup>

The [@jsrepo/transform-prettier](https://npmjs.com/package/@jsrepo/transform-prettier) package is a transform plugin for **jsrepo** that formats code using your local Prettier configuration before it's added to your project using [Prettier](https://prettier.io).

<Callout type="info">
    This is especially useful when you are making use of the `jsrepo update` command as it will format the code the same way as it is in your project preventing any formatting changes from being shown in the diff.
</Callout>

## Installation

To add the **@jsrepo/transform-prettier** transform to your config run the following command:

```sh
jsrepo config transform prettier
```

This will automatically install the transform and add it to your config:

```ts
import { defineConfig } from "jsrepo";
import prettier from "@jsrepo/transform-prettier"; // [!code ++]

export default defineConfig({
	transforms: [prettier()], // [!code ++]
});
```

================================================
FILE: apps/docs/instrumentation-client.js
================================================
import posthog from "posthog-js";

if (process.env.NODE_ENV === 'production') {
    posthog.init(process.env.NEXT_PUBLIC_POSTHOG_KEY, {
        api_host: process.env.NEXT_PUBLIC_POSTHOG_HOST,
        defaults: "2025-05-24"
    });
}


================================================
FILE: apps/docs/jsrepo.config.mts
================================================
import { defineConfig, DEFAULT_PROVIDERS } from "jsrepo";
import shadcn from '@jsrepo/shadcn';

export default defineConfig({
	registries: ["https://reactbits.dev/r", "https://magicui.design/r", "https://ui.shadcn.com/r/styles/new-york-v4"],
	paths: {
		component: '@/components',
		util: '@/lib/utils',
		ui: '@/components/ui',
		lib: '@/lib',
		hook: '@/hooks',
	},
	providers: [...DEFAULT_PROVIDERS, shadcn()]
});


================================================
FILE: apps/docs/middleware.ts
================================================
import { NextRequest, NextResponse } from "next/server";
import { isMarkdownPreferred, rewritePath } from "fumadocs-core/negotiation";

const { rewrite: rewriteLLM } = rewritePath("/docs/*path", "/llms.mdx/*path");

export function middleware(request: NextRequest) {
	if (isMarkdownPreferred(request)) {
		const result = rewriteLLM(request.nextUrl.pathname);

		if (result) {
			return NextResponse.rewrite(new URL(result, request.nextUrl));
		}
	}

	return NextResponse.next();
}


================================================
FILE: apps/docs/next.config.mjs
================================================
import { createMDX } from "fumadocs-mdx/next";

const withMDX = createMDX();

/** @type {import('next').NextConfig} */
const config = {
	reactStrictMode: true,
	async rewrites() {
		return [
			{
				source: "/docs/:path*.mdx",
				destination: "/llms.mdx/:path*",
			},
		];
	},
};

export default withMDX(config);


================================================
FILE: apps/docs/og-image.d.ts
================================================
/**
 * Type declarations for @vercel/og ImageResponse.
 * The `tw` prop allows Tailwind-style class names for OG image generation.
 * @see https://vercel.com/docs/og-image-generation
 */
export {};

declare module "react" {
	interface HTMLAttributes<T> {
		tw?: string;
	}
}


================================================
FILE: apps/docs/package.json
================================================
{
	"name": "@jsrepo/docs",
	"version": "0.0.0",
	"private": true,
	"scripts": {
		"build": "next build",
		"dev": "next dev --turbo",
		"start": "next start",
		"postinstall": "fumadocs-mdx"
	},
	"dependencies": {
		"@gsap/react": "^2.1.2",
		"@radix-ui/react-accordion": "^1.2.12",
		"@radix-ui/react-collapsible": "^1.1.12",
		"@radix-ui/react-label": "^2.1.8",
		"@radix-ui/react-navigation-menu": "^1.2.14",
		"@radix-ui/react-popover": "^1.1.15",
		"@radix-ui/react-presence": "^1.1.5",
		"@radix-ui/react-scroll-area": "^1.2.10",
		"@radix-ui/react-separator": "^1.1.8",
		"@radix-ui/react-slot": "^1.2.4",
		"@radix-ui/react-tabs": "^1.1.13",
		"@radix-ui/react-tooltip": "^1.2.8",
		"@shikijs/transformers": "3.14.0",
		"@tanstack/react-query": "^5.90.21",
		"class-variance-authority": "^0.7.1",
		"clsx": "^2.1.1",
		"fumadocs-core": "16.0.7",
		"fumadocs-mdx": "13.0.5",
		"fumadocs-ui": "16.0.7",
		"gsap": "^3.13.0",
		"lucide-react": "^0.575.0",
		"next": "16.1.6",
		"next-themes": "^0.4.6",
		"ogl": "^1.0.11",
		"react": "19.2.4",
		"react-dom": "19.2.4",
		"sonner": "^2.0.7",
		"tailwind-merge": "^3.5.0"
	},
	"devDependencies": {
		"@jsrepo/shadcn": "workspace:*",
		"@tailwindcss/postcss": "^4.2.0",
		"@types/mdx": "^2.0.13",
		"@types/node": "25.3.0",
		"@types/react": "^19.2.14",
		"@types/react-dom": "^19.2.3",
		"fuzzysort": "^3.1.0",
		"jsrepo": "workspace:*",
		"motion": "^12.34.3",
		"postcss": "^8.5.6",
		"posthog-js": "^1.352.0",
		"tailwindcss": "^4.2.0",
		"tw-animate-css": "^1.4.0",
		"typescript": "^5.9.3",
		"zod": "catalog:"
	}
}


================================================
FILE: apps/docs/postcss.config.mjs
================================================
export default {
  plugins: {
    '@tailwindcss/postcss': {},
  },
};


================================================
FILE: apps/docs/source.config.ts
================================================
import { defineConfig, defineDocs, frontmatterSchema, metaSchema } from "fumadocs-mdx/config";
import { remarkMdxFiles } from "fumadocs-core/mdx-plugins";

// You can customize Zod schemas for frontmatter and `meta.json` here
// see https://fumadocs.dev/docs/mdx/collections
export const docs = defineDocs({
	docs: {
		schema: frontmatterSchema,
		postprocess: {
			includeProcessedMarkdown: true,
		},
	},
	meta: {
		schema: metaSchema,
	},
});

export default defineConfig({
	mdxOptions: {
		remarkPlugins: [remarkMdxFiles],
	},
});


================================================
FILE: apps/docs/src/app/(home)/code-block.tsx
================================================
import * as Base from "fumadocs-ui/components/codeblock";
import { highlight } from "fumadocs-core/highlight";
import { type HTMLAttributes } from "react";
import { transformerNotationDiff, transformerNotationHighlight } from "@shikijs/transformers";
import { cn } from "@/lib/utils";

export async function CodeBlock({
	code,
	lang,
	className,
	...rest
}: HTMLAttributes<HTMLElement> & {
	code: string;
	lang: string;
}) {
	const rendered = await highlight(code, {
		lang,
		components: {
			pre: (props) => <Base.Pre {...props} />,
		},
		transformers: [transformerNotationDiff(), transformerNotationHighlight()],
	});

	return (
		<Base.CodeBlock className={cn("h-full my-0 [&_div.overflow-auto]:h-full", className)} {...rest}>
			{rendered}
		</Base.CodeBlock>
	);
}


================================================
FILE: apps/docs/src/app/(home)/layout.tsx
================================================
import { HomeLayout } from "@/components/layout/home";
import { baseOptions } from "@/lib/layout.shared";

export default function Layout({ children }: LayoutProps<"/">) {
	return (
		<HomeLayout
			{...baseOptions()}
			links={[
				{
					text: <>Docs</>,
					url: "/docs",
				},
			]}
		>
			{children}
		</HomeLayout>
	);
}


================================================
FILE: apps/docs/src/app/(home)/page.tsx
================================================
import Link from "next/link";
import type { Metadata } from "next";
import { Button } from "@/components/ui/button";
import { FeatureTabs, FeatureTabsList, FeatureTabsTrigger, FeatureTabsContent } from "@/components/feature-tabs";
import { AnimatedSpan, Terminal, TypingAnimation } from "@/components/ui/terminal";
import { CodeBlock } from "./code-block";
import { ProvidersSection } from "./providers-section";
import { cn } from "@/lib/utils";
import PrismaticBurst from "@/components/PrismaticBurst";
import { ExternalLinkIcon } from "lucide-react";

export const metadata: Metadata = {
	title: "jsrepo.dev - The modern registry toolchain",
	description: "jsrepo - The modern registry toolchain",
	openGraph: {
		title: "jsrepo.dev",
		description: "jsrepo - The modern registry toolchain",
		type: "website",
		siteName: "jsrepo.dev",
		images: [
			{
				url: "/og",
				width: 1200,
				height: 630,
			},
		],
	},
	twitter: {
		card: "summary_large_image",
		title: "jsrepo.dev",
		description: "jsrepo - The modern registry toolchain",
		images: [
			{
				url: "/og",
				width: 1200,
				height: 630,
			},
		],
	},
	metadataBase: new URL("https://jsrepo.dev"),
};

export default function HomePage() {
	return (
		<>
			<main className="flex flex-1 flex-col gap-12 justify-center text-center">
				<HeroSection />
				<div className="flex flex-col w-full">
					<FeatureAccordionSection />
					<div className="flex flex-col items-center justify-center border-b border-border px-6">
						<div className="max-w-6xl w-full border-x text-start p-6"></div>
					</div>
					<ProvidersSection />
					<div className="flex flex-col items-center justify-center border-b border-border px-6">
						<div className="max-w-6xl w-full border-x text-start p-6"></div>
					</div>
					<PluginsSection />
					<div className="flex flex-col items-center justify-center border-b border-border px-6">
						<div className="max-w-6xl w-full border-x text-start p-6"></div>
					</div>
					<ShadcnCompatibilitySection />
					<div className="flex flex-col items-center justify-center border-b border-border px-6">
						<div className="max-w-6xl w-full border-x text-start p-6"></div>
					</div>
					<LLMsSection />
					<div className="flex flex-col items-center justify-center border-b border-border px-6">
						<div className="max-w-6xl w-full border-x text-start p-6"></div>
					</div>
					<RestEasySection />
					<div className="flex flex-col items-center justify-center border-b border-border px-6">
						<div className="max-w-6xl w-full border-x text-start p-6"></div>
					</div>
					<div className="flex flex-col items-center justify-center border-b border-border px-6">
						<div className="max-w-6xl relative w-full border-x text-start p-10 flex items-center justify-center flex-col gap-3">
							<div className="relative z-10 flex items-center justify-center flex-col gap-3">
								<h2 className="text-2xl font-bold text-center">Ready to level up your registry?</h2>
								<Button asChild>
									<Link href="/docs/create-a-registry">Start Building</Link>
								</Button>
							</div>
							<div className="size-full absolute">
								<PrismaticBurst
									animationType="rotate3d"
									intensity={2}
									speed={0.5}
									distort={1.0}
									paused={false}
									offset={{ x: 0, y: 0 }}
									hoverDampness={0.25}
									rayCount={24}
									mixBlendMode="lighten"
									colors={["#ff007a", "#4d3dff", "#ffffff"]}
								/>
							</div>
						</div>
					</div>
				</div>
			</main>
			<div className="flex flex-col items-center px-6">
				<footer className="flex items-center justify-between py-8 w-full max-w-6xl px-6 gap-6">
					<span className="text-sm text-muted-foreground">
						© {new Date().getFullYear()} jsrepo, All rights reserved.
					</span>
					<div
						className={cn(
							"flex items-center gap-4 flex-wrap",
							"[&_a]:text-sm [&_a]:text-muted-foreground [&_a]:hover:text-primary [&_a]:hover:transition-colors"
						)}
					>
						<Link href="https://github.com/jsrepojs/jsrepo" target="_blank">
							GitHub
						</Link>
						<Link href="https://jsrepo.com">jsrepo.com</Link>
					</div>
				</footer>
			</div>
		</>
	);
}

function HeroSection() {
	return (
		<div className="flex flex-col items-center justify-center mt-[15svh]">
			<div className="flex flex-col gap-6 items-center justify-center max-w-3/4">
				<h1 className="text-balance text-4xl font-medium sm:text-5xl md:text-6xl">
					The modern registry toolchain
				</h1>
				<p className="mx-auto max-w-3xl text-pretty text-lg text-muted-foreground">
					jsrepo handles the hard parts of registries so you can focus on building.
				</p>
				<div className="flex items-center justify-center gap-2">
					<Button variant="default" asChild>
						<Link href="/docs">Get Started</Link>
					</Button>
					<Button variant="outline" asChild>
						<Link href="https://jsrepo.com/" target="_blank">
							Publish your Registry
							<ExternalLinkIcon/>
						</Link>
					</Button>
				</div>
			</div>
		</div>
	);
}

function PluginsSection() {
	return (
		<div className="flex flex-col items-center justify-center border-b border-border px-6">
			<div className="max-w-6xl w-full border-x flex flex-col text-start p-6 gap-6">
				<div className="flex flex-col items-center justify-center gap-1">
					<h2 className="text-2xl font-bold text-center">Customize your experience with plugins</h2>
					<p className="text-sm text-muted-foreground text-center">
						With a js based config the sky is the limit.
					</p>
				</div>
				<CodeBlock
					lang="ts"
					code={`import { defineConfig } from "jsrepo";
import javascript from "@jsrepo/transform-javascript";
import prettier from "@jsrepo/transform-prettier";

export default defineConfig({
	transforms: [javascript(), prettier()], // [!code highlight]
});`}
				/>
			</div>
		</div>
	);
}

function RestEasySection() {
	return (
		<div className="flex flex-col items-center justify-center border-b border-border px-6">
			<div className="max-w-6xl w-full border-x flex flex-col text-start p-6 gap-6">
				<div className="flex flex-col items-center justify-center gap-1">
					<h2 className="text-2xl font-bold text-center">Rest easy</h2>
					<p className="text-sm text-muted-foreground text-center">
						If your registry builds with jsrepo, it will work for your users.
					</p>
				</div>
				<div className="grid grid-cols-2 gap-6">
					<CodeBlock
						className="h-full"
						lang="ts"
						code={`import { createHighlighterCore } from 'shiki/core';
import { createJavaScriptRegexEngine } from 'shiki/engine/javascript';
import { customLang } from './langs/custom.ts';

export const highlighter = await createHighlighterCore({
  themes: [
    import('@shikijs/themes/nord'),
    import('@shikijs/themes/dark-plus'),
  ],
  langs: [
    import('@shikijs/langs/typescript'),
    import('@shikijs/langs/javascript'),
	customLang(),
  ],
  engine: createJavaScriptRegexEngine()
});`}
					/>
					<CodeBlock
						className="h-full"
						lang="jsonc"
						code={`{
	name: "shiki",
	files: [
		{
			path: "shiki.ts",
			content: //...,
		}
	],
	// auto detect dependencies within your registry
	registryDependencies: ['custom'],
	// automatically detect remote dependencies
	dependencies: [
		'shiki', 
		// including dynamic imports
		'@shikijs/themes', 
		'@shikijs/langs'
	]
}`}
					/>
				</div>
			</div>
		</div>
	);
}

function LLMsSection() {
	return (
		<div className="flex flex-col items-center justify-center border-b border-border px-6">
			<div className="max-w-6xl w-full border-x text-start p-6 flex flex-col gap-6">
				<div className="flex flex-col items-center justify-center gap-1">
					<h2 className="text-2xl font-bold text-center">Built for LLMs</h2>
					<p className="text-sm text-muted-foreground text-center">
						jsrepo is optimized for LLMs by giving them demos and documentation alongside registry items.
					</p>
				</div>
				<CodeBlock
					lang="ts"
					code={`import { defineConfig } from "jsrepo";

export default defineConfig({
	registry: {
		name: '@registry/kit',
		description: 'Components for your registry.',
		items: [
			{
				name: 'button',
				type: 'component',
				files: [
					{
						path: 'src/components/button.tsx',
					},
					{ // [!code highlight]
						path: 'src/demos/button.tsx', // [!code highlight]
						role: 'example', // [!code highlight]
					}, // [!code highlight]
				]
			}
		]
	}
});`}
				/>
			</div>
		</div>
	);
}

function ShadcnCompatibilitySection() {
	return (
		<div className="flex flex-col items-center justify-center border-b border-border px-6">
			<div className="max-w-6xl w-full border-x place-items-center text-start p-6 flex flex-col gap-6">
				<div className="flex flex-col items-center justify-center gap-1">
					<h2 className="text-2xl font-bold text-center">Shadcn compatible</h2>
					<p className="text-sm text-muted-foreground text-center">
						Add and update items seamlessly from shadcn registries.
					</p>
				</div>
				<Terminal startOnView={true} className="w-full max-w-2xl">
					<TypingAnimation>&gt; jsrepo add shadcn:@react-bits/AnimatedContent-TS-TW</TypingAnimation>

					<AnimatedSpan className="text-green-500">
						✔ Fetched manifest from shadcn:@react-bits/AnimatedContent-TS-TW
					</AnimatedSpan>

					<AnimatedSpan className="text-green-500">✔ Fetched AnimatedContent-TS-TW.</AnimatedSpan>

					<AnimatedSpan className="text-green-500">
						<span>Added AnimatedContent-TS-TW to your project.</span>
						<span className="pl-2">Updated 1 file.</span>
					</AnimatedSpan>
				</Terminal>
			</div>
		</div>
	);
}

function FeatureAccordionSection() {
	return (
		<div className="md:h-[368px]">
			<FeatureTabs defaultValue="config">
				<FeatureTabsList>
					<FeatureTabsTrigger
						value="config"
						duration={2150}
						description="Configure your registry in seconds."
					>
						Configure
					</FeatureTabsTrigger>
					<FeatureTabsTrigger
						value="build"
						duration={2650}
						description="Build your registry instantly and watch for changes."
					>
						Build
					</FeatureTabsTrigger>
					<FeatureTabsTrigger
						value="add"
						duration={2750}
						description="Add components to your project with a single command."
					>
						Add
					</FeatureTabsTrigger>
					<FeatureTabsTrigger
						value="update"
						duration={3150}
						description="Update components in your project with interactive diffs."
					>
						Update
					</FeatureTabsTrigger>
				</FeatureTabsList>
				<FeatureTabsContent value="config">
					<Terminal className="border-none rounded-none w-full text-start h-[368px] [&>pre]:w-full *:data-[slot='terminal-header']:hidden">
						<TypingAnimation>&gt; jsrepo init</TypingAnimation>

						<AnimatedSpan className="text-green-500">✔ Wrote config to jsrepo.config.ts</AnimatedSpan>

						<AnimatedSpan className="text-green-500">✔ Installed dependencies.</AnimatedSpan>

						<AnimatedSpan className="text-green-500">✔ Initialization complete.</AnimatedSpan>
					</Terminal>
				</FeatureTabsContent>
				<FeatureTabsContent value="build">
					<Terminal className="border-none rounded-none h-[368px] max-w-none text-start [&>pre]:w-full *:data-[slot='terminal-header']:hidden w-full">
						<TypingAnimation>&gt; jsrepo build --watch</TypingAnimation>

						<AnimatedSpan className="text-green-500" delay={10}>
							<span>✔ Finished in 10.49ms</span>
							<span className="pl-2">
								@ieedan/std: Created 1 output in 10.12ms with 3 items and 4 files.
							</span>
						</AnimatedSpan>

						<AnimatedSpan className="text-muted-foreground">Watching for changes...</AnimatedSpan>
					</Terminal>
				</FeatureTabsContent>
				<FeatureTabsContent value="add">
					<Terminal className="border-none rounded-none text-start h-[368px] [&>pre]:w-full *:data-[slot='terminal-header']:hidden w-full">
						<TypingAnimation>&gt; jsrepo add button</TypingAnimation>

						<AnimatedSpan className="text-green-500">
							✔ Fetched manifest from @ieedan/shadcn-svelte-extras
						</AnimatedSpan>

						<AnimatedSpan className="text-green-500">✔ Fetched button.</AnimatedSpan>

						<AnimatedSpan className="text-green-500">
							<span>Added button, utils to your project.</span>
							<span className="pl-2">Updated 2 files.</span>
						</AnimatedSpan>
					</Terminal>
				</FeatureTabsContent>
				<FeatureTabsContent value="update">
					<Terminal className="border-none rounded-none h-[368px] max-w-none text-start [&>pre]:w-full *:data-[slot='terminal-header']:hidden w-full">
						<TypingAnimation>&gt; jsrepo update button</TypingAnimation>

						<AnimatedSpan className="text-green-500">
							✔ Fetched manifest from @ieedan/shadcn-svelte-extras
						</AnimatedSpan>

						<AnimatedSpan className="text-green-500">✔ Fetched button.</AnimatedSpan>

						<AnimatedSpan>
							<div className="space-y-1 text-sm font-mono">
								<div className="text-muted-foreground">
									@ieedan/shadcn-svelte-extras/button {"->"} src/components/button.svelte
								</div>
								<div className="space-y-0.5 pl-4">
									<div className="text-muted-foreground">+ 20 more unchanged (-E to expand)</div>
									<div className="flex items-center gap-2">
										<span className="text-muted-foreground">21</span>
										<span className="text-foreground">
											{"    "}link: &apos;text-primary underline-offset
										</span>
									</div>
									<div className="flex items-center gap-2">
										<span className="text-muted-foreground">22</span>
										<span className="text-foreground">
											{"  "}
											{"},"}
										</span>
									</div>
									<div className="flex items-center gap-2">
										<span className="text-muted-foreground">23</span>
										<span className="text-foreground">
											{"  "}size: {"{"}
										</span>
									</div>
									<div className="flex items-center gap-2">
										<span className="text-muted-foreground">24</span>
										<span className="text-foreground">
											{"    default: 'h-10 px-"}
											<span className=" bg-red-500 text-white">3</span>
											<span className="bg-green-500 text-white">4</span>
											{" py-2',"}
										</span>
									</div>
									<div className="flex items-center gap-2">
										<span className="text-muted-foreground">25</span>
										<span className="text-foreground">
											{"    "}sm: &apos;h-9 rounded-md px-3&apos;,
										</span>
									</div>
									<div className="flex items-center gap-2">
										<span className="text-muted-foreground">26</span>
										<span className="text-foreground">
											{"    "}lg: &apos;h-11 rounded-md px-8&apos;,
										</span>
									</div>
									<div className="flex items-center gap-2">
										<span className="text-muted-foreground">27</span>
										<span className="text-foreground">{"    "}icon: &apos;h-10 w-10&apos;</span>
									</div>
									<div className="text-muted-foreground">+ 60 more unchanged (-E to expand)</div>
								</div>
							</div>
						</AnimatedSpan>

						<AnimatedSpan className="text-green-500">
							<span>Updated button, utils in your project.</span>
							<span className="pl-2">Updated 2 files.</span>
						</AnimatedSpan>
					</Terminal>
				</FeatureTabsContent>
			</FeatureTabs>
		</div>
	);
}


================================================
FILE: apps/docs/src/app/(home)/providers-section.tsx
================================================
"use client";

import { GitHubLogo, JsrepoLogo, RegistryKitLogo } from "@/components/logos";
import { AnimatedBeam } from "@/components/ui/animated-beam";
import { cn } from "@/lib/utils";
import { Folder } from "lucide-react";
import { useRef } from "react";

function Circle({ className, ...props }: React.ComponentProps<"div">) {
	return (
		<div
			className={cn(
				"rounded-full relative bg-accent z-10 [&_svg]:size-5 size-12 flex items-center justify-center",
				className
			)}
			{...props}
		/>
	);
}

export function ProvidersSection() {
	const containerRef = useRef<HTMLDivElement>(null);

	const githubRef = useRef<HTMLDivElement>(null);
	const httpRef = useRef<HTMLDivElement>(null);
	const jsrepoRef = useRef<HTMLDivElement>(null);

	const cliRef = useRef<HTMLDivElement>(null);

	const projectRef = useRef<HTMLDivElement>(null);

	return (
		<div className="flex flex-col items-center justify-center border-b border-border px-6">
			<div className="max-w-6xl w-full border-x text-start p-6 flex-col gap-6 flex">
				<div className="flex flex-col gap-1 items-center justify-center">
					<h2 className="text-2xl font-bold text-center">Host your registry anywhere</h2>
					<p className="text-sm text-muted-foreground text-center">
						Host your registry publicly or privately wherever you want.
					</p>
				</div>
				<div ref={containerRef} className="flex items-center justify-between relative overflow-hidden">
					<div className="flex flex-col items-center justify-center gap-2">
						<div
							ref={githubRef}
							className="rounded-full z-10 bg-accent px-3 py-2 flex items-center justify-center gap-2"
						>
							<GitHubLogo className="size-4" />
							<span className="text-sm text-muted-foreground">github/jsrepojs/registry-kit</span>
						</div>
						<div
							ref={jsrepoRef}
							className="rounded-full z-10 bg-accent px-3 py-2 flex items-center justify-center gap-2"
						>
							<JsrepoLogo className="size-4" />
							<span className="text-sm text-muted-foreground">@jsrepo/registry-kit</span>
						</div>
						<div
							ref={httpRef}
							className="rounded-full z-10 bg-accent px-3 py-2 flex items-center justify-center gap-2"
						>
							<RegistryKitLogo className="size-4" />
							<span className="text-sm text-muted-foreground">https://registry-kit.dev/r</span>
						</div>
					</div>

					<Circle ref={cliRef}>
						<JsrepoLogo />
					</Circle>

					<div>
						<Circle ref={projectRef}>
							<Folder className="text-muted-foreground" />
						</Circle>
					</div>

					<AnimatedBeam containerRef={containerRef} fromRef={githubRef} toRef={cliRef} />
					<AnimatedBeam containerRef={containerRef} fromRef={httpRef} toRef={cliRef} />
					<AnimatedBeam containerRef={containerRef} fromRef={jsrepoRef} toRef={cliRef} />
					<AnimatedBeam containerRef={containerRef} fromRef={projectRef} toRef={cliRef} />
				</div>
			</div>
		</div>
	);
}


================================================
FILE: apps/docs/src/app/api/search/route.ts
================================================
import { source } from '@/lib/source';
import { createFromSource } from 'fumadocs-core/search/server';

export const { GET } = createFromSource(source, {
  // https://docs.orama.com/docs/orama-js/supported-languages
  language: 'english',
});


================================================
FILE: apps/docs/src/app/app-client.tsx
================================================
"use client";

import { RootProvider } from "fumadocs-ui/provider/next";
import { QueryClientProvider, QueryClient } from "@tanstack/react-query";
import { useState } from "react";
import { useScrollToTop } from "@/hooks/use-scroll-to-top";

export function App({ children }: { children: React.ReactNode }) {
	useScrollToTop();
	const [queryClient] = useState(() => new QueryClient());

	return (
		<QueryClientProvider client={queryClient}>
			<RootProvider>{children}</RootProvider>
		</QueryClientProvider>
	);
}



================================================
FILE: apps/docs/src/app/docs/[[...slug]]/page.tsx
================================================
import { getPageImage, source } from "@/lib/source";
import { DocsBody, DocsDescription, DocsPage, DocsTitle } from "fumadocs-ui/page";
import { notFound } from "next/navigation";
import { getMDXComponents } from "@/mdx-components";
import type { Metadata } from "next";
import { createRelativeLink } from "fumadocs-ui/mdx";
import { LLMCopyButton, ViewOptions } from "@/components/page-actions";

export default async function Page(props: PageProps<"/docs/[[...slug]]">) {
	const params = await props.params;
	const page = source.getPage(params.slug);
	if (!page) notFound();

	const MDX = page.data.body;

	return (
		<div className="contents group/page">
			<DocsPage toc={page.data.toc} full={page.data.full}>
				<div className="flex gap-4 lg:flex-row flex-col lg:place-items-center lg:justify-between">
					<DocsTitle className="lg:order-1 order-2">{page.data.title}</DocsTitle>
					<div className="flex place-items-center gap-2 lg:order-2 order-1">
						<LLMCopyButton markdownUrl={`${page.url}.mdx`} />
						<ViewOptions
							markdownUrl={`${page.url}.mdx`}
							githubUrl={`https://github.com/jsrepojs/jsrepo/blob/main/apps/docs/content/docs/${page.path}`}
						/>
					</div>
				</div>
				<DocsDescription className="group-has-data-[slot='badge-group']/page:mb-0">
					{page.data.description}
				</DocsDescription>
				<DocsBody>
					<MDX
						components={getMDXComponents({
							// this allows you to link to other pages with relative file paths
							a: createRelativeLink(source, page),
						})}
					/>
				</DocsBody>
			</DocsPage>
		</div>
	);
}

export async function generateStaticParams() {
	return source.generateParams();
}

export async function generateMetadata(props: PageProps<"/docs/[[...slug]]">): Promise<Metadata> {
	const params = await props.params;
	const page = source.getPage(params.slug);
	if (!page) notFound();

	return {
		title: page.data.title,
		description: page.data.description,
		openGraph: {
			images: getPageImage(page).url,
		},
	};
}


================================================
FILE: apps/docs/src/app/docs/layout.tsx
================================================
import { DocsLayout } from 'fumadocs-ui/layouts/docs';
import { baseOptions } from '@/lib/layout.shared';
import { source } from '@/lib/source';

export default function Layout({ children }: LayoutProps<'/docs'>) {
  const base = baseOptions();
  return (
    <DocsLayout {...base} tree={source.pageTree}>
      {children}
    </DocsLayout>
  );
}


================================================
FILE: apps/docs/src/app/global.css
================================================
@import "tailwindcss";
@import "fumadocs-ui/css/neutral.css";
@import "fumadocs-ui/css/preset.css";
@import "tw-animate-css";

@custom-variant dark (&:is(.dark *));

@theme inline {
	--font-sans: "Manrope", "Manrope Fallback";
	--font-mono: "IBM Plex Mono", "IBM Plex Mono Fallback";
	--radius-sm: calc(var(--radius) - 4px);
	--radius-md: calc(var(--radius) - 2px);
	--radius-lg: var(--radius);
	--radius-xl: calc(var(--radius) + 4px);
	--color-background: var(--background);
	--color-foreground: var(--foreground);
	--color-card: var(--card);
	--color-card-foreground: var(--card-foreground);
	--color-popover: var(--popover);
	--color-popover-foreground: var(--popover-foreground);
	--color-primary: var(--primary);
	--color-primary-foreground: var(--primary-foreground);
	--color-secondary: var(--secondary);
	--color-secondary-foreground: var(--secondary-foreground);
	--color-muted: var(--muted);
	--color-muted-foreground: var(--muted-foreground);
	--color-accent: var(--accent);
	--color-accent-foreground: var(--accent-foreground);
	--color-destructive: var(--destructive);
	--color-border: var(--border);
	--color-input: var(--input);
	--color-ring: var(--ring);
	--color-chart-1: var(--chart-1);
	--color-chart-2: var(--chart-2);
	--color-chart-3: var(--chart-3);
	--color-chart-4: var(--chart-4);
	--color-chart-5: var(--chart-5);
	--color-sidebar: var(--sidebar);
	--color-sidebar-foreground: var(--sidebar-foreground);
	--color-sidebar-primary: var(--sidebar-primary);
	--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
	--color-sidebar-accent: var(--sidebar-accent);
	--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
	--color-sidebar-border: var(--sidebar-border);
	--color-sidebar-ring: var(--sidebar-ring);
}

:root {
	--radius: 0.625rem;
	--background: oklch(1 0 0);
	--foreground: oklch(0.141 0.005 285.823);
	--card: oklch(1 0 0);
	--card-foreground: oklch(0.141 0.005 285.823);
	--popover: oklch(1 0 0);
	--popover-foreground: oklch(0.141 0.005 285.823);
	--primary: oklch(0.21 0.006 285.885);
	--primary-foreground: oklch(0.985 0 0);
	--secondary: oklch(0.967 0.001 286.375);
	--secondary-foreground: oklch(0.21 0.006 285.885);
	--muted: oklch(0.967 0.001 286.375);
	--muted-foreground: oklch(0.552 0.016 285.938);
	--accent: oklch(0.967 0.001 286.375);
	--accent-foreground: oklch(0.21 0.006 285.885);
	--destructive: oklch(0.577 0.245 27.325);
	--border: oklch(0.92 0.004 286.32);
	--input: oklch(0.92 0.004 286.32);
	--ring: oklch(0.705 0.015 286.067);
	--chart-1: oklch(0.646 0.222 41.116);
	--chart-2: oklch(0.6 0.118 184.704);
	--chart-3: oklch(0.398 0.07 227.392);
	--chart-4: oklch(0.828 0.189 84.429);
	--chart-5: oklch(0.769 0.188 70.08);
	--sidebar: oklch(0.985 0 0);
	--sidebar-foreground: oklch(0.141 0.005 285.823);
	--sidebar-primary: oklch(0.21 0.006 285.885);
	--sidebar-primary-foreground: oklch(0.985 0 0);
	--sidebar-accent: oklch(0.967 0.001 286.375);
	--sidebar-accent-foreground: oklch(0.21 0.006 285.885);
	--sidebar-border: oklch(0.92 0.004 286.32);
	--sidebar-ring: oklch(0.705 0.015 286.067);
}

.dark {
	--background: oklch(0.141 0.005 285.823);
	--foreground: oklch(0.985 0 0);
	--card: oklch(0.21 0.006 285.885);
	--card-foreground: oklch(0.985 0 0);
	--popover: oklch(0.21 0.006 285.885);
	--popover-foreground: oklch(0.985 0 0);
	--primary: oklch(0.92 0.004 286.32);
	--primary-foreground: oklch(0.21 0.006 285.885);
	--secondary: oklch(0.274 0.006 286.033);
	--secondary-foreground: oklch(0.985 0 0);
	--muted: oklch(0.274 0.006 286.033);
	--muted-foreground: oklch(0.705 0.015 286.067);
	--accent: oklch(0.274 0.006 286.033);
	--accent-foreground: oklch(0.985 0 0);
	--destructive: oklch(0.704 0.191 22.216);
	--border: oklch(1 0 0 / 10%);
	--input: oklch(1 0 0 / 15%);
	--ring: oklch(0.552 0.016 285.938);
	--chart-1: oklch(0.488 0.243 264.376);
	--chart-2: oklch(0.696 0.17 162.48);
	--chart-3: oklch(0.769 0.188 70.08);
	--chart-4: oklch(0.627 0.265 303.9);
	--chart-5: oklch(0.645 0.246 16.439);
	--sidebar: oklch(0.21 0.006 285.885);
	--sidebar-foreground: oklch(0.985 0 0);
	--sidebar-primary: oklch(0.488 0.243 264.376);
	--sidebar-primary-foreground: oklch(0.985 0 0);
	--sidebar-accent: oklch(0.274 0.006 286.033);
	--sidebar-accent-foreground: oklch(0.985 0 0);
	--sidebar-border: oklch(1 0 0 / 10%);
	--sidebar-ring: oklch(0.552 0.016 285.938);
}

@layer base {
	* {
		@apply border-border outline-ring/50;
	}
	body {
		@apply bg-background text-foreground;
	}
	/* Apply monospace font to all code blocks */
	pre,
	code,
	[data-codeblock],
	.fd-codeblock pre,
	.fd-codeblock code {
		font-family: var(--font-mono), ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, 'Liberation Mono', monospace;
	}
}

/* For components that need horizontal scrolling */
.scrollbar-hide {
	-ms-overflow-style: none; /* Internet Explorer and Edge */
	scrollbar-width: none; /* Firefox */
}

.scrollbar-hide::-webkit-scrollbar {
	display: none; /* Chrome, Safari, and Opera */
}

================================================
FILE: apps/docs/src/app/layout.tsx
================================================
import "@/app/global.css";
import { Manrope, IBM_Plex_Mono } from "next/font/google";
import { App } from "./app-client";

const fontSans = Manrope({
	subsets: ["latin"],
	variable: "--font-sans",
});

const fontMono = IBM_Plex_Mono({
	subsets: ["latin"],
	variable: "--font-mono",
	weight: ["400", "500", "600", "700"],
});

export default function Layout({ children }: LayoutProps<"/">) {
	return (
		<html
			lang="en"
			className={`${fontSans.className} ${fontSans.variable} ${fontMono.variable}`}
			suppressHydrationWarning
		>
			<body className="flex flex-col min-h-screen">
				<App>{children}</App>
			</body>
		</html>
	);
}


================================================
FILE: apps/docs/src/app/llms-full.txt/route.ts
================================================
import { getLLMText, source } from '@/lib/source';

export const revalidate = false;

export async function GET() {
  const scan = source.getPages().map(getLLMText);
  const scanned = await Promise.all(scan);

  return new Response(scanned.join('\n\n'));
}


================================================
FILE: apps/docs/src/app/llms.mdx/[[...slug]]/route.ts
================================================
import { getLLMText } from "@/lib/source";
import { source } from "@/lib/source";
import { notFound } from "next/navigation";

export const revalidate = false;

export async function GET(_req: Request, { params }: RouteContext<"/llms.mdx/[[...slug]]">) {
	const { slug } = await params;
	const page = source.getPage(slug);
	if (!page) notFound();

	return new Response(await getLLMText(page), {
		headers: {
			"Content-Type": "text/markdown",
		},
	});
}

export function generateStaticParams() {
	return source.generateParams();
}


================================================
FILE: apps/docs/src/app/og/docs/[...slug]/route.tsx
================================================
import { getPageImage, source } from "@/lib/source";
import { notFound } from "next/navigation";
import { ImageResponse } from "next/og";
import { loadGoogleFont } from "@/lib/og";

export const revalidate = false;

export async function GET(_req: Request, { params }: RouteContext<"/og/docs/[...slug]">) {
	const { slug } = await params;
	const page = source.getPage(slug.slice(0, -1));
	if (!page) notFound();

	return new ImageResponse(
    (
      <div tw="flex flex-col gap-2 items-center justify-center w-[1200px] h-[630px] bg-[#1b1c1e]">
        <div tw="flex rounded-full text-black bg-yellow-500 px-2 py-1">
					jsrepo.dev
				</div>
				<h1 tw="text-8xl font-bold text-white">
					$ <span tw="text-yellow-500 mx-6">{page.data.title}</span>
					<div tw="h-lh bg-white w-8 ml-1"></div>
				</h1>
				<p tw="text-3xl font-bold text-white/50">
					{page.data.description}
				</p>
			</div>
    ),
		{
			width: 1200,
			height: 630,
			fonts: [
				{
					name: "IBM Plex Mono",
					data: await loadGoogleFont("IBM Plex Mono", "$ jsrepo.dev" + page.data.title + page.data.description),
					style: "normal",
				},
			],
		}
	);
}

export function generateStaticParams() {
	return source.getPages().map((page) => ({
		lang: page.locale,
		slug: getPageImage(page).segments,
	}));
}


================================================
FILE: apps/docs/src/app/og/route.tsx
================================================
import { loadGoogleFont } from "@/lib/og";
import { ImageResponse } from "next/og";

export const revalidate = false;

export async function GET() {
	const title = "jsrepo";
	const description = "The modern registry toolchain.";

	return new ImageResponse(
		(
			<div tw="flex flex-col gap-2 items-center justify-center w-[1200px] h-[630px] bg-[#1b1c1e]">
				<div tw="flex rounded-full text-black bg-yellow-500 px-2 py-1">
					jsrepo.dev
				</div>
				<h1 tw="text-8xl font-bold text-white">
					$ <span tw="text-yellow-500 mx-6">{title}</span>
					<div tw="h-lh bg-white w-8 ml-1"></div>
				</h1>
				<p tw="text-3xl font-bold text-white/50">
					{description}
				</p>
			</div>
		),
		{
			width: 1200,
			height: 630,
			fonts: [
				{
					name: "IBM Plex Mono",
					data: await loadGoogleFont("IBM Plex Mono", "$ jsrepo.dev" + title + description),
					style: "normal",
				},
			],
		}
	);
}


================================================
FILE: apps/docs/src/app/robots.txt
================================================
# allow crawling everything by default
User-agent: *
Disallow:

================================================
FILE: apps/docs/src/components/PrismaticBurst.tsx
================================================
'use client';

import React, { useEffect, useRef } from 'react';
import { Renderer, Program, Mesh, Triangle, Texture } from 'ogl';

type Offset = { x?: number | string; y?: number | string };
type AnimationType = 'rotate' | 'rotate3d' | 'hover';

export type PrismaticBurstProps = {
  intensity?: number;
  speed?: number;
  animationType?: AnimationType;
  colors?: string[];
  distort?: number;
  paused?: boolean;
  offset?: Offset;
  hoverDampness?: number;
  rayCount?: number;
  mixBlendMode?: React.CSSProperties['mixBlendMode'] | 'none';
};

const vertexShader = `#version 300 es
in vec2 position;
in vec2 uv;
out vec2 vUv;
void main() {
    vUv = uv;
    gl_Position = vec4(position, 0.0, 1.0);
}
`;

const fragmentShader = `#version 300 es
precision highp float;
precision highp int;

out vec4 fragColor;

uniform vec2  uResolution;
uniform float uTime;

uniform float uIntensity;
uniform float uSpeed;
uniform int   uAnimType;
uniform vec2  uMouse;
uniform int   uColorCount;
uniform float uDistort;
uniform vec2  uOffset;
uniform sampler2D uGradient;
uniform float uNoiseAmount;
uniform int   uRayCount;

float hash21(vec2 p){
    p = floor(p);
    float f = 52.9829189 * fract(dot(p, vec2(0.065, 0.005)));
    return fract(f);
}

mat2 rot30(){ return mat2(0.8, -0.5, 0.5, 0.8); }

float layeredNoise(vec2 fragPx){
    vec2 p = mod(fragPx + vec2(uTime * 30.0, -uTime * 21.0), 1024.0);
    vec2 q = rot30() * p;
    float n = 0.0;
    n += 0.40 * hash21(q);
    n += 0.25 * hash21(q * 2.0 + 17.0);
    n += 0.20 * hash21(q * 4.0 + 47.0);
    n += 0.10 * hash21(q * 8.0 + 113.0);
    n += 0.05 * hash21(q * 16.0 + 191.0);
    return n;
}

vec3 rayDir(vec2 frag, vec2 res, vec2 offset, float dist){
    float focal = res.y * max(dist, 1e-3);
    return normalize(vec3(2.0 * (frag - offset) - res, focal));
}

float edgeFade(vec2 frag, vec2 res, vec2 offset){
    vec2 toC = frag - 0.5 * res - offset;
    float r = length(toC) / (0.5 * min(res.x, res.y));
    float x = clamp(r, 0.0, 1.0);
    float q = x * x * x * (x * (x * 6.0 - 15.0) + 10.0);
    float s = q * 0.5;
    s = pow(s, 1.5);
    float tail = 1.0 - pow(1.0 - s, 2.0);
    s = mix(s, tail, 0.2);
    float dn = (layeredNoise(frag * 0.15) - 0.5) * 0.0015 * s;
    return clamp(s + dn, 0.0, 1.0);
}

mat3 rotX(float a){ float c = cos(a), s = sin(a); return mat3(1.0,0.0,0.0, 0.0,c,-s, 0.0,s,c); }
mat3 rotY(float a){ float c = cos(a), s = sin(a); return mat3(c,0.0,s, 0.0,1.0,0.0, -s,0.0,c); }
mat3 rotZ(float a){ float c = cos(a), s = sin(a); return mat3(c,-s,0.0, s,c,0.0, 0.0,0.0,1.0); }

vec3 sampleGradient(float t){
    t = clamp(t, 0.0, 1.0);
    return texture(uGradient, vec2(t, 0.5)).rgb;
}

vec2 rot2(vec2 v, float a){
    float s = sin(a), c = cos(a);
    return mat2(c, -s, s, c) * v;
}

float bendAngle(vec3 q, float t){
    float a = 0.8 * sin(q.x * 0.55 + t * 0.6)
            + 0.7 * sin(q.y * 0.50 - t * 0.5)
            + 0.6 * sin(q.z * 0.60 + t * 0.7);
    return a;
}

void main(){
    vec2 frag = gl_FragCoord.xy;
    float t = uTime * uSpeed;
    float jitterAmp = 0.1 * clamp(uNoiseAmount, 0.0, 1.0);
    vec3 dir = rayDir(frag, uResolution, uOffset, 1.0);
    float marchT = 0.0;
    vec3 col = vec3(0.0);
    float n = layeredNoise(frag);
    vec4 c = cos(t * 0.2 + vec4(0.0, 33.0, 11.0, 0.0));
    mat2 M2 = mat2(c.x, c.y, c.z, c.w);
    float amp = clamp(uDistort, 0.0, 50.0) * 0.15;

    mat3 rot3dMat = mat3(1.0);
    if(uAnimType == 1){
      vec3 ang = vec3(t * 0.31, t * 0.21, t * 0.17);
      rot3dMat = rotZ(ang.z) * rotY(ang.y) * rotX(ang.x);
    }
    mat3 hoverMat = mat3(1.0);
    if(uAnimType == 2){
      vec2 m = uMouse * 2.0 - 1.0;
      vec3 ang = vec3(m.y * 0.6, m.x * 0.6, 0.0);
      hoverMat = rotY(ang.y) * rotX(ang.x);
    }

    for (int i = 0; i < 44; ++i) {
        vec3 P = marchT * dir;
        P.z -= 2.0;
        float rad = length(P);
        vec3 Pl = P * (10.0 / max(rad, 1e-6));

        if(uAnimType == 0){
            Pl.xz *= M2;
        } else if(uAnimType == 1){
      Pl = rot3dMat * Pl;
        } else {
      Pl = hoverMat * Pl;
        }

        float stepLen = min(rad - 0.3, n * jitterAmp) + 0.1;

        float grow = smoothstep(0.35, 3.0, marchT);
        float a1 = amp * grow * bendAngle(Pl * 0.6, t);
        float a2 = 0.5 * amp * grow * bendAngle(Pl.zyx * 0.5 + 3.1, t * 0.9);
        vec3 Pb = Pl;
        Pb.xz = rot2(Pb.xz, a1);
        Pb.xy = rot2(Pb.xy, a2);

        float rayPattern = smoothstep(
            0.5, 0.7,
            sin(Pb.x + cos(Pb.y) * cos(Pb.z)) *
            sin(Pb.z + sin(Pb.y) * cos(Pb.x + t))
        );

        if (uRayCount > 0) {
            float ang = atan(Pb.y, Pb.x);
            float comb = 0.5 + 0.5 * cos(float(uRayCount) * ang);
            comb = pow(comb, 3.0);
            rayPattern *= smoothstep(0.15, 0.95, comb);
        }

        vec3 spectralDefault = 1.0 + vec3(
            cos(marchT * 3.0 + 0.0),
            cos(marchT * 3.0 + 1.0),
            cos(marchT * 3.0 + 2.0)
        );

        float saw = fract(marchT * 0.25);
        float tRay = saw * saw * (3.0 - 2.0 * saw);
        vec3 userGradient = 2.0 * sampleGradient(tRay);
        vec3 spectral = (uColorCount > 0) ? userGradient : spectralDefault;
        vec3 base = (0.05 / (0.4 + stepLen))
                  * smoothstep(5.0, 0.0, rad)
                  * spectral;

        col += base * rayPattern;
        marchT += stepLen;
    }

    col *= edgeFade(frag, uResolution, uOffset);
    col *= uIntensity;

    fragColor = vec4(clamp(col, 0.0, 1.0), 1.0);
}`;

const hexToRgb01 = (hex: string): [number, number, number] => {
  let h = hex.trim();
  if (h.startsWith('#')) h = h.slice(1);
  if (h.length === 3) {
    const r = h[0],
      g = h[1],
      b = h[2];
    h = r + r + g + g + b + b;
  }
  const intVal = parseInt(h, 16);
  if (isNaN(intVal) || (h.length !== 6 && h.length !== 8)) return [1, 1, 1];
  const r = ((intVal >> 16) & 255) / 255;
  const g = ((intVal >> 8) & 255) / 255;
  const b = (intVal & 255) / 255;
  return [r, g, b];
};

const toPx = (v: number | string | undefined): number => {
  if (v == null) return 0;
  if (typeof v === 'number') return v;
  const s = String(v).trim();
  const num = parseFloat(s.replace('px', ''));
  return isNaN(num) ? 0 : num;
};

const PrismaticBurst = ({
  intensity = 2,
  speed = 0.5,
  animationType = 'rotate3d',
  colors,
  distort = 0,
  paused = false,
  offset = { x: 0, y: 0 },
  hoverDampness = 0,
  rayCount,
  mixBlendMode = 'lighten'
}: PrismaticBurstProps) => {
  const containerRef = useRef<HTMLDivElement>(null);
  const programRef = useRef<Program | null>(null);
  const rendererRef = useRef<Renderer | null>(null);
  const mouseTargetRef = useRef<[number, number]>([0.5, 0.5]);
  const mouseSmoothRef = useRef<[number, number]>([0.5, 0.5]);
  const pausedRef = useRef<boolean>(paused);
  const gradTexRef = useRef<Texture | null>(null);
  const hoverDampRef = useRef<number>(hoverDampness);
  const isVisibleRef = useRef<boolean>(true);
  const meshRef = useRef<Mesh | null>(null);
  const triRef = useRef<Triangle | null>(null);

  useEffect(() => {
    pausedRef.current = paused;
  }, [paused]);
  useEffect(() => {
    hoverDampRef.current = hoverDampness;
  }, [hoverDampness]);

  useEffect(() => {
    const container = containerRef.current;
    if (!container) return;

    const dpr = Math.min(window.devicePixelRatio || 1, 2);
    const renderer = new Renderer({ dpr, alpha: false, antialias: false });
    rendererRef.current = renderer;

    const gl = renderer.gl;
    gl.canvas.style.position = 'absolute';
    gl.canvas.style.inset = '0';
    gl.canvas.style.width = '100%';
    gl.canvas.style.height = '100%';
    gl.canvas.style.mixBlendMode = mixBlendMode && mixBlendMode !== 'none' ? mixBlendMode : '';
    container.appendChild(gl.canvas);

    const white = new Uint8Array([255, 255, 255, 255]);
    const gradientTex = new Texture(gl, {
      image: white,
      width: 1,
      height: 1,
      generateMipmaps: false,
      flipY: false
    });

    gradientTex.minFilter = gl.LINEAR;
    gradientTex.magFilter = gl.LINEAR;
    gradientTex.wrapS = gl.CLAMP_TO_EDGE;
    gradientTex.wrapT = gl.CLAMP_TO_EDGE;
    gradTexRef.current = gradientTex;

    const program = new Program(gl, {
      vertex: vertexShader,
      fragment: fragmentShader,
      uniforms: {
        uResolution: { value: [1, 1] as [number, number] },
        uTime: { value: 0 },

        uIntensity: { value: 1 },
        uSpeed: { value: 1 },
        uAnimType: { value: 0 },
        uMouse: { value: [0.5, 0.5] as [number, number] },
        uColorCount: { value: 0 },
        uDistort: { value: 0 },
        uOffset: { value: [0, 0] as [number, number] },
        uGradient: { value: gradientTex },
        uNoiseAmount: { value: 0.8 },
        uRayCount: { value: 0 }
      }
    });

    programRef.current = program;

    const triangle = new Triangle(gl);
    const mesh = new Mesh(gl, { geometry: triangle, program });
    triRef.current = triangle;
    meshRef.current = mesh;

    const resize = () => {
      const w = container.clientWidth || 1;
      const h = container.clientHeight || 1;
      renderer.setSize(w, h);
      program.uniforms.uResolution.value = [gl.drawingBufferWidth, gl.drawingBufferHeight];
    };

    let ro: ResizeObserver | null = null;
    if ('ResizeObserver' in window) {
      ro = new ResizeObserver(resize);
      ro.observe(container);
    } else {
      (window as Window).addEventListener('resize', resize);
    }
    resize();

    const onPointer = (e: PointerEvent) => {
      const rect = container.getBoundingClientRect();
      const x = (e.clientX - rect.left) / Math.max(rect.width, 1);
      const y = (e.clientY - rect.top) / Math.max(rect.height, 1);
      mouseTargetRef.current = [Math.min(Math.max(x, 0), 1), Math.min(Math.max(y, 0), 1)];
    };
    container.addEventListener('pointermove', onPointer, { passive: true });

    let io: IntersectionObserver | null = null;
    if ('IntersectionObserver' in window) {
      io = new IntersectionObserver(
        entries => {
          if (entries[0]) isVisibleRef.current = entries[0].isIntersecting;
        },
        { root: null, threshold: 0.01 }
      );
      io.observe(container);
    }
    const onVis = () => {};
    document.addEventListener('visibilitychange', onVis);

    let raf = 0;
    let last = performance.now();
    let accumTime = 0;

    const update = (now: number) => {
      const dt = Math.max(0, now - last) * 0.001;
      last = now;
      const visible = isVisibleRef.current && !document.hidden;
      if (!pausedRef.current) accumTime += dt;
      if (!visible) {
        raf = requestAnimationFrame(update);
        return;
      }
      const tau = 0.02 + Math.max(0, Math.min(1, hoverDampRef.current)) * 0.5;
      const alpha = 1 - Math.exp(-dt / tau);
      const tgt = mouseTargetRef.current;
      const sm = mouseSmoothRef.current;
      sm[0] += (tgt[0] - sm[0]) * alpha;
      sm[1] += (tgt[1] - sm[1]) * alpha;
      program.uniforms.uMouse.value = sm as any;
      program.uniforms.uTime.value = accumTime;
      renderer.render({ scene: meshRef.current! });
      raf = requestAnimationFrame(update);
    };
    raf = requestAnimationFrame(update);

    return () => {
      cancelAnimationFrame(raf);
      container.removeEventListener('pointermove', onPointer);
      ro?.disconnect();
      if (!ro) window.removeEventListener('resize', resize);
      io?.disconnect();
      document.removeEventListener('visibilitychange', onVis);
      try {
        container.removeChild(gl.canvas);
      } catch (e) {
        void e;
      }
      meshRef.current = null;
      triRef.current = null;
      programRef.current = null;
      try {
        const glCtx = rendererRef.current?.gl;
        if (glCtx && gradTexRef.current?.texture) glCtx.deleteTexture(gradTexRef.current.texture);
      } catch (e) {
        void e;
      }
      rendererRef.current = null;
      gradTexRef.current = null;
    };
  }, []);

  useEffect(() => {
    const canvas = rendererRef.current?.gl?.canvas as HTMLCanvasElement | undefined;
    if (canvas) {
      canvas.style.mixBlendMode = mixBlendMode && mixBlendMode !== 'none' ? mixBlendMode : '';
    }
  }, [mixBlendMode]);

  useEffect(() => {
    const program = programRef.current;
    const renderer = rendererRef.current;
    const gradTex = gradTexRef.current;
    if (!program || !renderer || !gradTex) return;

    program.uniforms.uIntensity.value = intensity ?? 1;
    program.uniforms.uSpeed.value = speed ?? 1;

    const animTypeMap: Record<AnimationType, number> = {
      rotate: 0,
      rotate3d: 1,
      hover: 2
    };
    program.uniforms.uAnimType.value = animTypeMap[animationType ?? 'rotate'];

    program.uniforms.uDistort.value = typeof distort === 'number' ? distort : 0;

    const ox = toPx(offset?.x);
    const oy = toPx(offset?.y);
    program.uniforms.uOffset.value = [ox, oy];
    program.uniforms.uRayCount.value = Math.max(0, Math.floor(rayCount ?? 0));

    let count = 0;
    if (Array.isArray(colors) && colors.length > 0) {
      const gl = renderer.gl;
      const capped = colors.slice(0, 64);
      count = capped.length;
      const data = new Uint8Array(count * 4);
      for (let i = 0; i < count; i++) {
        const [r, g, b] = hexToRgb01(capped[i]);
        data[i * 4 + 0] = Math.round(r * 255);
        data[i * 4 + 1] = Math.round(g * 255);
        data[i * 4 + 2] = Math.round(b * 255);
        data[i * 4 + 3] = 255;
      }
      gradTex.image = data;
      gradTex.width = count;
      gradTex.height = 1;
      gradTex.minFilter = gl.LINEAR;
      gradTex.magFilter = gl.LINEAR;
      gradTex.wrapS = gl.CLAMP_TO_EDGE;
      gradTex.wrapT = gl.CLAMP_TO_EDGE;
      gradTex.flipY = false;
      gradTex.generateMipmaps = false;
      gradTex.format = gl.RGBA;
      gradTex.type = gl.UNSIGNED_BYTE;
      gradTex.needsUpdate = true;
    } else {
      count = 0;
    }
    program.uniforms.uColorCount.value = count;
  }, [intensity, speed, animationType, colors, distort, offset, rayCount]);

  return <div className="w-full h-full relative overflow-hidden" ref={containerRef} />;
};

export default PrismaticBurst;


================================================
FILE: apps/docs/src/components/badges-table.tsx
================================================
"use client";

import React from "react";
import { Table, TableHeader, TableRow, TableHead, TableBody, TableCell } from "@/components/ui/table";
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
import { CheckIcon, CopyIcon, EllipsisIcon } from "lucide-react";
import { Button, buttonVariants } from "./ui/button";
import { Input } from "./ui/input";
import { useCopyToClipboard } from "@/hooks/use-copy-to-clipboard";
import { Label } from "@/components/ui/label";

type Props = {
	badges: { alt: string; hrefTemplate: string }[];
	defaultRegistry: string;
};

function buildBadgeUrl(template: string, registry: string) {
	return template.replace("{{registry}}", registry);
}

type RegistryContextType = {
    registry: string;
    setRegistry: (registry: string) => void;
}
export const RegistryContext = React.createContext<RegistryContextType>({
    registry: "",
    setRegistry: () => {},
});

export function useRegistry() {
    const ctx = React.useContext(RegistryContext);
    if (!ctx) throw new Error("RegistryContext not found");
    return ctx;
}

export function BadgesTable({ badges, defaultRegistry }: Props) {
    const [registry, setRegistry] = React.useState<string>(defaultRegistry);
    const ctx = React.useMemo(() => ({ registry, setRegistry }), [registry, setRegistry]);
	return (
		<RegistryContext value={ctx}>
            <Table>
			<TableHeader>
				<TableRow>
					<TableHead>Badge</TableHead>
					<TableHead></TableHead>
				</TableRow>
			</TableHeader>
			<TableBody>
				{badges.map((badge) => (
					<TableRow key={badge.alt}>
						<TableCell>
							<img
								src={buildBadgeUrl(badge.hrefTemplate, defaultRegistry)}
								alt={badge.alt}
								height={20}
								className="not-prose"
							/>
						</TableCell>
						<TableCell>
							<BadgeActions badge={badge} />
						</TableCell>
					</TableRow>
				))}
			</TableBody>
		</Table>
        </RegistryContext>
	);
}

export function BadgeActions({ badge }: { badge: { alt: string; hrefTemplate: string } }) {
	const [copy, isCopied] = useCopyToClipboard();
	const [copyUrl, isUrlCopied] = useCopyToClipboard();
    const { registry, setRegistry } = useRegistry();

	return (
		<Popover>
			<PopoverTrigger className={buttonVariants({ variant: "ghost" })}>
				<EllipsisIcon />
			</PopoverTrigger>
			<PopoverContent align="end">
				<div className="flex flex-col gap-2">
					<div className="flex flex-col gap-2">
						<Label>Registry</Label>
						<Input
							placeholder="@<scope>/<registry>"
							value={registry}
							onChange={(e) => setRegistry(e.target.value)}
						/>
					</div>
					<div className="flex flex-col gap-2">
						<Label>Preview</Label>
						<div className="p-2 border rounded-md h-9">
							{registry === "" ? (
								<></>
							) : (
								<img
									src={buildBadgeUrl(badge.hrefTemplate, registry)}
									alt={badge.alt}
									height={20}
									className="not-prose"
								/>
							)}
						</div>
					</div>
					<Button
						variant="outline"
						className="w-full"
                        disabled={registry === ""}
						onClick={() => copyUrl(buildBadgeUrl(badge.hrefTemplate, registry))}
					>
						{isUrlCopied ? (
							<>
								<CheckIcon /> <span>Copied</span>
							</>
						) : (
							<>
								<CopyIcon /> <span>Copy URL</span>
							</>
						)}
					</Button>
					<Button
						variant="outline"
						className="w-full"
						disabled={registry === ""}
						onClick={() => copy(buildBadgeUrl(badge.hrefTemplate, registry))}
					>
						{isCopied ? (
							<>
								<CheckIcon /> <span>Copied</span>
							</>
						) : (
							<>
								<CopyIcon /> <span>Copy Markdown</span>
							</>
						)}
					</Button>
				</div>
			</PopoverContent>
		</Popover>
	);
}


================================================
FILE: apps/docs/src/components/feature-tabs.tsx
================================================
"use client";

import { cn } from "@/lib/utils";
import React, { createContext, useContext, useEffect, useMemo, useState } from "react";

type FeatureTabsContext = {
	activeTab: string;
	setActiveTab: (tab: string, fromUser?: boolean) => void;
	tabs: { value: string; duration: number }[];
	registerTab: (tab: { value: string; duration: number }) => void;
	mode: "auto" | "manual";
};

const FeatureTabsContext = createContext<FeatureTabsContext>({
	activeTab: "",
	setActiveTab: () => {},
	tabs: [],
	registerTab: () => {},
	mode: "auto",
});

function useFeatureTabs() {
	const ctx = useContext(FeatureTabsContext);
	if (!ctx) throw new Error("FeatureTabsContext not found");
	return ctx;
}

function FeatureTabs({
	defaultValue,
	className,
	children,
	subClassName,
	...props
}: React.HTMLAttributes<HTMLDivElement> & { defaultValue: string; subClassName?: string }) {
	const [activeTab, setActiveTab] = useState(defaultValue);
	const [mode, setMode] = useState<"auto" | "manual">("auto");
	const [tabs, setTabs] = useState<{ value: string; duration: number }[]>([]);
	function registerTab(tab: { value: string; duration: number }) {
		setTabs((prev) => [...prev, tab]);
	}
	function _setActiveTab(tab: string, fromUser: boolean = false) {
		if (fromUser) {
			setMode("manual");
		}
		setActiveTab(tab);
	}
	const ctx = useMemo(
		() => ({ activeTab, setActiveTab: _setActiveTab, tabs, registerTab, mode }),
		[activeTab, tabs, mode]
	);
	useEffect(() => {
		if (mode === "manual" || tabs.length === 0) return;

		const t = tabs.map((tab, i) => ({ tab, index: i })).find(({ tab }) => tab.value === activeTab);
		if (!t) return;

		const { index, tab } = t;
		const timeoutId = setTimeout(() => {
			if (index + 1 === tabs.length) {
				_setActiveTab(tabs[0].value, false);
			} else {
				_setActiveTab(tabs[index + 1].value, false);
			}
		}, tab.duration);

		return () => clearTimeout(timeoutId);
	}, [activeTab, mode, tabs]);
	return (
		<FeatureTabsContext value={ctx}>
			<div
				className={cn("flex items-center justify-center w-full border-y border-border px-6", className)}
				{...props}
			>
				<div
					className={cn(
						"max-w-6xl flex flex-col border-x border-border md:grid md:grid-cols-2 w-full",
						subClassName
					)}
				>
					{children}
				</div>
			</div>
		</FeatureTabsContext>
	);
}

function FeatureTabsList({ className, children, ...props }: React.HTMLAttributes<HTMLDivElement>) {
	return (
		<div
			className={cn(
				"flex flex-col md:h-[368px] border-border border-b md:border-b-0 md:border-r w-full",
				className
			)}
			{...props}
		>
			{children}
		</div>
	);
}

function FeatureTabsTrigger({
	value,
	duration,
	description,
	className,
	children,
	...props
}: React.HTMLAttributes<HTMLButtonElement> & { value: string; duration: number; description: string }) {
	const { registerTab, setActiveTab, activeTab } = useFeatureTabs();

	// we don't want to re-register the tab if the value changes
	useEffect(() => {
		registerTab({ value, duration });
	}, []);

	return (
		<div
			className="group border-border border-b last:border-b-0"
			data-value={value}
			data-state={activeTab === value ? "active" : "inactive"}
		>
			<button
				type="button"
				className={cn(
					"border-border py-4 px-6 transition-all duration-700 group w-full flex items-center gap-4",
					className
				)}
				onClick={() => setActiveTab(value, true)}
				{...props}
			>
				<div className="size-6 border p-1">
					<div className="size-full group-hover:bg-primary/50 group-data-[state=active]:bg-primary transition-colors duration-300"></div>
				</div>
				{children}
			</button>
			<div
				className={cn(
					"hidden md:block px-6 [--radix-accordion-content-height:144px] duration-300 h-0",
					"group-data-[state=inactive]:py-0 group-data-[state=active]:py-4 group-data-[state=inactive]:h-0",
					"group-data-[state=active]:h-[144px] group-data-[state=inactive]:animate-accordion-up group-data-[state=active]:animate-accordion-down",
				)}
			>
				<p className="text-start text-muted-foreground group-data-[state=inactive]:hidden">{description}</p>
			</div>
		</div>
	);
}

function FeatureTabsContent({
	value,
	className,
	children,
	...props
}: React.HTMLAttributes<HTMLDivElement> & { value: string }) {
	const { activeTab } = useFeatureTabs();
	return activeTab !== value ? (
		<></>
	) : (
		<div className={cn("w-full bg-card", className)} {...props}>
			{children}
		</div>
	);
}

export { FeatureTabs, FeatureTabsList, FeatureTabsTrigger, FeatureTabsContent };


================================================
FILE: apps/docs/src/components/files.tsx
================================================
'use client';

import { cva } from 'class-variance-authority';
import {
  FileIcon as LucideFileIcon,
  FolderIcon,
  FolderOpenIcon,
} from 'lucide-react';
import { type HTMLAttributes, type ReactNode, use
Download .txt
gitextract__1f43wdr/

├── .changeset/
│   └── config.json
├── .github/
│   └── workflows/
│       ├── build-example-registries.yml
│       ├── bundle-analyze.yml
│       ├── ci.yml
│       ├── cli-preview.yml
│       ├── publish.yml
│       └── test-external-projects.yml
├── .gitignore
├── .vscode/
│   └── settings.json
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── apps/
│   └── docs/
│       ├── .gitignore
│       ├── README.md
│       ├── biome.json
│       ├── cli.json
│       ├── content/
│       │   └── docs/
│       │       ├── cli/
│       │       │   ├── add.mdx
│       │       │   ├── auth.mdx
│       │       │   ├── build.mdx
│       │       │   ├── config/
│       │       │   │   ├── language.mdx
│       │       │   │   ├── mcp.mdx
│       │       │   │   ├── meta.json
│       │       │   │   ├── provider.mdx
│       │       │   │   └── transform.mdx
│       │       │   ├── meta.json
│       │       │   ├── publish.mdx
│       │       │   └── update.mdx
│       │       ├── create-a-registry.mdx
│       │       ├── index.mdx
│       │       ├── jsrepo-com.mdx
│       │       ├── jsrepo-config.mdx
│       │       ├── languages/
│       │       │   ├── css.mdx
│       │       │   ├── html.mdx
│       │       │   ├── index.mdx
│       │       │   ├── js.mdx
│       │       │   ├── svelte.mdx
│       │       │   └── vue.mdx
│       │       ├── legacy.mdx
│       │       ├── mcp.mdx
│       │       ├── migrate.mdx
│       │       ├── outputs/
│       │       │   ├── distributed.mdx
│       │       │   ├── index.mdx
│       │       │   ├── repository.mdx
│       │       │   └── shadcn.mdx
│       │       ├── providers/
│       │       │   ├── azure.mdx
│       │       │   ├── bitbucket.mdx
│       │       │   ├── fs.mdx
│       │       │   ├── github.mdx
│       │       │   ├── gitlab.mdx
│       │       │   ├── http.mdx
│       │       │   ├── index.mdx
│       │       │   ├── jsrepo.mdx
│       │       │   └── shadcn.mdx
│       │       └── transforms/
│       │           ├── biome.mdx
│       │           ├── filecasing.mdx
│       │           ├── index.mdx
│       │           ├── javascript.mdx
│       │           ├── oxfmt.mdx
│       │           └── prettier.mdx
│       ├── instrumentation-client.js
│       ├── jsrepo.config.mts
│       ├── middleware.ts
│       ├── next.config.mjs
│       ├── og-image.d.ts
│       ├── package.json
│       ├── postcss.config.mjs
│       ├── source.config.ts
│       ├── src/
│       │   ├── app/
│       │   │   ├── (home)/
│       │   │   │   ├── code-block.tsx
│       │   │   │   ├── layout.tsx
│       │   │   │   ├── page.tsx
│       │   │   │   └── providers-section.tsx
│       │   │   ├── api/
│       │   │   │   └── search/
│       │   │   │       └── route.ts
│       │   │   ├── app-client.tsx
│       │   │   ├── docs/
│       │   │   │   ├── [[...slug]]/
│       │   │   │   │   └── page.tsx
│       │   │   │   └── layout.tsx
│       │   │   ├── global.css
│       │   │   ├── layout.tsx
│       │   │   ├── llms-full.txt/
│       │   │   │   └── route.ts
│       │   │   ├── llms.mdx/
│       │   │   │   └── [[...slug]]/
│       │   │   │       └── route.ts
│       │   │   ├── og/
│       │   │   │   ├── docs/
│       │   │   │   │   └── [...slug]/
│       │   │   │   │       └── route.tsx
│       │   │   │   └── route.tsx
│       │   │   └── robots.txt
│       │   ├── components/
│       │   │   ├── PrismaticBurst.tsx
│       │   │   ├── badges-table.tsx
│       │   │   ├── feature-tabs.tsx
│       │   │   ├── files.tsx
│       │   │   ├── language-toggle.tsx
│       │   │   ├── layout/
│       │   │   │   ├── home/
│       │   │   │   │   ├── client.tsx
│       │   │   │   │   └── index.tsx
│       │   │   │   └── shared/
│       │   │   │       ├── client.tsx
│       │   │   │       └── index.tsx
│       │   │   ├── logos/
│       │   │   │   ├── antigravity.tsx
│       │   │   │   ├── azure-devops.tsx
│       │   │   │   ├── biome.tsx
│       │   │   │   ├── bitbucket.tsx
│       │   │   │   ├── claude.tsx
│       │   │   │   ├── css.tsx
│       │   │   │   ├── cursor.tsx
│       │   │   │   ├── github.tsx
│       │   │   │   ├── gitlab.tsx
│       │   │   │   ├── html.tsx
│       │   │   │   ├── index.ts
│       │   │   │   ├── javascript.tsx
│       │   │   │   ├── jsrepo-com.tsx
│       │   │   │   ├── npm.tsx
│       │   │   │   ├── openai.tsx
│       │   │   │   ├── oxfmt.tsx
│       │   │   │   ├── prettier.tsx
│       │   │   │   ├── registry-kit.tsx
│       │   │   │   ├── shadcn.tsx
│       │   │   │   ├── svelte.tsx
│       │   │   │   ├── typescript.tsx
│       │   │   │   ├── vscode.tsx
│       │   │   │   └── vue.tsx
│       │   │   ├── navigation-menu.tsx
│       │   │   ├── page-actions.tsx
│       │   │   ├── registry-index.tsx
│       │   │   ├── registry-kit/
│       │   │   │   ├── demo-example.tsx
│       │   │   │   └── demo.tsx
│       │   │   ├── search-toggle.tsx
│       │   │   ├── sidebar.tsx
│       │   │   ├── theme-toggle.tsx
│       │   │   └── ui/
│       │   │       ├── accordion.tsx
│       │   │       ├── animated-beam.tsx
│       │   │       ├── badge.tsx
│       │   │       ├── button.tsx
│       │   │       ├── collapsible.tsx
│       │   │       ├── field.tsx
│       │   │       ├── github-button.tsx
│       │   │       ├── index.ts
│       │   │       ├── input-group.tsx
│       │   │       ├── input.tsx
│       │   │       ├── item.tsx
│       │   │       ├── label.tsx
│       │   │       ├── popover.tsx
│       │   │       ├── scroll-area.tsx
│       │   │       ├── separator.tsx
│       │   │       ├── sonner.tsx
│       │   │       ├── table.tsx
│       │   │       ├── tabs.tsx
│       │   │       ├── terminal.tsx
│       │   │       ├── textarea.tsx
│       │   │       ├── tooltip.tsx
│       │   │       └── underline-tabs.tsx
│       │   ├── hooks/
│       │   │   ├── use-copy-to-clipboard.tsx
│       │   │   └── use-scroll-to-top.tsx
│       │   ├── lib/
│       │   │   ├── cn.ts
│       │   │   ├── is-active.ts
│       │   │   ├── layout.shared.tsx
│       │   │   ├── og.ts
│       │   │   ├── source.ts
│       │   │   └── utils.ts
│       │   └── mdx-components.tsx
│       └── tsconfig.json
├── biome.json
├── examples/
│   ├── react/
│   │   ├── .gitignore
│   │   ├── README.md
│   │   ├── biome.json
│   │   ├── jsrepo.config.mts
│   │   ├── next.config.ts
│   │   ├── package.json
│   │   ├── postcss.config.mjs
│   │   ├── public/
│   │   │   └── r/
│   │   │       ├── button.json
│   │   │       ├── registry.json
│   │   │       ├── shadcn/
│   │   │       │   ├── button.json
│   │   │       │   ├── registry.json
│   │   │       │   └── utils.json
│   │   │       └── utils.json
│   │   ├── src/
│   │   │   ├── app/
│   │   │   │   ├── demos/
│   │   │   │   │   └── button-demo/
│   │   │   │   │       └── page.tsx
│   │   │   │   ├── globals.css
│   │   │   │   ├── layout.tsx
│   │   │   │   └── page.tsx
│   │   │   └── registry/
│   │   │       ├── lib/
│   │   │       │   └── utils.ts
│   │   │       └── ui/
│   │   │           └── button.tsx
│   │   └── tsconfig.json
│   └── svelte/
│       ├── .gitignore
│       ├── .npmrc
│       ├── README.md
│       ├── biome.json
│       ├── jsrepo.config.ts
│       ├── package.json
│       ├── src/
│       │   ├── app.css
│       │   ├── app.d.ts
│       │   ├── app.html
│       │   ├── lib/
│       │   │   └── registry/
│       │   │       ├── lib/
│       │   │       │   └── utils.ts
│       │   │       └── ui/
│       │   │           └── button/
│       │   │               ├── button.svelte
│       │   │               └── index.ts
│       │   └── routes/
│       │       ├── +layout.svelte
│       │       ├── +page.svelte
│       │       └── demos/
│       │           └── button-demo/
│       │               └── +page.svelte
│       ├── static/
│       │   ├── r/
│       │   │   ├── button.json
│       │   │   ├── registry.json
│       │   │   └── utils.json
│       │   └── robots.txt
│       ├── svelte.config.js
│       ├── tsconfig.json
│       └── vite.config.ts
├── package.json
├── packages/
│   ├── bun/
│   │   ├── CHANGELOG.md
│   │   ├── README.md
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── index.ts
│   │   │   └── workspace.ts
│   │   ├── tests/
│   │   │   ├── bun.test.ts
│   │   │   └── fixtures/
│   │   │       ├── bun-workspace/
│   │   │       │   ├── package.json
│   │   │       │   └── packages/
│   │   │       │       ├── bar/
│   │   │       │       │   └── package.json
│   │   │       │       └── foo/
│   │   │       │           └── package.json
│   │   │       └── bun-workspace-object/
│   │   │           ├── package.json
│   │   │           └── packages/
│   │   │               └── baz/
│   │   │                   └── package.json
│   │   ├── tsconfig.json
│   │   └── tsdown.config.ts
│   ├── jsrepo/
│   │   ├── CHANGELOG.md
│   │   ├── LICENSE
│   │   ├── README.md
│   │   ├── biome.json
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── api/
│   │   │   │   ├── config.ts
│   │   │   │   ├── errors.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── langs/
│   │   │   │   │   ├── index.ts
│   │   │   │   │   └── js.ts
│   │   │   │   ├── outputs.ts
│   │   │   │   ├── providers.ts
│   │   │   │   ├── utils.ts
│   │   │   │   └── warnings.ts
│   │   │   ├── bin.ts
│   │   │   ├── cli.ts
│   │   │   ├── commands/
│   │   │   │   ├── add.ts
│   │   │   │   ├── auth.ts
│   │   │   │   ├── build.ts
│   │   │   │   ├── config/
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── language.ts
│   │   │   │   │   ├── mcp.ts
│   │   │   │   │   ├── provider.ts
│   │   │   │   │   └── transform.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── init.ts
│   │   │   │   ├── publish.ts
│   │   │   │   ├── update.ts
│   │   │   │   └── utils.ts
│   │   │   ├── langs/
│   │   │   │   ├── css.ts
│   │   │   │   ├── html.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── js.ts
│   │   │   │   ├── svelte.ts
│   │   │   │   ├── types.ts
│   │   │   │   └── vue.ts
│   │   │   ├── outputs/
│   │   │   │   ├── distributed.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── repository.ts
│   │   │   │   └── types.ts
│   │   │   ├── providers/
│   │   │   │   ├── azure.ts
│   │   │   │   ├── bitbucket.ts
│   │   │   │   ├── fs.ts
│   │   │   │   ├── github.ts
│   │   │   │   ├── gitlab.ts
│   │   │   │   ├── http.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── jsrepo.ts
│   │   │   │   └── types.ts
│   │   │   └── utils/
│   │   │       ├── add.ts
│   │   │       ├── build.ts
│   │   │       ├── casing.ts
│   │   │       ├── compat/
│   │   │       │   └── shadcn.ts
│   │   │       ├── config/
│   │   │       │   ├── index.ts
│   │   │       │   ├── mods/
│   │   │       │   │   ├── add-plugins.ts
│   │   │       │   │   ├── add-registries.ts
│   │   │       │   │   └── update-paths.ts
│   │   │       │   └── utils.ts
│   │   │       ├── diff.ts
│   │   │       ├── env.ts
│   │   │       ├── errors.ts
│   │   │       ├── fs.ts
│   │   │       ├── glob.ts
│   │   │       ├── hooks.ts
│   │   │       ├── json.ts
│   │   │       ├── lines.ts
│   │   │       ├── package.ts
│   │   │       ├── pad.ts
│   │   │       ├── parse-package-name.ts
│   │   │       ├── path.ts
│   │   │       ├── persisted.ts
│   │   │       ├── prompts.ts
│   │   │       ├── roles.ts
│   │   │       ├── strings.ts
│   │   │       ├── token-manager.ts
│   │   │       ├── tsconfig.ts
│   │   │       ├── types.ts
│   │   │       ├── url.ts
│   │   │       ├── utils.ts
│   │   │       ├── validate-npm-package-name.ts
│   │   │       ├── warnings.ts
│   │   │       └── zod.ts
│   │   ├── tests/
│   │   │   ├── __mocks__/
│   │   │   │   ├── fs/
│   │   │   │   │   └── promises.cjs
│   │   │   │   └── fs.cjs
│   │   │   ├── build.test.ts
│   │   │   ├── config.test.ts
│   │   │   ├── fixtures/
│   │   │   │   ├── build/
│   │   │   │   │   ├── .npmignore
│   │   │   │   │   ├── .npmrc
│   │   │   │   │   ├── jsrepo.config.ts
│   │   │   │   │   ├── package.json
│   │   │   │   │   └── src/
│   │   │   │   │       ├── components/
│   │   │   │   │       │   └── ui/
│   │   │   │   │       │       ├── button.tsx
│   │   │   │   │       │       ├── counter.svelte
│   │   │   │   │       │       ├── empty/
│   │   │   │   │       │       │   ├── empty-content.svelte
│   │   │   │   │       │       │   ├── empty.svelte
│   │   │   │   │       │       │   └── index.ts
│   │   │   │   │       │       └── lanyard/
│   │   │   │   │       │           ├── Lanyard.tsx
│   │   │   │   │       │           └── card.glb
│   │   │   │   │       ├── routes/
│   │   │   │   │       │   ├── demo/
│   │   │   │   │       │   │   ├── +page.server.ts
│   │   │   │   │       │   │   └── +page.svelte
│   │   │   │   │       │   └── demos/
│   │   │   │   │       │       ├── button-default.tsx
│   │   │   │   │       │       ├── button-loading.tsx
│   │   │   │   │       │       └── subdir/
│   │   │   │   │       │           ├── button-subdir.tsx
│   │   │   │   │       │           └── nested/
│   │   │   │   │       │               └── button-nested.tsx
│   │   │   │   │       ├── utils/
│   │   │   │   │       │   ├── math/
│   │   │   │   │       │   │   ├── add.test.ts
│   │   │   │   │       │   │   ├── add.ts
│   │   │   │   │       │   │   ├── answer-format.test.ts
│   │   │   │   │       │   │   └── answer-format.ts
│   │   │   │   │       │   ├── shiki.ts
│   │   │   │   │       │   └── stdout.ts
│   │   │   │   │       └── utils.ts
│   │   │   │   ├── config/
│   │   │   │   │   ├── basic/
│   │   │   │   │   │   └── jsrepo.config.ts
│   │   │   │   │   ├── mts/
│   │   │   │   │   │   └── jsrepo.config.mts
│   │   │   │   │   └── nested/
│   │   │   │   │       └── jsrepo.config.ts
│   │   │   │   └── langs/
│   │   │   │       ├── js/
│   │   │   │       │   ├── logger.ts
│   │   │   │       │   ├── math/
│   │   │   │       │   │   ├── add.ts
│   │   │   │       │   │   └── subtract.ts
│   │   │   │       │   ├── print-answer.ts
│   │   │   │       │   └── stdout.ts
│   │   │   │       ├── js-arbitrary-extensions/
│   │   │   │       │   ├── component.svelte
│   │   │   │       │   ├── config.json
│   │   │   │       │   ├── index.ts
│   │   │   │       │   └── svelte-entry.ts
│   │   │   │       ├── js-baseurl-bare-imports/
│   │   │   │       │   ├── package.json
│   │   │   │       │   ├── tsconfig.json
│   │   │   │       │   └── types.ts
│   │   │   │       ├── js-subpath-imports/
│   │   │   │       │   ├── index.ts
│   │   │   │       │   ├── package.json
│   │   │   │       │   └── src/
│   │   │   │       │       ├── meta.ts
│   │   │   │       │       └── utils/
│   │   │   │       │           └── print.ts
│   │   │   │       └── svelte/
│   │   │   │           └── page.svelte
│   │   │   ├── langs/
│   │   │   │   ├── js.test.ts
│   │   │   │   └── svelte.test.ts
│   │   │   ├── providers/
│   │   │   │   ├── azure.test.ts
│   │   │   │   ├── bitbucket.test.ts
│   │   │   │   ├── fs.test.ts
│   │   │   │   ├── github.test.ts
│   │   │   │   ├── gitlab.test.ts
│   │   │   │   └── http.test.ts
│   │   │   └── utils/
│   │   │       ├── add-plugins-to-config.test.ts
│   │   │       ├── add-registries.test.ts
│   │   │       ├── add.test.ts
│   │   │       ├── casing.test.ts
│   │   │       ├── config-mcp.test.ts
│   │   │       ├── config-utils.test.ts
│   │   │       ├── env.test.ts
│   │   │       ├── package.test.ts
│   │   │       ├── parse-package-name.test.ts
│   │   │       ├── roles.test.ts
│   │   │       ├── update-paths.test.ts
│   │   │       └── zod.test.ts
│   │   ├── tsconfig.json
│   │   ├── tsdown.config.ts
│   │   └── vitest.config.ts
│   ├── mcp/
│   │   ├── CHANGELOG.md
│   │   ├── README.md
│   │   ├── biome.json
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── index.ts
│   │   │   ├── server.ts
│   │   │   └── utils.ts
│   │   ├── tests/
│   │   │   └── mcp.test.ts
│   │   ├── tsconfig.json
│   │   └── tsdown.config.ts
│   ├── migrate/
│   │   ├── CHANGELOG.md
│   │   ├── LICENSE
│   │   ├── README.md
│   │   ├── biome.json
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── bin.ts
│   │   │   ├── cli.ts
│   │   │   ├── commands/
│   │   │   │   ├── index.ts
│   │   │   │   ├── utils.ts
│   │   │   │   └── v3.ts
│   │   │   └── utils/
│   │   │       ├── errors.ts
│   │   │       ├── fs.ts
│   │   │       ├── json.ts
│   │   │       ├── package.ts
│   │   │       ├── parse-package-name.ts
│   │   │       ├── path.ts
│   │   │       ├── prompts.ts
│   │   │       ├── strings.ts
│   │   │       ├── types.ts
│   │   │       ├── v2/
│   │   │       │   └── config.ts
│   │   │       └── zod.ts
│   │   ├── tsconfig.json
│   │   └── tsdown.config.ts
│   ├── pnpm/
│   │   ├── CHANGELOG.md
│   │   ├── README.md
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── catalog.ts
│   │   │   ├── index.ts
│   │   │   └── workspace.ts
│   │   ├── tests/
│   │   │   ├── fixtures/
│   │   │   │   └── pnpm-workspace/
│   │   │   │       ├── packages/
│   │   │   │       │   ├── pkg-a/
│   │   │   │       │   │   └── package.json
│   │   │   │       │   ├── pkg-b/
│   │   │   │       │   │   └── package.json
│   │   │   │       │   └── pkg-c/
│   │   │   │       │       └── package.json
│   │   │   │       └── pnpm-workspace.yaml
│   │   │   └── pnpm.test.ts
│   │   ├── tsconfig.json
│   │   └── tsdown.config.ts
│   ├── shadcn/
│   │   ├── CHANGELOG.md
│   │   ├── README.md
│   │   ├── biome.json
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── index.ts
│   │   │   ├── output.ts
│   │   │   ├── provider.ts
│   │   │   └── utils.ts
│   │   ├── tsconfig.json
│   │   └── tsdown.config.ts
│   ├── transform-biome/
│   │   ├── CHANGELOG.md
│   │   ├── README.md
│   │   ├── biome.json
│   │   ├── package.json
│   │   ├── src/
│   │   │   └── index.ts
│   │   ├── tsconfig.json
│   │   └── tsdown.config.ts
│   ├── transform-filecasing/
│   │   ├── CHANGELOG.md
│   │   ├── README.md
│   │   ├── biome.json
│   │   ├── package.json
│   │   ├── src/
│   │   │   └── index.ts
│   │   ├── tests/
│   │   │   └── filecasing.test.ts
│   │   ├── tsconfig.json
│   │   └── tsdown.config.ts
│   ├── transform-javascript/
│   │   ├── CHANGELOG.md
│   │   ├── README.md
│   │   ├── biome.json
│   │   ├── package.json
│   │   ├── src/
│   │   │   └── index.ts
│   │   ├── tests/
│   │   │   └── strip-types.test.ts
│   │   ├── tsconfig.json
│   │   └── tsdown.config.ts
│   ├── transform-oxfmt/
│   │   ├── CHANGELOG.md
│   │   ├── README.md
│   │   ├── biome.json
│   │   ├── package.json
│   │   ├── src/
│   │   │   └── index.ts
│   │   ├── tsconfig.json
│   │   └── tsdown.config.ts
│   └── transform-prettier/
│       ├── CHANGELOG.md
│       ├── README.md
│       ├── biome.json
│       ├── package.json
│       ├── src/
│       │   └── index.ts
│       ├── tsconfig.json
│       └── tsdown.config.ts
├── pnpm-workspace.yaml
└── task.config.json
Download .txt
SYMBOL INDEX (877 symbols across 171 files)

FILE: apps/docs/middleware.ts
  function middleware (line 6) | function middleware(request: NextRequest) {

FILE: apps/docs/next.config.mjs
  method rewrites (line 8) | async rewrites() {

FILE: apps/docs/og-image.d.ts
  type HTMLAttributes (line 9) | interface HTMLAttributes<T> {

FILE: apps/docs/src/app/(home)/code-block.tsx
  function CodeBlock (line 7) | async function CodeBlock({

FILE: apps/docs/src/app/(home)/layout.tsx
  function Layout (line 4) | function Layout({ children }: LayoutProps<"/">) {

FILE: apps/docs/src/app/(home)/page.tsx
  function HomePage (line 43) | function HomePage() {
  function HeroSection (line 121) | function HeroSection() {
  function PluginsSection (line 147) | function PluginsSection() {
  function RestEasySection (line 172) | function RestEasySection() {
  function LLMsSection (line 231) | function LLMsSection() {
  function ShadcnCompatibilitySection (line 272) | function ShadcnCompatibilitySection() {
  function FeatureAccordionSection (line 301) | function FeatureAccordionSection() {

FILE: apps/docs/src/app/(home)/providers-section.tsx
  function Circle (line 9) | function Circle({ className, ...props }: React.ComponentProps<"div">) {
  function ProvidersSection (line 21) | function ProvidersSection() {

FILE: apps/docs/src/app/app-client.tsx
  function App (line 8) | function App({ children }: { children: React.ReactNode }) {

FILE: apps/docs/src/app/docs/[[...slug]]/page.tsx
  function Page (line 9) | async function Page(props: PageProps<"/docs/[[...slug]]">) {
  function generateStaticParams (line 45) | async function generateStaticParams() {
  function generateMetadata (line 49) | async function generateMetadata(props: PageProps<"/docs/[[...slug]]">): ...

FILE: apps/docs/src/app/docs/layout.tsx
  function Layout (line 5) | function Layout({ children }: LayoutProps<'/docs'>) {

FILE: apps/docs/src/app/layout.tsx
  function Layout (line 16) | function Layout({ children }: LayoutProps<"/">) {

FILE: apps/docs/src/app/llms-full.txt/route.ts
  function GET (line 5) | async function GET() {

FILE: apps/docs/src/app/llms.mdx/[[...slug]]/route.ts
  function GET (line 7) | async function GET(_req: Request, { params }: RouteContext<"/llms.mdx/[[...
  function generateStaticParams (line 19) | function generateStaticParams() {

FILE: apps/docs/src/app/og/docs/[...slug]/route.tsx
  function GET (line 8) | async function GET(_req: Request, { params }: RouteContext<"/og/docs/[.....
  function generateStaticParams (line 42) | function generateStaticParams() {

FILE: apps/docs/src/app/og/route.tsx
  function GET (line 6) | async function GET() {

FILE: apps/docs/src/components/PrismaticBurst.tsx
  type Offset (line 6) | type Offset = { x?: number | string; y?: number | string };
  type AnimationType (line 7) | type AnimationType = 'rotate' | 'rotate3d' | 'hover';
  type PrismaticBurstProps (line 9) | type PrismaticBurstProps = {

FILE: apps/docs/src/components/badges-table.tsx
  type Props (line 12) | type Props = {
  function buildBadgeUrl (line 17) | function buildBadgeUrl(template: string, registry: string) {
  type RegistryContextType (line 21) | type RegistryContextType = {
  function useRegistry (line 30) | function useRegistry() {
  function BadgesTable (line 36) | function BadgesTable({ badges, defaultRegistry }: Props) {
  function BadgeActions (line 70) | function BadgeActions({ badge }: { badge: { alt: string; hrefTemplate: s...

FILE: apps/docs/src/components/feature-tabs.tsx
  type FeatureTabsContext (line 6) | type FeatureTabsContext = {
  function useFeatureTabs (line 22) | function useFeatureTabs() {
  function FeatureTabs (line 28) | function FeatureTabs({
  function FeatureTabsList (line 87) | function FeatureTabsList({ className, children, ...props }: React.HTMLAt...
  function FeatureTabsTrigger (line 101) | function FeatureTabsTrigger({
  function FeatureTabsContent (line 149) | function FeatureTabsContent({

FILE: apps/docs/src/components/files.tsx
  function Files (line 22) | function Files({
  type FileProps (line 36) | interface FileProps extends HTMLAttributes<HTMLDivElement> {
  type FolderProps (line 41) | interface FolderProps extends HTMLAttributes<HTMLDivElement> {
  function File (line 54) | function File({
  function FileIcon (line 67) | function FileIcon({ name }: { name: string }) {
  function Folder (line 83) | function Folder({

FILE: apps/docs/src/components/language-toggle.tsx
  type LanguageSelectProps (line 12) | type LanguageSelectProps = ButtonHTMLAttributes<HTMLButtonElement>;
  function LanguageToggle (line 14) | function LanguageToggle(props: LanguageSelectProps): React.ReactElement {
  function LanguageToggleText (line 59) | function LanguageToggleText(

FILE: apps/docs/src/components/layout/home/client.tsx
  function Navbar (line 38) | function Navbar(props: ComponentProps<'div'>) {
  function NavigationMenuLinkItem (line 69) | function NavigationMenuLinkItem({
  function MobileNavigationMenuLinkItem (line 151) | function MobileNavigationMenuLinkItem({
  function MobileNavigationMenuTrigger (line 216) | function MobileNavigationMenuTrigger({
  function MobileNavigationMenuContent (line 235) | function MobileNavigationMenuContent(

FILE: apps/docs/src/components/layout/home/index.tsx
  type HomeLayoutProps (line 32) | interface HomeLayoutProps extends BaseLayoutProps {
  function HomeLayout (line 43) | function HomeLayout(
  function Header (line 80) | function Header({
  function isSecondary (line 202) | function isSecondary(item: LinkItemType): boolean {

FILE: apps/docs/src/components/layout/shared/client.tsx
  function BaseLinkItem (line 8) | function BaseLinkItem({

FILE: apps/docs/src/components/layout/shared/index.tsx
  type NavOptions (line 5) | interface NavOptions extends NavProviderProps {
  type BaseLayoutProps (line 20) | interface BaseLayoutProps {
  type BaseItem (line 56) | interface BaseItem {
  type BaseLinkType (line 65) | interface BaseLinkType extends BaseItem {
  type MainItemType (line 76) | interface MainItemType extends BaseLinkType {
  type IconItemType (line 83) | interface IconItemType extends BaseLinkType {
  type ButtonItemType (line 97) | interface ButtonItemType extends BaseLinkType {
  type MenuItemType (line 107) | interface MenuItemType extends Partial<BaseLinkType> {
  type CustomItemType (line 130) | interface CustomItemType extends BaseItem {
  type LinkItemType (line 139) | type LinkItemType =
  function getLinks (line 149) | function getLinks(

FILE: apps/docs/src/components/logos/antigravity.tsx
  function Antigravity (line 3) | function Antigravity(props: SVGProps<SVGSVGElement>) {

FILE: apps/docs/src/components/page-actions.tsx
  function LLMCopyButton (line 23) | function LLMCopyButton({
  function ViewOptions (line 76) | function ViewOptions({

FILE: apps/docs/src/components/registry-index.tsx
  type RegistryIndexEntry (line 21) | type RegistryIndexEntry = z.infer<typeof RegistryIndexEntrySchema>;
  function RegistryDirectory (line 23) | function RegistryDirectory() {
  function Registry (line 80) | function Registry({ registry }: { registry: RegistryIndexEntry }) {

FILE: apps/docs/src/components/registry-kit/demo-example.tsx
  function DemoExample (line 3) | function DemoExample() {

FILE: apps/docs/src/components/registry-kit/demo.tsx
  function Demo (line 5) | function Demo({ className, ...props }: ComponentProps<typeof Tabs>): Rea...
  function DemoPreview (line 19) | function DemoPreview({ className, ...props }: Omit<ComponentProps<typeof...
  function DemoCode (line 27) | function DemoCode({ className, ...props }: Omit<ComponentProps<typeof Ta...

FILE: apps/docs/src/components/search-toggle.tsx
  type SearchToggleProps (line 9) | interface SearchToggleProps
  function SearchToggle (line 15) | function SearchToggle({
  function LargeSearchToggle (line 45) | function LargeSearchToggle({

FILE: apps/docs/src/components/sidebar.tsx
  type SidebarProps (line 37) | interface SidebarProps {
  type InternalContext (line 64) | interface InternalContext {
  function Sidebar (line 89) | function Sidebar({
  function SidebarContent (line 111) | function SidebarContent(props: ComponentProps<'aside'>) {
  function SidebarContentMobile (line 178) | function SidebarContentMobile({
  function SidebarHeader (line 215) | function SidebarHeader(props: ComponentProps<'div'>) {
  function SidebarFooter (line 226) | function SidebarFooter(props: ComponentProps<'div'>) {
  function SidebarViewport (line 237) | function SidebarViewport(props: ScrollAreaProps) {
  function SidebarSeparator (line 256) | function SidebarSeparator(props: ComponentProps<'p'>) {
  function SidebarItem (line 270) | function SidebarItem({
  function SidebarFolder (line 294) | function SidebarFolder({
  function SidebarFolderTrigger (line 317) | function SidebarFolderTrigger({
  function SidebarFolderLink (line 337) | function SidebarFolderLink(props: LinkProps) {
  function SidebarFolderContent (line 372) | function SidebarFolderContent(props: CollapsibleContentProps) {
  function SidebarTrigger (line 408) | function SidebarTrigger({
  function SidebarCollapseTrigger (line 425) | function SidebarCollapseTrigger(props: ComponentProps<'button'>) {
  function useFolderContext (line 443) | function useFolderContext() {
  function useInternalContext (line 450) | function useInternalContext() {
  type SidebarComponents (line 457) | interface SidebarComponents {
  function SidebarPageTree (line 466) | function SidebarPageTree(props: {
  function PageTreeFolder (line 525) | function PageTreeFolder({

FILE: apps/docs/src/components/theme-toggle.tsx
  function ThemeToggle (line 26) | function ThemeToggle({

FILE: apps/docs/src/components/ui/accordion.tsx
  function Accordion (line 9) | function Accordion({
  function AccordionItem (line 16) | function AccordionItem({
  function AccordionTrigger (line 29) | function AccordionTrigger({
  function AccordionContent (line 51) | function AccordionContent({

FILE: apps/docs/src/components/ui/animated-beam.tsx
  type AnimatedBeamProps (line 8) | interface AnimatedBeamProps {

FILE: apps/docs/src/components/ui/badge.tsx
  function Badge (line 30) | function Badge({
  function SourceBadge (line 41) | function SourceBadge({
  function OfficialBadge (line 64) | function OfficialBadge({ className, ...props }: Omit<React.ComponentProp...
  function DefaultBadge (line 80) | function DefaultBadge({ className, ...props }: Omit<React.ComponentProps...
  type DownloadsResponse (line 96) | type DownloadsResponse = {
  function NpmBadge (line 103) | function NpmBadge({
  function BadgeGroup (line 150) | function BadgeGroup({ className, ...props }: React.ComponentProps<"div">) {

FILE: apps/docs/src/components/ui/button.tsx
  type ButtonProps (line 37) | type ButtonProps = React.ComponentProps<"button"> &
  function Button (line 42) | function Button({ className, variant, size, asChild = false, ...props }:...

FILE: apps/docs/src/components/ui/field.tsx
  function FieldSet (line 10) | function FieldSet({ className, ...props }: React.ComponentProps<"fieldse...
  function FieldLegend (line 24) | function FieldLegend({
  function FieldGroup (line 44) | function FieldGroup({ className, ...props }: React.ComponentProps<"div">) {
  function Field (line 81) | function Field({
  function FieldContent (line 97) | function FieldContent({ className, ...props }: React.ComponentProps<"div...
  function FieldLabel (line 110) | function FieldLabel({
  function FieldTitle (line 128) | function FieldTitle({ className, ...props }: React.ComponentProps<"div">) {
  function FieldDescription (line 141) | function FieldDescription({ className, ...props }: React.ComponentProps<...
  function FieldSeparator (line 156) | function FieldSeparator({
  function FieldError (line 186) | function FieldError({

FILE: apps/docs/src/components/ui/github-button.tsx
  type GithubButtonProps (line 8) | type GithubButtonProps = {
  type UnGhStarResponse (line 13) | type UnGhStarResponse = {
  function GitHubButton (line 17) | function GitHubButton({ repo, fallback }: GithubButtonProps) {

FILE: apps/docs/src/components/ui/input-group.tsx
  function InputGroup (line 11) | function InputGroup({ className, ...props }: React.ComponentProps<"div">) {
  function InputGroupAddon (line 60) | function InputGroupAddon({
  function InputGroupButton (line 100) | function InputGroupButton({
  function InputGroupText (line 119) | function InputGroupText({ className, ...props }: React.ComponentProps<"s...
  function InputGroupInput (line 131) | function InputGroupInput({
  function InputGroupTextarea (line 147) | function InputGroupTextarea({

FILE: apps/docs/src/components/ui/input.tsx
  function Input (line 5) | function Input({ className, type, ...props }: React.ComponentProps<"inpu...

FILE: apps/docs/src/components/ui/item.tsx
  function ItemGroup (line 8) | function ItemGroup({ className, ...props }: React.ComponentProps<"div">) {
  function ItemSeparator (line 19) | function ItemSeparator({
  function Item (line 54) | function Item({
  function ItemMedia (line 91) | function ItemMedia({
  function ItemContent (line 106) | function ItemContent({ className, ...props }: React.ComponentProps<"div"...
  function ItemTitle (line 119) | function ItemTitle({ className, ...props }: React.ComponentProps<"div">) {
  function ItemDescription (line 132) | function ItemDescription({ className, ...props }: React.ComponentProps<"...
  function ItemActions (line 146) | function ItemActions({ className, ...props }: React.ComponentProps<"div"...
  function ItemHeader (line 156) | function ItemHeader({ className, ...props }: React.ComponentProps<"div">) {
  function ItemFooter (line 169) | function ItemFooter({ className, ...props }: React.ComponentProps<"div">) {

FILE: apps/docs/src/components/ui/label.tsx
  function Label (line 8) | function Label({

FILE: apps/docs/src/components/ui/popover.tsx
  function Popover (line 8) | function Popover({
  function PopoverTrigger (line 14) | function PopoverTrigger({
  function PopoverContent (line 20) | function PopoverContent({
  function PopoverAnchor (line 42) | function PopoverAnchor({

FILE: apps/docs/src/components/ui/separator.tsx
  function Separator (line 8) | function Separator({

FILE: apps/docs/src/components/ui/table.tsx
  function Table (line 7) | function Table({ className, ...props }: React.ComponentProps<"table">) {
  function TableHeader (line 22) | function TableHeader({ className, ...props }: React.ComponentProps<"thea...
  function TableBody (line 32) | function TableBody({ className, ...props }: React.ComponentProps<"tbody"...
  function TableFooter (line 42) | function TableFooter({ className, ...props }: React.ComponentProps<"tfoo...
  function TableRow (line 55) | function TableRow({ className, ...props }: React.ComponentProps<"tr">) {
  function TableHead (line 68) | function TableHead({ className, ...props }: React.ComponentProps<"th">) {
  function TableCell (line 81) | function TableCell({ className, ...props }: React.ComponentProps<"td">) {
  function TableCaption (line 94) | function TableCaption({

FILE: apps/docs/src/components/ui/tabs.tsx
  function Tabs (line 8) | function Tabs({
  function TabsList (line 21) | function TabsList({
  function TabsTrigger (line 37) | function TabsTrigger({
  function TabsContent (line 53) | function TabsContent({

FILE: apps/docs/src/components/ui/terminal.tsx
  type SequenceContextValue (line 16) | interface SequenceContextValue {
  type AnimatedSpanProps (line 29) | interface AnimatedSpanProps extends MotionProps {
  type TypingAnimationProps (line 82) | interface TypingAnimationProps extends MotionProps {
  type TerminalProps (line 184) | interface TerminalProps {

FILE: apps/docs/src/components/ui/textarea.tsx
  function Textarea (line 5) | function Textarea({ className, ...props }: React.ComponentProps<"textare...

FILE: apps/docs/src/components/ui/tooltip.tsx
  function TooltipProvider (line 8) | function TooltipProvider({
  function Tooltip (line 21) | function Tooltip({
  function TooltipTrigger (line 31) | function TooltipTrigger({
  function TooltipContent (line 37) | function TooltipContent({

FILE: apps/docs/src/components/ui/underline-tabs.tsx
  function UnderlineTabs (line 8) | function UnderlineTabs({ className, ...props }: React.ComponentProps<typ...
  function UnderlineTabsList (line 14) | function UnderlineTabsList({ className, ...props }: React.ComponentProps...
  function UnderlineTabsTrigger (line 27) | function UnderlineTabsTrigger({ className, ...props }: React.ComponentPr...
  function UnderlineTabsContent (line 45) | function UnderlineTabsContent({ className, ...props }: React.ComponentPr...

FILE: apps/docs/src/hooks/use-copy-to-clipboard.tsx
  type CopyFn (line 5) | type CopyFn = (text: string) => Promise<boolean>
  function useCopyToClipboard (line 7) | function useCopyToClipboard(delay = 2000): [CopyFn, boolean] {

FILE: apps/docs/src/hooks/use-scroll-to-top.tsx
  function useScrollToTop (line 6) | function useScrollToTop() {

FILE: apps/docs/src/lib/is-active.ts
  function normalize (line 3) | function normalize(url: string) {
  function isActive (line 8) | function isActive(
  function isTabActive (line 19) | function isTabActive(tab: SidebarTab, pathname: string) {

FILE: apps/docs/src/lib/layout.shared.tsx
  function baseOptions (line 12) | function baseOptions(): BaseLayoutProps {

FILE: apps/docs/src/lib/og.ts
  function loadGoogleFont (line 1) | async function loadGoogleFont(font: string, text: string) {

FILE: apps/docs/src/lib/source.ts
  function getPageImage (line 12) | function getPageImage(page: InferPageType<typeof source>) {
  function getLLMText (line 21) | async function getLLMText(page: InferPageType<typeof source>) {

FILE: apps/docs/src/lib/utils.ts
  function cn (line 4) | function cn(...inputs: ClassValue[]) {

FILE: apps/docs/src/mdx-components.tsx
  function getMDXComponents (line 18) | function getMDXComponents(components?: MDXComponents): MDXComponents {

FILE: examples/react/src/app/demos/button-demo/page.tsx
  function ButtonDemoPage (line 3) | function ButtonDemoPage() {

FILE: examples/react/src/app/layout.tsx
  function RootLayout (line 20) | function RootLayout({

FILE: examples/react/src/app/page.tsx
  function Home (line 3) | function Home() {

FILE: examples/react/src/registry/lib/utils.ts
  function cn (line 4) | function cn(...inputs: ClassValue[]) {

FILE: examples/react/src/registry/ui/button.tsx
  type Variant (line 20) | type Variant = VariantProps<typeof buttonVariants>['variant'];
  type Size (line 21) | type Size = VariantProps<typeof buttonVariants>['size'];
  function Button (line 23) | function Button({

FILE: examples/svelte/src/lib/registry/lib/utils.ts
  function cn (line 4) | function cn(...inputs: ClassValue[]) {

FILE: packages/bun/src/index.ts
  function bun (line 28) | function bun(): RemoteDependencyResolver {
  type BunWorkspaceState (line 55) | type BunWorkspaceState = {
  function getOrParseState (line 61) | function getOrParseState(cwd: string): BunWorkspaceState {
  function resolveWorkspaceVersion (line 78) | function resolveWorkspaceVersion(versionSpec: string, workspaceVersion: ...
  function parseWorkspaceVersion (line 95) | function parseWorkspaceVersion(version: string): string | null {

FILE: packages/bun/src/workspace.ts
  type WorkspacePackage (line 6) | type WorkspacePackage = {
  type PackageJsonWithWorkspaces (line 11) | type PackageJsonWithWorkspaces =
  function findBunWorkspaceRoot (line 18) | function findBunWorkspaceRoot(cwd: string): string | null {
  function getWorkspacePatterns (line 47) | function getWorkspacePatterns(workspaceRoot: string): string[] {
  function expandWorkspacePackages (line 69) | function expandWorkspacePackages(workspaceRoot: string, packages: string...
  function readPackageInfo (line 85) | function readPackageInfo(dir: string): WorkspacePackage | null {
  function buildWorkspacePackageMap (line 103) | function buildWorkspacePackageMap(

FILE: packages/jsrepo/src/commands/add.ts
  type AddOptions (line 63) | type AddOptions = z.infer<typeof schema>;
  type AddCommandResult (line 123) | type AddCommandResult = {
  function runAdd (line 134) | async function runAdd(
  function formatResult (line 343) | function formatResult(result: AddCommandResult): string {

FILE: packages/jsrepo/src/commands/auth.ts
  type AuthOptions (line 39) | type AuthOptions = z.infer<typeof schema>;
  type AuthCommandResult (line 81) | type AuthCommandResult = {
  function runAuth (line 87) | async function runAuth(
  function logout (line 139) | async function logout(
  function login (line 176) | async function login(
  function formatResult (line 322) | function formatResult({ type, provider, registry }: AuthCommandResult): ...

FILE: packages/jsrepo/src/commands/build.ts
  type BuildOptions (line 38) | type BuildOptions = z.infer<typeof schema>;
  type RegistryBuildResult (line 91) | type RegistryBuildResult = {
  type BuildCommandResult (line 99) | type BuildCommandResult = {
  function runBuild (line 104) | async function runBuild(
  function runWatch (line 158) | async function runWatch(
  function createWatcher (line 277) | function createWatcher(
  function formatResult (line 288) | function formatResult(
  function formatRegistryResult (line 296) | function formatRegistryResult(result: Result<RegistryBuildResult, BuildE...

FILE: packages/jsrepo/src/commands/config/language.ts
  type ConfigAddLanguageOptions (line 26) | type ConfigAddLanguageOptions = z.infer<typeof schema>;
  type ConfigAddLanguageCommandResult (line 68) | type ConfigAddLanguageCommandResult = {
  function runLanguage (line 73) | async function runLanguage(
  function formatResult (line 115) | function formatResult({ duration, languages }: ConfigAddLanguageCommandR...

FILE: packages/jsrepo/src/commands/config/mcp.ts
  type ConfigMcpOptions (line 31) | type ConfigMcpOptions = z.infer<typeof schema>;
  type McpClient (line 33) | type McpClient = (typeof supportedClients)[number];
  type ClientConfigResult (line 65) | type ClientConfigResult = {
  type ClientResult (line 70) | type ClientResult = {
  type ConfigMcpCommandResult (line 75) | type ConfigMcpCommandResult = {
  function runMcp (line 80) | async function runMcp(
  function formatResult (line 129) | function formatResult({
  function formatClientResult (line 139) | function formatClientResult({ name, result }: ClientResult, cwd: string)...
  type ClientConfig (line 147) | interface ClientConfig {
  function writeConfig (line 153) | function writeConfig(filePath: AbsolutePath, content: string): Result<vo...
  constant MCP_SERVER_CONFIG_JSON (line 169) | const MCP_SERVER_CONFIG_JSON: ServerConfig = {
  constant MCP_SERVER_CONFIG_TOML (line 174) | const MCP_SERVER_CONFIG_TOML = `[mcp_servers.jsrepo]
  function updateTomlConfig (line 179) | function updateTomlConfig(existingContent: string): string {
  type ServerConfig (line 200) | type ServerConfig = z.infer<typeof ServerConfigSchema>;
  type McpServerConfig (line 210) | type McpServerConfig = z.infer<typeof McpServerConfigSchema>;
  type VSCodeServerConfig (line 211) | type VSCodeServerConfig = z.infer<typeof VSCodeServerConfigSchema>;
  function updateJsonConfig (line 213) | function updateJsonConfig({
  function updateVSCodeJsonConfig (line 253) | function updateVSCodeJsonConfig({
  function updateJsonFile (line 293) | function updateJsonFile(
  constant CLIENTS (line 315) | const CLIENTS: Record<McpClient, ClientConfig> = {

FILE: packages/jsrepo/src/commands/config/provider.ts
  type ConfigAddProviderOptions (line 26) | type ConfigAddProviderOptions = z.infer<typeof schema>;
  type ConfigAddProviderCommandResult (line 69) | type ConfigAddProviderCommandResult = {
  function runProvider (line 74) | async function runProvider(
  function formatResult (line 117) | function formatResult({ duration, providers }: ConfigAddProviderCommandR...

FILE: packages/jsrepo/src/commands/config/transform.ts
  type ConfigAddTransformOptions (line 26) | type ConfigAddTransformOptions = z.infer<typeof schema>;
  type ConfigAddTransformCommandResult (line 68) | type ConfigAddTransformCommandResult = {
  function runTransform (line 73) | async function runTransform(
  function formatResult (line 116) | function formatResult({

FILE: packages/jsrepo/src/commands/init.ts
  type InitOptions (line 67) | type InitOptions = z.infer<typeof schema>;
  type InitCommandResult (line 69) | type InitCommandResult = {
  function runInit (line 127) | async function runInit(
  function initRegistry (line 417) | async function initRegistry(
  function initPlugins (line 456) | async function initPlugins(
  function initDefaultPaths (line 495) | async function initDefaultPaths(
  function getWantedPlugins (line 571) | async function getWantedPlugins(
  function initBlankConfig (line 630) | function initBlankConfig() {

FILE: packages/jsrepo/src/commands/publish.ts
  type PublishOptions (line 49) | type PublishOptions = z.infer<typeof schema>;
  type PublishCommandResult (line 106) | type PublishCommandResult = {
  type JsrepoProvider (line 123) | type JsrepoProvider = ReturnType<typeof jsrepo>;
  function runPublish (line 125) | async function runPublish(
  function validateRegistryPrepublish (line 250) | function validateRegistryPrepublish(
  function publishRegistry (line 296) | async function publishRegistry(
  function collectRegistryFiles (line 357) | function collectRegistryFiles(
  function formatResult (line 444) | function formatResult(result: PublishCommandResult): string {
  function formatRegistryResult (line 449) | function formatRegistryResult(

FILE: packages/jsrepo/src/commands/update.ts
  type UpdateOptions (line 61) | type UpdateOptions = z.infer<typeof schema>;
  type UpdateCommandResult (line 119) | type UpdateCommandResult = {
  function runUpdate (line 130) | async function runUpdate(
  function formatResult (line 358) | function formatResult(result: UpdateCommandResult): string {

FILE: packages/jsrepo/src/commands/utils.ts
  constant TRACE_ENV_VAR (line 12) | const TRACE_ENV_VAR = 'JSREPO_TRACE';
  function parseOptions (line 35) | function parseOptions<T>(
  function tryCommand (line 50) | async function tryCommand<T, E extends JsrepoError>(
  function error (line 71) | function error(err: Error): never {
  function handleError (line 75) | function handleError(err: Error): never {
  function forEachRegistry (line 93) | async function forEachRegistry<T>(
  function hasRegistries (line 109) | function hasRegistries(config: Config): boolean {

FILE: packages/jsrepo/src/langs/css.ts
  type CssOptions (line 5) | type CssOptions = {
  function css (line 28) | function css({ allowTailwindDirectives = true }: Partial<CssOptions> = {...

FILE: packages/jsrepo/src/langs/html.ts
  type HtmlOptions (line 6) | type HtmlOptions = {
  type HtmlAttribute (line 27) | interface HtmlAttribute {
  type HtmlNode (line 32) | interface HtmlNode {
  function html (line 53) | function html({

FILE: packages/jsrepo/src/langs/index.ts
  function isModuleAvailable (line 11) | function isModuleAvailable(moduleName: string): boolean {
  function createDefaultLangs (line 20) | function createDefaultLangs(): Language[] {
  constant DEFAULT_LANGS (line 34) | const DEFAULT_LANGS = createDefaultLangs();

FILE: packages/jsrepo/src/langs/js.ts
  constant SUPPORTED_EXTENSIONS (line 29) | const SUPPORTED_EXTENSIONS = ['.js', '.ts', '.jsx', '.tsx', '.mjs', '.mt...
  constant SUPPORTED_PACKAGE_IMPORT_CONDITIONS (line 30) | const SUPPORTED_PACKAGE_IMPORT_CONDITIONS = new Set(['default', 'import'...
  type JsOptions (line 33) | type JsOptions = {};
  function js (line 38) | function js(_options: JsOptions = {}): Language {
  function resolveImports (line 56) | async function resolveImports(
  function getImports (line 137) | async function getImports(
  function searchForModule (line 194) | function searchForModule(
  type AliasResolution (line 275) | type AliasResolution =
  function tryResolveAliasImport (line 286) | function tryResolveAliasImport(
  function tryResolveTsconfigAlias (line 304) | function tryResolveTsconfigAlias(
  function tryResolvePackageImportsAlias (line 348) | function tryResolvePackageImportsAlias(
  function getMatchingPackageImport (line 392) | function getMatchingPackageImport(
  function resolvePackageImportTargets (line 441) | function resolvePackageImportTargets(target: unknown, wildcardMatch?: st...
  function isRecord (line 465) | function isRecord(value: unknown): value is Record<string, unknown> {
  function isPotentiallyRemotePackageSpecifier (line 469) | function isPotentiallyRemotePackageSpecifier(specifier: string): boolean {
  function hasMatchingTsconfigPathAlias (line 480) | function hasMatchingTsconfigPathAlias(
  function resolveRemoteDeps (line 509) | function resolveRemoteDeps(
  function transformImports (line 557) | async function transformImports(
  function createImportPattern (line 667) | function createImportPattern(literal: string): RegExp {
  function createReplacement (line 672) | function createReplacement(replacement: string): string {
  function installDependencies (line 676) | async function installDependencies(

FILE: packages/jsrepo/src/langs/svelte.ts
  type SvelteOptions (line 7) | type SvelteOptions = {};
  function loadSvelteCompiler (line 11) | async function loadSvelteCompiler() {
  function svelte (line 30) | function svelte(_options: SvelteOptions = {}): Language {

FILE: packages/jsrepo/src/langs/types.ts
  type ResolveDependenciesOptions (line 6) | type ResolveDependenciesOptions = {
  type InstallDependenciesOptions (line 13) | type InstallDependenciesOptions = {
  type TransformImportsOptions (line 17) | type TransformImportsOptions = {
  type ImportTransform (line 31) | type ImportTransform = {
  type ResolveDependenciesResult (line 38) | type ResolveDependenciesResult = {
  type Language (line 44) | interface Language {

FILE: packages/jsrepo/src/langs/vue.ts
  type VueOptions (line 7) | type VueOptions = {};
  function loadVueCompiler (line 11) | async function loadVueCompiler() {
  function vue (line 30) | function vue(_options: VueOptions = {}): Language {

FILE: packages/jsrepo/src/outputs/distributed.ts
  type DistributedOutputOptions (line 11) | type DistributedOutputOptions = {
  function distributed (line 40) | function distributed({ dir, format }: DistributedOutputOptions): Output {
  type DistributedOutputManifestFile (line 154) | type DistributedOutputManifestFile = z.infer<typeof DistributedOutputMan...
  type DistributedOutputManifest (line 181) | type DistributedOutputManifest = z.infer<typeof DistributedOutputManifes...
  type DistributedOutputFile (line 195) | type DistributedOutputFile = z.infer<typeof DistributedOutputFileSchema>;
  type DistributedOutputItem (line 216) | type DistributedOutputItem = z.infer<typeof DistributedOutputItemSchema>;

FILE: packages/jsrepo/src/outputs/index.ts
  type Manifest (line 22) | type Manifest = z.infer<typeof ManifestSchema>;

FILE: packages/jsrepo/src/outputs/repository.ts
  type RepositoryOutputOptions (line 10) | type RepositoryOutputOptions = {
  function repository (line 35) | function repository({ format }: RepositoryOutputOptions = {}): Output {
  type RepositoryOutputFile (line 100) | type RepositoryOutputFile = z.infer<typeof RepositoryOutputFileSchema>;
  type RepositoryOutputManifestItem (line 120) | type RepositoryOutputManifestItem = z.infer<typeof RepositoryOutputManif...
  type RepositoryOutputManifest (line 129) | type RepositoryOutputManifest = z.infer<typeof RepositoryOutputManifestS...

FILE: packages/jsrepo/src/outputs/types.ts
  type Output (line 5) | interface Output {

FILE: packages/jsrepo/src/providers/azure.ts
  constant BASE_URL (line 4) | const BASE_URL = 'https://dev.azure.com';
  constant DEFAULT_BRANCH (line 5) | const DEFAULT_BRANCH = 'main';
  type AzureOptions (line 7) | type AzureOptions = {
  function azure (line 34) | function azure(options: AzureOptions = {}): ProviderFactory {
  type AzureState (line 47) | type AzureState = {
  class Azure (line 56) | class Azure implements Provider {
    method constructor (line 57) | constructor(
    method create (line 62) | static async create(
    method fetch (line 71) | async fetch(resourcePath: string, { token, fetch: f = fetch }: FetchOp...
    method getState (line 106) | private static async getState(
    method parseUrl (line 114) | private static parseUrl(url: string, opts: AzureOptions): AzureState {
    method resolveRaw (line 149) | private resolveRaw(resourcePath: string): URL {
    method authHeader (line 159) | private static authHeader(token: string | undefined) {

FILE: packages/jsrepo/src/providers/bitbucket.ts
  constant BASE_URL (line 4) | const BASE_URL = 'https://bitbucket.org';
  constant DEFAULT_BRANCH (line 5) | const DEFAULT_BRANCH = 'main';
  type BitBucketOptions (line 7) | type BitBucketOptions = {
  function bitbucket (line 34) | function bitbucket(options: BitBucketOptions = {}): ProviderFactory {
  type BitBucketState (line 50) | type BitBucketState = {
  class BitBucket (line 57) | class BitBucket implements Provider {
    method constructor (line 58) | constructor(
    method create (line 63) | static async create(
    method fetch (line 72) | async fetch(resourcePath: string, { token, fetch: f = fetch }: FetchOp...
    method getState (line 107) | private static async getState(
    method parseUrl (line 147) | private static parseUrl(url: string, opts: BitBucketOptions): BitBucke...
    method getApiUrl (line 176) | private static getApiUrl(baseUrl: string): string {
    method resolveRaw (line 181) | private resolveRaw(resourcePath: string): URL {
    method authHeader (line 190) | private static authHeader(token: string | undefined) {

FILE: packages/jsrepo/src/providers/fs.ts
  type FsOptions (line 8) | type FsOptions = {
  function _fs (line 35) | function _fs(options: FsOptions = {}): ProviderFactory {
  type FsState (line 45) | type FsState = {
  class Fs (line 49) | class Fs implements Provider {
    method constructor (line 50) | constructor(
    method fetch (line 55) | async fetch(resourcePath: string): Promise<string> {
    method create (line 74) | static async create(

FILE: packages/jsrepo/src/providers/github.ts
  constant BASE_URL (line 4) | const BASE_URL = 'https://github.com';
  constant DEFAULT_BRANCH (line 5) | const DEFAULT_BRANCH = 'main';
  type GitHubOptions (line 7) | type GitHubOptions = {
  function github (line 34) | function github(options: GitHubOptions = {}): ProviderFactory {
  type GitHubState (line 49) | type GitHubState = {
  class GitHub (line 57) | class GitHub implements Provider {
    method constructor (line 58) | constructor(
    method create (line 63) | static async create(
    method fetch (line 72) | async fetch(resourcePath: string, { token, fetch: f = fetch }: FetchOp...
    method getState (line 108) | private static async getState(
    method parseUrl (line 148) | private static parseUrl(
    method resolveRaw (line 191) | private resolveRaw(resourcePath: string): URL {
    method getApiUrl (line 200) | private static getApiUrl(baseUrl: string): string {
    method authHeader (line 205) | private static authHeader(token: string | undefined) {

FILE: packages/jsrepo/src/providers/gitlab.ts
  constant BASE_URL (line 4) | const BASE_URL = 'https://gitlab.com';
  constant DEFAULT_BRANCH (line 5) | const DEFAULT_BRANCH = 'main';
  type GitLabOptions (line 7) | type GitLabOptions = {
  function gitlab (line 35) | function gitlab(options: GitLabOptions = {}): ProviderFactory {
  type GitLabState (line 50) | type GitLabState = {
  class GitLab (line 58) | class GitLab implements Provider {
    method constructor (line 59) | constructor(
    method create (line 64) | static async create(
    method fetch (line 73) | async fetch(resourcePath: string, { token, fetch: f = fetch }: FetchOp...
    method getState (line 108) | private static async getState(
    method parseUrl (line 147) | private static parseUrl(url: string, opts: GitLabOptions): GitLabState {
    method getApiUrl (line 180) | private static getApiUrl(baseUrl: string): string {
    method resolveRaw (line 185) | private resolveRaw(resourcePath: string): URL {
    method authHeader (line 196) | private static authHeader(token: string | undefined) {

FILE: packages/jsrepo/src/providers/http.ts
  type HttpOptions (line 5) | type HttpOptions = (
  function http (line 71) | function http(options: HttpOptions = {}): ProviderFactory {
  type HttpState (line 88) | type HttpState = {
  class Http (line 92) | class Http implements Provider {
    method constructor (line 93) | constructor(
    method fetch (line 98) | async fetch(resourcePath: string, { token, fetch: f = fetch }: FetchOp...
    method resolveRaw (line 134) | private resolveRaw(resourcePath: string): URL {
    method authHeader (line 138) | private authHeader(token: string | undefined): Record<string, string> ...
    method create (line 145) | static async create(url: string, opts: HttpOptions): Promise<Provider> {

FILE: packages/jsrepo/src/providers/index.ts
  constant DEFAULT_PROVIDERS (line 15) | const DEFAULT_PROVIDERS = [jsrepo(), github(), gitlab(), bitbucket(), az...
  function fetchManifest (line 35) | async function fetchManifest(

FILE: packages/jsrepo/src/providers/jsrepo.ts
  constant NAME_REGEX (line 32) | const NAME_REGEX = /^(?![-0-9])(?!.*--)[a-z0-9]*(?:-[a-z0-9]+)*$/i;
  constant BASE_URL (line 34) | const BASE_URL = 'https://www.jsrepo.com';
  type JsrepoOptions (line 36) | type JsrepoOptions = {
  function jsrepo (line 62) | function jsrepo(options: JsrepoOptions = {}): ProviderFactory & { baseUr...
  type JsrepoState (line 77) | type JsrepoState = {
  class Jsrepo (line 86) | class Jsrepo implements Provider {
    method constructor (line 87) | constructor(
    method create (line 92) | static async create(
    method fetch (line 101) | async fetch(resourcePath: string, { token, fetch: f = fetch }: FetchOp...
    method getState (line 136) | private static async getState(url: string, opts: JsrepoOptions): Promi...
    method parseUrl (line 145) | private static parseUrl(url: string): {
    method resolveRaw (line 181) | private resolveRaw(resourcePath: string): URL {
    method authHeader (line 189) | private static authHeader(token: string | undefined): Record<string, s...

FILE: packages/jsrepo/src/providers/types.ts
  type FetchOptions (line 16) | type FetchOptions = {
  type CreateOptions (line 21) | type CreateOptions = {
  type Prompts (line 27) | type Prompts = {
  type GetToken (line 41) | type GetToken = (options: {
  type GetTokenWithRegistry (line 48) | type GetTokenWithRegistry = (options: {
  type ProviderFactory (line 59) | interface ProviderFactory {
  type Provider (line 113) | interface Provider {

FILE: packages/jsrepo/src/utils/add.ts
  type ResolvedRegistry (line 45) | type ResolvedRegistry = {
  function resolveRegistries (line 59) | async function resolveRegistries(
  type WantedItem (line 92) | type WantedItem = {
  function parseWantedItems (line 106) | function parseWantedItems(
  type ResolvedWantedItem (line 140) | type ResolvedWantedItem = {
  function resolveWantedItems (line 163) | async function resolveWantedItems(
  type ResolvedItem (line 245) | type ResolvedItem = {
  type ItemRepository (line 260) | type ItemRepository = {
  type ItemDistributed (line 274) | type ItemDistributed = DistributedOutputItem & { registry: ResolvedRegis...
  function fetchItem (line 276) | async function fetchItem(block: ResolvedItem) {
  function fetchFile (line 293) | async function fetchFile(fileName: string, block: ResolvedItem) {
  function fetchItemRepositoryMode (line 322) | async function fetchItemRepositoryMode(
  function fetchItemDistributedMode (line 364) | async function fetchItemDistributedMode(
  type ExtractResultValue (line 384) | type ExtractResultValue<T> = T extends Result<infer V, unknown> ? V : ne...
  function fetchAllResolvedItems (line 386) | async function fetchAllResolvedItems(
  function getItemLocation (line 422) | async function getItemLocation(
  type FetchedItem (line 489) | type FetchedItem = ExtractResultValue<
  type FileWithContents (line 493) | type FileWithContents = ExtractResultValue<
  function transformRemoteContent (line 497) | async function transformRemoteContent(
  function getTargetPath (line 528) | function getTargetPath(
  type RegistryItemWithContent (line 545) | type RegistryItemWithContent = ItemRepository | ItemDistributed;
  function resolveAndFetchAllItems (line 547) | async function resolveAndFetchAllItems(
  function resolveTree (line 582) | function resolveTree(
  function getPathsForItems (line 658) | async function getPathsForItems({
  function getItemPaths (line 732) | function getItemPaths(
  type UpdatedFile (line 805) | type UpdatedFile = {
  function prepareUpdates (line 830) | async function prepareUpdates({
  function updateFiles (line 1052) | async function updateFiles({
  function normalizeItemTypeForPath (line 1124) | function normalizeItemTypeForPath(type: RegistryItemType) {

FILE: packages/jsrepo/src/utils/build.ts
  constant DO_NOT_RESOLVE_EXTENSIONS (line 48) | const DO_NOT_RESOLVE_EXTENSIONS = [
  constant MANIFEST_FILE (line 90) | const MANIFEST_FILE = 'registry.json';
  type BuildResult (line 92) | type BuildResult = RegistryMeta & {
  type Ecosystem (line 102) | type Ecosystem = LooseAutocomplete<'js'>;
  type ResolvedItem (line 104) | type ResolvedItem = {
  type RegistryFile (line 121) | type RegistryFile = {
  type UnresolvedImport (line 148) | type UnresolvedImport = {
  type RemoteDependency (line 157) | type RemoteDependency = {
  type LocalDependency (line 164) | type LocalDependency = {
  type Dependency (line 175) | type Dependency = RemoteDependency | LocalDependency;
  function isLocalDependency (line 177) | function isLocalDependency(dependency: Dependency): dependency is LocalD...
  function isRemoteDependency (line 181) | function isRemoteDependency(dependency: Dependency): dependency is Remot...
  type ParentItem (line 185) | type ParentItem = { name: string; type: RegistryItemType; registryName: ...
  type UnresolvedFile (line 190) | type UnresolvedFile = {
  type ResolvedFile (line 209) | type ResolvedFile = {
  type ResolvedFiles (line 234) | type ResolvedFiles = Map<NormalizedAbsolutePath, ResolvedFile>;
  function validateRegistryConfig (line 240) | async function validateRegistryConfig(
  type ExpandedRegistryItem (line 286) | type ExpandedRegistryItem = Omit<RegistryItem, 'files'> & {
  function expandRegistryItems (line 296) | async function expandRegistryItems(
  function expandItemFiles (line 323) | async function expandItemFiles(
  function expandItemFolderFiles (line 493) | async function expandItemFolderFiles(
  function buildRegistry (line 656) | async function buildRegistry(
  function resolveFiles (line 700) | async function resolveFiles(
  function resolveFile (line 747) | async function resolveFile(
  function resolveRegistryItems (line 845) | async function resolveRegistryItems(
  type DependencyKey (line 875) | type DependencyKey = `${Ecosystem}:${string}@${string}`;
  function toDependencyKey (line 877) | function toDependencyKey(dep: RemoteDependency): DependencyKey {
  function resolveRemoteDependencies (line 881) | async function resolveRemoteDependencies(
  function resolveRegistryItem (line 913) | async function resolveRegistryItem(
  function resolveFileDependencies (line 1018) | async function resolveFileDependencies(
  function toRemoteDependencies (line 1186) | function toRemoteDependencies(
  function stringToRemoteDependency (line 1212) | function stringToRemoteDependency(

FILE: packages/jsrepo/src/utils/casing.ts
  function kebabToCamel (line 12) | function kebabToCamel(str: string): string {

FILE: packages/jsrepo/src/utils/compat/shadcn.ts
  constant SUPPORTED_EXTENSIONS (line 5) | const SUPPORTED_EXTENSIONS = ['.tsx', '.ts', '.jsx', '.js'];
  type Config (line 11) | type Config = {
  function transformShadcnImports (line 21) | async function transformShadcnImports({
  function updateImportAliases (line 52) | function updateImportAliases(moduleSpecifier: string, config: Config) {
  function endsWithOneOf (line 82) | function endsWithOneOf(fileName: string, extensions: string[]): boolean {

FILE: packages/jsrepo/src/utils/config/index.ts
  type RegistryConfigArgs (line 17) | type RegistryConfigArgs = [{ cwd: string }];
  type RemoteDependencyResolverOptions (line 19) | type RemoteDependencyResolverOptions = {
  type RemoteDependencyResolver (line 23) | type RemoteDependencyResolver = (
  type BuildTransform (line 28) | type BuildTransform = {
  type Config (line 35) | type Config = {
  type RegistryMeta (line 162) | type RegistryMeta = {
  type RegistryConfig (line 189) | type RegistryConfig = RegistryMeta & {
  type RegistryPlugin (line 207) | type RegistryPlugin = {
  type RegistryItemType (line 216) | type RegistryItemType = LooseAutocomplete<
  type RegistryItemAdd (line 227) | type RegistryItemAdd = (typeof RegistryItemAddOptions)[number];
  type RegistryItem (line 229) | type RegistryItem = {
  type BuiltinRegistryFileRole (line 288) | type BuiltinRegistryFileRole = (typeof RegistryFileRoles)[number];
  type RegistryFileRoles (line 289) | type RegistryFileRoles = LooseAutocomplete<BuiltinRegistryFileRole>;
  type RegistryItemFile (line 291) | type RegistryItemFile = {
  type RegistryItemFolderFile (line 354) | type RegistryItemFolderFile = Prettify<
  type TransformOptions (line 363) | type TransformOptions = {
  type Transform (line 372) | type Transform = {
  function defineConfig (line 380) | function defineConfig(config: Partial<Config> | (() => Partial<Config>))...

FILE: packages/jsrepo/src/utils/config/mods/add-plugins.ts
  class VisitorState (line 25) | class VisitorState {
  type Plugin (line 42) | type Plugin = {
  function addPluginsToConfig (line 48) | async function addPluginsToConfig({
  function neededPlugins (line 303) | async function neededPlugins({
  constant OFFICIAL_PLUGINS (line 320) | const OFFICIAL_PLUGINS = [
  function parsePlugins (line 343) | function parsePlugins(
  function parsePluginName (line 356) | function parsePluginName(

FILE: packages/jsrepo/src/utils/config/mods/add-registries.ts
  class VisitorState (line 13) | class VisitorState {
  function addRegistriesToConfig (line 26) | async function addRegistriesToConfig(

FILE: packages/jsrepo/src/utils/config/mods/update-paths.ts
  class VisitorState (line 15) | class VisitorState {
  function updateConfigPaths (line 28) | async function updateConfigPaths(

FILE: packages/jsrepo/src/utils/config/utils.ts
  constant VALID_VARIABLE_NAME_REGEX (line 13) | const VALID_VARIABLE_NAME_REGEX = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/;
  function _createConfigLoader (line 15) | function _createConfigLoader({ cwd }: { cwd: string }) {
  function loadConfig (line 32) | function loadConfig({
  function loadConfigOptional (line 47) | function loadConfigOptional({
  function loadConfigSearch (line 70) | async function loadConfigSearch({
  function getPathsMatcher (line 108) | function getPathsMatcher({ cwd }: { cwd: AbsolutePath }): PathsMatcher {
  function resolvePaths (line 114) | function resolvePaths(
  function resolvePath (line 128) | function resolvePath(

FILE: packages/jsrepo/src/utils/diff.ts
  type Options (line 6) | type Options = {
  function isWhitespace (line 36) | function isWhitespace(str: string) {
  function trimSingleNewLine (line 46) | function trimSingleNewLine(str: string): string {
  type DiffResult (line 64) | type DiffResult =
  function formatDiff (line 73) | function formatDiff({

FILE: packages/jsrepo/src/utils/env.ts
  constant ENV_FILE_NAMES (line 5) | const ENV_FILE_NAMES = [
  function searchForEnvFile (line 12) | function searchForEnvFile(
  function parseEnvVariables (line 31) | function parseEnvVariables(contents: string): Record<string, string> {
  function updateEnvFile (line 117) | function updateEnvFile(contents: string, envVars: Record<string, string>...

FILE: packages/jsrepo/src/utils/errors.ts
  type CLIError (line 6) | type CLIError =
  class JsrepoError (line 45) | class JsrepoError extends Error {
    method constructor (line 48) | constructor(
    method toString (line 61) | toString() {
  class NoPackageJsonFoundError (line 66) | class NoPackageJsonFoundError extends JsrepoError {
    method constructor (line 67) | constructor() {
  class InvalidRegistryError (line 75) | class InvalidRegistryError extends JsrepoError {
    method constructor (line 76) | constructor(registry: string) {
  class RegistryItemNotFoundError (line 87) | class RegistryItemNotFoundError extends JsrepoError {
    method constructor (line 88) | constructor(itemName: string, registry?: string) {
  class ProviderFetchError (line 100) | class ProviderFetchError extends JsrepoError {
    method constructor (line 103) | constructor(message: string, resourcePath: string) {
  class ManifestFetchError (line 112) | class ManifestFetchError extends JsrepoError {
    method constructor (line 113) | constructor(error: unknown) {
  class RegistryItemFetchError (line 127) | class RegistryItemFetchError extends JsrepoError {
    method constructor (line 128) | constructor(error: unknown, options: { registry: string; item: string ...
  class RegistryFileFetchError (line 144) | class RegistryFileFetchError extends JsrepoError {
    method constructor (line 145) | constructor(
  class RegistryNotProvidedError (line 160) | class RegistryNotProvidedError extends JsrepoError {
    method constructor (line 161) | constructor() {
  class MultipleRegistriesError (line 169) | class MultipleRegistriesError extends JsrepoError {
    method constructor (line 170) | constructor(itemName: string, registries: string[]) {
  class AlreadyInitializedError (line 184) | class AlreadyInitializedError extends JsrepoError {
    method constructor (line 185) | constructor() {
  class FailedToLoadConfigError (line 192) | class FailedToLoadConfigError extends JsrepoError {
    method constructor (line 193) | constructor(cause: unknown) {
  class ConfigNotFoundError (line 200) | class ConfigNotFoundError extends JsrepoError {
    method constructor (line 201) | constructor(path: string) {
  class InvalidOptionsError (line 209) | class InvalidOptionsError extends JsrepoError {
    method constructor (line 210) | constructor(error: z.ZodError) {
  class NoRegistriesError (line 220) | class NoRegistriesError extends JsrepoError {
    method constructor (line 221) | constructor() {
  class NoPathProvidedError (line 228) | class NoPathProvidedError extends JsrepoError {
    method constructor (line 229) | constructor({ item, type }: { item: string; type: string }) {
  class BuildError (line 237) | class BuildError extends JsrepoError {
    method constructor (line 239) | constructor(
  class ModuleNotFoundError (line 251) | class ModuleNotFoundError extends JsrepoError {
    method constructor (line 252) | constructor(mod: string, { fileName }: { fileName: string }) {
  class NoOutputsError (line 259) | class NoOutputsError extends BuildError {
    method constructor (line 260) | constructor({ registryName }: { registryName: string }) {
  class NoListedItemsError (line 269) | class NoListedItemsError extends BuildError {
    method constructor (line 270) | constructor({ registryName }: { registryName: string }) {
  class DuplicateItemNameError (line 278) | class DuplicateItemNameError extends BuildError {
    method constructor (line 279) | constructor({ name, registryName }: { name: string; registryName: stri...
  class SelfReferenceError (line 287) | class SelfReferenceError extends BuildError {
    method constructor (line 288) | constructor({ name, registryName }: { name: string; registryName: stri...
  class NoFilesError (line 296) | class NoFilesError extends BuildError {
    method constructor (line 297) | constructor({ name, registryName }: { name: string; registryName: stri...
  class IllegalItemNameError (line 305) | class IllegalItemNameError extends BuildError {
    method constructor (line 306) | constructor({ name, registryName }: { name: string; registryName: stri...
  class InvalidRegistryDependencyError (line 314) | class InvalidRegistryDependencyError extends BuildError {
    method constructor (line 315) | constructor({
  class InvalidDependencyError (line 327) | class InvalidDependencyError extends BuildError {
    method constructor (line 328) | constructor({
  class DuplicateFileReferenceError (line 344) | class DuplicateFileReferenceError extends BuildError {
    method constructor (line 345) | constructor({
  class FileNotFoundError (line 368) | class FileNotFoundError extends BuildError {
    method constructor (line 369) | constructor({
  class ImportedFileNotResolvedError (line 388) | class ImportedFileNotResolvedError extends BuildError {
    method constructor (line 389) | constructor({
  class InvalidPluginError (line 410) | class InvalidPluginError extends JsrepoError {
    method constructor (line 411) | constructor(plugin: string) {
  class InvalidKeyTypeError (line 418) | class InvalidKeyTypeError extends JsrepoError {
    method constructor (line 419) | constructor({ key, type }: { key: string; type: 'object' | 'array' }) {
  class ConfigObjectNotFoundError (line 426) | class ConfigObjectNotFoundError extends JsrepoError {
    method constructor (line 427) | constructor() {
  class CouldNotFindJsrepoImportError (line 434) | class CouldNotFindJsrepoImportError extends JsrepoError {
    method constructor (line 435) | constructor() {
  class ZodError (line 442) | class ZodError extends JsrepoError {
    method constructor (line 444) | constructor(error: z.ZodError) {
  class InvalidJSONError (line 452) | class InvalidJSONError extends JsrepoError {
    method constructor (line 453) | constructor(error: unknown) {
  class GlobError (line 463) | class GlobError extends BuildError {
    method constructor (line 464) | constructor(error: unknown, pattern: Pattern, registryName: string) {
  class NoProviderFoundError (line 475) | class NoProviderFoundError extends JsrepoError {
    method constructor (line 476) | constructor(provider: string) {
  class NoItemsToUpdateError (line 486) | class NoItemsToUpdateError extends JsrepoError {
    method constructor (line 487) | constructor() {
  class MissingPeerDependencyError (line 495) | class MissingPeerDependencyError extends JsrepoError {
    method constructor (line 496) | constructor(packageName: string, feature: string) {
  class InvalidRegistryNameError (line 503) | class InvalidRegistryNameError extends JsrepoError {
    method constructor (line 504) | constructor(registryName: string) {
  class InvalidRegistryVersionError (line 516) | class InvalidRegistryVersionError extends JsrepoError {
    method constructor (line 517) | constructor(registryVersion: string | undefined, registryName: string) {
  class Unreachable (line 540) | class Unreachable extends JsrepoError {
    method constructor (line 541) | constructor() {

FILE: packages/jsrepo/src/utils/fs.ts
  function readFileSync (line 7) | function readFileSync(p: AbsolutePath): Result<string, JsrepoError> {
  function writeFileSync (line 29) | function writeFileSync(p: AbsolutePath, data: string): Result<void, Jsre...
  function readdirSync (line 47) | function readdirSync(p: AbsolutePath): Result<string[], JsrepoError> {
  function mkdirSync (line 62) | function mkdirSync(p: AbsolutePath): Result<void, JsrepoError> {
  function rmSync (line 84) | function rmSync(p: AbsolutePath): Result<void, JsrepoError> {
  function existsSync (line 101) | function existsSync(p: AbsolutePath): boolean {
  function statSync (line 105) | function statSync(p: AbsolutePath): Result<fs.Stats, JsrepoError> {

FILE: packages/jsrepo/src/utils/glob.ts
  function glob (line 12) | async function glob(
  function getGlobBaseDirectory (line 31) | function getGlobBaseDirectory(pattern: Pattern, options?: fg.Options): s...

FILE: packages/jsrepo/src/utils/hooks.ts
  type BeforeArgs (line 25) | type BeforeArgs =
  type AfterArgs (line 37) | type AfterArgs =
  type HookFn (line 61) | type HookFn<Args> = (args: Args) => Promise<void>;
  type Hook (line 62) | type Hook<Args> = HookFn<Args> | string;
  type InferHookArgs (line 64) | type InferHookArgs<H> =
  type BeforeHook (line 67) | type BeforeHook = Hook<BeforeArgs>;
  type AfterHook (line 68) | type AfterHook = Hook<AfterArgs>;
  function runCommand (line 70) | async function runCommand(
  function runHooks (line 93) | async function runHooks<HookKey extends keyof NonNullable<Config['hooks'...
  function runBeforeHooks (line 123) | async function runBeforeHooks(
  function runAfterHooks (line 151) | async function runAfterHooks(

FILE: packages/jsrepo/src/utils/json.ts
  function stringify (line 1) | function stringify(data: unknown, options: { format?: boolean } = {}): s...

FILE: packages/jsrepo/src/utils/lines.ts
  constant NEW_LINE_REGEX (line 10) | const NEW_LINE_REGEX = /\n|\r\n/g;
  function get (line 23) | function get(str: string): string[] {
  type Options (line 27) | type Options = {
  function join (line 53) | function join(

FILE: packages/jsrepo/src/utils/package.ts
  function findNearestPackageJson (line 10) | function findNearestPackageJson(
  function tryGetPackage (line 25) | function tryGetPackage(path: AbsolutePath): Result<Partial<PackageJson>,...
  function getPackage (line 33) | function getPackage(path: AbsolutePath): Partial<PackageJson> {
  type PackageJson (line 37) | type PackageJson = {
  function cleanVersion (line 49) | function cleanVersion(version: string) {
  function shouldInstall (line 58) | function shouldInstall<T extends Omit<RemoteDependency, 'ecosystem'>>(

FILE: packages/jsrepo/src/utils/pad.ts
  function leftPad (line 17) | function leftPad(str: string, space: number, padWith = ' '): string {
  function leftPadMin (line 34) | function leftPadMin(str: string, length: number, padWith = ' '): string {
  function rightPad (line 57) | function rightPad(str: string, space: number, padWith = ' '): string {
  function rightPadMin (line 74) | function rightPadMin(str: string, length: number, padWith = ' '): string {
  function centerPad (line 99) | function centerPad(str: string, length: number, padWith = ' '): string {

FILE: packages/jsrepo/src/utils/parse-package-name.ts
  constant RE_SCOPED (line 9) | const RE_SCOPED = /^(@[^/]+\/[^@/]+)(?:@([^/]+))?(\/.*)?$/;
  constant RE_NON_SCOPED (line 11) | const RE_NON_SCOPED = /^([^@/]+)(?:@([^/]+))?(\/.*)?$/;
  type Package (line 13) | type Package = {
  function parsePackageName (line 21) | function parsePackageName(input: string) {

FILE: packages/jsrepo/src/utils/path.ts
  function joinAbsolute (line 11) | function joinAbsolute(p: AbsolutePath, ...paths: string[]): AbsolutePath {
  type NormalizedAbsolutePath (line 15) | type NormalizedAbsolutePath = Branded<AbsolutePath, 'normalizedAbsoluteP...
  function normalizeAbsolute (line 17) | function normalizeAbsolute(p: AbsolutePath): NormalizedAbsolutePath {
  function joinRelative (line 21) | function joinRelative(p: ItemRelativePath, ...paths: string[]): ItemRela...
  function dirname (line 32) | function dirname(p: AbsolutePath): AbsolutePath {
  type RelativeToCwdPath (line 36) | type RelativeToCwdPath = Branded<ItemRelativePath, 'relativeToCwdPath'>;
  function relativeToCwd (line 38) | function relativeToCwd(cwd: AbsolutePath, p: AbsolutePath): RelativeToCw...

FILE: packages/jsrepo/src/utils/persisted.ts
  function get (line 3) | function get() {

FILE: packages/jsrepo/src/utils/prompts.ts
  function intro (line 35) | function intro() {
  function createVerboseLogger (line 41) | function createVerboseLogger({
  type Spinner (line 52) | type Spinner = ReturnType<typeof spinner>;
  function initLogging (line 60) | function initLogging({ options }: { options: { verbose: boolean } }) {
  function spinner (line 73) | function spinner({
  function promptInstallDependencies (line 119) | async function promptInstallDependencies(
  function promptAddEnvVars (line 160) | async function promptAddEnvVars(
  function promptInstallDependenciesByEcosystem (line 211) | async function promptInstallDependenciesByEcosystem(
  function runCommands (line 297) | async function runCommands({
  function detectPackageManager (line 338) | async function detectPackageManager(cwd: AbsolutePath): Promise<Agent> {
  constant VERTICAL_LINE (line 348) | const VERTICAL_LINE = pc.gray(s('│', '|'));

FILE: packages/jsrepo/src/utils/roles.ts
  function resolveWithRoles (line 1) | function resolveWithRoles(options: {
  function shouldIncludeRole (line 17) | function shouldIncludeRole(role: string | undefined, withRoles: Set<stri...
  function isOptionalRole (line 22) | function isOptionalRole(role: string | undefined): boolean {

FILE: packages/jsrepo/src/utils/strings.ts
  function endsWithOneOf (line 13) | function endsWithOneOf<T extends string>(str: string, strings: readonly ...

FILE: packages/jsrepo/src/utils/token-manager.ts
  class TokenManager (line 6) | class TokenManager {
    method constructor (line 9) | constructor(storage?: Conf) {
    method get (line 13) | get(provider: ProviderFactory, registry: string | undefined): string |...
    method set (line 37) | set(provider: ProviderFactory, registry: string | undefined, secret: s...
    method delete (line 52) | delete(provider: ProviderFactory, registry: string | undefined) {
    method getProviderRegistryTokens (line 68) | getProviderRegistryTokens(provider: ProviderFactory): Record<string, s...
    method setProviderRegistryToken (line 74) | setProviderRegistryToken(provider: ProviderFactory, registry: string, ...

FILE: packages/jsrepo/src/utils/tsconfig.ts
  function tryGetTsconfig (line 14) | function tryGetTsconfig(
  type PathsMatcher (line 38) | type PathsMatcher = ((specifier: string) => string[]) | null;
  function _createPathsMatcher (line 40) | function _createPathsMatcher(

FILE: packages/jsrepo/src/utils/types.ts
  type LooseAutocomplete (line 1) | type LooseAutocomplete<T> = T | (string & {});
  type Prettify (line 3) | type Prettify<T> = {
  type Brand (line 9) | type Brand<B extends string> = { [brand]: B };
  type Branded (line 18) | type Branded<T, B extends string> = T & Brand<B>;
  type AbsolutePath (line 23) | type AbsolutePath = Branded<string, 'absolutePath'>;
  type ItemRelativePath (line 28) | type ItemRelativePath = Branded<string, 'itemRelativePath'>;
  type MaybePromise (line 30) | type MaybePromise<T> = T | Promise<T> | PromiseLike<T>;

FILE: packages/jsrepo/src/utils/url.ts
  function join (line 13) | function join(...segments: string[]): string {
  function removeLeadingAndTrailingSlash (line 32) | function removeLeadingAndTrailingSlash(segment: string): string {
  function addLeadingAndTrailingSlash (line 49) | function addLeadingAndTrailingSlash(segment: string): string {
  function removeLeadingSlash (line 69) | function removeLeadingSlash(segment: string): string {
  function addLeadingSlash (line 90) | function addLeadingSlash(segment: string): string {
  function removeTrailingSlash (line 111) | function removeTrailingSlash(segment: string): string {
  function addTrailingSlash (line 132) | function addTrailingSlash(segment: string): string {

FILE: packages/jsrepo/src/utils/utils.ts
  type MaybeGetter (line 1) | type MaybeGetter<T, Args extends unknown[] = unknown[]> = T | ((...args:...
  function extract (line 3) | function extract<T, Args extends unknown[] = unknown[]>(
  type MaybeGetterAsync (line 11) | type MaybeGetterAsync<T, Args extends unknown[] = unknown[]> =
  function extractAsync (line 15) | async function extractAsync<T, Args extends unknown[] = unknown[]>(
  function isFunction (line 23) | function isFunction<T, Args extends unknown[] = unknown[]>(
  function isFunctionAsync (line 29) | function isFunctionAsync<T, Args extends unknown[] = unknown[]>(
  function debounced (line 35) | function debounced<Args extends unknown[] = unknown[]>(
  function sleep (line 60) | function sleep(durationMs: number): Promise<void> {
  function noop (line 64) | function noop() {

FILE: packages/jsrepo/src/utils/validate-npm-package-name.ts
  type ValidationResult (line 3) | interface ValidationResult {
  function validateNpmPackageName (line 13) | function validateNpmPackageName(name: string | null | undefined): Valida...

FILE: packages/jsrepo/src/utils/warnings.ts
  class Warning (line 8) | class Warning {
    method constructor (line 9) | constructor(public readonly message: string) {}
  type WarningHandler (line 15) | type WarningHandler = (warning: Warning) => void;
  class LanguageNotFoundWarning (line 20) | class LanguageNotFoundWarning extends Warning {
    method constructor (line 22) | constructor(options: { path: string }) {
  class InvalidImportWarning (line 31) | class InvalidImportWarning extends Warning {
    method constructor (line 34) | constructor(options: { specifier: string; fileName: string }) {
  class UnresolvableDynamicImportWarning (line 46) | class UnresolvableDynamicImportWarning extends Warning {
    method constructor (line 49) | constructor(options: { specifier: string; fileName: string }) {
  class GlobPatternNoMatchWarning (line 61) | class GlobPatternNoMatchWarning extends Warning {
    method constructor (line 64) | constructor(options: { itemName: string; pattern: string }) {
  function createWarningHandler (line 76) | function createWarningHandler(onwarn?: Config['build']['onwarn']): Warni...

FILE: packages/jsrepo/src/utils/zod.ts
  function safeValidate (line 5) | function safeValidate<T>(schema: z.ZodSchema<T>, data: unknown): Result<...
  function safeParseFromJSON (line 13) | function safeParseFromJSON<T>(

FILE: packages/jsrepo/tests/build.test.ts
  function buildWithResolver (line 444) | async function buildWithResolver(

FILE: packages/jsrepo/tests/fixtures/build/src/components/ui/button.tsx
  function Button (line 3) | function Button(props: React.ComponentProps<'button'>) {

FILE: packages/jsrepo/tests/fixtures/build/src/utils.ts
  constant STDOUT_PREFIX (line 1) | const STDOUT_PREFIX = 'stdout: ';

FILE: packages/jsrepo/tests/fixtures/build/src/utils/math/add.ts
  function add (line 1) | function add(a: number, b: number) {

FILE: packages/jsrepo/tests/fixtures/build/src/utils/math/answer-format.ts
  function answerFormat (line 4) | function answerFormat(answer: number) {

FILE: packages/jsrepo/tests/fixtures/build/src/utils/stdout.ts
  function print (line 3) | function print(msg: string) {

FILE: packages/jsrepo/tests/fixtures/langs/js-baseurl-bare-imports/types.ts
  type BunRouteHandler (line 3) | type BunRouteHandler = (req: BunRequest) => Response | Promise<Response>;

FILE: packages/jsrepo/tests/fixtures/langs/js-subpath-imports/src/utils/print.ts
  function print (line 1) | function print(..._args: unknown[]) {}

FILE: packages/jsrepo/tests/fixtures/langs/js/logger.ts
  class Logger (line 4) | class Logger {
    method warn (line 5) | warn(msg: string) {
    method error (line 9) | error(msg: string) {

FILE: packages/jsrepo/tests/fixtures/langs/js/math/add.ts
  function add (line 1) | function add(a: number, b: number) {

FILE: packages/jsrepo/tests/fixtures/langs/js/math/subtract.ts
  function subtract (line 1) | function subtract(a: number, b: number) {

FILE: packages/jsrepo/tests/fixtures/langs/js/print-answer.ts
  function printAnswer (line 5) | function printAnswer(fn: typeof add | typeof subtract) {

FILE: packages/jsrepo/tests/fixtures/langs/js/stdout.ts
  function print (line 1) | function print(msg: string) {

FILE: packages/jsrepo/tests/langs/js.test.ts
  constant CWD (line 8) | const CWD = path.join(__dirname, '../fixtures/langs/js') as AbsolutePath;
  constant SUBPATH_IMPORTS_CWD (line 9) | const SUBPATH_IMPORTS_CWD = path.join(
  constant BASE_URL_BARE_IMPORTS_CWD (line 13) | const BASE_URL_BARE_IMPORTS_CWD = path.join(
  constant ARBITRARY_EXTENSIONS_CWD (line 17) | const ARBITRARY_EXTENSIONS_CWD = path.join(

FILE: packages/jsrepo/tests/langs/svelte.test.ts
  constant CWD (line 8) | const CWD = path.join(__dirname, '../fixtures/langs/svelte') as Absolute...

FILE: packages/jsrepo/tests/utils/add.test.ts
  constant RESOLVED_REGISTRY (line 138) | const RESOLVED_REGISTRY = {

FILE: packages/mcp/src/server.ts
  function displayItem (line 357) | function displayItem(item: (typeof candidateItems)[number]) {
  function displayItemDetails (line 384) | function displayItemDetails(item: RegistryItemWithContent): string {

FILE: packages/migrate/src/commands/utils.ts
  constant TRACE_ENV_VAR (line 10) | const TRACE_ENV_VAR = 'JSREPO_TRACE';
  function parseOptions (line 21) | function parseOptions<T>(
  function tryCommand (line 36) | async function tryCommand<T, E extends JsrepoError>(
  function error (line 57) | function error(err: Error): never {
  function handleError (line 61) | function handleError(err: Error): never {

FILE: packages/migrate/src/commands/v3.ts
  type V3Options (line 49) | type V3Options = z.infer<typeof schema>;
  type V3CommandResult (line 81) | type V3CommandResult = {
  function runV3 (line 92) | async function runV3(options: V3Options): Promise<Result<V3CommandResult...
  function getFileRole (line 297) | function getFileRole(file: string): RegistryItemFile['role'] {
  function migrateProjectConfig (line 303) | async function migrateProjectConfig({
  function migrateRegistryConfig (line 328) | async function migrateRegistryConfig({

FILE: packages/migrate/src/utils/errors.ts
  type CLIError (line 4) | type CLIError =
  class JsrepoError (line 11) | class JsrepoError extends Error {
    method constructor (line 14) | constructor(
    method toString (line 27) | toString() {
  class NoPackageJsonFoundError (line 32) | class NoPackageJsonFoundError extends JsrepoError {
    method constructor (line 33) | constructor() {
  class ManifestNotFoundError (line 41) | class ManifestNotFoundError extends JsrepoError {
    method constructor (line 42) | constructor({ path }: { path: string }) {
  class InvalidOptionsError (line 50) | class InvalidOptionsError extends JsrepoError {
    method constructor (line 51) | constructor(error: z.ZodError) {
  class ZodError (line 61) | class ZodError extends JsrepoError {
    method constructor (line 63) | constructor(error: z.ZodError) {
  class InvalidJSONError (line 71) | class InvalidJSONError extends JsrepoError {
    method constructor (line 72) | constructor(error: unknown) {

FILE: packages/migrate/src/utils/fs.ts
  function readFileSync (line 7) | function readFileSync(p: AbsolutePath): Result<string, JsrepoError> {
  function writeFileSync (line 29) | function writeFileSync(p: AbsolutePath, data: string): Result<void, Jsre...
  function mkdirSync (line 47) | function mkdirSync(p: AbsolutePath): Result<void, JsrepoError> {
  function rmSync (line 69) | function rmSync(p: AbsolutePath): Result<void, JsrepoError> {
  function existsSync (line 86) | function existsSync(p: AbsolutePath): boolean {

FILE: packages/migrate/src/utils/json.ts
  function stringify (line 1) | function stringify(data: unknown, options: { format?: boolean } = {}): s...

FILE: packages/migrate/src/utils/package.ts
  function findNearestPackageJson (line 10) | function findNearestPackageJson(
  function tryGetPackage (line 25) | function tryGetPackage(path: AbsolutePath): Result<Partial<PackageJson>,...
  function getPackage (line 33) | function getPackage(path: AbsolutePath): Partial<PackageJson> {
  type PackageJson (line 37) | type PackageJson = {
  function cleanVersion (line 49) | function cleanVersion(version: string) {
  function shouldInstall (line 58) | function shouldInstall(

FILE: packages/migrate/src/utils/parse-package-name.ts
  constant RE_SCOPED (line 9) | const RE_SCOPED = /^(@[^/]+\/[^@/]+)(?:@([^/]+))?(\/.*)?$/;
  constant RE_NON_SCOPED (line 11) | const RE_NON_SCOPED = /^([^@/]+)(?:@([^/]+))?(\/.*)?$/;
  type Package (line 13) | type Package = {
  function parsePackageName (line 21) | function parsePackageName(input: string) {

FILE: packages/migrate/src/utils/path.ts
  function joinAbsolute (line 11) | function joinAbsolute(p: AbsolutePath, ...paths: string[]): AbsolutePath {
  function dirname (line 22) | function dirname(p: AbsolutePath): AbsolutePath {

FILE: packages/migrate/src/utils/prompts.ts
  function intro (line 10) | function intro() {
  function runCommands (line 18) | async function runCommands({
  function installDependencies (line 59) | async function installDependencies(

FILE: packages/migrate/src/utils/strings.ts
  function endsWithOneOf (line 13) | function endsWithOneOf<T extends string>(str: string, strings: readonly ...

FILE: packages/migrate/src/utils/v2/config.ts
  constant REGISTRY_CONFIG_FILE_V2 (line 4) | const REGISTRY_CONFIG_FILE_V2 = 'jsrepo-build-config.json';
  constant MANIFEST_FILE_V2 (line 5) | const MANIFEST_FILE_V2 = 'jsrepo-manifest.json';
  constant PROJECT_CONFIG_FILE_V2 (line 6) | const PROJECT_CONFIG_FILE_V2 = 'jsrepo.json';
  type RegistryConfigV2 (line 71) | type RegistryConfigV2 = z.infer<typeof RegistryConfigSchemaV2>;
  type ProjectConfigV2 (line 122) | type ProjectConfigV2 = z.infer<typeof ProjectConfigSchemaV2>;
  constant TEST_SUFFIXES (line 124) | const TEST_SUFFIXES = [
  constant DOCS_SUFFIXES (line 139) | const DOCS_SUFFIXES = ['.mdx', '.md'] as const;
  function isTestFile (line 141) | function isTestFile(file: string): boolean {
  function isDocsFile (line 145) | function isDocsFile(file: string): boolean {

FILE: packages/migrate/src/utils/zod.ts
  function safeValidate (line 5) | function safeValidate<T>(schema: z.ZodSchema<T>, data: unknown): Result<...
  function safeParseFromJSON (line 13) | function safeParseFromJSON<T>(

FILE: packages/pnpm/src/catalog.ts
  type PnpmWorkspaceConfig (line 6) | type PnpmWorkspaceConfig = {
  type ParsedState (line 12) | type ParsedState = {
  function parsePnpmWorkspaceYaml (line 22) | function parsePnpmWorkspaceYaml(workspaceRoot: string): PnpmWorkspaceCon...
  function buildCatalogMaps (line 35) | function buildCatalogMaps(config: PnpmWorkspaceConfig): {
  function parsePnpmState (line 70) | function parsePnpmState(cwd: string): ParsedState {

FILE: packages/pnpm/src/index.ts
  function pnpm (line 26) | function pnpm(): RemoteDependencyResolver {
  function getOrParseState (line 112) | function getOrParseState(cwd: string): ParsedState {
  function resolveWorkspaceVersion (line 121) | function resolveWorkspaceVersion(versionSpec: string, workspaceVersion: ...
  function parseWorkspaceVersion (line 138) | function parseWorkspaceVersion(version: string):
  function parseCatalogVersion (line 173) | function parseCatalogVersion(version: string): { catalogName: string } |...
  function resolveWorkspacePath (line 180) | function resolveWorkspacePath(state: ParsedState, pathSpec: string): str...

FILE: packages/pnpm/src/workspace.ts
  type WorkspacePackage (line 6) | type WorkspacePackage = {
  function findPnpmWorkspaceRoot (line 14) | function findPnpmWorkspaceRoot(cwd: string): string | null {
  function expandWorkspacePackages (line 32) | function expandWorkspacePackages(workspaceRoot: string, packages: string...
  function readPackageInfo (line 48) | function readPackageInfo(dir: string): WorkspacePackage | null {
  function buildWorkspacePackageMap (line 66) | function buildWorkspacePackageMap(

FILE: packages/shadcn/src/index.ts
  type ShadcnRegistryItemType (line 15) | type ShadcnRegistryItemType = (typeof registryItemTypeSchema.options)[nu...
  type ShadcnRegistry (line 17) | type ShadcnRegistry = {
  type ShadcnRegistryItem (line 25) | type ShadcnRegistryItem = {
  function defineShadcnRegistry (line 67) | function defineShadcnRegistry(registry: ShadcnRegistry): RegistryConfig {

FILE: packages/shadcn/src/output.ts
  type OutputOptions (line 13) | type OutputOptions = {
  function output (line 18) | function output(options: OutputOptions): Output {
  function getType (line 170) | function getType(type?: string) {
  function stringify (line 176) | function stringify(data: unknown, options: { format?: boolean } = {}): s...

FILE: packages/shadcn/src/provider.ts
  type ShadcnOptions (line 4) | type ShadcnOptions = {
  function provider (line 33) | function provider(options: ShadcnOptions = {}): ProviderFactory {
  type ShadcnState (line 41) | type ShadcnState = {
  class Shadcn (line 45) | class Shadcn implements Provider {
    method constructor (line 46) | constructor(
    method fetch (line 51) | async fetch(resourcePath: string, { fetch: f = fetch }: FetchOptions):...
    method create (line 82) | static async create(

FILE: packages/shadcn/src/utils.ts
  constant RE_SCOPED (line 7) | const RE_SCOPED = /^(@[^/]+\/[^@/]+)(?:@([^/]+))?(\/.*)?$/;
  constant RE_NON_SCOPED (line 9) | const RE_NON_SCOPED = /^([^@/]+)(?:@([^/]+))?(\/.*)?$/;
  type Package (line 11) | type Package = {
  function parsePackageName (line 19) | function parsePackageName(

FILE: packages/transform-biome/src/index.ts
  function tryFormat (line 29) | async function tryFormat(code: string, { fileName, cwd }: { fileName: st...

FILE: packages/transform-filecasing/src/index.ts
  type CaseType (line 5) | type CaseType = 'kebab' | 'camel' | 'snake' | 'pascal';
  type Options (line 7) | type Options = {

FILE: packages/transform-javascript/src/index.ts
  type FileExtension (line 7) | type FileExtension = {
  type Options (line 14) | type Options = {
  constant SUPPORTED_EXTENSIONS (line 18) | const SUPPORTED_EXTENSIONS: FileExtension[] = [
  function endsWithOneOf (line 72) | function endsWithOneOf(fileName: string, extensions: string[]): boolean {
  function updateFileExtension (line 76) | function updateFileExtension(

FILE: packages/transform-oxfmt/src/index.ts
  function tryFormat (line 27) | async function tryFormat(

FILE: packages/transform-prettier/src/index.ts
  type Options (line 5) | type Options = {
  function tryFormat (line 39) | function tryFormat(
Condensed preview — 459 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,256K chars).
[
  {
    "path": ".changeset/config.json",
    "chars": 385,
    "preview": "{\n\t\"$schema\": \"https://unpkg.com/@changesets/config@3.1.1/schema.json\",\n\t\"changelog\": [\"@svitejs/changesets-changelog-gi"
  },
  {
    "path": ".github/workflows/build-example-registries.yml",
    "chars": 541,
    "preview": "name: build-example-registries\n\non:\n    pull_request:\n        branches: [main]\n\njobs:\n    build-example-registries:\n    "
  },
  {
    "path": ".github/workflows/bundle-analyze.yml",
    "chars": 657,
    "preview": "name: Bundle Analyze\n\non:\n    pull_request:\n        branches: [next, main]\n\njobs:\n    bundle-analyze:\n        runs-on: u"
  },
  {
    "path": ".github/workflows/ci.yml",
    "chars": 520,
    "preview": "name: CI\n\non:\n    pull_request:\n        branches: [main]\n\njobs:\n    CI:\n        runs-on: ubuntu-latest\n\n        steps:\n "
  },
  {
    "path": ".github/workflows/cli-preview.yml",
    "chars": 825,
    "preview": "name: Package Previews\non:\n    pull_request:\n        branches: [main]\n        paths:\n            - 'pnpm-lock.yaml'\n    "
  },
  {
    "path": ".github/workflows/publish.yml",
    "chars": 1378,
    "preview": "name: Publish\n\non:\n    push:\n        branches:\n            - main\n\nconcurrency: ${{ github.workflow }}-${{ github.ref }}"
  },
  {
    "path": ".github/workflows/test-external-projects.yml",
    "chars": 2468,
    "preview": "name: Test External Projects\n\non:\n    pull_request:\n        branches: [main]\n\njobs:\n    test-external-projects:\n        "
  },
  {
    "path": ".gitignore",
    "chars": 204,
    "preview": "node_modules\n\n# out\ndist\n\n# testing\ntemp-test\n**/tests/fixtures/**/node_modules\n**/tests/fixtures/**/package-lock.json\n*"
  },
  {
    "path": ".vscode/settings.json",
    "chars": 57,
    "preview": "{\n\t\"cSpell.words\": [\"fuzzysort\", \"onwarn\", \"packlist\"]\n}\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 2554,
    "preview": "# Contributing to jsrepo\n\nLooking to contribute to jsrepo? Great! You're in the right place. This guide will help you ge"
  },
  {
    "path": "LICENSE",
    "chars": 1063,
    "preview": "MIT License\n\nCopyright (c) 2025 jsrepo\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof "
  },
  {
    "path": "README.md",
    "chars": 501,
    "preview": "<img width=\"100%\" alt=\"CleanShot 2025-11-24 at 09 35 57\" src=\"https://github.com/user-attachments/assets/61899098-fbc9-4"
  },
  {
    "path": "apps/docs/.gitignore",
    "chars": 296,
    "preview": "# deps\n/node_modules\n\n# generated content\n.contentlayer\n.content-collections\n.source\n\n# test & build\n/coverage\n/.next/\n/"
  },
  {
    "path": "apps/docs/README.md",
    "chars": 1517,
    "preview": "# docs\n\nThis is a Next.js application generated with\n[Create Fumadocs](https://github.com/fuma-nama/fumadocs).\n\nRun deve"
  },
  {
    "path": "apps/docs/biome.json",
    "chars": 70,
    "preview": "{\n\t\"root\": false,\n\t\"extends\": \"//\",\n\t\"files\": {\n\t\t\"includes\": []\n\t}\n}\n"
  },
  {
    "path": "apps/docs/cli.json",
    "chars": 209,
    "preview": "{\n  \"aliases\": {\n    \"uiDir\": \"./components/ui\",\n    \"componentsDir\": \"./components\",\n    \"blockDir\": \"./components\",\n  "
  },
  {
    "path": "apps/docs/content/docs/cli/add.mdx",
    "chars": 1890,
    "preview": "---\ntitle: add\ndescription: Add items from registries to your project.\n---\n\n```sh\njsrepo add\n```\n\n## Usage\n\nAdd an item "
  },
  {
    "path": "apps/docs/content/docs/cli/auth.mdx",
    "chars": 1636,
    "preview": "---\ntitle: auth\ndescription: Authenticate to a provider or registry.\n---\n\n```sh\njsrepo auth\n```\n\n## Usage\n\nAuthenticate "
  },
  {
    "path": "apps/docs/content/docs/cli/build.mdx",
    "chars": 607,
    "preview": "---\ntitle: build\ndescription: Build your registry.\n---\n\n```sh\njsrepo build\n```\n\n## Usage\n\nBuild all blocks from the regi"
  },
  {
    "path": "apps/docs/content/docs/cli/config/language.mdx",
    "chars": 596,
    "preview": "---\ntitle: language\ndescription: Add a language to your config.\n---\n\n```sh\njsrepo config language\n```\n\n## Usage\n\nAdd a l"
  },
  {
    "path": "apps/docs/content/docs/cli/config/mcp.mdx",
    "chars": 1080,
    "preview": "---\ntitle: mcp\ndescription: Configure the jsrepo MCP server for your environment.\n---\n\n```sh\njsrepo config mcp\n```\n\n## U"
  },
  {
    "path": "apps/docs/content/docs/cli/config/meta.json",
    "chars": 25,
    "preview": "{\n  \"title\": \"config\"\n}\n\n"
  },
  {
    "path": "apps/docs/content/docs/cli/config/provider.mdx",
    "chars": 599,
    "preview": "---\ntitle: provider\ndescription: Add a provider to your config.\n---\n\n```sh\njsrepo config provider\n```\n\n## Usage\n\nAdd a p"
  },
  {
    "path": "apps/docs/content/docs/cli/config/transform.mdx",
    "chars": 640,
    "preview": "---\ntitle: transform\ndescription: Add a transform to your config.\n---\n\n```sh\njsrepo config transform\n```\n\n## Usage\n\nAdd "
  },
  {
    "path": "apps/docs/content/docs/cli/meta.json",
    "chars": 22,
    "preview": "{\n  \"title\": \"CLI\"\n}\n\n"
  },
  {
    "path": "apps/docs/content/docs/cli/publish.mdx",
    "chars": 673,
    "preview": "---\ntitle: publish\ndescription: Publish your registry to jsrepo.com.\n---\n\n```sh\njsrepo publish\n```\n\n## Usage\n\nPublish al"
  },
  {
    "path": "apps/docs/content/docs/cli/update.mdx",
    "chars": 1709,
    "preview": "---\ntitle: update\ndescription: Update items in your project.\n---\n\n```sh\njsrepo update\n```\n\n## Usage\n\nUpdate an item in y"
  },
  {
    "path": "apps/docs/content/docs/create-a-registry.mdx",
    "chars": 23524,
    "preview": "---\ntitle: Create a registry\ndescription: A complete guide to creating your own registry with jsrepo.\n---\n\nIn this guide"
  },
  {
    "path": "apps/docs/content/docs/index.mdx",
    "chars": 2616,
    "preview": "---\ntitle: Introduction\ndescription: Why we built jsrepo.\n---\n\nimport Link from \"next/link\";\n\n[shadcn/ui](https://ui.sha"
  },
  {
    "path": "apps/docs/content/docs/jsrepo-com.mdx",
    "chars": 5189,
    "preview": "---\ntitle: jsrepo.com\ndescription: A registry for your registries.\n---\n\nimport { BadgesTable } from \"@/components/badges"
  },
  {
    "path": "apps/docs/content/docs/jsrepo-config.mdx",
    "chars": 10265,
    "preview": "---\ntitle: jsrepo.config\ndescription: The configuration file for jsrepo.\n---\n\nThe `jsrepo.config.(ts|js|mts|mjs)` file i"
  },
  {
    "path": "apps/docs/content/docs/languages/css.mdx",
    "chars": 1293,
    "preview": "---\ntitle: css\ndescription: CSS language support for jsrepo.\n---\n\n<BadgeGroup>\n\t<SourceBadge path=\"packages/jsrepo/src/l"
  },
  {
    "path": "apps/docs/content/docs/languages/html.mdx",
    "chars": 1140,
    "preview": "---\ntitle: html\ndescription: HTML language support for jsrepo.\n---\n\n<BadgeGroup>\n\t<SourceBadge path=\"packages/jsrepo/src"
  },
  {
    "path": "apps/docs/content/docs/languages/index.mdx",
    "chars": 3432,
    "preview": "---\ntitle: Languages\ndescription: Language support for jsrepo.\n---\n\n**jsrepo** uses languages to determine the dependenc"
  },
  {
    "path": "apps/docs/content/docs/languages/js.mdx",
    "chars": 1215,
    "preview": "---\ntitle: js\ndescription: JavaScript language support for jsrepo.\n---\n\n<BadgeGroup>\n\t<SourceBadge path=\"packages/jsrepo"
  },
  {
    "path": "apps/docs/content/docs/languages/svelte.mdx",
    "chars": 779,
    "preview": "---\ntitle: svelte\ndescription: Svelte language support for jsrepo.\n---\n\n<BadgeGroup>\n\t<SourceBadge path=\"packages/jsrepo"
  },
  {
    "path": "apps/docs/content/docs/languages/vue.mdx",
    "chars": 750,
    "preview": "---\ntitle: vue\ndescription: Vue language support for jsrepo.\n---\n\n<BadgeGroup>\n\t<SourceBadge path=\"packages/jsrepo/src/l"
  },
  {
    "path": "apps/docs/content/docs/legacy.mdx",
    "chars": 284,
    "preview": "---\ntitle: Legacy Docs\ndescription: Legacy documentation for jsrepo.\n---\n\nAll documentation for older versions of **jsre"
  },
  {
    "path": "apps/docs/content/docs/mcp.mdx",
    "chars": 4855,
    "preview": "---\ntitle: MCP Server\ndescription: The jsrepo MCP server.\n---\n\n<BadgeGroup>\n\t<SourceBadge path=\"packages/mcp\" />\n\t<Offic"
  },
  {
    "path": "apps/docs/content/docs/migrate.mdx",
    "chars": 6152,
    "preview": "---\ntitle: Migration\ndescription: Migrate from jsrepo v2 to jsrepo v3.\n---\n\n**jsrepo** v3 is a complete rewrite of the *"
  },
  {
    "path": "apps/docs/content/docs/outputs/distributed.mdx",
    "chars": 1194,
    "preview": "---\ntitle: Distributed\ndescription: Output your registry as json files in a directory.\n---\n\nimport { Files, Folder, File"
  },
  {
    "path": "apps/docs/content/docs/outputs/index.mdx",
    "chars": 3883,
    "preview": "---\ntitle: Outputs\ndescription: Output your registry however you want.\n---\n\nOutputs allow you to customize the way your "
  },
  {
    "path": "apps/docs/content/docs/outputs/repository.mdx",
    "chars": 702,
    "preview": "---\ntitle: Repository\ndescription: Output your registry as a single json file in the root of your repository.\n---\n\n<Badg"
  },
  {
    "path": "apps/docs/content/docs/outputs/shadcn.mdx",
    "chars": 2748,
    "preview": "---\ntitle: shadcn\ndescription: Output your registry as a shadcn registry.\n---\n\n<BadgeGroup>\n\t<SourceBadge path=\"packages"
  },
  {
    "path": "apps/docs/content/docs/providers/azure.mdx",
    "chars": 2542,
    "preview": "---\ntitle: azure\ndescription: Download and add registry items from an Azure DevOps repository.\n---\n\n<BadgeGroup>\n\t<Sourc"
  },
  {
    "path": "apps/docs/content/docs/providers/bitbucket.mdx",
    "chars": 3130,
    "preview": "---\ntitle: bitbucket\ndescription: Download and add registry items from a Bitbucket repository.\n---\n\n<BadgeGroup>\n\t<Sourc"
  },
  {
    "path": "apps/docs/content/docs/providers/fs.mdx",
    "chars": 1383,
    "preview": "---\ntitle: fs\ndescription: Download and add registry items from your local filesystem.\n---\n\n<BadgeGroup>\n\t<SourceBadge p"
  },
  {
    "path": "apps/docs/content/docs/providers/github.mdx",
    "chars": 4162,
    "preview": "---\ntitle: github\ndescription: Download and add registry items from a GitHub repository.\n---\n\n<BadgeGroup>\n\t<SourceBadge"
  },
  {
    "path": "apps/docs/content/docs/providers/gitlab.mdx",
    "chars": 3123,
    "preview": "---\ntitle: gitlab\ndescription: Download and add registry items from a GitLab repository.\n---\n\n<BadgeGroup>\n\t<SourceBadge"
  },
  {
    "path": "apps/docs/content/docs/providers/http.mdx",
    "chars": 3769,
    "preview": "---\ntitle: http\ndescription: Download and add registry items from an arbitrary HTTP endpoint.\n---\n\nimport { Files, Folde"
  },
  {
    "path": "apps/docs/content/docs/providers/index.mdx",
    "chars": 2866,
    "preview": "---\ntitle: Providers\ndescription: Host your code anywhere with jsrepo.\n---\n\nProviders are how **jsrepo** knows where to "
  },
  {
    "path": "apps/docs/content/docs/providers/jsrepo.mdx",
    "chars": 1848,
    "preview": "---\ntitle: jsrepo\ndescription: Download and add registry items from jsrepo.com\n---\n\n<BadgeGroup>\n\t<SourceBadge path=\"pac"
  },
  {
    "path": "apps/docs/content/docs/providers/shadcn.mdx",
    "chars": 1298,
    "preview": "---\ntitle: shadcn\ndescription: Download and add items from the shadcn registry index.\n---\n\nimport { RegistryDirectory } "
  },
  {
    "path": "apps/docs/content/docs/transforms/biome.mdx",
    "chars": 1159,
    "preview": "---\ntitle: Biome\ndescription: Format code before it's added to your project using Biome.\n---\n\n<BadgeGroup>\n\t<SourceBadge"
  },
  {
    "path": "apps/docs/content/docs/transforms/filecasing.mdx",
    "chars": 3959,
    "preview": "---\ntitle: File Casing\ndescription: Transform file and folder names to different case formats before adding them to your"
  },
  {
    "path": "apps/docs/content/docs/transforms/index.mdx",
    "chars": 3744,
    "preview": "---\ntitle: Transforms\ndescription: Modify code before it is added to your project.\n---\n\nTransforms are a way to modify c"
  },
  {
    "path": "apps/docs/content/docs/transforms/javascript.mdx",
    "chars": 1807,
    "preview": "---\ntitle: JavaScript\ndescription: Transform TypeScript registry items into JavaScript before adding them to your projec"
  },
  {
    "path": "apps/docs/content/docs/transforms/oxfmt.mdx",
    "chars": 1140,
    "preview": "---\ntitle: oxfmt\ndescription: Format code before it's added to your project using oxfmt.\n---\n\n<BadgeGroup>\n\t<SourceBadge"
  },
  {
    "path": "apps/docs/content/docs/transforms/prettier.mdx",
    "chars": 1198,
    "preview": "---\ntitle: Prettier\ndescription: Format code before it's added to your project using Prettier.\n---\n\n<BadgeGroup>\n\t<Sourc"
  },
  {
    "path": "apps/docs/instrumentation-client.js",
    "chars": 233,
    "preview": "import posthog from \"posthog-js\";\n\nif (process.env.NODE_ENV === 'production') {\n    posthog.init(process.env.NEXT_PUBLIC"
  },
  {
    "path": "apps/docs/jsrepo.config.mts",
    "chars": 417,
    "preview": "import { defineConfig, DEFAULT_PROVIDERS } from \"jsrepo\";\nimport shadcn from '@jsrepo/shadcn';\n\nexport default defineCon"
  },
  {
    "path": "apps/docs/middleware.ts",
    "chars": 481,
    "preview": "import { NextRequest, NextResponse } from \"next/server\";\nimport { isMarkdownPreferred, rewritePath } from \"fumadocs-core"
  },
  {
    "path": "apps/docs/next.config.mjs",
    "chars": 316,
    "preview": "import { createMDX } from \"fumadocs-mdx/next\";\n\nconst withMDX = createMDX();\n\n/** @type {import('next').NextConfig} */\nc"
  },
  {
    "path": "apps/docs/og-image.d.ts",
    "chars": 275,
    "preview": "/**\n * Type declarations for @vercel/og ImageResponse.\n * The `tw` prop allows Tailwind-style class names for OG image g"
  },
  {
    "path": "apps/docs/package.json",
    "chars": 1573,
    "preview": "{\n\t\"name\": \"@jsrepo/docs\",\n\t\"version\": \"0.0.0\",\n\t\"private\": true,\n\t\"scripts\": {\n\t\t\"build\": \"next build\",\n\t\t\"dev\": \"next "
  },
  {
    "path": "apps/docs/postcss.config.mjs",
    "chars": 70,
    "preview": "export default {\n  plugins: {\n    '@tailwindcss/postcss': {},\n  },\n};\n"
  },
  {
    "path": "apps/docs/source.config.ts",
    "chars": 535,
    "preview": "import { defineConfig, defineDocs, frontmatterSchema, metaSchema } from \"fumadocs-mdx/config\";\nimport { remarkMdxFiles }"
  },
  {
    "path": "apps/docs/src/app/(home)/code-block.tsx",
    "chars": 772,
    "preview": "import * as Base from \"fumadocs-ui/components/codeblock\";\nimport { highlight } from \"fumadocs-core/highlight\";\nimport { "
  },
  {
    "path": "apps/docs/src/app/(home)/layout.tsx",
    "chars": 330,
    "preview": "import { HomeLayout } from \"@/components/layout/home\";\nimport { baseOptions } from \"@/lib/layout.shared\";\n\nexport defaul"
  },
  {
    "path": "apps/docs/src/app/(home)/page.tsx",
    "chars": 15436,
    "preview": "import Link from \"next/link\";\nimport type { Metadata } from \"next\";\nimport { Button } from \"@/components/ui/button\";\nimp"
  },
  {
    "path": "apps/docs/src/app/(home)/providers-section.tsx",
    "chars": 2924,
    "preview": "\"use client\";\n\nimport { GitHubLogo, JsrepoLogo, RegistryKitLogo } from \"@/components/logos\";\nimport { AnimatedBeam } fro"
  },
  {
    "path": "apps/docs/src/app/api/search/route.ts",
    "chars": 243,
    "preview": "import { source } from '@/lib/source';\nimport { createFromSource } from 'fumadocs-core/search/server';\n\nexport const { G"
  },
  {
    "path": "apps/docs/src/app/app-client.tsx",
    "chars": 517,
    "preview": "\"use client\";\n\nimport { RootProvider } from \"fumadocs-ui/provider/next\";\nimport { QueryClientProvider, QueryClient } fro"
  },
  {
    "path": "apps/docs/src/app/docs/[[...slug]]/page.tsx",
    "chars": 2004,
    "preview": "import { getPageImage, source } from \"@/lib/source\";\nimport { DocsBody, DocsDescription, DocsPage, DocsTitle } from \"fum"
  },
  {
    "path": "apps/docs/src/app/docs/layout.tsx",
    "chars": 348,
    "preview": "import { DocsLayout } from 'fumadocs-ui/layouts/docs';\nimport { baseOptions } from '@/lib/layout.shared';\nimport { sourc"
  },
  {
    "path": "apps/docs/src/app/global.css",
    "chars": 4973,
    "preview": "@import \"tailwindcss\";\n@import \"fumadocs-ui/css/neutral.css\";\n@import \"fumadocs-ui/css/preset.css\";\n@import \"tw-animate-"
  },
  {
    "path": "apps/docs/src/app/layout.tsx",
    "chars": 637,
    "preview": "import \"@/app/global.css\";\nimport { Manrope, IBM_Plex_Mono } from \"next/font/google\";\nimport { App } from \"./app-client\""
  },
  {
    "path": "apps/docs/src/app/llms-full.txt/route.ts",
    "chars": 257,
    "preview": "import { getLLMText, source } from '@/lib/source';\n\nexport const revalidate = false;\n\nexport async function GET() {\n  co"
  },
  {
    "path": "apps/docs/src/app/llms.mdx/[[...slug]]/route.ts",
    "chars": 533,
    "preview": "import { getLLMText } from \"@/lib/source\";\nimport { source } from \"@/lib/source\";\nimport { notFound } from \"next/navigat"
  },
  {
    "path": "apps/docs/src/app/og/docs/[...slug]/route.tsx",
    "chars": 1294,
    "preview": "import { getPageImage, source } from \"@/lib/source\";\nimport { notFound } from \"next/navigation\";\nimport { ImageResponse "
  },
  {
    "path": "apps/docs/src/app/og/route.tsx",
    "chars": 909,
    "preview": "import { loadGoogleFont } from \"@/lib/og\";\nimport { ImageResponse } from \"next/og\";\n\nexport const revalidate = false;\n\ne"
  },
  {
    "path": "apps/docs/src/app/robots.txt",
    "chars": 62,
    "preview": "# allow crawling everything by default\nUser-agent: *\nDisallow:"
  },
  {
    "path": "apps/docs/src/components/PrismaticBurst.tsx",
    "chars": 14217,
    "preview": "'use client';\n\nimport React, { useEffect, useRef } from 'react';\nimport { Renderer, Program, Mesh, Triangle, Texture } f"
  },
  {
    "path": "apps/docs/src/components/badges-table.tsx",
    "chars": 3801,
    "preview": "\"use client\";\n\nimport React from \"react\";\nimport { Table, TableHeader, TableRow, TableHead, TableBody, TableCell } from "
  },
  {
    "path": "apps/docs/src/components/feature-tabs.tsx",
    "chars": 4522,
    "preview": "\"use client\";\n\nimport { cn } from \"@/lib/utils\";\nimport React, { createContext, useContext, useEffect, useMemo, useState"
  },
  {
    "path": "apps/docs/src/components/files.tsx",
    "chars": 2370,
    "preview": "'use client';\n\nimport { cva } from 'class-variance-authority';\nimport {\n  FileIcon as LucideFileIcon,\n  FolderIcon,\n  Fo"
  },
  {
    "path": "apps/docs/src/components/language-toggle.tsx",
    "chars": 1956,
    "preview": "'use client';\nimport { type ButtonHTMLAttributes, type HTMLAttributes } from 'react';\nimport { useI18n } from 'fumadocs-"
  },
  {
    "path": "apps/docs/src/components/layout/home/client.tsx",
    "chars": 6801,
    "preview": "'use client';\nimport { type ComponentProps, Fragment, useState } from 'react';\nimport { cva } from 'class-variance-autho"
  },
  {
    "path": "apps/docs/src/components/layout/home/index.tsx",
    "chars": 6201,
    "preview": "import { type HTMLAttributes, useMemo } from 'react';\nimport { cn } from '../../../lib/cn';\nimport {\n  type BaseLayoutPr"
  },
  {
    "path": "apps/docs/src/components/layout/shared/client.tsx",
    "chars": 741,
    "preview": "'use client';\nimport type { ComponentProps } from 'react';\nimport { usePathname } from 'fumadocs-core/framework';\nimport"
  },
  {
    "path": "apps/docs/src/components/layout/shared/index.tsx",
    "chars": 3826,
    "preview": "import type { HTMLAttributes, ReactNode } from 'react';\nimport type { NavProviderProps } from 'fumadocs-ui/contexts/layo"
  },
  {
    "path": "apps/docs/src/components/logos/antigravity.tsx",
    "chars": 9536,
    "preview": "import type { SVGProps } from \"react\";\n\nfunction Antigravity(props: SVGProps<SVGSVGElement>) {\n\treturn (\n\t\t<svg {...prop"
  },
  {
    "path": "apps/docs/src/components/logos/azure-devops.tsx",
    "chars": 849,
    "preview": "import type { SVGProps } from \"react\";\n\nconst AzureDevops = (props: SVGProps<SVGSVGElement>) => (\n\t<svg {...props} xmlns"
  },
  {
    "path": "apps/docs/src/components/logos/biome.tsx",
    "chars": 644,
    "preview": "import type { SVGProps } from \"react\";\n\nconst Biomejs = (props: SVGProps<SVGSVGElement>) => (\n  <svg {...props} viewBox="
  },
  {
    "path": "apps/docs/src/components/logos/bitbucket.tsx",
    "chars": 953,
    "preview": "import type { SVGProps } from \"react\";\n\nconst Bitbucket = (props: SVGProps<SVGSVGElement>) => (\n\t<svg {...props} xmlns=\""
  },
  {
    "path": "apps/docs/src/components/logos/claude.tsx",
    "chars": 2094,
    "preview": "import type { SVGProps } from \"react\";\n\nconst Claude = (props: SVGProps<SVGSVGElement>) => (\n  <svg {...props} preserveA"
  },
  {
    "path": "apps/docs/src/components/logos/css.tsx",
    "chars": 2478,
    "preview": "import type { SVGProps } from \"react\";\n\nconst CSSNew = (props: SVGProps<SVGSVGElement>) => (\n  <svg\n    {...props}\n    a"
  },
  {
    "path": "apps/docs/src/components/logos/cursor.tsx",
    "chars": 733,
    "preview": "import { cn } from \"@/lib/utils\";\nimport type { SVGProps } from \"react\";\n\nconst Cursor = ({ className, ...props }: SVGPr"
  },
  {
    "path": "apps/docs/src/components/logos/github.tsx",
    "chars": 1131,
    "preview": "import { cn } from \"@/lib/utils\";\nimport type { SVGProps } from \"react\";\n\nconst GitHub = (props: SVGProps<SVGSVGElement>"
  },
  {
    "path": "apps/docs/src/components/logos/gitlab.tsx",
    "chars": 993,
    "preview": "import type { SVGProps } from \"react\";\n\nconst GitLab = (props: SVGProps<SVGSVGElement>) => (\n\t<svg {...props} viewBox=\"0"
  },
  {
    "path": "apps/docs/src/components/logos/html.tsx",
    "chars": 519,
    "preview": "import type { SVGProps } from \"react\";\n\nconst HTML5 = (props: SVGProps<SVGSVGElement>) => (\n  <svg {...props} viewBox=\"0"
  },
  {
    "path": "apps/docs/src/components/logos/index.ts",
    "chars": 1368,
    "preview": "import { GitHub } from \"./github\";\nimport { GitLab } from \"./gitlab\";\nimport { AzureDevops } from \"./azure-devops\";\nimpo"
  },
  {
    "path": "apps/docs/src/components/logos/javascript.tsx",
    "chars": 1161,
    "preview": "import type { SVGProps } from \"react\";\n\nconst JavaScript = (props: SVGProps<SVGSVGElement>) => (\n\t<svg {...props} viewBo"
  },
  {
    "path": "apps/docs/src/components/logos/jsrepo-com.tsx",
    "chars": 9783,
    "preview": "import type { SVGProps } from \"react\";\n\nconst Jsrepo = (props: SVGProps<SVGSVGElement>) => (\n\t<svg {...props} xmlns=\"htt"
  },
  {
    "path": "apps/docs/src/components/logos/npm.tsx",
    "chars": 314,
    "preview": "import type { SVGProps } from \"react\";\n\nconst NPM = (props: SVGProps<SVGSVGElement>) => (\n  <svg {...props} viewBox=\"0 0"
  },
  {
    "path": "apps/docs/src/components/logos/openai.tsx",
    "chars": 1913,
    "preview": "import { cn } from \"@/lib/utils\";\nimport type { SVGProps } from \"react\";\n\nconst OpenAI = ({ className, ...props }: SVGPr"
  },
  {
    "path": "apps/docs/src/components/logos/oxfmt.tsx",
    "chars": 12401,
    "preview": "import type { SVGProps } from \"react\";\n\nconst Oxfmt = (props: SVGProps<SVGSVGElement>) => (\n  <svg {...props} fill=\"none"
  },
  {
    "path": "apps/docs/src/components/logos/prettier.tsx",
    "chars": 3489,
    "preview": "import type { SVGProps } from \"react\";\n\nconst Prettier = (props: SVGProps<SVGSVGElement>) => (\n\t<svg {...props} viewBox="
  },
  {
    "path": "apps/docs/src/components/logos/registry-kit.tsx",
    "chars": 992,
    "preview": "import { cn } from \"@/lib/utils\";\nimport type { SVGProps } from \"react\";\n\nconst RegistryKit = ({ className, ...props }: "
  },
  {
    "path": "apps/docs/src/components/logos/shadcn.tsx",
    "chars": 365,
    "preview": "import type { SVGProps } from \"react\";\n\nconst Shadcn = (props: SVGProps<SVGSVGElement>) => (\n  <svg {...props} viewBox=\""
  },
  {
    "path": "apps/docs/src/components/logos/svelte.tsx",
    "chars": 1943,
    "preview": "import type { SVGProps } from \"react\";\n\nconst Svelte = (props: SVGProps<SVGSVGElement>) => (\n  <svg {...props} viewBox=\""
  },
  {
    "path": "apps/docs/src/components/logos/typescript.tsx",
    "chars": 1869,
    "preview": "import type { SVGProps } from \"react\";\n\nconst TypeScript = (props: SVGProps<SVGSVGElement>) => (\n  <svg {...props} viewB"
  },
  {
    "path": "apps/docs/src/components/logos/vscode.tsx",
    "chars": 1780,
    "preview": "import type { SVGProps } from \"react\";\n\nconst VSCode = (props: SVGProps<SVGSVGElement>) => (\n  <svg {...props} fill=\"non"
  },
  {
    "path": "apps/docs/src/components/logos/vue.tsx",
    "chars": 485,
    "preview": "import type { SVGProps } from \"react\";\n\nconst Vue = (props: SVGProps<SVGSVGElement>) => (\n  <svg {...props} viewBox=\"0 0"
  },
  {
    "path": "apps/docs/src/components/navigation-menu.tsx",
    "chars": 2632,
    "preview": "'use client';\nimport * as React from 'react';\nimport * as Primitive from '@radix-ui/react-navigation-menu';\nimport { cn "
  },
  {
    "path": "apps/docs/src/components/page-actions.tsx",
    "chars": 12401,
    "preview": "'use client';\nimport { useMemo, useState } from 'react';\nimport {\n  Check,\n  ChevronDown,\n  Copy,\n  ExternalLinkIcon,\n  "
  },
  {
    "path": "apps/docs/src/components/registry-index.tsx",
    "chars": 2992,
    "preview": "\"use client\";\n\nimport { useQuery } from \"@tanstack/react-query\";\nimport { z } from \"zod\";\nimport { InputGroup, InputGrou"
  },
  {
    "path": "apps/docs/src/components/registry-kit/demo-example.tsx",
    "chars": 227,
    "preview": "import { Demo, DemoCode, DemoPreview } from \"./demo\";\n\nexport function DemoExample() {\n\treturn (\n\t\t<Demo>\n\t\t\t<DemoPrevie"
  },
  {
    "path": "apps/docs/src/components/registry-kit/demo.tsx",
    "chars": 1040,
    "preview": "import { Tabs, TabsList, TabsTrigger, TabsContent } from \"@/components/ui/tabs\";\nimport { ComponentProps, useState } fro"
  },
  {
    "path": "apps/docs/src/components/search-toggle.tsx",
    "chars": 1976,
    "preview": "'use client';\nimport type { ComponentProps } from 'react';\nimport { Search } from 'lucide-react';\nimport { useSearchCont"
  },
  {
    "path": "apps/docs/src/components/sidebar.tsx",
    "chars": 14353,
    "preview": "'use client';\nimport { ChevronDown, ExternalLink } from 'lucide-react';\nimport { usePathname } from 'fumadocs-core/frame"
  },
  {
    "path": "apps/docs/src/components/theme-toggle.tsx",
    "chars": 2086,
    "preview": "'use client';\nimport { cva } from 'class-variance-authority';\nimport { Moon, Sun, Airplay } from 'lucide-react';\nimport "
  },
  {
    "path": "apps/docs/src/components/ui/accordion.tsx",
    "chars": 2105,
    "preview": "\"use client\"\n\nimport * as React from \"react\"\nimport * as AccordionPrimitive from \"@radix-ui/react-accordion\"\nimport { Ch"
  },
  {
    "path": "apps/docs/src/components/ui/animated-beam.tsx",
    "chars": 4933,
    "preview": "\"use client\"\n\nimport { RefObject, useEffect, useId, useState } from \"react\"\nimport { motion } from \"motion/react\"\n\nimpor"
  },
  {
    "path": "apps/docs/src/components/ui/badge.tsx",
    "chars": 4775,
    "preview": "\"use client\";\n\nimport * as React from \"react\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { cva, type VariantPr"
  },
  {
    "path": "apps/docs/src/components/ui/button.tsx",
    "chars": 2036,
    "preview": "import * as React from \"react\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { cva, type VariantProps } from \"cla"
  },
  {
    "path": "apps/docs/src/components/ui/collapsible.tsx",
    "chars": 1098,
    "preview": "'use client';\nimport * as CollapsiblePrimitive from '@radix-ui/react-collapsible';\nimport { forwardRef, useEffect, useSt"
  },
  {
    "path": "apps/docs/src/components/ui/field.tsx",
    "chars": 6159,
    "preview": "\"use client\"\n\nimport { useMemo } from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport "
  },
  {
    "path": "apps/docs/src/components/ui/github-button.tsx",
    "chars": 914,
    "preview": "\"use client\";\n\nimport Link from \"next/link\";\nimport { Button } from \"./button\";\nimport { GitHub } from \"../logos/github\""
  },
  {
    "path": "apps/docs/src/components/ui/index.ts",
    "chars": 403,
    "preview": "export { Badge, SourceBadge, OfficialBadge, DefaultBadge, BadgeGroup, NpmBadge } from \"./badge\";\nexport { Button } from "
  },
  {
    "path": "apps/docs/src/components/ui/input-group.tsx",
    "chars": 5065,
    "preview": "\"use client\"\n\nimport * as React from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport {"
  },
  {
    "path": "apps/docs/src/components/ui/input.tsx",
    "chars": 962,
    "preview": "import * as React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\n\nfunction Input({ className, type, ...props }: React.Co"
  },
  {
    "path": "apps/docs/src/components/ui/item.tsx",
    "chars": 4476,
    "preview": "import * as React from \"react\"\nimport { Slot } from \"@radix-ui/react-slot\"\nimport { cva, type VariantProps } from \"class"
  },
  {
    "path": "apps/docs/src/components/ui/label.tsx",
    "chars": 611,
    "preview": "\"use client\"\n\nimport * as React from \"react\"\nimport * as LabelPrimitive from \"@radix-ui/react-label\"\n\nimport { cn } from"
  },
  {
    "path": "apps/docs/src/components/ui/popover.tsx",
    "chars": 1635,
    "preview": "\"use client\"\n\nimport * as React from \"react\"\nimport * as PopoverPrimitive from \"@radix-ui/react-popover\"\n\nimport { cn } "
  },
  {
    "path": "apps/docs/src/components/ui/scroll-area.tsx",
    "chars": 1929,
    "preview": "import * as ScrollAreaPrimitive from '@radix-ui/react-scroll-area';\nimport * as React from 'react';\nimport { cn } from '"
  },
  {
    "path": "apps/docs/src/components/ui/separator.tsx",
    "chars": 699,
    "preview": "\"use client\"\n\nimport * as React from \"react\"\nimport * as SeparatorPrimitive from \"@radix-ui/react-separator\"\n\nimport { c"
  },
  {
    "path": "apps/docs/src/components/ui/sonner.tsx",
    "chars": 1034,
    "preview": "\"use client\"\n\nimport {\n  CircleCheckIcon,\n  InfoIcon,\n  Loader2Icon,\n  OctagonXIcon,\n  TriangleAlertIcon,\n} from \"lucide"
  },
  {
    "path": "apps/docs/src/components/ui/table.tsx",
    "chars": 2448,
    "preview": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\n\nfunction Table({ className, ...props }: "
  },
  {
    "path": "apps/docs/src/components/ui/tabs.tsx",
    "chars": 1969,
    "preview": "\"use client\"\n\nimport * as React from \"react\"\nimport * as TabsPrimitive from \"@radix-ui/react-tabs\"\n\nimport { cn } from \""
  },
  {
    "path": "apps/docs/src/components/ui/terminal.tsx",
    "chars": 6515,
    "preview": "\"use client\"\n\nimport {\n  Children,\n  createContext,\n  useContext,\n  useEffect,\n  useMemo,\n  useRef,\n  useState,\n} from \""
  },
  {
    "path": "apps/docs/src/components/ui/textarea.tsx",
    "chars": 759,
    "preview": "import * as React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\n\nfunction Textarea({ className, ...props }: React.Compo"
  },
  {
    "path": "apps/docs/src/components/ui/tooltip.tsx",
    "chars": 1892,
    "preview": "\"use client\"\n\nimport * as React from \"react\"\nimport * as TooltipPrimitive from \"@radix-ui/react-tooltip\"\n\nimport { cn } "
  },
  {
    "path": "apps/docs/src/components/ui/underline-tabs.tsx",
    "chars": 1903,
    "preview": "\"use client\";\n\nimport * as React from \"react\";\nimport * as TabsPrimitive from \"@radix-ui/react-tabs\";\n\nimport { cn } fro"
  },
  {
    "path": "apps/docs/src/hooks/use-copy-to-clipboard.tsx",
    "chars": 805,
    "preview": "\"use client\"\n\nimport * as React from \"react\"\n\ntype CopyFn = (text: string) => Promise<boolean>\n\nexport function useCopyT"
  },
  {
    "path": "apps/docs/src/hooks/use-scroll-to-top.tsx",
    "chars": 244,
    "preview": "\"use client\";\n\nimport { useEffect } from \"react\";\nimport { usePathname } from \"next/navigation\";\n\nexport function useScr"
  },
  {
    "path": "apps/docs/src/lib/cn.ts",
    "chars": 48,
    "preview": "export { twMerge as cn } from 'tailwind-merge';\n"
  },
  {
    "path": "apps/docs/src/lib/is-active.ts",
    "chars": 586,
    "preview": "import type { SidebarTab } from 'fumadocs-ui/utils/get-sidebar-tabs';\n\nfunction normalize(url: string) {\n  if (url.lengt"
  },
  {
    "path": "apps/docs/src/lib/layout.shared.tsx",
    "chars": 618,
    "preview": "import { JsrepoWordmark } from \"@/components/logos/jsrepo-com\";\nimport type { BaseLayoutProps } from \"fumadocs-ui/layout"
  },
  {
    "path": "apps/docs/src/lib/og.ts",
    "chars": 482,
    "preview": "export async function loadGoogleFont(font: string, text: string) {\n\tconst url = `https://fonts.googleapis.com/css2?famil"
  },
  {
    "path": "apps/docs/src/lib/source.ts",
    "chars": 751,
    "preview": "import { docs } from '@/.source';\nimport { type InferPageType, loader } from 'fumadocs-core/source';\nimport { lucideIcon"
  },
  {
    "path": "apps/docs/src/lib/utils.ts",
    "chars": 166,
    "preview": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: Cla"
  },
  {
    "path": "apps/docs/src/mdx-components.tsx",
    "chars": 1026,
    "preview": "import { CodeBlock, Pre } from \"fumadocs-ui/components/codeblock\";\nimport { Step, Steps } from 'fumadocs-ui/components/s"
  },
  {
    "path": "apps/docs/tsconfig.json",
    "chars": 850,
    "preview": "{\n  \"compilerOptions\": {\n    \"baseUrl\": \".\",\n    \"target\": \"ESNext\",\n    \"lib\": [\n      \"dom\",\n      \"dom.iterable\",\n   "
  },
  {
    "path": "biome.json",
    "chars": 3423,
    "preview": "{\n\t\"$schema\": \"https://biomejs.dev/schemas/2.3.11/schema.json\",\n\t\"formatter\": {\n\t\t\"enabled\": true,\n\t\t\"formatWithErrors\":"
  },
  {
    "path": "examples/react/.gitignore",
    "chars": 480,
    "preview": "# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.\n\n# dependencies\n/node_modules\n/.pn"
  },
  {
    "path": "examples/react/README.md",
    "chars": 170,
    "preview": "# @example/react\n\nAn example of using jsrepo to build and distribute a react registry.\n\n## Getting Started\n\n```sh\npnpm c"
  },
  {
    "path": "examples/react/biome.json",
    "chars": 83,
    "preview": "{\n\t\"root\": false,\n\t\"extends\": \"//\",\n\t\"files\": {\n\t\t\"includes\": [\"!.next/**/*\"]\n\t}\n}\n"
  },
  {
    "path": "examples/react/jsrepo.config.mts",
    "chars": 845,
    "preview": "import { output as shadcn } from '@jsrepo/shadcn/output';\nimport { defineConfig } from 'jsrepo';\nimport { distributed } "
  },
  {
    "path": "examples/react/next.config.ts",
    "chars": 154,
    "preview": "import type { NextConfig } from 'next';\n\nconst nextConfig: NextConfig = {\n\t/* config options here */\n\treactCompiler: tru"
  },
  {
    "path": "examples/react/package.json",
    "chars": 821,
    "preview": "{\n\t\"name\": \"@example/react\",\n\t\"version\": \"0.1.0\",\n\t\"private\": true,\n\t\"scripts\": {\n\t\t\"dev\": \"concurrently -n registry,app"
  },
  {
    "path": "examples/react/postcss.config.mjs",
    "chars": 90,
    "preview": "const config = {\n\tplugins: {\n\t\t'@tailwindcss/postcss': {},\n\t},\n};\n\nexport default config;\n"
  },
  {
    "path": "examples/react/public/r/button.json",
    "chars": 2730,
    "preview": "{\n\t\"name\": \"button\",\n\t\"type\": \"ui\",\n\t\"add\": \"when-added\",\n\t\"files\": [\n\t\t{\n\t\t\t\"type\": \"ui\",\n\t\t\t\"role\": \"file\",\n\t\t\t\"conten"
  },
  {
    "path": "examples/react/public/r/registry.json",
    "chars": 1406,
    "preview": "{\n\t\"name\": \"@example/react\",\n\t\"homepage\": \"https://www.jsrepo.com/@example/react\",\n\t\"version\": \"package\",\n\t\"type\": \"dist"
  },
  {
    "path": "examples/react/public/r/shadcn/button.json",
    "chars": 1959,
    "preview": "{\n\t\"$schema\": \"https://ui.shadcn.com/schema/registry-item.json\",\n\t\"name\": \"button\",\n\t\"type\": \"registry:ui\",\n\t\"files\": [\n"
  },
  {
    "path": "examples/react/public/r/shadcn/registry.json",
    "chars": 687,
    "preview": "{\n\t\"$schema\": \"https://ui.shadcn.com/schema/registry.json\",\n\t\"name\": \"@example/react\",\n\t\"homepage\": \"https://www.jsrepo."
  },
  {
    "path": "examples/react/public/r/shadcn/utils.json",
    "chars": 425,
    "preview": "{\n\t\"$schema\": \"https://ui.shadcn.com/schema/registry-item.json\",\n\t\"name\": \"utils\",\n\t\"type\": \"registry:lib\",\n\t\"files\": [\n"
  },
  {
    "path": "examples/react/public/r/utils.json",
    "chars": 666,
    "preview": "{\n\t\"name\": \"utils\",\n\t\"type\": \"lib\",\n\t\"add\": \"when-added\",\n\t\"files\": [\n\t\t{\n\t\t\t\"type\": \"lib\",\n\t\t\t\"role\": \"file\",\n\t\t\t\"conte"
  },
  {
    "path": "examples/react/src/app/demos/button-demo/page.tsx",
    "chars": 508,
    "preview": "import { Button } from '@/registry/ui/button';\n\nexport function ButtonDemoPage() {\n\treturn (\n\t\t<>\n\t\t\t<div className=\"fle"
  },
  {
    "path": "examples/react/src/app/globals.css",
    "chars": 6602,
    "preview": "@import \"tailwindcss\";\n\n:root {\n\t--background: oklch(1 0 0);\n\t--foreground: oklch(0.145 0 0);\n\t--card: oklch(1 0 0);\n\t--"
  },
  {
    "path": "examples/react/src/app/layout.tsx",
    "chars": 689,
    "preview": "import type { Metadata } from 'next';\nimport { Geist, Geist_Mono } from 'next/font/google';\nimport './globals.css';\n\ncon"
  },
  {
    "path": "examples/react/src/app/page.tsx",
    "chars": 290,
    "preview": "import { Button } from '@/registry/ui/button';\n\nexport default function Home() {\n\treturn (\n\t\t<main className=\"min-h-scre"
  },
  {
    "path": "examples/react/src/registry/lib/utils.ts",
    "chars": 168,
    "preview": "import { type ClassValue, clsx } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: C"
  },
  {
    "path": "examples/react/src/registry/ui/button.tsx",
    "chars": 895,
    "preview": "import type React from 'react';\nimport { tv, type VariantProps } from 'tailwind-variants';\nimport { cn } from '@/registr"
  },
  {
    "path": "examples/react/tsconfig.json",
    "chars": 606,
    "preview": "{\n\t\"compilerOptions\": {\n\t\t\"target\": \"ES2017\",\n\t\t\"lib\": [\"dom\", \"dom.iterable\", \"esnext\"],\n\t\t\"allowJs\": true,\n\t\t\"skipLibC"
  },
  {
    "path": "examples/svelte/.gitignore",
    "chars": 210,
    "preview": "node_modules\n\n# Output\n.output\n.vercel\n.netlify\n.wrangler\n/.svelte-kit\n/build\n\n# OS\n.DS_Store\nThumbs.db\n\n# Env\n.env\n.env"
  },
  {
    "path": "examples/svelte/.npmrc",
    "chars": 19,
    "preview": "engine-strict=true\n"
  },
  {
    "path": "examples/svelte/README.md",
    "chars": 170,
    "preview": "# @example/svelte\n\nAn example of using jsrepo to build and distribute a svelte registry.\n\n## Getting Started\n\n```sh\npnpm"
  },
  {
    "path": "examples/svelte/biome.json",
    "chars": 105,
    "preview": "{\n\t\"root\": false,\n\t\"extends\": \"//\",\n\t\"files\": {\n\t\t\"includes\": [\"!.svelte-kit/**/*\", \"!**/*.svelte\"]\n\t}\n}\n"
  },
  {
    "path": "examples/svelte/jsrepo.config.ts",
    "chars": 722,
    "preview": "import { defineConfig } from 'jsrepo';\nimport { distributed } from 'jsrepo/outputs';\n\nexport default defineConfig({\n\treg"
  },
  {
    "path": "examples/svelte/package.json",
    "chars": 1018,
    "preview": "{\n\t\"name\": \"@example/svelte\",\n\t\"private\": true,\n\t\"version\": \"0.0.1\",\n\t\"type\": \"module\",\n\t\"scripts\": {\n\t\t\"dev\": \"concurre"
  },
  {
    "path": "examples/svelte/src/app.css",
    "chars": 23,
    "preview": "@import \"tailwindcss\";\n"
  },
  {
    "path": "examples/svelte/src/app.d.ts",
    "chars": 324,
    "preview": "// See https://svelte.dev/docs/kit/types#app.d.ts\n// for information about these interfaces\ndeclare global {\n\t// biome-i"
  },
  {
    "path": "examples/svelte/src/app.html",
    "chars": 286,
    "preview": "<!doctype html>\n<html lang=\"en\">\n\t<head>\n\t\t<meta charset=\"utf-8\" />\n\t\t<meta name=\"viewport\" content=\"width=device-width,"
  },
  {
    "path": "examples/svelte/src/lib/registry/lib/utils.ts",
    "chars": 168,
    "preview": "import { type ClassValue, clsx } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: C"
  },
  {
    "path": "examples/svelte/src/lib/registry/ui/button/button.svelte",
    "chars": 1172,
    "preview": "<script lang=\"ts\" module>\n    import { tv, type VariantProps } from \"tailwind-variants\";\n\n    export const buttonVariant"
  },
  {
    "path": "examples/svelte/src/lib/registry/ui/button/index.ts",
    "chars": 144,
    "preview": "import Button, { buttonVariants, type Size, type Variant } from './button.svelte';\n\nexport { Button, buttonVariants, typ"
  },
  {
    "path": "examples/svelte/src/routes/+layout.svelte",
    "chars": 222,
    "preview": "<script lang=\"ts\">\n\timport '../app.css';\n\timport favicon from '$lib/assets/favicon.svg';\n\n\t\n\tconst { children } = $props"
  },
  {
    "path": "examples/svelte/src/routes/+page.svelte",
    "chars": 131,
    "preview": "<h1>Welcome to SvelteKit</h1>\n<p>Visit <a href=\"https://svelte.dev/docs/kit\">svelte.dev/docs/kit</a> to read the documen"
  },
  {
    "path": "examples/svelte/src/routes/demos/button-demo/+page.svelte",
    "chars": 440,
    "preview": "<script lang=\"ts\">\n    import { Button } from '$lib/registry/ui/button';\n</script>\n\n<div class=\"flex place-items-center "
  },
  {
    "path": "examples/svelte/static/r/button.json",
    "chars": 3250,
    "preview": "{\n\t\"name\": \"button\",\n\t\"type\": \"ui\",\n\t\"add\": \"when-added\",\n\t\"files\": [\n\t\t{\n\t\t\t\"type\": \"ui\",\n\t\t\t\"role\": \"file\",\n\t\t\t\"conten"
  },
  {
    "path": "examples/svelte/static/r/registry.json",
    "chars": 1575,
    "preview": "{\n\t\"name\": \"@example/svelte\",\n\t\"homepage\": \"https://www.jsrepo.com/@example/svelte\",\n\t\"type\": \"distributed\",\n\t\"items\": ["
  },
  {
    "path": "examples/svelte/static/r/utils.json",
    "chars": 666,
    "preview": "{\n\t\"name\": \"utils\",\n\t\"type\": \"lib\",\n\t\"add\": \"when-added\",\n\t\"files\": [\n\t\t{\n\t\t\t\"type\": \"lib\",\n\t\t\t\"role\": \"file\",\n\t\t\t\"conte"
  },
  {
    "path": "examples/svelte/static/robots.txt",
    "chars": 63,
    "preview": "# allow crawling everything by default\nUser-agent: *\nDisallow:\n"
  },
  {
    "path": "examples/svelte/svelte.config.js",
    "chars": 664,
    "preview": "import adapter from '@sveltejs/adapter-auto';\nimport { vitePreprocess } from '@sveltejs/vite-plugin-svelte';\n\n/** @type "
  },
  {
    "path": "examples/svelte/tsconfig.json",
    "chars": 687,
    "preview": "{\n\t\"extends\": \"./.svelte-kit/tsconfig.json\",\n\t\"compilerOptions\": {\n\t\t\"allowImportingTsExtensions\": true,\n\t\t\"allowJs\": tr"
  },
  {
    "path": "examples/svelte/vite.config.ts",
    "chars": 205,
    "preview": "import { sveltekit } from '@sveltejs/kit/vite';\nimport tailwindcss from '@tailwindcss/vite';\nimport { defineConfig } fro"
  },
  {
    "path": "package.json",
    "chars": 1603,
    "preview": "{\n\t\"name\": \"@jsrepo/monorepo\",\n\t\"version\": \"0.0.0\",\n\t\"description\": \"The monorepo for jsrepo\",\n\t\"license\": \"MIT\",\n\t\"pack"
  },
  {
    "path": "packages/bun/CHANGELOG.md",
    "chars": 773,
    "preview": "# @jsrepo/bun\n\n## 2.0.0\n### Patch Changes\n\n- Updated dependencies [[`84c436e`](https://github.com/jsrepojs/jsrepo/commit"
  },
  {
    "path": "packages/bun/README.md",
    "chars": 744,
    "preview": "# @jsrepo/bun\n\n[![npm version](https://flat.badgen.net/npm/v/@jsrepo/bun)](https://npmjs.com/package/@jsrepo/bun)\n[![npm"
  }
]

// ... and 259 more files (download for full content)

About this extraction

This page contains the full source code of the ieedan/jsrepo GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 459 files (1.1 MB), approximately 340.7k tokens, and a symbol index with 877 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!