npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@ctyun/desktop-agent-sdk

v0.0.18

Published

the agent web sdk to interactive with your computer

Downloads

143

Readme

Desktop Agent SDK

用于操作天翼云电脑的一套SDK,支持鼠标控制、键盘输入、屏幕截图等操作。

项目简介

@ctyun/desktop-agent-sdk 是天翼云电脑远程操作 SDK,第三方开发者可以通过该 SDK 以编程方式控制远程桌面。支持以下功能:

  • 鼠标移动、点击、拖拽和滚动
  • 键盘按键和文本输入
  • 屏幕截图
  • 获取鼠标位置

环境设置

系统要求

  • TypeScript/JavaScript
    Node.js 14及以上版本
    建议安装在维护期内的LTS版本
  • Window版本要求
    Windows 8.1 或 Windows Server 2012 R2 及以上
  • Linux版本要求
    kernel>=3.10

安装方法

npm 安装

npm install @ctyun/desktop-agent-sdk

yarn 安装

yarn add @ctyun/desktop-agent-sdk

pnpm 安装

pnpm add @ctyun/desktop-agent-sdk

基本使用方法

1、 创建 Client 实例

首先导入并创建 Client 实例。创建实例时需要提供以下参数:

  • apiKey (必需): 控制台上的AccessKey ID
  • apiSecret (必需): 控制台上的AccessKey Secret
  • desktopCode (必需): 桌面编码
  • serviceURL (可选): 服务地址,默认为 https://desk.ctyun.cn:8816
import Client from '@ctyun/desktop-agent-sdk';

const client = new Client({
  apiKey: 'your-api-key',
  apiSecret: 'your-api-secret',
  desktopCode: 'your-desktop-code',
  serviceURL: 'https://desk.ctyun.cn:8816' // 可选,使用默认值
});

2、 创建会话

使用 createSession() 方法创建会话,会话创建成功后将返回会话对象,包含 sessionId 和操作方法。

const session = await client.createSession();
console.log('会话创建成功,sessionId:', session.sessionId);

3、 使用 computer 方法

创建会话后,可以通过 session.computer 对象调用各种计算机控制方法。

移动鼠标

// 将鼠标移动到指定坐标
await session.computer.move_mouse({x:500, y:300});

点击鼠标

// 在指定坐标点击鼠标(默认左键、按下并释放)
await session.computer.click_mouse({x:500, y:300});

// 点击一下左键
await session.computer.click_mouse({x:500, y:300, clickMode:'left'});

// 点击一下右键
await session.computer.click_mouse({x:500, y:300, clickMode:'right'});

// 双击一下鼠标
await session.computer.click_mouse({x:500, y:300, clickMode:'double_left'});

// 仅按下鼠标左键(不释放)
await session.computer.click_mouse({x:500, y:300, clickMode:'left', pressMode:true, releaseMode:false});

// 仅释放鼠标
await session.computer.click_mouse({x:500, y:300, clickMode:'left', pressMode:false, releaseMode:true});

拖拽鼠标

// 从起始坐标拖拽到目标坐标
await session.computer.drag_mouse({startX:500, startY:300, endX:800, endY:500});

滚动

// 在指定位置滚动(Direction: 'up' 或 'down')
await session.computer.scroll({startX:500, startY:300, direction:'down', amount:3});

按下键盘按键

// 按下键盘按键(如 Enter)
await session.computer.press_key({key:'Enter'});

输入文本

// 输入文本
await session.computer.type_text({text:'Hello World'});

屏幕截图

// 截取屏幕
await session.computer.screen_shot();

获取鼠标位置

// 获取当前鼠标位置
await session.computer.get_cursor_position();

4、 关闭会话

使用完成后,应该关闭会话以释放资源。

await session.close();
console.log('会话已关闭');

完整示例

import Client from '@ctyun/desktop-agent-sdk';

async function main() {
  // 创建 Client 实例
  const client = new Client({
    apiKey: 'your-api-key',
    apiSecret: 'your-api-secret',
    desktopCode: 'your-desktop-code'
  });

  let session=null;
  try {
    // 创建会话
    session = await client.createSession();
    console.log('会话创建成功:', session.sessionId);

    // 移动鼠标并点击
    await session.computer.move_mouse({x:500, y:300});
    await session.computer.click_mouse({x:500, y:300});

    // 输入文本
    await session.computer.type_text({text:'Hello from Desktop Agent SDK!'});

    // 截图
    await session.computer.screen_shot();
  } catch (error) {
    console.error('操作失败:', error);
  } finally {
    // 关闭会话
    await session.close();
  }
}

main();

API 参考

Client 类

构造函数

new Client(options: ClientOptions): Client

ClientOptions 参数说明:

| 参数名 | 类型 | 必需 | 说明 | |--------|------|------|------| | apiKey | string | 是 | 控制台上的AccessKey ID 打开控制台 | | apiSecret | string | 是 | 控制台上的AccessKey Secret | | desktopCode | string | 是 | 桌面编码,控制台可查看 | | serviceURL | string | 否 | 服务地址,默认 https://desk.ctyun.cn:8816 |

方法

createSession()

创建会话并返回会话对象。

async createSession(): Promise<Session>

返回值:

| 属性名 | 类型 | 说明 | |--------|------|------| | sessionId | string | 会话唯一标识 | | computer | ComputerAPI | 计算机控制方法集合 | | close | Function | 关闭会话方法 |

Session 对象

  • computer 对象

返回值说明

对computer类下面的所有方法的调用都是异步调用,返回值遵循相同的返回格式:

{
   "code": 0,
   "data":null,
   "msg":null
}

| 参数名 | 类型 | 说明 | |--------|------|------| | code | number | 状态码,为0代表成功,其他表示失败 | | data | number | 结果,code为0时不为空 | | msg | number | code不为0时记录错误信息 |

move_mouse({x, y})

移动鼠标到指定坐标。

| 参数名 | 类型 | 说明 | |--------|------|------| | x | number | 目标 X 坐标 | | y | number | 目标 Y 坐标 |

click_mouse({x, y, clickMode?, pressMode?,releaseMode?})

在指定位置点击鼠标。

| 参数名 | 类型 | 必需 | 说明 | |--------|------|------|------| | x | number | 是 | X 坐标 | | y | number | 是 | Y 坐标 | | clickMode | string | 否 | 点击模式:'left'(默认)、'right''middle'double_left | | pressMode | Boolean | 否 | 鼠标按下状态:true保持按下,false(默认)不按下 | | releaseMode | Boolean | 否 | 鼠标松开状态:true松开鼠标,false(默认)不松开 |

提示

  • pressMode=true&releaseMode=true:鼠标点下又松开
  • pressMode=false&releaseMode=false:鼠标点下又松开
  • pressMode=true&releaseMode=false`:鼠标点下不松开
  • pressMode=false&releaseMode=true:鼠标松开
drag_mouse({startX, startY, endX, endY})

拖拽鼠标。

| 参数名 | 类型 | 说明 | |--------|------|------| | startX | number | 起始 X 坐标 | | startY | number | 起始 Y 坐标 | | endX | number | 目标 X 坐标 | | endY | number | 目标 Y 坐标 |

scroll({startX, startY, direction, amount})

滚动页面。

| 参数名 | 类型 | 说明 | |--------|------|------| | startX | number | 滚动位置 X 坐标 | | startY | number | 滚动位置 Y 坐标 | | direction | string | 滚动方向:'up''down' | | amount | number | 滚动量,单位:px |

press_key({key})

按下键盘按键。

| 参数名 | 类型 | 说明 | |--------|------|------| | key | string | 按键名称,如 'Enter''Escape' 等 |

type_text({text})

输入文本。

| 参数名 | 类型 | 说明 | |--------|------|------| | text | string | 要输入的文本内容 |

screen_shot()

截取屏幕。

get_cursor_position()

获取当前鼠标位置。

  • close()

关闭当前会话。

返回值: 关闭结果

FAQ

常见错误码

| 错误码 | 说明 | |--------|------| | 52060 | 指定桌面不属于当前用户 | | 92006 | 桌面不在线 | | 92100 | 通过 sessionId 找不到 session | | 92101 | 消息发送失败 | | 92102 | 消息长度不能超过 2000 字符 | | 92103 | 找不到消息记录 | | 92104 | 功能未开放,请联系管理员 | | 92105 | 功能未开放,请联系管理员 |

Filesystem API

The SDK also exposes a separate session.filesystem module so callers do not need to mix file actions into computer.

const session = await client.createSession();

await session.filesystem.create_directory({ path: 'D:/tmp/demo' });
await session.filesystem.write_file({ path: 'D:/tmp/demo/a.txt', content: 'hello world' });
const readResult = await session.filesystem.read_file({ path: 'D:/tmp/demo/a.txt' });
console.log(readResult.data.content);

const downloadResult = await session.filesystem.download_file({
  source: 'C:/ai-user-test/xigua2.zip',
  destination: 'D:/xigua3.zip'
});
console.log(downloadResult.data.localPath);

Available methods:

  • create_directory({ path })
  • read_file({ path, offset?, length? })
  • download_file({ source, destination })
  • move_file({ source, destination })
  • write_file({ path, content, mode? })
  • upload_file({ localPath, destination, mode? })
  • search_files({ path, pattern, matchMode? })

file_url handling

read_file and write_file hide the internal file_url transport from SDK callers:

  • When write_file content would exceed the 1500 character contract, the SDK uploads the text to the file server automatically and sends a file_url request to the backend.
  • When read_file comes back as transport=file_url, the SDK downloads the text automatically and returns inline content to the caller.
  • upload_file uploads a local binary file and writes it to the target desktop.
  • download_file calls the target desktop to upload a remote binary file, downloads the returned fileUrl, verifies size and sha256 when present, and writes it to destination.

Callers only pass content for write_file, and callers only consume content for read_file.

Optional fileServer config

If you need to override the default file service, pass fileServer when creating the client:

const client = new Client({
  apiKey: 'your-api-key',
  apiSecret: 'your-api-secret',
  desktopCode: 'your-desktop-code',
  fileServer: {
    baseURL: 'https://filesvryilian.ctyun.cn',
    uploadPath: '/fileserver/file/upload',
    type: 'aiusetool',
    tenantCode: 'aiusetool',
    tenantSecret: 'your-tenant-secret'
  }
});