clipygo Svelte Themes

Clipygo

Clipygo monitors your clipboard and intelligently sends content to your favorite platforms. Detect specific patterns automatically, or trigger manually with a hotkey. Preview before you send, choose your target, and clipboard of you go.

šŸ“‹ clipygo

Clipboard monitor that watches for specific content patterns and lets you route them to configured targets — instantly, with a single keypress.


✨ Features

  • šŸ” Pattern detection — regex-based clipboard monitoring triggers the popup automatically when a match is found (meeting links, JetBrains Code With Me, and more)
  • āŒØļø Global hotkey — summon the popup at any time with a configurable shortcut (default Ctrl+F10)
  • šŸŽÆ Target routing — send clipboard content to any configured target with one click or Enter
  • šŸ”Œ Subprocess plugin system — extend clipygo with any executable that speaks the JSON protocol over stdin/stdout (Node.js, Python, Rust, Go — anything)
  • šŸ’¾ Persistent plugins — plugin processes stay alive, maintaining their own state and connections
  • šŸ“¦ Plugin registry — browse and install published plugins from the registry with SHA256-verified downloads
  • šŸš€ System tray — runs silently in the background, always ready
  • šŸ”„ Autostart — optionally launch on system boot
  • 🪟 Frameless UI — compact, keyboard-driven popup with a cyberpunk aesthetic

šŸ–¼ļø How It Works

flowchart TD
    CB[šŸ“‹ Clipboard] -->|text copied| MON[Clipboard Monitor]
    MON -->|regex match| POPUP[clipygo Popup]
    HK[āŒØļø Global Hotkey] -->|Ctrl+F10| POPUP

    POPUP --> CONTENT[Clipboard Content]
    POPUP --> TARGETS[Target List]

    TARGETS --> PA[šŸŽÆ Target A]
    TARGETS --> PB[šŸŽÆ Target B]
    TARGETS --> PC[šŸŽÆ Target C]

    PA & PB & PC -->|user selects| SEND[Send Request]

    SEND -->|JSON over stdin| PLUGIN[Plugin Process\nnode / python / rust / go]

    PLUGIN -->|JSON over stdout| RESULT[āœ… Success / āŒ Error]

    PLUGIN -->|HTTP| EXT[Teams / Slack / GitHub / ...]

    style POPUP fill:#1a1a2e,color:#00d4ff,stroke:#00d4ff
    style PLUGIN fill:#1a1a2e,color:#ff6b35,stroke:#ff6b35
    style EXT fill:#1a1a2e,color:#00ff88,stroke:#00ff88
  1. clipygo monitors your clipboard in the background
  2. When text matches any configured regex — or you press the hotkey — the popup appears
  3. The popup shows your clipboard content and all available targets from all enabled plugins
  4. Pick a target with mouse or keyboard — content is sent, popup hides

šŸš€ Quick Start

Prerequisites

  • Rust 1.80+
  • Node.js 18+ with npm
  • Tauri CLI: cargo install tauri-cli
  • Windows 10/11 (primary target; macOS and Linux experimental)
  • WebView2 runtime — pre-installed on Windows 11 and most Windows 10 systems; required for the portable build

Build & Run

# Clone the repo
git clone https://github.com/it-atelier-gn/clipygo.git
cd clipygo

# Install frontend dependencies
npm install

# Run in development mode
cargo tauri dev

# Build a release binary
cargo tauri build

āš™ļø Configuration

Settings are persisted to %APPDATA%\clipygo\config.json and managed through the in-app settings window (tray icon → Settings).

Setting Default Description
autostart true Launch clipygo on system boot
global_shortcut Ctrl+F10 Hotkey to show the popup
regex_list see below Patterns that trigger the popup automatically
registry_url registry.json URL of the plugin registry

Default regex patterns

https://code-with-me\.jetbrains\.com/[a-zA-Z0-9\-_]+   # JetBrains Code With Me
https://[a-z0-9\-]+\.zoom\.us/j/[0-9]+                  # Zoom meeting links
https://meet\.google\.com/[a-z]{3}-[a-z]{4}-[a-z]{3}    # Google Meet
https://teams\.microsoft\.com/l/meetup-join/[^\s]+       # Microsoft Teams meetings

Add your own patterns in the settings window under Pattern Recognition.


šŸ”Œ Plugin System

clipygo uses a persistent subprocess model for target providers. A plugin is any executable that reads JSON requests from stdin and writes JSON responses to stdout — one JSON object per line. The process stays alive for the lifetime of the session.

Adding a plugin

Open Settings → Plugins → enter a name and the command to run:

Name:    My Plugin
Command: node C:\plugins\my-plugin\index.js

The command can be any executable or interpreter — compiled binaries, Node.js scripts, Python scripts, etc.

Protocol

Every request is a single line of JSON. Every response is a single line of JSON.

Command Required Description
get_info Yes Plugin name, version, description, author
get_targets Yes List of targets the plugin provides
send Yes Deliver clipboard content to a target
get_config_schema No JSON Schema + current values for the settings UI
set_config No Apply config values saved by the user

get_info — called on startup to verify the plugin

{"command":"get_info"}
{"name":"My Plugin","version":"1.0.0","description":"...","author":"..."}

get_targets — returns all available targets for this plugin

{"command":"get_targets"}
{
  "targets": [
    {
      "id": "unique-target-id",
      "provider": "My Plugin",
      "formats": ["text"],
      "title": "Target Display Name",
      "description": "Short description",
      "image": "<base64 PNG>"
    }
  ]
}

send — send clipboard content to a target

{"command":"send","target_id":"unique-target-id","content":"clipboard text here","format":"text"}
{"success":true}
{"success":false,"error":"Something went wrong"}

get_config_schema (optional) — return a JSON Schema and current values for the settings UI

{"command":"get_config_schema"}
{
  "schema": {
    "type": "object",
    "title": "My Plugin",
    "properties": {
      "api_key": { "type": "string", "title": "API Key", "description": "Your secret API key", "format": "password" },
      "verbose": { "type": "boolean", "title": "Verbose Logging" },
      "mode": { "type": "string", "title": "Mode", "enum": ["fast","slow"], "enumTitles": ["Fast","Slow"], "default": "fast" }
    },
    "required": ["api_key"]
  },
  "values": { "api_key": "", "verbose": false, "mode": "fast" }
}

If this command is implemented, clipygo shows a āš™ Configure button next to the plugin in Settings. Supported field types: string (text input), string with format: "password" (password input), string with enum (select), boolean (toggle).

set_config (optional) — apply configuration values saved by the user

{"command":"set_config","values":{"api_key":"secret","verbose":true,"mode":"fast"}}
{"success":true}

The plugin is responsible for persisting the values (e.g. to its own config file).

Error handling

clipygo auto-restarts a crashed plugin on the next request. After 3 consecutive failures the plugin is marked as errored and paused — remove and re-add it in settings to reset.

Demo plugin

clipygo-plugin-demo is a minimal reference implementation. Pre-built binaries are available on its releases page, or install it directly from the plugin registry in Settings.

Writing a plugin in Node.js

const readline = require('readline');
const rl = readline.createInterface({ input: process.stdin });

rl.on('line', (line) => {
  const req = JSON.parse(line);

  if (req.command === 'get_info') {
    respond({ name: 'My Plugin', version: '1.0.0', description: '...', author: '...' });

  } else if (req.command === 'get_targets') {
    respond({
      targets: [{
        id: 'my-target',
        provider: 'My Plugin',
        formats: ['text'],
        title: 'My Target',
        description: 'Does something useful',
        image: ''
      }]
    });

  } else if (req.command === 'send') {
    // do something with req.target_id, req.content, req.format
    respond({ success: true });
  }
});

function respond(obj) {
  process.stdout.write(JSON.stringify(obj) + '\n');
}

Writing a plugin in Python

import sys, json

for line in sys.stdin:
    req = json.loads(line.strip())

    if req['command'] == 'get_info':
        print(json.dumps({'name': 'My Plugin', 'version': '1.0.0', 'description': '...', 'author': '...'}), flush=True)

    elif req['command'] == 'get_targets':
        print(json.dumps({'targets': [{'id': 'my-target', 'provider': 'My Plugin', 'formats': ['text'], 'title': 'My Target', 'description': '...', 'image': ''}]}), flush=True)

    elif req['command'] == 'send':
        # do something with req['target_id'], req['content'], req['format']
        print(json.dumps({'success': True}), flush=True)

šŸ“¦ Plugin Registry

The built-in registry browser (Settings → Plugin Registry) lets you browse and install plugins with one click. The default registry is hosted at it-atelier-gn/clipygo-plugins.

To publish a plugin to the registry, see the registry README.


šŸ—ļø Architecture

clipygo/
ā”œā”€ā”€ src/                        # SvelteKit frontend
│   ā”œā”€ā”€ routes/
│   │   ā”œā”€ā”€ main/               # Popup window (clipboard content + target list)
│   │   └── settings/           # Settings window
│   └── app.css                 # Global styles
└── src-tauri/                  # Tauri / Rust backend
    └── src/
        ā”œā”€ā”€ lib.rs              # App setup, clipboard monitor, global shortcut
        ā”œā”€ā”€ targets.rs          # TargetProvider trait + coordinator
        ā”œā”€ā”€ settings.rs         # Settings model + persistence
        ā”œā”€ā”€ trayicon.rs         # System tray setup
        └── target_providers/
            └── subprocess.rs   # Persistent subprocess plugin runner

Key design decisions

  • šŸ”„ Persistent subprocess plugins — processes stay alive, maintaining their own connections, tokens, and state; no per-request startup cost
  • šŸ”’ Snapshot pattern — TargetProviderCoordinator::snapshot() extracts providers before any .await, avoiding MutexGuard held across async boundaries
  • šŸ’¾ Settings via tauri-plugin-store — JSON persistence with reactive reload; settings changes trigger live coordinator reload without restart
  • šŸ”‘ OS keychain ready — tmuntaner-keyring is available for providers that need to store secrets (e.g. OAuth tokens)

šŸ¤ Contributing

Contributions are welcome. For substantial changes, open an issue first to discuss the approach.

# Run checks before submitting
cd src-tauri && cargo check && cargo clippy

šŸ“„ License

MIT Ā© 2026 Georg Nelles

Top categories

Loading Svelte Themes