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/debugger.d.ts
CHANGED
|
@@ -65,7 +65,15 @@ export declare class HyphaDebugger {
|
|
|
65
65
|
private createGetSkillMd;
|
|
66
66
|
/** Build the instruction block for the overlay panel. */
|
|
67
67
|
private buildInstructionBlock;
|
|
68
|
-
/**
|
|
68
|
+
/**
|
|
69
|
+
* Wrap a service function with overlay logging + correct parameter names.
|
|
70
|
+
*
|
|
71
|
+
* Adds logging around the function, then applies baseWrapFn() which uses
|
|
72
|
+
* new Function() to create a wrapper with unminified parameter names from
|
|
73
|
+
* __schema__. This is critical for production builds where Babel/Terser
|
|
74
|
+
* minifies parameter names — hypha-rpc's getParamNames() parses
|
|
75
|
+
* Function.toString() to map kwargs to positional args.
|
|
76
|
+
*/
|
|
69
77
|
private wrapFn;
|
|
70
78
|
private summarizeArgs;
|
|
71
79
|
}
|
package/dist/hypha-debugger.js
CHANGED
|
@@ -9199,6 +9199,31 @@
|
|
|
9199
9199
|
},
|
|
9200
9200
|
},
|
|
9201
9201
|
};
|
|
9202
|
+
function getConsoleLogs(options) {
|
|
9203
|
+
const logs = window.__HYPHA_DEBUGGER__?.consoleLogs ?? [];
|
|
9204
|
+
const level = options?.level;
|
|
9205
|
+
const limit = options?.limit ?? 100;
|
|
9206
|
+
let filtered = level ? logs.filter((l) => l.level === level) : logs;
|
|
9207
|
+
return filtered.slice(-limit);
|
|
9208
|
+
}
|
|
9209
|
+
getConsoleLogs.__schema__ = {
|
|
9210
|
+
name: "getConsoleLogs",
|
|
9211
|
+
description: "Retrieve captured console output (log, warn, error, info).",
|
|
9212
|
+
parameters: {
|
|
9213
|
+
type: "object",
|
|
9214
|
+
properties: {
|
|
9215
|
+
level: {
|
|
9216
|
+
type: "string",
|
|
9217
|
+
description: 'Filter by log level: "log", "warn", "error", "info". Omit for all levels.',
|
|
9218
|
+
enum: ["log", "warn", "error", "info"],
|
|
9219
|
+
},
|
|
9220
|
+
limit: {
|
|
9221
|
+
type: "number",
|
|
9222
|
+
description: "Maximum number of log entries to return (most recent). Default: 100.",
|
|
9223
|
+
},
|
|
9224
|
+
},
|
|
9225
|
+
},
|
|
9226
|
+
};
|
|
9202
9227
|
/** Install console interceptor to capture logs. */
|
|
9203
9228
|
function installConsoleCapture(maxEntries = 500) {
|
|
9204
9229
|
var _a;
|
|
@@ -9398,6 +9423,88 @@
|
|
|
9398
9423
|
required: ["target"],
|
|
9399
9424
|
},
|
|
9400
9425
|
};
|
|
9426
|
+
function getComputedStyles(selector, properties) {
|
|
9427
|
+
const el = document.querySelector(selector);
|
|
9428
|
+
if (!el) {
|
|
9429
|
+
return { error: `No element found for selector: ${selector}` };
|
|
9430
|
+
}
|
|
9431
|
+
const computed = getComputedStyle(el);
|
|
9432
|
+
const result = {};
|
|
9433
|
+
const props = properties ??
|
|
9434
|
+
[
|
|
9435
|
+
"display",
|
|
9436
|
+
"position",
|
|
9437
|
+
"width",
|
|
9438
|
+
"height",
|
|
9439
|
+
"color",
|
|
9440
|
+
"background-color",
|
|
9441
|
+
"font-size",
|
|
9442
|
+
"font-family",
|
|
9443
|
+
"margin",
|
|
9444
|
+
"padding",
|
|
9445
|
+
"border",
|
|
9446
|
+
"opacity",
|
|
9447
|
+
"visibility",
|
|
9448
|
+
"overflow",
|
|
9449
|
+
"z-index",
|
|
9450
|
+
];
|
|
9451
|
+
for (const prop of props) {
|
|
9452
|
+
result[prop] = computed.getPropertyValue(prop);
|
|
9453
|
+
}
|
|
9454
|
+
return result;
|
|
9455
|
+
}
|
|
9456
|
+
getComputedStyles.__schema__ = {
|
|
9457
|
+
name: "getComputedStyles",
|
|
9458
|
+
description: "Get computed CSS styles for an element.",
|
|
9459
|
+
parameters: {
|
|
9460
|
+
type: "object",
|
|
9461
|
+
properties: {
|
|
9462
|
+
selector: {
|
|
9463
|
+
type: "string",
|
|
9464
|
+
description: "CSS selector of the element.",
|
|
9465
|
+
},
|
|
9466
|
+
properties: {
|
|
9467
|
+
type: "array",
|
|
9468
|
+
items: { type: "string" },
|
|
9469
|
+
description: 'CSS property names to retrieve, e.g. ["color", "font-size"]. Omit for common defaults.',
|
|
9470
|
+
},
|
|
9471
|
+
},
|
|
9472
|
+
required: ["selector"],
|
|
9473
|
+
},
|
|
9474
|
+
};
|
|
9475
|
+
function getElementBounds(selector) {
|
|
9476
|
+
const el = document.querySelector(selector);
|
|
9477
|
+
if (!el) {
|
|
9478
|
+
return { error: `No element found for selector: ${selector}` };
|
|
9479
|
+
}
|
|
9480
|
+
const rect = el.getBoundingClientRect();
|
|
9481
|
+
return {
|
|
9482
|
+
bounds: {
|
|
9483
|
+
x: Math.round(rect.x),
|
|
9484
|
+
y: Math.round(rect.y),
|
|
9485
|
+
width: Math.round(rect.width),
|
|
9486
|
+
height: Math.round(rect.height),
|
|
9487
|
+
},
|
|
9488
|
+
visible: rect.width > 0 &&
|
|
9489
|
+
rect.height > 0 &&
|
|
9490
|
+
getComputedStyle(el).visibility !== "hidden" &&
|
|
9491
|
+
getComputedStyle(el).display !== "none",
|
|
9492
|
+
};
|
|
9493
|
+
}
|
|
9494
|
+
getElementBounds.__schema__ = {
|
|
9495
|
+
name: "getElementBounds",
|
|
9496
|
+
description: "Get the bounding rectangle and visibility of a DOM element.",
|
|
9497
|
+
parameters: {
|
|
9498
|
+
type: "object",
|
|
9499
|
+
properties: {
|
|
9500
|
+
selector: {
|
|
9501
|
+
type: "string",
|
|
9502
|
+
description: "CSS selector of the element.",
|
|
9503
|
+
},
|
|
9504
|
+
},
|
|
9505
|
+
required: ["selector"],
|
|
9506
|
+
},
|
|
9507
|
+
};
|
|
9401
9508
|
function getHtml(selector, outer, max_length) {
|
|
9402
9509
|
const useOuter = outer ?? true;
|
|
9403
9510
|
const maxLen = max_length ?? 50000;
|
|
@@ -10502,6 +10609,60 @@
|
|
|
10502
10609
|
required: ["url"],
|
|
10503
10610
|
},
|
|
10504
10611
|
};
|
|
10612
|
+
function goBack() {
|
|
10613
|
+
try {
|
|
10614
|
+
window.history.back();
|
|
10615
|
+
return { success: true, message: "Navigated back" };
|
|
10616
|
+
}
|
|
10617
|
+
catch (err) {
|
|
10618
|
+
return { success: false, message: `Back navigation failed: ${err.message ?? err}` };
|
|
10619
|
+
}
|
|
10620
|
+
}
|
|
10621
|
+
goBack.__schema__ = {
|
|
10622
|
+
name: "goBack",
|
|
10623
|
+
description: "Navigate back in browser history.",
|
|
10624
|
+
parameters: {
|
|
10625
|
+
type: "object",
|
|
10626
|
+
properties: {},
|
|
10627
|
+
},
|
|
10628
|
+
};
|
|
10629
|
+
function goForward() {
|
|
10630
|
+
try {
|
|
10631
|
+
window.history.forward();
|
|
10632
|
+
return { success: true, message: "Navigated forward" };
|
|
10633
|
+
}
|
|
10634
|
+
catch (err) {
|
|
10635
|
+
return {
|
|
10636
|
+
success: false,
|
|
10637
|
+
message: `Forward navigation failed: ${err.message ?? err}`,
|
|
10638
|
+
};
|
|
10639
|
+
}
|
|
10640
|
+
}
|
|
10641
|
+
goForward.__schema__ = {
|
|
10642
|
+
name: "goForward",
|
|
10643
|
+
description: "Navigate forward in browser history.",
|
|
10644
|
+
parameters: {
|
|
10645
|
+
type: "object",
|
|
10646
|
+
properties: {},
|
|
10647
|
+
},
|
|
10648
|
+
};
|
|
10649
|
+
function reload() {
|
|
10650
|
+
try {
|
|
10651
|
+
window.location.reload();
|
|
10652
|
+
return { success: true, message: "Reloading page" };
|
|
10653
|
+
}
|
|
10654
|
+
catch (err) {
|
|
10655
|
+
return { success: false, message: `Reload failed: ${err.message ?? err}` };
|
|
10656
|
+
}
|
|
10657
|
+
}
|
|
10658
|
+
reload.__schema__ = {
|
|
10659
|
+
name: "reload",
|
|
10660
|
+
description: "Reload the current page.",
|
|
10661
|
+
parameters: {
|
|
10662
|
+
type: "object",
|
|
10663
|
+
properties: {},
|
|
10664
|
+
},
|
|
10665
|
+
};
|
|
10505
10666
|
|
|
10506
10667
|
/**
|
|
10507
10668
|
* React component tree inspection service.
|
|
@@ -10844,6 +11005,33 @@
|
|
|
10844
11005
|
return [frontmatter, intro, functionDocs.join("\n"), tips].join("\n");
|
|
10845
11006
|
}
|
|
10846
11007
|
|
|
11008
|
+
/**
|
|
11009
|
+
* Wrap a function with correct, unminified parameter names for hypha-rpc.
|
|
11010
|
+
*
|
|
11011
|
+
* In production builds, Babel/Terser minifies parameter names (e.g. 'code' → 'e').
|
|
11012
|
+
* hypha-rpc's getParamNames() parses Function.toString() to map kwargs to
|
|
11013
|
+
* positional args. With minified names, kwargs like {code: '...'} can't be
|
|
11014
|
+
* mapped and args are silently dropped.
|
|
11015
|
+
*
|
|
11016
|
+
* This helper uses new Function() to create a wrapper whose parameter names
|
|
11017
|
+
* are taken from the function's __schema__ property, so hypha-rpc always sees
|
|
11018
|
+
* the real parameter names regardless of minification.
|
|
11019
|
+
*/
|
|
11020
|
+
function wrapFn(fn) {
|
|
11021
|
+
const schema = fn.__schema__;
|
|
11022
|
+
const paramNames = schema?.parameters?.properties
|
|
11023
|
+
? Object.keys(schema.parameters.properties)
|
|
11024
|
+
: [];
|
|
11025
|
+
if (paramNames.length === 0) {
|
|
11026
|
+
return fn;
|
|
11027
|
+
}
|
|
11028
|
+
const paramList = paramNames.join(", ");
|
|
11029
|
+
const wrapper = new Function("fn", `return async function(${paramList}) { return fn(${paramList}); }`)(fn);
|
|
11030
|
+
if (schema)
|
|
11031
|
+
wrapper.__schema__ = schema;
|
|
11032
|
+
return wrapper;
|
|
11033
|
+
}
|
|
11034
|
+
|
|
10847
11035
|
/**
|
|
10848
11036
|
* @file port from browser-use
|
|
10849
11037
|
* @see https://github.com/browser-use/browser-use/commits/main/browser_use/dom/dom_tree/index.js
|
|
@@ -13847,50 +14035,39 @@
|
|
|
13847
14035
|
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}`);
|
|
13848
14036
|
return lines.join("\n");
|
|
13849
14037
|
}
|
|
13850
|
-
/**
|
|
14038
|
+
/**
|
|
14039
|
+
* Wrap a service function with overlay logging + correct parameter names.
|
|
14040
|
+
*
|
|
14041
|
+
* Adds logging around the function, then applies baseWrapFn() which uses
|
|
14042
|
+
* new Function() to create a wrapper with unminified parameter names from
|
|
14043
|
+
* __schema__. This is critical for production builds where Babel/Terser
|
|
14044
|
+
* minifies parameter names — hypha-rpc's getParamNames() parses
|
|
14045
|
+
* Function.toString() to map kwargs to positional args.
|
|
14046
|
+
*/
|
|
13851
14047
|
wrapFn(fn, name) {
|
|
13852
|
-
const
|
|
13853
|
-
|
|
13854
|
-
|
|
13855
|
-
// Destructure into positional args based on schema properties.
|
|
13856
|
-
if (args.length === 1 &&
|
|
13857
|
-
args[0] &&
|
|
13858
|
-
typeof args[0] === "object" &&
|
|
13859
|
-
!Array.isArray(args[0]) &&
|
|
13860
|
-
fn.__schema__?.parameters?.properties) {
|
|
13861
|
-
const kwargs = args[0];
|
|
13862
|
-
const props = fn.__schema__.parameters.properties;
|
|
13863
|
-
const paramNames = Object.keys(props);
|
|
13864
|
-
// Check if any kwargs key matches a schema property name
|
|
13865
|
-
const hasMatchingKey = paramNames.some((p) => p in kwargs);
|
|
13866
|
-
if (hasMatchingKey) {
|
|
13867
|
-
args = paramNames.map((p) => kwargs[p]);
|
|
13868
|
-
while (args.length > 0 && args[args.length - 1] === undefined) {
|
|
13869
|
-
args.pop();
|
|
13870
|
-
}
|
|
13871
|
-
}
|
|
13872
|
-
}
|
|
13873
|
-
this.overlay?.addLog(`${name}(${this.summarizeArgs(args)})`, "call");
|
|
14048
|
+
const self = this;
|
|
14049
|
+
const logged = async (...args) => {
|
|
14050
|
+
self.overlay?.addLog(`${name}(${self.summarizeArgs(args)})`, "call");
|
|
13874
14051
|
try {
|
|
13875
14052
|
const result = await fn(...args);
|
|
13876
14053
|
const hasError = result && typeof result === "object" && "error" in result;
|
|
13877
14054
|
if (hasError) {
|
|
13878
|
-
|
|
14055
|
+
self.overlay?.addLog(`${name}: ${result.error}`, "error");
|
|
13879
14056
|
}
|
|
13880
14057
|
else {
|
|
13881
|
-
|
|
14058
|
+
self.overlay?.addLog(`${name} -> OK`, "result");
|
|
13882
14059
|
}
|
|
13883
14060
|
return result;
|
|
13884
14061
|
}
|
|
13885
14062
|
catch (err) {
|
|
13886
|
-
|
|
14063
|
+
self.overlay?.addLog(`${name}: ${err.message}`, "error");
|
|
13887
14064
|
throw err;
|
|
13888
14065
|
}
|
|
13889
14066
|
};
|
|
13890
|
-
|
|
13891
|
-
|
|
13892
|
-
|
|
13893
|
-
return
|
|
14067
|
+
// Preserve __schema__ so baseWrapFn can read parameter names
|
|
14068
|
+
if (fn.__schema__)
|
|
14069
|
+
logged.__schema__ = fn.__schema__;
|
|
14070
|
+
return wrapFn(logged);
|
|
13894
14071
|
}
|
|
13895
14072
|
summarizeArgs(args) {
|
|
13896
14073
|
if (args.length === 0)
|
|
@@ -13920,7 +14097,11 @@
|
|
|
13920
14097
|
* Programmatic usage:
|
|
13921
14098
|
* import { startDebugger } from 'hypha-debugger';
|
|
13922
14099
|
* const session = await startDebugger({ server_url: 'https://hypha.aicell.io' });
|
|
14100
|
+
*
|
|
14101
|
+
* Library usage (import individual functions):
|
|
14102
|
+
* import { getPageInfo, clickElement, wrapFn, PageController } from 'hypha-debugger';
|
|
13923
14103
|
*/
|
|
14104
|
+
// ── Core debugger ──
|
|
13924
14105
|
/**
|
|
13925
14106
|
* Start the Hypha debugger. Connects to a Hypha server and registers
|
|
13926
14107
|
* a debug service that remote clients can use to inspect and interact
|
|
@@ -13989,8 +14170,36 @@
|
|
|
13989
14170
|
}
|
|
13990
14171
|
}
|
|
13991
14172
|
|
|
14173
|
+
exports.AICursor = AICursor;
|
|
13992
14174
|
exports.HyphaDebugger = HyphaDebugger;
|
|
14175
|
+
exports.PageController = PageController;
|
|
14176
|
+
exports.clickElement = clickElement$1;
|
|
14177
|
+
exports.clickElementByIndex = clickElementByIndex;
|
|
14178
|
+
exports.disposeController = disposeController;
|
|
14179
|
+
exports.executeScript = executeScript;
|
|
14180
|
+
exports.fillInput = fillInput;
|
|
14181
|
+
exports.generateSkillMd = generateSkillMd;
|
|
14182
|
+
exports.getBrowserState = getBrowserState;
|
|
14183
|
+
exports.getComputedStyles = getComputedStyles;
|
|
14184
|
+
exports.getConsoleLogs = getConsoleLogs;
|
|
14185
|
+
exports.getElementBounds = getElementBounds;
|
|
14186
|
+
exports.getHtml = getHtml;
|
|
14187
|
+
exports.getPageInfo = getPageInfo;
|
|
14188
|
+
exports.getReactTree = getReactTree;
|
|
14189
|
+
exports.goBack = goBack;
|
|
14190
|
+
exports.goForward = goForward;
|
|
14191
|
+
exports.inputText = inputText;
|
|
14192
|
+
exports.installConsoleCapture = installConsoleCapture;
|
|
14193
|
+
exports.navigate = navigate;
|
|
14194
|
+
exports.queryDom = queryDom;
|
|
14195
|
+
exports.reload = reload;
|
|
14196
|
+
exports.removeHighlights = removeHighlights;
|
|
14197
|
+
exports.scroll = scroll;
|
|
14198
|
+
exports.scrollTo = scrollTo;
|
|
14199
|
+
exports.selectOption = selectOption;
|
|
13993
14200
|
exports.startDebugger = startDebugger;
|
|
14201
|
+
exports.takeScreenshot = takeScreenshot;
|
|
14202
|
+
exports.wrapFn = wrapFn;
|
|
13994
14203
|
|
|
13995
14204
|
}));
|
|
13996
14205
|
//# sourceMappingURL=hypha-debugger.js.map
|