@ticktockbent/charlotte 0.6.0 → 0.6.1

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 (78) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/README.md +1 -1
  3. package/dist/browser/browser-manager.d.ts +3 -0
  4. package/dist/browser/browser-manager.d.ts.map +1 -1
  5. package/dist/browser/browser-manager.js +13 -2
  6. package/dist/browser/browser-manager.js.map +1 -1
  7. package/dist/cli.d.ts +1 -0
  8. package/dist/cli.d.ts.map +1 -1
  9. package/dist/cli.js +41 -16
  10. package/dist/cli.js.map +1 -1
  11. package/dist/index.js +2 -6
  12. package/dist/index.js.map +1 -1
  13. package/dist/renderer/interactive-extractor.d.ts.map +1 -1
  14. package/dist/renderer/interactive-extractor.js +10 -2
  15. package/dist/renderer/interactive-extractor.js.map +1 -1
  16. package/dist/renderer/layout-extractor.d.ts.map +1 -1
  17. package/dist/renderer/layout-extractor.js +10 -2
  18. package/dist/renderer/layout-extractor.js.map +1 -1
  19. package/dist/renderer/renderer-pipeline.d.ts +2 -2
  20. package/dist/renderer/renderer-pipeline.d.ts.map +1 -1
  21. package/dist/renderer/renderer-pipeline.js +5 -3
  22. package/dist/renderer/renderer-pipeline.js.map +1 -1
  23. package/dist/server.d.ts.map +1 -1
  24. package/dist/server.js +9 -4
  25. package/dist/server.js.map +1 -1
  26. package/dist/state/snapshot-store.d.ts +4 -0
  27. package/dist/state/snapshot-store.d.ts.map +1 -1
  28. package/dist/state/snapshot-store.js +15 -3
  29. package/dist/state/snapshot-store.js.map +1 -1
  30. package/dist/tools/dev-mode.d.ts.map +1 -1
  31. package/dist/tools/dev-mode.js +10 -10
  32. package/dist/tools/dev-mode.js.map +1 -1
  33. package/dist/tools/dialog.js +5 -5
  34. package/dist/tools/dialog.js.map +1 -1
  35. package/dist/tools/evaluate.d.ts +1 -1
  36. package/dist/tools/evaluate.d.ts.map +1 -1
  37. package/dist/tools/evaluate.js +3 -2
  38. package/dist/tools/evaluate.js.map +1 -1
  39. package/dist/tools/interaction-helpers.d.ts +55 -0
  40. package/dist/tools/interaction-helpers.d.ts.map +1 -0
  41. package/dist/tools/interaction-helpers.js +312 -0
  42. package/dist/tools/interaction-helpers.js.map +1 -0
  43. package/dist/tools/interaction.d.ts +1 -17
  44. package/dist/tools/interaction.d.ts.map +1 -1
  45. package/dist/tools/interaction.js +120 -500
  46. package/dist/tools/interaction.js.map +1 -1
  47. package/dist/tools/meta-tool.d.ts +2 -2
  48. package/dist/tools/meta-tool.js +3 -3
  49. package/dist/tools/monitoring.js +9 -9
  50. package/dist/tools/monitoring.js.map +1 -1
  51. package/dist/tools/navigation.d.ts.map +1 -1
  52. package/dist/tools/navigation.js +36 -76
  53. package/dist/tools/navigation.js.map +1 -1
  54. package/dist/tools/observation.d.ts.map +1 -1
  55. package/dist/tools/observation.js +94 -98
  56. package/dist/tools/observation.js.map +1 -1
  57. package/dist/tools/session.d.ts.map +1 -1
  58. package/dist/tools/session.js +135 -184
  59. package/dist/tools/session.js.map +1 -1
  60. package/dist/tools/tool-groups.d.ts +8 -8
  61. package/dist/tools/tool-groups.d.ts.map +1 -1
  62. package/dist/tools/tool-groups.js +113 -142
  63. package/dist/tools/tool-groups.js.map +1 -1
  64. package/dist/tools/tool-helpers.d.ts +18 -0
  65. package/dist/tools/tool-helpers.d.ts.map +1 -1
  66. package/dist/tools/tool-helpers.js +69 -2
  67. package/dist/tools/tool-helpers.js.map +1 -1
  68. package/dist/tools/wait-for.d.ts +5 -0
  69. package/dist/tools/wait-for.d.ts.map +1 -0
  70. package/dist/tools/wait-for.js +169 -0
  71. package/dist/tools/wait-for.js.map +1 -0
  72. package/dist/types/config.d.ts +16 -0
  73. package/dist/types/config.d.ts.map +1 -1
  74. package/dist/types/config.js +15 -0
  75. package/dist/types/config.js.map +1 -1
  76. package/dist/utils/wait.js +11 -5
  77. package/dist/utils/wait.js.map +1 -1
  78. package/package.json +1 -1
@@ -5,9 +5,13 @@ const MAX_DEPTH = 500;
5
5
  * Ring-buffer store for page snapshots. Snapshots have monotonically
6
6
  * increasing integer IDs and are evicted oldest-first when the buffer
7
7
  * reaches its configured depth.
8
+ *
9
+ * A secondary Map index provides O(1) lookup by snapshot ID alongside
10
+ * the ring buffer used for ordered access (latest, previous, oldest).
8
11
  */
9
12
  export class SnapshotStore {
10
13
  buffer = [];
14
+ index = new Map();
11
15
  nextSnapshotId = 1;
12
16
  maxDepth;
13
17
  constructor(depth = DEFAULT_DEPTH) {
@@ -29,9 +33,13 @@ export class SnapshotStore {
29
33
  representation,
30
34
  };
31
35
  this.buffer.push(snapshot);
36
+ this.index.set(snapshotId, snapshot);
32
37
  // Evict oldest if over capacity
33
38
  while (this.buffer.length > this.maxDepth) {
34
- this.buffer.shift();
39
+ const evicted = this.buffer.shift();
40
+ if (evicted !== undefined) {
41
+ this.index.delete(evicted.id);
42
+ }
35
43
  }
36
44
  return snapshotId;
37
45
  }
@@ -39,7 +47,7 @@ export class SnapshotStore {
39
47
  * Retrieve a snapshot by its ID. Returns null if evicted or never existed.
40
48
  */
41
49
  get(snapshotId) {
42
- return this.buffer.find((snapshot) => snapshot.id === snapshotId) ?? null;
50
+ return this.index.get(snapshotId) ?? null;
43
51
  }
44
52
  /**
45
53
  * Get the most recent snapshot, or null if the store is empty.
@@ -84,7 +92,10 @@ export class SnapshotStore {
84
92
  setDepth(newDepth) {
85
93
  this.maxDepth = Math.max(MIN_DEPTH, Math.min(MAX_DEPTH, newDepth));
86
94
  while (this.buffer.length > this.maxDepth) {
87
- this.buffer.shift();
95
+ const evicted = this.buffer.shift();
96
+ if (evicted !== undefined) {
97
+ this.index.delete(evicted.id);
98
+ }
88
99
  }
89
100
  }
90
101
  /**
@@ -92,6 +103,7 @@ export class SnapshotStore {
92
103
  */
93
104
  clear() {
94
105
  this.buffer = [];
106
+ this.index.clear();
95
107
  this.nextSnapshotId = 1;
96
108
  }
97
109
  }
@@ -1 +1 @@
1
- {"version":3,"file":"snapshot-store.js","sourceRoot":"","sources":["../../src/state/snapshot-store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"snapshot-store.js","sourceRoot":"","sources":["../../src/state/snapshot-store.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"dev-mode.d.ts","sourceRoot":"","sources":["../../src/tools/dev-mode.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,yCAAyC,CAAC;AAIzF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAQ1D,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,SAAS,EACjB,IAAI,EAAE,gBAAgB,GACrB,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAqMhC"}
1
+ {"version":3,"file":"dev-mode.d.ts","sourceRoot":"","sources":["../../src/tools/dev-mode.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,yCAAyC,CAAC;AAIzF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAS1D,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,SAAS,EACjB,IAAI,EAAE,gBAAgB,GACrB,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAqMhC"}
@@ -4,11 +4,11 @@ import * as path from "node:path";
4
4
  import { CharlotteError, CharlotteErrorCode } from "../types/errors.js";
5
5
  import { logger } from "../utils/logger.js";
6
6
  import { Auditor } from "../dev/auditor.js";
7
- import { renderActivePage, renderAfterAction, formatPageResponse, handleToolError, } from "./tool-helpers.js";
7
+ import { ensureReady, renderActivePage, renderAfterAction, formatPageResponse, handleToolError, } from "./tool-helpers.js";
8
8
  export function registerDevModeTools(server, deps) {
9
9
  const tools = {};
10
- // ─── charlotte:dev_serve ───
11
- tools["charlotte:dev_serve"] = server.registerTool("charlotte:dev_serve", {
10
+ // ─── charlotte_dev_serve ───
11
+ tools["charlotte_dev_serve"] = server.registerTool("charlotte_dev_serve", {
12
12
  description: "Serve a local directory as a static website and optionally watch for file changes. Navigates to the served URL and returns the page representation. File changes trigger automatic reloads and surface as reload_event on the next tool response.",
13
13
  inputSchema: {
14
14
  path: z.string().describe("Local directory to serve"),
@@ -17,7 +17,7 @@ export function registerDevModeTools(server, deps) {
17
17
  },
18
18
  }, async ({ path: directoryPath, port, watch }) => {
19
19
  try {
20
- await deps.browserManager.ensureConnected();
20
+ await ensureReady(deps);
21
21
  if (!deps.devModeState) {
22
22
  throw new CharlotteError(CharlotteErrorCode.SESSION_ERROR, "Dev mode is not available.", "DevModeState was not initialized.");
23
23
  }
@@ -72,8 +72,8 @@ export function registerDevModeTools(server, deps) {
72
72
  return handleToolError(error);
73
73
  }
74
74
  });
75
- // ─── charlotte:dev_inject ───
76
- tools["charlotte:dev_inject"] = server.registerTool("charlotte:dev_inject", {
75
+ // ─── charlotte_dev_inject ───
76
+ tools["charlotte_dev_inject"] = server.registerTool("charlotte_dev_inject", {
77
77
  description: "Inject CSS or JavaScript into the current page for testing modifications without editing files. Returns the page representation with a delta showing changes.",
78
78
  inputSchema: {
79
79
  css: z.string().optional().describe("CSS to inject into the page"),
@@ -81,7 +81,7 @@ export function registerDevModeTools(server, deps) {
81
81
  },
82
82
  }, async ({ css, js }) => {
83
83
  try {
84
- await deps.browserManager.ensureConnected();
84
+ await ensureReady(deps);
85
85
  if (!css && !js) {
86
86
  throw new CharlotteError(CharlotteErrorCode.SESSION_ERROR, "At least one of 'css' or 'js' must be provided.", "Provide CSS to inject, JS to execute, or both.");
87
87
  }
@@ -107,8 +107,8 @@ export function registerDevModeTools(server, deps) {
107
107
  return handleToolError(error);
108
108
  }
109
109
  });
110
- // ─── charlotte:dev_audit ───
111
- tools["charlotte:dev_audit"] = server.registerTool("charlotte:dev_audit", {
110
+ // ─── charlotte_dev_audit ───
111
+ tools["charlotte_dev_audit"] = server.registerTool("charlotte_dev_audit", {
112
112
  description: "Run accessibility and quality audits on the current page. Returns findings with severity levels and actionable recommendations.",
113
113
  inputSchema: {
114
114
  checks: z
@@ -118,7 +118,7 @@ export function registerDevModeTools(server, deps) {
118
118
  },
119
119
  }, async ({ checks }) => {
120
120
  try {
121
- await deps.browserManager.ensureConnected();
121
+ await ensureReady(deps);
122
122
  const page = deps.pageManager.getActivePage();
123
123
  const session = await page.createCDPSession();
124
124
  const auditor = new Auditor();
@@ -1 +1 @@
1
- {"version":3,"file":"dev-mode.js","sourceRoot":"","sources":["../../src/tools/dev-mode.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"dev-mode.js","sourceRoot":"","sources":["../../src/tools/dev-mode.ts"],"names":[],"mappings":"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"}
@@ -1,11 +1,11 @@
1
1
  import { z } from "zod";
2
2
  import { CharlotteError, CharlotteErrorCode } from "../types/errors.js";
3
3
  import { logger } from "../utils/logger.js";
4
- import { renderAfterAction, stripEmptyFields, handleToolError } from "./tool-helpers.js";
4
+ import { ensureReady, renderAfterAction, stripEmptyFields, handleToolError } from "./tool-helpers.js";
5
5
  export function registerDialogTools(server, deps) {
6
6
  const tools = {};
7
- // ─── charlotte:dialog ───
8
- tools["charlotte:dialog"] = server.registerTool("charlotte:dialog", {
7
+ // ─── charlotte_dialog ───
8
+ tools["charlotte_dialog"] = server.registerTool("charlotte_dialog", {
9
9
  description: "Handle a pending JavaScript dialog (alert, confirm, prompt, beforeunload). Accept or dismiss the dialog. Returns page representation after the dialog is resolved.",
10
10
  inputSchema: {
11
11
  accept: z.boolean().describe("true to accept/OK the dialog, false to dismiss/Cancel"),
@@ -16,11 +16,11 @@ export function registerDialogTools(server, deps) {
16
16
  },
17
17
  }, async ({ accept, prompt_text }) => {
18
18
  try {
19
- await deps.browserManager.ensureConnected();
19
+ await ensureReady(deps);
20
20
  const pendingDialog = deps.pageManager.getPendingDialog();
21
21
  const pendingDialogInfo = deps.pageManager.getPendingDialogInfo();
22
22
  if (!pendingDialog || !pendingDialogInfo) {
23
- throw new CharlotteError(CharlotteErrorCode.SESSION_ERROR, "No pending dialog to handle.", "Call charlotte:observe to check page state. Dialogs appear as pending_dialog in the response.");
23
+ throw new CharlotteError(CharlotteErrorCode.SESSION_ERROR, "No pending dialog to handle.", "Call charlotte_observe to check page state. Dialogs appear as pending_dialog in the response.");
24
24
  }
25
25
  // Capture dialog info before clearing for the response metadata
26
26
  const dialogHandled = {
@@ -1 +1 @@
1
- {"version":3,"file":"dialog.js","sourceRoot":"","sources":["../../src/tools/dialog.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxE,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAG5C,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEzF,MAAM,UAAU,mBAAmB,CACjC,MAAiB,EACjB,IAAsB;IAEtB,MAAM,KAAK,GAAmC,EAAE,CAAC;IAEjD,2BAA2B;IAC3B,KAAK,CAAC,kBAAkB,CAAC,GAAG,MAAM,CAAC,YAAY,CAC7C,kBAAkB,EAClB;QACE,WAAW,EACT,oKAAoK;QACtK,WAAW,EAAE;YACX,MAAM,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,CAAC,uDAAuD,CAAC;YACrF,WAAW,EAAE,CAAC;iBACX,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CACP,sFAAsF,CACvF;SACJ;KACF,EACD,KAAK,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE,EAAE;QAChC,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,cAAc,CAAC,eAAe,EAAE,CAAC;YAE5C,MAAM,aAAa,GAAG,IAAI,CAAC,WAAW,CAAC,gBAAgB,EAAE,CAAC;YAC1D,MAAM,iBAAiB,GAAG,IAAI,CAAC,WAAW,CAAC,oBAAoB,EAAE,CAAC;YAElE,IAAI,CAAC,aAAa,IAAI,CAAC,iBAAiB,EAAE,CAAC;gBACzC,MAAM,IAAI,cAAc,CACtB,kBAAkB,CAAC,aAAa,EAChC,8BAA8B,EAC9B,+FAA+F,CAChG,CAAC;YACJ,CAAC;YAED,gEAAgE;YAChE,MAAM,aAAa,GAAG;gBACpB,IAAI,EAAE,iBAAiB,CAAC,IAAI;gBAC5B,OAAO,EAAE,iBAAiB,CAAC,OAAO;gBAClC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,WAAW;aAC1C,CAAC;YAEF,MAAM,CAAC,IAAI,CAAC,iBAAiB,EAAE;gBAC7B,IAAI,EAAE,iBAAiB,CAAC,IAAI;gBAC5B,MAAM;gBACN,WAAW;aACZ,CAAC,CAAC;YAEH,+BAA+B;YAC/B,IAAI,MAAM,EAAE,CAAC;gBACX,MAAM,aAAa,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;YAC1C,CAAC;iBAAM,CAAC;gBACN,MAAM,aAAa,CAAC,OAAO,EAAE,CAAC;YAChC,CAAC;YAED,iCAAiC;YACjC,IAAI,CAAC,WAAW,CAAC,kBAAkB,EAAE,CAAC;YAEtC,iDAAiD;YACjD,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;YAExD,MAAM,cAAc,GAAG,MAAM,iBAAiB,CAAC,IAAI,CAAC,CAAC;YAErD,8CAA8C;YAC9C,MAAM,eAAe,GAAG;gBACtB,cAAc,EAAE,aAAa;gBAC7B,IAAI,EAAE,gBAAgB,CAAC,cAAc,CAAC;aACvC,CAAC;YAEF,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,eAAe,CAAC;qBACtC;iBACF;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,OAAO,eAAe,CAAC,KAAK,CAAC,CAAC;QAChC,CAAC;IACH,CAAC,CACF,CAAC;IAEF,OAAO,KAAK,CAAC;AACf,CAAC"}
1
+ {"version":3,"file":"dialog.js","sourceRoot":"","sources":["../../src/tools/dialog.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxE,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAG5C,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEtG,MAAM,UAAU,mBAAmB,CACjC,MAAiB,EACjB,IAAsB;IAEtB,MAAM,KAAK,GAAmC,EAAE,CAAC;IAEjD,2BAA2B;IAC3B,KAAK,CAAC,kBAAkB,CAAC,GAAG,MAAM,CAAC,YAAY,CAC7C,kBAAkB,EAClB;QACE,WAAW,EACT,oKAAoK;QACtK,WAAW,EAAE;YACX,MAAM,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,CAAC,uDAAuD,CAAC;YACrF,WAAW,EAAE,CAAC;iBACX,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CACP,sFAAsF,CACvF;SACJ;KACF,EACD,KAAK,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE,EAAE;QAChC,IAAI,CAAC;YACH,MAAM,WAAW,CAAC,IAAI,CAAC,CAAC;YAExB,MAAM,aAAa,GAAG,IAAI,CAAC,WAAW,CAAC,gBAAgB,EAAE,CAAC;YAC1D,MAAM,iBAAiB,GAAG,IAAI,CAAC,WAAW,CAAC,oBAAoB,EAAE,CAAC;YAElE,IAAI,CAAC,aAAa,IAAI,CAAC,iBAAiB,EAAE,CAAC;gBACzC,MAAM,IAAI,cAAc,CACtB,kBAAkB,CAAC,aAAa,EAChC,8BAA8B,EAC9B,+FAA+F,CAChG,CAAC;YACJ,CAAC;YAED,gEAAgE;YAChE,MAAM,aAAa,GAAG;gBACpB,IAAI,EAAE,iBAAiB,CAAC,IAAI;gBAC5B,OAAO,EAAE,iBAAiB,CAAC,OAAO;gBAClC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,WAAW;aAC1C,CAAC;YAEF,MAAM,CAAC,IAAI,CAAC,iBAAiB,EAAE;gBAC7B,IAAI,EAAE,iBAAiB,CAAC,IAAI;gBAC5B,MAAM;gBACN,WAAW;aACZ,CAAC,CAAC;YAEH,+BAA+B;YAC/B,IAAI,MAAM,EAAE,CAAC;gBACX,MAAM,aAAa,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;YAC1C,CAAC;iBAAM,CAAC;gBACN,MAAM,aAAa,CAAC,OAAO,EAAE,CAAC;YAChC,CAAC;YAED,iCAAiC;YACjC,IAAI,CAAC,WAAW,CAAC,kBAAkB,EAAE,CAAC;YAEtC,iDAAiD;YACjD,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;YAExD,MAAM,cAAc,GAAG,MAAM,iBAAiB,CAAC,IAAI,CAAC,CAAC;YAErD,8CAA8C;YAC9C,MAAM,eAAe,GAAG;gBACtB,cAAc,EAAE,aAAa;gBAC7B,IAAI,EAAE,gBAAgB,CAAC,cAAc,CAAC;aACvC,CAAC;YAEF,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,eAAe,CAAC;qBACtC;iBACF;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,OAAO,eAAe,CAAC,KAAK,CAAC,CAAC;QAChC,CAAC;IACH,CAAC,CACF,CAAC;IAEF,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -3,7 +3,7 @@ import type { BrowserManager } from "../browser/browser-manager.js";
3
3
  import type { PageManager } from "../browser/page-manager.js";
4
4
  export interface EvaluateDeps {
5
5
  browserManager: BrowserManager;
6
- pageManager?: PageManager;
6
+ pageManager: PageManager;
7
7
  getActivePage: () => import("puppeteer").Page;
8
8
  }
9
9
  export declare function registerEvaluateTools(server: McpServer, deps: EvaluateDeps): Record<string, RegisteredTool>;
@@ -1 +1 @@
1
- {"version":3,"file":"evaluate.d.ts","sourceRoot":"","sources":["../../src/tools/evaluate.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,yCAAyC,CAAC;AACzF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAI9D,MAAM,WAAW,YAAY;IAC3B,cAAc,EAAE,cAAc,CAAC;IAC/B,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,aAAa,EAAE,MAAM,OAAO,WAAW,EAAE,IAAI,CAAC;CAC/C;AAED,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,SAAS,EACjB,IAAI,EAAE,YAAY,GACjB,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAqHhC"}
1
+ {"version":3,"file":"evaluate.d.ts","sourceRoot":"","sources":["../../src/tools/evaluate.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,yCAAyC,CAAC;AACzF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAK9D,MAAM,WAAW,YAAY;IAC3B,cAAc,EAAE,cAAc,CAAC;IAC/B,WAAW,EAAE,WAAW,CAAC;IACzB,aAAa,EAAE,MAAM,OAAO,WAAW,EAAE,IAAI,CAAC;CAC/C;AAED,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,SAAS,EACjB,IAAI,EAAE,YAAY,GACjB,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAqHhC"}
@@ -1,9 +1,10 @@
1
1
  import { z } from "zod";
2
2
  import { CharlotteError, CharlotteErrorCode } from "../types/errors.js";
3
3
  import { logger } from "../utils/logger.js";
4
+ import { ensureReady } from "./tool-helpers.js";
4
5
  export function registerEvaluateTools(server, deps) {
5
6
  const tools = {};
6
- tools["charlotte:evaluate"] = server.registerTool("charlotte:evaluate", {
7
+ tools["charlotte_evaluate"] = server.registerTool("charlotte_evaluate", {
7
8
  description: "Execute JavaScript in page context. Supports single expressions and multi-statement code. Returns the completion value of the last expression-statement.",
8
9
  inputSchema: {
9
10
  expression: z.string().describe("JS expression or multi-statement code to evaluate"),
@@ -14,7 +15,7 @@ export function registerEvaluateTools(server, deps) {
14
15
  .describe("If the expression returns a Promise, await it before returning (default: true)"),
15
16
  },
16
17
  }, async ({ expression, timeout, await_promise }) => {
17
- await deps.browserManager.ensureConnected();
18
+ await ensureReady(deps);
18
19
  const page = deps.getActivePage();
19
20
  const evaluationTimeout = timeout ?? 5000;
20
21
  const shouldAwaitPromise = await_promise ?? true;
@@ -1 +1 @@
1
- {"version":3,"file":"evaluate.js","sourceRoot":"","sources":["../../src/tools/evaluate.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"evaluate.js","sourceRoot":"","sources":["../../src/tools/evaluate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ import type { Page, KeyInput } from "puppeteer";
2
+ /** Maps short modifier names to Puppeteer KeyInput values. */
3
+ export declare const MODIFIER_KEY_MAP: Record<string, KeyInput>;
4
+ /**
5
+ * Click an element by backend node ID using CDP to get coordinates, then click at those coords.
6
+ */
7
+ export declare function clickElementByBackendNodeId(page: Page, backendNodeId: number, clickType?: "left" | "right" | "double", modifiers?: Array<"ctrl" | "shift" | "alt" | "meta">): Promise<void>;
8
+ /**
9
+ * Wait for any navigation triggered by an action, or fall back to a brief settle pause.
10
+ *
11
+ * Listens for the `framenavigated` CDP event to detect if a click caused navigation.
12
+ * If navigation is detected within `detectionWindowMs`, waits for the page load event
13
+ * (up to `loadTimeoutMs`). If no navigation fires, returns after `settleMs`.
14
+ *
15
+ * Also races against dialog events — if the action triggers a JavaScript dialog
16
+ * (alert, confirm, prompt, beforeunload), the action promise will block indefinitely.
17
+ * This function detects that and returns early so the caller can surface `pending_dialog`.
18
+ */
19
+ export declare function waitForPossibleNavigation(page: Page, action: () => Promise<void>, { detectionWindowMs, loadTimeoutMs, settleMs }?: {
20
+ detectionWindowMs?: number | undefined;
21
+ loadTimeoutMs?: number | undefined;
22
+ settleMs?: number | undefined;
23
+ }): Promise<void>;
24
+ /**
25
+ * Focus an element by backend node ID using CDP.
26
+ */
27
+ export declare function focusElementByBackendNodeId(page: Page, backendNodeId: number): Promise<void>;
28
+ /**
29
+ * Hover over an element by backend node ID.
30
+ */
31
+ export declare function hoverElementByBackendNodeId(page: Page, backendNodeId: number): Promise<void>;
32
+ /**
33
+ * Drag one element to another using mouse primitives.
34
+ * Sequence: move to source → mousedown → move to target → mouseup
35
+ * Includes intermediate move steps and delays to ensure drag events fire reliably.
36
+ */
37
+ export declare function dragElementToElement(page: Page, sourceBackendNodeId: number, targetBackendNodeId: number): Promise<void>;
38
+ /**
39
+ * Type text into an input element. Uses CDP to focus, optionally clears, then types via keyboard.
40
+ */
41
+ export declare function typeIntoElement(page: Page, backendNodeId: number, text: string, clearFirst: boolean, pressEnter: boolean, characterDelay?: number): Promise<void>;
42
+ /**
43
+ * Select a value in a <select> element using CDP to set the value and dispatch change events.
44
+ */
45
+ export declare function selectOptionByBackendNodeId(page: Page, backendNodeId: number, value: string): Promise<void>;
46
+ /**
47
+ * Submit a form by backend node ID — calls form.submit() via CDP.
48
+ */
49
+ export declare function submitFormByBackendNodeId(page: Page, backendNodeId: number): Promise<void>;
50
+ /**
51
+ * Set files on a file input element using CDP DOM.setFileInputFiles.
52
+ * Validates that the target element is actually an <input type="file">.
53
+ */
54
+ export declare function setFileInputFiles(page: Page, backendNodeId: number, filePaths: string[]): Promise<void>;
55
+ //# sourceMappingURL=interaction-helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interaction-helpers.d.ts","sourceRoot":"","sources":["../../src/tools/interaction-helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAIhD,8DAA8D;AAC9D,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAKrD,CAAC;AAEF;;GAEG;AACH,wBAAsB,2BAA2B,CAC/C,IAAI,EAAE,IAAI,EACV,aAAa,EAAE,MAAM,EACrB,SAAS,GAAE,MAAM,GAAG,OAAO,GAAG,QAAiB,EAC/C,SAAS,GAAE,KAAK,CAAC,MAAM,GAAG,OAAO,GAAG,KAAK,GAAG,MAAM,CAAM,GACvD,OAAO,CAAC,IAAI,CAAC,CAiDf;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,yBAAyB,CAC7C,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,EAC3B,EAAE,iBAAuB,EAAE,aAAqB,EAAE,QAAa,EAAE;;;;CAAK,GACrE,OAAO,CAAC,IAAI,CAAC,CAoEf;AAED;;GAEG;AACH,wBAAsB,2BAA2B,CAC/C,IAAI,EAAE,IAAI,EACV,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,IAAI,CAAC,CAOf;AAED;;GAEG;AACH,wBAAsB,2BAA2B,CAC/C,IAAI,EAAE,IAAI,EACV,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,IAAI,CAAC,CAuBf;AAmCD;;;;GAIG;AACH,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,IAAI,EACV,mBAAmB,EAAE,MAAM,EAC3B,mBAAmB,EAAE,MAAM,GAC1B,OAAO,CAAC,IAAI,CAAC,CAsBf;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,IAAI,EACV,aAAa,EAAE,MAAM,EACrB,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,OAAO,EACnB,UAAU,EAAE,OAAO,EACnB,cAAc,CAAC,EAAE,MAAM,GACtB,OAAO,CAAC,IAAI,CAAC,CAmBf;AAED;;GAEG;AACH,wBAAsB,2BAA2B,CAC/C,IAAI,EAAE,IAAI,EACV,aAAa,EAAE,MAAM,EACrB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,IAAI,CAAC,CAoCf;AAED;;GAEG;AACH,wBAAsB,yBAAyB,CAC7C,IAAI,EAAE,IAAI,EACV,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,IAAI,CAAC,CAuBf;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,IAAI,EACV,aAAa,EAAE,MAAM,EACrB,SAAS,EAAE,MAAM,EAAE,GAClB,OAAO,CAAC,IAAI,CAAC,CAuBf"}
@@ -0,0 +1,312 @@
1
+ import { CharlotteError, CharlotteErrorCode } from "../types/errors.js";
2
+ import { logger } from "../utils/logger.js";
3
+ /** Maps short modifier names to Puppeteer KeyInput values. */
4
+ export const MODIFIER_KEY_MAP = {
5
+ ctrl: "Control",
6
+ shift: "Shift",
7
+ alt: "Alt",
8
+ meta: "Meta",
9
+ };
10
+ /**
11
+ * Click an element by backend node ID using CDP to get coordinates, then click at those coords.
12
+ */
13
+ export async function clickElementByBackendNodeId(page, backendNodeId, clickType = "left", modifiers = []) {
14
+ // Get the element's box model to find clickable coordinates
15
+ const cdpSession = await page.createCDPSession();
16
+ try {
17
+ // First, scroll the element into view
18
+ await cdpSession.send("DOM.scrollIntoViewIfNeeded", { backendNodeId });
19
+ // Get box model for coordinates
20
+ const { model } = await cdpSession.send("DOM.getBoxModel", {
21
+ backendNodeId,
22
+ });
23
+ if (!model) {
24
+ throw new CharlotteError(CharlotteErrorCode.ELEMENT_NOT_FOUND, "Element has no visible box model — it may be hidden or zero-sized.", "Call charlotte_observe to check the element's state.");
25
+ }
26
+ // content quad: [x1,y1, x2,y2, x3,y3, x4,y4]
27
+ const contentQuad = model.content;
28
+ const centerX = (contentQuad[0] + contentQuad[2] + contentQuad[4] + contentQuad[6]) / 4;
29
+ const centerY = (contentQuad[1] + contentQuad[3] + contentQuad[5] + contentQuad[7]) / 4;
30
+ // Hold down modifier keys before the click
31
+ for (const modifier of modifiers) {
32
+ const modifierKey = MODIFIER_KEY_MAP[modifier];
33
+ await page.keyboard.down(modifierKey);
34
+ }
35
+ try {
36
+ if (clickType === "right") {
37
+ await page.mouse.click(centerX, centerY, { button: "right" });
38
+ }
39
+ else if (clickType === "double") {
40
+ await page.mouse.click(centerX, centerY, { clickCount: 2 });
41
+ }
42
+ else {
43
+ await page.mouse.click(centerX, centerY);
44
+ }
45
+ }
46
+ finally {
47
+ // Release modifier keys in reverse order (always release even if click fails)
48
+ for (const modifier of [...modifiers].reverse()) {
49
+ const modifierKey = MODIFIER_KEY_MAP[modifier];
50
+ await page.keyboard.up(modifierKey);
51
+ }
52
+ }
53
+ }
54
+ finally {
55
+ await cdpSession.detach();
56
+ }
57
+ }
58
+ /**
59
+ * Wait for any navigation triggered by an action, or fall back to a brief settle pause.
60
+ *
61
+ * Listens for the `framenavigated` CDP event to detect if a click caused navigation.
62
+ * If navigation is detected within `detectionWindowMs`, waits for the page load event
63
+ * (up to `loadTimeoutMs`). If no navigation fires, returns after `settleMs`.
64
+ *
65
+ * Also races against dialog events — if the action triggers a JavaScript dialog
66
+ * (alert, confirm, prompt, beforeunload), the action promise will block indefinitely.
67
+ * This function detects that and returns early so the caller can surface `pending_dialog`.
68
+ */
69
+ export async function waitForPossibleNavigation(page, action, { detectionWindowMs = 500, loadTimeoutMs = 10000, settleMs = 50 } = {}) {
70
+ let navigationDetected = false;
71
+ let dialogDetected = false;
72
+ // Listen for navigation start via page event (fires on any navigation)
73
+ const navigationStartPromise = new Promise((resolve) => {
74
+ const handler = () => {
75
+ navigationDetected = true;
76
+ page.off("framenavigated", handler);
77
+ resolve();
78
+ };
79
+ page.on("framenavigated", handler);
80
+ // Clean up listener if no navigation fires within detection window
81
+ setTimeout(() => {
82
+ page.off("framenavigated", handler);
83
+ resolve();
84
+ }, detectionWindowMs);
85
+ });
86
+ // Listen for dialog (blocks the action from completing)
87
+ const dialogPromise = new Promise((resolve) => {
88
+ const handler = () => {
89
+ dialogDetected = true;
90
+ page.off("dialog", handler);
91
+ resolve();
92
+ };
93
+ page.on("dialog", handler);
94
+ // Clean up on timeout — if no dialog fires, we don't need this listener
95
+ setTimeout(() => {
96
+ page.off("dialog", handler);
97
+ resolve();
98
+ }, detectionWindowMs);
99
+ });
100
+ // Race: action vs dialog
101
+ const actionPromise = action();
102
+ await Promise.race([
103
+ actionPromise.then(() => "action"),
104
+ dialogPromise.then(() => "dialog"),
105
+ ]);
106
+ if (dialogDetected) {
107
+ // Dialog is blocking the action. Don't await actionPromise — it will
108
+ // resolve later when the dialog is handled via charlotte_dialog.
109
+ // Guard against unhandled rejection from the fire-and-forget promise.
110
+ actionPromise.catch(() => {
111
+ logger.debug("Post-dialog action promise rejected (expected)");
112
+ });
113
+ return;
114
+ }
115
+ // Action completed normally — check for navigation
116
+ await navigationStartPromise;
117
+ if (navigationDetected) {
118
+ // Navigation occurred — wait for the page to finish loading
119
+ try {
120
+ await page.waitForNavigation({ waitUntil: "load", timeout: loadTimeoutMs });
121
+ }
122
+ catch {
123
+ // Page may have already finished loading before we called waitForNavigation,
124
+ // or the load timed out. Either way, render what we have.
125
+ logger.debug("Post-navigation load wait ended (page may already be loaded)");
126
+ }
127
+ }
128
+ else {
129
+ // No navigation — brief settle for in-page DOM updates
130
+ await new Promise((resolve) => setTimeout(resolve, settleMs));
131
+ }
132
+ }
133
+ /**
134
+ * Focus an element by backend node ID using CDP.
135
+ */
136
+ export async function focusElementByBackendNodeId(page, backendNodeId) {
137
+ const cdpSession = await page.createCDPSession();
138
+ try {
139
+ await cdpSession.send("DOM.focus", { backendNodeId });
140
+ }
141
+ finally {
142
+ await cdpSession.detach();
143
+ }
144
+ }
145
+ /**
146
+ * Hover over an element by backend node ID.
147
+ */
148
+ export async function hoverElementByBackendNodeId(page, backendNodeId) {
149
+ const cdpSession = await page.createCDPSession();
150
+ try {
151
+ await cdpSession.send("DOM.scrollIntoViewIfNeeded", { backendNodeId });
152
+ const { model } = await cdpSession.send("DOM.getBoxModel", {
153
+ backendNodeId,
154
+ });
155
+ if (!model) {
156
+ throw new CharlotteError(CharlotteErrorCode.ELEMENT_NOT_FOUND, "Element has no visible box model for hover.");
157
+ }
158
+ const contentQuad = model.content;
159
+ const centerX = (contentQuad[0] + contentQuad[2] + contentQuad[4] + contentQuad[6]) / 4;
160
+ const centerY = (contentQuad[1] + contentQuad[3] + contentQuad[5] + contentQuad[7]) / 4;
161
+ await page.mouse.move(centerX, centerY);
162
+ }
163
+ finally {
164
+ await cdpSession.detach();
165
+ }
166
+ }
167
+ /**
168
+ * Get the center coordinates of an element by backend node ID.
169
+ * Scrolls the element into view first.
170
+ */
171
+ async function getElementCenter(page, backendNodeId) {
172
+ const cdpSession = await page.createCDPSession();
173
+ try {
174
+ await cdpSession.send("DOM.scrollIntoViewIfNeeded", { backendNodeId });
175
+ const { model } = await cdpSession.send("DOM.getBoxModel", {
176
+ backendNodeId,
177
+ });
178
+ if (!model) {
179
+ throw new CharlotteError(CharlotteErrorCode.ELEMENT_NOT_FOUND, "Element has no visible box model — it may be hidden or zero-sized.", "Call charlotte_observe to check the element's state.");
180
+ }
181
+ const contentQuad = model.content;
182
+ return {
183
+ x: (contentQuad[0] + contentQuad[2] + contentQuad[4] + contentQuad[6]) / 4,
184
+ y: (contentQuad[1] + contentQuad[3] + contentQuad[5] + contentQuad[7]) / 4,
185
+ };
186
+ }
187
+ finally {
188
+ await cdpSession.detach();
189
+ }
190
+ }
191
+ /**
192
+ * Drag one element to another using mouse primitives.
193
+ * Sequence: move to source → mousedown → move to target → mouseup
194
+ * Includes intermediate move steps and delays to ensure drag events fire reliably.
195
+ */
196
+ export async function dragElementToElement(page, sourceBackendNodeId, targetBackendNodeId) {
197
+ const sourceCenter = await getElementCenter(page, sourceBackendNodeId);
198
+ const targetCenter = await getElementCenter(page, targetBackendNodeId);
199
+ // Move to source and press down
200
+ await page.mouse.move(sourceCenter.x, sourceCenter.y);
201
+ await page.mouse.down();
202
+ // Intermediate move to trigger dragstart (some browsers need movement to begin a drag)
203
+ await page.mouse.move(sourceCenter.x + (targetCenter.x - sourceCenter.x) * 0.25, sourceCenter.y + (targetCenter.y - sourceCenter.y) * 0.25, { steps: 5 });
204
+ await new Promise((resolve) => setTimeout(resolve, 50));
205
+ // Move to target
206
+ await page.mouse.move(targetCenter.x, targetCenter.y, { steps: 10 });
207
+ await new Promise((resolve) => setTimeout(resolve, 50));
208
+ // Release
209
+ await page.mouse.up();
210
+ }
211
+ /**
212
+ * Type text into an input element. Uses CDP to focus, optionally clears, then types via keyboard.
213
+ */
214
+ export async function typeIntoElement(page, backendNodeId, text, clearFirst, pressEnter, characterDelay) {
215
+ // Focus the element
216
+ await focusElementByBackendNodeId(page, backendNodeId);
217
+ if (clearFirst) {
218
+ // Select all text then delete — works cross-platform
219
+ await page.keyboard.down("Control");
220
+ await page.keyboard.press("a");
221
+ await page.keyboard.up("Control");
222
+ await page.keyboard.press("Backspace");
223
+ }
224
+ // Type the text — with optional per-character delay for sites with
225
+ // key-by-key event handlers (autocomplete, search-as-you-type, etc.)
226
+ await page.keyboard.type(text, characterDelay ? { delay: characterDelay } : undefined);
227
+ if (pressEnter) {
228
+ await page.keyboard.press("Enter");
229
+ }
230
+ }
231
+ /**
232
+ * Select a value in a <select> element using CDP to set the value and dispatch change events.
233
+ */
234
+ export async function selectOptionByBackendNodeId(page, backendNodeId, value) {
235
+ const cdpSession = await page.createCDPSession();
236
+ try {
237
+ // Resolve the node to get a remote object reference
238
+ const { object } = await cdpSession.send("DOM.resolveNode", {
239
+ backendNodeId,
240
+ });
241
+ if (!object?.objectId) {
242
+ throw new CharlotteError(CharlotteErrorCode.ELEMENT_NOT_FOUND, "Could not resolve select element.");
243
+ }
244
+ // Use Runtime.callFunctionOn to set the value and fire events
245
+ await cdpSession.send("Runtime.callFunctionOn", {
246
+ objectId: object.objectId,
247
+ functionDeclaration: `function(targetValue) {
248
+ const options = Array.from(this.options);
249
+ const matchByValue = options.find(o => o.value === targetValue);
250
+ const matchByText = options.find(o => o.textContent.trim() === targetValue);
251
+ const match = matchByValue || matchByText;
252
+ if (match) {
253
+ this.value = match.value;
254
+ this.dispatchEvent(new Event('input', { bubbles: true }));
255
+ this.dispatchEvent(new Event('change', { bubbles: true }));
256
+ } else {
257
+ throw new Error('Option "' + targetValue + '" not found');
258
+ }
259
+ }`,
260
+ arguments: [{ value }],
261
+ });
262
+ }
263
+ finally {
264
+ await cdpSession.detach();
265
+ }
266
+ }
267
+ /**
268
+ * Submit a form by backend node ID — calls form.submit() via CDP.
269
+ */
270
+ export async function submitFormByBackendNodeId(page, backendNodeId) {
271
+ const cdpSession = await page.createCDPSession();
272
+ try {
273
+ const { object } = await cdpSession.send("DOM.resolveNode", {
274
+ backendNodeId,
275
+ });
276
+ if (!object?.objectId) {
277
+ throw new CharlotteError(CharlotteErrorCode.ELEMENT_NOT_FOUND, "Could not resolve form element.");
278
+ }
279
+ await cdpSession.send("Runtime.callFunctionOn", {
280
+ objectId: object.objectId,
281
+ functionDeclaration: `function() {
282
+ this.dispatchEvent(new Event('submit', { bubbles: true, cancelable: true }));
283
+ }`,
284
+ });
285
+ }
286
+ finally {
287
+ await cdpSession.detach();
288
+ }
289
+ }
290
+ /**
291
+ * Set files on a file input element using CDP DOM.setFileInputFiles.
292
+ * Validates that the target element is actually an <input type="file">.
293
+ */
294
+ export async function setFileInputFiles(page, backendNodeId, filePaths) {
295
+ const cdpSession = await page.createCDPSession();
296
+ try {
297
+ const { node } = await cdpSession.send("DOM.describeNode", { backendNodeId });
298
+ const isFileInput = node.nodeName === "INPUT" &&
299
+ (node.attributes ?? []).some((attr, i, arr) => attr === "type" && arr[i + 1] === "file");
300
+ if (!isFileInput) {
301
+ throw new CharlotteError(CharlotteErrorCode.SESSION_ERROR, "Element is not a file input.", "Use charlotte_find to locate file_input elements.");
302
+ }
303
+ await cdpSession.send("DOM.setFileInputFiles", {
304
+ files: filePaths,
305
+ backendNodeId,
306
+ });
307
+ }
308
+ finally {
309
+ await cdpSession.detach();
310
+ }
311
+ }
312
+ //# sourceMappingURL=interaction-helpers.js.map