@yottameta/yotta-compliance 0.0.0 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/SKILL.md ADDED
@@ -0,0 +1,208 @@
1
+ ---
2
+ name: yotta-compliance
3
+ version: 0.1.0
4
+ description: 元规 —— 本地确定性的合规条款审查技能:对 UTF-8 文本 / Markdown 按版本化 JSON 规则包做确定性匹配、断言求值与证据抽取,输出带原文位置、命中规则、框架覆盖级别与来源条款的 Markdown / JSON 报告;当前 baseline_review 覆盖 PIPL 11 条规则与数据出境 4 条规则,GDPR / HIPAA / SOC2 / PCI-DSS / ISO27001 / 等保仅做 mapping_only 主题映射。触发:用户要审查隐私政策 / 数据处理条款 / 个人信息合规文本、检查 PIPL 或数据出境条款缺口、核对框架覆盖范围、生成可复算的合规审查报告、把条款审查接入 CI 闸门时。边界:只做基于确定性规则的审查建议,不构成法律意见、不替代律师或合规顾问;核心路径不调用 LLM、不联网、不解析 PDF / docx;mapping_only 框架不输出独立合规结论;不判断合同效力或诉讼结果。
5
+ license: MIT
6
+ ---
7
+
8
+ # 元规(yotta-compliance)
9
+
10
+ 本地、确定性、可复算的合规条款审查技能。元规对文本或 Markdown 执行规则匹配、断言求值与证据抽取,
11
+ 输出带**原文位置、命中规则、框架覆盖级别与来源条款**的审查报告。
12
+
13
+ 可信契约:
14
+
15
+ - 每条风险结论必须回到原文证据、规则 id 和来源条款;
16
+ - 没有证据不输出风险结论;
17
+ - 同一输入得到同一结果(仅生成时间不同);
18
+ - `mapping_only` 框架只做主题映射,不输出该框架的独立合规结论;
19
+ - 核心路径不调用 LLM、不联网,规则包只作为只读 JSON 数据。
20
+
21
+ ## 何时使用
22
+
23
+ - 审查隐私政策、数据处理条款、个人信息处理规则等文本;
24
+ - 检查文本是否出现 PIPL 要求的告知、合法性依据、保存期限、单独同意、个人权利、影响评估等要素;
25
+ - 检查数据出境场景是否出现安全评估 / 标准合同 / 保护认证、单独同意、境外接收方告知、境内存储说明;
26
+ - 生成可复算的 Markdown / JSON 审查报告,作为人工复核的起点;
27
+ - 把达到指定严重度的条款缺口接入 CI 闸门。
28
+
29
+ **Do NOT trigger**:
30
+
31
+ - 不生成法律意见、不判断合同效力、不预测诉讼结果;
32
+ - 不替代律师、合规顾问或监管机构的判断;
33
+ - 不把 `mapping_only` 描述为“已审查该框架”;
34
+ - v0.1 不直接解析 PDF / docx,需先转成 UTF-8 文本或 Markdown;
35
+ - 不联网检索法条,不调用模型做语义裁决;
36
+ - 不自动修改合同或替用户签署、提交任何文件。
37
+
38
+ ## 快速使用
39
+
40
+ Windows 使用 `python`,Linux / macOS 使用 `python3`。
41
+
42
+ ```bash
43
+ # 审查一个文本 / Markdown 文件(默认装载 pipl + data-export)
44
+ python3 scripts/yotta_compliance.py review --input contract.md
45
+
46
+ # 只审查 PIPL 包
47
+ python3 scripts/yotta_compliance.py review --input contract.md --frameworks pipl
48
+
49
+ # 输出 JSON,并在达到 high 时返回退出码 1
50
+ python3 scripts/yotta_compliance.py review --input contract.md --format json --gate high --out report.json
51
+
52
+ # 从标准输入读取
53
+ python3 scripts/yotta_compliance.py review --stdin --frameworks pipl,data-export
54
+
55
+ # 规则包操作
56
+ python3 scripts/yotta_compliance.py rules list --framework pipl
57
+ python3 scripts/yotta_compliance.py rules show PIPL-NOTICE-001
58
+ python3 scripts/yotta_compliance.py rules validate --pack rules/pipl.json
59
+ ```
60
+
61
+ 报告默认写 stdout。只在显式提供 `--out` 时写文件,输出路径不得与输入文件相同,也不得写入规则包目录。
62
+
63
+ ## 命令一览
64
+
65
+ | 命令 | 说明 |
66
+ |---|---|
67
+ | `review --input <file>` | 审查 UTF-8 `.txt` / `.md` / `.markdown` 文件 |
68
+ | `review --stdin` | 从标准输入读取文本 |
69
+ | `review --frameworks <list>` | 选择规则包,逗号分隔;缺省装载全部规则包 |
70
+ | `review --format md\|json` | 输出 Markdown(默认)或 JSON |
71
+ | `review --out <file>` | 写报告文件;缺省写 stdout |
72
+ | `review --gate <level>` | CI 闸门:`off` / `low` / `medium` / `high` / `critical` |
73
+ | `review --min-severity <level>` | 只输出达到该严重度的 finding;汇总计数仍保留全量 |
74
+ | `review --include-safe` | 在 JSON `summary.checked_rules` 与 Markdown 未覆盖范围中列出已检查未命中的规则 |
75
+ | `rules list` | 列出规则包与规则 |
76
+ | `rules show <rule_id>` | 查看单条规则的说明、建议、来源与测试用例 |
77
+ | `rules validate --pack <file>` | 校验规则包;不合规立即失败 |
78
+
79
+ ## 退出码
80
+
81
+ | 退出码 | 含义 |
82
+ |---|---|
83
+ | 0 | 审查完成,未超过 gate |
84
+ | 1 | 审查完成,存在达到 gate 的 finding |
85
+ | 2 | 输入缺失、编码错误、路径不可用或超出输入上限 |
86
+ | 3 | 规则包缺失、schema 无效或重复 `rule_id` |
87
+ | 4 | CLI 用法错误 |
88
+
89
+ ## 覆盖范围
90
+
91
+ 当前正式规则包:
92
+
93
+ | 规则包 | 框架 | 覆盖级别 | 规则数 |
94
+ |---|---|---|---|
95
+ | `pipl` | PIPL | `baseline_review` | 11 |
96
+ | `data-export` | 数据出境 | `baseline_review` | 4 |
97
+
98
+ `GDPR` / `HIPAA` / `SOC2` / `PCI-DSS` / `ISO27001` / 等保 当前为 `mapping_only`:
99
+ 只把基础规则映射到对应主题,不输出这些框架的独立合规结论。
100
+
101
+ 完整规则清单、主题映射与明确未覆盖范围见 `references/coverage.md`。
102
+
103
+ ## 报告包含什么
104
+
105
+ Markdown 报告固定包含七节:
106
+
107
+ 1. 输入摘要(来源、大小、行数、SHA-256、规则包版本);
108
+ 2. 框架覆盖摘要(规则包、框架、覆盖级别、状态、规则数);
109
+ 3. 风险汇总;
110
+ 4. 逐条发现(严重度、置信度、框架映射、原文证据、位置、规则说明、建议动作、规则来源);
111
+ 5. 未覆盖范围;
112
+ 6. 人工复核清单;
113
+ 7. 免责声明。
114
+
115
+ JSON 报告固定提供稳定机器契约:`schema_version` / `tool` / `tool_version` / `generated_at` /
116
+ `input` / `rule_packs` / `framework_coverage` / `summary` / `findings` / `review_items` / `disclaimer`。
117
+ 字段语义与证据结构见 `references/report-format.md`。
118
+
119
+ 示例(对一份缺少多项护栏的隐私说明运行默认规则包):
120
+
121
+ ```text
122
+ - 本次输出 11 条发现(全部 11 条)
123
+ - high:3 条
124
+ - medium:4 条
125
+ - low:4 条
126
+ - 已检查规则:15 条 | 命中规则:13 条
127
+ ```
128
+
129
+ 实际结果取决于输入内容与所选规则包,示例数字不作为固定输出。
130
+
131
+ ## 规则包与证据链
132
+
133
+ 规则包是版本化 JSON 数据,包含 pack 元信息、条款类型词表、规则列表和可选的主题映射。
134
+ 每条规则必须声明 `test_ids`,且正式规则在发布前必须配有正例、反例和边界例。
135
+
136
+ 每条 finding 固定包含:
137
+
138
+ - `finding_id`、`rule_id`、`severity`、`confidence`;
139
+ - `framework_mapping`(基础框架与 `框架:mapping_only` 标签);
140
+ - `evidence`(`matched_span` 带原文 quote 与起止行列;`document_scope` / `section_scope` 只给范围);
141
+ - `rationale`、`remediation`、`source`。
142
+
143
+ 规则编写、断言契约与验收要求见 `references/rule-authoring.md`。
144
+
145
+ ## 已知局限(必须人工复核)
146
+
147
+ - **词形匹配,不是语义理解**:absence 规则只判断检索词是否出现;同义但词形不同的表述可能漏检。
148
+ - **文档级范围**:absence 的 `scope` 均为 `document`,任何位置出现检索词即视为已出现,不判断该表述是否适用于当前处理活动。
149
+ - **否定句不建模**:「不会对外提供」「未经同意不得处理」等否定表述仍会触发候选匹配,可能产生漏报。
150
+ - **只解析阿拉伯数字**:`保存期限:N年` 可解析;中文数字(如“三年”)不解析、不换算。
151
+ - **数据出境人数阈值未进入 v1**:需要单位感知的数值原语;相关阈值规则推迟到规则包 v2。
152
+ - **absence 类结论一律降低置信度**:medium / low 置信 finding 会进入人工复核清单,必须人工核验后才能采信。
153
+ - **不直接解析 PDF / docx**:请先用文档适配器转成 UTF-8 文本或 Markdown。
154
+
155
+ ## 数据与安全边界
156
+
157
+ - 纯本地运行:不发送原文、证据或报告,不联网检索法条,不调用模型;
158
+ - 规则包是只读数据,不从规则正文执行代码;
159
+ - 输入上限 2 MiB;仅接受 UTF-8 文本;
160
+ - 除非显式设置 `--out`,报告只写 stdout;
161
+ - 输出路径不得与输入文件相同,也不得位于规则包目录内;
162
+ - 不缓存原文,不把合同内容写入日志。
163
+
164
+ ## 使用范围与授权
165
+
166
+ - 只审查用户有权处理的文本;用户对输入来源与使用范围负责;
167
+ - 审查结果用于发现文本缺口并辅助人工复核,不构成法律意见;
168
+ - 不用于规避监管、伪造合规结论或对外声称“已通过某框架认证”;
169
+ - 引用规则来源时保留规则包中的条款号与链接,不凭记忆补写条款。
170
+
171
+ ## 法律与红线
172
+
173
+ - 元规是**审查建议工具**,不是律师事务所、认证机构或监管机关;
174
+ - 规则命中只代表文本中出现了可观察现象,不代表真实业务未履行义务;
175
+ - 规则未命中不代表不存在风险;`mapping_only` 框架不得被解读为已完成合规审查;
176
+ - 使用本工具须遵守所在地法律法规与平台条款,最终判断由具备资质的专业人士作出。
177
+
178
+ ## 家族协同
179
+
180
+ - **元信 yotta-verify**:规则包与技能发布前的确定性安全扫描;
181
+ - **元忆 yotta-memory**:仅在用户显式选择时保存报告摘要与规则包哈希,不自动保存合同原文;
182
+ - **元呈 yotta-present**:把审查结论呈现为报告或证据卡;
183
+ - **元安 yotta-security-audit**:审计规则包与文件读取面的安全风险;
184
+ - **元审 yotta-vetter**:自定义规则包安装前的来源与权限审查。
185
+
186
+ ## 开发与校验
187
+
188
+ ```bash
189
+ # 全量契约测试(技能目录内)
190
+ python3 scripts/test_yotta_compliance.py
191
+
192
+ # 规则包校验
193
+ python3 scripts/yotta_compliance.py rules validate --pack rules/pipl.json
194
+ python3 scripts/yotta_compliance.py rules validate --pack rules/data-export.json
195
+
196
+ # 语法检查
197
+ python3 -m py_compile scripts/yotta_compliance.py
198
+ ```
199
+
200
+ ## 参考文档
201
+
202
+ - `references/rule-authoring.md` — 规则包 schema、匹配原语、断言契约与规则验收;
203
+ - `references/report-format.md` — Markdown / JSON 报告契约、字段语义与退出码;
204
+ - `references/coverage.md` — 当前框架覆盖、规则清单、主题映射与明确未覆盖范围。
205
+
206
+ ## 免责声明
207
+
208
+ 本工具提供基于确定性规则的条款审查建议与证据链,不构成法律意见。
Binary file
package/bin/install.js ADDED
@@ -0,0 +1,163 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * yotta-compliance 跨平台安装器(YottaSkills)
4
+ * 用法:
5
+ * npx -y @yottameta/yotta-compliance --agent <name> # 按智能体默认用户级目录安装(推荐)
6
+ * npx -y @yottameta/yotta-compliance --dir PATH # 装到指定目录(用户改了目录的智能体)
7
+ * npx -y @yottameta/yotta-compliance -g # 安装到全部已知智能体用户级目录
8
+ * npx -y @yottameta/yotta-compliance # 安装到检测到的项目级目录
9
+ * npx -y @yottameta/yotta-compliance --list # 列出智能体 -> 默认目录
10
+ */
11
+ 'use strict';
12
+ const fs = require('fs');
13
+ const path = require('path');
14
+ const os = require('os');
15
+
16
+ const SKILL_NAME = 'yotta-compliance';
17
+ const PKG_ROOT = path.join(__dirname, '..');
18
+
19
+ // 智能体 -> 用户级默认技能目录(dirs 按优先级排列;--agent 装到第一个)
20
+ // 依据官方文档:.agents/skills 并非通用目录,被 OpenCode / Cursor / Cline / Amp /
21
+ // Kimi / Gemini CLI / GitHub Copilot 等读取;Claude Code 与 Codex 默认不读 .agents。
22
+ const AGENT_DIRS = {
23
+ claude: { label: 'Claude Code', dirs: ['.claude/skills'] },
24
+ cursor: { label: 'Cursor', dirs: ['.cursor/skills', '.agents/skills'] },
25
+ codex: { label: 'Codex', dirs: ['.codex/skills'] }, // 特判:$CODEX_HOME/skills
26
+ gemini: { label: 'Gemini CLI', dirs: ['.gemini/skills', '.agents/skills'] },
27
+ goose: { label: 'Goose', dirs: ['.config/goose/skills', '.agents/skills'] },
28
+ amp: { label: 'Amp', dirs: ['.config/agents/skills', '.agents/skills'] },
29
+ opencode: { label: 'OpenCode', dirs: ['.config/opencode/skills'] }, // 特判:$XDG_CONFIG_HOME
30
+ windsurf: { label: 'Windsurf', dirs: ['.codeium/windsurf/skills'] },
31
+ workbuddy: { label: 'WorkBuddy', dirs: ['.workbuddy/skills'] },
32
+ kiro: { label: 'Kiro', dirs: ['.kiro/skills'] },
33
+ trae: { label: 'Trae Code CLI', dirs: ['.traecli/skills'] },
34
+ 'trae-cn': { label: 'Trae IDE(国内)', dirs: ['.trae-cn/skills'] },
35
+ qwen: { label: 'Qwen Code', dirs: ['.qwen/skills'] },
36
+ comate: { label: 'Comate 文心快码', dirs: ['.comate/skills'] },
37
+ codebuddy: { label: 'CodeBuddy Code', dirs: ['.codebuddy/skills'] },
38
+ kimi: { label: 'Kimi Code CLI', dirs: ['.kimi/skills'] },
39
+ agents: { label: '通用 AGENTS.md', dirs: ['.agents/skills'] },
40
+ };
41
+
42
+ // Codex 用户级目录特判:优先 $CODEX_HOME/skills,否则 ~/.codex/skills
43
+ function codexUserDir() {
44
+ const base = process.env.CODEX_HOME || path.join(os.homedir(), '.codex');
45
+ return path.join(base, 'skills');
46
+ }
47
+
48
+ // OpenCode 用户级目录特判:优先 $XDG_CONFIG_HOME/opencode/skills,否则 ~/.config/opencode/skills
49
+ function opencodeUserDir() {
50
+ const base = process.env.XDG_CONFIG_HOME || path.join(os.homedir(), '.config');
51
+ return path.join(base, 'opencode', 'skills');
52
+ }
53
+
54
+ function resolveUserDir(rel) {
55
+ if (rel === '.codex/skills') return codexUserDir();
56
+ if (rel === '.config/opencode/skills') return opencodeUserDir();
57
+ return path.join(os.homedir(), rel);
58
+ }
59
+
60
+ function installTo(dest) {
61
+ const target = path.join(dest, SKILL_NAME);
62
+ fs.mkdirSync(target, { recursive: true });
63
+ copyDir(PKG_ROOT, target, new Set(['package.json', 'bin', 'node_modules', '.git']));
64
+ console.log('installed -> ' + target);
65
+ }
66
+
67
+ function copyDir(src, dst, skip) {
68
+ for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
69
+ if (skip.has(entry.name)) continue;
70
+ const s = path.join(src, entry.name);
71
+ const d = path.join(dst, entry.name);
72
+ if (entry.isDirectory()) {
73
+ fs.mkdirSync(d, { recursive: true });
74
+ copyDir(s, d, skip);
75
+ } else if (entry.isFile()) {
76
+ fs.copyFileSync(s, d);
77
+ }
78
+ }
79
+ }
80
+
81
+ function displayDir(rel) {
82
+ if (process.platform === 'win32') return '%USERPROFILE%\\' + rel.replace(/\//g, '\\');
83
+ return '~/' + rel;
84
+ }
85
+
86
+ function main() {
87
+ const args = process.argv.slice(2);
88
+ const isGlobal = args.includes('-g') || args.includes('--global');
89
+ const list = args.includes('--list') || args.includes('-l');
90
+ let explicitDir = null;
91
+ const di = args.indexOf('--dir');
92
+ if (di !== -1 && args[di + 1]) explicitDir = args[di + 1];
93
+ let agent = null;
94
+ const ai = args.indexOf('--agent');
95
+ if (ai !== -1 && args[ai + 1]) agent = String(args[ai + 1]).toLowerCase();
96
+
97
+ if (list) {
98
+ console.log('智能体 -> 默认技能目录(--agent <name> 装到第一个,用户级):');
99
+ for (const [key, v] of Object.entries(AGENT_DIRS)) {
100
+ const resolved = v.dirs.map(displayDir);
101
+ console.log(' ' + key.padEnd(10) + v.label.padEnd(18) + resolved.join('、'));
102
+ }
103
+ console.log('\n说明:Windows 用 %USERPROFILE%,Linux/macOS 用 ~;仅收录有官方默认目录的智能体。');
104
+ console.log('改了目录的请用 --dir <路径>,不要依赖默认位置;若设置了 CODEX_HOME / XDG_CONFIG_HOME,安装自动以该变量为准。');
105
+ return;
106
+ }
107
+
108
+ if (explicitDir) { installTo(explicitDir); return; }
109
+
110
+ if (agent) {
111
+ const info = AGENT_DIRS[agent];
112
+ if (!info) {
113
+ console.log('未收录智能体: ' + agent + '。请用 --dir <路径> 指定技能目录。');
114
+ console.log('可用: ' + Object.keys(AGENT_DIRS).join(', '));
115
+ return;
116
+ }
117
+ installTo(resolveUserDir(info.dirs[0]));
118
+ console.log('完成。');
119
+ return;
120
+ }
121
+
122
+ if (isGlobal) {
123
+ const seen = new Set();
124
+ for (const v of Object.values(AGENT_DIRS)) {
125
+ for (const d of v.dirs) {
126
+ if (seen.has(d)) continue;
127
+ seen.add(d);
128
+ installTo(resolveUserDir(d));
129
+ }
130
+ }
131
+ console.log('完成。');
132
+ return;
133
+ }
134
+
135
+ const PROJECT_DIRS = [
136
+ '.claude/skills',
137
+ '.cursor/skills',
138
+ '.codex/skills',
139
+ '.config/goose/skills',
140
+ '.config/agents/skills',
141
+ '.opencode/skills',
142
+ '.codeium/windsurf/skills',
143
+ '.workbuddy/skills',
144
+ '.kiro/skills',
145
+ '.traecli/skills',
146
+ '.gemini/skills',
147
+ '.trae-cn/skills',
148
+ '.qwen/skills',
149
+ '.comate/skills',
150
+ '.codebuddy/skills',
151
+ '.kimi/skills',
152
+ '.agents/skills',
153
+ ];
154
+ let installedAny = false;
155
+ for (const d of PROJECT_DIRS) {
156
+ if (fs.existsSync(d)) { installTo(d); installedAny = true; }
157
+ }
158
+ if (!installedAny) {
159
+ console.log('未检测到项目级智能体目录。可手动复制,或用 --agent <name> / -g 装到用户级。');
160
+ }
161
+ }
162
+
163
+ main();
package/install.sh ADDED
@@ -0,0 +1,132 @@
1
+ #!/usr/bin/env bash
2
+ # yotta-compliance 多智能体安装脚本(YottaSkills 模板)
3
+ # 用法:
4
+ # bash install.sh --agent <name> # 按智能体默认用户级目录安装
5
+ # bash install.sh --dir <path> # 装到指定目录(用户改过目录的智能体)
6
+ # bash install.sh -g # 装到全部已知智能体用户级目录
7
+ # bash install.sh # 检测并安装到已存在的项目级目录
8
+ # bash install.sh --list # 列出智能体 -> 默认目录
9
+ set -euo pipefail
10
+
11
+ SKILL_NAME="yotta-compliance"
12
+ SOURCE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
13
+ case "$(uname -s)" in
14
+ MINGW*|MSYS*)
15
+ SOURCE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -W)"
16
+ ;;
17
+ esac
18
+
19
+ # 智能体 -> 用户级默认目录(--agent 装到第一个)
20
+ # .agents/skills 并非通用目录:OpenCode / Cursor / Cline / Amp / Kimi / Gemini CLI / GitHub Copilot 读取。
21
+ # 判断当前环境:Windows Git Bash 用 %USERPROFILE%,Unix 用 ~
22
+ _IS_WINDOWS=0
23
+ case "$(uname -s)" in
24
+ MINGW*|MSYS*|CYGWIN*) _IS_WINDOWS=1 ;;
25
+ esac
26
+ dirs_for() {
27
+ case "$1" in
28
+ claude) echo ".claude/skills" ;;
29
+ cursor) echo ".cursor/skills .agents/skills" ;;
30
+ codex) echo "__CODEX__" ;;
31
+ gemini) echo ".gemini/skills .agents/skills" ;;
32
+ goose) echo ".config/goose/skills .agents/skills" ;;
33
+ amp) echo ".config/agents/skills .agents/skills" ;;
34
+ opencode) echo "__OPENCODE__" ;;
35
+ windsurf) echo ".codeium/windsurf/skills" ;;
36
+ workbuddy) echo ".workbuddy/skills" ;;
37
+ kiro) echo ".kiro/skills" ;;
38
+ trae) echo ".traecli/skills" ;;
39
+ trae-cn) echo ".trae-cn/skills" ;;
40
+ qwen) echo ".qwen/skills" ;;
41
+ comate) echo ".comate/skills" ;;
42
+ codebuddy) echo ".codebuddy/skills" ;;
43
+ kimi) echo ".kimi/skills" ;;
44
+ agents) echo ".agents/skills" ;;
45
+ *) return 1 ;;
46
+ esac
47
+ }
48
+
49
+ codex_dir() {
50
+ if [ -n "${CODEX_HOME:-}" ]; then printf '%s' "$CODEX_HOME/skills"; else printf '%s' "$HOME/.codex/skills"; fi
51
+ }
52
+ opencode_dir() {
53
+ if [ -n "${XDG_CONFIG_HOME:-}" ]; then printf '%s' "$XDG_CONFIG_HOME/opencode/skills"; else printf '%s' "$HOME/.config/opencode/skills"; fi
54
+ }
55
+ resolve_user() {
56
+ case "$1" in
57
+ __CODEX__) codex_dir ;;
58
+ __OPENCODE__) opencode_dir ;;
59
+ *) printf '%s' "$HOME/$1" ;;
60
+ esac
61
+ }
62
+
63
+ install_to() {
64
+ mkdir -p "$1/$SKILL_NAME"
65
+ cp -r "$SOURCE_DIR/." "$1/$SKILL_NAME/"
66
+ rm -rf "$1/$SKILL_NAME/.git"
67
+ echo "installed -> $1/$SKILL_NAME"
68
+ }
69
+
70
+ list() {
71
+ echo "智能体 -> 默认技能目录(--agent <name> 装到第一个,用户级):"
72
+ for a in claude cursor codex gemini goose amp opencode windsurf workbuddy kiro trae trae-cn qwen comate codebuddy kimi agents; do
73
+ local dirs first
74
+ dirs="$(dirs_for "$a")"
75
+ first="${dirs%% *}"
76
+ case "$first" in
77
+ __CODEX__) first=".codex/skills" ;;
78
+ __OPENCODE__) first=".config/opencode/skills" ;;
79
+ esac
80
+ if [ "$_IS_WINDOWS" = "1" ]; then
81
+ first="%USERPROFILE%\\${first//\//\\}"
82
+ else
83
+ first="~/$first"
84
+ fi
85
+ printf ' %-10s %s\n' "$a" "$first"
86
+ done
87
+ echo '说明:Windows 用 %USERPROFILE%,Linux/macOS 用 ~;仅收录有官方默认目录的智能体。'
88
+ echo '改了目录的请用 --dir <路径>,不要依赖默认位置;若设置了 CODEX_HOME / XDG_CONFIG_HOME,安装自动以该变量为准。'
89
+ }
90
+
91
+ main() {
92
+ local agent="" dir="" global=0 show_list=0
93
+ while [ $# -gt 0 ]; do
94
+ case "$1" in
95
+ --agent) shift; agent="${1:-}" ;;
96
+ --dir) shift; dir="${1:-}" ;;
97
+ -g|--global) global=1 ;;
98
+ --list|-l) show_list=1 ;;
99
+ *) echo "未知参数: $1" >&2; exit 2 ;;
100
+ esac
101
+ shift
102
+ done
103
+
104
+ if [ "$show_list" = "1" ]; then list; return; fi
105
+ if [ -n "$dir" ]; then install_to "$dir"; echo "完成。"; return; fi
106
+ if [ -n "$agent" ]; then
107
+ local dirs first
108
+ if ! dirs="$(dirs_for "$agent")"; then
109
+ echo "未收录智能体: $agent。请用 --dir <路径> 指定技能目录。" >&2; exit 2
110
+ fi
111
+ first="${dirs%% *}"
112
+ install_to "$(resolve_user "$first")"; echo "完成。"; return
113
+ fi
114
+ if [ "$global" = "1" ]; then
115
+ echo "安装到全部已知智能体用户级目录..."
116
+ local dirs rel
117
+ for a in claude cursor codex gemini goose amp opencode windsurf workbuddy kiro trae trae-cn qwen comate codebuddy kimi agents; do
118
+ dirs="$(dirs_for "$a")"
119
+ for rel in $dirs; do install_to "$(resolve_user "$rel")"; done
120
+ done
121
+ echo "完成。"; return
122
+ fi
123
+ local installed=0 d
124
+ for d in .claude/skills .cursor/skills .codex/skills .config/goose/skills .config/agents/skills .opencode/skills .codeium/windsurf/skills .workbuddy/skills .kiro/skills .traecli/skills .gemini/skills .trae-cn/skills .qwen/skills .comate/skills .codebuddy/skills .kimi/skills .agents/skills; do
125
+ if [ -d "$d" ]; then install_to "$d"; installed=1; fi
126
+ done
127
+ if [ "$installed" = "0" ]; then
128
+ echo "未检测到项目级智能体目录。可用 --agent <name> / -g 装到用户级,或 --dir 指定。"
129
+ fi
130
+ }
131
+
132
+ main "$@"
package/package.json CHANGED
@@ -1,23 +1,46 @@
1
1
  {
2
2
  "name": "@yottameta/yotta-compliance",
3
- "version": "0.0.0",
4
- "description": "Placeholder package for the YottaMeta yotta-compliance skill.",
5
- "main": "index.js",
6
- "scripts": {
7
- "test": "echo \"Error: no test specified\" && exit 1"
8
- },
9
- "keywords": [],
10
- "author": "",
3
+ "version": "0.1.0",
4
+ "description": "YuanGui (yotta-compliance) — a local, deterministic compliance-clause review skill for AI agents: reviews UTF-8 text / Markdown against versioned JSON rule packs with deterministic matching and assertion evaluation, and produces Markdown / JSON reports in which every conclusion carries the source-text span, matched rule id, framework coverage level and official clause citation. Baseline coverage: 11 PIPL rules and 4 cross-border data-transfer rules; the GDPR / HIPAA / SOC2 / PCI-DSS / ISO27001 / China MLPS frameworks are mapping_only. Triggers: reviewing privacy policies, data-processing clauses or personal-information compliance text; checking PIPL or data-export gaps; checking framework coverage; generating reproducible compliance review reports; gating clause review in CI. Boundaries: deterministic rule-based review suggestions only — not legal advice, not a substitute for a lawyer or compliance consultant; the core path uses no LLM and no network access and does not parse PDF / docx; mapping_only frameworks produce no independent compliance conclusion; it does not judge contract validity or litigation outcomes. Fully local, zero-dependency (Python 3.8+ standard library).",
11
5
  "license": "MIT",
12
- "type": "commonjs",
6
+ "keywords": [
7
+ "agent-skills",
8
+ "yotta-compliance",
9
+ "yottaskills",
10
+ "compliance",
11
+ "pipl"
12
+ ],
13
+ "files": [
14
+ "SKILL.md",
15
+ "LICENSE",
16
+ "NOTICE",
17
+ "README.md",
18
+ "README.zh-CN.md",
19
+ "CHANGELOG.md",
20
+ "install.sh",
21
+ "references",
22
+ "rules",
23
+ "scripts",
24
+ "assets",
25
+ "bin",
26
+ "!scripts/test_*.py",
27
+ "!scripts/fixtures",
28
+ "!scripts/fixtures/**",
29
+ "!**/__pycache__",
30
+ "!**/*.pyc",
31
+ "!**/*.pyo"
32
+ ],
13
33
  "repository": {
34
+ "type": "git",
14
35
  "url": "git+https://github.com/YottaMeta/yotta-compliance.git"
15
36
  },
16
37
  "publishConfig": {
17
38
  "access": "public"
18
39
  },
19
- "bugs": {
20
- "url": "https://github.com/YottaMeta/yotta-compliance/issues"
40
+ "bin": {
41
+ "yotta-compliance": "bin/install.js"
21
42
  },
22
- "homepage": "https://github.com/YottaMeta/yotta-compliance#readme"
43
+ "scripts": {
44
+ "test": "python scripts/test_yotta_compliance.py"
45
+ }
23
46
  }