Files
gstack/lib/code-intelligence/picker.ts
T
SinabinaandClaude Opus 4.8 b4421a4e69 docs: design the repo-oriented code-intelligence provider contract
Design for the OPTIONAL code-intelligence provider contract that lets a
user pick how their codebase is indexed and searched, replacing gstack's
~17k LOC of bespoke GBrain glue. Repo-oriented ops (register_source/
refresh/search/status required; add/delete/export optional), a per-provider
capability matrix, GBrain-recommended-first selection, repo-scoped + install
consent, and a phased rollout that keeps gstack fully functional with no
provider selected. All three providers are driven from the runtime via CLI
or HTTP — no MCP client.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-21 17:16:53 -07:00

44 lines
2.0 KiB
TypeScript

/**
* Picker — recommends a code-intelligence provider, GBrain first.
*
* RECOMMENDED_ORDER is the static "GBrain first" fact the options UX and phase-2
* resolution filter against. In phase 1 only GBrain is drivable from the runtime
* (it has a CLI the runtime can spawn); Sourcebot and Graphify are MCP tools in
* the host session and become resolvable in phase 2 once a host transport is
* wired. So recommendCodeProvider returns GBrain-or-nothing today, and
* resolveCodeProvider degrades to null — the provider-OFF path — when GBrain is
* unavailable. Callers then use grep / the file-only decision store.
*
* GBrain availability uses the real detector, localEngineStatus() ("ok"/"timeout"
* are usable). Graphify is NEVER auto-installed or auto-offered.
*/
import { localEngineStatus, type LocalEngineStatus } from "../gbrain-local-status";
import { GbrainProvider } from "./gbrain-adapter";
import type { CodeProvider, CodeProviderId } from "./contract";
/** Recommendation order — GBrain first. Sourcebot/Graphify join in phase 2. */
export const RECOMMENDED_ORDER: readonly CodeProviderId[] = ["gbrain", "sourcebot", "graphify"];
export interface PickerOptions {
env?: NodeJS.ProcessEnv;
/** Inject GBrain status for tests; otherwise probed via localEngineStatus(). */
gbrainStatus?: LocalEngineStatus;
}
const GBRAIN_USABLE: ReadonlySet<LocalEngineStatus> = new Set(["ok", "timeout"]);
/** Drivable providers, in recommendation order (GBrain first). */
export function recommendCodeProvider(opts: PickerOptions = {}): CodeProvider[] {
const status = opts.gbrainStatus ?? localEngineStatus({ env: opts.env });
return GBRAIN_USABLE.has(status) ? [new GbrainProvider()] : [];
}
/**
* The single recommended provider, or null when none is drivable. Null is the
* provider-OFF path: callers MUST degrade to grep / file-only, never fail.
*/
export function resolveCodeProvider(opts: PickerOptions = {}): CodeProvider | null {
return recommendCodeProvider(opts)[0] ?? null;
}