AI chat

can rebind take a screenshot of the screen or a selection of the screen

Yes, Rebind can take a screenshot of an entire monitor or a specific rectangular region using the Screen.Capture API.

How it works

  • Full screen: Calling Screen.Capture() captures the monitor currently under the mouse cursor. You can also specify a particular display with { display = index } (indexes come from Screen.List()).
  • Selection / Region: Pass a region table with { region = { x = X, y = Y, w = WIDTH, h = HEIGHT } } in the local coordinates of that display.
  • Output: The call returns a table containing:
    • image: A base64-encoded lossless PNG string.
    • width and height: Dimensions of the captured area.
    • cursor: The cursor position { x, y } at the moment of capture.
    • display: Metadata about the display that was captured.
  • Saving to disk: To write the screenshot to a file, decode the base64 string using Codec.Base64Decode(cap.image) and save it with File.Write("screenshot.png", bytes).

Important requirements

  1. Must run in a coroutine: Screen.Capture performs image encoding on a worker thread and yields, so it must be executed inside a Run(function() ... end) coroutine or an Async(...) callback. Calling it synchronously outside a coroutine will raise an error.
  2. Platform support: Screen capture is supported on Windows and macOS. On Linux, Screen.Capture is currently unavailable and will raise an error.
  3. Memory considerations: If you take large, uncompressed 4K captures or capture frequently, you can pass max_edge = 1280 in opts to automatically downscale the image, or add rebind: memory_limit_mb=64 to your script's modeline to avoid hitting the default 8 MB Luau heap limit.

create a script

I will assume you want hotkeys to capture either the full screen or a selected region and save the result as a PNG file in the script's directory.

How it works

  • Modeline (memory_limit_mb=64): Raises the script's Luau heap ceiling to prevent memory overflow when encoding and decoding large high-resolution screenshot strings.
  • Bind with Async: Wraps the keybind actions in coroutines so that Screen.Capture() can yield safely while processing the PNG on a worker thread.
  • Full screen (F9): Grabs the active display under the cursor using Screen.Capture(), decodes the base64 PNG data via Codec.Base64Decode, and saves it to a timestamped file in the script folder with File.Write.
  • Region capture (F10): Samples the current cursor position with System.Mouse() and captures a 500×500 square region centered on the cursor via the region = { x, y, w, h } option.

Learn more

can it resize the screenshot so that the images aren't huge

Yes. Screen.Capture includes a built-in max_edge option that automatically downscales the output image so its longer side is at most that many pixels while preserving the aspect ratio.

Here is the updated script with a configurable max-dimension slider in the UI options:

How it works

  • max_edge parameter: When passed to Screen.Capture({ max_edge = ... }), the capture engine proportionally downscales the image before producing the base64 PNG data. For example, a 4K display (3840×2160) with max_edge = 1280 outputs a 1280×720 image.
  • UI Slider: Added to the options panel so you can adjust the size limit between 320px and 3840px directly in the app.

what do perms look like in rebind.toml for a script

In rebind.toml, permissions are declared under the [runtime] table as a list of strings called permissions.

Rebind only gates two specific permissions:

  • "net": Access to the Net namespace (HTTP client, Net.Listen, WebSocket, and UDP).
  • "exec": Access to System.Exec and System.ExecDetached.

All other namespaces (Screen, File, HID, Input, Clipboard, Audio, etc.) have no permission checks.

Examples

1. Allow both network and shell execution

toml
[package]
name = "my-tool"
version = "1.0.0"
min_sdk = "3.0.0"

[runtime]
permissions = ["net", "exec"]

2. Allow only network access (blocks System.Exec)

toml
[runtime]
permissions = ["net"]

3. Explicitly declare no permissions needed

If your script doesn't need network or shell access (like a screen capture, key remap, or macro script), declare an empty list:

toml
[runtime]
permissions = []

Important rules to know

  • Allow-list behavior: The moment permissions is declared, the runtime switches to an allow-list mode. Any permission not explicitly in the list will throw a runtime error when called (e.g. System.Exec() requires 'exec' permission).
  • Omitted vs. Empty: If you omit the permissions key entirely, the package is granted all permissions by default. However, if you plan to publish the package to the Marketplace, rebind check and the registry will refuse it unless permissions is explicitly declared (even if just permissions = []).

how much of this is done permissions] target_process = ["PathOfExile.exe", "PathOfExileSteam.exe"] # HID output only when this window is focused network = ["poe.ninja", "api.rebind.gg"] # domain allowlist, nothing else screen = "target_window" # can't capture other apps clipboard = "read" files = "script_dir" # no access outside its own folder input_observe = "bound_keys" # sees only keys it binds, not everything typed

Here is the breakdown of what Rebind actually implements today versus what looks like a wishlist in that snippet:

1. target_process — Built-in (via targeting, not permissions)

  • Status: Fully supported.
  • How Rebind does it: It is not a permission key; it is standard runtime targeting under [runtime] in rebind.toml:
    toml
    [runtime]
    process = ["PathOfExile.exe", "PathOfExileSteam.exe"]
    When the targeted process is not focused, the script deactivates: its hooks, timers, and input processing stop running.

2. files = "script_dir" — Enforced by Sandbox Architecture

  • Status: Fully enforced, automatically.
  • How Rebind does it: Rebind does not need a permission flag for this because the entire File namespace is hard-sandboxed to the script directory by design. Any path traversal (like ../) or attempt to access outside folders throws path traversal not allowed at runtime.

3. input_observe = "bound_keys" — Supported by Default (Bind)

  • Status: Fully supported by API design.
  • How Rebind does it: When a script uses Bind(...) rather than defining global OnDown/OnUp hooks, Rebind only intercepts those exact declared keys at the OS level. It never captures or inspects other keystrokes. (Or, if defining OnDown/OnUp, setting key_block = false turns off exclusive capture).

What is NOT implemented (Wishlist / Not in SDK)

  • network = ["domain1", "domain2"] (Domain allowlisting):
    • Not supported. Permissions in Rebind are strictly binary flags (permissions = ["net"]). Once "net" is granted, the script can communicate with any URL or IP.
  • screen = "target_window" (Window-scoped capture):
    • Not supported. Screen.Capture and pixel sampling operate at the display or coordinate level across the virtual desktop. There is no OS-level window sandbox restricting pixel reads to only a specific window.
  • clipboard = "read" (Read/write granularity):
    • Not supported. The Clipboard namespace is ungated; if the script runs on Windows/macOS, it has access to both Clipboard.Get() and Clipboard.Set().

What that configuration actually translates to in rebind.toml:

To achieve as much of your goal as Rebind currently supports, your rebind.toml would look like this:

toml
[package]
name = "poe-overlay"
version = "1.0.0"
min_sdk = "3.4.1"

[runtime]
# 1. Target only PoE processes (script deactivates when tabbed out)
process = ["PathOfExile.exe", "PathOfExileSteam.exe"]

# 2. Grant network access (cannot restrict by domain)
#    Omitting "exec" ensures shell execution is blocked.
permissions = ["net"]

And in your code:

  • Use Bind("F5", ...) instead of OnDown so only your configured hotkeys are captured.
  • File operations remain securely locked inside the script's folder by the engine.

write a md spec of the unsupported perms that need to be added so i can add it to the backlog

RFC: Granular Script Permissions for rebind.toml

1. Summary

Rebind currently treats permissions as coarse binary switches (net, exec) while other capabilities are ungated (Clipboard, Screen). This specification proposes three additions to the permission model in rebind.toml:

  1. Network Domain Allowlisting (network = [...])
  2. Window-Scoped Screen Capture (screen = "target_window")
  3. Granular Clipboard Access (clipboard = "read" | "write" | ["read", "write"])

These controls limit data exfiltration risks and protect user privacy when running untrusted or marketplace community scripts.


2. Motivation

Security-sensitive game overlays, text utilities, and automation scripts often require partial access to external subsystems:

  • An item-pricing overlay needs to contact specific game APIs (e.g., poe.ninja), but should not have arbitrary outbound internet access.
  • An OCR or state-monitoring script needs to read pixels from the game client, but should never be able to capture sensitive browser tabs, private messages, or background windows.
  • A hotkey tool might need to read the user's clipboard to format text without possessing write access, or vice versa.

3. Detailed Design

3.1 Network Domain Allowlisting

Manifest Syntax (rebind.toml)

Replace or extend the current binary "net" permission with an explicit domain array:

toml
[runtime]
# Option A: Coarse permission (existing)
permissions = ["net"]

# Option B: Restricted domain allowlist (proposed)
[runtime.permissions]
network = [
  "poe.ninja",
  "*.poe.ninja",
  "api.rebind.gg"
]

Behavior & Enforcement

  • When network is specified as an array, the host network layer intercepts all outgoing requests across Net.Get, Net.Post, Net.Put, Net.Patch, Net.Delete, Net.Head, Net.Request, and Net.WSConnect.
  • Target URLs are parsed to extract the canonical hostname before DNS resolution.
  • Allowed host matching rules:
    • Exact match: "api.rebind.gg" matches only api.rebind.gg.
    • Subdomain wildcard: "*.poe.ninja" matches poe.ninja, api.poe.ninja, etc.
    • IP literals are blocked unless explicitly listed (e.g., "127.0.0.1").
  • Local bindings (Net.Listen, Net.WSListen, Net.UDPListen) are disallowed under domain-restricted mode unless "listen" or localhost is explicitly granted.
  • Violation: Attempting to contact an unlisted host raises:
    Net request to 'evil.com' blocked by network domain allowlist.

3.2 Window-Scoped Screen Capture

Manifest Syntax (rebind.toml)

Restrict visual inspection APIs (Screen.Capture, Screen.GetPixelColor, Screen.SearchForColor, Screen.FindImage) to only the process or window targeted by the script:

toml
[runtime]
process = ["PathOfExile.exe", "PathOfExileSteam.exe"]

[runtime.permissions]
screen = "target_window" # Options: "full" (default), "target_window", "none"

Behavior & Enforcement

  • "none": All Screen sampling calls fail immediately with a permission error.
  • "target_window":
    • Requires process, process_regex, window, or window_regex to be defined in [runtime].
    • When the targeted application is not active/focused, Screen sampling calls return nil or error.
    • Coordinate Translation: Screen reads are clamped or translated to the target window's client bounds. Pixels outside the targeted window boundaries return black (#000000) or raise an out-of-bounds error.
    • Capture Frame Isolation: On Windows (via PrintWindow/DWM capture) and macOS (via ScreenCaptureKit window-filtering), captures only composite the targeted window surface, excluding all occluding or underlying windows.
  • Violation: Calling Screen.Capture outside target bounds raises:
    Screen capture blocked: Script is restricted to target_window.

3.3 Granular Clipboard Access

Manifest Syntax (rebind.toml)

Control read and write capabilities independently:

toml
[runtime.permissions]
clipboard = "read" # Options: "read", "write", ["read", "write"], "none"

Behavior & Enforcement

  • "none": Both Clipboard.Get() and Clipboard.Set() fail.
  • "read":
    • Clipboard.Get() succeeds.
    • Clipboard.Set(...) raises a runtime permission error.
  • "write":
    • Clipboard.Set(...) succeeds.
    • Clipboard.Get() raises a runtime permission error.
  • ["read", "write"] or "full": Standard unrestricted behavior.
  • Violation: Calling a blocked clipboard method raises:
    Clipboard.Get() requires 'clipboard:read' permission.

4. Modeline Syntax Representation

For bare single-file scripts without a rebind.toml, represent these permissions using standard key-value modeline pairs:

luau
--[[
  rebind: min_sdk=3.8.0
  rebind: permission=clipboard:read
  rebind: permission=screen:target_window
  rebind: net_domain=poe.ninja net_domain=api.rebind.gg
]]

5. Backward Compatibility

  1. Existing Scripts: Scripts that omit [runtime.permissions] or define permissions = ["net"] retain legacy, unrestricted behavior for those subsystems.
  2. SDK Version Guard: These granular permissions require bumping min_sdk (e.g., 3.8.0). Older engines encountering these keys must fail validation at load time rather than silently widening the permission scope.
  3. Marketplace Validation: rebind check should inspect these fields and display the restricted bounds as security badges on marketplace listings (e.g., "Network: 2 domains", "Screen: Target Window Only").