skills/dev-wip-package-refer/SKILL.md
Pattern for consuming an in-progress (WIP) upstream npm/pnpm package from a sibling git checkout via a `file:../{name}/...` relative dep — without publishing the package. Use when: (1) Setting up a consumer project that needs to depend on a local in-development library or framework checked out next to it, (2) User mentions 'file: dep', 'sibling repo', 'upstream package', 'wip package', 'monorepo-style refer', 'how do we consume the upstream', (3) Deciding between this pattern and a published npm version or a `github:` git-URL dep, (4) Setting up a fresh machine that already has a consumer project but the sibling upstream isn't cloned yet, (5) A consumer's CI is failing because the sibling upstream isn't where the `file:` spec expects it.
npx skillsauth add takazudo/claude-resources dev-wip-package-referInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
The "consume a WIP upstream package via a sibling-relative file: dep" pattern. Lets a consumer project depend on an in-development library/framework without publishing each iteration to npm.
For the inverse — editing the upstream itself — see dev-wip-package-upstream-wt-dev.
Use when the upstream library is itself in active development by the same maintainer (or a tightly coordinated team) and the iteration loop matters: edit upstream → consumer sees the change immediately on next pnpm install, no publish step. Trades multi-machine setup pain for fast iteration.
Don't use it when the upstream is stable and shipped to npm — a normal versioned dep is simpler. Also don't use it for adversarial / arms-length dependencies — file: paths assume both repos live on disk under your control.
The consumer's package.json declares the dep with a path-style spec:
{
"dependencies": {
"@org/pkg": "file:../upstream/packages/pkg",
"@org/pkg-rt": "file:../upstream/packages/pkg-runtime"
}
}
pnpm/npm resolve file:../upstream/... against the consumer project root, so the upstream sibling is always at <consumer-root>/../upstream/. Identical on every machine as long as the sibling layout is preserved — clone the consumer at $HOME/repos/foo/consumer, the upstream at $HOME/repos/foo/upstream, and file:../upstream just works. No env-specific config.
Real example (zudo-doc):
"@takazudo/zfb": "file:../zfb/packages/zfb"
"@takazudo/zfb-adapter-cloudflare": "file:../zfb/packages/zfb-adapter-cloudflare"
"@takazudo/zfb-runtime": "file:../zfb/packages/zfb-runtime"
"@takazudo/zudo-design-token-panel": "file:../zdtp/packages/zudo-design-token-panel"
→ resolves to ../zfb/packages/zfb and ../zdtp/packages/zudo-design-token-panel.
For pnpm install to succeed in the consumer, the upstream sibling must:
../upstream/ (clone before installing).file: deps at install time. If the dep is "source + a built binary" (e.g. a Rust CLI shipped via the npm package), the binary must be built before the consumer installs. If the dep is "TypeScript + a dist/" the dist must be built first.If any of those are missing, the consumer's pnpm install either succeeds with broken/stale state or fails at a postinstall hook.
The consumer pins which upstream SHA it depends on. Two places to pin:
ZFB_PINNED_SHA, ZDTP_PINNED_SHA declared at the workflow env: level of every workflow that runs pnpm install. CI clones the upstream at that SHA before installing. This is the source of truth.framework-pins.json that both CI workflows and a local bootstrap script read from. Reduces "edit 3 YAML files per bump" to "edit 1 JSON file." Use when you have more than ~2 workflow files.Bumping the pin = the consumer adopts the upstream change. The change is reviewed and tested in CI's clean clone.
The consumer's CI workflow must clone the upstream at the pinned SHA into ../upstream/ before pnpm install runs in the consumer. Shape:
env:
UPSTREAM_PINNED_SHA: <full SHA>
jobs:
build:
steps:
- name: Checkout consumer
uses: actions/checkout@v5
- name: Clone pinned upstream sibling
run: |
git clone https://github.com/<org>/<upstream-repo>.git ../upstream
git -C ../upstream checkout "$UPSTREAM_PINNED_SHA"
# OPTIONAL: build upstream artifacts here if the npm package needs them
# (Rust binary, dist/, etc.). For heavy builds, do it in a separate
# job and upload the artifact, then download it into ../upstream/ in
# each consumer job. See zudo-doc's `build-zfb` job for that pattern.
- name: Setup Node + pnpm
# ...
- name: Install consumer deps
run: pnpm install
For expensive upstream builds (Rust toolchain, large bundles), split into a dedicated build job that uploads the binary as an artifact; consumer jobs cp it into ../upstream/target/release/ before pnpm install. See zudo-doc's .github/workflows/pr-checks.yml build-zfb job for a reference shape.
The brittle part of this pattern is "new machine = clone two repos in the right layout + build their artifacts before pnpm install." Solve it with a bootstrap script that does what CI does:
pnpm setup:upstream # ensure all WIP-sibling upstreams are present and built
The script:
framework-pins.json).../upstream/ doesn't exist → git clone <url> ../upstream, then git checkout <SHA>.../upstream/ exists with a clean tree → git fetch origin && git checkout <SHA> (matches CI).../upstream/ exists with a dirty tree → refuse to touch it (you have in-flight upstream edits; resolve first or pass --force-checkout).dist/, etc.). Skip if cache is fresh.pnpm install in the consumer.The "refuse on dirty tree" rule is what prevents stomping on a parallel upstream-edit session — see dev-wip-package-upstream-wt-dev for why the upstream root is shared.
A starter Node.js skeleton (adjust to the consumer's needs):
// scripts/setup-upstream.mjs
import { execSync } from "node:child_process";
import { existsSync, readFileSync } from "node:fs";
import { resolve } from "node:path";
const projectRoot = process.cwd();
const pkg = JSON.parse(readFileSync(resolve(projectRoot, "package.json"), "utf8"));
// Discover sibling-relative file: deps and group by upstream root.
const upstreams = new Map(); // siblingDir -> { siblingPath }
for (const [name, spec] of Object.entries(pkg.dependencies ?? {})) {
if (typeof spec !== "string" || !spec.startsWith("file:..")) continue;
const siblingDir = spec.slice("file:".length).split("/")[0]; // "../upstream"
const siblingPath = resolve(projectRoot, siblingDir);
if (!upstreams.has(siblingDir)) upstreams.set(siblingDir, { siblingPath });
}
// For each upstream, load (sha, gitUrl, buildSteps) from `framework-pins.json`
// (or grep the workflow YAML) and ensure-clone-build.
// ...left to the consumer to fill in based on its specific upstreams.
Wire the script into package.json as a regular script ("setup:upstream": "node scripts/setup-upstream.mjs"). Don't run it from postinstall — that would loop. Document it as the first thing to run on a new machine.
| Approach | Multi-machine | Lets you edit upstream live | Effort |
|---|---|---|---|
| file:../sibling + bootstrap (this pattern) | One command per new machine | ✅ | Small |
| github:org/repo#SHA git URL | Just works on any machine; lockfile pins SHA | ⚠️ slower iteration; needs an upstream prebuilt-binary release flow if there's a non-JS artifact | Medium |
| Published npm package | Cleanest | ❌ requires npm link for upstream-edit flow | Large; an upstream-side project of its own |
The file: pattern wins when iteration speed on upstream matters and the team can absorb the bootstrap step. The published-package pattern wins when the upstream stabilizes.
Edit the SHA in the single source of truth (CI workflow env var or framework-pins.json). Commit + push the consumer-side change. CI re-clones the upstream at the new SHA in its clean checkout and validates. Locally re-run pnpm setup:upstream to mirror the new pin if you want to test before pushing — otherwise trust CI.
For the how of preparing the new upstream SHA itself (an upstream PR, merge, watch CI green), see dev-wip-package-upstream-wt-dev.
git checkout random branches on ../upstream/. That checkout is shared with every consumer using file:../upstream/... and with any concurrent Claude session. Use a worktree — see dev-wip-package-upstream-wt-dev.postinstall. Postinstall already runs on every pnpm install — the bootstrap script itself runs pnpm install, so wiring it as postinstall loops.package.json. file:../upstream/... is portable; file:/home/you/repos/upstream/... is not.pnpm-lock.yaml. file: deps point at on-disk paths, not SHAs — the lockfile is stable across pin bumps and won't help reproducibility. The SHA must live in CI env vars (or framework-pins.json).development
Link Claude Code skill names mentioned in a CodeGrid article (data/{series}/{n}.md) to the author's public claude-resources repo, pinned to the latest commit hash so links don't rot. Use when: (1) user says 'linkify cc resources', 'link the skills', 'link skill names', or invokes /dev-linkify-cc-resources; (2) editing a CodeGrid article that mentions `/commits`, `/pr-complete`, `/skill-creator` or other Claude Code skills and they should point to claude-resources. Only links skills that actually exist in the public repo; skips hypothetical examples and code blocks.
development
Second opinion from Claude Opus on a plan or approach. Use when: (1) Planning phase of /big-plan needs a higher-quality review than /codex-2nd / /gco-2nd / /gcoc-2nd, (2) User says 'opus 2nd' or 'opus opinion', (3) Wanting Anthropic's larger model to critique a plan. Spawns a general-purpose Agent with model: opus that reads the plan file and returns structured feedback. Anthropic quota — not free.
tools
AI-based testing via subagent + a per-task test-flow skill. Use when the user wants to verify something that mechanical assertions can't fully capture — image recognition, visual size/position comparison, animation smoothness, multi-step manual flows that need AI judgment. Triggers: 'AI-based test', 'AI test', 'visual verify', 'image recognition test', 'manual operation test', 'human-eye check', 'verify visually', 'compare screenshots', 'looks the same', 'looks correct'. The skill's job is to (1) author a focused test-flow skill that captures the exact procedure + verdict criteria, then (2) dispatch a verification subagent via the Agent tool that loads BOTH the test-flow skill AND a browser-driving skill (/verify-ui primary, /headless-browser fallback) so the subagent has clear context and consistent verdicts. NEVER uses `claude -p` — subagent dispatch goes through the Agent tool exclusively.
development
End-of-workflow audit of touched GitHub issues, PRs, and branches via a Sonnet subagent. Use when: (1) /big-plan, /x-as-pr, or /x-wt-teams finishes its main work and needs to verify every touched resource is in the right state (closed when done, kept when ongoing, deleted when dead), (2) User says 'cleanup resources', 'audit cleanup', or 'check what should be closed', (3) A long workflow ends and the manager wants a structured paper trail of what it closed/kept/deleted. Auto-execute by default — the Sonnet agent proposes, the manager (you) executes safe actions and prints a final report.