palmier 0.2.5 → 0.2.6

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 (64) hide show
  1. package/.github/workflows/ci.yml +16 -0
  2. package/LICENSE +190 -0
  3. package/README.md +288 -219
  4. package/dist/agents/agent.d.ts +6 -3
  5. package/dist/agents/agent.js +2 -0
  6. package/dist/agents/claude.d.ts +1 -1
  7. package/dist/agents/claude.js +12 -9
  8. package/dist/agents/codex.d.ts +1 -1
  9. package/dist/agents/codex.js +12 -10
  10. package/dist/agents/gemini.d.ts +1 -1
  11. package/dist/agents/gemini.js +13 -9
  12. package/dist/agents/openclaw.d.ts +2 -2
  13. package/dist/agents/openclaw.js +8 -7
  14. package/dist/agents/shared-prompt.d.ts +5 -4
  15. package/dist/agents/shared-prompt.js +10 -8
  16. package/dist/commands/agents.js +11 -0
  17. package/dist/commands/init.js +109 -49
  18. package/dist/commands/mcpserver.js +11 -21
  19. package/dist/commands/plan-generation.md +24 -32
  20. package/dist/commands/restart.d.ts +5 -0
  21. package/dist/commands/restart.js +9 -0
  22. package/dist/commands/run.js +293 -101
  23. package/dist/commands/serve.js +83 -4
  24. package/dist/commands/task-cleanup.d.ts +14 -0
  25. package/dist/commands/task-cleanup.js +84 -0
  26. package/dist/events.d.ts +10 -0
  27. package/dist/events.js +29 -0
  28. package/dist/index.js +7 -0
  29. package/dist/platform/linux.d.ts +2 -0
  30. package/dist/platform/linux.js +22 -1
  31. package/dist/platform/platform.d.ts +4 -0
  32. package/dist/platform/windows.d.ts +3 -0
  33. package/dist/platform/windows.js +99 -82
  34. package/dist/rpc-handler.d.ts +2 -1
  35. package/dist/rpc-handler.js +43 -28
  36. package/dist/spawn-command.d.ts +29 -6
  37. package/dist/spawn-command.js +38 -15
  38. package/dist/transports/nats-transport.d.ts +4 -2
  39. package/dist/transports/nats-transport.js +3 -4
  40. package/dist/types.d.ts +4 -2
  41. package/package.json +5 -3
  42. package/src/agents/agent.ts +8 -3
  43. package/src/agents/claude.ts +44 -43
  44. package/src/agents/codex.ts +11 -12
  45. package/src/agents/gemini.ts +12 -10
  46. package/src/agents/openclaw.ts +8 -7
  47. package/src/agents/shared-prompt.ts +10 -8
  48. package/src/commands/agents.ts +11 -0
  49. package/src/commands/init.ts +120 -56
  50. package/src/commands/mcpserver.ts +11 -22
  51. package/src/commands/plan-generation.md +24 -32
  52. package/src/commands/restart.ts +9 -0
  53. package/src/commands/run.ts +365 -119
  54. package/src/commands/serve.ts +101 -5
  55. package/src/cross-spawn.d.ts +5 -0
  56. package/src/events.ts +38 -0
  57. package/src/index.ts +8 -0
  58. package/src/platform/linux.ts +25 -1
  59. package/src/platform/platform.ts +6 -0
  60. package/src/platform/windows.ts +100 -89
  61. package/src/rpc-handler.ts +46 -29
  62. package/src/spawn-command.ts +120 -83
  63. package/src/transports/nats-transport.ts +4 -4
  64. package/src/types.ts +4 -2
package/README.md CHANGED
@@ -1,219 +1,288 @@
1
- # Palmier
2
-
3
- A Node.js CLI that runs on your machine as a persistent daemon. It manages tasks, communicates with the Palmier app via NATS and/or direct HTTP, and executes tasks on schedule or demand using CLI tools.
4
-
5
- ## Connection Modes
6
-
7
- The host supports three connection modes:
8
-
9
- | Mode | Transport | Setup | Features |
10
- |------|-----------|-------|----------|
11
- | **`nats`** | NATS only | `palmier init` → Full access, skip LAN | All features |
12
- | **`auto`** | Both NATS + HTTP | `palmier init` → Full access + LAN | All features. PWA auto-detects best route. |
13
- | **`lan`** | HTTP only | `palmier init` → LAN only | No push notifications or email MCP. No server needed. |
14
-
15
- In **auto** mode, the PWA connects directly to the host via HTTP when on the same LAN (lower latency), and falls back to NATS when the host is unreachable. Push notifications and email relay always flow through NATS/server, so no features are lost.
16
-
17
- In **lan** mode, the host runs a standalone HTTP server. Multiple PWA clients can connect using session tokens. No Palmier web server or NATS broker is needed.
18
-
19
- ## Prerequisites
20
-
21
- - **Node.js 20+**
22
- - An agent CLI tool for task execution (e.g., Claude Code, Gemini CLI, OpenAI Codex)
23
- - **Linux with systemd** (the host installs as a systemd user service)
24
-
25
- ## Installation
26
-
27
- ```bash
28
- npm install -g palmier
29
- ```
30
-
31
- ## CLI Commands
32
-
33
- | Command | Description |
34
- |---|---|
35
- | `palmier init` | Interactive setup wizard (full access or LAN only) |
36
- | `palmier pair` | Generate an OTP code to pair a new device |
37
- | `palmier sessions list` | List active session tokens |
38
- | `palmier sessions revoke <token>` | Revoke a specific session token |
39
- | `palmier sessions revoke-all` | Revoke all session tokens |
40
- | `palmier info` | Show host connection info (address, mode) |
41
- | `palmier serve` | Run the persistent RPC handler (default command) |
42
- | `palmier run <task-id>` | Execute a specific task |
43
- | `palmier mcpserver` | Start an MCP server exposing Palmier tools (stdio transport) |
44
- | `palmier agents` | Re-detect installed agent CLIs and update config |
45
-
46
- ## Setup
47
-
48
- ### Quick Start
49
-
50
- 1. Install the host: `npm install -g palmier`
51
- 2. Run `palmier init` in your project directory.
52
- 3. The wizard walks you through:
53
- - **Full access** or **LAN only** mode
54
- - Server URL (for full access, defaults to `https://www.palmier.me`)
55
- - Optional LAN access (for full access — auto-detects best route when enabled)
56
- 4. The host saves config, installs a systemd service, and generates a pairing code.
57
- 5. Enter the pairing code in the Palmier PWA to connect your device.
58
-
59
- ### Pairing additional devices
60
-
61
- Run `palmier pair` on the host to generate a new OTP code. Each paired device gets its own session token.
62
-
63
- ### Managing sessions
64
-
65
- ```bash
66
- # List all paired devices
67
- palmier sessions list
68
-
69
- # Revoke a specific device's access
70
- palmier sessions revoke <token>
71
-
72
- # Revoke all sessions (unpair all devices)
73
- palmier sessions revoke-all
74
- ```
75
-
76
- The `init` command:
77
- - Detects installed agent CLIs (Claude Code, Gemini CLI, Codex CLI) and caches the result
78
- - Saves host configuration to `~/.config/palmier/host.json`
79
- - Installs a systemd user service for the host
80
- - Auto-enters pair mode to connect your first device
81
-
82
- To re-detect agents after installing or removing a CLI, run `palmier agents`.
83
-
84
- ### Verifying the Service
85
-
86
- After `palmier init`, verify the host is running:
87
-
88
- ```bash
89
- # Check service status
90
- systemctl --user status palmier.service
91
-
92
- # View recent logs
93
- journalctl --user -u palmier.service -n 50 --no-pager
94
-
95
- # Follow logs in real time
96
- journalctl --user -u palmier.service -f
97
- ```
98
-
99
- You should see `Active: active (running)` and log output showing a NATS connection. If the service failed:
100
-
101
- ```bash
102
- # Restart manually
103
- systemctl --user restart palmier.service
104
-
105
- # Check config is valid
106
- cat ~/.config/palmier/host.json
107
- ```
108
-
109
- ## How It Works
110
-
111
- - The host runs as a **systemd user service**, staying alive in the background via `palmier serve`.
112
- - **Paired devices** communicate with the host via NATS (cloud-routed) and/or direct HTTP (LAN), depending on the connection mode. Each paired device gets a session token that authenticates all requests.
113
- - **Tasks** are stored locally as Markdown files in a `tasks/` directory. Each task has a name, prompt, execution plan, and optional triggers (cron schedules or one-time dates).
114
- - **Plan generation** is automatic — when you create or update a task, the host invokes your chosen agent CLI to generate an execution plan and name.
115
- - **Triggers** are backed by systemd timers. You can enable/disable them without deleting the task, and any task can still be run manually at any time.
116
- - **Task confirmation** — tasks can optionally require your approval before running. You'll get a push notification (NATS mode) or a prompt in the PWA to confirm or abort.
117
- - **Run history** — each run produces a timestamped result file. You can view results and reports from the PWA.
118
- - **Real-time updates** — task status changes (started, finished, failed) are pushed to connected PWA clients via NATS pub/sub or SSE.
119
- - **MCP server** (`palmier mcpserver`) exposes platform tools (e.g., `send-email`) to AI agents like Claude Code over stdio.
120
-
121
- ## Project Structure
122
-
123
- ```
124
- src/
125
- index.ts # CLI entrypoint (commander setup)
126
- config.ts # Host configuration (read/write ~/.config/palmier)
127
- rpc-handler.ts # Transport-agnostic RPC handler (with session validation)
128
- session-store.ts # Session token management (~/.config/palmier/sessions.json)
129
- nats-client.ts # NATS connection helper
130
- spawn-command.ts # Shared helper for spawning CLI tools without a shell
131
- systemd.ts # systemd service installation
132
- task.ts # Task file management
133
- types.ts # Shared type definitions
134
- agents/
135
- agent.ts # AgentTool interface, registry, and agent detection
136
- claude.ts # Claude Code agent implementation
137
- gemini.ts # Gemini CLI agent implementation
138
- codex.ts # Codex CLI agent implementation
139
- openclaw.ts # OpenClaw agent implementation
140
- commands/
141
- init.ts # Interactive setup wizard (auto-pair)
142
- pair.ts # OTP code generation and pairing handler
143
- sessions.ts # Session token management CLI (list, revoke, revoke-all)
144
- info.ts # Print host connection info
145
- agents.ts # Re-detect installed agent CLIs
146
- serve.ts # Transport selection and startup
147
- run.ts # Single task execution
148
- mcpserver.ts # MCP server with platform tools (send-email)
149
- transports/
150
- nats-transport.ts # NATS subscription loop (host.<hostId>.rpc.>)
151
- http-transport.ts # HTTP server with RPC, SSE, and internal event endpoints
152
- ```
153
-
154
- ## MCP Server
155
-
156
- The host includes an MCP server that exposes Palmier platform tools to AI agents like Claude Code.
157
-
158
- ### Setup
159
-
160
- Add to your Claude Code MCP settings:
161
-
162
- ```json
163
- {
164
- "mcpServers": {
165
- "palmier": {
166
- "command": "palmier",
167
- "args": ["mcpserver"]
168
- }
169
- }
170
- }
171
- ```
172
-
173
- Requires a provisioned host (`palmier init`). In NATS/auto mode, uses NATS relay. In LAN mode with `serverUrl` configured, uses HTTP relay. Not available in standalone LAN mode without a server.
174
-
175
- ### Available Tools
176
-
177
- | Tool | Inputs | Description |
178
- |---|---|---|
179
- | `send-email` | `to`, `subject`, `text` (required); `html`, `reply_to`, `cc`, `bcc` (optional) | Send an email via the platform's SMTP relay |
180
-
181
- ## Removing a Host
182
-
183
- To fully remove a host from a machine:
184
-
185
- 1. **Unpair the host from the PWA** (via the host menu).
186
-
187
- 2. **Stop and remove the systemd service:**
188
-
189
- ```bash
190
- systemctl --user stop palmier.service
191
- systemctl --user disable palmier.service
192
- rm ~/.config/systemd/user/palmier.service
193
- ```
194
-
195
- 3. **Remove any task timers and services:**
196
-
197
- ```bash
198
- systemctl --user stop palmier-task-*.timer palmier-task-*.service 2>/dev/null
199
- systemctl --user disable palmier-task-*.timer 2>/dev/null
200
- rm -f ~/.config/systemd/user/palmier-task-*.timer ~/.config/systemd/user/palmier-task-*.service
201
- ```
202
-
203
- 4. **Reload systemd:**
204
-
205
- ```bash
206
- systemctl --user daemon-reload
207
- ```
208
-
209
- 5. **Remove the host configuration:**
210
-
211
- ```bash
212
- rm -rf ~/.config/palmier
213
- ```
214
-
215
- 6. **Remove the tasks directory** from your project root:
216
-
217
- ```bash
218
- rm -rf tasks/
219
- ```
1
+ # Palmier
2
+
3
+ ![CI](https://github.com/caihongxu/palmier/actions/workflows/ci.yml/badge.svg)
4
+
5
+ A Node.js CLI that runs on your machine as a persistent daemon. It manages tasks, communicates with the Palmier app via NATS and/or direct HTTP, and executes tasks on schedule or demand using CLI tools.
6
+
7
+ > **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.
8
+
9
+ ## Connection Modes
10
+
11
+ The host supports three connection modes:
12
+
13
+ | Mode | Transport | Setup | Features |
14
+ |------|-----------|-------|----------|
15
+ | **`nats`** | NATS only | `palmier init` Full access, skip LAN | All features |
16
+ | **`auto`** | Both NATS + HTTP | `palmier init` → Full access + LAN | All features. PWA auto-detects best route. |
17
+ | **`lan`** | HTTP only | `palmier init` LAN only | No push notifications. No server needed. |
18
+
19
+ In **auto** mode, the PWA connects directly to the host via HTTP when on the same LAN (lower latency), and falls back to NATS when the host is unreachable. Push notifications always flow through NATS/server, so no features are lost.
20
+
21
+ In **lan** mode, the host runs a standalone HTTP server. Multiple PWA clients can connect using session tokens. No Palmier web server or NATS broker is needed.
22
+
23
+ ## Prerequisites
24
+
25
+ - **Node.js 24+**
26
+ - An agent CLI tool for task execution (e.g., Claude Code, Gemini CLI, OpenAI Codex)
27
+ - **Linux with systemd** or **Windows 10/11**
28
+
29
+ ## Installation
30
+
31
+ ```bash
32
+ npm install -g palmier
33
+ ```
34
+
35
+ ## CLI Commands
36
+
37
+ | Command | Description |
38
+ |---|---|
39
+ | `palmier init` | Interactive setup wizard (full access or LAN only) |
40
+ | `palmier pair` | Generate an OTP code to pair a new device |
41
+ | `palmier sessions list` | List active session tokens |
42
+ | `palmier sessions revoke <token>` | Revoke a specific session token |
43
+ | `palmier sessions revoke-all` | Revoke all session tokens |
44
+ | `palmier info` | Show host connection info (address, mode) |
45
+ | `palmier serve` | Run the persistent RPC handler (default command) |
46
+ | `palmier restart` | Restart the palmier serve daemon |
47
+ | `palmier run <task-id>` | Execute a specific task |
48
+ | `palmier mcpserver` | Start an MCP server exposing Palmier tools (stdio transport) |
49
+ | `palmier agents` | Re-detect installed agent CLIs and update config |
50
+
51
+ ## Setup
52
+
53
+ ### Quick Start
54
+
55
+ 1. Install the host: `npm install -g palmier`
56
+ 2. Run `palmier init` in your project directory.
57
+ 3. The wizard walks you through:
58
+ - **Full access** or **LAN only** mode
59
+ - Server URL (for full access, used for registration only — not stored in config)
60
+ - Optional LAN access (for full access — auto-detects best route when enabled)
61
+ 4. The host saves config, installs a background daemon (systemd on Linux, Registry Run key on Windows), and generates a pairing code.
62
+ 5. Enter the pairing code in the Palmier PWA to connect your device.
63
+
64
+ ### Pairing additional devices
65
+
66
+ Run `palmier pair` on the host to generate a new OTP code. Each paired device gets its own session token.
67
+
68
+ ### Managing sessions
69
+
70
+ ```bash
71
+ # List all paired devices
72
+ palmier sessions list
73
+
74
+ # Revoke a specific device's access
75
+ palmier sessions revoke <token>
76
+
77
+ # Revoke all sessions (unpair all devices)
78
+ palmier sessions revoke-all
79
+ ```
80
+
81
+ The `init` command:
82
+ - Detects installed agent CLIs (Claude Code, Gemini CLI, Codex CLI) and caches the result
83
+ - Saves host configuration to `~/.config/palmier/host.json`
84
+ - Installs a background daemon (systemd user service on Linux, Registry Run key on Windows)
85
+ - Auto-enters pair mode to connect your first device
86
+
87
+ To re-detect agents after installing or removing a CLI, run `palmier agents`.
88
+
89
+ ### Verifying the Service
90
+
91
+ After `palmier init`, verify the host is running:
92
+
93
+ **Linux:**
94
+
95
+ ```bash
96
+ # Check service status
97
+ systemctl --user status palmier.service
98
+
99
+ # View recent logs
100
+ journalctl --user -u palmier.service -n 50 --no-pager
101
+
102
+ # Follow logs in real time
103
+ journalctl --user -u palmier.service -f
104
+ ```
105
+
106
+ **Windows (PowerShell):**
107
+
108
+ ```powershell
109
+ # Check if the daemon is running
110
+ Get-Process -Name node -ErrorAction SilentlyContinue | Where-Object { $_.CommandLine -like '*palmier*serve*' }
111
+ ```
112
+
113
+ **Restarting the daemon (both platforms):**
114
+
115
+ ```bash
116
+ palmier restart
117
+ ```
118
+
119
+ ## How It Works
120
+
121
+ - The host runs as a **background daemon** (systemd user service on Linux, Registry Run key on Windows), staying alive via `palmier serve`.
122
+ - **Paired devices** communicate with the host via NATS (cloud-routed) and/or direct HTTP (LAN), depending on the connection mode. Each paired device gets a session token that authenticates all requests.
123
+ - **Tasks** are stored locally as Markdown files in a `tasks/` directory. Each task has a name, prompt, execution plan, and optional triggers (cron schedules or one-time dates).
124
+ - **Plan generation** is automatic — when you create or update a task, the host invokes your chosen agent CLI to generate an execution plan and name.
125
+ - **Triggers** are backed by systemd timers (Linux) or Task Scheduler (Windows). You can enable/disable them without deleting the task, and any task can still be run manually at any time.
126
+ - **Task execution** uses the system scheduler on both platforms — `systemctl --user start` on Linux, `schtasks /run` on Windows. The daemon polls every 30 seconds to detect crashed tasks (processes that exited without updating status) and marks them as failed, broadcasting the failure to connected clients.
127
+ - **Command-triggered tasks** optionally specify a shell command (e.g., `tail -f /var/log/app.log`). Palmier runs the command continuously and invokes the agent for each line of stdout, passing it alongside your prompt. Useful for log monitoring, event-driven automation, and reactive workflows.
128
+ - **Task confirmation** — tasks can optionally require your approval before running. You'll get a push notification (NATS mode) or a prompt in the PWA to confirm or abort.
129
+ - **Run history** — each run produces a timestamped result file. You can view results and reports from the PWA.
130
+ - **Real-time updates** — task status changes (started, finished, failed) are pushed to connected PWA clients via NATS pub/sub or SSE. A shared events module handles broadcasting across both transports.
131
+ - **MCP server** (`palmier mcpserver`) exposes platform tools (e.g., `send-push-notification`) to AI agents like Claude Code over stdio.
132
+
133
+ ## Project Structure
134
+
135
+ ```
136
+ src/
137
+ index.ts # CLI entrypoint (commander setup)
138
+ config.ts # Host configuration (read/write ~/.config/palmier)
139
+ rpc-handler.ts # Transport-agnostic RPC handler (with session validation)
140
+ session-store.ts # Session token management (~/.config/palmier/sessions.json)
141
+ nats-client.ts # NATS connection helper
142
+ spawn-command.ts # Shared helper for spawning CLI tools
143
+ task.ts # Task file management
144
+ types.ts # Shared type definitions
145
+ agents/
146
+ agent.ts # AgentTool interface, registry, and agent detection
147
+ claude.ts # Claude Code agent implementation
148
+ gemini.ts # Gemini CLI agent implementation
149
+ codex.ts # Codex CLI agent implementation
150
+ openclaw.ts # OpenClaw agent implementation
151
+ events.ts # Shared event broadcasting (NATS pub/sub and HTTP SSE)
152
+ commands/
153
+ init.ts # Interactive setup wizard (auto-pair)
154
+ pair.ts # OTP code generation and pairing handler
155
+ sessions.ts # Session token management CLI (list, revoke, revoke-all)
156
+ info.ts # Print host connection info
157
+ agents.ts # Re-detect installed agent CLIs
158
+ serve.ts # Transport selection, startup, and crash detection polling
159
+ restart.ts # Daemon restart (cross-platform)
160
+ run.ts # Single task execution
161
+ mcpserver.ts # MCP server with platform tools (send-push-notification)
162
+ platform/
163
+ platform.ts # PlatformService interface
164
+ index.ts # Platform factory (Linux vs Windows)
165
+ linux.ts # Linux: systemd daemon, timers, systemctl task control
166
+ windows.ts # Windows: Registry Run key, Task Scheduler, schtasks-based task control
167
+ transports/
168
+ nats-transport.ts # NATS subscription loop (host.<hostId>.rpc.>)
169
+ http-transport.ts # HTTP server with RPC, SSE, and internal event endpoints
170
+ ```
171
+
172
+ ## MCP Server
173
+
174
+ The host includes an MCP server that exposes Palmier platform tools to AI agents like Claude Code.
175
+
176
+ ### Setup
177
+
178
+ Add to your Claude Code MCP settings:
179
+
180
+ ```json
181
+ {
182
+ "mcpServers": {
183
+ "palmier": {
184
+ "command": "palmier",
185
+ "args": ["mcpserver"]
186
+ }
187
+ }
188
+ }
189
+ ```
190
+
191
+ Requires a provisioned host (`palmier init`). In NATS/auto mode, uses NATS relay. Not available in LAN-only mode.
192
+
193
+ ### Available Tools
194
+
195
+ | Tool | Inputs | Description |
196
+ |---|---|---|
197
+ | `send-push-notification` | `title`, `body` (required) | Send a push notification to all paired devices |
198
+
199
+ ## Removing a Host
200
+
201
+ To fully remove a host from a machine:
202
+
203
+ 1. **Unpair the host from the PWA** (via the host menu).
204
+
205
+ 2. **Stop and remove the daemon:**
206
+
207
+ **Linux:**
208
+ ```bash
209
+ systemctl --user stop palmier.service
210
+ systemctl --user disable palmier.service
211
+ rm ~/.config/systemd/user/palmier.service
212
+ ```
213
+
214
+ **Windows (PowerShell):**
215
+ ```powershell
216
+ # Kill the daemon process
217
+ Get-Content "$env:USERPROFILE\.config\palmier\daemon.pid" | ForEach-Object { Stop-Process -Id $_ -Force -ErrorAction SilentlyContinue }
218
+ # Remove the Registry Run key
219
+ Remove-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Run" -Name "PalmierDaemon" -ErrorAction SilentlyContinue
220
+ ```
221
+
222
+ 3. **Remove any task timers:**
223
+
224
+ **Linux:**
225
+ ```bash
226
+ systemctl --user stop palmier-task-*.timer palmier-task-*.service 2>/dev/null
227
+ systemctl --user disable palmier-task-*.timer 2>/dev/null
228
+ rm -f ~/.config/systemd/user/palmier-task-*.timer ~/.config/systemd/user/palmier-task-*.service
229
+ systemctl --user daemon-reload
230
+ ```
231
+
232
+ **Windows (PowerShell):**
233
+ ```powershell
234
+ schtasks /delete /tn "PalmierTask-*" /f 2>$null
235
+ ```
236
+
237
+ 4. **Remove the host configuration:**
238
+
239
+ ```bash
240
+ rm -rf ~/.config/palmier
241
+ ```
242
+
243
+ 5. **Remove the tasks directory** from your project root:
244
+
245
+ ```bash
246
+ rm -rf tasks/
247
+ ```
248
+
249
+ ## Disclaimer
250
+
251
+ **USE AT YOUR OWN RISK.** Palmier is provided on an "AS IS" and "AS AVAILABLE" basis, without warranties of any kind, either express or implied.
252
+
253
+ ### AI Agent Execution
254
+
255
+ Palmier spawns third-party AI agent CLIs (such as Claude Code, Gemini CLI, and Codex CLI) that can:
256
+
257
+ - **Read, create, modify, and delete files** on your machine
258
+ - **Execute arbitrary shell commands** with your user permissions
259
+ - **Make network requests** and interact with external services
260
+
261
+ AI agents may produce unexpected, incorrect, or harmful outputs. **You are solely responsible for reviewing and approving all actions taken by AI agents on your system.** The authors of Palmier have no control over the behavior of third-party AI agents and accept no liability for their actions.
262
+
263
+ ### Unattended and Scheduled Execution
264
+
265
+ Tasks can be configured to run on schedules (cron) or in response to events without active supervision. You should:
266
+
267
+ - Use the **confirmation** feature for sensitive tasks
268
+ - Restrict **permissions** granted to agents to the minimum necessary
269
+ - Regularly review **task history and results**
270
+ - Maintain **backups** of any important data in directories where agents operate
271
+
272
+ ### Third-Party Services
273
+
274
+ Task prompts and execution data may be transmitted to third-party AI service providers (Anthropic, Google, OpenAI, etc.) according to their respective terms and privacy policies. Palmier does not control how these services process your data.
275
+
276
+ When using NATS or auto mode, communication between your device and the host is relayed through the Palmier server. See the [Privacy Policy](https://www.palmier.me/privacy) for details on what data is collected.
277
+
278
+ ### Limitation of Liability
279
+
280
+ To the maximum extent permitted by applicable law, the authors and contributors of Palmier shall not be liable for any direct, indirect, incidental, special, consequential, or exemplary damages arising from the use of this software, including but not limited to damages for loss of data, loss of profits, business interruption, or any other commercial damages or losses.
281
+
282
+ ### No Professional Advice
283
+
284
+ Palmier is a developer tool, not a substitute for professional advice. Do not rely on AI-generated outputs for critical decisions without independent verification.
285
+
286
+ ## License
287
+
288
+ This project is licensed under the Apache License 2.0. See [LICENSE](LICENSE) for the full text.
@@ -2,6 +2,8 @@ import type { ParsedTask, RequiredPermission } from "../types.js";
2
2
  export interface CommandLine {
3
3
  command: string;
4
4
  args: string[];
5
+ /** If provided, the string is written to the process's stdin and then the pipe is closed. */
6
+ stdin?: string;
5
7
  }
6
8
  /**
7
9
  * Interface that each agent tool must implement.
@@ -10,9 +12,10 @@ export interface CommandLine {
10
12
  export interface AgentTool {
11
13
  /** Return the command and args used to generate a plan from a prompt. */
12
14
  getPlanGenerationCommandLine(prompt: string): CommandLine;
13
- /** Return the command and args used to run a task. If prompt is provided, use it instead of the task's prompt.
14
- * extraPermissions are transient permissions granted for this run only (not persisted in frontmatter). */
15
- getTaskRunCommandLine(task: ParsedTask, prompt?: string, extraPermissions?: RequiredPermission[]): CommandLine;
15
+ /** Return the command and args used to run a task. If retryPrompt is provided, use it instead of the task's prompt,
16
+ * and treat it as a continuation of the original run (reuse the same session, etc). extraPermissions are transient
17
+ * permissions granted for this run only (not persisted in frontmatter). */
18
+ getTaskRunCommandLine(task: ParsedTask, retryPrompt?: string, extraPermissions?: RequiredPermission[]): CommandLine;
16
19
  /** Detect whether the agent CLI is available and perform any agent-specific
17
20
  * initialization. Returns true if the agent was detected and initialized successfully. */
18
21
  init(): Promise<boolean>;
@@ -1,10 +1,12 @@
1
1
  import { ClaudeAgent } from "./claude.js";
2
2
  import { GeminiAgent } from "./gemini.js";
3
3
  import { CodexAgent } from "./codex.js";
4
+ import { OpenClawAgent } from "./openclaw.js";
4
5
  const agentRegistry = {
5
6
  claude: new ClaudeAgent(),
6
7
  gemini: new GeminiAgent(),
7
8
  codex: new CodexAgent(),
9
+ openclaw: new OpenClawAgent(),
8
10
  };
9
11
  const agentLabels = {
10
12
  claude: "Claude Code",
@@ -2,7 +2,7 @@ import type { ParsedTask, RequiredPermission } from "../types.js";
2
2
  import type { AgentTool, CommandLine } from "./agent.js";
3
3
  export declare class ClaudeAgent implements AgentTool {
4
4
  getPlanGenerationCommandLine(prompt: string): CommandLine;
5
- getTaskRunCommandLine(task: ParsedTask, prompt?: string, extraPermissions?: RequiredPermission[]): CommandLine;
5
+ getTaskRunCommandLine(task: ParsedTask, retryPrompt?: string, extraPermissions?: RequiredPermission[]): CommandLine;
6
6
  init(): Promise<boolean>;
7
7
  }
8
8
  //# sourceMappingURL=claude.d.ts.map
@@ -1,5 +1,5 @@
1
1
  import { execSync } from "child_process";
2
- import { TASK_OUTCOME_SUFFIX } from "./shared-prompt.js";
2
+ import { AGENT_INSTRUCTIONS } from "./shared-prompt.js";
3
3
  // execSync's shell option takes a string (shell path), not boolean.
4
4
  // On Windows we need a shell so .cmd shims resolve correctly.
5
5
  const SHELL = process.platform === "win32" ? "cmd.exe" : undefined;
@@ -10,27 +10,30 @@ export class ClaudeAgent {
10
10
  args: ["-p", prompt],
11
11
  };
12
12
  }
13
- getTaskRunCommandLine(task, prompt, extraPermissions) {
14
- prompt = (prompt ?? (task.body || task.frontmatter.user_prompt)) + TASK_OUTCOME_SUFFIX;
15
- const args = ["-c", "--permission-mode", "acceptEdits", "-p", prompt];
13
+ getTaskRunCommandLine(task, retryPrompt, extraPermissions) {
14
+ const prompt = retryPrompt ?? (task.body || task.frontmatter.user_prompt);
15
+ const args = ["--permission-mode", "acceptEdits", "--append-system-prompt", AGENT_INSTRUCTIONS, "-p"];
16
16
  const allPerms = [...(task.frontmatter.permissions ?? []), ...(extraPermissions ?? [])];
17
17
  for (const p of allPerms) {
18
18
  args.push("--allowedTools", p.name);
19
19
  }
20
- return { command: "claude", args };
20
+ if (retryPrompt) {
21
+ args.push("-c");
22
+ } // continue mode for retries
23
+ return { command: "claude", args, stdin: prompt };
21
24
  }
22
25
  async init() {
23
26
  try {
24
- execSync("claude --version", { shell: SHELL });
27
+ execSync("claude --version", { stdio: "ignore", shell: SHELL });
25
28
  }
26
29
  catch {
27
30
  return false;
28
31
  }
29
32
  try {
30
- execSync("claude mcp add --transport stdio palmier --scope user -- palmier mcpserver", { shell: SHELL });
33
+ execSync("claude mcp add --transport stdio palmier --scope user -- palmier mcpserver", { stdio: "ignore", shell: SHELL });
31
34
  }
32
- catch (err) {
33
- console.warn("Warning: failed to install MCP for Claude:", err instanceof Error ? err.message : err);
35
+ catch {
36
+ // MCP registration is best-effort; agent still works without it
34
37
  }
35
38
  return true;
36
39
  }
@@ -2,7 +2,7 @@ import type { ParsedTask, RequiredPermission } from "../types.js";
2
2
  import type { AgentTool, CommandLine } from "./agent.js";
3
3
  export declare class CodexAgent implements AgentTool {
4
4
  getPlanGenerationCommandLine(prompt: string): CommandLine;
5
- getTaskRunCommandLine(task: ParsedTask, prompt?: string, extraPermissions?: RequiredPermission[]): CommandLine;
5
+ getTaskRunCommandLine(task: ParsedTask, retryPrompt?: string, extraPermissions?: RequiredPermission[]): CommandLine;
6
6
  init(): Promise<boolean>;
7
7
  }
8
8
  //# sourceMappingURL=codex.d.ts.map