-
Notifications
You must be signed in to change notification settings - Fork 0
Session-start code-intelligence indexing offer for large repos (v1.62.0.0) #23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
46f1590
578af24
4f646a5
410b317
4c2bfdd
7915a8a
4c62edd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -7,6 +7,43 @@ | |||||||||||||||||||||||||||||
| > completion state and remaining P0 gates. No version bump or release claim is | ||||||||||||||||||||||||||||||
| > made here while that status holds. | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| ## [1.62.0.0] - 2026-07-23 | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| ## **Open a large repo and gstack offers to index it.** | ||||||||||||||||||||||||||||||
| ## **Once, with real choices, then never again.** | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| Every gstack skill now checks the size of the repository it lands in before starting real work. Small repo, nothing happens, grep is already fast. Large repo (1,000+ tracked files) and you have never answered the question, the skill pauses once and asks whether you want code-intelligence indexing, with the actual trade-offs spelled out: GBrain gives semantic "where is X handled?" search but sends repo content to your GBrain database and asks consent per repo. Sourcebot gives fast whole-repo search, self-hosted, local when it runs on localhost. Graphify builds a local tree-sitter code graph and nothing ever leaves your machine, but you install it yourself. Or say no indexing, and gstack remembers that too. Decline once and no skill asks again, on any repo, until you change your mind with `gstack-code-intelligence select`. | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| ### The numbers that matter | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| Source: `bun run scripts/gstack2/run-parity.ts` and `bun test test/code-intelligence.test.ts` on this release. | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| | Metric | Before | After | | ||||||||||||||||||||||||||||||
| |---|---|---| | ||||||||||||||||||||||||||||||
| | Skills that surface the indexing option | 0 | all 6 dispatchers | | ||||||||||||||||||||||||||||||
| | Times the question is asked per machine | n/a | at most 1 | | ||||||||||||||||||||||||||||||
| | Large-repo threshold | n/a | 1,000 tracked files | | ||||||||||||||||||||||||||||||
| | Parity checks pinning the behavior | 5,032 | 5,050 | | ||||||||||||||||||||||||||||||
| | code-intelligence tests | 25 | 31 | | ||||||||||||||||||||||||||||||
|
Comment on lines
+21
to
+27
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P3: The release metrics omit the required Prompt for AI agents
Suggested change
|
||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| The "at most 1" row is the one that matters. The offer gate (`gstack-code-intelligence suggest`) refuses to fire when a provider is already selected, when you declined before, when the repo is small, or when the directory is not a git repo. A missing helper is a silent skip, not an error. | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| ### What this means for builders | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| On a 10-file toy, nothing changes. On your 5,000-file production monolith, the first `/plan` or `/review` run offers you semantic search over the whole codebase, you pick a provider (or none) in one question, and every later session benefits without ever being asked again. Grep and the file-only decision store remain the always-working default; indexing is an upgrade, never a dependency. | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| ### Itemized changes | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| #### Added | ||||||||||||||||||||||||||||||
| - Session-start indexing offer: every dispatcher reads the new generated `references/CODE-INTELLIGENCE.md` once per repository invocation and runs `gstack-code-intelligence suggest` to decide whether to ask. The question presents GBrain (recommended, consent-gated), Sourcebot, Graphify (local, never auto-installed), and No indexing, each with its reason and live availability. | ||||||||||||||||||||||||||||||
| - `gstack-code-intelligence suggest [path] [--json]`: the offer gate as a command. Emits offer/no-offer with the reason (`provider-selected`, `declined`, `not-a-repo`, `small-repo`, `large-repo`) and, when offering, the provider options. | ||||||||||||||||||||||||||||||
| - `gstack-code-intelligence select none` now persists the decline so the question is never repeated. | ||||||||||||||||||||||||||||||
| - The `gstack-code-intelligence` helper ships in the managed runtime, so standard installs can run the offer from `$GSTACK_HOME/bin`. | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| #### For contributors | ||||||||||||||||||||||||||||||
| - New `lib/code-intelligence/suggest.ts` (`shouldOfferIndexing`, `trackedFileCount`, threshold injectable for tests) and a `declined` flag in the selection store; 6 new tests in `test/code-intelligence.test.ts`. | ||||||||||||||||||||||||||||||
| - Parity pins the per-tree contract (existence, dispatcher wiring, silent-degrade, decline, no-auto-install), 3 checks per dispatcher. Runtime helper surface: `DEFAULT_RUNTIME_HELPERS` + `RUNTIME_HELPER_DEPENDENCIES` in `runtime/install.js`. | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| ## [1.61.2.0] - 2026-07-23 | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| ## **The founder-resources pitch now takes no for an answer.** | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +1 @@ | ||
| 1.61.2.0 | ||
| 1.62.0.0 |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,55 @@ | ||
| /** | ||
| * suggest — should the session-start indexing offer be made for this repo? | ||
| * | ||
| * The offer fires at most once per machine: never when a provider is already | ||
| * selected, never after an explicit decline (`select none`), and never for | ||
| * small repos where grep is already fast. Detection is cheap and local | ||
| * (`git ls-files` count); a non-repo directory never triggers the offer. | ||
| */ | ||
|
|
||
| import { spawnSync } from "child_process"; | ||
| import { resolve } from "path"; | ||
| import { readSelection } from "./selection"; | ||
|
|
||
| // ponytail: single tracked-file-count knob for "large"; add a LOC signal if it misfires | ||
| /** Tracked-file count at which indexing starts paying for itself. */ | ||
| export const LARGE_REPO_FILE_THRESHOLD = 1000; | ||
|
|
||
| export type SuggestReason = | ||
| | "provider-selected" | ||
| | "declined" | ||
| | "not-a-repo" | ||
| | "small-repo" | ||
| | "large-repo"; | ||
|
|
||
| export interface Suggestion { | ||
| offer: boolean; | ||
| reason: SuggestReason; | ||
| fileCount: number | null; | ||
| threshold: number; | ||
| } | ||
|
|
||
| /** Count of git-tracked files, or null when the path is not a git repo. */ | ||
| export function trackedFileCount(repoPath: string): number | null { | ||
| const result = spawnSync("git", ["-C", resolve(repoPath), "ls-files"], { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P1: Invoking a skill from a nested directory can suppress the indexing offer because Prompt for AI agents |
||
| encoding: "utf-8", | ||
| maxBuffer: 64 * 1024 * 1024, | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P2: Repositories whose tracked-path output exceeds 64 MiB are silently classified as Prompt for AI agents |
||
| }); | ||
| if (result.status !== 0 || typeof result.stdout !== "string") return null; | ||
| const out = result.stdout.trim(); | ||
| return out ? out.split("\n").length : 0; | ||
| } | ||
|
|
||
| export function shouldOfferIndexing( | ||
| repoPath: string, | ||
| opts: { env?: NodeJS.ProcessEnv; threshold?: number } = {}, | ||
| ): Suggestion { | ||
| const threshold = opts.threshold ?? LARGE_REPO_FILE_THRESHOLD; | ||
| const selection = readSelection(opts.env); | ||
| if (selection.provider) return { offer: false, reason: "provider-selected", fileCount: null, threshold }; | ||
| if (selection.declined) return { offer: false, reason: "declined", fileCount: null, threshold }; | ||
| const fileCount = trackedFileCount(repoPath); | ||
| if (fileCount === null) return { offer: false, reason: "not-a-repo", fileCount, threshold }; | ||
| if (fileCount < threshold) return { offer: false, reason: "small-repo", fileCount, threshold }; | ||
| return { offer: true, reason: "large-repo", fileCount, threshold }; | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -98,6 +98,7 @@ export const DEFAULT_RUNTIME_HELPERS = Object.freeze({ | |
| "gstack-brain-cache": helper("bin/gstack-brain-cache"), | ||
| "gstack-brain-sync": helper("bin/gstack-brain-sync"), | ||
| "gstack-builder-profile": helper("bin/gstack-builder-profile"), | ||
| "gstack-code-intelligence": helper("bin/gstack-code-intelligence"), | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P3: The new stable helper is installed but remains absent from the audited runtime-helper closure, so parity cannot verify its source path or consumers. Consider extending Prompt for AI agents |
||
| "gstack-codex-probe": helper("bin/gstack-codex-probe"), | ||
| "gstack-config": helper("bin/gstack-config"), | ||
| "gstack-decision-log": helper("bin/gstack-decision-log"), | ||
|
|
@@ -156,6 +157,7 @@ const RUNTIME_HELPER_DEPENDENCIES = Object.freeze([ | |
| "VERSION", | ||
| "package.json", | ||
| "lib/bin-context.ts", | ||
| "lib/code-intelligence", | ||
| "lib/conductor-env-shim.ts", | ||
| "lib/gbrain-exec.ts", | ||
| "lib/gbrain-guards.ts", | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P3: The user-facing release entry exposes internal parity/eval and runtime implementation details in the summary and itemized sections. Replacing these with observable indexing behavior would keep the changelog within its documented audience and content rules.
Prompt for AI agents