填写功能清单
功能清单(FuncList.json)是你的程序向外界的自我介绍——它告诉工具链和其他开发者:
- 我提供了哪些接口(OpenSocket)
- 我发送哪些信号(Signal)
- 每个接口/信号需要什么参数、返回什么结果
有了这份清单,KnotLink 工具链就能自动生成 API 测试页和 API 文档。
核心理念(30 秒读完)
在填写任何字段之前,先理解三个概念:
① 清单描述两种东西
| 类型 | 方向 | 例子 |
|---|---|---|
openSocket(接口) | 别人调你 | 搜索文件、弹出通知、控制设备 |
signal(信号) | 你广播给所有人 | 备份完成、上课了、温度过高 |
② 功能 ≠ 接口
一个接口可以通过不同参数实现多个功能。比如 control 接口,传 cmd=BACKUP 是备份,传 cmd=RESTORE 是还原——同一个 openSocketID,靠 static 参数区分。写清单时可以为每个功能单独建条目。
③ 三种参数类型
| 类型 | 直觉理解 | 调用方看到什么 |
|---|---|---|
input | 用户自己填 | 输入框 |
optional | 从几个选项里选 | 下拉菜单 |
static | 固定值,用户看不到 | 灰显(不可改) |
👉 看真实项目的清单体会一下:Everything 搜索节点 | 消息提醒
一、使用 FLEditor(推荐)
FLEditor 是 KnotLink 官方功能清单编辑器——不需要手写一行 JSON,在可视化表单中填写即可。编辑 → 测试 → 导出,一站式完成。
安装与启动
pip install PyQt5 PyQtWebEngine
cd FLEditor
python fleditor.py
启动后自动加载示例数据,可直接上手体验。
三步完成清单
① 编辑——三个标签页中的"功能编辑":
- 左栏:树形结构管理应用、OpenSocket、Signal
- 中栏:动态表单填写字段,三种参数类型(input/optional/static)自动切换对应输入控件
- 右栏:JSON 实时预览
② 测试——切到"测试调用"标签页,选择功能直接发起 TCP 调用,验证接口是否可达。守护进程离线时自动回退模拟数据。
③ 导出——切到"导出文档"标签页,一键生成 HTML/PDF API 文档,直接交付给接入方。
核心优势
- 零手写:表单输入替代 JSON 编辑,自动校验必填字段
- 类型安全:三种参数类型通过下拉切换,避免类型与字段不匹配
- 即时反馈:编辑完直接测试,不需要离开编辑器
- 所见即所得:右侧 JSON 预览实时同步
FLEditor 输出的
FuncList.json符合规范,可直接用于后续的 API 测试页和文档生成。完整使用说明见 FLEditor 用户手册。
二、手动编写 JSON(参考)
如果你想理解底层格式或手动编写,展开查看
文件位置
FuncList.json 放在项目的根目录下,与主程序入口文件同级:
MsgNotification/
├── FuncList.json ← 放这里
├── plugin_manifest.json ← 自述清单
├── main.py
└── src/
└── ...
从代码到清单
回忆我们在 编写代码 中实现的消息提醒功能:
# 开放了一个接口
responser = OpenSocketResponser(
APPID="com.example.msgreminder",
OpenSocketID="show"
)
# 发送了一个信号
sender = SignalSender(
APPID="com.example.msgreminder",
SignalID="messageReceived"
)
现在,把这几行代码翻译成 funclist.json。
基本结构
{
"specVersion": "1.0",
"manifestVersion": "1.0.0",
"appName": "消息提醒",
"openSocket": {
"show": {
"appID": "com.example.msgreminder",
"openSocketID": "show",
"description": "弹出消息窗口",
"args": {
"msgContext": {
"type": "input",
"description": "消息内容",
"defaultVal": "测试消息"
}
},
"returns": [
["状态", "status"]
]
}
},
"signal": {}
}
顶层字段:
| 字段 | 必填 | 含义 |
|---|---|---|
specVersion | 是 | 遵循的规范版本(如 "1.0") |
manifestVersion | 是 | 本清单自身的版本号(如 "1.0.0") |
appName | 否 | 应用名称 |
早期项目 appID 和 openSocketID / signalID 使用 0x 开头的 8 位十六进制数字(如 "0x00000014"),这是合法且继续支持的格式。本文档以新格式(倒置域名 + 描述性名称)示范,两种格式的填写方式完全一致。
openSocket 功能条目:
| 字段 | 含义 |
|---|---|
"show" | 功能名称(自定义,建议与 openSocketID 一致) |
appID | 应用标识符(倒置域名格式),与代码中 APPID 一致 |
openSocketID | 接口标识符(描述性名称),与代码中 OpenSocketID 一致 |
description | 功能描述 |
args | 参数定义 |
returns | 返回值字段列表,数组格式:[["中文说明", "字段名"], ...] |
三种参数类型
| type | 含义 | 何时使用 |
|---|---|---|
input | 运行时由调用方输入 | 参数值每次都不同 |
static | 固定值,调用方不可修改 | 参数已确定,无需调用方提供 |
optional | 调用方从预设选项中选一个 | 参数只能取几个合法值 |
"args": {
"msgContext": {
"type": "input",
"description": "消息内容",
"defaultVal": "Hello"
},
"action": {
"type": "static",
"value": "show",
"description": "固定操作类型"
},
"mode": {
"type": "optional",
"options": [["快", "fast"], ["正常", "normal"], ["安全", "safe"]],
"description": "执行模式"
}
}
调用方在 API 测试页中看到的效果:
msgContext:输入框,可自由填写,默认"Hello"action:灰显,不可修改,固定"show"mode:下拉选择框,可选 快/正常/安全
多个功能共用 openSocketID
多个功能条目可以共用同一个 appID 和 openSocketID——通过 static 参数区分操作:
"openSocket": {
"backup": {
"appID": "com.example.msgreminder",
"openSocketID": "control",
"description": "触发备份",
"args": {
"cmd": { "type": "static", "value": "BACKUP", "description": "操作指令" },
"folder": { "type": "input", "description": "文件夹名" }
},
"returns": [["状态", "status"]]
},
"restore": {
"appID": "com.example.msgreminder",
"openSocketID": "control",
"description": "触发还原",
"args": {
"cmd": { "type": "static", "value": "RESTORE", "description": "操作指令" },
"folder": { "type": "input", "description": "文件夹名" }
},
"returns": [["状态", "status"]]
}
}
描述信号(signal)
信号通常无需 args。注意 signal 的 returns 是对象格式,与 openSocket 的数组格式不同:
"signal": {
"messageReceived": {
"appID": "com.example.msgreminder",
"signalID": "messageReceived",
"description": "有新消息到达时广播",
"returns": {
"content": { "description": "消息内容" },
"timestamp": { "description": "消息到达时间" }
}
}
}
可选 verification 字段用于信号鉴别——该参数必须等于此值才被识别为此信号:
"returns": {
"exitCode": {
"description": "进程退出码",
"verification": "0"
}
}
上例中,只有
exitCode为"0"时才被认定为该信号,其他值不会被路由到此处理器。
| 格式对比 | openSocket | signal |
|---|---|---|
returns 类型 | 数组 [["说明", "字段名"], ...] | 对象 {"字段名": {"description": "说明"}} |
| 鉴别字段 | 无 | verification(参数必须等于此值) |
完整示例
{
"specVersion": "1.0",
"manifestVersion": "1.0.0",
"appName": "消息提醒",
"openSocket": {
"show": {
"appID": "com.example.msgreminder",
"openSocketID": "show",
"description": "弹出消息窗口",
"args": {
"msgContext": { "type": "input", "description": "消息内容", "defaultVal": "I am A Msg" }
},
"returns": [["状态", "status"]]
}
},
"signal": {
"messageReceived": {
"appID": "com.example.msgreminder",
"signalID": "messageReceived",
"description": "有新消息到达时广播",
"returns": {
"content": { "description": "消息内容" },
"timestamp": { "description": "消息到达时间" }
}
}
}
}
验证
保存后用命令行快速检查 JSON 格式:
python -m json.tool FuncList.json
启动守护进程后打开操作面板,切换到 调试 API 选项卡,确认你的功能出现在列表中并能正常调用。
检查清单
-
specVersion和manifestVersion已填写 -
appID采用倒置域名格式(如com.example.myapp) -
openSocketID和signalID与代码中一致 - 每个
input参数设置了合理的defaultVal - 每个
optional参数提供了options数组 - 每个
static参数指定了value - openSocket 的
returns用数组格式,signal 的returns用对象格式 - signal 的
verification是信号鉴别值,不是取值范围 - JSON 格式合法,文件放在项目根目录
完整字段规范参见 功能清单规范。
下一步
功能清单填好了,最后一个步骤:打包与分发。