cdp-skill 1.0.14 → 1.0.16

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/SKILL.md CHANGED
@@ -111,8 +111,12 @@ The skill now passes 1261/1263 unit tests (99.8%) and maintains SHS 99/100 on th
111
111
 
112
112
  ## Element References
113
113
 
114
- Snapshots return versioned refs like `[ref=s1e4]` — format: `s{snapshotId}e{elementNumber}`.
115
- Use refs with `click`, `fill`, `hover`. Each snapshot increments the ID. Refs from earlier snapshots remain valid while the element is in DOM.
114
+ Snapshots return versioned refs like `[ref=f0s1e4]` — format: `f{frameId}s{snapshotId}e{elementNumber}`.
115
+ - `f0` = main frame (default)
116
+ - `f1`, `f2`, ... = iframe by index
117
+ - `f[name]` = iframe by name (e.g., `f[frame-top]`)
118
+
119
+ Each frame maintains its own snapshot counter. Use refs with `click`, `fill`, `hover`. Refs remain valid while the element is in DOM.
116
120
 
117
121
  **Auto re-resolution**: when a ref's element leaves the DOM (React re-render, lazy-load), the system tries to re-find it by stored selector + role + name. Response includes `reResolved: true` on success.
118
122
 
@@ -175,8 +179,8 @@ Returns: `{scrollX, scrollY}`
175
179
  ### snapshot
176
180
  `true` | `{root, detail, mode, maxDepth, maxElements, includeText, includeFrames, pierceShadow, viewportOnly, inlineLimit, since}`
177
181
  Detail: summary | interactive | full(default)
178
- Since: `"s1"` — returns `{unchanged: true}` if page hasn't changed
179
- Returns: YAML with role, "name", states, `[ref=s{N}e{M}]`, snapshotId
182
+ Since: `"f0s1"` — returns `{unchanged: true}` if page hasn't changed
183
+ Returns: YAML with role, "name", states, `[ref=f{F}s{N}e{M}]`, snapshotId (`f0s1`, `f1s1`, etc.)
180
184
  Notes: snapshots over 9KB saved to file (configurable via inlineLimit)
181
185
 
182
186
  ### snapshotSearch
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cdp-skill",
3
- "version": "1.0.14",
3
+ "version": "1.0.16",
4
4
  "description": "Browser automation skill using Chrome DevTools Protocol for Claude Code and AI agents",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
package/src/aria.js CHANGED
@@ -475,7 +475,7 @@ export function createRoleQueryExecutor(session, elementLocator, options = {}) {
475
475
  // The snapshot script runs entirely in the browser context
476
476
  const SNAPSHOT_SCRIPT = `
477
477
  (function generateAriaSnapshot(rootSelector, options) {
478
- const { mode = 'ai', maxDepth = 50, maxElements = 0, includeText = false, includeFrames = false, viewportOnly = false, pierceShadow = false, preserveRefs = false, since = null, internal = false } = options || {};
478
+ const { mode = 'ai', maxDepth = 50, maxElements = 0, includeText = false, includeFrames = false, viewportOnly = false, pierceShadow = false, preserveRefs = false, since = null, internal = false, frameIdentifier = 'f0' } = options || {};
479
479
 
480
480
  // Viewport dimensions for viewport-only mode
481
481
  const viewportWidth = window.innerWidth;
@@ -491,6 +491,9 @@ const SNAPSHOT_SCRIPT = `
491
491
  window.__ariaSnapshotId = 0;
492
492
  }
493
493
 
494
+ // Store frame identifier for ref generation (used by all ref-generating operations)
495
+ window.__ariaFrameIdentifier = frameIdentifier;
496
+
494
497
  // Compute page hash for change detection
495
498
  // Hash combines: URL + scroll position + DOM size + interactive element count
496
499
  function computePageHash() {
@@ -514,7 +517,7 @@ const SNAPSHOT_SCRIPT = `
514
517
  if (currentHash === window.__ariaSnapshotHash) {
515
518
  return {
516
519
  unchanged: true,
517
- snapshotId: 's' + window.__ariaSnapshotId,
520
+ snapshotId: frameIdentifier + 's' + window.__ariaSnapshotId,
518
521
  hash: currentHash
519
522
  };
520
523
  }
@@ -951,9 +954,9 @@ const SNAPSHOT_SCRIPT = `
951
954
  }
952
955
  }
953
956
 
954
- // New element - assign new ref with versioned format: s{snapshotId}e{refCounter}
957
+ // New element - assign new ref with versioned format: f{frameId}s{snapshotId}e{refCounter}
955
958
  refCounter++;
956
- const ref = 's' + currentSnapshotId + 'e' + refCounter;
959
+ const ref = frameIdentifier + 's' + currentSnapshotId + 'e' + refCounter;
957
960
  elementRefs.set(el, ref);
958
961
  refElements.set(ref, el);
959
962
  // Store metadata for re-resolution fallback
@@ -1389,7 +1392,7 @@ const SNAPSHOT_SCRIPT = `
1389
1392
  yaml,
1390
1393
  refs,
1391
1394
  truncated: limitReached,
1392
- snapshotId: 's' + currentSnapshotId
1395
+ snapshotId: frameIdentifier + 's' + currentSnapshotId
1393
1396
  };
1394
1397
  if (autoScoped) snapshotResult.autoScoped = true;
1395
1398
  return snapshotResult;
@@ -1403,6 +1406,7 @@ const SNAPSHOT_SCRIPT = `
1403
1406
  */
1404
1407
  export function createAriaSnapshot(session, options = {}) {
1405
1408
  const getFrameContext = options.getFrameContext || null;
1409
+ const getFrameIdentifier = options.getFrameIdentifier || null;
1406
1410
  /**
1407
1411
  * Generate accessibility snapshot of the page
1408
1412
  * @param {Object} options - Snapshot options
@@ -1416,14 +1420,17 @@ export function createAriaSnapshot(session, options = {}) {
1416
1420
  * @param {boolean} options.viewportOnly - Only include elements visible in viewport (default: false)
1417
1421
  * @param {boolean} options.pierceShadow - Traverse into open shadow DOM trees (default: false)
1418
1422
  * @param {boolean} options.preserveRefs - Merge new refs into existing instead of overwriting (default: false)
1419
- * @param {string} options.since - Snapshot ID to check against (e.g., "s1") - returns {unchanged: true} if page hasn't changed
1423
+ * @param {string} options.since - Snapshot ID to check against (e.g., "f0s1") - returns {unchanged: true} if page hasn't changed
1420
1424
  * @returns {Promise<Object>} Snapshot result with tree, yaml, refs, and snapshotId
1421
1425
  */
1422
1426
  async function generate(options = {}) {
1423
1427
  const { root = null, mode = 'ai', detail = 'full', maxDepth = 50, maxElements = 0, includeText = false, includeFrames = false, viewportOnly = false, pierceShadow = false, preserveRefs = false, since = null, internal = false } = options;
1424
1428
 
1429
+ // Get frame identifier for ref generation (f0 for main frame, f1, f2, etc. for iframes)
1430
+ const frameIdentifier = getFrameIdentifier ? await getFrameIdentifier() : 'f0';
1431
+
1425
1432
  const evalArgs = {
1426
- expression: `(${SNAPSHOT_SCRIPT})(${JSON.stringify(root)}, ${JSON.stringify({ mode, detail, maxDepth, maxElements, includeText, includeFrames, viewportOnly, pierceShadow, preserveRefs, since, internal })})`,
1433
+ expression: `(${SNAPSHOT_SCRIPT})(${JSON.stringify(root)}, ${JSON.stringify({ mode, detail, maxDepth, maxElements, includeText, includeFrames, viewportOnly, pierceShadow, preserveRefs, since, internal, frameIdentifier })})`,
1427
1434
  returnByValue: true,
1428
1435
  awaitPromise: false
1429
1436
  };
package/src/cdp-skill.js CHANGED
@@ -687,12 +687,13 @@ async function main() {
687
687
  getSavedFrameState: () => loadFrameState(session.targetId)
688
688
  });
689
689
  const frameContextProvider = () => pageController.getFrameContext();
690
+ const frameIdentifierProvider = () => pageController.getFrameIdentifier();
690
691
  const elementLocator = createElementLocator(session, { getFrameContext: frameContextProvider });
691
692
  const inputEmulator = createInputEmulator(session);
692
693
  const screenshotCapture = createScreenshotCapture(session);
693
694
  const consoleCapture = createConsoleCapture(session);
694
695
  const pdfCapture = createPdfCapture(session);
695
- const ariaSnapshot = createAriaSnapshot(session, { getFrameContext: frameContextProvider });
696
+ const ariaSnapshot = createAriaSnapshot(session, { getFrameContext: frameContextProvider, getFrameIdentifier: frameIdentifierProvider });
696
697
  const cookieManager = createCookieManager(session);
697
698
 
698
699
  // Initialize page controller (enables required CDP domains)