kld-sdd 2.6.14 → 2.6.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/README.md +7 -5
  2. package/lib/init.js +118 -73
  3. package/lib/skills-bundle.js +3 -0
  4. package/package.json +3 -2
  5. package/skywalk-sdd/index.cjs +936 -109
  6. package/skywalk-sdd/metrics-v3.cjs +103 -15
  7. package/skywalk-sdd/openspec-shim.cjs +48 -0
  8. package/skywalk-sdd/reporting/change-report-markdown.cjs +294 -0
  9. package/skywalk-sdd/reporting/change-report-model.cjs +170 -27
  10. package/skywalk-sdd/reporting/change-report-renderer.cjs +78 -154
  11. package/skywalk-sdd/reporting/change-report-view-model.cjs +340 -0
  12. package/templates/git-hooks/commit-msg +46 -0
  13. package/templates/git-hooks/pre-commit +57 -0
  14. package/templates/git-hooks/pre-commit-consistency-check.cjs +193 -0
  15. package/templates/git-hooks/pre-push +57 -0
  16. package/templates/git-hooks/pre-push-consistency-check.cjs +197 -0
  17. package/templates/hooks/codebuddy/hooks/hook-gate-core.cjs +369 -0
  18. package/templates/hooks/codebuddy/hooks/sdd-apply-test-gate.cjs +41 -0
  19. package/templates/hooks/codebuddy/hooks/sdd-mid-checkpoint.cjs +108 -0
  20. package/templates/hooks/codebuddy/hooks/sdd-post-tool.cjs +36 -1
  21. package/templates/hooks/codebuddy/hooks/sdd-tdd-rhythm-gate.cjs +248 -0
  22. package/templates/hooks/codebuddy/settings.json +8 -0
  23. package/templates/skills/kld-sdd/opsx-apply/SKILL.md +13 -0
  24. package/templates/skills/kld-sdd/opsx-apply/checklist.md +15 -0
  25. package/templates/skills/kld-sdd/opsx-apply/reference.md +45 -2
  26. package/templates/skills/kld-sdd/opsx-archive/SKILL.md +1 -1
  27. package/templates/skills/kld-sdd/opsx-consistency-check/SKILL.md +592 -0
  28. package/templates/skills/kld-sdd/opsx-propose/SKILL.md +3 -3
  29. package/templates/skills/kld-sdd/opsx-propose/reference.md +6 -7
  30. package/templates/skills/kld-sdd/tdd-core/reference.md +3 -1
  31. package/templates/skills/kld-sdd/tdd-rules/SKILL.md +1 -0
  32. package/templates/skills/kld-sdd/tdd-rules/rules/tdd-rhythm-enforcement.md +101 -0
  33. package/templates/skills/kld-sdd/tdd-rules/rules/test-skeleton-telemetry.md +1 -1
package/README.md CHANGED
@@ -104,24 +104,26 @@ npx kld-sdd
104
104
 
105
105
  初始化完成后,打开你的 AI 编辑器,激活 `opsx-*` skills 开始工作。
106
106
 
107
- ### 提效评估报告(SkyWalk V3
107
+ ### 提效评估报告(SkyWalk;单次变更为 v4
108
108
 
109
- 归档与独立 `report` 命令会基于同一 Report Model 生成 Markdown / HTML / JSON 三份同源产物(`schema_version=sdd-efficiency-report/v3`)。单次变更 HTML 使用桌面方案 A,只展示当前 change 的四个页签:概览、指标与阶段、问题与证据、产物与追溯,不混入跨变更趋势。
109
+ 归档与独立 `report --change=` 会基于同一 Report Model 生成 Markdown / HTML / JSON 三份同源产物(`schema_version=sdd-efficiency-report/v4`,指标契约 `4.0`)。**仅 change 级**破坏性删除公开 `legacy_metrics`、无折叠兼容附录;变更类型仅 `config|transaction|report|composite`。单次变更 HTML 使用桌面方案 A,只展示当前 change 的四个页签:概览、指标与阶段、问题与证据、产物与追溯,不混入跨变更趋势。
110
+
111
+ `--period=biweekly|monthly` 等**项目/周期报告**仍使用既有长模板(可含历史兼容附录)。若要对 project 级同步去 legacy,须另开 change,勿在本发行中半迁移。
110
112
 
111
113
  报告中的业务名称优先于缩写:E1=每个验收场景平均用时,Q3=规约检查得分,P4=编码前检查覆盖,P-R=标准阶段重复次数,P-H=执行记录完整度。标准测量阶段固定为 propose、spec、design、task、check、apply、archive;test、explore 是辅助阶段,可展示但不进入效率分母。
112
114
 
113
115
  ```bash
114
- # 单变更报告(默认 html;可指定 markdown/json
116
+ # 单变更报告(默认 html;可指定 markdown/json)→ v4
115
117
  node skywalk-sdd/log.cjs report --project=. --change=<name> --format=json --output=reports/demo.json
116
118
 
117
- # 双周 / 月度周期对比(需完整窗口)
119
+ # 双周 / 月度周期对比(需完整窗口)→ 仍为项目级模板
118
120
  node skywalk-sdd/log.cjs report --project=. --period=biweekly --date-from=YYYY-MM-DD --date-to=YYYY-MM-DD
119
121
  node skywalk-sdd/log.cjs report --project=. --period=monthly --date-from=YYYY-MM-DD --date-to=YYYY-MM-DD
120
122
  ```
121
123
 
122
124
  `propose` 须确认 `change-type`;所有阶段必须显式携带 change,历史 general 事件只能通过 `scope_link` 归属。`check_result` 应携带 reviewer 独立性与 warning 处置元数据;归档 `archive_result` 只列真实写入成功的 `report_path` / `report_html_path` / `report_json_path`。
123
125
 
124
- 任务采用两个不可混淆的口径:“文档完成度”来自 tasks checkbox,“事件可追溯度”来自严格 task/test 证据。问题同时显示“类别数”和“规则命中次数”;指标同时显示“可计算性”和“可信度”。旧 E4/P1/P2/Q5 与旧 Q3 构建一次通过率仅出现在 legacy 区。
126
+ 任务采用两个不可混淆的口径:“文档完成度”来自 tasks checkbox,“事件可追溯度”来自严格 task/test 证据。问题同时显示“类别数”和“规则命中次数”;指标同时显示“可计算性”和“可信度”。change 级主视图不再渲染旧 E4/P1/P2/Q5;上述旧指标若仍出现,只可能在**项目级**兼容附录中。
125
127
 
126
128
  ---
127
129
 
package/lib/init.js CHANGED
@@ -845,6 +845,8 @@ function deployTelemetryDataDir(targetCwd = process.cwd()) {
845
845
  if (fs.existsSync(reportingSrc)) {
846
846
  copyDir(reportingSrc, reportingDst);
847
847
  console.log(' ✓ 部署 skywalk-sdd/reporting/(V3 单次变更报告)');
848
+ } else {
849
+ throw new Error(`E_INIT_MISSING_CRITICAL: reporting/ 目录缺失: ${reportingSrc}(归档报告生成将失败)`);
848
850
  }
849
851
 
850
852
  const contextClientSrc = path.join(pkgPath, 'skywalk-sdd', 'context-client.cjs');
@@ -870,6 +872,8 @@ function deployTelemetryDataDir(targetCwd = process.cwd()) {
870
872
  if (fs.existsSync(worktreeFinishSrc)) {
871
873
  fs.copyFileSync(worktreeFinishSrc, worktreeFinishDst);
872
874
  console.log(' ✓ 部署 skywalk-sdd/apply-worktree-finish.cjs(Apply 收尾脚本)');
875
+ } else {
876
+ console.log(' ⚠️ apply-worktree-finish.cjs 源文件缺失,Apply 阶段收尾需要手动执行');
873
877
  }
874
878
 
875
879
  const openspecShimSrc = path.join(pkgPath, 'skywalk-sdd', 'openspec-shim.cjs');
@@ -877,6 +881,8 @@ function deployTelemetryDataDir(targetCwd = process.cwd()) {
877
881
  if (fs.existsSync(openspecShimSrc)) {
878
882
  fs.copyFileSync(openspecShimSrc, openspecShimDst);
879
883
  console.log(' ✓ 部署 skywalk-sdd/openspec-shim.cjs(openspec 包裹包路径 shim)');
884
+ } else {
885
+ console.log(' ⚠️ openspec-shim.cjs 源文件缺失,openspec 命令需要手动 cd 到 spec 包执行');
880
886
  }
881
887
 
882
888
  console.log(' ✓ 调用方式: node skywalk-sdd/log.cjs start|end|metrics|semantic-identity|semantic-reconcile|semantic-check');
@@ -888,64 +894,115 @@ function deployTelemetryDataDir(targetCwd = process.cwd()) {
888
894
  return true;
889
895
  }
890
896
 
891
- function installGitHookShim(cwd, hookName, scriptPath, options = {}) {
897
+ /**
898
+ * 安装 SDD shell hook(多脚本调用型 hook,如 pre-commit / pre-push / commit-msg)。
899
+ * 直接部署完整的 shell 脚本到 .git/hooks/,脚本内部远程引用 spec 仓的 .cjs 脚本。
900
+ *
901
+ * shell hook 运行时通过 git config sdd.specPath / .sdd-spec-root / 向上搜索
902
+ * 定位 spec 仓的 skywalk-sdd/git-hooks/ 目录,兼容单仓/多仓/mono 布局。
903
+ *
904
+ * @param {string} cwd - Git 仓库根目录
905
+ * @param {string} hookName - hook 名称(如 'pre-commit'、'pre-push')
906
+ * @param {string} pkgPath - kld-sdd 包路径(用于读取模板)
907
+ */
908
+ function installSddShellHook(cwd, hookName, pkgPath = getPackagePath()) {
892
909
  const hooksDir = path.join(cwd, '.git', 'hooks');
893
910
  if (!fs.existsSync(hooksDir)) {
894
911
  return;
895
912
  }
896
913
 
914
+ const templatePath = path.join(pkgPath, 'templates', 'git-hooks', hookName);
915
+ if (!fs.existsSync(templatePath)) {
916
+ console.log(` ⚠️ Hook 模板不存在: ${templatePath}`);
917
+ return;
918
+ }
919
+
897
920
  const hookPath = path.join(hooksDir, hookName);
898
921
  const marker = 'KLD SDD quality gate';
899
- // Git commit-msg 文件路径放在 $1;--project 等额外参数必须跟在 "$@" 后面,
900
- // 否则 trailer 脚本会把 --project=… 误当成 message 文件(argv[2])。
901
- const extraArgs = options.extraArgs || '';
902
- // Windows 反斜杠路径在 #!/bin/sh(Git for Windows MSYS2)中不被 [ -f ] 和 node 识别,
903
- // 统一转为正斜杠,确保 hook shim 跨平台可执行。
904
- const shScriptPath = scriptPath.replace(/\\/g, '/');
905
- const shExtraArgs = extraArgs.replace(/\\/g, '/');
906
- const nodeLine = shExtraArgs
907
- ? ` node "${shScriptPath}" "$@" ${shExtraArgs}`
908
- : ` node "${shScriptPath}" "$@"`;
909
- const shim = [
910
- '#!/bin/sh',
911
- `# ${marker}`,
912
- `if [ -f "${shScriptPath}" ]; then`,
913
- nodeLine,
914
- 'else',
915
- ` echo "[kld-sdd] Hook 脚本不存在: ${shScriptPath}" >&2`,
916
- ' exit 1',
917
- 'fi',
918
- '',
919
- ].join('\n');
922
+ const content = fs.readFileSync(templatePath, 'utf8');
920
923
 
921
924
  if (fs.existsSync(hookPath)) {
922
925
  const existing = fs.readFileSync(hookPath, 'utf8');
923
926
  if (existing.includes(marker)) {
924
- // 已是 SDD shim:若指向路径变化(如改为引用 spec 仓),允许覆盖升级
925
- if (existing.includes(shScriptPath) && (!shExtraArgs || existing.includes(shExtraArgs.trim()))) {
926
- console.log(` ✓ .git/hooks/${hookName} 已包含 SDD 质量门禁`);
927
- return;
928
- }
929
- fs.writeFileSync(hookPath, shim, 'utf8');
927
+ // 已是 SDD hook:允许覆盖升级
928
+ fs.writeFileSync(hookPath, content, 'utf8');
930
929
  try {
931
930
  fs.chmodSync(hookPath, 0o755);
932
931
  } catch {
933
932
  // ignore
934
933
  }
935
- console.log(` ✓ 更新 .git/hooks/${hookName} SDD 质量门禁`);
934
+ console.log(` ✓ 更新 .git/hooks/${hookName} SDD 质量门禁(多脚本)`);
936
935
  return;
937
936
  }
938
- console.log(` ℹ️ .git/hooks/${hookName} 已存在,已保留不覆盖;可手动调用 ${scriptPath}`);
937
+ console.log(` ℹ️ .git/hooks/${hookName} 已存在且非 SDD 受管 hook,已保留不覆盖`);
939
938
  return;
940
939
  }
941
940
 
942
- fs.writeFileSync(hookPath, shim, 'utf8');
941
+ fs.writeFileSync(hookPath, content, 'utf8');
943
942
  try {
944
943
  fs.chmodSync(hookPath, 0o755);
945
944
  } catch {
946
- // Windows 上 chmod 可能没有实际效果,不影响 Git Bash 执行文本 hook。
945
+ // Windows 上 chmod 可能没有实际效果
946
+ }
947
+ console.log(` ✓ 安装 .git/hooks/${hookName} SDD 质量门禁(多脚本)`);
948
+ }
949
+
950
+ /**
951
+ * 部署代码仓全部 Git hooks(commit-msg + pre-commit + pre-push)。
952
+ *
953
+ * 统一入口,封装三种 hook 的部署逻辑。代码仓**不落 skywalk-sdd/**,
954
+ * 只在 .git/hooks/ 安装 shell hook 模板,远程引用 spec 仓的 .cjs 脚本:
955
+ *
956
+ * - **spec 仓**:确保 skywalk-sdd/git-hooks/ 下有全部 .cjs 脚本
957
+ * (commit-msg-sdd-trailer + pre-commit-* + pre-push-* + ontology)。
958
+ * - **代码仓 .git/hooks/**:仅安装 3 个 shell hook 模板,运行时通过
959
+ * git config sdd.specPath / .sdd-spec-root / 向上搜索定位 spec 仓的脚本。
960
+ *
961
+ * @param {string} codeRepoRoot - 代码仓根目录
962
+ * @param {string} specRepoRoot - spec 包裹包根目录
963
+ * @param {object} options - { pkgPath }
964
+ * @returns {{ ok: boolean, message?: string }}
965
+ */
966
+ function deployCodeRepoHooks(codeRepoRoot, specRepoRoot, options = {}) {
967
+ const cwd = path.resolve(codeRepoRoot);
968
+ const specRoot = path.resolve(specRepoRoot);
969
+ const pkgPath = options.pkgPath || getPackagePath();
970
+
971
+ if (!workspaceLayout.isGitRepo(cwd)) {
972
+ return { ok: false, message: '不是 Git 仓库' };
973
+ }
974
+
975
+ // ── 1. 确保 spec 仓有全部 hook 脚本 + ontology ──
976
+ // commit-msg .cjs + ontology(ensureSpecCommitMsgScript 已处理)
977
+ ensureSpecCommitMsgScript(specRoot, pkgPath);
978
+ // pre-commit / pre-push .cjs 脚本
979
+ const specHooksDir = path.join(specRoot, 'skywalk-sdd', 'git-hooks');
980
+ const gitHooksTemplateDir = path.join(pkgPath, 'templates', 'git-hooks');
981
+ if (!fs.existsSync(specHooksDir)) {
982
+ fs.mkdirSync(specHooksDir, { recursive: true });
983
+ }
984
+ const hookScripts = [
985
+ 'pre-commit-sdd-check.cjs',
986
+ 'pre-commit-consistency-check.cjs',
987
+ 'pre-push-sdd-check.cjs',
988
+ 'pre-push-consistency-check.cjs',
989
+ ];
990
+ for (const script of hookScripts) {
991
+ const src = path.join(gitHooksTemplateDir, script);
992
+ const dst = path.join(specHooksDir, script);
993
+ if (fs.existsSync(src) && !fs.existsSync(dst)) {
994
+ fs.copyFileSync(src, dst);
995
+ }
947
996
  }
948
- console.log(` ✓ 安装 .git/hooks/${hookName} SDD 质量门禁`);
997
+ console.log(` ✓ 确保 spec 仓 skywalk-sdd/git-hooks/ 脚本齐全`);
998
+
999
+ // ── 2. 安装三个 shell hooks 到代码仓 .git/hooks/ ──
1000
+ // 模板 hook 运行时自动定位 spec 仓的 .cjs 脚本
1001
+ installSddShellHook(cwd, 'commit-msg', pkgPath);
1002
+ installSddShellHook(cwd, 'pre-commit', pkgPath);
1003
+ installSddShellHook(cwd, 'pre-push', pkgPath);
1004
+
1005
+ return { ok: true };
949
1006
  }
950
1007
 
951
1008
  /**
@@ -970,22 +1027,6 @@ function ensureSpecCommitMsgScript(specRepoRoot, pkgPath = getPackagePath()) {
970
1027
  return { ok: true, scriptPath, deployed: true };
971
1028
  }
972
1029
 
973
- /**
974
- * 代码仓 commit-msg:只写 .git/hooks,脚本与 ontology 一律用 spec 仓那一份。
975
- */
976
- function installCodeRepoCommitMsgHook(codeRepoRoot, specRepoRoot, options = {}) {
977
- const cwd = path.resolve(codeRepoRoot);
978
- const ensured = ensureSpecCommitMsgScript(specRepoRoot, options.pkgPath || getPackagePath());
979
- if (!ensured.ok) {
980
- console.log(` ⚠️ ${ensured.message}`);
981
- return false;
982
- }
983
- installGitHookShim(cwd, 'commit-msg', ensured.scriptPath, {
984
- extraArgs: `"--project=${cwd}"`,
985
- });
986
- return true;
987
- }
988
-
989
1030
  /**
990
1031
  * 部署 Git hooks / CI 兜底模板
991
1032
  * 这些脚本只做质量门禁和 CI 补充记录,不替代 OPSX 主采集链路。
@@ -993,7 +1034,7 @@ function installCodeRepoCommitMsgHook(codeRepoRoot, specRepoRoot, options = {})
993
1034
  * @param {string} [targetCwd]
994
1035
  * @param {{ mode?: 'full'|'commit-msg-only' }} [options]
995
1036
  * full: spec 包裹包(pre-commit/pre-push/commit-msg + CI)
996
- * commit-msg-only: 单仓 Git 根(本仓落 skywalk-sdd/git-hooks;多仓代码仓请用 installCodeRepoCommitMsgHook
1037
+ * commit-msg-only: 仅安装 commit-msg hook(跳过 pre-commit/pre-push
997
1038
  */
998
1039
  function deployQualityGateTemplates(targetCwd = process.cwd(), options = {}) {
999
1040
  const pkgPath = getPackagePath();
@@ -1024,18 +1065,18 @@ function deployQualityGateTemplates(targetCwd = process.cwd(), options = {}) {
1024
1065
  }
1025
1066
 
1026
1067
  if (mode === 'full') {
1027
- installGitHookShim(cwd, 'pre-commit', 'skywalk-sdd/git-hooks/pre-commit-sdd-check.cjs');
1028
- installGitHookShim(cwd, 'pre-push', 'skywalk-sdd/git-hooks/pre-push-sdd-check.cjs');
1068
+ installSddShellHook(cwd, 'pre-commit', pkgPath);
1069
+ installSddShellHook(cwd, 'pre-push', pkgPath);
1029
1070
  }
1030
- installGitHookShim(cwd, 'commit-msg', 'skywalk-sdd/git-hooks/commit-msg-sdd-trailer.cjs');
1071
+ installSddShellHook(cwd, 'commit-msg', pkgPath);
1031
1072
 
1032
1073
  console.log('✅ Git hooks 已就绪');
1033
1074
  return true;
1034
1075
  }
1035
1076
 
1036
1077
  /**
1037
- * 代码仓轻量接入:只写 .sdd.yaml + sdd.specPath + .git/hooks/commit-msg
1038
- * 不在代码仓落 skywalk-sdd/——Hook 脚本与 ontology 引用 spec 包裹包那一份。
1078
+ * 代码仓轻量接入:写 .sdd.yaml + sdd.specPath + .git/hooks/(commit-msg + pre-commit + pre-push)。
1079
+ * 代码仓不落 skywalk-sdd/,shell hook 远程引用 spec 仓 skywalk-sdd/git-hooks/ 下的 .cjs 脚本。
1039
1080
  */
1040
1081
  function attachCodeRepoLite(codeRepoRoot, specRepoRoot, options = {}) {
1041
1082
  const cwd = path.resolve(codeRepoRoot);
@@ -1049,7 +1090,7 @@ function attachCodeRepoLite(codeRepoRoot, specRepoRoot, options = {}) {
1049
1090
  return { ok: false, repo: label, message: `spec 路径不是 Git 仓库: ${specRoot}` };
1050
1091
  }
1051
1092
 
1052
- console.log(`🔗 轻量接入代码仓(无 skywalk-sdd/、无 skills): ${label}`);
1093
+ console.log(`🔗 轻量接入代码仓(commit-msg + pre-commit + pre-push): ${label}`);
1053
1094
 
1054
1095
  const remote = sddConfig.gitRemoteUrl(specRoot) || 'git@gitlab.example.com:biz/xxx-sdd-specs.git';
1055
1096
  const sddYamlPath = path.join(cwd, '.sdd.yaml');
@@ -1075,8 +1116,8 @@ function attachCodeRepoLite(codeRepoRoot, specRepoRoot, options = {}) {
1075
1116
  }
1076
1117
  console.log(` ✓ sdd.specPath = ${linked.path}`);
1077
1118
 
1078
- installCodeRepoCommitMsgHook(cwd, specRoot, options);
1079
- console.log(' ✓ commit-msg → spec 仓 skywalk-sdd/git-hooks/(代码仓不落 skywalk-sdd/)');
1119
+ // 部署代码仓全部 Git hooks(commit-msg + pre-commit + pre-push)
1120
+ deployCodeRepoHooks(cwd, specRoot, options);
1080
1121
 
1081
1122
  return { ok: true, repo: label, path: cwd, specPath: linked.path };
1082
1123
  }
@@ -1549,8 +1590,9 @@ async function main() {
1549
1590
  removeOuterSkywalk(workspaceRoot);
1550
1591
 
1551
1592
  deployMonoSddYaml(workspaceRoot, { specPathRelative: specPackage.name });
1552
- // Hook 装在 Git 根,脚本在包裹包内(Git 根不落 skywalk-sdd/)
1553
- installCodeRepoCommitMsgHook(workspaceRoot, specPackage.abs);
1593
+ // 部署代码仓全部 Git hooks(commit-msg + pre-commit + pre-push)
1594
+ // 单仓 mono:hook 通过 .sdd-spec-root 定位包裹包的 skywalk-sdd/git-hooks/
1595
+ deployCodeRepoHooks(workspaceRoot, specPackage.abs);
1554
1596
  const linked = sddConfig.setSpecPath(workspaceRoot, specPackage.abs, {
1555
1597
  allowNestedPackage: true,
1556
1598
  });
@@ -1643,7 +1685,7 @@ async function main() {
1643
1685
  console.log(' 📌 .sdd-spec-root → 包裹包;无根目录 skywalk-sdd/');
1644
1686
  }
1645
1687
  if (selectedTools.includes('kunlunzhima')) {
1646
- console.log(' 📎 .kunlunzhima/commands/opsx/ # KunlunZhima OPSX command bridge(11 个)');
1688
+ console.log(' 📎 .kunlunzhima/commands/opsx/ # KunlunZhima OPSX command bridge(12 个)');
1647
1689
  console.log(' ℹ️ KunlunZhima 通过 commands/skills 入口使用 SDD,未启用自动 Hook');
1648
1690
  }
1649
1691
  if (selectedTools.includes('codebuddy')) {
@@ -1655,18 +1697,19 @@ async function main() {
1655
1697
  console.log();
1656
1698
 
1657
1699
  // 统一的 skill 格式说明
1658
- console.log('可用 skills(opsx-* 系列,11 个 SDD skills):');
1659
- console.log(' opsx-propose - 创建业务意图文档(Why)');
1660
- console.log(' opsx-spec - 创建技术契约文档(What)');
1661
- console.log(' opsx-design - 创建技术实现方案(How)');
1662
- console.log(' opsx-task - 拆解AI编码任务(Do)');
1663
- console.log(' opsx-check - 质量门禁检查(Verify)');
1664
- console.log(' opsx-apply - 申请变更实施(Apply)');
1665
- console.log(' opsx-test - 执行单元测试(Test)');
1666
- console.log(' opsx-archive - 归档变更(Archive)');
1667
- console.log(' opsx-explore - 浏览变更状态(Explore)');
1668
- console.log(' opsx-knowledge - 业务知识库检索(辅助)');
1669
- console.log(' opsx-rules - 生成/更新 Agent 规则(辅助)');
1700
+ console.log('可用 skills(opsx-* 系列,14 个 SDD skills):');
1701
+ console.log(' opsx-propose - 创建业务意图文档(Why)');
1702
+ console.log(' opsx-spec - 创建技术契约文档(What)');
1703
+ console.log(' opsx-design - 创建技术实现方案(How)');
1704
+ console.log(' opsx-task - 拆解AI编码任务(Do)');
1705
+ console.log(' opsx-check - 质量门禁检查(Verify)');
1706
+ console.log(' opsx-apply - 申请变更实施(Apply)');
1707
+ console.log(' opsx-test - 执行单元测试(Test)');
1708
+ console.log(' opsx-archive - 归档变更(Archive)');
1709
+ console.log(' opsx-explore - 浏览变更状态(Explore)');
1710
+ console.log(' opsx-knowledge - 业务知识库检索(辅助)');
1711
+ console.log(' opsx-rules - 生成/更新 Agent 规则(辅助)');
1712
+ console.log(' opsx-consistency-check - Spec 一致性校验(代码 vs spec)');
1670
1713
 
1671
1714
  console.log();
1672
1715
  console.log('后续步骤:');
@@ -1723,5 +1766,7 @@ module.exports = {
1723
1766
  syncWorkspaceRepos,
1724
1767
  copyDirRendered,
1725
1768
  parseSelectedTools,
1769
+ installSddShellHook,
1770
+ deployCodeRepoHooks,
1726
1771
  TOOL_CONFIGS,
1727
1772
  };
@@ -22,6 +22,8 @@ const OPSX_SKILL_DIRS = [
22
22
  // Engineering KB 依赖技能(随 init 部署;propose/spec/archive 硬依赖)
23
23
  'opsx-ontology-query',
24
24
  'opsx-kb-ingest',
25
+ // Spec 一致性校验技能
26
+ 'opsx-consistency-check',
25
27
  ];
26
28
 
27
29
  const PKG_ROOT = path.resolve(__dirname, '..');
@@ -102,6 +104,7 @@ const KUNLUN_SLASH_COMMANDS = [
102
104
  'explore',
103
105
  'ontology-query',
104
106
  'kb-ingest',
107
+ 'consistency-check',
105
108
  ];
106
109
 
107
110
  function transformKunlunSlashCommands(content) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kld-sdd",
3
- "version": "2.6.14",
3
+ "version": "2.6.16",
4
4
  "description": "KLD SDD OpenSpec 项目初始化工具 - 一键部署 SDD skills",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -8,7 +8,7 @@
8
8
  "kld-sdd-init": "bin/kld-sdd-init.js"
9
9
  },
10
10
  "scripts": {
11
- "test": "node test/external-key.cjs && node test/change-key.cjs && node test/modules-and-sdd-config.cjs && node test/active-changes.cjs && node test/hook-layouts.cjs && node test/spec-package-init.cjs && node test/workspace-layout.cjs && node test/ontology-release-blockers.cjs && node test/ontology-semantic-core.cjs && node test/ontology-identity-versioning.cjs && node test/ontology-identity-continuity.cjs && node test/ontology-state-transaction.cjs && node test/ontology-process-concurrency.cjs && node test/ontology-observer-convergence.cjs && node test/ontology-working-runtime.cjs && node test/ontology-stage-materialization.cjs && node test/ontology-template-contract.cjs && node test/ontology-cli-archive.cjs && node test/archive-package-producer.cjs && node --test test/change-report-correctness.cjs test/report-metrics-correctness.cjs test/change-report-model-ui.cjs && node test/validate-skills-bundle.cjs && node test/tool-profiles.cjs && node test/settings-merge.cjs && node test/command-bridge.cjs && node test/codebuddy-hooks.cjs && node test/skill-content-contract.cjs && node test/init-agent-profiles.cjs && node test/init-report-runtime.cjs"
11
+ "test": "node test/external-key.cjs && node test/change-key.cjs && node test/modules-and-sdd-config.cjs && node test/active-changes.cjs && node test/hook-layouts.cjs && node test/spec-package-init.cjs && node test/workspace-layout.cjs && node test/ontology-release-blockers.cjs && node test/ontology-semantic-core.cjs && node test/ontology-identity-versioning.cjs && node test/ontology-identity-continuity.cjs && node test/ontology-state-transaction.cjs && node test/ontology-process-concurrency.cjs && node test/ontology-observer-convergence.cjs && node test/ontology-working-runtime.cjs && node test/ontology-stage-materialization.cjs && node test/ontology-template-contract.cjs && node test/ontology-cli-archive.cjs && node test/archive-package-producer.cjs && node --test test/evidence-integrity-oracle.cjs test/evidence-integrity-wiring.cjs test/change-report-correctness.cjs test/report-metrics-correctness.cjs test/change-report-model-ui.cjs && node test/validate-skills-bundle.cjs && node test/tool-profiles.cjs && node test/settings-merge.cjs && node test/command-bridge.cjs && node test/codebuddy-hooks.cjs && node test/skill-content-contract.cjs && node test/init-agent-profiles.cjs && node test/init-report-runtime.cjs"
12
12
  },
13
13
  "keywords": [
14
14
  "kld",
@@ -36,6 +36,7 @@
36
36
  "skywalk-sdd/runtime-metadata.cjs",
37
37
  "skywalk-sdd/reporting/",
38
38
  "skywalk-sdd/context-client.cjs",
39
+ "skywalk-sdd/openspec-shim.cjs",
39
40
  "skywalk-sdd/ontology/",
40
41
  "skywalk-sdd/apply-worktree-finish.cjs",
41
42
  "README.md"