// panes/mac.js — macOS native app distribution.
import { registerPane } from '../app.js';
import { jget, escapeHtml, formatUptime } from '../lib/api.js';
import { fmtJSON, fmtBytes, copyToClipboard, ok, err } from '../lib/ui.js';
const TPL = `
macOS
Native CxLLM Desktop client distribution.
Install instructions
- Click Download to grab the latest
.app.zip bundle.
- Unzip and drag
CxLLM.app into /Applications.
- First launch may show a Gatekeeper warning. To allow:
xattr -dr com.apple.quarantine /Applications/CxLLM.app
- Or right-click the app and choose Open, then confirm.
System requirements
- macOS 13 Ventura or later
- Apple silicon (arm64) or Intel (x86_64)
- ~120 MB disk · 200 MB RAM at idle
`;
function row(k, v) { return `${escapeHtml(k)}${escapeHtml(v ?? '—')}`; }
async function load(host) {
try {
const r = await jget('/api/mac/info');
host.querySelector('#mac-info').textContent = fmtJSON(r);
const b = r.build || {};
host.querySelector('#mac-build').innerHTML =
row('Name', b.name) +
row('Version', b.version) +
row('Built', b.build_time) +
row('Channel', b.channel || 'stable') +
row('Size', b.size_bytes ? fmtBytes(b.size_bytes) : (b.size || '—')) +
row('Arch', (b.architectures || []).join(', ') || b.arch || '—');
host.querySelector('#mac-sha').textContent = b.sha256 || b.checksum || '—';
const a = host.querySelector('#mac-download');
if (r.download_url) {
a.href = r.download_url;
a.textContent = `Download ${b.name || 'CxLLM'} ${b.version || ''}`.trim();
a.hidden = false;
a.download = (r.download_url.split('/').pop() || 'cxllm.app.zip');
} else {
a.hidden = true;
}
} catch (e) {
host.querySelector('#mac-info').textContent = e.message;
err(e.message);
}
}
registerPane('mac', {
label: 'macOS',
init(host) {
host.innerHTML = TPL;
host.querySelector('#mac-refresh').addEventListener('click', () => load(host));
host.querySelector('#mac-copy-sha').addEventListener('click', () => copyToClipboard(host.querySelector('#mac-sha').textContent.trim(), 'sha copied'));
host.querySelector('#mac-copy-json').addEventListener('click', () => copyToClipboard(host.querySelector('#mac-info').textContent, 'copied'));
load(host);
},
refresh: load,
});