chore(beads): add 18 NOTE beads from per-note-search PRD

Break down docs/prd-per-note-search.md into granular agent-executable beads:
- Phase 0 (0A-0D): Stable note identity via upsert/sweep
- Phase 1 (1A-1E): lore notes CLI command
- Phase 2 (2A-2I): Per-note documents in FTS/embedding pipeline
Wire 20 dependency edges matching PRD dependency graph.
Close bd-2l3s (replaced by granular beads).
This commit is contained in:
teernisse
2026-02-12 11:34:10 -05:00
parent ecbfef537a
commit 02fb484eb0
3 changed files with 65 additions and 1 deletions

File diff suppressed because one or more lines are too long

View File

@@ -77,6 +77,7 @@ pub fn strip_schemas(commands: &mut serde_json::Value) {
for (_cmd_name, cmd) in map.iter_mut() {
if let Some(obj) = cmd.as_object_mut() {
obj.remove("response_schema");
obj.remove("example_output");
}
}
}

View File

@@ -2065,6 +2065,7 @@ struct RobotDocsData {
version: String,
description: String,
activation: RobotDocsActivation,
quick_start: serde_json::Value,
commands: serde_json::Value,
/// Deprecated command aliases (old -> new)
aliases: serde_json::Value,
@@ -2168,6 +2169,7 @@ fn handle_robot_docs(robot_mode: bool, brief: bool) -> Result<(), Box<dyn std::e
"meta": {"elapsed_ms": "int"}
}
},
"example_output": {"list": {"ok":true,"data":{"issues":[{"iid":3864,"title":"Switch Health Card","state":"opened","status_name":"In progress","labels":["customer:BNSF"],"assignees":["teernisse"],"discussion_count":12,"updated_at_iso":"2026-02-12T..."}],"total_count":1,"showing":1},"meta":{"elapsed_ms":42}}},
"fields_presets": {"minimal": ["iid", "title", "state", "updated_at_iso"]}
},
"mrs": {
@@ -2186,6 +2188,7 @@ fn handle_robot_docs(robot_mode: bool, brief: bool) -> Result<(), Box<dyn std::e
"meta": {"elapsed_ms": "int"}
}
},
"example_output": {"list": {"ok":true,"data":{"mrs":[{"iid":200,"title":"Add throw time chart","state":"opened","draft":false,"author_username":"teernisse","target_branch":"main","source_branch":"feat/throw-time","reviewers":["cseiber"],"discussion_count":5,"updated_at_iso":"2026-02-11T..."}],"total_count":1,"showing":1},"meta":{"elapsed_ms":38}}},
"fields_presets": {"minimal": ["iid", "title", "state", "updated_at_iso"]}
},
"search": {
@@ -2197,6 +2200,7 @@ fn handle_robot_docs(robot_mode: bool, brief: bool) -> Result<(), Box<dyn std::e
"data": {"results": "[{document_id:int, source_type:string, title:string, snippet:string, score:float, url:string?, author:string?, created_at:string?, updated_at:string?, project_path:string, labels:[string], paths:[string]}]", "total_results": "int", "query": "string", "mode": "string", "warnings": "[string]"},
"meta": {"elapsed_ms": "int"}
},
"example_output": {"ok":true,"data":{"query":"throw time","mode":"hybrid","total_results":3,"results":[{"document_id":42,"source_type":"issue","title":"Switch Health Card","score":0.92,"snippet":"...throw time data from BNSF...","project_path":"vs/typescript-code"}],"warnings":[]},"meta":{"elapsed_ms":85}},
"fields_presets": {"minimal": ["document_id", "title", "source_type", "score"]}
},
"count": {
@@ -2306,6 +2310,7 @@ fn handle_robot_docs(robot_mode: bool, brief: bool) -> Result<(), Box<dyn std::e
},
"meta": {"elapsed_ms": "int"}
},
"example_output": {"expert": {"ok":true,"data":{"mode":"expert","result":{"experts":[{"username":"teernisse","score":42,"note_count":15,"diff_note_count":8}]}},"meta":{"elapsed_ms":65}}},
"fields_presets": {
"expert_minimal": ["username", "score"],
"workload_minimal": ["entity_type", "iid", "title", "state"],
@@ -2319,7 +2324,28 @@ fn handle_robot_docs(robot_mode: bool, brief: bool) -> Result<(), Box<dyn std::e
}
});
// --brief: strip response_schema from every command (~60% smaller)
let quick_start = serde_json::json!({
"glab_equivalents": [
{ "glab": "glab issue list", "lore": "lore -J issues -n 50", "note": "Richer: includes labels, status, closing MRs, discussion counts" },
{ "glab": "glab issue view 123", "lore": "lore -J issues 123", "note": "Includes full discussions, work-item status, cross-references" },
{ "glab": "glab issue list -l bug", "lore": "lore -J issues --label bug", "note": "AND logic for multiple --label flags" },
{ "glab": "glab mr list", "lore": "lore -J mrs", "note": "Includes draft status, reviewers, discussion counts" },
{ "glab": "glab mr view 456", "lore": "lore -J mrs 456", "note": "Includes discussions, review threads, source/target branches" },
{ "glab": "glab mr list -s opened", "lore": "lore -J mrs -s opened", "note": "States: opened, merged, closed, locked, all" },
{ "glab": "glab api '/projects/:id/issues'", "lore": "lore -J issues -p project", "note": "Fuzzy project matching (suffix or substring)" }
],
"lore_exclusive": [
"search: FTS5 + vector hybrid search across all entities",
"who: Expert/workload/reviews analysis per file path or person",
"timeline: Chronological event reconstruction across entities",
"stats: Database statistics with document/note/discussion counts",
"count: Entity counts with state breakdowns",
"embed: Generate vector embeddings for semantic search via Ollama"
],
"read_write_split": "lore = ALL reads (issues, MRs, search, who, timeline, intelligence). glab = ALL writes (create, update, approve, merge, CI/CD)."
});
// --brief: strip response_schema and example_output from every command (~60% smaller)
let mut commands = commands;
if brief {
strip_schemas(&mut commands);
@@ -2422,6 +2448,7 @@ fn handle_robot_docs(robot_mode: bool, brief: bool) -> Result<(), Box<dyn std::e
env: "LORE_ROBOT=1".to_string(),
auto: "Non-TTY stdout".to_string(),
},
quick_start,
commands,
aliases,
exit_codes,