Hook modules were creating separate logger instances, so a single PreToolUse run could emit multiple invocationIds once hook-env catch logging fired. Reusing one process-scoped invocationId keeps all lines from one hook invocation correlated.
This also demotes internal trigger diagnostics back to debug so summary mode stays limited to complete and issue events, matching the logger contract and tests.
Verified: bun test tests/pretooluse-skill-inject.test.ts (278 tests pass)
Verified: bun test tests/logger.test.ts (12 tests pass)
Verified: bun test tests/hook-sync.test.ts -t "logger .mts/.mjs sync|pretooluse-skill-inject .mts/.mjs sync" (6 tests pass)
Swarm-Agent: codex-invocation-id-fix
Replace empty catch blocks in hook-env and session-start-profiler with\nstructured debug logging using the shared hook logger.\nAlso make the Vercel CLI update check compare numeric version\nsegments so 1.9.0 correctly sorts below 1.10.0.\n\nVerified: bun test tests/session-start-profiler.test.ts\nHow to test: bun test tests/session-start-profiler.test.ts\nSwarm-Agent: codex-profiler-harden-split-1
- Replace tsc+cp+rm pipeline with tsup (7ms builds, no intermediate dir)
- tsup compiles hooks/src/*.mts directly to hooks/*.mjs
- tsconfig.json retained for type-checking only (noEmit)
- Remove all .sh references from tests, docs, and hooks.json
- Fix glob pattern test to handle tsup's output format
Hook source now lives in hooks/src/*.mts and compiles to hooks/*.mjs via tsc.
The formatOutput() return type is checked against SyncHookJSONOutput from
@anthropic-ai/claude-agent-sdk, preventing unknown fields in hookSpecificOutput
that Claude Code's strict Zod validation would silently reject.
Root cause: skillInjection metadata was a sibling key in hookSpecificOutput,
which Claude Code rejected as "Hook JSON output validation failed: Invalid input".
All skill injections were silently discarded. Now skillInjection metadata is
embedded as an HTML comment inside additionalContext.
- Add hooks/src/*.mts (TypeScript source for all 6 hook modules)
- Add hooks/tsconfig.json (strict, NodeNext, compiles .mts → .mjs)
- Add build:hooks script and pre-commit hook for auto-compilation
- Install @anthropic-ai/claude-agent-sdk as devDependency for types
- Bump plugin version to 0.4.0
Create hooks/vercel-config.mjs that reads vercel.json and maps top-level keys (rewrites, redirects, headers, crons, functions) to skill slugs, so skills are injected when the project uses those Vercel features.
Create hooks/logger.mjs with structured logging at four levels (off, summary, debug, trace) controlled by VERCEL_PLUGIN_LOG_LEVEL env var. Support legacy VERCEL_PLUGIN_DEBUG=1 mapping to debug level.
Create src/cli/explain.ts that takes a tool name and input JSON, runs the match engine, and prints which skills would fire and why. Create src/cli/index.ts as the CLI entry point. Create src/commands/doctor.ts for diagnosing plugin setup issues.
Create src/shared/logger.ts and src/shared/match-engine.ts as TypeScript versions of the shared utilities.
Create scripts/build-manifest.ts that reads all SKILL.md files, parses frontmatter, and generates generated/skill-manifest.json.
Add CLAUDE.md documenting the architecture, dedup contract, YAML parser quirks, test conventions, and log levels.
Add tests: tests/cli-explain.test.ts, tests/logger.test.ts, tests/vercel-config.test.ts, tests/snapshot-runner.test.ts with snapshot files in tests/snapshots/. Add test fixtures in tests/fixtures/. Update existing tests to copy new hook modules (logger.mjs, vercel-config.mjs) into temp dirs.
Update package.json with new bin entry and dependencies.