kld-sdd 2.6.16 → 2.6.21
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/bin/kld-sdd-init.js +10 -0
- package/kld-sdd-guide.html +22 -0
- package/lib/device-auth-cli.js +130 -0
- package/lib/device-auth.js +345 -0
- package/lib/init-account-binding.js +108 -0
- package/lib/init.js +238 -55
- package/lib/skills-bundle.js +20 -1
- package/lib/tool-profiles.js +8 -0
- package/package.json +7 -3
- package/skywalk-sdd/apply-worktree-finish.cjs +2 -23
- package/skywalk-sdd/context-client.cjs +38 -87
- package/skywalk-sdd/index.cjs +860 -132
- package/skywalk-sdd/kb-sync-identity.cjs +780 -0
- package/skywalk-sdd/kb-upload.cjs +505 -0
- package/skywalk-sdd/lib/shared.cjs +811 -0
- package/skywalk-sdd/lib/usage-contract.cjs +276 -0
- package/skywalk-sdd/lib/usage-reporter.cjs +354 -0
- package/skywalk-sdd/lib/user-config.cjs +157 -0
- package/skywalk-sdd/metrics-v3.cjs +138 -8
- package/skywalk-sdd/ontology/archive-package.cjs +19 -34
- package/skywalk-sdd/ontology/change-lock.cjs +3 -7
- package/skywalk-sdd/ontology/external-key.cjs +18 -4
- package/skywalk-sdd/ontology/id.cjs +26 -5
- package/skywalk-sdd/ontology/identity-index.cjs +3 -7
- package/skywalk-sdd/ontology/resolve-spec-root.cjs +20 -6
- package/skywalk-sdd/ontology/runtime.cjs +16 -12
- package/skywalk-sdd/ontology/traceability-validator.cjs +7 -4
- package/skywalk-sdd/reporting/change-report-markdown.cjs +137 -19
- package/skywalk-sdd/reporting/change-report-model.cjs +993 -14
- package/skywalk-sdd/reporting/change-report-renderer.cjs +106 -41
- package/skywalk-sdd/reporting/change-report-view-model.cjs +272 -43
- package/skywalk-sdd/reporting/core-metric-definitions.cjs +192 -0
- package/skywalk-sdd/spec-root.cjs +31 -0
- package/templates/git-hooks/pre-commit-consistency-check.cjs +271 -116
- package/templates/git-hooks/pre-push-consistency-check.cjs +252 -123
- package/templates/hooks/codebuddy/hooks/hook-gate-core.cjs +327 -0
- package/templates/hooks/codebuddy/hooks/sdd-apply-test-gate.cjs +54 -9
- package/templates/hooks/codebuddy/hooks/sdd-mid-checkpoint.cjs +63 -6
- package/templates/hooks/codebuddy/hooks/sdd-tdd-rhythm-gate.cjs +113 -65
- package/templates/openspec/proposal.md +7 -3
- package/templates/openspec/spec.md +3 -3
- package/templates/skills/kld-sdd/opsx-apply/SKILL.md +8 -6
- package/templates/skills/kld-sdd/opsx-apply/checklist.md +2 -0
- package/templates/skills/kld-sdd/opsx-apply/reference.md +29 -7
- package/templates/skills/kld-sdd/opsx-archive/SKILL.md +6 -5
- package/templates/skills/kld-sdd/opsx-check/SKILL.md +49 -17
- package/templates/skills/kld-sdd/opsx-check/checklist.md +4 -2
- package/templates/skills/kld-sdd/opsx-consistency-check/SKILL.md +187 -257
- package/templates/skills/kld-sdd/opsx-consistency-check/reference.md +129 -0
- package/templates/skills/kld-sdd/opsx-design/SKILL.md +2 -2
- package/templates/skills/kld-sdd/opsx-explore/SKILL.md +2 -2
- package/templates/skills/kld-sdd/opsx-kb-config/SKILL.md +185 -0
- package/templates/skills/kld-sdd/opsx-kb-config/reference.md +127 -0
- package/templates/skills/kld-sdd/opsx-kb-ingest/SKILL.md +218 -53
- package/templates/skills/kld-sdd/opsx-kb-ingest/reference.md +51 -9
- package/templates/skills/kld-sdd/opsx-ontology-query/SKILL.md +12 -50
- package/templates/skills/kld-sdd/opsx-ontology-query/phase-3-postchange.md +2 -2
- package/templates/skills/kld-sdd/opsx-ontology-query/reference.md +1 -1
- package/templates/skills/kld-sdd/opsx-propose/SKILL.md +35 -23
- package/templates/skills/kld-sdd/opsx-propose/checklist.md +2 -0
- package/templates/skills/kld-sdd/opsx-propose/reference.md +22 -17
- package/templates/skills/kld-sdd/opsx-rules/SKILL.md +2 -2
- package/templates/skills/kld-sdd/opsx-spec/SKILL.md +19 -15
- package/templates/skills/kld-sdd/opsx-spec/checklist.md +2 -0
- package/templates/skills/kld-sdd/opsx-task/SKILL.md +2 -4
- package/templates/skills/kld-sdd/opsx-test/SKILL.md +2 -2
- package/templates/skills/kld-sdd/tdd-core/reference.md +1 -1
- package/templates/skills/kld-sdd/tdd-rules/rules/test-skeleton-telemetry.md +1 -1
- package/templates/skills/kld-sdd/opsx-kb-ingest/state.example.json +0 -7
- package/templates/skills/kld-sdd/opsx-ontology-query/state.example.json +0 -7
package/lib/init.js
CHANGED
|
@@ -30,11 +30,26 @@ const {
|
|
|
30
30
|
const { deployCodebuddyHookPack } = require('./deploy-codebuddy-hooks');
|
|
31
31
|
const workspaceLayout = require('./workspace-layout');
|
|
32
32
|
const sddConfig = require('../skywalk-sdd/ontology/sdd-config.cjs');
|
|
33
|
+
const { runAccountBinding } = require('./init-account-binding');
|
|
33
34
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
35
|
+
let rl = null;
|
|
36
|
+
|
|
37
|
+
function getRl() {
|
|
38
|
+
if (!rl) {
|
|
39
|
+
rl = readline.createInterface({
|
|
40
|
+
input: process.stdin,
|
|
41
|
+
output: process.stdout,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
return rl;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function closeRl() {
|
|
48
|
+
if (rl) {
|
|
49
|
+
rl.close();
|
|
50
|
+
rl = null;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
38
53
|
|
|
39
54
|
// 工具类型配置(路径字段从 TOOL_PROFILES 派生,避免双份漂移)
|
|
40
55
|
const TOOL_CONFIGS = buildToolConfigs();
|
|
@@ -44,10 +59,30 @@ const TOOL_CONFIGS = buildToolConfigs();
|
|
|
44
59
|
*/
|
|
45
60
|
function ask(question) {
|
|
46
61
|
return new Promise(resolve => {
|
|
47
|
-
|
|
62
|
+
getRl().question(question, answer => resolve(answer.trim()));
|
|
48
63
|
});
|
|
49
64
|
}
|
|
50
65
|
|
|
66
|
+
/**
|
|
67
|
+
* 输出详细度判定(惰性读取,便于测试在运行期注入)
|
|
68
|
+
* 触发条件:argv 含 --verbose,或 KLD_SDD_VERBOSE 为 1/true(大小写不敏感)
|
|
69
|
+
* 注意:-v 已被 --version 占用,不复用
|
|
70
|
+
*/
|
|
71
|
+
function isVerbose() {
|
|
72
|
+
if (process.argv.includes('--verbose')) return true;
|
|
73
|
+
const env = process.env.KLD_SDD_VERBOSE;
|
|
74
|
+
return typeof env === 'string' && /^(1|true)$/i.test(env);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* verbose 模式下的明细日志;默认模式静默
|
|
79
|
+
*/
|
|
80
|
+
function vlog(...args) {
|
|
81
|
+
if (isVerbose()) {
|
|
82
|
+
console.log(...args);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
51
86
|
/**
|
|
52
87
|
* 从命令行参数读取指定编辑器
|
|
53
88
|
* 支持:--tool codex、--tool=codex、--tool cursor,codex、--tool all
|
|
@@ -496,7 +531,7 @@ function deployOpsxSkills(selectedTools = Object.keys(TOOL_CONFIGS)) {
|
|
|
496
531
|
|
|
497
532
|
if (fs.existsSync(sourceDir)) {
|
|
498
533
|
copyDirRendered(sourceDir, targetDir, config, toolKey);
|
|
499
|
-
|
|
534
|
+
vlog(` ✓ ${skillDir}/`);
|
|
500
535
|
}
|
|
501
536
|
}
|
|
502
537
|
}
|
|
@@ -706,14 +741,14 @@ function copyTemplatesToProject(cwd = process.cwd()) {
|
|
|
706
741
|
}
|
|
707
742
|
|
|
708
743
|
copyDir(templatePath, targetDir);
|
|
709
|
-
|
|
710
|
-
console.log(`✅ 标准文档模版已复制到: ${targetDir}`);
|
|
711
|
-
console.log(' 包含文件:');
|
|
744
|
+
|
|
712
745
|
const files = fs.readdirSync(targetDir);
|
|
746
|
+
console.log(`✅ 标准文档模版已复制到: ${targetDir}(${files.length} 个文件)`);
|
|
747
|
+
vlog(' 包含文件:');
|
|
713
748
|
files.forEach(file => {
|
|
714
|
-
|
|
749
|
+
vlog(` - ${file}`);
|
|
715
750
|
});
|
|
716
|
-
|
|
751
|
+
|
|
717
752
|
return true;
|
|
718
753
|
}
|
|
719
754
|
|
|
@@ -803,13 +838,15 @@ function deployTelemetryDataDir(targetCwd = process.cwd()) {
|
|
|
803
838
|
// 创建本地数据目录(事件和活跃状态存储;报告落 change 子目录,不在此创建)
|
|
804
839
|
const eventsDir = path.join(dataDir, 'events');
|
|
805
840
|
const stateDir = path.join(dataDir, 'state');
|
|
841
|
+
// 成功部署的模块计数(用于默认模式单行摘要)
|
|
842
|
+
let deployedModules = 0;
|
|
806
843
|
if (!fs.existsSync(eventsDir)) {
|
|
807
844
|
fs.mkdirSync(eventsDir, { recursive: true });
|
|
808
|
-
|
|
845
|
+
vlog(' ✓ 创建 skywalk-sdd/events/ 数据目录');
|
|
809
846
|
}
|
|
810
847
|
if (!fs.existsSync(stateDir)) {
|
|
811
848
|
fs.mkdirSync(stateDir, { recursive: true });
|
|
812
|
-
|
|
849
|
+
vlog(' ✓ 创建 skywalk-sdd/state/ 活跃阶段状态目录');
|
|
813
850
|
}
|
|
814
851
|
|
|
815
852
|
// 部署项目内 Telemetry CLI(不依赖 npm 发布)
|
|
@@ -817,7 +854,8 @@ function deployTelemetryDataDir(targetCwd = process.cwd()) {
|
|
|
817
854
|
const telemetryDst = path.join(dataDir, 'log.cjs');
|
|
818
855
|
if (fs.existsSync(telemetrySrc)) {
|
|
819
856
|
fs.copyFileSync(telemetrySrc, telemetryDst);
|
|
820
|
-
|
|
857
|
+
deployedModules += 1;
|
|
858
|
+
vlog(' ✓ 部署 skywalk-sdd/log.cjs(本地 Telemetry CLI)');
|
|
821
859
|
} else {
|
|
822
860
|
console.log(` ⚠️ Telemetry CLI 源文件缺失: ${telemetrySrc}`);
|
|
823
861
|
}
|
|
@@ -826,11 +864,58 @@ function deployTelemetryDataDir(targetCwd = process.cwd()) {
|
|
|
826
864
|
const metricsV3Dst = path.join(dataDir, 'metrics-v3.cjs');
|
|
827
865
|
if (fs.existsSync(metricsV3Src)) {
|
|
828
866
|
fs.copyFileSync(metricsV3Src, metricsV3Dst);
|
|
829
|
-
|
|
867
|
+
deployedModules += 1;
|
|
868
|
+
vlog(' ✓ 部署 skywalk-sdd/metrics-v3.cjs(V3 指标运行时)');
|
|
830
869
|
} else {
|
|
831
870
|
console.log(` ⚠️ V3 指标模块源文件缺失: ${metricsV3Src}(report/metrics 可能无法加载 metrics-v3)`);
|
|
832
871
|
}
|
|
833
872
|
|
|
873
|
+
// 部署 spec-root.cjs(替代脆弱的 $(cat .sdd-spec-root),CWD 无关)
|
|
874
|
+
const specRootSrc = path.join(pkgPath, 'skywalk-sdd', 'spec-root.cjs');
|
|
875
|
+
const specRootDst = path.join(dataDir, 'spec-root.cjs');
|
|
876
|
+
if (fs.existsSync(specRootSrc)) {
|
|
877
|
+
fs.copyFileSync(specRootSrc, specRootDst);
|
|
878
|
+
deployedModules += 1;
|
|
879
|
+
vlog(' ✓ 部署 skywalk-sdd/spec-root.cjs(CWD 无关的 spec 根路径解析器)');
|
|
880
|
+
} else {
|
|
881
|
+
console.log(' ⚠️ spec-root.cjs 源文件缺失,$(cat .sdd-spec-root) 模式可能受影响');
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
// 部署 lib/shared.cjs(共用工具模块:parseArgs/readJson/atomicWrite/HTTP/specRoot/KB状态)
|
|
885
|
+
const sharedLibDir = path.join(dataDir, 'lib');
|
|
886
|
+
if (!fs.existsSync(sharedLibDir)) {
|
|
887
|
+
fs.mkdirSync(sharedLibDir, { recursive: true });
|
|
888
|
+
}
|
|
889
|
+
const sharedSrc = path.join(pkgPath, 'skywalk-sdd', 'lib', 'shared.cjs');
|
|
890
|
+
const sharedDst = path.join(sharedLibDir, 'shared.cjs');
|
|
891
|
+
if (fs.existsSync(sharedSrc)) {
|
|
892
|
+
fs.copyFileSync(sharedSrc, sharedDst);
|
|
893
|
+
deployedModules += 1;
|
|
894
|
+
vlog(' ✓ 部署 skywalk-sdd/lib/shared.cjs(共用工具:parseArgs/JSON/BOM/HTTP/specRoot/KB)');
|
|
895
|
+
} else {
|
|
896
|
+
console.log(' ⚠️ lib/shared.cjs 源文件缺失,多个脚本将缺少共用工具依赖');
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
// kld-fixback: 部署使用统计上报模块(usage-contract/usage-reporter/user-config)
|
|
900
|
+
// 这些模块被部署后的 skywalk-sdd/log.cjs(即 index.cjs 副本)在 cmdStart 中 require,
|
|
901
|
+
// 缺失时会上报静默失效。三件套必须同时部署,路径与 npm 包内布局一致。
|
|
902
|
+
const usageModules = [
|
|
903
|
+
{ src: 'usage-contract.cjs', desc: '使用统计契约(七值/Device/ApiResponse/HTTP)' },
|
|
904
|
+
{ src: 'usage-reporter.cjs', desc: '使用事件上报器(3s deadline + pending 队列)' },
|
|
905
|
+
{ src: 'user-config.cjs', desc: '用户级配置(~/.kld-sdd/config.json + cli_token)' },
|
|
906
|
+
];
|
|
907
|
+
for (const mod of usageModules) {
|
|
908
|
+
const src = path.join(pkgPath, 'skywalk-sdd', 'lib', mod.src);
|
|
909
|
+
const dst = path.join(sharedLibDir, mod.src);
|
|
910
|
+
if (fs.existsSync(src)) {
|
|
911
|
+
fs.copyFileSync(src, dst);
|
|
912
|
+
deployedModules += 1;
|
|
913
|
+
vlog(` ✓ 部署 skywalk-sdd/lib/${mod.src}(${mod.desc})`);
|
|
914
|
+
} else {
|
|
915
|
+
console.log(` ⚠️ ${mod.src} 源文件缺失,使用统计上报将不可用`);
|
|
916
|
+
}
|
|
917
|
+
}
|
|
918
|
+
|
|
834
919
|
const packageVersion = require(path.join(pkgPath, 'package.json')).version;
|
|
835
920
|
const runtimeMetadataDst = path.join(dataDir, 'runtime-metadata.cjs');
|
|
836
921
|
fs.writeFileSync(
|
|
@@ -838,13 +923,15 @@ function deployTelemetryDataDir(targetCwd = process.cwd()) {
|
|
|
838
923
|
`'use strict';\nmodule.exports = { resolveRuntimeMetadata() { return { version: '${packageVersion}', producer: 'kld-sdd@${packageVersion}' }; } };\n`,
|
|
839
924
|
'utf8',
|
|
840
925
|
);
|
|
841
|
-
|
|
926
|
+
deployedModules += 1;
|
|
927
|
+
vlog(` ✓ 部署 kld-sdd 运行时身份(${packageVersion})`);
|
|
842
928
|
|
|
843
929
|
const reportingSrc = path.join(pkgPath, 'skywalk-sdd', 'reporting');
|
|
844
930
|
const reportingDst = path.join(dataDir, 'reporting');
|
|
845
931
|
if (fs.existsSync(reportingSrc)) {
|
|
846
932
|
copyDir(reportingSrc, reportingDst);
|
|
847
|
-
|
|
933
|
+
deployedModules += 1;
|
|
934
|
+
vlog(' ✓ 部署 skywalk-sdd/reporting/(V3 单次变更报告)');
|
|
848
935
|
} else {
|
|
849
936
|
throw new Error(`E_INIT_MISSING_CRITICAL: reporting/ 目录缺失: ${reportingSrc}(归档报告生成将失败)`);
|
|
850
937
|
}
|
|
@@ -853,7 +940,8 @@ function deployTelemetryDataDir(targetCwd = process.cwd()) {
|
|
|
853
940
|
const contextClientDst = path.join(dataDir, 'context-client.cjs');
|
|
854
941
|
if (fs.existsSync(contextClientSrc)) {
|
|
855
942
|
fs.copyFileSync(contextClientSrc, contextClientDst);
|
|
856
|
-
|
|
943
|
+
deployedModules += 1;
|
|
944
|
+
vlog(' ✓ 部署 skywalk-sdd/context-client.cjs(工程 Spec 上下文客户端)');
|
|
857
945
|
} else {
|
|
858
946
|
console.log(` ⚠️ 工程 Spec 上下文客户端缺失: ${contextClientSrc}`);
|
|
859
947
|
}
|
|
@@ -862,7 +950,8 @@ function deployTelemetryDataDir(targetCwd = process.cwd()) {
|
|
|
862
950
|
const ontologyDst = path.join(dataDir, 'ontology');
|
|
863
951
|
if (fs.existsSync(ontologySrc)) {
|
|
864
952
|
copyDir(ontologySrc, ontologyDst);
|
|
865
|
-
|
|
953
|
+
deployedModules += 1;
|
|
954
|
+
vlog(' ✓ 部署 skywalk-sdd/ontology/(本地本体语义运行时)');
|
|
866
955
|
} else {
|
|
867
956
|
console.log(` ⚠️ 本体语义运行时缺失: ${ontologySrc}`);
|
|
868
957
|
}
|
|
@@ -871,7 +960,8 @@ function deployTelemetryDataDir(targetCwd = process.cwd()) {
|
|
|
871
960
|
const worktreeFinishDst = path.join(dataDir, 'apply-worktree-finish.cjs');
|
|
872
961
|
if (fs.existsSync(worktreeFinishSrc)) {
|
|
873
962
|
fs.copyFileSync(worktreeFinishSrc, worktreeFinishDst);
|
|
874
|
-
|
|
963
|
+
deployedModules += 1;
|
|
964
|
+
vlog(' ✓ 部署 skywalk-sdd/apply-worktree-finish.cjs(Apply 收尾脚本)');
|
|
875
965
|
} else {
|
|
876
966
|
console.log(' ⚠️ apply-worktree-finish.cjs 源文件缺失,Apply 阶段收尾需要手动执行');
|
|
877
967
|
}
|
|
@@ -880,16 +970,40 @@ function deployTelemetryDataDir(targetCwd = process.cwd()) {
|
|
|
880
970
|
const openspecShimDst = path.join(dataDir, 'openspec-shim.cjs');
|
|
881
971
|
if (fs.existsSync(openspecShimSrc)) {
|
|
882
972
|
fs.copyFileSync(openspecShimSrc, openspecShimDst);
|
|
883
|
-
|
|
973
|
+
deployedModules += 1;
|
|
974
|
+
vlog(' ✓ 部署 skywalk-sdd/openspec-shim.cjs(openspec 包裹包路径 shim)');
|
|
884
975
|
} else {
|
|
885
976
|
console.log(' ⚠️ openspec-shim.cjs 源文件缺失,openspec 命令需要手动 cd 到 spec 包执行');
|
|
886
977
|
}
|
|
887
978
|
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
979
|
+
// 部署 kb-upload.cjs(知识库上传脚本,支持文件夹/zip 双模式随时入库)
|
|
980
|
+
const kbUploadSrc = path.join(pkgPath, 'skywalk-sdd', 'kb-upload.cjs');
|
|
981
|
+
const kbUploadDst = path.join(dataDir, 'kb-upload.cjs');
|
|
982
|
+
if (fs.existsSync(kbUploadSrc)) {
|
|
983
|
+
fs.copyFileSync(kbUploadSrc, kbUploadDst);
|
|
984
|
+
deployedModules += 1;
|
|
985
|
+
vlog(' ✓ 部署 skywalk-sdd/kb-upload.cjs(知识库上传:文件夹/zip 双模式)');
|
|
986
|
+
} else {
|
|
987
|
+
console.log(' ⚠️ kb-upload.cjs 源文件缺失,随时入库功能不可用');
|
|
988
|
+
}
|
|
989
|
+
|
|
990
|
+
// 部署 kb-sync-identity.cjs(KB 身份同步脚本,重新入库前同步 version-id)
|
|
991
|
+
const kbSyncIdentitySrc = path.join(pkgPath, 'skywalk-sdd', 'kb-sync-identity.cjs');
|
|
992
|
+
const kbSyncIdentityDst = path.join(dataDir, 'kb-sync-identity.cjs');
|
|
993
|
+
if (fs.existsSync(kbSyncIdentitySrc)) {
|
|
994
|
+
fs.copyFileSync(kbSyncIdentitySrc, kbSyncIdentityDst);
|
|
995
|
+
deployedModules += 1;
|
|
996
|
+
vlog(' ✓ 部署 skywalk-sdd/kb-sync-identity.cjs(KB 身份同步:重新入库前同步 version-id)');
|
|
997
|
+
} else {
|
|
998
|
+
console.log(' ⚠️ kb-sync-identity.cjs 源文件缺失,重新入库身份同步不可用');
|
|
999
|
+
}
|
|
1000
|
+
|
|
1001
|
+
console.log(` ✓ 部署 skywalk-sdd/ 运行时(events/state 数据目录 + ${deployedModules} 个模块)`);
|
|
1002
|
+
vlog(' ✓ 调用方式: node skywalk-sdd/log.cjs start|end|metrics|semantic-identity|semantic-reconcile|semantic-check');
|
|
1003
|
+
vlog(' ✓ openspec: node skywalk-sdd/openspec-shim.cjs list(自动 cd 到 *-sdd-specs)');
|
|
1004
|
+
vlog(' ✓ Spec Context: node skywalk-sdd/context-client.cjs --query="<自然语言需求>" --target-stage=spec');
|
|
1005
|
+
vlog(' ✓ Apply worktree: record-base 在 §1.5;收尾 apply-worktree-finish.cjs --change=<name>');
|
|
1006
|
+
vlog(' ℹ️ project-identity.json 将在首次配置 KB(opsx-kb-config)时自动创建');
|
|
893
1007
|
console.log('✅ Telemetry 已就绪(数据存储在 skywalk-sdd/,无需配置 MCP)');
|
|
894
1008
|
return true;
|
|
895
1009
|
}
|
|
@@ -990,7 +1104,9 @@ function deployCodeRepoHooks(codeRepoRoot, specRepoRoot, options = {}) {
|
|
|
990
1104
|
for (const script of hookScripts) {
|
|
991
1105
|
const src = path.join(gitHooksTemplateDir, script);
|
|
992
1106
|
const dst = path.join(specHooksDir, script);
|
|
993
|
-
|
|
1107
|
+
// 删除 !fs.existsSync(dst) 条件:原逻辑只在目标不存在时复制,导致模板升级后 spec 仓不会拿到最新脚本。
|
|
1108
|
+
// 现在始终覆盖,与 shell hook 的 marker 覆盖策略保持一致。
|
|
1109
|
+
if (fs.existsSync(src)) {
|
|
994
1110
|
fs.copyFileSync(src, dst);
|
|
995
1111
|
}
|
|
996
1112
|
}
|
|
@@ -1053,8 +1169,16 @@ function deployQualityGateTemplates(targetCwd = process.cwd(), options = {}) {
|
|
|
1053
1169
|
const targetCiDir = path.join(dataDir, 'ci');
|
|
1054
1170
|
|
|
1055
1171
|
if (fs.existsSync(gitHooksTemplateDir)) {
|
|
1056
|
-
|
|
1057
|
-
|
|
1172
|
+
// 只复制 .cjs 脚本到 skywalk-sdd/git-hooks/,shell hook 模板(commit-msg/pre-commit/pre-push)不落此目录
|
|
1173
|
+
if (!fs.existsSync(targetGitHooksDir)) {
|
|
1174
|
+
fs.mkdirSync(targetGitHooksDir, { recursive: true });
|
|
1175
|
+
}
|
|
1176
|
+
for (const file of fs.readdirSync(gitHooksTemplateDir)) {
|
|
1177
|
+
if (file.endsWith('.cjs')) {
|
|
1178
|
+
fs.copyFileSync(path.join(gitHooksTemplateDir, file), path.join(targetGitHooksDir, file));
|
|
1179
|
+
}
|
|
1180
|
+
}
|
|
1181
|
+
console.log(' ✓ 部署 skywalk-sdd/git-hooks/(.cjs 脚本)');
|
|
1058
1182
|
} else {
|
|
1059
1183
|
console.log(` ⚠️ Git hooks 模板缺失: ${gitHooksTemplateDir}`);
|
|
1060
1184
|
}
|
|
@@ -1354,10 +1478,11 @@ function detectTools() {
|
|
|
1354
1478
|
|
|
1355
1479
|
/**
|
|
1356
1480
|
* 创建 / 更新 .gitignore
|
|
1481
|
+
* @param {string} [cwd=process.cwd()]
|
|
1357
1482
|
*/
|
|
1358
|
-
function updateGitignore() {
|
|
1359
|
-
const
|
|
1360
|
-
const gitignorePath = path.join(
|
|
1483
|
+
function updateGitignore(cwd = process.cwd()) {
|
|
1484
|
+
const root = path.resolve(cwd);
|
|
1485
|
+
const gitignorePath = path.join(root, '.gitignore');
|
|
1361
1486
|
const requiredLines = [
|
|
1362
1487
|
'.cursor/commands/personal-*',
|
|
1363
1488
|
'.claude/commands/personal-*',
|
|
@@ -1366,6 +1491,10 @@ function updateGitignore() {
|
|
|
1366
1491
|
'.kunlunzhima/commands/personal-*',
|
|
1367
1492
|
'.workbuddy/commands/personal-*',
|
|
1368
1493
|
'.agents/commands/personal-*',
|
|
1494
|
+
'kb-state.json',
|
|
1495
|
+
'**/kb-state.json',
|
|
1496
|
+
'skywalk-sdd/kb-state.json',
|
|
1497
|
+
'**/skywalk-sdd/kb-state.json',
|
|
1369
1498
|
'skywalk-sdd/events/',
|
|
1370
1499
|
'skywalk-sdd/state/',
|
|
1371
1500
|
'**/skywalk-sdd/events/',
|
|
@@ -1383,6 +1512,12 @@ function updateGitignore() {
|
|
|
1383
1512
|
.workbuddy/commands/personal-*
|
|
1384
1513
|
.agents/commands/personal-*
|
|
1385
1514
|
|
|
1515
|
+
# KB 绑定状态(含 API Key,勿提交)
|
|
1516
|
+
kb-state.json
|
|
1517
|
+
**/kb-state.json
|
|
1518
|
+
skywalk-sdd/kb-state.json
|
|
1519
|
+
**/skywalk-sdd/kb-state.json
|
|
1520
|
+
|
|
1386
1521
|
# SDD Telemetry 数据(实体在 *-sdd-specs/skywalk-sdd/;工作区可能是 symlink)
|
|
1387
1522
|
skywalk-sdd/events/
|
|
1388
1523
|
skywalk-sdd/state/
|
|
@@ -1411,6 +1546,20 @@ skywalk-sdd/state/
|
|
|
1411
1546
|
}
|
|
1412
1547
|
}
|
|
1413
1548
|
|
|
1549
|
+
/**
|
|
1550
|
+
* B1 汇总块绑定文案:已绑定显示用户,未绑定引导 auth login;不出现“使用统计”字样
|
|
1551
|
+
*/
|
|
1552
|
+
function formatBindingSummaryLine(bindingResult) {
|
|
1553
|
+
if (
|
|
1554
|
+
bindingResult
|
|
1555
|
+
&& (bindingResult.status === 'bound' || bindingResult.status === 'kept')
|
|
1556
|
+
&& bindingResult.userName
|
|
1557
|
+
) {
|
|
1558
|
+
return ` ✓ 平台账号已绑定:${bindingResult.userName}`;
|
|
1559
|
+
}
|
|
1560
|
+
return ' 6. 绑定平台账号:npx kld-sdd auth login';
|
|
1561
|
+
}
|
|
1562
|
+
|
|
1414
1563
|
/**
|
|
1415
1564
|
* 显示帮助信息
|
|
1416
1565
|
*/
|
|
@@ -1426,6 +1575,7 @@ KLD SDD 项目初始化工具
|
|
|
1426
1575
|
选项:
|
|
1427
1576
|
-h, --help 显示帮助信息
|
|
1428
1577
|
-v, --version 显示版本号
|
|
1578
|
+
--verbose 输出每个安装文件/目录的明细日志(默认仅摘要,亦可用 KLD_SDD_VERBOSE=1)
|
|
1429
1579
|
--skip-openspec 跳过 openspec init 步骤
|
|
1430
1580
|
--skip-template 跳过复制内置模版
|
|
1431
1581
|
--tool <name> 指定编辑器,可用值: cursor, claude, codebuddy, qoder, opencode, kunlunzhima, workbuddy, codex, all
|
|
@@ -1494,14 +1644,14 @@ async function main() {
|
|
|
1494
1644
|
// 解析参数
|
|
1495
1645
|
if (args.includes('-h') || args.includes('--help')) {
|
|
1496
1646
|
showHelp();
|
|
1497
|
-
|
|
1647
|
+
closeRl();
|
|
1498
1648
|
return;
|
|
1499
1649
|
}
|
|
1500
1650
|
|
|
1501
1651
|
if (args.includes('-v') || args.includes('--version')) {
|
|
1502
1652
|
const pkg = require('../package.json');
|
|
1503
1653
|
console.log(pkg.version);
|
|
1504
|
-
|
|
1654
|
+
closeRl();
|
|
1505
1655
|
return;
|
|
1506
1656
|
}
|
|
1507
1657
|
|
|
@@ -1520,7 +1670,7 @@ async function main() {
|
|
|
1520
1670
|
selectedTools = parseSelectedTools(args) || await selectEditor();
|
|
1521
1671
|
} catch (error) {
|
|
1522
1672
|
console.error(`❌ ${error.message}`);
|
|
1523
|
-
|
|
1673
|
+
closeRl();
|
|
1524
1674
|
process.exit(1);
|
|
1525
1675
|
}
|
|
1526
1676
|
|
|
@@ -1640,7 +1790,7 @@ async function main() {
|
|
|
1640
1790
|
}
|
|
1641
1791
|
|
|
1642
1792
|
// 7. 更新工作目录 .gitignore
|
|
1643
|
-
updateGitignore();
|
|
1793
|
+
updateGitignore(workspaceRoot);
|
|
1644
1794
|
|
|
1645
1795
|
// 8. 收尾:无论前面是否走过 symlink/旧副本路径,强制清掉工作区/Git 根多余 skywalk-sdd/
|
|
1646
1796
|
if (specPackage && fs.existsSync(specPackage.abs)) {
|
|
@@ -1648,6 +1798,23 @@ async function main() {
|
|
|
1648
1798
|
}
|
|
1649
1799
|
removeOuterSkywalk(workspaceRoot);
|
|
1650
1800
|
|
|
1801
|
+
// 9. B1 账号绑定向导(部署完成后、最终汇总前;--skip-auth/非 TTY 自动跳过;失败不阻塞 init)
|
|
1802
|
+
const bindingController = new AbortController();
|
|
1803
|
+
const onBindingSigint = () => bindingController.abort();
|
|
1804
|
+
process.on('SIGINT', onBindingSigint);
|
|
1805
|
+
let bindingResult = null;
|
|
1806
|
+
try {
|
|
1807
|
+
bindingResult = await runAccountBinding({
|
|
1808
|
+
ask,
|
|
1809
|
+
skipAuth: args.includes('--skip-auth'),
|
|
1810
|
+
signal: bindingController.signal,
|
|
1811
|
+
});
|
|
1812
|
+
} catch (error) {
|
|
1813
|
+
console.log(`⚠️ 账号绑定向导异常(${error && error.message ? error.message : error}),已跳过`);
|
|
1814
|
+
} finally {
|
|
1815
|
+
process.removeListener('SIGINT', onBindingSigint);
|
|
1816
|
+
}
|
|
1817
|
+
|
|
1651
1818
|
const selectedNames = selectedTools.map(t => TOOL_CONFIGS[t].name).join(', ');
|
|
1652
1819
|
|
|
1653
1820
|
console.log();
|
|
@@ -1685,7 +1852,7 @@ async function main() {
|
|
|
1685
1852
|
console.log(' 📌 .sdd-spec-root → 包裹包;无根目录 skywalk-sdd/');
|
|
1686
1853
|
}
|
|
1687
1854
|
if (selectedTools.includes('kunlunzhima')) {
|
|
1688
|
-
console.log(' 📎 .kunlunzhima/commands/opsx/ # KunlunZhima OPSX command bridge(
|
|
1855
|
+
console.log(' 📎 .kunlunzhima/commands/opsx/ # KunlunZhima OPSX command bridge(13 个)');
|
|
1689
1856
|
console.log(' ℹ️ KunlunZhima 通过 commands/skills 入口使用 SDD,未启用自动 Hook');
|
|
1690
1857
|
}
|
|
1691
1858
|
if (selectedTools.includes('codebuddy')) {
|
|
@@ -1696,20 +1863,23 @@ async function main() {
|
|
|
1696
1863
|
}
|
|
1697
1864
|
console.log();
|
|
1698
1865
|
|
|
1699
|
-
// 统一的 skill
|
|
1700
|
-
console.log('可用 skills
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1866
|
+
// 统一的 skill 格式说明(默认单行指引,完整列表走 --verbose)
|
|
1867
|
+
console.log('可用 skills:opsx-* 系列 15 个 SDD skills(--verbose 查看完整列表,或见 openspec/kld-sdd操作手册.html)');
|
|
1868
|
+
vlog(' opsx-propose - 创建业务意图文档(Why)');
|
|
1869
|
+
vlog(' opsx-spec - 创建技术契约文档(What)');
|
|
1870
|
+
vlog(' opsx-design - 创建技术实现方案(How)');
|
|
1871
|
+
vlog(' opsx-task - 拆解AI编码任务(Do)');
|
|
1872
|
+
vlog(' opsx-check - 质量门禁检查(Verify)');
|
|
1873
|
+
vlog(' opsx-apply - 申请变更实施(Apply)');
|
|
1874
|
+
vlog(' opsx-test - 执行单元测试(Test)');
|
|
1875
|
+
vlog(' opsx-archive - 归档变更(Archive)');
|
|
1876
|
+
vlog(' opsx-explore - 浏览变更状态(Explore)');
|
|
1877
|
+
vlog(' opsx-knowledge - 业务知识库检索(辅助)');
|
|
1878
|
+
vlog(' opsx-rules - 生成/更新 Agent 规则(辅助)');
|
|
1879
|
+
vlog(' opsx-consistency-check - Spec 一致性校验(代码 vs spec)');
|
|
1880
|
+
vlog(' opsx-kb-config - 知识库配置(API Key + Space/KB 选择)');
|
|
1881
|
+
vlog(' opsx-ontology-query - 本体知识库查询');
|
|
1882
|
+
vlog(' opsx-kb-ingest - 知识库入库(zip / 文件夹上传)');
|
|
1713
1883
|
|
|
1714
1884
|
console.log();
|
|
1715
1885
|
console.log('后续步骤:');
|
|
@@ -1722,14 +1892,18 @@ async function main() {
|
|
|
1722
1892
|
console.log(' 2. 按顺序执行 propose → spec → design → task');
|
|
1723
1893
|
console.log(' 3. 激活 opsx-check 验证文档质量');
|
|
1724
1894
|
console.log(' 4. 激活 opsx-apply 申请实施,opsx-archive 归档完成');
|
|
1895
|
+
console.log(' 5. 随时入库:node skywalk-sdd/kb-upload.cjs --folder=<变更目录> --minimum-level=propose-spec');
|
|
1896
|
+
console.log(' (需先运行 /opsx-kb-config 配置知识库)');
|
|
1897
|
+
// B1: 汇总块绑定文案(不出现“使用统计”字样)
|
|
1898
|
+
console.log(formatBindingSummaryLine(bindingResult));
|
|
1725
1899
|
if (selectedTools.includes('codebuddy')) {
|
|
1726
|
-
console.log('
|
|
1900
|
+
console.log(' - CodeBuddy 用户:SDD Hook Pack 已随初始化自动部署,门禁自动生效,无需手动配置');
|
|
1727
1901
|
}
|
|
1728
1902
|
if (selectedTools.includes('kunlunzhima')) {
|
|
1729
|
-
console.log('
|
|
1903
|
+
console.log(' - KunlunZhima 用户:在 Craft 模式使用 /opsx:propose 等 OPSX 命令(.kunlunzhima/commands/opsx/)');
|
|
1730
1904
|
}
|
|
1731
1905
|
if (selectedTools.includes('opencode')) {
|
|
1732
|
-
console.log('
|
|
1906
|
+
console.log(' - OpenCode 用户:用 /opsx-propose 或 /skills 启动 SDD(.opencode/skills/opsx-*/,skill 即斜杠命令)');
|
|
1733
1907
|
}
|
|
1734
1908
|
console.log();
|
|
1735
1909
|
console.log('📊 SDD Telemetry(嵌入在 skill 流程中,自动执行,无需配置):');
|
|
@@ -1741,16 +1915,24 @@ async function main() {
|
|
|
1741
1915
|
console.log(' - 运行 node skywalk-sdd/log.cjs metrics --project=<包裹包> 查看四维度指标');
|
|
1742
1916
|
console.log();
|
|
1743
1917
|
|
|
1744
|
-
|
|
1918
|
+
closeRl();
|
|
1745
1919
|
}
|
|
1746
1920
|
|
|
1921
|
+
// kld-T06: Progress Runtime 已删除,用户级 workspace 注册函数一并移除。
|
|
1922
|
+
// 用户级 Device Flow 绑定由 lib/device-auth.js + skywalk-sdd/lib/user-config.cjs 负责,
|
|
1923
|
+
// 通过 `kld-sdd auth login` 显式触发。
|
|
1924
|
+
|
|
1747
1925
|
module.exports = {
|
|
1748
1926
|
main,
|
|
1749
1927
|
detectTools,
|
|
1750
1928
|
getTemplatePath,
|
|
1751
1929
|
getPackagePath,
|
|
1752
1930
|
selectEditor,
|
|
1931
|
+
isVerbose,
|
|
1932
|
+
vlog,
|
|
1933
|
+
formatBindingSummaryLine,
|
|
1753
1934
|
deployOpsxSkills,
|
|
1935
|
+
copyTemplatesToProject,
|
|
1754
1936
|
deployProfileArtifacts,
|
|
1755
1937
|
deploySddGuideManual,
|
|
1756
1938
|
deployModulesYaml,
|
|
@@ -1762,6 +1944,7 @@ module.exports = {
|
|
|
1762
1944
|
removeOuterSkywalk,
|
|
1763
1945
|
deployQualityGateTemplates,
|
|
1764
1946
|
deployTelemetryDataDir,
|
|
1947
|
+
updateGitignore,
|
|
1765
1948
|
attachCodeRepoLite,
|
|
1766
1949
|
syncWorkspaceRepos,
|
|
1767
1950
|
copyDirRendered,
|
package/lib/skills-bundle.js
CHANGED
|
@@ -7,6 +7,22 @@ const path = require('path');
|
|
|
7
7
|
|
|
8
8
|
const SKILLS_BUNDLE_NAME = 'kld-sdd';
|
|
9
9
|
|
|
10
|
+
/**
|
|
11
|
+
* PowerShell 禁忌 — 追加到 SHELL_GUIDANCE 后,自动注入所有 SKILL.md。
|
|
12
|
+
* 根因:PowerShell 的 cat/curl/Get-Content 行为与 bash 不同,导致管道断裂、
|
|
13
|
+
* HTTP 请求失败、JSON 文件 BOM 污染引发静默降级(sdd-output 错误 #1/#3/#4/#5)。
|
|
14
|
+
*/
|
|
15
|
+
const POWERSHELL_TABOOS = [
|
|
16
|
+
'',
|
|
17
|
+
'> - **PowerShell 禁忌**(Windows 用户必读):',
|
|
18
|
+
'> - 禁止 `| cat`(PowerShell 将 cat 解释为 Get-Content,不接受管道输入)→ 直接执行命令',
|
|
19
|
+
'> - 禁止 `node -e "..."` 内联脚本(PowerShell 对 `||`/`{}`/`()` 有特殊解析,导致 JS 语法被破坏)→ 用 `write_to_file` 创建临时 `.cjs` 脚本执行后删除',
|
|
20
|
+
'> - 禁止 cmd.exe 语法(如 `for /L %i in (1,1,N) do ...`)→ PowerShell 不支持,改用逐个 `execute_command` 调用或 PowerShell `foreach`',
|
|
21
|
+
'> - 警告 CLIXML:PowerShell 捕获 `node`/`npx` 子进程输出时可能包装为 `#< CLIXML <Objs...>` 格式 → 检测到 CLIXML 时以文件系统实际产物为准,忽略 stdout',
|
|
22
|
+
'> - 禁止 `curl`(PowerShell 将 curl 别名为 Invoke-WebRequest)→ HTTP 请求走 `context-client.cjs` / `kb-upload.cjs`,或用 `Invoke-RestMethod`',
|
|
23
|
+
'> - 禁止 `Get-Content` / `Out-File` 读写 JSON(PowerShell 默认写 BOM 导致 JSON.parse 失败)→ 用 write_to_file 工具或 Node.js `fs` 模块',
|
|
24
|
+
].join('\n');
|
|
25
|
+
|
|
10
26
|
const OPSX_SKILL_DIRS = [
|
|
11
27
|
'opsx-propose',
|
|
12
28
|
'opsx-spec',
|
|
@@ -20,6 +36,7 @@ const OPSX_SKILL_DIRS = [
|
|
|
20
36
|
'opsx-knowledge',
|
|
21
37
|
'opsx-rules',
|
|
22
38
|
// Engineering KB 依赖技能(随 init 部署;propose/spec/archive 硬依赖)
|
|
39
|
+
'opsx-kb-config',
|
|
23
40
|
'opsx-ontology-query',
|
|
24
41
|
'opsx-kb-ingest',
|
|
25
42
|
// Spec 一致性校验技能
|
|
@@ -104,6 +121,7 @@ const KUNLUN_SLASH_COMMANDS = [
|
|
|
104
121
|
'explore',
|
|
105
122
|
'ontology-query',
|
|
106
123
|
'kb-ingest',
|
|
124
|
+
'kb-config',
|
|
107
125
|
'consistency-check',
|
|
108
126
|
];
|
|
109
127
|
|
|
@@ -128,7 +146,8 @@ function replaceProfileTokens(content, profile) {
|
|
|
128
146
|
return content
|
|
129
147
|
.replace(/\$\{SKILL_RUNTIME_DIR\}/g, vars.SKILL_RUNTIME_DIR || profile.skillsDir || '')
|
|
130
148
|
.replace(/\$\{HOOK_GATE_DESCRIPTION\}/g, vars.HOOK_GATE_DESCRIPTION || '')
|
|
131
|
-
.replace(/\$\{SHELL_GUIDANCE\}/g, vars.SHELL_GUIDANCE || '')
|
|
149
|
+
.replace(/\$\{SHELL_GUIDANCE\}/g, (vars.SHELL_GUIDANCE || '') + POWERSHELL_TABOOS)
|
|
150
|
+
.replace(/\$\{CHECK_REVIEW_DELEGATION_GUIDANCE\}/g, vars.CHECK_REVIEW_DELEGATION_GUIDANCE || '')
|
|
132
151
|
.replace(/\$\{AGENT_SKILL_DIR\}/g, profile.skillsDir || '');
|
|
133
152
|
}
|
|
134
153
|
|
package/lib/tool-profiles.js
CHANGED
|
@@ -24,6 +24,7 @@ const TOOL_PROFILES = Object.freeze({
|
|
|
24
24
|
SKILL_RUNTIME_DIR: '.cursor/skills',
|
|
25
25
|
HOOK_GATE_DESCRIPTION: '本项目未为此 Agent 部署自动 Hook 门禁;请遵循 Skill 自检与 CI/Git 证据门禁。',
|
|
26
26
|
SHELL_GUIDANCE: '在 Windows 上优先使用 PowerShell;如需 Bash 请使用 Git Bash。',
|
|
27
|
+
CHECK_REVIEW_DELEGATION_GUIDANCE: '使用 Cursor 当前可用的独立 Agent/子代理能力启动一个全新评审上下文;若能力不可用,按本 Skill 的受控回退规则由主 Agent 检查。',
|
|
27
28
|
},
|
|
28
29
|
},
|
|
29
30
|
claude: {
|
|
@@ -44,6 +45,7 @@ const TOOL_PROFILES = Object.freeze({
|
|
|
44
45
|
SKILL_RUNTIME_DIR: '.claude/skills',
|
|
45
46
|
HOOK_GATE_DESCRIPTION: 'Claude Code 已部署 SDD Hook Pack(.claude/hooks + settings.json),自动门禁与遥测增强已启用。',
|
|
46
47
|
SHELL_GUIDANCE: '在 Windows Bash / Git Bash / Claude Bash 中,禁止裸写 Windows 反斜杠绝对路径;如必须使用绝对路径,请写成正斜杠路径或加引号。',
|
|
48
|
+
CHECK_REVIEW_DELEGATION_GUIDANCE: '使用 Claude Code 的 Agent 能力启动一个全新、无作者上下文的评审子代理;不得让评审子代理再次委派。',
|
|
47
49
|
},
|
|
48
50
|
},
|
|
49
51
|
codebuddy: {
|
|
@@ -64,6 +66,7 @@ const TOOL_PROFILES = Object.freeze({
|
|
|
64
66
|
SKILL_RUNTIME_DIR: '.codebuddy/skills',
|
|
65
67
|
HOOK_GATE_DESCRIPTION: 'CodeBuddy CLI 已部署 SDD Hook Pack(.codebuddy/hooks + settings.json),初始化后自动生效。',
|
|
66
68
|
SHELL_GUIDANCE: 'CodeBuddy Hooks 在 Windows 上通过 Git Bash 执行;命令使用 node "$CODEBUDDY_PROJECT_DIR/..." 引用项目路径。',
|
|
69
|
+
CHECK_REVIEW_DELEGATION_GUIDANCE: '使用 CodeBuddy 当前可用的独立 Agent 能力启动一个评审子代理;若启动失败,记录标准回退原因后由主 Agent 检查。',
|
|
67
70
|
},
|
|
68
71
|
},
|
|
69
72
|
qoder: {
|
|
@@ -84,6 +87,7 @@ const TOOL_PROFILES = Object.freeze({
|
|
|
84
87
|
SKILL_RUNTIME_DIR: '.qoder/skills',
|
|
85
88
|
HOOK_GATE_DESCRIPTION: '本项目未为此 Agent 部署自动 Hook 门禁;请遵循 Skill 自检与 CI/Git 证据门禁。',
|
|
86
89
|
SHELL_GUIDANCE: '在 Windows 上优先使用 PowerShell;如需 Bash 请使用 Git Bash。',
|
|
90
|
+
CHECK_REVIEW_DELEGATION_GUIDANCE: '使用 Qoder 当前可用的独立 Agent/子代理能力启动一个全新评审上下文;能力不可用时才允许主 Agent 回退。',
|
|
87
91
|
},
|
|
88
92
|
},
|
|
89
93
|
opencode: {
|
|
@@ -107,6 +111,7 @@ const TOOL_PROFILES = Object.freeze({
|
|
|
107
111
|
SKILL_RUNTIME_DIR: '.opencode/skills',
|
|
108
112
|
HOOK_GATE_DESCRIPTION: '本项目未为此 Agent 部署自动 Hook 门禁;请遵循 Skill 自检与 CI/Git 证据门禁。',
|
|
109
113
|
SHELL_GUIDANCE: '在 Windows 上优先使用 PowerShell;OpenCode 可通过环境变量 OPENCODE_GIT_BASH_PATH 指定 Git Bash;如需 Bash 请使用 Git Bash。',
|
|
114
|
+
CHECK_REVIEW_DELEGATION_GUIDANCE: '使用 OpenCode 当前可用的独立 Agent 能力启动一个无作者上下文的评审子代理;不得递归委派。',
|
|
110
115
|
},
|
|
111
116
|
},
|
|
112
117
|
kunlunzhima: {
|
|
@@ -127,6 +132,7 @@ const TOOL_PROFILES = Object.freeze({
|
|
|
127
132
|
SKILL_RUNTIME_DIR: '.kunlunzhima/skills',
|
|
128
133
|
HOOK_GATE_DESCRIPTION: 'KunlunZhima IDE 不支持自动 Hook 门禁;请通过 Skill 自检、commands 入口与 CI/Git 证据门禁保障质量。',
|
|
129
134
|
SHELL_GUIDANCE: 'KunlunZhima IDE 通过 commands/skills 入口使用 SDD;相对引用以 Skill 目录解析。',
|
|
135
|
+
CHECK_REVIEW_DELEGATION_GUIDANCE: '使用 KunlunZhima 当前可用的独立智能体能力启动一个全新评审上下文;若不支持,记录标准回退原因后由主智能体检查。',
|
|
130
136
|
},
|
|
131
137
|
},
|
|
132
138
|
workbuddy: {
|
|
@@ -147,6 +153,7 @@ const TOOL_PROFILES = Object.freeze({
|
|
|
147
153
|
SKILL_RUNTIME_DIR: '.workbuddy/skills',
|
|
148
154
|
HOOK_GATE_DESCRIPTION: '本项目未为此 Agent 部署自动 Hook 门禁;请遵循 Skill 自检与 CI/Git 证据门禁。',
|
|
149
155
|
SHELL_GUIDANCE: '在 Windows 上优先使用 PowerShell;如需 Bash 请使用 Git Bash。',
|
|
156
|
+
CHECK_REVIEW_DELEGATION_GUIDANCE: '使用 WorkBuddy 当前可用的独立 Agent/子代理能力启动一个全新评审上下文;能力不可用时才允许主 Agent 回退。',
|
|
150
157
|
},
|
|
151
158
|
},
|
|
152
159
|
codex: {
|
|
@@ -167,6 +174,7 @@ const TOOL_PROFILES = Object.freeze({
|
|
|
167
174
|
SKILL_RUNTIME_DIR: '.agents/skills',
|
|
168
175
|
HOOK_GATE_DESCRIPTION: '本项目未为此 Agent 部署自动 Hook 门禁;请遵循 Skill 自检与 CI/Git 证据门禁。',
|
|
169
176
|
SHELL_GUIDANCE: '在 Windows 上优先使用 PowerShell;如需 Bash 请使用 Git Bash。',
|
|
177
|
+
CHECK_REVIEW_DELEGATION_GUIDANCE: '使用 Codex 的多代理能力启动恰好一个独立评审子代理,并传入所需文件而不是作者对话;不得让评审子代理再次委派。',
|
|
170
178
|
},
|
|
171
179
|
},
|
|
172
180
|
});
|