diff --git a/README.md b/README.md
index 99ee2b9..022d899 100644
--- a/README.md
+++ b/README.md
@@ -24,7 +24,7 @@ The script automatically detects your OS (Linux, macOS) and architecture (x64, a
To install a specific version or to a custom directory:
```bash
-INSTALL_DIR=~/.local/bin VERSION=v1.2.0 \
+INSTALL_DIR=~/.local/bin VERSION=v1.0.6 \
curl -fsSL https://raw.githubusercontent.com/fulll/github-code-search/main/install.sh | bash
```
@@ -150,7 +150,6 @@ GitHub Code Search: useFeatureFlag in fulll
After pressing **Enter**:
-```
3 repos · 6 files · 7 matches selected
- **fulll/auth-service** (2 matches)
@@ -164,11 +163,16 @@ After pressing **Enter**:
- [src/hooks/useFeatureFlag.ts:1:1](https://github.com/fulll/frontend-app/blob/main/src/hooks/useFeatureFlag.ts#L1)
- [src/components/Dashboard.tsx:4:3](https://github.com/fulll/frontend-app/blob/main/src/components/Dashboard.tsx#L4)
-# Replay:
+
+replay command
+
+```bash
github-code-search "useFeatureFlag" --org fulll --no-interactive \
--exclude-repositories legacy-monolith
```
+
+
## Non-interactive mode (CI)
### Why use it?
@@ -202,7 +206,6 @@ github-code-search "useFeatureFlag" --org fulll --no-interactive
$ CI=true github-code-search "useFeatureFlag" --org fulll
```
-```
3 repos · 5 matches selected
- **fulll/auth-service**
@@ -214,10 +217,15 @@ $ CI=true github-code-search "useFeatureFlag" --org fulll
- **fulll/frontend-app**
- [src/hooks/useFeatureFlag.ts:1:1](https://github.com/fulll/frontend-app/blob/main/src/hooks/useFeatureFlag.ts#L1)
-# Replay:
+
+replay command
+
+```bash
github-code-search "useFeatureFlag" --org fulll --no-interactive
```
+
+
## Exclusion options
### `--exclude-repositories`
@@ -265,7 +273,6 @@ github-code-search "useFeatureFlag" --org fulll
**2. Output + replay command:**
-```
2 repos · 3 matches selected
- **fulll/auth-service**
@@ -276,12 +283,17 @@ github-code-search "useFeatureFlag" --org fulll
- **fulll/frontend-app**
- [src/hooks/useFeatureFlag.ts:1:1](https://github.com/fulll/frontend-app/blob/main/src/hooks/useFeatureFlag.ts#L1)
-# Replay:
+
+replay command
+
+```bash
github-code-search "useFeatureFlag" --org fulll --no-interactive \
--exclude-repositories legacy-monolith \
--exclude-extracts auth-service:tests/unit/featureFlags.test.ts:0
```
+
+
**3. Replay without UI (CI, scripting, documentation):**
```bash
diff --git a/package.json b/package.json
index 5194d92..c0f2951 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "github-code-search",
- "version": "1.0.5",
+ "version": "1.1.0",
"description": "Interactive GitHub code search with per-repo aggregation",
"license": "MIT",
"author": "fulll",
diff --git a/src/render.test.ts b/src/render.test.ts
index eeaf40a..cbbc957 100644
--- a/src/render.test.ts
+++ b/src/render.test.ts
@@ -781,6 +781,20 @@ describe("renderGroups filter opts", () => {
expect(stripped).toContain("Enter confirm");
});
+ it("live-filters rows by filterInput when filterMode=true", () => {
+ // The caller (tui.ts) builds rows with filterInput as the active filter
+ // while in filterMode so the view updates as the user types.
+ const groups = [makeGroup("org/repo", ["src/a.ts", "lib/b.ts"], false)];
+ const rows = buildRows(groups, "src"); // rows already filtered by filterInput
+ const out = renderGroups(groups, 0, rows, 40, 0, "q", "org", {
+ filterMode: true,
+ filterInput: "src",
+ });
+ const stripped = out.replace(/\x1b\[[0-9;]*m/g, "");
+ expect(stripped).toContain("src/a.ts");
+ expect(stripped).not.toContain("lib/b.ts");
+ });
+
it("shows confirmed filter path with stats when filterPath is set", () => {
const groups = [makeGroup("org/repo", ["src/a.ts", "lib/b.ts"], false)];
const rows = buildRows(groups, "src");
diff --git a/src/tui.ts b/src/tui.ts
index ca03fb8..19779f5 100644
--- a/src/tui.ts
+++ b/src/tui.ts
@@ -52,7 +52,8 @@ export async function runInteractive(
let showHelp = false;
const redraw = () => {
- const rows = buildRows(groups, filterPath);
+ const activeFilter = filterMode ? filterInput : filterPath;
+ const rows = buildRows(groups, activeFilter);
const rendered = renderGroups(groups, cursor, rows, termHeight, scrollOffset, query, org, {
filterPath,
filterMode,
@@ -88,11 +89,15 @@ export async function runInteractive(
cursor = Math.min(cursor, Math.max(0, newRows.length - 1));
scrollOffset = Math.min(scrollOffset, cursor);
} else if (key === "\x7f" || key === "\b") {
- // Backspace
+ // Backspace — trim and clamp cursor to new live-filtered row list
filterInput = filterInput.slice(0, -1);
+ const newRows = buildRows(groups, filterInput);
+ cursor = Math.min(cursor, Math.max(0, newRows.length - 1));
} else if (key.length === 1 && key >= " ") {
- // Printable character
+ // Printable character — clamp cursor to new live-filtered row list
filterInput += key;
+ const newRows = buildRows(groups, filterInput);
+ cursor = Math.min(cursor, Math.max(0, newRows.length - 1));
}
redraw();
continue;