@vox-ai-app/integrations 1.0.1 → 1.0.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/README.md +7 -5
- package/package.json +5 -6
- package/src/imessage/mac/reply.js +26 -0
- package/src/mail/manage/mac/index.js +5 -5
- package/src/mail/send/mac/index.js +2 -2
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
macOS system integrations for Vox: Apple Mail, Screen control, and iMessage. Each integration ships with tool implementations and LLM tool definitions.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
- Initial release.## [1.0.0] - 2026-03-24- `openDb` / `closeDb` lifecycle.- WAL journal mode, foreign keys, auto-schema creation.- Initial SQLite-based persistence: conversations, messages, tasks, task activity.### Added## [1.0.2] - 2026-04-01- `checkpointId` type consistency.- `getAllSettings` return type (now returns object instead of array).### Fixed- Added migration system (`src/migrations/runner.js` + `001_initial_schema.js`).- Added new exports: `./tools`, `./settings`, `./mcp-servers`, `./schedules`, `./tool-secrets`, `./patterns`, `./vectors`.- Updated exports map: all repo modules now resolve to `./src/repos/*.js`.- Moved 9 repository files from flat `src/` into `src/repos/` subdirectory.### ChangedRequires macOS. Each integration needs specific system permissions granted by the user.
|
|
6
6
|
|
|
7
7
|
## Install
|
|
8
8
|
|
|
@@ -17,7 +17,9 @@ Peer dependency: `electron >= 28`
|
|
|
17
17
|
| Export | Contents |
|
|
18
18
|
| ----------------------------------------- | ----------------------------- |
|
|
19
19
|
| `@vox-ai-app/integrations` | All exports |
|
|
20
|
-
| `@vox-ai-app/integrations/defs`
|
|
20
|
+
| `@vox-ai-app/integrations/defs/mail` | Mail tool definitions |
|
|
21
|
+
| `@vox-ai-app/integrations/defs/screen` | Screen tool definitions |
|
|
22
|
+
| `@vox-ai-app/integrations/defs/imessage` | iMessage tool definitions |
|
|
21
23
|
| `@vox-ai-app/integrations/mail` | Mail functions |
|
|
22
24
|
| `@vox-ai-app/integrations/screen` | Screen capture + control |
|
|
23
25
|
| `@vox-ai-app/integrations/screen/capture` | Capture only |
|
|
@@ -40,7 +42,7 @@ await replyToEmail({ messageId: '...', body: 'Thanks!' })
|
|
|
40
42
|
Tool definitions:
|
|
41
43
|
|
|
42
44
|
```js
|
|
43
|
-
import { MAIL_TOOL_DEFINITIONS } from '@vox-ai-app/integrations/defs'
|
|
45
|
+
import { MAIL_TOOL_DEFINITIONS } from '@vox-ai-app/integrations/defs/mail'
|
|
44
46
|
```
|
|
45
47
|
|
|
46
48
|
## Screen
|
|
@@ -69,7 +71,7 @@ try {
|
|
|
69
71
|
Tool definitions:
|
|
70
72
|
|
|
71
73
|
```js
|
|
72
|
-
import { SCREEN_TOOL_DEFINITIONS } from '@vox-ai-app/integrations/defs'
|
|
74
|
+
import { SCREEN_TOOL_DEFINITIONS } from '@vox-ai-app/integrations/defs/screen'
|
|
73
75
|
```
|
|
74
76
|
|
|
75
77
|
## iMessage
|
|
@@ -112,7 +114,7 @@ svc.start('my-passphrase')
|
|
|
112
114
|
Tool definitions:
|
|
113
115
|
|
|
114
116
|
```js
|
|
115
|
-
import { IMESSAGE_TOOL_DEFINITIONS } from '@vox-ai-app/integrations/defs'
|
|
117
|
+
import { IMESSAGE_TOOL_DEFINITIONS } from '@vox-ai-app/integrations/defs/imessage'
|
|
116
118
|
```
|
|
117
119
|
|
|
118
120
|
## License
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vox-ai-app/integrations",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "macOS integrations (Mail, Screen, iMessage) for Vox",
|
|
@@ -8,10 +8,9 @@
|
|
|
8
8
|
"private": false,
|
|
9
9
|
"exports": {
|
|
10
10
|
".": "./src/index.js",
|
|
11
|
-
"./defs": "./src/
|
|
12
|
-
"./defs/
|
|
13
|
-
"./defs/
|
|
14
|
-
"./defs/imessage": "./src/defs/imessage.js",
|
|
11
|
+
"./defs/mail": "./src/mail/def.js",
|
|
12
|
+
"./defs/screen": "./src/screen/def.js",
|
|
13
|
+
"./defs/imessage": "./src/imessage/def.js",
|
|
15
14
|
"./mail": "./src/mail/index.js",
|
|
16
15
|
"./screen": "./src/screen/index.js",
|
|
17
16
|
"./screen/capture": "./src/screen/capture/index.js",
|
|
@@ -36,7 +35,7 @@
|
|
|
36
35
|
"electron": ">=28.0.0"
|
|
37
36
|
},
|
|
38
37
|
"dependencies": {
|
|
39
|
-
"@vox-ai-app/tools": "^1.0.
|
|
38
|
+
"@vox-ai-app/tools": "^1.0.1",
|
|
40
39
|
"better-sqlite3": "^12.0.0"
|
|
41
40
|
}
|
|
42
41
|
}
|
|
@@ -3,9 +3,24 @@ import os from 'os'
|
|
|
3
3
|
import path from 'path'
|
|
4
4
|
import { promisify } from 'util'
|
|
5
5
|
import { exec } from 'child_process'
|
|
6
|
+
import { shell } from 'electron'
|
|
6
7
|
|
|
7
8
|
const execAsync = promisify(exec)
|
|
8
9
|
|
|
10
|
+
const isAutomationDeniedError = (err) => {
|
|
11
|
+
const msg = String(err?.message || err?.stderr || '').toLowerCase()
|
|
12
|
+
return (
|
|
13
|
+
msg.includes('not allowed to send apple events') ||
|
|
14
|
+
msg.includes('apple event handler failed') ||
|
|
15
|
+
msg.includes('-1743') ||
|
|
16
|
+
msg.includes('access not allowed')
|
|
17
|
+
)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const openMessagesAutomationSettings = () => {
|
|
21
|
+
shell.openExternal('x-apple.systempreferences:com.apple.preference.security?Privacy_Automation')
|
|
22
|
+
}
|
|
23
|
+
|
|
9
24
|
const writeTmp = async (content, ext) => {
|
|
10
25
|
const file = path.join(os.tmpdir(), `vox_ims_${Date.now()}.${ext}`)
|
|
11
26
|
await fs.writeFile(file, content, 'utf8')
|
|
@@ -62,6 +77,17 @@ end tell`
|
|
|
62
77
|
try {
|
|
63
78
|
await execAsync(`osascript "${scriptFile}"`, { timeout: 15_000 })
|
|
64
79
|
console.info('[imessage] Reply sent to', handle, 'files:', filePaths.length)
|
|
80
|
+
} catch (err) {
|
|
81
|
+
if (isAutomationDeniedError(err)) {
|
|
82
|
+
openMessagesAutomationSettings()
|
|
83
|
+
throw Object.assign(
|
|
84
|
+
new Error(
|
|
85
|
+
'Vox needs permission to control Messages. Please grant it in System Settings → Privacy & Security → Automation → Vox → Messages.'
|
|
86
|
+
),
|
|
87
|
+
{ code: 'IMESSAGE_AUTOMATION_REQUIRED' }
|
|
88
|
+
)
|
|
89
|
+
}
|
|
90
|
+
throw err
|
|
65
91
|
} finally {
|
|
66
92
|
await fs.unlink(scriptFile).catch(() => {})
|
|
67
93
|
}
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
import { ensureAppleMailConfigured } from '../../shared/index.js'
|
|
10
10
|
|
|
11
11
|
const runAs = async (script, signal) => {
|
|
12
|
-
await ensureAppleMailConfigured()
|
|
12
|
+
await ensureAppleMailConfigured(signal)
|
|
13
13
|
const scriptFile = await writeTempScript(script, 'scpt')
|
|
14
14
|
try {
|
|
15
15
|
const { stdout } = await execAbortable(
|
|
@@ -53,7 +53,7 @@ export const replyToEmailMac = async (
|
|
|
53
53
|
{ messageId, body, replyAll = false, account },
|
|
54
54
|
{ signal } = {}
|
|
55
55
|
) => {
|
|
56
|
-
const bodyEsc = esc(body)
|
|
56
|
+
const bodyEsc = esc(body).replace(/\n/g, '" & return & "')
|
|
57
57
|
const replyCmd = replyAll ? 'reply theMsg with reply to all' : 'reply theMsg'
|
|
58
58
|
const senderLines = account
|
|
59
59
|
? [
|
|
@@ -83,7 +83,7 @@ export const replyToEmailMac = async (
|
|
|
83
83
|
}
|
|
84
84
|
}
|
|
85
85
|
export const forwardEmailMac = async ({ messageId, to, body = '', account }, { signal } = {}) => {
|
|
86
|
-
const bodyEsc = esc(body)
|
|
86
|
+
const bodyEsc = esc(body).replace(/\n/g, '" & return & "')
|
|
87
87
|
const senderLines = account
|
|
88
88
|
? [
|
|
89
89
|
` set acct to first account whose name contains "${esc(account)}"`,
|
|
@@ -205,11 +205,11 @@ export const createDraftMac = async (
|
|
|
205
205
|
` set acct to first account whose name contains "${esc(account)}"`,
|
|
206
206
|
' set addressesList to email addresses of acct',
|
|
207
207
|
' set senderAddr to item 1 of addressesList',
|
|
208
|
-
` set msg to make new outgoing message with properties {subject:"${esc(subject)}", content:"${esc(body).replace(/\n/g, '
|
|
208
|
+
` set msg to make new outgoing message with properties {subject:"${esc(subject)}", content:"${esc(body).replace(/\n/g, '" & return & "')}", visible:true, sender:senderAddr}`
|
|
209
209
|
)
|
|
210
210
|
} else {
|
|
211
211
|
lines.push(
|
|
212
|
-
` set msg to make new outgoing message with properties {subject:"${esc(subject)}", content:"${esc(body).replace(/\n/g, '
|
|
212
|
+
` set msg to make new outgoing message with properties {subject:"${esc(subject)}", content:"${esc(body).replace(/\n/g, '" & return & "')}", visible:true}`
|
|
213
213
|
)
|
|
214
214
|
}
|
|
215
215
|
lines.push(' tell msg')
|
|
@@ -9,11 +9,11 @@ import {
|
|
|
9
9
|
} from '@vox-ai-app/tools/exec'
|
|
10
10
|
import { ensureAppleMailConfigured } from '../../shared/index.js'
|
|
11
11
|
export const sendEmailMac = async (
|
|
12
|
-
{ to, cc, bcc, subject, body, attachments, account },
|
|
12
|
+
{ to, cc = [], bcc = [], subject, body, attachments = [], account },
|
|
13
13
|
{ signal } = {}
|
|
14
14
|
) => {
|
|
15
15
|
await ensureAppleMailConfigured(signal)
|
|
16
|
-
const bodyEsc = esc(body).replace(/\n/g, '
|
|
16
|
+
const bodyEsc = esc(body).replace(/\n/g, '" & return & "')
|
|
17
17
|
const lines = ['tell application "Mail"']
|
|
18
18
|
if (account) {
|
|
19
19
|
lines.push(
|