Forge
csharp72c0d4fb
1using System.Text;
2using Microsoft.Data.Sqlite;
3
4namespace HybridCodebaseIndex.Core;
5
6internal static partial class SqliteFtsIndex
7{
8 internal static Task<DocDraftResponse> DraftDocAsync(
9 string workspaceRoot,
10 string dbPath,
11 string title,
12 IReadOnlyList<string> changedPaths,
13 CancellationToken cancellationToken)
14 => Task.Run(() => DraftDoc(workspaceRoot, dbPath, title, changedPaths), cancellationToken);
15
16 private static DocDraftResponse DraftDoc(
17 string workspaceRoot,
18 string dbPath,
19 string title,
20 IReadOnlyList<string> changedPaths)
21 {
22 workspaceRoot = Path.GetFullPath(workspaceRoot.TrimEnd(Path.DirectorySeparatorChar));
23 if (!File.Exists(dbPath))
24 return new DocDraftResponse(FormatVersion, dbPath, title, "", "Index database not found; run codebase_index_reindex.");
25
26 if (changedPaths.Count == 0)
27 return new DocDraftResponse(FormatVersion, dbPath, title, "", "changed_paths is empty.");
28
29 using var conn = new SqliteConnection($"Data Source={dbPath};Mode=ReadOnly");
30 conn.Open();
31
32 var sb = new StringBuilder(capacity: 4096);
33 sb.AppendLine($"# {title}");
34 sb.AppendLine();
35 sb.AppendLine("## Summary");
36 sb.AppendLine("- TODO");
37 sb.AppendLine();
38 sb.AppendLine("## Motivation");
39 sb.AppendLine("- TODO");
40 sb.AppendLine();
41 sb.AppendLine("## Changes");
42 sb.AppendLine();
43
44 foreach (var raw in changedPaths.Take(200))
45 {
46 var p = raw.Trim().Replace("\\", "/", StringComparison.Ordinal).TrimStart('/');
47 if (p.Length == 0)
48 continue;
49
50 sb.AppendLine($"### `{p}`");
51
52 using var cmd = conn.CreateCommand();
53 cmd.CommandText = """
54 SELECT rowid, extension, line_start, line_end, substr(body, 1, 900)
55 FROM chunks
56 WHERE path = $p
57 ORDER BY line_start ASC
58 LIMIT 1;
59 """;
60 cmd.Parameters.AddWithValue("$p", p);
61
62 using var r = cmd.ExecuteReader();
63 if (!r.Read())
64 {
65 sb.AppendLine("- (no indexed content found for this path)");
66 sb.AppendLine();
67 continue;
68 }
69
70 var ext = r.IsDBNull(1) ? "" : r.GetString(1);
71 var ls = r.IsDBNull(2) ? 0 : r.GetInt32(2);
72 var le = r.IsDBNull(3) ? 0 : r.GetInt32(3);
73 var excerpt = r.IsDBNull(4) ? "" : r.GetString(4);
74
75 sb.AppendLine($"- extension: `{ext}`");
76 sb.AppendLine($"- lines: {ls}..{le}");
77 sb.AppendLine();
78 sb.AppendLine("```");
79 sb.AppendLine(excerpt.TrimEnd());
80 sb.AppendLine("```");
81 sb.AppendLine();
82 }
83
84 sb.AppendLine("## Notes / Follow-ups");
85 sb.AppendLine("- TODO");
86 sb.AppendLine();
87
88 return new DocDraftResponse(FormatVersion, dbPath, title, sb.ToString(), null);
89 }
90}
91
92
View only · write via MCP/CIDE