vibe-annotations-server 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/server.js +60 -11
- package/package.json +1 -1
package/lib/server.js
CHANGED
|
@@ -882,23 +882,69 @@ class LocalAnnotationsServer {
|
|
|
882
882
|
has_more: (offset + limit) < total
|
|
883
883
|
};
|
|
884
884
|
|
|
885
|
-
// Transform annotations
|
|
886
|
-
const
|
|
887
|
-
const { screenshot, ...
|
|
888
|
-
|
|
889
|
-
...
|
|
885
|
+
// Transform annotations for MCP consumers: strip screenshots, styles, and noise
|
|
886
|
+
const optimized = paginatedResults.map(annotation => {
|
|
887
|
+
const { screenshot, ...rest } = annotation;
|
|
888
|
+
const optimized = {
|
|
889
|
+
...rest,
|
|
890
890
|
has_screenshot: !!(screenshot && screenshot.data_url)
|
|
891
891
|
};
|
|
892
|
+
return this.optimizeForAgent(optimized);
|
|
892
893
|
});
|
|
893
894
|
|
|
894
895
|
return {
|
|
895
|
-
annotations:
|
|
896
|
+
annotations: optimized,
|
|
896
897
|
pagination: pagination,
|
|
897
898
|
projectInfo: projectInfo,
|
|
898
899
|
multiProjectWarning: multiProjectWarning
|
|
899
900
|
};
|
|
900
901
|
}
|
|
901
902
|
|
|
903
|
+
/**
|
|
904
|
+
* Optimize annotation for AI agent consumption:
|
|
905
|
+
* - Strip element_context.styles (computed values, not in source code)
|
|
906
|
+
* - Strip internal extension fields (_synced, badge_offset)
|
|
907
|
+
* - Strip null/empty fields to reduce token noise
|
|
908
|
+
*/
|
|
909
|
+
optimizeForAgent(annotation) {
|
|
910
|
+
const { _synced, badge_offset, context_hints, ...clean } = annotation;
|
|
911
|
+
|
|
912
|
+
// Strip computed styles — agents use classes/path/selector_preview to find elements,
|
|
913
|
+
// and pending_changes for design deltas. Computed styles are never useful.
|
|
914
|
+
if (clean.element_context) {
|
|
915
|
+
const { styles, ...ecWithoutStyles } = clean.element_context;
|
|
916
|
+
clean.element_context = ecWithoutStyles;
|
|
917
|
+
|
|
918
|
+
// Strip null values from element_context
|
|
919
|
+
for (const key of Object.keys(clean.element_context)) {
|
|
920
|
+
if (clean.element_context[key] == null) delete clean.element_context[key];
|
|
921
|
+
}
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
// Strip null values from parent_chain entries
|
|
925
|
+
if (Array.isArray(clean.parent_chain)) {
|
|
926
|
+
clean.parent_chain = clean.parent_chain.map(node => {
|
|
927
|
+
const cleaned = {};
|
|
928
|
+
for (const [key, value] of Object.entries(node)) {
|
|
929
|
+
if (value != null) cleaned[key] = value;
|
|
930
|
+
}
|
|
931
|
+
return cleaned;
|
|
932
|
+
});
|
|
933
|
+
}
|
|
934
|
+
|
|
935
|
+
// Strip null/empty fields that add no information
|
|
936
|
+
// Preserve: comment (empty string is intentional), has_screenshot (false is informative)
|
|
937
|
+
const keepFields = new Set(['comment', 'has_screenshot', 'status', 'id', 'url', 'created_at', 'updated_at']);
|
|
938
|
+
for (const [key, value] of Object.entries(clean)) {
|
|
939
|
+
if (keepFields.has(key)) continue;
|
|
940
|
+
if (value == null || value === false || (Array.isArray(value) && value.length === 0)) {
|
|
941
|
+
delete clean[key];
|
|
942
|
+
}
|
|
943
|
+
}
|
|
944
|
+
|
|
945
|
+
return clean;
|
|
946
|
+
}
|
|
947
|
+
|
|
902
948
|
async watchAnnotations(args) {
|
|
903
949
|
const { url, timeout = 300 } = args;
|
|
904
950
|
if (!url) throw new Error('url parameter is required');
|
|
@@ -950,11 +996,14 @@ class LocalAnnotationsServer {
|
|
|
950
996
|
if (w) { w.polling = false; w.lastSeenAt = Date.now(); }
|
|
951
997
|
console.log(`Watcher ${watcherId}: found ${pending.length} annotations`);
|
|
952
998
|
|
|
953
|
-
// Strip screenshots,
|
|
954
|
-
const cleaned = pending.map(({ screenshot, ...rest }) =>
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
999
|
+
// Strip screenshots, styles, and noise (same as readAnnotations)
|
|
1000
|
+
const cleaned = pending.map(({ screenshot, ...rest }) => {
|
|
1001
|
+
const annotation = {
|
|
1002
|
+
...rest,
|
|
1003
|
+
has_screenshot: !!(screenshot && screenshot.data_url)
|
|
1004
|
+
};
|
|
1005
|
+
return this.optimizeForAgent(annotation);
|
|
1006
|
+
});
|
|
958
1007
|
|
|
959
1008
|
return { annotations: cleaned, message: `Found ${cleaned.length} pending annotations` };
|
|
960
1009
|
}
|