hypha-debugger 0.1.2 → 0.1.4
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/dist/debugger.d.ts +9 -1
- package/dist/hypha-debugger.js +239 -30
- package/dist/hypha-debugger.js.map +1 -1
- package/dist/hypha-debugger.min.js +4 -4
- package/dist/hypha-debugger.min.js.map +1 -1
- package/dist/hypha-debugger.mjs +212 -31
- package/dist/hypha-debugger.mjs.map +1 -1
- package/dist/index.d.ts +15 -0
- package/dist/utils/wrap-fn.d.ts +13 -0
- package/package.json +1 -1
package/dist/hypha-debugger.mjs
CHANGED
|
@@ -742,6 +742,31 @@ getPageInfo.__schema__ = {
|
|
|
742
742
|
},
|
|
743
743
|
},
|
|
744
744
|
};
|
|
745
|
+
function getConsoleLogs(options) {
|
|
746
|
+
const logs = window.__HYPHA_DEBUGGER__?.consoleLogs ?? [];
|
|
747
|
+
const level = options?.level;
|
|
748
|
+
const limit = options?.limit ?? 100;
|
|
749
|
+
let filtered = level ? logs.filter((l) => l.level === level) : logs;
|
|
750
|
+
return filtered.slice(-limit);
|
|
751
|
+
}
|
|
752
|
+
getConsoleLogs.__schema__ = {
|
|
753
|
+
name: "getConsoleLogs",
|
|
754
|
+
description: "Retrieve captured console output (log, warn, error, info).",
|
|
755
|
+
parameters: {
|
|
756
|
+
type: "object",
|
|
757
|
+
properties: {
|
|
758
|
+
level: {
|
|
759
|
+
type: "string",
|
|
760
|
+
description: 'Filter by log level: "log", "warn", "error", "info". Omit for all levels.',
|
|
761
|
+
enum: ["log", "warn", "error", "info"],
|
|
762
|
+
},
|
|
763
|
+
limit: {
|
|
764
|
+
type: "number",
|
|
765
|
+
description: "Maximum number of log entries to return (most recent). Default: 100.",
|
|
766
|
+
},
|
|
767
|
+
},
|
|
768
|
+
},
|
|
769
|
+
};
|
|
745
770
|
/** Install console interceptor to capture logs. */
|
|
746
771
|
function installConsoleCapture(maxEntries = 500) {
|
|
747
772
|
var _a;
|
|
@@ -941,6 +966,88 @@ scrollTo.__schema__ = {
|
|
|
941
966
|
required: ["target"],
|
|
942
967
|
},
|
|
943
968
|
};
|
|
969
|
+
function getComputedStyles(selector, properties) {
|
|
970
|
+
const el = document.querySelector(selector);
|
|
971
|
+
if (!el) {
|
|
972
|
+
return { error: `No element found for selector: ${selector}` };
|
|
973
|
+
}
|
|
974
|
+
const computed = getComputedStyle(el);
|
|
975
|
+
const result = {};
|
|
976
|
+
const props = properties ??
|
|
977
|
+
[
|
|
978
|
+
"display",
|
|
979
|
+
"position",
|
|
980
|
+
"width",
|
|
981
|
+
"height",
|
|
982
|
+
"color",
|
|
983
|
+
"background-color",
|
|
984
|
+
"font-size",
|
|
985
|
+
"font-family",
|
|
986
|
+
"margin",
|
|
987
|
+
"padding",
|
|
988
|
+
"border",
|
|
989
|
+
"opacity",
|
|
990
|
+
"visibility",
|
|
991
|
+
"overflow",
|
|
992
|
+
"z-index",
|
|
993
|
+
];
|
|
994
|
+
for (const prop of props) {
|
|
995
|
+
result[prop] = computed.getPropertyValue(prop);
|
|
996
|
+
}
|
|
997
|
+
return result;
|
|
998
|
+
}
|
|
999
|
+
getComputedStyles.__schema__ = {
|
|
1000
|
+
name: "getComputedStyles",
|
|
1001
|
+
description: "Get computed CSS styles for an element.",
|
|
1002
|
+
parameters: {
|
|
1003
|
+
type: "object",
|
|
1004
|
+
properties: {
|
|
1005
|
+
selector: {
|
|
1006
|
+
type: "string",
|
|
1007
|
+
description: "CSS selector of the element.",
|
|
1008
|
+
},
|
|
1009
|
+
properties: {
|
|
1010
|
+
type: "array",
|
|
1011
|
+
items: { type: "string" },
|
|
1012
|
+
description: 'CSS property names to retrieve, e.g. ["color", "font-size"]. Omit for common defaults.',
|
|
1013
|
+
},
|
|
1014
|
+
},
|
|
1015
|
+
required: ["selector"],
|
|
1016
|
+
},
|
|
1017
|
+
};
|
|
1018
|
+
function getElementBounds(selector) {
|
|
1019
|
+
const el = document.querySelector(selector);
|
|
1020
|
+
if (!el) {
|
|
1021
|
+
return { error: `No element found for selector: ${selector}` };
|
|
1022
|
+
}
|
|
1023
|
+
const rect = el.getBoundingClientRect();
|
|
1024
|
+
return {
|
|
1025
|
+
bounds: {
|
|
1026
|
+
x: Math.round(rect.x),
|
|
1027
|
+
y: Math.round(rect.y),
|
|
1028
|
+
width: Math.round(rect.width),
|
|
1029
|
+
height: Math.round(rect.height),
|
|
1030
|
+
},
|
|
1031
|
+
visible: rect.width > 0 &&
|
|
1032
|
+
rect.height > 0 &&
|
|
1033
|
+
getComputedStyle(el).visibility !== "hidden" &&
|
|
1034
|
+
getComputedStyle(el).display !== "none",
|
|
1035
|
+
};
|
|
1036
|
+
}
|
|
1037
|
+
getElementBounds.__schema__ = {
|
|
1038
|
+
name: "getElementBounds",
|
|
1039
|
+
description: "Get the bounding rectangle and visibility of a DOM element.",
|
|
1040
|
+
parameters: {
|
|
1041
|
+
type: "object",
|
|
1042
|
+
properties: {
|
|
1043
|
+
selector: {
|
|
1044
|
+
type: "string",
|
|
1045
|
+
description: "CSS selector of the element.",
|
|
1046
|
+
},
|
|
1047
|
+
},
|
|
1048
|
+
required: ["selector"],
|
|
1049
|
+
},
|
|
1050
|
+
};
|
|
944
1051
|
function getHtml(selector, outer, max_length) {
|
|
945
1052
|
const useOuter = outer ?? true;
|
|
946
1053
|
const maxLen = max_length ?? 50000;
|
|
@@ -2045,6 +2152,60 @@ navigate.__schema__ = {
|
|
|
2045
2152
|
required: ["url"],
|
|
2046
2153
|
},
|
|
2047
2154
|
};
|
|
2155
|
+
function goBack() {
|
|
2156
|
+
try {
|
|
2157
|
+
window.history.back();
|
|
2158
|
+
return { success: true, message: "Navigated back" };
|
|
2159
|
+
}
|
|
2160
|
+
catch (err) {
|
|
2161
|
+
return { success: false, message: `Back navigation failed: ${err.message ?? err}` };
|
|
2162
|
+
}
|
|
2163
|
+
}
|
|
2164
|
+
goBack.__schema__ = {
|
|
2165
|
+
name: "goBack",
|
|
2166
|
+
description: "Navigate back in browser history.",
|
|
2167
|
+
parameters: {
|
|
2168
|
+
type: "object",
|
|
2169
|
+
properties: {},
|
|
2170
|
+
},
|
|
2171
|
+
};
|
|
2172
|
+
function goForward() {
|
|
2173
|
+
try {
|
|
2174
|
+
window.history.forward();
|
|
2175
|
+
return { success: true, message: "Navigated forward" };
|
|
2176
|
+
}
|
|
2177
|
+
catch (err) {
|
|
2178
|
+
return {
|
|
2179
|
+
success: false,
|
|
2180
|
+
message: `Forward navigation failed: ${err.message ?? err}`,
|
|
2181
|
+
};
|
|
2182
|
+
}
|
|
2183
|
+
}
|
|
2184
|
+
goForward.__schema__ = {
|
|
2185
|
+
name: "goForward",
|
|
2186
|
+
description: "Navigate forward in browser history.",
|
|
2187
|
+
parameters: {
|
|
2188
|
+
type: "object",
|
|
2189
|
+
properties: {},
|
|
2190
|
+
},
|
|
2191
|
+
};
|
|
2192
|
+
function reload() {
|
|
2193
|
+
try {
|
|
2194
|
+
window.location.reload();
|
|
2195
|
+
return { success: true, message: "Reloading page" };
|
|
2196
|
+
}
|
|
2197
|
+
catch (err) {
|
|
2198
|
+
return { success: false, message: `Reload failed: ${err.message ?? err}` };
|
|
2199
|
+
}
|
|
2200
|
+
}
|
|
2201
|
+
reload.__schema__ = {
|
|
2202
|
+
name: "reload",
|
|
2203
|
+
description: "Reload the current page.",
|
|
2204
|
+
parameters: {
|
|
2205
|
+
type: "object",
|
|
2206
|
+
properties: {},
|
|
2207
|
+
},
|
|
2208
|
+
};
|
|
2048
2209
|
|
|
2049
2210
|
/**
|
|
2050
2211
|
* React component tree inspection service.
|
|
@@ -2387,6 +2548,33 @@ function generateSkillMd(serviceFunctions, serviceUrl) {
|
|
|
2387
2548
|
return [frontmatter, intro, functionDocs.join("\n"), tips].join("\n");
|
|
2388
2549
|
}
|
|
2389
2550
|
|
|
2551
|
+
/**
|
|
2552
|
+
* Wrap a function with correct, unminified parameter names for hypha-rpc.
|
|
2553
|
+
*
|
|
2554
|
+
* In production builds, Babel/Terser minifies parameter names (e.g. 'code' → 'e').
|
|
2555
|
+
* hypha-rpc's getParamNames() parses Function.toString() to map kwargs to
|
|
2556
|
+
* positional args. With minified names, kwargs like {code: '...'} can't be
|
|
2557
|
+
* mapped and args are silently dropped.
|
|
2558
|
+
*
|
|
2559
|
+
* This helper uses new Function() to create a wrapper whose parameter names
|
|
2560
|
+
* are taken from the function's __schema__ property, so hypha-rpc always sees
|
|
2561
|
+
* the real parameter names regardless of minification.
|
|
2562
|
+
*/
|
|
2563
|
+
function wrapFn(fn) {
|
|
2564
|
+
const schema = fn.__schema__;
|
|
2565
|
+
const paramNames = schema?.parameters?.properties
|
|
2566
|
+
? Object.keys(schema.parameters.properties)
|
|
2567
|
+
: [];
|
|
2568
|
+
if (paramNames.length === 0) {
|
|
2569
|
+
return fn;
|
|
2570
|
+
}
|
|
2571
|
+
const paramList = paramNames.join(", ");
|
|
2572
|
+
const wrapper = new Function("fn", `return async function(${paramList}) { return fn(${paramList}); }`)(fn);
|
|
2573
|
+
if (schema)
|
|
2574
|
+
wrapper.__schema__ = schema;
|
|
2575
|
+
return wrapper;
|
|
2576
|
+
}
|
|
2577
|
+
|
|
2390
2578
|
/**
|
|
2391
2579
|
* @file port from browser-use
|
|
2392
2580
|
* @see https://github.com/browser-use/browser-use/commits/main/browser_use/dom/dom_tree/index.js
|
|
@@ -5390,50 +5578,39 @@ class HyphaDebugger {
|
|
|
5390
5578
|
lines.push(``, `# 1. Get interactive elements (smart DOM analysis with indexed elements):`, `curl "$SERVICE_URL/get_browser_state"${auth}`, ``, `# 2. Click element by index (e.g. click [3]):`, `curl -X POST "$SERVICE_URL/click_element_by_index"${auth} -H "Content-Type: application/json" -d '{"index": 3}'`, ``, `# 3. Type into an input by index:`, `curl -X POST "$SERVICE_URL/input_text"${auth} -H "Content-Type: application/json" -d '{"index": 5, "text": "hello"}'`, ``, `# Take a screenshot:`, `curl "$SERVICE_URL/take_screenshot"${auth}`, ``, `# Execute JavaScript remotely:`, `curl -X POST "$SERVICE_URL/execute_script"${auth} -H "Content-Type: application/json" -d '{"code": "document.title"}'`, ``, `# Full API docs:`, `curl "$SERVICE_URL/get_skill_md"${auth}`);
|
|
5391
5579
|
return lines.join("\n");
|
|
5392
5580
|
}
|
|
5393
|
-
/**
|
|
5581
|
+
/**
|
|
5582
|
+
* Wrap a service function with overlay logging + correct parameter names.
|
|
5583
|
+
*
|
|
5584
|
+
* Adds logging around the function, then applies baseWrapFn() which uses
|
|
5585
|
+
* new Function() to create a wrapper with unminified parameter names from
|
|
5586
|
+
* __schema__. This is critical for production builds where Babel/Terser
|
|
5587
|
+
* minifies parameter names — hypha-rpc's getParamNames() parses
|
|
5588
|
+
* Function.toString() to map kwargs to positional args.
|
|
5589
|
+
*/
|
|
5394
5590
|
wrapFn(fn, name) {
|
|
5395
|
-
const
|
|
5396
|
-
|
|
5397
|
-
|
|
5398
|
-
// Destructure into positional args based on schema properties.
|
|
5399
|
-
if (args.length === 1 &&
|
|
5400
|
-
args[0] &&
|
|
5401
|
-
typeof args[0] === "object" &&
|
|
5402
|
-
!Array.isArray(args[0]) &&
|
|
5403
|
-
fn.__schema__?.parameters?.properties) {
|
|
5404
|
-
const kwargs = args[0];
|
|
5405
|
-
const props = fn.__schema__.parameters.properties;
|
|
5406
|
-
const paramNames = Object.keys(props);
|
|
5407
|
-
// Check if any kwargs key matches a schema property name
|
|
5408
|
-
const hasMatchingKey = paramNames.some((p) => p in kwargs);
|
|
5409
|
-
if (hasMatchingKey) {
|
|
5410
|
-
args = paramNames.map((p) => kwargs[p]);
|
|
5411
|
-
while (args.length > 0 && args[args.length - 1] === undefined) {
|
|
5412
|
-
args.pop();
|
|
5413
|
-
}
|
|
5414
|
-
}
|
|
5415
|
-
}
|
|
5416
|
-
this.overlay?.addLog(`${name}(${this.summarizeArgs(args)})`, "call");
|
|
5591
|
+
const self = this;
|
|
5592
|
+
const logged = async (...args) => {
|
|
5593
|
+
self.overlay?.addLog(`${name}(${self.summarizeArgs(args)})`, "call");
|
|
5417
5594
|
try {
|
|
5418
5595
|
const result = await fn(...args);
|
|
5419
5596
|
const hasError = result && typeof result === "object" && "error" in result;
|
|
5420
5597
|
if (hasError) {
|
|
5421
|
-
|
|
5598
|
+
self.overlay?.addLog(`${name}: ${result.error}`, "error");
|
|
5422
5599
|
}
|
|
5423
5600
|
else {
|
|
5424
|
-
|
|
5601
|
+
self.overlay?.addLog(`${name} -> OK`, "result");
|
|
5425
5602
|
}
|
|
5426
5603
|
return result;
|
|
5427
5604
|
}
|
|
5428
5605
|
catch (err) {
|
|
5429
|
-
|
|
5606
|
+
self.overlay?.addLog(`${name}: ${err.message}`, "error");
|
|
5430
5607
|
throw err;
|
|
5431
5608
|
}
|
|
5432
5609
|
};
|
|
5433
|
-
|
|
5434
|
-
|
|
5435
|
-
|
|
5436
|
-
return
|
|
5610
|
+
// Preserve __schema__ so baseWrapFn can read parameter names
|
|
5611
|
+
if (fn.__schema__)
|
|
5612
|
+
logged.__schema__ = fn.__schema__;
|
|
5613
|
+
return wrapFn(logged);
|
|
5437
5614
|
}
|
|
5438
5615
|
summarizeArgs(args) {
|
|
5439
5616
|
if (args.length === 0)
|
|
@@ -5463,7 +5640,11 @@ class HyphaDebugger {
|
|
|
5463
5640
|
* Programmatic usage:
|
|
5464
5641
|
* import { startDebugger } from 'hypha-debugger';
|
|
5465
5642
|
* const session = await startDebugger({ server_url: 'https://hypha.aicell.io' });
|
|
5643
|
+
*
|
|
5644
|
+
* Library usage (import individual functions):
|
|
5645
|
+
* import { getPageInfo, clickElement, wrapFn, PageController } from 'hypha-debugger';
|
|
5466
5646
|
*/
|
|
5647
|
+
// ── Core debugger ──
|
|
5467
5648
|
/**
|
|
5468
5649
|
* Start the Hypha debugger. Connects to a Hypha server and registers
|
|
5469
5650
|
* a debug service that remote clients can use to inspect and interact
|
|
@@ -5532,5 +5713,5 @@ if (typeof window !== "undefined") {
|
|
|
5532
5713
|
}
|
|
5533
5714
|
}
|
|
5534
5715
|
|
|
5535
|
-
export { HyphaDebugger, startDebugger };
|
|
5716
|
+
export { AICursor, HyphaDebugger, PageController, clickElement$1 as clickElement, clickElementByIndex, disposeController, executeScript, fillInput, generateSkillMd, getBrowserState, getComputedStyles, getConsoleLogs, getElementBounds, getHtml, getPageInfo, getReactTree, goBack, goForward, inputText, installConsoleCapture, navigate, queryDom, reload, removeHighlights, scroll, scrollTo, selectOption, startDebugger, takeScreenshot, wrapFn };
|
|
5536
5717
|
//# sourceMappingURL=hypha-debugger.mjs.map
|