Skip to content

Commit 7129159

Browse files
feat: search normalized session archives
1 parent df534d9 commit 7129159

13 files changed

Lines changed: 603 additions & 23 deletions

File tree

PROJECT_STATUS.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,15 @@ CodeVetter is a local-first desktop workbench for checking agent-generated code.
2323
- Review Memory Graph has a repo-level and review-scoped first slice: Repo Unpacked now persists a deterministic local `repo_graph` artifact with package scripts, routes, Tauri commands, DB tables, tests, and decision markers; exports local graph JSON plus agent-context markdown sidecars for optional Graphify/Hunk-style interop without adding either dependency; imports graph JSON only through an explicit Repo Unpacked file action, validates CodeVetter or loose graph-shaped JSON, and renders imported graphs as non-mutating previews; CLI review results also carry a bounded local graph over changed files, evidence candidates, procedure gates, blast/history context, the review prompt includes that graph neighborhood, Review shows a compact graph panel plus selected-finding graph focus, copied reviewer proof includes both full graph and focused finding graph nodes/edges, and Review can copy a selected finding as a Hunk-style agent-context note with file/line, evidence status, local history, focused graph, and next verification actions.
2424
- Agent Verification Timeline has a first normalized spine: Review now builds a shared task/review/QA/evidence/claim-check/fix/worktree timeline contract, attaches bounded raw-session command anchors to evidence rows with transcript excerpts, adds a dedicated Claim check row for failed/stale command claims, explicit extracted agent claims, positive test/check claims contradicted by failed/stale command evidence, unchecked findings, unresolved post-fix QA, and fixes without same-flow reruns, attaches edit-origin anchors for fix changed files to worktree rows, renders timeline stages and anchors in the sidebar, exposes first-class jump targets for findings, files, QA artifacts, fix worktrees, command source anchors, and edited files, shows same-flow post-fix QA before/after deltas with artifact anchors on the QA row, can copy segment-scoped fix packets directly from Review/Evidence/QA/Fix/Worktree timeline rows, includes clicked-row timeline replay metadata and transcript snippets in those packets, and includes the same timeline plus source/event/artifact/jump/edit/transcript anchors in copied reviewer proof.
2525
- Codebase History Explainer has a first file-level slice: Review now builds bounded, cited "why this code exists" explanations from local commits, decision markers, recurring findings, agent notes, and command anchors, renders them in the sidebar, and includes them in copied reviewer proof.
26-
- AI Session Intelligence has a first local scorecard slice: indexed sessions produce a schema-versioned six-dimension scorecard with cited evidence refs, anti-gaming notes, recommendations, normalized Claude/Codex/Cursor adapter coverage summaries, production and scorecard adapter run metadata/parse warnings in `session_adapter_runs`, a compact `session_message_archive` for normalized adapter messages/tool calls, local backfill for previously indexed Claude/Codex sessions missing archive rows, a shared raw parser adapter contract with Claude/Codex/Cursor fixtures, Claude/Codex/Cursor production indexing wired through that contract, a Tauri IPC contract, compact Roadmap dashboard panels for scorecard and source health, visible adapter run status, per-adapter run trends, and recent-run drilldowns.
26+
- AI Session Intelligence has a first local scorecard slice: indexed sessions produce a schema-versioned six-dimension scorecard with cited evidence refs, anti-gaming notes, recommendations, normalized Claude/Codex/Cursor adapter coverage summaries, production and scorecard adapter run metadata/parse warnings in `session_adapter_runs`, a compact `session_message_archive` for normalized adapter messages/tool calls, local backfill for previously indexed Claude/Codex sessions missing archive rows, FTS-backed local archive search over messages/tool calls, manual re-index archive update events, a shared raw parser adapter contract with Claude/Codex/Cursor fixtures, Claude/Codex/Cursor production indexing wired through that contract, a Tauri IPC contract, compact Roadmap dashboard panels for scorecard and source health, visible adapter run status, per-adapter run trends, and recent-run drilldowns.
2727
- Home now opens on usage first. The Verification Workbench launcher and latest-roadmap-build banner live on the Roadmap page, so Evidence Search, Agent Timeline, Synthetic QA, Memory Graph, History Brief, AI Sessions, transcript replay, claim checks, replay packets, timeline fix packets, edit origins, and post-fix QA deltas remain visible without pushing usage down on app launch.
2828
- OSS repo-analysis engines were evaluated in `docs/oss-integration-evaluation.md`; optional `ast-grep` changed-file evidence is implemented behind PATH detection with no required runtime dependency.
2929
- Product direction has been consolidated around agent-written code verification, evidence levels, timelines, and explainable codebase history.
3030

3131
## Planned Next
3232

33-
1. Continue the AI Session Intelligence PRD in `docs/PRD-AI-SESSION-INTELLIGENCE.md`: add full-text search and live update events over the normalized session message archive; Claude, Codex, and Cursor production session rows now use the normalized raw parser adapter contract, production index passes persist adapter run metadata/parse warnings plus compact message/tool-call archive rows, local backfill repairs older Claude/Codex sessions with missing archive rows, and Roadmap shows latest source-health status with per-adapter trends and recent-run drilldowns.
34-
2. Continue the Agent Verification Timeline PRD in `docs/PRD-AGENT-VERIFICATION-TIMELINE.md`: add richer claim-vs-evidence discrepancy parsing beyond literal positive test/check claim contradictions, command/QA/evidence-count signals, and fuller multi-turn transcript replay; raw session command anchors with bounded transcript excerpts, explicit agent-claim anchors, dedicated claim-check rows, edit-origin anchors, timeline-specific jump targets, timeline-segment replay packets, same-flow post-fix QA deltas, and the Roadmap latest-build banner are now attached to visible Review/Roadmap actions and proof export.
33+
1. Continue the AI Session Intelligence PRD in `docs/PRD-AI-SESSION-INTELLIGENCE.md`: add active-session tailing events beyond manual re-index refresh; Claude, Codex, and Cursor production session rows now use the normalized raw parser adapter contract, production index passes persist adapter run metadata/parse warnings plus compact message/tool-call archive rows, local backfill repairs older Claude/Codex sessions with missing archive rows, Roadmap shows latest source-health status with per-adapter trends and recent-run drilldowns, and Roadmap can search the normalized archive locally.
34+
2. Continue the Agent Verification Timeline PRD in `docs/PRD-AGENT-VERIFICATION-TIMELINE.md`: add richer claim-vs-evidence discrepancy parsing beyond literal positive test/check claim contradictions, command/QA/evidence-count signals, and fuller multi-turn transcript replay; raw session command anchors with bounded transcript excerpts, explicit agent-claim anchors, dedicated claim-check rows, edit-origin anchors, timeline-specific jump targets, timeline-segment replay packets, same-flow post-fix QA deltas, archive search, and the Roadmap latest-build banner are now attached to visible Review/Roadmap actions and proof export.
3535
3. Continue the Codebase History Explainer PRD in `docs/PRD-CODEBASE-HISTORY-EXPLAINER.md`: turn the persisted `history_brief` slice into a queryable local history graph; Repo Unpacked history brief integration and agent-context sidecar export are now implemented.
3636
4. Curate 20-30 real public agent-generated PR benchmark cases with hand-labeled ground truth before making external catch-rate claims.
3737
5. Add benchmark fields for unverified-fix count and time/cost impact once review artifacts capture those values consistently.

apps/desktop/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@code-reviewer/desktop",
3-
"version": "1.1.45",
3+
"version": "1.1.46",
44
"private": true,
55
"scripts": {
66
"dev": "lsof -ti:1420 | xargs kill -9 2>/dev/null; vite",

apps/desktop/src-tauri/src/commands/history.rs

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,13 @@ use crate::commands::session_adapters::{
33
};
44
use crate::db::queries;
55
use crate::DbState;
6+
use serde::Serialize;
67
use serde_json::{json, Value};
78
use std::io::BufRead;
8-
use tauri::State;
9+
use std::sync::Mutex;
10+
use tauri::{AppHandle, Emitter, State};
11+
12+
static FULL_INDEX_LOCK: Mutex<()> = Mutex::new(());
913

1014
#[derive(Debug, Clone)]
1115
struct IndexedAdapterSession {
@@ -28,6 +32,15 @@ struct ProductionAdapterRunStats {
2832
supports_incremental: bool,
2933
}
3034

35+
#[derive(Debug, Clone, Serialize)]
36+
struct SessionArchiveUpdatedPayload {
37+
indexed_sessions: u64,
38+
indexed_messages: u64,
39+
skipped_sessions: u64,
40+
archive_search_rows_indexed: i64,
41+
indexed_at: String,
42+
}
43+
3144
impl ProductionAdapterRunStats {
3245
fn new(
3346
adapter_id: &str,
@@ -120,6 +133,9 @@ fn persist_production_adapter_run(
120133
/// Run the full index directly with a connection reference.
121134
/// Used by the startup background thread.
122135
pub fn run_full_index_with_conn(conn: &rusqlite::Connection) -> Result<String, String> {
136+
let _index_guard = FULL_INDEX_LOCK
137+
.lock()
138+
.map_err(|e| format!("full index lock poisoned: {e}"))?;
123139
let (indexed_sessions, indexed_messages, skipped_sessions) = full_index_impl(conn)?;
124140

125141
// Store the last indexed timestamp
@@ -132,19 +148,35 @@ pub fn run_full_index_with_conn(conn: &rusqlite::Connection) -> Result<String, S
132148
}
133149

134150
#[tauri::command]
135-
pub async fn trigger_index(db: State<'_, DbState>) -> Result<Value, String> {
151+
pub async fn trigger_index(app: AppHandle, db: State<'_, DbState>) -> Result<Value, String> {
136152
let conn = conn_lock(&db)?;
153+
let _index_guard = FULL_INDEX_LOCK
154+
.lock()
155+
.map_err(|e| format!("full index lock poisoned: {e}"))?;
137156
let (indexed_sessions, indexed_messages, skipped_sessions) =
138157
full_index_impl(&conn).map_err(|e| e.to_string())?;
158+
let archive_search_rows_indexed =
159+
queries::sync_session_message_archive_fts(&conn).map_err(|e| e.to_string())?;
139160

140161
// Store the last indexed timestamp
141162
let now = chrono::Utc::now().to_rfc3339();
142163
let _ = queries::set_preference(&conn, "last_indexed_at", &now);
164+
let payload = SessionArchiveUpdatedPayload {
165+
indexed_sessions,
166+
indexed_messages,
167+
skipped_sessions,
168+
archive_search_rows_indexed,
169+
indexed_at: now.clone(),
170+
};
171+
if let Err(error) = app.emit("session_archive_updated", payload) {
172+
log::warn!("Failed to emit session_archive_updated: {error}");
173+
}
143174

144175
Ok(json!({
145176
"indexed_sessions": indexed_sessions,
146177
"indexed_messages": indexed_messages,
147178
"skipped_sessions": skipped_sessions,
179+
"archive_search_rows_indexed": archive_search_rows_indexed,
148180
"projects_scanned": 0,
149181
}))
150182
}

apps/desktop/src-tauri/src/commands/sessions.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,28 @@ pub async fn list_session_message_archive(
3737
Ok(json!({ "messages": messages }))
3838
}
3939

40+
/// Full-text search over the compact normalized adapter message/tool archive.
41+
#[tauri::command]
42+
pub async fn search_session_message_archive(
43+
db: State<'_, DbState>,
44+
query: String,
45+
adapter_id: Option<String>,
46+
kind: Option<String>,
47+
limit: Option<i64>,
48+
) -> Result<Value, String> {
49+
let conn = db.0.lock().map_err(|e| e.to_string())?;
50+
queries::sync_session_message_archive_fts(&conn).map_err(|e| e.to_string())?;
51+
let results = queries::search_session_message_archive(
52+
&conn,
53+
&query,
54+
adapter_id.as_deref(),
55+
kind.as_deref(),
56+
limit.unwrap_or(50),
57+
)
58+
.map_err(|e| e.to_string())?;
59+
Ok(json!({ "results": results }))
60+
}
61+
4062
/// Move all sessions from one or more source projects into a target project.
4163
/// Updates session counts on both source and target projects.
4264
#[tauri::command]

0 commit comments

Comments
 (0)