fix(artifacts): prioritize PDF deliverables in sidebar

This commit is contained in:
Haitao Pan 2026-06-28 10:55:29 +08:00
parent 5360d0d427
commit 39ba3d0772
2 changed files with 67 additions and 0 deletions

View File

@ -270,6 +270,20 @@ class DesktopThreadArtifactService {
} }
} }
entries.sort((a, b) { entries.sort((a, b) {
final deliveryCompare = artifactDisplayPriorityInternal(
a.relativePath,
).compareTo(artifactDisplayPriorityInternal(b.relativePath));
if (deliveryCompare != 0) {
return deliveryCompare;
}
if (fileExtensionInternal(a.relativePath) == 'pdf') {
final depthCompare = artifactPathDepthInternal(
a.relativePath,
).compareTo(artifactPathDepthInternal(b.relativePath));
if (depthCompare != 0) {
return depthCompare;
}
}
final updatedCompare = (b.updatedAtMs ?? 0).compareTo(a.updatedAtMs ?? 0); final updatedCompare = (b.updatedAtMs ?? 0).compareTo(a.updatedAtMs ?? 0);
if (updatedCompare != 0) { if (updatedCompare != 0) {
return updatedCompare; return updatedCompare;
@ -279,6 +293,16 @@ class DesktopThreadArtifactService {
return entries; return entries;
} }
static int artifactDisplayPriorityInternal(String relativePath) {
return fileExtensionInternal(relativePath) == 'pdf' ? 0 : 1;
}
static int artifactPathDepthInternal(String relativePath) {
return normalizeArtifactPathInternal(
relativePath,
).split('/').where((segment) => segment.isNotEmpty).length;
}
Future<List<AssistantArtifactEntry>> buildResultEntriesInternal({ Future<List<AssistantArtifactEntry>> buildResultEntriesInternal({
required List<AssistantArtifactChangeEntry> changes, required List<AssistantArtifactChangeEntry> changes,
required List<AssistantArtifactEntry> fileEntries, required List<AssistantArtifactEntry> fileEntries,

View File

@ -65,6 +65,49 @@ void main() {
}, },
); );
test(
'loadSnapshot shows the root PDF deliverable before supporting files',
() async {
final workspace = await Directory.systemTemp.createTemp(
'xworkmate-pdf-artifact-order-',
);
addTearDown(() async {
if (await workspace.exists()) {
await workspace.delete(recursive: true);
}
});
await Directory(
'${workspace.path}/assets/diagrams',
).create(recursive: true);
await File(
'${workspace.path}/assets/diagrams/chapter.png',
).writeAsBytes(<int>[1, 2, 3]);
await File(
'${workspace.path}/assets/安全架构演进白皮书.pdf',
).writeAsBytes(<int>[4, 5, 6]);
await File(
'${workspace.path}/安全架构演进白皮书.pdf',
).writeAsBytes(<int>[4, 5, 6]);
final snapshot = await DesktopThreadArtifactService().loadSnapshot(
workspacePath: workspace.path,
workspaceKind: WorkspaceRefKind.localPath,
artifactRelativePaths: const <String>[
'assets/diagrams/chapter.png',
'assets/安全架构演进白皮书.pdf',
'安全架构演进白皮书.pdf',
],
);
expect(snapshot.fileEntries.map((entry) => entry.relativePath), <String>[
'安全架构演进白皮书.pdf',
'assets/安全架构演进白皮书.pdf',
'assets/diagrams/chapter.png',
]);
expect(snapshot.resultEntries.first.mimeType, 'application/pdf');
},
);
test( test(
'loadPreview rejects historical files outside current task artifacts', 'loadPreview rejects historical files outside current task artifacts',
() async { () async {