Skip to content

示例插件

Hello World

最简单的插件示例:

javascript
/* hello - TSH Hello World Plugin */
var name = args.slice(1).join(' ').trim() || 'World'
return '\x1b[32mHello, ' + name + '!\x1b[0m\r\n'

安装和使用:

bash
plugin install /path/to/hello.js
hello
# 输出: Hello, World!

hello TSH
# 输出: Hello, TSH!

calx — 计算器插件

calx 是 TSH 内置的计算器插件,支持数学表达式计算。

用法

bash
calx 2+3*4           # 输出: 14
calx sqrt(144)        # 输出: 12
calx sin(PI/2)        # 输出: 1
calx "1 + 2 * 3"     # 输出: 7
calx 2**10            # 输出: 1024
calx 10 % 3           # 输出: 1

支持的运算符

运算符说明
+ -加减
* /乘除
%取模
**^幂运算
()括号优先级

支持的函数

函数说明
sin cos tan三角函数
asin acos atan反三角函数
sqrt平方根
abs绝对值
log常用对数 (log10)
ln自然对数
ceil floor round取整
min max最值
pow exp幂/指数
cbrt sign trunc立方根/符号/截断

常量

常量
PI3.141592653589793
E2.718281828459045

错误处理

bash
calx
# 输出: calx: no expression provided (红色)

calx 1/0
# 输出: calx: division by zero (红色)

calx 2+
# 输出: calx: unexpected end of expression (红色)

核心实现

calx 使用手写的递归下降解析器:

  1. 词法分析 — 将表达式拆分为数字、运算符、标识符 Token
  2. 递归下降解析 — 按优先级解析:表达式 → 项 → 幂 → 一元 → 基元
  3. 求值 — 解析同时计算结果
parseExpr   → parseTerm (+|-) parseTerm
parseTerm   → parsePower (*|/|%) parsePower
parsePower  → parseUnary (** ) parsePower
parseUnary  → (-|+) parseUnary | parsePrimary
parsePrimary → number | function(args) | (expr) | constant

ck — 设备检测插件

ck 检测访问网页的设备信息、IP 地址和浏览器指纹。

用法

bash
ck              # 显示所有信息
ck device       # 仅设备信息
ck screen       # 仅屏幕信息
ck browser      # 仅浏览器信息
ck ip           # 仅 IP/网络信息
ck fp           # 仅浏览器指纹

检测项目

分类项目
Device设备类型、OS、平台、CPU 核心数、内存、触控
Screen分辨率、可用区域、色深、像素比
Browser浏览器版本、语言、Cookies、DNT、在线状态、时区、连接类型
Network公网 IP、地理位置、ISP
FingerprintCanvas 哈希、WebGL 厂商/渲染器、设备综合指纹

输出示例

  ▸ Device
  Type:         Desktop
  OS:           Windows 10/11
  CPU Cores:    8
  Memory:       8 GB

  ▸ Network
  IP Address:   203.0.113.42
  Location:     Shanghai, Shanghai, China  |  ISP: China Telecom

  ▸ Fingerprint
  Canvas Hash:  A1B2C3D4
  Device FP:    E5F6A7B8

技术要点

  • IP 检测 — 客户端 fetch ipwho.is(返回 IP+地理+ISP),失败回退 api.ipify.org
  • Canvas 指纹 — 绘制特定图形后用 DJB2 哈希生成 8 位标识
  • WebGL 指纹 — 通过 WEBGL_debug_renderer_info 获取 GPU 厂商和渲染器
  • 异步支持 — 返回 async IIFE 的 Promise

管道插件示例

利用 stdin 处理管道输入:

javascript
/* wc - 统计行数/单词数 */
var text = stdin || ''
if (!text) return '0 0\r\n'

var lines = text.split('\n').length
var words = text.trim().split(/\s+/).filter(function(w) { return w }).length
return lines + ' ' + words + '\r\n'

使用:

bash
echo "hello world foo" | wc
# 输出: 1 3

异步插件示例

调用外部 API 获取数据:

javascript
/* weather - 天气查询 */
var city = args.slice(1).join(' ').trim()
if (!city) return '\x1b[31mweather: please specify a city\x1b[0m\r\n'

return (async function() {
  try {
    var resp = await fetch('https://wttr.in/' + encodeURIComponent(city) + '?format=3')
    var text = await resp.text()
    return '\x1b[36m' + text.trim() + '\x1b[0m\r\n'
  } catch(e) {
    return '\x1b[31mweather: ' + e.message + '\x1b[0m\r\n'
  }
})()

文件操作插件示例

通过 host 读取文件:

javascript
/* head - 显示文件前几行 */
var file = args[1]
if (!file) return '\x1b[31mhead: missing filename\x1b[0m\r\n'
var n = parseInt(args[2]) || 10

return (async function() {
  try {
    var content = await host.readFile(file)
    var lines = content.split('\n').slice(0, n)
    return lines.join('\r\n') + '\r\n'
  } catch(e) {
    return '\x1b[31mhead: ' + e.message + '\x1b[0m\r\n'
  }
})()

发布插件

将插件 JS 文件上传到任意可访问的 URL,然后安装:

bash
# GitHub
plugin install https://github.com/user/repo/raw/main/myplugin.js

# Codeberg
plugin install https://codeberg.org/user/repo/raw/branch/main/myplugin.js

# Gist
plugin install gist:user/gist_id

# 本地路径(需 TSH 内置)
plugin install /plugins/myplugin.js

CORS 说明

外部 URL 的插件通过 TSH Worker 的 /proxy 端点代理加载,无需目标服务器支持 CORS。任意 HTTPS URL 均可使用。

基于 MIT 许可证发布