From e8b529da31ced9a1fe37990d0cfe522041fc0d57 Mon Sep 17 00:00:00 2001 From: Juha Litola Date: Tue, 5 May 2026 15:07:50 +0300 Subject: [PATCH] chore: prepare 0.4.0 release Bump release metadata and keep terminal freshness warnings visible for floating-target search results. --- .claude-plugin/marketplace.json | 2 +- .claude-plugin/plugin.json | 2 +- .plugin/plugin.json | 2 +- docs/implementation/cli-commands.md | 2 +- gemini-extension.json | 2 +- package.json | 2 +- plugins/claude/.claude-plugin/plugin.json | 2 +- src/commands/search.test.ts | 43 +++++++++++++++++++++++ src/commands/search.ts | 8 +++-- 9 files changed, 56 insertions(+), 9 deletions(-) diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index a5ddfd87..d92065af 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -6,7 +6,7 @@ }, "metadata": { "description": "GitHits plugins for Claude Code - code examples from global open source", - "version": "0.3.3" + "version": "0.4.0" }, "plugins": [ { diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json index 1017bd0f..c982151c 100644 --- a/.claude-plugin/plugin.json +++ b/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "githits", - "version": "0.3.3", + "version": "0.4.0", "description": "Code examples from global open source for developers and AI assistants", "author": { "name": "GitHits" diff --git a/.plugin/plugin.json b/.plugin/plugin.json index 1017bd0f..c982151c 100644 --- a/.plugin/plugin.json +++ b/.plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "githits", - "version": "0.3.3", + "version": "0.4.0", "description": "Code examples from global open source for developers and AI assistants", "author": { "name": "GitHits" diff --git a/docs/implementation/cli-commands.md b/docs/implementation/cli-commands.md index 5b537d75..de6ec913 100644 --- a/docs/implementation/cli-commands.md +++ b/docs/implementation/cli-commands.md @@ -80,7 +80,7 @@ The original unified-search plan envisaged hiding partial mode entirely in v1 to **Highlighting.** The CLI applies the backend's structured `highlights` spans on titles and summaries, plus structural emphasis on headers and badges. It does **not** attempt client-side substring highlighting for terms the backend did not flag, since the compiled query is not a faithful match spec. -**Source-status surfacing.** The JSON `sourceStatus` block is always passed through verbatim for debugging. Human-readable output surfaces only the actionable subset: ignored / incompatible filters, ignored / incompatible query features, free-form `note`s, and an `INDEXING` indicator when a source is still indexing on a partial-result payload. `STALE` (served from a slightly old index while a fresh reindex runs) is intentionally not shown in human output — agents and users do not need to second-guess otherwise-correct results, but it remains in JSON for diagnostics. +**Trust signals.** The JSON `sourceStatus` block is always passed through verbatim for debugging. Human-readable output surfaces the actionable subset: ignored / incompatible filters, ignored / incompatible query features, free-form `note`s, an `INDEXING` indicator when a source is still indexing on a partial-result payload, and promoted freshness warnings when a floating target was served from stale evidence while a fresher index is building. Non-divergent `CURRENT` / `STALE` metadata stays JSON-only because it does not change how a user should interpret the displayed results. ### `githits search-status` diff --git a/gemini-extension.json b/gemini-extension.json index 27ba2e85..38ff3f65 100644 --- a/gemini-extension.json +++ b/gemini-extension.json @@ -1,6 +1,6 @@ { "name": "githits", - "version": "0.3.3", + "version": "0.4.0", "description": "Code examples from global open source for developers and AI assistants.", "mcpServers": { "githits": { diff --git a/package.json b/package.json index 3374277c..39562f07 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "githits", "description": "CLI companion for GitHits - code examples from global open source for developers and AI assistants", - "version": "0.3.3", + "version": "0.4.0", "type": "module", "files": [ "dist", diff --git a/plugins/claude/.claude-plugin/plugin.json b/plugins/claude/.claude-plugin/plugin.json index 1017bd0f..c982151c 100644 --- a/plugins/claude/.claude-plugin/plugin.json +++ b/plugins/claude/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "githits", - "version": "0.3.3", + "version": "0.4.0", "description": "Code examples from global open source for developers and AI assistants", "author": { "name": "GitHits" diff --git a/src/commands/search.test.ts b/src/commands/search.test.ts index dad4119c..dec6b945 100644 --- a/src/commands/search.test.ts +++ b/src/commands/search.test.ts @@ -358,6 +358,49 @@ describe("searchAction", () => { consoleSpy.mockRestore(); }); + it("prints promoted freshness warnings in terminal output", async () => { + const consoleSpy = spyOn(console, "log").mockImplementation(() => {}); + + if (defaultUnifiedSearchOutcome.state !== "completed") { + throw new Error("expected completed outcome fixture"); + } + + const outcomeWithStaleFreshness: UnifiedSearchOutcome = { + ...defaultUnifiedSearchOutcome, + result: { + ...defaultUnifiedSearchOutcome.result, + results: defaultUnifiedSearchOutcome.result.results.map( + (entry, index) => + index === 0 + ? { + ...entry, + requestedTargetLabel: "npm:express latest", + freshTargetLabel: "npm:express@5.2.1", + servedTargetLabel: "npm:express@5.1.0", + freshness: "STALE", + } + : entry, + ), + }, + }; + + await searchAction( + "router middleware", + { in: ["npm:express"] }, + createDeps({ + codeNavigationService: createMockCodeNavigationService({ + search: mock(() => Promise.resolve(outcomeWithStaleFreshness)), + }), + }), + ); + + const output = String(consoleSpy.mock.calls[0]?.[0]); + expect(output).toContain( + "Warning: requested npm:express latest; served stale npm:express@5.1.0 while npm:express@5.2.1 indexes.", + ); + consoleSpy.mockRestore(); + }); + it("renders backend summaries verbatim in terminal output", async () => { const consoleSpy = spyOn(console, "log").mockImplementation(() => {}); diff --git a/src/commands/search.ts b/src/commands/search.ts index d486eaee..dce91af1 100644 --- a/src/commands/search.ts +++ b/src/commands/search.ts @@ -405,13 +405,15 @@ function formatUnifiedSearchTerminal(payload: { searchRef?: string; progress?: { targetsReady?: number; targetsTotal?: number }; query: { raw?: string; warnings?: string[] }; + warnings?: string[]; sourceStatus?: SourceStatusEntry[]; }): string { const lines: string[] = []; const useColors = shouldUseColors(); - if (payload.query.warnings && payload.query.warnings.length > 0) { - for (const warning of payload.query.warnings) { + const warnings = payload.warnings ?? payload.query.warnings; + if (warnings && warnings.length > 0) { + for (const warning of warnings) { lines.push(`Warning: ${warning}`); } lines.push(""); @@ -560,6 +562,7 @@ function formatSearchStatusCompletedTerminal(payload: { raw: payload.result.query?.raw, warnings: payload.result.warnings, }, + warnings: payload.result.warnings, sourceStatus: payload.result.sourceStatus, }); } @@ -580,6 +583,7 @@ function formatSearchStatusPartialTerminal( raw: payload.result.query?.raw, warnings: payload.result.warnings, }, + warnings: payload.result.warnings, sourceStatus: payload.result.sourceStatus, }); }