Files
vercel__vercel-plugin/hooks/subagent-stop-sync.mjs
John Lindquist b8b233995c feat(skills): broaden trigger patterns for 7 under-injected skills based on eval findings; add next-forge skill; bump to 0.15.0
Eval analysis of 9 real sessions showed 10 skills never triggering despite being
requested. Root causes: pathPatterns too narrow (agents write to lib/email-template.tsx
not emails/), promptSignals containing regex instead of plain text (vercel-sandbox),
and missing promptSignals entirely (v0-dev, vercel-firewall).

Skills updated: email, vercel-queues, edge-runtime, vercel-firewall, chat-sdk,
v0-dev, vercel-sandbox. New skill: next-forge (bootstrap detection).
2026-03-09 17:56:23 -06:00

83 lines
2.3 KiB
JavaScript
Executable File

#!/usr/bin/env node
import { appendFileSync } from "node:fs";
import { readFileSync } from "node:fs";
import { resolve } from "node:path";
import { tmpdir } from "node:os";
import { fileURLToPath } from "node:url";
import { listSessionKeys } from "./hook-env.mjs";
import { createLogger, logCaughtError } from "./logger.mjs";
const log = createLogger();
function parseInput() {
try {
const raw = readFileSync(0, "utf8");
if (!raw.trim()) return null;
return JSON.parse(raw);
} catch {
return null;
}
}
function ledgerPath(sessionId) {
return resolve(tmpdir(), `vercel-plugin-${sessionId}-subagent-ledger.jsonl`);
}
function appendLedger(entry) {
const path = ledgerPath(entry.session_id);
try {
appendFileSync(path, JSON.stringify(entry) + "\n", "utf-8");
} catch (error) {
logCaughtError(log, "subagent-stop-sync:append-ledger-failed", error, { path });
}
}
function main() {
const input = parseInput();
if (!input) {
process.exit(0);
}
const sessionId = input.session_id;
if (!sessionId) {
process.exit(0);
}
const agentId = input.agent_id ?? "unknown";
const agentType = input.agent_type ?? "unknown";
log.debug("subagent-stop-sync", { sessionId, agentId, agentType });
let ledgerEntryWritten = false;
try {
appendLedger({
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
session_id: sessionId,
agent_id: agentId,
agent_type: agentType,
agent_transcript_path: input.agent_transcript_path
});
ledgerEntryWritten = true;
} catch (error) {
logCaughtError(log, "subagent-stop-sync:ledger-write-failed", error, {
sessionId,
agentId
});
}
let skillsInjected = 0;
try {
const claimed = listSessionKeys(sessionId, "seen-skills", agentId !== "unknown" ? agentId : void 0);
skillsInjected = claimed.length;
} catch {
}
log.summary("subagent-stop-sync:complete", {
agent_id: agentId,
agent_type: agentType,
skills_injected: skillsInjected,
ledger_entry_written: ledgerEntryWritten
});
process.exit(0);
}
const ENTRYPOINT = fileURLToPath(import.meta.url);
const isEntrypoint = process.argv[1] ? resolve(process.argv[1]) === ENTRYPOINT : false;
if (isEntrypoint) {
main();
}
export {
appendLedger,
ledgerPath,
main,
parseInput
};