@mapier/imsg-sdk 0.1.0 → 0.1.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mapier/imsg-sdk",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "TypeScript SDK for iMessage automation on macOS: the Gateway contract, ImsgGateway (real), and a device-free FakeGateway.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -37,14 +37,37 @@
37
37
  ".": {
38
38
  "types": "./dist/index.d.ts",
39
39
  "import": "./dist/index.js"
40
- }
40
+ },
41
+ "./types": {
42
+ "types": "./dist/types.d.ts",
43
+ "import": "./dist/types.js"
44
+ },
45
+ "./polls": {
46
+ "types": "./dist/polls.d.ts",
47
+ "import": "./dist/polls.js"
48
+ },
49
+ "./gateway/types": {
50
+ "types": "./dist/gateway/types.d.ts",
51
+ "import": "./dist/gateway/types.js"
52
+ },
53
+ "./gateway/fake": {
54
+ "types": "./dist/gateway/fake.d.ts",
55
+ "import": "./dist/gateway/fake.js"
56
+ },
57
+ "./gateway/portable-chat": {
58
+ "types": "./dist/gateway/portable-chat.d.ts",
59
+ "import": "./dist/gateway/portable-chat.js"
60
+ },
61
+ "./package.json": "./package.json"
41
62
  },
42
63
  "files": [
43
- "dist"
64
+ "dist",
65
+ "scripts/*.applescript"
44
66
  ],
45
67
  "scripts": {
46
68
  "build": "tsc -p tsconfig.build.json",
47
69
  "test": "tsx --test tests/*.test.ts",
70
+ "pack:smoke": "tsx scripts/pack-smoke.ts",
48
71
  "typecheck": "tsc --noEmit",
49
72
  "lint": "biome check .",
50
73
  "format": "biome check --write .",
@@ -0,0 +1,65 @@
1
+ -- Create an iMessage group chat by driving Messages.app's compose window.
2
+ -- The AppleScript group-chat API died in Big Sur; this is the same System
3
+ -- Events / Accessibility path `imsg react` uses. Needs an unlocked GUI
4
+ -- session + Accessibility permission for the invoking terminal.
5
+ --
6
+ -- Usage:
7
+ -- osascript scripts/create-group.applescript "+14155551212" "+16505551212" "first message"
8
+ --
9
+ -- Last argument is the first message (sending it is what creates the thread);
10
+ -- everything before it is a recipient (E.164 or iMessage email). Two or more
11
+ -- recipients = group. Recipients should be iMessage-reachable (blue), or the
12
+ -- thread degrades to SMS/MMS.
13
+ --
14
+ -- The message body is pasted via the clipboard (set the clipboard + Cmd+V),
15
+ -- not keystroke-typed — keystroke typing passes through Messages autocorrect
16
+ -- and mangles it ("mapi" -> "maxi"). Recipient handles stay keystroke-typed:
17
+ -- they're digits/short strings, autocorrect-safe, and need the per-character
18
+ -- autocomplete-chip behavior anyway.
19
+ --
20
+ -- Known-fragile keystrokes (tweak here if the smoke test fails):
21
+ -- * Return after each recipient commits the autocomplete chip.
22
+ -- * Tab moves focus from the To: field to the message body.
23
+
24
+ on run argv
25
+ set argc to count of argv
26
+ if argc < 3 then
27
+ error "usage: create-group.applescript <handle1> <handle2> [more handles...] <first message>"
28
+ end if
29
+ set msgText to item argc of argv
30
+ set recipients to items 1 thru (argc - 1) of argv
31
+
32
+ set the clipboard to msgText
33
+
34
+ tell application "Messages" to activate
35
+ delay 1
36
+
37
+ tell application "System Events"
38
+ tell process "Messages"
39
+ set titleBeforeCompose to name of front window
40
+ keystroke "n" using {command down} -- new compose
41
+ delay 1
42
+ -- Compose guard: if Cmd+N failed to enter compose (sibling of the
43
+ -- react.applescript Cmd+T failure, observed live 2026-07-17), every
44
+ -- keystroke below would land in the FOCUSED CHAT's compose field and
45
+ -- each Return would send it — recipient handles texted to whatever
46
+ -- thread is open. Entering compose retitles the window (chat title ->
47
+ -- "Messages" on macOS 26); an unchanged title means no compose, so
48
+ -- abort before typing anything.
49
+ if (name of front window) is titleBeforeCompose then
50
+ error "create-group.applescript: compose window did not open (window title unchanged) — nothing typed, no message sent"
51
+ end if
52
+ repeat with r in recipients
53
+ keystroke (r as text)
54
+ delay 1 -- let autocomplete settle
55
+ key code 36 -- Return: commit recipient chip
56
+ delay 1
57
+ end repeat
58
+ key code 48 -- Tab: To: field -> message body
59
+ delay 0.5
60
+ keystroke "v" using {command down} -- paste msgText, autocorrect-safe
61
+ delay 0.5
62
+ key code 36 -- Return: send (this creates the group thread)
63
+ end tell
64
+ end tell
65
+ end run
@@ -0,0 +1,94 @@
1
+ -- Tapback the most recent incoming message in a DM — our replacement for
2
+ -- `imsg react`, whose Cmd+F search-select race fires Cmd+T into whatever
3
+ -- chat happens to be focused (observed live 2026-07-02 tapbacking an
4
+ -- unrelated thread; its dance also simply fails to switch threads on
5
+ -- macOS 26 Messages). Differences:
6
+ -- 1. navigation via the OS-routed sms: URL scheme — addressed by handle,
7
+ -- no search UI, no race, no locale dependence
8
+ -- 2. focused-window title check before Cmd+T as defense-in-depth: titles
9
+ -- with digits must match the handle; Siri-suggested contact-name titles
10
+ -- ("Maybe: Mark Xiong") carry no digits and pass — the URL routing
11
+ -- already pinned the thread by handle
12
+ --
13
+ -- argv: 1 = handle (e.g. +17738867338), 2 = tapback key 1-6
14
+ -- (1 love, 2 like, 3 dislike, 4 laugh, 5 emphasis, 6 question)
15
+ -- DM-only. The caller (ImsgGateway.react) verifies the tapback actually
16
+ -- landed by re-reading history; this script only guarantees no side effect
17
+ -- in a wrong thread.
18
+
19
+ on digitsOf(s)
20
+ set out to ""
21
+ repeat with c in characters of s
22
+ if c is in "0123456789" then set out to out & c
23
+ end repeat
24
+ return out
25
+ end digitsOf
26
+
27
+ on run argv
28
+ set chatLookup to item 1 of argv
29
+ set reactionKey to item 2 of argv
30
+ set wantedDigits to digitsOf(chatLookup)
31
+ if wantedDigits is "" then error "react.applescript: handle has no digits: " & chatLookup
32
+
33
+ open location "sms:" & chatLookup
34
+ delay 1.5
35
+
36
+ tell application "System Events"
37
+ tell process "Messages"
38
+ set frontmost to true
39
+ set winTitle to name of front window
40
+ end tell
41
+ end tell
42
+
43
+ set titleDigits to digitsOf(winTitle)
44
+ if titleDigits is not "" and titleDigits does not contain wantedDigits and wantedDigits does not contain titleDigits then
45
+ error "react.applescript: wrong chat focused ('" & winTitle & "', wanted " & chatLookup & ") — no tapback sent"
46
+ end if
47
+
48
+ tell application "System Events"
49
+ tell process "Messages"
50
+ keystroke "t" using command down
51
+ delay 0.4
52
+ keystroke reactionKey
53
+ delay 0.3
54
+ end tell
55
+ end tell
56
+
57
+ -- Compose-leak guard: when Cmd+T fails to open the tapback picker (observed
58
+ -- live 2026-07-17 with the display asleep), the reaction key lands in the
59
+ -- compose field and the Return below would SEND it as a text. The picker
60
+ -- never puts the typed digit into a focused text input, so a focused text
61
+ -- input containing the key means no picker — clear the field and abort.
62
+ set leaked to false
63
+ tell application "System Events"
64
+ tell process "Messages"
65
+ try
66
+ set fe to value of attribute "AXFocusedUIElement"
67
+ set feRole to role of fe
68
+ if feRole is "AXTextField" or feRole is "AXTextArea" then
69
+ set fv to ""
70
+ try
71
+ set fv to value of fe as text
72
+ end try
73
+ if fv contains reactionKey then set leaked to true
74
+ end if
75
+ end try
76
+ end tell
77
+ end tell
78
+ if leaked then
79
+ tell application "System Events"
80
+ tell process "Messages"
81
+ keystroke "a" using command down
82
+ delay 0.2
83
+ key code 51
84
+ end tell
85
+ end tell
86
+ error "react.applescript: tapback picker did not open — reaction key landed in the compose field (cleared); no tapback sent"
87
+ end if
88
+
89
+ tell application "System Events"
90
+ tell process "Messages"
91
+ key code 36
92
+ end tell
93
+ end tell
94
+ end run