Skip to content

Create fork-extractor #165

@daviddgonzalez

Description

@daviddgonzalez

Fork-extractor would essentially be a feature to create plug-ins that are very similar to an existing one without having to fork the whole repo or start from scratch with the new create-extractor (coming to a PR near you).

*Should wait until after I (David) push test-extractor

More in depth description with claude:

Title: Build vv fork-extractor — copy a built-in extractor into a local plugin for customization

Problem

Today, users who want to customize a built-in extractor (e.g., tweak maven-compiler for their company's Maven plugin variant) have two options, both bad:

  1. Modify vibe-validate's source — not possible without forking the whole project.
  2. Write a plugin from scratch with vv create-extractor — the scaffold is a Hello World (a keyword-match in detect, one error per matching line in extract), so users effectively rebuild from zero. The built-in they wanted to
    customize is 300–700 lines of tuned regex, accumulated edge-case handling, and tests they're throwing away.

vibe-validate's "LLM-optimized error extraction" value prop degrades for customized toolchains: users either spend weeks rebuilding a parser or fall back to the generic extractor and feed their LLM noisy data.

Variations: forking vitest to add metadata fields from a custom reporter; forking eslint for a custom formatter; etc.

Proposed command

vv fork-extractor maven-compiler

Creates: vibe-validate-local-plugins/maven-compiler/

├── index.ts (copy of built-in source, imports rewritten)

├── index.test.ts (copy of built-in's tests, helper imports remapped)

├── samples/... (copy of built-in's samples)

├── package.json (peerDependency on @vibe-validate/extractors)

├── tsconfig.json

├── README.md

└── CLAUDE.md

User then edits index.ts, runs pnpm install && pnpm build, and vibe-validate auto-loads the fork from vibe-validate-local-plugins/. Collisions with the built-in are resolved by priority (or the user adds the built-in to
extractors.builtins.disable).

Required work

Three blockers exist today against current main. None of them is addressed by main-line PRs 1–3 (cleanup --dry-run, create-extractor papercuts, test-extractor) — those touch the CLI and git layers, not the extractor loader or public
API surface. This issue's work is independent of and additive to PRs 1–3.

  1. Loader doesn't discover directory-based plugins (packages/extractors/src/plugin-loader.ts:152). The auto-discovery loop matches .js/.mjs files in vibe-validate-local-plugins/ and silently skips directories. A forked plugin in
    vibe-validate-local-plugins/maven-compiler/dist/index.js would never load. Fix: when an entry is a directory, read /package.json, resolve the main field, load that. ~30 LOC + tests.
  2. Internal helper imports. Audit of packages/extractors/src/extractors/*/index.ts:
- 7 of 15 built-ins are forkable today with only MAX_ERRORS_IN_ARRAY re-exported from @vibe-validate/extractors/index.ts (currently not re-exported): generic, playwright, eslint, jest, junit, typescript, vitest.
- 8 of 15 require promoting internal utility modules to public API, clustered as:
    - utils/formatter-utils.js (formatCleanOutput) — used by ava, tap
  - utils/test-framework-utils.js (processTestFailures, TestFailureInfo) — used by jasmine, mocha, pytest
  - utils/parser-utils.js (extractErrorType) — used by pytest
  - utils/guidance-generator.js (generateGuidanceFromPatterns) — used by tap
  - utils/maven-extractor-utils.js (createLowConfidenceResult, createMavenResult) — used by maven-*
  - maven-utils.js (extractRelativePath) — used by maven-*

These would need API-stability review (signatures, JSDoc, semver commitment) before promotion.
3. Test-helper imports. Built-in tests use ../../test/helpers/extractor-test-helpers.js (e.g., expectDetection, expectPluginMetadata). Two options: (a) add @vibe-validate/extractors/testing subpath export and rewrite imports during
fork; (b) generate a fresh minimal test file instead of copying. Option (a) preserves the rich test coverage forks inherit.

Suggested sequencing (this issue's work)

  • Step 1: Loader supports directory-based local plugins. Self-contained, no consumer changes. (~30 LOC + tests)
  • Step 2: Re-export MAX_ERRORS_IN_ARRAY from @vibe-validate/extractors/index.ts (one line + tests).
  • Step 3: vv fork-extractor v1 — supports the 7 public-only built-ins (generic, playwright, eslint, jest, junit, typescript, vitest). Errors with a clear message when forking one of the other 8 (" uses internal helpers
    not yet exposed publicly; tracked in #N"). Includes UX for collision (priority bump or disable config guidance). (~1.5 days)
  • Step 4 (separate follow-up issue): Promote the 6 utility modules to public API (or @vibe-validate/extractors/testing subpath export for test helpers). Expand fork-extractor to support the remaining 8 built-ins.

Relationship to main-line PR 3 (test-extractor)

test-extractor is not a blocker for fork-extractor, but it is a useful complementary tool. Once main-line PR 3 ships, plugin authors who fork a built-in will be able to validate their fork works correctly via vv test-extractor
./vibe-validate-local-plugins/my-fork/. This issue's Step 3 should reference test-extractor in the post-fork "next steps" guidance the command prints.

Out of scope

  • AST-based source-transform tool that inlines internal helpers (alternative to public API promotion). Considered too complex for the value delivered.
  • --disable-builtin flag that automatically edits the user's vibe-validate.config.yaml. Manual config edit is fine for v1.

Acceptance criteria (Step 3, the v1 command)

  • vv fork-extractor vitest creates vibe-validate-local-plugins/vitest/ with all expected files.
  • The forked directory builds (pnpm install && pnpm build) without modification.
  • The forked plugin's tests pass (pnpm test).
  • vv validate in the host repo loads the forked plugin (verified via debug logging or a smoke test).
  • vv fork-extractor maven-compiler exits with a clear error explaining which internal helpers it depends on and linking to the follow-up issue.
  • Documentation updated: docs/error-extractors-guide.md or a new skill explaining when to use fork-extractor vs. create-extractor.

References

  • Original design proposal: docs/contributing/sandbox-research.md lines 335–342 and 404–407
  • Current loader: packages/extractors/src/plugin-loader.ts:138-168
  • Built-in extractor inventory: packages/extractors/src/extractors/
  • Existing create-extractor scaffold (template to model fork output on): packages/cli/src/commands/create-extractor.ts

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions