Skip to content

Commit 8057a17

Browse files
authored
Merge pull request #7 from mallaire77/pgf-446-file-search-extension
feat(extensions): add file search retrieval extension (PGF-446)
2 parents 727f87e + 1ad735f commit 8057a17

File tree

11 files changed

+1261
-0
lines changed

11 files changed

+1261
-0
lines changed

README-badal.md

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
# Badal Gemini CLI Notes
2+
3+
This document explains the long-lived Badal-specific shape of the
4+
`badal-io/gemini-cli` fork. It is meant to capture fork-level operational and
5+
development context, not ticket-specific work.
6+
7+
## What This Repo Is
8+
9+
- This repository is a fork of `google-gemini/gemini-cli`.
10+
- Badal uses the fork in `badal-io/gemini-cli`.
11+
- The `badal` branch is the effective Badal baseline branch.
12+
13+
Important: a lot of upstream identity still remains in the codebase.
14+
15+
- Package names are still largely `@google/*`.
16+
- The root `package.json` repository URL still points at the upstream Google
17+
repository.
18+
- The root `README.md` and many GitHub workflows still describe the upstream
19+
project rather than Badal's operational use.
20+
21+
## How Badal Uses This Fork
22+
23+
Badal does not use this repo only as a local CLI. This fork is also used as the
24+
runtime for containerized agent sessions launched by Backstage.
25+
26+
The high-level Badal-specific shape is:
27+
28+
- a custom runtime image defined in `deploy/cloudrun/Dockerfile`
29+
- a Badal-managed image build workflow in `.github/workflows/cloudrun-image.yml`
30+
- bundled extensions installed into the runtime image
31+
- extra operational tooling added to the container for agent use
32+
- integration with Backstage, which is responsible for launching sessions and
33+
injecting runtime configuration
34+
35+
## Runtime Image
36+
37+
The custom runtime image is built from `deploy/cloudrun/Dockerfile`.
38+
39+
At a high level it:
40+
41+
- builds and packs the Gemini CLI monorepo packages
42+
- installs the packed CLI artifacts globally in the runtime container
43+
- installs operational tools used by agent sessions such as `gh`, `gcloud`,
44+
`terraform`, `vault`, `bun`, and `bd`
45+
- installs extensions under `/root/.gemini/extensions`
46+
- copies in Badal-managed Gemini settings and the container entrypoint
47+
48+
Known note:
49+
50+
- the `hookwise` / `captain-hook` extension is intentionally disabled in the
51+
Dockerfile because of build issues
52+
53+
## Extensions
54+
55+
Gemini CLI already supports extensions natively. The extension docs live under
56+
`docs/extensions/`.
57+
58+
For Badal, extensions matter because they are part of the deployed agent
59+
runtime, not just a user-side convenience feature.
60+
61+
General extension-related locations to know:
62+
63+
- `docs/extensions/`
64+
- `packages/`
65+
- `deploy/cloudrun/Dockerfile`
66+
67+
When working on extensions in this fork, verify both:
68+
69+
- the extension package itself
70+
- whether the runtime image is bundling it correctly
71+
72+
## Workflows
73+
74+
Current workflow reality:
75+
76+
- the repository still contains a large inherited set of upstream Google
77+
workflows
78+
- only some workflows reflect Badal-specific operational needs
79+
- `.github/workflows/cloudrun-image.yml` is the clearest Badal-specific workflow
80+
today
81+
82+
### `cloudrun-image.yml`
83+
84+
Purpose:
85+
86+
- build and publish the `gemini-a2a` runtime image to GHCR
87+
88+
Behavior to verify when editing it:
89+
90+
- which branches trigger builds
91+
- which pull request targets trigger builds
92+
- which paths are included in the workflow filters
93+
- how the image name and tags are computed
94+
95+
## Code Areas That Matter Most For Badal
96+
97+
If you need to understand or modify the Badal flavor, start here:
98+
99+
- `deploy/cloudrun/Dockerfile`
100+
- `.github/workflows/cloudrun-image.yml`
101+
- `docs/extensions/`
102+
- `packages/`
103+
104+
If the work involves agent launch behavior, credentials, or session wiring, the
105+
other repo to read is `repo-devex-backstage`, especially the Gemini agent
106+
backend that injects runtime configuration into this container.
107+
108+
## Testing Notes
109+
110+
Useful baseline commands in this repo:
111+
112+
```bash
113+
npm ci
114+
npm run build
115+
npm test
116+
```
117+
118+
When making Badal-specific changes, also verify the behavior that matters for
119+
the deployment path you touched, for example:
120+
121+
- image build behavior if you changed `deploy/cloudrun/Dockerfile`
122+
- workflow behavior if you changed `.github/workflows/`
123+
- extension packaging if you changed extension-related code
124+
125+
## Practical Takeaways
126+
127+
- Treat this repo as "upstream Gemini CLI plus Badal deployment/runtime
128+
customizations".
129+
- Do not assume upstream docs, README badges, workflow names, or repository URLs
130+
reflect Badal's actual usage.
131+
- For agent-runtime work, the Dockerfile, workflows, and extension packaging are
132+
more important than the upstream marketing/docs surface.

deploy/cloudrun/Dockerfile

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,12 @@ RUN mkdir -p /root/.gemini/extensions
116116
# ai-plugin-translator extension
117117
COPY --from=translator-builder /build /root/.gemini/extensions/ai-plugin-translator
118118

119+
# File Search extension
120+
COPY packages/file-search-extension /root/.gemini/extensions/file-search-extension
121+
RUN cd /root/.gemini/extensions/file-search-extension && \
122+
npm install --omit=dev && \
123+
npm cache clean --force
124+
119125
# TODO: hookwise extension disabled (see comment at top of file)
120126
# COPY --from=hookwise-builder /build/target/release/hookwise /root/.gemini/extensions/captain-hook/captain-hook
121127
# COPY --from=hookwise-builder /build/.claude-plugin /root/.gemini/extensions/captain-hook/.claude-plugin

package-lock.json

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# File Search Retrieval
2+
3+
This extension gives you repository-scoped retrieval against Gemini File Search.
4+
5+
Use it when:
6+
- you need context that is not present in the current workspace checkout
7+
- you need to inspect indexed files without broad local scanning
8+
- you suspect the current answer is missing adjacent files, callers, callees, or partial definitions
9+
10+
Retrieval strategy:
11+
- Search first and fetch narrowly second.
12+
- Prefer `search_store` to locate likely files or concepts before calling a more specific fetch tool.
13+
- Use `fetch_file_context` when you already know the file path you want.
14+
- Use `fetch_symbol_context` when the task is centered on a declaration, type, function, or symbol name.
15+
- Use `expand_related_context` when the first retrieval shows the context is partial or points to neighboring files.
16+
17+
When to do follow-up retrieval:
18+
- the retrieved answer says context is incomplete
19+
- a symbol is referenced but not defined
20+
- a file references callers, imports, or implementation details in another file
21+
- the user asks for behavior that likely spans multiple files
22+
23+
Bound retrieval:
24+
- do not fan out across many files at once
25+
- follow the recommended next steps from the previous retrieval
26+
- stop once the extension reports that the current context is sufficient
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"name": "file-search-extension",
3+
"version": "0.1.0",
4+
"contextFileName": "GEMINI.md",
5+
"mcpServers": {
6+
"fileSearch": {
7+
"command": "node",
8+
"args": ["${extensionPath}${/}src${/}server.js"],
9+
"cwd": "${extensionPath}"
10+
}
11+
}
12+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"hooks": {
3+
"BeforeAgent": [
4+
{
5+
"hooks": [
6+
{
7+
"type": "command",
8+
"command": "node ${extensionPath}/scripts/before-agent.js"
9+
}
10+
]
11+
}
12+
]
13+
}
14+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"name": "@badal/file-search-extension",
3+
"version": "0.1.0",
4+
"description": "Gemini CLI extension for repository-scoped Gemini File Search retrieval",
5+
"private": true,
6+
"type": "module",
7+
"main": "src/server.js",
8+
"scripts": {
9+
"test": "vitest run"
10+
},
11+
"dependencies": {
12+
"@modelcontextprotocol/sdk": "^1.23.0",
13+
"zod": "^3.23.8"
14+
}
15+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/**
2+
* @license
3+
* Copyright 2026 Badal
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
const storeName = process.env.FILE_SEARCH_STORE_NAME;
8+
const repo = process.env.FILE_SEARCH_REPO;
9+
const sourceRepository = process.env.FILE_SEARCH_SOURCE_REPOSITORY;
10+
const authMode = process.env.FILE_SEARCH_AUTH_MODE || 'unconfigured';
11+
12+
const lines = [];
13+
if (storeName) {
14+
lines.push(`File Search store: ${storeName}`);
15+
}
16+
if (repo) {
17+
lines.push(`File Search repo tag: ${repo}`);
18+
}
19+
if (sourceRepository) {
20+
lines.push(`Source repository: ${sourceRepository}`);
21+
}
22+
lines.push(`File Search auth mode: ${authMode}`);
23+
lines.push(
24+
'Use File Search tools when local context is missing, partial, or points to neighboring files.',
25+
);
26+
lines.push('Search first, then fetch narrowly, then expand only if needed.');
27+
28+
console.log(
29+
JSON.stringify({
30+
hookSpecificOutput: {
31+
hookEventName: 'BeforeAgent',
32+
additionalContext: lines.join('\n'),
33+
},
34+
}),
35+
);

0 commit comments

Comments
 (0)