Index of every page on this site: llms.txt
All skills
harlan-zw avatar

/pkg-conform

@2a530d0
Run it yourself

Conform or scaffold TypeScript packages and Nuxt modules. Use for workspace catalogs, package config, CI, ESLint, Vitest, playgrounds, fixtures, or Nuxt module setup.

  • 14 files
  • 57.3 KB
  • MIT
  • Updated last month
  • GitHub
Use this Skill: https://skilld.dev/gh/harlan-zw/harlan-agent-kit/pkg-conform

Nothing lands on disk. Nothing to clean up.

Fork this Skill

Edit a local copy. It keeps the author and licence.

SKILL.md

≈45 tokens for metadata: the name and description. ≈3.3k when used: this file. ≈11k more on demand in 13 files.

Description uses 2.3% of example budget

Before choosing a Skill, your Agent reads its name and description. All available Skills share that space.

  • A shorter description leaves more room for other Skills. This entry exceeds our 1% size suggestion.

In our Claude Code example, all Skill names and descriptions share 8,000 characters. This Skill uses ≈180 characters, or 2.3%.

The 1% threshold is a size suggestion. Longer descriptions can still fit.

Your model, settings, and other Skills decide how much text your Agent can read.

Example settings and source

The example uses a 200k-token context and default Claude Code settings. The count includes the name, description, separators, and when_to_use when present. Codex also counts local file paths.

Skit's source and limits: Codex 0.160.1, Claude Code 2.1.292.

Package Conform Skill

Conform a package to standardized architecture, or scaffold a new one.

Worktree isolation

Before any edit, read and follow the worktree isolation contract. Keep mutation in a task-owned wt worktree with a live claim. Keep the primary checkout read only.

Usage

/pkg-conform              # conform existing project
/pkg-conform my-package   # scaffold new package

Behavior

  1. New project: scaffold with all standards below
  2. Existing project: compare and offer to sync each component

Detection

Check for package.json in cwd to determine new vs existing. Check for packages: in pnpm-workspace.yaml to detect monorepo vs single repo. Check for @nuxt/module-builder in devDependencies to detect Nuxt module -> apply Nuxt-specific patterns.

Project Type Detection

Determine project type from the absolute path of the working directory:

Path pattern Type Description
*/pkg/* Package Published library/module -- needs exports, build, release
*/sites/* or */site/* Site Nuxt app -- private, no exports, deploy not publish

If path doesn't match either pattern, fall back to heuristics: private: true + nuxt in deps -> Site, otherwise Package.

The project type selects the rule set. Package-only rules (exports, obuild, test:attw, prepack, release) never apply to Sites. Site-only rules (nuxi scripts, generate, preview) never apply to Packages.


Gotchas

  • Catalog version conflicts -- when migrating deps to catalog:, check that the catalog version satisfies all consumers in the monorepo. A single catalog: entry shared across packages with different version requirements will break.
  • obuild vs tsc -- obuild doesn't do type-checking. If you remove tsc from the build, types won't be validated. Always keep typecheck as a separate script.
  • module: preserve in tsconfig -- this is correct for packages built with obuild, but breaks Nuxt apps that need module: esnext or defer to .nuxt/tsconfig.json. Don't apply package tsconfig rules to sites.
  • ESM-only exports trap -- removing CJS exports breaks consumers that haven't migrated to ESM. For public packages, confirm the audience before dropping .cjs.
  • pnpm install after catalog changes -- lockfile must be regenerated. If you edit pnpm-workspace.yaml catalogs, always run pnpm install before running any other commands.
  • Nuxt module dev:prepare order -- must run before typecheck or test. Missing this causes confusing "module not found" errors from auto-generated types.
  • Site vs Package misdetection -- path-based detection (*/pkg/* vs */sites/*) can fail for unusual directory structures. Always verify the detected type before applying rules.
  • Markdown-only CI: Test, build, and deploy workflows skip Markdown-only changes by default. If the default branch requires checks, skip at the job level, never at the event. An event filter starts no run, so a required check never reports and the pull request blocks. If the branch requires no checks, paths-ignore: ['**/*.md'] at the event is fine. An explicit paths list may include Markdown. GitHub forbids paths and paths-ignore on the same event.

UnJS Conventions

Always prefer UnJS ecosystem packages over Node.js builtins:

Instead of Use Import
path pathe import { join, resolve } from 'pathe'
console.log/warn/error consola import { consola } from 'consola'
fetch ofetch import { $fetch } from 'ofetch'
fs.readFile (JSON) pkg-types import { readPackageJSON } from 'pkg-types'
Object.assign defaults defu import { defu } from 'defu'
require.resolve mlly import { resolveImports } from 'mlly'
EventEmitter hookable import { createHooks } from 'hookable'
yargs/commander citty import { defineCommand } from 'citty'
cosmiconfig c12 import { loadConfig } from 'c12'
git clone templates giget import { downloadTemplate } from 'giget'

Principles: ESM-only, minimal deps, full TypeScript, universal (Node/browser/edge)


Root docs

Every project carries the same root documents and the same docs lifecycle. Read root-docs.md before creating, moving, or renaming any Markdown at the root or under docs/.

AGENTS.md is the only file an agent loads every turn, so it routes rather than explains. Scaffold it from templates/AGENTS.md.


Package.json

Package (single repo / monorepo)

See references/pkg-package-json.md for single repo and monorepo root templates.

Site (Nuxt app)

See references/site-package-json.md for template, optional scripts, and rules.

See references/site-structure.md for Nuxt 4 directory layout.

See references/site-configs.md for nuxt.config.ts, tsconfig, eslint, .npmrc, .gitignore templates.


Test Structure

test/
  unit/           # unit tests
    *.test.ts
  e2e/            # e2e/integration tests
    *.test.ts
  fixtures/       # test data

Nuxt Module (when @nuxt/module-builder detected)

Build-time vs Runtime

Context Location Access Registration
Build-time src/module.ts @nuxt/kit, nuxt config runs during nuxi build
App runtime src/runtime/app/ Vue, useNuxtApp() addPlugin(), addImports()
Server runtime src/runtime/server/ H3, Nitro addServerHandler(), addServerPlugin()
Shared src/runtime/shared/ Pure JS only import via alias

See references/nuxt-module-template.md for full module.ts template with registration examples.

See references/nuxt-module-structure.md for directory layout and runtime rules.


References

See references/ for detailed templates:

  • ../../references/code-comments.md - the comment contract for any code this skill writes
  • references/pkg-package-json.md - single repo and monorepo package.json templates
  • references/catalogs.md - pnpm workspace catalogs
  • references/configs.md - package config file templates (eslint, vitest, tsconfig, obuild)
  • references/github-actions.md - CI/CD workflows (Package only)

Site references (when project type is Site):

  • references/site-package-json.md - package.json template, rules, optional scripts
  • references/site-structure.md - Nuxt 4 directory layout and conventions
  • references/site-configs.md - nuxt.config.ts, tsconfig, eslint, npmrc, editorconfig, gitignore
  • references/site-github-actions.md - the shared CI gate, deploy gating, self-hosted runner rules

Nuxt module references (when @nuxt/module-builder detected):

  • references/nuxt-module-structure.md - directory layout and runtime rules
  • references/nuxt-module-template.md - full src/module.ts template
  • references/nuxt-configs.md - vitest, tsconfig, build.config, package.json for Nuxt
  • references/nuxt-test-patterns.md - playground, fixtures, e2e tests
  • ../../references/root-docs.md - the root document set, docs lifecycle, and brief contract
  • templates/AGENTS.md - the router template

Sync Checklist

Shared (all project types)

  1. pnpm-workspace.yaml - default catalog, ignoredBuiltDependencies, shellEmulator
  2. package.json - type: module, migrate deps to catalog:, add packageManager
  3. .github/workflows/test.yml - action versions and Markdown path filtering
  4. .editorconfig - standard config
  5. .gitignore - standard patterns
  6. ESLint config - antfu + eslint-plugin-harlanzw. Package: eslint.config.mjs; Site: eslint.config.js
  7. tsconfig.json - Package: module: preserve, moduleDetection: force; Site: extends .nuxt/tsconfig.json
  8. Git hooks - lint-staged in devDeps, pre-commit runs lint-staged
  9. AGENTS.md - router shape, 30 to 80 lines. No CLAUDE.md, no CONTEXT.md. See ../../references/root-docs.md
  10. Root Markdown - only the allowed set. Reference docs move to docs/arch/, open work to docs/work/

Package-only (when in */pkg/*)

  1. vitest.config.ts - coverage config, projects if unit + e2e
  2. tsconfig.json - add types: ["node", "vitest/globals"]
  3. build.config.ts - obuild with explicit entry points
  4. Package exports - ESM-only (.d.mts + .mjs), no CJS
  5. Package scripts - obuild, dev:prepare, test:attw, lint:fix, prepack, release
  6. .github/workflows/release.yml - action versions, bumpp --output=CHANGELOG.md

Site-only (when in */sites/* or */site/*)

  1. package.json - private: true, engines.node set to latest stable even-numbered Node (e.g. >=22.0.0, >=24.0.0), no exports/main/types/files
  2. Scripts - dev (nuxi dev), build (nuxi prepare && nuxi build), postinstall (nuxt prepare), lint, lint:fix, typecheck (nuxt typecheck)
  3. pnpm.overrides - vite set to ^8.0.0
  4. nuxt.config.ts - future.compatibilityVersion: 5, compatibilityDate, standard module stack
  5. tsconfig.json - just { "extends": "./.nuxt/tsconfig.json" }
  6. eslint.config.js - antfu config with node/prefer-global/process and node/prefer-global/buffer off
  7. .npmrc - shamefully-hoist=true
  8. .gitignore - includes .nuxt/, .output/, .data/, .wrangler/, wrangler.toml
  9. .editorconfig - 2-space indent, LF, UTF-8, trim trailing whitespace (except .md)
  10. content.config.ts - Zod schemas for content collections (if using @nuxt/content)
  11. app/ directory - Nuxt 4 structure (app.vue, pages/, layouts/, components/, composables/)
  12. .github/workflows/ci.yml - calls the shared gate and skips Markdown-only changes in the shape its required checks allow. See references/site-github-actions.md.

Additional Nuxt Module Checklist

When @nuxt/module-builder detected, also check (extends Package checklist):

Structure: 17. [ ] src/module.ts - main module entry exists 18. [ ] src/runtime/app/ - client/SSR code directory 19. [ ] src/runtime/server/ - Nitro server code directory 20. [ ] src/types.ts - module options types 21. [ ] playground/ - nuxt.config.ts, app.vue, pages/ 22. [ ] test/fixtures/basic/ - nuxt.config.ts

Config: 23. [ ] pnpm-workspace.yaml - add nuxt: catalog 24. [ ] package.json - nuxt module exports, peerDependencies 25. [ ] tsconfig.json - extends .nuxt/tsconfig.json 26. [ ] vitest.config.ts - use defineVitestProject for e2e 27. [ ] build.config.ts - nuxt externals including #imports 28. [ ] eslint.config.mjs - ignore fixtures/playground 29. [ ] .gitignore - nuxt build dirs

Scripts: 30. [ ] typecheck - uses nuxt typecheck (not tsc) 31. [ ] dev:prepare - prepares module + playground 32. [ ] prepare:fixtures - prepares test fixtures 33. [ ] .github/workflows/test.yml - includes the prepare step and Markdown path filtering

Sync Process

Phase 0: Detect Project Type

Determine from cwd path whether this is a Package (*/pkg/*) or Site (*/sites/*, */site/*).

Phase 1: Config Review

Read the config files directly (one batch of parallel Read calls) and compare against the checklist. The comparison is cross-cutting (catalog ↔ lockfile ↔ exports ↔ tsconfig interact), so read inline to keep the whole picture in context. Exception: for a large monorepo where one read pass is unwieldy, delegate per-package walks to subagent_type=Explore.

Read for all project types:

  • pnpm-workspace.yaml, package.json — deps, catalogs, packageManager, type
  • .github/workflows/*.yml — action versions against v6 standards
  • eslint.config.{js,mjs}, tsconfig.json, .editorconfig, .gitignore

If Package, also read: build.config.ts, vitest.config.ts, package exports, release scripts.

If Site, also read: nuxt.config.ts, app/ structure (pages/, layouts/, components/), .npmrc.

If Nuxt module (Package + @nuxt/module-builder), also read: src/module.ts (registration methods, resolver, options), src/runtime/app/ (composables/plugins/imports), src/runtime/server/ (handlers/plugins/middleware — verify no Vue deps), playground/ + test/fixtures/ (nuxt.config, prepare scripts, test patterns).

Phase 2: Apply Changes

Based on the review, apply necessary updates using the appropriate checklist (Package or Site).

Phase 3: Parallel Verification

Package verification:

Bash(background): pnpm install
Bash(background): pnpm lint
Bash(background): pnpm typecheck

Then sequentially (depends on install):

Bash: pnpm build
Bash: pnpm test --run

Site verification:

Bash(background): pnpm install
Bash(background): pnpm lint
Bash(background): pnpm typecheck  # Uses nuxt typecheck

Then sequentially:

Bash: pnpm build  # nuxi build

Nuxt module verification:

Bash: pnpm dev:prepare && pnpm prepare:fixtures
Bash(background): pnpm lint
Bash(background): pnpm typecheck  # Uses nuxt typecheck
Bash: pnpm test:run

Source: SKILL.md on GitHub

skilld matched fixed text patterns in SKILL.md and file names. Patterns miss obfuscated code.

skilld run checks every file with the same patterns. It asks for approval before it loads a Skill with a behavior marked Needs approval.

No third-party reports yet.

Signed by skilld at 2a530d0. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 2 days ago.

Activeupdated last month

README badge

README badge for harlan-zw/harlan-agent-kit/pkg-conform