palmier 0.9.25 → 0.9.26
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 +3 -8
- package/dist/agents/wizard.js +1 -1
- package/dist/mcp-tools.js +39 -1
- package/dist/pwa/assets/index-CsXEu9PI.js +120 -0
- package/dist/pwa/assets/{web-BcJSY5-D.js → web-BNVl5cy2.js} +1 -1
- package/dist/pwa/assets/{web-BQCHF9J7.js → web-CfKyecWX.js} +1 -1
- package/dist/pwa/assets/{web-CrbgQM5-.js → web-D9PV07-0.js} +1 -1
- package/dist/pwa/index.html +1 -1
- package/package.json +1 -1
- package/dist/pwa/assets/index-Dhvun09d.js +0 -120
package/README.md
CHANGED
|
@@ -11,14 +11,9 @@ Palmier installs, manages, and runs AI agent CLIs (Claude Code, Gemini CLI, Code
|
|
|
11
11
|
The control surface is bidirectional:
|
|
12
12
|
|
|
13
13
|
* **Phone → agents:** start ad-hoc sessions, register schedule- or event-triggered tasks, inspect session output, and respond to agent input/confirmation requests.
|
|
14
|
-
* **Agents → phone:** agents can
|
|
14
|
+
* **Agents → phone:** agents can read device state (location, calendar, contacts, notifications, SMS, battery) and trigger actions (push notifications, full-screen alarms, SMS, email, contact/calendar writes, ringer mode).
|
|
15
15
|
|
|
16
|
-
Capability access is opt-in per device: each
|
|
17
|
-
|
|
18
|
-
It is not:
|
|
19
|
-
|
|
20
|
-
* an agent runtime itself — Palmier shells out to the agent CLI and streams its stdio
|
|
21
|
-
* a system for driving phone UI like a human tapping through apps — phone access is via OS-level APIs (FCM data messages, content providers, calendar/contacts APIs), not UI automation
|
|
16
|
+
Capability access is opt-in per device: each capability is gated behind an Android permission and a per-host toggle. An optional yolo mode auto-approves agent input/confirmation requests.
|
|
22
17
|
|
|
23
18
|
## Quick Start
|
|
24
19
|
|
|
@@ -34,7 +29,7 @@ It is not:
|
|
|
34
29
|
powershell -c "irm https://palmier.me/install.ps1 | iex"
|
|
35
30
|
```
|
|
36
31
|
|
|
37
|
-
The one-liner installs Node.js 24+ if needed
|
|
32
|
+
The one-liner installs Node.js 24+ if needed, installs `palmier` globally, and runs the setup wizard. If you already have Node.js 24+ and npm:
|
|
38
33
|
```bash
|
|
39
34
|
npm install -g palmier && palmier init
|
|
40
35
|
```
|
package/dist/agents/wizard.js
CHANGED
|
@@ -187,7 +187,7 @@ function runAgentAuthFlow(label, command, args) {
|
|
|
187
187
|
console.log(`Re-run ${cyan(cmd)} manually after this.\n`);
|
|
188
188
|
return;
|
|
189
189
|
}
|
|
190
|
-
console.log(green(`
|
|
190
|
+
console.log(green(`Finished authenticating ${label}.\n`));
|
|
191
191
|
}
|
|
192
192
|
async function waitForEnter(message) {
|
|
193
193
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
package/dist/mcp-tools.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import * as fs from "fs";
|
|
1
2
|
import { StringCodec } from "nats";
|
|
2
3
|
import { registerPending } from "./pending-requests.js";
|
|
3
4
|
import { getLinkedDevice } from "./linked-device.js";
|
|
4
5
|
import { getNotifications, onNotificationsChanged } from "./notification-store.js";
|
|
5
6
|
import { getSmsMessages, onSmsChanged } from "./sms-store.js";
|
|
7
|
+
import { getTaskDir, readHistory, spliceUserMessage } from "./task.js";
|
|
6
8
|
export class ToolError extends Error {
|
|
7
9
|
statusCode;
|
|
8
10
|
constructor(message, statusCode = 500) {
|
|
@@ -84,7 +86,9 @@ const requestInputTool = {
|
|
|
84
86
|
input_questions: questions,
|
|
85
87
|
});
|
|
86
88
|
const response = await pendingPromise;
|
|
87
|
-
|
|
89
|
+
const aborted = response.length === 1 && response[0] === "aborted";
|
|
90
|
+
recordUserInputToRun(ctx, questions, response, aborted);
|
|
91
|
+
if (aborted) {
|
|
88
92
|
await ctx.publishEvent("_input", {
|
|
89
93
|
event_type: "input-resolved", host_id: ctx.config.hostId,
|
|
90
94
|
session_id: ctx.sessionId, status: "aborted",
|
|
@@ -98,6 +102,40 @@ const requestInputTool = {
|
|
|
98
102
|
return { values: response };
|
|
99
103
|
},
|
|
100
104
|
};
|
|
105
|
+
/**
|
|
106
|
+
* Splice the user's answer into the task run file so the conversation history
|
|
107
|
+
* shows what the user typed, independent of whether the agent echoes it.
|
|
108
|
+
* Only writes when sessionId resolves to a task with an active run (i.e. the
|
|
109
|
+
* agent called via the REST endpoint with taskId); silently skips for pure
|
|
110
|
+
* MCP-protocol sessions where sessionId is a random UUID.
|
|
111
|
+
*/
|
|
112
|
+
function recordUserInputToRun(ctx, questions, response, aborted) {
|
|
113
|
+
const taskId = ctx.sessionId;
|
|
114
|
+
if (!taskId)
|
|
115
|
+
return;
|
|
116
|
+
const taskDir = getTaskDir(ctx.config.projectRoot, taskId);
|
|
117
|
+
if (!fs.existsSync(taskDir))
|
|
118
|
+
return;
|
|
119
|
+
const { entries } = readHistory(ctx.config.projectRoot, { task_id: taskId, limit: 1 });
|
|
120
|
+
const runId = entries[0]?.run_id;
|
|
121
|
+
if (!runId)
|
|
122
|
+
return;
|
|
123
|
+
const content = aborted
|
|
124
|
+
? "Cancel"
|
|
125
|
+
: questions.map((q, i) => `**${q}**\n\n${response[i] ?? ""}`).join("\n\n");
|
|
126
|
+
try {
|
|
127
|
+
spliceUserMessage(taskDir, runId, {
|
|
128
|
+
role: "user",
|
|
129
|
+
time: Date.now(),
|
|
130
|
+
content,
|
|
131
|
+
type: "input",
|
|
132
|
+
});
|
|
133
|
+
void ctx.publishEvent(taskId, { event_type: "result-updated", run_id: runId });
|
|
134
|
+
}
|
|
135
|
+
catch {
|
|
136
|
+
// Run file missing or unwritable — best-effort, do not fail the tool call.
|
|
137
|
+
}
|
|
138
|
+
}
|
|
101
139
|
const requestConfirmationTool = {
|
|
102
140
|
name: "request-confirmation",
|
|
103
141
|
description: [
|