@wwkit/harness 1.0.28 → 1.0.30

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.
Files changed (37) hide show
  1. package/bin/index.js +10 -0
  2. package/package.json +3 -2
  3. package/skills/extract/SKILL.md +43 -68
  4. package/skills/extract/references/detail.md +1 -1
  5. package/skills/extract/references/list.md +3 -3
  6. package/skills/extract/references/navi.md +1 -1
  7. package/skills/jstest/SKILL.md +561 -0
  8. package/skills/jstest/references/case-create.md +327 -0
  9. package/skills/jstest/references/case-fix.md +273 -0
  10. package/skills/jstest/references/config.md +148 -0
  11. package/skills/jstest/references/coverage-analyze.md +247 -0
  12. package/skills/jstest/references/env-ensure.md +210 -0
  13. package/skills/jstest/references/execute.md +168 -0
  14. package/skills/jstest/references/sample.md +166 -0
  15. package/skills/jstest/references/scoring-rules.md +75 -0
  16. package/skills/jstest/references/src/jstest-sample/Calculator.js +80 -0
  17. package/skills/jstest/references/src/jstest-sample/ConfigManager.js +72 -0
  18. package/skills/jstest/references/src/jstest-sample/FileProcessor.js +57 -0
  19. package/skills/jstest/references/src/jstest-sample/OrderService.js +98 -0
  20. package/skills/jstest/references/src/jstest-sample/TokenGenerator.js +60 -0
  21. package/skills/jstest/references/src/jstest-sample/UserService.js +56 -0
  22. package/skills/jstest/references/src/jstest-sample/index.js +6 -0
  23. package/skills/jstest/references/suitability-check.md +232 -0
  24. package/skills/jstest/references/test-standards.md +288 -0
  25. package/skills/query/SKILL.md +16 -47
  26. package/skills/revise/SKILL.md +52 -96
  27. package/skills/revise/references/article.md +12 -15
  28. package/skills/revise/references/gallery.md +11 -15
  29. package/skills/revise/references/question.md +11 -15
  30. package/skills/revise/references/status.md +10 -14
  31. package/src/config.js +29 -0
  32. package/src/config.json5 +19 -0
  33. package/skills/extract/references/format-aliases.json5 +0 -22
  34. package/skills/extract/references/input.schema.json5 +0 -23
  35. package/skills/query/references/input.schema.json5 +0 -25
  36. package/skills/revise/references/format-aliases.json5 +0 -22
  37. package/skills/revise/references/input.schema.json5 +0 -28
package/bin/index.js CHANGED
@@ -4,6 +4,14 @@ import { execSync } from 'node:child_process'
4
4
  import { readFileSync, readdirSync, existsSync } from 'node:fs'
5
5
  import path from 'node:path'
6
6
  import { fileURLToPath } from 'node:url'
7
+ import { getConfigPath, mergeBuiltinConfig } from '../src/config.js'
8
+
9
+ // Lazy-init: if user config doesn't exist (postinstall skipped), create it now
10
+ if (!existsSync(getConfigPath())) {
11
+ if (mergeBuiltinConfig()) {
12
+ console.log(`harness: config initialized at ${getConfigPath()}`)
13
+ }
14
+ }
7
15
 
8
16
  const __dirname = path.dirname(fileURLToPath(import.meta.url))
9
17
  const pkgRoot = path.resolve(__dirname, '..')
@@ -211,6 +219,8 @@ switch (cmd) {
211
219
  cmdUpgrade()
212
220
  break
213
221
  case 'help':
222
+ case '-h':
223
+ case '--help':
214
224
  default:
215
225
  printHelp()
216
226
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wwkit/harness",
3
- "version": "1.0.28",
3
+ "version": "1.0.30",
4
4
  "author": "bluesliu <langcai163@163.com>",
5
5
  "description": "WebWork abilities for opencode",
6
6
  "type": "module",
@@ -10,6 +10,7 @@
10
10
  },
11
11
  "files": [
12
12
  "bin",
13
+ "src",
13
14
  "plugin.js",
14
15
  "plugins",
15
16
  "scripts",
@@ -48,7 +49,7 @@
48
49
  "ajv": "^8.17.0",
49
50
  "cheerio": "^1.0.0",
50
51
  "json5": "^2.2.3",
51
- "@wwkit/shared": "1.0.23"
52
+ "@wwkit/shared": "1.0.26"
52
53
  },
53
54
  "devDependencies": {
54
55
  "jest": "^29.7.0"
@@ -1,10 +1,8 @@
1
1
  ---
2
2
  name: extract
3
3
  description: |
4
- 自包含内容提取 skill:每次调用 = 一个固定 Sprint——Sprint Planning(解析入参、定义 Sprint Goal、todowrite 落固定 Sprint Backlog)→ Sprint Execution(逐项执行并验证 DoD)→ Sprint Review(对照 Sprint Goal 校验交付 + 简要回顾)。
5
- format=list/detail/text/navi。调用方直接传原始任务消息,skill 自解析自包含。
6
- 内部用 todowrite 管理固定 6 项 Sprint Backlog(每项带 DoD)。禁止 WebFetch/网络请求。
7
- 适用:列表页/详情页/纯文本/结构化 JSON 列表/导航 XPath 等各类网页内容提取。
4
+ 自包含内容提取 skill(固定 Sprint 范式):每次调用 = 一个固定 Sprint(Planning→Execution→Review),todowrite 落 3 项带 DoD 的 Sprint Backlog 并逐项验证,产出通过 schema 校验的 JSON 数组。
5
+ format=list/detail/text/navi(支持中文别名指定)。调用方直接传原始任务消息即可,无需预处理;禁止 WebFetch/网络请求。
8
6
  license: MIT
9
7
  metadata:
10
8
  workflow: sequential
@@ -16,113 +14,91 @@ metadata:
16
14
 
17
15
  每次调用 = 一个固定 Sprint,三个事件:
18
16
 
19
- 1. **Sprint Planning**:解析入参 → 定义 Sprint Goal → todowrite 落固定 6 项 Sprint Backlog(每项带 DoD)
17
+ 1. **Sprint Planning**:解析入参 → 定义 Sprint Goal → todowrite 落固定 3 项 Sprint Backlog(每项带 DoD)
20
18
  2. **Sprint Execution**:逐项执行,每项 = 执行 → 验证 DoD → todowrite 勾单 Done
21
- 3. **Sprint Review**:对照 Sprint Goal 验证 Increment(JSON 数组)及输出语义,沉淀 1 条回顾
19
+ 3. **Sprint Review**:对照 Sprint Goal 验证 Increment(JSON 数组)及输出语义
22
20
 
23
21
  **Sprint Goal** = `从 {{source}} 提取符合 {{format}} 格式的 JSON 数组,并通过 schema 校验`。
24
22
 
25
23
  ## 输入参数
26
24
 
27
- 入参为调用方传入的**原始任务消息**,可为 JSON 对象、key=value 或自然语言等任意形态,agent 依据字段语义自主提取(详见 Item 1)。字段清单(字段/类型/必填/默认值)以 `references/input.schema.json5` 为准:
25
+ 入参为调用方传入的**原始任务消息**,可为 JSON 对象、key=value 或自然语言等任意形态,agent 依据字段语义自主提取。字段清单(字段/类型/必填/默认值):
28
26
 
29
27
  | 字段 | 类型 | 必填 | 说明 |
30
28
  |---|---|---|---|
31
- | `format` | string | ✅ | 提取类型,标准值 `list`/`detail`/`text`/`navi`,可由别名表翻译 |
29
+ | `format` | string | ✅ | 提取类型,标准值 `list`/`detail`/`text`/`navi`,可用自然语言别名指定(见别名对照) |
32
30
  | `source` | string | ✅ | 网页 HTML / 文本 / 结构化 JSON,或本地文件路径 |
33
31
  | `url` | string | ❌ | 页面 URL,**静态补充字段,仅供相对路径转绝对地址 / 图片 src 补全域名,禁止访问该地址** |
34
32
  | `output` | string | ❌ | 输出文件路径(提供则写文件,否则 stdout) |
35
33
 
36
- 本技能仅使用上表四个字段,忽略所有其他字段(如 `count`、`max_length`、`max_image_count`、`language`),不得读取、写入或据此推断任何行为。
34
+ 本技能仅使用上表四个字段,忽略所有其他字段(如 `count`、`max_length`、`max_image_count`、`language`)。
37
35
 
38
- ## 固定 Sprint Backlog(todowrite 落单,覆盖历史 todos)
39
-
40
- 1. 解析入参(从任意形态任务消息自主提取 format/source/url/output) | DoD: 得到四个字段值(或按短路规则输出 `[]`/错误并结束)
41
- 2. 加载 references(format 流程文件 + schema 文件) | DoD: 对应流程与 schema 已确认,schema 绝对路径已记录(或 format 无效/文件不存在时输出 `[]`)
42
- 3. 按 format 执行提取 | DoD: 产出符合 format 的 JSON 数组
43
- 4. Schema 校验 | DoD: `node validate-schema.js` 执行完成,返回通过/失败结果
44
- 5. 校验失败修复重试(≤3 次) | DoD: 重试后校验通过,或重试 3 次耗尽后 stderr 输出错误
45
- 6. 输出(写 output 文件或 stdout) | DoD: 按输出语义交付 JSON 数组(文件路径或 stdout),校验未通过时 stderr 报错
46
-
47
- ## Sprint Execution
48
-
49
- 按固定 6 项逐项执行,每项周期 = 进度检查(刚完成什么/本项做什么/有无阻塞)→ 执行 → 验证 DoD → 勾单 Done。
50
-
51
- ### Item 1:解析入参
52
-
53
- 将第 1 项标记 in_progress,从原始任务消息中**自主提取**四个字段。入参可为 JSON 对象、key=value 或自然语言等任意形态,依据字段语义理解提取即可,无需固定解析规则。提取原则:
54
-
55
- - **格式翻译**:若消息中以自然语言指定提取类型(如"列表/导航/详情/纯文本"),用 `read` 读取 `references/format-aliases.json5`,将命中的 `terms` 翻译为该 format 标准值;未命中则 `format` 取消息中明确给出的值。
36
+ **format 别名对照**:
56
37
 
57
- 解析后得到 `format`、`source`、`url`、`output` 四个字段(字段说明见上文输入参数表;`url`/`output` 缺省时留空由后续 Item 处理)。
38
+ | format 标准值 | 别名 terms |
39
+ |---|---|
40
+ | `list` | 列表 / 集合 / 条目 / list |
41
+ | `detail` | 详情 / 正文 / 内容页 / detail |
42
+ | `text` | 纯文本 / 文字 / 文本 / 转文本 / text |
43
+ | `navi` | 导航 / 栏目 / 链接导航 / navi |
58
44
 
59
- **短路规则(按顺序执行,命中即结束):**
60
-
61
- 1. **空 source 短路**:若 `source` 为空、null 或仅含空白:直接输出 `[]` 并结束,**禁止**继续执行。即使提供了 `url` 也**不得**用 WebFetch/网络请求访问该地址来获取内容——`url` 是静态补充字段,不能替代 `source`。
62
- 2. **format 缺失校验**:若 `format` 未提供或经别名表翻译后仍为空:将错误信息输出到 stderr 并结束,**禁止**继续执行。
45
+ ## 固定 Sprint Backlog(todowrite 落单,覆盖历史 todos)
63
46
 
64
- **验证 DoD**:四个字段值已得到(或按短路规则结束)。通过后标记 Done。
47
+ 1. 解析入参 + 加载 references | DoD: 四字段已提取、对应流程文件与 schema 已读且 schema 绝对路径已记录(或短路输出 `[]`)
48
+ 2. 执行提取 + Schema 校验(失败修复重试 ≤3 次) | DoD: 产出符合 `{{format}}` 的 JSON 数组且 `node validate-schema.js` 校验通过(或重试耗尽 stderr 报错)
49
+ 3. 输出 | DoD: 按输出语义交付 JSON 数组(文件路径或 stdout)
65
50
 
66
- ### Item 2:加载 references
51
+ ## Sprint Execution
67
52
 
68
- 将第 2 项标记 in_progress,从技能目录的 `references/` 加载流程文件和 schema 文件:
53
+ 按固定 3 项逐项执行(勾单机制见执行范式)。
69
54
 
70
- - `format=list` 时,直接使用 `references/list.md`(内部按 source 类型分三条分支处理)与 `references/list.schema.json5`
71
- - 其他 format 直接使用 `references/{{ format }}.md` 与 `references/{{ format }}.schema.json5`
55
+ ### Item 1:解析入参 + 加载 references
72
56
 
73
- 用 `read` 工具读取对应流程文件(list 为 `references/list.md`)与 schema 文件,并**记录 schema 文件的绝对路径**(Item 4 校验时需要)。若 `format` 为空或对应 references 文件不存在:直接输出 `[]` 并结束(`format` 缺失已在 Item 1 处理)。
57
+ 从原始任务消息中自主提取 `format`/`source`/`url`/`output` 四个字段;自然语言格式按「format 别名对照」翻译。`source` 为文件路径时用 `read` 读取其内容作为提取输入。
74
58
 
75
- `url` 按需透传给对应流程(相对路径转绝对)。
59
+ **短路规则(命中即结束,禁止继续执行):**
76
60
 
77
- **验证 DoD**:流程与 schema 文件已确认、schema 绝对路径已记录(或 references 文件不存在已短路)。通过后标记 Done。
61
+ 1. `source` 为空、null 或仅含空白 → 直接输出 `[]`(即使提供 `url` 也不得访问网络获取内容)
62
+ 2. `format` 未提供或经别名对照翻译后仍为空 → 直接输出 `[]`
78
63
 
79
- ### Item 3:按 format 执行提取
64
+ 未短路时**并行读取** `references/{{format}}.md`(提取流程)与 `references/{{format}}.schema.json5`(输出校验规则),记录 schema 绝对路径(Item 2 校验用);references 文件不存在 → 输出 `[]` 结束。`url` 按需透传给流程(相对路径转绝对)。
80
65
 
81
- 将第 3 项标记 in_progress,按 Item 2 确认的流程文件步骤执行提取(`list` 格式使用 `references/list.md` 内部按 source 类型选定的分支),得到 JSON 数组。**禁止使用 WebFetch 或任何网络请求获取内容。**
66
+ ### Item 2:执行提取 + Schema 校验
82
67
 
83
- **验证 DoD**:已产出符合 format 的 JSON 数组。通过后标记 Done。
68
+ 按流程文件步骤执行提取,**禁止使用 WebFetch 或任何网络请求获取内容**。**必须输出 JSON 数组**,字段/必填/数量以 schema 为准。
84
69
 
85
- ### Item 4:Schema 校验
70
+ **裸 JSON 硬约束**:最终输出必须为裸 JSON 数组——不使用 markdown 代码围栏(```json)、不输出任何解释、思考过程或额外文本、无尾注,直接以 `[` 开始、`]` 结束。
86
71
 
87
- 将第 4 项标记 in_progress,用 `write` 工具将待校验的 JSON 数组写入临时文件,再用 `write` 工具将 `{"data": <JSON 数组>, "schema_path": "<schema 绝对路径>"}` 写入 JSON 输入文件,stdin 重定向交给 Node.js 校验:
72
+ 用 `write` 将 `{"data": <JSON 数组>, "schema_path": "<schema 绝对路径>"}` 写入**单个**临时 JSON 输入文件(数组内嵌于 `data`,无需单独写待校验数组文件),stdin 重定向交给 Node.js 校验:
88
73
 
89
74
  ```bash
90
75
  node '<技能目录>/references/validate-schema.js' < <临时 JSON 输入文件>
91
76
  ```
92
77
 
93
- - 若校验通过:**验证 DoD**(校验执行完成且返回通过),标记 Done,跳过 Item 5,进入 Item 6
94
- - 若校验失败:**验证 DoD**(校验执行完成且返回失败),标记 Done,进入 Item 5 进行修复重试(最多 3 次)
95
-
96
- ### Item 5:校验失败时修复重试
97
-
98
- 将第 5 项标记 in_progress,将错误信息反馈,重新执行 Item 3 提取并再次校验。**最多重试 3 次**。
99
-
100
- **验证 DoD**:重试后校验通过 → 标记 Done,进入 Item 6;重试 3 次耗尽 → stderr 输出错误并结束(**不进入 Item 6**)。
101
-
102
- ### Item 6:输出
78
+ - 通过 → 进入 Item 3
79
+ - 失败 → 将 Schema 校验错误反馈,按流程文件重新提取后再次校验,**最多重试 3 次**;耗尽 → stderr 输出错误并结束
103
80
 
104
- 将第 6 项标记 in_progress。进入本项时校验必已通过(重试耗尽场景已在 Item 5 结束):
81
+ ### Item 3:输出
105
82
 
106
- - 提供 `output` 参数:用 `write` 工具将最终 JSON 数组写入 `output` 指定文件(**禁止创建其他文件**),stdout 输出该文件路径。
107
- - 未提供 `output` 参数:将最终 JSON 数组直接输出到 stdout,**不写任何文件**。
83
+ 本项执行时校验必已通过:
108
84
 
109
- **验证 DoD**:按输出语义交付(文件路径或 stdout 数组)。通过后标记 Done。
85
+ - 提供 `output` → 用 `write` 将最终 JSON 数组写入该文件(**禁止创建其他文件**),stdout 输出文件路径
86
+ - 未提供 `output` → 将最终 JSON 数组直接输出到 stdout,**不写任何文件**
110
87
 
111
88
  ## Sprint Review
112
89
 
113
- 所有 Backlog Items 完成后:
90
+ 本 skill 每次调用 = 无状态独立 Sprint,无跨轮次状态,故不进行 Retrospective。所有 Backlog Items 完成后:
114
91
 
115
92
  - **对照 Sprint Goal 验证**:产出的是否为符合 `{{format}}` 格式的 JSON 数组且通过 schema 校验?输出语义是否正确(写文件输出路径 / stdout 输出数组)?
116
93
  - **展示 Increment**:输出文件路径或 stdout 的 JSON 数组。
117
- - **简要回顾(Retrospective)**:沉淀 1 条改进项供下一轮采纳。
118
94
 
119
95
  ## 约束
120
96
 
121
97
  - 只处理已声明字段(source/format/url/output),忽略所有其他传入参数(如 `count`、`max_length`、`max_image_count`、`language`),**禁止**以任何形式使用它们。
122
- - **禁止使用 WebFetch 或任何网络请求、禁止访问外部网络**;`source` 无正文或为空时必须输出 `[]`,绝不自行获取内容。`url` 字段为静态补充字段,**禁止**通过 WebFetch/任何网络请求访问其指向地址——仅用于相对路径转绝对地址、图片 `src` 补全域名等纯文本处理。
123
- - 写文件一律用 `write` 工具;读文件用 `read` 工具;需要中间数据时写入临时文件,以 stdin 重定向传给 node。
124
- - 禁止使用未授权的 `cp`/`rm`/`mv` 等命令;需要复制、移动或删除临时文件时,一律用允许的 `node -e` 的 fs 模块完成。
125
- - 内部重试步骤的中间产物用临时文件,完成后清理,禁止写入 output 以外的任何持久文件。
98
+ - **禁止使用 WebFetch 或任何网络请求、禁止访问外部网络**;`source` 为空时必须输出 `[]`,绝不自行获取内容。`url` 为静态补充字段,**禁止**访问其指向地址——仅用于相对路径转绝对地址、图片 `src` 补全域名等纯文本处理。
99
+ - 写文件一律用 `write` 工具;读文件用 `read` 工具;中间数据写入临时文件,以 stdin 重定向传给 node。
100
+ - 禁止使用未授权的 `cp`/`rm`/`mv` 等命令;需要复制、移动或删除临时文件时用 `node -e` 的 fs 模块完成。
101
+ - 中间产物完成后清理,禁止写入 output 以外的任何持久文件。
126
102
 
127
103
  ## 资源目录
128
104
 
@@ -135,10 +111,9 @@ references/
135
111
  ├── extract-regex.js # 正则批量提取
136
112
  ├── to-text.js # HTML 转纯文本
137
113
  ├── validate-schema.js # Schema 校验
138
- ├── input.schema.json5
139
114
  ├── list.schema.json5
140
- ├── list.md
141
- ├── list-rule-gen.md # list 分支 B 的 HTML 正则生成指导
115
+ ├── list.md # 列表提取流程(按 source 类型分 A/B/C 分支)
116
+ ├── list-rule-gen.md # 分支 B 的 HTML 正则生成指导
142
117
  ├── detail.md + detail.schema.json5
143
118
  ├── text.md + text.schema.json5
144
119
  └── navi.md + navi.schema.json5
@@ -52,4 +52,4 @@ node '<技能目录>/references/extract-detail.js' < <临时 HTML 文件>
52
52
 
53
53
  ### Step 3 — 验证
54
54
 
55
- 检查 `blocks` 非空,输出规范后的 JSON 数组(供 extract 技能 Item 4 校验)。
55
+ 检查 `blocks` 非空,输出规范后的 JSON 数组(供 extract 技能校验)。
@@ -47,7 +47,7 @@
47
47
 
48
48
  ### A2 — 验证
49
49
 
50
- 检查每项 title 非空(空时输出 Warning),输出规范后的 JSON 数组(供 extract 技能 Item 4 校验)。
50
+ 检查每项 title 非空(空时输出 Warning),输出规范后的 JSON 数组(供 extract 技能校验)。
51
51
 
52
52
  ## 分支 B:HTML 源码(list_from_html)
53
53
 
@@ -96,7 +96,7 @@ node '<技能目录>/references/extract-regex.js' < <临时输入文件>
96
96
 
97
97
  ### B5 — 验证
98
98
 
99
- 检查每项 title 非空,输出规范后的 JSON 数组(供 extract 技能 Item 4 校验)。
99
+ 检查每项 title 非空,输出规范后的 JSON 数组(供 extract 技能校验)。
100
100
 
101
101
  ## 分支 C:纯文本(list_from_text)
102
102
 
@@ -132,4 +132,4 @@ node '<技能目录>/references/extract-regex.js' < <临时输入文件>
132
132
 
133
133
  ### C4 — 验证
134
134
 
135
- 检查每项 `title` 非空,输出规范后的 JSON 数组(供 extract 技能 Item 4 校验)。
135
+ 检查每项 `title` 非空,输出规范后的 JSON 数组(供 extract 技能校验)。
@@ -42,4 +42,4 @@
42
42
  node '<技能目录>/references/build-xpath.js' < <临时 title 文件>
43
43
  ```
44
44
 
45
- 输出:`{selector, title}` 数组,供 extract 技能 Item 4 校验。
45
+ 输出:`{selector, title}` 数组,供 extract 技能校验。