chaoxing-work-cua 0.0.0-stage → 1.0.0
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/LICENSE +21 -0
- package/README.md +111 -2
- package/SKILL.md +280 -0
- package/bin/install.js +56 -0
- package/package.json +28 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 chaoxing-work-cua contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,112 @@
|
|
|
1
|
-
#
|
|
1
|
+
# chaoxing-work-cua
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> 一个基于 **Computer Use(计算机操作代理)** 的在线作业自动作答 Skill 模板,
|
|
4
|
+
> 以超星学习通(chaoxing.com)作业页面为例,沉淀了从读题、作答到保存提交的
|
|
5
|
+
> 完整自动化流程,以及实操中踩过的**全部坑**与规避方法。
|
|
6
|
+
|
|
7
|
+
[](LICENSE)
|
|
8
|
+
[](#平台适配改造点)
|
|
9
|
+
[](#这是什么)
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## ⚠️ 免责声明
|
|
14
|
+
|
|
15
|
+
- 本项目**只是一个自动化方法论的模板**,不含任何真实课程、题目、答案或个人信息。
|
|
16
|
+
- 请仅用于**自动化你自己的作业操作流程**或学习 Computer Use 自动化技术。
|
|
17
|
+
- 是否允许使用作业辅助工具,请遵循你所在学校/平台的规定;**因使用不当产生的
|
|
18
|
+
一切后果由使用者自行承担**。
|
|
19
|
+
- 请勿将本模板用于作弊、代写或任何违反学术诚信的行为。
|
|
20
|
+
|
|
21
|
+
## 这是什么
|
|
22
|
+
|
|
23
|
+
这是一个给支持 **Computer Use** 能力的 AI Agent(如 ZCode / Claude Code +
|
|
24
|
+
computer-use 插件)使用的 **Skill(技能指令文件)**。安装后,当用户打开在线作业
|
|
25
|
+
页面说"帮我做题"时,Agent 会按照本 Skill 沉淀的实战流程完成:
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
读题(截图 + 视觉转录) → 客观题点选 → 填空/简答键盘录入
|
|
29
|
+
→ 逐项截图验证 → 暂时保存 → (经用户确认后)提交
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## ✨ 核心经验(为什么值得用)
|
|
33
|
+
|
|
34
|
+
全部内容来自真实多轮实操(累计完成 30+ 题、跨 5 份作业、2 个账号),每条规则
|
|
35
|
+
都对应一次真实返工:
|
|
36
|
+
|
|
37
|
+
- **表单控件不在无障碍树里** → 读题靠截图+视觉,操作靠坐标+键盘
|
|
38
|
+
- **坐标事件要求前台** → 用户一切窗口焦点就会失效,每次操作前重新前台化
|
|
39
|
+
- **多标签页标题全部同名** → 必须用 URL 里的 `workId` 校验,否则会答错别人的卷子
|
|
40
|
+
- **坐标必须来自当前帧** → 页面一动旧坐标就作废,用"路标+元素间距"推算而不是目测
|
|
41
|
+
- **富文本编辑器屏蔽粘贴** → 一律模拟键盘逐字输入(支持中文)
|
|
42
|
+
- **段落以"1."开头会触发自动编号** → 变成"2.2."重复,改用"(1)(2)"
|
|
43
|
+
- **保存 toast 只有 2 秒** → 错过不代表失败,以最终提交结果页为权威验证
|
|
44
|
+
- ……共 **11 条硬规则 + 12 行报错对照表**,详见 [SKILL.md](SKILL.md)
|
|
45
|
+
|
|
46
|
+
## 📦 安装
|
|
47
|
+
|
|
48
|
+
### 方式一:npx 一键安装(推荐)
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
npx chaoxing-work-cua
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
会自动把 SKILL.md 安装到已存在的 Agent 技能目录
|
|
55
|
+
(按 `~/.agents/skills` → `~/.zcode/skills` → `~/.claude/skills` 顺序检测,
|
|
56
|
+
都不存在时装到 `~/.agents/skills`)。
|
|
57
|
+
|
|
58
|
+
指定安装位置:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
npx chaoxing-work-cua --target "D:\my-agent\skills"
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### 方式二:手动安装
|
|
65
|
+
|
|
66
|
+
把 `SKILL.md` 放到你所用 Agent 的技能目录下,例如:
|
|
67
|
+
|
|
68
|
+
```text
|
|
69
|
+
# ZCode / Claude Code 用户技能目录(Windows 示例)
|
|
70
|
+
C:\Users\<你>\.agents\skills\chaoxing-work-cua\SKILL.md
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
前置要求:
|
|
74
|
+
|
|
75
|
+
- Agent 具备 Computer Use / 计算机操作能力(截图、点击、键盘输入)
|
|
76
|
+
- 浏览器中已登录作业平台账号,并打开作业页面
|
|
77
|
+
|
|
78
|
+
## 🚀 使用
|
|
79
|
+
|
|
80
|
+
1. 在浏览器中打开作业页面(可以同时开多份,Skill 会用 URL 参数区分)。
|
|
81
|
+
2. 对 Agent 说:"帮我做一下打开的作业 / 依次完成这几份作业"。
|
|
82
|
+
3. Agent 会自动:枚举作业 → 读题 → 核实客观题答案 → 逐题作答 → 验证 → 暂时保存。
|
|
83
|
+
4. 提交属于不可逆动作,**默认只暂时保存**;确认无误后明确告诉 Agent"提交"即可。
|
|
84
|
+
|
|
85
|
+
## 📁 目录结构
|
|
86
|
+
|
|
87
|
+
```text
|
|
88
|
+
chaoxing-work-cua/
|
|
89
|
+
├── README.md # 本文件
|
|
90
|
+
├── SKILL.md # Skill 主文件:完整流程 + 踩坑手册 + 可复用代码片段
|
|
91
|
+
└── LICENSE # MIT
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## 🔧 平台适配改造点
|
|
95
|
+
|
|
96
|
+
模板以学习通为例,换其他在线作业平台只需替换(见 SKILL.md 末尾对照表):
|
|
97
|
+
|
|
98
|
+
| 改造点 | 说明 |
|
|
99
|
+
|---|---|
|
|
100
|
+
| 业务主键参数 | 作业页 URL 中的唯一标识(如 `workId=`) |
|
|
101
|
+
| 标签页标题特征 | 用于枚举同名作业标签的正则 |
|
|
102
|
+
| 保存/提交按钮文案与坐标 | 重新实测 |
|
|
103
|
+
| 富文本编辑器行为 | 自动编号、粘贴屏蔽等特性逐个实测 |
|
|
104
|
+
| 布局偏移量表 | 按目标平台重新标定 |
|
|
105
|
+
|
|
106
|
+
## 🤝 贡献
|
|
107
|
+
|
|
108
|
+
欢迎提 Issue / PR 补充:新平台的适配参数、新踩到的坑、更稳的校准方法。
|
|
109
|
+
|
|
110
|
+
## 📄 License
|
|
111
|
+
|
|
112
|
+
[MIT](LICENSE)
|
package/SKILL.md
ADDED
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: chaoxing-work-cua
|
|
3
|
+
description: 用 Computer Use (CUA) 在浏览器中自动作答超星学习通等在线作业平台的作业。当用户提供作业页面链接,或屏幕上已打开作业页面并要求自动作答时使用。封装读题、填空题、单选题、简答题、暂时保存与提交的完整流程,以及实操中踩过的全部坑的规避方法。可按"平台适配改造点"一节改造为其他在线作业平台的模板。
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# 在线作业自动作答 Skill 模板(Computer Use 实战手册)
|
|
7
|
+
|
|
8
|
+
> 本文件是一份**通用模板**:以超星学习通(chaoxing.com)作业页面为例沉淀的 Computer Use
|
|
9
|
+
> 自动化方法论。不含任何真实课程、题目、答案或个人信息;换一个在线作业平台时,
|
|
10
|
+
> 只需按文末「平台适配改造点」替换平台相关的细节即可复用。
|
|
11
|
+
|
|
12
|
+
## TL;DR 硬规则(违反必返工)
|
|
13
|
+
|
|
14
|
+
1. **每个脚本调用都是全新执行环境**。上一轮的绑定对象、import 全部消失,直接复用会报
|
|
15
|
+
`agent is not defined`。初始化代码必须放在**每个**执行单元的开头。
|
|
16
|
+
2. **网页表单控件通常不在无障碍树里**。浏览器 a11y 树一般只暴露浏览器外壳和部分页面
|
|
17
|
+
结构(导航、容器),输入框、单选圆圈、富文本编辑器**大多不可见**。读题靠截图+视觉
|
|
18
|
+
转录,操作靠坐标点击+键盘。
|
|
19
|
+
3. **坐标事件要求目标窗口在前台**。不在前台会被系统拦截(前台进程不匹配)。
|
|
20
|
+
**用户切回自己的窗口(比如给助手发消息)就会抢走焦点**,不能假设上一次的前台状态
|
|
21
|
+
仍然有效。
|
|
22
|
+
4. **坐标必须来自"当前"这帧截图,且靠"路标 + 元素间距"推算而非目测**。页面一滚动/
|
|
23
|
+
缩放,旧坐标立即作废——这是点错选项的唯一根源。方法见《滚动与坐标校准》。
|
|
24
|
+
5. **部分平台的富文本编辑器屏蔽粘贴事件**,`paste()` 毫无反应。一律用模拟键盘逐字
|
|
25
|
+
输入(`typeText`),它支持中文 Unicode,实测可靠。
|
|
26
|
+
6. **自动化框架返回的截图可能是带时效的临时 URL**,不是本地文件。拿到后直接交给视觉
|
|
27
|
+
模型转录,注意别过期。
|
|
28
|
+
7. **每个选项点击后都要截图验证选中高亮**。点击成功 ≠ 选对,页面偏移会点到相邻选项
|
|
29
|
+
(实测想点 B 结果选中了 C)。
|
|
30
|
+
8. **滚动参数要现场标定**:滚动单位可能是"一个滚动刻度"而非整页,实际像素随缩放/窗口
|
|
31
|
+
而变;且参数必须为整数。
|
|
32
|
+
9. **无障碍元素索引跨调用经常失效**(树会漂移)。正确姿势:同一执行单元内
|
|
33
|
+
`枚举 → 查找 → 点击`一气呵成,中间不要插入其他操作;失败就重取重试(≤3 次)。
|
|
34
|
+
10. **多标签页必须用 URL 参数校验身份**。同一平台的作业页标题往往完全相同(如都叫
|
|
35
|
+
"作业作答"),按标题找标签会切错,然后对着另一份作业操作。唯一可靠标识是 URL 中
|
|
36
|
+
的业务主键参数(如 `workId=`)。
|
|
37
|
+
11. **省 token 的帧绑定技巧**:截图接口支持"只绑定帧、不回显图片"的模式(如
|
|
38
|
+
`emit:false`)。任何"点击/滚动前需要重新绑定帧"的场合都用它,只有真正要读内容时
|
|
39
|
+
才回显截图。
|
|
40
|
+
|
|
41
|
+
## 可直接复制的代码片段
|
|
42
|
+
|
|
43
|
+
### 初始化(每个执行单元的开头)
|
|
44
|
+
|
|
45
|
+
```js
|
|
46
|
+
// 以 ZCode Computer Use 为例;其他框架替换为对应的初始化调用
|
|
47
|
+
const root =
|
|
48
|
+
process.env.ZCODE_CUA_PLUGIN_ROOT ??
|
|
49
|
+
process.env.ZCODE_PLUGIN_ROOT ??
|
|
50
|
+
process.env.CLAUDE_PLUGIN_ROOT;
|
|
51
|
+
const { join } = await import("node:path");
|
|
52
|
+
const { pathToFileURL } = await import("node:url");
|
|
53
|
+
const { setupComputerUseRuntime } = await import(
|
|
54
|
+
pathToFileURL(join(root, "scripts", "computer-use-client.mjs")).href,
|
|
55
|
+
);
|
|
56
|
+
await setupComputerUseRuntime({ globals: globalThis });
|
|
57
|
+
const app = await agent.computerUse.getApp({ pid: <浏览器进程pid> }); // 首次用 listApps() 查询
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### 确认"前台 + 目标标签页"(所有坐标操作前调用)
|
|
61
|
+
|
|
62
|
+
```js
|
|
63
|
+
function workId(els) {
|
|
64
|
+
const doc = els.find(e => e.kind === "textarea" && /workId=/.test(e.value || ""));
|
|
65
|
+
return doc ? (doc.value.match(/workId=(\d+)/) || [])[1] : null;
|
|
66
|
+
}
|
|
67
|
+
async function ensureReady(app, targetWorkId) {
|
|
68
|
+
let els = await app.elements();
|
|
69
|
+
if (workId(els) !== targetWorkId) {
|
|
70
|
+
const tabs = els.filter(e => e.kind === "tab" && /作业作答/.test(e.title || ""));
|
|
71
|
+
for (let i = 0; i < tabs.length; i++) {
|
|
72
|
+
await app.click(tabs[i].index); // 点击标签页同时起到激活窗口的作用
|
|
73
|
+
els = await app.elements();
|
|
74
|
+
if (workId(els) === targetWorkId) break;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return workId(els) === targetWorkId;
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
调用方式:`await ensureReady(app, "<目标作业的workId>")`,之后再做任何坐标操作。
|
|
82
|
+
它同时解决**前台化**(点击标签会激活窗口)和**切错标签**(workId 校验)两个问题。
|
|
83
|
+
|
|
84
|
+
### 无障碍跳题(读题阶段用,后台可用、不抢焦点)
|
|
85
|
+
|
|
86
|
+
```js
|
|
87
|
+
const els = await app.elements(); // 取完立刻用
|
|
88
|
+
const rowN = els.find(e => e.kind === "row" && e.title === String(n));
|
|
89
|
+
await app.click(rowN.index); // 点击题号导航
|
|
90
|
+
await app.getScreenshot(); // 截图给视觉模型转录
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
索引失效报错就重取重试。注意:点击题号 N 后**页面落点不稳定**(有时 N 在顶部,
|
|
94
|
+
有时 N 刚好滚出视口上方),所以跳转后的坐标一律以跳转后那张新截图为准。
|
|
95
|
+
|
|
96
|
+
## 滚动与坐标校准(防止点错的关键,先标定再动手)
|
|
97
|
+
|
|
98
|
+
**凭手感滚动和目测坐标是点错选项的唯一根源**(实测想点 B 因滚后未校准点成了 C)。
|
|
99
|
+
正确做法是三步:标定滚动格距 → 路标锚定 → 间距推算。
|
|
100
|
+
|
|
101
|
+
### 1. 标定"每格滚动多少像素"(每份作业开始时做一次)
|
|
102
|
+
|
|
103
|
+
```js
|
|
104
|
+
// 执行单元 A:滚 1 格并截图
|
|
105
|
+
await app.scroll([536, 600], "down", 1);
|
|
106
|
+
await app.getScreenshot();
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
对比滚动前后同一**路标**(如题号文本)的 y 坐标差,得到 `pxPerNotch`。之后要移动某
|
|
110
|
+
元素到目标位置时**用公式算,不要猜**:
|
|
111
|
+
|
|
112
|
+
```
|
|
113
|
+
scroll_amount = round((元素当前y - 期望y) / pxPerNotch)
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
滚动是近似的(平滑滚动、动态布局会有偏差),所以**每次滚动后必须重新截图确认落点**,
|
|
117
|
+
偏差大就补滚或微调,确认后再点击。
|
|
118
|
+
|
|
119
|
+
> 同理,**编辑器内容的变化等价于一次"滚动"**:清空重输、输入长文本都会让下方元素
|
|
120
|
+
> 大幅位移。凡是写过内容的执行单元,下一个单元的坐标必须基于新截图。
|
|
121
|
+
|
|
122
|
+
### 2. 路标锚定:坐标靠"算",不靠"目测"
|
|
123
|
+
|
|
124
|
+
页面每次滚动/跳转后,在新截图里先找一个**唯一、清晰的路标**(首选题号文本,它在截图
|
|
125
|
+
里的 y 坐标可以直接读出来),然后:
|
|
126
|
+
|
|
127
|
+
```
|
|
128
|
+
目标坐标 = 路标坐标 + (目标元素相对路标的固定偏移)
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
相对偏移在同一缩放级别下是**布局常量**,进入作答阶段时用第一帧截图一次性量好并记录
|
|
132
|
+
(示例实测值,以 110% 缩放、1072×1280 截图为例):
|
|
133
|
+
|
|
134
|
+
| 偏移 | 值 |
|
|
135
|
+
|---|---|
|
|
136
|
+
| 题号 → 题干首行 | ≈ +38px |
|
|
137
|
+
| 题号 → 第一个选项圆圈中心 | ≈ +120px |
|
|
138
|
+
| 单选选项圆圈之间(中心到中心) | ≈ +75px |
|
|
139
|
+
| 填空各空输入框之间(中心到中心) | ≈ +120px |
|
|
140
|
+
| 富文本编辑器可点击区 | 工具栏下方 ≥80px 的空白 |
|
|
141
|
+
|
|
142
|
+
这样看到路标在 (x, 447),第 3 个选项就是 y ≈ 447 + 120 + 75×2 = 717,**一帧截图推出
|
|
143
|
+
整题所有选项坐标**,不用逐个目测。缩放一变偏移全部作废,必须重新量。
|
|
144
|
+
|
|
145
|
+
### 3. 借助 snapshot_mode 判断坐标是否仍然有效
|
|
146
|
+
|
|
147
|
+
每次截图的结构化返回里有 `snapshot_mode`:
|
|
148
|
+
|
|
149
|
+
- `no_change`:页面没动,**旧坐标仍然有效**,可以直接继续点击;
|
|
150
|
+
- `full` / `delta`:页面变了(滚动了、内容增删了),**旧坐标全部作废**,必须重新定位。
|
|
151
|
+
|
|
152
|
+
跨步骤沿用坐标前先看这个字段,能省掉大量"点了没反应/点错"的返工。
|
|
153
|
+
|
|
154
|
+
### 4. 水平偏移校准
|
|
155
|
+
|
|
156
|
+
页面可能被横向滚动(症状:左侧标签被截断,"第1空"显示成"空",题干首字缺失)。处理:
|
|
157
|
+
|
|
158
|
+
- 校正:向左滚动(如 `scroll direction "left"`);
|
|
159
|
+
- 容忍:只影响读题时可忽略,但**转录题干时若首尾缺字,先怀疑水平偏移**,别当成题目
|
|
160
|
+
本身不完整。
|
|
161
|
+
|
|
162
|
+
## 完整流程
|
|
163
|
+
|
|
164
|
+
### 第 1 步:读题(先读完所有题,再开始答)
|
|
165
|
+
|
|
166
|
+
1. 首屏截图:确认作业标题、题量、题型分布(如"一. 填空题(共5题)")。
|
|
167
|
+
2. 逐题用无障碍跳题 + 截图,视觉模型逐字转录题干、选项、空格数量("第1空/第2空…")。
|
|
168
|
+
3. **宽屏截断处理**:题干右侧被截断时优先 `Ctrl+-` 缩小页面一到两档——题干完整可见且
|
|
169
|
+
单帧能装下更多内容(读题帧数减半);只在缩小后仍截断时才放大。缩放后布局全变,
|
|
170
|
+
旧坐标作废。
|
|
171
|
+
4. 把全部题目整理成一张完整清单(题号/题型/题干/选项/空数)后再进入作答,避免边读
|
|
172
|
+
边答来回滚动浪费 token。
|
|
173
|
+
5. **数字、法条、金额类答案必须先联网检索核实**。凭记忆答大概率错,且会连带坑掉相关
|
|
174
|
+
的客观题。
|
|
175
|
+
|
|
176
|
+
### 第 2 步:作答
|
|
177
|
+
|
|
178
|
+
每个作答执行单元的固定骨架:
|
|
179
|
+
|
|
180
|
+
```
|
|
181
|
+
初始化 → ensureReady(校验业务主键+前台化) → [跳到目标题] → 新截图 + 路标锚定算坐标
|
|
182
|
+
→ 坐标操作 → 输入/点击 → 截图验证
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
"路标锚定算坐标"即校准章节的方法:滚动/跳转后先读路标(题号)位置,用固定偏移推算
|
|
186
|
+
所有目标点,不目测、不沿用旧坐标。
|
|
187
|
+
|
|
188
|
+
- **填空题**:`click(输入框中心)` → `typeText(答案)`。输入框为全宽横条,同题各空纵向
|
|
189
|
+
间距固定(用第 2 步量出的偏移)。
|
|
190
|
+
- **单选题**:点击选项**圆圈** → 截图确认该项变为**选中高亮**。选错了就再点正确项
|
|
191
|
+
(单选互斥,直接覆盖)。
|
|
192
|
+
- **简答题**:`click(编辑器区域内一点)`(编辑器获得焦点后边框变色、工具栏激活)→
|
|
193
|
+
`typeText(长答案)`。**不要用 paste**,学习通等平台会屏蔽粘贴事件。输入一段 300+ 字
|
|
194
|
+
答案约需 30~60 秒,超时参数给足 120 秒。**注意:对编辑器清空重输或输入长文本后,
|
|
195
|
+
页面布局会收缩/展开,之后点击任何目标前必须重新截图取新坐标**(实测因此连续两次
|
|
196
|
+
点空,文字误入上一题的编辑器)。判断点击落空:输入后编辑器仍为空即点击没进编辑器,
|
|
197
|
+
重新定位补做。
|
|
198
|
+
- **分段排版**:需要分段的答案,用回车键在段落之间换行(输入文本里的换行符不可靠),
|
|
199
|
+
即:段落数组循环 `回车 + typeText(段)`。**段落开头不要用"1."这种"数字+点"**——
|
|
200
|
+
富文本编辑器会触发自动编号列表,下一段自动带出"2.",与手打的编号叠加成"2.2.";
|
|
201
|
+
改用"(1)(2)"或"一、二、"开头则不会触发。
|
|
202
|
+
|
|
203
|
+
### 第 3 步:保存 / 提交
|
|
204
|
+
|
|
205
|
+
- 点**暂时保存** → 应出现"保存成功"类 toast。**toast 约 2 秒即消失,点完立即截图也
|
|
206
|
+
可能错过;看不到 toast 不必反复重点**——实测连点 4 次均未捕获 toast,最终提交成功
|
|
207
|
+
证明保存早已生效。toast 只当"可能成功"的信号,不做硬验收。
|
|
208
|
+
- 改过任何答案后**再点一次暂时保存**。
|
|
209
|
+
- **提交需用户明确要求**(默认只暂时保存;用户说"直接提交/提交吧"即可执行)。流程:
|
|
210
|
+
点**提交** → 弹「确认提交?」对话框 → 点**对话框内**的提交按钮(不是外层右上角
|
|
211
|
+
那个)→ 页面跳转为「提交成功 / 等待批阅 / 提交时间」,并带"修改答案"按钮。
|
|
212
|
+
**这一页是保存与提交的最终权威验证**——如果暂时保存的 toast 没看到,以此页为准。
|
|
213
|
+
|
|
214
|
+
## 页面布局速查(1072×1280 截图、100~110% 缩放的实测参考)
|
|
215
|
+
|
|
216
|
+
| 元素 | 位置 |
|
|
217
|
+
|---|---|
|
|
218
|
+
| 暂时保存按钮 | ≈ (829, 131) |
|
|
219
|
+
| 提交按钮 | ≈ (981, 131) |
|
|
220
|
+
| 左侧题号导航行 | 无障碍树 `kind:"row"`,title 为题号数字 |
|
|
221
|
+
| 填空输入框 | 全宽横条,中心 x≈560,纵向间距 ≈120 |
|
|
222
|
+
| 单选圆圈 | x≈93,选项间距 ≈75 |
|
|
223
|
+
| 富文本编辑器 | 工具栏(段落/字体/字号/B I U…)下方的大片空白区 |
|
|
224
|
+
|
|
225
|
+
坐标只作初值参考,**每次操作前仍以当前帧截图实测为准**。窗口大小、页面缩放、水平
|
|
226
|
+
滚动偏移都会让这些数字失效(实测出现过页面水平偏移 50px,左侧"第1空"标签被切成
|
|
227
|
+
"空")。
|
|
228
|
+
|
|
229
|
+
## 常见报错 → 处置
|
|
230
|
+
|
|
231
|
+
| 报错/现象 | 原因 | 处置 |
|
|
232
|
+
|---|---|---|
|
|
233
|
+
| `agent is not defined` | 新执行单元未初始化 | 单元开头加初始化代码 |
|
|
234
|
+
| `raw foreground event ... refused ... frontmost_pid_mismatch` | 目标窗口不在前台 | ensureReady()(点标签页激活)后重试 |
|
|
235
|
+
| `element index N no longer refers to...tree has shifted` | 无障碍索引跨调用失效 | 同单元内重取元素表再点,重试≤3 次 |
|
|
236
|
+
| `frame_id ... is expired frame` | 帧绑定过期(切换标签页、间隔太久) | 先截一帧(不回显)重新绑定,再提交坐标 |
|
|
237
|
+
| `scroll: expected an integer` | 滚动量传了小数 | 取整 |
|
|
238
|
+
| `paste()` 后编辑器仍为空 | 平台屏蔽粘贴事件 | 改用模拟键盘逐字输入 |
|
|
239
|
+
| 输入后编辑器仍为空(非粘贴场景) | 点击落在编辑器外(布局变化或滚动) | 重新截图定位,用新帧坐标补做 |
|
|
240
|
+
| 答案串进了上一题的编辑器 | 相邻编辑器,点击坐标来自旧帧 | 全选清空重输本题,下一题用新帧坐标 |
|
|
241
|
+
| 暂时保存后没看到 toast | toast 约 2 秒消失,截图晚于渲染 | 不必反复重点,以最终「提交成功」页为权威验证 |
|
|
242
|
+
| 点了没反应/选错项 | 坐标来自旧截图 | 重新截图,用新坐标 |
|
|
243
|
+
| 操作到了另一份作业 | 多个同名标签页,切错 | 按 URL 业务主键校验当前标签 |
|
|
244
|
+
| 点击后弹出全屏图片预览 | 坐标命中了拓扑图等图片 | 按 Esc 关闭,重新截图定位编辑器;期间输入的文字已丢失需补打 |
|
|
245
|
+
|
|
246
|
+
## 答案风格建议
|
|
247
|
+
|
|
248
|
+
- **口语化**:简答/分析题不要写成论文腔,用"我判断""我觉得要注意"这类自然表达;
|
|
249
|
+
结论清晰直接。
|
|
250
|
+
- **分段排版**:答案必须分自然段,一段只讲一个主题;段内枚举用①②③内联。
|
|
251
|
+
- **编号安全**:段落开头用"(1)(2)"或"一、二、",不要用"1."(会触发编辑器自动
|
|
252
|
+
编号,导致下一段出现"2.2."这类重复)。
|
|
253
|
+
|
|
254
|
+
## 多作业批量处理
|
|
255
|
+
|
|
256
|
+
1. 逐个点击"作业作答"标签,用 URL 业务主键枚举全部作业(标题都相同,不能靠标题区分)。
|
|
257
|
+
2. 按顺序处理每一份:切标签(主键校验)→ 读题(缩小页面后逐屏截图)→ 定答案
|
|
258
|
+
(法条/数字先检索核实)→ 作答 → 逐项验证 → 暂时保存。
|
|
259
|
+
3. 每份作业独立验收完毕再切下一份;全部完成后统一汇报作答内容,**等用户明确说
|
|
260
|
+
"提交"再提交**。
|
|
261
|
+
|
|
262
|
+
## 提交前验收清单
|
|
263
|
+
|
|
264
|
+
- [ ] 全部题目清单齐全(题量与页面标注一致)
|
|
265
|
+
- [ ] 每道填空题每空都有验证截图
|
|
266
|
+
- [ ] 每道单选题选中高亮与预期选项一致(逐题验证过,不是凭点击记录推断)
|
|
267
|
+
- [ ] 每道简答题编辑器内文字完整可见(首尾都在)
|
|
268
|
+
- [ ] 点过「暂时保存」(toast 未捕获不阻塞,最终以提交结果页为准)
|
|
269
|
+
- [ ] 已把答案汇总告知用户;提交动作在用户明确要求后才执行,并验证「提交成功」页
|
|
270
|
+
|
|
271
|
+
## 平台适配改造点(换平台时改这里)
|
|
272
|
+
|
|
273
|
+
| 需要替换的内容 | 说明 |
|
|
274
|
+
|---|---|
|
|
275
|
+
| 业务主键参数 | `workId=` 换成目标平台作业页 URL 里的唯一标识 |
|
|
276
|
+
| 同名标签页的过滤正则 | `/作业作答/` 换成目标平台标签页标题特征 |
|
|
277
|
+
| 保存/提交按钮名称与坐标 | 「暂时保存」「提交」换成目标平台的按钮文案,坐标重新实测 |
|
|
278
|
+
| 确认对话框文案与按钮位置 | 「确认提交?」换成本平台的文案 |
|
|
279
|
+
| 富文本编辑器行为 | 自动编号、粘贴屏蔽等是编辑器特性,需实测目标平台的编辑器 |
|
|
280
|
+
| 布局速查表 | 全部偏移量按目标平台重新标定 |
|
package/bin/install.js
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* chaoxing-work-cua 安装器
|
|
4
|
+
* 把 SKILL.md 安装到 Agent 的技能目录(零依赖)。
|
|
5
|
+
*
|
|
6
|
+
* 用法:
|
|
7
|
+
* npx chaoxing-work-cua # 自动检测已存在的技能目录并安装
|
|
8
|
+
* npx chaoxing-work-cua --target <dir> # 安装到指定目录
|
|
9
|
+
*/
|
|
10
|
+
const fs = require("fs");
|
|
11
|
+
const path = require("path");
|
|
12
|
+
const os = require("os");
|
|
13
|
+
|
|
14
|
+
const SKILL_NAME = "chaoxing-work-cua";
|
|
15
|
+
const args = process.argv.slice(2);
|
|
16
|
+
|
|
17
|
+
// --target <dir>
|
|
18
|
+
let customTarget = null;
|
|
19
|
+
const tIdx = args.indexOf("--target");
|
|
20
|
+
if (tIdx > -1 && args[tIdx + 1]) customTarget = path.resolve(args[tIdx + 1]);
|
|
21
|
+
|
|
22
|
+
// 候选技能目录(存在哪个装哪个;都没有则装到默认目录)
|
|
23
|
+
const candidates = [".agents/skills", ".zcode/skills", ".claude/skills"];
|
|
24
|
+
let targets = candidates
|
|
25
|
+
.map((c) => path.join(os.homedir(), c))
|
|
26
|
+
.filter((p) => fs.existsSync(p));
|
|
27
|
+
|
|
28
|
+
if (customTarget) {
|
|
29
|
+
targets = [customTarget];
|
|
30
|
+
} else if (targets.length === 0) {
|
|
31
|
+
targets = [path.join(os.homedir(), ".agents", "skills")];
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// 源文件:包根目录下的 SKILL.md
|
|
35
|
+
const src = path.join(__dirname, "..", "SKILL.md");
|
|
36
|
+
if (!fs.existsSync(src)) {
|
|
37
|
+
console.error("✗ 安装包损坏:找不到 SKILL.md,请重新 npx 或 npm i -g。");
|
|
38
|
+
process.exit(1);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
console.log(`安装 ${SKILL_NAME} skill ...`);
|
|
42
|
+
for (const t of targets) {
|
|
43
|
+
const dir = path.join(t, SKILL_NAME);
|
|
44
|
+
try {
|
|
45
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
46
|
+
fs.copyFileSync(src, path.join(dir, "SKILL.md"));
|
|
47
|
+
console.log(` ✓ ${dir}`);
|
|
48
|
+
} catch (e) {
|
|
49
|
+
console.error(` ✗ ${dir} : ${e.message}`);
|
|
50
|
+
process.exitCode = 1;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
console.log("");
|
|
55
|
+
console.log("完成!重启你的 Agent 后,skill 即被识别。");
|
|
56
|
+
console.log("免责声明:仅供学习 Computer Use 自动化技术,请遵守所在学校/平台规定,勿用于违反学术诚信的行为。");
|
package/package.json
CHANGED
|
@@ -1,6 +1,30 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "chaoxing-work-cua",
|
|
3
|
-
"version": "
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "基于 Computer Use 的在线作业自动作答 Skill 模板(超星学习通示例)。npx 一键安装到 Agent 技能目录,含完整踩坑手册。",
|
|
5
|
+
"bin": {
|
|
6
|
+
"chaoxing-work-cua": "bin/install.js"
|
|
7
|
+
},
|
|
8
|
+
"files": [
|
|
9
|
+
"bin",
|
|
10
|
+
"SKILL.md",
|
|
11
|
+
"README.md",
|
|
12
|
+
"LICENSE"
|
|
13
|
+
],
|
|
14
|
+
"keywords": [
|
|
15
|
+
"computer-use",
|
|
16
|
+
"agent-skill",
|
|
17
|
+
"skill-template",
|
|
18
|
+
"chaoxing",
|
|
19
|
+
"automation",
|
|
20
|
+
"cua"
|
|
21
|
+
],
|
|
22
|
+
"license": "MIT",
|
|
23
|
+
"repository": {
|
|
24
|
+
"type": "git",
|
|
25
|
+
"url": "git+ssh://git@github.com/0xAlchemist-cs/chaoxing-work-cua.git"
|
|
26
|
+
},
|
|
27
|
+
"engines": {
|
|
28
|
+
"node": ">=16"
|
|
29
|
+
}
|
|
30
|
+
}
|