@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 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
- Requires macOS. Each integration needs specific system permissions granted by the user.
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` | All tool definitions |
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.1",
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/defs/index.js",
12
- "./defs/mail": "./src/defs/mail.js",
13
- "./defs/screen": "./src/defs/screen.js",
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.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, '\\n')}", visible:true, sender:senderAddr}`
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, '\\n')}", visible:true}`
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, '\\n')
16
+ const bodyEsc = esc(body).replace(/\n/g, '" & return & "')
17
17
  const lines = ['tell application "Mail"']
18
18
  if (account) {
19
19
  lines.push(