palmier 1.0.4 → 1.0.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.
package/README.md CHANGED
@@ -203,15 +203,17 @@ Run `palmier agents` to manage agent CLIs after setup: it lists installed agents
203
203
 
204
204
  ### Browser Automation
205
205
 
206
- Some capabilities (like the [saved-password autofill](#saved-passwords)) drive a real browser through the [`playwright-cli`](https://www.npmjs.com/package/@playwright/cli) skill. `palmier init` offers to install and manage the Playwright CLI (`@playwright/cli`) for this. When you opt in, Palmier manages it **just like an agent CLI** — the version is stamped, re-probed live on each daemon start, and the PWA shows a "Browser Automation Update Available" dialog (same flow as agents) when a newer version is published. Its version is shown in the app's host drawer. The browser binaries Playwright needs are downloaded lazily on first use, not during init.
206
+ Some capabilities (like the [saved-password autofill](#saved-passwords)) drive a real browser through the [`playwright-cli`](https://www.npmjs.com/package/@playwright/cli) skill. `palmier init` offers to install and manage the Playwright CLI (`@playwright/cli`) for this, and on install also runs `playwright-cli install --skills` in your Palmier task directory (`~/palmier`) so agents get the Playwright skills that teach them how to drive the browser. When you opt in, Palmier manages it **just like an agent CLI** — the version is stamped, re-probed live on each daemon start, and the PWA shows a "Browser Automation Update Available" dialog (same flow as agents) when a newer version is published. Its version is shown in the app's host drawer. The browser binaries Playwright needs are downloaded lazily on first use, not during init.
207
207
 
208
208
  Unlike agents, the Playwright CLI has **no explicit uninstall** — it's not offered in any uninstall picker. It is removed only by a full `palmier uninstall`.
209
209
 
210
210
  ### Updates
211
211
 
212
- - **Palmier itself** — when a newer version of `palmier` is published to npm, the PWA shows a dismissible "Update Available" dialog. Clicking "Update Now" runs `npm update -g palmier` on the host and restarts the daemon. Clicking "Dismiss" suppresses the dialog for that exact version (per host, per device); a future release re-arms it.
213
- - **Palmier-managed agents** — same flow per agent: when npm publishes a newer version, the PWA shows an "Agent Update Available" dialog. Clicking "Update Now" runs `npm update -g <pkg>` on the host (no daemon restart needed). Dismissals are per host, per agent, per version.
214
- - **Managed Playwright CLI** — same flow: a "Browser Automation Update Available" dialog runs `npm update -g @playwright/cli`. Dismissals are per host, per version.
212
+ - **Palmier itself** — when a newer version of `palmier` is published to npm, the PWA shows an "Update Available" dialog. Clicking "Update Now" runs `npm update -g palmier` on the host and restarts the daemon. Clicking "Dismiss" only hides it for the current session reopening or reloading the app shows it again until you update.
213
+ - **Palmier-managed agents** — same flow per agent: when npm publishes a newer version, the PWA shows an "Agent Update Available" dialog. Clicking "Update Now" runs `npm update -g <pkg>` on the host (no daemon restart needed).
214
+ - **Managed Playwright CLI** — same flow: a "Browser Automation Update Available" dialog runs `npm update -g @playwright/cli`.
215
+
216
+ Dismissals are session-only: they are never persisted, so a reload re-arms every update dialog until the update is applied.
215
217
 
216
218
  ### Re-detecting the LAN Network
217
219
 
@@ -20,7 +20,7 @@ Whenever a tool you are trying to use is denied or you lack the required permiss
20
20
 
21
21
  ## Browsers
22
22
 
23
- When launching a browser with the Playwright CLI, always pass `--headed`; never run headless.
23
+ When launching a browser with the Playwright CLI `open` command, always pass `--headed` (never run headless) and `--persistent` (reuse a persistent profile so logins and cookies survive across runs).
24
24
 
25
25
  ## HTTP Endpoints
26
26
 
@@ -14,7 +14,7 @@ export const claudeAgent = {
14
14
  const prompt = followupPrompt ?? getAgentInstructions(task);
15
15
  const args = ["--permission-mode", yolo ? "bypassPermissions" : "acceptEdits", "-p"];
16
16
  if (!yolo) {
17
- args.push("--allowedTools", "WebFetch", "Skill(playwright-cli)", "Bash(curl)", "Bash(wget)", "Bash(playwright)", "Bash(playwright-cli)");
17
+ args.push("--allowedTools", "WebFetch", "Skill(playwright-cli:*)", "Bash(curl:*)", "Bash(wget:*)", "Bash(playwright:*)", "Bash(playwright-cli:*)");
18
18
  const allPerms = [...(task.frontmatter.permissions ?? []), ...(extraPermissions ?? [])];
19
19
  for (const p of allPerms) {
20
20
  args.push(p.name);
@@ -23,6 +23,15 @@ export const claudeAgent = {
23
23
  if (followupPrompt) {
24
24
  args.push("-c");
25
25
  }
26
- return { args, stdin: prompt };
26
+ return {
27
+ args,
28
+ stdin: prompt,
29
+ // Don't let the Bash tool kill the curl that blocks on user input — the
30
+ // user may take arbitrarily long to answer. Max non-overflowing setTimeout.
31
+ env: {
32
+ BASH_DEFAULT_TIMEOUT_MS: "2147483647",
33
+ BASH_MAX_TIMEOUT_MS: "2147483647",
34
+ },
35
+ };
27
36
  },
28
37
  };
@@ -1,6 +1,7 @@
1
1
  import { loadConfig } from "../config.js";
2
2
  import { loadClients } from "../client-store.js";
3
3
  import { buildLanUrl } from "../network.js";
4
+ import { PLAYWRIGHT_CLI_LABEL } from "../playwright-cli.js";
4
5
  export async function infoCommand() {
5
6
  const config = loadConfig();
6
7
  const clients = loadClients();
@@ -16,6 +17,9 @@ export async function infoCommand() {
16
17
  else {
17
18
  console.log(`Agents: (none detected — run \`palmier agents\`)`);
18
19
  }
20
+ if (config.playwrightCliVersion) {
21
+ console.log(`Browser: ${PLAYWRIGHT_CLI_LABEL} (v${config.playwrightCliVersion})`);
22
+ }
19
23
  console.log(`Clients: ${clients.length} active`);
20
24
  if (clients.length === 0) {
21
25
  console.log("");
@@ -5,7 +5,7 @@ import { homedir } from "os";
5
5
  import { loadConfig, saveConfig } from "../config.js";
6
6
  import { detectAgents } from "../agents/agent.js";
7
7
  import { colors, pickAndInstallAgent, printInstalledAgents } from "../agents/wizard.js";
8
- import { installPlaywrightCli, getPlaywrightCliVersion, PLAYWRIGHT_CLI_LABEL } from "../playwright-cli.js";
8
+ import { installPlaywrightCli, installPlaywrightSkills, getPlaywrightCliVersion, PLAYWRIGHT_CLI_LABEL } from "../playwright-cli.js";
9
9
  import { getPlatform } from "../platform/index.js";
10
10
  import { pairCommand } from "./pair.js";
11
11
  import { detectDefaultInterface, getInterfaceIpv4 } from "../network.js";
@@ -49,18 +49,20 @@ export async function initCommand() {
49
49
  const ask = (q) => new Promise((resolve) => rl.question(q, resolve));
50
50
  try {
51
51
  // Browser automation is optional. Palmier manages the Playwright CLI like an
52
- // agent CLI (install, version-stamp, update) once the user opts in; an
53
- // already-managed install is re-probed rather than re-prompted.
54
- let playwrightCliVersion = previousConfig?.playwrightCliVersion;
55
- if (playwrightCliVersion) {
56
- playwrightCliVersion = getPlaywrightCliVersion() ?? playwrightCliVersion;
57
- }
58
- else {
52
+ // agent CLI (install, version-stamp, update) once the user opts in. Trust the
53
+ // actual global install, not just the saved marker: `palmier uninstall`
54
+ // removes the package but leaves host.json, so a stale playwrightCliVersion
55
+ // must not suppress the prompt.
56
+ let playwrightCliVersion = previousConfig?.playwrightCliVersion
57
+ ? getPlaywrightCliVersion() ?? undefined
58
+ : undefined;
59
+ if (!playwrightCliVersion) {
59
60
  const answer = (await ask(`\nInstall ${PLAYWRIGHT_CLI_LABEL} for browser automation? Lets agents control a browser — e.g. autofill saved passwords. (Y/n): `)).trim().toLowerCase();
60
61
  if (answer !== "n" && answer !== "no") {
61
62
  if (installPlaywrightCli()) {
62
63
  playwrightCliVersion = getPlaywrightCliVersion() ?? undefined;
63
64
  console.log(green(` ${PLAYWRIGHT_CLI_LABEL} installed.`));
65
+ installPlaywrightSkills(projectRoot);
64
66
  }
65
67
  }
66
68
  }
@@ -103,10 +103,11 @@ export async function serveCommand() {
103
103
  console.log(`Starting Palmier daemon v${currentVersion}...`);
104
104
  const agents = await detectAgents(config.agents);
105
105
  config.agents = agents;
106
- // Keep the managed Playwright CLI version in sync with manual upgrades, same
107
- // as agents. Only touched when Palmier already manages it.
106
+ // Keep the managed Playwright CLI version in sync with manual upgrades, and
107
+ // drop the marker if the package was removed out-of-band. Only touched when
108
+ // Palmier already manages it.
108
109
  if (config.playwrightCliVersion) {
109
- config.playwrightCliVersion = getPlaywrightCliVersion() ?? config.playwrightCliVersion;
110
+ config.playwrightCliVersion = getPlaywrightCliVersion() ?? undefined;
110
111
  }
111
112
  saveConfig(config);
112
113
  console.log(`Detected agents: ${agents.map((a) => a.key).join(", ") || "none"}`);
@@ -2,9 +2,14 @@
2
2
  * version-stamp, re-probe, PWA update prompt) but never offered for explicit
3
3
  * uninstall — it's only removed by `palmier uninstall`. */
4
4
  export declare const PLAYWRIGHT_CLI_PACKAGE = "@playwright/cli";
5
+ export declare const PLAYWRIGHT_CLI_COMMAND = "playwright-cli";
5
6
  export declare const PLAYWRIGHT_CLI_LABEL = "Playwright CLI";
6
7
  /** Installed global version, or null when not installed. Doubles as the
7
8
  * "is it installed" check (mirrors how agents resolve their version). */
8
9
  export declare function getPlaywrightCliVersion(): string | null;
9
10
  export declare function installPlaywrightCli(): boolean;
11
+ /** Install the Playwright agent skills so agent CLIs know how to drive the
12
+ * browser. Runs in `cwd` (the Palmier task directory) so the skills land where
13
+ * agents execute. Best-effort: a failure leaves the CLI installed and managed. */
14
+ export declare function installPlaywrightSkills(cwd: string): boolean;
10
15
  export declare function uninstallPlaywrightCli(): boolean;
@@ -1,9 +1,11 @@
1
+ import { spawnSync } from "child_process";
1
2
  import { getNpmInstalledVersion } from "./agents/agent.js";
2
3
  import { npmInstallGlobal, npmUninstallGlobal } from "./agents/wizard.js";
3
4
  /** Palmier-managed browser-automation tool. Managed like an agent CLI (install,
4
5
  * version-stamp, re-probe, PWA update prompt) but never offered for explicit
5
6
  * uninstall — it's only removed by `palmier uninstall`. */
6
7
  export const PLAYWRIGHT_CLI_PACKAGE = "@playwright/cli";
8
+ export const PLAYWRIGHT_CLI_COMMAND = "playwright-cli";
7
9
  export const PLAYWRIGHT_CLI_LABEL = "Playwright CLI";
8
10
  /** Installed global version, or null when not installed. Doubles as the
9
11
  * "is it installed" check (mirrors how agents resolve their version). */
@@ -13,6 +15,18 @@ export function getPlaywrightCliVersion() {
13
15
  export function installPlaywrightCli() {
14
16
  return npmInstallGlobal(PLAYWRIGHT_CLI_PACKAGE);
15
17
  }
18
+ /** Install the Playwright agent skills so agent CLIs know how to drive the
19
+ * browser. Runs in `cwd` (the Palmier task directory) so the skills land where
20
+ * agents execute. Best-effort: a failure leaves the CLI installed and managed. */
21
+ export function installPlaywrightSkills(cwd) {
22
+ console.log(`\nInstalling Playwright skills...\n`);
23
+ const result = spawnSync(`${PLAYWRIGHT_CLI_COMMAND} install --skills`, { cwd, shell: true, stdio: "inherit" });
24
+ if (result.error || result.status !== 0) {
25
+ console.log(`\nCould not install Playwright skills. Run \`${PLAYWRIGHT_CLI_COMMAND} install --skills\` manually.`);
26
+ return false;
27
+ }
28
+ return true;
29
+ }
16
30
  export function uninstallPlaywrightCli() {
17
31
  return npmUninstallGlobal(PLAYWRIGHT_CLI_PACKAGE);
18
32
  }