Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,15 @@ as a plugin because it does not discover the shared skill collection recursively
Upstream skills are installed through `home/.chezmoiexternal.toml`. Keep personal
rules in the Agents repository so upstream packages stay unmodified.

## Browser Tools

[agent-browser](https://agent-browser.dev) uses the Browserless container started
by `mise run services:browserless` when needed. Mise installs the CLI; chezmoi
configures its skill and native endpoint setting.
Both platforms use the same Compose definition. On Linux it runs under the user’s
Podman runtime; start it explicitly when needed. Apply its configuration with
chezmoi first; the start task does not apply preferences or enable boot startup.

## Shared Tools & Tasks

`home/dot_config/mise/conf.d/tools.toml` declares shared tools;
Expand Down
5 changes: 5 additions & 0 deletions home/.chezmoidata.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ url = "https://bifrost.excloo.com/mcp/reactive-resume"
[mcp.unifi_network]
url = "https://bifrost.excloo.com/mcp/unifi-network"

[services.browserless]
port = 9222
# renovate: datasource=docker depName=ghcr.io/browserless/chromium
version = "v2.62.0"

[services.connect]
# renovate: datasource=docker depName=1password/connect-api
version = "1.8.4"
10 changes: 10 additions & 0 deletions home/.chezmoiexternal.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
[".agents/skills/agent-browser/LICENSE"]
type = "file"
# renovate: datasource=github-releases depName=vercel-labs/agent-browser
url = "https://raw.githubusercontent.com/vercel-labs/agent-browser/v0.42.0/LICENSE"

[".agents/skills/agent-browser/SKILL.md"]
type = "file"
# renovate: datasource=github-releases depName=vercel-labs/agent-browser
url = "https://raw.githubusercontent.com/vercel-labs/agent-browser/v0.42.0/skills/agent-browser/SKILL.md"

[".agents/skills/humanizer"]
type = "archive"
exact = true
Expand Down
3 changes: 3 additions & 0 deletions home/dot_agent-browser/private_config.json.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"cdp": "ws://127.0.0.1:{{ .services.browserless.port }}/chromium"
}
1 change: 1 addition & 0 deletions home/dot_claude/skills/symlink_agent-browser.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{{ joinPath .chezmoi.homeDir ".agents" "skills" "agent-browser" }}
1 change: 1 addition & 0 deletions home/dot_config/mise/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ claude-code = "latest"
codex = "latest"
k9s = "latest"
"npm:@deepseek-ai/dsh" = "latest"
"npm:agent-browser" = "latest"
opencode = "latest"
pi = "latest"
rclone = "latest"
Expand Down
10 changes: 10 additions & 0 deletions home/dot_config/mise/tasks/services.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
["services:browserless"]
description = "Start Browserless"
run = '''
{% if os() == "macos" %}
docker compose --file "$HOME/.config/services/browserless/compose.yaml" up --detach
{% else %}
podman-compose --file "$HOME/.config/services/browserless/compose.yaml" up --detach
{% endif %}
'''

["services:connect"]
description = "Start 1Password Connect"
run = '''
Expand Down
12 changes: 12 additions & 0 deletions home/dot_config/services/browserless/compose.yaml.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
name: browserless
services:
browserless:
image: ghcr.io/browserless/chromium:{{ .services.browserless.version }}
restart: unless-stopped
shm_size: 1gb
environment:
CONCURRENT: 4
QUEUED: 4
TIMEOUT: 3600000
ports:
- "127.0.0.1:{{ .services.browserless.port }}:3000"
22 changes: 20 additions & 2 deletions tests/services.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ const root = fileURLToPath(new URL("..", import.meta.url));
const base = ["--source", root, "--config", "/dev/null", "--config-format", "toml"];
const execute = (args, input = "") =>
execFileSync("chezmoi", [...base, ...args], { input, encoding: "utf8" });
const render = (path, platform = "darwin") =>
const render = (path, platform = "darwin", services) =>
execute([
"--override-data",
JSON.stringify({ chezmoi: { os: platform } }),
JSON.stringify({ chezmoi: { os: platform }, ...(services ? { services } : {}) }),
"execute-template",
"--file",
`home/${path}`,
Expand Down Expand Up @@ -94,3 +94,21 @@ test("Linux Compose reuses Connect’s rootful external volume and secret", () =
]);
}
});

test("Browserless uses the same configured port across both runtimes and the client", () => {
const services = JSON.parse(execute(["execute-template", "{{ .services | toJson }}"]));
services.browserless.port = 19333;
const compose = yaml(
render("dot_config/services/browserless/compose.yaml.tmpl", "darwin", services),
);
assert.equal(compose.name, "browserless");
assert.deepEqual(compose.services.browserless.ports, ["127.0.0.1:19333:3000"]);
const linux = yaml(
render("dot_config/services/browserless/compose.yaml.tmpl", "linux", services),
);
assert.deepEqual(linux, compose);
const client = JSON.parse(
render("dot_agent-browser/private_config.json.tmpl", "darwin", services),
);
assert.equal(client.cdp, "ws://127.0.0.1:19333/chromium");
});
Loading