apple-tools-mcp 2.0.9 → 2.0.10
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 +3 -1
- package/lib/mailWrite.js +36 -13
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -472,9 +472,11 @@ Paste uses System Events, so **node needs Accessibility** (Privacy & Security
|
|
|
472
472
|
|
|
473
473
|
**macOS 26 focus compile (2.0.9).** Dual-host Sent prove on `@2.0.8` never reached paste: `atmSafeToPaste` used bare `focused UI element`, which System Events 26.x rejects at compile. The 2.0.8 fail-closed gates stay; only the focus *query* changed to the forms hosts compiled.
|
|
474
474
|
|
|
475
|
+
**AppleScript reserved identifiers (2.0.10).** Dual-host Sent prove on `@2.0.9` compiled past the focused-UI fix, then failed in `atmFocusMailBody`: `set {tw, th} to size of atmElem` → **-2741** Expected expression but found `th` (AppleScript reserved ordinal). Size/position lists now use `atmW`/`atmH` (hosts confirmed) and other `atm*` names — never `th`/`tw`/`st`/`nd`/`rd`/`to`/`by`/`id` in destructuring. 2.0.8/2.0.9 fail-closed paste-focus and 2.0.9 AXFocusedUIElement / `whose focused is true` are unchanged.
|
|
476
|
+
|
|
475
477
|
**mail_send success is Sent/Outbox verify (2.0.7).** AppleScript `send` returning without throw is not enough. After a real send the tool looks in **Sent** and **Outbox** and reports success only if the message is there. The success text names the delivery state (`mailbox: sent` + `delivery: sent`, or `mailbox: outbox` + `delivery: outbox` while still sending). If verify misses, the tool returns a failure (`isError`) — not success. Hang/timeout recover matches **To + subject** (and Message-ID when compose captured one). It never matches subject alone (short subjects like `test` are unsafe). `from` / account selection is out of scope; Mail's default From is used.
|
|
476
478
|
|
|
477
|
-
**Manual prove (2.0.
|
|
479
|
+
**Manual prove (2.0.10 on the Mac host):** AppleScript for paste-focus **compiles** (no `-2741` on `th`; no `-2741`/`-2740` on `focused UI element`). Then `mail_send` a short plain message and a short `body_format: "html"` message whose body looks like ordinary paragraphs (for example `<p>Quick note</p>`), neither with a `Re:`/`Fwd:` subject. The caret must land in the **body** (not To/Subject): no `BODY_FOCUS_FAILED` / `BODY_PASTE_MISDIRECTED`, and the intended text must be in the native body before send. Inspect each Sent `.emlx`: the text/plain part must not prefix every body line with `>`, and any HTML alternative must not wrap the whole body in `<blockquote type="cite">`. Compose must succeed (no `-2753` / undefined `newMessage`, no **-2741** / **-2740** on body focus). That quote-prefix dual-host Sent prove is a separate bar from the 2.0.7 verify contract.
|
|
478
480
|
|
|
479
481
|
Emails are addressed by their RFC822 **Message-ID**. Pass `message_id`, or pass the `file_path` from `mail_search` / `mail_recent` and the server reads the Message-ID out of the `.emlx` headers for you. `mail_archive` moves the message to its account's Archive (or All Mail) mailbox; `mail_trash` moves it to that account's Trash.
|
|
480
482
|
|
package/lib/mailWrite.js
CHANGED
|
@@ -159,6 +159,21 @@ export const BODY_FOCUS_FAILED_SENTINEL = "BODY_FOCUS_FAILED";
|
|
|
159
159
|
/** Compose body AX height vs To/Subject/Cc fields (those are ~22px). */
|
|
160
160
|
export const MAIL_BODY_MIN_AX_HEIGHT = 50;
|
|
161
161
|
|
|
162
|
+
/**
|
|
163
|
+
* AppleScript ordinal/keyword tokens that fail compile in `set {a, b}`
|
|
164
|
+
* lists on macOS 26.x (MacBook 26.1 + Mini 26.6.2: `th` → -2741).
|
|
165
|
+
* Paste-focus handlers must not destructure into these names.
|
|
166
|
+
*/
|
|
167
|
+
export const ATM_APPLESCRIPT_RESERVED_SHORTS = Object.freeze([
|
|
168
|
+
"th",
|
|
169
|
+
"st",
|
|
170
|
+
"nd",
|
|
171
|
+
"rd",
|
|
172
|
+
"to",
|
|
173
|
+
"by",
|
|
174
|
+
"id"
|
|
175
|
+
]);
|
|
176
|
+
|
|
162
177
|
/**
|
|
163
178
|
* macOS 26.x System Events rejects the compound `focused UI element`
|
|
164
179
|
* (MacBook 26.1 compile -2741; Mini 26.6.2 compile -2740). Hosts compile
|
|
@@ -231,6 +246,14 @@ const BODY_MIN_H = asInteger(MAIL_BODY_MIN_AX_HEIGHT, { min: 1, max: 500, field:
|
|
|
231
246
|
* AXTextArea blindly — on MacBook Mail that is a header field, and
|
|
232
247
|
* Cmd-V becomes BODY_PASTE_MISDIRECTED.
|
|
233
248
|
*
|
|
249
|
+
* AppleScript treats ordinal suffixes as reserved tokens (`th` as in 4th,
|
|
250
|
+
* also `st`/`nd`/`rd`). Dual-host Sent prove on 2.0.9 compiled past the
|
|
251
|
+
* focused-UI fix, then failed in `atmFocusMailBody`:
|
|
252
|
+
* `set {tw, th} to size of atmElem` → -2741 Expected expression but found
|
|
253
|
+
* `th`. Size/position lists use `atmW`/`atmH` (hosts confirmed) and other
|
|
254
|
+
* `atm*` names — never `th`/`tw`/`st`/`nd`/`rd`/`to`/`by`/`id` in
|
|
255
|
+
* destructuring.
|
|
256
|
+
*
|
|
234
257
|
* Strategies, each fail-closed unless the caret left the header:
|
|
235
258
|
* 1. Click a tall AXWebArea (HTML compose body)
|
|
236
259
|
* 2. Focus a tall `text area` (plain compose body), never a short header
|
|
@@ -253,11 +276,11 @@ on atmSafeToPaste()
|
|
|
253
276
|
if r is "AXButton" then return false
|
|
254
277
|
if r is "AXMenuButton" then return false
|
|
255
278
|
if r is "AXPopUpButton" then return false
|
|
256
|
-
set
|
|
279
|
+
set atmH to 0
|
|
257
280
|
try
|
|
258
|
-
set {
|
|
281
|
+
set {atmW, atmH} to size of fe
|
|
259
282
|
end try
|
|
260
|
-
if r is "AXTextArea" and
|
|
283
|
+
if r is "AXTextArea" and atmH < ${BODY_MIN_H} then return false
|
|
261
284
|
ignoring case
|
|
262
285
|
set bits to ""
|
|
263
286
|
try
|
|
@@ -273,7 +296,7 @@ on atmSafeToPaste()
|
|
|
273
296
|
end ignoring
|
|
274
297
|
if r is "AXWebArea" then return true
|
|
275
298
|
if r is "AXTextArea" then return true
|
|
276
|
-
if
|
|
299
|
+
if atmH >= ${BODY_MIN_H} then return true
|
|
277
300
|
end try
|
|
278
301
|
return false
|
|
279
302
|
end tell
|
|
@@ -333,8 +356,8 @@ on atmFocusMailBody(expectedSubject)
|
|
|
333
356
|
end if
|
|
334
357
|
try
|
|
335
358
|
if (role of atmElem as string) is "AXWebArea" then
|
|
336
|
-
set {
|
|
337
|
-
if
|
|
359
|
+
set {atmW, atmH} to size of atmElem
|
|
360
|
+
if atmH >= ${BODY_MIN_H} then
|
|
338
361
|
click atmElem
|
|
339
362
|
delay 0.08
|
|
340
363
|
if my atmSafeToPaste() then return
|
|
@@ -343,8 +366,8 @@ on atmFocusMailBody(expectedSubject)
|
|
|
343
366
|
end try
|
|
344
367
|
try
|
|
345
368
|
if (role of atmElem as string) is "AXTextArea" then
|
|
346
|
-
set {
|
|
347
|
-
if
|
|
369
|
+
set {atmW, atmH} to size of atmElem
|
|
370
|
+
if atmH >= ${BODY_MIN_H} and atmTallText is missing value then set atmTallText to atmElem
|
|
348
371
|
end if
|
|
349
372
|
end try
|
|
350
373
|
try
|
|
@@ -371,8 +394,8 @@ on atmFocusMailBody(expectedSubject)
|
|
|
371
394
|
end repeat
|
|
372
395
|
try
|
|
373
396
|
set ta to text area 1 of scroll area 1 of w
|
|
374
|
-
set {
|
|
375
|
-
if
|
|
397
|
+
set {atmW, atmH} to size of ta
|
|
398
|
+
if atmH >= ${BODY_MIN_H} then
|
|
376
399
|
set focused of ta to true
|
|
377
400
|
delay 0.08
|
|
378
401
|
if my atmSafeToPaste() then return
|
|
@@ -404,9 +427,9 @@ on atmFocusMailBody(expectedSubject)
|
|
|
404
427
|
if my atmSafeToPaste() then return
|
|
405
428
|
end try
|
|
406
429
|
end if
|
|
407
|
-
set {
|
|
408
|
-
set {
|
|
409
|
-
click at {(
|
|
430
|
+
set {atmX, atmY} to position of w
|
|
431
|
+
set {atmWinW, atmWinH} to size of w
|
|
432
|
+
click at {(atmX + (atmWinW div 2)) as integer, (atmY + ((atmWinH * 2) div 3)) as integer}
|
|
410
433
|
delay 0.08
|
|
411
434
|
if my atmSafeToPaste() then return
|
|
412
435
|
error "${BODY_FOCUS_FAILED_SENTINEL}"
|