Skip to content

Extension API: add semantic review presentation and provider progress #612

Description

@codybrouwers

I’ve been prototyping a semantic-review extension that analyzes a changeset and reorganizes it into a behavior-first review. The prototype highlighted a few places where the extension API can describe the analysis, but not the complete review presentation.

The existing registerReviewPlanProvider approach feels like the right foundation: extensions return a declarative plan, while Hunk retains control of diff rendering, navigation, comments, and canonical file identities.

The current plan can express:

  • Ordered semantic sections.
  • Section headings and explanations.
  • Canonical file and line-range targets.
  • Target-specific callouts.
  • primary, supporting, and mechanical importance.

The main limitation is that importance currently also determines presentation. In the prototype, "mechanical" has to mean all of the following:

  • Group these changes near the end of the review.
  • Show their files and aggregate stats.
  • Minimize their diff bodies.
  • Exclude them from normal hunk navigation.
  • Allow the user to recover them through View → Full diff.

I think importance and presentation should be separate concepts. A possible API could look like:

{
  heading: "Other changes",
  summary: "Necessary plumbing, generated output, and routine test updates.",
  importance: "low",
  presentation: {
    kind: "minimized-files",
    defaultCollapsed: true,
  },
  targets: [
    { fileId: "...", newRange: [1, 40] },
  ],
}

This would support cases such as:

  • Important changes that should initially be collapsed.
  • Mechanical changes that should remain expanded.
  • A final minimized “Other changes” section.
  • Future presentation styles without adding more meanings to importance.

The extension should still only describe its intent. Hunk should own the implementation of minimized rows, deterministic geometry, viewport behavior, canonical identity, hunk navigation, and restoration of the complete diff.

The other gap is progress reporting. Review providers may call an agent and take several seconds or minutes. During initial startup this currently looks like Hunk has hung, especially when running in a remote terminal.

It would be useful for the provider context to expose progress and cancellation:

hunk.registerReviewPlanProvider(async (changeset, ctx) => {
  ctx.progress.report("Analyzing the changeset…");

  const plan = await generateReview(changeset, {
    signal: ctx.signal,
    onProgress(message) {
      ctx.progress.report(message);
    },
  });

  return plan;
});

Hunk could show a generic loading indicator whenever a provider is pending, with provider messages replacing it when available. An AbortSignal would also let providers stop external agent work if the review is reloaded or the session exits.

Longer-term, it may also be useful to register review providers with metadata:

hunk.registerReviewPlanProvider({
  id: "semantic-review",
  label: "Semantic review",
  priority: 100,
  provide: async (changeset, ctx) => {
    // ...
  },
});

That would leave room for multiple review modes instead of relying permanently on the first provider returning a plan.

My suggested scope for the next version of the API would be:

  1. Separate section importance from its presentation.
  2. Add a first-class minimized-files presentation.
  3. Add provider progress reporting and cancellation.
  4. Keep rendering, navigation, canonical identity, and Full diff recovery inside Hunk core.

This keeps extensions declarative and relatively safe while giving them enough control to create workflows that feel meaningfully different from the normal diff view.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions