feat: run opencode acp with launchd on macos

This commit is contained in:
Haitao Pan 2026-06-18 14:51:06 +08:00
parent 75c4c98613
commit 5e3db5dfd5
4 changed files with 68 additions and 1 deletions

View File

@ -18,7 +18,7 @@ acp_opencode_bridge_service_name: xworkmate-bridge
acp_opencode_bridge_local_source_dir: "{{ playbook_dir }}/../xworkmate-bridge"
acp_opencode_bridge_local_build_dir: "{{ playbook_dir }}/.artifacts/acp_opencode"
acp_opencode_bridge_local_binary_path: "{{ acp_opencode_bridge_local_build_dir }}/xworkmate-go-core"
acp_opencode_bridge_build_goos: linux
acp_opencode_bridge_build_goos: "{{ 'darwin' if ansible_os_family == 'Darwin' else 'linux' }}"
acp_opencode_bridge_build_goarch: "{{ 'arm64' if ansible_architecture in ['aarch64', 'arm64'] else 'amd64' }}"
acp_opencode_bridge_binary_path: /usr/local/bin/xworkmate-go-core
acp_opencode_bridge_use_prebuilt: "{{ lookup('ansible.builtin.env', 'AI_WORKSPACE_USE_PREBUILT_BRIDGE') | default('false', true) | bool }}"

View File

@ -32,6 +32,7 @@
ansible.builtin.command:
cmd: chattr -i "{{ acp_opencode_bridge_binary_path }}"
when:
- ansible_os_family != 'Darwin'
- "'i' in (acp_opencode_bridge_binary_attrs.stdout | default(''))"
changed_when: true
become: true
@ -49,6 +50,7 @@
ansible.builtin.command:
cmd: chattr +i "{{ acp_opencode_bridge_binary_path }}"
when:
- ansible_os_family != 'Darwin'
- "'i' in (acp_opencode_bridge_binary_attrs.stdout | default(''))"
changed_when: true
become: true
@ -89,11 +91,13 @@
register: acp_opencode_service_attrs
changed_when: false
failed_when: false
when: ansible_os_family != 'Darwin'
- name: Remove immutable flag from OpenCode ACP systemd service when present
ansible.builtin.command:
cmd: chattr -i "/etc/systemd/system/{{ acp_opencode_service_name }}.service"
when:
- ansible_os_family != 'Darwin'
- "'i' in (acp_opencode_service_attrs.stdout | default(''))"
changed_when: true
become: true
@ -106,11 +110,13 @@
group: root
mode: "0644"
notify: Restart acp opencode
when: ansible_os_family != 'Darwin'
- name: Restore immutable flag on OpenCode ACP systemd service
ansible.builtin.command:
cmd: chattr +i "/etc/systemd/system/{{ acp_opencode_service_name }}.service"
when:
- ansible_os_family != 'Darwin'
- "'i' in (acp_opencode_service_attrs.stdout | default(''))"
changed_when: true
become: true
@ -118,6 +124,7 @@
- name: Reload systemd manager configuration
ansible.builtin.systemd:
daemon_reload: true
when: ansible_os_family != 'Darwin'
- name: Ensure Caddy is enabled and running
ansible.builtin.systemd:
@ -125,6 +132,7 @@
enabled: true
state: started
when:
- ansible_os_family != 'Darwin'
- acp_opencode_manage_caddy | bool
- name: Ensure OpenCode ACP service is enabled and running
@ -134,3 +142,8 @@
state: started
when:
- not ansible_check_mode
- ansible_os_family != 'Darwin'
- name: Import macOS specific OpenCode ACP tasks
ansible.builtin.import_tasks: macos.yml
when: ansible_os_family == 'Darwin'

View File

@ -0,0 +1,13 @@
---
- name: Create launchd plist template for OpenCode ACP
ansible.builtin.template:
src: opencode.plist.j2
dest: "{{ ansible_env.HOME }}/Library/LaunchAgents/plus.svc.xworkspace.acp.opencode.plist"
mode: "0644"
notify: Restart acp opencode on macOS
- name: Reload launchd agent for OpenCode ACP
ansible.builtin.command: "launchctl load -w {{ ansible_env.HOME }}/Library/LaunchAgents/plus.svc.xworkspace.acp.opencode.plist"
register: launchctl_result
changed_when: false
failed_when: launchctl_result.rc != 0 and 'already loaded' not in launchctl_result.stderr

View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>plus.svc.xworkspace.acp.opencode</string>
<key>ProgramArguments</key>
<array>
<string>/bin/bash</string>
<string>-c</string>
<string>
export PATH="{{ acp_opencode_path }}"
export LITELLM_MASTER_KEY="{{ acp_opencode_auth_token }}"
{% for key, value in acp_opencode_environment.items() %}
export {{ key }}="{{ value }}"
{% endfor %}
exec "{{ acp_opencode_bridge_binary_path }}" acp-server \
--port {{ acp_opencode_listen_port }} \
--host {{ acp_opencode_listen_host }} \
--sub-command opencode \
--sub-command mcp-app-server
</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
<key>WorkingDirectory</key>
<string>{{ acp_opencode_workdir }}</string>
<key>StandardOutPath</key>
<string>{{ ansible_env.HOME }}/.local/state/xworkspace/acp.opencode.log</string>
<key>StandardErrorPath</key>
<string>{{ ansible_env.HOME }}/.local/state/xworkspace/acp.opencode.err.log</string>
<key>EnvironmentVariables</key>
<dict>
<key>HOME</key>
<string>{{ acp_opencode_workdir }}</string>
</dict>
</dict>
</plist>