본문으로 건너뛰기
cccskills
무료GitHub에 공개

js-library-packaging

Use when a JavaScript/TypeScript package is consumed by another package — exports map, peer vs. direct dependencies, files allow-list, and whether it should be built at all.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

설치 방법 보기

포함된 파일(4)

  • SKILL.md9.1 KB
  • evals/triggers.json1.5 KB
  • scripts/check_package_surface.mjs7.2 KB
  • scripts/check_package_surface.ts13.2 KB

SKILL.md(원문)

설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.

js-library-packaging

Pack placement. engineering-base. The step asked for it to be suggested by the react and typescript packs, and the skill schema carries no suggested_by key — so the intent is recorded here rather than expressed in frontmatter that would fail validation. A React or TypeScript consumer receives this skill through engineering-base, which both of those packs require.

The JavaScript twin of composer-packages. A component is a file; a library is a package with a public surface, and that surface is declared in package.json rather than inferred. Most of the failures below are silent at author time and loud at the consumer's — which is why the surface is read, not assumed.

The Iron Law

`react` AND `react-dom` ARE peerDependencies. NEVER dependencies.
`types` IS THE FIRST KEY OF EVERY CONDITIONS OBJECT.
DECIDE buildable-VS-source-consumed BEFORE WRITING THE EXPORTS MAP.
NEVER HAND-BUMP A VERSION.

When to use

A package in the repository is imported by another package, or is about to be published: an exports map is being written or changed, a hook fails at runtime with "invalid hook call", an install fails on a workspace: range, a release needs cutting, or the buildable-vs-source question has not been answered yet.

Procedure

  1. Answer buildable-vs-source-consumed FIRST. It determines the exports map, the files list, and whether a build step exists at all — deciding it after writing the map means rewriting the map.
    • Source of truth: is the package published to a registry, or only consumed inside this workspace?
    • Verify: the exports targets all point into one of the two worlds (src/ or the build directory), never a mix.
  2. Read the surface rather than asserting it. Run the check below over the package root.
    • Source of truth: package.json — exports, dependencies, peerDependencies, files, private, publishConfig.
    • Verify: zero error-severity findings.
  3. Fix peer placement before anything else. A library carrying react in dependencies gives the consumer a second copy of React.
    • Verify: react and react-dom appear under peerDependencies only.
  4. Order the conditions. types first, then import / require.
    • Verify: the check reports no types-not-first.
  5. Cut the release through the repository's own mechanism — never by editing a version field. See § Release.
    • Verify: the version change is produced by the tool the repository already carries.

Read the surface

node <skills-root>/js-library-packaging/scripts/check_package_surface.mjs \
  <library-root> [<library-root> …]

scripts/check_package_surface.ts beside this skill, shipped as the .mjs the line above names. Deterministic, JSON on stdout, no network and no subprocess. It reports:

CodeSeverityWhy
peer-as-dependencyerrortwo copies of React in one tree break hooks at runtime, with a message that names neither package
export-target-missingerrorthe manifest promises a file the package does not ship
no-exports-mapwarnmain/module without exports — the entry point resolves by bundler convention, not by declaration
types-not-firstwarnconditions match in declaration order, so a later types is never seen and the package silently ships untyped
workspace-range-publishablewarna workspace: range does not resolve outside the workspace; published, the consumer's install fails

It classifies from the declared export targets, never from a directory name. A package directory called ui-lib-vite is not evidence about Vite, and one called buildable is not evidence that anything builds. A mixed declaration is reported as undeclared rather than resolved to a guess — declaring both is the ambiguity worth surfacing.

What it does not do: it never compiles and never runs a bundler, so it cannot tell you the declared layout is producible. A checker that grew a parser would report compile errors as packaging errors, and the two have different fixes.

Buildable vs. source-consumed

source-consumedbuildable
exports point atsrc/the build directory
build stepnoneone, and it must run before publish
filesnot needed (nothing published)the build directory, as an allow-list
privatetrue on a workspace-only packageabsent; publishConfig.access set instead
costconsumer compiles ita build to maintain, and output that can go stale

Default to source-consumed inside a workspace. A build step exists to serve publication; adding one for a package nobody publishes is a maintenance cost with no consumer.

Release

Read the repository, then take exactly one branch — Class A, per standards-from-config: the config is the answer.

  1. .changeset/ present → changesets. Add a changeset describing the change and let the release job bump and publish. Never edit version by hand.
  2. A task runner with a release command (e.g. nx release) → that command. It owns version, tag, and changelog together; splitting them by hand desynchronises them.
  3. Neither present → none configured. Propose a mechanism and stop. Do not hand-bump: a manually edited version has no changelog entry and no tag, so the next release cannot tell what shipped.

A breaking change carries the ! marker and the footer — see conventional-commits-writing. The marker is what a release tool reads to decide the major bump, so omitting it publishes a breaking change as a patch.

Output format

  1. State the classification (source-consumed / built surface / undeclared) and where it was read from.
  2. List every error finding with its fix, then the warnings.
  3. Name the release branch taken and the evidence in the repository for it.
  4. Say explicitly what was not checked — buildability, types, runtime behaviour.

Gotchas

  • "Invalid hook call" names neither package. The developer sees a React error and looks at their component; the cause is a library shipping its own React. This is why peer placement is an error and not a warning.
  • Condition order is silent. { "import": …, "types": … } type-checks fine at author time and ships untyped to the consumer.
  • A stale build directory passes every metadata check. The manifest points at files that exist; nothing says they match src/. Only a real build proves that.
  • files is an allow-list, not a deny-list. Adding a directory to the package means adding it here, and forgetting is invisible until a consumer imports a missing path.
  • A workspace: range is not a version. It resolves in the workspace and nowhere else.

Do NOT

  • Do NOT put react or react-dom in dependencies.
  • Do NOT write an exports map before answering buildable-vs-source-consumed.
  • Do NOT place types after import or require.
  • Do NOT edit a version field by hand, in any of the three release branches.
  • Do NOT claim the package builds because the check passed — it never ran a build.

Security constraints

scripts/check_package_surface.ts is read-only and offline by construction, and the constraint is worth stating because a packaging tool is a tempting place to lose it:

  • No network. It never resolves a version, queries a registry, or checks whether a name is taken. Every verdict comes from the manifest in front of it.
  • No subprocess. No package manager, no bundler, no compiler. It cannot install, build, or publish, so running it on an untrusted repository executes none of that repository's code — which a package manager's lifecycle scripts would.
  • No writes. It reads package.json and tests path existence. It never edits a manifest, so it can never "fix" a version field, which is the one thing § Release forbids.
  • Paths come from the caller, targets from the manifest. Export targets are resolved relative to the given root and used only for an existence test; nothing is read from them.

Widening any of these turns a metadata reader into something that runs a third party's code. If a future check needs a build, it belongs in a separate integration test with its own declared cost — never here.

See also

리뷰

아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.

댓글

로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.

아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.

보내면 바로 공개됩니다. 이메일 주소나 전화번호 같은 개인 정보는 쓰지 마세요. URL은 2개까지입니다.

0 / 1,000자

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

같은 저장소의 스킬

Use when reviewing UI for accessibility — WCAG 2.2 AA, keyboard nav, focus, ARIA, contrast, screen-reader semantics — even on 'is this a11y-OK?' or 'mach das barrierefrei'.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

event4u-app/agent-config122026년 10월 20일 업데이트

Use when defining or auditing the activation event — aha-moment selection, retention correlation, falsifiable definition. Triggers on 'what is our aha moment', 'redefine activation'.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

event4u-app/agent-config122026년 10월 20일 업데이트

Use when capturing an architectural decision — file naming, next ADR number, Status / Context / Decision / Consequences, index regen; fires even without saying 'ADR'.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

event4u-app/agent-config122026년 10월 20일 업데이트

Adversarial critique — devil's advocate, stress-test, honest teardown ('poke holes', 'be brutal', 'was hältst du davon'); explicit request only. Routine code or design review → code-review.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

event4u-app/agent-config122026년 10월 20일 업데이트

Use when reading, creating, or updating agent documentation, module docs, roadmaps, or AGENTS.md. Understands the full .augment/, agents/, and copilot-instructions structure.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

event4u-app/agent-config122026년 10월 20일 업데이트

Use for an adversarial red-team / blue-team / auditor review of an AI agent's CONFIG + behaviour (rules, skills, MCP, hooks, permissions) — attack-chain → defensive-gap list, not a code audit.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

event4u-app/agent-config122026년 10월 20일 업데이트

event4u-app의 스킬 모두 보기

이 스킬의 문제 신고