@rebind.gg/mcp-server 0.1.4 → 0.1.6
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/README.md +52 -39
- package/package.json +2 -2
- package/src/index.ts +56 -11
- package/src/rebind.d.luau +698 -0
package/README.md
CHANGED
|
@@ -1,19 +1,17 @@
|
|
|
1
1
|
# @rebind.gg/mcp-server
|
|
2
2
|
|
|
3
|
-
Stdio MCP server that
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
(https://
|
|
8
|
-
(recommended) or `remote_access.lua` (protocol >= 1.1.0)
|
|
9
|
-
|
|
10
|
-
called
|
|
3
|
+
Stdio MCP server that turns [Rebind](https://rebind.gg) into a computer-use toolkit: screenshots, verified clicks, keyboard input, window control, and direct Luau scripting on the connected machine — driven over real HID, not synthetic OS events.
|
|
4
|
+
|
|
5
|
+
**Requirements**
|
|
6
|
+
|
|
7
|
+
- [Bun](https://bun.sh) >= 1.1 (the server runs via `bunx`)
|
|
8
|
+
- The [Rebind app](https://rebind.gg/download) running its Remote Access relay: `remote.luau` (recommended) or `remote_access.lua` (protocol >= 1.1.0)
|
|
9
|
+
|
|
10
|
+
> Older copies of `remote_access.lua` called `hid.press` outside a coroutine, so clicks silently failed. Use `remote.luau` or a current `remote_access.lua`.
|
|
11
11
|
|
|
12
12
|
## Install
|
|
13
13
|
|
|
14
|
-
One command writes the correct config for whichever clients you name — Claude
|
|
15
|
-
Code, Cursor, Codex, OpenCode, VS Code, Windsurf, Zed, and more — each in its
|
|
16
|
-
native format, via [`add-mcp`](https://github.com/neondatabase/add-mcp):
|
|
14
|
+
One command writes the correct config for whichever clients you name — Claude Code, Cursor, Codex, OpenCode, VS Code, Windsurf, Zed, and more — via [`add-mcp`](https://github.com/neondatabase/add-mcp):
|
|
17
15
|
|
|
18
16
|
```sh
|
|
19
17
|
npx add-mcp "bunx @rebind.gg/mcp-server" --name rebind \
|
|
@@ -21,13 +19,9 @@ npx add-mcp "bunx @rebind.gg/mcp-server" --name rebind \
|
|
|
21
19
|
-g -a claude-code -a cursor -a codex -a opencode
|
|
22
20
|
```
|
|
23
21
|
|
|
24
|
-
Drop `-a <agent>` for the clients you want, or pass `--all`. `-g` installs
|
|
25
|
-
globally; omit it for project-local config. Restart the client afterward.
|
|
26
|
-
|
|
27
|
-
Requires **Bun** (the server runs via `bunx`) and the **Rebind** app
|
|
28
|
-
(https://rebind.gg/download) running its Remote Access relay.
|
|
22
|
+
Drop `-a <agent>` for the clients you want, or pass `--all`. `-g` installs globally; omit it for project-local config. Restart the client afterward.
|
|
29
23
|
|
|
30
|
-
|
|
24
|
+
### Manual configuration
|
|
31
25
|
|
|
32
26
|
Any MCP client takes the stdio block directly:
|
|
33
27
|
|
|
@@ -43,33 +37,48 @@ Any MCP client takes the stdio block directly:
|
|
|
43
37
|
}
|
|
44
38
|
```
|
|
45
39
|
|
|
46
|
-
|
|
47
|
-
token** panel field on `remote.luau`, or `AUTH_TOKEN` on `remote_access.lua`).
|
|
48
|
-
|
|
49
|
-
Check the relay is reachable before wiring it up:
|
|
40
|
+
### Verify the relay is reachable
|
|
50
41
|
|
|
51
42
|
```sh
|
|
52
43
|
bunx @rebind.gg/mcp-server --selftest
|
|
53
44
|
```
|
|
54
45
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
click
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
46
|
+
Connects, takes a capture, and reports the display — the fastest way to catch the #1 first-run failure (relay not loaded).
|
|
47
|
+
|
|
48
|
+
## Tools
|
|
49
|
+
|
|
50
|
+
| Tool | What it does |
|
|
51
|
+
| --- | --- |
|
|
52
|
+
| `screenshot` | Capture a display (cursor marked with a crosshair). All coordinates the model emits are pixels in the most recent screenshot. |
|
|
53
|
+
| `screenshot_window` | Capture one window by title substring (or the active window) — smaller, cheaper, monitor-proof. |
|
|
54
|
+
| `zoom` | Re-capture a region of the last screenshot at native resolution, for small text. Read-only. |
|
|
55
|
+
| `click` | Move to a point and click (`left`/`right`/`middle`, optional double). Landing position is verified and corrected before pressing. |
|
|
56
|
+
| `move_mouse` | Move without clicking, with the same verification. |
|
|
57
|
+
| `type` | Type text into the focused element. |
|
|
58
|
+
| `key` | Press a key or combo, e.g. `Enter`, `LCtrl+L`, `LAlt+Tab`. |
|
|
59
|
+
| `scroll` | Scroll the wheel at the cursor (positive = up). |
|
|
60
|
+
| `run_lua` | Run a Luau script on the connected machine and return its `return` value as JSON — the fast path for any deterministic sequence (launch apps, place windows, shell commands, pixel search). |
|
|
61
|
+
| `lua_docs` | Full Luau SDK type definitions for `run_lua`. |
|
|
62
|
+
| `list_displays` / `list_windows` / `focus_window` / `active_window` | Display and window enumeration and control. |
|
|
63
|
+
| `get_cursor` / `wait` / `calibrate` | Cursor readback, pauses, and the mouse scale probe. |
|
|
64
|
+
|
|
65
|
+
## Configuration
|
|
66
|
+
|
|
67
|
+
| Env var | Default | Purpose |
|
|
68
|
+
| --- | --- | --- |
|
|
69
|
+
| `REBIND_URL` | `ws://127.0.0.1:19561` | Relay WebSocket URL. |
|
|
70
|
+
| `REBIND_TOKEN` | — | Required when the relay has an auth token set (the **Auth token** panel field on `remote.luau`, or `AUTH_TOKEN` on `remote_access.lua`). |
|
|
71
|
+
| `REBIND_AGENT_LOG` | off | Path to append one JSONL line per tool call (`{ts, tool, ok, latency_ms, note}`). No screenshot bytes, no user content. |
|
|
72
|
+
|
|
73
|
+
## How it works
|
|
74
|
+
|
|
75
|
+
**Verified clicks.** `click` and `move_mouse` reach an absolute screen point by reading the real OS cursor and sending relative HID deltas (which map 1:1 to pixels), correcting against the true cursor until it lands. This sidesteps the relay's own absolute move, whose delta comes from a cached cursor position that goes stale and flings the pointer to a screen edge.
|
|
76
|
+
|
|
77
|
+
**Calibration.** A mouse scale probe runs on the first `click`/`move_mouse`. If pointer ballistics are detected (enhance pointer precision, DPI mismatch), the probe reports it, since acceleration would break the 1:1 assumption. Re-run it any time with `calibrate`.
|
|
78
|
+
|
|
79
|
+
**One queue.** There is one physical cursor and keyboard, so tool calls are serialized: parallel calls from the model run one after another instead of interleaving HID input.
|
|
80
|
+
|
|
81
|
+
**One coordinate space.** All results are reported in the pixel space of the last screenshot — the same space the model emits — so no rescaling math ever falls on the model.
|
|
73
82
|
|
|
74
83
|
## Develop
|
|
75
84
|
|
|
@@ -77,3 +86,7 @@ model emits.
|
|
|
77
86
|
bun test packages/mcp-server/tests/
|
|
78
87
|
bun run --cwd packages/mcp-server typecheck
|
|
79
88
|
```
|
|
89
|
+
|
|
90
|
+
## License
|
|
91
|
+
|
|
92
|
+
MIT © [US Input Company](https://usinput.com)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rebind.gg/mcp-server",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
4
4
|
"description": "MCP server exposing Rebind as computer-use tools: screenshot, verified click, type, key, scroll, and window control over the Remote Access protocol.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
},
|
|
48
48
|
"dependencies": {
|
|
49
49
|
"@modelcontextprotocol/sdk": "^1.12.0",
|
|
50
|
-
"@rebind.gg/client-ts": "0.2.
|
|
50
|
+
"@rebind.gg/client-ts": "0.2.1",
|
|
51
51
|
"sharp": "^0.34.2",
|
|
52
52
|
"zod": "^3.25.0"
|
|
53
53
|
},
|
package/src/index.ts
CHANGED
|
@@ -53,7 +53,7 @@ async function main() {
|
|
|
53
53
|
|
|
54
54
|
const session = new Session(client);
|
|
55
55
|
|
|
56
|
-
const server = new McpServer({ name: "rebind", version: "0.1.
|
|
56
|
+
const server = new McpServer({ name: "rebind", version: "0.1.6" });
|
|
57
57
|
|
|
58
58
|
// REBIND_AGENT_LOG=<path>: opt-in telemetry — one JSONL line per tool call
|
|
59
59
|
// ({ts, tool, ok, latency_ms, note}). No screenshot bytes, no user content.
|
|
@@ -101,7 +101,8 @@ async function main() {
|
|
|
101
101
|
description:
|
|
102
102
|
"Capture a display and return it as an image. The cursor is marked with a red crosshair. " +
|
|
103
103
|
"All click/move coordinates you emit must be pixel coordinates in the MOST RECENT screenshot. " +
|
|
104
|
-
"After every action, take a new screenshot and verify the action had the intended effect before continuing; if not, correct and retry."
|
|
104
|
+
"After every action, take a new screenshot and verify the action had the intended effect before continuing; if not, correct and retry. " +
|
|
105
|
+
"Identify UI elements (labels, inputs, search boxes) before acting; prefer type/key over blind clicking.",
|
|
105
106
|
inputSchema: {
|
|
106
107
|
display: z
|
|
107
108
|
.number()
|
|
@@ -224,7 +225,8 @@ async function main() {
|
|
|
224
225
|
{
|
|
225
226
|
description:
|
|
226
227
|
"Capture a region of the last screenshot at full native resolution, for reading small text or inspecting small targets. " +
|
|
227
|
-
"READ-ONLY: click coordinates still refer to the last full screenshot, not the zoomed image."
|
|
228
|
+
"READ-ONLY: click coordinates still refer to the last full screenshot, not the zoomed image. " +
|
|
229
|
+
"Useful to check cursor-target alignment when a click missed.",
|
|
228
230
|
inputSchema: {
|
|
229
231
|
x: z
|
|
230
232
|
.number()
|
|
@@ -288,7 +290,8 @@ async function main() {
|
|
|
288
290
|
{
|
|
289
291
|
description:
|
|
290
292
|
"Move the mouse to a point in the last screenshot and click. The landing position is verified and corrected before pressing. " +
|
|
291
|
-
"Prefer keyboard shortcuts (the key tool) for fiddly widgets like address bars and dropdowns."
|
|
293
|
+
"Prefer keyboard shortcuts (the key tool) for fiddly widgets like address bars and dropdowns. " +
|
|
294
|
+
"Identify the target (read its label/text) before clicking, and confirm the effect with a screenshot after.",
|
|
292
295
|
inputSchema: {
|
|
293
296
|
x: z.number().describe("x in last-screenshot image pixels"),
|
|
294
297
|
y: z.number().describe("y in last-screenshot image pixels"),
|
|
@@ -314,7 +317,8 @@ async function main() {
|
|
|
314
317
|
"move_mouse",
|
|
315
318
|
{
|
|
316
319
|
description:
|
|
317
|
-
"Move the mouse to a point in the last screenshot without clicking."
|
|
320
|
+
"Move the mouse to a point in the last screenshot without clicking. " +
|
|
321
|
+
"If the response warns the cursor stopped short, take a fresh screenshot and retry.",
|
|
318
322
|
inputSchema: {
|
|
319
323
|
x: z.number().describe("x in last-screenshot image pixels"),
|
|
320
324
|
y: z.number().describe("y in last-screenshot image pixels"),
|
|
@@ -337,7 +341,9 @@ async function main() {
|
|
|
337
341
|
register(
|
|
338
342
|
"type",
|
|
339
343
|
{
|
|
340
|
-
description:
|
|
344
|
+
description:
|
|
345
|
+
"Type text into the focused element via the keyboard. " +
|
|
346
|
+
"Use LCtrl+A / LMeta+A (key tool) to select all first when replacing existing text.",
|
|
341
347
|
inputSchema: { text: z.string() },
|
|
342
348
|
},
|
|
343
349
|
async ({ text: t }) => {
|
|
@@ -353,7 +359,8 @@ async function main() {
|
|
|
353
359
|
{
|
|
354
360
|
description:
|
|
355
361
|
'Press a key or combo. Names: "Enter", "Escape", "Tab", "Backspace", arrows ("Up", "Down", "Left", "Right"), letters/digits, modifiers "LCtrl", "LAlt", "LShift", "LMeta". ' +
|
|
356
|
-
'Combos join with "+", e.g. "LCtrl+L" (focus address bar), "LCtrl+C", "LAlt+Tab".'
|
|
362
|
+
'Combos join with "+", e.g. "LCtrl+L" (focus address bar), "LCtrl+C", "LAlt+Tab". ' +
|
|
363
|
+
'Useful shortcuts: Space/PageDown/PageUp to scroll, LCtrl+F or LMeta+F to find text on the page, Escape to close dialogs.',
|
|
357
364
|
inputSchema: { combo: z.string() },
|
|
358
365
|
},
|
|
359
366
|
async ({ combo }) => {
|
|
@@ -367,7 +374,8 @@ async function main() {
|
|
|
367
374
|
"scroll",
|
|
368
375
|
{
|
|
369
376
|
description:
|
|
370
|
-
"Scroll the mouse wheel at the current cursor position. Positive = up, negative = down."
|
|
377
|
+
"Scroll the mouse wheel at the current cursor position. Positive = up, negative = down. " +
|
|
378
|
+
"Key shortcuts (Space, PageDown/PageUp, arrows) are often more reliable for page-level scrolling.",
|
|
371
379
|
inputSchema: { clicks: z.number().int().describe("wheel clicks") },
|
|
372
380
|
},
|
|
373
381
|
async ({ clicks }) => {
|
|
@@ -397,8 +405,31 @@ async function main() {
|
|
|
397
405
|
inputSchema: { handle: z.number() },
|
|
398
406
|
},
|
|
399
407
|
async ({ handle }) => {
|
|
400
|
-
|
|
401
|
-
|
|
408
|
+
// handle-based activation can raise without focusing on macOS; fall back
|
|
409
|
+
// to app-name activation (App.Activate, macOS-only, no-op elsewhere via
|
|
410
|
+
// pcall). Decided relay-side: this process may run on a different
|
|
411
|
+
// machine than the relay, so process.platform is the wrong signal.
|
|
412
|
+
const r = (await client.luaExec(`
|
|
413
|
+
local h = ${handle}
|
|
414
|
+
Window.Activate(h)
|
|
415
|
+
Sleep(150)
|
|
416
|
+
if Window.IsActive(h) then return { ok = true } end
|
|
417
|
+
local name
|
|
418
|
+
for _, w in ipairs(Window.List()) do
|
|
419
|
+
if w.handle == h then name = w.process; break end
|
|
420
|
+
end
|
|
421
|
+
if not name then return { ok = false, err = "window handle not found" } end
|
|
422
|
+
pcall(function() App.Activate(name) end)
|
|
423
|
+
Sleep(150)
|
|
424
|
+
return { ok = Window.IsActive(h), name = name }
|
|
425
|
+
`)) as { ok?: boolean; name?: string; err?: string };
|
|
426
|
+
if (r.ok)
|
|
427
|
+
return text(
|
|
428
|
+
`activated window ${handle}${r.name ? ` via app "${r.name}"` : ""}`,
|
|
429
|
+
);
|
|
430
|
+
return text(
|
|
431
|
+
`WARNING: window ${handle} ${r.err ?? "may not be focused"} — verify with active_window or a screenshot`,
|
|
432
|
+
);
|
|
402
433
|
},
|
|
403
434
|
);
|
|
404
435
|
|
|
@@ -445,7 +476,8 @@ async function main() {
|
|
|
445
476
|
"reliable, and it sidesteps multi-monitor guessing. Use it to: launch apps (`System.ExecDetached(\"cmd\", {\"/c\",\"start\",\"\",url})`), " +
|
|
446
477
|
"wait for and place windows on a known display (`local h=Window.Wait(title, ms); Window.Move(h, x, y, w, h)`), " +
|
|
447
478
|
"run shell commands (`System.Exec(cmd) -> {exit,stdout,stderr}`), find UI by color (`Screen.SearchForColor(region,hex)`), " +
|
|
448
|
-
"type, click, read pixels, manage processes. Namespaces: System, HID, Input, Screen, Window, Process, File, Clipboard, Net, Macro, Env, Log. " +
|
|
479
|
+
"type, click, read pixels, manage processes. Namespaces: System, HID, Input, Screen, Window, App, Process, File, Clipboard, Net, Macro, Env, Log; global Sleep(ms). " +
|
|
480
|
+
"Call `lua_docs` for exact signatures BEFORE writing nontrivial scripts — do not guess APIs. " +
|
|
449
481
|
"Fall back to `screenshot` only for genuinely visual reasoning the script cannot resolve. End the script with `return <value>` to get data back.",
|
|
450
482
|
inputSchema: {
|
|
451
483
|
source: z
|
|
@@ -461,6 +493,19 @@ async function main() {
|
|
|
461
493
|
},
|
|
462
494
|
);
|
|
463
495
|
|
|
496
|
+
register(
|
|
497
|
+
"lua_docs",
|
|
498
|
+
{
|
|
499
|
+
description:
|
|
500
|
+
"Return the full Luau SDK type definitions for run_lua: every namespace, function signature, and type. " +
|
|
501
|
+
"Read this before writing any nontrivial run_lua script instead of guessing APIs.",
|
|
502
|
+
},
|
|
503
|
+
// byte-identical copy of packages/lua-sdk/types/rebind.d.luau, shipped in
|
|
504
|
+
// the package; tests/lua-docs-sync.test.ts guards against drift
|
|
505
|
+
async () =>
|
|
506
|
+
text(await Bun.file(new URL("./rebind.d.luau", import.meta.url)).text()),
|
|
507
|
+
);
|
|
508
|
+
|
|
464
509
|
await server.connect(new StdioServerTransport());
|
|
465
510
|
// stdout carries the MCP protocol — log to stderr only
|
|
466
511
|
console.error(
|
|
@@ -0,0 +1,698 @@
|
|
|
1
|
+
-- rebind sdk type definitions for luau language server
|
|
2
|
+
-- provides autocomplete, hover docs, and type checking for all sdk namespaces.
|
|
3
|
+
-- reference this file in your .luaurc: { "languageMode": "strict", "paths": ["types"] }
|
|
4
|
+
|
|
5
|
+
-- handle types
|
|
6
|
+
|
|
7
|
+
export type TaskHandle = {
|
|
8
|
+
Cancel: (self: TaskHandle) -> (),
|
|
9
|
+
IsRunning: (self: TaskHandle) -> boolean,
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export type TimerHandle = {
|
|
13
|
+
Cancel: (self: TimerHandle) -> (),
|
|
14
|
+
Pause: (self: TimerHandle) -> (),
|
|
15
|
+
Resume: (self: TimerHandle) -> (),
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export type MacroHandle = {
|
|
19
|
+
Stop: (self: MacroHandle) -> (),
|
|
20
|
+
Pause: (self: MacroHandle) -> (),
|
|
21
|
+
Resume: (self: MacroHandle) -> (),
|
|
22
|
+
IsPlaying: (self: MacroHandle) -> boolean,
|
|
23
|
+
GetProgress: (self: MacroHandle) -> number,
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export type BindHandle = {
|
|
27
|
+
unbind: (self: BindHandle) -> (),
|
|
28
|
+
disable: (self: BindHandle) -> (),
|
|
29
|
+
enable: (self: BindHandle) -> (),
|
|
30
|
+
enabled: boolean,
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export type ServerHandle = {
|
|
34
|
+
port: number,
|
|
35
|
+
Stop: (self: ServerHandle) -> (),
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
-- WebSocket: server-side per-connection handle passed to OnConnect/OnMessage/OnClose.
|
|
39
|
+
-- `id` is a monotonic identifier unique to this connection.
|
|
40
|
+
export type WsClient = {
|
|
41
|
+
id: number,
|
|
42
|
+
Send: (self: WsClient, text: string) -> (),
|
|
43
|
+
SendBinary: (self: WsClient, bytes: string) -> (),
|
|
44
|
+
Close: (self: WsClient) -> (),
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
-- WebSocket: server handle returned by Net.WSListen.
|
|
48
|
+
export type WsServerHandle = {
|
|
49
|
+
port: number,
|
|
50
|
+
Broadcast: (self: WsServerHandle, text: string) -> (),
|
|
51
|
+
BroadcastBinary: (self: WsServerHandle, bytes: string) -> (),
|
|
52
|
+
ClientCount: (self: WsServerHandle) -> number,
|
|
53
|
+
Stop: (self: WsServerHandle) -> (),
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
-- WebSocket: outbound-connection handle returned by Net.WSConnect.
|
|
57
|
+
export type WsConnectHandle = {
|
|
58
|
+
Send: (self: WsConnectHandle, text: string) -> (),
|
|
59
|
+
SendBinary: (self: WsConnectHandle, bytes: string) -> (),
|
|
60
|
+
Close: (self: WsConnectHandle) -> (),
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
-- WebSocket: server event-handler table passed to Net.WSListen.
|
|
64
|
+
-- All fields are optional; handlers that are absent are never called.
|
|
65
|
+
export type WsListenHandlers = {
|
|
66
|
+
OnConnect: ((client: WsClient) -> ())?,
|
|
67
|
+
OnMessage: ((client: WsClient, payload: string, isBinary: boolean) -> ())?,
|
|
68
|
+
OnClose: ((client: WsClient) -> ())?,
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
-- WebSocket: client event-handler table passed to Net.WSConnect.
|
|
72
|
+
export type WsConnectHandlers = {
|
|
73
|
+
OnOpen: (() -> ())?,
|
|
74
|
+
OnMessage: ((payload: string, isBinary: boolean) -> ())?,
|
|
75
|
+
OnClose: (() -> ())?,
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export type PipeHandle = {
|
|
79
|
+
name: string,
|
|
80
|
+
size: number,
|
|
81
|
+
capacity: number,
|
|
82
|
+
Read: (self: PipeHandle) -> string?,
|
|
83
|
+
Write: (self: PipeHandle, data: string) -> (),
|
|
84
|
+
Close: (self: PipeHandle) -> (),
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
-- data types
|
|
88
|
+
|
|
89
|
+
export type WindowInfo = {
|
|
90
|
+
title: string,
|
|
91
|
+
process: string,
|
|
92
|
+
x: number,
|
|
93
|
+
y: number,
|
|
94
|
+
width: number,
|
|
95
|
+
height: number,
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export type WindowEntry = {
|
|
99
|
+
handle: number,
|
|
100
|
+
title: string,
|
|
101
|
+
process: string,
|
|
102
|
+
x: number,
|
|
103
|
+
y: number,
|
|
104
|
+
width: number,
|
|
105
|
+
height: number,
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export type WindowPos = {
|
|
109
|
+
x: number,
|
|
110
|
+
y: number,
|
|
111
|
+
width: number,
|
|
112
|
+
height: number,
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export type MousePos = {
|
|
116
|
+
x: number,
|
|
117
|
+
y: number,
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export type ModifierState = {
|
|
121
|
+
ctrl: boolean,
|
|
122
|
+
shift: boolean,
|
|
123
|
+
alt: boolean,
|
|
124
|
+
win: boolean,
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export type HttpResponse = {
|
|
128
|
+
status: number,
|
|
129
|
+
body: string,
|
|
130
|
+
headers: { [string]: string },
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
-- `body` may contain arbitrary bytes (Luau strings are byte strings).
|
|
134
|
+
export type HttpRequest = {
|
|
135
|
+
method: string,
|
|
136
|
+
path: string,
|
|
137
|
+
body: string,
|
|
138
|
+
headers: { [string]: string },
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
-- `body` may contain arbitrary bytes; set a Content-Type header for binary.
|
|
142
|
+
export type HttpResponseSpec = {
|
|
143
|
+
status: number?,
|
|
144
|
+
body: string?,
|
|
145
|
+
headers: { [string]: string }?,
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
export type HttpOptions = {
|
|
149
|
+
timeout: number?,
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export type HttpRequestOptions = {
|
|
153
|
+
method: string,
|
|
154
|
+
url: string,
|
|
155
|
+
body: string?,
|
|
156
|
+
headers: { [string]: string }?,
|
|
157
|
+
timeout: number?,
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
-- macro action types
|
|
161
|
+
|
|
162
|
+
export type MacroMoveAction = {
|
|
163
|
+
x: number,
|
|
164
|
+
y: number,
|
|
165
|
+
delay: number,
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
export type MacroExplicitAction = {
|
|
169
|
+
action: string,
|
|
170
|
+
code: string?,
|
|
171
|
+
dx: number?,
|
|
172
|
+
dy: number?,
|
|
173
|
+
x: number?,
|
|
174
|
+
y: number?,
|
|
175
|
+
text: string?,
|
|
176
|
+
amount: number?,
|
|
177
|
+
holdMs: number?,
|
|
178
|
+
charDelay: number?,
|
|
179
|
+
delay: number,
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
export type MacroAction = MacroMoveAction | MacroExplicitAction
|
|
183
|
+
|
|
184
|
+
-- ui widget option types
|
|
185
|
+
|
|
186
|
+
export type ToggleOpts = {
|
|
187
|
+
label: string?,
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
export type SliderOpts = {
|
|
191
|
+
label: string?,
|
|
192
|
+
min: number?,
|
|
193
|
+
max: number?,
|
|
194
|
+
step: number?,
|
|
195
|
+
suffix: string?,
|
|
196
|
+
tooltip: string?,
|
|
197
|
+
group: string?,
|
|
198
|
+
tab: string?,
|
|
199
|
+
showIf: string?,
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
export type KeybindOpts = {
|
|
203
|
+
label: string?,
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
export type SelectOpts = {
|
|
207
|
+
label: string?,
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
export type TextOpts = {
|
|
211
|
+
label: string?,
|
|
212
|
+
placeholder: string?,
|
|
213
|
+
maxLength: number?,
|
|
214
|
+
tooltip: string?,
|
|
215
|
+
group: string?,
|
|
216
|
+
tab: string?,
|
|
217
|
+
showIf: string?,
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
export type ColorOpts = {
|
|
221
|
+
label: string?,
|
|
222
|
+
tooltip: string?,
|
|
223
|
+
group: string?,
|
|
224
|
+
tab: string?,
|
|
225
|
+
showIf: string?,
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
export type RecordOpts = {
|
|
229
|
+
ignore_mouse: boolean?,
|
|
230
|
+
ignore_keyboard: boolean?,
|
|
231
|
+
precision: string?,
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
-- ui proxy: returned by UI.Schema, supports dynamic field access
|
|
235
|
+
-- cfg.key reads the current value, cfg.key = value writes it
|
|
236
|
+
export type UiProxy = { [string]: any }
|
|
237
|
+
|
|
238
|
+
-- bind config for table-style binding
|
|
239
|
+
export type BindConfig = {
|
|
240
|
+
when: (() -> boolean)?,
|
|
241
|
+
action: (() -> boolean?)?,
|
|
242
|
+
release: (() -> ())?,
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
-- runtime identity table
|
|
246
|
+
export type RebindInfo = {
|
|
247
|
+
min_sdk: string,
|
|
248
|
+
tick_rate: number,
|
|
249
|
+
version: string,
|
|
250
|
+
name: string,
|
|
251
|
+
runtime_uuid: string,
|
|
252
|
+
id: string?,
|
|
253
|
+
instance: string,
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
-- global functions
|
|
257
|
+
|
|
258
|
+
declare function Run(fn: () -> ()): TaskHandle
|
|
259
|
+
-- RunAsync was removed. Use Run() directly.
|
|
260
|
+
declare function Sleep(ms: number): ()
|
|
261
|
+
declare function After(ms: number, fn: () -> ()): TaskHandle
|
|
262
|
+
declare function Async(fn: (...any) -> ...any): (...any) -> ...any
|
|
263
|
+
declare function print(...: any): ()
|
|
264
|
+
declare function require(module: string): any
|
|
265
|
+
|
|
266
|
+
-- global tables
|
|
267
|
+
|
|
268
|
+
declare _REBIND: RebindInfo
|
|
269
|
+
|
|
270
|
+
-- system namespace
|
|
271
|
+
|
|
272
|
+
export type ExecOptions = {
|
|
273
|
+
timeout: number?,
|
|
274
|
+
cwd: string?,
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
export type ExecResult = {
|
|
278
|
+
exit: number,
|
|
279
|
+
stdout: string,
|
|
280
|
+
stderr: string,
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
export type ExecDetachedOptions = {
|
|
284
|
+
cwd: string?,
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
declare System: {
|
|
288
|
+
Time: () -> number,
|
|
289
|
+
Mouse: () -> (number, number),
|
|
290
|
+
Screen: () -> (number, number),
|
|
291
|
+
Window: () -> WindowInfo,
|
|
292
|
+
Exec: (cmd: string, options: ExecOptions?) -> ExecResult,
|
|
293
|
+
ExecDetached: (cmd: string, args: { string }?, options: ExecDetachedOptions?) -> number,
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
-- hid namespace
|
|
297
|
+
|
|
298
|
+
declare HID: {
|
|
299
|
+
Down: (code: string) -> (),
|
|
300
|
+
Up: (code: string) -> (),
|
|
301
|
+
Press: (code: string, holdMs: number?) -> (),
|
|
302
|
+
-- fire a chord in one synchronous call (press L→R, release R→L). no sleep,
|
|
303
|
+
-- so callable directly from a Bind action / OnDown. modifier tokens accept
|
|
304
|
+
-- macOS aliases: "cmd", "opt"/"option", plus "ctrl"/"shift"/"alt"/"win".
|
|
305
|
+
Combo: (code: string) -> (),
|
|
306
|
+
-- instant whole-string insertion (native; no coroutine). For a human-like
|
|
307
|
+
-- per-character typewriter effect use Typewriter (coroutine-only).
|
|
308
|
+
Type: (text: string) -> (),
|
|
309
|
+
Typewriter: (text: string, delayMs: number?) -> (),
|
|
310
|
+
Move: (dx: number, dy: number) -> (),
|
|
311
|
+
MoveTo: (x: number, y: number) -> (),
|
|
312
|
+
Scroll: (amount: number) -> (),
|
|
313
|
+
SetMouseMode: (mode: string) -> (),
|
|
314
|
+
GetMouseMode: () -> string,
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
-- input namespace
|
|
318
|
+
|
|
319
|
+
declare Input: {
|
|
320
|
+
IsDown: (code: string) -> boolean,
|
|
321
|
+
GetDuration: (code: string) -> number,
|
|
322
|
+
GetActiveKeys: () -> { string },
|
|
323
|
+
GetMousePos: () -> MousePos,
|
|
324
|
+
GetModifiers: () -> ModifierState,
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
-- ui namespace
|
|
328
|
+
|
|
329
|
+
declare UI: {
|
|
330
|
+
Schema: (descriptors: { [string]: any }) -> UiProxy,
|
|
331
|
+
Toggle: (default: boolean, opts: ToggleOpts?) -> any,
|
|
332
|
+
Slider: (default: number, opts: SliderOpts?) -> any,
|
|
333
|
+
Keybind: (default: string, opts: KeybindOpts?) -> any,
|
|
334
|
+
Select: (default: string, choices: { string }, opts: SelectOpts?) -> any,
|
|
335
|
+
Text: (default: string, opts: TextOpts?) -> any,
|
|
336
|
+
Color: (default: string, opts: ColorOpts?) -> any,
|
|
337
|
+
Get: (id: string) -> any,
|
|
338
|
+
Set: (id: string, value: any) -> (),
|
|
339
|
+
GetAll: () -> { [string]: any },
|
|
340
|
+
GetSchema: () -> { any },
|
|
341
|
+
Notify: (text: string, variant: string?) -> (),
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
-- bind namespace (callable table)
|
|
345
|
+
|
|
346
|
+
declare Bind: typeof(setmetatable({} :: {
|
|
347
|
+
Toggle: (key: string, uiId: string) -> BindHandle,
|
|
348
|
+
Remap: (from: string, to: string) -> BindHandle,
|
|
349
|
+
}, {} :: {
|
|
350
|
+
__call: (self: any, key: string, config: (() -> boolean?) | BindConfig) -> BindHandle,
|
|
351
|
+
}))
|
|
352
|
+
|
|
353
|
+
-- timer namespace
|
|
354
|
+
|
|
355
|
+
declare Timer: {
|
|
356
|
+
After: (ms: number, callback: () -> ()) -> TimerHandle,
|
|
357
|
+
Every: (ms: number, callback: () -> ()) -> TimerHandle,
|
|
358
|
+
CancelAll: () -> (),
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
-- macro namespace
|
|
362
|
+
|
|
363
|
+
declare Macro: {
|
|
364
|
+
Play: (macro: { MacroAction }, speed: number?, mode: string?) -> MacroHandle,
|
|
365
|
+
StopAll: () -> (),
|
|
366
|
+
Record: (options: RecordOpts?) -> (),
|
|
367
|
+
Finish: () -> { MacroAction },
|
|
368
|
+
Stream: (macro: { MacroAction }) -> (),
|
|
369
|
+
Abort: () -> (),
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
-- math namespace
|
|
373
|
+
|
|
374
|
+
declare Math: {
|
|
375
|
+
Random: (min: number, max: number) -> number,
|
|
376
|
+
Gaussian: (mean: number, stdDev: number) -> number,
|
|
377
|
+
Scale: (macro: { MacroAction }, xFactor: number, yFactor: number) -> { MacroAction },
|
|
378
|
+
Spline: (macro: { MacroAction }, tension: number) -> { MacroAction },
|
|
379
|
+
Resample: (macro: { MacroAction }, intervalMs: number) -> { MacroAction },
|
|
380
|
+
TimeComp: (macro: { MacroAction }, targetMs: number) -> { MacroAction },
|
|
381
|
+
Interpolate: (macro: { MacroAction }, intervalMs: number, mode: string?) -> { MacroAction },
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
-- log namespace
|
|
385
|
+
|
|
386
|
+
declare Log: {
|
|
387
|
+
Info: (msg: string) -> (),
|
|
388
|
+
Warn: (msg: string) -> (),
|
|
389
|
+
Error: (msg: string) -> (),
|
|
390
|
+
Debug: (msg: string) -> (),
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
-- json namespace
|
|
394
|
+
|
|
395
|
+
declare JSON: {
|
|
396
|
+
Parse: (s: string) -> any,
|
|
397
|
+
Stringify: (value: any) -> string,
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
-- process namespace
|
|
401
|
+
|
|
402
|
+
export type ProcessEntry = {
|
|
403
|
+
pid: number,
|
|
404
|
+
name: string,
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
declare Process: {
|
|
408
|
+
Exists: (name: string) -> number?,
|
|
409
|
+
List: (name: string?) -> { ProcessEntry },
|
|
410
|
+
Kill: (pid: number) -> boolean,
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
-- screen namespace
|
|
414
|
+
|
|
415
|
+
export type PixelMatch = {
|
|
416
|
+
x: number,
|
|
417
|
+
y: number,
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
export type MonitorEntry = {
|
|
421
|
+
index: number,
|
|
422
|
+
x: number,
|
|
423
|
+
y: number,
|
|
424
|
+
width: number,
|
|
425
|
+
height: number,
|
|
426
|
+
primary: boolean,
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
declare Screen: {
|
|
430
|
+
GetPixelColor: (x: number?, y: number?) -> string,
|
|
431
|
+
SearchForColor: (region: {number}, color: string, tolerance: number?) -> PixelMatch?,
|
|
432
|
+
List: () -> { MonitorEntry },
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
-- window namespace
|
|
436
|
+
|
|
437
|
+
declare Window: {
|
|
438
|
+
Find: (title: string) -> number?,
|
|
439
|
+
List: (title: string?) -> { WindowEntry },
|
|
440
|
+
GetTitle: (handle: number?) -> string,
|
|
441
|
+
GetClass: (handle: number?) -> string,
|
|
442
|
+
GetPos: (handle: number?) -> WindowPos,
|
|
443
|
+
GetPID: (handle: number?) -> number,
|
|
444
|
+
Activate: (handle: number) -> (),
|
|
445
|
+
Move: (handle: number, x: number?, y: number?, width: number?, height: number?) -> (),
|
|
446
|
+
SetAlwaysOnTop: (handle: number, enabled: boolean) -> (),
|
|
447
|
+
SetTransparency: (handle: number, alpha: number) -> (),
|
|
448
|
+
SetTitle: (handle: number, title: string) -> (),
|
|
449
|
+
Minimize: (handle: number?) -> (),
|
|
450
|
+
Maximize: (handle: number?) -> (),
|
|
451
|
+
Restore: (handle: number?) -> (),
|
|
452
|
+
Hide: (handle: number?) -> (),
|
|
453
|
+
Show: (handle: number?) -> (),
|
|
454
|
+
Close: (handle: number?) -> (),
|
|
455
|
+
Kill: (handle: number?) -> (),
|
|
456
|
+
IsVisible: (handle: number) -> boolean,
|
|
457
|
+
IsActive: (handle: number?) -> boolean,
|
|
458
|
+
Wait: (title: string, timeout: number?) -> number?,
|
|
459
|
+
WaitActive: (title: string, timeout: number?) -> boolean,
|
|
460
|
+
WaitClose: (title: string, timeout: number?) -> boolean,
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
-- app namespace: application-level control (Keyboard Maestro's Application
|
|
464
|
+
-- Control). names match case-insensitively by app display name. Front/IsRunning/
|
|
465
|
+
-- Activate are permission-free; Hide/Quit/IsHidden drive an AppleEvent and
|
|
466
|
+
-- prompt for macOS Automation permission on first use.
|
|
467
|
+
|
|
468
|
+
export type AppInfo = {
|
|
469
|
+
name: string,
|
|
470
|
+
pid: number,
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
declare App: {
|
|
474
|
+
Front: () -> AppInfo?,
|
|
475
|
+
IsFront: (name: string) -> boolean,
|
|
476
|
+
IsRunning: (name: string) -> boolean,
|
|
477
|
+
IsHidden: (name: string) -> boolean,
|
|
478
|
+
Activate: (name: string) -> (),
|
|
479
|
+
Hide: (name: string) -> (),
|
|
480
|
+
Quit: (name: string) -> (),
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
-- net namespace
|
|
484
|
+
|
|
485
|
+
declare Net: {
|
|
486
|
+
Get: (url: string, headers: { [string]: string }?, options: HttpOptions?) -> HttpResponse,
|
|
487
|
+
Post: (url: string, body: string, headers: { [string]: string }?, options: HttpOptions?) -> HttpResponse,
|
|
488
|
+
Put: (url: string, body: string, headers: { [string]: string }?, options: HttpOptions?) -> HttpResponse,
|
|
489
|
+
Patch: (url: string, body: string, headers: { [string]: string }?, options: HttpOptions?) -> HttpResponse,
|
|
490
|
+
Delete: (url: string, headers: { [string]: string }?, options: HttpOptions?) -> HttpResponse,
|
|
491
|
+
Head: (url: string, headers: { [string]: string }?, options: HttpOptions?) -> HttpResponse,
|
|
492
|
+
Request: (options: HttpRequestOptions) -> HttpResponse,
|
|
493
|
+
Listen: (port: number, handler: (request: HttpRequest) -> HttpResponseSpec | string) -> ServerHandle,
|
|
494
|
+
WSListen: (port: number, handlers: WsListenHandlers) -> WsServerHandle,
|
|
495
|
+
WSConnect: (url: string, handlers: WsConnectHandlers) -> WsConnectHandle,
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
-- pipe namespace
|
|
499
|
+
|
|
500
|
+
declare Pipe: {
|
|
501
|
+
Open: (name: string, options: { size: number? }?) -> PipeHandle,
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
-- file namespace
|
|
505
|
+
|
|
506
|
+
declare File: {
|
|
507
|
+
Read: (path: string) -> string,
|
|
508
|
+
ReadBytes: (path: string) -> string,
|
|
509
|
+
Write: (path: string, content: string) -> (),
|
|
510
|
+
Append: (path: string, content: string) -> (),
|
|
511
|
+
Exists: (path: string) -> boolean,
|
|
512
|
+
Delete: (path: string) -> boolean,
|
|
513
|
+
List: (path: string?) -> { string },
|
|
514
|
+
MkDir: (path: string) -> boolean,
|
|
515
|
+
RmDir: (path: string) -> (),
|
|
516
|
+
ReadJSON: (path: string) -> any,
|
|
517
|
+
WriteJSON: (path: string, value: any) -> (),
|
|
518
|
+
GetScriptDir: () -> string,
|
|
519
|
+
GetSize: (path: string) -> number,
|
|
520
|
+
GetTime: (path: string) -> number,
|
|
521
|
+
Copy: (src: string, dst: string) -> (),
|
|
522
|
+
Move: (src: string, dst: string) -> (),
|
|
523
|
+
IsDir: (path: string) -> boolean,
|
|
524
|
+
IsFile: (path: string) -> boolean,
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
-- audio namespace
|
|
528
|
+
|
|
529
|
+
export type PlayOptions = {
|
|
530
|
+
volume: number?,
|
|
531
|
+
loop: boolean?,
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
export type SoundHandle = {
|
|
535
|
+
Stop: (self: SoundHandle) -> (),
|
|
536
|
+
Pause: (self: SoundHandle) -> (),
|
|
537
|
+
Resume: (self: SoundHandle) -> (),
|
|
538
|
+
IsPlaying: (self: SoundHandle) -> boolean,
|
|
539
|
+
SetVolume: (self: SoundHandle, vol: number) -> (),
|
|
540
|
+
GetVolume: (self: SoundHandle) -> number,
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
declare Audio: {
|
|
544
|
+
Beep: () -> (),
|
|
545
|
+
Play: (path: string, options: PlayOptions?) -> SoundHandle,
|
|
546
|
+
StopAll: () -> (),
|
|
547
|
+
SetMasterVolume: (vol: number) -> (),
|
|
548
|
+
GetMasterVolume: () -> number,
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
-- dialog namespace
|
|
552
|
+
|
|
553
|
+
export type DialogMessageOptions = {
|
|
554
|
+
title: string?,
|
|
555
|
+
level: string?,
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
export type DialogFileFilter = {
|
|
559
|
+
name: string,
|
|
560
|
+
extensions: { string },
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
export type DialogFileOptions = {
|
|
564
|
+
title: string?,
|
|
565
|
+
location: string?,
|
|
566
|
+
filters: { DialogFileFilter }?,
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
declare Dialog: {
|
|
570
|
+
Message: (text: string, options: DialogMessageOptions?) -> (),
|
|
571
|
+
Confirm: (text: string, options: DialogMessageOptions?) -> boolean,
|
|
572
|
+
OpenFile: (options: DialogFileOptions?) -> string?,
|
|
573
|
+
OpenDir: (options: DialogFileOptions?) -> string?,
|
|
574
|
+
SaveFile: (options: DialogFileOptions?) -> string?,
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
-- clipboard namespace
|
|
578
|
+
|
|
579
|
+
declare Clipboard: {
|
|
580
|
+
Get: () -> string?,
|
|
581
|
+
Set: (text: string) -> (),
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
-- script namespace
|
|
585
|
+
|
|
586
|
+
declare Script: {
|
|
587
|
+
Exit: (reason: string?) -> (),
|
|
588
|
+
Reload: () -> (),
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
-- regex namespace
|
|
592
|
+
|
|
593
|
+
export type RegexMatch = {
|
|
594
|
+
match: string,
|
|
595
|
+
captures: { string },
|
|
596
|
+
start: number,
|
|
597
|
+
finish: number,
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
declare Regex: {
|
|
601
|
+
IsMatch: (text: string, pattern: string) -> boolean,
|
|
602
|
+
Find: (text: string, pattern: string) -> RegexMatch?,
|
|
603
|
+
FindAll: (text: string, pattern: string) -> { RegexMatch },
|
|
604
|
+
Replace: (text: string, pattern: string, replacement: string) -> string,
|
|
605
|
+
ReplaceAll: (text: string, pattern: string, replacement: string) -> string,
|
|
606
|
+
Split: (text: string, pattern: string) -> { string },
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
-- config namespace
|
|
610
|
+
|
|
611
|
+
declare Config: {
|
|
612
|
+
ParseTOML: (text: string) -> { [string]: any },
|
|
613
|
+
ToTOML: (value: { [string]: any }) -> string,
|
|
614
|
+
ReadTOML: (path: string) -> { [string]: any },
|
|
615
|
+
WriteTOML: (path: string, value: { [string]: any }) -> (),
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
-- hash namespace
|
|
619
|
+
|
|
620
|
+
declare Hash: {
|
|
621
|
+
MD5: (data: string) -> string,
|
|
622
|
+
SHA1: (data: string) -> string,
|
|
623
|
+
SHA256: (data: string) -> string,
|
|
624
|
+
SHA512: (data: string) -> string,
|
|
625
|
+
CRC32: (data: string) -> number,
|
|
626
|
+
HMAC: (algo: string, key: string, data: string) -> string,
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
-- codec namespace
|
|
630
|
+
|
|
631
|
+
declare Codec: {
|
|
632
|
+
Base64: (data: string) -> string,
|
|
633
|
+
Base64Decode: (str: string) -> string,
|
|
634
|
+
Hex: (data: string) -> string,
|
|
635
|
+
HexDecode: (str: string) -> string,
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
-- env namespace
|
|
639
|
+
|
|
640
|
+
declare Env: {
|
|
641
|
+
Get: (name: string) -> string?,
|
|
642
|
+
Set: (name: string, value: string) -> (),
|
|
643
|
+
Home: () -> string?,
|
|
644
|
+
Config: () -> string?,
|
|
645
|
+
Data: () -> string?,
|
|
646
|
+
Desktop: () -> string?,
|
|
647
|
+
Documents: () -> string?,
|
|
648
|
+
Downloads: () -> string?,
|
|
649
|
+
AppData: () -> string?,
|
|
650
|
+
Temp: () -> string?,
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
-- registry namespace (windows only)
|
|
654
|
+
|
|
655
|
+
declare Registry: {
|
|
656
|
+
Read: (keyPath: string, valueName: string) -> string | number,
|
|
657
|
+
Write: (keyPath: string, type: string, valueName: string, value: any) -> (),
|
|
658
|
+
DeleteValue: (keyPath: string, valueName: string) -> (),
|
|
659
|
+
DeleteKey: (keyPath: string) -> (),
|
|
660
|
+
CreateKey: (keyPath: string) -> (),
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
-- valid key names for input hooks (OnDown, OnUp):
|
|
664
|
+
--
|
|
665
|
+
-- letters: A-Z
|
|
666
|
+
-- numbers: 0-9
|
|
667
|
+
-- function: F1-F12
|
|
668
|
+
-- mouse: Mouse1 (left), Mouse2 (right), Mouse3 (middle), Mouse4, Mouse5
|
|
669
|
+
-- modifiers: LCtrl, RCtrl, LShift, RShift, LAlt, RAlt, LWin, RWin
|
|
670
|
+
-- navigation: Up, Down, Left, Right, Home, End, PageUp, PageDown, Insert, Delete
|
|
671
|
+
-- editing: Backspace, Tab, Enter, Space, Escape
|
|
672
|
+
-- punctuation: Minus, Equal, LeftBrace, RightBrace, Backslash, Semicolon,
|
|
673
|
+
-- Apostrophe, Grave, Comma, Period, Slash
|
|
674
|
+
-- locks: CapsLock, ScrollLock, NumLock
|
|
675
|
+
-- system: PrintScreen, Pause, Menu
|
|
676
|
+
-- numpad: Kp0-Kp9, KpPlus, KpMinus, KpMultiply, KpDivide, KpEnter, KpDot
|
|
677
|
+
--
|
|
678
|
+
-- HID output only (HID.Down, HID.Press, etc.):
|
|
679
|
+
-- function: F13-F24
|
|
680
|
+
-- media: MediaNext, MediaPrev, MediaStop, MediaPlay, VolumeUp, VolumeDown, Mute
|
|
681
|
+
-- aliases: Numpad0-9, NP0-9, NPAdd, NPSubtract, NPMultiply, NPDivide, NPEnter,
|
|
682
|
+
-- NPDecimal, Ctrl, Shift, Alt, Win, Meta, Del, PgUp, PgDn, etc.
|
|
683
|
+
|
|
684
|
+
-- hooks: declare these as global functions in your script.
|
|
685
|
+
-- uncomment the ones you use; the runtime calls them when events occur.
|
|
686
|
+
|
|
687
|
+
-- declare function OnStart(): ()
|
|
688
|
+
-- declare function OnStop(): ()
|
|
689
|
+
-- declare function OnFocus(window: WindowInfo): ()
|
|
690
|
+
-- declare function OnBlur(window: WindowInfo): ()
|
|
691
|
+
-- declare function OnTick(dtMs: number): () -- ms elapsed since the previous OnTick (0 on the first)
|
|
692
|
+
-- declare function OnDown(key: string): boolean?
|
|
693
|
+
-- declare function OnUp(key: string, durationMs: number): boolean?
|
|
694
|
+
-- declare function OnMove(dx: number, dy: number): boolean? -- return value only used with mouse_block=true (hardware mode only)
|
|
695
|
+
-- declare function OnScroll(delta: number): boolean?
|
|
696
|
+
-- declare function OnScrollH(delta: number): boolean?
|
|
697
|
+
-- declare function OnError(): ()
|
|
698
|
+
-- declare function OnReload(): ()
|