palmier 0.2.3 → 0.2.5

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 (43) hide show
  1. package/README.md +21 -30
  2. package/dist/agents/claude.js +5 -2
  3. package/dist/agents/codex.js +4 -2
  4. package/dist/agents/gemini.js +4 -2
  5. package/dist/commands/info.js +17 -10
  6. package/dist/commands/init.d.ts +2 -10
  7. package/dist/commands/init.js +102 -154
  8. package/dist/commands/pair.js +3 -3
  9. package/dist/commands/run.js +2 -13
  10. package/dist/commands/sessions.js +1 -4
  11. package/dist/config.js +1 -1
  12. package/dist/index.js +7 -7
  13. package/dist/platform/index.d.ts +4 -0
  14. package/dist/platform/index.js +12 -0
  15. package/dist/platform/linux.d.ts +11 -0
  16. package/dist/platform/linux.js +186 -0
  17. package/dist/platform/platform.d.ts +20 -0
  18. package/dist/platform/platform.js +2 -0
  19. package/dist/platform/windows.d.ts +11 -0
  20. package/dist/platform/windows.js +201 -0
  21. package/dist/rpc-handler.js +13 -30
  22. package/dist/spawn-command.d.ts +5 -2
  23. package/dist/spawn-command.js +2 -0
  24. package/dist/transports/http-transport.js +2 -7
  25. package/package.json +1 -1
  26. package/src/agents/claude.ts +6 -2
  27. package/src/agents/codex.ts +5 -2
  28. package/src/agents/gemini.ts +5 -2
  29. package/src/commands/info.ts +18 -10
  30. package/src/commands/init.ts +131 -180
  31. package/src/commands/pair.ts +4 -3
  32. package/src/commands/run.ts +3 -15
  33. package/src/commands/sessions.ts +1 -4
  34. package/src/config.ts +1 -1
  35. package/src/index.ts +8 -7
  36. package/src/platform/index.ts +16 -0
  37. package/src/platform/linux.ts +207 -0
  38. package/src/platform/platform.ts +25 -0
  39. package/src/platform/windows.ts +223 -0
  40. package/src/rpc-handler.ts +13 -37
  41. package/src/spawn-command.ts +7 -2
  42. package/src/transports/http-transport.ts +2 -5
  43. package/src/systemd.ts +0 -164
package/src/systemd.ts DELETED
@@ -1,164 +0,0 @@
1
- import * as fs from "fs";
2
- import * as path from "path";
3
- import { homedir } from "os";
4
- import { execSync } from "child_process";
5
- import type { HostConfig } from "./types.js";
6
- import type { ParsedTask } from "./types.js";
7
-
8
- const UNIT_DIR = path.join(homedir(), ".config", "systemd", "user");
9
-
10
- function getTimerName(taskId: string): string {
11
- return `palmier-task-${taskId}.timer`;
12
- }
13
-
14
- function getServiceName(taskId: string): string {
15
- return `palmier-task-${taskId}.service`;
16
- }
17
-
18
- /**
19
- * Convert a cron expression (5-field) to a systemd OnCalendar string.
20
- * Handles basic cron patterns: minute hour day-of-month month day-of-week
21
- */
22
- export function cronToOnCalendar(cron: string): string {
23
- const parts = cron.trim().split(/\s+/);
24
- if (parts.length !== 5) {
25
- throw new Error(`Invalid cron expression (expected 5 fields): ${cron}`);
26
- }
27
-
28
- const [minute, hour, dayOfMonth, month, dayOfWeek] = parts;
29
-
30
- // Map cron day-of-week names/numbers to systemd abbreviated names
31
- const dowMap: Record<string, string> = {
32
- "0": "Sun",
33
- "1": "Mon",
34
- "2": "Tue",
35
- "3": "Wed",
36
- "4": "Thu",
37
- "5": "Fri",
38
- "6": "Sat",
39
- "7": "Sun",
40
- };
41
-
42
- // Convert day-of-week
43
- let dow = dayOfWeek === "*" ? "*" : dayOfWeek;
44
- if (dowMap[dow]) {
45
- dow = dowMap[dow];
46
- }
47
-
48
- // Build OnCalendar string
49
- // Format: DayOfWeek Year-Month-Day Hour:Minute:Second
50
- const monthPart = month === "*" ? "*" : month.padStart(2, "0");
51
- const dayPart = dayOfMonth === "*" ? "*" : dayOfMonth.padStart(2, "0");
52
- const hourPart = hour === "*" ? "*" : hour.padStart(2, "0");
53
- const minutePart = minute === "*" ? "*" : minute.padStart(2, "0");
54
-
55
- if (dow === "*") {
56
- return `*-${monthPart}-${dayPart} ${hourPart}:${minutePart}:00`;
57
- }
58
-
59
- return `${dow} *-${monthPart}-${dayPart} ${hourPart}:${minutePart}:00`;
60
- }
61
-
62
- /**
63
- * Install a systemd user timer + service for a task.
64
- */
65
- export function installTaskTimer(config: HostConfig, task: ParsedTask): void {
66
- fs.mkdirSync(UNIT_DIR, { recursive: true });
67
-
68
- const taskId = task.frontmatter.id;
69
- const serviceName = getServiceName(taskId);
70
- const timerName = getTimerName(taskId);
71
-
72
- // Determine the palmier binary path
73
- const palmierBin = process.argv[1] || "palmier";
74
-
75
- // Generate service unit
76
- const serviceContent = `[Unit]
77
- Description=Palmier Task: ${taskId}
78
-
79
- [Service]
80
- Type=oneshot
81
- ExecStart=${palmierBin} run ${taskId}
82
- WorkingDirectory=${config.projectRoot}
83
- Environment=PATH=${process.env.PATH || "/usr/local/bin:/usr/bin:/bin"}
84
- `;
85
-
86
- // Write service unit (always needed for on-demand runs)
87
- fs.writeFileSync(path.join(UNIT_DIR, serviceName), serviceContent, "utf-8");
88
- daemonReload();
89
-
90
- // Only create and enable a timer if there are actual triggers
91
- const triggers = task.frontmatter.triggers || [];
92
- const onCalendarLines: string[] = [];
93
- for (const trigger of triggers) {
94
- if (trigger.type === "cron") {
95
- onCalendarLines.push(`OnCalendar=${cronToOnCalendar(trigger.value)}`);
96
- } else if (trigger.type === "once") {
97
- onCalendarLines.push(`OnActiveSec=${trigger.value}`);
98
- }
99
- }
100
-
101
- if (onCalendarLines.length > 0) {
102
- const timerContent = `[Unit]
103
- Description=Timer for Palmier Task: ${taskId}
104
-
105
- [Timer]
106
- ${onCalendarLines.join("\n")}
107
- Persistent=true
108
-
109
- [Install]
110
- WantedBy=timers.target
111
- `;
112
- fs.writeFileSync(path.join(UNIT_DIR, timerName), timerContent, "utf-8");
113
- daemonReload();
114
-
115
- try {
116
- execSync(`systemctl --user enable --now ${timerName}`, { encoding: "utf-8" });
117
- } catch (err: unknown) {
118
- const e = err as { stderr?: string };
119
- console.error(`Failed to enable timer ${timerName}: ${e.stderr || err}`);
120
- }
121
- }
122
- }
123
-
124
- /**
125
- * Remove a task's systemd timer and service files.
126
- */
127
- export function removeTaskTimer(taskId: string): void {
128
- const timerName = getTimerName(taskId);
129
- const serviceName = getServiceName(taskId);
130
-
131
- const timerPath = path.join(UNIT_DIR, timerName);
132
- const servicePath = path.join(UNIT_DIR, serviceName);
133
-
134
- // Only stop/disable the timer if the file exists
135
- if (fs.existsSync(timerPath)) {
136
- try {
137
- execSync(`systemctl --user stop ${timerName}`, { encoding: "utf-8" });
138
- } catch {
139
- // Timer might not be running
140
- }
141
- try {
142
- execSync(`systemctl --user disable ${timerName}`, { encoding: "utf-8" });
143
- } catch {
144
- // Timer might not be enabled
145
- }
146
- fs.unlinkSync(timerPath);
147
- }
148
-
149
- if (fs.existsSync(servicePath)) fs.unlinkSync(servicePath);
150
-
151
- daemonReload();
152
- }
153
-
154
- /**
155
- * Run systemctl --user daemon-reload.
156
- */
157
- export function daemonReload(): void {
158
- try {
159
- execSync("systemctl --user daemon-reload", { encoding: "utf-8" });
160
- } catch (err: unknown) {
161
- const e = err as { stderr?: string };
162
- console.error(`daemon-reload failed: ${e.stderr || err}`);
163
- }
164
- }