Skip to content

Commit 0844e3c

Browse files
committed
Address adversarial suggestion review (#5061)
1 parent 009d557 commit 0844e3c

4 files changed

Lines changed: 90 additions & 1 deletion

File tree

changelog.d/unreleased/5061.added.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ affected:
1111
- tests/CodeIndex.Tests/ProgramCliTests.cs
1212
- tests/CodeIndex.Tests/CliFlagSchemaTests.cs
1313
- tests/CodeIndex.Tests/ConsoleUiTests.cs
14+
- tests/CodeIndex.Tests/JsonOutputSnapshotTests.cs
15+
- tests/CodeIndex.Tests/golden/suggestions-compact.json
1416
- USER_GUIDE.md
1517
- DEVELOPER_GUIDE.md
1618
- TESTING_GUIDE.md

src/CodeIndex/Cli/SuggestionsCommandRunner.cs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -928,7 +928,19 @@ private static bool MatchesAgent(SuggestionRecord record, string agent)
928928
private static string FormatTitle(string description, int maxLength)
929929
{
930930
var firstLine = description.Replace('\r', ' ').Replace('\n', ' ').Trim();
931-
return firstLine.Length <= maxLength ? firstLine : firstLine[..(maxLength - 1)] + "...";
931+
if (firstLine.Length <= maxLength)
932+
return firstLine;
933+
934+
var end = maxLength - 1;
935+
if (end > 0
936+
&& end < firstLine.Length
937+
&& char.IsHighSurrogate(firstLine[end - 1])
938+
&& char.IsLowSurrogate(firstLine[end]))
939+
{
940+
end--;
941+
}
942+
943+
return firstLine[..end] + "...";
932944
}
933945

934946
private static SuggestionListItemJsonResult ToListItem(SuggestionRecord record) => new(

tests/CodeIndex.Tests/JsonOutputSnapshotTests.cs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
using System.Text.Json;
22
using System.Text.Json.Nodes;
3+
using System.Text.Json.Serialization.Metadata;
34
using CodeIndex.Cli;
45
using CodeIndex.Database;
6+
using CodeIndex.Models;
57

68
namespace CodeIndex.Tests;
79

@@ -22,6 +24,7 @@ public class JsonOutputSnapshotTests
2224
private readonly JsonSerializerOptions _jsonOptions = new()
2325
{
2426
PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower,
27+
TypeInfoResolver = new DefaultJsonTypeInfoResolver(),
2528
};
2629

2730
private const string LibSource = @"namespace Demo;
@@ -233,6 +236,52 @@ public void RunExcerpt_JsonOutput_MatchesGolden()
233236
}
234237
}
235238

239+
[Fact]
240+
public void RunSuggestionsCompact_JsonOutput_MatchesGolden_Issue5061()
241+
{
242+
var projectRoot = TestProjectHelper.CreateTempProject("cdidx_snapshot_suggestions_compact");
243+
try
244+
{
245+
var cdidxDir = Path.Combine(projectRoot, ".cdidx");
246+
Directory.CreateDirectory(cdidxDir);
247+
var dbPath = Path.Combine(cdidxDir, "codeindex.db");
248+
var titlePrefix = new string('a', 118);
249+
var store = new SuggestionStore(cdidxDir);
250+
Assert.True(store.TryAdd(new SuggestionRecord
251+
{
252+
Id = new string('1', 64),
253+
Category = "output_format",
254+
Language = "csharp",
255+
Description = "Snapshot query description",
256+
SampledTitle = titlePrefix + "😀suffix",
257+
EvidencePaths = ["src/Snapshot.cs"],
258+
CreatedAt = new DateTime(2026, 8, 11, 0, 0, 0, DateTimeKind.Utc),
259+
}));
260+
261+
var (exitCode, stdout, stderr) = CaptureConsole(() => SuggestionsCommandRunner.Run(
262+
["list", "--db", dbPath, "--query", "snapshot query", "--compact"],
263+
_jsonOptions));
264+
265+
Assert.Equal(CommandExitCodes.Success, exitCode);
266+
Assert.Equal(string.Empty, stderr);
267+
using var document = JsonDocument.Parse(stdout);
268+
var item = Assert.Single(document.RootElement.GetProperty("results").EnumerateArray());
269+
var compactTitle = item.GetProperty("title").GetString()
270+
?? throw new InvalidOperationException("Compact suggestion title was null.");
271+
Assert.Equal(titlePrefix + "...", compactTitle);
272+
Assert.DoesNotContain('\uFFFD', compactTitle);
273+
274+
JsonOutputSnapshotHelper.AssertMatches(
275+
"suggestions-compact.json",
276+
stdout,
277+
BuildPathReplacements(projectRoot));
278+
}
279+
finally
280+
{
281+
TestProjectHelper.DeleteDirectory(projectRoot);
282+
}
283+
}
284+
236285
private static void MarkGraphAndFoldReady(string dbPath)
237286
{
238287
using var db = new DbContext(DbOpenIntent.WriteIndex, dbPath);
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"api_version": "1",
3+
"mode": "compact",
4+
"query": "snapshot query",
5+
"total_count": 1,
6+
"total_count_authoritative": true,
7+
"returned_count": 1,
8+
"offset": 0,
9+
"omitted_count": 0,
10+
"pagination_omitted_count": 0,
11+
"byte_limit_omitted_count": 0,
12+
"projection_omitted_count": 0,
13+
"truncated": false,
14+
"has_more": false,
15+
"next_offset": null,
16+
"results": [
17+
{
18+
"id": "1111111111111111111111111111111111111111111111111111111111111111",
19+
"title": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa...",
20+
"status": "draft",
21+
"evidence_paths": [
22+
"src/Snapshot.cs"
23+
]
24+
}
25+
]
26+
}

0 commit comments

Comments
 (0)