mirror of
https://github.com/vercel/vercel-plugin.git
synced 2026-09-14 15:39:47 +08:00
8e24d0694a
Add a chainTo frontmatter field to skills that triggers follow-up skill injection when PostToolUse file contents match regex patterns. Add upgradeToSkill/upgradeWhy fields to validation rules so validate errors can recommend loading a specific skill. Register posttooluse-bash-chain.mjs in hooks.json. Add ChainToRule interface to patterns.mts and skill-map-frontmatter.mts, with parseChainToRules() parser. Add duplicate-key detection to the YAML parser. Reset dedup claim dir and session file on clear/compact events in session-start-seen-skills so skills re-inject into fresh context windows. Add chainTo rules to: agent-browser-verify, agent-browser, ai-elements, ai-gateway, ai-generation-persistence, ai-sdk, auth, bootstrap, chat-sdk, cms, cron-jobs, deployments-cicd, email, env-vars, geist, investigation-mode, json-render, marketplace, micro, ncc, next-forge, nextjs, observability, payments, react-best-practices, routing-middleware, runtime-cache, satori, shadcn, sign-in-with-vercel, swr, turbopack, turborepo, v0-dev, vercel-agent, vercel-api, vercel-cli, vercel-firewall, vercel-flags, vercel-functions, vercel-queues, vercel-sandbox, vercel-storage, verification, workflow. Add upgradeToSkill to ai-elements and ai-sdk validate rules. Expand ai-sdk validate messages with Run Skill() hints. Update nextjs, vercel-storage, runtime-cache, workflow, turborepo skill bodies. Add new skills: geistdocs (Geist design system docs), zzz-test-meta-name-mask (test fixture). Add skills/_chain-audit.md chain coverage audit doc. Delete .claude-plugin/marketplace.json, .claude-plugin/plugin.json (deprecated), skills/edge-runtime/SKILL.md (consolidated into vercel-functions). Add tests: posttooluse-chain.test.ts (4699 lines, chain injection e2e), ai-sdk-companion.test.ts (181 lines). Expand build-skill-map.test.ts (+335 lines), validate-rules.test.ts (+936 lines), session-start-seen-skills.test.ts (+74 lines), skill-map-frontmatter.test.ts (+50 lines), verification-skill.test.ts (+20 lines). Update build-manifest.ts to emit chainTo rules and upgradeToSkill fields. Rebuild generated/skill-manifest.json, generated/skill-catalog.md, generated/build-from-skills.manifest.json. Rebuild all compiled hooks/*.mjs. Update CLAUDE.md lexical prompt default to on. Update vercel.md ecosystem graph, docs, and cli-reference.
56 lines
1.9 KiB
TypeScript
56 lines
1.9 KiB
TypeScript
import { defineConfig } from "tsup";
|
|
import { readdirSync } from "node:fs";
|
|
|
|
// Build each .mts source file as a separate .mjs output (no bundling)
|
|
const discoveredEntries = readdirSync("hooks/src")
|
|
.filter((f) => f.endsWith(".mts"))
|
|
.map((f) => `hooks/src/${f}`);
|
|
const entries = Array.from(
|
|
new Set([
|
|
...discoveredEntries,
|
|
"hooks/src/session-end-cleanup.mts",
|
|
]),
|
|
).sort();
|
|
|
|
// Local hook-to-hook imports stay as external (sibling .mjs files at runtime).
|
|
// Everything from node_modules gets bundled inline — plugins can't install deps.
|
|
//
|
|
// IMPORTANT: noExternal: [/.*/] overrides the `external` array in tsup, so
|
|
// sibling hook imports were being inlined — duplicating side-effecting
|
|
// isMainModule() guards and producing invalid double-JSON output (e.g. "{}{}").
|
|
// Fix: use an esbuild plugin to mark sibling .mjs imports as external before
|
|
// tsup's noExternal logic runs.
|
|
const hookExternalSet = new Set(
|
|
entries.map((e) => `./${e.replace("hooks/src/", "").replace(".mts", ".mjs")}`),
|
|
);
|
|
|
|
export default defineConfig({
|
|
entry: entries,
|
|
format: ["esm"],
|
|
outDir: "hooks",
|
|
outExtension: () => ({ js: ".mjs" }),
|
|
bundle: true,
|
|
splitting: false,
|
|
noExternal: [/.*/], // bundle ALL npm deps — plugins can't install
|
|
sourcemap: false,
|
|
dts: false,
|
|
clean: false, // don't wipe hooks/ — it has hooks.json, src/, etc.
|
|
target: "node20",
|
|
esbuildPlugins: [
|
|
{
|
|
name: "externalize-sibling-hooks",
|
|
setup(build) {
|
|
// Mark sibling hook imports (./foo.mjs) as external so they're not
|
|
// inlined. This runs before tsup's noExternal catch-all.
|
|
build.onResolve({ filter: /^\.\/.*\.mjs$/ }, (args) => {
|
|
if (hookExternalSet.has(args.path)) {
|
|
return { path: args.path, external: true };
|
|
}
|
|
return undefined;
|
|
});
|
|
},
|
|
},
|
|
],
|
|
// No banner — source files that need a shebang already include #!/usr/bin/env node
|
|
});
|