@weavetab/skills 2.5.0 → 2.5.2

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 (63) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +108 -108
  3. package/ROUTER.md +43 -43
  4. package/bin/cli.js +232 -232
  5. package/browser/dom-strategy.md +121 -119
  6. package/browser/form-automation.md +84 -87
  7. package/browser/interaction-pipeline.md +242 -216
  8. package/browser/tab-and-window.md +136 -136
  9. package/desktop/desktop-targeting.md +85 -85
  10. package/desktop/electron-discovery.md +115 -115
  11. package/developer/github-forensics.md +89 -74
  12. package/dist/bundled/weavetab-all.md +1885 -1709
  13. package/dist/bundled/weavetab-browser.md +526 -501
  14. package/dist/bundled/weavetab-desktop.md +176 -176
  15. package/dist/bundled/weavetab-developer.md +84 -67
  16. package/dist/bundled/weavetab-documents.md +184 -142
  17. package/dist/bundled/weavetab-memory.md +259 -233
  18. package/dist/bundled/weavetab-network-and-perf.md +250 -223
  19. package/dist/bundled/weavetab-plugins.md +88 -83
  20. package/dist/bundled/weavetab-resilience.md +244 -216
  21. package/dist/bundled/weavetab-security.md +93 -87
  22. package/dist/granular/browser_dom-strategy.md +121 -119
  23. package/dist/granular/browser_form-automation.md +84 -87
  24. package/dist/granular/browser_interaction-pipeline.md +242 -216
  25. package/dist/granular/browser_tab-and-window.md +136 -136
  26. package/dist/granular/desktop_desktop-targeting.md +85 -85
  27. package/dist/granular/desktop_electron-discovery.md +115 -115
  28. package/dist/granular/developer_github-forensics.md +89 -74
  29. package/dist/granular/documents_canvas-and-visual-capture.md +117 -103
  30. package/dist/granular/documents_office-document-ingestion.md +91 -63
  31. package/dist/granular/memory_selector-memory-system.md +127 -127
  32. package/dist/granular/memory_session-trail.md +111 -95
  33. package/dist/granular/memory_site-learning.md +62 -53
  34. package/dist/granular/network-and-perf_device-and-environment.md +100 -87
  35. package/dist/granular/network-and-perf_network-intercept-and-mock.md +97 -84
  36. package/dist/granular/network-and-perf_performance-and-vitals.md +86 -84
  37. package/dist/granular/plugins_hooks-and-overrides.md +40 -35
  38. package/dist/granular/plugins_plugin-runtime.md +63 -63
  39. package/dist/granular/resilience_loop-breaker.md +72 -67
  40. package/dist/granular/resilience_session-time-travel.md +146 -131
  41. package/dist/granular/resilience_stale-ref-recovery.md +61 -53
  42. package/dist/granular/security_rbac-and-policies.md +50 -47
  43. package/dist/granular/security_secret-containment-protocol.md +62 -59
  44. package/documents/canvas-and-visual-capture.md +117 -103
  45. package/documents/office-document-ingestion.md +91 -63
  46. package/evals/evaluator.js +146 -146
  47. package/evals/scenarios.json +239 -239
  48. package/memory/selector-memory-system.md +127 -127
  49. package/memory/session-trail.md +111 -95
  50. package/memory/site-learning.md +61 -52
  51. package/network-and-perf/device-and-environment.md +100 -87
  52. package/network-and-perf/network-intercept-and-mock.md +97 -84
  53. package/network-and-perf/performance-and-vitals.md +86 -84
  54. package/package.json +74 -73
  55. package/plugins/hooks-and-overrides.md +40 -35
  56. package/plugins/plugin-runtime.md +63 -63
  57. package/resilience/loop-breaker.md +72 -67
  58. package/resilience/session-time-travel.md +146 -131
  59. package/resilience/stale-ref-recovery.md +61 -53
  60. package/security/rbac-and-policies.md +50 -47
  61. package/security/secret-containment-protocol.md +62 -59
  62. package/skills.json +425 -426
  63. package/src/api.js +239 -239
@@ -1,103 +1,117 @@
1
- ---
2
- id: canvas-and-visual-capture
3
- domain: documents
4
- triggers:
5
- - "take screenshot"
6
- - "capture viewport"
7
- - "export pdf"
8
- - "canvas inspection"
9
- - "extract design tokens"
10
- tools:
11
- - "browser_screenshot"
12
- - "browser_viewport"
13
- - "browser_canvas"
14
- - "browser_pdf"
15
- - "browser_extract_design"
16
- - "browser_map"
17
- - "browser_click"
18
- weavetab: ">=2.5.0"
19
- ---
20
-
21
- # Visual Capture, Canvas Forensics & Design Extraction
22
-
23
- Beyond textual DOM manipulation, modern web applications contain dynamic HTML5 canvas renderings (charts, maps, WebGL games), and agents often need high-fidelity visual artifacts.
24
-
25
- ---
26
-
27
- ## 1. Targeted Screenshots (`browser_screenshot`)
28
-
29
- Capture full page layouts, the visible viewport, or specific element bounding boxes:
30
-
31
- ```json
32
- {
33
- "fullPage": true,
34
- "format": "png"
35
- }
36
- ```
37
-
38
- Or target a specific element ref:
39
- ```json
40
- {
41
- "ref": "w:55",
42
- "format": "jpeg",
43
- "quality": 80
44
- }
45
- ```
46
-
47
- ---
48
-
49
- ## 2. PDF Document Generation (`browser_pdf`)
50
-
51
- Render the current page into a print-ready PDF document with print CSS styles applied:
52
-
53
- ```json
54
- {
55
- "landscape": false,
56
- "printBackground": true,
57
- "paperWidth": 8.5,
58
- "paperHeight": 11
59
- }
60
- ```
61
-
62
- ---
63
-
64
- ## 3. HTML5 Canvas Pixel Inspection & Visual Grounding (`browser_canvas` & `browser_map`)
65
-
66
- When a chart or graphic is rendered via `<canvas>`, standard DOM reading tools cannot see individual buttons or nodes. You have two strategies:
67
-
68
- ### A. Set-of-Marks Visual Grounding (Recommended for Canvas UIs & WebGL)
69
- Run `browser_map({ visual: "auto" })`. It detects canvas elements and high-contrast regions, attaches numbered badges `[1]…[N]`, and returns an annotated image:
70
- ```json
71
- {
72
- "visual": "auto"
73
- }
74
- ```
75
- Then interact directly by mark number without guessing pixel coordinates:
76
- ```json
77
- {
78
- "mark": 3
79
- }
80
- ```
81
-
82
- ### B. Direct Canvas Pixel Export (`browser_canvas`)
83
- To extract the raw image data or draw programmatic gesture paths:
84
- ```json
85
- {
86
- "ref": "w:19",
87
- "action": "toDataURL"
88
- }
89
- ```
90
-
91
- ---
92
-
93
- ## 4. Design System Extraction (`browser_extract_design`)
94
-
95
- Reverse-engineer UI stylesheets, active CSS custom properties (variables), typography scales, and color palettes:
96
-
97
- ```json
98
- {
99
- "selector": ".antigravity-hud-panel"
100
- }
101
- ```
102
-
103
- Returns structured JSON representing colors, font families, shadows, and spacing tokens.
1
+ ---
2
+ id: canvas-and-visual-capture
3
+ domain: documents
4
+ triggers:
5
+ - "take screenshot"
6
+ - "capture viewport"
7
+ - "export pdf"
8
+ - "canvas inspection"
9
+ - "extract design tokens"
10
+ tools:
11
+ - "browser_screenshot"
12
+ - "browser_viewport"
13
+ - "browser_canvas"
14
+ - "browser_pdf"
15
+ - "browser_extract_design"
16
+ - "browser_map"
17
+ - "browser_click"
18
+ weavetab: ">=2.5.0"
19
+ ---
20
+
21
+ # Visual Capture, Canvas Forensics & Design Extraction
22
+
23
+ Beyond textual DOM manipulation, modern web applications contain dynamic HTML5 canvas renderings (charts, maps, WebGL games), and agents often need high-fidelity visual artifacts.
24
+
25
+ ---
26
+
27
+ ## 1. Targeted Screenshots (`browser_screenshot`)
28
+
29
+ Capture full page layouts, the visible viewport, or specific element bounding boxes:
30
+
31
+ ```json
32
+ {
33
+ "fullPage": true,
34
+ "format": "png"
35
+ }
36
+ ```
37
+
38
+ Or crop to a specific element by CSS selector, or to a pixel rectangle with `clip`:
39
+ ```json
40
+ {
41
+ "selector": "#pricing-table",
42
+ "format": "jpeg",
43
+ "quality": 80
44
+ }
45
+ ```
46
+
47
+ Options: `format` (`png` default, or `jpeg`), `quality` (JPEG only), `fullPage`, `selector`, and `clip` (`{x, y, width, height}`).
48
+
49
+ ---
50
+
51
+ ## 2. PDF Document Generation (`browser_pdf`)
52
+
53
+ Render the current page into a print-ready PDF file:
54
+
55
+ ```json
56
+ {
57
+ "filename": "report.pdf",
58
+ "landscape": false,
59
+ "scale": 1.0,
60
+ "pageRanges": "1-5",
61
+ "margin": { "top": 0.4, "bottom": 0.4, "left": 0.4, "right": 0.4 }
62
+ }
63
+ ```
64
+
65
+ Options: `filename` (defaults to `capture_<timestamp>.pdf`), `landscape`, `scale` (default 1.0), `pageRanges` (e.g. `"1-5"`, empty for all), and `margin` — either a single number in inches or a `{top,bottom,left,right}` object (default 0.4).
66
+
67
+ ---
68
+
69
+ ## 3. HTML5 Canvas Pixel Inspection & Visual Grounding (`browser_canvas` & `browser_map`)
70
+
71
+ When a chart or graphic is rendered via `<canvas>`, standard DOM reading tools cannot see individual buttons or nodes. You have two strategies:
72
+
73
+ ### A. Set-of-Marks Visual Grounding (Recommended for Canvas UIs & WebGL)
74
+ Run `browser_map({ visual: "auto" })`. It detects canvas elements and high-contrast regions, attaches numbered badges `[1]…[N]`, and returns an annotated image:
75
+ ```json
76
+ {
77
+ "visual": "auto"
78
+ }
79
+ ```
80
+ Then interact directly by mark number without guessing pixel coordinates:
81
+ ```json
82
+ {
83
+ "mark": 3
84
+ }
85
+ ```
86
+
87
+ ### B. Direct Canvas Pixel Export (`browser_canvas`)
88
+ To export the raw canvas as an image, or simulate a drag/gesture path across it:
89
+ ```json
90
+ {
91
+ "ref": "w:19",
92
+ "action": "get_image"
93
+ }
94
+ ```
95
+
96
+ For drawing or selecting a region, pass `"action": "draw"` with a `points` array of `{x, y}` positions (relative to the canvas):
97
+ ```json
98
+ {
99
+ "action": "draw",
100
+ "selector": "canvas#chart",
101
+ "points": [ { "x": 40, "y": 10 }, { "x": 200, "y": 120 } ]
102
+ }
103
+ ```
104
+
105
+ ---
106
+
107
+ ## 4. Design System Extraction (`browser_extract_design`)
108
+
109
+ Reverse-engineer UI stylesheets, active CSS custom properties (variables), typography scales, and color palettes:
110
+
111
+ ```json
112
+ {
113
+ "selector": ".antigravity-hud-panel"
114
+ }
115
+ ```
116
+
117
+ Returns structured JSON representing colors, font families, shadows, and spacing tokens.
@@ -1,63 +1,91 @@
1
- ---
2
- id: office-document-ingestion
3
- domain: documents
4
- triggers:
5
- - "read excel"
6
- - "read docx"
7
- - "parse csv"
8
- - "spreadsheet"
9
- - "word document"
10
- - "parse table"
11
- tools:
12
- - "browser_office"
13
- weavetab: ">=2.5.0"
14
- ---
15
-
16
- # Office Document Ingestion: Word, Excel & CSV Parsing
17
-
18
- Agents frequently need to parse structured spreadsheets or corporate documents downloaded during automation runs. `browser_office` parses `.docx`, `.xlsx`, `.xls`, and `.csv` files directly into clean JSON structures.
19
-
20
- ---
21
-
22
- ## 1. Parsing Spreadsheets (`.xlsx`, `.csv`)
23
-
24
- Stream structured sheet data, headers, and cell values:
25
-
26
- ```json
27
- {
28
- "filePath": "C:/Users/fy2ne/Downloads/quarterly_revenue.xlsx",
29
- "sheet": "Q3_Summary",
30
- "headerRow": 1,
31
- "maxRows": 100
32
- }
33
- ```
34
-
35
- ### Response Example:
36
- ```json
37
- {
38
- "fileType": "xlsx",
39
- "sheets": ["Q1", "Q2", "Q3_Summary"],
40
- "rowCount": 45,
41
- "data": [
42
- { "Department": "Engineering", "Budget": 1250000, "Actual": 1180000 },
43
- { "Department": "Marketing", "Budget": 600000, "Actual": 620000 }
44
- ]
45
- }
46
- ```
47
-
48
- ---
49
-
50
- ## 2. Ingesting Word Documents (`.docx`)
51
-
52
- Extract semantic paragraphs, document headings, tables, and lists:
53
-
54
- ```json
55
- {
56
- "filePath": "C:/Users/fy2ne/Documents/service_agreement.docx",
57
- "extractTables": true
58
- }
59
- ```
60
-
61
- ### Operational Advantages:
62
- - Eliminates the need for heavy external Python libraries or microservices.
63
- - Safely sanitizes binary formats before passing content into LLM context.
1
+ ---
2
+ id: office-document-ingestion
3
+ domain: documents
4
+ triggers:
5
+ - "read excel"
6
+ - "read docx"
7
+ - "parse csv"
8
+ - "spreadsheet"
9
+ - "word document"
10
+ - "parse table"
11
+ tools:
12
+ - "browser_office"
13
+ weavetab: ">=2.5.0"
14
+ ---
15
+
16
+ # Office Document Ingestion: Word, Excel, PDF & CSV Parsing
17
+
18
+ Agents frequently need to parse structured spreadsheets or corporate documents downloaded during automation runs. `browser_office` reads `.xlsx`, `.xls`, `.docx`, `.pdf`, and `.csv` content directly into JSON.
19
+
20
+ ---
21
+
22
+ ## 1. Two Modes: `url` and `file`
23
+
24
+ `browser_office({ action: "read" })` accepts exactly one source:
25
+
26
+ - **`url`** — fetch a document URL in-browser using the active session cookies. Ideal for authenticated downloads, SharePoint links, and Google Drive exports. The format is auto-detected from the URL path or MIME type (and magic bytes as a fallback).
27
+ - **`file`** — parse a file already present in the local downloads directory. Pass a **bare filename** only (e.g. `"report.xlsx"`); path separators are rejected.
28
+
29
+ `max_rows` (default 500) caps Excel/CSV rows; `max_chars` (default 50000) caps PDF/Word text.
30
+
31
+ Use `action: "list"` first if you don't know what files are in the downloads directory.
32
+
33
+ ---
34
+
35
+ ## 2. Parsing Spreadsheets (`.xlsx`, `.xls`, `.csv`)
36
+
37
+ ```json
38
+ {
39
+ "action": "read",
40
+ "file": "quarterly_revenue.xlsx",
41
+ "max_rows": 100
42
+ }
43
+ ```
44
+
45
+ Excel returns per-sheet tables (rows as objects keyed by header):
46
+
47
+ ```json
48
+ {
49
+ "success": true,
50
+ "source": "quarterly_revenue.xlsx",
51
+ "type": "excel",
52
+ "data": {
53
+ "Q3_Summary": [
54
+ { "Department": "Engineering", "Budget": 1250000, "Actual": 1180000 },
55
+ { "Department": "Marketing", "Budget": 600000, "Actual": 620000 }
56
+ ]
57
+ },
58
+ "truncated": false
59
+ }
60
+ ```
61
+
62
+ CSV returns `type: "csv"` with a flat `data` array of row objects.
63
+
64
+ ---
65
+
66
+ ## 3. Ingesting Word & PDF Documents (`.docx`, `.pdf`)
67
+
68
+ Word and PDF extraction return text in `content` (truncated by `max_chars`). PDF additionally reports page metadata under `data`:
69
+
70
+ ```json
71
+ {
72
+ "action": "read",
73
+ "url": "https://intranet.example.com/docs/service_agreement.pdf"
74
+ }
75
+ ```
76
+
77
+ ```json
78
+ {
79
+ "success": true,
80
+ "source": "https://intranet.example.com/docs/service_agreement.pdf",
81
+ "type": "pdf",
82
+ "content": "SERVICE AGREEMENT ...",
83
+ "truncated": true,
84
+ "data": { "numpages": 12, "info": { "Title": "Service Agreement" } }
85
+ }
86
+ ```
87
+
88
+ ### Operational Notes:
89
+ - PDF/Word parsing relies on local binary dependencies (e.g. poppler); if unavailable the call returns `success: false` with an explanatory `error`.
90
+ - If the URL resolves to an HTML login page rather than a document, `type` is `"html"` and `success` is `false` — the link is likely gated.
91
+ - Never point `browser_scrape` or `browser_map` at binary documents; they cannot read inside Excel, Word, or PDF files.
@@ -1,146 +1,146 @@
1
- const fs = require('fs');
2
- const path = require('path');
3
-
4
- const packageRoot = path.join(__dirname, '..');
5
- const scenariosPath = path.join(packageRoot, 'evals', 'scenarios.json');
6
- const skillsJsonPath = path.join(packageRoot, 'skills.json');
7
-
8
- const OFFICIAL_TOOLS = new Set([
9
- "browser_map", "browser_navigate", "browser_click", "browser_type",
10
- "browser_type_secret", "browser_key", "browser_scroll", "browser_dialog",
11
- "browser_burst", "browser_tabs", "browser_wait", "browser_captcha",
12
- "browser_thoughts", "browser_pointer", "browser_select", "browser_fill",
13
- "browser_highlight", "browser_upload", "browser_find", "browser_storage",
14
- "browser_network_intercept", "browser_console", "browser_pdf", "browser_eval",
15
- "browser_cookies", "browser_canvas", "browser_scrape", "browser_snapshot",
16
- "browser_screenshot", "browser_viewport", "browser_clipboard", "browser_inspect",
17
- "browser_extract_design", "browser_automation", "browser_recording",
18
- "browser_detect", "browser_performance",
19
- "browser_github", "browser_office", "browser_emulate",
20
- "browser_checkpoint", "browser_pattern_learn"
21
- ]);
22
-
23
- const BANNED_TOOLS = [
24
- "browser_evaluate", "browser_ask", "scrape_page", "click_element", "fill_field"
25
- ];
26
-
27
- console.log("====================================================");
28
- console.log("Weavetab Agent Skills Evaluation Harness (evals/)");
29
- console.log("====================================================");
30
-
31
- if (!fs.existsSync(scenariosPath)) {
32
- console.error("Missing evals/scenarios.json");
33
- process.exit(1);
34
- }
35
-
36
- if (!fs.existsSync(skillsJsonPath)) {
37
- console.error("Missing skills.json. Run 'npm run build' first.");
38
- process.exit(1);
39
- }
40
-
41
- const scenariosData = JSON.parse(fs.readFileSync(scenariosPath, 'utf8'));
42
- const skillsData = JSON.parse(fs.readFileSync(skillsJsonPath, 'utf8'));
43
-
44
- let passed = 0;
45
- let failed = 0;
46
- const errors = [];
47
-
48
- console.log(`Running evaluation on ${scenariosData.scenarios.length} scenarios...\n`);
49
-
50
- for (const scenario of scenariosData.scenarios) {
51
- process.stdout.write(` [TEST] ${scenario.id.padEnd(35)} `);
52
-
53
- const guidePath = path.join(packageRoot, scenario.expectedDomain, scenario.expectedGuide);
54
- if (!fs.existsSync(guidePath)) {
55
- console.log("❌ FAIL: Guide file missing");
56
- errors.push(`Scenario '${scenario.id}': Expected guide not found at ${guidePath}`);
57
- failed++;
58
- continue;
59
- }
60
-
61
- const guideContent = fs.readFileSync(guidePath, 'utf8');
62
-
63
- // 1. Verify expected tools are documented
64
- let toolsMissing = [];
65
- for (const tool of scenario.expectedTools) {
66
- if (!guideContent.includes(tool)) {
67
- toolsMissing.push(tool);
68
- }
69
- }
70
-
71
- if (toolsMissing.length > 0) {
72
- console.log(`❌ FAIL: Missing tools (${toolsMissing.join(', ')})`);
73
- errors.push(`Scenario '${scenario.id}': Guide ${scenario.expectedGuide} does not document required tools: ${toolsMissing.join(', ')}`);
74
- failed++;
75
- continue;
76
- }
77
-
78
- // 2. Verify no banned tools in guide
79
- let bannedFound = [];
80
- for (const banned of scenario.bannedTools || BANNED_TOOLS) {
81
- if (guideContent.includes(`\`${banned}\``) || guideContent.includes(`"${banned}"`)) {
82
- bannedFound.push(banned);
83
- }
84
- }
85
-
86
- if (bannedFound.length > 0) {
87
- console.log(`❌ FAIL: Contains banned tools (${bannedFound.join(', ')})`);
88
- errors.push(`Scenario '${scenario.id}': Guide ${scenario.expectedGuide} references banned tools: ${bannedFound.join(', ')}`);
89
- failed++;
90
- continue;
91
- }
92
-
93
- console.log("✔ PASS");
94
- passed++;
95
- }
96
-
97
- // Global Check: Verify all 48 tools appear across the entire skill base
98
- console.log("\n----------------------------------------------------");
99
- console.log("Auditing Global Tool Coverage Across All 9 Domains...");
100
- const coveredTools = new Set();
101
- for (const skill of skillsData.skills) {
102
- for (const t of skill.tools) {
103
- coveredTools.add(t);
104
- }
105
- }
106
-
107
- // Also scan markdown files for tools covered in text
108
- for (const domain of skillsData.domains) {
109
- const dPath = path.join(packageRoot, domain);
110
- if (!fs.existsSync(dPath)) continue;
111
- for (const f of fs.readdirSync(dPath).filter(x => x.endsWith('.md'))) {
112
- const content = fs.readFileSync(path.join(dPath, f), 'utf8');
113
- for (const tool of OFFICIAL_TOOLS) {
114
- if (content.includes(tool)) {
115
- coveredTools.add(tool);
116
- }
117
- }
118
- }
119
- }
120
-
121
- let uncoveredTools = [];
122
- for (const tool of OFFICIAL_TOOLS) {
123
- if (!coveredTools.has(tool)) {
124
- uncoveredTools.push(tool);
125
- }
126
- }
127
-
128
- console.log(`Official Tools In MCP: ${OFFICIAL_TOOLS.size}`);
129
- console.log(`Covered in Skills: ${coveredTools.size}`);
130
-
131
- if (uncoveredTools.length > 0) {
132
- console.warn(`⚠️ Warning: Uncovered tools in skills: ${uncoveredTools.join(', ')}`);
133
- }
134
-
135
- console.log("====================================================");
136
- console.log(`Test Summary: ${passed} Passed, ${failed} Failed`);
137
- console.log("====================================================");
138
-
139
- if (failed > 0) {
140
- console.error("\nFailure details:");
141
- errors.forEach(err => console.error(` - ${err}`));
142
- process.exit(1);
143
- } else {
144
- console.log("\nAll benchmark evaluation tests passed successfully.");
145
- process.exit(0);
146
- }
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+
4
+ const packageRoot = path.join(__dirname, '..');
5
+ const scenariosPath = path.join(packageRoot, 'evals', 'scenarios.json');
6
+ const skillsJsonPath = path.join(packageRoot, 'skills.json');
7
+
8
+ const OFFICIAL_TOOLS = new Set([
9
+ "browser_map", "browser_navigate", "browser_click", "browser_type",
10
+ "browser_type_secret", "browser_key", "browser_scroll", "browser_dialog",
11
+ "browser_burst", "browser_tabs", "browser_wait", "browser_captcha",
12
+ "browser_thoughts", "browser_pointer", "browser_select", "browser_fill",
13
+ "browser_highlight", "browser_upload", "browser_find", "browser_storage",
14
+ "browser_network_intercept", "browser_console", "browser_pdf", "browser_eval",
15
+ "browser_cookies", "browser_canvas", "browser_scrape", "browser_snapshot",
16
+ "browser_screenshot", "browser_viewport", "browser_clipboard", "browser_inspect",
17
+ "browser_extract_design", "browser_automation", "browser_recording",
18
+ "browser_detect", "browser_performance",
19
+ "browser_office", "browser_emulate",
20
+ "browser_checkpoint", "browser_pattern_learn"
21
+ ]);
22
+
23
+ const BANNED_TOOLS = [
24
+ "browser_evaluate", "browser_ask", "scrape_page", "click_element", "fill_field"
25
+ ];
26
+
27
+ console.log("====================================================");
28
+ console.log("Weavetab Agent Skills Evaluation Harness (evals/)");
29
+ console.log("====================================================");
30
+
31
+ if (!fs.existsSync(scenariosPath)) {
32
+ console.error("Missing evals/scenarios.json");
33
+ process.exit(1);
34
+ }
35
+
36
+ if (!fs.existsSync(skillsJsonPath)) {
37
+ console.error("Missing skills.json. Run 'npm run build' first.");
38
+ process.exit(1);
39
+ }
40
+
41
+ const scenariosData = JSON.parse(fs.readFileSync(scenariosPath, 'utf8'));
42
+ const skillsData = JSON.parse(fs.readFileSync(skillsJsonPath, 'utf8'));
43
+
44
+ let passed = 0;
45
+ let failed = 0;
46
+ const errors = [];
47
+
48
+ console.log(`Running evaluation on ${scenariosData.scenarios.length} scenarios...\n`);
49
+
50
+ for (const scenario of scenariosData.scenarios) {
51
+ process.stdout.write(` [TEST] ${scenario.id.padEnd(35)} `);
52
+
53
+ const guidePath = path.join(packageRoot, scenario.expectedDomain, scenario.expectedGuide);
54
+ if (!fs.existsSync(guidePath)) {
55
+ console.log("❌ FAIL: Guide file missing");
56
+ errors.push(`Scenario '${scenario.id}': Expected guide not found at ${guidePath}`);
57
+ failed++;
58
+ continue;
59
+ }
60
+
61
+ const guideContent = fs.readFileSync(guidePath, 'utf8');
62
+
63
+ // 1. Verify expected tools are documented
64
+ let toolsMissing = [];
65
+ for (const tool of scenario.expectedTools) {
66
+ if (!guideContent.includes(tool)) {
67
+ toolsMissing.push(tool);
68
+ }
69
+ }
70
+
71
+ if (toolsMissing.length > 0) {
72
+ console.log(`❌ FAIL: Missing tools (${toolsMissing.join(', ')})`);
73
+ errors.push(`Scenario '${scenario.id}': Guide ${scenario.expectedGuide} does not document required tools: ${toolsMissing.join(', ')}`);
74
+ failed++;
75
+ continue;
76
+ }
77
+
78
+ // 2. Verify no banned tools in guide
79
+ let bannedFound = [];
80
+ for (const banned of scenario.bannedTools || BANNED_TOOLS) {
81
+ if (guideContent.includes(`\`${banned}\``) || guideContent.includes(`"${banned}"`)) {
82
+ bannedFound.push(banned);
83
+ }
84
+ }
85
+
86
+ if (bannedFound.length > 0) {
87
+ console.log(`❌ FAIL: Contains banned tools (${bannedFound.join(', ')})`);
88
+ errors.push(`Scenario '${scenario.id}': Guide ${scenario.expectedGuide} references banned tools: ${bannedFound.join(', ')}`);
89
+ failed++;
90
+ continue;
91
+ }
92
+
93
+ console.log("✔ PASS");
94
+ passed++;
95
+ }
96
+
97
+ // Global Check: Verify all 41 tools appear across the entire skill base
98
+ console.log("\n----------------------------------------------------");
99
+ console.log("Auditing Global Tool Coverage Across All 9 Domains...");
100
+ const coveredTools = new Set();
101
+ for (const skill of skillsData.skills) {
102
+ for (const t of skill.tools) {
103
+ coveredTools.add(t);
104
+ }
105
+ }
106
+
107
+ // Also scan markdown files for tools covered in text
108
+ for (const domain of skillsData.domains) {
109
+ const dPath = path.join(packageRoot, domain);
110
+ if (!fs.existsSync(dPath)) continue;
111
+ for (const f of fs.readdirSync(dPath).filter(x => x.endsWith('.md'))) {
112
+ const content = fs.readFileSync(path.join(dPath, f), 'utf8');
113
+ for (const tool of OFFICIAL_TOOLS) {
114
+ if (content.includes(tool)) {
115
+ coveredTools.add(tool);
116
+ }
117
+ }
118
+ }
119
+ }
120
+
121
+ let uncoveredTools = [];
122
+ for (const tool of OFFICIAL_TOOLS) {
123
+ if (!coveredTools.has(tool)) {
124
+ uncoveredTools.push(tool);
125
+ }
126
+ }
127
+
128
+ console.log(`Official Tools In MCP: ${OFFICIAL_TOOLS.size}`);
129
+ console.log(`Covered in Skills: ${coveredTools.size}`);
130
+
131
+ if (uncoveredTools.length > 0) {
132
+ console.warn(`⚠️ Warning: Uncovered tools in skills: ${uncoveredTools.join(', ')}`);
133
+ }
134
+
135
+ console.log("====================================================");
136
+ console.log(`Test Summary: ${passed} Passed, ${failed} Failed`);
137
+ console.log("====================================================");
138
+
139
+ if (failed > 0) {
140
+ console.error("\nFailure details:");
141
+ errors.forEach(err => console.error(` - ${err}`));
142
+ process.exit(1);
143
+ } else {
144
+ console.log("\nAll benchmark evaluation tests passed successfully.");
145
+ process.exit(0);
146
+ }