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.
Files changed (2) hide show
  1. package/lib/server.js +60 -11
  2. 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 to strip screenshot data and add has_screenshot flag
886
- const annotationsWithScreenshotFlag = paginatedResults.map(annotation => {
887
- const { screenshot, ...annotationWithoutScreenshot } = annotation;
888
- return {
889
- ...annotationWithoutScreenshot,
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: annotationsWithScreenshotFlag,
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, add flag (same as readAnnotations)
954
- const cleaned = pending.map(({ screenshot, ...rest }) => ({
955
- ...rest,
956
- has_screenshot: !!(screenshot && screenshot.data_url)
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
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vibe-annotations-server",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Global MCP server for Vibe Annotations browser extension",
5
5
  "main": "lib/server.js",
6
6
  "type": "module",