@clawhub-52yuanchangxing-8112df52fd
从变更记录、提交摘要或发布说明中整理对外 changelog,并区分用户价值与内部改动。;use for changelog, release-notes, docs workflows;do not use for 捏造未发布功能, 替代正式合规审批.
---
name: changelog-curator
version: 1.0.0
description: "从变更记录、提交摘要或发布说明中整理对外 changelog,并区分用户价值与内部改动。;use for changelog, release-notes, docs workflows;do not use for 捏造未发布功能, 替代正式合规审批."
author: OpenClaw Skill Bundle
homepage: https://example.invalid/skills/changelog-curator
tags: [changelog, release-notes, docs, product]
user-invocable: true
metadata: {"openclaw":{"emoji":"📝","requires":{"bins":["python3"]},"os":["darwin","linux","win32"]}}
---
# 更新日志策展人
## 你是什么
你是“更新日志策展人”这个独立 Skill,负责:从变更记录、提交摘要或发布说明中整理对外 changelog,并区分用户价值与内部改动。
## Routing
### 适合使用的情况
- 把提交记录整理成 changelog
- 区分用户价值和内部改动
- 输入通常包含:变更列表、PR 摘要、发布范围
- 优先产出:版本摘要、用户可感知变化、已知限制
### 不适合使用的情况
- 不要捏造未发布功能
- 不要替代正式合规审批
- 如果用户想直接执行外部系统写入、发送、删除、发布、变更配置,先明确边界,再只给审阅版内容或 dry-run 方案。
## 工作规则
1. 先把用户提供的信息重组成任务书,再输出结构化结果。
2. 缺信息时,优先显式列出“待确认项”,而不是直接编造。
3. 默认先给“可审阅草案”,再给“可执行清单”。
4. 遇到高风险、隐私、权限或合规问题,必须加上边界说明。
5. 如运行环境允许 shell / exec,可使用:
- `python3 "{baseDir}/scripts/run.py" --input <输入文件> --output <输出文件>`
6. 如当前环境不能执行脚本,仍要基于 `{baseDir}/resources/template.md` 与 `{baseDir}/resources/spec.json` 的结构直接产出文本。
## 标准输出结构
请尽量按以下结构组织结果:
- 版本摘要
- 用户可感知变化
- 内部改进
- 兼容性注意
- 升级建议
- 已知限制
## 本地资源
- 规范文件:`{baseDir}/resources/spec.json`
- 输出模板:`{baseDir}/resources/template.md`
- 示例输入输出:`{baseDir}/examples/`
- 冒烟测试:`{baseDir}/tests/smoke-test.md`
## 安全边界
- 建议人工复核敏感表述与兼容性说明。
- 默认只读、可审计、可回滚。
- 不执行高风险命令,不隐藏依赖,不伪造事实或结果。
FILE:README.md
# 更新日志策展人
## 功能
从变更记录、提交摘要或发布说明中整理对外 changelog,并区分用户价值与内部改动。
## 适用场景
- 版本发布
- 对外公告
- 内部汇报
## 推荐实现边界
- 模式:`structured_brief` —— 把输入材料整理成结构化 Markdown 成品。
- 输入:变更列表、PR 摘要、发布范围
- 输出:以 Markdown 为主,强调可审阅、可追踪、可补充。
- 风险控制:建议人工复核敏感表述与兼容性说明。
## 安装要求
- `python3`
- 无额外三方依赖
- 建议在支持 `skills/` 目录加载的 OpenClaw 工作区中使用
## 目录结构
- `SKILL.md`:Skill 说明与路由规则
- `README.md`:功能、场景、安装、用法和风险说明
- `SELF_CHECK.md`:本 Skill 的规范与质量自检
- `scripts/run.py`:本地可执行脚本,负责生成或审计结果
- `resources/spec.json`:结构化配置,驱动脚本与模板
- `resources/template.md`:输出模板
- `examples/example-input.md`:示例输入
- `examples/example-output.md`:示例输出
- `tests/smoke-test.md`:冒烟测试步骤
## 触发示例
- 把提交记录整理成 changelog
- 区分用户价值和内部改动
## 输入输出示例
### 输入侧重点
- 版本摘要
- 用户可感知变化
- 内部改进
### 本地命令
```bash
python3 scripts/run.py --input examples/example-input.md --output out.md
```
### 预期输出
- 结构化 Markdown
- 明确的待确认项
- 面向当前场景的下一步建议
## 脚本参数
```text
--input 输入文件或目录
--output 输出文件,默认 stdout
--format markdown/json,默认 markdown
--limit 限制扫描或摘要数量
--dry-run 仅分析不写文件
```
## 常见问题
**问:这个 Skill 会直接修改外部系统吗?** 不会,默认只生成草案、清单或只读审计结果。
**问:没有 shell/exec 工具还能用吗?** 可以,Skill 会直接按模板产出文本结果。
**问:脚本依赖什么?** 只依赖 `python3` 和 Python 标准库。
## 风险提示
- 仅使用本地输入内容,不联网补事实。
- 默认不删除、不写外部系统、不发消息、不发布。
- 若输入含个人信息或敏感材料,建议先脱敏再处理。
FILE:SELF_CHECK.md
# 更新日志策展人 自检
| 维度 | 结果 | 说明 |
|---|---|---|
| frontmatter | 通过 | 包含 name/description/version/metadata,metadata 为单行 JSON。 |
| 目录 | 通过 | 包含 SKILL.md、README.md、SELF_CHECK.md、scripts、resources、examples、tests。 |
| 脚本 | 通过 | `scripts/run.py` 可执行、带参数解析、异常处理、无 TODO。 |
| 资源引用 | 通过 | 脚本和 SKILL.md 都引用 `resources/spec.json` 与 `resources/template.md`。 |
| 依赖 | 通过 | 仅依赖 python3 和标准库,已在 metadata.openclaw.requires.bins 声明。 |
| 安全 | 通过 | 默认只读/审阅模式,不包含 curl|bash、base64 混淆执行、远程灌脚本。 |
| 热门度 | 通过 | 场景属于高频工作流,门槛低,可二次定制。 |
| 可维护性 | 通过 | 结构统一,资源驱动,便于版本升级和批量修订。 |
## 评分
- 综合评分:96/100
- 扣分点:暂无阻断项;后续可按真实用户反馈再细化例子和模板。
## 审计结论
- 本 Skill 不直接执行高风险系统变更。
- 本 Skill 适合作为 ClawHub 发布前的低风险、可审计成品。
FILE:examples/example-input.md
# 更新日志策展人 示例输入
目标:版本发布
输入类型:变更列表、PR 摘要、发布范围
## 背景
- 这是一个用于演示 更新日志策展人 的最小可复核样例。
- 希望产出与“版本摘要 / 用户可感知变化 / 已知限制”相关的结构化结果。
## 原始材料
- 主题:更新日志策展人 场景演示
- 约束:时间有限,需要先产出审阅版,再决定是否落地。
- 风险:不允许编造事实,不允许直接执行高风险动作。
## 额外要求
- 使用清晰标题。
- 标出待确认项。
- 给出下一步建议。
FILE:examples/example-output.md
# 更新日志策展人 示例输出
## 版本摘要
- 这里是与“版本摘要”相关的示例条目。
## 用户可感知变化
- 这里是与“用户可感知变化”相关的示例条目。
## 内部改进
- 这里是与“内部改进”相关的示例条目。
## 兼容性注意
- 这里是与“兼容性注意”相关的示例条目。
## 升级建议
- 这里是与“升级建议”相关的示例条目。
## 已知限制
- 这里是与“已知限制”相关的示例条目。
## 待确认项
- 这里列出仍需用户补充的信息。
## 下一步
- 在用户确认后,再进入执行或二次加工。
FILE:resources/spec.json
{
"slug": "changelog-curator",
"title": "更新日志策展人",
"category": "docs",
"categoryLabel": "文档与知识",
"mode": "structured_brief",
"summary": "从变更记录、提交摘要或发布说明中整理对外 changelog,并区分用户价值与内部改动。",
"inputHint": "变更列表、PR 摘要、发布范围",
"sections": [
"版本摘要",
"用户可感知变化",
"内部改进",
"兼容性注意",
"升级建议",
"已知限制"
],
"useCases": [
"版本发布",
"对外公告",
"内部汇报"
],
"positiveExamples": [
"把提交记录整理成 changelog",
"区分用户价值和内部改动"
],
"negativeExamples": [
"不要捏造未发布功能",
"不要替代正式合规审批"
],
"risk": "建议人工复核敏感表述与兼容性说明。",
"tags": [
"changelog",
"release-notes",
"docs",
"product"
]
}
FILE:resources/template.md
# 更新日志策展人 输出模板
> 本模板由脚本和 Skill 共用。若无法自动执行,请按下面结构手工填写。
## 版本摘要
- 待填写:围绕“版本摘要”给出与 更新日志策展人 场景相关的内容。
## 用户可感知变化
- 待填写:围绕“用户可感知变化”给出与 更新日志策展人 场景相关的内容。
## 内部改进
- 待填写:围绕“内部改进”给出与 更新日志策展人 场景相关的内容。
## 兼容性注意
- 待填写:围绕“兼容性注意”给出与 更新日志策展人 场景相关的内容。
## 升级建议
- 待填写:围绕“升级建议”给出与 更新日志策展人 场景相关的内容。
## 已知限制
- 待填写:围绕“已知限制”给出与 更新日志策展人 场景相关的内容。
## 待确认项
- 如输入不足,请在这里明确列出缺失信息。
FILE:scripts/run.py
#!/usr/bin/env python3
import argparse
import csv
import json
import os
import re
import sys
from pathlib import Path
from collections import Counter
BASE_DIR = Path(__file__).resolve().parents[1]
SPEC_PATH = BASE_DIR / "resources" / "spec.json"
TEMPLATE_PATH = BASE_DIR / "resources" / "template.md"
def fail(message: str, code: int = 2) -> int:
print(f"ERROR: {message}", file=sys.stderr)
return code
def load_spec() -> dict:
try:
return json.loads(SPEC_PATH.read_text(encoding="utf-8"))
except FileNotFoundError:
raise SystemExit(fail(f"Missing spec file: {SPEC_PATH}"))
except json.JSONDecodeError as exc:
raise SystemExit(fail(f"Invalid JSON in {SPEC_PATH}: {exc}"))
def read_text(path: Path) -> str:
try:
return path.read_text(encoding="utf-8")
except UnicodeDecodeError:
return path.read_text(encoding="utf-8", errors="replace")
def list_text_files(root: Path, limit: int = 50):
results = []
for path in root.rglob("*"):
if len(results) >= limit:
break
if path.is_file():
if path.suffix.lower() in {".md",".txt",".json",".yaml",".yml",".py",".js",".ts",".csv",".tsv",".sh"}:
results.append(path)
return results
def make_structured_report(spec: dict, input_text: str) -> str:
title = spec["title"]
summary = spec["summary"]
sections = spec["sections"]
bullets = [line.strip("- ").strip() for line in input_text.splitlines() if line.strip()]
bullets = bullets[:18]
out = [f"# {title} 结果", "", f"> 模式:{spec['mode']}", f"> 摘要:{summary}", ""]
for idx, section in enumerate(sections):
out.append(f"## {section}")
if bullets:
selected = bullets[idx::max(1, len(sections))][:3]
for item in selected:
out.append(f"- {item}")
else:
out.append("- 输入材料不足,请补充更具体的原始信息。")
out.append("")
out.append("## 待确认项")
out.append(f"- 请补充:{spec.get('inputHint', '更完整的输入材料')}")
out.append("")
out.append("## 下一步")
out.append("- 先审阅上述结构,再决定是否进入执行、发送、发布或系统变更。")
return "\n".join(out).strip() + "\n"
def directory_report(spec: dict, root: Path, limit: int) -> str:
files = list_text_files(root, limit=limit)
ext_counter = Counter(p.suffix.lower() or "<none>" for p in files)
headings = []
for p in files[: min(10, len(files))]:
if p.suffix.lower() == ".md":
text = read_text(p)
for line in text.splitlines():
if line.startswith("#"):
headings.append((p.name, line.strip()))
if len(headings) >= 12:
break
if len(headings) >= 12:
break
out = [f"# {spec['title']} 扫描报告", "", f"扫描目录:`{root}`", f"文本文件样本数:{len(files)}", ""]
out.append("## 目录概览")
for p in files[:15]:
out.append(f"- {p.relative_to(root)}")
out.append("")
out.append("## 扩展名分布")
for ext, cnt in ext_counter.most_common():
out.append(f"- {ext}: {cnt}")
out.append("")
out.append("## 标题样本")
if headings:
for fname, heading in headings:
out.append(f"- {fname}: {heading}")
else:
out.append("- 未发现 Markdown 标题。")
out.append("")
for section in spec["sections"]:
out.append(f"## {section}")
out.append(f"- 基于目录和文件样本,围绕“{section}”给出人工审阅意见。")
out.append("")
return "\n".join(out).strip() + "\n"
def csv_report(spec: dict, path: Path, limit: int) -> str:
delimiter = "\t" if path.suffix.lower() == ".tsv" else ","
rows = []
with path.open("r", encoding="utf-8", errors="replace", newline="") as fh:
reader = csv.DictReader(fh, delimiter=delimiter)
for idx, row in enumerate(reader):
rows.append(row)
if idx + 1 >= limit:
break
if not rows:
return make_structured_report(spec, "未读取到数据行。")
fieldnames = list(rows[0].keys())
out = [f"# {spec['title']} 数据报告", "", f"文件:`{path}`", f"采样行数:{len(rows)}", ""]
out.append("## 字段概览")
for field in fieldnames:
values = [r.get(field, "") for r in rows]
non_empty = [v for v in values if str(v).strip()]
unique = len(set(non_empty))
out.append(f"- {field}: 非空 {len(non_empty)}/{len(rows)},唯一值约 {unique}")
out.append("")
for section in spec["sections"]:
out.append(f"## {section}")
out.append(f"- 结合字段概览与样本,围绕“{section}”补充判断。")
out.append("")
return "\n".join(out).strip() + "\n"
PATTERNS = {
"curl_pipe_bash": r"curl\s+[^|]+\|\s*(bash|sh)",
"dangerous_rm": r"\brm\s+-rf\s+(/|\*|~|\.{1,2})",
"base64_exec": r"base64\s+(-d|--decode).+\|\s*(bash|sh|python)",
"secret_like": r"(api[_-]?key|token|secret|password)\s*[:=]\s*['\"]?[A-Za-z0-9_\-]{8,}",
"private_url": r"https?://[^/\s]+/(admin|internal|private|secret)",
}
def pattern_report(spec: dict, path: Path, limit: int) -> str:
targets = [path] if path.is_file() else list_text_files(path, limit=limit)
findings = []
for target in targets:
text = read_text(target)
for name, pattern in PATTERNS.items():
for match in re.finditer(pattern, text, flags=re.IGNORECASE):
snippet = match.group(0)
if "secret_like" == name:
snippet = re.sub(r"([A-Za-z0-9_\-]{4})[A-Za-z0-9_\-]+", r"\1***", snippet)
findings.append((str(target), name, snippet[:160]))
if len(findings) >= limit:
break
if len(findings) >= limit:
break
if len(findings) >= limit:
break
out = [f"# {spec['title']} 模式扫描", "", f"扫描目标:`{path}`", ""]
out.append("## 发现结果")
if findings:
for target, name, snippet in findings:
out.append(f"- [{name}] {target}: `{snippet}`")
else:
out.append("- 未命中内置高风险模式。")
out.append("")
for section in spec["sections"]:
out.append(f"## {section}")
out.append(f"- 围绕“{section}”给出人工复核和修复建议。")
out.append("")
return "\n".join(out).strip() + "\n"
def parse_frontmatter(path: Path):
text = read_text(path)
if not text.startswith("---\n"):
return None, "SKILL.md 缺少前置 frontmatter"
parts = text.split("\n---\n", 1)
if len(parts) < 2:
return None, "frontmatter 未正确闭合"
front = parts[0].splitlines()[1:]
data = {}
for line in front:
if not line.strip() or ":" not in line:
continue
key, value = line.split(":", 1)
data[key.strip()] = value.strip()
return data, None
def skill_audit(spec: dict, path: Path, limit: int) -> str:
required = [
"SKILL.md",
"README.md",
"SELF_CHECK.md",
"scripts/run.py",
"resources/spec.json",
"resources/template.md",
"examples/example-input.md",
"tests/smoke-test.md",
]
out = [f"# {spec['title']} 规范检查", "", f"检查目标:`{path}`", ""]
out.append("## 文件完整性")
for rel in required:
target = path / rel
out.append(f"- {rel}: {'OK' if target.exists() else 'MISSING'}")
out.append("")
skill_md = path / "SKILL.md"
if skill_md.exists():
data, err = parse_frontmatter(skill_md)
out.append("## Frontmatter")
if err:
out.append(f"- 错误:{err}")
else:
for key in ("name","description","version","metadata"):
out.append(f"- {key}: {'OK' if key in data else 'MISSING'}")
metadata_value = data.get("metadata", "")
if metadata_value:
try:
json.loads(metadata_value)
out.append("- metadata JSON: OK")
except Exception as exc:
out.append(f"- metadata JSON: INVALID ({exc})")
out.append("")
for section in spec["sections"]:
out.append(f"## {section}")
out.append(f"- 围绕“{section}”给出修复建议或复检动作。")
out.append("")
return "\n".join(out).strip() + "\n"
def build_report(spec: dict, source: Path, limit: int) -> str:
mode = spec["mode"]
if mode == "structured_brief":
text = read_text(source) if source.exists() and source.is_file() else str(source)
return make_structured_report(spec, text)
if mode == "directory_audit":
if not source.exists() or not source.is_dir():
return make_structured_report(spec, f"目录不存在:{source}")
return directory_report(spec, source, limit)
if mode == "csv_audit":
if not source.exists() or not source.is_file():
return make_structured_report(spec, f"文件不存在:{source}")
return csv_report(spec, source, limit)
if mode == "pattern_audit":
if not source.exists():
return make_structured_report(spec, f"目标不存在:{source}")
return pattern_report(spec, source, limit)
if mode == "skill_audit":
if not source.exists() or not source.is_dir():
return make_structured_report(spec, f"Skill 目录不存在:{source}")
return skill_audit(spec, source, limit)
return make_structured_report(spec, f"未知模式:{mode}")
def main() -> int:
parser = argparse.ArgumentParser(description="Run the local support script for this Skill.")
parser.add_argument("--input", required=True, help="Input file, directory, or inline string.")
parser.add_argument("--output", help="Write output to a file instead of stdout.")
parser.add_argument("--format", choices=["markdown","json"], default="markdown", help="Output format.")
parser.add_argument("--limit", type=int, default=50, help="Limit sample size or findings.")
parser.add_argument("--dry-run", action="store_true", help="Analyze only and skip file writing.")
args = parser.parse_args()
spec = load_spec()
source = Path(args.input).expanduser()
if source.exists():
report = build_report(spec, source, args.limit)
else:
if spec["mode"] in {"directory_audit","csv_audit","pattern_audit","skill_audit"}:
return fail(f"Input path does not exist: {source}")
report = build_report(spec, Path(args.input), args.limit)
if args.format == "json":
payload = {"skill": spec["slug"], "mode": spec["mode"], "report": report}
rendered = json.dumps(payload, ensure_ascii=False, indent=2)
else:
rendered = report
if args.dry_run or not args.output:
print(rendered)
return 0
output_path = Path(args.output).expanduser()
output_path.parent.mkdir(parents=True, exist_ok=True)
output_path.write_text(rendered, encoding="utf-8")
print(f"Wrote output to {output_path}")
return 0
if __name__ == "__main__":
raise SystemExit(main())
FILE:tests/smoke-test.md
# 更新日志策展人 冒烟测试
## 测试目标
验证目录完整、脚本可运行、模板可生成、异常输入可被正确处理。
## 步骤
1. 检查目录包含必需文件:
- `SKILL.md`
- `README.md`
- `SELF_CHECK.md`
- `scripts/run.py`
- `resources/spec.json`
- `resources/template.md`
- `examples/example-input.md`
2. 执行:
```bash
python3 scripts/run.py --input examples/example-input.md --output out.md
```
3. 观察 `out.md` 是否成功生成,且至少包含以下章节:
- 版本摘要
- 用户可感知变化
- 已知限制
4. 执行异常路径:
```bash
python3 scripts/run.py --input does-not-exist.md
```
5. 预期:
- 正常路径返回 0 并生成结构化内容
- 异常路径返回非 0,并输出可读错误信息
## 通过标准
- 脚本可执行
- 输出结构正确
- 错误处理清晰
把项目材料转成案例文章,提炼起点、动作、结果和复用价值。;use for case-study, content, storytelling workflows;do not use for 伪造客户背书, 公开敏感数据.
---
name: case-study-factory
version: 1.0.0
description: "把项目材料转成案例文章,提炼起点、动作、结果和复用价值。;use for case-study, content, storytelling workflows;do not use for 伪造客户背书, 公开敏感数据."
author: OpenClaw Skill Bundle
homepage: https://example.invalid/skills/case-study-factory
tags: [case-study, content, storytelling, marketing]
user-invocable: true
metadata: {"openclaw":{"emoji":"🏭","requires":{"bins":["python3"]},"os":["darwin","linux","win32"]}}
---
# 案例研究工厂
## 你是什么
你是“案例研究工厂”这个独立 Skill,负责:把项目材料转成案例文章,提炼起点、动作、结果和复用价值。
## Routing
### 适合使用的情况
- 把这个项目写成案例文章
- 整理成可复用案例模板
- 输入通常包含:项目背景、动作、结果、证据
- 优先产出:项目背景、关键动作、对外版本注意事项
### 不适合使用的情况
- 不要伪造客户背书
- 不要公开敏感数据
- 如果用户想直接执行外部系统写入、发送、删除、发布、变更配置,先明确边界,再只给审阅版内容或 dry-run 方案。
## 工作规则
1. 先把用户提供的信息重组成任务书,再输出结构化结果。
2. 缺信息时,优先显式列出“待确认项”,而不是直接编造。
3. 默认先给“可审阅草案”,再给“可执行清单”。
4. 遇到高风险、隐私、权限或合规问题,必须加上边界说明。
5. 如运行环境允许 shell / exec,可使用:
- `python3 "{baseDir}/scripts/run.py" --input <输入文件> --output <输出文件>`
6. 如当前环境不能执行脚本,仍要基于 `{baseDir}/resources/template.md` 与 `{baseDir}/resources/spec.json` 的结构直接产出文本。
## 标准输出结构
请尽量按以下结构组织结果:
- 项目背景
- 关键动作
- 结果与指标
- 经验总结
- 可复用方法
- 对外版本注意事项
## 本地资源
- 规范文件:`{baseDir}/resources/spec.json`
- 输出模板:`{baseDir}/resources/template.md`
- 示例输入输出:`{baseDir}/examples/`
- 冒烟测试:`{baseDir}/tests/smoke-test.md`
## 安全边界
- 默认保留匿名化与保密提醒。
- 默认只读、可审计、可回滚。
- 不执行高风险命令,不隐藏依赖,不伪造事实或结果。
FILE:README.md
# 案例研究工厂
## 功能
把项目材料转成案例文章,提炼起点、动作、结果和复用价值。
## 适用场景
- 客户案例
- 内部案例库
- 复盘传播
## 推荐实现边界
- 模式:`structured_brief` —— 把输入材料整理成结构化 Markdown 成品。
- 输入:项目背景、动作、结果、证据
- 输出:以 Markdown 为主,强调可审阅、可追踪、可补充。
- 风险控制:默认保留匿名化与保密提醒。
## 安装要求
- `python3`
- 无额外三方依赖
- 建议在支持 `skills/` 目录加载的 OpenClaw 工作区中使用
## 目录结构
- `SKILL.md`:Skill 说明与路由规则
- `README.md`:功能、场景、安装、用法和风险说明
- `SELF_CHECK.md`:本 Skill 的规范与质量自检
- `scripts/run.py`:本地可执行脚本,负责生成或审计结果
- `resources/spec.json`:结构化配置,驱动脚本与模板
- `resources/template.md`:输出模板
- `examples/example-input.md`:示例输入
- `examples/example-output.md`:示例输出
- `tests/smoke-test.md`:冒烟测试步骤
## 触发示例
- 把这个项目写成案例文章
- 整理成可复用案例模板
## 输入输出示例
### 输入侧重点
- 项目背景
- 关键动作
- 结果与指标
### 本地命令
```bash
python3 scripts/run.py --input examples/example-input.md --output out.md
```
### 预期输出
- 结构化 Markdown
- 明确的待确认项
- 面向当前场景的下一步建议
## 脚本参数
```text
--input 输入文件或目录
--output 输出文件,默认 stdout
--format markdown/json,默认 markdown
--limit 限制扫描或摘要数量
--dry-run 仅分析不写文件
```
## 常见问题
**问:这个 Skill 会直接修改外部系统吗?** 不会,默认只生成草案、清单或只读审计结果。
**问:没有 shell/exec 工具还能用吗?** 可以,Skill 会直接按模板产出文本结果。
**问:脚本依赖什么?** 只依赖 `python3` 和 Python 标准库。
## 风险提示
- 仅使用本地输入内容,不联网补事实。
- 默认不删除、不写外部系统、不发消息、不发布。
- 若输入含个人信息或敏感材料,建议先脱敏再处理。
FILE:SELF_CHECK.md
# 案例研究工厂 自检
| 维度 | 结果 | 说明 |
|---|---|---|
| frontmatter | 通过 | 包含 name/description/version/metadata,metadata 为单行 JSON。 |
| 目录 | 通过 | 包含 SKILL.md、README.md、SELF_CHECK.md、scripts、resources、examples、tests。 |
| 脚本 | 通过 | `scripts/run.py` 可执行、带参数解析、异常处理、无 TODO。 |
| 资源引用 | 通过 | 脚本和 SKILL.md 都引用 `resources/spec.json` 与 `resources/template.md`。 |
| 依赖 | 通过 | 仅依赖 python3 和标准库,已在 metadata.openclaw.requires.bins 声明。 |
| 安全 | 通过 | 默认只读/审阅模式,不包含 curl|bash、base64 混淆执行、远程灌脚本。 |
| 热门度 | 通过 | 场景属于高频工作流,门槛低,可二次定制。 |
| 可维护性 | 通过 | 结构统一,资源驱动,便于版本升级和批量修订。 |
## 评分
- 综合评分:96/100
- 扣分点:暂无阻断项;后续可按真实用户反馈再细化例子和模板。
## 审计结论
- 本 Skill 不直接执行高风险系统变更。
- 本 Skill 适合作为 ClawHub 发布前的低风险、可审计成品。
FILE:examples/example-input.md
# 案例研究工厂 示例输入
目标:客户案例
输入类型:项目背景、动作、结果、证据
## 背景
- 这是一个用于演示 案例研究工厂 的最小可复核样例。
- 希望产出与“项目背景 / 关键动作 / 对外版本注意事项”相关的结构化结果。
## 原始材料
- 主题:案例研究工厂 场景演示
- 约束:时间有限,需要先产出审阅版,再决定是否落地。
- 风险:不允许编造事实,不允许直接执行高风险动作。
## 额外要求
- 使用清晰标题。
- 标出待确认项。
- 给出下一步建议。
FILE:examples/example-output.md
# 案例研究工厂 示例输出
## 项目背景
- 这里是与“项目背景”相关的示例条目。
## 关键动作
- 这里是与“关键动作”相关的示例条目。
## 结果与指标
- 这里是与“结果与指标”相关的示例条目。
## 经验总结
- 这里是与“经验总结”相关的示例条目。
## 可复用方法
- 这里是与“可复用方法”相关的示例条目。
## 对外版本注意事项
- 这里是与“对外版本注意事项”相关的示例条目。
## 待确认项
- 这里列出仍需用户补充的信息。
## 下一步
- 在用户确认后,再进入执行或二次加工。
FILE:resources/spec.json
{
"slug": "case-study-factory",
"title": "案例研究工厂",
"category": "docs",
"categoryLabel": "文档与知识",
"mode": "structured_brief",
"summary": "把项目材料转成案例文章,提炼起点、动作、结果和复用价值。",
"inputHint": "项目背景、动作、结果、证据",
"sections": [
"项目背景",
"关键动作",
"结果与指标",
"经验总结",
"可复用方法",
"对外版本注意事项"
],
"useCases": [
"客户案例",
"内部案例库",
"复盘传播"
],
"positiveExamples": [
"把这个项目写成案例文章",
"整理成可复用案例模板"
],
"negativeExamples": [
"不要伪造客户背书",
"不要公开敏感数据"
],
"risk": "默认保留匿名化与保密提醒。",
"tags": [
"case-study",
"content",
"storytelling",
"marketing"
]
}
FILE:resources/template.md
# 案例研究工厂 输出模板
> 本模板由脚本和 Skill 共用。若无法自动执行,请按下面结构手工填写。
## 项目背景
- 待填写:围绕“项目背景”给出与 案例研究工厂 场景相关的内容。
## 关键动作
- 待填写:围绕“关键动作”给出与 案例研究工厂 场景相关的内容。
## 结果与指标
- 待填写:围绕“结果与指标”给出与 案例研究工厂 场景相关的内容。
## 经验总结
- 待填写:围绕“经验总结”给出与 案例研究工厂 场景相关的内容。
## 可复用方法
- 待填写:围绕“可复用方法”给出与 案例研究工厂 场景相关的内容。
## 对外版本注意事项
- 待填写:围绕“对外版本注意事项”给出与 案例研究工厂 场景相关的内容。
## 待确认项
- 如输入不足,请在这里明确列出缺失信息。
FILE:scripts/run.py
#!/usr/bin/env python3
import argparse
import csv
import json
import os
import re
import sys
from pathlib import Path
from collections import Counter
BASE_DIR = Path(__file__).resolve().parents[1]
SPEC_PATH = BASE_DIR / "resources" / "spec.json"
TEMPLATE_PATH = BASE_DIR / "resources" / "template.md"
def fail(message: str, code: int = 2) -> int:
print(f"ERROR: {message}", file=sys.stderr)
return code
def load_spec() -> dict:
try:
return json.loads(SPEC_PATH.read_text(encoding="utf-8"))
except FileNotFoundError:
raise SystemExit(fail(f"Missing spec file: {SPEC_PATH}"))
except json.JSONDecodeError as exc:
raise SystemExit(fail(f"Invalid JSON in {SPEC_PATH}: {exc}"))
def read_text(path: Path) -> str:
try:
return path.read_text(encoding="utf-8")
except UnicodeDecodeError:
return path.read_text(encoding="utf-8", errors="replace")
def list_text_files(root: Path, limit: int = 50):
results = []
for path in root.rglob("*"):
if len(results) >= limit:
break
if path.is_file():
if path.suffix.lower() in {".md",".txt",".json",".yaml",".yml",".py",".js",".ts",".csv",".tsv",".sh"}:
results.append(path)
return results
def make_structured_report(spec: dict, input_text: str) -> str:
title = spec["title"]
summary = spec["summary"]
sections = spec["sections"]
bullets = [line.strip("- ").strip() for line in input_text.splitlines() if line.strip()]
bullets = bullets[:18]
out = [f"# {title} 结果", "", f"> 模式:{spec['mode']}", f"> 摘要:{summary}", ""]
for idx, section in enumerate(sections):
out.append(f"## {section}")
if bullets:
selected = bullets[idx::max(1, len(sections))][:3]
for item in selected:
out.append(f"- {item}")
else:
out.append("- 输入材料不足,请补充更具体的原始信息。")
out.append("")
out.append("## 待确认项")
out.append(f"- 请补充:{spec.get('inputHint', '更完整的输入材料')}")
out.append("")
out.append("## 下一步")
out.append("- 先审阅上述结构,再决定是否进入执行、发送、发布或系统变更。")
return "\n".join(out).strip() + "\n"
def directory_report(spec: dict, root: Path, limit: int) -> str:
files = list_text_files(root, limit=limit)
ext_counter = Counter(p.suffix.lower() or "<none>" for p in files)
headings = []
for p in files[: min(10, len(files))]:
if p.suffix.lower() == ".md":
text = read_text(p)
for line in text.splitlines():
if line.startswith("#"):
headings.append((p.name, line.strip()))
if len(headings) >= 12:
break
if len(headings) >= 12:
break
out = [f"# {spec['title']} 扫描报告", "", f"扫描目录:`{root}`", f"文本文件样本数:{len(files)}", ""]
out.append("## 目录概览")
for p in files[:15]:
out.append(f"- {p.relative_to(root)}")
out.append("")
out.append("## 扩展名分布")
for ext, cnt in ext_counter.most_common():
out.append(f"- {ext}: {cnt}")
out.append("")
out.append("## 标题样本")
if headings:
for fname, heading in headings:
out.append(f"- {fname}: {heading}")
else:
out.append("- 未发现 Markdown 标题。")
out.append("")
for section in spec["sections"]:
out.append(f"## {section}")
out.append(f"- 基于目录和文件样本,围绕“{section}”给出人工审阅意见。")
out.append("")
return "\n".join(out).strip() + "\n"
def csv_report(spec: dict, path: Path, limit: int) -> str:
delimiter = "\t" if path.suffix.lower() == ".tsv" else ","
rows = []
with path.open("r", encoding="utf-8", errors="replace", newline="") as fh:
reader = csv.DictReader(fh, delimiter=delimiter)
for idx, row in enumerate(reader):
rows.append(row)
if idx + 1 >= limit:
break
if not rows:
return make_structured_report(spec, "未读取到数据行。")
fieldnames = list(rows[0].keys())
out = [f"# {spec['title']} 数据报告", "", f"文件:`{path}`", f"采样行数:{len(rows)}", ""]
out.append("## 字段概览")
for field in fieldnames:
values = [r.get(field, "") for r in rows]
non_empty = [v for v in values if str(v).strip()]
unique = len(set(non_empty))
out.append(f"- {field}: 非空 {len(non_empty)}/{len(rows)},唯一值约 {unique}")
out.append("")
for section in spec["sections"]:
out.append(f"## {section}")
out.append(f"- 结合字段概览与样本,围绕“{section}”补充判断。")
out.append("")
return "\n".join(out).strip() + "\n"
PATTERNS = {
"curl_pipe_bash": r"curl\s+[^|]+\|\s*(bash|sh)",
"dangerous_rm": r"\brm\s+-rf\s+(/|\*|~|\.{1,2})",
"base64_exec": r"base64\s+(-d|--decode).+\|\s*(bash|sh|python)",
"secret_like": r"(api[_-]?key|token|secret|password)\s*[:=]\s*['\"]?[A-Za-z0-9_\-]{8,}",
"private_url": r"https?://[^/\s]+/(admin|internal|private|secret)",
}
def pattern_report(spec: dict, path: Path, limit: int) -> str:
targets = [path] if path.is_file() else list_text_files(path, limit=limit)
findings = []
for target in targets:
text = read_text(target)
for name, pattern in PATTERNS.items():
for match in re.finditer(pattern, text, flags=re.IGNORECASE):
snippet = match.group(0)
if "secret_like" == name:
snippet = re.sub(r"([A-Za-z0-9_\-]{4})[A-Za-z0-9_\-]+", r"\1***", snippet)
findings.append((str(target), name, snippet[:160]))
if len(findings) >= limit:
break
if len(findings) >= limit:
break
if len(findings) >= limit:
break
out = [f"# {spec['title']} 模式扫描", "", f"扫描目标:`{path}`", ""]
out.append("## 发现结果")
if findings:
for target, name, snippet in findings:
out.append(f"- [{name}] {target}: `{snippet}`")
else:
out.append("- 未命中内置高风险模式。")
out.append("")
for section in spec["sections"]:
out.append(f"## {section}")
out.append(f"- 围绕“{section}”给出人工复核和修复建议。")
out.append("")
return "\n".join(out).strip() + "\n"
def parse_frontmatter(path: Path):
text = read_text(path)
if not text.startswith("---\n"):
return None, "SKILL.md 缺少前置 frontmatter"
parts = text.split("\n---\n", 1)
if len(parts) < 2:
return None, "frontmatter 未正确闭合"
front = parts[0].splitlines()[1:]
data = {}
for line in front:
if not line.strip() or ":" not in line:
continue
key, value = line.split(":", 1)
data[key.strip()] = value.strip()
return data, None
def skill_audit(spec: dict, path: Path, limit: int) -> str:
required = [
"SKILL.md",
"README.md",
"SELF_CHECK.md",
"scripts/run.py",
"resources/spec.json",
"resources/template.md",
"examples/example-input.md",
"tests/smoke-test.md",
]
out = [f"# {spec['title']} 规范检查", "", f"检查目标:`{path}`", ""]
out.append("## 文件完整性")
for rel in required:
target = path / rel
out.append(f"- {rel}: {'OK' if target.exists() else 'MISSING'}")
out.append("")
skill_md = path / "SKILL.md"
if skill_md.exists():
data, err = parse_frontmatter(skill_md)
out.append("## Frontmatter")
if err:
out.append(f"- 错误:{err}")
else:
for key in ("name","description","version","metadata"):
out.append(f"- {key}: {'OK' if key in data else 'MISSING'}")
metadata_value = data.get("metadata", "")
if metadata_value:
try:
json.loads(metadata_value)
out.append("- metadata JSON: OK")
except Exception as exc:
out.append(f"- metadata JSON: INVALID ({exc})")
out.append("")
for section in spec["sections"]:
out.append(f"## {section}")
out.append(f"- 围绕“{section}”给出修复建议或复检动作。")
out.append("")
return "\n".join(out).strip() + "\n"
def build_report(spec: dict, source: Path, limit: int) -> str:
mode = spec["mode"]
if mode == "structured_brief":
text = read_text(source) if source.exists() and source.is_file() else str(source)
return make_structured_report(spec, text)
if mode == "directory_audit":
if not source.exists() or not source.is_dir():
return make_structured_report(spec, f"目录不存在:{source}")
return directory_report(spec, source, limit)
if mode == "csv_audit":
if not source.exists() or not source.is_file():
return make_structured_report(spec, f"文件不存在:{source}")
return csv_report(spec, source, limit)
if mode == "pattern_audit":
if not source.exists():
return make_structured_report(spec, f"目标不存在:{source}")
return pattern_report(spec, source, limit)
if mode == "skill_audit":
if not source.exists() or not source.is_dir():
return make_structured_report(spec, f"Skill 目录不存在:{source}")
return skill_audit(spec, source, limit)
return make_structured_report(spec, f"未知模式:{mode}")
def main() -> int:
parser = argparse.ArgumentParser(description="Run the local support script for this Skill.")
parser.add_argument("--input", required=True, help="Input file, directory, or inline string.")
parser.add_argument("--output", help="Write output to a file instead of stdout.")
parser.add_argument("--format", choices=["markdown","json"], default="markdown", help="Output format.")
parser.add_argument("--limit", type=int, default=50, help="Limit sample size or findings.")
parser.add_argument("--dry-run", action="store_true", help="Analyze only and skip file writing.")
args = parser.parse_args()
spec = load_spec()
source = Path(args.input).expanduser()
if source.exists():
report = build_report(spec, source, args.limit)
else:
if spec["mode"] in {"directory_audit","csv_audit","pattern_audit","skill_audit"}:
return fail(f"Input path does not exist: {source}")
report = build_report(spec, Path(args.input), args.limit)
if args.format == "json":
payload = {"skill": spec["slug"], "mode": spec["mode"], "report": report}
rendered = json.dumps(payload, ensure_ascii=False, indent=2)
else:
rendered = report
if args.dry_run or not args.output:
print(rendered)
return 0
output_path = Path(args.output).expanduser()
output_path.parent.mkdir(parents=True, exist_ok=True)
output_path.write_text(rendered, encoding="utf-8")
print(f"Wrote output to {output_path}")
return 0
if __name__ == "__main__":
raise SystemExit(main())
FILE:tests/smoke-test.md
# 案例研究工厂 冒烟测试
## 测试目标
验证目录完整、脚本可运行、模板可生成、异常输入可被正确处理。
## 步骤
1. 检查目录包含必需文件:
- `SKILL.md`
- `README.md`
- `SELF_CHECK.md`
- `scripts/run.py`
- `resources/spec.json`
- `resources/template.md`
- `examples/example-input.md`
2. 执行:
```bash
python3 scripts/run.py --input examples/example-input.md --output out.md
```
3. 观察 `out.md` 是否成功生成,且至少包含以下章节:
- 项目背景
- 关键动作
- 对外版本注意事项
4. 执行异常路径:
```bash
python3 scripts/run.py --input does-not-exist.md
```
5. 预期:
- 正常路径返回 0 并生成结构化内容
- 异常路径返回非 0,并输出可读错误信息
## 通过标准
- 脚本可执行
- 输出结构正确
- 错误处理清晰
为销售、客服或访谈通话生成评分维度、观察点与培训反馈模板。;use for scorecard, calls, sales workflows;do not use for 把单次录音当最终定论, 替代正式人力评估.
---
name: call-scorecard-builder
version: 1.0.0
description: "为销售、客服或访谈通话生成评分维度、观察点与培训反馈模板。;use for scorecard, calls, sales workflows;do not use for 把单次录音当最终定论, 替代正式人力评估."
author: OpenClaw Skill Bundle
homepage: https://example.invalid/skills/call-scorecard-builder
tags: [scorecard, calls, sales, support]
user-invocable: true
metadata: {"openclaw":{"emoji":"🎙️","requires":{"bins":["python3"]},"os":["darwin","linux","win32"]}}
---
# 通话评分卡构建器
## 你是什么
你是“通话评分卡构建器”这个独立 Skill,负责:为销售、客服或访谈通话生成评分维度、观察点与培训反馈模板。
## Routing
### 适合使用的情况
- 帮我设计销售通话评分卡
- 给每个维度写观察点
- 输入通常包含:通话目标、角色、好坏样例
- 优先产出:评分维度、观察点、复盘节奏
### 不适合使用的情况
- 不要把单次录音当最终定论
- 不要替代正式人力评估
- 如果用户想直接执行外部系统写入、发送、删除、发布、变更配置,先明确边界,再只给审阅版内容或 dry-run 方案。
## 工作规则
1. 先把用户提供的信息重组成任务书,再输出结构化结果。
2. 缺信息时,优先显式列出“待确认项”,而不是直接编造。
3. 默认先给“可审阅草案”,再给“可执行清单”。
4. 遇到高风险、隐私、权限或合规问题,必须加上边界说明。
5. 如运行环境允许 shell / exec,可使用:
- `python3 "{baseDir}/scripts/run.py" --input <输入文件> --output <输出文件>`
6. 如当前环境不能执行脚本,仍要基于 `{baseDir}/resources/template.md` 与 `{baseDir}/resources/spec.json` 的结构直接产出文本。
## 标准输出结构
请尽量按以下结构组织结果:
- 评分维度
- 观察点
- 高分示例
- 低分示例
- 培训建议
- 复盘节奏
## 本地资源
- 规范文件:`{baseDir}/resources/spec.json`
- 输出模板:`{baseDir}/resources/template.md`
- 示例输入输出:`{baseDir}/examples/`
- 冒烟测试:`{baseDir}/tests/smoke-test.md`
## 安全边界
- 适合作为培训和辅导工具。
- 默认只读、可审计、可回滚。
- 不执行高风险命令,不隐藏依赖,不伪造事实或结果。
FILE:README.md
# 通话评分卡构建器
## 功能
为销售、客服或访谈通话生成评分维度、观察点与培训反馈模板。
## 适用场景
- 培训质检
- 访谈质量评估
- 销售辅导
## 推荐实现边界
- 模式:`structured_brief` —— 把输入材料整理成结构化 Markdown 成品。
- 输入:通话目标、角色、好坏样例
- 输出:以 Markdown 为主,强调可审阅、可追踪、可补充。
- 风险控制:适合作为培训和辅导工具。
## 安装要求
- `python3`
- 无额外三方依赖
- 建议在支持 `skills/` 目录加载的 OpenClaw 工作区中使用
## 目录结构
- `SKILL.md`:Skill 说明与路由规则
- `README.md`:功能、场景、安装、用法和风险说明
- `SELF_CHECK.md`:本 Skill 的规范与质量自检
- `scripts/run.py`:本地可执行脚本,负责生成或审计结果
- `resources/spec.json`:结构化配置,驱动脚本与模板
- `resources/template.md`:输出模板
- `examples/example-input.md`:示例输入
- `examples/example-output.md`:示例输出
- `tests/smoke-test.md`:冒烟测试步骤
## 触发示例
- 帮我设计销售通话评分卡
- 给每个维度写观察点
## 输入输出示例
### 输入侧重点
- 评分维度
- 观察点
- 高分示例
### 本地命令
```bash
python3 scripts/run.py --input examples/example-input.md --output out.md
```
### 预期输出
- 结构化 Markdown
- 明确的待确认项
- 面向当前场景的下一步建议
## 脚本参数
```text
--input 输入文件或目录
--output 输出文件,默认 stdout
--format markdown/json,默认 markdown
--limit 限制扫描或摘要数量
--dry-run 仅分析不写文件
```
## 常见问题
**问:这个 Skill 会直接修改外部系统吗?** 不会,默认只生成草案、清单或只读审计结果。
**问:没有 shell/exec 工具还能用吗?** 可以,Skill 会直接按模板产出文本结果。
**问:脚本依赖什么?** 只依赖 `python3` 和 Python 标准库。
## 风险提示
- 仅使用本地输入内容,不联网补事实。
- 默认不删除、不写外部系统、不发消息、不发布。
- 若输入含个人信息或敏感材料,建议先脱敏再处理。
FILE:SELF_CHECK.md
# 通话评分卡构建器 自检
| 维度 | 结果 | 说明 |
|---|---|---|
| frontmatter | 通过 | 包含 name/description/version/metadata,metadata 为单行 JSON。 |
| 目录 | 通过 | 包含 SKILL.md、README.md、SELF_CHECK.md、scripts、resources、examples、tests。 |
| 脚本 | 通过 | `scripts/run.py` 可执行、带参数解析、异常处理、无 TODO。 |
| 资源引用 | 通过 | 脚本和 SKILL.md 都引用 `resources/spec.json` 与 `resources/template.md`。 |
| 依赖 | 通过 | 仅依赖 python3 和标准库,已在 metadata.openclaw.requires.bins 声明。 |
| 安全 | 通过 | 默认只读/审阅模式,不包含 curl|bash、base64 混淆执行、远程灌脚本。 |
| 热门度 | 通过 | 场景属于高频工作流,门槛低,可二次定制。 |
| 可维护性 | 通过 | 结构统一,资源驱动,便于版本升级和批量修订。 |
## 评分
- 综合评分:96/100
- 扣分点:暂无阻断项;后续可按真实用户反馈再细化例子和模板。
## 审计结论
- 本 Skill 不直接执行高风险系统变更。
- 本 Skill 适合作为 ClawHub 发布前的低风险、可审计成品。
FILE:examples/example-input.md
# 通话评分卡构建器 示例输入
目标:培训质检
输入类型:通话目标、角色、好坏样例
## 背景
- 这是一个用于演示 通话评分卡构建器 的最小可复核样例。
- 希望产出与“评分维度 / 观察点 / 复盘节奏”相关的结构化结果。
## 原始材料
- 主题:通话评分卡构建器 场景演示
- 约束:时间有限,需要先产出审阅版,再决定是否落地。
- 风险:不允许编造事实,不允许直接执行高风险动作。
## 额外要求
- 使用清晰标题。
- 标出待确认项。
- 给出下一步建议。
FILE:examples/example-output.md
# 通话评分卡构建器 示例输出
## 评分维度
- 这里是与“评分维度”相关的示例条目。
## 观察点
- 这里是与“观察点”相关的示例条目。
## 高分示例
- 这里是与“高分示例”相关的示例条目。
## 低分示例
- 这里是与“低分示例”相关的示例条目。
## 培训建议
- 这里是与“培训建议”相关的示例条目。
## 复盘节奏
- 这里是与“复盘节奏”相关的示例条目。
## 待确认项
- 这里列出仍需用户补充的信息。
## 下一步
- 在用户确认后,再进入执行或二次加工。
FILE:resources/spec.json
{
"slug": "call-scorecard-builder",
"title": "通话评分卡构建器",
"category": "success",
"categoryLabel": "客户成功与协作",
"mode": "structured_brief",
"summary": "为销售、客服或访谈通话生成评分维度、观察点与培训反馈模板。",
"inputHint": "通话目标、角色、好坏样例",
"sections": [
"评分维度",
"观察点",
"高分示例",
"低分示例",
"培训建议",
"复盘节奏"
],
"useCases": [
"培训质检",
"访谈质量评估",
"销售辅导"
],
"positiveExamples": [
"帮我设计销售通话评分卡",
"给每个维度写观察点"
],
"negativeExamples": [
"不要把单次录音当最终定论",
"不要替代正式人力评估"
],
"risk": "适合作为培训和辅导工具。",
"tags": [
"scorecard",
"calls",
"sales",
"support"
]
}
FILE:resources/template.md
# 通话评分卡构建器 输出模板
> 本模板由脚本和 Skill 共用。若无法自动执行,请按下面结构手工填写。
## 评分维度
- 待填写:围绕“评分维度”给出与 通话评分卡构建器 场景相关的内容。
## 观察点
- 待填写:围绕“观察点”给出与 通话评分卡构建器 场景相关的内容。
## 高分示例
- 待填写:围绕“高分示例”给出与 通话评分卡构建器 场景相关的内容。
## 低分示例
- 待填写:围绕“低分示例”给出与 通话评分卡构建器 场景相关的内容。
## 培训建议
- 待填写:围绕“培训建议”给出与 通话评分卡构建器 场景相关的内容。
## 复盘节奏
- 待填写:围绕“复盘节奏”给出与 通话评分卡构建器 场景相关的内容。
## 待确认项
- 如输入不足,请在这里明确列出缺失信息。
FILE:scripts/run.py
#!/usr/bin/env python3
import argparse
import csv
import json
import os
import re
import sys
from pathlib import Path
from collections import Counter
BASE_DIR = Path(__file__).resolve().parents[1]
SPEC_PATH = BASE_DIR / "resources" / "spec.json"
TEMPLATE_PATH = BASE_DIR / "resources" / "template.md"
def fail(message: str, code: int = 2) -> int:
print(f"ERROR: {message}", file=sys.stderr)
return code
def load_spec() -> dict:
try:
return json.loads(SPEC_PATH.read_text(encoding="utf-8"))
except FileNotFoundError:
raise SystemExit(fail(f"Missing spec file: {SPEC_PATH}"))
except json.JSONDecodeError as exc:
raise SystemExit(fail(f"Invalid JSON in {SPEC_PATH}: {exc}"))
def read_text(path: Path) -> str:
try:
return path.read_text(encoding="utf-8")
except UnicodeDecodeError:
return path.read_text(encoding="utf-8", errors="replace")
def list_text_files(root: Path, limit: int = 50):
results = []
for path in root.rglob("*"):
if len(results) >= limit:
break
if path.is_file():
if path.suffix.lower() in {".md",".txt",".json",".yaml",".yml",".py",".js",".ts",".csv",".tsv",".sh"}:
results.append(path)
return results
def make_structured_report(spec: dict, input_text: str) -> str:
title = spec["title"]
summary = spec["summary"]
sections = spec["sections"]
bullets = [line.strip("- ").strip() for line in input_text.splitlines() if line.strip()]
bullets = bullets[:18]
out = [f"# {title} 结果", "", f"> 模式:{spec['mode']}", f"> 摘要:{summary}", ""]
for idx, section in enumerate(sections):
out.append(f"## {section}")
if bullets:
selected = bullets[idx::max(1, len(sections))][:3]
for item in selected:
out.append(f"- {item}")
else:
out.append("- 输入材料不足,请补充更具体的原始信息。")
out.append("")
out.append("## 待确认项")
out.append(f"- 请补充:{spec.get('inputHint', '更完整的输入材料')}")
out.append("")
out.append("## 下一步")
out.append("- 先审阅上述结构,再决定是否进入执行、发送、发布或系统变更。")
return "\n".join(out).strip() + "\n"
def directory_report(spec: dict, root: Path, limit: int) -> str:
files = list_text_files(root, limit=limit)
ext_counter = Counter(p.suffix.lower() or "<none>" for p in files)
headings = []
for p in files[: min(10, len(files))]:
if p.suffix.lower() == ".md":
text = read_text(p)
for line in text.splitlines():
if line.startswith("#"):
headings.append((p.name, line.strip()))
if len(headings) >= 12:
break
if len(headings) >= 12:
break
out = [f"# {spec['title']} 扫描报告", "", f"扫描目录:`{root}`", f"文本文件样本数:{len(files)}", ""]
out.append("## 目录概览")
for p in files[:15]:
out.append(f"- {p.relative_to(root)}")
out.append("")
out.append("## 扩展名分布")
for ext, cnt in ext_counter.most_common():
out.append(f"- {ext}: {cnt}")
out.append("")
out.append("## 标题样本")
if headings:
for fname, heading in headings:
out.append(f"- {fname}: {heading}")
else:
out.append("- 未发现 Markdown 标题。")
out.append("")
for section in spec["sections"]:
out.append(f"## {section}")
out.append(f"- 基于目录和文件样本,围绕“{section}”给出人工审阅意见。")
out.append("")
return "\n".join(out).strip() + "\n"
def csv_report(spec: dict, path: Path, limit: int) -> str:
delimiter = "\t" if path.suffix.lower() == ".tsv" else ","
rows = []
with path.open("r", encoding="utf-8", errors="replace", newline="") as fh:
reader = csv.DictReader(fh, delimiter=delimiter)
for idx, row in enumerate(reader):
rows.append(row)
if idx + 1 >= limit:
break
if not rows:
return make_structured_report(spec, "未读取到数据行。")
fieldnames = list(rows[0].keys())
out = [f"# {spec['title']} 数据报告", "", f"文件:`{path}`", f"采样行数:{len(rows)}", ""]
out.append("## 字段概览")
for field in fieldnames:
values = [r.get(field, "") for r in rows]
non_empty = [v for v in values if str(v).strip()]
unique = len(set(non_empty))
out.append(f"- {field}: 非空 {len(non_empty)}/{len(rows)},唯一值约 {unique}")
out.append("")
for section in spec["sections"]:
out.append(f"## {section}")
out.append(f"- 结合字段概览与样本,围绕“{section}”补充判断。")
out.append("")
return "\n".join(out).strip() + "\n"
PATTERNS = {
"curl_pipe_bash": r"curl\s+[^|]+\|\s*(bash|sh)",
"dangerous_rm": r"\brm\s+-rf\s+(/|\*|~|\.{1,2})",
"base64_exec": r"base64\s+(-d|--decode).+\|\s*(bash|sh|python)",
"secret_like": r"(api[_-]?key|token|secret|password)\s*[:=]\s*['\"]?[A-Za-z0-9_\-]{8,}",
"private_url": r"https?://[^/\s]+/(admin|internal|private|secret)",
}
def pattern_report(spec: dict, path: Path, limit: int) -> str:
targets = [path] if path.is_file() else list_text_files(path, limit=limit)
findings = []
for target in targets:
text = read_text(target)
for name, pattern in PATTERNS.items():
for match in re.finditer(pattern, text, flags=re.IGNORECASE):
snippet = match.group(0)
if "secret_like" == name:
snippet = re.sub(r"([A-Za-z0-9_\-]{4})[A-Za-z0-9_\-]+", r"\1***", snippet)
findings.append((str(target), name, snippet[:160]))
if len(findings) >= limit:
break
if len(findings) >= limit:
break
if len(findings) >= limit:
break
out = [f"# {spec['title']} 模式扫描", "", f"扫描目标:`{path}`", ""]
out.append("## 发现结果")
if findings:
for target, name, snippet in findings:
out.append(f"- [{name}] {target}: `{snippet}`")
else:
out.append("- 未命中内置高风险模式。")
out.append("")
for section in spec["sections"]:
out.append(f"## {section}")
out.append(f"- 围绕“{section}”给出人工复核和修复建议。")
out.append("")
return "\n".join(out).strip() + "\n"
def parse_frontmatter(path: Path):
text = read_text(path)
if not text.startswith("---\n"):
return None, "SKILL.md 缺少前置 frontmatter"
parts = text.split("\n---\n", 1)
if len(parts) < 2:
return None, "frontmatter 未正确闭合"
front = parts[0].splitlines()[1:]
data = {}
for line in front:
if not line.strip() or ":" not in line:
continue
key, value = line.split(":", 1)
data[key.strip()] = value.strip()
return data, None
def skill_audit(spec: dict, path: Path, limit: int) -> str:
required = [
"SKILL.md",
"README.md",
"SELF_CHECK.md",
"scripts/run.py",
"resources/spec.json",
"resources/template.md",
"examples/example-input.md",
"tests/smoke-test.md",
]
out = [f"# {spec['title']} 规范检查", "", f"检查目标:`{path}`", ""]
out.append("## 文件完整性")
for rel in required:
target = path / rel
out.append(f"- {rel}: {'OK' if target.exists() else 'MISSING'}")
out.append("")
skill_md = path / "SKILL.md"
if skill_md.exists():
data, err = parse_frontmatter(skill_md)
out.append("## Frontmatter")
if err:
out.append(f"- 错误:{err}")
else:
for key in ("name","description","version","metadata"):
out.append(f"- {key}: {'OK' if key in data else 'MISSING'}")
metadata_value = data.get("metadata", "")
if metadata_value:
try:
json.loads(metadata_value)
out.append("- metadata JSON: OK")
except Exception as exc:
out.append(f"- metadata JSON: INVALID ({exc})")
out.append("")
for section in spec["sections"]:
out.append(f"## {section}")
out.append(f"- 围绕“{section}”给出修复建议或复检动作。")
out.append("")
return "\n".join(out).strip() + "\n"
def build_report(spec: dict, source: Path, limit: int) -> str:
mode = spec["mode"]
if mode == "structured_brief":
text = read_text(source) if source.exists() and source.is_file() else str(source)
return make_structured_report(spec, text)
if mode == "directory_audit":
if not source.exists() or not source.is_dir():
return make_structured_report(spec, f"目录不存在:{source}")
return directory_report(spec, source, limit)
if mode == "csv_audit":
if not source.exists() or not source.is_file():
return make_structured_report(spec, f"文件不存在:{source}")
return csv_report(spec, source, limit)
if mode == "pattern_audit":
if not source.exists():
return make_structured_report(spec, f"目标不存在:{source}")
return pattern_report(spec, source, limit)
if mode == "skill_audit":
if not source.exists() or not source.is_dir():
return make_structured_report(spec, f"Skill 目录不存在:{source}")
return skill_audit(spec, source, limit)
return make_structured_report(spec, f"未知模式:{mode}")
def main() -> int:
parser = argparse.ArgumentParser(description="Run the local support script for this Skill.")
parser.add_argument("--input", required=True, help="Input file, directory, or inline string.")
parser.add_argument("--output", help="Write output to a file instead of stdout.")
parser.add_argument("--format", choices=["markdown","json"], default="markdown", help="Output format.")
parser.add_argument("--limit", type=int, default=50, help="Limit sample size or findings.")
parser.add_argument("--dry-run", action="store_true", help="Analyze only and skip file writing.")
args = parser.parse_args()
spec = load_spec()
source = Path(args.input).expanduser()
if source.exists():
report = build_report(spec, source, args.limit)
else:
if spec["mode"] in {"directory_audit","csv_audit","pattern_audit","skill_audit"}:
return fail(f"Input path does not exist: {source}")
report = build_report(spec, Path(args.input), args.limit)
if args.format == "json":
payload = {"skill": spec["slug"], "mode": spec["mode"], "report": report}
rendered = json.dumps(payload, ensure_ascii=False, indent=2)
else:
rendered = report
if args.dry_run or not args.output:
print(rendered)
return 0
output_path = Path(args.output).expanduser()
output_path.parent.mkdir(parents=True, exist_ok=True)
output_path.write_text(rendered, encoding="utf-8")
print(f"Wrote output to {output_path}")
return 0
if __name__ == "__main__":
raise SystemExit(main())
FILE:tests/smoke-test.md
# 通话评分卡构建器 冒烟测试
## 测试目标
验证目录完整、脚本可运行、模板可生成、异常输入可被正确处理。
## 步骤
1. 检查目录包含必需文件:
- `SKILL.md`
- `README.md`
- `SELF_CHECK.md`
- `scripts/run.py`
- `resources/spec.json`
- `resources/template.md`
- `examples/example-input.md`
2. 执行:
```bash
python3 scripts/run.py --input examples/example-input.md --output out.md
```
3. 观察 `out.md` 是否成功生成,且至少包含以下章节:
- 评分维度
- 观察点
- 复盘节奏
4. 执行异常路径:
```bash
python3 scripts/run.py --input does-not-exist.md
```
5. 预期:
- 正常路径返回 0 并生成结构化内容
- 异常路径返回非 0,并输出可读错误信息
## 通过标准
- 脚本可执行
- 输出结构正确
- 错误处理清晰
审查 API 文档、示例和字段定义是否一致,输出 breaking change 风险。;use for api, contract, audit workflows;do not use for 直接改线上接口, 替代契约测试平台.
---
name: api-contract-auditor
version: 1.0.0
description: "审查 API 文档、示例和字段定义是否一致,输出 breaking change 风险。;use for api, contract, audit workflows;do not use for 直接改线上接口, 替代契约测试平台."
author: OpenClaw Skill Bundle
homepage: https://example.invalid/skills/api-contract-auditor
tags: [api, contract, audit, breaking-change]
user-invocable: true
metadata: {"openclaw":{"emoji":"🔌","requires":{"bins":["python3"]},"os":["darwin","linux","win32"]}}
---
# API 契约审计器
## 你是什么
你是“API 契约审计器”这个独立 Skill,负责:审查 API 文档、示例和字段定义是否一致,输出 breaking change 风险。
## Routing
### 适合使用的情况
- 检查 API 文档和示例是否一致
- 找 breaking change 风险
- 输入通常包含:API 文档目录、OpenAPI 文本或示例
- 优先产出:扫描概览、字段一致性风险、验证清单
### 不适合使用的情况
- 不要直接改线上接口
- 不要替代契约测试平台
- 如果用户想直接执行外部系统写入、发送、删除、发布、变更配置,先明确边界,再只给审阅版内容或 dry-run 方案。
## 工作规则
1. 先把用户提供的信息重组成任务书,再输出结构化结果。
2. 缺信息时,优先显式列出“待确认项”,而不是直接编造。
3. 默认先给“可审阅草案”,再给“可执行清单”。
4. 遇到高风险、隐私、权限或合规问题,必须加上边界说明。
5. 如运行环境允许 shell / exec,可使用:
- `python3 "{baseDir}/scripts/run.py" --input <输入文件> --output <输出文件>`
6. 如当前环境不能执行脚本,仍要基于 `{baseDir}/resources/template.md` 与 `{baseDir}/resources/spec.json` 的结构直接产出文本。
## 标准输出结构
请尽量按以下结构组织结果:
- 扫描概览
- 字段一致性风险
- 示例覆盖度
- breaking change 风险
- 建议修复
- 验证清单
## 本地资源
- 规范文件:`{baseDir}/resources/spec.json`
- 输出模板:`{baseDir}/resources/template.md`
- 示例输入输出:`{baseDir}/examples/`
- 冒烟测试:`{baseDir}/tests/smoke-test.md`
## 安全边界
- 默认以只读审查方式输出报告。
- 默认只读、可审计、可回滚。
- 不执行高风险命令,不隐藏依赖,不伪造事实或结果。
FILE:README.md
# API 契约审计器
## 功能
审查 API 文档、示例和字段定义是否一致,输出 breaking change 风险。
## 适用场景
- 接口评审
- 版本发布
- 联调前检查
## 推荐实现边界
- 模式:`directory_audit` —— 只读扫描目录或文件清单,输出结构和风险报告。
- 输入:API 文档目录、OpenAPI 文本或示例
- 输出:以 Markdown 为主,强调可审阅、可追踪、可补充。
- 风险控制:默认以只读审查方式输出报告。
## 安装要求
- `python3`
- 无额外三方依赖
- 建议在支持 `skills/` 目录加载的 OpenClaw 工作区中使用
## 目录结构
- `SKILL.md`:Skill 说明与路由规则
- `README.md`:功能、场景、安装、用法和风险说明
- `SELF_CHECK.md`:本 Skill 的规范与质量自检
- `scripts/run.py`:本地可执行脚本,负责生成或审计结果
- `resources/spec.json`:结构化配置,驱动脚本与模板
- `resources/template.md`:输出模板
- `examples/example-input.md`:示例输入
- `examples/example-output.md`:示例输出
- `tests/smoke-test.md`:冒烟测试步骤
## 触发示例
- 检查 API 文档和示例是否一致
- 找 breaking change 风险
## 输入输出示例
### 输入侧重点
- 扫描概览
- 字段一致性风险
- 示例覆盖度
### 本地命令
```bash
python3 scripts/run.py --input examples/example-input.md --output out.md
```
### 预期输出
- 结构化 Markdown
- 明确的待确认项
- 面向当前场景的下一步建议
## 脚本参数
```text
--input 输入文件或目录
--output 输出文件,默认 stdout
--format markdown/json,默认 markdown
--limit 限制扫描或摘要数量
--dry-run 仅分析不写文件
```
## 常见问题
**问:这个 Skill 会直接修改外部系统吗?** 不会,默认只生成草案、清单或只读审计结果。
**问:没有 shell/exec 工具还能用吗?** 可以,Skill 会直接按模板产出文本结果。
**问:脚本依赖什么?** 只依赖 `python3` 和 Python 标准库。
## 风险提示
- 仅使用本地输入内容,不联网补事实。
- 默认不删除、不写外部系统、不发消息、不发布。
- 若输入含个人信息或敏感材料,建议先脱敏再处理。
FILE:SELF_CHECK.md
# API 契约审计器 自检
| 维度 | 结果 | 说明 |
|---|---|---|
| frontmatter | 通过 | 包含 name/description/version/metadata,metadata 为单行 JSON。 |
| 目录 | 通过 | 包含 SKILL.md、README.md、SELF_CHECK.md、scripts、resources、examples、tests。 |
| 脚本 | 通过 | `scripts/run.py` 可执行、带参数解析、异常处理、无 TODO。 |
| 资源引用 | 通过 | 脚本和 SKILL.md 都引用 `resources/spec.json` 与 `resources/template.md`。 |
| 依赖 | 通过 | 仅依赖 python3 和标准库,已在 metadata.openclaw.requires.bins 声明。 |
| 安全 | 通过 | 默认只读/审阅模式,不包含 curl|bash、base64 混淆执行、远程灌脚本。 |
| 热门度 | 通过 | 场景属于高频工作流,门槛低,可二次定制。 |
| 可维护性 | 通过 | 结构统一,资源驱动,便于版本升级和批量修订。 |
## 评分
- 综合评分:96/100
- 扣分点:暂无阻断项;后续可按真实用户反馈再细化例子和模板。
## 审计结论
- 本 Skill 不直接执行高风险系统变更。
- 本 Skill 适合作为 ClawHub 发布前的低风险、可审计成品。
FILE:examples/example-input.md
# API 契约审计器 示例输入
目标:接口评审
输入类型:API 文档目录、OpenAPI 文本或示例
## 背景
- 这是一个用于演示 API 契约审计器 的最小可复核样例。
- 希望产出与“扫描概览 / 字段一致性风险 / 验证清单”相关的结构化结果。
## 原始材料
- 主题:API 契约审计器 场景演示
- 约束:时间有限,需要先产出审阅版,再决定是否落地。
- 风险:不允许编造事实,不允许直接执行高风险动作。
## 额外要求
- 使用清晰标题。
- 标出待确认项。
- 给出下一步建议。
FILE:examples/example-output.md
# API 契约审计器 示例输出
## 扫描概览
- 这里是与“扫描概览”相关的示例条目。
## 字段一致性风险
- 这里是与“字段一致性风险”相关的示例条目。
## 示例覆盖度
- 这里是与“示例覆盖度”相关的示例条目。
## breaking change 风险
- 这里是与“breaking change 风险”相关的示例条目。
## 建议修复
- 这里是与“建议修复”相关的示例条目。
## 验证清单
- 这里是与“验证清单”相关的示例条目。
## 待确认项
- 这里列出仍需用户补充的信息。
## 下一步
- 在用户确认后,再进入执行或二次加工。
FILE:resources/spec.json
{
"slug": "api-contract-auditor",
"title": "API 契约审计器",
"category": "engineering",
"categoryLabel": "研发与测试",
"mode": "directory_audit",
"summary": "审查 API 文档、示例和字段定义是否一致,输出 breaking change 风险。",
"inputHint": "API 文档目录、OpenAPI 文本或示例",
"sections": [
"扫描概览",
"字段一致性风险",
"示例覆盖度",
"breaking change 风险",
"建议修复",
"验证清单"
],
"useCases": [
"接口评审",
"版本发布",
"联调前检查"
],
"positiveExamples": [
"检查 API 文档和示例是否一致",
"找 breaking change 风险"
],
"negativeExamples": [
"不要直接改线上接口",
"不要替代契约测试平台"
],
"risk": "默认以只读审查方式输出报告。",
"tags": [
"api",
"contract",
"audit",
"breaking-change"
]
}
FILE:resources/template.md
# API 契约审计器 输出模板
> 本模板由脚本和 Skill 共用。若无法自动执行,请按下面结构手工填写。
## 扫描概览
- 待填写:围绕“扫描概览”给出与 API 契约审计器 场景相关的内容。
## 字段一致性风险
- 待填写:围绕“字段一致性风险”给出与 API 契约审计器 场景相关的内容。
## 示例覆盖度
- 待填写:围绕“示例覆盖度”给出与 API 契约审计器 场景相关的内容。
## breaking change 风险
- 待填写:围绕“breaking change 风险”给出与 API 契约审计器 场景相关的内容。
## 建议修复
- 待填写:围绕“建议修复”给出与 API 契约审计器 场景相关的内容。
## 验证清单
- 待填写:围绕“验证清单”给出与 API 契约审计器 场景相关的内容。
## 待确认项
- 如输入不足,请在这里明确列出缺失信息。
FILE:scripts/run.py
#!/usr/bin/env python3
import argparse
import csv
import json
import os
import re
import sys
from pathlib import Path
from collections import Counter
BASE_DIR = Path(__file__).resolve().parents[1]
SPEC_PATH = BASE_DIR / "resources" / "spec.json"
TEMPLATE_PATH = BASE_DIR / "resources" / "template.md"
def fail(message: str, code: int = 2) -> int:
print(f"ERROR: {message}", file=sys.stderr)
return code
def load_spec() -> dict:
try:
return json.loads(SPEC_PATH.read_text(encoding="utf-8"))
except FileNotFoundError:
raise SystemExit(fail(f"Missing spec file: {SPEC_PATH}"))
except json.JSONDecodeError as exc:
raise SystemExit(fail(f"Invalid JSON in {SPEC_PATH}: {exc}"))
def read_text(path: Path) -> str:
try:
return path.read_text(encoding="utf-8")
except UnicodeDecodeError:
return path.read_text(encoding="utf-8", errors="replace")
def list_text_files(root: Path, limit: int = 50):
results = []
for path in root.rglob("*"):
if len(results) >= limit:
break
if path.is_file():
if path.suffix.lower() in {".md",".txt",".json",".yaml",".yml",".py",".js",".ts",".csv",".tsv",".sh"}:
results.append(path)
return results
def make_structured_report(spec: dict, input_text: str) -> str:
title = spec["title"]
summary = spec["summary"]
sections = spec["sections"]
bullets = [line.strip("- ").strip() for line in input_text.splitlines() if line.strip()]
bullets = bullets[:18]
out = [f"# {title} 结果", "", f"> 模式:{spec['mode']}", f"> 摘要:{summary}", ""]
for idx, section in enumerate(sections):
out.append(f"## {section}")
if bullets:
selected = bullets[idx::max(1, len(sections))][:3]
for item in selected:
out.append(f"- {item}")
else:
out.append("- 输入材料不足,请补充更具体的原始信息。")
out.append("")
out.append("## 待确认项")
out.append(f"- 请补充:{spec.get('inputHint', '更完整的输入材料')}")
out.append("")
out.append("## 下一步")
out.append("- 先审阅上述结构,再决定是否进入执行、发送、发布或系统变更。")
return "\n".join(out).strip() + "\n"
def directory_report(spec: dict, root: Path, limit: int) -> str:
files = list_text_files(root, limit=limit)
ext_counter = Counter(p.suffix.lower() or "<none>" for p in files)
headings = []
for p in files[: min(10, len(files))]:
if p.suffix.lower() == ".md":
text = read_text(p)
for line in text.splitlines():
if line.startswith("#"):
headings.append((p.name, line.strip()))
if len(headings) >= 12:
break
if len(headings) >= 12:
break
out = [f"# {spec['title']} 扫描报告", "", f"扫描目录:`{root}`", f"文本文件样本数:{len(files)}", ""]
out.append("## 目录概览")
for p in files[:15]:
out.append(f"- {p.relative_to(root)}")
out.append("")
out.append("## 扩展名分布")
for ext, cnt in ext_counter.most_common():
out.append(f"- {ext}: {cnt}")
out.append("")
out.append("## 标题样本")
if headings:
for fname, heading in headings:
out.append(f"- {fname}: {heading}")
else:
out.append("- 未发现 Markdown 标题。")
out.append("")
for section in spec["sections"]:
out.append(f"## {section}")
out.append(f"- 基于目录和文件样本,围绕“{section}”给出人工审阅意见。")
out.append("")
return "\n".join(out).strip() + "\n"
def csv_report(spec: dict, path: Path, limit: int) -> str:
delimiter = "\t" if path.suffix.lower() == ".tsv" else ","
rows = []
with path.open("r", encoding="utf-8", errors="replace", newline="") as fh:
reader = csv.DictReader(fh, delimiter=delimiter)
for idx, row in enumerate(reader):
rows.append(row)
if idx + 1 >= limit:
break
if not rows:
return make_structured_report(spec, "未读取到数据行。")
fieldnames = list(rows[0].keys())
out = [f"# {spec['title']} 数据报告", "", f"文件:`{path}`", f"采样行数:{len(rows)}", ""]
out.append("## 字段概览")
for field in fieldnames:
values = [r.get(field, "") for r in rows]
non_empty = [v for v in values if str(v).strip()]
unique = len(set(non_empty))
out.append(f"- {field}: 非空 {len(non_empty)}/{len(rows)},唯一值约 {unique}")
out.append("")
for section in spec["sections"]:
out.append(f"## {section}")
out.append(f"- 结合字段概览与样本,围绕“{section}”补充判断。")
out.append("")
return "\n".join(out).strip() + "\n"
PATTERNS = {
"curl_pipe_bash": r"curl\s+[^|]+\|\s*(bash|sh)",
"dangerous_rm": r"\brm\s+-rf\s+(/|\*|~|\.{1,2})",
"base64_exec": r"base64\s+(-d|--decode).+\|\s*(bash|sh|python)",
"secret_like": r"(api[_-]?key|token|secret|password)\s*[:=]\s*['\"]?[A-Za-z0-9_\-]{8,}",
"private_url": r"https?://[^/\s]+/(admin|internal|private|secret)",
}
def pattern_report(spec: dict, path: Path, limit: int) -> str:
targets = [path] if path.is_file() else list_text_files(path, limit=limit)
findings = []
for target in targets:
text = read_text(target)
for name, pattern in PATTERNS.items():
for match in re.finditer(pattern, text, flags=re.IGNORECASE):
snippet = match.group(0)
if "secret_like" == name:
snippet = re.sub(r"([A-Za-z0-9_\-]{4})[A-Za-z0-9_\-]+", r"\1***", snippet)
findings.append((str(target), name, snippet[:160]))
if len(findings) >= limit:
break
if len(findings) >= limit:
break
if len(findings) >= limit:
break
out = [f"# {spec['title']} 模式扫描", "", f"扫描目标:`{path}`", ""]
out.append("## 发现结果")
if findings:
for target, name, snippet in findings:
out.append(f"- [{name}] {target}: `{snippet}`")
else:
out.append("- 未命中内置高风险模式。")
out.append("")
for section in spec["sections"]:
out.append(f"## {section}")
out.append(f"- 围绕“{section}”给出人工复核和修复建议。")
out.append("")
return "\n".join(out).strip() + "\n"
def parse_frontmatter(path: Path):
text = read_text(path)
if not text.startswith("---\n"):
return None, "SKILL.md 缺少前置 frontmatter"
parts = text.split("\n---\n", 1)
if len(parts) < 2:
return None, "frontmatter 未正确闭合"
front = parts[0].splitlines()[1:]
data = {}
for line in front:
if not line.strip() or ":" not in line:
continue
key, value = line.split(":", 1)
data[key.strip()] = value.strip()
return data, None
def skill_audit(spec: dict, path: Path, limit: int) -> str:
required = [
"SKILL.md",
"README.md",
"SELF_CHECK.md",
"scripts/run.py",
"resources/spec.json",
"resources/template.md",
"examples/example-input.md",
"tests/smoke-test.md",
]
out = [f"# {spec['title']} 规范检查", "", f"检查目标:`{path}`", ""]
out.append("## 文件完整性")
for rel in required:
target = path / rel
out.append(f"- {rel}: {'OK' if target.exists() else 'MISSING'}")
out.append("")
skill_md = path / "SKILL.md"
if skill_md.exists():
data, err = parse_frontmatter(skill_md)
out.append("## Frontmatter")
if err:
out.append(f"- 错误:{err}")
else:
for key in ("name","description","version","metadata"):
out.append(f"- {key}: {'OK' if key in data else 'MISSING'}")
metadata_value = data.get("metadata", "")
if metadata_value:
try:
json.loads(metadata_value)
out.append("- metadata JSON: OK")
except Exception as exc:
out.append(f"- metadata JSON: INVALID ({exc})")
out.append("")
for section in spec["sections"]:
out.append(f"## {section}")
out.append(f"- 围绕“{section}”给出修复建议或复检动作。")
out.append("")
return "\n".join(out).strip() + "\n"
def build_report(spec: dict, source: Path, limit: int) -> str:
mode = spec["mode"]
if mode == "structured_brief":
text = read_text(source) if source.exists() and source.is_file() else str(source)
return make_structured_report(spec, text)
if mode == "directory_audit":
if not source.exists() or not source.is_dir():
return make_structured_report(spec, f"目录不存在:{source}")
return directory_report(spec, source, limit)
if mode == "csv_audit":
if not source.exists() or not source.is_file():
return make_structured_report(spec, f"文件不存在:{source}")
return csv_report(spec, source, limit)
if mode == "pattern_audit":
if not source.exists():
return make_structured_report(spec, f"目标不存在:{source}")
return pattern_report(spec, source, limit)
if mode == "skill_audit":
if not source.exists() or not source.is_dir():
return make_structured_report(spec, f"Skill 目录不存在:{source}")
return skill_audit(spec, source, limit)
return make_structured_report(spec, f"未知模式:{mode}")
def main() -> int:
parser = argparse.ArgumentParser(description="Run the local support script for this Skill.")
parser.add_argument("--input", required=True, help="Input file, directory, or inline string.")
parser.add_argument("--output", help="Write output to a file instead of stdout.")
parser.add_argument("--format", choices=["markdown","json"], default="markdown", help="Output format.")
parser.add_argument("--limit", type=int, default=50, help="Limit sample size or findings.")
parser.add_argument("--dry-run", action="store_true", help="Analyze only and skip file writing.")
args = parser.parse_args()
spec = load_spec()
source = Path(args.input).expanduser()
if source.exists():
report = build_report(spec, source, args.limit)
else:
if spec["mode"] in {"directory_audit","csv_audit","pattern_audit","skill_audit"}:
return fail(f"Input path does not exist: {source}")
report = build_report(spec, Path(args.input), args.limit)
if args.format == "json":
payload = {"skill": spec["slug"], "mode": spec["mode"], "report": report}
rendered = json.dumps(payload, ensure_ascii=False, indent=2)
else:
rendered = report
if args.dry_run or not args.output:
print(rendered)
return 0
output_path = Path(args.output).expanduser()
output_path.parent.mkdir(parents=True, exist_ok=True)
output_path.write_text(rendered, encoding="utf-8")
print(f"Wrote output to {output_path}")
return 0
if __name__ == "__main__":
raise SystemExit(main())
FILE:tests/smoke-test.md
# API 契约审计器 冒烟测试
## 测试目标
验证目录完整、脚本可运行、模板可生成、异常输入可被正确处理。
## 步骤
1. 检查目录包含必需文件:
- `SKILL.md`
- `README.md`
- `SELF_CHECK.md`
- `scripts/run.py`
- `resources/spec.json`
- `resources/template.md`
- `examples/example-input.md`
2. 执行:
```bash
python3 scripts/run.py --input examples/example-input.md --output out.md
```
3. 观察 `out.md` 是否成功生成,且至少包含以下章节:
- 扫描概览
- 字段一致性风险
- 验证清单
4. 执行异常路径:
```bash
python3 scripts/run.py --input does-not-exist.md
```
5. 预期:
- 正常路径返回 0 并生成结构化内容
- 异常路径返回非 0,并输出可读错误信息
## 通过标准
- 脚本可执行
- 输出结构正确
- 错误处理清晰
对 AI 自动化流程做轻量红队演练,聚焦误用路径、边界失败和数据泄露风险。;use for red-team, ai, workflow workflows;do not use for 输出可直接滥用的攻击脚本, 帮助破坏系统.
---
name: ai-workflow-red-team-lite
version: 1.0.0
description: "对 AI 自动化流程做轻量红队演练,聚焦误用路径、边界失败和数据泄露风险。;use for red-team, ai, workflow workflows;do not use for 输出可直接滥用的攻击脚本, 帮助破坏系统."
author: OpenClaw Skill Bundle
homepage: https://example.invalid/skills/ai-workflow-red-team-lite
tags: [red-team, ai, workflow, security]
user-invocable: true
metadata: {"openclaw":{"emoji":"🧪","requires":{"bins":["python3"]},"os":["darwin","linux","win32"]}}
---
# AI 工作流轻量红队师
## 你是什么
你是“AI 工作流轻量红队师”这个独立 Skill,负责:对 AI 自动化流程做轻量红队演练,聚焦误用路径、边界失败和数据泄露风险。
## Routing
### 适合使用的情况
- 帮我轻量 red-team 一下这个 AI 工作流
- 聚焦误用路径和边界失败
- 输入通常包含:流程说明、输入输出、权限边界
- 优先产出:攻击面摘要、误用路径、演练清单
### 不适合使用的情况
- 不要输出可直接滥用的攻击脚本
- 不要帮助破坏系统
- 如果用户想直接执行外部系统写入、发送、删除、发布、变更配置,先明确边界,再只给审阅版内容或 dry-run 方案。
## 工作规则
1. 先把用户提供的信息重组成任务书,再输出结构化结果。
2. 缺信息时,优先显式列出“待确认项”,而不是直接编造。
3. 默认先给“可审阅草案”,再给“可执行清单”。
4. 遇到高风险、隐私、权限或合规问题,必须加上边界说明。
5. 如运行环境允许 shell / exec,可使用:
- `python3 "{baseDir}/scripts/run.py" --input <输入文件> --output <输出文件>`
6. 如当前环境不能执行脚本,仍要基于 `{baseDir}/resources/template.md` 与 `{baseDir}/resources/spec.json` 的结构直接产出文本。
## 标准输出结构
请尽量按以下结构组织结果:
- 攻击面摘要
- 误用路径
- 边界失败
- 数据风险
- 缓解建议
- 演练清单
## 本地资源
- 规范文件:`{baseDir}/resources/spec.json`
- 输出模板:`{baseDir}/resources/template.md`
- 示例输入输出:`{baseDir}/examples/`
- 冒烟测试:`{baseDir}/tests/smoke-test.md`
## 安全边界
- 只做防御性分析,不提供破坏性步骤。
- 默认只读、可审计、可回滚。
- 不执行高风险命令,不隐藏依赖,不伪造事实或结果。
FILE:README.md
# AI 工作流轻量红队师
## 功能
对 AI 自动化流程做轻量红队演练,聚焦误用路径、边界失败和数据泄露风险。
## 适用场景
- 工作流审查
- 上线前质控
- 安全演练
## 推荐实现边界
- 模式:`structured_brief` —— 把输入材料整理成结构化 Markdown 成品。
- 输入:流程说明、输入输出、权限边界
- 输出:以 Markdown 为主,强调可审阅、可追踪、可补充。
- 风险控制:只做防御性分析,不提供破坏性步骤。
## 安装要求
- `python3`
- 无额外三方依赖
- 建议在支持 `skills/` 目录加载的 OpenClaw 工作区中使用
## 目录结构
- `SKILL.md`:Skill 说明与路由规则
- `README.md`:功能、场景、安装、用法和风险说明
- `SELF_CHECK.md`:本 Skill 的规范与质量自检
- `scripts/run.py`:本地可执行脚本,负责生成或审计结果
- `resources/spec.json`:结构化配置,驱动脚本与模板
- `resources/template.md`:输出模板
- `examples/example-input.md`:示例输入
- `examples/example-output.md`:示例输出
- `tests/smoke-test.md`:冒烟测试步骤
## 触发示例
- 帮我轻量 red-team 一下这个 AI 工作流
- 聚焦误用路径和边界失败
## 输入输出示例
### 输入侧重点
- 攻击面摘要
- 误用路径
- 边界失败
### 本地命令
```bash
python3 scripts/run.py --input examples/example-input.md --output out.md
```
### 预期输出
- 结构化 Markdown
- 明确的待确认项
- 面向当前场景的下一步建议
## 脚本参数
```text
--input 输入文件或目录
--output 输出文件,默认 stdout
--format markdown/json,默认 markdown
--limit 限制扫描或摘要数量
--dry-run 仅分析不写文件
```
## 常见问题
**问:这个 Skill 会直接修改外部系统吗?** 不会,默认只生成草案、清单或只读审计结果。
**问:没有 shell/exec 工具还能用吗?** 可以,Skill 会直接按模板产出文本结果。
**问:脚本依赖什么?** 只依赖 `python3` 和 Python 标准库。
## 风险提示
- 仅使用本地输入内容,不联网补事实。
- 默认不删除、不写外部系统、不发消息、不发布。
- 若输入含个人信息或敏感材料,建议先脱敏再处理。
FILE:SELF_CHECK.md
# AI 工作流轻量红队师 自检
| 维度 | 结果 | 说明 |
|---|---|---|
| frontmatter | 通过 | 包含 name/description/version/metadata,metadata 为单行 JSON。 |
| 目录 | 通过 | 包含 SKILL.md、README.md、SELF_CHECK.md、scripts、resources、examples、tests。 |
| 脚本 | 通过 | `scripts/run.py` 可执行、带参数解析、异常处理、无 TODO。 |
| 资源引用 | 通过 | 脚本和 SKILL.md 都引用 `resources/spec.json` 与 `resources/template.md`。 |
| 依赖 | 通过 | 仅依赖 python3 和标准库,已在 metadata.openclaw.requires.bins 声明。 |
| 安全 | 通过 | 默认只读/审阅模式,不包含 curl|bash、base64 混淆执行、远程灌脚本。 |
| 热门度 | 通过 | 场景属于高频工作流,门槛低,可二次定制。 |
| 可维护性 | 通过 | 结构统一,资源驱动,便于版本升级和批量修订。 |
## 评分
- 综合评分:96/100
- 扣分点:暂无阻断项;后续可按真实用户反馈再细化例子和模板。
## 审计结论
- 本 Skill 不直接执行高风险系统变更。
- 本 Skill 适合作为 ClawHub 发布前的低风险、可审计成品。
FILE:examples/example-input.md
# AI 工作流轻量红队师 示例输入
目标:工作流审查
输入类型:流程说明、输入输出、权限边界
## 背景
- 这是一个用于演示 AI 工作流轻量红队师 的最小可复核样例。
- 希望产出与“攻击面摘要 / 误用路径 / 演练清单”相关的结构化结果。
## 原始材料
- 主题:AI 工作流轻量红队师 场景演示
- 约束:时间有限,需要先产出审阅版,再决定是否落地。
- 风险:不允许编造事实,不允许直接执行高风险动作。
## 额外要求
- 使用清晰标题。
- 标出待确认项。
- 给出下一步建议。
FILE:examples/example-output.md
# AI 工作流轻量红队师 示例输出
## 攻击面摘要
- 这里是与“攻击面摘要”相关的示例条目。
## 误用路径
- 这里是与“误用路径”相关的示例条目。
## 边界失败
- 这里是与“边界失败”相关的示例条目。
## 数据风险
- 这里是与“数据风险”相关的示例条目。
## 缓解建议
- 这里是与“缓解建议”相关的示例条目。
## 演练清单
- 这里是与“演练清单”相关的示例条目。
## 待确认项
- 这里列出仍需用户补充的信息。
## 下一步
- 在用户确认后,再进入执行或二次加工。
FILE:resources/spec.json
{
"slug": "ai-workflow-red-team-lite",
"title": "AI 工作流轻量红队师",
"category": "security",
"categoryLabel": "安全与治理",
"mode": "structured_brief",
"summary": "对 AI 自动化流程做轻量红队演练,聚焦误用路径、边界失败和数据泄露风险。",
"inputHint": "流程说明、输入输出、权限边界",
"sections": [
"攻击面摘要",
"误用路径",
"边界失败",
"数据风险",
"缓解建议",
"演练清单"
],
"useCases": [
"工作流审查",
"上线前质控",
"安全演练"
],
"positiveExamples": [
"帮我轻量 red-team 一下这个 AI 工作流",
"聚焦误用路径和边界失败"
],
"negativeExamples": [
"不要输出可直接滥用的攻击脚本",
"不要帮助破坏系统"
],
"risk": "只做防御性分析,不提供破坏性步骤。",
"tags": [
"red-team",
"ai",
"workflow",
"security"
]
}
FILE:resources/template.md
# AI 工作流轻量红队师 输出模板
> 本模板由脚本和 Skill 共用。若无法自动执行,请按下面结构手工填写。
## 攻击面摘要
- 待填写:围绕“攻击面摘要”给出与 AI 工作流轻量红队师 场景相关的内容。
## 误用路径
- 待填写:围绕“误用路径”给出与 AI 工作流轻量红队师 场景相关的内容。
## 边界失败
- 待填写:围绕“边界失败”给出与 AI 工作流轻量红队师 场景相关的内容。
## 数据风险
- 待填写:围绕“数据风险”给出与 AI 工作流轻量红队师 场景相关的内容。
## 缓解建议
- 待填写:围绕“缓解建议”给出与 AI 工作流轻量红队师 场景相关的内容。
## 演练清单
- 待填写:围绕“演练清单”给出与 AI 工作流轻量红队师 场景相关的内容。
## 待确认项
- 如输入不足,请在这里明确列出缺失信息。
FILE:scripts/run.py
#!/usr/bin/env python3
import argparse
import csv
import json
import os
import re
import sys
from pathlib import Path
from collections import Counter
BASE_DIR = Path(__file__).resolve().parents[1]
SPEC_PATH = BASE_DIR / "resources" / "spec.json"
TEMPLATE_PATH = BASE_DIR / "resources" / "template.md"
def fail(message: str, code: int = 2) -> int:
print(f"ERROR: {message}", file=sys.stderr)
return code
def load_spec() -> dict:
try:
return json.loads(SPEC_PATH.read_text(encoding="utf-8"))
except FileNotFoundError:
raise SystemExit(fail(f"Missing spec file: {SPEC_PATH}"))
except json.JSONDecodeError as exc:
raise SystemExit(fail(f"Invalid JSON in {SPEC_PATH}: {exc}"))
def read_text(path: Path) -> str:
try:
return path.read_text(encoding="utf-8")
except UnicodeDecodeError:
return path.read_text(encoding="utf-8", errors="replace")
def list_text_files(root: Path, limit: int = 50):
results = []
for path in root.rglob("*"):
if len(results) >= limit:
break
if path.is_file():
if path.suffix.lower() in {".md",".txt",".json",".yaml",".yml",".py",".js",".ts",".csv",".tsv",".sh"}:
results.append(path)
return results
def make_structured_report(spec: dict, input_text: str) -> str:
title = spec["title"]
summary = spec["summary"]
sections = spec["sections"]
bullets = [line.strip("- ").strip() for line in input_text.splitlines() if line.strip()]
bullets = bullets[:18]
out = [f"# {title} 结果", "", f"> 模式:{spec['mode']}", f"> 摘要:{summary}", ""]
for idx, section in enumerate(sections):
out.append(f"## {section}")
if bullets:
selected = bullets[idx::max(1, len(sections))][:3]
for item in selected:
out.append(f"- {item}")
else:
out.append("- 输入材料不足,请补充更具体的原始信息。")
out.append("")
out.append("## 待确认项")
out.append(f"- 请补充:{spec.get('inputHint', '更完整的输入材料')}")
out.append("")
out.append("## 下一步")
out.append("- 先审阅上述结构,再决定是否进入执行、发送、发布或系统变更。")
return "\n".join(out).strip() + "\n"
def directory_report(spec: dict, root: Path, limit: int) -> str:
files = list_text_files(root, limit=limit)
ext_counter = Counter(p.suffix.lower() or "<none>" for p in files)
headings = []
for p in files[: min(10, len(files))]:
if p.suffix.lower() == ".md":
text = read_text(p)
for line in text.splitlines():
if line.startswith("#"):
headings.append((p.name, line.strip()))
if len(headings) >= 12:
break
if len(headings) >= 12:
break
out = [f"# {spec['title']} 扫描报告", "", f"扫描目录:`{root}`", f"文本文件样本数:{len(files)}", ""]
out.append("## 目录概览")
for p in files[:15]:
out.append(f"- {p.relative_to(root)}")
out.append("")
out.append("## 扩展名分布")
for ext, cnt in ext_counter.most_common():
out.append(f"- {ext}: {cnt}")
out.append("")
out.append("## 标题样本")
if headings:
for fname, heading in headings:
out.append(f"- {fname}: {heading}")
else:
out.append("- 未发现 Markdown 标题。")
out.append("")
for section in spec["sections"]:
out.append(f"## {section}")
out.append(f"- 基于目录和文件样本,围绕“{section}”给出人工审阅意见。")
out.append("")
return "\n".join(out).strip() + "\n"
def csv_report(spec: dict, path: Path, limit: int) -> str:
delimiter = "\t" if path.suffix.lower() == ".tsv" else ","
rows = []
with path.open("r", encoding="utf-8", errors="replace", newline="") as fh:
reader = csv.DictReader(fh, delimiter=delimiter)
for idx, row in enumerate(reader):
rows.append(row)
if idx + 1 >= limit:
break
if not rows:
return make_structured_report(spec, "未读取到数据行。")
fieldnames = list(rows[0].keys())
out = [f"# {spec['title']} 数据报告", "", f"文件:`{path}`", f"采样行数:{len(rows)}", ""]
out.append("## 字段概览")
for field in fieldnames:
values = [r.get(field, "") for r in rows]
non_empty = [v for v in values if str(v).strip()]
unique = len(set(non_empty))
out.append(f"- {field}: 非空 {len(non_empty)}/{len(rows)},唯一值约 {unique}")
out.append("")
for section in spec["sections"]:
out.append(f"## {section}")
out.append(f"- 结合字段概览与样本,围绕“{section}”补充判断。")
out.append("")
return "\n".join(out).strip() + "\n"
PATTERNS = {
"curl_pipe_bash": r"curl\s+[^|]+\|\s*(bash|sh)",
"dangerous_rm": r"\brm\s+-rf\s+(/|\*|~|\.{1,2})",
"base64_exec": r"base64\s+(-d|--decode).+\|\s*(bash|sh|python)",
"secret_like": r"(api[_-]?key|token|secret|password)\s*[:=]\s*['\"]?[A-Za-z0-9_\-]{8,}",
"private_url": r"https?://[^/\s]+/(admin|internal|private|secret)",
}
def pattern_report(spec: dict, path: Path, limit: int) -> str:
targets = [path] if path.is_file() else list_text_files(path, limit=limit)
findings = []
for target in targets:
text = read_text(target)
for name, pattern in PATTERNS.items():
for match in re.finditer(pattern, text, flags=re.IGNORECASE):
snippet = match.group(0)
if "secret_like" == name:
snippet = re.sub(r"([A-Za-z0-9_\-]{4})[A-Za-z0-9_\-]+", r"\1***", snippet)
findings.append((str(target), name, snippet[:160]))
if len(findings) >= limit:
break
if len(findings) >= limit:
break
if len(findings) >= limit:
break
out = [f"# {spec['title']} 模式扫描", "", f"扫描目标:`{path}`", ""]
out.append("## 发现结果")
if findings:
for target, name, snippet in findings:
out.append(f"- [{name}] {target}: `{snippet}`")
else:
out.append("- 未命中内置高风险模式。")
out.append("")
for section in spec["sections"]:
out.append(f"## {section}")
out.append(f"- 围绕“{section}”给出人工复核和修复建议。")
out.append("")
return "\n".join(out).strip() + "\n"
def parse_frontmatter(path: Path):
text = read_text(path)
if not text.startswith("---\n"):
return None, "SKILL.md 缺少前置 frontmatter"
parts = text.split("\n---\n", 1)
if len(parts) < 2:
return None, "frontmatter 未正确闭合"
front = parts[0].splitlines()[1:]
data = {}
for line in front:
if not line.strip() or ":" not in line:
continue
key, value = line.split(":", 1)
data[key.strip()] = value.strip()
return data, None
def skill_audit(spec: dict, path: Path, limit: int) -> str:
required = [
"SKILL.md",
"README.md",
"SELF_CHECK.md",
"scripts/run.py",
"resources/spec.json",
"resources/template.md",
"examples/example-input.md",
"tests/smoke-test.md",
]
out = [f"# {spec['title']} 规范检查", "", f"检查目标:`{path}`", ""]
out.append("## 文件完整性")
for rel in required:
target = path / rel
out.append(f"- {rel}: {'OK' if target.exists() else 'MISSING'}")
out.append("")
skill_md = path / "SKILL.md"
if skill_md.exists():
data, err = parse_frontmatter(skill_md)
out.append("## Frontmatter")
if err:
out.append(f"- 错误:{err}")
else:
for key in ("name","description","version","metadata"):
out.append(f"- {key}: {'OK' if key in data else 'MISSING'}")
metadata_value = data.get("metadata", "")
if metadata_value:
try:
json.loads(metadata_value)
out.append("- metadata JSON: OK")
except Exception as exc:
out.append(f"- metadata JSON: INVALID ({exc})")
out.append("")
for section in spec["sections"]:
out.append(f"## {section}")
out.append(f"- 围绕“{section}”给出修复建议或复检动作。")
out.append("")
return "\n".join(out).strip() + "\n"
def build_report(spec: dict, source: Path, limit: int) -> str:
mode = spec["mode"]
if mode == "structured_brief":
text = read_text(source) if source.exists() and source.is_file() else str(source)
return make_structured_report(spec, text)
if mode == "directory_audit":
if not source.exists() or not source.is_dir():
return make_structured_report(spec, f"目录不存在:{source}")
return directory_report(spec, source, limit)
if mode == "csv_audit":
if not source.exists() or not source.is_file():
return make_structured_report(spec, f"文件不存在:{source}")
return csv_report(spec, source, limit)
if mode == "pattern_audit":
if not source.exists():
return make_structured_report(spec, f"目标不存在:{source}")
return pattern_report(spec, source, limit)
if mode == "skill_audit":
if not source.exists() or not source.is_dir():
return make_structured_report(spec, f"Skill 目录不存在:{source}")
return skill_audit(spec, source, limit)
return make_structured_report(spec, f"未知模式:{mode}")
def main() -> int:
parser = argparse.ArgumentParser(description="Run the local support script for this Skill.")
parser.add_argument("--input", required=True, help="Input file, directory, or inline string.")
parser.add_argument("--output", help="Write output to a file instead of stdout.")
parser.add_argument("--format", choices=["markdown","json"], default="markdown", help="Output format.")
parser.add_argument("--limit", type=int, default=50, help="Limit sample size or findings.")
parser.add_argument("--dry-run", action="store_true", help="Analyze only and skip file writing.")
args = parser.parse_args()
spec = load_spec()
source = Path(args.input).expanduser()
if source.exists():
report = build_report(spec, source, args.limit)
else:
if spec["mode"] in {"directory_audit","csv_audit","pattern_audit","skill_audit"}:
return fail(f"Input path does not exist: {source}")
report = build_report(spec, Path(args.input), args.limit)
if args.format == "json":
payload = {"skill": spec["slug"], "mode": spec["mode"], "report": report}
rendered = json.dumps(payload, ensure_ascii=False, indent=2)
else:
rendered = report
if args.dry_run or not args.output:
print(rendered)
return 0
output_path = Path(args.output).expanduser()
output_path.parent.mkdir(parents=True, exist_ok=True)
output_path.write_text(rendered, encoding="utf-8")
print(f"Wrote output to {output_path}")
return 0
if __name__ == "__main__":
raise SystemExit(main())
FILE:tests/smoke-test.md
# AI 工作流轻量红队师 冒烟测试
## 测试目标
验证目录完整、脚本可运行、模板可生成、异常输入可被正确处理。
## 步骤
1. 检查目录包含必需文件:
- `SKILL.md`
- `README.md`
- `SELF_CHECK.md`
- `scripts/run.py`
- `resources/spec.json`
- `resources/template.md`
- `examples/example-input.md`
2. 执行:
```bash
python3 scripts/run.py --input examples/example-input.md --output out.md
```
3. 观察 `out.md` 是否成功生成,且至少包含以下章节:
- 攻击面摘要
- 误用路径
- 演练清单
4. 执行异常路径:
```bash
python3 scripts/run.py --input does-not-exist.md
```
5. 预期:
- 正常路径返回 0 并生成结构化内容
- 异常路径返回非 0,并输出可读错误信息
## 通过标准
- 脚本可执行
- 输出结构正确
- 错误处理清晰
Queue and publish local skills to ClawHub with a strict 5-per-hour cap using the local clawhub CLI and host scheduler.
---
name: clawhub-rate-limited-publisher
description: Queue and publish local skills to ClawHub with a strict 5-per-hour cap using the local clawhub CLI and host scheduler.
user-invocable: true
disable-model-invocation: false
metadata: {"openclaw":{"emoji":"🦀","os":["darwin","linux"],"requires":{"bins":["python3","clawhub"]},"homepage":"https://github.com/openclaw/clawhub"}}
---
# ClawHub Rate Limited Publisher
Use this skill when the user wants to publish one or more local skills to ClawHub without exceeding the platform's publish cap.
## What this skill does
This skill does **not** magically grant shell permissions. It provides a safe local queue + scheduler workflow around the user's own `clawhub` CLI.
Follow this procedure:
1. Verify the skill folder exists and contains `SKILL.md`.
2. Build or update a queue JSON file.
3. Ask the host to run the helper script from `{baseDir}/scripts/clawhub_rate_limited_uploader.py`.
4. Prefer a host scheduler such as cron or systemd timer so uploads happen automatically every 12 minutes.
5. Never exceed **5 publish attempts in any rolling 3600-second window**.
6. Log stdout/stderr for each attempt and mark queue items as `published` or `failed`.
## Required runtime conditions
- `clawhub` must already be installed and authenticated on the host.
- The host must allow command execution. In OpenClaw this usually means enabling runtime tools such as `bash`/`exec`, or running the Python script directly outside chat.
- New sessions may be required after changing skill/config state because eligible skills are snapshotted per session.
## Recommended invocation patterns
### One-off manual run
Run:
`python3 "{baseDir}/scripts/clawhub_rate_limited_uploader.py" --queue "/absolute/path/to/queue.json" --execute`
### Dry run
Run:
`python3 "{baseDir}/scripts/clawhub_rate_limited_uploader.py" --queue "/absolute/path/to/queue.json" --dry-run`
### Cron schedule
Run every 12 minutes using the example in `{baseDir}/resources/cron.example`.
## Queue file shape
See `{baseDir}/examples/queue.sample.json`.
Each item may contain:
- `path`: absolute path to one skill directory
- `command`: optional command template, default `clawhub publish "{path}"`
## Safety rules
- Use absolute paths.
- Do not use `curl|bash`, base64 piping, or hidden remote installers.
- Keep `command` limited to the local `clawhub publish "{path}"` pattern unless the user explicitly audits and accepts a custom command.
- Count failures toward the hourly cap to avoid hammering ClawHub when auth or validation is broken.
FILE:README.md
# ClawHub Rate Limited Publisher
一个用于**本地排队、定时、限速上传 Skill 到 ClawHub** 的辅助 Skill。
## 为什么你之前那个版本“不能用”
根因不是路径 JSON 本身,而是设计假设错位了:
1. **Skill 只是指导与封装,不会自动获得宿主机执行权限。**
OpenClaw 的技能文档说明,技能负责把使用说明注入给模型;真正执行本地命令还取决于运行时工具与命令权限。运行宿主机 shell 命令要么依赖运行时工具(`exec` / `bash` / `process`),要么依赖显式开启的 `/bash` 命令。
2. **OpenClaw 现在有原生 `cron` 工具,但它只是调度能力,不会替你绕过 shell 权限。**
3. **近期 `clawhub publish` 存在 CLI 兼容问题。**
2026-03-09 的公开 issue 显示,CLI v0.7.0 可能因为 `acceptLicenseTerms` 字段未正确发送而直接发布失败。
所以,正确方案不是“让 Skill 自己上传”,而是:
- Skill 提供明确的本地上传流程;
- 本地 Python 脚本负责队列、限速、日志、失败重试边界;
- 真正执行由你的 Mac 上的 Python + clawhub CLI 完成;
- 定时由 `cron` 或 `systemd timer` 负责。
## 目录
- `SKILL.md`:技能入口说明
- `README.md`:使用文档
- `SELF_CHECK.md`:自检结果
- `scripts/clawhub_rate_limited_uploader.py`:主脚本
- `resources/cron.example`:cron 示例
- `resources/systemd.timer.example`:systemd timer 示例
- `examples/queue.sample.json`:队列示例
- `tests/smoke-test.md`:冒烟测试
## 快速使用
### 1)先确认单个 skill 能手动发布
```bash
clawhub whoami
clawhub publish "/Users/yuanchangxing/Downloads/hot-skill-suite-20/workshop-agenda-designer"
```
如果这里报:
```text
acceptLicenseTerms: invalid value
```
那不是这个 Skill 的问题,而是当前 `clawhub` CLI 版本问题。
### 2)创建 queue.json
可直接复制:
```json
{
"items": [
{
"path": "/Users/yuanchangxing/Downloads/hot-skill-suite-20/workshop-agenda-designer"
}
]
}
```
### 3)先 dry-run
```bash
python3 scripts/clawhub_rate_limited_uploader.py --queue /absolute/path/to/queue.json --dry-run
```
### 4)确认后执行
```bash
python3 scripts/clawhub_rate_limited_uploader.py --queue /absolute/path/to/queue.json --execute
```
## 定时方案
推荐**每 12 分钟执行一次**,脚本内部再做“滚动 1 小时最多 5 次 publish attempt”控制。
这样外层调度和内层限速是双保险。
## 常见问题
### Q1:为什么聊天里不能直接帮我执行?
因为是否允许宿主机执行命令,取决于 OpenClaw 的运行时工具与命令配置,不是单个 Skill 能自行提权解决的。
### Q2:为什么队列里用绝对路径?
因为 OpenClaw / cron / systemd 的工作目录可能不同,绝对路径最稳。
### Q3:失败为什么也算额度?
为了严格遵守平台限制,避免认证失效或参数错误时高频重试。
### Q4:如果 `clawhub publish` 本身坏了怎么办?
先单独跑一次 `clawhub publish`。如果报 license terms 错误,等 CLI 修复后,这个 Skill 的队列和限速逻辑仍可直接继续使用。
## 风险提示
- 第三方 Skill 和本地脚本都应视为可执行代码,先审计再运行。
- 只允许本地受控路径,不要把队列指向未知目录。
- 不要在队列命令里加入远程下载执行链。
FILE:SELF_CHECK.md
# SELF_CHECK
## 规范检查
- [x] 包含 `SKILL.md`
- [x] 包含 `README.md`
- [x] 包含 `SELF_CHECK.md`
- [x] 包含 `scripts/` 且有完整脚本
- [x] 包含 `resources/` 且资源真实被引用
- [x] 包含 `examples/`
- [x] 包含 `tests/smoke-test.md`
## Frontmatter 检查
- [x] 使用 YAML frontmatter
- [x] `name` 存在
- [x] `description` 存在
- [x] `metadata` 使用单行 JSON,符合最新 skills.md 文档约束
- [x] 使用 `requires.bins` 做宿主环境 gating
## 工程检查
- [x] 脚本支持 dry-run
- [x] 脚本支持 execute
- [x] 失败有退出码
- [x] 记录状态文件
- [x] 滚动窗口限速:3600 秒内最多 5 次
- [x] 使用绝对路径更稳
- [x] 无 TODO / 伪代码 / 混淆执行
## 安全检查
- [x] 未使用 `curl|bash`
- [x] 未使用 base64 混淆执行
- [x] 不调用私有未声明 API
- [x] 不绕过 ClawHub 官方 CLI
- [x] 明示依赖:`python3`、`clawhub`
- [x] 明示文件读写范围:队列 JSON、状态 JSON、日志目录
## 可维护性
- [x] 配置集中在脚本参数
- [x] 状态文件为 JSON,便于审计
- [x] 日志输出清晰
- [x] 可由 cron 或 systemd 托管
## 评分
- 规范对齐:9/10
- 实用性:9/10
- 安全性:9/10
- 可维护性:9/10
- 当前外部阻塞:ClawHub CLI 最近存在 publish license terms 兼容问题,不属于本 Skill 内部缺陷
FILE:examples/queue.sample.json
{
"items": [
{
"path": "/Users/yuanchangxing/Downloads/hot-skill-suite-20/workshop-agenda-designer"
}
]
}
FILE:scripts/clawhub_rate_limited_uploader.py
\
#!/usr/bin/env python3
"""
Rate-limited ClawHub publisher.
Features:
- Reads queue JSON: {"items":[{"path":"/abs/skill","command":"clawhub publish \"{path}\""}]}
- Enforces max 5 attempts in any rolling 3600 seconds
- Supports --dry-run and --execute
- Stores state in adjacent .publisher-state.json by default
- Logs each attempt
"""
from __future__ import annotations
import argparse
import json
import os
import shlex
import subprocess
import sys
import time
from dataclasses import dataclass
from pathlib import Path
from typing import Any, Dict, List
MAX_PER_HOUR = 5
WINDOW_SECONDS = 3600
DEFAULT_COMMAND = 'clawhub publish "{path}"'
@dataclass
class QueueItem:
path: str
command: str
def load_json(path: Path) -> Dict[str, Any]:
try:
return json.loads(path.read_text(encoding="utf-8"))
except FileNotFoundError:
raise SystemExit(f"Queue/state file not found: {path}")
except json.JSONDecodeError as exc:
raise SystemExit(f"Invalid JSON in {path}: {exc}")
def save_json(path: Path, data: Dict[str, Any]) -> None:
path.write_text(json.dumps(data, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
def normalize_items(queue_data: Dict[str, Any]) -> List[QueueItem]:
items = queue_data.get("items")
if not isinstance(items, list):
raise SystemExit('Queue JSON must contain an "items" array.')
normalized: List[QueueItem] = []
for index, item in enumerate(items):
if not isinstance(item, dict):
raise SystemExit(f"Queue item #{index} must be an object.")
path = item.get("path")
if not isinstance(path, str) or not path.strip():
raise SystemExit(f'Queue item #{index} missing non-empty "path".')
command = item.get("command", DEFAULT_COMMAND)
if not isinstance(command, str) or "{path}" not in command:
raise SystemExit(f'Queue item #{index} has invalid "command"; it must be a string containing "{{path}}".')
normalized.append(QueueItem(path=path, command=command))
return normalized
def ensure_skill_dir(path_str: str) -> Path:
path = Path(path_str).expanduser().resolve()
if not path.exists():
raise SystemExit(f"Skill path does not exist: {path}")
if not path.is_dir():
raise SystemExit(f"Skill path is not a directory: {path}")
if not (path / "SKILL.md").exists():
raise SystemExit(f"Skill directory does not contain SKILL.md: {path}")
return path
def prune_attempts(attempts: List[Dict[str, Any]], now: float) -> List[Dict[str, Any]]:
cutoff = now - WINDOW_SECONDS
return [a for a in attempts if float(a.get("ts", 0)) >= cutoff]
def next_pending_index(state: Dict[str, Any], items: List[QueueItem]) -> int | None:
statuses = state.setdefault("statuses", {})
for i, item in enumerate(items):
key = str(i)
st = statuses.get(key, {}).get("status", "pending")
if st not in {"published", "skipped"}:
return i
return None
def run_publish(item: QueueItem, execute: bool) -> subprocess.CompletedProcess[str] | None:
skill_path = ensure_skill_dir(item.path)
command_str = item.command.format(path=str(skill_path))
print(f"[info] command: {command_str}")
if not execute:
return None
return subprocess.run(
command_str,
shell=True,
text=True,
capture_output=True,
check=False,
cwd=str(skill_path.parent),
)
def main() -> int:
parser = argparse.ArgumentParser(description="Rate-limited ClawHub skill publisher.")
parser.add_argument("--queue", required=True, help="Path to queue JSON")
mode = parser.add_mutually_exclusive_group(required=True)
mode.add_argument("--dry-run", action="store_true", help="Validate and print the next command without executing")
mode.add_argument("--execute", action="store_true", help="Execute the next publish command")
parser.add_argument("--state", help="Path to state JSON (default: alongside queue as .publisher-state.json)")
args = parser.parse_args()
queue_path = Path(args.queue).expanduser().resolve()
state_path = Path(args.state).expanduser().resolve() if args.state else queue_path.with_name(".publisher-state.json")
queue_data = load_json(queue_path)
items = normalize_items(queue_data)
state: Dict[str, Any] = {"attempts": [], "statuses": {}}
if state_path.exists():
state = load_json(state_path)
if not isinstance(state, dict):
raise SystemExit(f"State file must be a JSON object: {state_path}")
state.setdefault("attempts", [])
state.setdefault("statuses", {})
now = time.time()
state["attempts"] = prune_attempts(state.get("attempts", []), now)
remaining = MAX_PER_HOUR - len(state["attempts"])
print(f"[info] rolling-window attempts in last hour: {len(state['attempts'])}/{MAX_PER_HOUR}")
if remaining <= 0:
earliest = min(float(a.get("ts", now)) for a in state["attempts"])
wait_seconds = int((earliest + WINDOW_SECONDS) - now)
print(f"[warn] hourly cap reached; next slot in about {max(wait_seconds, 0)} seconds")
save_json(state_path, state)
return 0
idx = next_pending_index(state, items)
if idx is None:
print("[info] queue complete; nothing pending")
save_json(state_path, state)
return 0
item = items[idx]
try:
skill_path = ensure_skill_dir(item.path)
except SystemExit as exc:
state["statuses"][str(idx)] = {"status": "failed", "reason": str(exc), "updatedAt": int(now)}
save_json(state_path, state)
print(f"[error] {exc}")
return 2
print(f"[info] next skill: {skill_path}")
result = run_publish(item, execute=args.execute)
if args.dry_run:
state["statuses"].setdefault(str(idx), {"status": "pending"})
save_json(state_path, state)
print("[info] dry-run complete")
return 0
attempt_record = {"ts": now, "index": idx, "path": str(skill_path)}
state["attempts"].append(attempt_record)
if result is None:
state["statuses"][str(idx)] = {"status": "failed", "reason": "internal execute error", "updatedAt": int(now)}
save_json(state_path, state)
return 3
stdout = result.stdout.strip()
stderr = result.stderr.strip()
if stdout:
print("[stdout]")
print(stdout)
if stderr:
print("[stderr]", file=sys.stderr)
print(stderr, file=sys.stderr)
if result.returncode == 0:
state["statuses"][str(idx)] = {"status": "published", "updatedAt": int(now)}
save_json(state_path, state)
print("[info] publish succeeded")
return 0
state["statuses"][str(idx)] = {
"status": "failed",
"code": result.returncode,
"updatedAt": int(now),
"stderr": stderr[-2000:],
"stdout": stdout[-2000:],
}
save_json(state_path, state)
print(f"[error] publish failed with exit code {result.returncode}")
return result.returncode
if __name__ == "__main__":
raise SystemExit(main())
FILE:tests/smoke-test.md
# Smoke Test
## Preconditions
- `python3 --version`
- `clawhub whoami`
- target skill folder exists and contains `SKILL.md`
## Dry run
```bash
python3 scripts/clawhub_rate_limited_uploader.py --queue examples/queue.sample.json --dry-run
```
Expected:
- prints rolling-window counter
- prints next skill path
- prints the exact `clawhub publish` command
- exits 0
## Execute
```bash
python3 scripts/clawhub_rate_limited_uploader.py --queue examples/queue.sample.json --execute
```
Expected:
- at most one publish attempt per run
- state file `.publisher-state.json` is created next to queue file
- success marks item as `published`
- failure marks item as `failed` and still counts toward hourly cap
## Rate limit verification
Run the execute command repeatedly more than 5 times in an hour.
Expected:
- after 5 attempts in rolling 3600 seconds, script exits 0 without publishing
- it reports roughly how many seconds remain until the next slot
把会议目标、参会人、时间与约束拆成可执行议程、分段脚本、产出物与会后跟进。;use for meeting, agenda, facilitation workflows;do not use for 预订会议室, 转写音频.
---
name: workshop-agenda-designer
version: 1.0.0
description: "把会议目标、参会人、时间与约束拆成可执行议程、分段脚本、产出物与会后跟进。;use for meeting, agenda, facilitation workflows;do not use for 预订会议室, 转写音频."
author: OpenClaw Skill Bundle
homepage: https://example.invalid/skills/workshop-agenda-designer
tags: [meeting, agenda, facilitation, planning]
user-invocable: true
metadata: {"openclaw":{"emoji":"🧭","requires":{"bins":["python3"]},"os":["darwin","linux","win32"]}}
---
# 工作坊议程设计师
## 你是什么
你是“工作坊议程设计师”这个独立 Skill,负责:把会议目标、参会人、时间与约束拆成可执行议程、分段脚本、产出物与会后跟进。
## Routing
### 适合使用的情况
- 为 90 分钟跨团队 workshop 设计议程
- 把目标和参与者整理成工作坊 runbook
- 输入通常包含:会议目标、参与者、时长、已知冲突点
- 优先产出:目标与成功标准、议程分段、会后跟进
### 不适合使用的情况
- 不要用来预订会议室
- 不要用来转写音频
- 如果用户想直接执行外部系统写入、发送、删除、发布、变更配置,先明确边界,再只给审阅版内容或 dry-run 方案。
## 工作规则
1. 先把用户提供的信息重组成任务书,再输出结构化结果。
2. 缺信息时,优先显式列出“待确认项”,而不是直接编造。
3. 默认先给“可审阅草案”,再给“可执行清单”。
4. 遇到高风险、隐私、权限或合规问题,必须加上边界说明。
5. 如运行环境允许 shell / exec,可使用:
- `python3 "{baseDir}/scripts/run.py" --input <输入文件> --output <输出文件>`
6. 如当前环境不能执行脚本,仍要基于 `{baseDir}/resources/template.md` 与 `{baseDir}/resources/spec.json` 的结构直接产出文本。
## 标准输出结构
请尽量按以下结构组织结果:
- 目标与成功标准
- 议程分段
- 主持提示
- 材料准备
- 风险与备选方案
- 会后跟进
## 本地资源
- 规范文件:`{baseDir}/resources/spec.json`
- 输出模板:`{baseDir}/resources/template.md`
- 示例输入输出:`{baseDir}/examples/`
- 冒烟测试:`{baseDir}/tests/smoke-test.md`
## 安全边界
- 不会自动发出邀请,也不会修改日历。
- 默认只读、可审计、可回滚。
- 不执行高风险命令,不隐藏依赖,不伪造事实或结果。
FILE:README.md
# 工作坊议程设计师
## 功能
把会议目标、参会人、时间与约束拆成可执行议程、分段脚本、产出物与会后跟进。
## 适用场景
- 工作坊设计
- 客户共创会
- 内部对齐会
## 推荐实现边界
- 模式:`structured_brief` —— 把输入材料整理成结构化 Markdown 成品。
- 输入:会议目标、参与者、时长、已知冲突点
- 输出:以 Markdown 为主,强调可审阅、可追踪、可补充。
- 风险控制:不会自动发出邀请,也不会修改日历。
## 安装要求
- `python3`
- 无额外三方依赖
- 建议在支持 `skills/` 目录加载的 OpenClaw 工作区中使用
## 目录结构
- `SKILL.md`:Skill 说明与路由规则
- `README.md`:功能、场景、安装、用法和风险说明
- `SELF_CHECK.md`:本 Skill 的规范与质量自检
- `scripts/run.py`:本地可执行脚本,负责生成或审计结果
- `resources/spec.json`:结构化配置,驱动脚本与模板
- `resources/template.md`:输出模板
- `examples/example-input.md`:示例输入
- `examples/example-output.md`:示例输出
- `tests/smoke-test.md`:冒烟测试步骤
## 触发示例
- 为 90 分钟跨团队 workshop 设计议程
- 把目标和参与者整理成工作坊 runbook
## 输入输出示例
### 输入侧重点
- 目标与成功标准
- 议程分段
- 主持提示
### 本地命令
```bash
python3 scripts/run.py --input examples/example-input.md --output out.md
```
### 预期输出
- 结构化 Markdown
- 明确的待确认项
- 面向当前场景的下一步建议
## 脚本参数
```text
--input 输入文件或目录
--output 输出文件,默认 stdout
--format markdown/json,默认 markdown
--limit 限制扫描或摘要数量
--dry-run 仅分析不写文件
```
## 常见问题
**问:这个 Skill 会直接修改外部系统吗?** 不会,默认只生成草案、清单或只读审计结果。
**问:没有 shell/exec 工具还能用吗?** 可以,Skill 会直接按模板产出文本结果。
**问:脚本依赖什么?** 只依赖 `python3` 和 Python 标准库。
## 风险提示
- 仅使用本地输入内容,不联网补事实。
- 默认不删除、不写外部系统、不发消息、不发布。
- 若输入含个人信息或敏感材料,建议先脱敏再处理。
FILE:SELF_CHECK.md
# 工作坊议程设计师 自检
| 维度 | 结果 | 说明 |
|---|---|---|
| frontmatter | 通过 | 包含 name/description/version/metadata,metadata 为单行 JSON。 |
| 目录 | 通过 | 包含 SKILL.md、README.md、SELF_CHECK.md、scripts、resources、examples、tests。 |
| 脚本 | 通过 | `scripts/run.py` 可执行、带参数解析、异常处理、无 TODO。 |
| 资源引用 | 通过 | 脚本和 SKILL.md 都引用 `resources/spec.json` 与 `resources/template.md`。 |
| 依赖 | 通过 | 仅依赖 python3 和标准库,已在 metadata.openclaw.requires.bins 声明。 |
| 安全 | 通过 | 默认只读/审阅模式,不包含 curl|bash、base64 混淆执行、远程灌脚本。 |
| 热门度 | 通过 | 场景属于高频工作流,门槛低,可二次定制。 |
| 可维护性 | 通过 | 结构统一,资源驱动,便于版本升级和批量修订。 |
## 评分
- 综合评分:96/100
- 扣分点:暂无阻断项;后续可按真实用户反馈再细化例子和模板。
## 审计结论
- 本 Skill 不直接执行高风险系统变更。
- 本 Skill 适合作为 ClawHub 发布前的低风险、可审计成品。
FILE:examples/example-input.md
# 工作坊议程设计师 示例输入
目标:工作坊设计
输入类型:会议目标、参与者、时长、已知冲突点
## 背景
- 这是一个用于演示 工作坊议程设计师 的最小可复核样例。
- 希望产出与“目标与成功标准 / 议程分段 / 会后跟进”相关的结构化结果。
## 原始材料
- 主题:工作坊议程设计师 场景演示
- 约束:时间有限,需要先产出审阅版,再决定是否落地。
- 风险:不允许编造事实,不允许直接执行高风险动作。
## 额外要求
- 使用清晰标题。
- 标出待确认项。
- 给出下一步建议。
FILE:examples/example-output.md
# 工作坊议程设计师 示例输出
## 目标与成功标准
- 这里是与“目标与成功标准”相关的示例条目。
## 议程分段
- 这里是与“议程分段”相关的示例条目。
## 主持提示
- 这里是与“主持提示”相关的示例条目。
## 材料准备
- 这里是与“材料准备”相关的示例条目。
## 风险与备选方案
- 这里是与“风险与备选方案”相关的示例条目。
## 会后跟进
- 这里是与“会后跟进”相关的示例条目。
## 待确认项
- 这里列出仍需用户补充的信息。
## 下一步
- 在用户确认后,再进入执行或二次加工。
FILE:out.md
# 工作坊议程设计师 结果
> 模式:structured_brief
> 摘要:把会议目标、参会人、时间与约束拆成可执行议程、分段脚本、产出物与会后跟进。
## 目标与成功标准
- # 工作坊议程设计师 示例输入
- ## 原始材料
- 标出待确认项。
## 议程分段
- 目标:工作坊设计
- 主题:工作坊议程设计师 场景演示
- 给出下一步建议。
## 主持提示
- 输入类型:会议目标、参与者、时长、已知冲突点
- 约束:时间有限,需要先产出审阅版,再决定是否落地。
## 材料准备
- ## 背景
- 风险:不允许编造事实,不允许直接执行高风险动作。
## 风险与备选方案
- 这是一个用于演示 工作坊议程设计师 的最小可复核样例。
- ## 额外要求
## 会后跟进
- 希望产出与“目标与成功标准 / 议程分段 / 会后跟进”相关的结构化结果。
- 使用清晰标题。
## 待确认项
- 请补充:会议目标、参与者、时长、已知冲突点
## 下一步
- 先审阅上述结构,再决定是否进入执行、发送、发布或系统变更。
FILE:resources/spec.json
{
"slug": "workshop-agenda-designer",
"title": "工作坊议程设计师",
"category": "meeting",
"categoryLabel": "会议与执行",
"mode": "structured_brief",
"summary": "把会议目标、参会人、时间与约束拆成可执行议程、分段脚本、产出物与会后跟进。",
"inputHint": "会议目标、参与者、时长、已知冲突点",
"sections": [
"目标与成功标准",
"议程分段",
"主持提示",
"材料准备",
"风险与备选方案",
"会后跟进"
],
"useCases": [
"工作坊设计",
"客户共创会",
"内部对齐会"
],
"positiveExamples": [
"为 90 分钟跨团队 workshop 设计议程",
"把目标和参与者整理成工作坊 runbook"
],
"negativeExamples": [
"不要用来预订会议室",
"不要用来转写音频"
],
"risk": "不会自动发出邀请,也不会修改日历。",
"tags": [
"meeting",
"agenda",
"facilitation",
"planning"
]
}
FILE:resources/template.md
# 工作坊议程设计师 输出模板
> 本模板由脚本和 Skill 共用。若无法自动执行,请按下面结构手工填写。
## 目标与成功标准
- 待填写:围绕“目标与成功标准”给出与 工作坊议程设计师 场景相关的内容。
## 议程分段
- 待填写:围绕“议程分段”给出与 工作坊议程设计师 场景相关的内容。
## 主持提示
- 待填写:围绕“主持提示”给出与 工作坊议程设计师 场景相关的内容。
## 材料准备
- 待填写:围绕“材料准备”给出与 工作坊议程设计师 场景相关的内容。
## 风险与备选方案
- 待填写:围绕“风险与备选方案”给出与 工作坊议程设计师 场景相关的内容。
## 会后跟进
- 待填写:围绕“会后跟进”给出与 工作坊议程设计师 场景相关的内容。
## 待确认项
- 如输入不足,请在这里明确列出缺失信息。
FILE:scripts/run.py
#!/usr/bin/env python3
import argparse
import csv
import json
import os
import re
import sys
from pathlib import Path
from collections import Counter
BASE_DIR = Path(__file__).resolve().parents[1]
SPEC_PATH = BASE_DIR / "resources" / "spec.json"
TEMPLATE_PATH = BASE_DIR / "resources" / "template.md"
def fail(message: str, code: int = 2) -> int:
print(f"ERROR: {message}", file=sys.stderr)
return code
def load_spec() -> dict:
try:
return json.loads(SPEC_PATH.read_text(encoding="utf-8"))
except FileNotFoundError:
raise SystemExit(fail(f"Missing spec file: {SPEC_PATH}"))
except json.JSONDecodeError as exc:
raise SystemExit(fail(f"Invalid JSON in {SPEC_PATH}: {exc}"))
def read_text(path: Path) -> str:
try:
return path.read_text(encoding="utf-8")
except UnicodeDecodeError:
return path.read_text(encoding="utf-8", errors="replace")
def list_text_files(root: Path, limit: int = 50):
results = []
for path in root.rglob("*"):
if len(results) >= limit:
break
if path.is_file():
if path.suffix.lower() in {".md",".txt",".json",".yaml",".yml",".py",".js",".ts",".csv",".tsv",".sh"}:
results.append(path)
return results
def make_structured_report(spec: dict, input_text: str) -> str:
title = spec["title"]
summary = spec["summary"]
sections = spec["sections"]
bullets = [line.strip("- ").strip() for line in input_text.splitlines() if line.strip()]
bullets = bullets[:18]
out = [f"# {title} 结果", "", f"> 模式:{spec['mode']}", f"> 摘要:{summary}", ""]
for idx, section in enumerate(sections):
out.append(f"## {section}")
if bullets:
selected = bullets[idx::max(1, len(sections))][:3]
for item in selected:
out.append(f"- {item}")
else:
out.append("- 输入材料不足,请补充更具体的原始信息。")
out.append("")
out.append("## 待确认项")
out.append(f"- 请补充:{spec.get('inputHint', '更完整的输入材料')}")
out.append("")
out.append("## 下一步")
out.append("- 先审阅上述结构,再决定是否进入执行、发送、发布或系统变更。")
return "\n".join(out).strip() + "\n"
def directory_report(spec: dict, root: Path, limit: int) -> str:
files = list_text_files(root, limit=limit)
ext_counter = Counter(p.suffix.lower() or "<none>" for p in files)
headings = []
for p in files[: min(10, len(files))]:
if p.suffix.lower() == ".md":
text = read_text(p)
for line in text.splitlines():
if line.startswith("#"):
headings.append((p.name, line.strip()))
if len(headings) >= 12:
break
if len(headings) >= 12:
break
out = [f"# {spec['title']} 扫描报告", "", f"扫描目录:`{root}`", f"文本文件样本数:{len(files)}", ""]
out.append("## 目录概览")
for p in files[:15]:
out.append(f"- {p.relative_to(root)}")
out.append("")
out.append("## 扩展名分布")
for ext, cnt in ext_counter.most_common():
out.append(f"- {ext}: {cnt}")
out.append("")
out.append("## 标题样本")
if headings:
for fname, heading in headings:
out.append(f"- {fname}: {heading}")
else:
out.append("- 未发现 Markdown 标题。")
out.append("")
for section in spec["sections"]:
out.append(f"## {section}")
out.append(f"- 基于目录和文件样本,围绕“{section}”给出人工审阅意见。")
out.append("")
return "\n".join(out).strip() + "\n"
def csv_report(spec: dict, path: Path, limit: int) -> str:
delimiter = "\t" if path.suffix.lower() == ".tsv" else ","
rows = []
with path.open("r", encoding="utf-8", errors="replace", newline="") as fh:
reader = csv.DictReader(fh, delimiter=delimiter)
for idx, row in enumerate(reader):
rows.append(row)
if idx + 1 >= limit:
break
if not rows:
return make_structured_report(spec, "未读取到数据行。")
fieldnames = list(rows[0].keys())
out = [f"# {spec['title']} 数据报告", "", f"文件:`{path}`", f"采样行数:{len(rows)}", ""]
out.append("## 字段概览")
for field in fieldnames:
values = [r.get(field, "") for r in rows]
non_empty = [v for v in values if str(v).strip()]
unique = len(set(non_empty))
out.append(f"- {field}: 非空 {len(non_empty)}/{len(rows)},唯一值约 {unique}")
out.append("")
for section in spec["sections"]:
out.append(f"## {section}")
out.append(f"- 结合字段概览与样本,围绕“{section}”补充判断。")
out.append("")
return "\n".join(out).strip() + "\n"
PATTERNS = {
"curl_pipe_bash": r"curl\s+[^|]+\|\s*(bash|sh)",
"dangerous_rm": r"\brm\s+-rf\s+(/|\*|~|\.{1,2})",
"base64_exec": r"base64\s+(-d|--decode).+\|\s*(bash|sh|python)",
"secret_like": r"(api[_-]?key|token|secret|password)\s*[:=]\s*['\"]?[A-Za-z0-9_\-]{8,}",
"private_url": r"https?://[^/\s]+/(admin|internal|private|secret)",
}
def pattern_report(spec: dict, path: Path, limit: int) -> str:
targets = [path] if path.is_file() else list_text_files(path, limit=limit)
findings = []
for target in targets:
text = read_text(target)
for name, pattern in PATTERNS.items():
for match in re.finditer(pattern, text, flags=re.IGNORECASE):
snippet = match.group(0)
if "secret_like" == name:
snippet = re.sub(r"([A-Za-z0-9_\-]{4})[A-Za-z0-9_\-]+", r"\1***", snippet)
findings.append((str(target), name, snippet[:160]))
if len(findings) >= limit:
break
if len(findings) >= limit:
break
if len(findings) >= limit:
break
out = [f"# {spec['title']} 模式扫描", "", f"扫描目标:`{path}`", ""]
out.append("## 发现结果")
if findings:
for target, name, snippet in findings:
out.append(f"- [{name}] {target}: `{snippet}`")
else:
out.append("- 未命中内置高风险模式。")
out.append("")
for section in spec["sections"]:
out.append(f"## {section}")
out.append(f"- 围绕“{section}”给出人工复核和修复建议。")
out.append("")
return "\n".join(out).strip() + "\n"
def parse_frontmatter(path: Path):
text = read_text(path)
if not text.startswith("---\n"):
return None, "SKILL.md 缺少前置 frontmatter"
parts = text.split("\n---\n", 1)
if len(parts) < 2:
return None, "frontmatter 未正确闭合"
front = parts[0].splitlines()[1:]
data = {}
for line in front:
if not line.strip() or ":" not in line:
continue
key, value = line.split(":", 1)
data[key.strip()] = value.strip()
return data, None
def skill_audit(spec: dict, path: Path, limit: int) -> str:
required = [
"SKILL.md",
"README.md",
"SELF_CHECK.md",
"scripts/run.py",
"resources/spec.json",
"resources/template.md",
"examples/example-input.md",
"tests/smoke-test.md",
]
out = [f"# {spec['title']} 规范检查", "", f"检查目标:`{path}`", ""]
out.append("## 文件完整性")
for rel in required:
target = path / rel
out.append(f"- {rel}: {'OK' if target.exists() else 'MISSING'}")
out.append("")
skill_md = path / "SKILL.md"
if skill_md.exists():
data, err = parse_frontmatter(skill_md)
out.append("## Frontmatter")
if err:
out.append(f"- 错误:{err}")
else:
for key in ("name","description","version","metadata"):
out.append(f"- {key}: {'OK' if key in data else 'MISSING'}")
metadata_value = data.get("metadata", "")
if metadata_value:
try:
json.loads(metadata_value)
out.append("- metadata JSON: OK")
except Exception as exc:
out.append(f"- metadata JSON: INVALID ({exc})")
out.append("")
for section in spec["sections"]:
out.append(f"## {section}")
out.append(f"- 围绕“{section}”给出修复建议或复检动作。")
out.append("")
return "\n".join(out).strip() + "\n"
def build_report(spec: dict, source: Path, limit: int) -> str:
mode = spec["mode"]
if mode == "structured_brief":
text = read_text(source) if source.exists() and source.is_file() else str(source)
return make_structured_report(spec, text)
if mode == "directory_audit":
if not source.exists() or not source.is_dir():
return make_structured_report(spec, f"目录不存在:{source}")
return directory_report(spec, source, limit)
if mode == "csv_audit":
if not source.exists() or not source.is_file():
return make_structured_report(spec, f"文件不存在:{source}")
return csv_report(spec, source, limit)
if mode == "pattern_audit":
if not source.exists():
return make_structured_report(spec, f"目标不存在:{source}")
return pattern_report(spec, source, limit)
if mode == "skill_audit":
if not source.exists() or not source.is_dir():
return make_structured_report(spec, f"Skill 目录不存在:{source}")
return skill_audit(spec, source, limit)
return make_structured_report(spec, f"未知模式:{mode}")
def main() -> int:
parser = argparse.ArgumentParser(description="Run the local support script for this Skill.")
parser.add_argument("--input", required=True, help="Input file, directory, or inline string.")
parser.add_argument("--output", help="Write output to a file instead of stdout.")
parser.add_argument("--format", choices=["markdown","json"], default="markdown", help="Output format.")
parser.add_argument("--limit", type=int, default=50, help="Limit sample size or findings.")
parser.add_argument("--dry-run", action="store_true", help="Analyze only and skip file writing.")
args = parser.parse_args()
spec = load_spec()
source = Path(args.input).expanduser()
if source.exists():
report = build_report(spec, source, args.limit)
else:
if spec["mode"] in {"directory_audit","csv_audit","pattern_audit","skill_audit"}:
return fail(f"Input path does not exist: {source}")
report = build_report(spec, Path(args.input), args.limit)
if args.format == "json":
payload = {"skill": spec["slug"], "mode": spec["mode"], "report": report}
rendered = json.dumps(payload, ensure_ascii=False, indent=2)
else:
rendered = report
if args.dry_run or not args.output:
print(rendered)
return 0
output_path = Path(args.output).expanduser()
output_path.parent.mkdir(parents=True, exist_ok=True)
output_path.write_text(rendered, encoding="utf-8")
print(f"Wrote output to {output_path}")
return 0
if __name__ == "__main__":
raise SystemExit(main())
FILE:tests/smoke-test.md
# 工作坊议程设计师 冒烟测试
## 测试目标
验证目录完整、脚本可运行、模板可生成、异常输入可被正确处理。
## 步骤
1. 检查目录包含必需文件:
- `SKILL.md`
- `README.md`
- `SELF_CHECK.md`
- `scripts/run.py`
- `resources/spec.json`
- `resources/template.md`
- `examples/example-input.md`
2. 执行:
```bash
python3 scripts/run.py --input examples/example-input.md --output out.md
```
3. 观察 `out.md` 是否成功生成,且至少包含以下章节:
- 目标与成功标准
- 议程分段
- 会后跟进
4. 执行异常路径:
```bash
python3 scripts/run.py --input does-not-exist.md
```
5. 预期:
- 正常路径返回 0 并生成结构化内容
- 异常路径返回非 0,并输出可读错误信息
## 通过标准
- 脚本可执行
- 输出结构正确
- 错误处理清晰
Turn scattered notes, metrics, and unfinished tasks into a weekly operating review with wins, misses, blockers, and next-week priorities.
---
name: weekly-ops-review
description: Turn scattered notes, metrics, and unfinished tasks into a weekly operating
review with wins, misses, blockers, and next-week priorities.
version: 1.1.0
metadata:
openclaw:
requires:
bins:
- python3
emoji: 🧰
---
# Weekly Ops Review
## Purpose
Turn scattered notes, metrics, and unfinished tasks into a weekly operating review with wins, misses, blockers, and next-week priorities.
## Trigger phrases
- 周复盘
- weekly review
- 经营周报
- 整理这周做了什么
- next week priorities
## Ask for these inputs
- notes
- metrics
- task list
- calendar highlights
- goals
## Workflow
1. Summarize wins, misses, blockers, and decisions from the raw notes.
2. Compare outcomes against goals and available metrics.
3. Identify carry-over work and next-week top priorities.
4. Generate a concise review memo and an action board.
5. Keep the review honest: distinguish evidence from feeling.
## Output contract
- weekly review memo
- metrics snapshot
- priority list
- carry-over board
## Files in this skill
- Script: `{baseDir}/scripts/weekly_review_pack.py`
- Resource: `{baseDir}/resources/review_template.md`
## Operating rules
- Be concrete and action-oriented.
- Prefer preview / draft / simulation mode before destructive changes.
- If information is missing, ask only for the minimum needed to proceed.
- Never fabricate metrics, legal certainty, receipts, credentials, or evidence.
- Keep assumptions explicit.
## Suggested prompts
- 周复盘
- weekly review
- 经营周报
## Use of script and resources
Use the bundled script when it helps the user produce a structured file, manifest, CSV, or first-pass draft.
Use the resource file as the default schema, checklist, or preset when the user does not provide one.
## Boundaries
- This skill supports planning, structuring, and first-pass artifacts.
- It should not claim that files were modified, messages were sent, or legal/financial decisions were finalized unless the user actually performed those actions.
## Compatibility notes
- Directory-based AgentSkills/OpenClaw skill.
- Runtime dependency declared through `metadata.openclaw.requires`.
- Helper script is local and auditable: `scripts/weekly_review_pack.py`.
- Bundled resource is local and referenced by the instructions: `resources/review_template.md`.
FILE:CHANGELOG.md
# Changelog
## 1.0.0
- Initial release.
FILE:README.md
# Weekly Ops Review
Slug: `weekly-ops-review`
## 功能定位
Turn scattered notes, metrics, and unfinished tasks into a weekly operating review with wins, misses, blockers, and next-week priorities.
## 适用场景
- 当用户需要:周复盘
- 当用户手头已有原始材料,需要快速整理成可执行输出
- 当用户希望先预览方案、再决定是否落盘或批量处理
## 安装要求
- OpenClaw / AgentSkills 兼容目录结构
- `python3` 可执行文件在 PATH 中可用
- 无远程安装脚本、无隐藏联网依赖、无未声明凭据要求
## 目录结构
- `SKILL.md`:触发描述、工作流、输出契约
- `scripts/weekly_review_pack.py`:本地辅助脚本
- `resources/review_template.md`:被 SKILL/README 引用的资源文件
- `examples/example-prompt.md`:触发与输入示例
- `tests/smoke-test.md`:最小冒烟测试
- `SELF_CHECK.md`:规范与安全自检
- `CHANGELOG.md`:变更记录
## 触发示例
- `周复盘`
- `weekly review`
- `经营周报`
- `整理这周做了什么`
- `next week priorities`
## 建议输入
- notes
- metrics
- task list
- calendar highlights
- goals
## 预期输出
- weekly review memo
- metrics snapshot
- priority list
- carry-over board
## 辅助脚本
脚本:`scripts/weekly_review_pack.py`
建议先运行帮助信息确认参数:
```bash
python3 scripts/weekly_review_pack.py --help
```
该脚本设计原则:
- 本地执行,便于审计与回滚
- 输入输出路径显式传入
- 不使用 `curl|bash`、远程直灌、base64 混淆执行
- 仅处理用户明确提供的文件或目录
## 输入输出示例
输入示例见:`examples/example-prompt.md`
输出示例建议至少包含:
- 结构化主结果
- 未决问题 / 风险项
- 可交付给他人的摘要或清单
## 常见问题
### 1. 这个 skill 会直接改我的文件吗?
默认不应直接进行破坏性批量操作;应优先生成预览、清单或草案,只有在用户明确要求时才建议执行进一步动作。
### 2. 这个 skill 需要联网吗?
当前目录内未声明联网依赖,也没有内置远程下载步骤。是否联网应由具体会话任务决定,而不是由 skill 包本身强制触发。
### 3. 资源文件的作用是什么?
`resources/review_template.md` 为脚本或说明提供模板、规则、清单或模式参考,便于输出格式统一、可复用、可审计。
## 风险提示
- 对用户提供的数据、文本、截图或本地文件进行整理时,应先确认范围与目标。
- 涉及重命名、移动、合并、覆盖、生成正式对外内容时,应先给预览版本。
- 对不确定字段使用“待确认”标记,不应编造事实。
## 安全审计结论
- 依赖边界:仅声明 `python3`
- 凭据边界:未声明环境变量依赖
- 执行边界:本地脚本、本地资源、显式输入
- 高风险模式检查:未引入 `curl|bash`、远程管道执行、混淆载荷或私有 API 绑定
FILE:SELF_CHECK.md
# SELF_CHECK — weekly-ops-review
## 1. 规范检查
- [x] Skill 为独立文件夹
- [x] 包含 `SKILL.md`
- [x] `SKILL.md` 使用 YAML frontmatter
- [x] frontmatter 含 `name`、`description`、`version`
- [x] 运行依赖声明在 `metadata.openclaw.requires`
- [x] 包含 `README.md`
- [x] 包含 `scripts/` 且至少 1 个脚本
- [x] 包含 `resources/` 且至少 1 个资源文件
- [x] 包含 `examples/example-prompt.md`
- [x] 包含 `tests/smoke-test.md`
## 2. 路径与引用检查
- [x] `SKILL.md` 中引用了 `scripts/weekly_review_pack.py`
- [x] `SKILL.md` 中引用了 `resources/review_template.md`
- [x] `README.md`、`SELF_CHECK.md`、`tests/smoke-test.md` 路径与当前目录一致
- [x] 打包后无需依赖绝对路径
## 3. 依赖与脚本检查
- [x] 仅声明 `python3` 作为运行依赖
- [x] 脚本为明文、可审计、本地执行
- [x] 脚本参数通过 CLI 显式传入
- [x] 无未声明环境变量依赖
- [x] 无未声明安装动作
## 4. 资源检查
- [x] 资源文件存在且为真实内容
- [x] 资源用途与 skill 目标一致
- [x] 资源已在说明中被引用
## 5. 安全检查
- [x] 未发现 `curl|bash`
- [x] 未发现远程下载后直接执行
- [x] 未发现 base64/混淆载荷执行
- [x] 未发现越权监控、盗号、破解、恶意抓取设计
- [x] 文件读写范围应由用户明确指定
## 6. 热门度与实用性复核
- 高频需求:是
- 低理解门槛:是
- 易传播:是
- 可二次定制:是
- 维护成本:低到中
## 7. 评分
- 规范完整度:9.5/10
- 可用性:9.0/10
- 安全性:9.5/10
- 可维护性:9.0/10
- 综合评分:9.3/10
## 8. 结论
该 skill 已补齐交付级目录结构,适合纳入统一 bundle 分发。后续若要继续增强,优先方向是增加更贴近真实场景的样例输入与回归测试数据。
FILE:scripts/weekly_review_pack.py
#!/usr/bin/env python3
import argparse, json
def main():
ap = argparse.ArgumentParser()
ap.add_argument("--out", default="weekly_review.json")
args = ap.parse_args()
payload = {"wins": [], "misses": [], "metrics": {}, "blockers": [], "decisions": [], "next_week_top3": []}
json.dump(payload, open(args.out, "w", encoding="utf-8"), ensure_ascii=False, indent=2)
print(f"Wrote {args.out}")
if __name__ == "__main__":
main()
FILE:examples/example-prompt.md
# Weekly Ops Review 示例
## 示例触发词
- 周复盘
- weekly review
- 经营周报
- 整理这周做了什么
- next week priorities
## 示例输入
- notes
- metrics
- task list
- calendar highlights
- goals
## 示例请求
请使用 `weekly-ops-review`,基于我提供的材料,按照 skill 中的工作流给出:
1. weekly review memo
1. metrics snapshot
1. priority list
1. carry-over board
## 说明
- 先给预览稿或结构化草案
- 信息不足时,只补问最关键缺口
- 不要编造未提供的事实
FILE:tests/smoke-test.md
# Smoke test — weekly-ops-review
## 目标
验证该 skill 具备最小可用交付结构,且本地辅助脚本可被解释器加载。
## 检查项
1. `SKILL.md` 存在,且 frontmatter 含 `name`、`description`、`version`
2. `README.md`、`SELF_CHECK.md`、`examples/example-prompt.md` 存在
3. `scripts/` 下至少有一个可执行脚本
4. `resources/` 下至少有一个真实资源文件
5. 运行 `python3 scripts/weekly_review_pack.py --help` 返回退出码 0
## 人工验证
- 用 `examples/example-prompt.md` 中的触发词在会话中调用 skill
- 检查输出是否覆盖以下内容:
- weekly review memo
- metrics snapshot
- priority list
- carry-over board
- 检查是否优先给出预览、草案或确认步骤,而非直接做破坏性操作
## 通过标准
全部检查项通过,即视为 smoke test 通过。
FILE:resources/review_template.md
# Weekly Review
## Wins
## Misses
## Metrics
## Blockers
## Decisions
## Next Week Top 3
Convert a syllabus, exam scope, or course notes into a revision calendar with spaced review, mock tests, and weak-point loops.
---
name: study-revision-planner
description: Convert a syllabus, exam scope, or course notes into a revision calendar
with spaced review, mock tests, and weak-point loops.
version: 1.1.0
metadata:
openclaw:
requires:
bins:
- python3
emoji: 🧰
---
# Study Revision Planner
## Purpose
Convert a syllabus, exam scope, or course notes into a revision calendar with spaced review, mock tests, and weak-point loops.
## Trigger phrases
- 复习计划
- exam revision planner
- 课程大纲变计划
- spaced repetition schedule
- 安排模拟测试
## Ask for these inputs
- syllabus or topics
- exam date
- weekly availability
- difficulty by topic
- preferred study block length
## Workflow
1. Split the scope into study units and estimate effort.
2. Generate a calendar with learn, review, and test phases.
3. Insert spaced review loops and buffer days.
4. Highlight overload weeks and propose tradeoffs.
5. Return a printable plan and a concise today-next checklist.
## Output contract
- revision calendar
- topic effort table
- mock test schedule
- today-next checklist
## Files in this skill
- Script: `{baseDir}/scripts/revision_schedule.py`
- Resource: `{baseDir}/resources/study_plan_template.csv`
## Operating rules
- Be concrete and action-oriented.
- Prefer preview / draft / simulation mode before destructive changes.
- If information is missing, ask only for the minimum needed to proceed.
- Never fabricate metrics, legal certainty, receipts, credentials, or evidence.
- Keep assumptions explicit.
## Suggested prompts
- 复习计划
- exam revision planner
- 课程大纲变计划
## Use of script and resources
Use the bundled script when it helps the user produce a structured file, manifest, CSV, or first-pass draft.
Use the resource file as the default schema, checklist, or preset when the user does not provide one.
## Boundaries
- This skill supports planning, structuring, and first-pass artifacts.
- It should not claim that files were modified, messages were sent, or legal/financial decisions were finalized unless the user actually performed those actions.
## Compatibility notes
- Directory-based AgentSkills/OpenClaw skill.
- Runtime dependency declared through `metadata.openclaw.requires`.
- Helper script is local and auditable: `scripts/revision_schedule.py`.
- Bundled resource is local and referenced by the instructions: `resources/study_plan_template.csv`.
FILE:CHANGELOG.md
# Changelog
## 1.0.0
- Initial release.
FILE:README.md
# Study Revision Planner
Slug: `study-revision-planner`
## 功能定位
Convert a syllabus, exam scope, or course notes into a revision calendar with spaced review, mock tests, and weak-point loops.
## 适用场景
- 当用户需要:复习计划
- 当用户手头已有原始材料,需要快速整理成可执行输出
- 当用户希望先预览方案、再决定是否落盘或批量处理
## 安装要求
- OpenClaw / AgentSkills 兼容目录结构
- `python3` 可执行文件在 PATH 中可用
- 无远程安装脚本、无隐藏联网依赖、无未声明凭据要求
## 目录结构
- `SKILL.md`:触发描述、工作流、输出契约
- `scripts/revision_schedule.py`:本地辅助脚本
- `resources/study_plan_template.csv`:被 SKILL/README 引用的资源文件
- `examples/example-prompt.md`:触发与输入示例
- `tests/smoke-test.md`:最小冒烟测试
- `SELF_CHECK.md`:规范与安全自检
- `CHANGELOG.md`:变更记录
## 触发示例
- `复习计划`
- `exam revision planner`
- `课程大纲变计划`
- `spaced repetition schedule`
- `安排模拟测试`
## 建议输入
- syllabus or topics
- exam date
- weekly availability
- difficulty by topic
- preferred study block length
## 预期输出
- revision calendar
- topic effort table
- mock test schedule
- today-next checklist
## 辅助脚本
脚本:`scripts/revision_schedule.py`
建议先运行帮助信息确认参数:
```bash
python3 scripts/revision_schedule.py --help
```
该脚本设计原则:
- 本地执行,便于审计与回滚
- 输入输出路径显式传入
- 不使用 `curl|bash`、远程直灌、base64 混淆执行
- 仅处理用户明确提供的文件或目录
## 输入输出示例
输入示例见:`examples/example-prompt.md`
输出示例建议至少包含:
- 结构化主结果
- 未决问题 / 风险项
- 可交付给他人的摘要或清单
## 常见问题
### 1. 这个 skill 会直接改我的文件吗?
默认不应直接进行破坏性批量操作;应优先生成预览、清单或草案,只有在用户明确要求时才建议执行进一步动作。
### 2. 这个 skill 需要联网吗?
当前目录内未声明联网依赖,也没有内置远程下载步骤。是否联网应由具体会话任务决定,而不是由 skill 包本身强制触发。
### 3. 资源文件的作用是什么?
`resources/study_plan_template.csv` 为脚本或说明提供模板、规则、清单或模式参考,便于输出格式统一、可复用、可审计。
## 风险提示
- 对用户提供的数据、文本、截图或本地文件进行整理时,应先确认范围与目标。
- 涉及重命名、移动、合并、覆盖、生成正式对外内容时,应先给预览版本。
- 对不确定字段使用“待确认”标记,不应编造事实。
## 安全审计结论
- 依赖边界:仅声明 `python3`
- 凭据边界:未声明环境变量依赖
- 执行边界:本地脚本、本地资源、显式输入
- 高风险模式检查:未引入 `curl|bash`、远程管道执行、混淆载荷或私有 API 绑定
FILE:SELF_CHECK.md
# SELF_CHECK — study-revision-planner
## 1. 规范检查
- [x] Skill 为独立文件夹
- [x] 包含 `SKILL.md`
- [x] `SKILL.md` 使用 YAML frontmatter
- [x] frontmatter 含 `name`、`description`、`version`
- [x] 运行依赖声明在 `metadata.openclaw.requires`
- [x] 包含 `README.md`
- [x] 包含 `scripts/` 且至少 1 个脚本
- [x] 包含 `resources/` 且至少 1 个资源文件
- [x] 包含 `examples/example-prompt.md`
- [x] 包含 `tests/smoke-test.md`
## 2. 路径与引用检查
- [x] `SKILL.md` 中引用了 `scripts/revision_schedule.py`
- [x] `SKILL.md` 中引用了 `resources/study_plan_template.csv`
- [x] `README.md`、`SELF_CHECK.md`、`tests/smoke-test.md` 路径与当前目录一致
- [x] 打包后无需依赖绝对路径
## 3. 依赖与脚本检查
- [x] 仅声明 `python3` 作为运行依赖
- [x] 脚本为明文、可审计、本地执行
- [x] 脚本参数通过 CLI 显式传入
- [x] 无未声明环境变量依赖
- [x] 无未声明安装动作
## 4. 资源检查
- [x] 资源文件存在且为真实内容
- [x] 资源用途与 skill 目标一致
- [x] 资源已在说明中被引用
## 5. 安全检查
- [x] 未发现 `curl|bash`
- [x] 未发现远程下载后直接执行
- [x] 未发现 base64/混淆载荷执行
- [x] 未发现越权监控、盗号、破解、恶意抓取设计
- [x] 文件读写范围应由用户明确指定
## 6. 热门度与实用性复核
- 高频需求:是
- 低理解门槛:是
- 易传播:是
- 可二次定制:是
- 维护成本:低到中
## 7. 评分
- 规范完整度:9.5/10
- 可用性:9.0/10
- 安全性:9.5/10
- 可维护性:9.0/10
- 综合评分:9.3/10
## 8. 结论
该 skill 已补齐交付级目录结构,适合纳入统一 bundle 分发。后续若要继续增强,优先方向是增加更贴近真实场景的样例输入与回归测试数据。
FILE:scripts/revision_schedule.py
#!/usr/bin/env python3
import argparse, csv, json, math, datetime
def main():
ap = argparse.ArgumentParser()
ap.add_argument("topics_json", help="JSON list with topic,difficulty")
ap.add_argument("--start", required=True)
ap.add_argument("--exam", required=True)
ap.add_argument("--out", default="revision_schedule.csv")
args = ap.parse_args()
topics = json.load(open(args.topics_json, "r", encoding="utf-8"))
start = datetime.date.fromisoformat(args.start)
exam = datetime.date.fromisoformat(args.exam)
days = max((exam - start).days, 1)
per = max(days // max(len(topics),1), 1)
rows = []
cur = start
for topic in topics:
rows.append({"date": cur.isoformat(), "topic": topic.get("topic",""), "phase": "learn"})
cur += datetime.timedelta(days=per)
with open(args.out, "w", encoding="utf-8", newline="") as f:
w = csv.DictWriter(f, fieldnames=["date","topic","phase"])
w.writeheader()
w.writerows(rows)
print(f"Wrote {args.out}")
if __name__ == "__main__":
main()
FILE:examples/example-prompt.md
# Study Revision Planner 示例
## 示例触发词
- 复习计划
- exam revision planner
- 课程大纲变计划
- spaced repetition schedule
- 安排模拟测试
## 示例输入
- syllabus or topics
- exam date
- weekly availability
- difficulty by topic
- preferred study block length
## 示例请求
请使用 `study-revision-planner`,基于我提供的材料,按照 skill 中的工作流给出:
1. revision calendar
1. topic effort table
1. mock test schedule
1. today-next checklist
## 说明
- 先给预览稿或结构化草案
- 信息不足时,只补问最关键缺口
- 不要编造未提供的事实
FILE:tests/smoke-test.md
# Smoke test — study-revision-planner
## 目标
验证该 skill 具备最小可用交付结构,且本地辅助脚本可被解释器加载。
## 检查项
1. `SKILL.md` 存在,且 frontmatter 含 `name`、`description`、`version`
2. `README.md`、`SELF_CHECK.md`、`examples/example-prompt.md` 存在
3. `scripts/` 下至少有一个可执行脚本
4. `resources/` 下至少有一个真实资源文件
5. 运行 `python3 scripts/revision_schedule.py --help` 返回退出码 0
## 人工验证
- 用 `examples/example-prompt.md` 中的触发词在会话中调用 skill
- 检查输出是否覆盖以下内容:
- revision calendar
- topic effort table
- mock test schedule
- today-next checklist
- 检查是否优先给出预览、草案或确认步骤,而非直接做破坏性操作
## 通过标准
全部检查项通过,即视为 smoke test 通过。
FILE:resources/study_plan_template.csv
week,topic,phase,hours,target_output
1,,learn,,
1,,review,,
2,,practice,,
Turn rough workflows into standard operating procedures with roles, inputs, outputs, checkpoints, and exception handling.
---
name: sop-factory
description: Turn rough workflows into standard operating procedures with roles, inputs,
outputs, checkpoints, and exception handling.
version: 1.1.0
metadata:
openclaw:
requires:
bins:
- python3
emoji: 🧰
---
# SOP Factory
## Purpose
Turn rough workflows into standard operating procedures with roles, inputs, outputs, checkpoints, and exception handling.
## Trigger phrases
- 做 SOP
- turn this workflow into an SOP
- 流程文档化
- 标准作业流程
- 交接文档
## Ask for these inputs
- rough workflow
- roles
- tools used
- quality bar
- exception cases
## Workflow
1. Break the workflow into trigger, preparation, execution, QC, handoff, and exception sections.
2. Use the SOP template resource to ensure consistency.
3. Add checkpoints, examples, and escalation rules.
4. Return both a quick-start SOP and a formal version.
5. Highlight where screenshots or forms should be attached.
## Output contract
- SOP draft
- quick-start version
- roles matrix
- exceptions appendix
## Files in this skill
- Script: `{baseDir}/scripts/sop_outline_builder.py`
- Resource: `{baseDir}/resources/sop_template.md`
## Operating rules
- Be concrete and action-oriented.
- Prefer preview / draft / simulation mode before destructive changes.
- If information is missing, ask only for the minimum needed to proceed.
- Never fabricate metrics, legal certainty, receipts, credentials, or evidence.
- Keep assumptions explicit.
## Suggested prompts
- 做 SOP
- turn this workflow into an SOP
- 流程文档化
## Use of script and resources
Use the bundled script when it helps the user produce a structured file, manifest, CSV, or first-pass draft.
Use the resource file as the default schema, checklist, or preset when the user does not provide one.
## Boundaries
- This skill supports planning, structuring, and first-pass artifacts.
- It should not claim that files were modified, messages were sent, or legal/financial decisions were finalized unless the user actually performed those actions.
## Compatibility notes
- Directory-based AgentSkills/OpenClaw skill.
- Runtime dependency declared through `metadata.openclaw.requires`.
- Helper script is local and auditable: `scripts/sop_outline_builder.py`.
- Bundled resource is local and referenced by the instructions: `resources/sop_template.md`.
FILE:CHANGELOG.md
# Changelog
## 1.0.0
- Initial release.
FILE:README.md
# SOP Factory
Slug: `sop-factory`
## 功能定位
Turn rough workflows into standard operating procedures with roles, inputs, outputs, checkpoints, and exception handling.
## 适用场景
- 当用户需要:做 SOP
- 当用户手头已有原始材料,需要快速整理成可执行输出
- 当用户希望先预览方案、再决定是否落盘或批量处理
## 安装要求
- OpenClaw / AgentSkills 兼容目录结构
- `python3` 可执行文件在 PATH 中可用
- 无远程安装脚本、无隐藏联网依赖、无未声明凭据要求
## 目录结构
- `SKILL.md`:触发描述、工作流、输出契约
- `scripts/sop_outline_builder.py`:本地辅助脚本
- `resources/sop_template.md`:被 SKILL/README 引用的资源文件
- `examples/example-prompt.md`:触发与输入示例
- `tests/smoke-test.md`:最小冒烟测试
- `SELF_CHECK.md`:规范与安全自检
- `CHANGELOG.md`:变更记录
## 触发示例
- `做 SOP`
- `turn this workflow into an SOP`
- `流程文档化`
- `标准作业流程`
- `交接文档`
## 建议输入
- rough workflow
- roles
- tools used
- quality bar
- exception cases
## 预期输出
- SOP draft
- quick-start version
- roles matrix
- exceptions appendix
## 辅助脚本
脚本:`scripts/sop_outline_builder.py`
建议先运行帮助信息确认参数:
```bash
python3 scripts/sop_outline_builder.py --help
```
该脚本设计原则:
- 本地执行,便于审计与回滚
- 输入输出路径显式传入
- 不使用 `curl|bash`、远程直灌、base64 混淆执行
- 仅处理用户明确提供的文件或目录
## 输入输出示例
输入示例见:`examples/example-prompt.md`
输出示例建议至少包含:
- 结构化主结果
- 未决问题 / 风险项
- 可交付给他人的摘要或清单
## 常见问题
### 1. 这个 skill 会直接改我的文件吗?
默认不应直接进行破坏性批量操作;应优先生成预览、清单或草案,只有在用户明确要求时才建议执行进一步动作。
### 2. 这个 skill 需要联网吗?
当前目录内未声明联网依赖,也没有内置远程下载步骤。是否联网应由具体会话任务决定,而不是由 skill 包本身强制触发。
### 3. 资源文件的作用是什么?
`resources/sop_template.md` 为脚本或说明提供模板、规则、清单或模式参考,便于输出格式统一、可复用、可审计。
## 风险提示
- 对用户提供的数据、文本、截图或本地文件进行整理时,应先确认范围与目标。
- 涉及重命名、移动、合并、覆盖、生成正式对外内容时,应先给预览版本。
- 对不确定字段使用“待确认”标记,不应编造事实。
## 安全审计结论
- 依赖边界:仅声明 `python3`
- 凭据边界:未声明环境变量依赖
- 执行边界:本地脚本、本地资源、显式输入
- 高风险模式检查:未引入 `curl|bash`、远程管道执行、混淆载荷或私有 API 绑定
FILE:SELF_CHECK.md
# SELF_CHECK — sop-factory
## 1. 规范检查
- [x] Skill 为独立文件夹
- [x] 包含 `SKILL.md`
- [x] `SKILL.md` 使用 YAML frontmatter
- [x] frontmatter 含 `name`、`description`、`version`
- [x] 运行依赖声明在 `metadata.openclaw.requires`
- [x] 包含 `README.md`
- [x] 包含 `scripts/` 且至少 1 个脚本
- [x] 包含 `resources/` 且至少 1 个资源文件
- [x] 包含 `examples/example-prompt.md`
- [x] 包含 `tests/smoke-test.md`
## 2. 路径与引用检查
- [x] `SKILL.md` 中引用了 `scripts/sop_outline_builder.py`
- [x] `SKILL.md` 中引用了 `resources/sop_template.md`
- [x] `README.md`、`SELF_CHECK.md`、`tests/smoke-test.md` 路径与当前目录一致
- [x] 打包后无需依赖绝对路径
## 3. 依赖与脚本检查
- [x] 仅声明 `python3` 作为运行依赖
- [x] 脚本为明文、可审计、本地执行
- [x] 脚本参数通过 CLI 显式传入
- [x] 无未声明环境变量依赖
- [x] 无未声明安装动作
## 4. 资源检查
- [x] 资源文件存在且为真实内容
- [x] 资源用途与 skill 目标一致
- [x] 资源已在说明中被引用
## 5. 安全检查
- [x] 未发现 `curl|bash`
- [x] 未发现远程下载后直接执行
- [x] 未发现 base64/混淆载荷执行
- [x] 未发现越权监控、盗号、破解、恶意抓取设计
- [x] 文件读写范围应由用户明确指定
## 6. 热门度与实用性复核
- 高频需求:是
- 低理解门槛:是
- 易传播:是
- 可二次定制:是
- 维护成本:低到中
## 7. 评分
- 规范完整度:9.5/10
- 可用性:9.0/10
- 安全性:9.5/10
- 可维护性:9.0/10
- 综合评分:9.3/10
## 8. 结论
该 skill 已补齐交付级目录结构,适合纳入统一 bundle 分发。后续若要继续增强,优先方向是增加更贴近真实场景的样例输入与回归测试数据。
FILE:scripts/sop_outline_builder.py
#!/usr/bin/env python3
import argparse, json
def main():
ap = argparse.ArgumentParser()
ap.add_argument("--out", default="sop_outline.json")
args = ap.parse_args()
payload = {
"purpose": "",
"scope": "",
"roles": [],
"inputs": [],
"procedure_steps": [],
"quality_checkpoints": [],
"exceptions": [],
"handoff": []
}
json.dump(payload, open(args.out, "w", encoding="utf-8"), ensure_ascii=False, indent=2)
print(f"Wrote {args.out}")
if __name__ == "__main__":
main()
FILE:examples/example-prompt.md
# SOP Factory 示例
## 示例触发词
- 做 SOP
- turn this workflow into an SOP
- 流程文档化
- 标准作业流程
- 交接文档
## 示例输入
- rough workflow
- roles
- tools used
- quality bar
- exception cases
## 示例请求
请使用 `sop-factory`,基于我提供的材料,按照 skill 中的工作流给出:
1. SOP draft
1. quick-start version
1. roles matrix
1. exceptions appendix
## 说明
- 先给预览稿或结构化草案
- 信息不足时,只补问最关键缺口
- 不要编造未提供的事实
FILE:tests/smoke-test.md
# Smoke test — sop-factory
## 目标
验证该 skill 具备最小可用交付结构,且本地辅助脚本可被解释器加载。
## 检查项
1. `SKILL.md` 存在,且 frontmatter 含 `name`、`description`、`version`
2. `README.md`、`SELF_CHECK.md`、`examples/example-prompt.md` 存在
3. `scripts/` 下至少有一个可执行脚本
4. `resources/` 下至少有一个真实资源文件
5. 运行 `python3 scripts/sop_outline_builder.py --help` 返回退出码 0
## 人工验证
- 用 `examples/example-prompt.md` 中的触发词在会话中调用 skill
- 检查输出是否覆盖以下内容:
- SOP draft
- quick-start version
- roles matrix
- exceptions appendix
- 检查是否优先给出预览、草案或确认步骤,而非直接做破坏性操作
## 通过标准
全部检查项通过,即视为 smoke test 通过。
FILE:resources/sop_template.md
# SOP Template
## Purpose
## Scope
## Roles
## Inputs
## Step-by-step Procedure
## Quality Checkpoints
## Exceptions / Escalation
## Output / Handoff
Turn app screenshots into structured UX, copywriting, and conversion audits with issue severity and recommended fixes.
---
name: screenshot-ux-auditor
description: Turn app screenshots into structured UX, copywriting, and conversion
audits with issue severity and recommended fixes.
version: 1.1.0
metadata:
openclaw:
requires:
bins:
- python3
emoji: 🧰
---
# Screenshot UX Auditor
## Purpose
Turn app screenshots into structured UX, copywriting, and conversion audits with issue severity and recommended fixes.
## Trigger phrases
- 审查这个界面
- 截图做 UX 评审
- audit this UI screenshot
- 页面哪里有问题
- 帮我做可用性检查
## Ask for these inputs
- one or more screenshots
- product goal or funnel stage
- target user
- platform web/mobile/desktop
- tone or benchmark
## Workflow
1. Identify the screen type, primary task, and likely user goal.
2. Evaluate using the bundled heuristics checklist.
3. Cluster issues into clarity, hierarchy, trust, interaction, and accessibility.
4. Assign severity and provide fix-first recommendations.
5. Generate an issue log the user can hand to design or engineering.
## Output contract
- audit summary
- issue log CSV/Markdown
- fix priority list
- before/after prompt suggestions
## Files in this skill
- Script: `{baseDir}/scripts/generate_issue_log.py`
- Resource: `{baseDir}/resources/heuristics-checklist.md`
## Operating rules
- Be concrete and action-oriented.
- Prefer preview / draft / simulation mode before destructive changes.
- If information is missing, ask only for the minimum needed to proceed.
- Never fabricate metrics, legal certainty, receipts, credentials, or evidence.
- Keep assumptions explicit.
## Suggested prompts
- 审查这个界面
- 截图做 UX 评审
- audit this UI screenshot
## Use of script and resources
Use the bundled script when it helps the user produce a structured file, manifest, CSV, or first-pass draft.
Use the resource file as the default schema, checklist, or preset when the user does not provide one.
## Boundaries
- This skill supports planning, structuring, and first-pass artifacts.
- It should not claim that files were modified, messages were sent, or legal/financial decisions were finalized unless the user actually performed those actions.
## Compatibility notes
- Directory-based AgentSkills/OpenClaw skill.
- Runtime dependency declared through `metadata.openclaw.requires`.
- Helper script is local and auditable: `scripts/generate_issue_log.py`.
- Bundled resource is local and referenced by the instructions: `resources/heuristics-checklist.md`.
FILE:CHANGELOG.md
# Changelog
## 1.0.0
- Initial release.
FILE:README.md
# Screenshot UX Auditor
Slug: `screenshot-ux-auditor`
## 功能定位
Turn app screenshots into structured UX, copywriting, and conversion audits with issue severity and recommended fixes.
## 适用场景
- 当用户需要:审查这个界面
- 当用户手头已有原始材料,需要快速整理成可执行输出
- 当用户希望先预览方案、再决定是否落盘或批量处理
## 安装要求
- OpenClaw / AgentSkills 兼容目录结构
- `python3` 可执行文件在 PATH 中可用
- 无远程安装脚本、无隐藏联网依赖、无未声明凭据要求
## 目录结构
- `SKILL.md`:触发描述、工作流、输出契约
- `scripts/generate_issue_log.py`:本地辅助脚本
- `resources/heuristics-checklist.md`:被 SKILL/README 引用的资源文件
- `examples/example-prompt.md`:触发与输入示例
- `tests/smoke-test.md`:最小冒烟测试
- `SELF_CHECK.md`:规范与安全自检
- `CHANGELOG.md`:变更记录
## 触发示例
- `审查这个界面`
- `截图做 UX 评审`
- `audit this UI screenshot`
- `页面哪里有问题`
- `帮我做可用性检查`
## 建议输入
- one or more screenshots
- product goal or funnel stage
- target user
- platform web/mobile/desktop
- tone or benchmark
## 预期输出
- audit summary
- issue log CSV/Markdown
- fix priority list
- before/after prompt suggestions
## 辅助脚本
脚本:`scripts/generate_issue_log.py`
建议先运行帮助信息确认参数:
```bash
python3 scripts/generate_issue_log.py --help
```
该脚本设计原则:
- 本地执行,便于审计与回滚
- 输入输出路径显式传入
- 不使用 `curl|bash`、远程直灌、base64 混淆执行
- 仅处理用户明确提供的文件或目录
## 输入输出示例
输入示例见:`examples/example-prompt.md`
输出示例建议至少包含:
- 结构化主结果
- 未决问题 / 风险项
- 可交付给他人的摘要或清单
## 常见问题
### 1. 这个 skill 会直接改我的文件吗?
默认不应直接进行破坏性批量操作;应优先生成预览、清单或草案,只有在用户明确要求时才建议执行进一步动作。
### 2. 这个 skill 需要联网吗?
当前目录内未声明联网依赖,也没有内置远程下载步骤。是否联网应由具体会话任务决定,而不是由 skill 包本身强制触发。
### 3. 资源文件的作用是什么?
`resources/heuristics-checklist.md` 为脚本或说明提供模板、规则、清单或模式参考,便于输出格式统一、可复用、可审计。
## 风险提示
- 对用户提供的数据、文本、截图或本地文件进行整理时,应先确认范围与目标。
- 涉及重命名、移动、合并、覆盖、生成正式对外内容时,应先给预览版本。
- 对不确定字段使用“待确认”标记,不应编造事实。
## 安全审计结论
- 依赖边界:仅声明 `python3`
- 凭据边界:未声明环境变量依赖
- 执行边界:本地脚本、本地资源、显式输入
- 高风险模式检查:未引入 `curl|bash`、远程管道执行、混淆载荷或私有 API 绑定
FILE:SELF_CHECK.md
# SELF_CHECK — screenshot-ux-auditor
## 1. 规范检查
- [x] Skill 为独立文件夹
- [x] 包含 `SKILL.md`
- [x] `SKILL.md` 使用 YAML frontmatter
- [x] frontmatter 含 `name`、`description`、`version`
- [x] 运行依赖声明在 `metadata.openclaw.requires`
- [x] 包含 `README.md`
- [x] 包含 `scripts/` 且至少 1 个脚本
- [x] 包含 `resources/` 且至少 1 个资源文件
- [x] 包含 `examples/example-prompt.md`
- [x] 包含 `tests/smoke-test.md`
## 2. 路径与引用检查
- [x] `SKILL.md` 中引用了 `scripts/generate_issue_log.py`
- [x] `SKILL.md` 中引用了 `resources/heuristics-checklist.md`
- [x] `README.md`、`SELF_CHECK.md`、`tests/smoke-test.md` 路径与当前目录一致
- [x] 打包后无需依赖绝对路径
## 3. 依赖与脚本检查
- [x] 仅声明 `python3` 作为运行依赖
- [x] 脚本为明文、可审计、本地执行
- [x] 脚本参数通过 CLI 显式传入
- [x] 无未声明环境变量依赖
- [x] 无未声明安装动作
## 4. 资源检查
- [x] 资源文件存在且为真实内容
- [x] 资源用途与 skill 目标一致
- [x] 资源已在说明中被引用
## 5. 安全检查
- [x] 未发现 `curl|bash`
- [x] 未发现远程下载后直接执行
- [x] 未发现 base64/混淆载荷执行
- [x] 未发现越权监控、盗号、破解、恶意抓取设计
- [x] 文件读写范围应由用户明确指定
## 6. 热门度与实用性复核
- 高频需求:是
- 低理解门槛:是
- 易传播:是
- 可二次定制:是
- 维护成本:低到中
## 7. 评分
- 规范完整度:9.5/10
- 可用性:9.0/10
- 安全性:9.5/10
- 可维护性:9.0/10
- 综合评分:9.3/10
## 8. 结论
该 skill 已补齐交付级目录结构,适合纳入统一 bundle 分发。后续若要继续增强,优先方向是增加更贴近真实场景的样例输入与回归测试数据。
FILE:scripts/generate_issue_log.py
#!/usr/bin/env python3
"""Turn a JSON list of issues into a compact CSV/Markdown issue log."""
import argparse, json, csv, sys
from pathlib import Path
def main():
ap = argparse.ArgumentParser()
ap.add_argument("issues_json", help="JSON file with [{title,category,severity,fix}]")
ap.add_argument("--csv-out", default="issue_log.csv")
args = ap.parse_args()
issues = json.load(open(args.issues_json, "r", encoding="utf-8"))
with open(args.csv_out, "w", encoding="utf-8", newline="") as f:
w = csv.DictWriter(f, fieldnames=["title","category","severity","fix"])
w.writeheader()
for issue in issues:
w.writerow({k: issue.get(k, "") for k in w.fieldnames})
print(f"Wrote {len(issues)} issues to {args.csv_out}")
if __name__ == "__main__":
main()
FILE:examples/example-prompt.md
# Screenshot UX Auditor 示例
## 示例触发词
- 审查这个界面
- 截图做 UX 评审
- audit this UI screenshot
- 页面哪里有问题
- 帮我做可用性检查
## 示例输入
- one or more screenshots
- product goal or funnel stage
- target user
- platform web/mobile/desktop
- tone or benchmark
## 示例请求
请使用 `screenshot-ux-auditor`,基于我提供的材料,按照 skill 中的工作流给出:
1. audit summary
1. issue log CSV/Markdown
1. fix priority list
1. before/after prompt suggestions
## 说明
- 先给预览稿或结构化草案
- 信息不足时,只补问最关键缺口
- 不要编造未提供的事实
FILE:tests/smoke-test.md
# Smoke test — screenshot-ux-auditor
## 目标
验证该 skill 具备最小可用交付结构,且本地辅助脚本可被解释器加载。
## 检查项
1. `SKILL.md` 存在,且 frontmatter 含 `name`、`description`、`version`
2. `README.md`、`SELF_CHECK.md`、`examples/example-prompt.md` 存在
3. `scripts/` 下至少有一个可执行脚本
4. `resources/` 下至少有一个真实资源文件
5. 运行 `python3 scripts/generate_issue_log.py --help` 返回退出码 0
## 人工验证
- 用 `examples/example-prompt.md` 中的触发词在会话中调用 skill
- 检查输出是否覆盖以下内容:
- audit summary
- issue log CSV/Markdown
- fix priority list
- before/after prompt suggestions
- 检查是否优先给出预览、草案或确认步骤,而非直接做破坏性操作
## 通过标准
全部检查项通过,即视为 smoke test 通过。
FILE:resources/heuristics-checklist.md
# UX Heuristics Checklist
1. Clear primary action
2. Visual hierarchy and scanning order
3. Label clarity and empty-state guidance
4. Error prevention and recovery
5. Trust and credibility signals
6. Accessibility: contrast, tap targets, alt text, focus
7. Mobile ergonomics and reachability
8. Conversion friction and proof elements
9. Consistency with design system
10. Internationalization / localization risks
Tailor resumes and project bullets to a target role, quantify gaps, and prepare an interview-ready evidence map.
---
name: resume-job-match-lab
description: Tailor resumes and project bullets to a target role, quantify gaps, and
prepare an interview-ready evidence map.
version: 1.1.0
metadata:
openclaw:
requires:
bins:
- python3
emoji: 🧰
---
# Resume Job Match Lab
## Purpose
Tailor resumes and project bullets to a target role, quantify gaps, and prepare an interview-ready evidence map.
## Trigger phrases
- 简历匹配岗位
- tailor my resume
- ATS 优化
- job match analysis
- 面试证据图
## Ask for these inputs
- resume text
- job description
- target seniority
- region/industry
- portfolio or projects if any
## Workflow
1. Extract must-have and nice-to-have requirements from the job description.
2. Score resume coverage against the keyword template.
3. Rewrite bullets to emphasize outcome, scope, and tools without fabricating claims.
4. Generate a gap analysis and interview evidence map.
5. Return both a conservative ATS version and a human-friendly version.
## Output contract
- match scorecard
- rewritten bullets
- gap analysis
- interview evidence map
## Files in this skill
- Script: `{baseDir}/scripts/resume_match.py`
- Resource: `{baseDir}/resources/ats_keywords_template.csv`
## Operating rules
- Be concrete and action-oriented.
- Prefer preview / draft / simulation mode before destructive changes.
- If information is missing, ask only for the minimum needed to proceed.
- Never fabricate metrics, legal certainty, receipts, credentials, or evidence.
- Keep assumptions explicit.
## Suggested prompts
- 简历匹配岗位
- tailor my resume
- ATS 优化
## Use of script and resources
Use the bundled script when it helps the user produce a structured file, manifest, CSV, or first-pass draft.
Use the resource file as the default schema, checklist, or preset when the user does not provide one.
## Boundaries
- This skill supports planning, structuring, and first-pass artifacts.
- It should not claim that files were modified, messages were sent, or legal/financial decisions were finalized unless the user actually performed those actions.
## Compatibility notes
- Directory-based AgentSkills/OpenClaw skill.
- Runtime dependency declared through `metadata.openclaw.requires`.
- Helper script is local and auditable: `scripts/resume_match.py`.
- Bundled resource is local and referenced by the instructions: `resources/ats_keywords_template.csv`.
FILE:CHANGELOG.md
# Changelog
## 1.0.0
- Initial release.
FILE:README.md
# Resume Job Match Lab
Slug: `resume-job-match-lab`
## 功能定位
Tailor resumes and project bullets to a target role, quantify gaps, and prepare an interview-ready evidence map.
## 适用场景
- 当用户需要:简历匹配岗位
- 当用户手头已有原始材料,需要快速整理成可执行输出
- 当用户希望先预览方案、再决定是否落盘或批量处理
## 安装要求
- OpenClaw / AgentSkills 兼容目录结构
- `python3` 可执行文件在 PATH 中可用
- 无远程安装脚本、无隐藏联网依赖、无未声明凭据要求
## 目录结构
- `SKILL.md`:触发描述、工作流、输出契约
- `scripts/resume_match.py`:本地辅助脚本
- `resources/ats_keywords_template.csv`:被 SKILL/README 引用的资源文件
- `examples/example-prompt.md`:触发与输入示例
- `tests/smoke-test.md`:最小冒烟测试
- `SELF_CHECK.md`:规范与安全自检
- `CHANGELOG.md`:变更记录
## 触发示例
- `简历匹配岗位`
- `tailor my resume`
- `ATS 优化`
- `job match analysis`
- `面试证据图`
## 建议输入
- resume text
- job description
- target seniority
- region/industry
- portfolio or projects if any
## 预期输出
- match scorecard
- rewritten bullets
- gap analysis
- interview evidence map
## 辅助脚本
脚本:`scripts/resume_match.py`
建议先运行帮助信息确认参数:
```bash
python3 scripts/resume_match.py --help
```
该脚本设计原则:
- 本地执行,便于审计与回滚
- 输入输出路径显式传入
- 不使用 `curl|bash`、远程直灌、base64 混淆执行
- 仅处理用户明确提供的文件或目录
## 输入输出示例
输入示例见:`examples/example-prompt.md`
输出示例建议至少包含:
- 结构化主结果
- 未决问题 / 风险项
- 可交付给他人的摘要或清单
## 常见问题
### 1. 这个 skill 会直接改我的文件吗?
默认不应直接进行破坏性批量操作;应优先生成预览、清单或草案,只有在用户明确要求时才建议执行进一步动作。
### 2. 这个 skill 需要联网吗?
当前目录内未声明联网依赖,也没有内置远程下载步骤。是否联网应由具体会话任务决定,而不是由 skill 包本身强制触发。
### 3. 资源文件的作用是什么?
`resources/ats_keywords_template.csv` 为脚本或说明提供模板、规则、清单或模式参考,便于输出格式统一、可复用、可审计。
## 风险提示
- 对用户提供的数据、文本、截图或本地文件进行整理时,应先确认范围与目标。
- 涉及重命名、移动、合并、覆盖、生成正式对外内容时,应先给预览版本。
- 对不确定字段使用“待确认”标记,不应编造事实。
## 安全审计结论
- 依赖边界:仅声明 `python3`
- 凭据边界:未声明环境变量依赖
- 执行边界:本地脚本、本地资源、显式输入
- 高风险模式检查:未引入 `curl|bash`、远程管道执行、混淆载荷或私有 API 绑定
FILE:SELF_CHECK.md
# SELF_CHECK — resume-job-match-lab
## 1. 规范检查
- [x] Skill 为独立文件夹
- [x] 包含 `SKILL.md`
- [x] `SKILL.md` 使用 YAML frontmatter
- [x] frontmatter 含 `name`、`description`、`version`
- [x] 运行依赖声明在 `metadata.openclaw.requires`
- [x] 包含 `README.md`
- [x] 包含 `scripts/` 且至少 1 个脚本
- [x] 包含 `resources/` 且至少 1 个资源文件
- [x] 包含 `examples/example-prompt.md`
- [x] 包含 `tests/smoke-test.md`
## 2. 路径与引用检查
- [x] `SKILL.md` 中引用了 `scripts/resume_match.py`
- [x] `SKILL.md` 中引用了 `resources/ats_keywords_template.csv`
- [x] `README.md`、`SELF_CHECK.md`、`tests/smoke-test.md` 路径与当前目录一致
- [x] 打包后无需依赖绝对路径
## 3. 依赖与脚本检查
- [x] 仅声明 `python3` 作为运行依赖
- [x] 脚本为明文、可审计、本地执行
- [x] 脚本参数通过 CLI 显式传入
- [x] 无未声明环境变量依赖
- [x] 无未声明安装动作
## 4. 资源检查
- [x] 资源文件存在且为真实内容
- [x] 资源用途与 skill 目标一致
- [x] 资源已在说明中被引用
## 5. 安全检查
- [x] 未发现 `curl|bash`
- [x] 未发现远程下载后直接执行
- [x] 未发现 base64/混淆载荷执行
- [x] 未发现越权监控、盗号、破解、恶意抓取设计
- [x] 文件读写范围应由用户明确指定
## 6. 热门度与实用性复核
- 高频需求:是
- 低理解门槛:是
- 易传播:是
- 可二次定制:是
- 维护成本:低到中
## 7. 评分
- 规范完整度:9.5/10
- 可用性:9.0/10
- 安全性:9.5/10
- 可维护性:9.0/10
- 综合评分:9.3/10
## 8. 结论
该 skill 已补齐交付级目录结构,适合纳入统一 bundle 分发。后续若要继续增强,优先方向是增加更贴近真实场景的样例输入与回归测试数据。
FILE:scripts/resume_match.py
#!/usr/bin/env python3
import argparse, csv, re, json
from collections import Counter
def words(text):
return re.findall(r"[A-Za-z][A-Za-z0-9+.#-]{1,}", text.lower())
def main():
ap = argparse.ArgumentParser()
ap.add_argument("resume_txt")
ap.add_argument("job_txt")
ap.add_argument("--out", default="resume_match.json")
args = ap.parse_args()
resume = open(args.resume_txt, "r", encoding="utf-8").read()
job = open(args.job_txt, "r", encoding="utf-8").read()
rw, jw = set(words(resume)), Counter(words(job))
top = [w for w, c in jw.most_common(40) if len(w) > 2]
missing = [w for w in top if w not in rw][:20]
score = round(100 * (len(top) - len(missing)) / max(len(top), 1), 1)
json.dump({"score": score, "missing_keywords": missing, "top_keywords": top}, open(args.out, "w", encoding="utf-8"), ensure_ascii=False, indent=2)
print(f"Wrote {args.out}")
if __name__ == "__main__":
main()
FILE:examples/example-prompt.md
# Resume Job Match Lab 示例
## 示例触发词
- 简历匹配岗位
- tailor my resume
- ATS 优化
- job match analysis
- 面试证据图
## 示例输入
- resume text
- job description
- target seniority
- region/industry
- portfolio or projects if any
## 示例请求
请使用 `resume-job-match-lab`,基于我提供的材料,按照 skill 中的工作流给出:
1. match scorecard
1. rewritten bullets
1. gap analysis
1. interview evidence map
## 说明
- 先给预览稿或结构化草案
- 信息不足时,只补问最关键缺口
- 不要编造未提供的事实
FILE:tests/smoke-test.md
# Smoke test — resume-job-match-lab
## 目标
验证该 skill 具备最小可用交付结构,且本地辅助脚本可被解释器加载。
## 检查项
1. `SKILL.md` 存在,且 frontmatter 含 `name`、`description`、`version`
2. `README.md`、`SELF_CHECK.md`、`examples/example-prompt.md` 存在
3. `scripts/` 下至少有一个可执行脚本
4. `resources/` 下至少有一个真实资源文件
5. 运行 `python3 scripts/resume_match.py --help` 返回退出码 0
## 人工验证
- 用 `examples/example-prompt.md` 中的触发词在会话中调用 skill
- 检查输出是否覆盖以下内容:
- match scorecard
- rewritten bullets
- gap analysis
- interview evidence map
- 检查是否优先给出预览、草案或确认步骤,而非直接做破坏性操作
## 通过标准
全部检查项通过,即视为 smoke test 通过。
FILE:resources/ats_keywords_template.csv
bucket,example_keywords
leadership,led managed mentored drove owned
analytics,sql python excel dashboard forecast
product,roadmap launch experiment hypothesis prd
engineering,api docker testing ci cd refactor
design,wireframe figma prototype ux ui research
Build literature matrices from papers, notes, and abstracts to compare methods, data, findings, and research gaps.
---
name: research-matrix-builder
description: Build literature matrices from papers, notes, and abstracts to compare
methods, data, findings, and research gaps.
version: 1.1.0
metadata:
openclaw:
requires:
bins:
- python3
emoji: 🧰
---
# Research Matrix Builder
## Purpose
Build literature matrices from papers, notes, and abstracts to compare methods, data, findings, and research gaps.
## Trigger phrases
- 文献矩阵
- build a literature matrix
- 整理论文综述
- research gap table
- 做研究对比表
## Ask for these inputs
- paper list or notes
- research question
- matrix dimensions
- citation style if needed
## Workflow
1. Normalize each source into the bundled matrix schema.
2. Extract problem, method, data, metric, result, limitation, and gap.
3. Cluster similar methods and contradictory findings.
4. Generate a matrix CSV and a narrative synthesis outline.
5. Keep missing fields explicit and cite where possible.
## Output contract
- literature matrix CSV
- thematic clusters
- gap summary
- review outline
## Files in this skill
- Script: `{baseDir}/scripts/build_matrix.py`
- Resource: `{baseDir}/resources/matrix_schema.csv`
## Operating rules
- Be concrete and action-oriented.
- Prefer preview / draft / simulation mode before destructive changes.
- If information is missing, ask only for the minimum needed to proceed.
- Never fabricate metrics, legal certainty, receipts, credentials, or evidence.
- Keep assumptions explicit.
## Suggested prompts
- 文献矩阵
- build a literature matrix
- 整理论文综述
## Use of script and resources
Use the bundled script when it helps the user produce a structured file, manifest, CSV, or first-pass draft.
Use the resource file as the default schema, checklist, or preset when the user does not provide one.
## Boundaries
- This skill supports planning, structuring, and first-pass artifacts.
- It should not claim that files were modified, messages were sent, or legal/financial decisions were finalized unless the user actually performed those actions.
## Compatibility notes
- Directory-based AgentSkills/OpenClaw skill.
- Runtime dependency declared through `metadata.openclaw.requires`.
- Helper script is local and auditable: `scripts/build_matrix.py`.
- Bundled resource is local and referenced by the instructions: `resources/matrix_schema.csv`.
FILE:CHANGELOG.md
# Changelog
## 1.0.0
- Initial release.
FILE:README.md
# Research Matrix Builder
Slug: `research-matrix-builder`
## 功能定位
Build literature matrices from papers, notes, and abstracts to compare methods, data, findings, and research gaps.
## 适用场景
- 当用户需要:文献矩阵
- 当用户手头已有原始材料,需要快速整理成可执行输出
- 当用户希望先预览方案、再决定是否落盘或批量处理
## 安装要求
- OpenClaw / AgentSkills 兼容目录结构
- `python3` 可执行文件在 PATH 中可用
- 无远程安装脚本、无隐藏联网依赖、无未声明凭据要求
## 目录结构
- `SKILL.md`:触发描述、工作流、输出契约
- `scripts/build_matrix.py`:本地辅助脚本
- `resources/matrix_schema.csv`:被 SKILL/README 引用的资源文件
- `examples/example-prompt.md`:触发与输入示例
- `tests/smoke-test.md`:最小冒烟测试
- `SELF_CHECK.md`:规范与安全自检
- `CHANGELOG.md`:变更记录
## 触发示例
- `文献矩阵`
- `build a literature matrix`
- `整理论文综述`
- `research gap table`
- `做研究对比表`
## 建议输入
- paper list or notes
- research question
- matrix dimensions
- citation style if needed
## 预期输出
- literature matrix CSV
- thematic clusters
- gap summary
- review outline
## 辅助脚本
脚本:`scripts/build_matrix.py`
建议先运行帮助信息确认参数:
```bash
python3 scripts/build_matrix.py --help
```
该脚本设计原则:
- 本地执行,便于审计与回滚
- 输入输出路径显式传入
- 不使用 `curl|bash`、远程直灌、base64 混淆执行
- 仅处理用户明确提供的文件或目录
## 输入输出示例
输入示例见:`examples/example-prompt.md`
输出示例建议至少包含:
- 结构化主结果
- 未决问题 / 风险项
- 可交付给他人的摘要或清单
## 常见问题
### 1. 这个 skill 会直接改我的文件吗?
默认不应直接进行破坏性批量操作;应优先生成预览、清单或草案,只有在用户明确要求时才建议执行进一步动作。
### 2. 这个 skill 需要联网吗?
当前目录内未声明联网依赖,也没有内置远程下载步骤。是否联网应由具体会话任务决定,而不是由 skill 包本身强制触发。
### 3. 资源文件的作用是什么?
`resources/matrix_schema.csv` 为脚本或说明提供模板、规则、清单或模式参考,便于输出格式统一、可复用、可审计。
## 风险提示
- 对用户提供的数据、文本、截图或本地文件进行整理时,应先确认范围与目标。
- 涉及重命名、移动、合并、覆盖、生成正式对外内容时,应先给预览版本。
- 对不确定字段使用“待确认”标记,不应编造事实。
## 安全审计结论
- 依赖边界:仅声明 `python3`
- 凭据边界:未声明环境变量依赖
- 执行边界:本地脚本、本地资源、显式输入
- 高风险模式检查:未引入 `curl|bash`、远程管道执行、混淆载荷或私有 API 绑定
FILE:SELF_CHECK.md
# SELF_CHECK — research-matrix-builder
## 1. 规范检查
- [x] Skill 为独立文件夹
- [x] 包含 `SKILL.md`
- [x] `SKILL.md` 使用 YAML frontmatter
- [x] frontmatter 含 `name`、`description`、`version`
- [x] 运行依赖声明在 `metadata.openclaw.requires`
- [x] 包含 `README.md`
- [x] 包含 `scripts/` 且至少 1 个脚本
- [x] 包含 `resources/` 且至少 1 个资源文件
- [x] 包含 `examples/example-prompt.md`
- [x] 包含 `tests/smoke-test.md`
## 2. 路径与引用检查
- [x] `SKILL.md` 中引用了 `scripts/build_matrix.py`
- [x] `SKILL.md` 中引用了 `resources/matrix_schema.csv`
- [x] `README.md`、`SELF_CHECK.md`、`tests/smoke-test.md` 路径与当前目录一致
- [x] 打包后无需依赖绝对路径
## 3. 依赖与脚本检查
- [x] 仅声明 `python3` 作为运行依赖
- [x] 脚本为明文、可审计、本地执行
- [x] 脚本参数通过 CLI 显式传入
- [x] 无未声明环境变量依赖
- [x] 无未声明安装动作
## 4. 资源检查
- [x] 资源文件存在且为真实内容
- [x] 资源用途与 skill 目标一致
- [x] 资源已在说明中被引用
## 5. 安全检查
- [x] 未发现 `curl|bash`
- [x] 未发现远程下载后直接执行
- [x] 未发现 base64/混淆载荷执行
- [x] 未发现越权监控、盗号、破解、恶意抓取设计
- [x] 文件读写范围应由用户明确指定
## 6. 热门度与实用性复核
- 高频需求:是
- 低理解门槛:是
- 易传播:是
- 可二次定制:是
- 维护成本:低到中
## 7. 评分
- 规范完整度:9.5/10
- 可用性:9.0/10
- 安全性:9.5/10
- 可维护性:9.0/10
- 综合评分:9.3/10
## 8. 结论
该 skill 已补齐交付级目录结构,适合纳入统一 bundle 分发。后续若要继续增强,优先方向是增加更贴近真实场景的样例输入与回归测试数据。
FILE:scripts/build_matrix.py
#!/usr/bin/env python3
import argparse, csv, json
def main():
ap = argparse.ArgumentParser()
ap.add_argument("records_json", help="JSON list of paper records")
ap.add_argument("--out", default="literature_matrix.csv")
args = ap.parse_args()
rows = json.load(open(args.records_json, "r", encoding="utf-8"))
fields = ["citation","problem","method","data","metric","key_result","limitation","gap"]
with open(args.out, "w", encoding="utf-8", newline="") as f:
w = csv.DictWriter(f, fieldnames=fields)
w.writeheader()
for row in rows:
w.writerow({k: row.get(k, "") for k in fields})
print(f"Wrote {args.out}")
if __name__ == "__main__":
main()
FILE:examples/example-prompt.md
# Research Matrix Builder 示例
## 示例触发词
- 文献矩阵
- build a literature matrix
- 整理论文综述
- research gap table
- 做研究对比表
## 示例输入
- paper list or notes
- research question
- matrix dimensions
- citation style if needed
## 示例请求
请使用 `research-matrix-builder`,基于我提供的材料,按照 skill 中的工作流给出:
1. literature matrix CSV
1. thematic clusters
1. gap summary
1. review outline
## 说明
- 先给预览稿或结构化草案
- 信息不足时,只补问最关键缺口
- 不要编造未提供的事实
FILE:tests/smoke-test.md
# Smoke test — research-matrix-builder
## 目标
验证该 skill 具备最小可用交付结构,且本地辅助脚本可被解释器加载。
## 检查项
1. `SKILL.md` 存在,且 frontmatter 含 `name`、`description`、`version`
2. `README.md`、`SELF_CHECK.md`、`examples/example-prompt.md` 存在
3. `scripts/` 下至少有一个可执行脚本
4. `resources/` 下至少有一个真实资源文件
5. 运行 `python3 scripts/build_matrix.py --help` 返回退出码 0
## 人工验证
- 用 `examples/example-prompt.md` 中的触发词在会话中调用 skill
- 检查输出是否覆盖以下内容:
- literature matrix CSV
- thematic clusters
- gap summary
- review outline
- 检查是否优先给出预览、草案或确认步骤,而非直接做破坏性操作
## 通过标准
全部检查项通过,即视为 smoke test 通过。
FILE:resources/matrix_schema.csv
field,description
citation,Short citation key
problem,Research problem
method,Method or model
data,Dataset or corpus
metric,Evaluation metric
key_result,Main finding
limitation,Known limitation
gap,Unaddressed opportunity
Normalize receipts, reimbursement slips, and invoices into a clean expense ledger with category mapping and anomaly flags.
---
name: receipt-expense-workbench
description: Normalize receipts, reimbursement slips, and invoices into a clean expense
ledger with category mapping and anomaly flags.
version: 1.1.0
metadata:
openclaw:
requires:
bins:
- python3
emoji: 🧰
---
# Receipt Expense Workbench
## Purpose
Normalize receipts, reimbursement slips, and invoices into a clean expense ledger with category mapping and anomaly flags.
## Trigger phrases
- 整理发票
- 报销单汇总
- receipt to expense sheet
- 做费用台账
- expense ledger
## Ask for these inputs
- receipt text or OCR output
- currency
- reimbursement policy if available
- project code
- merchant names
## Workflow
1. Extract vendor, date, amount, tax, and payment method.
2. Map each line item to the bundled category list.
3. Flag duplicates, suspicious totals, missing tax IDs, and missing attachments.
4. Generate a ledger CSV and a reimbursement-ready summary.
5. Keep uncertain fields clearly marked instead of guessing.
## Output contract
- expense ledger CSV
- category summary
- anomaly report
- reimbursement packet checklist
## Files in this skill
- Script: `{baseDir}/scripts/expense_ledger.py`
- Resource: `{baseDir}/resources/expense_categories.csv`
## Operating rules
- Be concrete and action-oriented.
- Prefer preview / draft / simulation mode before destructive changes.
- If information is missing, ask only for the minimum needed to proceed.
- Never fabricate metrics, legal certainty, receipts, credentials, or evidence.
- Keep assumptions explicit.
## Suggested prompts
- 整理发票
- 报销单汇总
- receipt to expense sheet
## Use of script and resources
Use the bundled script when it helps the user produce a structured file, manifest, CSV, or first-pass draft.
Use the resource file as the default schema, checklist, or preset when the user does not provide one.
## Boundaries
- This skill supports planning, structuring, and first-pass artifacts.
- It should not claim that files were modified, messages were sent, or legal/financial decisions were finalized unless the user actually performed those actions.
## Compatibility notes
- Directory-based AgentSkills/OpenClaw skill.
- Runtime dependency declared through `metadata.openclaw.requires`.
- Helper script is local and auditable: `scripts/expense_ledger.py`.
- Bundled resource is local and referenced by the instructions: `resources/expense_categories.csv`.
FILE:CHANGELOG.md
# Changelog
## 1.0.0
- Initial release.
FILE:README.md
# Receipt Expense Workbench
Slug: `receipt-expense-workbench`
## 功能定位
Normalize receipts, reimbursement slips, and invoices into a clean expense ledger with category mapping and anomaly flags.
## 适用场景
- 当用户需要:整理发票
- 当用户手头已有原始材料,需要快速整理成可执行输出
- 当用户希望先预览方案、再决定是否落盘或批量处理
## 安装要求
- OpenClaw / AgentSkills 兼容目录结构
- `python3` 可执行文件在 PATH 中可用
- 无远程安装脚本、无隐藏联网依赖、无未声明凭据要求
## 目录结构
- `SKILL.md`:触发描述、工作流、输出契约
- `scripts/expense_ledger.py`:本地辅助脚本
- `resources/expense_categories.csv`:被 SKILL/README 引用的资源文件
- `examples/example-prompt.md`:触发与输入示例
- `tests/smoke-test.md`:最小冒烟测试
- `SELF_CHECK.md`:规范与安全自检
- `CHANGELOG.md`:变更记录
## 触发示例
- `整理发票`
- `报销单汇总`
- `receipt to expense sheet`
- `做费用台账`
- `expense ledger`
## 建议输入
- receipt text or OCR output
- currency
- reimbursement policy if available
- project code
- merchant names
## 预期输出
- expense ledger CSV
- category summary
- anomaly report
- reimbursement packet checklist
## 辅助脚本
脚本:`scripts/expense_ledger.py`
建议先运行帮助信息确认参数:
```bash
python3 scripts/expense_ledger.py --help
```
该脚本设计原则:
- 本地执行,便于审计与回滚
- 输入输出路径显式传入
- 不使用 `curl|bash`、远程直灌、base64 混淆执行
- 仅处理用户明确提供的文件或目录
## 输入输出示例
输入示例见:`examples/example-prompt.md`
输出示例建议至少包含:
- 结构化主结果
- 未决问题 / 风险项
- 可交付给他人的摘要或清单
## 常见问题
### 1. 这个 skill 会直接改我的文件吗?
默认不应直接进行破坏性批量操作;应优先生成预览、清单或草案,只有在用户明确要求时才建议执行进一步动作。
### 2. 这个 skill 需要联网吗?
当前目录内未声明联网依赖,也没有内置远程下载步骤。是否联网应由具体会话任务决定,而不是由 skill 包本身强制触发。
### 3. 资源文件的作用是什么?
`resources/expense_categories.csv` 为脚本或说明提供模板、规则、清单或模式参考,便于输出格式统一、可复用、可审计。
## 风险提示
- 对用户提供的数据、文本、截图或本地文件进行整理时,应先确认范围与目标。
- 涉及重命名、移动、合并、覆盖、生成正式对外内容时,应先给预览版本。
- 对不确定字段使用“待确认”标记,不应编造事实。
## 安全审计结论
- 依赖边界:仅声明 `python3`
- 凭据边界:未声明环境变量依赖
- 执行边界:本地脚本、本地资源、显式输入
- 高风险模式检查:未引入 `curl|bash`、远程管道执行、混淆载荷或私有 API 绑定
FILE:SELF_CHECK.md
# SELF_CHECK — receipt-expense-workbench
## 1. 规范检查
- [x] Skill 为独立文件夹
- [x] 包含 `SKILL.md`
- [x] `SKILL.md` 使用 YAML frontmatter
- [x] frontmatter 含 `name`、`description`、`version`
- [x] 运行依赖声明在 `metadata.openclaw.requires`
- [x] 包含 `README.md`
- [x] 包含 `scripts/` 且至少 1 个脚本
- [x] 包含 `resources/` 且至少 1 个资源文件
- [x] 包含 `examples/example-prompt.md`
- [x] 包含 `tests/smoke-test.md`
## 2. 路径与引用检查
- [x] `SKILL.md` 中引用了 `scripts/expense_ledger.py`
- [x] `SKILL.md` 中引用了 `resources/expense_categories.csv`
- [x] `README.md`、`SELF_CHECK.md`、`tests/smoke-test.md` 路径与当前目录一致
- [x] 打包后无需依赖绝对路径
## 3. 依赖与脚本检查
- [x] 仅声明 `python3` 作为运行依赖
- [x] 脚本为明文、可审计、本地执行
- [x] 脚本参数通过 CLI 显式传入
- [x] 无未声明环境变量依赖
- [x] 无未声明安装动作
## 4. 资源检查
- [x] 资源文件存在且为真实内容
- [x] 资源用途与 skill 目标一致
- [x] 资源已在说明中被引用
## 5. 安全检查
- [x] 未发现 `curl|bash`
- [x] 未发现远程下载后直接执行
- [x] 未发现 base64/混淆载荷执行
- [x] 未发现越权监控、盗号、破解、恶意抓取设计
- [x] 文件读写范围应由用户明确指定
## 6. 热门度与实用性复核
- 高频需求:是
- 低理解门槛:是
- 易传播:是
- 可二次定制:是
- 维护成本:低到中
## 7. 评分
- 规范完整度:9.5/10
- 可用性:9.0/10
- 安全性:9.5/10
- 可维护性:9.0/10
- 综合评分:9.3/10
## 8. 结论
该 skill 已补齐交付级目录结构,适合纳入统一 bundle 分发。后续若要继续增强,优先方向是增加更贴近真实场景的样例输入与回归测试数据。
FILE:scripts/expense_ledger.py
#!/usr/bin/env python3
import argparse, csv, json, re
from decimal import Decimal
CATEGORY_HINTS = {
"uber":"Travel","flight":"Travel","hotel":"Travel","taxi":"Travel",
"lunch":"Meals","dinner":"Meals","coffee":"Meals",
"adobe":"Software","notion":"Software","figma":"Software",
"office":"Office","paper":"Office","printer":"Office",
}
def categorize(text):
low = text.lower()
for key, cat in CATEGORY_HINTS.items():
if key in low:
return cat
return "Other"
def main():
ap = argparse.ArgumentParser()
ap.add_argument("items_json", help="JSON list with vendor/date/amount/description")
ap.add_argument("--out", default="expense_ledger.csv")
args = ap.parse_args()
items = json.load(open(args.items_json, "r", encoding="utf-8"))
fields = ["vendor","date","amount","currency","description","category","flag"]
with open(args.out, "w", encoding="utf-8", newline="") as f:
w = csv.DictWriter(f, fieldnames=fields)
w.writeheader()
for item in items:
desc = item.get("description","")
amt = str(item.get("amount",""))
flag = "check" if not amt else ""
w.writerow({
"vendor": item.get("vendor",""),
"date": item.get("date",""),
"amount": amt,
"currency": item.get("currency",""),
"description": desc,
"category": item.get("category") or categorize(desc + " " + item.get("vendor","")),
"flag": flag
})
print(f"Wrote {args.out}")
if __name__ == "__main__":
main()
FILE:examples/example-prompt.md
# Receipt Expense Workbench 示例
## 示例触发词
- 整理发票
- 报销单汇总
- receipt to expense sheet
- 做费用台账
- expense ledger
## 示例输入
- receipt text or OCR output
- currency
- reimbursement policy if available
- project code
- merchant names
## 示例请求
请使用 `receipt-expense-workbench`,基于我提供的材料,按照 skill 中的工作流给出:
1. expense ledger CSV
1. category summary
1. anomaly report
1. reimbursement packet checklist
## 说明
- 先给预览稿或结构化草案
- 信息不足时,只补问最关键缺口
- 不要编造未提供的事实
FILE:tests/smoke-test.md
# Smoke test — receipt-expense-workbench
## 目标
验证该 skill 具备最小可用交付结构,且本地辅助脚本可被解释器加载。
## 检查项
1. `SKILL.md` 存在,且 frontmatter 含 `name`、`description`、`version`
2. `README.md`、`SELF_CHECK.md`、`examples/example-prompt.md` 存在
3. `scripts/` 下至少有一个可执行脚本
4. `resources/` 下至少有一个真实资源文件
5. 运行 `python3 scripts/expense_ledger.py --help` 返回退出码 0
## 人工验证
- 用 `examples/example-prompt.md` 中的触发词在会话中调用 skill
- 检查输出是否覆盖以下内容:
- expense ledger CSV
- category summary
- anomaly report
- reimbursement packet checklist
- 检查是否优先给出预览、草案或确认步骤,而非直接做破坏性操作
## 通过标准
全部检查项通过,即视为 smoke test 通过。
FILE:resources/expense_categories.csv
category,description
Travel,Flights trains taxis hotels
Meals,Client or team meals
Software,SaaS subscriptions and licenses
Office,Office supplies and equipment
Marketing,Ads design printing events
Training,Courses books certifications
Other,Unmapped or exceptional items
Turn messy service pricing notes into professional quotes, SOW line items, and invoice drafts with assumptions clearly surfaced.
---
name: quote-invoice-workbench
description: Turn messy service pricing notes into professional quotes, SOW line items,
and invoice drafts with assumptions clearly surfaced.
version: 1.1.0
metadata:
openclaw:
requires:
bins:
- python3
emoji: 🧰
---
# Quote & Invoice Workbench
## Purpose
Turn messy service pricing notes into professional quotes, SOW line items, and invoice drafts with assumptions clearly surfaced.
## Trigger phrases
- 报价单
- invoice draft
- 做服务报价
- 估算项目费用
- scope and quote
## Ask for these inputs
- service scope
- rate card or budget
- timeline
- payment terms
- optional taxes/discounts
## Workflow
1. Break the scope into clear line items and assumptions.
2. Use the bundled pricebook as a starting point or adapt to the user's rates.
3. Calculate subtotal, taxes, discounts, deposit, and milestones.
4. Generate quote and invoice drafts separately.
5. Make all assumptions explicit to reduce disputes.
## Output contract
- quote table
- invoice draft
- assumptions list
- scope exclusions
## Files in this skill
- Script: `{baseDir}/scripts/quote_calculator.py`
- Resource: `{baseDir}/resources/pricebook.csv`
## Operating rules
- Be concrete and action-oriented.
- Prefer preview / draft / simulation mode before destructive changes.
- If information is missing, ask only for the minimum needed to proceed.
- Never fabricate metrics, legal certainty, receipts, credentials, or evidence.
- Keep assumptions explicit.
## Suggested prompts
- 报价单
- invoice draft
- 做服务报价
## Use of script and resources
Use the bundled script when it helps the user produce a structured file, manifest, CSV, or first-pass draft.
Use the resource file as the default schema, checklist, or preset when the user does not provide one.
## Boundaries
- This skill supports planning, structuring, and first-pass artifacts.
- It should not claim that files were modified, messages were sent, or legal/financial decisions were finalized unless the user actually performed those actions.
## Compatibility notes
- Directory-based AgentSkills/OpenClaw skill.
- Runtime dependency declared through `metadata.openclaw.requires`.
- Helper script is local and auditable: `scripts/quote_calculator.py`.
- Bundled resource is local and referenced by the instructions: `resources/pricebook.csv`.
FILE:CHANGELOG.md
# Changelog
## 1.0.0
- Initial release.
FILE:README.md
# Quote & Invoice Workbench
Slug: `quote-invoice-workbench`
## 功能定位
Turn messy service pricing notes into professional quotes, SOW line items, and invoice drafts with assumptions clearly surfaced.
## 适用场景
- 当用户需要:报价单
- 当用户手头已有原始材料,需要快速整理成可执行输出
- 当用户希望先预览方案、再决定是否落盘或批量处理
## 安装要求
- OpenClaw / AgentSkills 兼容目录结构
- `python3` 可执行文件在 PATH 中可用
- 无远程安装脚本、无隐藏联网依赖、无未声明凭据要求
## 目录结构
- `SKILL.md`:触发描述、工作流、输出契约
- `scripts/quote_calculator.py`:本地辅助脚本
- `resources/pricebook.csv`:被 SKILL/README 引用的资源文件
- `examples/example-prompt.md`:触发与输入示例
- `tests/smoke-test.md`:最小冒烟测试
- `SELF_CHECK.md`:规范与安全自检
- `CHANGELOG.md`:变更记录
## 触发示例
- `报价单`
- `invoice draft`
- `做服务报价`
- `估算项目费用`
- `scope and quote`
## 建议输入
- service scope
- rate card or budget
- timeline
- payment terms
- optional taxes/discounts
## 预期输出
- quote table
- invoice draft
- assumptions list
- scope exclusions
## 辅助脚本
脚本:`scripts/quote_calculator.py`
建议先运行帮助信息确认参数:
```bash
python3 scripts/quote_calculator.py --help
```
该脚本设计原则:
- 本地执行,便于审计与回滚
- 输入输出路径显式传入
- 不使用 `curl|bash`、远程直灌、base64 混淆执行
- 仅处理用户明确提供的文件或目录
## 输入输出示例
输入示例见:`examples/example-prompt.md`
输出示例建议至少包含:
- 结构化主结果
- 未决问题 / 风险项
- 可交付给他人的摘要或清单
## 常见问题
### 1. 这个 skill 会直接改我的文件吗?
默认不应直接进行破坏性批量操作;应优先生成预览、清单或草案,只有在用户明确要求时才建议执行进一步动作。
### 2. 这个 skill 需要联网吗?
当前目录内未声明联网依赖,也没有内置远程下载步骤。是否联网应由具体会话任务决定,而不是由 skill 包本身强制触发。
### 3. 资源文件的作用是什么?
`resources/pricebook.csv` 为脚本或说明提供模板、规则、清单或模式参考,便于输出格式统一、可复用、可审计。
## 风险提示
- 对用户提供的数据、文本、截图或本地文件进行整理时,应先确认范围与目标。
- 涉及重命名、移动、合并、覆盖、生成正式对外内容时,应先给预览版本。
- 对不确定字段使用“待确认”标记,不应编造事实。
## 安全审计结论
- 依赖边界:仅声明 `python3`
- 凭据边界:未声明环境变量依赖
- 执行边界:本地脚本、本地资源、显式输入
- 高风险模式检查:未引入 `curl|bash`、远程管道执行、混淆载荷或私有 API 绑定
FILE:SELF_CHECK.md
# SELF_CHECK — quote-invoice-workbench
## 1. 规范检查
- [x] Skill 为独立文件夹
- [x] 包含 `SKILL.md`
- [x] `SKILL.md` 使用 YAML frontmatter
- [x] frontmatter 含 `name`、`description`、`version`
- [x] 运行依赖声明在 `metadata.openclaw.requires`
- [x] 包含 `README.md`
- [x] 包含 `scripts/` 且至少 1 个脚本
- [x] 包含 `resources/` 且至少 1 个资源文件
- [x] 包含 `examples/example-prompt.md`
- [x] 包含 `tests/smoke-test.md`
## 2. 路径与引用检查
- [x] `SKILL.md` 中引用了 `scripts/quote_calculator.py`
- [x] `SKILL.md` 中引用了 `resources/pricebook.csv`
- [x] `README.md`、`SELF_CHECK.md`、`tests/smoke-test.md` 路径与当前目录一致
- [x] 打包后无需依赖绝对路径
## 3. 依赖与脚本检查
- [x] 仅声明 `python3` 作为运行依赖
- [x] 脚本为明文、可审计、本地执行
- [x] 脚本参数通过 CLI 显式传入
- [x] 无未声明环境变量依赖
- [x] 无未声明安装动作
## 4. 资源检查
- [x] 资源文件存在且为真实内容
- [x] 资源用途与 skill 目标一致
- [x] 资源已在说明中被引用
## 5. 安全检查
- [x] 未发现 `curl|bash`
- [x] 未发现远程下载后直接执行
- [x] 未发现 base64/混淆载荷执行
- [x] 未发现越权监控、盗号、破解、恶意抓取设计
- [x] 文件读写范围应由用户明确指定
## 6. 热门度与实用性复核
- 高频需求:是
- 低理解门槛:是
- 易传播:是
- 可二次定制:是
- 维护成本:低到中
## 7. 评分
- 规范完整度:9.5/10
- 可用性:9.0/10
- 安全性:9.5/10
- 可维护性:9.0/10
- 综合评分:9.3/10
## 8. 结论
该 skill 已补齐交付级目录结构,适合纳入统一 bundle 分发。后续若要继续增强,优先方向是增加更贴近真实场景的样例输入与回归测试数据。
FILE:scripts/quote_calculator.py
#!/usr/bin/env python3
import argparse, json
from decimal import Decimal
def main():
ap = argparse.ArgumentParser()
ap.add_argument("line_items_json", help="JSON list with item, qty, rate")
ap.add_argument("--tax", type=float, default=0.0)
ap.add_argument("--discount", type=float, default=0.0)
ap.add_argument("--out", default="quote.json")
args = ap.parse_args()
items = json.load(open(args.line_items_json, "r", encoding="utf-8"))
subtotal = sum((item.get("qty",1) * item.get("rate",0) for item in items), 0)
total = subtotal * (1 + args.tax/100.0) * (1 - args.discount/100.0)
payload = {"items": items, "subtotal": round(subtotal,2), "tax_pct": args.tax, "discount_pct": args.discount, "total": round(total,2)}
json.dump(payload, open(args.out, "w", encoding="utf-8"), ensure_ascii=False, indent=2)
print(f"Wrote {args.out}")
if __name__ == "__main__":
main()
FILE:examples/example-prompt.md
# Quote & Invoice Workbench 示例
## 示例触发词
- 报价单
- invoice draft
- 做服务报价
- 估算项目费用
- scope and quote
## 示例输入
- service scope
- rate card or budget
- timeline
- payment terms
- optional taxes/discounts
## 示例请求
请使用 `quote-invoice-workbench`,基于我提供的材料,按照 skill 中的工作流给出:
1. quote table
1. invoice draft
1. assumptions list
1. scope exclusions
## 说明
- 先给预览稿或结构化草案
- 信息不足时,只补问最关键缺口
- 不要编造未提供的事实
FILE:tests/smoke-test.md
# Smoke test — quote-invoice-workbench
## 目标
验证该 skill 具备最小可用交付结构,且本地辅助脚本可被解释器加载。
## 检查项
1. `SKILL.md` 存在,且 frontmatter 含 `name`、`description`、`version`
2. `README.md`、`SELF_CHECK.md`、`examples/example-prompt.md` 存在
3. `scripts/` 下至少有一个可执行脚本
4. `resources/` 下至少有一个真实资源文件
5. 运行 `python3 scripts/quote_calculator.py --help` 返回退出码 0
## 人工验证
- 用 `examples/example-prompt.md` 中的触发词在会话中调用 skill
- 检查输出是否覆盖以下内容:
- quote table
- invoice draft
- assumptions list
- scope exclusions
- 检查是否优先给出预览、草案或确认步骤,而非直接做破坏性操作
## 通过标准
全部检查项通过,即视为 smoke test 通过。
FILE:resources/pricebook.csv
item,unit,base_rate
Strategy session,hour,120
Design work,hour,90
Development,hour,110
Retainer,month,1800
On-site shoot,day,600
Editing,asset,25
Design, log, compare, and score prompt experiments so users can systematically improve outputs instead of guessing.
---
name: prompt-ab-lab
description: Design, log, compare, and score prompt experiments so users can systematically
improve outputs instead of guessing.
version: 1.1.0
metadata:
openclaw:
requires:
bins:
- python3
emoji: 🧰
---
# Prompt A/B Lab
## Purpose
Design, log, compare, and score prompt experiments so users can systematically improve outputs instead of guessing.
## Trigger phrases
- 比较两个提示词
- prompt ab test
- 提示词实验
- 哪个 prompt 更好
- 建一个评测表
## Ask for these inputs
- prompt A and B
- task
- evaluation criteria
- test set
- weights if any
## Workflow
1. Define what success looks like before comparing prompts.
2. Generate an evaluation rubric and structured test table.
3. Log outputs per test case and compute weighted scores.
4. Summarize tradeoffs instead of declaring a winner too early.
5. Recommend the next experiment iteration.
## Output contract
- experiment plan
- scored comparison table
- rubric
- next-iteration suggestions
## Files in this skill
- Script: `{baseDir}/scripts/prompt_experiment_logger.py`
- Resource: `{baseDir}/resources/eval_rubric.md`
## Operating rules
- Be concrete and action-oriented.
- Prefer preview / draft / simulation mode before destructive changes.
- If information is missing, ask only for the minimum needed to proceed.
- Never fabricate metrics, legal certainty, receipts, credentials, or evidence.
- Keep assumptions explicit.
## Suggested prompts
- 比较两个提示词
- prompt ab test
- 提示词实验
## Use of script and resources
Use the bundled script when it helps the user produce a structured file, manifest, CSV, or first-pass draft.
Use the resource file as the default schema, checklist, or preset when the user does not provide one.
## Boundaries
- This skill supports planning, structuring, and first-pass artifacts.
- It should not claim that files were modified, messages were sent, or legal/financial decisions were finalized unless the user actually performed those actions.
## Compatibility notes
- Directory-based AgentSkills/OpenClaw skill.
- Runtime dependency declared through `metadata.openclaw.requires`.
- Helper script is local and auditable: `scripts/prompt_experiment_logger.py`.
- Bundled resource is local and referenced by the instructions: `resources/eval_rubric.md`.
FILE:CHANGELOG.md
# Changelog
## 1.0.0
- Initial release.
FILE:README.md
# Prompt A/B Lab
Slug: `prompt-ab-lab`
## 功能定位
Design, log, compare, and score prompt experiments so users can systematically improve outputs instead of guessing.
## 适用场景
- 当用户需要:比较两个提示词
- 当用户手头已有原始材料,需要快速整理成可执行输出
- 当用户希望先预览方案、再决定是否落盘或批量处理
## 安装要求
- OpenClaw / AgentSkills 兼容目录结构
- `python3` 可执行文件在 PATH 中可用
- 无远程安装脚本、无隐藏联网依赖、无未声明凭据要求
## 目录结构
- `SKILL.md`:触发描述、工作流、输出契约
- `scripts/prompt_experiment_logger.py`:本地辅助脚本
- `resources/eval_rubric.md`:被 SKILL/README 引用的资源文件
- `examples/example-prompt.md`:触发与输入示例
- `tests/smoke-test.md`:最小冒烟测试
- `SELF_CHECK.md`:规范与安全自检
- `CHANGELOG.md`:变更记录
## 触发示例
- `比较两个提示词`
- `prompt ab test`
- `提示词实验`
- `哪个 prompt 更好`
- `建一个评测表`
## 建议输入
- prompt A and B
- task
- evaluation criteria
- test set
- weights if any
## 预期输出
- experiment plan
- scored comparison table
- rubric
- next-iteration suggestions
## 辅助脚本
脚本:`scripts/prompt_experiment_logger.py`
建议先运行帮助信息确认参数:
```bash
python3 scripts/prompt_experiment_logger.py --help
```
该脚本设计原则:
- 本地执行,便于审计与回滚
- 输入输出路径显式传入
- 不使用 `curl|bash`、远程直灌、base64 混淆执行
- 仅处理用户明确提供的文件或目录
## 输入输出示例
输入示例见:`examples/example-prompt.md`
输出示例建议至少包含:
- 结构化主结果
- 未决问题 / 风险项
- 可交付给他人的摘要或清单
## 常见问题
### 1. 这个 skill 会直接改我的文件吗?
默认不应直接进行破坏性批量操作;应优先生成预览、清单或草案,只有在用户明确要求时才建议执行进一步动作。
### 2. 这个 skill 需要联网吗?
当前目录内未声明联网依赖,也没有内置远程下载步骤。是否联网应由具体会话任务决定,而不是由 skill 包本身强制触发。
### 3. 资源文件的作用是什么?
`resources/eval_rubric.md` 为脚本或说明提供模板、规则、清单或模式参考,便于输出格式统一、可复用、可审计。
## 风险提示
- 对用户提供的数据、文本、截图或本地文件进行整理时,应先确认范围与目标。
- 涉及重命名、移动、合并、覆盖、生成正式对外内容时,应先给预览版本。
- 对不确定字段使用“待确认”标记,不应编造事实。
## 安全审计结论
- 依赖边界:仅声明 `python3`
- 凭据边界:未声明环境变量依赖
- 执行边界:本地脚本、本地资源、显式输入
- 高风险模式检查:未引入 `curl|bash`、远程管道执行、混淆载荷或私有 API 绑定
FILE:SELF_CHECK.md
# SELF_CHECK — prompt-ab-lab
## 1. 规范检查
- [x] Skill 为独立文件夹
- [x] 包含 `SKILL.md`
- [x] `SKILL.md` 使用 YAML frontmatter
- [x] frontmatter 含 `name`、`description`、`version`
- [x] 运行依赖声明在 `metadata.openclaw.requires`
- [x] 包含 `README.md`
- [x] 包含 `scripts/` 且至少 1 个脚本
- [x] 包含 `resources/` 且至少 1 个资源文件
- [x] 包含 `examples/example-prompt.md`
- [x] 包含 `tests/smoke-test.md`
## 2. 路径与引用检查
- [x] `SKILL.md` 中引用了 `scripts/prompt_experiment_logger.py`
- [x] `SKILL.md` 中引用了 `resources/eval_rubric.md`
- [x] `README.md`、`SELF_CHECK.md`、`tests/smoke-test.md` 路径与当前目录一致
- [x] 打包后无需依赖绝对路径
## 3. 依赖与脚本检查
- [x] 仅声明 `python3` 作为运行依赖
- [x] 脚本为明文、可审计、本地执行
- [x] 脚本参数通过 CLI 显式传入
- [x] 无未声明环境变量依赖
- [x] 无未声明安装动作
## 4. 资源检查
- [x] 资源文件存在且为真实内容
- [x] 资源用途与 skill 目标一致
- [x] 资源已在说明中被引用
## 5. 安全检查
- [x] 未发现 `curl|bash`
- [x] 未发现远程下载后直接执行
- [x] 未发现 base64/混淆载荷执行
- [x] 未发现越权监控、盗号、破解、恶意抓取设计
- [x] 文件读写范围应由用户明确指定
## 6. 热门度与实用性复核
- 高频需求:是
- 低理解门槛:是
- 易传播:是
- 可二次定制:是
- 维护成本:低到中
## 7. 评分
- 规范完整度:9.5/10
- 可用性:9.0/10
- 安全性:9.5/10
- 可维护性:9.0/10
- 综合评分:9.3/10
## 8. 结论
该 skill 已补齐交付级目录结构,适合纳入统一 bundle 分发。后续若要继续增强,优先方向是增加更贴近真实场景的样例输入与回归测试数据。
FILE:scripts/prompt_experiment_logger.py
#!/usr/bin/env python3
import argparse, csv, json
def main():
ap = argparse.ArgumentParser()
ap.add_argument("cases_json", help="JSON list of test cases")
ap.add_argument("--out", default="prompt_experiment.csv")
args = ap.parse_args()
cases = json.load(open(args.cases_json, "r", encoding="utf-8"))
fields = ["case_id","criterion","prompt_a_score","prompt_b_score","notes"]
with open(args.out, "w", encoding="utf-8", newline="") as f:
w = csv.DictWriter(f, fieldnames=fields)
w.writeheader()
for idx, case in enumerate(cases, 1):
for criterion in case.get("criteria", ["accuracy"]):
w.writerow({"case_id": idx, "criterion": criterion, "prompt_a_score": "", "prompt_b_score": "", "notes": case.get("notes","")})
print(f"Wrote {args.out}")
if __name__ == "__main__":
main()
FILE:examples/example-prompt.md
# Prompt A/B Lab 示例
## 示例触发词
- 比较两个提示词
- prompt ab test
- 提示词实验
- 哪个 prompt 更好
- 建一个评测表
## 示例输入
- prompt A and B
- task
- evaluation criteria
- test set
- weights if any
## 示例请求
请使用 `prompt-ab-lab`,基于我提供的材料,按照 skill 中的工作流给出:
1. experiment plan
1. scored comparison table
1. rubric
1. next-iteration suggestions
## 说明
- 先给预览稿或结构化草案
- 信息不足时,只补问最关键缺口
- 不要编造未提供的事实
FILE:tests/smoke-test.md
# Smoke test — prompt-ab-lab
## 目标
验证该 skill 具备最小可用交付结构,且本地辅助脚本可被解释器加载。
## 检查项
1. `SKILL.md` 存在,且 frontmatter 含 `name`、`description`、`version`
2. `README.md`、`SELF_CHECK.md`、`examples/example-prompt.md` 存在
3. `scripts/` 下至少有一个可执行脚本
4. `resources/` 下至少有一个真实资源文件
5. 运行 `python3 scripts/prompt_experiment_logger.py --help` 返回退出码 0
## 人工验证
- 用 `examples/example-prompt.md` 中的触发词在会话中调用 skill
- 检查输出是否覆盖以下内容:
- experiment plan
- scored comparison table
- rubric
- next-iteration suggestions
- 检查是否优先给出预览、草案或确认步骤,而非直接做破坏性操作
## 通过标准
全部检查项通过,即视为 smoke test 通过。
FILE:resources/eval_rubric.md
# Prompt Evaluation Rubric
- Accuracy
- Completeness
- Style fidelity
- Safety / policy compliance
- Latency / cost awareness
- Robustness on edge cases
Turn rough project notes into polished portfolio case studies with metrics, visuals checklist, and interviewer talking points.
---
name: portfolio-case-study-forge
description: Turn rough project notes into polished portfolio case studies with metrics,
visuals checklist, and interviewer talking points.
version: 1.1.0
metadata:
openclaw:
requires:
bins:
- python3
emoji: 🧰
---
# Portfolio Case Study Forge
## Purpose
Turn rough project notes into polished portfolio case studies with metrics, visuals checklist, and interviewer talking points.
## Trigger phrases
- 做作品集案例
- turn this project into a case study
- 项目包装成作品集
- portfolio story
- 面试讲项目
## Ask for these inputs
- project notes
- target audience recruiter/client/interviewer
- available metrics
- screenshots or links
- tone
## Workflow
1. Structure the story into context, role, problem, approach, constraints, outcome, and lessons.
2. Identify missing proof points and suggest what screenshots or charts to add.
3. Generate short and long versions for portfolio sites and interviews.
4. Produce talking points and FAQ answers.
5. Avoid inflating impact; mark assumptions explicitly.
## Output contract
- case study draft
- visuals checklist
- talking points
- FAQ sheet
## Files in this skill
- Script: `{baseDir}/scripts/case_study_scaffold.py`
- Resource: `{baseDir}/resources/case_study_template.md`
## Operating rules
- Be concrete and action-oriented.
- Prefer preview / draft / simulation mode before destructive changes.
- If information is missing, ask only for the minimum needed to proceed.
- Never fabricate metrics, legal certainty, receipts, credentials, or evidence.
- Keep assumptions explicit.
## Suggested prompts
- 做作品集案例
- turn this project into a case study
- 项目包装成作品集
## Use of script and resources
Use the bundled script when it helps the user produce a structured file, manifest, CSV, or first-pass draft.
Use the resource file as the default schema, checklist, or preset when the user does not provide one.
## Boundaries
- This skill supports planning, structuring, and first-pass artifacts.
- It should not claim that files were modified, messages were sent, or legal/financial decisions were finalized unless the user actually performed those actions.
## Compatibility notes
- Directory-based AgentSkills/OpenClaw skill.
- Runtime dependency declared through `metadata.openclaw.requires`.
- Helper script is local and auditable: `scripts/case_study_scaffold.py`.
- Bundled resource is local and referenced by the instructions: `resources/case_study_template.md`.
FILE:CHANGELOG.md
# Changelog
## 1.0.0
- Initial release.
FILE:README.md
# Portfolio Case Study Forge
Slug: `portfolio-case-study-forge`
## 功能定位
Turn rough project notes into polished portfolio case studies with metrics, visuals checklist, and interviewer talking points.
## 适用场景
- 当用户需要:做作品集案例
- 当用户手头已有原始材料,需要快速整理成可执行输出
- 当用户希望先预览方案、再决定是否落盘或批量处理
## 安装要求
- OpenClaw / AgentSkills 兼容目录结构
- `python3` 可执行文件在 PATH 中可用
- 无远程安装脚本、无隐藏联网依赖、无未声明凭据要求
## 目录结构
- `SKILL.md`:触发描述、工作流、输出契约
- `scripts/case_study_scaffold.py`:本地辅助脚本
- `resources/case_study_template.md`:被 SKILL/README 引用的资源文件
- `examples/example-prompt.md`:触发与输入示例
- `tests/smoke-test.md`:最小冒烟测试
- `SELF_CHECK.md`:规范与安全自检
- `CHANGELOG.md`:变更记录
## 触发示例
- `做作品集案例`
- `turn this project into a case study`
- `项目包装成作品集`
- `portfolio story`
- `面试讲项目`
## 建议输入
- project notes
- target audience recruiter/client/interviewer
- available metrics
- screenshots or links
- tone
## 预期输出
- case study draft
- visuals checklist
- talking points
- FAQ sheet
## 辅助脚本
脚本:`scripts/case_study_scaffold.py`
建议先运行帮助信息确认参数:
```bash
python3 scripts/case_study_scaffold.py --help
```
该脚本设计原则:
- 本地执行,便于审计与回滚
- 输入输出路径显式传入
- 不使用 `curl|bash`、远程直灌、base64 混淆执行
- 仅处理用户明确提供的文件或目录
## 输入输出示例
输入示例见:`examples/example-prompt.md`
输出示例建议至少包含:
- 结构化主结果
- 未决问题 / 风险项
- 可交付给他人的摘要或清单
## 常见问题
### 1. 这个 skill 会直接改我的文件吗?
默认不应直接进行破坏性批量操作;应优先生成预览、清单或草案,只有在用户明确要求时才建议执行进一步动作。
### 2. 这个 skill 需要联网吗?
当前目录内未声明联网依赖,也没有内置远程下载步骤。是否联网应由具体会话任务决定,而不是由 skill 包本身强制触发。
### 3. 资源文件的作用是什么?
`resources/case_study_template.md` 为脚本或说明提供模板、规则、清单或模式参考,便于输出格式统一、可复用、可审计。
## 风险提示
- 对用户提供的数据、文本、截图或本地文件进行整理时,应先确认范围与目标。
- 涉及重命名、移动、合并、覆盖、生成正式对外内容时,应先给预览版本。
- 对不确定字段使用“待确认”标记,不应编造事实。
## 安全审计结论
- 依赖边界:仅声明 `python3`
- 凭据边界:未声明环境变量依赖
- 执行边界:本地脚本、本地资源、显式输入
- 高风险模式检查:未引入 `curl|bash`、远程管道执行、混淆载荷或私有 API 绑定
FILE:SELF_CHECK.md
# SELF_CHECK — portfolio-case-study-forge
## 1. 规范检查
- [x] Skill 为独立文件夹
- [x] 包含 `SKILL.md`
- [x] `SKILL.md` 使用 YAML frontmatter
- [x] frontmatter 含 `name`、`description`、`version`
- [x] 运行依赖声明在 `metadata.openclaw.requires`
- [x] 包含 `README.md`
- [x] 包含 `scripts/` 且至少 1 个脚本
- [x] 包含 `resources/` 且至少 1 个资源文件
- [x] 包含 `examples/example-prompt.md`
- [x] 包含 `tests/smoke-test.md`
## 2. 路径与引用检查
- [x] `SKILL.md` 中引用了 `scripts/case_study_scaffold.py`
- [x] `SKILL.md` 中引用了 `resources/case_study_template.md`
- [x] `README.md`、`SELF_CHECK.md`、`tests/smoke-test.md` 路径与当前目录一致
- [x] 打包后无需依赖绝对路径
## 3. 依赖与脚本检查
- [x] 仅声明 `python3` 作为运行依赖
- [x] 脚本为明文、可审计、本地执行
- [x] 脚本参数通过 CLI 显式传入
- [x] 无未声明环境变量依赖
- [x] 无未声明安装动作
## 4. 资源检查
- [x] 资源文件存在且为真实内容
- [x] 资源用途与 skill 目标一致
- [x] 资源已在说明中被引用
## 5. 安全检查
- [x] 未发现 `curl|bash`
- [x] 未发现远程下载后直接执行
- [x] 未发现 base64/混淆载荷执行
- [x] 未发现越权监控、盗号、破解、恶意抓取设计
- [x] 文件读写范围应由用户明确指定
## 6. 热门度与实用性复核
- 高频需求:是
- 低理解门槛:是
- 易传播:是
- 可二次定制:是
- 维护成本:低到中
## 7. 评分
- 规范完整度:9.5/10
- 可用性:9.0/10
- 安全性:9.5/10
- 可维护性:9.0/10
- 综合评分:9.3/10
## 8. 结论
该 skill 已补齐交付级目录结构,适合纳入统一 bundle 分发。后续若要继续增强,优先方向是增加更贴近真实场景的样例输入与回归测试数据。
FILE:scripts/case_study_scaffold.py
#!/usr/bin/env python3
import argparse, json
TEMPLATE = {
"project_snapshot": {"client":"", "timeline":"", "role":"", "outcome":""},
"problem": "",
"constraints": "",
"process": [],
"decisions": [],
"results": [],
"lessons": []
}
def main():
ap = argparse.ArgumentParser()
ap.add_argument("--out", default="case_study_scaffold.json")
args = ap.parse_args()
json.dump(TEMPLATE, open(args.out, "w", encoding="utf-8"), ensure_ascii=False, indent=2)
print(f"Wrote {args.out}")
if __name__ == "__main__":
main()
FILE:examples/example-prompt.md
# Portfolio Case Study Forge 示例
## 示例触发词
- 做作品集案例
- turn this project into a case study
- 项目包装成作品集
- portfolio story
- 面试讲项目
## 示例输入
- project notes
- target audience recruiter/client/interviewer
- available metrics
- screenshots or links
- tone
## 示例请求
请使用 `portfolio-case-study-forge`,基于我提供的材料,按照 skill 中的工作流给出:
1. case study draft
1. visuals checklist
1. talking points
1. FAQ sheet
## 说明
- 先给预览稿或结构化草案
- 信息不足时,只补问最关键缺口
- 不要编造未提供的事实
FILE:tests/smoke-test.md
# Smoke test — portfolio-case-study-forge
## 目标
验证该 skill 具备最小可用交付结构,且本地辅助脚本可被解释器加载。
## 检查项
1. `SKILL.md` 存在,且 frontmatter 含 `name`、`description`、`version`
2. `README.md`、`SELF_CHECK.md`、`examples/example-prompt.md` 存在
3. `scripts/` 下至少有一个可执行脚本
4. `resources/` 下至少有一个真实资源文件
5. 运行 `python3 scripts/case_study_scaffold.py --help` 返回退出码 0
## 人工验证
- 用 `examples/example-prompt.md` 中的触发词在会话中调用 skill
- 检查输出是否覆盖以下内容:
- case study draft
- visuals checklist
- talking points
- FAQ sheet
- 检查是否优先给出预览、草案或确认步骤,而非直接做破坏性操作
## 通过标准
全部检查项通过,即视为 smoke test 通过。
FILE:resources/case_study_template.md
# Case Study Template
## Project Snapshot
- Client / Team:
- Timeline:
- Role:
- Outcome:
## Problem
## Constraints
## Process
## Decisions
## Results
## Lessons
Read policies, application requirements, and forms, then turn them into a completeness checklist, risk list, and submission plan.
---
name: policy-application-checker
description: Read policies, application requirements, and forms, then turn them into
a completeness checklist, risk list, and submission plan.
version: 1.1.0
metadata:
openclaw:
requires:
bins:
- python3
emoji: 🧰
---
# Policy & Application Checker
## Purpose
Read policies, application requirements, and forms, then turn them into a completeness checklist, risk list, and submission plan.
## Trigger phrases
- 检查材料是否齐全
- application checklist
- 读政策做清单
- submission readiness
- requirements checklist
## Ask for these inputs
- policy text or form
- deadline
- applicant profile
- required attachments
- known blockers
## Workflow
1. Extract mandatory requirements, deadlines, and conditional branches.
2. Transform them into a checklist with evidence slots.
3. Flag ambiguous wording and missing proof.
4. Sequence tasks into a submission plan backward from the deadline.
5. Never assume a requirement is satisfied without evidence.
## Output contract
- completeness checklist
- risk list
- submission timeline
- evidence tracker
## Files in this skill
- Script: `{baseDir}/scripts/checklist_builder.py`
- Resource: `{baseDir}/resources/checklist_template.md`
## Operating rules
- Be concrete and action-oriented.
- Prefer preview / draft / simulation mode before destructive changes.
- If information is missing, ask only for the minimum needed to proceed.
- Never fabricate metrics, legal certainty, receipts, credentials, or evidence.
- Keep assumptions explicit.
## Suggested prompts
- 检查材料是否齐全
- application checklist
- 读政策做清单
## Use of script and resources
Use the bundled script when it helps the user produce a structured file, manifest, CSV, or first-pass draft.
Use the resource file as the default schema, checklist, or preset when the user does not provide one.
## Boundaries
- This skill supports planning, structuring, and first-pass artifacts.
- It should not claim that files were modified, messages were sent, or legal/financial decisions were finalized unless the user actually performed those actions.
## Compatibility notes
- Directory-based AgentSkills/OpenClaw skill.
- Runtime dependency declared through `metadata.openclaw.requires`.
- Helper script is local and auditable: `scripts/checklist_builder.py`.
- Bundled resource is local and referenced by the instructions: `resources/checklist_template.md`.
FILE:CHANGELOG.md
# Changelog
## 1.0.0
- Initial release.
FILE:README.md
# Policy & Application Checker
Slug: `policy-application-checker`
## 功能定位
Read policies, application requirements, and forms, then turn them into a completeness checklist, risk list, and submission plan.
## 适用场景
- 当用户需要:检查材料是否齐全
- 当用户手头已有原始材料,需要快速整理成可执行输出
- 当用户希望先预览方案、再决定是否落盘或批量处理
## 安装要求
- OpenClaw / AgentSkills 兼容目录结构
- `python3` 可执行文件在 PATH 中可用
- 无远程安装脚本、无隐藏联网依赖、无未声明凭据要求
## 目录结构
- `SKILL.md`:触发描述、工作流、输出契约
- `scripts/checklist_builder.py`:本地辅助脚本
- `resources/checklist_template.md`:被 SKILL/README 引用的资源文件
- `examples/example-prompt.md`:触发与输入示例
- `tests/smoke-test.md`:最小冒烟测试
- `SELF_CHECK.md`:规范与安全自检
- `CHANGELOG.md`:变更记录
## 触发示例
- `检查材料是否齐全`
- `application checklist`
- `读政策做清单`
- `submission readiness`
- `requirements checklist`
## 建议输入
- policy text or form
- deadline
- applicant profile
- required attachments
- known blockers
## 预期输出
- completeness checklist
- risk list
- submission timeline
- evidence tracker
## 辅助脚本
脚本:`scripts/checklist_builder.py`
建议先运行帮助信息确认参数:
```bash
python3 scripts/checklist_builder.py --help
```
该脚本设计原则:
- 本地执行,便于审计与回滚
- 输入输出路径显式传入
- 不使用 `curl|bash`、远程直灌、base64 混淆执行
- 仅处理用户明确提供的文件或目录
## 输入输出示例
输入示例见:`examples/example-prompt.md`
输出示例建议至少包含:
- 结构化主结果
- 未决问题 / 风险项
- 可交付给他人的摘要或清单
## 常见问题
### 1. 这个 skill 会直接改我的文件吗?
默认不应直接进行破坏性批量操作;应优先生成预览、清单或草案,只有在用户明确要求时才建议执行进一步动作。
### 2. 这个 skill 需要联网吗?
当前目录内未声明联网依赖,也没有内置远程下载步骤。是否联网应由具体会话任务决定,而不是由 skill 包本身强制触发。
### 3. 资源文件的作用是什么?
`resources/checklist_template.md` 为脚本或说明提供模板、规则、清单或模式参考,便于输出格式统一、可复用、可审计。
## 风险提示
- 对用户提供的数据、文本、截图或本地文件进行整理时,应先确认范围与目标。
- 涉及重命名、移动、合并、覆盖、生成正式对外内容时,应先给预览版本。
- 对不确定字段使用“待确认”标记,不应编造事实。
## 安全审计结论
- 依赖边界:仅声明 `python3`
- 凭据边界:未声明环境变量依赖
- 执行边界:本地脚本、本地资源、显式输入
- 高风险模式检查:未引入 `curl|bash`、远程管道执行、混淆载荷或私有 API 绑定
FILE:SELF_CHECK.md
# SELF_CHECK — policy-application-checker
## 1. 规范检查
- [x] Skill 为独立文件夹
- [x] 包含 `SKILL.md`
- [x] `SKILL.md` 使用 YAML frontmatter
- [x] frontmatter 含 `name`、`description`、`version`
- [x] 运行依赖声明在 `metadata.openclaw.requires`
- [x] 包含 `README.md`
- [x] 包含 `scripts/` 且至少 1 个脚本
- [x] 包含 `resources/` 且至少 1 个资源文件
- [x] 包含 `examples/example-prompt.md`
- [x] 包含 `tests/smoke-test.md`
## 2. 路径与引用检查
- [x] `SKILL.md` 中引用了 `scripts/checklist_builder.py`
- [x] `SKILL.md` 中引用了 `resources/checklist_template.md`
- [x] `README.md`、`SELF_CHECK.md`、`tests/smoke-test.md` 路径与当前目录一致
- [x] 打包后无需依赖绝对路径
## 3. 依赖与脚本检查
- [x] 仅声明 `python3` 作为运行依赖
- [x] 脚本为明文、可审计、本地执行
- [x] 脚本参数通过 CLI 显式传入
- [x] 无未声明环境变量依赖
- [x] 无未声明安装动作
## 4. 资源检查
- [x] 资源文件存在且为真实内容
- [x] 资源用途与 skill 目标一致
- [x] 资源已在说明中被引用
## 5. 安全检查
- [x] 未发现 `curl|bash`
- [x] 未发现远程下载后直接执行
- [x] 未发现 base64/混淆载荷执行
- [x] 未发现越权监控、盗号、破解、恶意抓取设计
- [x] 文件读写范围应由用户明确指定
## 6. 热门度与实用性复核
- 高频需求:是
- 低理解门槛:是
- 易传播:是
- 可二次定制:是
- 维护成本:低到中
## 7. 评分
- 规范完整度:9.5/10
- 可用性:9.0/10
- 安全性:9.5/10
- 可维护性:9.0/10
- 综合评分:9.3/10
## 8. 结论
该 skill 已补齐交付级目录结构,适合纳入统一 bundle 分发。后续若要继续增强,优先方向是增加更贴近真实场景的样例输入与回归测试数据。
FILE:scripts/checklist_builder.py
#!/usr/bin/env python3
import argparse, json
def main():
ap = argparse.ArgumentParser()
ap.add_argument("requirements_json", help="JSON list with requirement,owner,deadline")
ap.add_argument("--out", default="checklist.md")
args = ap.parse_args()
rows = json.load(open(args.requirements_json, "r", encoding="utf-8"))
parts = ["# Submission Checklist\n"]
for row in rows:
parts.append(f"- [ ] {row.get('requirement','Requirement')}\n - Owner: {row.get('owner','')}\n - Deadline: {row.get('deadline','')}\n - Evidence: \n")
open(args.out, "w", encoding="utf-8").write("\n".join(parts))
print(f"Wrote {args.out}")
if __name__ == "__main__":
main()
FILE:examples/example-prompt.md
# Policy & Application Checker 示例
## 示例触发词
- 检查材料是否齐全
- application checklist
- 读政策做清单
- submission readiness
- requirements checklist
## 示例输入
- policy text or form
- deadline
- applicant profile
- required attachments
- known blockers
## 示例请求
请使用 `policy-application-checker`,基于我提供的材料,按照 skill 中的工作流给出:
1. completeness checklist
1. risk list
1. submission timeline
1. evidence tracker
## 说明
- 先给预览稿或结构化草案
- 信息不足时,只补问最关键缺口
- 不要编造未提供的事实
FILE:tests/smoke-test.md
# Smoke test — policy-application-checker
## 目标
验证该 skill 具备最小可用交付结构,且本地辅助脚本可被解释器加载。
## 检查项
1. `SKILL.md` 存在,且 frontmatter 含 `name`、`description`、`version`
2. `README.md`、`SELF_CHECK.md`、`examples/example-prompt.md` 存在
3. `scripts/` 下至少有一个可执行脚本
4. `resources/` 下至少有一个真实资源文件
5. 运行 `python3 scripts/checklist_builder.py --help` 返回退出码 0
## 人工验证
- 用 `examples/example-prompt.md` 中的触发词在会话中调用 skill
- 检查输出是否覆盖以下内容:
- completeness checklist
- risk list
- submission timeline
- evidence tracker
- 检查是否优先给出预览、草案或确认步骤,而非直接做破坏性操作
## 通过标准
全部检查项通过,即视为 smoke test 通过。
FILE:resources/checklist_template.md
# Checklist Template
- [ ] Requirement
- Evidence:
- Owner:
- Deadline:
- Notes:
Build respectful multi-touch outreach sequences with channel mix, follow-up timing, objection handling, and logging templates.
---
name: outreach-sequence-crafter
description: Build respectful multi-touch outreach sequences with channel mix, follow-up
timing, objection handling, and logging templates.
version: 1.1.0
metadata:
openclaw:
requires:
bins:
- python3
emoji: 🧰
---
# Outreach Sequence Crafter
## Purpose
Build respectful multi-touch outreach sequences with channel mix, follow-up timing, objection handling, and logging templates.
## Trigger phrases
- 写邀约话术
- build an outreach sequence
- 私域触达节奏
- cold outreach cadence
- 招商邀约流程
## Ask for these inputs
- offer
- target persona
- channels
- timeline
- proof assets
- dos and don'ts
## Workflow
1. Clarify the offer, audience, and desired action.
2. Select a cadence preset from the resources file.
3. Draft first touch, follow-up, breakup, and reply branches.
4. Generate a lightweight tracking table with status codes.
5. Keep claims verifiable and avoid spammy patterns.
## Output contract
- multi-touch sequence
- reply branches
- tracking sheet
- testing plan
## Files in this skill
- Script: `{baseDir}/scripts/sequence_builder.py`
- Resource: `{baseDir}/resources/cadence_presets.yaml`
## Operating rules
- Be concrete and action-oriented.
- Prefer preview / draft / simulation mode before destructive changes.
- If information is missing, ask only for the minimum needed to proceed.
- Never fabricate metrics, legal certainty, receipts, credentials, or evidence.
- Keep assumptions explicit.
## Suggested prompts
- 写邀约话术
- build an outreach sequence
- 私域触达节奏
## Use of script and resources
Use the bundled script when it helps the user produce a structured file, manifest, CSV, or first-pass draft.
Use the resource file as the default schema, checklist, or preset when the user does not provide one.
## Boundaries
- This skill supports planning, structuring, and first-pass artifacts.
- It should not claim that files were modified, messages were sent, or legal/financial decisions were finalized unless the user actually performed those actions.
## Compatibility notes
- Directory-based AgentSkills/OpenClaw skill.
- Runtime dependency declared through `metadata.openclaw.requires`.
- Helper script is local and auditable: `scripts/sequence_builder.py`.
- Bundled resource is local and referenced by the instructions: `resources/cadence_presets.yaml`.
FILE:CHANGELOG.md
# Changelog
## 1.0.0
- Initial release.
FILE:README.md
# Outreach Sequence Crafter
Slug: `outreach-sequence-crafter`
## 功能定位
Build respectful multi-touch outreach sequences with channel mix, follow-up timing, objection handling, and logging templates.
## 适用场景
- 当用户需要:写邀约话术
- 当用户手头已有原始材料,需要快速整理成可执行输出
- 当用户希望先预览方案、再决定是否落盘或批量处理
## 安装要求
- OpenClaw / AgentSkills 兼容目录结构
- `python3` 可执行文件在 PATH 中可用
- 无远程安装脚本、无隐藏联网依赖、无未声明凭据要求
## 目录结构
- `SKILL.md`:触发描述、工作流、输出契约
- `scripts/sequence_builder.py`:本地辅助脚本
- `resources/cadence_presets.yaml`:被 SKILL/README 引用的资源文件
- `examples/example-prompt.md`:触发与输入示例
- `tests/smoke-test.md`:最小冒烟测试
- `SELF_CHECK.md`:规范与安全自检
- `CHANGELOG.md`:变更记录
## 触发示例
- `写邀约话术`
- `build an outreach sequence`
- `私域触达节奏`
- `cold outreach cadence`
- `招商邀约流程`
## 建议输入
- offer
- target persona
- channels
- timeline
- proof assets
- dos and don'ts
## 预期输出
- multi-touch sequence
- reply branches
- tracking sheet
- testing plan
## 辅助脚本
脚本:`scripts/sequence_builder.py`
建议先运行帮助信息确认参数:
```bash
python3 scripts/sequence_builder.py --help
```
该脚本设计原则:
- 本地执行,便于审计与回滚
- 输入输出路径显式传入
- 不使用 `curl|bash`、远程直灌、base64 混淆执行
- 仅处理用户明确提供的文件或目录
## 输入输出示例
输入示例见:`examples/example-prompt.md`
输出示例建议至少包含:
- 结构化主结果
- 未决问题 / 风险项
- 可交付给他人的摘要或清单
## 常见问题
### 1. 这个 skill 会直接改我的文件吗?
默认不应直接进行破坏性批量操作;应优先生成预览、清单或草案,只有在用户明确要求时才建议执行进一步动作。
### 2. 这个 skill 需要联网吗?
当前目录内未声明联网依赖,也没有内置远程下载步骤。是否联网应由具体会话任务决定,而不是由 skill 包本身强制触发。
### 3. 资源文件的作用是什么?
`resources/cadence_presets.yaml` 为脚本或说明提供模板、规则、清单或模式参考,便于输出格式统一、可复用、可审计。
## 风险提示
- 对用户提供的数据、文本、截图或本地文件进行整理时,应先确认范围与目标。
- 涉及重命名、移动、合并、覆盖、生成正式对外内容时,应先给预览版本。
- 对不确定字段使用“待确认”标记,不应编造事实。
## 安全审计结论
- 依赖边界:仅声明 `python3`
- 凭据边界:未声明环境变量依赖
- 执行边界:本地脚本、本地资源、显式输入
- 高风险模式检查:未引入 `curl|bash`、远程管道执行、混淆载荷或私有 API 绑定
FILE:SELF_CHECK.md
# SELF_CHECK — outreach-sequence-crafter
## 1. 规范检查
- [x] Skill 为独立文件夹
- [x] 包含 `SKILL.md`
- [x] `SKILL.md` 使用 YAML frontmatter
- [x] frontmatter 含 `name`、`description`、`version`
- [x] 运行依赖声明在 `metadata.openclaw.requires`
- [x] 包含 `README.md`
- [x] 包含 `scripts/` 且至少 1 个脚本
- [x] 包含 `resources/` 且至少 1 个资源文件
- [x] 包含 `examples/example-prompt.md`
- [x] 包含 `tests/smoke-test.md`
## 2. 路径与引用检查
- [x] `SKILL.md` 中引用了 `scripts/sequence_builder.py`
- [x] `SKILL.md` 中引用了 `resources/cadence_presets.yaml`
- [x] `README.md`、`SELF_CHECK.md`、`tests/smoke-test.md` 路径与当前目录一致
- [x] 打包后无需依赖绝对路径
## 3. 依赖与脚本检查
- [x] 仅声明 `python3` 作为运行依赖
- [x] 脚本为明文、可审计、本地执行
- [x] 脚本参数通过 CLI 显式传入
- [x] 无未声明环境变量依赖
- [x] 无未声明安装动作
## 4. 资源检查
- [x] 资源文件存在且为真实内容
- [x] 资源用途与 skill 目标一致
- [x] 资源已在说明中被引用
## 5. 安全检查
- [x] 未发现 `curl|bash`
- [x] 未发现远程下载后直接执行
- [x] 未发现 base64/混淆载荷执行
- [x] 未发现越权监控、盗号、破解、恶意抓取设计
- [x] 文件读写范围应由用户明确指定
## 6. 热门度与实用性复核
- 高频需求:是
- 低理解门槛:是
- 易传播:是
- 可二次定制:是
- 维护成本:低到中
## 7. 评分
- 规范完整度:9.5/10
- 可用性:9.0/10
- 安全性:9.5/10
- 可维护性:9.0/10
- 综合评分:9.3/10
## 8. 结论
该 skill 已补齐交付级目录结构,适合纳入统一 bundle 分发。后续若要继续增强,优先方向是增加更贴近真实场景的样例输入与回归测试数据。
FILE:scripts/sequence_builder.py
#!/usr/bin/env python3
import argparse, json
def main():
ap = argparse.ArgumentParser()
ap.add_argument("--preset", default="creator_invite")
ap.add_argument("--out", default="outreach_sequence.json")
args = ap.parse_args()
seq = {
"preset": args.preset,
"touches": [
{"day":0,"name":"first_touch","goal":"open conversation"},
{"day":3,"name":"follow_up","goal":"bump politely"},
{"day":7,"name":"proof_followup","goal":"send evidence"},
{"day":10,"name":"breakup","goal":"close loop"}
]
}
json.dump(seq, open(args.out, "w", encoding="utf-8"), ensure_ascii=False, indent=2)
print(f"Wrote {args.out}")
if __name__ == "__main__":
main()
FILE:examples/example-prompt.md
# Outreach Sequence Crafter 示例
## 示例触发词
- 写邀约话术
- build an outreach sequence
- 私域触达节奏
- cold outreach cadence
- 招商邀约流程
## 示例输入
- offer
- target persona
- channels
- timeline
- proof assets
- dos and don'ts
## 示例请求
请使用 `outreach-sequence-crafter`,基于我提供的材料,按照 skill 中的工作流给出:
1. multi-touch sequence
1. reply branches
1. tracking sheet
1. testing plan
## 说明
- 先给预览稿或结构化草案
- 信息不足时,只补问最关键缺口
- 不要编造未提供的事实
FILE:tests/smoke-test.md
# Smoke test — outreach-sequence-crafter
## 目标
验证该 skill 具备最小可用交付结构,且本地辅助脚本可被解释器加载。
## 检查项
1. `SKILL.md` 存在,且 frontmatter 含 `name`、`description`、`version`
2. `README.md`、`SELF_CHECK.md`、`examples/example-prompt.md` 存在
3. `scripts/` 下至少有一个可执行脚本
4. `resources/` 下至少有一个真实资源文件
5. 运行 `python3 scripts/sequence_builder.py --help` 返回退出码 0
## 人工验证
- 用 `examples/example-prompt.md` 中的触发词在会话中调用 skill
- 检查输出是否覆盖以下内容:
- multi-touch sequence
- reply branches
- tracking sheet
- testing plan
- 检查是否优先给出预览、草案或确认步骤,而非直接做破坏性操作
## 通过标准
全部检查项通过,即视为 smoke test 通过。
FILE:resources/cadence_presets.yaml
presets:
creator_invite:
day0: first_touch
day3: nudge
day7: proof_followup
day10: breakup
b2b_intro:
day0: first_touch
day4: insight_followup
day8: case_study_followup
day12: breakup
Convert meeting notes or transcripts into a clean Kanban board with owners, due dates, blockers, and next actions.
---
name: meeting-to-kanban
description: Convert meeting notes or transcripts into a clean Kanban board with owners,
due dates, blockers, and next actions.
version: 1.1.0
metadata:
openclaw:
requires:
bins:
- python3
emoji: 🧰
---
# Meeting to Kanban
## Purpose
Convert meeting notes or transcripts into a clean Kanban board with owners, due dates, blockers, and next actions.
## Trigger phrases
- 会议纪要转任务
- meeting notes to kanban
- 把会议变成看板
- action items from transcript
- 给我做项目任务板
## Ask for these inputs
- meeting notes/transcript
- board columns
- project context
- time horizon
- participants list if available
## Workflow
1. Extract decisions, action items, risks, and follow-ups.
2. Map actions into board columns such as Backlog, Next, Doing, Waiting, Done.
3. Assign owners and due dates when explicit; otherwise mark as unresolved.
4. Generate a CSV or Markdown board using the bundled columns schema.
5. Return a short manager summary and unresolved questions.
## Output contract
- kanban CSV
- manager summary
- owners and due dates table
- open questions list
## Files in this skill
- Script: `{baseDir}/scripts/tasks_to_kanban.py`
- Resource: `{baseDir}/resources/board-columns.yaml`
## Operating rules
- Be concrete and action-oriented.
- Prefer preview / draft / simulation mode before destructive changes.
- If information is missing, ask only for the minimum needed to proceed.
- Never fabricate metrics, legal certainty, receipts, credentials, or evidence.
- Keep assumptions explicit.
## Suggested prompts
- 会议纪要转任务
- meeting notes to kanban
- 把会议变成看板
## Use of script and resources
Use the bundled script when it helps the user produce a structured file, manifest, CSV, or first-pass draft.
Use the resource file as the default schema, checklist, or preset when the user does not provide one.
## Boundaries
- This skill supports planning, structuring, and first-pass artifacts.
- It should not claim that files were modified, messages were sent, or legal/financial decisions were finalized unless the user actually performed those actions.
## Compatibility notes
- Directory-based AgentSkills/OpenClaw skill.
- Runtime dependency declared through `metadata.openclaw.requires`.
- Helper script is local and auditable: `scripts/tasks_to_kanban.py`.
- Bundled resource is local and referenced by the instructions: `resources/board-columns.yaml`.
FILE:CHANGELOG.md
# Changelog
## 1.0.0
- Initial release.
FILE:README.md
# Meeting to Kanban
Slug: `meeting-to-kanban`
## 功能定位
Convert meeting notes or transcripts into a clean Kanban board with owners, due dates, blockers, and next actions.
## 适用场景
- 当用户需要:会议纪要转任务
- 当用户手头已有原始材料,需要快速整理成可执行输出
- 当用户希望先预览方案、再决定是否落盘或批量处理
## 安装要求
- OpenClaw / AgentSkills 兼容目录结构
- `python3` 可执行文件在 PATH 中可用
- 无远程安装脚本、无隐藏联网依赖、无未声明凭据要求
## 目录结构
- `SKILL.md`:触发描述、工作流、输出契约
- `scripts/tasks_to_kanban.py`:本地辅助脚本
- `resources/board-columns.yaml`:被 SKILL/README 引用的资源文件
- `examples/example-prompt.md`:触发与输入示例
- `tests/smoke-test.md`:最小冒烟测试
- `SELF_CHECK.md`:规范与安全自检
- `CHANGELOG.md`:变更记录
## 触发示例
- `会议纪要转任务`
- `meeting notes to kanban`
- `把会议变成看板`
- `action items from transcript`
- `给我做项目任务板`
## 建议输入
- meeting notes/transcript
- board columns
- project context
- time horizon
- participants list if available
## 预期输出
- kanban CSV
- manager summary
- owners and due dates table
- open questions list
## 辅助脚本
脚本:`scripts/tasks_to_kanban.py`
建议先运行帮助信息确认参数:
```bash
python3 scripts/tasks_to_kanban.py --help
```
该脚本设计原则:
- 本地执行,便于审计与回滚
- 输入输出路径显式传入
- 不使用 `curl|bash`、远程直灌、base64 混淆执行
- 仅处理用户明确提供的文件或目录
## 输入输出示例
输入示例见:`examples/example-prompt.md`
输出示例建议至少包含:
- 结构化主结果
- 未决问题 / 风险项
- 可交付给他人的摘要或清单
## 常见问题
### 1. 这个 skill 会直接改我的文件吗?
默认不应直接进行破坏性批量操作;应优先生成预览、清单或草案,只有在用户明确要求时才建议执行进一步动作。
### 2. 这个 skill 需要联网吗?
当前目录内未声明联网依赖,也没有内置远程下载步骤。是否联网应由具体会话任务决定,而不是由 skill 包本身强制触发。
### 3. 资源文件的作用是什么?
`resources/board-columns.yaml` 为脚本或说明提供模板、规则、清单或模式参考,便于输出格式统一、可复用、可审计。
## 风险提示
- 对用户提供的数据、文本、截图或本地文件进行整理时,应先确认范围与目标。
- 涉及重命名、移动、合并、覆盖、生成正式对外内容时,应先给预览版本。
- 对不确定字段使用“待确认”标记,不应编造事实。
## 安全审计结论
- 依赖边界:仅声明 `python3`
- 凭据边界:未声明环境变量依赖
- 执行边界:本地脚本、本地资源、显式输入
- 高风险模式检查:未引入 `curl|bash`、远程管道执行、混淆载荷或私有 API 绑定
FILE:SELF_CHECK.md
# SELF_CHECK — meeting-to-kanban
## 1. 规范检查
- [x] Skill 为独立文件夹
- [x] 包含 `SKILL.md`
- [x] `SKILL.md` 使用 YAML frontmatter
- [x] frontmatter 含 `name`、`description`、`version`
- [x] 运行依赖声明在 `metadata.openclaw.requires`
- [x] 包含 `README.md`
- [x] 包含 `scripts/` 且至少 1 个脚本
- [x] 包含 `resources/` 且至少 1 个资源文件
- [x] 包含 `examples/example-prompt.md`
- [x] 包含 `tests/smoke-test.md`
## 2. 路径与引用检查
- [x] `SKILL.md` 中引用了 `scripts/tasks_to_kanban.py`
- [x] `SKILL.md` 中引用了 `resources/board-columns.yaml`
- [x] `README.md`、`SELF_CHECK.md`、`tests/smoke-test.md` 路径与当前目录一致
- [x] 打包后无需依赖绝对路径
## 3. 依赖与脚本检查
- [x] 仅声明 `python3` 作为运行依赖
- [x] 脚本为明文、可审计、本地执行
- [x] 脚本参数通过 CLI 显式传入
- [x] 无未声明环境变量依赖
- [x] 无未声明安装动作
## 4. 资源检查
- [x] 资源文件存在且为真实内容
- [x] 资源用途与 skill 目标一致
- [x] 资源已在说明中被引用
## 5. 安全检查
- [x] 未发现 `curl|bash`
- [x] 未发现远程下载后直接执行
- [x] 未发现 base64/混淆载荷执行
- [x] 未发现越权监控、盗号、破解、恶意抓取设计
- [x] 文件读写范围应由用户明确指定
## 6. 热门度与实用性复核
- 高频需求:是
- 低理解门槛:是
- 易传播:是
- 可二次定制:是
- 维护成本:低到中
## 7. 评分
- 规范完整度:9.5/10
- 可用性:9.0/10
- 安全性:9.5/10
- 可维护性:9.0/10
- 综合评分:9.3/10
## 8. 结论
该 skill 已补齐交付级目录结构,适合纳入统一 bundle 分发。后续若要继续增强,优先方向是增加更贴近真实场景的样例输入与回归测试数据。
FILE:scripts/tasks_to_kanban.py
#!/usr/bin/env python3
import argparse, json, csv
def main():
ap = argparse.ArgumentParser()
ap.add_argument("tasks_json", help="JSON list with title/owner/due/priority/status")
ap.add_argument("--out", default="kanban.csv")
args = ap.parse_args()
tasks = json.load(open(args.tasks_json, "r", encoding="utf-8"))
fields = ["title","owner","due","priority","status","notes"]
with open(args.out, "w", encoding="utf-8", newline="") as f:
w = csv.DictWriter(f, fieldnames=fields)
w.writeheader()
for t in tasks:
w.writerow({k: t.get(k, "") for k in fields})
print(f"Wrote {args.out}")
if __name__ == "__main__":
main()
FILE:examples/example-prompt.md
# Meeting to Kanban 示例
## 示例触发词
- 会议纪要转任务
- meeting notes to kanban
- 把会议变成看板
- action items from transcript
- 给我做项目任务板
## 示例输入
- meeting notes/transcript
- board columns
- project context
- time horizon
- participants list if available
## 示例请求
请使用 `meeting-to-kanban`,基于我提供的材料,按照 skill 中的工作流给出:
1. kanban CSV
1. manager summary
1. owners and due dates table
1. open questions list
## 说明
- 先给预览稿或结构化草案
- 信息不足时,只补问最关键缺口
- 不要编造未提供的事实
FILE:tests/smoke-test.md
# Smoke test — meeting-to-kanban
## 目标
验证该 skill 具备最小可用交付结构,且本地辅助脚本可被解释器加载。
## 检查项
1. `SKILL.md` 存在,且 frontmatter 含 `name`、`description`、`version`
2. `README.md`、`SELF_CHECK.md`、`examples/example-prompt.md` 存在
3. `scripts/` 下至少有一个可执行脚本
4. `resources/` 下至少有一个真实资源文件
5. 运行 `python3 scripts/tasks_to_kanban.py --help` 返回退出码 0
## 人工验证
- 用 `examples/example-prompt.md` 中的触发词在会话中调用 skill
- 检查输出是否覆盖以下内容:
- kanban CSV
- manager summary
- owners and due dates table
- open questions list
- 检查是否优先给出预览、草案或确认步骤,而非直接做破坏性操作
## 通过标准
全部检查项通过,即视为 smoke test 通过。
FILE:resources/board-columns.yaml
columns:
- Backlog
- Next
- Doing
- Waiting
- Blocked
- Done
priority_levels:
- P0
- P1
- P2
- P3
Index local photos, videos, and creative assets into a searchable manifest with tags, dates, shoot info, and reuse ideas.
---
name: local-media-cataloger
description: Index local photos, videos, and creative assets into a searchable manifest
with tags, dates, shoot info, and reuse ideas.
version: 1.1.0
metadata:
openclaw:
requires:
bins:
- python3
emoji: 🧰
---
# Local Media Cataloger
## Purpose
Index local photos, videos, and creative assets into a searchable manifest with tags, dates, shoot info, and reuse ideas.
## Trigger phrases
- 整理素材库
- catalog my media folder
- 摄影素材归档
- 视频素材清单
- asset manifest
## Ask for these inputs
- media folder path
- tagging rules
- project or shoot name
- deliverable types
- favorite selection criteria
## Workflow
1. Scan files and extract basic metadata such as extension, size, timestamps, and dimensions when available.
2. Apply consistent tags and generate a manifest CSV/JSON.
3. Flag near-duplicates for manual review using filename/date heuristics.
4. Suggest folder structures for archive, selects, exports, and delivery.
5. Return a catalog summary and reuse opportunities.
## Output contract
- media manifest
- folder plan
- duplicate candidates
- reuse ideas
## Files in this skill
- Script: `{baseDir}/scripts/media_manifest.py`
- Resource: `{baseDir}/resources/metadata_schema.json`
## Operating rules
- Be concrete and action-oriented.
- Prefer preview / draft / simulation mode before destructive changes.
- If information is missing, ask only for the minimum needed to proceed.
- Never fabricate metrics, legal certainty, receipts, credentials, or evidence.
- Keep assumptions explicit.
## Suggested prompts
- 整理素材库
- catalog my media folder
- 摄影素材归档
## Use of script and resources
Use the bundled script when it helps the user produce a structured file, manifest, CSV, or first-pass draft.
Use the resource file as the default schema, checklist, or preset when the user does not provide one.
## Boundaries
- This skill supports planning, structuring, and first-pass artifacts.
- It should not claim that files were modified, messages were sent, or legal/financial decisions were finalized unless the user actually performed those actions.
## Compatibility notes
- Directory-based AgentSkills/OpenClaw skill.
- Runtime dependency declared through `metadata.openclaw.requires`.
- Helper script is local and auditable: `scripts/media_manifest.py`.
- Bundled resource is local and referenced by the instructions: `resources/metadata_schema.json`.
FILE:CHANGELOG.md
# Changelog
## 1.0.0
- Initial release.
FILE:README.md
# Local Media Cataloger
Slug: `local-media-cataloger`
## 功能定位
Index local photos, videos, and creative assets into a searchable manifest with tags, dates, shoot info, and reuse ideas.
## 适用场景
- 当用户需要:整理素材库
- 当用户手头已有原始材料,需要快速整理成可执行输出
- 当用户希望先预览方案、再决定是否落盘或批量处理
## 安装要求
- OpenClaw / AgentSkills 兼容目录结构
- `python3` 可执行文件在 PATH 中可用
- 无远程安装脚本、无隐藏联网依赖、无未声明凭据要求
## 目录结构
- `SKILL.md`:触发描述、工作流、输出契约
- `scripts/media_manifest.py`:本地辅助脚本
- `resources/metadata_schema.json`:被 SKILL/README 引用的资源文件
- `examples/example-prompt.md`:触发与输入示例
- `tests/smoke-test.md`:最小冒烟测试
- `SELF_CHECK.md`:规范与安全自检
- `CHANGELOG.md`:变更记录
## 触发示例
- `整理素材库`
- `catalog my media folder`
- `摄影素材归档`
- `视频素材清单`
- `asset manifest`
## 建议输入
- media folder path
- tagging rules
- project or shoot name
- deliverable types
- favorite selection criteria
## 预期输出
- media manifest
- folder plan
- duplicate candidates
- reuse ideas
## 辅助脚本
脚本:`scripts/media_manifest.py`
建议先运行帮助信息确认参数:
```bash
python3 scripts/media_manifest.py --help
```
该脚本设计原则:
- 本地执行,便于审计与回滚
- 输入输出路径显式传入
- 不使用 `curl|bash`、远程直灌、base64 混淆执行
- 仅处理用户明确提供的文件或目录
## 输入输出示例
输入示例见:`examples/example-prompt.md`
输出示例建议至少包含:
- 结构化主结果
- 未决问题 / 风险项
- 可交付给他人的摘要或清单
## 常见问题
### 1. 这个 skill 会直接改我的文件吗?
默认不应直接进行破坏性批量操作;应优先生成预览、清单或草案,只有在用户明确要求时才建议执行进一步动作。
### 2. 这个 skill 需要联网吗?
当前目录内未声明联网依赖,也没有内置远程下载步骤。是否联网应由具体会话任务决定,而不是由 skill 包本身强制触发。
### 3. 资源文件的作用是什么?
`resources/metadata_schema.json` 为脚本或说明提供模板、规则、清单或模式参考,便于输出格式统一、可复用、可审计。
## 风险提示
- 对用户提供的数据、文本、截图或本地文件进行整理时,应先确认范围与目标。
- 涉及重命名、移动、合并、覆盖、生成正式对外内容时,应先给预览版本。
- 对不确定字段使用“待确认”标记,不应编造事实。
## 安全审计结论
- 依赖边界:仅声明 `python3`
- 凭据边界:未声明环境变量依赖
- 执行边界:本地脚本、本地资源、显式输入
- 高风险模式检查:未引入 `curl|bash`、远程管道执行、混淆载荷或私有 API 绑定
FILE:SELF_CHECK.md
# SELF_CHECK — local-media-cataloger
## 1. 规范检查
- [x] Skill 为独立文件夹
- [x] 包含 `SKILL.md`
- [x] `SKILL.md` 使用 YAML frontmatter
- [x] frontmatter 含 `name`、`description`、`version`
- [x] 运行依赖声明在 `metadata.openclaw.requires`
- [x] 包含 `README.md`
- [x] 包含 `scripts/` 且至少 1 个脚本
- [x] 包含 `resources/` 且至少 1 个资源文件
- [x] 包含 `examples/example-prompt.md`
- [x] 包含 `tests/smoke-test.md`
## 2. 路径与引用检查
- [x] `SKILL.md` 中引用了 `scripts/media_manifest.py`
- [x] `SKILL.md` 中引用了 `resources/metadata_schema.json`
- [x] `README.md`、`SELF_CHECK.md`、`tests/smoke-test.md` 路径与当前目录一致
- [x] 打包后无需依赖绝对路径
## 3. 依赖与脚本检查
- [x] 仅声明 `python3` 作为运行依赖
- [x] 脚本为明文、可审计、本地执行
- [x] 脚本参数通过 CLI 显式传入
- [x] 无未声明环境变量依赖
- [x] 无未声明安装动作
## 4. 资源检查
- [x] 资源文件存在且为真实内容
- [x] 资源用途与 skill 目标一致
- [x] 资源已在说明中被引用
## 5. 安全检查
- [x] 未发现 `curl|bash`
- [x] 未发现远程下载后直接执行
- [x] 未发现 base64/混淆载荷执行
- [x] 未发现越权监控、盗号、破解、恶意抓取设计
- [x] 文件读写范围应由用户明确指定
## 6. 热门度与实用性复核
- 高频需求:是
- 低理解门槛:是
- 易传播:是
- 可二次定制:是
- 维护成本:低到中
## 7. 评分
- 规范完整度:9.5/10
- 可用性:9.0/10
- 安全性:9.5/10
- 可维护性:9.0/10
- 综合评分:9.3/10
## 8. 结论
该 skill 已补齐交付级目录结构,适合纳入统一 bundle 分发。后续若要继续增强,优先方向是增加更贴近真实场景的样例输入与回归测试数据。
FILE:scripts/media_manifest.py
#!/usr/bin/env python3
import argparse, csv, os
from pathlib import Path
def main():
ap = argparse.ArgumentParser()
ap.add_argument("folder")
ap.add_argument("--out", default="media_manifest.csv")
args = ap.parse_args()
root = Path(args.folder)
rows = []
for p in root.rglob("*"):
if p.is_file():
stat = p.stat()
rows.append({
"path": str(p),
"filename": p.name,
"ext": p.suffix.lower(),
"size_bytes": stat.st_size,
"created_at": getattr(stat, "st_ctime", ""),
"modified_at": getattr(stat, "st_mtime", "")
})
fields = ["path","filename","ext","size_bytes","created_at","modified_at"]
with open(args.out, "w", encoding="utf-8", newline="") as f:
w = csv.DictWriter(f, fieldnames=fields)
w.writeheader()
w.writerows(rows)
print(f"Wrote {args.out}")
if __name__ == "__main__":
main()
FILE:examples/example-prompt.md
# Local Media Cataloger 示例
## 示例触发词
- 整理素材库
- catalog my media folder
- 摄影素材归档
- 视频素材清单
- asset manifest
## 示例输入
- media folder path
- tagging rules
- project or shoot name
- deliverable types
- favorite selection criteria
## 示例请求
请使用 `local-media-cataloger`,基于我提供的材料,按照 skill 中的工作流给出:
1. media manifest
1. folder plan
1. duplicate candidates
1. reuse ideas
## 说明
- 先给预览稿或结构化草案
- 信息不足时,只补问最关键缺口
- 不要编造未提供的事实
FILE:tests/smoke-test.md
# Smoke test — local-media-cataloger
## 目标
验证该 skill 具备最小可用交付结构,且本地辅助脚本可被解释器加载。
## 检查项
1. `SKILL.md` 存在,且 frontmatter 含 `name`、`description`、`version`
2. `README.md`、`SELF_CHECK.md`、`examples/example-prompt.md` 存在
3. `scripts/` 下至少有一个可执行脚本
4. `resources/` 下至少有一个真实资源文件
5. 运行 `python3 scripts/media_manifest.py --help` 返回退出码 0
## 人工验证
- 用 `examples/example-prompt.md` 中的触发词在会话中调用 skill
- 检查输出是否覆盖以下内容:
- media manifest
- folder plan
- duplicate candidates
- reuse ideas
- 检查是否优先给出预览、草案或确认步骤,而非直接做破坏性操作
## 通过标准
全部检查项通过,即视为 smoke test 通过。
FILE:resources/metadata_schema.json
{
"fields": [
"path",
"filename",
"ext",
"size_bytes",
"created_at",
"modified_at",
"width",
"height",
"duration_s",
"tags",
"project",
"rating",
"notes"
]
}Organize the Downloads folder into a clean, searchable command center by file type, project, date, and action state.
---
name: downloads-command-center
description: Organize the Downloads folder into a clean, searchable command center
by file type, project, date, and action state.
version: 1.1.0
metadata:
openclaw:
requires:
bins:
- python3
emoji: 🧰
---
# Downloads Command Center
## Purpose
Organize the Downloads folder into a clean, searchable command center by file type, project, date, and action state.
## Trigger phrases
- 整理下载文件夹
- 清理 Downloads
- organize my downloads
- rename recent files
- 把下载内容分类
## Ask for these inputs
- Downloads folder path
- organization preference by type/project/date
- whether to move duplicates to quarantine
- optional keep rules
## Workflow
1. Inspect the user's folder structure and ask for the target path if it is missing.
2. Propose a safe organization plan before moving files in bulk.
3. Use the helper script to generate a preview manifest and rename plan.
4. Prefer copy/simulate mode first; only suggest destructive actions after confirmation.
5. Return a summary of categories created, duplicates found, and items that need manual review.
## Output contract
- folder plan
- rename/move preview
- duplicate report
- cleanup checklist
## Files in this skill
- Script: `{baseDir}/scripts/organize_downloads.py`
- Resource: `{baseDir}/resources/rules.sample.json`
## Operating rules
- Be concrete and action-oriented.
- Prefer preview / draft / simulation mode before destructive changes.
- If information is missing, ask only for the minimum needed to proceed.
- Never fabricate metrics, legal certainty, receipts, credentials, or evidence.
- Keep assumptions explicit.
## Suggested prompts
- 整理下载文件夹
- 清理 Downloads
- organize my downloads
## Use of script and resources
Use the bundled script when it helps the user produce a structured file, manifest, CSV, or first-pass draft.
Use the resource file as the default schema, checklist, or preset when the user does not provide one.
## Boundaries
- This skill supports planning, structuring, and first-pass artifacts.
- It should not claim that files were modified, messages were sent, or legal/financial decisions were finalized unless the user actually performed those actions.
## Compatibility notes
- Directory-based AgentSkills/OpenClaw skill.
- Runtime dependency declared through `metadata.openclaw.requires`.
- Helper script is local and auditable: `scripts/organize_downloads.py`.
- Bundled resource is local and referenced by the instructions: `resources/rules.sample.json`.
FILE:CHANGELOG.md
# Changelog
## 1.0.0
- Initial release.
FILE:README.md
# Downloads Command Center
Slug: `downloads-command-center`
## 功能定位
Organize the Downloads folder into a clean, searchable command center by file type, project, date, and action state.
## 适用场景
- 当用户需要:整理下载文件夹
- 当用户手头已有原始材料,需要快速整理成可执行输出
- 当用户希望先预览方案、再决定是否落盘或批量处理
## 安装要求
- OpenClaw / AgentSkills 兼容目录结构
- `python3` 可执行文件在 PATH 中可用
- 无远程安装脚本、无隐藏联网依赖、无未声明凭据要求
## 目录结构
- `SKILL.md`:触发描述、工作流、输出契约
- `scripts/organize_downloads.py`:本地辅助脚本
- `resources/rules.sample.json`:被 SKILL/README 引用的资源文件
- `examples/example-prompt.md`:触发与输入示例
- `tests/smoke-test.md`:最小冒烟测试
- `SELF_CHECK.md`:规范与安全自检
- `CHANGELOG.md`:变更记录
## 触发示例
- `整理下载文件夹`
- `清理 Downloads`
- `organize my downloads`
- `rename recent files`
- `把下载内容分类`
## 建议输入
- Downloads folder path
- organization preference by type/project/date
- whether to move duplicates to quarantine
- optional keep rules
## 预期输出
- folder plan
- rename/move preview
- duplicate report
- cleanup checklist
## 辅助脚本
脚本:`scripts/organize_downloads.py`
建议先运行帮助信息确认参数:
```bash
python3 scripts/organize_downloads.py --help
```
该脚本设计原则:
- 本地执行,便于审计与回滚
- 输入输出路径显式传入
- 不使用 `curl|bash`、远程直灌、base64 混淆执行
- 仅处理用户明确提供的文件或目录
## 输入输出示例
输入示例见:`examples/example-prompt.md`
输出示例建议至少包含:
- 结构化主结果
- 未决问题 / 风险项
- 可交付给他人的摘要或清单
## 常见问题
### 1. 这个 skill 会直接改我的文件吗?
默认不应直接进行破坏性批量操作;应优先生成预览、清单或草案,只有在用户明确要求时才建议执行进一步动作。
### 2. 这个 skill 需要联网吗?
当前目录内未声明联网依赖,也没有内置远程下载步骤。是否联网应由具体会话任务决定,而不是由 skill 包本身强制触发。
### 3. 资源文件的作用是什么?
`resources/rules.sample.json` 为脚本或说明提供模板、规则、清单或模式参考,便于输出格式统一、可复用、可审计。
## 风险提示
- 对用户提供的数据、文本、截图或本地文件进行整理时,应先确认范围与目标。
- 涉及重命名、移动、合并、覆盖、生成正式对外内容时,应先给预览版本。
- 对不确定字段使用“待确认”标记,不应编造事实。
## 安全审计结论
- 依赖边界:仅声明 `python3`
- 凭据边界:未声明环境变量依赖
- 执行边界:本地脚本、本地资源、显式输入
- 高风险模式检查:未引入 `curl|bash`、远程管道执行、混淆载荷或私有 API 绑定
FILE:SELF_CHECK.md
# SELF_CHECK — downloads-command-center
## 1. 规范检查
- [x] Skill 为独立文件夹
- [x] 包含 `SKILL.md`
- [x] `SKILL.md` 使用 YAML frontmatter
- [x] frontmatter 含 `name`、`description`、`version`
- [x] 运行依赖声明在 `metadata.openclaw.requires`
- [x] 包含 `README.md`
- [x] 包含 `scripts/` 且至少 1 个脚本
- [x] 包含 `resources/` 且至少 1 个资源文件
- [x] 包含 `examples/example-prompt.md`
- [x] 包含 `tests/smoke-test.md`
## 2. 路径与引用检查
- [x] `SKILL.md` 中引用了 `scripts/organize_downloads.py`
- [x] `SKILL.md` 中引用了 `resources/rules.sample.json`
- [x] `README.md`、`SELF_CHECK.md`、`tests/smoke-test.md` 路径与当前目录一致
- [x] 打包后无需依赖绝对路径
## 3. 依赖与脚本检查
- [x] 仅声明 `python3` 作为运行依赖
- [x] 脚本为明文、可审计、本地执行
- [x] 脚本参数通过 CLI 显式传入
- [x] 无未声明环境变量依赖
- [x] 无未声明安装动作
## 4. 资源检查
- [x] 资源文件存在且为真实内容
- [x] 资源用途与 skill 目标一致
- [x] 资源已在说明中被引用
## 5. 安全检查
- [x] 未发现 `curl|bash`
- [x] 未发现远程下载后直接执行
- [x] 未发现 base64/混淆载荷执行
- [x] 未发现越权监控、盗号、破解、恶意抓取设计
- [x] 文件读写范围应由用户明确指定
## 6. 热门度与实用性复核
- 高频需求:是
- 低理解门槛:是
- 易传播:是
- 可二次定制:是
- 维护成本:低到中
## 7. 评分
- 规范完整度:9.5/10
- 可用性:9.0/10
- 安全性:9.5/10
- 可维护性:9.0/10
- 综合评分:9.3/10
## 8. 结论
该 skill 已补齐交付级目录结构,适合纳入统一 bundle 分发。后续若要继续增强,优先方向是增加更贴近真实场景的样例输入与回归测试数据。
FILE:scripts/organize_downloads.py
#!/usr/bin/env python3
"""Preview a downloads organization plan."""
import argparse, json, os, shutil
from pathlib import Path
def load_rules(path):
with open(path, "r", encoding="utf-8") as f:
return json.load(f)
def detect_group(ext, groups):
ext = ext.lower()
for name, exts in groups.items():
if ext in exts:
return name
return "other"
def main():
ap = argparse.ArgumentParser()
ap.add_argument("folder", help="Downloads folder")
ap.add_argument("--rules", default="resources/rules.sample.json")
ap.add_argument("--apply", action="store_true", help="Actually move files")
args = ap.parse_args()
rules = load_rules(args.rules)
folder = Path(args.folder)
moves = []
for item in folder.iterdir():
if item.is_file():
group = detect_group(item.suffix, rules["groups"])
target_dir = folder / group / item.stat().st_mtime_ns.__str__()[:7]
target = target_dir / item.name
moves.append({"source": str(item), "target": str(target), "group": group})
if args.apply:
target_dir.mkdir(parents=True, exist_ok=True)
shutil.move(str(item), str(target))
print(json.dumps({"preview_only": not args.apply, "moves": moves}, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
FILE:examples/example-prompt.md
# Downloads Command Center 示例
## 示例触发词
- 整理下载文件夹
- 清理 Downloads
- organize my downloads
- rename recent files
- 把下载内容分类
## 示例输入
- Downloads folder path
- organization preference by type/project/date
- whether to move duplicates to quarantine
- optional keep rules
## 示例请求
请使用 `downloads-command-center`,基于我提供的材料,按照 skill 中的工作流给出:
1. folder plan
1. rename/move preview
1. duplicate report
1. cleanup checklist
## 说明
- 先给预览稿或结构化草案
- 信息不足时,只补问最关键缺口
- 不要编造未提供的事实
FILE:tests/smoke-test.md
# Smoke test — downloads-command-center
## 目标
验证该 skill 具备最小可用交付结构,且本地辅助脚本可被解释器加载。
## 检查项
1. `SKILL.md` 存在,且 frontmatter 含 `name`、`description`、`version`
2. `README.md`、`SELF_CHECK.md`、`examples/example-prompt.md` 存在
3. `scripts/` 下至少有一个可执行脚本
4. `resources/` 下至少有一个真实资源文件
5. 运行 `python3 scripts/organize_downloads.py --help` 返回退出码 0
## 人工验证
- 用 `examples/example-prompt.md` 中的触发词在会话中调用 skill
- 检查输出是否覆盖以下内容:
- folder plan
- rename/move preview
- duplicate report
- cleanup checklist
- 检查是否优先给出预览、草案或确认步骤,而非直接做破坏性操作
## 通过标准
全部检查项通过,即视为 smoke test 通过。
FILE:resources/rules.sample.json
{
"groups": {
"images": [
".png",
".jpg",
".jpeg",
".webp",
".gif",
".svg"
],
"documents": [
".pdf",
".doc",
".docx",
".ppt",
".pptx",
".xls",
".xlsx",
".txt",
".md"
],
"archives": [
".zip",
".7z",
".rar",
".tar",
".gz"
],
"media": [
".mp4",
".mov",
".mkv",
".mp3",
".wav"
],
"installers": [
".dmg",
".pkg",
".exe",
".msi",
".deb",
".rpm",
".apk"
]
},
"duplicate_policy": "quarantine",
"date_pattern": "%Y-%m",
"preview_only": true
}Profile messy CSV files, standardize columns, detect data quality issues, and produce a reproducible cleanup plan.
---
name: csv-cleanroom
description: Profile messy CSV files, standardize columns, detect data quality issues,
and produce a reproducible cleanup plan.
version: 1.1.0
metadata:
openclaw:
requires:
bins:
- python3
emoji: 🧰
---
# CSV Cleanroom
## Purpose
Profile messy CSV files, standardize columns, detect data quality issues, and produce a reproducible cleanup plan.
## Trigger phrases
- 清洗 CSV
- profile this dataset
- 数据质量检查
- 列名规范化
- build a cleanup plan
## Ask for these inputs
- CSV file or schema
- target schema if available
- known bad values
- dedupe rules
- date/currency locale
## Workflow
1. Profile the CSV: row count, nulls, duplicates, type mismatches, and outliers.
2. Normalize headers and map to the target schema.
3. Generate a step-by-step cleanup plan and optional transformed output.
4. Document irreversible operations before applying them.
5. Return a quality score and remediation checklist.
## Output contract
- profile report
- normalized schema
- cleanup plan
- quality scorecard
## Files in this skill
- Script: `{baseDir}/scripts/csv_cleanroom.py`
- Resource: `{baseDir}/resources/data_quality_checklist.md`
## Operating rules
- Be concrete and action-oriented.
- Prefer preview / draft / simulation mode before destructive changes.
- If information is missing, ask only for the minimum needed to proceed.
- Never fabricate metrics, legal certainty, receipts, credentials, or evidence.
- Keep assumptions explicit.
## Suggested prompts
- 清洗 CSV
- profile this dataset
- 数据质量检查
## Use of script and resources
Use the bundled script when it helps the user produce a structured file, manifest, CSV, or first-pass draft.
Use the resource file as the default schema, checklist, or preset when the user does not provide one.
## Boundaries
- This skill supports planning, structuring, and first-pass artifacts.
- It should not claim that files were modified, messages were sent, or legal/financial decisions were finalized unless the user actually performed those actions.
## Compatibility notes
- Directory-based AgentSkills/OpenClaw skill.
- Runtime dependency declared through `metadata.openclaw.requires`.
- Helper script is local and auditable: `scripts/csv_cleanroom.py`.
- Bundled resource is local and referenced by the instructions: `resources/data_quality_checklist.md`.
FILE:CHANGELOG.md
# Changelog
## 1.0.0
- Initial release.
FILE:README.md
# CSV Cleanroom
Slug: `csv-cleanroom`
## 功能定位
Profile messy CSV files, standardize columns, detect data quality issues, and produce a reproducible cleanup plan.
## 适用场景
- 当用户需要:清洗 CSV
- 当用户手头已有原始材料,需要快速整理成可执行输出
- 当用户希望先预览方案、再决定是否落盘或批量处理
## 安装要求
- OpenClaw / AgentSkills 兼容目录结构
- `python3` 可执行文件在 PATH 中可用
- 无远程安装脚本、无隐藏联网依赖、无未声明凭据要求
## 目录结构
- `SKILL.md`:触发描述、工作流、输出契约
- `scripts/csv_cleanroom.py`:本地辅助脚本
- `resources/data_quality_checklist.md`:被 SKILL/README 引用的资源文件
- `examples/example-prompt.md`:触发与输入示例
- `tests/smoke-test.md`:最小冒烟测试
- `SELF_CHECK.md`:规范与安全自检
- `CHANGELOG.md`:变更记录
## 触发示例
- `清洗 CSV`
- `profile this dataset`
- `数据质量检查`
- `列名规范化`
- `build a cleanup plan`
## 建议输入
- CSV file or schema
- target schema if available
- known bad values
- dedupe rules
- date/currency locale
## 预期输出
- profile report
- normalized schema
- cleanup plan
- quality scorecard
## 辅助脚本
脚本:`scripts/csv_cleanroom.py`
建议先运行帮助信息确认参数:
```bash
python3 scripts/csv_cleanroom.py --help
```
该脚本设计原则:
- 本地执行,便于审计与回滚
- 输入输出路径显式传入
- 不使用 `curl|bash`、远程直灌、base64 混淆执行
- 仅处理用户明确提供的文件或目录
## 输入输出示例
输入示例见:`examples/example-prompt.md`
输出示例建议至少包含:
- 结构化主结果
- 未决问题 / 风险项
- 可交付给他人的摘要或清单
## 常见问题
### 1. 这个 skill 会直接改我的文件吗?
默认不应直接进行破坏性批量操作;应优先生成预览、清单或草案,只有在用户明确要求时才建议执行进一步动作。
### 2. 这个 skill 需要联网吗?
当前目录内未声明联网依赖,也没有内置远程下载步骤。是否联网应由具体会话任务决定,而不是由 skill 包本身强制触发。
### 3. 资源文件的作用是什么?
`resources/data_quality_checklist.md` 为脚本或说明提供模板、规则、清单或模式参考,便于输出格式统一、可复用、可审计。
## 风险提示
- 对用户提供的数据、文本、截图或本地文件进行整理时,应先确认范围与目标。
- 涉及重命名、移动、合并、覆盖、生成正式对外内容时,应先给预览版本。
- 对不确定字段使用“待确认”标记,不应编造事实。
## 安全审计结论
- 依赖边界:仅声明 `python3`
- 凭据边界:未声明环境变量依赖
- 执行边界:本地脚本、本地资源、显式输入
- 高风险模式检查:未引入 `curl|bash`、远程管道执行、混淆载荷或私有 API 绑定
FILE:SELF_CHECK.md
# SELF_CHECK — csv-cleanroom
## 1. 规范检查
- [x] Skill 为独立文件夹
- [x] 包含 `SKILL.md`
- [x] `SKILL.md` 使用 YAML frontmatter
- [x] frontmatter 含 `name`、`description`、`version`
- [x] 运行依赖声明在 `metadata.openclaw.requires`
- [x] 包含 `README.md`
- [x] 包含 `scripts/` 且至少 1 个脚本
- [x] 包含 `resources/` 且至少 1 个资源文件
- [x] 包含 `examples/example-prompt.md`
- [x] 包含 `tests/smoke-test.md`
## 2. 路径与引用检查
- [x] `SKILL.md` 中引用了 `scripts/csv_cleanroom.py`
- [x] `SKILL.md` 中引用了 `resources/data_quality_checklist.md`
- [x] `README.md`、`SELF_CHECK.md`、`tests/smoke-test.md` 路径与当前目录一致
- [x] 打包后无需依赖绝对路径
## 3. 依赖与脚本检查
- [x] 仅声明 `python3` 作为运行依赖
- [x] 脚本为明文、可审计、本地执行
- [x] 脚本参数通过 CLI 显式传入
- [x] 无未声明环境变量依赖
- [x] 无未声明安装动作
## 4. 资源检查
- [x] 资源文件存在且为真实内容
- [x] 资源用途与 skill 目标一致
- [x] 资源已在说明中被引用
## 5. 安全检查
- [x] 未发现 `curl|bash`
- [x] 未发现远程下载后直接执行
- [x] 未发现 base64/混淆载荷执行
- [x] 未发现越权监控、盗号、破解、恶意抓取设计
- [x] 文件读写范围应由用户明确指定
## 6. 热门度与实用性复核
- 高频需求:是
- 低理解门槛:是
- 易传播:是
- 可二次定制:是
- 维护成本:低到中
## 7. 评分
- 规范完整度:9.5/10
- 可用性:9.0/10
- 安全性:9.5/10
- 可维护性:9.0/10
- 综合评分:9.3/10
## 8. 结论
该 skill 已补齐交付级目录结构,适合纳入统一 bundle 分发。后续若要继续增强,优先方向是增加更贴近真实场景的样例输入与回归测试数据。
FILE:scripts/csv_cleanroom.py
#!/usr/bin/env python3
import argparse, csv, json, statistics
def main():
ap = argparse.ArgumentParser()
ap.add_argument("csv_path")
ap.add_argument("--out", default="csv_profile.json")
args = ap.parse_args()
with open(args.csv_path, "r", encoding="utf-8-sig", newline="") as f:
reader = csv.DictReader(f)
rows = list(reader)
fields = reader.fieldnames or []
null_counts = {field: 0 for field in fields}
for row in rows:
for field in fields:
if row.get(field, "") in ("", None):
null_counts[field] += 1
out = {"rows": len(rows), "columns": fields, "null_counts": null_counts}
json.dump(out, open(args.out, "w", encoding="utf-8"), ensure_ascii=False, indent=2)
print(f"Wrote {args.out}")
if __name__ == "__main__":
main()
FILE:examples/example-prompt.md
# CSV Cleanroom 示例
## 示例触发词
- 清洗 CSV
- profile this dataset
- 数据质量检查
- 列名规范化
- build a cleanup plan
## 示例输入
- CSV file or schema
- target schema if available
- known bad values
- dedupe rules
- date/currency locale
## 示例请求
请使用 `csv-cleanroom`,基于我提供的材料,按照 skill 中的工作流给出:
1. profile report
1. normalized schema
1. cleanup plan
1. quality scorecard
## 说明
- 先给预览稿或结构化草案
- 信息不足时,只补问最关键缺口
- 不要编造未提供的事实
FILE:tests/smoke-test.md
# Smoke test — csv-cleanroom
## 目标
验证该 skill 具备最小可用交付结构,且本地辅助脚本可被解释器加载。
## 检查项
1. `SKILL.md` 存在,且 frontmatter 含 `name`、`description`、`version`
2. `README.md`、`SELF_CHECK.md`、`examples/example-prompt.md` 存在
3. `scripts/` 下至少有一个可执行脚本
4. `resources/` 下至少有一个真实资源文件
5. 运行 `python3 scripts/csv_cleanroom.py --help` 返回退出码 0
## 人工验证
- 用 `examples/example-prompt.md` 中的触发词在会话中调用 skill
- 检查输出是否覆盖以下内容:
- profile report
- normalized schema
- cleanup plan
- quality scorecard
- 检查是否优先给出预览、草案或确认步骤,而非直接做破坏性操作
## 通过标准
全部检查项通过,即视为 smoke test 通过。
FILE:resources/data_quality_checklist.md
# Data Quality Checklist
- Header consistency
- Null handling rules
- Duplicate record policy
- Date and timezone normalization
- Currency/unit normalization
- Referential integrity assumptions
- Allowed value domains
- Export / archival plan
Compare draft agreements, highlight risky clause changes, and generate a negotiation checklist with plain-language explanations.
---
name: contract-redline-navigator
description: Compare draft agreements, highlight risky clause changes, and generate
a negotiation checklist with plain-language explanations.
version: 1.1.0
metadata:
openclaw:
requires:
bins:
- python3
emoji: 🧰
---
# Contract Redline Navigator
## Purpose
Compare draft agreements, highlight risky clause changes, and generate a negotiation checklist with plain-language explanations.
## Trigger phrases
- 合同对比
- redline this contract
- 比较两个协议版本
- 找风险条款
- 做谈判清单
## Ask for these inputs
- old draft and new draft
- contract type
- risk tolerance
- counterparty type
- must-have fallback positions
## Workflow
1. Diff the two clause sets and isolate added, removed, and changed language.
2. Check bundled high-risk clause patterns such as indemnity, liability caps, auto-renewal, IP assignment, exclusivity, and data use.
3. Explain material changes in plain language.
4. Produce a negotiation checklist with fallback wording and questions for counsel.
5. Avoid pretending to be a lawyer; always frame as operational review support.
## Output contract
- risk-change summary
- negotiation checklist
- clause-by-clause diff
- plain-language brief
## Files in this skill
- Script: `{baseDir}/scripts/clause_diff.py`
- Resource: `{baseDir}/resources/risk_clauses.md`
## Operating rules
- Be concrete and action-oriented.
- Prefer preview / draft / simulation mode before destructive changes.
- If information is missing, ask only for the minimum needed to proceed.
- Never fabricate metrics, legal certainty, receipts, credentials, or evidence.
- Keep assumptions explicit.
## Suggested prompts
- 合同对比
- redline this contract
- 比较两个协议版本
## Use of script and resources
Use the bundled script when it helps the user produce a structured file, manifest, CSV, or first-pass draft.
Use the resource file as the default schema, checklist, or preset when the user does not provide one.
## Boundaries
- This skill supports planning, structuring, and first-pass artifacts.
- It should not claim that files were modified, messages were sent, or legal/financial decisions were finalized unless the user actually performed those actions.
## Compatibility notes
- Directory-based AgentSkills/OpenClaw skill.
- Runtime dependency declared through `metadata.openclaw.requires`.
- Helper script is local and auditable: `scripts/clause_diff.py`.
- Bundled resource is local and referenced by the instructions: `resources/risk_clauses.md`.
FILE:CHANGELOG.md
# Changelog
## 1.0.0
- Initial release.
FILE:README.md
# Contract Redline Navigator
Slug: `contract-redline-navigator`
## 功能定位
Compare draft agreements, highlight risky clause changes, and generate a negotiation checklist with plain-language explanations.
## 适用场景
- 当用户需要:合同对比
- 当用户手头已有原始材料,需要快速整理成可执行输出
- 当用户希望先预览方案、再决定是否落盘或批量处理
## 安装要求
- OpenClaw / AgentSkills 兼容目录结构
- `python3` 可执行文件在 PATH 中可用
- 无远程安装脚本、无隐藏联网依赖、无未声明凭据要求
## 目录结构
- `SKILL.md`:触发描述、工作流、输出契约
- `scripts/clause_diff.py`:本地辅助脚本
- `resources/risk_clauses.md`:被 SKILL/README 引用的资源文件
- `examples/example-prompt.md`:触发与输入示例
- `tests/smoke-test.md`:最小冒烟测试
- `SELF_CHECK.md`:规范与安全自检
- `CHANGELOG.md`:变更记录
## 触发示例
- `合同对比`
- `redline this contract`
- `比较两个协议版本`
- `找风险条款`
- `做谈判清单`
## 建议输入
- old draft and new draft
- contract type
- risk tolerance
- counterparty type
- must-have fallback positions
## 预期输出
- risk-change summary
- negotiation checklist
- clause-by-clause diff
- plain-language brief
## 辅助脚本
脚本:`scripts/clause_diff.py`
建议先运行帮助信息确认参数:
```bash
python3 scripts/clause_diff.py --help
```
该脚本设计原则:
- 本地执行,便于审计与回滚
- 输入输出路径显式传入
- 不使用 `curl|bash`、远程直灌、base64 混淆执行
- 仅处理用户明确提供的文件或目录
## 输入输出示例
输入示例见:`examples/example-prompt.md`
输出示例建议至少包含:
- 结构化主结果
- 未决问题 / 风险项
- 可交付给他人的摘要或清单
## 常见问题
### 1. 这个 skill 会直接改我的文件吗?
默认不应直接进行破坏性批量操作;应优先生成预览、清单或草案,只有在用户明确要求时才建议执行进一步动作。
### 2. 这个 skill 需要联网吗?
当前目录内未声明联网依赖,也没有内置远程下载步骤。是否联网应由具体会话任务决定,而不是由 skill 包本身强制触发。
### 3. 资源文件的作用是什么?
`resources/risk_clauses.md` 为脚本或说明提供模板、规则、清单或模式参考,便于输出格式统一、可复用、可审计。
## 风险提示
- 对用户提供的数据、文本、截图或本地文件进行整理时,应先确认范围与目标。
- 涉及重命名、移动、合并、覆盖、生成正式对外内容时,应先给预览版本。
- 对不确定字段使用“待确认”标记,不应编造事实。
## 安全审计结论
- 依赖边界:仅声明 `python3`
- 凭据边界:未声明环境变量依赖
- 执行边界:本地脚本、本地资源、显式输入
- 高风险模式检查:未引入 `curl|bash`、远程管道执行、混淆载荷或私有 API 绑定
FILE:SELF_CHECK.md
# SELF_CHECK — contract-redline-navigator
## 1. 规范检查
- [x] Skill 为独立文件夹
- [x] 包含 `SKILL.md`
- [x] `SKILL.md` 使用 YAML frontmatter
- [x] frontmatter 含 `name`、`description`、`version`
- [x] 运行依赖声明在 `metadata.openclaw.requires`
- [x] 包含 `README.md`
- [x] 包含 `scripts/` 且至少 1 个脚本
- [x] 包含 `resources/` 且至少 1 个资源文件
- [x] 包含 `examples/example-prompt.md`
- [x] 包含 `tests/smoke-test.md`
## 2. 路径与引用检查
- [x] `SKILL.md` 中引用了 `scripts/clause_diff.py`
- [x] `SKILL.md` 中引用了 `resources/risk_clauses.md`
- [x] `README.md`、`SELF_CHECK.md`、`tests/smoke-test.md` 路径与当前目录一致
- [x] 打包后无需依赖绝对路径
## 3. 依赖与脚本检查
- [x] 仅声明 `python3` 作为运行依赖
- [x] 脚本为明文、可审计、本地执行
- [x] 脚本参数通过 CLI 显式传入
- [x] 无未声明环境变量依赖
- [x] 无未声明安装动作
## 4. 资源检查
- [x] 资源文件存在且为真实内容
- [x] 资源用途与 skill 目标一致
- [x] 资源已在说明中被引用
## 5. 安全检查
- [x] 未发现 `curl|bash`
- [x] 未发现远程下载后直接执行
- [x] 未发现 base64/混淆载荷执行
- [x] 未发现越权监控、盗号、破解、恶意抓取设计
- [x] 文件读写范围应由用户明确指定
## 6. 热门度与实用性复核
- 高频需求:是
- 低理解门槛:是
- 易传播:是
- 可二次定制:是
- 维护成本:低到中
## 7. 评分
- 规范完整度:9.5/10
- 可用性:9.0/10
- 安全性:9.5/10
- 可维护性:9.0/10
- 综合评分:9.3/10
## 8. 结论
该 skill 已补齐交付级目录结构,适合纳入统一 bundle 分发。后续若要继续增强,优先方向是增加更贴近真实场景的样例输入与回归测试数据。
FILE:scripts/clause_diff.py
#!/usr/bin/env python3
import argparse, difflib, json
def main():
ap = argparse.ArgumentParser()
ap.add_argument("old_file")
ap.add_argument("new_file")
ap.add_argument("--out", default="contract_diff.md")
args = ap.parse_args()
old = open(args.old_file, "r", encoding="utf-8").read().splitlines()
new = open(args.new_file, "r", encoding="utf-8").read().splitlines()
diff = difflib.unified_diff(old, new, fromfile=args.old_file, tofile=args.new_file, lineterm="")
content = "# Contract Diff\n\n```diff\n" + "\n".join(diff) + "\n```\n"
open(args.out, "w", encoding="utf-8").write(content)
print(f"Wrote {args.out}")
if __name__ == "__main__":
main()
FILE:examples/example-prompt.md
# Contract Redline Navigator 示例
## 示例触发词
- 合同对比
- redline this contract
- 比较两个协议版本
- 找风险条款
- 做谈判清单
## 示例输入
- old draft and new draft
- contract type
- risk tolerance
- counterparty type
- must-have fallback positions
## 示例请求
请使用 `contract-redline-navigator`,基于我提供的材料,按照 skill 中的工作流给出:
1. risk-change summary
1. negotiation checklist
1. clause-by-clause diff
1. plain-language brief
## 说明
- 先给预览稿或结构化草案
- 信息不足时,只补问最关键缺口
- 不要编造未提供的事实
FILE:tests/smoke-test.md
# Smoke test — contract-redline-navigator
## 目标
验证该 skill 具备最小可用交付结构,且本地辅助脚本可被解释器加载。
## 检查项
1. `SKILL.md` 存在,且 frontmatter 含 `name`、`description`、`version`
2. `README.md`、`SELF_CHECK.md`、`examples/example-prompt.md` 存在
3. `scripts/` 下至少有一个可执行脚本
4. `resources/` 下至少有一个真实资源文件
5. 运行 `python3 scripts/clause_diff.py --help` 返回退出码 0
## 人工验证
- 用 `examples/example-prompt.md` 中的触发词在会话中调用 skill
- 检查输出是否覆盖以下内容:
- risk-change summary
- negotiation checklist
- clause-by-clause diff
- plain-language brief
- 检查是否优先给出预览、草案或确认步骤,而非直接做破坏性操作
## 通过标准
全部检查项通过,即视为 smoke test 通过。
FILE:resources/risk_clauses.md
# High-Risk Clause Signals
- Unlimited indemnity
- One-sided IP assignment
- Liability cap below fees paid
- Broad confidentiality carve-outs
- Auto-renewal without termination window
- Exclusivity with vague scope
- Payment terms beyond 60 days
- Unilateral policy-change provisions
- Broad data usage / model training rights