palmier 0.9.6 → 0.9.8

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.
Files changed (255) hide show
  1. package/README.md +28 -13
  2. package/dist/agents/agent.d.ts +0 -1
  3. package/dist/agents/agent.js +0 -1
  4. package/dist/agents/aider.d.ts +0 -1
  5. package/dist/agents/aider.js +0 -1
  6. package/dist/agents/claude.d.ts +0 -1
  7. package/dist/agents/claude.js +0 -1
  8. package/dist/agents/cline.d.ts +0 -1
  9. package/dist/agents/cline.js +0 -1
  10. package/dist/agents/codex.d.ts +0 -1
  11. package/dist/agents/codex.js +0 -1
  12. package/dist/agents/copilot.d.ts +0 -1
  13. package/dist/agents/copilot.js +0 -1
  14. package/dist/agents/cursor.d.ts +0 -1
  15. package/dist/agents/cursor.js +0 -1
  16. package/dist/agents/deepagents.d.ts +0 -1
  17. package/dist/agents/deepagents.js +0 -1
  18. package/dist/agents/droid.d.ts +0 -1
  19. package/dist/agents/droid.js +0 -1
  20. package/dist/agents/gemini.d.ts +0 -1
  21. package/dist/agents/gemini.js +0 -1
  22. package/dist/agents/goose.d.ts +0 -1
  23. package/dist/agents/goose.js +0 -1
  24. package/dist/agents/hermes.d.ts +0 -1
  25. package/dist/agents/hermes.js +0 -1
  26. package/dist/agents/kimi.d.ts +0 -1
  27. package/dist/agents/kimi.js +0 -1
  28. package/dist/agents/kiro.d.ts +0 -1
  29. package/dist/agents/kiro.js +0 -1
  30. package/dist/agents/openclaw.d.ts +0 -1
  31. package/dist/agents/openclaw.js +0 -1
  32. package/dist/agents/opencode.d.ts +0 -1
  33. package/dist/agents/opencode.js +0 -1
  34. package/dist/agents/qoder.d.ts +0 -1
  35. package/dist/agents/qoder.js +0 -1
  36. package/dist/agents/qwen.d.ts +0 -1
  37. package/dist/agents/qwen.js +0 -1
  38. package/dist/agents/shared-prompt.d.ts +0 -1
  39. package/dist/agents/shared-prompt.js +0 -1
  40. package/dist/client-store.d.ts +0 -1
  41. package/dist/client-store.js +0 -1
  42. package/dist/commands/clients.d.ts +0 -1
  43. package/dist/commands/clients.js +0 -1
  44. package/dist/commands/info.d.ts +0 -1
  45. package/dist/commands/info.js +0 -1
  46. package/dist/commands/init.d.ts +0 -1
  47. package/dist/commands/init.js +1 -2
  48. package/dist/commands/pair.d.ts +0 -1
  49. package/dist/commands/pair.js +0 -1
  50. package/dist/commands/restart.d.ts +0 -1
  51. package/dist/commands/restart.js +0 -1
  52. package/dist/commands/run.d.ts +0 -1
  53. package/dist/commands/run.js +19 -3
  54. package/dist/commands/serve.d.ts +0 -1
  55. package/dist/commands/serve.js +0 -1
  56. package/dist/commands/uninstall.d.ts +0 -1
  57. package/dist/commands/uninstall.js +0 -1
  58. package/dist/config.d.ts +0 -1
  59. package/dist/config.js +0 -1
  60. package/dist/event-queues.d.ts +0 -1
  61. package/dist/event-queues.js +0 -1
  62. package/dist/events.d.ts +0 -1
  63. package/dist/events.js +0 -1
  64. package/dist/index.d.ts +0 -1
  65. package/dist/index.js +0 -1
  66. package/dist/linked-device.d.ts +0 -1
  67. package/dist/linked-device.js +0 -1
  68. package/dist/mcp-handler.d.ts +0 -1
  69. package/dist/mcp-handler.js +0 -1
  70. package/dist/mcp-tools.d.ts +0 -1
  71. package/dist/mcp-tools.js +0 -1
  72. package/dist/nats-client.d.ts +0 -1
  73. package/dist/nats-client.js +0 -1
  74. package/dist/network.d.ts +0 -1
  75. package/dist/network.js +0 -1
  76. package/dist/notification-store.d.ts +0 -1
  77. package/dist/notification-store.js +0 -1
  78. package/dist/pending-requests.d.ts +0 -1
  79. package/dist/pending-requests.js +0 -1
  80. package/dist/platform/index.d.ts +0 -1
  81. package/dist/platform/index.js +0 -1
  82. package/dist/platform/linux.d.ts +0 -1
  83. package/dist/platform/linux.js +0 -1
  84. package/dist/platform/macos.d.ts +0 -1
  85. package/dist/platform/macos.js +0 -1
  86. package/dist/platform/platform.d.ts +0 -1
  87. package/dist/platform/platform.js +0 -1
  88. package/dist/platform/windows.d.ts +0 -1
  89. package/dist/platform/windows.js +0 -1
  90. package/dist/pwa/assets/{index-MLEFUP3r.js → index-DWvRAUiy.js} +31 -31
  91. package/dist/pwa/assets/{web-B1sKCc7e.js → web-C4iZbqTC.js} +1 -1
  92. package/dist/pwa/assets/{web-ETD-8ZHd.js → web-CBFqJGX6.js} +1 -1
  93. package/dist/pwa/assets/{web-B4xEa6WO.js → web-DL4uXOpS.js} +1 -1
  94. package/dist/pwa/index.html +2 -2
  95. package/dist/rpc-handler.d.ts +0 -1
  96. package/dist/rpc-handler.js +0 -1
  97. package/dist/sms-store.d.ts +0 -1
  98. package/dist/sms-store.js +0 -1
  99. package/dist/spawn-command.d.ts +0 -1
  100. package/dist/spawn-command.js +0 -1
  101. package/dist/task.d.ts +0 -1
  102. package/dist/task.js +0 -1
  103. package/dist/transports/http-transport.d.ts +0 -1
  104. package/dist/transports/http-transport.js +0 -1
  105. package/dist/transports/nats-transport.d.ts +0 -1
  106. package/dist/transports/nats-transport.js +0 -1
  107. package/dist/types.d.ts +0 -1
  108. package/dist/types.js +0 -1
  109. package/dist/update-checker.d.ts +0 -1
  110. package/dist/update-checker.js +0 -1
  111. package/package.json +11 -1
  112. package/.github/workflows/ci.yml +0 -16
  113. package/.github/workflows/publish.yml +0 -37
  114. package/CLAUDE.md +0 -22
  115. package/dist/pwa/apple-touch-icon.png +0 -0
  116. package/dist/pwa/manifest.webmanifest +0 -1
  117. package/dist/pwa/pwa-192x192.png +0 -0
  118. package/dist/pwa/pwa-512x512.png +0 -0
  119. package/dist/pwa/registerSW.js +0 -1
  120. package/dist/pwa/service-worker.js +0 -2
  121. package/palmier-server/.github/workflows/ci.yml +0 -21
  122. package/palmier-server/.github/workflows/deploy.yml +0 -38
  123. package/palmier-server/CLAUDE.md +0 -17
  124. package/palmier-server/PRODUCTION.md +0 -358
  125. package/palmier-server/README.md +0 -231
  126. package/palmier-server/nats.conf +0 -19
  127. package/palmier-server/package.json +0 -15
  128. package/palmier-server/pnpm-lock.yaml +0 -7639
  129. package/palmier-server/pnpm-workspace.yaml +0 -3
  130. package/palmier-server/pwa/index.html +0 -16
  131. package/palmier-server/pwa/logo/logo_20260421.png +0 -0
  132. package/palmier-server/pwa/package.json +0 -34
  133. package/palmier-server/pwa/public/apple-touch-icon.png +0 -0
  134. package/palmier-server/pwa/public/favicon.ico +0 -0
  135. package/palmier-server/pwa/public/pwa-192x192.png +0 -0
  136. package/palmier-server/pwa/public/pwa-512x512.png +0 -0
  137. package/palmier-server/pwa/src/App.css +0 -3012
  138. package/palmier-server/pwa/src/App.tsx +0 -59
  139. package/palmier-server/pwa/src/agentLabels.ts +0 -11
  140. package/palmier-server/pwa/src/api.ts +0 -67
  141. package/palmier-server/pwa/src/components/CapabilityToggles.tsx +0 -170
  142. package/palmier-server/pwa/src/components/ConnectionStatusIcon.tsx +0 -113
  143. package/palmier-server/pwa/src/components/HostMenu.tsx +0 -429
  144. package/palmier-server/pwa/src/components/PermissionsDialog.tsx +0 -34
  145. package/palmier-server/pwa/src/components/PullToRefreshIndicator.tsx +0 -46
  146. package/palmier-server/pwa/src/components/RunDetailView.tsx +0 -343
  147. package/palmier-server/pwa/src/components/SessionComposer.tsx +0 -157
  148. package/palmier-server/pwa/src/components/SessionsView.tsx +0 -326
  149. package/palmier-server/pwa/src/components/SwipeToDeleteRow.tsx +0 -170
  150. package/palmier-server/pwa/src/components/TabBar.tsx +0 -40
  151. package/palmier-server/pwa/src/components/TaskCard.tsx +0 -255
  152. package/palmier-server/pwa/src/components/TaskForm.tsx +0 -766
  153. package/palmier-server/pwa/src/components/TasksView.tsx +0 -179
  154. package/palmier-server/pwa/src/constants.ts +0 -2
  155. package/palmier-server/pwa/src/contexts/HostConnectionContext.tsx +0 -432
  156. package/palmier-server/pwa/src/contexts/HostStoreContext.tsx +0 -124
  157. package/palmier-server/pwa/src/draftGuard.ts +0 -24
  158. package/palmier-server/pwa/src/formatTime.ts +0 -44
  159. package/palmier-server/pwa/src/hooks/useBackClose.ts +0 -75
  160. package/palmier-server/pwa/src/hooks/useMediaQuery.ts +0 -17
  161. package/palmier-server/pwa/src/hooks/usePullToRefresh.ts +0 -102
  162. package/palmier-server/pwa/src/hooks/usePushSubscription.ts +0 -77
  163. package/palmier-server/pwa/src/main.tsx +0 -14
  164. package/palmier-server/pwa/src/native/Device.ts +0 -49
  165. package/palmier-server/pwa/src/pages/Dashboard.tsx +0 -542
  166. package/palmier-server/pwa/src/pages/PairHost.tsx +0 -232
  167. package/palmier-server/pwa/src/pages/PairSetup.tsx +0 -134
  168. package/palmier-server/pwa/src/service-worker.ts +0 -142
  169. package/palmier-server/pwa/src/types.ts +0 -75
  170. package/palmier-server/pwa/src/vite-env.d.ts +0 -11
  171. package/palmier-server/pwa/tsconfig.json +0 -21
  172. package/palmier-server/pwa/tsconfig.node.json +0 -19
  173. package/palmier-server/pwa/vite.config.ts +0 -47
  174. package/palmier-server/server/.env.example +0 -20
  175. package/palmier-server/server/package.json +0 -36
  176. package/palmier-server/server/src/db.ts +0 -44
  177. package/palmier-server/server/src/fcm.ts +0 -74
  178. package/palmier-server/server/src/index.ts +0 -688
  179. package/palmier-server/server/src/nats-jwt.ts +0 -299
  180. package/palmier-server/server/src/nats-setup.ts +0 -48
  181. package/palmier-server/server/src/nats.ts +0 -33
  182. package/palmier-server/server/src/notify.ts +0 -34
  183. package/palmier-server/server/src/push.ts +0 -68
  184. package/palmier-server/server/src/routes/device.ts +0 -224
  185. package/palmier-server/server/src/routes/fcm.ts +0 -64
  186. package/palmier-server/server/src/routes/hosts.ts +0 -56
  187. package/palmier-server/server/src/routes/push.ts +0 -101
  188. package/palmier-server/server/tsconfig.json +0 -20
  189. package/palmier-server/spec.md +0 -533
  190. package/src/agents/agent-instructions.md +0 -28
  191. package/src/agents/agent.ts +0 -114
  192. package/src/agents/aider.ts +0 -35
  193. package/src/agents/claude.ts +0 -39
  194. package/src/agents/cline.ts +0 -35
  195. package/src/agents/codex.ts +0 -40
  196. package/src/agents/copilot.ts +0 -37
  197. package/src/agents/cursor.ts +0 -36
  198. package/src/agents/deepagents.ts +0 -36
  199. package/src/agents/droid.ts +0 -35
  200. package/src/agents/gemini.ts +0 -43
  201. package/src/agents/goose.ts +0 -33
  202. package/src/agents/hermes.ts +0 -36
  203. package/src/agents/kimi.ts +0 -35
  204. package/src/agents/kiro.ts +0 -36
  205. package/src/agents/openclaw.ts +0 -29
  206. package/src/agents/opencode.ts +0 -36
  207. package/src/agents/qoder.ts +0 -36
  208. package/src/agents/qwen.ts +0 -32
  209. package/src/agents/shared-prompt.ts +0 -30
  210. package/src/client-store.ts +0 -68
  211. package/src/commands/clients.ts +0 -29
  212. package/src/commands/info.ts +0 -29
  213. package/src/commands/init.ts +0 -165
  214. package/src/commands/pair.ts +0 -137
  215. package/src/commands/restart.ts +0 -6
  216. package/src/commands/run.ts +0 -608
  217. package/src/commands/serve.ts +0 -211
  218. package/src/commands/uninstall.ts +0 -9
  219. package/src/config.ts +0 -36
  220. package/src/cross-spawn.d.ts +0 -5
  221. package/src/event-queues.ts +0 -41
  222. package/src/events.ts +0 -29
  223. package/src/index.ts +0 -111
  224. package/src/linked-device.ts +0 -52
  225. package/src/mcp-handler.ts +0 -200
  226. package/src/mcp-tools.ts +0 -839
  227. package/src/nats-client.ts +0 -19
  228. package/src/network.ts +0 -96
  229. package/src/notification-store.ts +0 -30
  230. package/src/pending-requests.ts +0 -73
  231. package/src/platform/index.ts +0 -20
  232. package/src/platform/linux.ts +0 -296
  233. package/src/platform/macos.ts +0 -329
  234. package/src/platform/platform.ts +0 -31
  235. package/src/platform/windows.ts +0 -299
  236. package/src/rpc-handler.ts +0 -691
  237. package/src/sms-store.ts +0 -28
  238. package/src/spawn-command.ts +0 -123
  239. package/src/task.ts +0 -343
  240. package/src/transports/http-transport.ts +0 -478
  241. package/src/transports/nats-transport.ts +0 -76
  242. package/src/types.ts +0 -89
  243. package/src/update-checker.ts +0 -40
  244. package/test/agent-instructions.test.ts +0 -209
  245. package/test/agent-output-parsing.test.ts +0 -74
  246. package/test/linux-cron.test.ts +0 -41
  247. package/test/macos-plist.test.ts +0 -112
  248. package/test/notification-store.test.ts +0 -57
  249. package/test/pairing.test.ts +0 -35
  250. package/test/result-state.test.ts +0 -110
  251. package/test/task-parsing.test.ts +0 -82
  252. package/test/taskrun-messages.test.ts +0 -224
  253. package/test/tsconfig.json +0 -9
  254. package/test/windows-xml.test.ts +0 -89
  255. package/tsconfig.json +0 -19
package/README.md CHANGED
@@ -4,14 +4,29 @@
4
4
  [![npm version](https://img.shields.io/npm/v/palmier)](https://www.npmjs.com/package/palmier)
5
5
  [![license](https://img.shields.io/npm/l/palmier)](https://github.com/caihongxu/palmier/blob/master/LICENSE)
6
6
 
7
- **Website:** [palmier.me](https://www.palmier.me) | **App:** [app.palmier.me](https://app.palmier.me)
7
+ **Website:** [palmier.me](https://www.palmier.me) | **Web App:** [app.palmier.me](https://app.palmier.me) | **Android App:** [caihongxu/palmier-android](https://github.com/caihongxu/palmier-android)
8
8
 
9
- You have AI agents on your machine. Palmier is a two-way bridge between them and your phone: you reach your agents from anywhere, and they reach you wherever you are.
9
+ You already have AI agents running on your machine. Palmier is an agent-agnostic bridge between those agents and your phone.
10
10
 
11
- From your phone, dispatch one-off sessions, schedule recurring tasks, approve permission requests, and check results. From your machine, agents push notifications and alarms, ask you questions, and tap into phone-side capabilities like SMS, contacts, and calendar — so they can act on real-world events, not just sit idle until you open a terminal.
11
+ From your phone, you can start sessions, schedule tasks, approve requests, and review results. From your machine, your agents can use phone-side capabilities like notifications, location, SMS, contacts, and calendar — so they can react to the real world, not just the terminal.
12
12
 
13
13
  It runs on your machine as a background daemon and pairs with a mobile-friendly PWA.
14
- > **Important:** By using Palmier, you agree to the [Terms of Service](https://www.palmier.me/terms) and [Privacy Policy](https://www.palmier.me/privacy). See the [Disclaimer](#disclaimer) section below.
14
+
15
+ ## What Palmier is
16
+
17
+ Palmier is an **agent-agnostic phone bridge and mobile control layer** for the agents you already use.
18
+
19
+ It is not:
20
+
21
+ * an agent runtime itself
22
+ * a replacement for Claude Code / Codex CLI / Gemini CLI / OpenClaw / Hermes
23
+ * a system for driving your phone UI like a human tapping through apps
24
+
25
+ Instead, Palmier focuses on:
26
+
27
+ * letting agents access phone-side capabilities and context in the background
28
+ * letting you talk to, manage, and schedule your agents from your phone
29
+ * making phone integrations work out of the box without requiring users to wire up separate calendar/email/contact stacks
15
30
 
16
31
  ## Quick Start
17
32
 
@@ -37,7 +52,7 @@ It runs on your machine as a background daemon and pairs with a mobile-friendly
37
52
  palmier init
38
53
  ```
39
54
  This detects your agents, configures access, installs the background daemon, and starts pairing.
40
- 4. Open `http://localhost:<port>` to access the app locally — no pairing needed.
55
+ 4. Open `http://localhost:7256` to access the app locally — no pairing needed.
41
56
  5. To access from other devices, enter the pairing code shown after init into the [PWA](https://app.palmier.me).
42
57
 
43
58
  ### Prerequisites
@@ -52,9 +67,9 @@ Palmier runs as a background daemon (systemd on Linux, launchd on macOS, Task Sc
52
67
 
53
68
  ### MCP Server
54
69
 
55
- Palmier exposes an [MCP](https://modelcontextprotocol.io) server at `http://localhost:<port>/mcp` (streamable HTTP transport). MCP-capable agents can register it to get tool and resource definitions automatically. The same tools and resources are also available as REST endpoints for curl-based agents.
70
+ Palmier exposes an [MCP](https://modelcontextprotocol.io) server at `http://localhost:7256/mcp` (streamable HTTP transport). MCP-capable agents can register it to get tool and resource definitions automatically. The same tools and resources are also available as REST endpoints for curl-based agents.
56
71
 
57
- **MCP server URL:** `http://localhost:<port>/mcp`
72
+ **MCP server URL:** `http://localhost:7256/mcp`
58
73
 
59
74
  **Available tools:**
60
75
  | Tool | Description |
@@ -117,17 +132,17 @@ Three ways to reach your host, ordered by setup effort:
117
132
 
118
133
  | Mode | Where | Pairing | Notes |
119
134
  |------|-------|---------|-------|
120
- | **Local** | `http://localhost:<port>` in a browser on the host machine | Not required | Loopback only. No internet needed. |
135
+ | **Local** | `http://localhost:7256` in a browser on the host machine | Not required | Loopback only. No internet needed. |
121
136
  | **Remote (web)** | [https://app.palmier.me](https://app.palmier.me) in any browser | Required | Always goes through the cloud relay. |
122
- | **Remote (app)** | [Android APK](https://github.com/caihongxu/palmier-android/releases) | Required | Push notifications, device capabilities, and **auto-LAN**. |
137
+ | **Remote (app)** | [Android APK](https://github.com/caihongxu/palmier-android/releases/latest) | Required | Push notifications, device capabilities, and **auto-LAN**. |
123
138
 
124
- **Auto-LAN (native app only).** When the Android app is on the same network as the host, it transparently routes RPC over direct LAN HTTP (`http://<host-ip>:<port>/rpc/...`) instead of through the relay — lower latency, no protocol change. Events still flow over the relay. Pairing always goes through the relay regardless. Browser PWAs can't do this (Private Network Access / mixed-content restrictions) and stay on the relay.
139
+ **Auto-LAN (native app only).** When the Android app is on the same network as the host, it transparently routes RPC over direct LAN HTTP (`http://<host-ip>:7256/rpc/...`) instead of through the relay — lower latency, no protocol change. Browser PWAs can't do this (Private Network Access / mixed-content restrictions) and stay on the relay.
125
140
 
126
141
  ## Security & Privacy
127
142
 
128
143
  **Local mode** — all traffic stays on `127.0.0.1`. No data leaves your machine. The web UI, `/pair`, and `/events` reject any non-loopback caller; only `/rpc/<method>` (bearer-auth) and `/health` are reachable from the LAN.
129
144
 
130
- **Server mode** — communication between your device and host is relayed through the Palmier cloud server over TLS-encrypted NATS connections. The server acts as a passthrough relay only — it does not store, log, or inspect any user data, task content, or agent output. The only data the server persists is a host registration ID used for message routing and Web Push subscription info for delivering notifications. See the [Privacy Policy](https://www.palmier.me/privacy) for full details.
145
+ **Server mode** — communication between your device and host is relayed through the Palmier cloud server over TLS-encrypted NATS connections. The server acts as a passthrough relay only — it does not store, log, or inspect any user data, task content, or agent output. The only data the server persists is a host registration ID used for message routing and push subscription tokens for delivering notifications. See the [Privacy Policy](https://www.palmier.me/privacy) for full details.
131
146
 
132
147
  **Auto-LAN** — direct LAN HTTP requests use the same client token (Bearer auth) generated during pairing. The host validates every `/rpc/*` call regardless of source.
133
148
 
@@ -137,7 +152,7 @@ In all modes, client tokens are generated and validated entirely on your host. T
137
152
 
138
153
  ### Pairing Devices
139
154
 
140
- Local access (`http://localhost:<port>`) works immediately — no pairing needed.
155
+ Local access (`http://localhost:7256`) works immediately — no pairing needed.
141
156
 
142
157
  For remote access (web or app), run `palmier pair` on the host to generate a code, then enter it at [https://app.palmier.me](https://app.palmier.me) or in the Android app. Pairing always goes through the relay; auto-LAN kicks in transparently afterward in the native app when on the same network.
143
158
 
@@ -226,7 +241,7 @@ To fully remove Palmier from a machine:
226
241
 
227
242
  ## Disclaimer
228
243
 
229
- Palmier spawns AI agents that can read, write, and execute on your machine. [Read the full disclaimer](DISCLAIMER.md) before use.
244
+ Palmier spawns AI agents that can read, write, and execute on your machine. [Read the full disclaimer](DISCLAIMER.md) before use. By using Palmier, you agree to the [Terms of Service](https://www.palmier.me/terms) and [Privacy Policy](https://www.palmier.me/privacy).
230
245
 
231
246
  ## License
232
247
 
@@ -32,4 +32,3 @@ export interface DetectedAgent {
32
32
  }
33
33
  export declare function detectAgents(): Promise<DetectedAgent[]>;
34
34
  export declare function getAgent(name: string): AgentTool;
35
- //# sourceMappingURL=agent.d.ts.map
@@ -70,4 +70,3 @@ export function getAgent(name) {
70
70
  }
71
71
  return agent;
72
72
  }
73
- //# sourceMappingURL=agent.js.map
@@ -7,4 +7,3 @@ export declare class Aider implements AgentTool {
7
7
  getTaskRunCommandLine(task: ParsedTask, followupPrompt?: string, extraPermissions?: RequiredPermission[] | "yolo"): CommandLine;
8
8
  init(): Promise<boolean>;
9
9
  }
10
- //# sourceMappingURL=aider.d.ts.map
@@ -27,4 +27,3 @@ export class Aider {
27
27
  return true;
28
28
  }
29
29
  }
30
- //# sourceMappingURL=aider.js.map
@@ -7,4 +7,3 @@ export declare class ClaudeAgent implements AgentTool {
7
7
  getTaskRunCommandLine(task: ParsedTask, followupPrompt?: string, extraPermissions?: RequiredPermission[] | "yolo"): CommandLine;
8
8
  init(): Promise<boolean>;
9
9
  }
10
- //# sourceMappingURL=claude.d.ts.map
@@ -33,4 +33,3 @@ export class ClaudeAgent {
33
33
  return true;
34
34
  }
35
35
  }
36
- //# sourceMappingURL=claude.js.map
@@ -7,4 +7,3 @@ export declare class Cline implements AgentTool {
7
7
  getTaskRunCommandLine(task: ParsedTask, followupPrompt?: string, extraPermissions?: RequiredPermission[] | "yolo"): CommandLine;
8
8
  init(): Promise<boolean>;
9
9
  }
10
- //# sourceMappingURL=cline.d.ts.map
@@ -27,4 +27,3 @@ export class Cline {
27
27
  return true;
28
28
  }
29
29
  }
30
- //# sourceMappingURL=cline.js.map
@@ -7,4 +7,3 @@ export declare class CodexAgent implements AgentTool {
7
7
  getTaskRunCommandLine(task: ParsedTask, followupPrompt?: string, extraPermissions?: RequiredPermission[] | "yolo"): CommandLine;
8
8
  init(): Promise<boolean>;
9
9
  }
10
- //# sourceMappingURL=codex.d.ts.map
@@ -34,4 +34,3 @@ export class CodexAgent {
34
34
  return true;
35
35
  }
36
36
  }
37
- //# sourceMappingURL=codex.js.map
@@ -7,4 +7,3 @@ export declare class CopilotAgent implements AgentTool {
7
7
  getTaskRunCommandLine(task: ParsedTask, followupPrompt?: string, extraPermissions?: RequiredPermission[] | "yolo"): CommandLine;
8
8
  init(): Promise<boolean>;
9
9
  }
10
- //# sourceMappingURL=copilot.d.ts.map
@@ -33,4 +33,3 @@ export class CopilotAgent {
33
33
  return true;
34
34
  }
35
35
  }
36
- //# sourceMappingURL=copilot.js.map
@@ -7,4 +7,3 @@ export declare class Cursor implements AgentTool {
7
7
  getTaskRunCommandLine(task: ParsedTask, followupPrompt?: string, extraPermissions?: RequiredPermission[] | "yolo"): CommandLine;
8
8
  init(): Promise<boolean>;
9
9
  }
10
- //# sourceMappingURL=cursor.d.ts.map
@@ -30,4 +30,3 @@ export class Cursor {
30
30
  return true;
31
31
  }
32
32
  }
33
- //# sourceMappingURL=cursor.js.map
@@ -7,4 +7,3 @@ export declare class DeepAgents implements AgentTool {
7
7
  getTaskRunCommandLine(task: ParsedTask, followupPrompt?: string, extraPermissions?: RequiredPermission[] | "yolo"): CommandLine;
8
8
  init(): Promise<boolean>;
9
9
  }
10
- //# sourceMappingURL=deepagents.d.ts.map
@@ -30,4 +30,3 @@ export class DeepAgents {
30
30
  return true;
31
31
  }
32
32
  }
33
- //# sourceMappingURL=deepagents.js.map
@@ -7,4 +7,3 @@ export declare class DroidAgent implements AgentTool {
7
7
  getTaskRunCommandLine(task: ParsedTask, followupPrompt?: string, extraPermissions?: RequiredPermission[] | "yolo"): CommandLine;
8
8
  init(): Promise<boolean>;
9
9
  }
10
- //# sourceMappingURL=droid.d.ts.map
@@ -27,4 +27,3 @@ export class DroidAgent {
27
27
  return true;
28
28
  }
29
29
  }
30
- //# sourceMappingURL=droid.js.map
@@ -7,4 +7,3 @@ export declare class GeminiAgent implements AgentTool {
7
7
  getTaskRunCommandLine(task: ParsedTask, followupPrompt?: string, extraPermissions?: RequiredPermission[] | "yolo"): CommandLine;
8
8
  init(): Promise<boolean>;
9
9
  }
10
- //# sourceMappingURL=gemini.d.ts.map
@@ -36,4 +36,3 @@ export class GeminiAgent {
36
36
  return true;
37
37
  }
38
38
  }
39
- //# sourceMappingURL=gemini.js.map
@@ -7,4 +7,3 @@ export declare class GooseAgent implements AgentTool {
7
7
  getTaskRunCommandLine(task: ParsedTask, followupPrompt?: string, extraPermissions?: RequiredPermission[] | "yolo"): CommandLine;
8
8
  init(): Promise<boolean>;
9
9
  }
10
- //# sourceMappingURL=goose.d.ts.map
@@ -27,4 +27,3 @@ export class GooseAgent {
27
27
  return true;
28
28
  }
29
29
  }
30
- //# sourceMappingURL=goose.js.map
@@ -7,4 +7,3 @@ export declare class Hermes implements AgentTool {
7
7
  getTaskRunCommandLine(task: ParsedTask, followupPrompt?: string, extraPermissions?: RequiredPermission[] | "yolo"): CommandLine;
8
8
  init(): Promise<boolean>;
9
9
  }
10
- //# sourceMappingURL=hermes.d.ts.map
@@ -30,4 +30,3 @@ export class Hermes {
30
30
  return true;
31
31
  }
32
32
  }
33
- //# sourceMappingURL=hermes.js.map
@@ -7,4 +7,3 @@ export declare class KimiAgent implements AgentTool {
7
7
  getTaskRunCommandLine(task: ParsedTask, followupPrompt?: string, extraPermissions?: RequiredPermission[] | "yolo"): CommandLine;
8
8
  init(): Promise<boolean>;
9
9
  }
10
- //# sourceMappingURL=kimi.d.ts.map
@@ -30,4 +30,3 @@ export class KimiAgent {
30
30
  return true;
31
31
  }
32
32
  }
33
- //# sourceMappingURL=kimi.js.map
@@ -7,4 +7,3 @@ export declare class Kiro implements AgentTool {
7
7
  getTaskRunCommandLine(task: ParsedTask, followupPrompt?: string, extraPermissions?: RequiredPermission[] | "yolo"): CommandLine;
8
8
  init(): Promise<boolean>;
9
9
  }
10
- //# sourceMappingURL=kiro.d.ts.map
@@ -30,4 +30,3 @@ export class Kiro {
30
30
  return true;
31
31
  }
32
32
  }
33
- //# sourceMappingURL=kiro.js.map
@@ -7,4 +7,3 @@ export declare class OpenClawAgent implements AgentTool {
7
7
  getTaskRunCommandLine(task: ParsedTask, followupPrompt?: string, extraPermissions?: RequiredPermission[] | "yolo"): CommandLine;
8
8
  init(): Promise<boolean>;
9
9
  }
10
- //# sourceMappingURL=openclaw.d.ts.map
@@ -22,4 +22,3 @@ export class OpenClawAgent {
22
22
  return true;
23
23
  }
24
24
  }
25
- //# sourceMappingURL=openclaw.js.map
@@ -7,4 +7,3 @@ export declare class OpenCodeAgent implements AgentTool {
7
7
  getTaskRunCommandLine(task: ParsedTask, followupPrompt?: string, extraPermissions?: RequiredPermission[] | "yolo"): CommandLine;
8
8
  init(): Promise<boolean>;
9
9
  }
10
- //# sourceMappingURL=opencode.d.ts.map
@@ -30,4 +30,3 @@ export class OpenCodeAgent {
30
30
  return true;
31
31
  }
32
32
  }
33
- //# sourceMappingURL=opencode.js.map
@@ -7,4 +7,3 @@ export declare class Qoder implements AgentTool {
7
7
  getTaskRunCommandLine(task: ParsedTask, followupPrompt?: string, extraPermissions?: RequiredPermission[] | "yolo"): CommandLine;
8
8
  init(): Promise<boolean>;
9
9
  }
10
- //# sourceMappingURL=qoder.d.ts.map
@@ -30,4 +30,3 @@ export class Qoder {
30
30
  return true;
31
31
  }
32
32
  }
33
- //# sourceMappingURL=qoder.js.map
@@ -7,4 +7,3 @@ export declare class QwenAgent implements AgentTool {
7
7
  getTaskRunCommandLine(task: ParsedTask, followupPrompt?: string, extraPermissions?: RequiredPermission[] | "yolo"): CommandLine;
8
8
  init(): Promise<boolean>;
9
9
  }
10
- //# sourceMappingURL=qwen.d.ts.map
@@ -27,4 +27,3 @@ export class QwenAgent {
27
27
  return true;
28
28
  }
29
29
  }
30
- //# sourceMappingURL=qwen.js.map
@@ -4,4 +4,3 @@ export declare const TASK_SUCCESS_MARKER = "[PALMIER_TASK_SUCCESS]";
4
4
  export declare const TASK_FAILURE_MARKER = "[PALMIER_TASK_FAILURE]";
5
5
  export declare const TASK_REPORT_PREFIX = "[PALMIER_REPORT]";
6
6
  export declare const TASK_PERMISSION_PREFIX = "[PALMIER_PERMISSION]";
7
- //# sourceMappingURL=shared-prompt.d.ts.map
@@ -20,4 +20,3 @@ export const TASK_SUCCESS_MARKER = "[PALMIER_TASK_SUCCESS]";
20
20
  export const TASK_FAILURE_MARKER = "[PALMIER_TASK_FAILURE]";
21
21
  export const TASK_REPORT_PREFIX = "[PALMIER_REPORT]";
22
22
  export const TASK_PERMISSION_PREFIX = "[PALMIER_PERMISSION]";
23
- //# sourceMappingURL=shared-prompt.js.map
@@ -9,4 +9,3 @@ export declare function revokeClient(token: string): boolean;
9
9
  export declare function revokeAllClients(): number;
10
10
  export declare function validateClient(token: string): boolean;
11
11
  export declare function hasClients(): boolean;
12
- //# sourceMappingURL=client-store.d.ts.map
@@ -54,4 +54,3 @@ export function validateClient(token) {
54
54
  export function hasClients() {
55
55
  return readFile().length > 0;
56
56
  }
57
- //# sourceMappingURL=client-store.js.map
@@ -1,4 +1,3 @@
1
1
  export declare function clientsListCommand(): Promise<void>;
2
2
  export declare function clientsRevokeCommand(token: string): Promise<void>;
3
3
  export declare function clientsRevokeAllCommand(): Promise<void>;
4
- //# sourceMappingURL=clients.d.ts.map
@@ -24,4 +24,3 @@ export async function clientsRevokeAllCommand() {
24
24
  const count = revokeAllClients();
25
25
  console.log(`Revoked ${count} client(s).`);
26
26
  }
27
- //# sourceMappingURL=clients.js.map
@@ -1,2 +1 @@
1
1
  export declare function infoCommand(): Promise<void>;
2
- //# sourceMappingURL=info.d.ts.map
@@ -22,4 +22,3 @@ export async function infoCommand() {
22
22
  console.log("No paired clients. Run `palmier pair` to connect a device.");
23
23
  }
24
24
  }
25
- //# sourceMappingURL=info.js.map
@@ -1,2 +1 @@
1
1
  export declare function initCommand(): Promise<void>;
2
- //# sourceMappingURL=init.d.ts.map
@@ -39,7 +39,7 @@ export async function initCommand() {
39
39
  console.log(` All tasks and execution data will be stored here.\n`);
40
40
  console.log(` ${dim("Local:")} ${cyan(`http://localhost:${httpPort}`)}`);
41
41
  console.log(` Open in a browser on this machine — no internet required.\n`);
42
- console.log(` ${dim("Remote (app):")} ${cyan("https://github.com/caihongxu/palmier-android/releases")}`);
42
+ console.log(` ${dim("Remote (app):")} ${cyan("https://github.com/caihongxu/palmier-android/releases/latest")}`);
43
43
  if (lanIp) {
44
44
  console.log(` Download the Android APK. The app uses LAN for direct RPC`);
45
45
  console.log(` on the same network (detected ${cyan(`http://${lanIp}:${httpPort}`)}),`);
@@ -136,4 +136,3 @@ async function registerHost(serverUrl, existingHostId) {
136
136
  throw new Error(`Failed to register host: ${message}`);
137
137
  }
138
138
  }
139
- //# sourceMappingURL=init.js.map
@@ -2,4 +2,3 @@ export declare const PAIRING_EXPIRY_MS: number;
2
2
  export declare function generatePairingCode(): string;
3
3
  /** Listens on NATS (server mode) and HTTP (via serve daemon) in parallel. */
4
4
  export declare function pairCommand(): Promise<void>;
5
- //# sourceMappingURL=pair.d.ts.map
@@ -114,4 +114,3 @@ export async function pairCommand() {
114
114
  }
115
115
  process.exit(paired ? 0 : 1);
116
116
  }
117
- //# sourceMappingURL=pair.js.map
@@ -1,2 +1 @@
1
1
  export declare function restartCommand(): Promise<void>;
2
- //# sourceMappingURL=restart.d.ts.map
@@ -3,4 +3,3 @@ export async function restartCommand() {
3
3
  const platform = getPlatform();
4
4
  await platform.restartDaemon();
5
5
  }
6
- //# sourceMappingURL=restart.js.map
@@ -5,4 +5,3 @@ export declare function parseReportFiles(output: string): string[];
5
5
  export declare function parsePermissions(output: string): RequiredPermission[];
6
6
  /** Falls back to "finished" if no success/failure marker is found. */
7
7
  export declare function parseTaskOutcome(output: string): TaskRunningState;
8
- //# sourceMappingURL=run.d.ts.map
@@ -1,6 +1,7 @@
1
1
  import * as fs from "fs";
2
2
  import * as path from "path";
3
3
  import * as readline from "readline";
4
+ import { StringCodec } from "nats";
4
5
  import { spawnCommand, spawnStreamingCommand } from "../spawn-command.js";
5
6
  import { loadConfig } from "../config.js";
6
7
  import { connectNats } from "../nats-client.js";
@@ -9,6 +10,18 @@ import { getAgent } from "../agents/agent.js";
9
10
  import { getPlatform } from "../platform/index.js";
10
11
  import { TASK_SUCCESS_MARKER, TASK_FAILURE_MARKER, TASK_REPORT_PREFIX, TASK_PERMISSION_PREFIX } from "../agents/shared-prompt.js";
11
12
  import { publishHostEvent } from "../events.js";
13
+ async function sendPushNotification(nc, hostId, title, body) {
14
+ if (!nc)
15
+ return;
16
+ try {
17
+ const sc = StringCodec();
18
+ const subject = `host.${hostId}.push.send`;
19
+ await nc.request(subject, sc.encode(JSON.stringify({ hostId, title, body })), { timeout: 15_000 });
20
+ }
21
+ catch (err) {
22
+ console.warn(`[push] failed to send notification:`, err);
23
+ }
24
+ }
12
25
  /**
13
26
  * Invoke the agent CLI in a continuation loop to handle permission requests.
14
27
  * `invokeTask` is the ParsedTask whose prompt is passed to the agent (in
@@ -289,6 +302,8 @@ async function runCommandTriggeredMode(ctx) {
289
302
  }
290
303
  else {
291
304
  invocationsFailed++;
305
+ const taskLabel = ctx.task.frontmatter.name || ctx.task.frontmatter.user_prompt;
306
+ await sendPushNotification(ctx.nc, ctx.config.hostId, `Task "${taskLabel}" invocation failed`, line.length > 200 ? line.slice(0, 200) + "…" : line);
292
307
  }
293
308
  appendLog(line, "", result.outcome);
294
309
  // Signal "waiting for more input" in the UI.
@@ -381,6 +396,7 @@ async function runEventTriggeredMode(ctx) {
381
396
  appendRunMessage(ctx.taskDir, ctx.runId, { role: "status", time: Date.now(), content: "", type: "monitoring" });
382
397
  await publishHostEvent(ctx.nc, ctx.config.hostId, ctx.taskId, { event_type: "result-updated", run_id: ctx.runId });
383
398
  let eventsProcessed = 0;
399
+ let lastOutcome = "finished";
384
400
  try {
385
401
  // eslint-disable-next-line no-constant-condition
386
402
  while (true) {
@@ -396,7 +412,8 @@ async function runEventTriggeredMode(ctx) {
396
412
  const perEventTask = {
397
413
  frontmatter: { ...ctx.task.frontmatter, user_prompt: perEventPrompt },
398
414
  };
399
- await invokeAgentWithRetries(ctx, perEventTask);
415
+ const result = await invokeAgentWithRetries(ctx, perEventTask);
416
+ lastOutcome = result.outcome;
400
417
  appendRunMessage(ctx.taskDir, ctx.runId, { role: "status", time: Date.now(), content: "", type: "monitoring" });
401
418
  await publishHostEvent(ctx.nc, ctx.config.hostId, ctx.taskId, { event_type: "result-updated", run_id: ctx.runId });
402
419
  }
@@ -407,7 +424,7 @@ async function runEventTriggeredMode(ctx) {
407
424
  await publishHostEvent(ctx.nc, ctx.config.hostId, ctx.taskId, { event_type: "result-updated", run_id: ctx.runId });
408
425
  return { outcome: "failed", endTime: Date.now() };
409
426
  }
410
- return { outcome: "finished", endTime: Date.now() };
427
+ return { outcome: lastOutcome, endTime: Date.now() };
411
428
  }
412
429
  async function publishTaskEvent(nc, config, taskDir, taskId, eventType, taskName, runId) {
413
430
  writeTaskStatus(taskDir, {
@@ -513,4 +530,3 @@ export function parseTaskOutcome(output) {
513
530
  return "finished";
514
531
  return "finished";
515
532
  }
516
- //# sourceMappingURL=run.js.map
@@ -1,2 +1 @@
1
1
  export declare function serveCommand(): Promise<void>;
2
- //# sourceMappingURL=serve.d.ts.map
@@ -194,4 +194,3 @@ export async function serveCommand() {
194
194
  }
195
195
  await startHttpTransport(config, handleRpc, httpPort, nc);
196
196
  }
197
- //# sourceMappingURL=serve.js.map
@@ -1,2 +1 @@
1
1
  export declare function uninstallCommand(): Promise<void>;
2
- //# sourceMappingURL=uninstall.d.ts.map
@@ -5,4 +5,3 @@ export async function uninstallCommand() {
5
5
  console.log("\nTo uninstall the package: npm uninstall -g palmier");
6
6
  console.log("To also remove configuration and task data, see https://github.com/caihongxu/palmier#uninstalling");
7
7
  }
8
- //# sourceMappingURL=uninstall.js.map
package/dist/config.d.ts CHANGED
@@ -4,4 +4,3 @@ declare const CONFIG_FILE: string;
4
4
  export declare function loadConfig(): HostConfig;
5
5
  export declare function saveConfig(config: HostConfig): void;
6
6
  export { CONFIG_DIR, CONFIG_FILE };
7
- //# sourceMappingURL=config.d.ts.map
package/dist/config.js CHANGED
@@ -23,4 +23,3 @@ export function saveConfig(config) {
23
23
  fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2), "utf-8");
24
24
  }
25
25
  export { CONFIG_DIR, CONFIG_FILE };
26
- //# sourceMappingURL=config.js.map
@@ -18,4 +18,3 @@ export declare function popEvent(taskId: string): {
18
18
  };
19
19
  /** Remove any state for a task (called from task.delete). */
20
20
  export declare function clearTaskQueue(taskId: string): void;
21
- //# sourceMappingURL=event-queues.d.ts.map
@@ -35,4 +35,3 @@ export function clearTaskQueue(taskId) {
35
35
  queues.delete(taskId);
36
36
  activeRuns.delete(taskId);
37
37
  }
38
- //# sourceMappingURL=event-queues.js.map
package/dist/events.d.ts CHANGED
@@ -1,3 +1,2 @@
1
1
  import { type NatsConnection } from "nats";
2
2
  export declare function publishHostEvent(nc: NatsConnection | undefined, hostId: string, taskId: string, payload: Record<string, unknown>): Promise<void>;
3
- //# sourceMappingURL=events.d.ts.map
package/dist/events.js CHANGED
@@ -19,4 +19,3 @@ export async function publishHostEvent(nc, hostId, taskId, payload) {
19
19
  }
20
20
  catch { /* serve HTTP may not be ready yet */ }
21
21
  }
22
- //# sourceMappingURL=events.js.map
package/dist/index.d.ts CHANGED
@@ -1,3 +1,2 @@
1
1
  #!/usr/bin/env node
2
2
  import "dotenv/config";
3
- //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -89,4 +89,3 @@ program.parseAsync(process.argv).catch((err) => {
89
89
  console.error(err);
90
90
  process.exit(1);
91
91
  });
92
- //# sourceMappingURL=index.js.map
@@ -6,4 +6,3 @@ export declare function getLinkedDevice(): LinkedDevice | null;
6
6
  export declare function setLinkedDevice(clientToken: string, fcmToken: string): void;
7
7
  export declare function clearLinkedDevice(): void;
8
8
  export declare function clearLinkedDeviceIfMatches(clientToken: string): boolean;
9
- //# sourceMappingURL=linked-device.d.ts.map
@@ -42,4 +42,3 @@ export function clearLinkedDeviceIfMatches(clientToken) {
42
42
  }
43
43
  return false;
44
44
  }
45
- //# sourceMappingURL=linked-device.js.map
@@ -8,4 +8,3 @@ export interface McpResponse {
8
8
  export declare function getResourceSubscriptions(): Map<string, Set<string>>;
9
9
  export declare function getAgentName(sessionId: string): string | undefined;
10
10
  export declare function handleMcpRequest(body: string, sessionId: string | undefined, ctx: ToolContext): Promise<McpResponse>;
11
- //# sourceMappingURL=mcp-handler.d.ts.map
@@ -165,4 +165,3 @@ export async function handleMcpRequest(body, sessionId, ctx) {
165
165
  return { body: rpcError(id, -32601, `Method not found: ${req.method}`) };
166
166
  }
167
167
  }
168
- //# sourceMappingURL=mcp-handler.js.map
@@ -38,4 +38,3 @@ export interface ResourceDefinition {
38
38
  export declare const agentResources: ResourceDefinition[];
39
39
  export declare const agentResourceMap: Map<string, ResourceDefinition>;
40
40
  export declare function generateEndpointDocs(port: number, taskId: string, tools?: ToolDefinition[], resources?: ResourceDefinition[]): string;
41
- //# sourceMappingURL=mcp-tools.d.ts.map
package/dist/mcp-tools.js CHANGED
@@ -714,4 +714,3 @@ export function generateEndpointDocs(port, taskId, tools = agentTools, resources
714
714
  }
715
715
  return lines.join("\n").trimEnd();
716
716
  }
717
- //# sourceMappingURL=mcp-tools.js.map
@@ -1,4 +1,3 @@
1
1
  import { type NatsConnection } from "nats";
2
2
  import type { HostConfig } from "./types.js";
3
3
  export declare function connectNats(config: HostConfig): Promise<NatsConnection>;
4
- //# sourceMappingURL=nats-client.d.ts.map
@@ -10,4 +10,3 @@ export async function connectNats(config) {
10
10
  // Do not log — it would pollute stdout for the MCP server.
11
11
  return nc;
12
12
  }
13
- //# sourceMappingURL=nats-client.js.map
package/dist/network.d.ts CHANGED
@@ -1,4 +1,3 @@
1
1
  export declare function detectDefaultInterface(): Promise<string | null>;
2
2
  export declare function getInterfaceIpv4(interfaceName: string): string | null;
3
3
  export declare function buildLanUrl(port: number, interfaceName: string | undefined): string | null;
4
- //# sourceMappingURL=network.d.ts.map