Platform
ScaiWave ScaiGrid ScaiCore ScaiBot ScaiDrive ScaiKey Modellen Tools & Services
Oplossingen
Organisaties Ontwikkelaars Internet Service Providers Managed Service Providers AI-in-a-Box
Kenniscentrum
Ondersteuning Documentation Blog Downloads
Bedrijf
Over ons Onderzoek Vacatures Investeren Contact
Inloggen

Install the T1 daemon

The T1 daemon is a headless background process that hooks your OS clipboard. Copy on your laptop → paste on your phone. Copy on your phone → paste on your workstation. All encrypted end-to-end.

Runs anywhere Python runs. Install-and-forget on Linux (systemd user unit) and macOS (LaunchAgent); Windows Task Scheduler works too.

Prerequisites#

  • Python 3.10 or newer with pip.
  • A ScaiGrid API key with scopes scaiclip:read and scaiclip:write.
  • Linux: one of xclip, xsel, or wl-copy (Wayland). The daemon auto-detects.

Install the daemon package (this is currently distributed as the ScaiGrid repo — a standalone PyPI wheel lands in a follow-up):

bash
1
2
3
git clone https://github.com/scailabs/scaigrid.git
cd scaigrid
pip install -e .

Test the daemon runs:

bash
1
2
3
export SCAIGRID_HOST=https://scaigrid.scailabs.ai
export SCAIGRID_API_KEY=sgk_...
python -m modules.scaiclip.tools.t1_daemon --profile $(hostname) &

You should see the daemon connect, subscribe to your personal channel, and start watching the clipboard. Copy something and check the log — [pub] seq=1 len=N recips=1.

Linux — systemd user service#

The daemon ships a hardened systemd unit file:

bash
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
# Copy the unit to your user's systemd dir.
mkdir -p ~/.config/systemd/user/
cp modules/scaiclip/tools/installers/scaiclip-daemon.service \
   ~/.config/systemd/user/

# Put your API key in the environment file.
mkdir -p ~/.config/scaiclip/
cat > ~/.config/scaiclip/env <<'EOF'
SCAIGRID_HOST=https://scaigrid.scailabs.ai
SCAIGRID_API_KEY=sgk_your_key_here
EOF
chmod 600 ~/.config/scaiclip/env

# Enable + start.
systemctl --user daemon-reload
systemctl --user enable --now scaiclip-daemon.service

# Check status.
systemctl --user status scaiclip-daemon.service
journalctl --user -u scaiclip-daemon.service -f

The unit is hardened — restricted paths, no new privileges, memory + CPU caps. Reads its API key from ~/.config/scaiclip/env rather than the unit file so you can rotate keys without touching systemd.

macOS — LaunchAgent#

bash
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# Copy the plist to your LaunchAgents dir.
cp modules/scaiclip/tools/installers/com.scailabs.scaiclip.plist \
   ~/Library/LaunchAgents/

# Edit and set your SCAIGRID_API_KEY in the plist.
open -e ~/Library/LaunchAgents/com.scailabs.scaiclip.plist

# Load + start.
launchctl load ~/Library/LaunchAgents/com.scailabs.scaiclip.plist

# Check logs.
tail -f /tmp/scaiclip-daemon.err.log

Windows — Task Scheduler#

Windows-native support is coming; for now use Task Scheduler:

  1. Open Task Scheduler → Create Task.
  2. General: name ScaiClip Daemon. Check "Run whether user is logged on or not" if you want autostart before login; otherwise leave default.
  3. Triggers: add "At log on".
  4. Actions: Start a program. Program: python. Arguments: -m modules.scaiclip.tools.t1_daemon --profile %COMPUTERNAME%. Start in: your ScaiGrid repo root.
  5. Environment: set SCAIGRID_HOST and SCAIGRID_API_KEY in the user's System Properties → Environment Variables before creating the task.

Log output goes to whatever console the task runs in; redirect to a file in the Arguments field if you want persistence.

Enrolling a second device#

Once the daemon runs on device A, enrol device B by running the daemon there with a distinct --profile name (usually the machine's hostname). First launch calls POST /devices/me to register B's keys with ScaiKey. Both devices' KEM public keys land in the directory; the next clip published on either device gets wrapped for both.

If device B was offline when A first published a clip, that specific clip won't be readable on B — its wrap wasn't included. Future clips will be. The onboarding-broker flow that back-fills clips for late-joining devices is on the roadmap.

Verifying it works#

Copy a distinctive string on device A. Within ~350 ms plus network RTT, the same string should appear in device B's clipboard. Paste it into a text editor to confirm.

If nothing happens:

bash
1
2
3
4
5
# Both devices — check daemon logs.
journalctl --user -u scaiclip-daemon.service -n 50    # Linux
tail -50 /tmp/scaiclip-daemon.err.log                 # macOS

# Look for [pub] on the sender, [recv] on the receiver.

Common causes:

  • no OS clipboard backend detected — install xclip or wl-copy on Linux. macOS/Windows should work out of the box.
  • [warn] directory lookup failed — API key doesn't have scaiclip:read scope, or the ScaiGrid endpoint isn't reachable.
  • [recv] no matching wrap — the publishing device didn't include a wrap for the receiver. Usually means the receiver enrolled after the clip was published; try copying something new.

Uninstall#

Linux:

bash
1
2
3
4
systemctl --user disable --now scaiclip-daemon.service
rm ~/.config/systemd/user/scaiclip-daemon.service
rm -rf ~/.config/scaiclip/
rm -rf ~/.scaiclip/     # device keys — deletes device from local; ScaiKey still lists it as revoked

macOS:

bash
1
2
3
launchctl unload ~/Library/LaunchAgents/com.scailabs.scaiclip.plist
rm ~/Library/LaunchAgents/com.scailabs.scaiclip.plist
rm -rf ~/.scaiclip/

To also delete the device from your ScaiKey account, use DELETE /v1/modules/scaiclip/devices/me/{device_id} — the daemon will refuse to reconnect after that.

Optional tray UI#

The tray UI is a PySide6 GUI companion that embeds the daemon in a background thread. Shows a system-tray icon with:

  • Recent clips (last 20) — click to re-copy.
  • Pause/resume publish toggle.
  • Notifications on inbound clips.
  • About + quit.

Install PySide6 and run the tray instead of the daemon:

bash
1
2
pip install PySide6
python -m modules.scaiclip.tools.t1_tray --profile $(hostname)

Without PySide6 installed, the tray script falls back to the headless daemon with a friendly message.

For persistent autostart with the tray, replace the ExecStart= line in scaiclip-daemon.service with -m modules.scaiclip.tools.t1_tray (Linux) or edit the plist arguments accordingly (macOS).

Image clip support#

The daemon publishes and receives PNG images on Linux via xclip or wl-copy. Copy an image → daemon detects, encrypts, uploads to scratch storage, publishes the envelope with a ref_scratch pointer. Receiver fetches from scratch, decrypts, writes the PNG back to the OS clipboard.

macOS + Windows image read/write is a follow-up (NSPasteboard + DataFormats gymnastics).

Team-channel onboarding#

The daemon fetches team-channel keys on connect (key.wraps.get). If no wrap exists for its device yet, the onboarding broker fires wrap.request to sibling devices. Any sibling running the daemon responds with key.wraps.put, the grid pushes wraps.ready, and the new daemon refetches. Result: fully automatic team-channel onboarding across devices.

What the daemon doesn't do yet#

  • No file clips. Only text and PNG images. File-URI clipboard integration varies wildly across desktop environments and is deferred.
  • No macOS/Windows image support. Text works everywhere; image read/write on those platforms needs native APIs.
  • No T2 native platform integration. Deeper OS notifications, deeper platform hooks — separate track.

What's next#

Updated 2026-07-12 00:26:08 View source (.md) rev 4