kyneticbyantigravlabs
v1.1.2
Published
Kynetic – cloud-controlled native UI automation agent powered by @nut-tree/nut-js. Exposes a WebSocket server on port 8765 to receive automation tasks (or AI voice/text intents via Puter.js) from the Antigrav Labs cloud frontend.
Readme
kyneticbyantigravlabs
Kynetic — Native UI automation agent by Antigrav Labs
Exposes a WebSocket server on port 8765 that your cloud frontend can drive to control the mouse and desktop of any machine running this agent.
✨ Features
| Capability | Details |
|---|---|
| 🖱️ Mouse Move | Smooth cursor movement to absolute screen coordinates |
| 🖱️ Mouse Click | Left / right / middle click at any (x, y) |
| 🖱️ Double Click | Native double-click |
| 🖱️ Right Click | Context-menu click |
| 🖱️ Scroll | Directional scroll (up / down / left / right) with configurable steps |
| 📐 Screen Size | Query the primary display resolution |
| 🏓 Ping / Pong | Health-check handshake |
| 📡 Real-time | Multi-step ACK → RUNNING → SUCCESS / ERROR responses per task |
| 📝 Log files | Rotating daily log at ~/.kynetic/logs/ |
📦 Installation (Global CLI)
npm install -g kyneticbyantigravlabsPrerequisites: Node.js ≥ 18, and the native dependencies of
@nut-tree/nut-js.
See the nut-js installation guide for platform-specific requirements.
Platform native deps
| OS | Requirements |
|---|---|
| Windows | Visual C++ Redistributable, no extra setup |
| macOS | Accessibility permission for Terminal/Node (System Preferences → Security → Accessibility) |
| Linux | libx11-dev, libxtst-dev, libpng-dev |
🚀 Usage
Start the agent
kyneticYou will see the branded banner and the confirmation:
✔ SUCCESS Kynetic WebSocket server is live on ws://localhost:8765Custom port
KYNETIC_PORT=9000 kyneticDebug logging
KYNETIC_DEBUG=1 kynetic📡 WebSocket Protocol
Connect to ws://localhost:8765 from your cloud frontend.
Inbound message (Cloud → Agent)
{
"taskId": "550e8400-e29b-41d4-a716-446655440000",
"type": "MOUSE_MOVE_AND_CLICK",
"params": {
"x": 960,
"y": 540,
"button": "left",
"speed": 1200
}
}Outbound messages (Agent → Cloud)
The agent sends three sequential messages for each task:
// 1. Acknowledgement (instant)
{ "taskId": "550e...", "status": "ACK", "message": "Task \"MOUSE_MOVE_AND_CLICK\" acknowledged", "timestamp": "..." }
// 2. Execution started
{ "taskId": "550e...", "status": "RUNNING", "message": "Executing \"MOUSE_MOVE_AND_CLICK\"…", "timestamp": "..." }
// 3a. Success
{ "taskId": "550e...", "status": "SUCCESS", "message": "Moved and left-clicked at (960, 540)", "timestamp": "..." }
// 3b. OR Error
{ "taskId": "550e...", "status": "ERROR", "message": "Execution failed: <reason>", "timestamp": "..." }Welcome handshake
On first connection the agent sends:
{ "taskId": "system", "status": "SUCCESS", "message": "Kynetic agent ready. Connection ID: a3f9c1b2", "timestamp": "..." }📋 Task Reference
PING
{ "taskId": "...", "type": "PING", "params": {} }GET_SCREEN_SIZE
{ "taskId": "...", "type": "GET_SCREEN_SIZE", "params": {} }Response data: { "width": 1920, "height": 1080 }
MOUSE_MOVE
{ "taskId": "...", "type": "MOUSE_MOVE", "params": { "x": 400, "y": 300, "speed": 1000 } }| Field | Type | Default | Description |
|---|---|---|---|
| x | number | required | Target X in pixels |
| y | number | required | Target Y in pixels |
| speed | number | 1500 | Movement speed (px/s) |
MOUSE_CLICK
{ "taskId": "...", "type": "MOUSE_CLICK", "params": { "x": 400, "y": 300, "button": "left" } }| Field | Type | Default | Description |
|---|---|---|---|
| x | number | required | Click X |
| y | number | required | Click Y |
| button | "left" | "right" | "middle" | "left" | Mouse button |
| speed | number | 1500 | Movement speed |
MOUSE_MOVE_AND_CLICK
Same params as MOUSE_CLICK. Moves smoothly then clicks.
MOUSE_DOUBLE_CLICK
{ "taskId": "...", "type": "MOUSE_DOUBLE_CLICK", "params": { "x": 600, "y": 400 } }MOUSE_RIGHT_CLICK
{ "taskId": "...", "type": "MOUSE_RIGHT_CLICK", "params": { "x": 600, "y": 400 } }MOUSE_SCROLL
{
"taskId": "...",
"type": "MOUSE_SCROLL",
"params": { "x": 500, "y": 500, "direction": "down", "steps": 5 }
}| Field | Type | Default | Description |
|---|---|---|---|
| x | number | required | Scroll position X |
| y | number | required | Scroll position Y |
| direction | "up" | "down" | "left" | "right" | required | Scroll direction |
| steps | number | 3 | Number of scroll ticks |
🧪 Local Testing
1. Install dependencies
cd kyneticbyantigravlabs
npm install2. Build
npm run build3. Run the agent (terminal 1)
npm run dev
# OR after build:
node dist/cli.js4. Run the smoke-test client (terminal 2)
npx ts-node test/test-client.ts🌐 Global npm Publishing
One-time setup
# 1. Create an npm account at https://www.npmjs.com
# 2. Login
npm login
# 3. (Optional) scope to an org
# Update "name" in package.json to "@your-org/kyneticbyantigravlabs"Publish
# Verify the build and what files will be included
npm run build
npm pack --dry-run
# Publish
npm publish --access publicUpdating a version
# Bump patch / minor / major
npm version patch # 1.0.0 → 1.0.1
npm version minor # 1.0.0 → 1.1.0
npm version major # 1.0.0 → 2.0.0
npm publish --access public🔒 Security Notes
- The WebSocket server binds to
localhostonly by default (thewslibrary with just aportoption creates a local server). - For remote access (cloud → agent over the internet), run Kynetic behind an SSH tunnel or ngrok — do not expose port 8765 directly to the internet without authentication.
- Consider adding a shared-secret header check in
server.tsfor production deployments.
📁 Project Structure
kyneticbyantigravlabs/
├── src/
│ ├── cli.ts # Binary entry-point (kynetic command)
│ ├── server.ts # WebSocket server & message lifecycle
│ ├── automation.ts # @nut-tree/nut-js task executor
│ ├── logger.ts # Timestamped coloured logger + file output
│ ├── types.ts # Full TypeScript protocol types
│ └── index.ts # Programmatic library exports
├── test/
│ └── test-client.ts # Standalone smoke-test WebSocket client
├── dist/ # Compiled JS output (git-ignored)
├── package.json
├── tsconfig.json
└── README.md📄 License
MIT © Antigrav Labs
