palmier 0.3.5 → 0.3.7

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 CHANGED
@@ -52,7 +52,6 @@ All `palmier` commands should be run from a dedicated Palmier root directory (e.
52
52
  | `palmier restart` | Restart the palmier serve daemon |
53
53
  | `palmier run <task-id>` | Execute a specific task |
54
54
  | `palmier mcpserver` | Start an MCP server exposing Palmier tools (stdio transport) |
55
- | `palmier agents` | Re-detect installed agent CLIs and update config |
56
55
 
57
56
  ## Setup
58
57
 
@@ -88,7 +87,7 @@ The `init` command:
88
87
  - Installs a background daemon (systemd user service on Linux, Registry Run key on Windows)
89
88
  - Auto-enters pair mode to connect your first device
90
89
 
91
- To re-detect agents after installing or removing a CLI, run `palmier agents`.
90
+ Agents are re-detected on every daemon start. Run `palmier restart` after installing or removing a CLI.
92
91
 
93
92
  ### Verifying the Service
94
93
 
@@ -170,7 +169,7 @@ src/
170
169
  lan.ts # On-demand LAN server
171
170
  sessions.ts # Session token management CLI (list, revoke, revoke-all)
172
171
  info.ts # Print host connection info
173
- agents.ts # Re-detect installed agent CLIs
172
+
174
173
  serve.ts # Transport selection, startup, and crash detection polling
175
174
  restart.ts # Daemon restart (cross-platform)
176
175
  run.ts # Single task execution
@@ -16,7 +16,8 @@ export class CopilotAgent {
16
16
  const args = ["-p", prompt];
17
17
  const allPerms = [...(task.frontmatter.permissions ?? []), ...(extraPermissions ?? [])];
18
18
  if (allPerms.length > 0) {
19
- args.push("--allow-tool", allPerms.map((p) => p.name).join(","));
19
+ args.push(`--allow-tool='${allPerms.map((p) => p.name).join(",")}'`);
20
+ ;
20
21
  }
21
22
  if (retryPrompt) {
22
23
  args.push("--continue");
@@ -8,6 +8,8 @@ import { getTaskDir, readTaskStatus, writeTaskStatus, appendHistory, parseTaskFi
8
8
  import { publishHostEvent } from "../events.js";
9
9
  import { getPlatform } from "../platform/index.js";
10
10
  import { checkForUpdate } from "../update-checker.js";
11
+ import { detectAgents } from "../agents/agent.js";
12
+ import { saveConfig } from "../config.js";
11
13
  import { CONFIG_DIR } from "../config.js";
12
14
  const POLL_INTERVAL_MS = 30_000;
13
15
  const DAEMON_PID_FILE = path.join(CONFIG_DIR, "daemon.pid");
@@ -72,6 +74,11 @@ export async function serveCommand() {
72
74
  // Write PID so `palmier restart` can find us regardless of how we were started
73
75
  fs.writeFileSync(DAEMON_PID_FILE, String(process.pid), "utf-8");
74
76
  console.log("Starting...");
77
+ // Re-detect agents on every daemon start
78
+ const agents = await detectAgents();
79
+ config.agents = agents;
80
+ saveConfig(config);
81
+ console.log(`Detected agents: ${agents.map((a) => a.key).join(", ") || "none"}`);
75
82
  const nc = await connectNats(config);
76
83
  // Reconcile any tasks stuck from before daemon started
77
84
  await checkStaleTasks(config, nc);
package/dist/index.js CHANGED
@@ -9,7 +9,6 @@ import { infoCommand } from "./commands/info.js";
9
9
  import { runCommand } from "./commands/run.js";
10
10
  import { serveCommand } from "./commands/serve.js";
11
11
  import { mcpserverCommand } from "./commands/mcpserver.js";
12
- import { agentsCommand } from "./commands/agents.js";
13
12
  import { pairCommand } from "./commands/pair.js";
14
13
  import { lanCommand } from "./commands/lan.js";
15
14
  import { restartCommand } from "./commands/restart.js";
@@ -57,12 +56,6 @@ program
57
56
  .action(async () => {
58
57
  await mcpserverCommand();
59
58
  });
60
- program
61
- .command("agents")
62
- .description("Re-detect installed agent CLIs and update config")
63
- .action(async () => {
64
- await agentsCommand();
65
- });
66
59
  program
67
60
  .command("pair")
68
61
  .description("Generate a pairing code for connecting a PWA client")
@@ -96,6 +96,17 @@ WantedBy=default.target
96
96
  console.log("\nHost initialization complete!");
97
97
  }
98
98
  async restartDaemon() {
99
+ // Update the service file's PATH to the current shell PATH,
100
+ // so the daemon can find agent CLIs installed after init.
101
+ const servicePath = path.join(UNIT_DIR, "palmier.service");
102
+ if (fs.existsSync(servicePath)) {
103
+ const content = fs.readFileSync(servicePath, "utf-8");
104
+ const updated = content.replace(/^Environment=PATH=.*/m, `Environment=PATH=${process.env.PATH || "/usr/local/bin:/usr/bin:/bin"}`);
105
+ if (updated !== content) {
106
+ fs.writeFileSync(servicePath, updated, "utf-8");
107
+ execSync("systemctl --user daemon-reload", { encoding: "utf-8" });
108
+ }
109
+ }
99
110
  execSync("systemctl --user restart palmier.service", { stdio: "inherit" });
100
111
  console.log("Palmier daemon restarted.");
101
112
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "palmier",
3
- "version": "0.3.5",
3
+ "version": "0.3.7",
4
4
  "description": "Palmier host CLI - provisions, executes tasks, and serves NATS RPC",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Hongxu Cai",
@@ -21,7 +21,7 @@ export class CopilotAgent implements AgentTool {
21
21
 
22
22
  const allPerms = [...(task.frontmatter.permissions ?? []), ...(extraPermissions ?? [])];
23
23
  if (allPerms.length > 0) {
24
- args.push("--allow-tool", allPerms.map((p) => p.name).join(","));
24
+ args.push(`--allow-tool='${allPerms.map((p) => p.name).join(",")}'`);;
25
25
  }
26
26
 
27
27
  if (retryPrompt) { args.push("--continue"); }
@@ -8,6 +8,8 @@ import { getTaskDir, readTaskStatus, writeTaskStatus, appendHistory, parseTaskFi
8
8
  import { publishHostEvent } from "../events.js";
9
9
  import { getPlatform } from "../platform/index.js";
10
10
  import { checkForUpdate } from "../update-checker.js";
11
+ import { detectAgents } from "../agents/agent.js";
12
+ import { saveConfig } from "../config.js";
11
13
  import type { HostConfig } from "../types.js";
12
14
  import { CONFIG_DIR } from "../config.js";
13
15
  import type { NatsConnection } from "nats";
@@ -89,6 +91,12 @@ export async function serveCommand(): Promise<void> {
89
91
 
90
92
  console.log("Starting...");
91
93
 
94
+ // Re-detect agents on every daemon start
95
+ const agents = await detectAgents();
96
+ config.agents = agents;
97
+ saveConfig(config);
98
+ console.log(`Detected agents: ${agents.map((a) => a.key).join(", ") || "none"}`);
99
+
92
100
  const nc = await connectNats(config);
93
101
 
94
102
  // Reconcile any tasks stuck from before daemon started
package/src/index.ts CHANGED
@@ -10,7 +10,7 @@ import { infoCommand } from "./commands/info.js";
10
10
  import { runCommand } from "./commands/run.js";
11
11
  import { serveCommand } from "./commands/serve.js";
12
12
  import { mcpserverCommand } from "./commands/mcpserver.js";
13
- import { agentsCommand } from "./commands/agents.js";
13
+
14
14
  import { pairCommand } from "./commands/pair.js";
15
15
  import { lanCommand } from "./commands/lan.js";
16
16
  import { restartCommand } from "./commands/restart.js";
@@ -68,13 +68,6 @@ program
68
68
  await mcpserverCommand();
69
69
  });
70
70
 
71
- program
72
- .command("agents")
73
- .description("Re-detect installed agent CLIs and update config")
74
- .action(async () => {
75
- await agentsCommand();
76
- });
77
-
78
71
  program
79
72
  .command("pair")
80
73
  .description("Generate a pairing code for connecting a PWA client")
@@ -113,6 +113,20 @@ WantedBy=default.target
113
113
  }
114
114
 
115
115
  async restartDaemon(): Promise<void> {
116
+ // Update the service file's PATH to the current shell PATH,
117
+ // so the daemon can find agent CLIs installed after init.
118
+ const servicePath = path.join(UNIT_DIR, "palmier.service");
119
+ if (fs.existsSync(servicePath)) {
120
+ const content = fs.readFileSync(servicePath, "utf-8");
121
+ const updated = content.replace(
122
+ /^Environment=PATH=.*/m,
123
+ `Environment=PATH=${process.env.PATH || "/usr/local/bin:/usr/bin:/bin"}`,
124
+ );
125
+ if (updated !== content) {
126
+ fs.writeFileSync(servicePath, updated, "utf-8");
127
+ execSync("systemctl --user daemon-reload", { encoding: "utf-8" });
128
+ }
129
+ }
116
130
  execSync("systemctl --user restart palmier.service", { stdio: "inherit" });
117
131
  console.log("Palmier daemon restarted.");
118
132
  }
@@ -1,2 +0,0 @@
1
- export declare function agentsCommand(): Promise<void>;
2
- //# sourceMappingURL=agents.d.ts.map
@@ -1,30 +0,0 @@
1
- import { loadConfig, saveConfig } from "../config.js";
2
- import { detectAgents } from "../agents/agent.js";
3
- import { getPlatform } from "../platform/index.js";
4
- export async function agentsCommand() {
5
- const config = loadConfig();
6
- const oldKeys = (config.agents ?? []).map((a) => a.key).sort().join(",");
7
- console.log("Detecting installed agents...");
8
- const agents = await detectAgents();
9
- config.agents = agents;
10
- saveConfig(config);
11
- if (agents.length === 0) {
12
- console.log("No agent CLIs detected.");
13
- }
14
- else {
15
- console.log("Detected agents:");
16
- for (const a of agents) {
17
- console.log(` ${a.key} — ${a.label}`);
18
- }
19
- }
20
- // Restart daemon if agent list changed so the UI picks it up immediately
21
- const newKeys = agents.map((a) => a.key).sort().join(",");
22
- if (newKeys !== oldKeys) {
23
- try {
24
- console.log("Agent list changed, restarting daemon...");
25
- await getPlatform().restartDaemon();
26
- }
27
- catch { /* daemon may not be running yet */ }
28
- }
29
- }
30
- //# sourceMappingURL=agents.js.map
@@ -1,31 +0,0 @@
1
- import { loadConfig, saveConfig } from "../config.js";
2
- import { detectAgents } from "../agents/agent.js";
3
- import { getPlatform } from "../platform/index.js";
4
-
5
- export async function agentsCommand(): Promise<void> {
6
- const config = loadConfig();
7
- const oldKeys = (config.agents ?? []).map((a) => a.key).sort().join(",");
8
-
9
- console.log("Detecting installed agents...");
10
- const agents = await detectAgents();
11
- config.agents = agents;
12
- saveConfig(config);
13
-
14
- if (agents.length === 0) {
15
- console.log("No agent CLIs detected.");
16
- } else {
17
- console.log("Detected agents:");
18
- for (const a of agents) {
19
- console.log(` ${a.key} — ${a.label}`);
20
- }
21
- }
22
-
23
- // Restart daemon if agent list changed so the UI picks it up immediately
24
- const newKeys = agents.map((a) => a.key).sort().join(",");
25
- if (newKeys !== oldKeys) {
26
- try {
27
- console.log("Agent list changed, restarting daemon...");
28
- await getPlatform().restartDaemon();
29
- } catch { /* daemon may not be running yet */ }
30
- }
31
- }