Skip to content

SDK: export a public item→ContextRelevanceCandidate signal builder so extensions can reproduce pm next ranking #558

Closed

Description

@unbraind

Summary

The public SDK (@unbrained/pm-cli/sdk) exports the scorer — scoreContextCandidatesWithActiveExtensions('next' | 'context', candidates), defaultScoreContextCandidates, and the ContextRelevanceCandidate / ContextRelevanceSignals types — but it does not export the helper that derives those signals from a pm item. That helper, buildItemContextRelevanceCandidates(items, statusRegistry, now, author), lives in CLI internals (dist/cli/commands/context.js) and is only reachable via a deep, non-public import path.

As a result, an extension that wants to rank items the same way pm next does cannot call the scorer with correct inputs — it would have to reverse-engineer the recency / activity_density / graph_proximity / claim_focus / priority_pressure / risk_pressure / deadline_pressure / knowledge_density / author_affinity signal derivation, which is undocumented and will silently drift whenever the CLI's derivation changes.

Why it matters (agent context management)

project management = context management. Multiple published extensions surface a "what's next" ranking (e.g. pm-brief's brief next). Without a shared signal builder, each one either:

  1. reimplements its own scorer → diverges from pm next, so an agent gets two contradictory "top item" answers from two built-in commands (this exact bug: pm-brief brief next disagreed with pm next), or
  2. shells out to pm next --json as a subprocess just to borrow the ranking — the workaround I had to ship in pm-brief. That's an extra process per invocation and only works when a real workspace is on disk.

Repro

import { scoreContextCandidatesWithActiveExtensions } from "@unbrained/pm-cli/sdk";
// I have PmItem[] and want the same ranking as `pm next`.
// ...but there is no public way to turn PmItem[] into ContextRelevanceCandidate[]
// with the same signals the CLI uses. buildItemContextRelevanceCandidates is not exported.

Proposed fix

Re-export from @unbrained/pm-cli/sdk a stable, documented helper, e.g.:

export function deriveContextRelevanceCandidates(
  items: readonly ItemFrontMatter[],
  options?: { statusRegistry?: RuntimeStatusRegistry; now?: string; author?: string },
): ContextRelevanceCandidate<ItemFrontMatter>[];

so deriveContextRelevanceCandidates(items) + scoreContextCandidatesWithActiveExtensions('next', candidates) reproduces pm next in-process, identically, with no subprocess and no drift.

Environment

  • SDK/CLI: 2026.7.13 / 2026.7.14
  • Public exports checked in dist/sdk/context-relevance.d.ts and dist/sdk/index.d.ts; builder found only in dist/cli/commands/context.d.ts.

Filed from the pm-cli companion hub while fixing pm-brief brief next convergence.

Activity

  1. coderabbitai commented on Jul 14, 2026

    @coderabbitai
    🔗 Related PRs

    #466 - Expose SDK read primitives and auto PM context hint [merged]
    #487 - feat(sdk): adaptive context relevance and evaluation gates [merged]
    #502 - Atomic agent work selection, dependency integrity, and recovery primitives [merged]
    #517 - Add ranked atomic agent work selection primitives [merged]
    #525 - perf(cli, sdk): indexed reads, cursor bounds, and local scale benchmarks [merged]


    📝 Issue Planner

    Check the box below or use the @coderabbitai plan command to generate an implementation plan and prompts that you can use with your favorite coding assistant.

    • Create Plan

    🧪 Issue enrichment is currently in open beta.

    You can configure auto-planning by selecting labels in the issue_enrichment configuration.

    To disable automatic issue enrichment, add the following to your .coderabbit.yaml:

    issue_enrichment:
      auto_enrich:
        enabled: false

    💬 Have feedback or questions? Drop into our discord!

  2. unbraind commented on Jul 14, 2026

    @unbraind
    OwnerAuthor

    pm tracker item: pm-qyc6

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

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions