@cyning/harness 1.1.0 → 2.0.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/CHANGELOG.md +23 -0
- package/README.md +4 -3
- package/docs/USER_GUIDE_v1.0_zh.md +40 -4
- package/docs/methodology/graph/DECISIONS_hgm_g1_maintainer_v1_zh.md +196 -0
- package/docs/methodology/graph/HGM_UPGRADE_OUTLINE_v1_zh.md +12 -6
- package/docs/methodology/graph/schemas/hgm_event_v1.schema.json +301 -0
- package/lib/cli.js +141 -11
- package/lib/graph-hgm.js +563 -0
- package/ontology.yaml +1 -1
- package/package.json +1 -1
package/lib/cli.js
CHANGED
|
@@ -19,6 +19,13 @@ import {
|
|
|
19
19
|
GraphYamlError,
|
|
20
20
|
yamlPathFor,
|
|
21
21
|
} from './graph-yaml.js';
|
|
22
|
+
import {
|
|
23
|
+
buildSnapshot,
|
|
24
|
+
checkAxioms,
|
|
25
|
+
ingestRepoIdempotent,
|
|
26
|
+
loadEvents,
|
|
27
|
+
writeSnapshot,
|
|
28
|
+
} from './graph-hgm.js';
|
|
22
29
|
|
|
23
30
|
function usage(version = 'unknown') {
|
|
24
31
|
console.log(`@cyning/harness · cyning-harness CLI (v${version})
|
|
@@ -38,6 +45,9 @@ function usage(version = 'unknown') {
|
|
|
38
45
|
npx @cyning/harness graph yaml check --graph-id ID [--input DIR] [--graph-json FILE]
|
|
39
46
|
npx @cyning/harness graph yaml compile --all [--input DIR]
|
|
40
47
|
npx @cyning/harness graph yaml check --all [--input DIR] [--graph-json FILE]
|
|
48
|
+
npx @cyning/harness graph ingest [--target PATH] [--actor ACTOR] [--dry-run]
|
|
49
|
+
npx @cyning/harness graph snapshot [--target PATH]
|
|
50
|
+
npx @cyning/harness graph axioms check [--target PATH] [--json]
|
|
41
51
|
|
|
42
52
|
说明:
|
|
43
53
|
init 首次接入 · 内部调用 wizard/install.sh + harness-sync.sh apply
|
|
@@ -48,7 +58,10 @@ function usage(version = 'unknown') {
|
|
|
48
58
|
verify 30 前聚合:gate-check + audit D5 + S5 warn + 可选 --graph
|
|
49
59
|
sync index 生成 .cyning-harness/invoke_index.json
|
|
50
60
|
task check 校验 task.harness.v1.json sidecar · --no-circular 检测 depends_on 环
|
|
51
|
-
graph yaml
|
|
61
|
+
graph yaml Inform 图谱 YAML 编译 / 校验(v1.1+)
|
|
62
|
+
graph ingest 扫描业务仓 → 追加 HGM 事件(v2.0+)
|
|
63
|
+
graph snapshot 事件重放 → graph/snapshot.json(v2.0+)
|
|
64
|
+
graph axioms 跑 HGM 公理检查(v2.0+)
|
|
52
65
|
|
|
53
66
|
环境:
|
|
54
67
|
CYNING_HARNESS 覆盖产品包根(维护者本地 clone 开发)
|
|
@@ -514,31 +527,54 @@ async function cmdTask(args) {
|
|
|
514
527
|
|
|
515
528
|
async function cmdGraph(args) {
|
|
516
529
|
if (args.includes('--help') || args.includes('-h')) {
|
|
517
|
-
console.log(`用法: npx @cyning/harness graph
|
|
530
|
+
console.log(`用法: npx @cyning/harness graph <子命令> [选项]
|
|
518
531
|
|
|
519
532
|
子命令:
|
|
520
533
|
graph yaml compile --graph-id ID [--input DIR] [--output FILE]
|
|
521
534
|
graph yaml compile --all [--input DIR]
|
|
522
535
|
graph yaml check --graph-id ID [--input DIR] [--graph-json FILE]
|
|
523
536
|
graph yaml check --all [--input DIR] [--graph-json FILE]
|
|
537
|
+
graph ingest [--target PATH] [--actor ACTOR] [--dry-run]
|
|
538
|
+
graph snapshot [--target PATH]
|
|
539
|
+
graph axioms check [--target PATH] [--json]
|
|
524
540
|
|
|
525
541
|
选项:
|
|
526
|
-
--input DIR 输入目录(默认 target/docs/_tech_graph)
|
|
527
|
-
--output FILE 输出 MD 路径(仅单图 compile)
|
|
528
|
-
--graph-json FILE 对比的 graph.json
|
|
529
|
-
--
|
|
542
|
+
--input DIR graph yaml 输入目录(默认 target/docs/_tech_graph)
|
|
543
|
+
--output FILE graph yaml 输出 MD 路径(仅单图 compile)
|
|
544
|
+
--graph-json FILE graph yaml 对比的 graph.json 路径
|
|
545
|
+
--target PATH 业务仓根目录(默认当前目录)
|
|
546
|
+
--actor ACTOR ingest actor(默认 system)
|
|
547
|
+
--dry-run ingest 仅输出事件数 · 不写入
|
|
548
|
+
--json axioms 输出 JSON
|
|
530
549
|
`);
|
|
531
550
|
return;
|
|
532
551
|
}
|
|
533
552
|
|
|
534
553
|
const [sub, ...subRest] = args;
|
|
535
|
-
if (sub
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
554
|
+
if (sub === 'yaml') {
|
|
555
|
+
await cmdGraphYaml(subRest);
|
|
556
|
+
return;
|
|
557
|
+
}
|
|
558
|
+
if (sub === 'ingest') {
|
|
559
|
+
await cmdGraphIngest(subRest);
|
|
560
|
+
return;
|
|
561
|
+
}
|
|
562
|
+
if (sub === 'snapshot') {
|
|
563
|
+
await cmdGraphSnapshot(subRest);
|
|
564
|
+
return;
|
|
565
|
+
}
|
|
566
|
+
if (sub === 'axioms') {
|
|
567
|
+
await cmdGraphAxioms(subRest);
|
|
568
|
+
return;
|
|
539
569
|
}
|
|
540
570
|
|
|
541
|
-
const
|
|
571
|
+
const err = new Error(`graph 子命令未知: ${sub ?? '(空)'}`);
|
|
572
|
+
err.exitCode = 1;
|
|
573
|
+
throw err;
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
async function cmdGraphYaml(args) {
|
|
577
|
+
const [action, ...actionRest] = args;
|
|
542
578
|
if (action !== 'compile' && action !== 'check') {
|
|
543
579
|
const err = new Error(`graph yaml 动作未知: ${action ?? '(空)'}`);
|
|
544
580
|
err.exitCode = 1;
|
|
@@ -638,3 +674,97 @@ async function cmdGraph(args) {
|
|
|
638
674
|
throw err;
|
|
639
675
|
}
|
|
640
676
|
}
|
|
677
|
+
|
|
678
|
+
async function cmdGraphIngest(args) {
|
|
679
|
+
let rest = args;
|
|
680
|
+
const { value: targetArg, rest: r1 } = takeOption(rest, '--target');
|
|
681
|
+
rest = r1;
|
|
682
|
+
const { value: actor, rest: r2 } = takeOption(rest, '--actor');
|
|
683
|
+
rest = r2;
|
|
684
|
+
const dryRun = rest.includes('--dry-run');
|
|
685
|
+
rest = rest.filter((a) => a !== '--dry-run');
|
|
686
|
+
|
|
687
|
+
if (rest.length > 0) {
|
|
688
|
+
const err = new Error(`graph ingest 未知参数: ${rest.join(' ')}`);
|
|
689
|
+
err.exitCode = 1;
|
|
690
|
+
throw err;
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
const target = resolveTarget(process.cwd(), targetArg);
|
|
694
|
+
const result = ingestRepoIdempotent(target, {
|
|
695
|
+
actor: actor || 'system',
|
|
696
|
+
source: 'cli',
|
|
697
|
+
dryRun,
|
|
698
|
+
});
|
|
699
|
+
|
|
700
|
+
console.log(`目标: ${target}`);
|
|
701
|
+
console.log(`新事件: ${result.count}`);
|
|
702
|
+
console.log(`跳过(已存在): ${result.skipped}`);
|
|
703
|
+
if (dryRun) {
|
|
704
|
+
console.log('mode: dry-run(未写入)');
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
async function cmdGraphSnapshot(args) {
|
|
709
|
+
let rest = args;
|
|
710
|
+
const { value: targetArg, rest: r1 } = takeOption(rest, '--target');
|
|
711
|
+
rest = r1;
|
|
712
|
+
|
|
713
|
+
if (rest.length > 0) {
|
|
714
|
+
const err = new Error(`graph snapshot 未知参数: ${rest.join(' ')}`);
|
|
715
|
+
err.exitCode = 1;
|
|
716
|
+
throw err;
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
const target = resolveTarget(process.cwd(), targetArg);
|
|
720
|
+
const events = loadEvents(target);
|
|
721
|
+
const snapshot = buildSnapshot(events);
|
|
722
|
+
const out = writeSnapshot(target, snapshot);
|
|
723
|
+
|
|
724
|
+
console.log(`events: ${events.length}`);
|
|
725
|
+
console.log(`nodes: ${Object.keys(snapshot.nodes).length}`);
|
|
726
|
+
console.log(`edges: ${snapshot.edges.length}`);
|
|
727
|
+
console.log(`snapshot: ${out}`);
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
async function cmdGraphAxioms(args) {
|
|
731
|
+
const [sub, ...rest] = args;
|
|
732
|
+
if (sub !== 'check') {
|
|
733
|
+
const err = new Error(`graph axioms 动作未知: ${sub ?? '(空)'}`);
|
|
734
|
+
err.exitCode = 1;
|
|
735
|
+
throw err;
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
let remaining = rest;
|
|
739
|
+
const { value: targetArg, rest: r1 } = takeOption(remaining, '--target');
|
|
740
|
+
remaining = r1;
|
|
741
|
+
const json = remaining.includes('--json');
|
|
742
|
+
remaining = remaining.filter((a) => a !== '--json');
|
|
743
|
+
|
|
744
|
+
if (remaining.length > 0) {
|
|
745
|
+
const err = new Error(`graph axioms check 未知参数: ${remaining.join(' ')}`);
|
|
746
|
+
err.exitCode = 1;
|
|
747
|
+
throw err;
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
const target = resolveTarget(process.cwd(), targetArg);
|
|
751
|
+
const events = loadEvents(target);
|
|
752
|
+
const snapshot = buildSnapshot(events);
|
|
753
|
+
const result = checkAxioms(snapshot);
|
|
754
|
+
|
|
755
|
+
if (json) {
|
|
756
|
+
console.log(JSON.stringify(result, null, 2));
|
|
757
|
+
} else {
|
|
758
|
+
console.log(`axioms: ${result.ok ? 'PASS' : 'FAIL'}`);
|
|
759
|
+
console.log(`violations: ${result.violations.length}`);
|
|
760
|
+
for (const v of result.violations) {
|
|
761
|
+
console.log(` [${v.axiom}/${v.severity}] ${v.message}`);
|
|
762
|
+
}
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
if (!result.ok) {
|
|
766
|
+
const err = new Error('HGM axioms 未通过');
|
|
767
|
+
err.exitCode = 2;
|
|
768
|
+
throw err;
|
|
769
|
+
}
|
|
770
|
+
}
|