| name | sky-chrome-screenshot |
| description | Use node_repl and @oai/sky to navigate Chrome and send real screenshots. |
Sky Chrome Screenshot
Use only the Node REPL tool and @oai/sky for Chrome UI interaction. Do not substitute Playwright, browser automation, Chrome DevTools, shell-driven AppleScript, Peekaboo, or another browser tool when this skill triggers.
Preconditions
- Run on macOS with Google Chrome installed.
- Use Chrome bundle identifier
com.google.Chrome.
- The host must grant the required Accessibility, Automation, and Screen Recording permissions.
- Read the applicable Computer Use confirmation policy before UI actions. Normal navigation to a public URL needs no additional confirmation.
Workflow
- Start or foreground a standard Chrome window before the first capture:
globalThis.sky = globalThis.sky ?? (await import("@oai/sky")).sky;
await sky.press_key({ app: "com.google.Chrome", key: "super+n" });
- Capture initial state:
var state = await sky.get_app_state({
app: "com.google.Chrome",
disableDiff: true,
});
- If the first capture returns
cgWindowNotFound, send super+n once and retry the same bundle-identifier capture. Do not guess that screen-recording permission is missing when Chrome is known to be running.
- Navigate with exact key strings:
await sky.press_key({ app: "com.google.Chrome", key: "super+l" });
await sky.type_text({ app: "com.google.Chrome", text: targetUrl });
await sky.press_key({ app: "com.google.Chrome", key: "Return" });
Never pass a modifiers array. Use Return exactly; do not spell it enter or return.
- Wait briefly for the page to render, then capture the full current state:
await new Promise(resolve => setTimeout(resolve, 2500));
state = await sky.get_app_state({
app: "com.google.Chrome",
disableDiff: true,
});
- Emit the actual screenshot:
var fs = await import("node:fs/promises");
var { fileURLToPath } = await import("node:url");
if (!state.screenshot) throw new Error("No screenshot returned");
var shotPath = fileURLToPath(state.screenshot.url);
await nodeRepl.emitImage({
bytes: await fs.readFile(shotPath),
mimeType: "image/jpeg",
});
- When a downstream messenger rejects macOS temporary paths, copy the image from the same Node REPL session into an allowed workspace path and attach that copy:
var deliveryPath = "/absolute/allowed/workspace/chrome-screenshot.jpeg";
await fs.copyFile(shotPath, deliveryPath);
Validation
- Confirm the address bar shows the requested host.
- Confirm the expected page content is visible.
- Send the screenshot as an image attachment, not only as a path or textual description.
- Report navigation or capture failures honestly; do not fabricate a screenshot.
Reusable example
globalThis.sky = globalThis.sky ?? (await import("@oai/sky")).sky;
await sky.press_key({ app: "com.google.Chrome", key: "super+n" });
var state = await sky.get_app_state({
app: "com.google.Chrome",
disableDiff: true,
});
var targetUrl = "https://example.com/";
await sky.press_key({ app: "com.google.Chrome", key: "super+l" });
await sky.type_text({ app: "com.google.Chrome", text: targetUrl });
await sky.press_key({ app: "com.google.Chrome", key: "Return" });
await new Promise(resolve => setTimeout(resolve, 2500));
state = await sky.get_app_state({
app: "com.google.Chrome",
disableDiff: true,
});
var fs = await ();
{ fileURLToPath } = ();
(!state.) ();
shotPath = (state..);
nodeRepl.({
: fs.(shotPath),
: ,
});