Commit Graph

104 Commits

Author SHA1 Message Date
John Lindquist 8e3350454c feat: prompt scoring improvements, compaction re-injection, validation dedup, strip droppedByCap from context; bump to 0.18.0
- Add dominant-topic suppression (top score >= 600 filters scores < 50)
- Add project-context boost (+3 for VERCEL_PLUGIN_LIKELY_SKILLS skills)
- Add lexical fallback floor (reject raw score < 20)
- Add compaction re-injection for priority >= 7 skills (VERCEL_PLUGIN_CONTEXT_COMPACTED)
- Add validation rule dedup tracking (ruleId + filePath on violations)
- Strip droppedByCap from injected HTML comments (kept in debug logs)
- Fix ncc/SKILL.md and next-forge/SKILL.md YAML frontmatter
- Add startup diagnostic for broken skill frontmatter
2026-03-11 19:01:59 -06:00
John Lindquist ed7c3eb8ad fix(skill-frontmatter): warn on broken startup skills
Normalize fragile SKILL.md frontmatter in ncc and next-forge so the custom
frontmatter parser keeps their regex and nested prompt signal data intact.
Add a session-start summary log for broken skill frontmatter and keep
telemetry env export non-fatal when the env file is missing.

Verified: bun test tests/skill-map-frontmatter.test.ts tests/session-start-profiler.test.ts

Swarm-Agent: codex-skill-reliability
2026-03-11 19:01:59 -06:00
John Lindquist b7e9b1b053 feat: merge upstream telemetry + Cursor compat, fix tests and dedup migration; bump to 0.17.0 2026-03-11 16:12:55 -06:00
John Lindquist 3348f2a5bc fix(tsup): externalize sibling hook imports to prevent double-JSON output, enable lexical prompt matching by default
In hooks/tsup.config.ts, add an esbuild plugin (externalize-sibling-hooks) that marks sibling ./*.mjs imports as external before tsup's noExternal catch-all runs. The previous config used noExternal: [/.*/] which overrode the external array, causing sibling hooks to be inlined with their side-effecting isMainModule() guards — producing invalid concatenated JSON output like "{}{}". The fix uses build.onResolve to intercept ./foo.mjs imports matching the hookExternalSet and return { external: true }. npm dependencies (minisearch, etc.) remain bundled inline.

In hooks/src/user-prompt-submit-skill-inject.mts line 581, change the lexical check from process.env.VERCEL_PLUGIN_LEXICAL_PROMPT === "1" to !== "0" so lexical stemmer fallback is on by default. Update the CLAUDE.md env var table to show default as "on" with "0" to disable.

Rebuild all compiled hooks via bun run build:hooks.
2026-03-11 15:18:35 -06:00
John Lindquist 8e24d0694a feat: add chainTo skill chaining, prompt signals, validation upgrades, and dedup reset on context clear
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.
2026-03-11 15:18:35 -06:00
John Lindquist 089b5aefa4 fix(benchmark-sandbox): extend sandbox before snapshot
Move the timeout extension ahead of the snapshot call so long builds do not
expire before the restore point is created.
Also double the sandbox creation lifetime and only apply a post-snapshot
extension when keep-alive is enabled.

Verified: bun test tests/run-eval-build-polling.test.ts
Swarm-Agent: codex-snapshot-timing
2026-03-11 15:18:19 -06:00
John Lindquist 4c00fc0a00 fix(prompt-submit): drop seen-skills env merge
UserPromptSubmit no longer merges or rewrites seen-skill state through VERCEL_PLUGIN_SEEN_SKILLS when file-backed dedup state exists.
The helper now keeps session-file state authoritative and only forwards the dedup flag into injectSkills inline.

Verified: bun run build:hooks
Verified: bun test hooks/user-prompt-submit-skill-inject.test.ts tests/user-prompt-submit-skill-inject.test.ts
Swarm-Agent: codex-prompt-drop-env-v2
2026-03-11 15:18:19 -06:00
John Lindquist 9bec068d63 fix(posttool): drop seen-skills env merge from validate and bash-chain hooks
Both posttool hooks now consult the persisted session-backed seen-skills state instead of merging in VERCEL_PLUGIN_SEEN_SKILLS. This keeps dedup behavior consistent across subagents and avoids env leakage into hook chaining decisions.

Verified: bun run build:hooks
Verified: tsc -p hooks/tsconfig.json --noEmit
Verified: bun test tests/posttooluse-validate.test.ts
Verified: bun test hooks/platform-hook-compat.test.ts
Verified: bun -e '...runChainInjection smoke for session-file-only seen-skills...'
Verified: bun -e '...runBashChainInjection smoke for session-file-only seen-skills...'
Swarm-Agent: codex-posttool-commit
2026-03-11 15:18:19 -06:00
John Lindquist e048cbc9bd fix(pretooluse): drop seen env merge writes
The pretool hook no longer folds VERCEL_PLUGIN_SEEN_SKILLS into
session-file dedup state or writes claim-sync results back into
process.env. File-backed dedup still claims and syncs session state,
while env-only dedup remains a fallback when no session scope exists.

Verified: bun run build:hooks
Verified: bun test tests/hook-sync.test.ts
Verified: bun test tests/pretooluse-skill-inject.test.ts --test-name-pattern "file-based dedup persists across invocations with same session_id|debug mode logs dedup strategy for file, memory-only, and disabled"
Verified: node --input-type=module <<'EOF' ... fresh cursor Write payload asserts no VERCEL_PLUGIN_SEEN_SKILLS env update and TSX counter update EOF
Verified: node --input-type=module <<'EOF' ... env-only Read payload without session_id returns {} when VERCEL_PLUGIN_SEEN_SKILLS=nextjs EOF
Swarm-Agent: codex-pretool-drop-env-merge
2026-03-11 15:18:19 -06:00
John Lindquist a80ac3581c fix(session-start-profiler): store profiler state in session files
Claude session-start-profiler no longer requires CLAUDE_ENV_FILE to persist likely skills or greenfield state.
Those values now come from the hook input session ID and are written to session files,
while Claude env exports remain only for the other profiler vars.

Verified: bun run build:hooks
Verified: bun test tests/session-start-profiler.test.ts
Swarm-Agent: codex-profiler-env-cleanup
2026-03-11 15:18:19 -06:00
John Lindquist 7566bed4d4 fix(session-start): noop Claude seen-skills init
Claude session-start no longer appends VERCEL_PLUGIN_SEEN_SKILLS to
CLAUDE_ENV_FILE now that claim-dir/session initialization handles dedup.
Cursor still emits the empty env var payload on stdout.

Verified: bun run build:hooks
Verified: bun test tests/session-start-seen-skills.test.ts
Verified: bun test tests/session-timeline-subagent.test.ts
Verified: bun test hooks/session-hooks-platform-compat.test.ts
Swarm-Agent: codex-seen-skills-init-cleanup
2026-03-11 15:18:19 -06:00
John Lindquist 8e7c146c73 fix(prompt-submit): drop seen-skills env appends
UserPromptSubmit no longer appends VERCEL_PLUGIN_SEEN_SKILLS into CLAUDE_ENV_FILE.
Session claims/files remain the persistence path, while Cursor keeps its existing output-env fallback when no env file is present.

Verified: bun run build:hooks
Verified: bun test tests/user-prompt-submit.test.ts -t "cursor payload returns flat output with continue and env patch"
Verified: bun test tests/user-prompt-submit.test.ts -t "does not append seen skills to CLAUDE_ENV_FILE when available"
Swarm-Agent: codex-prompt-submit-env-cleanup
2026-03-11 15:18:19 -06:00
John Lindquist 95176e59dc fix(pretooluse): move hook counters off Claude env file
PreToolUse now persists TSX review and dev-server verify counters via session files,
and it no longer appends runtime env exports to CLAUDE_ENV_FILE for Claude.
This keeps seen-skills dedup on the claim/session-file path and avoids shell-init
side effects during hook execution.

Verified: bun run build:hooks
Verified: bun test tests/pretooluse-skill-inject.test.ts -t "file-based dedup persists across invocations with same session_id"
Verified: bun test tests/pretooluse-skill-inject.test.ts -t "empty VERCEL_PLUGIN_SEEN_SKILLS env var dedups across invocations"
Verified: custom node smoke test (tsx-migration-check) — CLAUDE_ENV_FILE unchanged, tsx-edit-count reset in session file, seen-skills persisted
Verified: custom node smoke test (dev-migration-check) — CLAUDE_ENV_FILE unchanged, dev-verify-count persisted in session file
Swarm-Agent: codex-pretooluse-env-cleanup
2026-03-11 15:18:18 -06:00
John Lindquist b9fcf22191 feat(hooks): add Cursor compat to pretooluse-skill-inject
Detect platform via conversation_id/workspace_roots/cursor_version
fields in stdin JSON. Normalize sessionId, cwd, and output format:
- Cursor: flat { additional_context, env } output
- Claude Code: nested { hookSpecificOutput } output (unchanged)

Env var updates use JSON env field for Cursor instead of
CLAUDE_ENV_FILE. Includes platform-hook-compat test suite.
2026-03-11 15:18:18 -06:00
John Lindquist 92b69b6ee7 fix(hooks): support Cursor session-start profiler output
Finish the session-start profiler Cursor path without touching the profiling logic.
Platform detection now keys off hook input and CLAUDE_ENV_FILE, project root lookup falls back to CURSOR_PROJECT_DIR, and Cursor receives env plus additional_context JSON on stdout.

Verified: bun test hooks/session-start-profiler-platform.test.ts
Verified: bun test hooks/session-hooks-platform-compat.test.ts
Verified: zsh -lc 'tmpdir=/var/folders/c3/r013q3_93_s4zycmx0mdnt2h0000gn/T/tmp.p6JmjuMjls; printf "{\"conversation_id\":\"conv-123\",\"cursor_version\":\"1.0.0\"}" | env -u CLAUDE_ENV_FILE -u CLAUDE_PROJECT_ROOT CURSOR_PROJECT_DIR="" bun hooks/src/session-start-profiler.mts'
Swarm-Agent: codex-profiler-v2
2026-03-11 15:18:18 -06:00
John Lindquist a78ac86798 fix(hooks): add Cursor support for session hooks
Session start hooks now detect Cursor payloads from stdin and emit Cursor-compatible JSON while keeping Claude Code env-file behavior intact.
Session end cleanup now falls back to conversation_id so Cursor sessions clean up the same temp artifacts.

Verified: bun test hooks/session-hooks-platform-compat.test.ts tests/session-start-seen-skills.test.ts tests/session-end-cleanup.test.ts
How to test: run the same bun test command, or pipe Cursor-style JSON into the three hook scripts under hooks/*.mjs.
Swarm-Agent: codex-session-start-v2
2026-03-11 15:17:31 -06:00
John Lindquist 8d8faffe57 fix(hooks): add cursor support to posttool validator
Normalize PostToolUse stdin with compat-based platform detection and Cursor workspace/session fallbacks.
Emit Cursor additional_context/env payloads while preserving Claude output shape and empty-result behavior.

Verified: bun test hooks/platform-hook-compat.test.ts
Verified: bun --eval 'import assert from "node:assert/strict"; import { mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs"; import { tmpdir } from "node:os"; import { join } from "node:path"; import { formatOutput, markValidated } from "./hooks/src/posttooluse-validate.mts"; const tempDir = mkdtempSync(join(tmpdir(), "posttooluse-validate-")); const envFile = join(tempDir, "claude.env"); writeFileSync(envFile, "", "utf-8"); delete process.env.VERCEL_PLUGIN_VALIDATED_FILES; process.env.CLAUDE_ENV_FILE = envFile; const next = markValidated("app/page.tsx", "abc123def456", null); assert.equal(next, "app/page.tsx:abc123def456"); assert.match(readFileSync(envFile, "utf-8"), /VERCEL_PLUGIN_VALIDATED_FILES="app\/page\.tsx:abc123def456"/); const output = JSON.parse(formatOutput([{ skill: "ai-sdk", line: 8, message: "Use streamText for streaming responses.", severity: "recommended", matchedText: "generateText" }], ["ai-sdk"], "app/page.tsx", undefined, "cursor", { VERCEL_PLUGIN_VALIDATED_FILES: next })); assert.equal(output.env.VERCEL_PLUGIN_VALIDATED_FILES, next); rmSync(tempDir, { recursive: true, force: true }); delete process.env.CLAUDE_ENV_FILE; delete process.env.VERCEL_PLUGIN_VALIDATED_FILES;'
Swarm-Agent: codex-posttool-validate-v2
2026-03-11 15:17:02 -06:00
John Lindquist e91067f1aa chore(hooks): drop accidental generated artifacts
Restore generated hook outputs that were accidentally committed when the
repo pre-commit hook rebuilt the entire hooks directory. This follow-up
keeps this agent's change set focused on the UserPromptSubmit source and
tests without touching the in-progress source files owned by other agents.

Verified: bun test hooks/user-prompt-submit-skill-inject.test.ts tests/user-prompt-submit.test.ts
Verified: restored generated outputs to their HEAD~1 content for six unrelated hook artifacts
Swarm-Agent: codex-prompt-hook
2026-03-11 15:17:02 -06:00
John Lindquist 1142c51906 fix(user-prompt-submit): support cursor prompt hook
Normalize UserPromptSubmit input fields across Claude Code and Cursor,
including conversation/session IDs, cwd roots, and prompt/message
fallbacks. Cursor now returns flat beforeSubmitPrompt output with
continue:true and emits seen-skill env patches when no CLAUDE_ENV_FILE is
available, while Claude continues using hookSpecificOutput and appends
seen-skill exports to CLAUDE_ENV_FILE when present.

Verified: bun test hooks/user-prompt-submit-skill-inject.test.ts tests/user-prompt-submit.test.ts
Verified: cursor beforeSubmitPrompt payload returns continue:true + env patch in tests/user-prompt-submit.test.ts
Swarm-Agent: codex-prompt-hook
2026-03-11 15:17:02 -06:00
John Lindquist 0beeedb807 chore(hooks): restore unrelated generated outputs
The local pre-commit hook rebuilt several hooks/*.mjs files from other agents' dirty source changes while I was committing the new compat layer. Restore the unrelated generated artifacts to their previous state so this task only carries the compat-layer files it owns.

Verified: bun test hooks/compat.test.ts
Swarm-Agent: codex-compat-layer
2026-03-11 15:16:27 -06:00
John Lindquist e37004a002 feat(hooks): add compat layer for cursor payloads
Add a shared Claude Code/Cursor compatibility module that normalizes hook input, formats platform-specific output, and persists session env state across both runtimes.

Verified: bun test hooks/compat.test.ts
Verified: bun x tsc --noEmit --module nodenext --moduleResolution nodenext --target es2022 --types node hooks/src/compat.mts
Swarm-Agent: codex-compat-layer
2026-03-11 15:16:27 -06:00
John Lindquist 9fdcc5c8b0 chore(pretooluse-skill-inject): restore generated bundle
The previous commit unintentionally included this compiled hook artifact because the local pre-commit hook rebuilt and auto-staged hook bundles. This restores the generated file to its prior committed state without touching the dirty source file.

Verified: tmp=/var/folders/c3/r013q3_93_s4zycmx0mdnt2h0000gn/T/tmp.2y6bxG5m6P && git show HEAD^:hooks/pretooluse-skill-inject.mjs > "" && cmp -s hooks/pretooluse-skill-inject.mjs "" && rm ""
Swarm-Agent: codex-hook-chain
2026-03-11 15:16:21 -06:00
John Lindquist 994a5431a8 fix(posttooluse-validate): dedupe skill upgrade instructions
formatOutput now emits a single skill-upgrade instruction block per target skill, adds the requested blank line and reason text, and marks hard upgrades as REQUIRED so agents get clearer follow-up actions.

Verified: bun run build:hooks
Verified: bun test tests/posttooluse-validate.test.ts
Verified: bun run typecheck
Swarm-Agent: codex-hook-chain
2026-03-11 15:16:21 -06:00
John Lindquist ab8810509e fix(hooks): drop unrelated generated injector diff
The repo pre-commit hook rebuilt hook outputs and accidentally staged a generated pretooluse injector artifact from another in-progress source change. This commit restores that generated file to its pre-commit content so the skill-upgrade change stays isolated.

Verified: diff -u <(git show HEAD^:hooks/pretooluse-skill-inject.mjs) hooks/pretooluse-skill-inject.mjs
Swarm-Agent: codex-schema
2026-03-11 15:16:21 -06:00
John Lindquist 4525723e15 feat(hooks): add skill upgrade metadata to validate rules
Validate rules can now carry optional skill-upgrade metadata from SKILL.md frontmatter through the post-tool-use validator. When a matching rule requests an upgrade, the hook output now emits both human-readable Skill tool guidance and a machine-readable HTML comment for downstream parsing.

Verified: bun run typecheck
Verified: bun -e 'const mod = await import("./hooks/src/posttooluse-validate.mts"); const violations = mod.runValidation("foo\n", ["source-skill"], new Map([["source-skill", [{ pattern: "foo", message: "needs upgrade", severity: "error", upgradeToSkill: "target-skill", upgradeWhy: "more specific context" }]] ])); const out = JSON.parse(mod.formatOutput(violations, ["source-skill"], "/tmp/test.ts")); console.log(JSON.stringify(violations)); console.log(out.hookSpecificOutput.additionalContext);'
Verified: bun -e 'const mod = await import("./hooks/src/skill-map-frontmatter.mts"); const parsed = mod.parseSkillFrontmatter(`validate:\n  -\n    pattern: foo\n    message: needs upgrade\n    severity: error\n    upgradeToSkill: target-skill\n    upgradeWhy: use the more specific skill\n  -\n    pattern: bar\n    message: hard upgrade\n    severity: warn\n    upgradeToSkill: hard-skill\n    upgradeMode: hard\n`); console.log(JSON.stringify(parsed.validate));'
Swarm-Agent: codex-schema
2026-03-11 15:16:21 -06:00
melkeydev fd61d00d91 removing setup hook that doesnt exist 2026-03-11 14:11:14 -07:00
melkeydev 25c1cae890 fixing telemetry 2026-03-11 12:39:08 -07:00
melkeydev 16db2e9c95 removing timeouts 2026-03-11 12:24:48 -07:00
melkeydev 6258a7e349 adding event bridge and reviewer comments 2026-03-11 12:16:28 -07:00
melkeydev 55eeae089f adding telemetry 2026-03-11 10:46:51 -07:00
melkeydev c7a13ac307 adding telemetry 2026-03-11 09:23:07 -07:00
melkeydev dd67615a1c Stashing for now 2026-03-10 22:41:41 -07:00
melkeydev 4f95105551 fixing telemetry 2026-03-10 22:06:08 -07:00
melkeydev 0493dbcd70 adding telemetry 2026-03-10 22:04:10 -07:00
John Lindquist 17be9898ea Add sitemap field to SkillConfig and inject sitemap URLs alongside doc links in the docs warning block. For each skill, find the sitemap.xml URL for its primary documentation domain and add it as metadata.sitemap in SKILL.md frontmatter. Update buildDocsBlock() in patterns.mts to render sitemap URLs parenthetically after doc links. Parse and validate the new field in skill-map-frontmatter.mts, include it in the generated manifest via build-manifest.ts, and propagate the type through pretooluse and user-prompt-submit hooks. 35 of 46 skills now have sitemaps (8 skipped: domains without sitemaps). Rebuild hooks and manifest. 2026-03-10 14:29:36 -06:00
John Lindquist d5b5ef47f7 Replace skill body injection with Skill tool invocation instructions
Instead of injecting the full SKILL.md body as additionalContext, inject
"You must run the Skill(<name>) tool." — a more conventional way of
telling the agent to use the Skill tool for context loading.
2026-03-10 12:46:11 -06:00
John Lindquist 905ffba7fa feat: add lexical stemmer, prompt signal scoring, docs, and plugin metadata
- Add stemmer and shared contractions modules for lexical prompt matching
- Enhance lexical index and prompt patterns with stemming support
- Add promptSignals metadata to all 43 skill frontmatter files
- Add comprehensive documentation site (docs/)
- Add .claude-plugin marketplace and plugin metadata
- Add benchmark scenarios script
- Update skill manifest with prompt signal data
- Add lexical-index and stemmer tests, expand prompt-patterns tests
2026-03-10 03:24:38 -06:00
John Lindquist 319bf1eb65 feat(hooks): add lexical prompt fallback scoring
Add scorePromptWithLexical as an additive wrapper around the existing exact prompt matcher.
It preserves current matching behavior, then falls back to lexical index hits when the exact score stays below threshold.

Verified: bun test tests/prompt-patterns-lexical.test.ts
Verified: tsc -p hooks/tsconfig.json --noEmit
Swarm-Agent: codex-prompt-patterns
2026-03-09 19:07:07 -06:00
John Lindquist 657e96a294 feat(hooks): add lexical skill index
Add a MiniSearch-backed lexical index for retrieval frontmatter with synonym and contraction expansion so hooks can rank skills from short natural-language queries.

Verified: bun test hooks/lexical-index.test.ts
Verified: ./node_modules/.bin/tsc --noEmit --module NodeNext --moduleResolution NodeNext --target ES2022 --strict --skipLibCheck --types node hooks/src/lexical-index.mts
Swarm-Agent: codex-lexical-index
2026-03-09 19:04:18 -06:00
John Lindquist e9ee9f2966 feat(hooks): add unified skill ranker
Add a shared rankSkills utility that combines path, command, import, profiler, prompt, lexical, and priority signals into a single sortable score with per-signal breakdowns.

Add a focused Bun regression test covering weighted scoring, ordering, and default field behavior for sparse candidates.

Verified: bun test tests/unified-ranker.test.ts
How to test: bun test tests/unified-ranker.test.ts
Swarm-Agent: codex-unified-ranker
2026-03-09 19:04:01 -06:00
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
John Lindquist 0c49abc547 fix(skills): quote YAML validate patterns ending with colon to fix js-yaml parse errors; bump to 0.14.1 2026-03-09 16:38:11 -06:00
John Lindquist 1e0fc2467c feat(hooks): wire subagent launch bootstrap
Connect SubagentStart to pending launch records so prompt-signal matches
can be merged into likely skills before context assembly.
SessionEnd now cleans hashed pending-launch temp directories and the
hook registry observes Agent tool launches.

Verified: node --input-type=module -e "import { build } from 'tsup'; await build({ entry: ['hooks/src/subagent-start-bootstrap.mts','hooks/src/session-end-cleanup.mts'], format: ['esm'], outDir: 'hooks', outExtension: () => ({ js: '.mjs' }), bundle: false, splitting: false, sourcemap: false, dts: false, clean: false, target: 'node20' });"
Verified: bun test tests/subagent-start-context.test.ts tests/session-end-cleanup.test.ts
Swarm-Agent: codex-wiring
2026-03-09 16:30:02 -06:00
John Lindquist 1dfa612df7 feat(hooks): observe agent subagent spawns
Add a PreToolUse observer hook that records Agent tool launches as pending subagent spawn metadata for downstream bootstrap logic.
It preserves the existing no-mutation contract by always returning {} and now integrates with the committed subagent-state append API.

Verified: bun test tests/pretooluse-subagent-spawn-observe.test.ts
Verified: ./node_modules/.bin/tsc -p hooks/tsconfig.json --noEmit
How to test: run bun test tests/pretooluse-subagent-spawn-observe.test.ts
Swarm-Agent: codex-observer
2026-03-09 16:28:50 -06:00
John Lindquist 2f8111da6d feat(subagent-state): add pending launch state helpers
Add a shared hooks library for pending subagent launch records and per-agent JSON state. The module filters stale launch records, claims the oldest matching launch under a file lock, and writes agent state with atomic rename semantics.

Verified: bun test tests/subagent-state.test.ts
Verified: node --input-type=module -e "import('./hooks/subagent-state.mjs').then((mod) => { if (typeof mod.listPendingLaunches !== 'function' || typeof mod.claimPendingLaunch !== 'function' || typeof mod.appendPendingLaunch !== 'function' || typeof mod.readAgentState !== 'function' || typeof mod.writeAgentState !== 'function') { process.exit(1); } })"
Swarm-Agent: codex-subagent-state
2026-03-09 16:25:50 -06:00
John Lindquist 92dbe3ae02 feat(hooks): add SubagentStart/SubagentStop hooks for subagent skill injection; bump to 0.14.0
- SubagentStart bootstrap hook injects project context (likely skills, summaries) into spawned subagents
  with budget scaling by agent type (minimal for Explore/Plan, standard for general-purpose)
- SubagentStop sync hook writes agent metadata to a session-scoped JSONL ledger for observability
- SessionEnd cleanup extended to remove subagent ledger files
- Updated ai-elements/nextjs skills, benchmark-agents and eval skill definitions
2026-03-09 15:52:56 -06:00
John Lindquist 5d548e5be8 fix(security): address audit findings — path traversal, brace expansion, injection escaping, profiler hardening; bump to 0.12.0
- Validate sessionId in dedupClaimDirPath() to prevent path traversal (HIGH)
- Add brace expansion pre-pass in globToRegex for {ts,js,mjs} patterns (HIGH)
- Escape --> sequences in HTML comment metadata blocks (MEDIUM)
- Harden checkVercelCli/checkAgentBrowser with 3s timeouts, suggest latest version (MEDIUM)
- Replace silent catch {} blocks with debug logging (LOW)
- Add semver-aware version comparison (LOW)
- Update golden snapshots and fix invocationId sharing
2026-03-09 14:18:43 -06:00
John Lindquist fdef1e9ff7 fix(hooks): share invocation ids across hook logs
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
2026-03-09 14:16:27 -06:00
John Lindquist 830e49c69b fix(profiler): harden CLI availability checks
Make the session-start profiler resolve binaries from PATH safely before
invoking them, cap the version-check subprocesses at 3 seconds, and
avoid crashing when npm or agent-browser is missing.

Also expand the outdated Vercel CLI guidance to include the pnpm global
upgrade path and cover the new skip/timeout behavior in profiler tests.

Verified: bun test tests/session-start-profiler.test.ts
Swarm-Agent: codex-profiler-harden-split-2-v2
2026-03-09 14:06:35 -06:00
John Lindquist ee21fef192 fix(hooks): log swallowed profiler errors
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
2026-03-09 13:55:54 -06:00