用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/SocketDev/action --skill trimming-bundle命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
Propagate a wheelhouse template change across fleet repos: worktrees, push/PR fallback, cleanup.
Run this repo's GitHub Actions locally with Agent-CI before pushing CI-sensitive changes.
Audit package exports for dead, internal-only, or weakly-consumed subpaths before pruning.
基于 SOC 职业分类
正在显示 SKILL.md
| name | trimming-bundle |
| description | Find unused bundled code paths and keep only stubs that rebuild and pass tests. |
| user-invocable | true |
| allowed-tools | Read, Edit, Grep, Glob, AskUserQuestion, Bash(pnpm:*), Bash(node:*), Bash(grep:*), Bash(rg:*), Bash(find:*), Bash(ls:*), Bash(wc:*), Bash(du:*), Bash(stat:*), Bash(git status:*), Bash(git diff:*) |
| model | claude-haiku-4-5 |
| context | fork |
| metadata | {"internal":true} |
Iteratively stub heavyweight modules that the bundler statically pulls in but the runtime never reaches. Apply on repos that ship a built bundle. Today: rolldown only (socket-packageurl-js, socket-sdk-js; any repo with .config/repo/rolldown.config.mts). The skill is named generically because the dead-path-stubbing pattern applies to any bundler; today the only fleet bundler is rolldown.
dist/index.js grows by more than ~10% between releases without a corresponding feature addition.scanning-quality flags bundle-trim candidates (the quality scan reads dist/ but doesn't mutate it; this skill does the trim loop)..config/repo/rolldown.config.mts).moduleSideEffects: false annotation).pnpm test fails before any trim). Fix tests first; trim depends on the test signal.🚨 This skill REQUIRES .config/repo/rolldown/lib-stub.mts to be present and to export createLibStubPlugin. The file is fleet-canonical (cascades from socket-wheelhouse/template/.config/repo/rolldown/lib-stub.mts via sync-scaffolding) and must NOT be edited locally per the no-fleet-fork rule.
Before doing anything else:
[ -f .config/repo/rolldown/lib-stub.mts ] || {
echo "ERROR: .config/repo/rolldown/lib-stub.mts is missing."
echo "Cascade it from socket-wheelhouse:"
echo " cd /Users/<user>/projects/socket-wheelhouse &&" # socket-lint: allow cross-repo
echo " node scripts/repo/sync-scaffolding/cli.mts --target <this-repo> --fix"
exit 1
}
If the file is missing, STOP and run the cascade. Do NOT inline a copy of the plugin. It must be the fleet-canonical version.
Verify the rolldown config imports it:
grep -q "createLibStubPlugin" .config/repo/rolldown.config.mts || {
echo "ERROR: .config/repo/rolldown.config.mts doesn't import createLibStubPlugin."
echo "Add: import { createLibStubPlugin } from './rolldown/lib-stub.mts'"
echo "And: plugins: [createLibStubPlugin({ stubPattern: /...regex.../ })]"
exit 1
}
dist/: the most recent build output (run pnpm build first if missing or stale)..config/repo/rolldown.config.mts: already imports createLibStubPlugin from .config/repo/rolldown/lib-stub.mts (fleet-canonical; cascaded via sync-scaffolding).pnpm test: must pass at start; the trim loop's signal is "tests still pass after stub."pnpm build
node scripts/fleet/trimming-bundle/measure-bundle.mts --json
pnpm test
measure-bundle.mts emits { bundleSizeBytes, perFileSizes (heaviest-first), preconditions (dist exists / rolldown.config imports createLibStubPlugin / lib-stub.mts present), rawDistImportSurvey (the deduped dist import specifiers, at full subpath granularity) }. It MEASURES only — the candidate discovery +
HIGH/MEDIUM/LOW grading in Phase 2 stay your call (the static signal is
ambiguous; the engine deliberately renders no verdict). Record:
bundleSizeBytes (re-run after each stub for the delta).Read dist/index.js (or the primary entry) and grep for module imports / requires. The static analyzer keeps modules that are statically reachable from any export. Candidates for stubbing are modules whose entire surface area is:
globs imported by a deprecated helper that's no longer in the entry chain).if (DEBUG_MODE) where DEBUG_MODE is false in the build).How to identify, in priority order:
rg "from '@socketsecurity/lib/(globs|sorts|http-request|.*)'" dist/. Note which lib subpaths show up. Cross-reference against published API surface (src/index.ts exports). Anything imported by the bundle that's not transitively reached from src/index.ts is a candidate.du -bc dist/*.js | sort -rn | head -10. Identifies the largest bundle outputs. If dist/index.js is unexpectedly large, the heaviest unused dep is usually the culprit.verbose: true (if added) on createLibStubPlugin to log every resolved module. The list of resolved paths NOT under your repo's src/ is the candidate set.For each candidate, record:
/.../@socketsecurity/lib/dist/globs.js).du -b on the file).🚨 Stubbing a file that IS reached at runtime gives runtime crashes, not bundle-time errors. Verify each candidate before stubbing:
# 1. Search the published API surface for direct imports.
rg --no-heading "from .*<candidate-name>" src/
# 2. Search transitively reachable code for indirect imports.
rg --no-heading "<candidate-name>" src/
# 3. Confirm the candidate is NOT reached from any test.
rg --no-heading "<candidate-name>" test/
If any of these find a hit, the candidate is reachable; skip it. Only candidates with zero hits across all three queries proceed to Phase 4.
The stub → rebuild → test → keep-or-revert loop is scripted — it's
mechanical and attribution-sensitive, so it's not the model's to run by hand.
Hand the candidate tokens you graded in Phases 2–3 to lib/trim-loop.mts:
node .claude/skills/fleet/trimming-bundle/lib/trim-loop.mts \
--repo <dir> --candidates globs,sorts,<new-candidate> --json
Run it --dry-run first to confirm the candidate list (it reports what it would
stub without building). The loop, one candidate at a time:
stubPattern alternation.pnpm build + pnpm test.verdict is one of: kept,
reverted-tests (candidate IS reached — Phase 3 missed an import path,
investigate), reverted-no-shrink (regex didn't match the resolved path —
adjust the basename/fragment, it's stable across pnpm hoisting), or
reverted-grew (stub overhead exceeded the saving).The loop owns one-at-a-time discipline and the size-delta bookkeeping so failure
attribution stays clean. The JSON result carries keptCandidates,
totalSavedBytes, and a per-candidate outcomes array — read it to decide which
kept stubs need a Phase 5 WHY comment.
For each candidate that survived the loop, add a one-line comment in the stubPattern definition explaining WHY it's safe to stub (which import path it's on, why runtime never reaches it). Future maintainers need to know the chain of reasoning, not just the regex.
pnpm build
pnpm test
pnpm exec oxlint
pnpm exec tsgo -p tsconfig.check.json
All four must pass before committing.
git add .config/repo/rolldown.config.mts
git commit -m "perf(bundle): stub <N> unused lib internals (<size> saved)"
The commit message states the count + size delta. If the trim is significant (say >50KB), also update docs/rolldown-migration.md with the new baseline.
.config/repo/rolldown/lib-stub.mts: fleet-canonical plugin (cascade via sync-scaffolding; never edit locally per the no-fleet-fork rule).docs/rolldown-migration.md: repo-specific (in repos that ran the migration). Records baseline numbers from before/after the esbuild → rolldown switch.socket-packageurl-js/.config/rolldown.config.mts: the worked example of createLibStubPlugin use, with a populated stubPattern.The bundle-trim scan in scanning-quality/scans/bundle-trim.md runs the discovery half of this skill (Phase 1–3) and reports candidates. It does NOT mutate the repo. Use this skill for the actual trim loop.
Before stubbing, collapse duplicate majors with /deduping-dependencies — a bundle that pulls two copies of a utility (e.g. string-width@4 + @8) ships both. For bundled outputs that skill prefers the ESM major (tree-shakes smaller) and forces it where the break is module-format-only; one deduped copy beats two stubbed ones.
await import(): the static analyzer flags it as unreachable but the runtime path needs it. Add the dep back to the entry's static imports OR remove the dynamic import.stubPattern matches more paths than intended: too-broad regex. Tighten to a specific basename or a unique path segment. The plugin matches against the absolute resolved path, so node_modules/.pnpm/@socketsecurity+lib@.../dist/globs.js is what you're matching.