new-packagelisted
Install: claude install-skill RemiMyrset/roots
# New workspace package
Scaffold under `packages/<name>` (shared library) or `apps/<name>` (deployable
app or service). Placement alone registers it; the workspace globs cover both.
1. Directory is kebab-case; the package name takes the scope the existing
workspace packages use (`@repo/` out of the box): `@repo/<name>`.
2. Create `package.json` in this exact shape, every version `catalog:`:
```json
{
"name": "@<scope>/<name>",
"type": "module",
"version": "0.0.0",
"private": true,
"exports": { ".": "./src/index.ts" },
"scripts": {
"test": "vitest run",
"test:watch": "vitest",
"typecheck": "tsc --noEmit"
},
"devDependencies": {
"@types/node": "catalog:",
"typescript": "catalog:",
"vite": "catalog:",
"vitest": "catalog:"
}
}
```
Keep `vite`: vitest 4 peers on vite >= 6 and fails at startup without an
explicit entry. `@vitest/coverage-v8` is omitted repo-wide because its
transitive vite peer dedupes to vitepress's vite 5 and crashes
`vitest --coverage`; re-add it once vitepress moves off vite 5 (see the
`vite` note in `pnpm-workspace.yaml`).
Exports stay source-direct; add a `build` script only when the package must
emit `dist/` (turbo discovers it). No per-package `lint`; lint runs
repo-wide. Internal cross-package deps use `"workspace:*"`, and a new
dependency first gets a version entry in the `catalog:` block of
`pnpm-workspace.yaml`,