palmier 0.8.8 → 0.8.9
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 +26 -17
- package/dist/commands/init.js +6 -11
- package/dist/commands/pair.js +3 -0
- package/dist/pwa/assets/index-1gs4vwFo.js +120 -0
- package/dist/pwa/assets/{index-UaZFu6XL.css → index-DQJHVyP6.css} +1 -1
- package/dist/pwa/assets/{web-DYwZE4qa.js → web-BqVsIFtP.js} +1 -1
- package/dist/pwa/assets/web-DrSNtZ3i.js +1 -0
- package/dist/pwa/assets/{web-nSzKzI8x.js → web-lefgO9YR.js} +1 -1
- package/dist/pwa/index.html +2 -2
- package/dist/pwa/service-worker.js +1 -1
- package/dist/transports/http-transport.js +42 -27
- package/dist/types.d.ts +0 -2
- package/package.json +1 -1
- package/palmier-server/CLAUDE.md +4 -0
- package/palmier-server/PRODUCTION.md +1 -1
- package/palmier-server/README.md +1 -1
- package/palmier-server/pnpm-lock.yaml +12 -0
- package/palmier-server/pwa/package.json +1 -0
- package/palmier-server/pwa/src/App.css +61 -0
- package/palmier-server/pwa/src/components/CapabilityToggles.tsx +1 -1
- package/palmier-server/pwa/src/components/ConnectionStatusIcon.tsx +69 -0
- package/palmier-server/pwa/src/components/HostMenu.tsx +5 -4
- package/palmier-server/pwa/src/constants.ts +1 -1
- package/palmier-server/pwa/src/contexts/HostConnectionContext.tsx +156 -66
- package/palmier-server/pwa/src/pages/Dashboard.tsx +2 -0
- package/palmier-server/pwa/src/pages/PairHost.tsx +9 -9
- package/palmier-server/pwa/src/types.ts +3 -1
- package/palmier-server/spec.md +21 -19
- package/src/commands/init.ts +7 -12
- package/src/commands/pair.ts +3 -0
- package/src/transports/http-transport.ts +34 -29
- package/src/types.ts +0 -2
- package/dist/pwa/assets/index-BiAE5qeC.js +0 -120
package/README.md
CHANGED
|
@@ -15,6 +15,18 @@ It runs on your machine as a background daemon and connects to a mobile-friendly
|
|
|
15
15
|
|
|
16
16
|
1. Install a supported agent CLI — [Claude Code](https://docs.anthropic.com/en/docs/claude-code), [Gemini CLI](https://github.com/google-gemini/gemini-cli), [Codex CLI](https://github.com/openai/codex), [GitHub Copilot](https://github.com/github/gh-copilot), [OpenClaw](https://openclaw.ai/), or [others](https://www.palmier.me/agents).
|
|
17
17
|
2. Install Palmier:
|
|
18
|
+
|
|
19
|
+
**Linux / macOS:**
|
|
20
|
+
```bash
|
|
21
|
+
curl -fsSL https://palmier.me/install.sh | bash
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
**Windows (PowerShell):**
|
|
25
|
+
```powershell
|
|
26
|
+
irm https://palmier.me/install.ps1 | iex
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
The one-liner installs Node.js 24+ if needed (via [fnm](https://github.com/Schniz/fnm) on Linux/macOS, winget on Windows), then `palmier` globally. If you already have Node.js 24+ and npm:
|
|
18
30
|
```bash
|
|
19
31
|
npm install -g palmier
|
|
20
32
|
```
|
|
@@ -61,7 +73,7 @@ Palmier exposes an [MCP](https://modelcontextprotocol.io) server at `http://loca
|
|
|
61
73
|
**Available resources:**
|
|
62
74
|
| Resource | URI | Permission | Description |
|
|
63
75
|
|----------|-----|------------|-------------|
|
|
64
|
-
| Device Notifications | `notifications://device` |
|
|
76
|
+
| Device Notifications | `notifications://device` | Notifications from Other Apps | Recent notifications from the user's Android device |
|
|
65
77
|
| Device SMS | `sms-messages://device` | Read SMS | Recent SMS messages from the user's Android device |
|
|
66
78
|
|
|
67
79
|
Resources support MCP subscriptions — clients can subscribe via `resources/subscribe` and receive real-time `notifications/resources/updated` events via the streamable HTTP transport when the resource changes.
|
|
@@ -92,32 +104,29 @@ All device tools work while the Palmier Android app is in the background — the
|
|
|
92
104
|
│ SMS, contacts, │
|
|
93
105
|
│ calendar, GPS) │
|
|
94
106
|
└──────────────────┘
|
|
95
|
-
Local
|
|
96
|
-
Server mode: via relay
|
|
107
|
+
Local mode (loopback): direct HTTP on the host machine
|
|
108
|
+
Server mode: via relay (events) + auto-LAN direct HTTP for RPC when reachable (native app)
|
|
97
109
|
```
|
|
98
110
|
|
|
99
111
|
## Access Modes
|
|
100
112
|
|
|
101
|
-
Local always works
|
|
113
|
+
Two modes — Local always works on the host machine; Server pairs other devices through the cloud relay.
|
|
102
114
|
|
|
103
|
-
| Mode |
|
|
104
|
-
|
|
105
|
-
| **Local** |
|
|
106
|
-
| **
|
|
107
|
-
| **Server** | Cloud relay (NATS) | [https://app.palmier.me](https://app.palmier.me) | Required | Push notifications, remote access from anywhere |
|
|
115
|
+
| Mode | URL | Pairing | Notes |
|
|
116
|
+
|------|-----|---------|-------|
|
|
117
|
+
| **Local** | `http://localhost:<port>` | Not required | Loopback only — open in a browser on the host machine. No internet needed. |
|
|
118
|
+
| **Server** | [https://app.palmier.me](https://app.palmier.me) | Required | Pair the device with a one-time code. Push notifications, remote access from anywhere. |
|
|
108
119
|
|
|
109
|
-
**LAN
|
|
110
|
-
|
|
111
|
-
**Server mode** relays communication through the Palmier cloud server (via [NATS](https://nats.io)). All features including push notifications are available. Server mode and LAN mode can be active at the same time.
|
|
120
|
+
**Auto-LAN (native app only).** When the Capacitor 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. Browser PWAs can't do this and stay on the relay.
|
|
112
121
|
|
|
113
122
|
## Security & Privacy
|
|
114
123
|
|
|
115
|
-
**Local mode** — all traffic stays on `127.0.0.1`. No data leaves your machine.
|
|
116
|
-
|
|
117
|
-
**LAN mode** — traffic stays on your local network. Devices must pair with a one-time pairing code before they can access the host. Unpaired requests are rejected.
|
|
124
|
+
**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.
|
|
118
125
|
|
|
119
126
|
**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.
|
|
120
127
|
|
|
128
|
+
**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.
|
|
129
|
+
|
|
121
130
|
In all modes, client tokens are generated and validated entirely on your host. The Palmier server never sees or stores them.
|
|
122
131
|
|
|
123
132
|
## Setup Details
|
|
@@ -126,7 +135,7 @@ In all modes, client tokens are generated and validated entirely on your host. T
|
|
|
126
135
|
|
|
127
136
|
Local access (`http://localhost:<port>`) works immediately — no pairing needed.
|
|
128
137
|
|
|
129
|
-
For
|
|
138
|
+
For other devices, run `palmier pair` on the host to generate a code, then enter it at [https://app.palmier.me](https://app.palmier.me). Pairing always goes through the relay; auto-LAN kicks in transparently afterward when the device is on the same network.
|
|
130
139
|
|
|
131
140
|
### Managing Clients
|
|
132
141
|
|
|
@@ -145,7 +154,7 @@ palmier clients revoke-all
|
|
|
145
154
|
|
|
146
155
|
The wizard:
|
|
147
156
|
- Detects installed agent CLIs and caches the result
|
|
148
|
-
-
|
|
157
|
+
- Asks for the HTTP port
|
|
149
158
|
- Shows a summary (including any existing scheduled tasks to recover) and asks for confirmation
|
|
150
159
|
- Registers with the Palmier server, saves configuration to `~/.config/palmier/host.json`
|
|
151
160
|
- Installs a background daemon (systemd user service on Linux, LaunchAgent on macOS, Task Scheduler on Windows)
|
package/dist/commands/init.js
CHANGED
|
@@ -27,24 +27,20 @@ export async function initCommand() {
|
|
|
27
27
|
process.exit(1);
|
|
28
28
|
}
|
|
29
29
|
console.log(` Found: ${green(agents.map((a) => a.label).join(", "))}\n`);
|
|
30
|
-
const lanAnswer = await ask("Enable LAN access (direct HTTP from local network)? (y/N): ");
|
|
31
|
-
const lanEnabled = lanAnswer.trim().toLowerCase() === "y";
|
|
32
30
|
let httpPort = 7256;
|
|
33
|
-
const
|
|
34
|
-
const portAnswer = await ask(`${portLabel} (default ${httpPort}): `);
|
|
31
|
+
const portAnswer = await ask(`HTTP port (default ${httpPort}): `);
|
|
35
32
|
const parsed = parseInt(portAnswer.trim(), 10);
|
|
36
33
|
if (parsed > 0 && parsed < 65536)
|
|
37
34
|
httpPort = parsed;
|
|
35
|
+
const lanIp = detectLanIp();
|
|
38
36
|
console.log(`\n${bold("Setup summary:")}\n`);
|
|
39
37
|
console.log(` ${dim("Task storage:")} ${bold(process.cwd())}`);
|
|
40
38
|
console.log(` All tasks and execution data will be stored here.\n`);
|
|
41
39
|
console.log(` ${dim("Local access:")} ${cyan(`http://localhost:${httpPort}`)}`);
|
|
42
|
-
console.log(`
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
console.log(` Accessible from other devices on your local network. Pairing required.\n`);
|
|
47
|
-
}
|
|
40
|
+
console.log(` Open in a browser on this machine — no internet required.\n`);
|
|
41
|
+
console.log(` ${dim("Remote access:")} ${cyan("https://app.palmier.me")}`);
|
|
42
|
+
console.log(` Pair the app to your host. The app uses ${cyan(`http://${lanIp}:${httpPort}`)}`);
|
|
43
|
+
console.log(` for direct RPC when on the same network, otherwise the relay.\n`);
|
|
48
44
|
console.log(` ${dim("Agents:")} ${agents.map((a) => a.label).join(", ")}\n`);
|
|
49
45
|
const existingTasks = listTasks(process.cwd());
|
|
50
46
|
if (existingTasks.length > 0) {
|
|
@@ -93,7 +89,6 @@ export async function initCommand() {
|
|
|
93
89
|
natsNkeySeed: registerResponse.natsNkeySeed,
|
|
94
90
|
agents,
|
|
95
91
|
httpPort,
|
|
96
|
-
lanEnabled,
|
|
97
92
|
};
|
|
98
93
|
saveConfig(config);
|
|
99
94
|
console.log(`Config saved to ${dim("~/.config/palmier/host.json")}`);
|
package/dist/commands/pair.js
CHANGED
|
@@ -4,6 +4,7 @@ import { StringCodec } from "nats";
|
|
|
4
4
|
import { loadConfig } from "../config.js";
|
|
5
5
|
import { connectNats } from "../nats-client.js";
|
|
6
6
|
import { addClient } from "../client-store.js";
|
|
7
|
+
import { detectLanIp } from "../transports/http-transport.js";
|
|
7
8
|
const CODE_CHARS = "ABCDEFGHJKMNPQRSTUVWXYZ23456789"; // no O/0/I/1/L
|
|
8
9
|
const CODE_LENGTH = 6;
|
|
9
10
|
export const PAIRING_EXPIRY_MS = 60 * 1000; // 1 minute
|
|
@@ -14,9 +15,11 @@ export function generatePairingCode() {
|
|
|
14
15
|
}
|
|
15
16
|
function buildPairResponse(config, label) {
|
|
16
17
|
const client = addClient(label);
|
|
18
|
+
const port = config.httpPort ?? 7256;
|
|
17
19
|
return {
|
|
18
20
|
hostId: config.hostId,
|
|
19
21
|
clientToken: client.token,
|
|
22
|
+
directUrl: `http://${detectLanIp()}:${port}`,
|
|
20
23
|
hostName: os.hostname(),
|
|
21
24
|
};
|
|
22
25
|
}
|