palmier 0.7.8 → 0.7.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 +1 -1
- package/dist/mcp-tools.d.ts +2 -0
- package/dist/mcp-tools.js +4 -2
- package/dist/platform/linux.js +11 -8
- package/dist/platform/windows.d.ts +5 -6
- package/dist/platform/windows.js +15 -12
- package/dist/pwa/assets/index-FP1Mipr6.js +120 -0
- package/dist/pwa/assets/index-bLTn8zBj.css +1 -0
- package/dist/pwa/assets/{web-BNr628AV.js → web-BpM3fNCn.js} +1 -1
- package/dist/pwa/assets/{web-DyQPewAi.js → web-CF-N8Di6.js} +1 -1
- package/dist/pwa/index.html +2 -2
- package/dist/pwa/service-worker.js +1 -1
- package/dist/rpc-handler.js +23 -8
- package/dist/task.js +1 -1
- package/dist/transports/http-transport.js +3 -5
- package/dist/types.d.ts +9 -6
- package/package.json +1 -1
- package/palmier-server/README.md +3 -3
- package/palmier-server/pwa/src/App.css +117 -36
- package/palmier-server/pwa/src/components/PullToRefreshIndicator.tsx +46 -0
- package/palmier-server/pwa/src/components/RunDetailView.tsx +58 -15
- package/palmier-server/pwa/src/components/SessionComposer.tsx +20 -10
- package/palmier-server/pwa/src/components/{RunsView.tsx → SessionsView.tsx} +33 -25
- package/palmier-server/pwa/src/components/TaskCard.tsx +33 -35
- package/palmier-server/pwa/src/components/TaskForm.tsx +274 -293
- package/palmier-server/pwa/src/components/{TaskListView.tsx → TasksView.tsx} +20 -13
- package/palmier-server/pwa/src/contexts/HostStoreContext.tsx +16 -8
- package/palmier-server/pwa/src/hooks/usePullToRefresh.ts +102 -0
- package/palmier-server/pwa/src/pages/Dashboard.tsx +9 -26
- package/palmier-server/pwa/src/types.ts +5 -9
- package/palmier-server/spec.md +23 -23
- package/src/mcp-tools.ts +6 -2
- package/src/platform/linux.ts +10 -8
- package/src/platform/windows.ts +15 -12
- package/src/rpc-handler.ts +26 -10
- package/src/task.ts +1 -1
- package/src/transports/http-transport.ts +3 -5
- package/src/types.ts +9 -7
- package/dist/pwa/assets/index-8cTctVnD.js +0 -120
- package/dist/pwa/assets/index-CSUkBBsQ.css +0 -1
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
You have AI agents on your machine. But you have to sit at your desk to use them. Palmier lets you dispatch, schedule, and monitor them from any device, anywhere.
|
|
10
10
|
|
|
11
|
-
It runs on your machine as a background daemon and connects to a mobile-friendly PWA, so you can
|
|
11
|
+
It runs on your machine as a background daemon and connects to a mobile-friendly PWA, so you can start one-off sessions, schedule recurring tasks, approve permissions, and check results without being at your computer.
|
|
12
12
|
> **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.
|
|
13
13
|
|
|
14
14
|
## Quick Start
|
package/dist/mcp-tools.d.ts
CHANGED
|
@@ -32,6 +32,8 @@ export interface ResourceDefinition {
|
|
|
32
32
|
restPath: string;
|
|
33
33
|
/** Return the current resource content. */
|
|
34
34
|
read: () => unknown;
|
|
35
|
+
/** Register a listener for content changes. Returns an unsubscribe function. */
|
|
36
|
+
subscribe: (listener: () => void) => () => void;
|
|
35
37
|
}
|
|
36
38
|
export declare const agentResources: ResourceDefinition[];
|
|
37
39
|
export declare const agentResourceMap: Map<string, ResourceDefinition>;
|
package/dist/mcp-tools.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { StringCodec } from "nats";
|
|
2
2
|
import { registerPending } from "./pending-requests.js";
|
|
3
3
|
import { getCapabilityDevice } from "./device-capabilities.js";
|
|
4
|
-
import { getNotifications } from "./notification-store.js";
|
|
5
|
-
import { getSmsMessages } from "./sms-store.js";
|
|
4
|
+
import { getNotifications, onNotificationsChanged } from "./notification-store.js";
|
|
5
|
+
import { getSmsMessages, onSmsChanged } from "./sms-store.js";
|
|
6
6
|
export class ToolError extends Error {
|
|
7
7
|
statusCode;
|
|
8
8
|
constructor(message, statusCode = 500) {
|
|
@@ -651,6 +651,7 @@ const deviceNotificationsResource = {
|
|
|
651
651
|
mimeType: "application/json",
|
|
652
652
|
restPath: "/notifications",
|
|
653
653
|
read: getNotifications,
|
|
654
|
+
subscribe: onNotificationsChanged,
|
|
654
655
|
};
|
|
655
656
|
const deviceSmsResource = {
|
|
656
657
|
uri: "sms-messages://device",
|
|
@@ -662,6 +663,7 @@ const deviceSmsResource = {
|
|
|
662
663
|
mimeType: "application/json",
|
|
663
664
|
restPath: "/sms-messages",
|
|
664
665
|
read: getSmsMessages,
|
|
666
|
+
subscribe: onSmsChanged,
|
|
665
667
|
};
|
|
666
668
|
export const agentResources = [deviceNotificationsResource, deviceSmsResource];
|
|
667
669
|
export const agentResourceMap = new Map(agentResources.map((r) => [r.uri, r]));
|
package/dist/platform/linux.js
CHANGED
|
@@ -181,17 +181,20 @@ Environment=PATH=${process.env.PATH || "/usr/local/bin:/usr/bin:/bin"}
|
|
|
181
181
|
`;
|
|
182
182
|
fs.writeFileSync(path.join(UNIT_DIR, serviceName), serviceContent, "utf-8");
|
|
183
183
|
daemonReload();
|
|
184
|
-
// Only create and enable a timer if
|
|
185
|
-
if (!task.frontmatter.
|
|
184
|
+
// Only create and enable a timer if the schedule exists and is enabled
|
|
185
|
+
if (!task.frontmatter.schedule_enabled)
|
|
186
|
+
return;
|
|
187
|
+
const scheduleType = task.frontmatter.schedule_type;
|
|
188
|
+
const scheduleValues = task.frontmatter.schedule_values;
|
|
189
|
+
if (!scheduleType || !scheduleValues?.length)
|
|
186
190
|
return;
|
|
187
|
-
const triggers = task.frontmatter.triggers || [];
|
|
188
191
|
const onCalendarLines = [];
|
|
189
|
-
for (const
|
|
190
|
-
if (
|
|
191
|
-
onCalendarLines.push(`OnCalendar=${cronToOnCalendar(
|
|
192
|
+
for (const value of scheduleValues) {
|
|
193
|
+
if (scheduleType === "crons") {
|
|
194
|
+
onCalendarLines.push(`OnCalendar=${cronToOnCalendar(value)}`);
|
|
192
195
|
}
|
|
193
|
-
else if (
|
|
194
|
-
onCalendarLines.push(`OnActiveSec=${
|
|
196
|
+
else if (scheduleType === "specific_times") {
|
|
197
|
+
onCalendarLines.push(`OnActiveSec=${value}`);
|
|
195
198
|
}
|
|
196
199
|
}
|
|
197
200
|
if (onCalendarLines.length > 0) {
|
|
@@ -1,18 +1,17 @@
|
|
|
1
1
|
import type { PlatformService } from "./platform.js";
|
|
2
2
|
import type { HostConfig, ParsedTask } from "../types.js";
|
|
3
3
|
/**
|
|
4
|
-
* Convert a
|
|
4
|
+
* Convert a single schedule value to a Task Scheduler XML trigger element.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
6
|
+
* `specific_times` values are ISO datetime strings like "2026-03-28T09:00".
|
|
7
|
+
*
|
|
8
|
+
* `crons` values are cron expressions. Only these patterns (produced by the PWA UI) are handled:
|
|
7
9
|
* hourly: "0 * * * *"
|
|
8
10
|
* daily: "MM HH * * *"
|
|
9
11
|
* weekly: "MM HH * * D"
|
|
10
12
|
* monthly: "MM HH D * *"
|
|
11
13
|
*/
|
|
12
|
-
export declare function
|
|
13
|
-
type: string;
|
|
14
|
-
value: string;
|
|
15
|
-
}): string;
|
|
14
|
+
export declare function scheduleValueToXml(scheduleType: "crons" | "specific_times", value: string): string;
|
|
16
15
|
/**
|
|
17
16
|
* Build a complete Task Scheduler XML definition.
|
|
18
17
|
*/
|
package/dist/platform/windows.js
CHANGED
|
@@ -7,22 +7,23 @@ const TASK_PREFIX = "\\Palmier\\PalmierTask-";
|
|
|
7
7
|
const DAEMON_TASK_NAME = "PalmierDaemon";
|
|
8
8
|
const DOW_NAMES = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"];
|
|
9
9
|
/**
|
|
10
|
-
* Convert a
|
|
10
|
+
* Convert a single schedule value to a Task Scheduler XML trigger element.
|
|
11
11
|
*
|
|
12
|
-
*
|
|
12
|
+
* `specific_times` values are ISO datetime strings like "2026-03-28T09:00".
|
|
13
|
+
*
|
|
14
|
+
* `crons` values are cron expressions. Only these patterns (produced by the PWA UI) are handled:
|
|
13
15
|
* hourly: "0 * * * *"
|
|
14
16
|
* daily: "MM HH * * *"
|
|
15
17
|
* weekly: "MM HH * * D"
|
|
16
18
|
* monthly: "MM HH D * *"
|
|
17
19
|
*/
|
|
18
|
-
export function
|
|
19
|
-
if (
|
|
20
|
-
|
|
21
|
-
return `<TimeTrigger><StartBoundary>${trigger.value}:00</StartBoundary></TimeTrigger>`;
|
|
20
|
+
export function scheduleValueToXml(scheduleType, value) {
|
|
21
|
+
if (scheduleType === "specific_times") {
|
|
22
|
+
return `<TimeTrigger><StartBoundary>${value}:00</StartBoundary></TimeTrigger>`;
|
|
22
23
|
}
|
|
23
|
-
const parts =
|
|
24
|
+
const parts = value.trim().split(/\s+/);
|
|
24
25
|
if (parts.length !== 5)
|
|
25
|
-
throw new Error(`Invalid cron expression: ${
|
|
26
|
+
throw new Error(`Invalid cron expression: ${value}`);
|
|
26
27
|
const [minute, hour, dayOfMonth, , dayOfWeek] = parts;
|
|
27
28
|
const st = `${hour.padStart(2, "0")}:${minute.padStart(2, "0")}:00`;
|
|
28
29
|
// StartBoundary needs a full date; use a past date as the anchor
|
|
@@ -178,13 +179,15 @@ export class WindowsPlatform {
|
|
|
178
179
|
const tr = `"${process.execPath}" "${script}" run ${taskId}`;
|
|
179
180
|
// Build trigger XML elements
|
|
180
181
|
const triggerElements = [];
|
|
181
|
-
|
|
182
|
-
|
|
182
|
+
const scheduleType = task.frontmatter.schedule_type;
|
|
183
|
+
const scheduleValues = task.frontmatter.schedule_values;
|
|
184
|
+
if (task.frontmatter.schedule_enabled && scheduleType && scheduleValues?.length) {
|
|
185
|
+
for (const value of scheduleValues) {
|
|
183
186
|
try {
|
|
184
|
-
triggerElements.push(
|
|
187
|
+
triggerElements.push(scheduleValueToXml(scheduleType, value));
|
|
185
188
|
}
|
|
186
189
|
catch (err) {
|
|
187
|
-
console.error(`Invalid
|
|
190
|
+
console.error(`Invalid schedule value: ${err}`);
|
|
188
191
|
}
|
|
189
192
|
}
|
|
190
193
|
}
|