Skip to content

Internal analyzer contract: replace hardcoded runner registry with typed analyzers #28

Description

@serge-ivo

Summary

Formalize the current CLI runner shape into an internal Analyzer contract and registry. This is Phase 1 from app/docs/analyzer-platform-vision.md: keep current VibeReport output compatible, but stop adding framework checks as ad hoc entries in core.ts.

Implementation spec: cli/docs/internal-analyzer-contract.md.

Why

cli/src/core.ts currently owns a long hardcoded runner array. That makes every new stack/framework touch the same file and encourages mixed generic/framework behavior. The analyzer platform roadmap calls for one app + CLI engine + internal analyzers before any public plugin SDK.

Terminology

This issue creates internal analyzers, not public plugins.

  • Analyzer: built-in/internal capability scheduled by the CLI engine.
  • Framework analyzer: analyzer whose result depends on framework semantics.
  • Out-of-process analyzer: analyzer launched by the CLI over JSON/stdio; tracked separately in Internal out-of-process analyzer protocol over stdio JSON #32.
  • Plugin SDK: future third-party surface; explicitly out of scope here.

Proposed contract sketch

See cli/docs/internal-analyzer-contract.md for the fuller contract. The Phase 1 shape is intentionally compatible with existing CheckResult / VibeReport output.

interface AnalyzerManifest {
  id: string;
  name: string;
  kind: "generic" | "framework" | "ecosystem" | "integration" | "pro";
  resultSchemaVersion: number;
  appliesTo?: AppliesTo;
  settingsSchema?: AnalyzerSettingsSchema;
  metricDefinitions?: AnalyzerMetricDefinition[];
}

interface Analyzer {
  manifest: AnalyzerManifest;
  detect?(ctx: AnalyzerContext): AnalyzerDetection | Promise<AnalyzerDetection>;
  run(ctx: AnalyzerContext): CheckResult | Promise<CheckResult>;
}

interface AnalyzerContext {
  cwd: string;
  workspace: WorkspaceInfo;
  stack: StackInfo;
  config: VcqaConfig;
  settings: Record<string, unknown>;
  effectiveSettings: Record<string, unknown>;
  skipTests: boolean;
  srcRoots?: string[];
  ignoreNames: string[];
}

Phase 1 can wrap existing runners with analyzer objects. It does not need to solve out-of-process execution; that is #32.

Tasks

  • Add internal analyzer types under cli/src/analyzers/ or equivalent.
  • Create an analyzer registry module that exports ordered analyzers.
  • Convert the core.ts hardcoded runner list to consume the registry.
  • Preserve existing check order, --checks filtering, appliesTo gating, tool provenance, ignore filtering, and score behavior.
  • Keep CheckResult/VibeReport output unchanged for consumers.
  • Add tests proving the registry covers existing check metadata and respects --checks filtering.
  • Document that the contract is internal/experimental until several built-in analyzers prove it.

Acceptance criteria

  • core.ts no longer contains the full hardcoded runner registry.
  • Adding a built-in analyzer requires registering one analyzer object, not editing scan orchestration logic.
  • Existing CLI tests and fixture scans pass with unchanged report shape.
  • No public plugin SDK is exposed from this issue.

Related

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    analyzer-platformAnalyzer engine, registry, contracts, and normalized resultsenhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions