Link Workspace Packages
nomcopter/react-mosaic
Link workspace packages in monorepos (npm, yarn, pnpm, bun).
Design, build, verify, and publish production-grade TypeScript SDKs as npm packages inside a pnpm monorepo.
$ npx skills add mindfold-ai/Trellis --skill ts-sdk-author -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install mindfold-ai/Trellis ts-sdk-author --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/mindfold-ai/Trellis.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/ts-sdk-author .claude/skills/ts-sdk-author && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "ts-sdk-author" agent skill from https://github.com/mindfold-ai/Trellis/tree/main/.agents/skills/ts-sdk-author into .claude/skills/ts-sdk-author/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "ts-sdk-author", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/mindfold-ai/Trellis/tree/main/.agents/skills/ts-sdk-authorType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add mindfold-ai/Trellis --skill ts-sdk-author -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install mindfold-ai/Trellis ts-sdk-author --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/mindfold-ai/Trellis.git skills-src && mkdir -p .agents/skills && cp -r skills-src/.agents/skills/ts-sdk-author .agents/skills/ts-sdk-author && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "ts-sdk-author" agent skill from https://github.com/mindfold-ai/Trellis/tree/main/.agents/skills/ts-sdk-author into .agents/skills/ts-sdk-author/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "ts-sdk-author", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add mindfold-ai/Trellis --skill ts-sdk-author -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install mindfold-ai/Trellis ts-sdk-author --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/mindfold-ai/Trellis.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/.agents/skills/ts-sdk-author .cursor/skills/ts-sdk-author && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "ts-sdk-author" agent skill from https://github.com/mindfold-ai/Trellis/tree/main/.agents/skills/ts-sdk-author into .cursor/skills/ts-sdk-author/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "ts-sdk-author", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/mindfold-ai/Trellis.git --path .agents/skills/ts-sdk-author--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add mindfold-ai/Trellis --skill ts-sdk-author -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install mindfold-ai/Trellis ts-sdk-author --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/mindfold-ai/Trellis.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/.agents/skills/ts-sdk-author .gemini/skills/ts-sdk-author && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "ts-sdk-author" agent skill from https://github.com/mindfold-ai/Trellis/tree/main/.agents/skills/ts-sdk-author into .gemini/skills/ts-sdk-author/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "ts-sdk-author", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install mindfold-ai/Trellis ts-sdk-authorInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add mindfold-ai/Trellis --skill ts-sdk-author -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/mindfold-ai/Trellis.git skills-src && mkdir -p .github/skills && cp -r skills-src/.agents/skills/ts-sdk-author .github/skills/ts-sdk-author && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "ts-sdk-author" agent skill from https://github.com/mindfold-ai/Trellis/tree/main/.agents/skills/ts-sdk-author into .github/skills/ts-sdk-author/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "ts-sdk-author", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add mindfold-ai/Trellis --skill ts-sdk-author -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install mindfold-ai/Trellis ts-sdk-author --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/mindfold-ai/Trellis.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/.agents/skills/ts-sdk-author .opencode/skills/ts-sdk-author && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "ts-sdk-author" agent skill from https://github.com/mindfold-ai/Trellis/tree/main/.agents/skills/ts-sdk-author into .opencode/skills/ts-sdk-author/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "ts-sdk-author", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
ts-sdk-authorDesign, build, verify, and publish production-grade TypeScript SDKs as npm packages inside a pnpm monorepo.
TS SDK Author is an agent skill from mindfold-ai/Trellis. Design, build, verify, and publish production-grade TypeScript SDKs as npm packages inside a pnpm monorepo. Covers workspace layout, public API and module boundaries, plugin extension points, branded types and library-tuned tsconfig, tsdown bundling (vs tsup/tsc-only/unbuild), package.json exports with dual ESM+CJS and isomorphic conditions (browser/workers/RN/deno), Turborepo pipelines, publint and @arethetypeswrong/cli verification, changesets pre-release mode, npm dist-tags (latest/next/beta/rc/canary), and…
Its SKILL.md is about 6.1k tokens, which your agent loads only when the skill is triggered. The skill folder holds 8 other files, including reference files (for example `references/module-boundaries-and-plugins.md`, `references/package-json-exports.md` and `references/tsdown-bundling.md`).
It sits in Development, covering Monorepo tooling and Deployment. It works with npm, TypeScript, pnpm and Turborepo. The repository describes itself as: The best agent harness. The licence is MIT.
7 steps, taken from the step headings in SKILL.md.
Read from SKILL.md and the folder at commit f089cb3. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Shell commands in SKILL.md call:
pnpmnpmturbonodetscFrom the folder's file list and the shell code blocks in SKILL.md.
Hosts in commands or code, which the agent is likely to contact:
turborepo.comFrom URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
TS SDK Author loads about 6.1k tokens when it runs, and up to ~58k if it reads all its reference files. Until then it costs about 218 tokens; SKILL.md has 2,104 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from mindfold-ai/Trellis at commit f089cb3, republished under its MIT licence (© mindfold-ai). 2,104 words, ~6,092 tokens.
.claude/skills/ts-sdk-author/SKILL.md (or your agent's skills folder). This skill also uses 7 other files; get the full folder from GitHub.End-to-end workflow for shipping a TypeScript SDK as a standalone npm package from inside a pnpm monorepo: workspace layout, public API design, build configuration, distribution shape, monorepo pipeline, verification, and the full release lifecycle including beta / rc / canary channels.
The seven references hold the depth. This file is the unified workflow plus a quick-reference for the patterns you reach for daily.
packages/core, packages/sdk) out of an
existing CLI or app inside a pnpm workspacepackage.json exports field with dual ESM+CJS, isomorphic
runtime conditions, and subpath plugin entriessrc via a custom
condition)publint --strict and attw --pack into prepublishOnly or CIcanary per commit, next for the upcoming
major, beta / rc for stabilization, latest for stable — and the
transitions between them (beta.N → rc.0 → 1.0.0 → 1.1.0-beta.0)changesets/action@v1 plus
npm provenanceA single TS SDK build flows through these seven phases. Skip any phase and something will break later — the dependencies between phases are real.
Lay down the monorepo and create the empty SDK package.
Core moves:
apps/ + packages/ + optional tools/ at the workspace rootpackages/<sdk-name>/ (or packages/core/)@<org>/<sdk-name>)workspace:* protocolmy-repo/
├── pnpm-workspace.yaml
├── package.json # root: only devDeps + workspace scripts
├── apps/
│ └── example-app/ # consumer of the SDK
└── packages/
├── sdk/ # ← the SDK
└── shared-tsconfig/ # internal-only, never published# pnpm-workspace.yaml
packages:
- "apps/*"
- "packages/*"Read next: references/workspace-and-layout.md — §2 layout, §3 SDK naming
patterns, §4 internal package creation, §5 package.json skeleton, §7 multi
-repo → monorepo migration.
Before writing any code, decide what the SDK's public face looks like.
Two parallel concerns:
A. Module boundaries. The src/ tree splits cleanly into api/ (what
gets re-exported and is part of the contract) and internal/ (do not import
from outside the package). The package.json exports field is your
cheapest enforcement mechanism — anything not listed there cannot be
imported by consumers.
packages/sdk/src/
├── index.ts # barrel — re-exports from api/
├── api/
│ ├── client.ts
│ └── types.ts
└── internal/
├── transport.ts # NOT exported
└── state.ts # NOT exportedB. Type design. SDK types are consumed by strangers, must not leak internals, must be evolvable. Use:
type UserId = Brand<string, "UserId">createClient<Schema = DefaultSchema>(...)Result<T, E> with
{ ok: true; value: T } | { ok: false; error: E }Read next:
references/module-boundaries-and-plugins.md — §2 src/ boundary,
§3 runtime layering, §4 provider/adapter, §5 plugin extension, §6 boundary
enforcement, §7 patterns vs anti-patternsreferences/type-design-for-public-api.md — §1 branded types, §2 generic
surfaces, §3 conditional/mapped types, §4 type guards, §5 builder, §6
utility types ship/internal, §7 tsconfig for libraries, §8 API evolutionYou need (a) a tsconfig.json tuned for library output, and (b) a bundler
that produces the actual dist/.
tsconfig for libraries — the critical flags:
// tsconfig.build.json — library build config
{
"compilerOptions": {
"target": "es2022",
"module": "nodenext",
"moduleResolution": "nodenext",
"strict": true,
"declaration": true, // emit .d.ts
"declarationMap": true, // sourcemap from .d.ts → .ts
"sourceMap": true,
"verbatimModuleSyntax": true, // TS 5.0+ — strict import elision
"isolatedDeclarations": true, // TS 5.5+ — explicit return types on public API
"composite": true, // enable project references
"outDir": "./dist",
"rootDir": "./src"
},
"include": ["src"]
}Bundler choice in 2026: tsdown. tRPC and Inngest migrated to it from
tsup; tsup's own README now says "This project is not actively maintained
anymore. Please consider using tsdown instead."
Minimum viable tsdown.config.ts:
import { defineConfig } from "tsdown";
export default defineConfig({
entry: ["src/index.ts", "src/plugin/index.ts", "src/testing/index.ts"],
format: ["esm", "cjs"],
dts: true,
sourcemap: true,
treeshake: true,
clean: true,
outExtensions: ({ format }) => ({
js: format === "esm" ? ".mjs" : ".cjs",
dts: format === "esm" ? ".d.mts" : ".d.cts",
}),
});Alternatives:
tsc-only / zshy — small SDK with no runtime deps, source-faithful publishunbuild — only when already in UnJS ecosystemtsup — community familiarity but losing mind-share; viable for inertiaRead next:
references/tsdown-bundling.md — §3 verdict, §4 working config, §6–§8
alternatives, §11 selection decision treereferences/type-design-for-public-api.md §7 — full library tsconfig
walkthroughpackage.json exports)This is where most TS SDK bugs live. Five invariants:
types must be first inside each import / require branchdefault must be last.d.mts and .d.cts (TS 5.0+)"./package.json": "./package.json" (lets publint/attw introspect)module before require if you use bothThe canonical dual shape (verbatim from @trpc/server):
{
"exports": {
"./package.json": "./package.json",
".": {
"import": {
"types": "./dist/index.d.mts",
"default": "./dist/index.mjs"
},
"require": {
"types": "./dist/index.d.cts",
"default": "./dist/index.cjs"
}
}
}
}Add subpaths for plugin entry points so they version separately from the root barrel:
{
"exports": {
".": { "import": { ... }, "require": { ... } },
"./plugin": { "import": { ... }, "require": { ... } },
"./testing": { "import": { ... }, "require": { ... } }
}
}For isomorphic SDKs (browser / workers / RN / edge), runtime conditions
come before import / require:
{
".": {
"browser": { "import": "./dist/browser.mjs" },
"workerd": { "import": "./dist/workerd.mjs" },
"react-native": { "import": "./dist/rn.mjs" },
"deno": { "import": "./dist/deno.mjs" },
"import": { "types": "./dist/index.d.mts", "default": "./dist/index.mjs" },
"require": { "types": "./dist/index.d.cts", "default": "./dist/index.cjs" }
}
}Read next: references/package-json-exports.md — §3 the five rules,
§4 tRPC dual pattern annotated, §5 ESM-only pattern, §6 subpath plugins,
§7 isomorphic conditions (Sanity client pattern), §9 common mistakes
bad → fixed → why.
Once the SDK builds in isolation, wire it into the workspace so:
Minimum viable turbo.json:
{
"$schema": "https://turborepo.com/schema.json",
"tasks": {
"build": {
"dependsOn": ["^build"],
"inputs": ["src/**", "tsconfig*.json", "tsdown.config.ts", "package.json"],
"outputs": ["dist/**"]
},
"test": { "dependsOn": ["^build"], "inputs": ["src/**", "test/**"] },
"lint": { "inputs": ["src/**"] },
"typecheck": { "dependsOn": ["^build"], "inputs": ["src/**", "tsconfig*.json"] },
"dev": { "persistent": true, "cache": false }
}
}Daily --filter patterns:
pnpm turbo run build --filter=@acme/sdk # SDK alone
pnpm turbo run dev --filter=@acme/sdk... --filter=@acme/example-app
pnpm turbo run test --filter=...@acme/sdk # affected-by-SDK
pnpm turbo run lint --filter=[HEAD^1] # affected since last commitCritical rules: put scripts in each package's package.json, not in
root. Root only delegates turbo run X.
Read next: references/turborepo-for-sdk.md — §2 minimum viable
turbo.json, §3 per-package vs root, §4 dependsOn, §5 caching
inputs/outputs, §6 --filter patterns, §7 boundaries field, §8 CI patterns,
§9 dev mode with watch.
Before publish, two static checks + one runtime check are non-negotiable:
# After pnpm build:
pnpm exec publint --strict # static lint of package.json
pnpm exec attw --pack . # simulate Node/Bun/Deno/bundler resolution
# Then pack + install in a sandbox dir
pnpm pack
cd /tmp/sandbox && npm init -y && npm install /path/to/your-pkg-1.0.0.tgz
node -e "console.log(require('@acme/sdk'))" # CJS reaches
node --input-type=module -e "import('@acme/sdk').then(console.log)" # ESM reachesWire all three into prepublishOnly:
{
"scripts": {
"prepublishOnly": "pnpm build && pnpm exec publint --strict && pnpm exec attw --pack ."
}
}Why both publint and attw? publint statically checks package.json
shape; attw actually simulates how each consumer runtime resolves your
tarball. The most common attw failure is Masquerading ESM — a .js
file that contains ESM but is exposed under require — which publint
cannot catch.
Read next: references/verification-and-publishing.md — §2 publint
rules + 3 common failures, §3 attw resolution-mode table + 7 failure modes,
§4 smoke tests (tarball → fresh dir).
This is where most SDK projects accumulate debt. Get it right from day 1.
Semver + pre-release identifiers:
0.x.y # pre-1.0 — breaking changes allowed in minors
1.0.0-alpha.0 # internal feature spike
1.0.0-beta.0 # feature-complete, API may still shift
1.0.0-rc.0 # frozen, blocker-only fixes
1.0.0 # stable
1.0.1 # patch on stable
1.1.0-beta.0 # next minor's beta cycle while 1.0.x ships patchesnpm dist-tags — never publish a pre-release to latest:
# Publish a beta under the `beta` tag (NOT `latest`)
npm publish --tag beta
# Recover from a mistaken latest:
npm dist-tag add @acme/sdk@1.0.0 latest # repoint latest to stable
npm dist-tag rm @acme/sdk beta # if no longer neededConvention tags: latest (stable), next (upcoming major prerelease),
beta, rc, canary (per-commit), alpha, experimental, nightly.
changesets pre-release mode — the canonical transitions:
# Cut beta line
pnpm changeset pre enter beta
pnpm changeset # write a changeset
pnpm changeset version # bumps to 1.0.0-beta.0
pnpm changeset publish
# Feature-complete; move beta → rc
pnpm changeset pre exit
pnpm changeset pre enter rc
pnpm changeset version # bumps to 1.0.0-rc.0
pnpm changeset publish
# RC stable; ship 1.0.0
pnpm changeset pre exit
pnpm changeset version # bumps to 1.0.0
pnpm changeset publish
# Open next minor's beta line
pnpm changeset pre enter beta
pnpm changeset version # bumps to 1.1.0-beta.0npm provenance — turn it on:
{
"publishConfig": {
"access": "public",
"provenance": true
}
}Pair with id-token: write permission in the GitHub Actions release job;
npm will display a verified attestation on the package page.
Read next: references/verification-and-publishing.md — §5 semver
refresher, §6 dist-tag rules, §7 full lifecycle state diagram, §8 case
studies (Next.js / vercel-ai / tRPC / Storybook / Stripe with real version
sequences), §9 changesets pre-release flow, §10 GitHub Actions release
workflow, §11 provenance, §12 yank vs deprecate, §13 strategy decision tree.
| File | Owns | Quick check |
|---|---|---|
pnpm-workspace.yaml | Which dirs are packages | apps/* + packages/* |
Root package.json | Workspace devDeps + turbo run delegates | No package-level build script in root |
Package package.json | name, version, type, exports, files, sideEffects, bin, scripts.prepublishOnly | Run publint --strict |
Package tsconfig.json | Editor + tsc --noEmit | strict: true + declaration: true |
tsconfig.build.json | Library build config | isolatedDeclarations: true if you want fast .d.ts |
tsdown.config.ts | Bundling | format: ['esm', 'cjs'] + dual outExtensions |
turbo.json | Task pipeline | dependsOn: ['^build'] for compile order |
.changeset/config.json | Release policy | commit: false, access: public |
| Situation | Choice |
|---|---|
| Modern TS SDK, dual ESM+CJS, plugin subpaths | tsdown |
| Zero runtime deps, want raw source-faithful publish | tsc only / zshy |
| Existing project on tsup that works | Stay on tsup; plan tsdown migration |
| UnJS / Nuxt ecosystem | unbuild |
| Need bundle-splitting + advanced rollup config | Direct rolldown |
| Situation | Recommendation |
|---|---|
| Default for new SDK in 2026 | dual ESM + CJS |
| Library has stable consumer base ≥ Node 22 | ESM-only is defensible |
| Library is internal-only inside a Node app | ESM-only |
| Library is consumed by Jest, older Next.js, Lambda CJS | dual is mandatory |
| Tag | Meaning | npm install pkg@? resolves |
|---|---|---|
latest | The current stable | npm install pkg |
next | Upcoming major prerelease | npm install pkg@next |
beta | Feature-complete stabilization | npm install pkg@beta |
rc | Frozen, blocker-only | npm install pkg@rc |
canary | Per-commit/per-PR snapshot | npm install pkg@canary |
experimental | Unstable spike | npm install pkg@experimental |
# Add the SDK as a workspace-internal dep
pnpm add @acme/sdk@workspace:* --filter @acme/example-app
# Build SDK + everything that depends on it
pnpm turbo run build --filter=...@acme/sdk
# Pre-publish gate
pnpm build && pnpm exec publint --strict && pnpm exec attw --pack .
# Cut a snapshot release for a PR (vercel/ai pattern)
pnpm changeset version --snapshot pr-123
pnpm publish --tag pr-123 --no-git-checksRun through this once per release. Skipping any item is how broken SDKs ship.
pnpm build produces dist/ with both .mjs and .cjs (if dual) or just .mjs (if ESM-only).d.mts and .d.cts exist for dual, OR .d.ts only for ESM-only.mjs.map, .d.mts.map)dist/ size is reasonable (du -sh dist/ — sanity check, no surprise bloat)name is scoped (@org/name) — required if you'll ever go private laterversion matches what you're about to publishtype matches your default format ("module" for ESM-default, omit for CJS-default)exports has "./package.json": "./package.json"exports branch has types first, default lastfiles lists dist (and src if shipping sources for IDE jump-to-def)sideEffects: false (unless you genuinely have top-level side effects)publishConfig.access: "public" for first scoped publishpublishConfig.provenance: truepublint --strict passesattw --pack . passes (or only has expected node10 warnings)/tmp + CJS + ESM + TS consumer all resolvelatest only for stable)pnpm changeset pre enter <tag> was run BEFORE versionpnpm changeset pre exit was run if previously in pre-modev1.0.0-beta.3)| Mistake | What goes wrong | Fix |
|---|---|---|
types not first inside exports branch | TS picks up .js as type source → cascade of errors at consumer | Move types to top of each import / require branch (publint will flag) |
Single .d.ts for dual ESM+CJS | TS resolves the .d.ts against the wrong module mode | Emit .d.mts + .d.cts (TS 5.0+); tsdown does this automatically |
Missing "./package.json": "./package.json" in exports | publint/attw cannot introspect your package | Always include it |
Publishing pre-release to latest | Every npm install pkg user gets your beta | Use npm publish --tag beta; recover via npm dist-tag add pkg@stable latest |
Forgetting pnpm changeset pre exit before stable release | Stable version comes out as 1.0.0-beta.N instead of 1.0.0 | Always pre exit before final |
Root package.json containing the actual build script | Defeats Turborepo parallelism + caching | Per-package scripts; root only delegates via turbo run |
Deep imports into dist/internal/... from consumers | Consumers couple to internals; your refactors break them | Don't list internals in exports; use ESLint no-restricted-imports |
| Leaking internal types into public API surface | Users see types they shouldn't depend on | Re-export only from src/api/*.ts; don't export * from internals |
Missing sideEffects: false with no side effects | Bundlers can't tree-shake your library | Add "sideEffects": false or list the actual side-effecting files |
Forgetting id-token: write permission for provenance | Provenance attestation fails silently in CI | Add permissions: { id-token: write, contents: read } to release job |
| Mixing watch + build in same Turbo task | Cache invalidates constantly; watch never settles | Separate build (cacheable) and dev (persistent: true, cache: false) |
exports with both module and unrelated runtime conditions in wrong order | Edge runtime picks the wrong file | Runtime conditions (browser, workerd) → module → import → require → default |
Using enum in public API types | Forces consumers into TS-only land, breaks erasable syntax | Use union of string literals or as const objects |
Using default export from the SDK root | Breaks tree-shaking + interop story | Always named exports |
| File | Use when |
|---|---|
references/workspace-and-layout.md | Setting up apps/ + packages/ + tools/; naming the SDK package; creating internal packages; choosing dep field (dependencies / peerDependencies / devDependencies); migrating from multi-repo |
references/module-boundaries-and-plugins.md | Splitting src/ into api/ vs internal/; designing the orchestration layer vs adapters vs tools; building a plugin extension model with lifecycle hooks; enforcing boundaries via eslint-plugin-boundaries / dependency-cruiser / Turbo boundaries |
references/type-design-for-public-api.md | Branded types; generic clients; conditional + mapped types; type-safe builders; which utility types to ship vs keep internal; tsconfig flags for libraries (verbatimModuleSyntax, isolatedDeclarations, composite); API evolution patterns |
references/package-json-exports.md | Authoring the exports field; dual ESM+CJS with separate .d.mts/.d.cts; subpath plugin entries; isomorphic runtime conditions (browser, workerd, react-native, deno, edge-light); fixing common exports bugs |
references/tsdown-bundling.md | Choosing tsdown vs tsup vs tsc-only vs unbuild; minimum-viable tsdown.config.ts; subpath output mapping; side-effects + tree-shaking; watch & dev mode; bundler selection decision tree |
references/turborepo-for-sdk.md | Writing turbo.json for an SDK monorepo; dependsOn: ['^build']; caching inputs/outputs; --filter patterns for SDK dev; the boundaries field; CI with remote cache + affected-only builds; dev mode with persistent: true |
references/verification-and-publishing.md | publint + attw setup; tarball smoke tests; semver + pre-release identifiers; npm dist-tags; the full beta → rc → stable → next-cycle state machine; changesets pre-release mode; the canonical beta → rc transition command sequence; GitHub Actions release workflow with snapshot PRs; npm provenance; yank vs deprecate; release-strategy decision tree |
This skill was composed from four source skills inside oh-my-openclaw:
agent-cli-architecture (architect-claw) — workspace structure, module
boundaries, runtime layering, plugin extension patterns. Generalized from
"agent CLI" framing to general "SDK + supporting CLI".typescript-pro (frontend-claw) — branded types, generics, conditional
types, type guards, utility types, tsconfig deep dive. Reframed toward
library/SDK-author concerns.turborepo (frontend-claw) — task pipelines, caching, --filter,
boundaries. Heavily trimmed to SDK-monorepo-relevant subset.monorepo-navigator (architect-claw) — pnpm workspaces, changesets,
publishing, migration.Plus original research on package.json exports, dual ESM/CJS in 2026,
the tsdown landscape, publint + attw, and the alpha→beta→rc→stable
lifecycle, with verbatim examples from the GitHub package.json of
tRPC, vercel/ai, Inngest, Sanity client, Hono, Zustand, and TanStack
query-core.
© mindfold-ai, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
SKILL.md and 7 other files (references) in .agents/skills/ts-sdk-author of mindfold-ai/Trellis.
Open the folder on GitHubat commit f089cb3
TS SDK Author next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| TS SDK Author this skillmindfold-ai/Trellis | 15k | — | ~6.1k | Automated safety check: Pass | MIT | |
| Link Workspace Packagesnomcopter/react-mosaic | 4.8k | 6 repos | ~760 | Automated safety check: Pass | Custom licence | |
| Linea Dependency MaintenanceConsensys-Incorporated/linea-attestation-registry | 177 | 1 repos | ~3.7k | Automated safety check: Warn | MIT | |
| Monorepo Tooling and Dependenciespierrecomputer/pierre | 6.3k | — | ~1.1k | Automated safety check: Pass | Apache-2.0 | |
| Turborepo WorkflowChatbotXIO/ChatbotX | 885 | — | ~880 | Automated safety check: Notes | Custom licence | |
| Migrate to Denodenoland/skills | 100 | — | ~2.2k | Automated safety check: Warn | MIT |
nomcopter/react-mosaic
Link workspace packages in monorepos (npm, yarn, pnpm, bun).
Consensys-Incorporated/linea-attestation-registry
Safely plan and execute dependency maintenance for JavaScript/TypeScript (npm, pnpm) and GitHub Actions, including npm lockfiles, pnpm workspaces, catalogs, overrides, SHA-pinned action versions…
pierrecomputer/pierre
Sets one monorepo's rules for toolchain pins, pnpm package operations, the shared dependency catalog and moon tasks, so the agent adds versions and scripts the right way.
ChatbotXIO/ChatbotX
Manage turborepo monorepo development workflow including dev servers, builds, linting, and package management.
denoland/skills
Moves a Node.js, npm, Yarn, pnpm or Bun project to Deno in reversible steps, starting with Deno as the package manager and changing no code unless needed.
deinsoftware/swpm
Manage cmds and args props in SWPM package manager configs (src/packages/managers/.ts), including adding, modifying or removing command and argument mappings across npm, yarn, pnpm, bun, deno.
mindfold-ai/Trellis
Reach into past AI conversation history through the trellis mem CLI.
mindfold-ai/Trellis
Systematic first principles thinking for any problem domain.
mindfold-ai/Trellis
Use Trellis channel for live multi-agent collaboration, spawned workers, cross-agent review, progress inspection, forum channels, and channel log debugging.
mindfold-ai/Trellis
Understand and customize the local Trellis architecture inside a user project.
mindfold-ai/Trellis
Guide for contributing to Trellis documentation and marketplace.
mindfold-ai/Trellis
Create a Trellis migration manifest and matching docs-site changelogs for a target release by analyzing commits since the previous release.
Works with
Categories
Design, build, verify, and publish production-grade TypeScript SDKs as npm packages inside a pnpm monorepo. TS SDK Author is an agent skill from mindfold-ai/Trellis. Design, build, verify, and publish production-grade TypeScript SDKs as npm packages inside a pnpm monorepo.
TS SDK Author fits situations like: : build a TS SDK; extract core library; package.json exports; changesets prerelease.
Run `npx skills add mindfold-ai/Trellis --skill ts-sdk-author -a claude-code`. Or copy the skill folder (.agents/skills/ts-sdk-author in mindfold-ai/Trellis) into .claude/skills/ts-sdk-author in your project. Claude Code loads it when a task matches its description.
Run `npx skills add mindfold-ai/Trellis --skill ts-sdk-author -a codex`. Or copy the skill folder (.agents/skills/ts-sdk-author in mindfold-ai/Trellis) into .agents/skills/ts-sdk-author in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add mindfold-ai/Trellis --skill ts-sdk-author -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/ts-sdk-author, .gemini/skills/ts-sdk-author, .github/skills/ts-sdk-author and .opencode/skills/ts-sdk-author in your project.
Going by SKILL.md and its folder, TS SDK Author needs the command-line tools its instructions call (pnpm, npm, turbo, node and tsc). Our summary lists: Node.js.
SKILL.md names 1 domain. In commands or code: turborepo.com; the agent is likely to contact it when it follows the instructions. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
TS SDK Author is published under the MIT licence (declared in SKILL.md). It allows redistribution, so the full SKILL.md is shown on this page.
About 6.1k tokens (SKILL.md is roughly 24k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 52k tokens, read only when the agent opens those files.
Skills that share tags, products or a category with TS SDK Author: Link Workspace Packages (nomcopter/react-mosaic, 4.8k stars), Linea Dependency Maintenance (Consensys-Incorporated/linea-attestation-registry, 177 stars), Monorepo Tooling and Dependencies (pierrecomputer/pierre, 6.3k stars) and Turborepo Workflow (ChatbotXIO/ChatbotX, 885 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
mindfold-ai (a GitHub organization) maintains it in mindfold-ai/Trellis, which has 14,914 GitHub stars. The repository holds 8 skills in this directory. The repository was last updated on September 29, 2026.
Source: mindfold-ai/Trellis on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.