@jian-ai/remote-control 0.8.2 → 0.8.3
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 +16 -4
- package/bin/computer-macos.mjs +52 -39
- package/bin/jian-remote.mjs +792 -95
- package/linux/computer-helper.py +5 -4
- package/macos/computer-helper +0 -0
- package/macos/computer-helper.swift +164 -57
- package/macos/jian-pointer.png +0 -0
- package/package.json +1 -1
- package/windows/computer-helper.ps1 +5 -4
package/linux/computer-helper.py
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Jian Remote Control — Linux computer-use helper (X11).
|
|
4
4
|
|
|
5
5
|
Newline-delimited JSON on stdin → JSON lines on stdout (same cmds as macOS helper).
|
|
6
|
-
Overlay: override-redirect window with
|
|
6
|
+
Overlay: override-redirect window with white pointer + #2880F8 stroke/glow (parity with macOS sprite).
|
|
7
7
|
Input: xdotool when available (save/restore cursor around clicks so the user's
|
|
8
8
|
pointer is not left at the Jian position). Wayland: best-effort; overlay may be
|
|
9
9
|
unavailable — input still works when ydotool/wtype/xdotool can reach the session.
|
|
@@ -279,13 +279,14 @@ class Overlay:
|
|
|
279
279
|
cmap = X11.XDefaultColormap(self.dpy, self.screen)
|
|
280
280
|
white = XColor()
|
|
281
281
|
exact = XColor()
|
|
282
|
-
if X11.XAllocNamedColor(self.dpy, cmap, b"#
|
|
282
|
+
if X11.XAllocNamedColor(self.dpy, cmap, b"#FFFFFF", byref(white), byref(exact)):
|
|
283
283
|
X11.XSetForeground(self.dpy, self.gc, white.pixel)
|
|
284
284
|
glow = XColor()
|
|
285
|
-
|
|
285
|
+
# Match macOS ship sprite stroke #2880F8 (geometric stand-in; bitmap is macOS-only).
|
|
286
|
+
if X11.XAllocNamedColor(self.dpy, cmap, b"#2880F8", byref(glow), byref(exact)):
|
|
286
287
|
X11.XSetForeground(self.dpy, self.gc_glow, glow.pixel)
|
|
287
288
|
ink = XColor()
|
|
288
|
-
if X11.XAllocNamedColor(self.dpy, cmap, b"#
|
|
289
|
+
if X11.XAllocNamedColor(self.dpy, cmap, b"#2880F8", byref(ink), byref(exact)):
|
|
289
290
|
X11.XSetForeground(self.dpy, self.gc_ink, ink.pixel)
|
|
290
291
|
self.available = True
|
|
291
292
|
return True
|
package/macos/computer-helper
CHANGED
|
Binary file
|
|
@@ -5,8 +5,9 @@
|
|
|
5
5
|
Protocol: newline-delimited JSON on stdin → newline-delimited JSON on stdout (flush each).
|
|
6
6
|
Errors go to stderr in English only.
|
|
7
7
|
|
|
8
|
-
Pointer UX (Lucas / v0.8.
|
|
9
|
-
-
|
|
8
|
+
Pointer UX (Lucas / v0.8.3):
|
|
9
|
+
- Bitmap sprite: white fill + thick #2880F8 stroke + soft blue glow (embedded PNG).
|
|
10
|
+
Prefer sprite over live CGPath so AA/glow match the approved preview.
|
|
10
11
|
- Agent actions save the user’s cursor, hide it briefly, drive HID at the target, then
|
|
11
12
|
restore — so clicks do not leave the physical mouse stranded at the Jian position.
|
|
12
13
|
- Overlay tip animates (ease-out) between positions; system cursor is not the visible UX.
|
|
@@ -79,18 +80,151 @@ private func intValue(_ object: [String: Any], _ key: String) -> Int? {
|
|
|
79
80
|
return nil
|
|
80
81
|
}
|
|
81
82
|
|
|
82
|
-
// MARK: -
|
|
83
|
+
// MARK: - Pointer sprite (embedded PNG)
|
|
83
84
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
private let jianGlow = NSColor(srgbRed: 0x3A / 255, green: 0x7A / 255, blue: 0xD6 / 255, alpha: 1)
|
|
87
|
-
private let pointerWhite = NSColor(srgbRed: 0xFA / 255, green: 0xFA / 255, blue: 0xF8 / 255, alpha: 1)
|
|
85
|
+
/// Soft click-ripple blue (matches ship stroke #2880F8).
|
|
86
|
+
private let jianGlow = NSColor(srgbRed: 0x28 / 255, green: 0x80 / 255, blue: 0xF8 / 255, alpha: 1)
|
|
88
87
|
|
|
89
88
|
private let sessionAlpha: CGFloat = 0.94
|
|
90
89
|
private let idleAlpha: CGFloat = 0.18
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
90
|
+
/// Padded sprite canvas (40 pt blade + 10 pt glow pad each side).
|
|
91
|
+
private let pointerSize: CGFloat = 60
|
|
92
|
+
/// Tip hotspot in the padded 60 pt view (content tip was (2,2) in the 40 pt box).
|
|
93
|
+
private let hotspot = CGPoint(x: 12, y: 12)
|
|
94
|
+
|
|
95
|
+
/// Ship asset `macos/jian-pointer.png` (@3x master) as base64 — single-file helper stays
|
|
96
|
+
/// reliable when only the binary is copied into Application Support (no sidecar PNG).
|
|
97
|
+
private let jianPointerPngBase64 =
|
|
98
|
+
"iVBORw0KGgoAAAANSUhEUgAAALQAAAC0CAYAAAA9zQYyAAAaf0lEQVR4nO1dW6wkV3Vd+1T38EcQ"
|
|
99
|
+
"Fi+bGc+MZ+w4g4AoJIoQkSIh8oNEflAUPhARQrZxHIcoxglfiD+IQTaDI5IoEZHgI5FCflBeH0mk"
|
|
100
|
+
"RCbGCEuQsQdzPXc8Y5vwCijhJ3du19n5OK99TlXfe7v7VN+err3s7nr0o2qq1121zt7n7AMoFAqF"
|
|
101
|
+
"QqFQKBQKhUKhUCgUCoVCoVAoFAqFQqFQKBQKhUKhUCgUCoVCoTh20HGfwHyQODfm4zsPxc2EYyQ0"
|
|
102
|
+
"VTq2kl2RsCZC95B31SPPpbESfMxYA6EFmXuPRnM35oB7V3s2ldzjw4CELlS5y9tDjl2+fCA3ufOe"
|
|
103
|
+
"7O1K7LFgIELPU+U+IpNcULG3A04rXRJnO5TcY8QAhO4jc0lkAigxueckDjqvDlPZPfURnPuJraTe"
|
|
104
|
+
"VlQmNM3T2STDFNgtX6O+M+nZyfFJrqLLaZ5LbCX1VqMioXvJfACRKawWxD2kEemoW8ouC4KnHUrs"
|
|
105
|
+
"0aESoQ8nc5fIgbgkxbrfX2eQqizJGYjJGbl7iK2k3mJM6n/lXDKT42sgvyB011NT8X0Ckb2UFJn9"
|
|
106
|
+
"+8Sqf4UAcNpmt0VuiwK3iZTU24EKCi3VeR6ZpSqLdU9wimTPuEy9ycRcjd0Tc3xy+5j9WxhJoVWt"
|
|
107
|
+
"R4A6Ct3hXYfMXoUDodOOqNpOsenOj/3wp+FbvvPJ170yHYDlsTjxjhlgJqfDgbhecYMgu/eSV29h"
|
|
108
|
+
"sv0fEHM6hKr1zYwVFbpPnecocyKzYzZRRvI7P/aDn/YdYedTt77KfS6KqfDK0ic7YoulV225H/F9"
|
|
109
|
+
"c9VaY9Y3NWoSOnjjaJZz9XVLgnHbhxB5HnYeOXkLgEBMwKk1g9mz2HaJHdaL/eg2GtWC3OSoROh5"
|
|
110
|
+
"6izJbIIqE8gQiMydf/j9/13mqM9/5sxrI6EjkQNRreW0fhDZD/DWQc2Rbys2Hit46DJUB3S8MoQy"
|
|
111
|
+
"JzIbENGyZAYAMpOGBaHJk9XtM0Rk3TbIghypyVkOL82e1MJbewcewiRui4Jah9apEnvTsYJCp2gc"
|
|
112
|
+
"kIjsNNoAgAEZgMgkm2GMU2pjQGTOP/zyj1c5+SuP3XVbICdHNbaWnRJbp9CWmdM6/I6uNQF61Fot"
|
|
113
|
+
"yE2GGoSOcWXKIxnk1JKMsxhOmYkaAzLm/MMvrUTmgN2LF05xICuz9es2EdtaWGbAitekorNFEm+1"
|
|
114
|
+
"IDc5KhE6euegxADIkPfKgdBOmRs6//BLP6l0/gCA3cfffMYR1BHZq7FlG4md9ol1562TzxYNR09p"
|
|
115
|
+
"ZsliVevNR8VMobfMyYL4DZ88caR2Sl0ZZx/41lUA2H38LWeTOreGYFtma4hbC6aWmYiYCEyWmQC2"
|
|
116
|
+
"TL616FhqQ6aRiV2LoIhZc0o/Ahqz3jwsQa6gwkAQeOrkqlOgw9kMQwCZqNID4ewD39ylZjqFmU7J"
|
|
117
|
+
"TCdophNqJg2ZSQMzmRA1DfzDrRsDagyRMd4auQecPUL4h6ZsPIk7Uroeio3BquSSzE6ZvxiLjiE6"
|
|
118
|
+
"H7YbRqElztz/9A410wk10wkZ94CZTsg4YrtHY2Aak0jtrFC6i1D2iFYqkTeRWqb0FceOupbDL72j"
|
|
119
|
+
"TmQIihcVcFic+fDXnwOAq5//xbvAxoJMCzbEZCzZ1lkP27ZsYIkJYAKzJTAsOQthmRmgaEFC2tx1"
|
|
120
|
+
"itK0+caiErlILoV0CZWLUQ6zNiU78+GvP0cmqPVkQmYygVs2aRktiIGPwKBrQWiOBYFakM1CDUKn"
|
|
121
|
+
"BItMrGRZwmg5DMzwCi1x+r6vXSZzYormxDSzIs5bT4gmDZmmgWkaIiMtiFELcvNhBXJ1MoVhW0hX"
|
|
122
|
+
"SLYEhVvMQ1/++CuWPz2B0/d+9Zkz9z31bfKkRhO89aShZuKW1BiYiSHTGOexTWzEUqHSgdRRtPPI"
|
|
123
|
+
"jqr1MWI1tSwyheG/dBuWqmaWinLUIjUAnL73yWc9qaNaIzUWJ06pJ30WxFsmtSCbjsoeOhkP8YNL"
|
|
124
|
+
"H+1u4QuiKqnv8WrtQnvT4LHRJFJHC2KahowRvlotyKajrp+NiRXpnfMedstGOS5//BV1iX3f1y5T"
|
|
125
|
+
"c2JCzYkpUniv8Q1HR2oXszaO4H0WxKgF2TCsSGgSi/jjdW65FNXM37pXQF0L8h/PevvhH5NIah+v"
|
|
126
|
+
"dkkZaky/BSG1IBuGlRMrc7YzqwGYQrFXQ2ULcslZkBOTaEOaaRbWS8tgQRq1IBuKumE7v0KxsZga"
|
|
127
|
+
"hxSiHagTtqtvQZ70FmQaiB0yjBMkpfYWxKgF2VBUjgnnCRb/HHxJahhWRH0LcmKKEK9uJhMy08al"
|
|
128
|
+
"0Bu1IDcBKhA6KHG+wzcQw3r+qIy6FuSJSz5mPaHmxATJW6sFuQkwQNaOslXZ7S766AFQ3YLc++Tl"
|
|
129
|
+
"GNaL1iMsJ2pBNhQVCU0kFMc/idtt+jEH/dEqW5BnnAXx3rpJ5A72Qy3IZqF2KTAqVsm7j8EVWiKQ"
|
|
130
|
+
"+u5P7K38XafveeISALzwp7/8c6AZsW/fsiUitK3rfkfE3PrBA3CDB6xlAiyHgQMCYlAufO88AkgH"
|
|
131
|
+
"5VbAMI1CKrY9qZP9WA+qp807FmSS+oRIC0JqQY4LQ/R88w3BuOmNiBDrNWJ4CzKZpERMGB1T24Io"
|
|
132
|
+
"sY+KgaqPzldqrJvRWKcFIWdBLBGbxSwIqGf8IslBuURqQQ7HkH2T0+0zhaWl9Kwdm2xBetRaLcgS"
|
|
133
|
+
"GJDQKdxx8L71YqMtSB6z9kcRFkRj1odiAMshIZMr2AQ+A9hgC6IlFFbGmoZDldG8zcCwFmQ6z4I0"
|
|
134
|
+
"cyyIK8hzaAkFqAU5AGsc30dRozcJx2BBjLAgjbAgvr+4iNerBVkYA1uOEuuNQx8Vw1kQ6rMgRJZa"
|
|
135
|
+
"b0GsK6FAWsWpEtY6AnvTMYgFkQVvfO+92NdaqzhVhxK6QHULIksohH4gzVGrOFHnoT33DsaaLcfN"
|
|
136
|
+
"gcEtiCViBAtCfVWcAD/zka9njSNUcVILAlXoAzFICQVTWpBJgxSv7liQWMXpaIkYd7ARWxAl9CGo"
|
|
137
|
+
"XULBR0FyCxKiIKmKkyFRlqxIxJRRkH5SR4yL1Go5joDBLAjKKAiCBQEb+CgIwBaAi4VYlkkYIFgQ"
|
|
138
|
+
"ZmIXDwlFJElOUzce+6EKvQDqW5BOPZBJqrPn+oH4uiByFoR8mBd67Qcg+9K4lVEotRJ6QdQelHvm"
|
|
139
|
+
"w19/jprp1A/GFX56YsgkP51XcCIqrUc/qUtPvf1QQi+B2uMX3aDciR9lHhqJvnKTSRnFVDA+xqqj"
|
|
140
|
+
"Qh/aUAQwBpVWQq+AunVBnvo2ykZiHFneITX5GcaKcmtIpC5leiTWQwm9Iuoq9dcun7n/6Z1QkN1X"
|
|
141
|
+
"QhU+OpZL8DMixJnGQtmIRN+s68xWcziDEroCqluQ+7+xE5Q5VkPt+GjfjzqyWSp19M55NnEEUEJX"
|
|
142
|
+
"RF1SP71DSaVD1KMR8WlKE5qaLOKB6EOyDo7lOM+thBK6MmqT+uwD37qa+nu4KT3IhBAeBesh/bT7"
|
|
143
|
+
"cNLmPOqx5aRWQg+A2hbk7O/85wtuygxP6uijTayFAGmkc7Uei9sAoIQeFFVJ/eClayT6d6RZebNE"
|
|
144
|
+
"C7KeeOn5gNT4dkFT3wOjZtr87IPPXgeAK4+ev5XJMoGYXZiDmVMcml1HPM9gHkfO20MVek2oqdZ3"
|
|
145
|
+
"/N7Od8/9/tXvd3rgSZWOXjqEp3NXHV/cMiih14iapAaAcw+98MNYVSyPcABxRIsc97b9jUMl9JpR"
|
|
146
|
+
"u8F47qHrPxIKDUjPXCQMO8zdQlIroY8JNUl9/uGXfhzZm4IbiaS0hcydAyX0MaIWqXceOXVLsh0A"
|
|
147
|
+
"ksXI+bvtbIYS+thRw4Kc/+j1/z7/8Ms/EYNk0ekXnfcl3drwnRJ6Q1BHrbeTpItACb1BWFmp/+C/"
|
|
148
|
+
"/kdsFoo8DiihNwyrWxA6YHP7ea2ZwgVRI+M3LMaUF+xCFXoBbD6ZM7B4znZtM5TQiq2CEnrrwfFp"
|
|
149
|
+
"DFBCbxG+88nXvdIVlGEWHC7IvN3cPgZCb/cFPWZw4Zk5e20EWDOhmTGSC7tu7Hzy9T/jLy+H/+OL"
|
|
150
|
+
"gddiz7b+DGsitL/QYVVRFTufesOrOLcaoq7dfMneRgwch45EdnoxrvbJ4Nh55OSrwS2DOXsIcos7"
|
|
151
|
+
"4jiu+4CE7mOvMroGnv/06dcwtxZsGeyeMgJLHRb3Re79OYBtEu6BCC2Imyvz1nq3oXHl0fO3Mrct"
|
|
152
|
+
"rLXM1pPZsuOztVGd2RObpQXJPHXxG2wPmYFBCC1uc3nkKPi6tV/Ao2b4DutDcfnjr1gqW/i9r/z2"
|
|
153
|
+
"e7nd2+d2f5/bG/vc3phxu78Puz/jdn/Gdtaync0Ql61l27bMsxbWWnDbMrfWrUcye2JnVgMZX3mO"
|
|
154
|
+
"gmyhMgdUbhR2bnVIBOdCKIbH3Z/YW4iAR3nvUh2HbGth25btrIWdtbBtG7bZti3btvVk9tszT+a2"
|
|
155
|
+
"ZW5bto7MzK11VqO1zOzJ7EjNsMlHI1dnPw8LMIff24TaUY4+ZUZgMstox4BYlMjlZ2vj9b/+J3/L"
|
|
156
|
+
"bB0prQ3qa2HbFuzJzG0guoVfd6ocCNxGdRaWwwKCzNJLs2yvbDeJJSoSurx2SZkdk6W3Gw7r6EC0"
|
|
157
|
+
"lEqzZXh1RSA3W8u2tcy2hW2jAnOwFs5uBM8syMyJzFKVmaXJ8Jd9nnfeTtRUaJ6nzEh85qEUehVV"
|
|
158
|
+
"Xgdufe8X/4EjQkMuLFsWpHUkto74XTKnRqD/nrwR6MUjkXn7IxsSFQhd2ojcM6fXh1Po2kQezEuD"
|
|
159
|
+
"GbAMWO/AJEETeTkncKHM3LUZmTJzce3dgXOB3k4yA8M2CoMyF4F/W+1ibroql3jj+/7mX8HhP5EA"
|
|
160
|
+
"kZEKjkQNcWbOGoDI3iPJHBuC3EfmkaAGoYuGYNhI8hxVmq37cSpgaCIPp9KAvCzcR+zgjSN5rVf2"
|
|
161
|
+
"XjJnNmMumUegzsAgUY4Q0QAn9xEi/uGWuxpuJlUucfL9X3kije3rOLWCqIVVm9sA7PXMoyMzsDKh"
|
|
162
|
+
"WahzvHipEdj7oyxP6E20GMuo9Knf+qenitoZBeL1y3ZySVCOF/UIZB4HKkc5sh8hWg0ORGZrl7Uc"
|
|
163
|
+
"x0HkQY+ZzWAFzCG3VGaU4hBuhEXiZA6Zt1+dgWqEliSGuB32NXjsQoTeRFUusYxK3/7Bf3k6q4Hb"
|
|
164
|
+
"U0tRIrJU3g3dqlBmQeTMZoyDzEC1sF1YC1cyqIlv8yCLoR754g5B5B/840PvX+T961PpUPX2ABvi"
|
|
165
|
+
"ltHLdVrifS5lZFiB0CwvYBKQtJ03YHwMlRdU6Jr43lfuf6+d7e19/+8/8r7a372USn/o376ZzQRL"
|
|
166
|
+
"afLMo9eEKdTZrY9KlSVq9LZjwM2D4H4EZjATyEkGeQNNsMalc9u1E/q7X/7Au90EO36OEtM06z6H"
|
|
167
|
+
"uaBUhT9MAMREAOczabplxxv3sHmcRA6o66FZ3BZjiMnHUJ06L+yhV8XLf/Ub7+TZ3h7P/u+Gne3d"
|
|
168
|
+
"4HbvBs/2bizyHbW6n/bh9D1PXJKkzubsTlNJ9Ot1T1Bj7KjfOUkEnyWxWfbhXQNe/NJ73vHil97z"
|
|
169
|
+
"DtsmEvvlvm339r/75Q+8e4jjLkNqIhKT0RvqeOswJb1/+3w7Mm51BpYidAqHAvB5XL8a8lQpqpR6"
|
|
170
|
+
"g4l+C88/eu4NdU6/H9f/8td+yRN4n2eOxNze2PfLG/6xv8h3Dtk4PH3vk8+KqdmKGWHD5Gxid8D2"
|
|
171
|
+
"115cGEsqdCB1bAIKaYgKjdQ48X0S4Elth1Ppa3/xq291hN3b55kjriBx2N7n9sb+y3/9m+8a4hyW"
|
|
172
|
+
"SonHOQezWWEFwaX1SGERv13pzG9+VByC5TlMFNZTYgXMBMtgYoa1CzThj4wX/uztFzIfGarZE4k5"
|
|
173
|
+
"sRsDtpZ44u8cm+M8z9z31Lev/vHPnwMMsfDRDL/q2tm+5d1z2gTfkBy37RggsRIag9J/2KDOvntk"
|
|
174
|
+
"a5//9OnX1Dk2cPXzb7uTZ0l5ex6z4rHvxvLtzxY5ziK2YzmVDopc+migUGqoKvejZm87kcnyKylV"
|
|
175
|
+
"KzukR1KveuDdx996dvfxt5x15Lyxnz08Ybndn7nBqX5Qqt8XBqi++KX3vGPV86iFM/c/vRMnoxeV"
|
|
176
|
+
"9+NkQMW0KVTuUNRIrIieMrGJWHSDFA1DSeqdR07esuzRdy9eOMX2hiesJ3DxQCCuTQRGO5uxnaV9"
|
|
177
|
+
"drZZKi0noCefPRQWmsJchH1cjpMGjRe1PLRLrqR0oZ9yGgC5FiPBsvv7sZYBQ4AFmHf+6I2vdkkP"
|
|
178
|
+
"onMPXfvRvANceezO24ojyiyDCMSmmc2iFzXGMAzDiM49/r1ERC9+8d1vP/n+v/tqnUuxIrIJNP06"
|
|
179
|
+
"IzE6XecDLfVYUYnQ/vo65sKx2KuI28cMMLFFIjUT2BgitgATM9HOIydvIRCd++j1SOznP3PmtZnq"
|
|
180
|
+
"ZD8gJ1KHn1gQ2iubARsLMobADUcOSI9qBlO1ZWp5EIg42gpQh6+uAQjPZ3L/em0QAit7L+nt0vx3"
|
|
181
|
+
"KQ8gwk4iUeCSCATAmJgZS0kEkTFLp1j22uEyPRZT7yK05b7KuDtAY0CmITNpYCYNmUlDzXQKM52Y"
|
|
182
|
+
"5sT01Af/+RuL/MsXsROLEnr34oXbud3fZ7vfws5m7OtzpJIGceR3snUAOuHUEWKITGHoCoasYSgH"
|
|
183
|
+
"eGZFUnwj0VpZhyIWY4Gdtb4uRRsfRcEW956ZhfW1LmIhF1eByFUimvnPz0RRl1kLdtWKrn/hXW+r"
|
|
184
|
+
"dy1yLOqlzz74zLX5s7GN2iIfihUtB7tbXbzdR+/hXyQQOHVc4uRL3GvEIv1FADHH7xM2g/PIdSdV"
|
|
185
|
+
"WQagKUi9u0swmIk5/vGyIRATwZqWyRAwc3HqBXD3J/aqztctsXvxwu0H+2I1zvNQoz+0CNdlRBNP"
|
|
186
|
+
"PePkfGclzofri0IsbZvVqRCP2GvPVR6yKD8f6sH5SkWpwKG/XYfacUHpffWi61945y+sfj36sQj5"
|
|
187
|
+
"zz74zDW3No+0SuZ5GKDguUh9+4R3TINn9iMUSAlVNCPBU0FC6y2IJ6V7BFviKw+xFWRPxPWVijhV"
|
|
188
|
+
"LArkdvbFVzEKteQSwRfAsCNp8r4FMjyqmI9aUY7Cevh4nW+KMxPge/lK8yFSMeTb6t6OsLinytvr"
|
|
189
|
+
"gT9mOB7YH5tcdJBY+BdmIrIEhm0BS0StddZjRrCL2Y5FsAT5g5Uqb3uKA1CzL8ccUntPzcRMHANO"
|
|
190
|
+
"ediY2XdoR/oRQ7Ks50ec35L3n3PcZrLefxv4/iQW7EJixC2BybKlFmSIrCHQzFz781958+0f+vdv"
|
|
191
|
+
"1boqS6t46GvCJakVB6FyfejDSQ0ATIK9IdgWgtgkvuuwn7F8vfvHEXI4Bm6kgSEm686RLHNriQ3B"
|
|
192
|
+
"tpZhWsQ+yUdHX+NwVSty5bG7bktp2BAzSt4tb58oJAaIARVJkHyjzNPGJC51P7D0CYhIhw92GEOu"
|
|
193
|
+
"w4+BaQz5YVhEjYtJN5OGzGRCZjpBM52QmU5O3/PEpRonswyuPHrnraHBGsOUoTELa2GZAR+LhghD"
|
|
194
|
+
"axx6sAr+iEoNlGrt98Qkn/fN4T04tNcNx88VkH8u3rcjdPkjC4KxYOsP78OF3BIsESNYj7IX/Xpx"
|
|
195
|
+
"5bN3n4xlv1LPRaSl2+g2K8ZLYokhJw3iSIxI43T1kXG2+C0EWRf6lTgchInJPTlSc/wbcBuWicky"
|
|
196
|
+
"iIiJmC2RI3bLnWEha4YrxsPo1LBDMNTZJdmgLt0bgYHnKSxUg8sN4ROlRzzyg7n7+RgiRHjqvq8Y"
|
|
197
|
+
"42hbl6m0rYWfFuLq599216CXZh5i2NJlVUUX3HhLE2/urIwdA89TCPSTeo4CdrvhzPnKOftJREjc"
|
|
198
|
+
"cWPsMPkUy+6WQOyGhoVGYgswWuaQRTzaqdTElcfuui1UG+U4bM03Cv3foXsns3K4H2sgdB8kyWWK"
|
|
199
|
+
"e9WvRYp0OA/P3kcnjhN8nxLrXT3BWQ+ALRGhdX56jdi9eOF2DnOqhPp/he1I3WNEC7D0GyNvEALH"
|
|
200
|
+
"RmiJmj9A1hANwWif1+GYo2Hi0KOVmS0TyLIFyLTENqVydi++6XaYpjn7wDd3651jFzFzWU7bltRZ"
|
|
201
|
+
"WCf0XDIV7IANIHRNiIZolOvCZ7oOUiHRwgBs7FkVOM8AWYAN8x0PXLo25Blf+ezPvjGl4+WIntA7"
|
|
202
|
+
"0Xp/ESxHCErH9qGg8rjVGdjavoiyNlzqZ+2i0yZVJyJj0ohwQ2SMATVNKBlGxvWhvuMjz71U+wyv"
|
|
203
|
+
"XLxwSvRvjrNgxXhzNr+KIzZEwROECq9ZAkoJvaWEBhKpxUABigMJ4kiVWLHIkdoQGQPTEJFp3H5P"
|
|
204
|
+
"cNOYO3738ournNHu5958Jp+mLU3hJuYhlFMf2zgFhZ9fpYjeQAmdY7sJDSCROg6mkYNPZRaRIqE9"
|
|
205
|
+
"wR2RfT2PWOzR/RGcffDZ60c9k93Pvem0S+iV0xpHAnP/umwYhqgHhDrHvh5QMjtsMaEBodL+qUNq"
|
|
206
|
+
"EyyI2yfsh1DunOSyboaZq9pXLl44FX1vTJAUE2fKuQdhLdtgLcQ8hLG7bWodZuE7VecM209oABmp"
|
|
207
|
+
"Y80L8rWYU1GXkqxSud3rYQyk+Ez2XbGTqkjhhTF/Yi5ulvMUynolro9GLP2Qz0VYWI3QUAz/ViU0"
|
|
208
|
+
"sHVRjhI9UQ9m5lAcwMXzYvyWYYhgjSemG5kOQwRmMBl2I8SIYOOAX1cqQZA5D6yI2PFBxE4eOdoM"
|
|
209
|
+
"mSVMmXvBYCVzH7ac0B4x4eLXGMxpwIEgoQWDbBgY4LMxxEwEMuzGR/p6H+zFmYmEUU+x7kg3EW6L"
|
|
210
|
+
"EbcsUtElt4xixMhzDNNBrihybLnlCOgvtxArLkjLIKIgVGzn+0GxsRmOIa9mUNW44Q1DQeyk3N39"
|
|
211
|
+
"6c4RLIxajcMwEkIDh5MaKfohQ34lsd1u0SMvkNt/BVIGxy8KIkbljS1GkSsRoTjP5j4yi69XQucY"
|
|
212
|
+
"EaGBIuHinxIhuw28EA2RjUmkfdmXUX41O4SLigt4z5HHkXNVdu9UMi+K8REaQC+pg4noJW2RpBGv"
|
|
213
|
+
"iabgPKTYWt6ok4rsXy1VGVAyL4aRERqYT2q/oELGY2dAaTf6PnsgpOntiSMn0oa4SN4AVDIfFSMk"
|
|
214
|
+
"NHAwqf0qlaY7cxg9163cJxuFxT7OX+9XcBklyb5DyXwARkpoICPgwcQWb6biE0cxHNmK2OLOSv6p"
|
|
215
|
+
"3t1K5kMwYkID/aSOG8W1Kcnd85a54Hytn8R+ByN/M6BEPjpGTmjgcH4e5JMXuXy9nOS+hXhZibwg"
|
|
216
|
+
"lNAdFF64q9y9G4egT3YP2KVEXhZK6LnoafjVulr9Yq0krgAl9JFRu1aHElihUCgUCoVCoVAoFAqF"
|
|
217
|
+
"QqFQKBQKhUKhUCgUCoVCoVAoFAqFQqFQKBQKhUKhUCgUa8X/A+26fqLnlvojAAAAAElFTkSuQmCC"
|
|
218
|
+
|
|
219
|
+
private let jianPointerImage: NSImage? = {
|
|
220
|
+
guard let data = Data(base64Encoded: jianPointerPngBase64, options: .ignoreUnknownCharacters)
|
|
221
|
+
else {
|
|
222
|
+
fputs("computer-helper: embedded pointer PNG base64 decode failed\n", stderr)
|
|
223
|
+
fflush(stderr)
|
|
224
|
+
return nil
|
|
225
|
+
}
|
|
226
|
+
return NSImage(data: data)
|
|
227
|
+
}()
|
|
94
228
|
|
|
95
229
|
// MARK: - Overlay view
|
|
96
230
|
|
|
@@ -106,7 +240,7 @@ private final class JianPointerView: NSView {
|
|
|
106
240
|
guard let ctx = NSGraphicsContext.current?.cgContext else { return }
|
|
107
241
|
|
|
108
242
|
if rippleVisible {
|
|
109
|
-
let maxRadius = pointerSize * 0.
|
|
243
|
+
let maxRadius = pointerSize * 0.55
|
|
110
244
|
let radius = 3 + maxRadius * rippleProgress
|
|
111
245
|
let alpha = max(0, 1 - rippleProgress)
|
|
112
246
|
ctx.saveGState()
|
|
@@ -121,52 +255,25 @@ private final class JianPointerView: NSView {
|
|
|
121
255
|
ctx.restoreGState()
|
|
122
256
|
}
|
|
123
257
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
let fillAlpha = 1 - fillPulse * 0.28
|
|
144
|
-
pointerWhite.withAlphaComponent(fillAlpha).setFill()
|
|
145
|
-
path.fill()
|
|
146
|
-
ctx.restoreGState()
|
|
147
|
-
|
|
148
|
-
jianInk.withAlphaComponent(0.85).setStroke()
|
|
149
|
-
path.lineWidth = 1.15
|
|
150
|
-
path.lineJoinStyle = .miter
|
|
151
|
-
path.lineCapStyle = .butt
|
|
152
|
-
path.miterLimit = 8
|
|
153
|
-
path.stroke()
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
/// Sharp geometric pointer (anathema-white style): tip → shaft → barb.
|
|
157
|
-
private static func arrowPath(in bounds: NSRect) -> NSBezierPath {
|
|
158
|
-
let s = min(bounds.width, bounds.height)
|
|
159
|
-
let path = NSBezierPath()
|
|
160
|
-
// Coordinates in view space (flipped Y): tip near top-left hotspot.
|
|
161
|
-
path.move(to: CGPoint(x: s * 0.06, y: s * 0.06))
|
|
162
|
-
path.line(to: CGPoint(x: s * 0.06, y: s * 0.72))
|
|
163
|
-
path.line(to: CGPoint(x: s * 0.28, y: s * 0.55))
|
|
164
|
-
path.line(to: CGPoint(x: s * 0.42, y: s * 0.88))
|
|
165
|
-
path.line(to: CGPoint(x: s * 0.55, y: s * 0.82))
|
|
166
|
-
path.line(to: CGPoint(x: s * 0.36, y: s * 0.48))
|
|
167
|
-
path.line(to: CGPoint(x: s * 0.62, y: s * 0.48))
|
|
168
|
-
path.close()
|
|
169
|
-
return path
|
|
258
|
+
// Bitmap blade (white + #2880F8 stroke + baked glow). Pulse alpha on click flash.
|
|
259
|
+
let alpha = 1 - fillPulse * 0.28
|
|
260
|
+
if let image = jianPointerImage {
|
|
261
|
+
image.draw(
|
|
262
|
+
in: bounds,
|
|
263
|
+
from: .zero,
|
|
264
|
+
operation: .sourceOver,
|
|
265
|
+
fraction: alpha,
|
|
266
|
+
respectFlipped: true,
|
|
267
|
+
hints: nil
|
|
268
|
+
)
|
|
269
|
+
} else {
|
|
270
|
+
// Last-resort fallback if decode failed — still a visible tip, not ink/cream geometry.
|
|
271
|
+
jianGlow.withAlphaComponent(0.9 * alpha).setFill()
|
|
272
|
+
let tip = NSBezierPath(
|
|
273
|
+
ovalIn: CGRect(x: hotspot.x - 3, y: hotspot.y - 3, width: 6, height: 6)
|
|
274
|
+
)
|
|
275
|
+
tip.fill()
|
|
276
|
+
}
|
|
170
277
|
}
|
|
171
278
|
|
|
172
279
|
func flashClick(duration: TimeInterval = 0.16) {
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Jian Remote Control — Windows computer-use helper
|
|
2
2
|
# JSON lines on stdin → JSON lines on stdout (same cmds as macOS/Linux helpers).
|
|
3
|
-
# Overlay: topmost transparent WinForms pointer (
|
|
3
|
+
# Overlay: topmost transparent WinForms pointer (white + #2880F8 stroke/glow; macOS uses bitmap).
|
|
4
4
|
# Input: SendInput with save/restore so agent clicks do not strand the user cursor.
|
|
5
5
|
# English-only errors.
|
|
6
6
|
|
|
@@ -123,7 +123,8 @@ function Ensure-Overlay {
|
|
|
123
123
|
(New-Object System.Drawing.Point(13, 17)),
|
|
124
124
|
(New-Object System.Drawing.Point(22, 17))
|
|
125
125
|
)
|
|
126
|
-
|
|
126
|
+
# Parity with macOS ship sprite: white fill + #2880F8 stroke/glow (geometric stand-in).
|
|
127
|
+
$glowBrush = New-Object System.Drawing.SolidBrush ([System.Drawing.Color]::FromArgb(140, 40, 128, 248))
|
|
127
128
|
$glowPts = @(
|
|
128
129
|
(New-Object System.Drawing.Point(3, 4)),
|
|
129
130
|
(New-Object System.Drawing.Point(3, 28)),
|
|
@@ -134,9 +135,9 @@ function Ensure-Overlay {
|
|
|
134
135
|
(New-Object System.Drawing.Point(23, 19))
|
|
135
136
|
)
|
|
136
137
|
$g.FillPolygon($glowBrush, $glowPts)
|
|
137
|
-
$fill = New-Object System.Drawing.SolidBrush ([System.Drawing.Color]::FromArgb(255,
|
|
138
|
+
$fill = New-Object System.Drawing.SolidBrush ([System.Drawing.Color]::FromArgb(255, 255, 255, 255))
|
|
138
139
|
$g.FillPolygon($fill, $pts)
|
|
139
|
-
$pen = New-Object System.Drawing.Pen ([System.Drawing.Color]::FromArgb(
|
|
140
|
+
$pen = New-Object System.Drawing.Pen ([System.Drawing.Color]::FromArgb(255, 40, 128, 248), 2.4)
|
|
140
141
|
$g.DrawPolygon($pen, $pts)
|
|
141
142
|
$glowBrush.Dispose(); $fill.Dispose(); $pen.Dispose()
|
|
142
143
|
})
|