@vashp2029/glovebox 0.3.0 → 0.3.2
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/CHANGELOG.md +11 -0
- package/README.md +5 -3
- package/SECURITY.md +6 -4
- package/docs/api.md +8 -4
- package/docs/design.md +2 -2
- package/native/macos/GloveboxHelper.swift +16 -9
- package/package.json +2 -1
- package/src/config.mjs +1 -1
- package/src/macos-helper.mjs +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.3.2 (2026-11-03)
|
|
4
|
+
|
|
5
|
+
- List glovebox in the official MCP Registry. No change to behavior.
|
|
6
|
+
|
|
7
|
+
## 0.3.1 (2026-11-03)
|
|
8
|
+
|
|
9
|
+
- Fix: the drawn agent cursor now glides to every action. Its animation never
|
|
10
|
+
moved the window, so it froze after the first action, and launching the helper
|
|
11
|
+
hidden could keep it from appearing at all.
|
|
12
|
+
- Add a demo to the README.
|
|
13
|
+
|
|
3
14
|
## 0.3.0 (2026-11-03)
|
|
4
15
|
|
|
5
16
|
- First npm release, as `@vashp2029/glovebox`. CI runs the unit tests on every
|
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
**Computer use for coding agents on macOS: one JavaScript call per step,
|
|
9
9
|
accessibility diffs instead of screenshots, and your screen stays yours.**
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+

|
|
12
12
|
|
|
13
13
|
```js
|
|
14
14
|
const calc = await gb.getApp("Calculator");
|
|
@@ -164,8 +164,10 @@ OpenAI's actual runtime and already have the ChatGPT app (lcu).
|
|
|
164
164
|
The first time a session touches an app, you get a dialog: Allow for This
|
|
165
165
|
Session, Always Allow, or Deny. Terminals, password managers, System Settings,
|
|
166
166
|
and a few others are blocked unless you run `glovebox allow <bundle id>`; the
|
|
167
|
-
list is in [SECURITY.md](SECURITY.md#blocked-apps).
|
|
168
|
-
stops
|
|
167
|
+
list is in [SECURITY.md](SECURITY.md#blocked-apps). A script that had to bring
|
|
168
|
+
an app forward stops if you switch away. Scripts running in the background keep
|
|
169
|
+
going while you use other apps, and Escape stops any script if you grant Input
|
|
170
|
+
Monitoring. Every action is
|
|
169
171
|
logged to `~/.glovebox/actions.log`.
|
|
170
172
|
|
|
171
173
|
An approved app is approved for everything in it: allowing a browser lets the
|
package/SECURITY.md
CHANGED
|
@@ -14,10 +14,12 @@ computer. Treat it with the same care as giving someone remote control.
|
|
|
14
14
|
(see the list below). An agent with terminal access could otherwise use the
|
|
15
15
|
GUI to run commands its sandbox would not allow. An app on the `deny` list
|
|
16
16
|
is refused even if it is also allowed.
|
|
17
|
-
- **Taking over stops a script.** If
|
|
18
|
-
|
|
19
|
-
the
|
|
20
|
-
|
|
17
|
+
- **Taking over stops a script.** If a script had to bring an app forward and
|
|
18
|
+
you switch away, the script stops instead of taking focus back. A script
|
|
19
|
+
working in the background keeps running while you use other apps, so switching
|
|
20
|
+
apps does not stop it. With the optional Input Monitoring permission, pressing
|
|
21
|
+
Escape stops any script (glovebox marks its own key events, so its own Escapes
|
|
22
|
+
do not count).
|
|
21
23
|
- **Menu-bar item.** While an agent is connected, Glovebox Helper shows a
|
|
22
24
|
menu-bar item listing each session and its approved apps. Stop Running
|
|
23
25
|
Scripts stops every running script. Revoke Session Approvals clears the
|
package/docs/api.md
CHANGED
|
@@ -119,10 +119,11 @@ windows).
|
|
|
119
119
|
|
|
120
120
|
The first time a session touches an app, the user sees a dialog: Allow for
|
|
121
121
|
This Session, Always Allow, or Deny. Terminals, password managers, and System
|
|
122
|
-
Settings are blocked unless the user runs `glovebox allow <app>`. If
|
|
123
|
-
|
|
124
|
-
"Stopped: ..." message.
|
|
125
|
-
|
|
122
|
+
Settings are blocked unless the user runs `glovebox allow <app>`. If a script
|
|
123
|
+
brought an app forward and the user switches away, the script stops with a
|
|
124
|
+
"Stopped: ..." message. Background scripts keep running while the user works in
|
|
125
|
+
other apps. Escape stops any script, but only when the user has granted Input
|
|
126
|
+
Monitoring. Do not continue GUI work until the user asks.
|
|
126
127
|
On the foreground route a script brings an app forward at most once per call.
|
|
127
128
|
Every action is appended to `~/.glovebox/actions.log` (typed text is logged
|
|
128
129
|
as a length only).
|
|
@@ -134,6 +135,9 @@ as a length only).
|
|
|
134
135
|
word you type can land in its field. Keep the time the menu is open short: open
|
|
135
136
|
it and pick the item in one script, with no read in between. A dedicated
|
|
136
137
|
`app.select(popup, item)` is planned.
|
|
138
|
+
- **Window controls during background typing.** A target window can show active
|
|
139
|
+
window controls while it receives background keys, even though your app stays
|
|
140
|
+
frontmost and keeps your keyboard.
|
|
137
141
|
- **One-node trees.** Remote desktops such as Citrix expose a single accessibility
|
|
138
142
|
node, so work there runs on screenshots and pixel clicks.
|
|
139
143
|
|
package/docs/design.md
CHANGED
|
@@ -158,8 +158,8 @@ Computer use can click anything, so approval is part of the product:
|
|
|
158
158
|
Editor, Automator, and the helper itself are blocked by default and never
|
|
159
159
|
offered in a dialog. Only an explicit `glovebox allow` unlocks one. The
|
|
160
160
|
full list is in `SECURITY.md`.
|
|
161
|
-
- Switching
|
|
162
|
-
forward at most once per call; if the app is no longer in front later in
|
|
161
|
+
- Switching away stops a script on the foreground route; background scripts
|
|
162
|
+
keep running. A script brings an app forward at most once per call; if the app is no longer in front later in
|
|
163
163
|
the same call, the user took over, and the script stops rather than taking
|
|
164
164
|
focus back. (An earlier version re-activated before every key and fought
|
|
165
165
|
the user for focus.)
|
|
@@ -20,7 +20,7 @@ import Foundation
|
|
|
20
20
|
import ScreenCaptureKit
|
|
21
21
|
import UniformTypeIdentifiers
|
|
22
22
|
|
|
23
|
-
let helperVersion = "0.
|
|
23
|
+
let helperVersion = "0.3.1"
|
|
24
24
|
// Marks events we synthesize so the Escape watcher ignores them.
|
|
25
25
|
let syntheticMarker: Int64 = 0x676C_6F76
|
|
26
26
|
|
|
@@ -1078,26 +1078,33 @@ final class AgentCursor {
|
|
|
1078
1078
|
// Blocks until the move animation finishes so the action lines up with it.
|
|
1079
1079
|
func move(to point: CGPoint, above windowId: Int?) {
|
|
1080
1080
|
guard enabled else { return }
|
|
1081
|
+
var from = NSPoint.zero
|
|
1082
|
+
var target = NSPoint.zero
|
|
1081
1083
|
var duration: TimeInterval = 0
|
|
1082
1084
|
DispatchQueue.main.sync {
|
|
1083
1085
|
let w = self.window ?? self.makeWindow()
|
|
1084
1086
|
self.window = w
|
|
1085
1087
|
guard let primary = NSScreen.screens.first else { return }
|
|
1086
1088
|
// AppKit frames are bottom-left origin; the arrow tip is the frame's top-left.
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
+
target = NSPoint(x: point.x - 4, y: primary.frame.height - point.y - self.size.height + 3)
|
|
1090
|
+
from = w.isVisible ? w.frame.origin : target
|
|
1089
1091
|
let distance = hypot(target.x - from.x, target.y - from.y)
|
|
1090
1092
|
duration = w.isVisible ? min(0.45, 0.12 + Double(distance) / 2400) : 0
|
|
1091
1093
|
if let id = windowId { w.order(.above, relativeTo: id) } else { w.orderFrontRegardless() }
|
|
1092
|
-
|
|
1093
|
-
ctx.duration = duration
|
|
1094
|
-
ctx.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
|
|
1095
|
-
w.animator().setFrameOrigin(target)
|
|
1096
|
-
}
|
|
1094
|
+
if duration == 0 { w.setFrameOrigin(target) }
|
|
1097
1095
|
self.hideTimer?.invalidate()
|
|
1098
1096
|
self.hideTimer = Timer.scheduledTimer(withTimeInterval: 4, repeats: false) { _ in self.hide() }
|
|
1099
1097
|
}
|
|
1100
|
-
|
|
1098
|
+
guard duration > 0 else { return }
|
|
1099
|
+
// Stepped by hand: an animator() frame move left the window where it was.
|
|
1100
|
+
let steps = max(1, Int(duration * 60))
|
|
1101
|
+
for step in 1...steps {
|
|
1102
|
+
let t = Double(step) / Double(steps)
|
|
1103
|
+
let eased = t * t * (3 - 2 * t)
|
|
1104
|
+
let next = NSPoint(x: from.x + (target.x - from.x) * eased, y: from.y + (target.y - from.y) * eased)
|
|
1105
|
+
DispatchQueue.main.sync { self.window?.setFrameOrigin(next) }
|
|
1106
|
+
usleep(useconds_t(duration / Double(steps) * 1_000_000))
|
|
1107
|
+
}
|
|
1101
1108
|
}
|
|
1102
1109
|
|
|
1103
1110
|
func hide() {
|
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vashp2029/glovebox",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.2",
|
|
4
|
+
"mcpName": "io.github.vpatel9202/glovebox",
|
|
4
5
|
"description": "Computer use for coding agents on macOS: one JavaScript call per step, accessibility diffs instead of screenshots, input in the background. MCP and CLI.",
|
|
5
6
|
"type": "module",
|
|
6
7
|
"license": "MIT",
|
package/src/config.mjs
CHANGED
package/src/macos-helper.mjs
CHANGED
|
@@ -135,7 +135,7 @@ export async function build({ log = () => {} } = {}) {
|
|
|
135
135
|
|
|
136
136
|
// Starts the helper through LaunchServices so it is its own responsible process.
|
|
137
137
|
export async function launch({ requestPermissions = false } = {}) {
|
|
138
|
-
const args = ["-g", "-
|
|
138
|
+
const args = ["-g", "-a", appPath()]; // Not -j: a hidden app cannot show the agent cursor.
|
|
139
139
|
for (const name of ["GLOVEBOX_HOME", "GLOVEBOX_APPROVAL", "GLOVEBOX_SOCKET"]) {
|
|
140
140
|
if (process.env[name]) args.push("--env", `${name}=${process.env[name]}`);
|
|
141
141
|
}
|