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).tools
Acceptance gate for a branch produced by an OpenAI Codex CLI run — usually Codex implementing a /big-plan epic that was handed off to it. Codex reports the work 'done' (or the user flags it WIP with corrections); this skill confirms the branch actually fulfils the original spec, fixes what falls short, and routes larger discoveries into GitHub issues. Use when: (1) User says '/finalize-codex-work', 'finalize codex work', 'confirm the codex work', 'check the codex branch', or 'codex said it's done', (2) A branch is the result of a Codex CLI session and needs verification against its spec issue/PR, (3) After assigning a /big-plan epic to Codex CLI. Pass -m/--merge to run /pr-complete -c at the end.
tools
Read a Figma design node directly from a share URL via the Figma REST API — no Dev Mode subscription, no MCP, no desktop app. Renders the node to PNG and dumps its full style/layout JSON so the design can be described, compared, or implemented. Use whenever the user gives a Figma design URL (figma.com/design/... or /file/...) and wants to see, read, inspect, reference, or implement that node — including `/fig-url-refer <url>`. This is the URL-based counterpart to `/figrefer` (which needs a Dev-plan desktop MCP); prefer this one when the input is a URL rather than a live desktop selection.
tools
Sync the user's Claude Code workflow skills into the OpenAI Codex CLI settings repo ($HOME/.codex) as Codex-native ports, fix the Codex .gitignore for new local state, then commit and push. Use when: (1) user says '/dev-codex-sync-settings-from-claude', 'sync codex settings', 'sync claude skills to codex', 'port skills to codex', or 'update codex from claude'; (2) after updating ~/.claude workflow skills (big-plan, x, x-as-pr, x-wt-teams) and Codex should catch up; (3) the $HOME/.codex repo has drifted behind $HOME/.claude. The ports are condensed Codex-native REWRITES, never file copies.
development
Analyze a video file (mov, mp4, webm, etc.) or a YouTube video by extracting still frames with ffmpeg and reading them chronologically with vision — Claude cannot ingest video files directly. Use whenever the user provides a video file path or YouTube URL and wants to know what happens in it: "read this video", "watch this video", "check this recording", "what happens in this .mov/.mp4", analyzing a screen recording of a UI bug, or verifying UI behavior captured in a video, even if they don't name this skill.