@quicktvui/ai 1.1.16 → 1.1.19
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 +128 -0
- package/rules/.cursorrules +128 -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 +214 -0
- package/rules/.docs/zh-CN/tool/api/runtime-status.md +95 -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 +169 -0
- package/rules/.docs/zh-CN/tool/cli/runtime-status.md +49 -0
- package/rules/.github/copilot-instructions.md +129 -1
- package/rules/.windsurfrules +128 -0
- package/rules/AGENTS.md +130 -1
- package/rules/AI_HANDOFF.md +113 -1
- package/rules/CLAUDE.md +131 -1
- package/rules/GEMINI.md +131 -1
package/README.md
CHANGED
|
@@ -66,6 +66,50 @@ quicktvui-ai prompt --lang zh
|
|
|
66
66
|
|
|
67
67
|
> 注意:全局 skills 不是对所有 AI 都自动生效。对仅读取项目文件的工具,仍需使用 `npm install @quicktvui/ai --save-dev` 注入项目内规则。
|
|
68
68
|
|
|
69
|
+
## 🧩 插件服务工作流
|
|
70
|
+
|
|
71
|
+
从当前版本开始,`@quicktvui/ai` 注入的规则也会约束 AI 如何联调电视插件服务:
|
|
72
|
+
|
|
73
|
+
1. 优先使用 `quicktvui-ai-mcp` 的插件工具:`plugin_server_check`、`plugin_server_status`、`plugin_upload_so`、`plugin_upload_plugin`
|
|
74
|
+
2. 没有 MCP 时,退回 `quicktvui-ai plugin-*`
|
|
75
|
+
3. 只有两者都不可用时,才允许 AI 手写 `adb` / `curl`
|
|
76
|
+
|
|
77
|
+
包内同时提供了可检索的插件服务文档:
|
|
78
|
+
|
|
79
|
+
- `node_modules/@quicktvui/ai/rules/.docs/zh-CN/tool/api/plugin-server-api.md`
|
|
80
|
+
- `node_modules/@quicktvui/ai/rules/.docs/zh-CN/tool/cli/plugin-server.md`
|
|
81
|
+
|
|
82
|
+
规则会强制 AI 先打开 Toolkit `RESTFUL_API`,并要求:
|
|
83
|
+
|
|
84
|
+
- 接口返回优先于 Markdown 文档
|
|
85
|
+
- ABI 必须匹配 `ro.product.cpu.abi`
|
|
86
|
+
- `uploadSo` 调用时优先同时传 `pkg` 和 `tag`
|
|
87
|
+
- 默认测试标识使用 `eskit.so.ffmpeg.command` 与 `eskit.plugin.imagequality`
|
|
88
|
+
|
|
89
|
+
## 🏗️ 插件脚手架工作流
|
|
90
|
+
|
|
91
|
+
从当前版本开始,`@quicktvui/ai` 注入的规则还会约束 AI 如何创建 Android 插件工程、原生模块与原生组件:
|
|
92
|
+
|
|
93
|
+
1. 优先使用 `quicktvui-ai-mcp`:`plugin_project_create`、`plugin_project_build`、`plugin_module_create`、`plugin_component_create`
|
|
94
|
+
2. 没有 MCP 时,退回 `quicktvui-ai plugin-create-project`、`plugin-build`、`plugin-create-module`、`plugin-create-component`
|
|
95
|
+
3. 只有两者都不可用时,才允许 AI 手工修改脚手架
|
|
96
|
+
|
|
97
|
+
包内同步提供了可检索文档:
|
|
98
|
+
|
|
99
|
+
- `node_modules/@quicktvui/ai/rules/.docs/zh-CN/tool/cli/plugin-create-project.md`
|
|
100
|
+
- `node_modules/@quicktvui/ai/rules/.docs/zh-CN/tool/cli/plugin-create-module.md`
|
|
101
|
+
- `node_modules/@quicktvui/ai/rules/.docs/zh-CN/tool/cli/plugin-create-component.md`
|
|
102
|
+
- `node_modules/@quicktvui/ai/rules/.docs/zh-CN/tool/api/plugin-scaffold-mcp.md`
|
|
103
|
+
|
|
104
|
+
规则会进一步强制 AI:
|
|
105
|
+
|
|
106
|
+
- 先根据需求区分“无界面模块”还是“有界面组件”
|
|
107
|
+
- 以 `.source/sdk/base/...` 中的真实接口为准,而不是旧版 markdown 包名
|
|
108
|
+
- 创建工程后写入 `.kyy-plugin-project.json`
|
|
109
|
+
- 子目录工程自动补 `build:android-plugin`
|
|
110
|
+
- 组件必须补 `docs/component/<kebab-name>.md`
|
|
111
|
+
- Vue 标签必须使用 `kebab-case`
|
|
112
|
+
|
|
69
113
|
---
|
|
70
114
|
|
|
71
115
|
## 🤖 支持的 AI 工具与配置
|
package/package.json
CHANGED
package/rules/.clinerules
CHANGED
|
@@ -102,6 +102,134 @@ Required CLI order:
|
|
|
102
102
|
|
|
103
103
|
AI MUST NOT claim it inspected runtime data unless MCP or `quicktvui-ai debug-*` actually returned it.
|
|
104
104
|
|
|
105
|
+
## Plugin Server Workflow (CRITICAL)
|
|
106
|
+
|
|
107
|
+
When the user asks AI to inspect, upload, or debug TV plugin server endpoints (`/hello`, `/status`, `/uploadSo`, `/uploadPlugin`) or recent runtime load status from `/status`:
|
|
108
|
+
|
|
109
|
+
1. Prefer connected `quicktvui-ai-mcp` plugin tools:
|
|
110
|
+
- `plugin_server_check`
|
|
111
|
+
- `plugin_server_hello`
|
|
112
|
+
- `plugin_server_status`
|
|
113
|
+
- `quicktvui_runtime_status`
|
|
114
|
+
- `plugin_upload_so`
|
|
115
|
+
- `plugin_upload_plugin`
|
|
116
|
+
2. Otherwise use `quicktvui-ai plugin-*`
|
|
117
|
+
3. Only fall back to manual `adb` + `curl` when neither path is available
|
|
118
|
+
|
|
119
|
+
Required order:
|
|
120
|
+
|
|
121
|
+
1. Enable Toolkit RESTful API first:
|
|
122
|
+
- `quicktvui-ai plugin-enable-api --device <serial>`
|
|
123
|
+
- manual fallback: `adb -s <serial> shell am broadcast -a "eskit.sdk.core.ACTION_TOOLKIT_SETTING" --es "RESTFUL_API" "true"`
|
|
124
|
+
2. Probe readiness:
|
|
125
|
+
- `plugin_server_check`
|
|
126
|
+
- or `quicktvui-ai plugin-check --device <serial>`
|
|
127
|
+
3. Read current state:
|
|
128
|
+
- `plugin_server_status`
|
|
129
|
+
- or `quicktvui-ai plugin-status --device <serial>`
|
|
130
|
+
4. If the task is to inspect recent runtime load state or latest error info after quick-app/plugin load:
|
|
131
|
+
- `quicktvui_runtime_status`
|
|
132
|
+
- or `quicktvui-ai runtime-status --device <serial>`
|
|
133
|
+
5. Upload So zip:
|
|
134
|
+
- choose the archive matching `ro.product.cpu.abi` on the service-corresponding device
|
|
135
|
+
- `quicktvui-ai plugin-upload-so --device <serial> --tag eskit.so.ffmpeg.command --pkg eskit.so.ffmpeg.command --file <zip-path>`
|
|
136
|
+
5. Upload plugin APK:
|
|
137
|
+
- `quicktvui-ai plugin-upload-plugin --device <serial> --pkg eskit.plugin.imagequality --file <apk-path>`
|
|
138
|
+
|
|
139
|
+
Hard requirements:
|
|
140
|
+
|
|
141
|
+
- Runtime endpoint behavior overrides markdown docs.
|
|
142
|
+
- Probe `/hello`, `/status`, `/uploadSo`, `/uploadPlugin` with `POST`, not `GET`.
|
|
143
|
+
- `/status` may include `data.loadStatus`, which is the authoritative recent runtime load-state/error map for quick-app/plugin startup. After `run-dev`, `run-esapp`, page-side install, or a startup failure, query `quicktvui_runtime_status` / `runtime-status` and report the package key plus `__debug__`.
|
|
144
|
+
- Resolve plugin server address in this order:
|
|
145
|
+
- explicit `baseUrl` / `--plugin-base-url`
|
|
146
|
+
- adb-connected device service address
|
|
147
|
+
- adb forward + `http://127.0.0.1:36366` when target host cannot be inferred
|
|
148
|
+
- If multiple adb devices are connected, ask the user to choose `serial` or provide service IP / `baseUrl`.
|
|
149
|
+
- If no adb-connected device exists, ask the user for service IP / `baseUrl` and never invent a developer-specific TV IP.
|
|
150
|
+
- If AI is working inside the `quicktvui-ai` repo and finds doc/runtime drift, AI MUST update the docs.
|
|
151
|
+
- `uploadSo` currently has `pkg` / `tag` drift. AI SHOULD send both fields and trust successful `data.tag`.
|
|
152
|
+
- Default demo identifiers:
|
|
153
|
+
- So package/tag: `eskit.so.ffmpeg.command`
|
|
154
|
+
- Plugin package: `eskit.plugin.imagequality`
|
|
155
|
+
- 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.
|
|
156
|
+
- AI MUST NOT claim upload success unless MCP or CLI returned a success payload.
|
|
157
|
+
- `status.pluginList` may still be empty after `uploadPlugin` returns `registered: true`; report that exact state.
|
|
158
|
+
- `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.
|
|
159
|
+
- 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.
|
|
160
|
+
- Consult:
|
|
161
|
+
- `node_modules/@quicktvui/ai/rules/.docs/zh-CN/tool/api/plugin-server-api.md`
|
|
162
|
+
- `node_modules/@quicktvui/ai/rules/.docs/zh-CN/tool/api/runtime-status.md`
|
|
163
|
+
- `node_modules/@quicktvui/ai/rules/.docs/zh-CN/tool/cli/plugin-server.md`
|
|
164
|
+
- `node_modules/@quicktvui/ai/rules/.docs/zh-CN/tool/cli/runtime-status.md`
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
## Plugin Scaffold Workflow (CRITICAL)
|
|
168
|
+
|
|
169
|
+
When the user asks AI to create/update/build Android plugin projects, native modules, or native UI components, AI MUST use this priority:
|
|
170
|
+
|
|
171
|
+
1. Prefer connected `quicktvui-ai-mcp` tools:
|
|
172
|
+
- `plugin_project_create`
|
|
173
|
+
- `plugin_project_build`
|
|
174
|
+
- `plugin_module_create`
|
|
175
|
+
- `plugin_component_create`
|
|
176
|
+
2. Otherwise use `quicktvui-ai`:
|
|
177
|
+
- `plugin-create-project`
|
|
178
|
+
- `plugin-build`
|
|
179
|
+
- `plugin-create-module`
|
|
180
|
+
- `plugin-create-component`
|
|
181
|
+
3. Only if neither MCP nor CLI execution is available may AI scaffold manually
|
|
182
|
+
|
|
183
|
+
Decision rules:
|
|
184
|
+
|
|
185
|
+
- Project init / update / packaging -> `plugin_project_create` / `plugin_project_build`
|
|
186
|
+
- Non-UI native capability -> `plugin_module_create`
|
|
187
|
+
- Native View + props/events/functions -> `plugin_component_create`
|
|
188
|
+
|
|
189
|
+
Hard requirements:
|
|
190
|
+
|
|
191
|
+
- Read these packaged docs first:
|
|
192
|
+
- `node_modules/@quicktvui/ai/rules/.docs/zh-CN/tool/cli/plugin-create-project.md`
|
|
193
|
+
- `node_modules/@quicktvui/ai/rules/.docs/zh-CN/tool/cli/plugin-create-module.md`
|
|
194
|
+
- `node_modules/@quicktvui/ai/rules/.docs/zh-CN/tool/cli/plugin-create-component.md`
|
|
195
|
+
- `node_modules/@quicktvui/ai/rules/.docs/zh-CN/tool/api/plugin-scaffold-mcp.md`
|
|
196
|
+
- Source-of-truth interfaces come from `.source/sdk/base/...`:
|
|
197
|
+
- `com.quicktvui.sdk.base.module.IEsModule`
|
|
198
|
+
- `com.quicktvui.sdk.base.component.IEsComponent`
|
|
199
|
+
- `com.quicktvui.sdk.base.component.IEsComponentView`
|
|
200
|
+
- `com.quicktvui.sdk.base.component.EsComponentAttribute`
|
|
201
|
+
- Project creation MUST write `.kyy-plugin-project.json`
|
|
202
|
+
- By default, long-lived or releasable plugin projects SHOULD live under `<project-root>/plugin/<plugin-name>`
|
|
203
|
+
- Plugin projects MUST NOT default to hidden directories such as `.ai-test/*` or other dot-prefixed paths
|
|
204
|
+
- If plugin project is under a workspace subdirectory and root has `package.json`, AI MUST inject `build:android-plugin`
|
|
205
|
+
- Build order MUST be:
|
|
206
|
+
1. `npm run build:android-plugin`
|
|
207
|
+
2. `npm run build:plugin`
|
|
208
|
+
3. `npm run build`
|
|
209
|
+
4. `./gradlew assembleGeneralDebug`
|
|
210
|
+
- If plugin build reports missing Android SDK, resolve SDK generically in this order: `ANDROID_SDK_ROOT` -> `ANDROID_HOME` -> platform default SDK directories.
|
|
211
|
+
- 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.
|
|
212
|
+
- Never turn one developer's local Android SDK path into a shared rule, hardcoded project setting, or committed repository file.
|
|
213
|
+
- Module/component generation MUST require a concrete feature description first
|
|
214
|
+
- Java package segments MUST be valid identifiers; do NOT place kebab-case directly into Java package names
|
|
215
|
+
- Component generation MUST create/update `docs/component/<kebab-name>.md`
|
|
216
|
+
- Component tags MUST be kebab-case
|
|
217
|
+
- In Vue `h()`, do NOT use the fully-qualified Java class name
|
|
218
|
+
- Read plugin runtime installation references when the page must really use the plugin:
|
|
219
|
+
- `node_modules/@quicktvui/ai/rules/.docs/zh-CN/module/plugin.md`
|
|
220
|
+
- `node_modules/@quicktvui/ai/rules/.docs/examples/module/plugin/es-basic.vue`
|
|
221
|
+
- `node_modules/@quicktvui/ai/rules/.source/quicktvui/src/long-image/index.vue`
|
|
222
|
+
- Build/upload success does NOT mean the Vue page can already use the plugin.
|
|
223
|
+
- If a Vue page depends on the plugin, use `useESPlugin()` from `@extscreen/es3-core`, add listeners in `onESCreate`, and remove them in `onESDestroy`.
|
|
224
|
+
- For component plugins, call `useES().isComponentRegistered("<fully-qualified-component-class>")` before using the component, and install the plugin first when registration is still missing.
|
|
225
|
+
- Gate plugin-dependent rendering and calls on installation / registration readiness instead of assuming upload or install finishes synchronously.
|
|
226
|
+
- Scaffold structure should follow `.source/sdk/base/...`, but live device logs override the default runtime namespace when startup fails.
|
|
227
|
+
- 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.
|
|
228
|
+
- 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.
|
|
229
|
+
- Do not confuse local stub compilation with device runtime availability.
|
|
230
|
+
- After install success, allow a short retry/recheck window if registration is still briefly missing.
|
|
231
|
+
- After reuploading a compatibility-fixed plugin build, restart the host/runtime process before retesting.
|
|
232
|
+
- If docs drift from source or implementation, AI MUST update docs
|
|
105
233
|
|
|
106
234
|
## Game Loop & Timer Constraints (CRITICAL)
|
|
107
235
|
|
package/rules/.cursorrules
CHANGED
|
@@ -102,6 +102,134 @@ Required CLI order:
|
|
|
102
102
|
|
|
103
103
|
AI MUST NOT claim it inspected runtime data unless MCP or `quicktvui-ai debug-*` actually returned it.
|
|
104
104
|
|
|
105
|
+
## Plugin Server Workflow (CRITICAL)
|
|
106
|
+
|
|
107
|
+
When the user asks AI to inspect, upload, or debug TV plugin server endpoints (`/hello`, `/status`, `/uploadSo`, `/uploadPlugin`) or recent runtime load status from `/status`:
|
|
108
|
+
|
|
109
|
+
1. Prefer connected `quicktvui-ai-mcp` plugin tools:
|
|
110
|
+
- `plugin_server_check`
|
|
111
|
+
- `plugin_server_hello`
|
|
112
|
+
- `plugin_server_status`
|
|
113
|
+
- `quicktvui_runtime_status`
|
|
114
|
+
- `plugin_upload_so`
|
|
115
|
+
- `plugin_upload_plugin`
|
|
116
|
+
2. Otherwise use `quicktvui-ai plugin-*`
|
|
117
|
+
3. Only fall back to manual `adb` + `curl` when neither path is available
|
|
118
|
+
|
|
119
|
+
Required order:
|
|
120
|
+
|
|
121
|
+
1. Enable Toolkit RESTful API first:
|
|
122
|
+
- `quicktvui-ai plugin-enable-api --device <serial>`
|
|
123
|
+
- manual fallback: `adb -s <serial> shell am broadcast -a "eskit.sdk.core.ACTION_TOOLKIT_SETTING" --es "RESTFUL_API" "true"`
|
|
124
|
+
2. Probe readiness:
|
|
125
|
+
- `plugin_server_check`
|
|
126
|
+
- or `quicktvui-ai plugin-check --device <serial>`
|
|
127
|
+
3. Read current state:
|
|
128
|
+
- `plugin_server_status`
|
|
129
|
+
- or `quicktvui-ai plugin-status --device <serial>`
|
|
130
|
+
4. If the task is to inspect recent runtime load state or latest error info after quick-app/plugin load:
|
|
131
|
+
- `quicktvui_runtime_status`
|
|
132
|
+
- or `quicktvui-ai runtime-status --device <serial>`
|
|
133
|
+
5. Upload So zip:
|
|
134
|
+
- choose the archive matching `ro.product.cpu.abi` on the service-corresponding device
|
|
135
|
+
- `quicktvui-ai plugin-upload-so --device <serial> --tag eskit.so.ffmpeg.command --pkg eskit.so.ffmpeg.command --file <zip-path>`
|
|
136
|
+
5. Upload plugin APK:
|
|
137
|
+
- `quicktvui-ai plugin-upload-plugin --device <serial> --pkg eskit.plugin.imagequality --file <apk-path>`
|
|
138
|
+
|
|
139
|
+
Hard requirements:
|
|
140
|
+
|
|
141
|
+
- Runtime endpoint behavior overrides markdown docs.
|
|
142
|
+
- Probe `/hello`, `/status`, `/uploadSo`, `/uploadPlugin` with `POST`, not `GET`.
|
|
143
|
+
- `/status` may include `data.loadStatus`, which is the authoritative recent runtime load-state/error map for quick-app/plugin startup. After `run-dev`, `run-esapp`, page-side install, or a startup failure, query `quicktvui_runtime_status` / `runtime-status` and report the package key plus `__debug__`.
|
|
144
|
+
- Resolve plugin server address in this order:
|
|
145
|
+
- explicit `baseUrl` / `--plugin-base-url`
|
|
146
|
+
- adb-connected device service address
|
|
147
|
+
- adb forward + `http://127.0.0.1:36366` when target host cannot be inferred
|
|
148
|
+
- If multiple adb devices are connected, ask the user to choose `serial` or provide service IP / `baseUrl`.
|
|
149
|
+
- If no adb-connected device exists, ask the user for service IP / `baseUrl` and never invent a developer-specific TV IP.
|
|
150
|
+
- If AI is working inside the `quicktvui-ai` repo and finds doc/runtime drift, AI MUST update the docs.
|
|
151
|
+
- `uploadSo` currently has `pkg` / `tag` drift. AI SHOULD send both fields and trust successful `data.tag`.
|
|
152
|
+
- Default demo identifiers:
|
|
153
|
+
- So package/tag: `eskit.so.ffmpeg.command`
|
|
154
|
+
- Plugin package: `eskit.plugin.imagequality`
|
|
155
|
+
- 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.
|
|
156
|
+
- AI MUST NOT claim upload success unless MCP or CLI returned a success payload.
|
|
157
|
+
- `status.pluginList` may still be empty after `uploadPlugin` returns `registered: true`; report that exact state.
|
|
158
|
+
- `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.
|
|
159
|
+
- 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.
|
|
160
|
+
- Consult:
|
|
161
|
+
- `node_modules/@quicktvui/ai/rules/.docs/zh-CN/tool/api/plugin-server-api.md`
|
|
162
|
+
- `node_modules/@quicktvui/ai/rules/.docs/zh-CN/tool/api/runtime-status.md`
|
|
163
|
+
- `node_modules/@quicktvui/ai/rules/.docs/zh-CN/tool/cli/plugin-server.md`
|
|
164
|
+
- `node_modules/@quicktvui/ai/rules/.docs/zh-CN/tool/cli/runtime-status.md`
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
## Plugin Scaffold Workflow (CRITICAL)
|
|
168
|
+
|
|
169
|
+
When the user asks AI to create/update/build Android plugin projects, native modules, or native UI components, AI MUST use this priority:
|
|
170
|
+
|
|
171
|
+
1. Prefer connected `quicktvui-ai-mcp` tools:
|
|
172
|
+
- `plugin_project_create`
|
|
173
|
+
- `plugin_project_build`
|
|
174
|
+
- `plugin_module_create`
|
|
175
|
+
- `plugin_component_create`
|
|
176
|
+
2. Otherwise use `quicktvui-ai`:
|
|
177
|
+
- `plugin-create-project`
|
|
178
|
+
- `plugin-build`
|
|
179
|
+
- `plugin-create-module`
|
|
180
|
+
- `plugin-create-component`
|
|
181
|
+
3. Only if neither MCP nor CLI execution is available may AI scaffold manually
|
|
182
|
+
|
|
183
|
+
Decision rules:
|
|
184
|
+
|
|
185
|
+
- Project init / update / packaging -> `plugin_project_create` / `plugin_project_build`
|
|
186
|
+
- Non-UI native capability -> `plugin_module_create`
|
|
187
|
+
- Native View + props/events/functions -> `plugin_component_create`
|
|
188
|
+
|
|
189
|
+
Hard requirements:
|
|
190
|
+
|
|
191
|
+
- Read these packaged docs first:
|
|
192
|
+
- `node_modules/@quicktvui/ai/rules/.docs/zh-CN/tool/cli/plugin-create-project.md`
|
|
193
|
+
- `node_modules/@quicktvui/ai/rules/.docs/zh-CN/tool/cli/plugin-create-module.md`
|
|
194
|
+
- `node_modules/@quicktvui/ai/rules/.docs/zh-CN/tool/cli/plugin-create-component.md`
|
|
195
|
+
- `node_modules/@quicktvui/ai/rules/.docs/zh-CN/tool/api/plugin-scaffold-mcp.md`
|
|
196
|
+
- Source-of-truth interfaces come from `.source/sdk/base/...`:
|
|
197
|
+
- `com.quicktvui.sdk.base.module.IEsModule`
|
|
198
|
+
- `com.quicktvui.sdk.base.component.IEsComponent`
|
|
199
|
+
- `com.quicktvui.sdk.base.component.IEsComponentView`
|
|
200
|
+
- `com.quicktvui.sdk.base.component.EsComponentAttribute`
|
|
201
|
+
- Project creation MUST write `.kyy-plugin-project.json`
|
|
202
|
+
- By default, long-lived or releasable plugin projects SHOULD live under `<project-root>/plugin/<plugin-name>`
|
|
203
|
+
- Plugin projects MUST NOT default to hidden directories such as `.ai-test/*` or other dot-prefixed paths
|
|
204
|
+
- If plugin project is under a workspace subdirectory and root has `package.json`, AI MUST inject `build:android-plugin`
|
|
205
|
+
- Build order MUST be:
|
|
206
|
+
1. `npm run build:android-plugin`
|
|
207
|
+
2. `npm run build:plugin`
|
|
208
|
+
3. `npm run build`
|
|
209
|
+
4. `./gradlew assembleGeneralDebug`
|
|
210
|
+
- If plugin build reports missing Android SDK, resolve SDK generically in this order: `ANDROID_SDK_ROOT` -> `ANDROID_HOME` -> platform default SDK directories.
|
|
211
|
+
- 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.
|
|
212
|
+
- Never turn one developer's local Android SDK path into a shared rule, hardcoded project setting, or committed repository file.
|
|
213
|
+
- Module/component generation MUST require a concrete feature description first
|
|
214
|
+
- Java package segments MUST be valid identifiers; do NOT place kebab-case directly into Java package names
|
|
215
|
+
- Component generation MUST create/update `docs/component/<kebab-name>.md`
|
|
216
|
+
- Component tags MUST be kebab-case
|
|
217
|
+
- In Vue `h()`, do NOT use the fully-qualified Java class name
|
|
218
|
+
- Read plugin runtime installation references when the page must really use the plugin:
|
|
219
|
+
- `node_modules/@quicktvui/ai/rules/.docs/zh-CN/module/plugin.md`
|
|
220
|
+
- `node_modules/@quicktvui/ai/rules/.docs/examples/module/plugin/es-basic.vue`
|
|
221
|
+
- `node_modules/@quicktvui/ai/rules/.source/quicktvui/src/long-image/index.vue`
|
|
222
|
+
- Build/upload success does NOT mean the Vue page can already use the plugin.
|
|
223
|
+
- If a Vue page depends on the plugin, use `useESPlugin()` from `@extscreen/es3-core`, add listeners in `onESCreate`, and remove them in `onESDestroy`.
|
|
224
|
+
- For component plugins, call `useES().isComponentRegistered("<fully-qualified-component-class>")` before using the component, and install the plugin first when registration is still missing.
|
|
225
|
+
- Gate plugin-dependent rendering and calls on installation / registration readiness instead of assuming upload or install finishes synchronously.
|
|
226
|
+
- Scaffold structure should follow `.source/sdk/base/...`, but live device logs override the default runtime namespace when startup fails.
|
|
227
|
+
- 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.
|
|
228
|
+
- 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.
|
|
229
|
+
- Do not confuse local stub compilation with device runtime availability.
|
|
230
|
+
- After install success, allow a short retry/recheck window if registration is still briefly missing.
|
|
231
|
+
- After reuploading a compatibility-fixed plugin build, restart the host/runtime process before retesting.
|
|
232
|
+
- If docs drift from source or implementation, AI MUST update docs
|
|
105
233
|
|
|
106
234
|
## Game Loop & Timer Constraints (CRITICAL)
|
|
107
235
|
|
|
@@ -94,6 +94,10 @@ qt.view.requestFocus(viewRef)
|
|
|
94
94
|
| `qt.brightness` | ESBrightness | [点击查看详细API](/zh-CN/module/brightness#exposes) |
|
|
95
95
|
| `qt.service` | ESService | [点击查看详细API](/zh-CN/module/service#exposes) |
|
|
96
96
|
|
|
97
|
+
## QuickTVUI AI 插件接口工作流
|
|
98
|
+
|
|
99
|
+
* 插件服务接口 [`plugin-server-api`](/zh-CN/tool/api/plugin-server-api)
|
|
100
|
+
* 插件脚手架 MCP [`plugin-scaffold-mcp`](/zh-CN/tool/api/plugin-scaffold-mcp)
|
|
97
101
|
|
|
98
102
|
|
|
99
103
|
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Plugin Scaffold MCP
|
|
3
|
+
lang: zh-CN
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# 插件创建 MCP 工具
|
|
7
|
+
|
|
8
|
+
## 一、工具列表
|
|
9
|
+
|
|
10
|
+
| 工具 | 用途 |
|
|
11
|
+
| ---- | ---- |
|
|
12
|
+
| `plugin_project_create` | 创建或更新插件工程 |
|
|
13
|
+
| `plugin_project_build` | 打包插件工程 |
|
|
14
|
+
| `plugin_module_create` | 创建无界面原生模块 |
|
|
15
|
+
| `plugin_component_create` | 创建有界面原生组件 |
|
|
16
|
+
|
|
17
|
+
## 二、使用优先级
|
|
18
|
+
|
|
19
|
+
当 AI 在支持 MCP 的客户端中工作时,插件创建类任务应优先调用上述工具,而不是直接手写文件。
|
|
20
|
+
|
|
21
|
+
## 三、决策规则
|
|
22
|
+
|
|
23
|
+
1. 创建工程或打包工程:使用 `plugin_project_create` / `plugin_project_build`
|
|
24
|
+
2. 无独立原生 UI 的原生能力:使用 `plugin_module_create`
|
|
25
|
+
3. 有原生 View、属性、事件、方法的能力:使用 `plugin_component_create`
|
|
26
|
+
|
|
27
|
+
## 四、硬约束
|
|
28
|
+
|
|
29
|
+
1. 真实源码优先于 markdown 文档
|
|
30
|
+
2. `plugin_module_create` 必须按 `com.quicktvui.sdk.base.module.IEsModule` 生成
|
|
31
|
+
3. `plugin_component_create` 必须按 `com.quicktvui.sdk.base.component.IEsComponent`、`IEsComponentView`、`EsComponentAttribute` 生成
|
|
32
|
+
4. 组件必须补 `docs/component/<name>.md`
|
|
33
|
+
5. 组件标签必须使用 `kebab-case`
|
|
34
|
+
6. `plugin_project_build` 构建前应优先复用 CLI 的通用 Android SDK 探测逻辑:先看 `ANDROID_SDK_ROOT` / `ANDROID_HOME`,再看平台默认 SDK 目录
|
|
35
|
+
7. 如探测到 SDK 且目标工程缺少 `local.properties` / `sdk.dir`,允许工具在目标插件工程内自动补齐本地 `local.properties`
|
|
36
|
+
8. `local.properties` 只属于开发机本地配置,不应作为共享工程规则提交
|
|
37
|
+
9. 长期保留或准备发布的插件工程,默认应创建到项目根目录下可见的 `plugin/<plugin-name>`
|
|
38
|
+
10. 不要把插件工程默认创建到 `.ai-test/*` 等隐藏目录
|
|
39
|
+
11. 插件工程打包成功或插件包上传成功,并不代表 Vue 页面已经可直接使用插件
|
|
40
|
+
12. 如果页面里要实际使用插件,AI 还必须补齐 Vue 侧安装逻辑:`useESPlugin()`、`addListener` / `removeListener`、`installPlugin({ pkg })`
|
|
41
|
+
13. 对于组件型插件,优先参考 `module/plugin` 文档与 `quicktvui/src/long-image/index.vue`,先用 `useES().isComponentRegistered("<组件完整类名>")` 检查注册状态,再决定是否安装或渲染
|
|
42
|
+
14. 脚手架结构默认按 `.source/sdk/base/...` 生成,但一旦设备日志显示 `ClassNotFoundException: com.quicktvui.sdk.base.core.EsProxy` 或缺失 `com.quicktvui.sdk.base.*`,应立即把运行时日志视为更高优先级的兼容性信号
|
|
43
|
+
15. 这类报错通常表示本地 stub 可编译,但目标 TV 运行时只暴露旧命名空间;AI 应切换运行时侧注册/导入到设备真实存在的命名空间后重新构建、重传
|
|
44
|
+
16. 页面侧收到安装成功回调后,如注册状态仍短暂不可见,允许一个简短轮询复查窗口,再决定是否判定失败
|
|
45
|
+
17. 如果设备日志出现 `java.lang.NoSuchMethodError: No static method get()Leskit/sdk/support/core/EsProxy;`,应视为插件注册入口的字节码签名不兼容,而不是页面逻辑问题;AI 应按设备真实 runtime 的 `EsProxy.get()` 签名 / 调用路径调整注册实现后重新构建、重传
|
|
46
|
+
18. 如果是为修复运行时兼容性而重新上传的新插件版本,AI 在复测前必须先重启宿主 / runtime 进程,否则当前进程仍可能持有旧插件字节码
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Plugin Server API
|
|
3
|
+
lang: zh-CN
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# 插件服务接口
|
|
7
|
+
|
|
8
|
+
## 一、概述
|
|
9
|
+
|
|
10
|
+
电视侧插件服务默认监听 `36366` 端口,接口根路径为:
|
|
11
|
+
|
|
12
|
+
```text
|
|
13
|
+
http://<tv-ip>:36366/api/v1
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
在调用 `/hello`、`/status`、`/uploadSo`、`/uploadPlugin` 之前,必须先通过 Toolkit 广播打开 `RESTFUL_API`。
|
|
17
|
+
|
|
18
|
+
重要约束:
|
|
19
|
+
|
|
20
|
+
1. 文档与接口返回不一致时,统一以接口真实返回为准。
|
|
21
|
+
2. 这些接口要求使用 `POST`;同路径 `GET` 在实测设备上可能返回 `404`。
|
|
22
|
+
3. `uploadSo` 已观察到 `pkg` / `tag` 字段漂移;调用时建议同时传这两个字段。
|
|
23
|
+
4. `status.pluginList` 可能在 `uploadPlugin` 返回 `registered: true` 后仍为空,这属于真实接口行为,不能自行推导为失败或成功安装完成。
|
|
24
|
+
5. QuickTVUI AI 工具在未显式传 `baseUrl` 时,会优先尝试 adb 已连接设备的插件服务地址;如果没有 adb 设备,AI 应先向用户索要服务 IP / `baseUrl`。
|
|
25
|
+
6. `abi` 只在上传 So 时才需要。CLI / MCP 如果在 `uploadSo` 时未显式传 `abi`,会尝试读取当前插件服务对应设备的 `ro.product.cpu.abi` 并按需补齐;`check` / `hello` / `status` / `uploadPlugin` 不会主动查询 ABI。
|
|
26
|
+
7. `uploadPlugin` 返回成功,只代表插件包已上传到插件服务缓存;如果 Vue 页面需要实际使用该插件,还必须在页面侧通过 `useESPlugin()` 监听并调用 `installPlugin({ pkg })`,不能把“上传成功”误当成“页面已安装完成”。
|
|
27
|
+
8. 上传新的插件包到服务后,当前宿主 / runtime 进程不会自动热更新到新字节码;复测启动、注册或页面接入前,必须先重启宿主进程。
|
|
28
|
+
9. 当快应用、插件或页面刚刚发起加载后,若需要继续查看最近一次加载状态与错误信息,应优先查询 `/status` 中的 `data.loadStatus`,推荐参考同目录 `runtime-status.md`。
|
|
29
|
+
|
|
30
|
+
## 二、开启服务
|
|
31
|
+
|
|
32
|
+
### 2.1 adb 广播
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
adb -s <serial> shell am broadcast -a "eskit.sdk.core.ACTION_TOOLKIT_SETTING" --es "RESTFUL_API" "true"
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### 2.2 QuickTVUI AI CLI
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
quicktvui-ai plugin-enable-api --device <serial>
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## 三、接口列表
|
|
45
|
+
|
|
46
|
+
### 3.1 `POST /hello`
|
|
47
|
+
|
|
48
|
+
用途:确认服务已启动。
|
|
49
|
+
|
|
50
|
+
典型响应:
|
|
51
|
+
|
|
52
|
+
```json
|
|
53
|
+
{
|
|
54
|
+
"code": 0,
|
|
55
|
+
"message": "success",
|
|
56
|
+
"data": {}
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### 3.2 `POST /status`
|
|
61
|
+
|
|
62
|
+
用途:读取当前插件服务缓存状态。
|
|
63
|
+
|
|
64
|
+
典型响应:
|
|
65
|
+
|
|
66
|
+
```json
|
|
67
|
+
{
|
|
68
|
+
"code": 0,
|
|
69
|
+
"message": "success",
|
|
70
|
+
"data": {
|
|
71
|
+
"soList": [
|
|
72
|
+
"eskit.so.player.v1"
|
|
73
|
+
],
|
|
74
|
+
"pluginList": [],
|
|
75
|
+
"loadStatus": {
|
|
76
|
+
"es.extscreen.runtime.error": {
|
|
77
|
+
"status": "SUCCESS",
|
|
78
|
+
"message": ""
|
|
79
|
+
},
|
|
80
|
+
"__debug__": {
|
|
81
|
+
"status": "ERROR",
|
|
82
|
+
"message": "网络不可用,请检查网络后重试"
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
说明:
|
|
90
|
+
|
|
91
|
+
1. `soList` / `pluginList` / `loadStatus` 都以当前服务实际返回为准,不应脑补额外状态。
|
|
92
|
+
2. 即使上传插件成功,`pluginList` 也可能仍为空。
|
|
93
|
+
3. `loadStatus` 用于表达最近一次加载状态映射,key 一般是包名或 `__debug__`。
|
|
94
|
+
4. 当快应用加载失败、页面没起来、或插件安装后仍不可用时,AI 应优先继续分析 `loadStatus` 中对应项的 `status` / `message`。
|
|
95
|
+
5. QuickTVUI AI 推荐命令:
|
|
96
|
+
- CLI:`quicktvui-ai runtime-status --device <serial>`
|
|
97
|
+
- MCP:`quicktvui_runtime_status`
|
|
98
|
+
|
|
99
|
+
### 3.3 `POST /uploadSo`
|
|
100
|
+
|
|
101
|
+
用途:上传 So zip。
|
|
102
|
+
|
|
103
|
+
推荐请求方式:`multipart/form-data`
|
|
104
|
+
|
|
105
|
+
建议字段:
|
|
106
|
+
|
|
107
|
+
| 字段 | 必填 | 说明 |
|
|
108
|
+
| ---- | ---- | ---- |
|
|
109
|
+
| `tag` | 是 | So 标识,建议与包名保持一致 |
|
|
110
|
+
| `pkg` | 是 | 兼容字段,当前建议与 `tag` 同时传 |
|
|
111
|
+
| `abi` | 是 | 目标设备 ABI,例如 `armeabi-v7a` / `arm64-v8a`;CLI / MCP 在 `uploadSo` 且未显式传值时,会尝试按当前服务目标设备自动补齐 |
|
|
112
|
+
| `osCpuAbi` | 否 | 建议与 `abi` 保持一致 |
|
|
113
|
+
| `file` | 是 | zip 文件 |
|
|
114
|
+
| `fileName` / `name` | 否 | 上传文件名 |
|
|
115
|
+
|
|
116
|
+
空请求实测返回:
|
|
117
|
+
|
|
118
|
+
```json
|
|
119
|
+
{
|
|
120
|
+
"code": 400,
|
|
121
|
+
"message": "tag is required",
|
|
122
|
+
"data": null
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
成功响应示例:
|
|
127
|
+
|
|
128
|
+
```json
|
|
129
|
+
{
|
|
130
|
+
"code": 0,
|
|
131
|
+
"message": "success",
|
|
132
|
+
"data": {
|
|
133
|
+
"tag": "eskit.so.ffmpeg.command",
|
|
134
|
+
"abi": "armeabi-v7a",
|
|
135
|
+
"fileName": "armeabi-v7a.zip",
|
|
136
|
+
"filePath": "/data/user/0/tv.eskit.debugger/cache/rpk/local_install_so/eskit.so.ffmpeg.command/armeabi-v7a/armeabi-v7a.zip",
|
|
137
|
+
"size": 4623751,
|
|
138
|
+
"registered": true
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
说明:
|
|
144
|
+
|
|
145
|
+
1. 返回字段以 `data.tag` 为准。
|
|
146
|
+
2. `filePath` 实测会带 `rpk/local_install_so/` 路径层级。
|
|
147
|
+
3. 上传前必须根据当前插件服务对应设备的 `ro.product.cpu.abi` 选择正确的 zip。
|
|
148
|
+
|
|
149
|
+
### 3.4 `POST /uploadPlugin`
|
|
150
|
+
|
|
151
|
+
用途:上传插件 APK。
|
|
152
|
+
|
|
153
|
+
推荐请求方式:`multipart/form-data`
|
|
154
|
+
|
|
155
|
+
建议字段:
|
|
156
|
+
|
|
157
|
+
| 字段 | 必填 | 说明 |
|
|
158
|
+
| ---- | ---- | ---- |
|
|
159
|
+
| `pkg` | 是 | 插件包名 |
|
|
160
|
+
| `packageName` | 否 | 兼容字段,建议与 `pkg` 同时传 |
|
|
161
|
+
| `file` | 是 | APK 文件 |
|
|
162
|
+
| `fileName` / `name` | 否 | 上传文件名 |
|
|
163
|
+
|
|
164
|
+
空请求实测返回:
|
|
165
|
+
|
|
166
|
+
```json
|
|
167
|
+
{
|
|
168
|
+
"code": 400,
|
|
169
|
+
"message": "pkg is required",
|
|
170
|
+
"data": null
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
成功响应示例:
|
|
175
|
+
|
|
176
|
+
```json
|
|
177
|
+
{
|
|
178
|
+
"code": 0,
|
|
179
|
+
"message": "success",
|
|
180
|
+
"data": {
|
|
181
|
+
"pkg": "eskit.plugin.imagequality",
|
|
182
|
+
"fileName": "plugin-general-debug.apk",
|
|
183
|
+
"filePath": "/data/user/0/tv.eskit.debugger/cache/rpk/local_upload_plugin/eskit.plugin.imagequality/plugin-general-debug.apk",
|
|
184
|
+
"size": 89578,
|
|
185
|
+
"registered": true
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
说明:
|
|
191
|
+
|
|
192
|
+
1. `filePath` 实测会带 `rpk/local_upload_plugin/` 路径层级。
|
|
193
|
+
2. `registered: true` 只代表接口返回注册成功,不代表 `status.pluginList` 一定马上可见。
|
|
194
|
+
3. 如果业务页面要真正使用该插件,还必须在 Vue 侧调用插件安装流程,推荐参考 `module/plugin` 文档、`module/plugin/es-basic.vue` 示例,以及 `quicktvui/src/long-image/index.vue` 的注册检查实现。
|
|
195
|
+
4. 如果上传成功但设备日志出现 `ClassNotFoundException: com.quicktvui.sdk.base.core.EsProxy` 或缺失 `com.quicktvui.sdk.base.*`,应视为运行时命名空间兼容性问题,而不是插件服务上传失败。
|
|
196
|
+
5. 如果设备日志出现 `java.lang.NoSuchMethodError: No static method get()Leskit/sdk/support/core/EsProxy;`,应视为插件注册入口的字节码签名与设备 runtime 不兼容;需要改成匹配设备真实 `EsProxy.get()` 签名 / 调用路径的实现后重新构建、重传。
|
|
197
|
+
6. 上传新的插件版本后,必须先重启宿主 / runtime 进程,再验证插件启动、注册和页面侧安装,否则当前进程仍可能持有旧插件字节码。
|
|
198
|
+
|
|
199
|
+
## 四、测试 Demo 标识
|
|
200
|
+
|
|
201
|
+
推荐默认测试标识:
|
|
202
|
+
|
|
203
|
+
| 类型 | 标识 |
|
|
204
|
+
| ---- | ---- |
|
|
205
|
+
| So 包名 / tag | `eskit.so.ffmpeg.command` |
|
|
206
|
+
| 插件包名 | `eskit.plugin.imagequality` |
|
|
207
|
+
|
|
208
|
+
本地测试文件映射:
|
|
209
|
+
|
|
210
|
+
| 文件 | 用途 | 对应标识 |
|
|
211
|
+
| ---- | ---- | -------- |
|
|
212
|
+
| `docs/plugin/arm64-v8a.zip` | arm64-v8a So 包 | `eskit.so.ffmpeg.command` |
|
|
213
|
+
| `docs/plugin/armeabi-v7a.zip` | armeabi-v7a So 包 | `eskit.so.ffmpeg.command` |
|
|
214
|
+
| `docs/plugin/plugin-general-debug.apk` | 插件 APK | `eskit.plugin.imagequality` |
|