@quicktvui/ai 1.1.16 → 1.1.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +44 -0
- package/package.json +1 -1
- package/rules/.claude/commands/create-component.md +1 -1
- package/rules/.claude/commands/create-page.md +1 -1
- package/rules/.claude/commands/create-project.md +1 -1
- package/rules/.claude/commands/lookup-api.md +1 -1
- package/rules/.claude/commands/lookup-css.md +1 -1
- package/rules/.clinerules +121 -0
- package/rules/.cursorrules +121 -0
- package/rules/.docs/zh-CN/tool/api/overview.md +4 -0
- package/rules/.docs/zh-CN/tool/api/plugin-scaffold-mcp.md +46 -0
- package/rules/.docs/zh-CN/tool/api/plugin-server-api.md +198 -0
- package/rules/.docs/zh-CN/tool/cli/introduction.md +7 -0
- package/rules/.docs/zh-CN/tool/cli/plugin-create-component.md +101 -0
- package/rules/.docs/zh-CN/tool/cli/plugin-create-module.md +88 -0
- package/rules/.docs/zh-CN/tool/cli/plugin-create-project.md +106 -0
- package/rules/.docs/zh-CN/tool/cli/plugin-server.md +152 -0
- package/rules/.github/copilot-instructions.md +122 -1
- package/rules/.windsurfrules +121 -0
- package/rules/AGENTS.md +122 -1
- package/rules/AI_HANDOFF.md +107 -1
- package/rules/CLAUDE.md +123 -1
- package/rules/GEMINI.md +123 -1
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Plugin Create Component
|
|
3
|
+
lang: zh-CN
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# 插件组件创建
|
|
7
|
+
|
|
8
|
+
## 一、适用范围
|
|
9
|
+
|
|
10
|
+
组件用于有原生 UI 的能力,例如二维码、卡片、轮播、支付入口、图片容器等。
|
|
11
|
+
|
|
12
|
+
如果只是无界面能力,请改用 `plugin-create-module`。
|
|
13
|
+
|
|
14
|
+
## 二、源码真值
|
|
15
|
+
|
|
16
|
+
生成组件前,必须优先对照:
|
|
17
|
+
|
|
18
|
+
1. `node_modules/@quicktvui/ai/rules/.source/sdk/base/sdk-base/src/main/java/com/quicktvui/sdk/base/component/IEsComponent.java`
|
|
19
|
+
2. `node_modules/@quicktvui/ai/rules/.source/sdk/base/sdk-base/src/main/java/com/quicktvui/sdk/base/component/IEsComponentView.java`
|
|
20
|
+
3. `node_modules/@quicktvui/ai/rules/.source/sdk/base/sdk-base/src/main/java/com/quicktvui/sdk/base/component/EsComponentAttribute.java`
|
|
21
|
+
|
|
22
|
+
真实接口:
|
|
23
|
+
|
|
24
|
+
```java
|
|
25
|
+
com.quicktvui.sdk.base.component.IEsComponent
|
|
26
|
+
com.quicktvui.sdk.base.component.IEsComponentView
|
|
27
|
+
com.quicktvui.sdk.base.component.EsComponentAttribute
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## 三、CLI 命令
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
quicktvui-ai plugin-create-component \
|
|
34
|
+
--project plugin/demo-plugin \
|
|
35
|
+
--description "展示二维码" \
|
|
36
|
+
--props '[{"name":"content","type":"String","description":"二维码内容"}]' \
|
|
37
|
+
--events onRendered \
|
|
38
|
+
--functions refresh
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## 四、MCP 工具
|
|
42
|
+
|
|
43
|
+
```text
|
|
44
|
+
plugin_component_create
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## 五、生成规则
|
|
48
|
+
|
|
49
|
+
1. `--description` 必填
|
|
50
|
+
2. 组件类名追加 `Component`
|
|
51
|
+
3. View 类名追加 `View`
|
|
52
|
+
4. Java 包名必须合法,不能把 `kebab-case` 直接写入包路径
|
|
53
|
+
5. Vue 标签必须使用 `kebab-case`
|
|
54
|
+
6. `--project` 默认应指向项目根目录下可见的 `plugin/<plugin-name>`,不要默认指向隐藏目录
|
|
55
|
+
7. 默认生成 `docs/component/<name>.md`
|
|
56
|
+
8. 默认不强依赖 `@ESKitAutoRegister`
|
|
57
|
+
9. 默认尝试在 `Application#onCreate` 中注册 `EsProxy.get().registerComponent("com.xxx.Component")`
|
|
58
|
+
10. 编译期接口由插件工程内的 `quicktvui-plugin-stubs` 模块提供;运行时依赖仍以模板工程里的 `com.extscreen.runtime:eskit:2.6.0` 为准
|
|
59
|
+
|
|
60
|
+
## 六、Vue 侧安装约束
|
|
61
|
+
|
|
62
|
+
组件插件生成完成、打包完成或上传成功,并不代表 Vue 页面已经可以直接渲染该组件。
|
|
63
|
+
|
|
64
|
+
如果页面里要真正使用组件型插件,还必须:
|
|
65
|
+
|
|
66
|
+
1. 使用 `@extscreen/es3-core` 的 `useESPlugin()`
|
|
67
|
+
2. 在 `onESCreate` 中 `addListener(pluginInfo, listener)`
|
|
68
|
+
3. 在 `onESDestroy` 中 `removeListener(listener)`
|
|
69
|
+
4. 在组件未注册时调用 `installPlugin({ pkg })`
|
|
70
|
+
5. 优先使用 `useES().isComponentRegistered("<组件完整类名>")` 检查注册状态,再决定是否渲染组件
|
|
71
|
+
|
|
72
|
+
推荐参考:
|
|
73
|
+
|
|
74
|
+
1. `node_modules/@quicktvui/ai/rules/.docs/zh-CN/module/plugin.md`
|
|
75
|
+
2. `node_modules/@quicktvui/ai/rules/.docs/examples/module/plugin/es-basic.vue`
|
|
76
|
+
3. `node_modules/@quicktvui/ai/rules/.source/quicktvui/src/long-image/index.vue`
|
|
77
|
+
|
|
78
|
+
## 七、运行时兼容约束
|
|
79
|
+
|
|
80
|
+
1. 组件骨架默认仍以 `com.quicktvui.sdk.base.component.*` 和 `EsProxy` 的源码结构为准。
|
|
81
|
+
2. 但如果设备日志出现 `ClassNotFoundException: com.quicktvui.sdk.base.core.EsProxy`,或提示缺失 `com.quicktvui.sdk.base.*`,必须把设备日志视为运行时命名空间兼容性的最高优先级信号。
|
|
82
|
+
3. 这说明本地 stub 虽然可编译,但目标 TV 运行时并没有这套类;此时应切换运行时侧注册/导入到设备实际存在的命名空间后重新构建、重传。
|
|
83
|
+
4. 如果设备日志出现 `java.lang.NoSuchMethodError: No static method get()Leskit/sdk/support/core/EsProxy;`,必须把它视为插件注册入口的字节码签名不兼容,而不是页面逻辑问题;应按设备真实 runtime 的 `EsProxy.get()` 签名 / 调用路径调整注册实现后重新构建、重传。
|
|
84
|
+
5. 页面侧安装成功回调后,如果组件注册仍短暂不可见,允许一个简短轮询复查窗口,再决定是否判定失败。
|
|
85
|
+
6. 如果是为修复运行时兼容性而重新上传的新插件版本,复测前必须先重启宿主 / runtime 进程,否则当前进程仍可能持有旧插件字节码。
|
|
86
|
+
|
|
87
|
+
## 八、关键参数
|
|
88
|
+
|
|
89
|
+
| 参数 | 说明 |
|
|
90
|
+
| ---- | ---- |
|
|
91
|
+
| `--description <text>` | 功能描述,必填 |
|
|
92
|
+
| `--class-name <name>` | 显式组件类名 |
|
|
93
|
+
| `--view-class-name <name>` | 显式 View 类名 |
|
|
94
|
+
| `--view-base-class <name>` | View 基类 |
|
|
95
|
+
| `--package-name <pkg>` | 显式包名 |
|
|
96
|
+
| `--props <json|csv>` | 属性列表 |
|
|
97
|
+
| `--events <json|csv>` | 事件列表 |
|
|
98
|
+
| `--functions <json|csv>` | dispatchFunction 列表 |
|
|
99
|
+
| `--docs-dir <path>` | 组件文档目录 |
|
|
100
|
+
| `--native-tag-name <name>` | 原生标签名 |
|
|
101
|
+
| `--wrapper-tag-name <name>` | 包装组件标签名 |
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Plugin Create Module
|
|
3
|
+
lang: zh-CN
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# 插件模块创建
|
|
7
|
+
|
|
8
|
+
## 一、适用范围
|
|
9
|
+
|
|
10
|
+
模块用于无独立原生 UI 的能力封装,例如设备信息、网络能力、Toast、下载、埋点等。
|
|
11
|
+
|
|
12
|
+
如果需要原生 View、属性、UI 事件,应改用 `plugin-create-component`。
|
|
13
|
+
|
|
14
|
+
## 二、源码真值
|
|
15
|
+
|
|
16
|
+
生成模块前,必须优先对照:
|
|
17
|
+
|
|
18
|
+
1. `node_modules/@quicktvui/ai/rules/.source/sdk/base/sdk-base/src/main/java/com/quicktvui/sdk/base/module/IEsModule.java`
|
|
19
|
+
2. `node_modules/@quicktvui/ai/rules/.source/sdk/base/sdk-base/src/main/java/com/quicktvui/sdk/base/core/EsProxy.java`
|
|
20
|
+
|
|
21
|
+
真实接口:
|
|
22
|
+
|
|
23
|
+
```java
|
|
24
|
+
com.quicktvui.sdk.base.module.IEsModule
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## 三、CLI 命令
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
quicktvui-ai plugin-create-module \
|
|
31
|
+
--project plugin/demo-plugin \
|
|
32
|
+
--description "展示设备信息" \
|
|
33
|
+
--methods "showInfo,getInfo"
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## 四、MCP 工具
|
|
37
|
+
|
|
38
|
+
```text
|
|
39
|
+
plugin_module_create
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## 五、生成规则
|
|
43
|
+
|
|
44
|
+
1. `--description` 必填
|
|
45
|
+
2. 类名使用 PascalCase,并追加 `Module`
|
|
46
|
+
3. Java 包名必须合法,不能把 `kebab-case` 直接写入包路径
|
|
47
|
+
4. `--project` 默认应指向项目根目录下可见的 `plugin/<plugin-name>`,不要默认指向隐藏目录
|
|
48
|
+
5. 默认实现 `IEsModule`
|
|
49
|
+
6. 默认不强依赖 `@ESKitAutoRegister`
|
|
50
|
+
7. 默认尝试在 `Application#onCreate` 中注册 `EsProxy.get().registerModule("com.xxx.Module")`
|
|
51
|
+
8. 编译期接口由插件工程内的 `quicktvui-plugin-stubs` 模块提供;运行时依赖仍以模板工程里的 `com.extscreen.runtime:eskit:2.6.0` 为准
|
|
52
|
+
|
|
53
|
+
## 六、Vue 侧安装约束
|
|
54
|
+
|
|
55
|
+
模块插件生成完成、打包完成或上传成功,并不代表 Vue 页面已经可以直接调用该模块。
|
|
56
|
+
|
|
57
|
+
如果页面里要真正使用插件模块,还必须:
|
|
58
|
+
|
|
59
|
+
1. 使用 `@extscreen/es3-core` 的 `useESPlugin()`
|
|
60
|
+
2. 在 `onESCreate` 中 `addListener(pluginInfo, listener)`
|
|
61
|
+
3. 在 `onESDestroy` 中 `removeListener(listener)`
|
|
62
|
+
4. 在插件尚未可用时调用 `installPlugin({ pkg })`
|
|
63
|
+
|
|
64
|
+
推荐参考:
|
|
65
|
+
|
|
66
|
+
1. `node_modules/@quicktvui/ai/rules/.docs/zh-CN/module/plugin.md`
|
|
67
|
+
2. `node_modules/@quicktvui/ai/rules/.docs/examples/module/plugin/es-basic.vue`
|
|
68
|
+
|
|
69
|
+
## 七、运行时兼容约束
|
|
70
|
+
|
|
71
|
+
1. 模块骨架默认仍以 `com.quicktvui.sdk.base.module.IEsModule` 和 `EsProxy` 的源码结构为准。
|
|
72
|
+
2. 但如果设备日志出现 `ClassNotFoundException: com.quicktvui.sdk.base.core.EsProxy`,或提示缺失 `com.quicktvui.sdk.base.*`,必须把设备日志视为运行时命名空间兼容性的最高优先级信号。
|
|
73
|
+
3. 这说明本地 stub 虽然可编译,但目标 TV 运行时并没有这套类;此时应切换运行时侧注册/导入到设备实际存在的命名空间后重新构建、重传。
|
|
74
|
+
4. 如果设备日志出现 `java.lang.NoSuchMethodError: No static method get()Leskit/sdk/support/core/EsProxy;`,必须把它视为插件注册入口的字节码签名不兼容,而不是页面逻辑问题;应按设备真实 runtime 的 `EsProxy.get()` 签名 / 调用路径调整注册实现后重新构建、重传。
|
|
75
|
+
5. 页面侧安装成功回调后,如果模块注册仍短暂不可见,允许一个简短轮询复查窗口,再决定是否判定失败。
|
|
76
|
+
6. 如果是为修复运行时兼容性而重新上传的新插件版本,复测前必须先重启宿主 / runtime 进程,否则当前进程仍可能持有旧插件字节码。
|
|
77
|
+
|
|
78
|
+
## 八、关键参数
|
|
79
|
+
|
|
80
|
+
| 参数 | 说明 |
|
|
81
|
+
| ---- | ---- |
|
|
82
|
+
| `--description <text>` | 功能描述,必填 |
|
|
83
|
+
| `--class-name <name>` | 显式类名 |
|
|
84
|
+
| `--package-name <pkg>` | 显式包名 |
|
|
85
|
+
| `--methods <json|csv>` | 对外暴露方法 |
|
|
86
|
+
| `--register <true|false>` | 是否自动注册 |
|
|
87
|
+
| `--app-file <path>` | 指定 Application 文件 |
|
|
88
|
+
| `--src-root <path>` | 指定源码根目录 |
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Plugin Create Project
|
|
3
|
+
lang: zh-CN
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# 插件工程创建与打包
|
|
7
|
+
|
|
8
|
+
## 一、推荐入口
|
|
9
|
+
|
|
10
|
+
1. 优先使用 MCP:`plugin_project_create`、`plugin_project_build`
|
|
11
|
+
2. 没有 MCP 时,使用 CLI:`quicktvui-ai plugin-create-project`、`quicktvui-ai plugin-build`
|
|
12
|
+
3. 只有两者都不可用时,才手工执行 `git clone` / `gradlew`
|
|
13
|
+
|
|
14
|
+
## 二、创建命令
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
quicktvui-ai plugin-create-project plugin/demo-plugin \
|
|
18
|
+
--workspace-root . \
|
|
19
|
+
--package-name com.qtapp.plugin.demo
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
关键行为:
|
|
23
|
+
|
|
24
|
+
1. 默认模板仓库:`https://gitlab01.huan.tv/weipeng/eskit-plugin-template.git`
|
|
25
|
+
2. 创建成功后写入 `.kyy-plugin-project.json`
|
|
26
|
+
3. 如指定 `--package-name`,会同步改清单、源码包声明和包目录
|
|
27
|
+
4. 会补充本地编译支撑模块 `quicktvui-plugin-stubs`
|
|
28
|
+
5. 会在 `settings.gradle` 中追加 `include ':quicktvui-plugin-stubs'`
|
|
29
|
+
6. 会在 `app/build.gradle` 中追加 `compileOnly project(':quicktvui-plugin-stubs')`
|
|
30
|
+
7. 若创建到子目录且工作区根有 `package.json`,会注入 `build:android-plugin`
|
|
31
|
+
8. 长期保留或准备发布的插件工程,默认放到项目根目录下可见的 `plugin/` 目录,例如 `plugin/demo-plugin`
|
|
32
|
+
9. 不要把插件工程默认放到 `.ai-test/*` 等隐藏目录
|
|
33
|
+
|
|
34
|
+
## 三、更新模式
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
quicktvui-ai plugin-create-project plugin/demo-plugin --mode update
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
说明:
|
|
41
|
+
|
|
42
|
+
1. `update` 仅允许用于已带 `.kyy-plugin-project.json` 的工程
|
|
43
|
+
2. 非插件工程目录拒绝更新,避免误改
|
|
44
|
+
|
|
45
|
+
## 四、打包命令
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
quicktvui-ai plugin-build plugin/demo-plugin
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
固定优先级:
|
|
52
|
+
|
|
53
|
+
1. `npm run build:android-plugin`
|
|
54
|
+
2. `npm run build:plugin`
|
|
55
|
+
3. `npm run build`
|
|
56
|
+
4. `./gradlew assembleGeneralDebug`
|
|
57
|
+
|
|
58
|
+
说明:
|
|
59
|
+
|
|
60
|
+
1. 模板运行时依赖仍以 `com.extscreen.runtime:eskit:2.6.0` 为准
|
|
61
|
+
2. `quicktvui-plugin-stubs` 只用于补齐脚手架生成代码的编译期接口
|
|
62
|
+
3. 构建前会优先从 `ANDROID_SDK_ROOT`、`ANDROID_HOME` 和当前平台默认 Android SDK 目录中自动探测 SDK
|
|
63
|
+
4. 如探测到 SDK 且目标工程缺少 `local.properties` / `sdk.dir`,CLI 会在目标插件工程内自动补齐本地 `local.properties`
|
|
64
|
+
5. `local.properties` 属于开发机本地文件,不应提交到共享仓库
|
|
65
|
+
|
|
66
|
+
## 五、Vue 侧安装约束
|
|
67
|
+
|
|
68
|
+
插件工程创建、打包或插件服务上传成功,并不代表 Vue 页面已经可以直接使用插件。
|
|
69
|
+
|
|
70
|
+
如果业务页面需要真正接入插件,必须额外补齐:
|
|
71
|
+
|
|
72
|
+
1. 使用 `@extscreen/es3-core` 的 `useESPlugin()`
|
|
73
|
+
2. 在 `onESCreate` 中 `addListener(pluginInfo, listener)`
|
|
74
|
+
3. 在 `onESDestroy` 中 `removeListener(listener)`
|
|
75
|
+
4. 在插件尚未可用时调用 `installPlugin({ pkg })`
|
|
76
|
+
5. 如果是组件型插件,优先使用 `useES().isComponentRegistered("<组件完整类名>")` 检查是否已注册,再决定是否安装或渲染
|
|
77
|
+
|
|
78
|
+
推荐参考:
|
|
79
|
+
|
|
80
|
+
1. `node_modules/@quicktvui/ai/rules/.docs/zh-CN/module/plugin.md`
|
|
81
|
+
2. `node_modules/@quicktvui/ai/rules/.docs/examples/module/plugin/es-basic.vue`
|
|
82
|
+
3. `node_modules/@quicktvui/ai/rules/.source/quicktvui/src/long-image/index.vue`
|
|
83
|
+
|
|
84
|
+
## 六、运行时兼容约束
|
|
85
|
+
|
|
86
|
+
1. 脚手架结构默认仍以 `.source/sdk/base/...` 为准。
|
|
87
|
+
2. 但如果设备日志出现 `ClassNotFoundException: com.quicktvui.sdk.base.core.EsProxy`,或启动阶段提示缺失 `com.quicktvui.sdk.base.*`,必须把设备日志视为运行时命名空间兼容性的最高优先级信号。
|
|
88
|
+
3. 这通常意味着“本地 stub 能编译”但“目标 TV 运行时并没有这套类”;此时必须改为适配设备实际存在的运行时命名空间后重新构建、重传。
|
|
89
|
+
4. 如果设备日志出现 `java.lang.NoSuchMethodError: No static method get()Leskit/sdk/support/core/EsProxy;`,必须把它视为插件注册入口的字节码签名不兼容,而不是页面逻辑问题;应按设备真实 runtime 的 `EsProxy.get()` 签名 / 调用路径调整注册实现后重新构建、重传。
|
|
90
|
+
5. 页面侧安装成功回调后,如果组件或模块注册仍短暂不可见,允许一个简短轮询复查窗口,再决定是否判定失败。
|
|
91
|
+
6. 如果是为修复运行时兼容性而重新上传的新插件版本,复测前必须先重启宿主 / runtime 进程,否则当前进程仍可能持有旧插件字节码。
|
|
92
|
+
|
|
93
|
+
## 七、关键参数
|
|
94
|
+
|
|
95
|
+
| 参数 | 说明 |
|
|
96
|
+
| ---- | ---- |
|
|
97
|
+
| `--mode <create|update>` | 创建或更新 |
|
|
98
|
+
| `--template-repo <url>` | 自定义模板仓库 |
|
|
99
|
+
| `--package-name <pkg>` | 目标 Java 包名 |
|
|
100
|
+
| `--workspace-root <path>` | 工作区根目录 |
|
|
101
|
+
|
|
102
|
+
## 八、注意事项
|
|
103
|
+
|
|
104
|
+
1. 文档与实现不一致时,以 `quicktvui-ai-cli/lib/plugin-scaffold.js` 为准。
|
|
105
|
+
2. 创建到子目录时,建议始终传 `--workspace-root`,让根脚本注入更稳定。
|
|
106
|
+
3. 如果插件工程后续需要继续开发、交接或发布,优先使用项目根目录下的 `plugin/<plugin-name>` 路径。
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Plugin Server
|
|
3
|
+
lang: zh-CN
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# 插件服务 CLI 工作流
|
|
7
|
+
|
|
8
|
+
## 一、推荐优先级
|
|
9
|
+
|
|
10
|
+
当 AI 需要联调电视插件服务时,推荐优先级如下:
|
|
11
|
+
|
|
12
|
+
1. 优先使用 `quicktvui-ai-mcp`
|
|
13
|
+
2. 没有 MCP 时,使用 `quicktvui-ai plugin-*`
|
|
14
|
+
3. CLI 也不可用时,再退回手工 `adb` + `curl`
|
|
15
|
+
|
|
16
|
+
## 二、标准命令链路
|
|
17
|
+
|
|
18
|
+
### 2.1 打开 RESTful API
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
quicktvui-ai plugin-enable-api --device <serial>
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
说明:
|
|
25
|
+
|
|
26
|
+
1. 该命令内部会发送 `eskit.sdk.core.ACTION_TOOLKIT_SETTING`
|
|
27
|
+
2. 默认等价于 `RESTFUL_API=true`
|
|
28
|
+
3. 如需关闭,可显式传 `--enabled false`
|
|
29
|
+
|
|
30
|
+
### 2.2 检查服务可用性
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
quicktvui-ai plugin-check --device <serial>
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
说明:
|
|
37
|
+
|
|
38
|
+
1. 会以 `POST` 探测 `/hello`、`/status`、`/uploadSo`、`/uploadPlugin`
|
|
39
|
+
2. 同路径 `GET` 在实测设备上可能返回 `404`,不能据此判断服务未启动
|
|
40
|
+
3. `uploadSo` / `uploadPlugin` 返回缺参 `400` 视为“接口活着”,不是失败
|
|
41
|
+
|
|
42
|
+
### 2.3 查看当前状态
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
quicktvui-ai plugin-status --device <serial>
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### 2.4 上传 So
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
quicktvui-ai plugin-upload-so \
|
|
52
|
+
--device <serial> \
|
|
53
|
+
--tag eskit.so.ffmpeg.command \
|
|
54
|
+
--pkg eskit.so.ffmpeg.command \
|
|
55
|
+
--file docs/plugin/armeabi-v7a.zip
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
说明:
|
|
59
|
+
|
|
60
|
+
1. `--abi` 省略时,CLI 只会在执行 `uploadSo` 的这一刻,从当前插件服务对应设备读取 `ro.product.cpu.abi`
|
|
61
|
+
2. 建议总是同时传 `--tag` 和 `--pkg`
|
|
62
|
+
3. So zip 必须和设备 ABI 一致
|
|
63
|
+
|
|
64
|
+
### 2.5 上传插件 APK
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
quicktvui-ai plugin-upload-plugin \
|
|
68
|
+
--device <serial> \
|
|
69
|
+
--pkg eskit.plugin.imagequality \
|
|
70
|
+
--file docs/plugin/plugin-general-debug.apk
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
说明:
|
|
74
|
+
|
|
75
|
+
1. 上传成功只代表插件包已经进入插件服务缓存,不代表当前宿主进程已经切到新插件字节码
|
|
76
|
+
2. 如果上传的是新构建或覆盖上传的插件包,复测前必须先重启宿主 / runtime 进程
|
|
77
|
+
3. 宿主重启后,再继续做 Vue 页面安装、注册校验或启动验证
|
|
78
|
+
|
|
79
|
+
### 2.6 Vue 侧安装插件
|
|
80
|
+
|
|
81
|
+
`plugin-upload-plugin` 成功,只代表插件包已经进入插件服务缓存;如果页面里需要真正使用插件,还必须在 Vue 侧补齐安装流程。
|
|
82
|
+
|
|
83
|
+
标准约束:
|
|
84
|
+
|
|
85
|
+
1. 使用 `@extscreen/es3-core` 的 `useESPlugin()`
|
|
86
|
+
2. 在 `onESCreate` 中 `addListener(pluginInfo, listener)`
|
|
87
|
+
3. 在 `onESDestroy` 中 `removeListener(listener)`
|
|
88
|
+
4. 在插件尚未可用时调用 `installPlugin({ pkg })`
|
|
89
|
+
5. 如果是组件型插件,优先用 `useES().isComponentRegistered("<组件完整类名>")` 检查是否已注册,再决定是否安装或渲染
|
|
90
|
+
|
|
91
|
+
推荐参考:
|
|
92
|
+
|
|
93
|
+
1. `node_modules/@quicktvui/ai/rules/.docs/zh-CN/module/plugin.md`
|
|
94
|
+
2. `node_modules/@quicktvui/ai/rules/.docs/examples/module/plugin/es-basic.vue`
|
|
95
|
+
3. `node_modules/@quicktvui/ai/rules/.source/quicktvui/src/long-image/index.vue`
|
|
96
|
+
|
|
97
|
+
如果上传成功但插件启动失败,应继续看设备日志;若日志出现 `ClassNotFoundException: com.quicktvui.sdk.base.core.EsProxy` 或缺失 `com.quicktvui.sdk.base.*`,说明问题在运行时命名空间兼容性,而不是上传链路本身。若日志出现 `java.lang.NoSuchMethodError: No static method get()Leskit/sdk/support/core/EsProxy;`,则说明插件注册入口的字节码签名与设备 runtime 不兼容,必须改成匹配设备真实 `EsProxy.get()` 签名 / 调用路径的实现,重新构建、重传,并在复测前重启宿主进程。
|
|
98
|
+
|
|
99
|
+
## 三、关键参数
|
|
100
|
+
|
|
101
|
+
| 参数 | 说明 |
|
|
102
|
+
| ---- | ---- |
|
|
103
|
+
| `--device <serial>` | 目标 adb 设备序列号 |
|
|
104
|
+
| `--device-ip <ip[:port]>` | 先 `adb connect` 再执行命令 |
|
|
105
|
+
| `--plugin-base-url <url>` | 显式覆盖插件服务地址;不传时 CLI 会优先自动探测 |
|
|
106
|
+
| `--timeout-ms <n>` | 请求超时 |
|
|
107
|
+
| `--enabled <true|false>` | `plugin-enable-api` 的值 |
|
|
108
|
+
| `--tag` | So 标识 |
|
|
109
|
+
| `--pkg` | So 或插件包名 |
|
|
110
|
+
| `--abi` | 可选;仅在 `plugin-upload-so` 时使用,不传则按当前服务目标设备按需读取 |
|
|
111
|
+
| `--file` | 本地 zip/apk 文件 |
|
|
112
|
+
| `--file-name` | 覆盖上传文件名 |
|
|
113
|
+
|
|
114
|
+
## 四、地址自动解析与转发行为
|
|
115
|
+
|
|
116
|
+
不传 `--plugin-base-url` 时,CLI 会按下面顺序解析插件服务地址:
|
|
117
|
+
|
|
118
|
+
1. 如果 adb 已连接目标设备:
|
|
119
|
+
- 优先尝试该设备的插件服务地址
|
|
120
|
+
- 若无法从目标设备推断 host,则自动使用 adb 端口转发并回落到 `http://127.0.0.1:36366`
|
|
121
|
+
2. 如果同时连接了多台 adb 设备:
|
|
122
|
+
- 必须显式传 `--device <serial>`,或直接传 `--plugin-base-url`
|
|
123
|
+
3. 如果没有 adb 已连接设备:
|
|
124
|
+
- 交互模式下会提示输入服务 IP / URL
|
|
125
|
+
- 非交互模式下会直接报错,要求显式传 `--plugin-base-url`
|
|
126
|
+
|
|
127
|
+
如果目标是设备本地服务而本机回环地址无法直连,CLI 会自动尝试:
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
adb -s <serial> forward tcp:36366 tcp:36366
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
如果你已经知道电视局域网地址,也可以显式指定:
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
quicktvui-ai plugin-check --plugin-base-url http://<tv-ip>:36366
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## 五、推荐测试标识
|
|
140
|
+
|
|
141
|
+
| 类型 | 标识 |
|
|
142
|
+
| ---- | ---- |
|
|
143
|
+
| So 包名 / tag | `eskit.so.ffmpeg.command` |
|
|
144
|
+
| 插件包名 | `eskit.plugin.imagequality` |
|
|
145
|
+
|
|
146
|
+
推荐测试文件:
|
|
147
|
+
|
|
148
|
+
| 文件 | 用途 |
|
|
149
|
+
| ---- | ---- |
|
|
150
|
+
| `docs/plugin/arm64-v8a.zip` | arm64-v8a So 包 |
|
|
151
|
+
| `docs/plugin/armeabi-v7a.zip` | armeabi-v7a So 包 |
|
|
152
|
+
| `docs/plugin/plugin-general-debug.apk` | 插件 APK |
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: copilot-instructions.md
|
|
3
|
-
version: 1.1.
|
|
3
|
+
version: 1.1.18
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# copilot-instructions.md - QuickTVUI AI Development Guide
|
|
@@ -68,6 +68,127 @@ Required CLI sequence:
|
|
|
68
68
|
|
|
69
69
|
AI MUST NOT say it has checked logs/screenshots unless one of those MCP/CLI reads actually succeeded.
|
|
70
70
|
|
|
71
|
+
## Plugin Server Workflow (CRITICAL)
|
|
72
|
+
|
|
73
|
+
When the task is to inspect, upload, or debug TV plugin server endpoints (`/hello`, `/status`, `/uploadSo`, `/uploadPlugin`), AI MUST use this priority:
|
|
74
|
+
|
|
75
|
+
1. Prefer connected `quicktvui-ai-mcp` plugin tools:
|
|
76
|
+
- `plugin_server_check`
|
|
77
|
+
- `plugin_server_hello`
|
|
78
|
+
- `plugin_server_status`
|
|
79
|
+
- `plugin_upload_so`
|
|
80
|
+
- `plugin_upload_plugin`
|
|
81
|
+
2. Otherwise use `quicktvui-ai plugin-*`
|
|
82
|
+
3. Only fall back to manual `adb` + `curl` when neither tool path is available
|
|
83
|
+
|
|
84
|
+
Required order:
|
|
85
|
+
|
|
86
|
+
- Enable Toolkit RESTful API first:
|
|
87
|
+
- `quicktvui-ai plugin-enable-api --device <serial>`
|
|
88
|
+
- manual fallback: `adb -s <serial> shell am broadcast -a "eskit.sdk.core.ACTION_TOOLKIT_SETTING" --es "RESTFUL_API" "true"`
|
|
89
|
+
- Probe readiness:
|
|
90
|
+
- `plugin_server_check`
|
|
91
|
+
- or `quicktvui-ai plugin-check --device <serial>`
|
|
92
|
+
- Read current state:
|
|
93
|
+
- `plugin_server_status`
|
|
94
|
+
- or `quicktvui-ai plugin-status --device <serial>`
|
|
95
|
+
- Resolve plugin server address:
|
|
96
|
+
- explicit `baseUrl` / `--plugin-base-url`
|
|
97
|
+
- adb-connected device service address
|
|
98
|
+
- adb forward + `http://127.0.0.1:36366` when target host cannot be inferred
|
|
99
|
+
- if multiple adb devices are connected, ask for `serial` or `baseUrl`
|
|
100
|
+
- if no adb-connected device exists, ask the user for service IP / `baseUrl` and never invent a developer-specific TV IP
|
|
101
|
+
- Upload So zip:
|
|
102
|
+
- choose the archive matching `ro.product.cpu.abi`
|
|
103
|
+
- `quicktvui-ai plugin-upload-so --device <serial> --tag eskit.so.ffmpeg.command --pkg eskit.so.ffmpeg.command --file <zip-path>`
|
|
104
|
+
- Upload plugin APK:
|
|
105
|
+
- `quicktvui-ai plugin-upload-plugin --device <serial> --pkg eskit.plugin.imagequality --file <apk-path>`
|
|
106
|
+
|
|
107
|
+
Hard requirements:
|
|
108
|
+
|
|
109
|
+
- Runtime endpoint behavior overrides markdown docs.
|
|
110
|
+
- Probe `/hello`, `/status`, `/uploadSo`, `/uploadPlugin` with `POST`, not `GET`.
|
|
111
|
+
- If AI is working inside the `quicktvui-ai` repo and finds doc/runtime drift, AI MUST update the docs.
|
|
112
|
+
- `uploadSo` currently has `pkg` / `tag` drift. AI SHOULD send both fields and trust successful `data.tag`.
|
|
113
|
+
- Default demo identifiers:
|
|
114
|
+
- So package/tag: `eskit.so.ffmpeg.command`
|
|
115
|
+
- Plugin package: `eskit.plugin.imagequality`
|
|
116
|
+
- ABI MUST match `ro.product.cpu.abi` on the service-corresponding device, but AI SHOULD only resolve ABI when uploading So and SHOULD let CLI / MCP fill it on demand if `abi` is not explicitly provided.
|
|
117
|
+
- AI MUST NOT claim upload success unless MCP or CLI returned a success payload.
|
|
118
|
+
- `status.pluginList` may still be empty after `uploadPlugin` returns `registered: true`; report that exact state.
|
|
119
|
+
- `uploadPlugin` success or `registered: true` only means the package reached plugin service storage. If the task is to use the plugin from a Vue page, AI MUST still add Vue-side installation logic.
|
|
120
|
+
- After uploading a newly rebuilt or replaced plugin package, restart the host/runtime process before validating page-side usage or startup; the running host does not hot-swap new plugin bytes automatically.
|
|
121
|
+
- Consult:
|
|
122
|
+
- `node_modules/@quicktvui/ai/rules/.docs/zh-CN/tool/api/plugin-server-api.md`
|
|
123
|
+
- `node_modules/@quicktvui/ai/rules/.docs/zh-CN/tool/cli/plugin-server.md`
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
## Plugin Scaffold Workflow (CRITICAL)
|
|
127
|
+
|
|
128
|
+
When the user asks AI to create/update/build Android plugin projects, native modules, or native UI components, AI MUST use this priority:
|
|
129
|
+
|
|
130
|
+
1. Prefer connected `quicktvui-ai-mcp` tools:
|
|
131
|
+
- `plugin_project_create`
|
|
132
|
+
- `plugin_project_build`
|
|
133
|
+
- `plugin_module_create`
|
|
134
|
+
- `plugin_component_create`
|
|
135
|
+
2. Otherwise use `quicktvui-ai`:
|
|
136
|
+
- `plugin-create-project`
|
|
137
|
+
- `plugin-build`
|
|
138
|
+
- `plugin-create-module`
|
|
139
|
+
- `plugin-create-component`
|
|
140
|
+
3. Only if neither MCP nor CLI execution is available may AI scaffold manually
|
|
141
|
+
|
|
142
|
+
Decision rules:
|
|
143
|
+
|
|
144
|
+
- project init / update / packaging -> `plugin_project_create` / `plugin_project_build`
|
|
145
|
+
- non-UI native capability -> `plugin_module_create`
|
|
146
|
+
- native View + props/events/functions -> `plugin_component_create`
|
|
147
|
+
|
|
148
|
+
Hard requirements:
|
|
149
|
+
|
|
150
|
+
- Read these packaged docs first:
|
|
151
|
+
- `node_modules/@quicktvui/ai/rules/.docs/zh-CN/tool/cli/plugin-create-project.md`
|
|
152
|
+
- `node_modules/@quicktvui/ai/rules/.docs/zh-CN/tool/cli/plugin-create-module.md`
|
|
153
|
+
- `node_modules/@quicktvui/ai/rules/.docs/zh-CN/tool/cli/plugin-create-component.md`
|
|
154
|
+
- `node_modules/@quicktvui/ai/rules/.docs/zh-CN/tool/api/plugin-scaffold-mcp.md`
|
|
155
|
+
- Source-of-truth interfaces come from `.source/sdk/base/...`:
|
|
156
|
+
- `com.quicktvui.sdk.base.module.IEsModule`
|
|
157
|
+
- `com.quicktvui.sdk.base.component.IEsComponent`
|
|
158
|
+
- `com.quicktvui.sdk.base.component.IEsComponentView`
|
|
159
|
+
- `com.quicktvui.sdk.base.component.EsComponentAttribute`
|
|
160
|
+
- Project creation MUST write `.kyy-plugin-project.json`
|
|
161
|
+
- By default, long-lived or releasable plugin projects SHOULD live under `<project-root>/plugin/<plugin-name>`
|
|
162
|
+
- Plugin projects MUST NOT default to hidden directories such as `.ai-test/*` or other dot-prefixed paths
|
|
163
|
+
- If plugin project is under a workspace subdirectory and root has `package.json`, AI MUST inject `build:android-plugin`
|
|
164
|
+
- Build order MUST be:
|
|
165
|
+
1. `npm run build:android-plugin`
|
|
166
|
+
2. `npm run build:plugin`
|
|
167
|
+
3. `npm run build`
|
|
168
|
+
4. `./gradlew assembleGeneralDebug`
|
|
169
|
+
- Module/component generation MUST require a concrete feature description first
|
|
170
|
+
- Java package segments MUST be valid identifiers; do NOT place kebab-case directly into Java package names
|
|
171
|
+
- Component generation MUST create/update `docs/component/<kebab-name>.md`
|
|
172
|
+
- Component tags MUST be kebab-case
|
|
173
|
+
- In Vue `h()`, do NOT use the fully-qualified Java class name
|
|
174
|
+
- If plugin build reports missing Android SDK, resolve SDK generically in this order: `ANDROID_SDK_ROOT` -> `ANDROID_HOME` -> platform default SDK directories.
|
|
175
|
+
- If SDK is found and the target plugin project lacks `local.properties` / `sdk.dir`, allow CLI / MCP to create or update that local file for the current machine only.
|
|
176
|
+
- Never turn one developer's local Android SDK path into a shared rule, hardcoded project setting, or committed repository file.
|
|
177
|
+
- Read plugin runtime installation references when the page must really use the plugin:
|
|
178
|
+
- `node_modules/@quicktvui/ai/rules/.docs/zh-CN/module/plugin.md`
|
|
179
|
+
- `node_modules/@quicktvui/ai/rules/.docs/examples/module/plugin/es-basic.vue`
|
|
180
|
+
- `node_modules/@quicktvui/ai/rules/.source/quicktvui/src/long-image/index.vue`
|
|
181
|
+
- Build/upload success does NOT mean the Vue page can already use the plugin.
|
|
182
|
+
- If a Vue page depends on the plugin, use `useESPlugin()` from `@extscreen/es3-core`, add listeners in `onESCreate`, and remove them in `onESDestroy`.
|
|
183
|
+
- For component plugins, call `useES().isComponentRegistered("<fully-qualified-component-class>")` before using the component, and install the plugin first when registration is still missing.
|
|
184
|
+
- Gate plugin-dependent rendering and calls on installation / registration readiness instead of assuming upload or install finishes synchronously.
|
|
185
|
+
- Scaffold structure should follow `.source/sdk/base/...`, but live device logs override the default runtime namespace when startup fails.
|
|
186
|
+
- If logs show `ClassNotFoundException: com.quicktvui.sdk.base.core.EsProxy` or missing `com.quicktvui.sdk.base.*`, treat that as runtime compatibility drift and adapt runtime-facing imports/registration to the namespace actually present on the device before rebuilding/reuploading.
|
|
187
|
+
- If logs show `java.lang.NoSuchMethodError: No static method get()Leskit/sdk/support/core/EsProxy;`, treat that as a bytecode-signature mismatch in the plugin registration entry, realign `EsProxy.get()` usage / registration to the actual device runtime signature, then rebuild/reupload.
|
|
188
|
+
- Do not confuse local stub compilation with device runtime availability.
|
|
189
|
+
- After install success, allow a short retry/recheck window if registration is still briefly missing.
|
|
190
|
+
- After reuploading a compatibility-fixed plugin build, restart the host/runtime process before retesting.
|
|
191
|
+
- If docs drift from source or implementation, AI MUST update docs
|
|
71
192
|
|
|
72
193
|
## Game Loop & Timer Constraints (CRITICAL)
|
|
73
194
|
|