@yottameta/yotta-skills-plugin 0.25.1 → 0.27.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.
@@ -0,0 +1,97 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Shared "yotta-verify" engine discovery + scan runner for Hub adoption.
5
+ *
6
+ * The CLI and the local Hub panel (yotta-skills view) both import this module
7
+ * so an adopt action always runs the same gate: locate a trusted verifier,
8
+ * run it against the candidate directory, then evaluate the verdict.
9
+ */
10
+
11
+ const path = require('path');
12
+ const { spawnSync } = require('child_process');
13
+ const depsLib = require('./deps');
14
+ const gateLib = require('./verify-gate');
15
+ const trustedVerifierLib = require('./trusted-verifier');
16
+
17
+ function currentCommand() {
18
+ const args = process.argv.slice(2).map((a) => (/\s/.test(a) ? '"' + a + '"' : a));
19
+ return 'yotta-skills ' + args.join(' ');
20
+ }
21
+
22
+ function findVerifyEngine(dest, opts) {
23
+ // Do not use the registry for verifier identity: only the trusted record
24
+ // written by the install pipeline (path + digest) counts.
25
+ return gateLib.findVerifier({ dest, opts, trustedVerifier: trustedVerifierLib.loadRecord() });
26
+ }
27
+
28
+ function findPython(opts) {
29
+ const options = opts || {};
30
+ const cands = [];
31
+ if (options.python) cands.push(options.python);
32
+ if (process.env.YOTTA_SKILLS_PYTHON) cands.push(process.env.YOTTA_SKILLS_PYTHON);
33
+ cands.push('python3', 'python');
34
+ if (process.platform === 'win32') cands.push('py');
35
+ for (const c of cands) {
36
+ try {
37
+ const r = spawnSync(c, ['--version'], { encoding: 'utf8', timeout: 10000 });
38
+ if (r.status === 0) return c;
39
+ } catch (_) { /* next candidate */ }
40
+ }
41
+ return null;
42
+ }
43
+
44
+ function runScan(engine, skillDir, opts) {
45
+ const python = findPython(opts || {});
46
+ if (!python) {
47
+ return {
48
+ ok: false,
49
+ error: depsLib.describe('python', { command: currentCommand(), missing: true }),
50
+ };
51
+ }
52
+ return gateLib.runVerifier(engine, skillDir, { python, spawnSync });
53
+ }
54
+
55
+ /** Hub adopt scan engine: Hub itself first, then every discovered host dir. */
56
+ function scanEngineForHub(hubDir, discovery, opts) {
57
+ const direct = findVerifyEngine(hubDir, opts);
58
+ if (direct) return direct;
59
+ const hosts = (discovery && discovery.hosts) || [];
60
+ for (const host of hosts) {
61
+ if (!host.exists) continue;
62
+ const engine = findVerifyEngine(host.dir, opts);
63
+ if (engine) return engine;
64
+ }
65
+ return null;
66
+ }
67
+
68
+ /**
69
+ * Scan one candidate directory for Hub adoption.
70
+ * Returns { ok, verdict, counts, block } or { ok:false, error }.
71
+ */
72
+ function hubScanSkill(hubDir, discovery, opts, skillDir) {
73
+ const options = opts || {};
74
+ if (options.skipScan) {
75
+ return { ok: true, verdict: 'explicit-unverified', counts: null, block: false };
76
+ }
77
+ const engine = scanEngineForHub(hubDir, discovery, options);
78
+ if (!engine) {
79
+ return {
80
+ ok: false,
81
+ error: '未找到元信扫描引擎(可先安装 yotta-verify,或用 --allow-unverified 显式降级)',
82
+ };
83
+ }
84
+ const scan = runScan(engine, skillDir, options);
85
+ if (!scan.ok) return scan;
86
+ const verdict = gateLib.evaluateVerdict(scan.verdict);
87
+ return { ok: true, verdict: scan.verdict, counts: scan.counts, block: verdict.block };
88
+ }
89
+
90
+ module.exports = {
91
+ currentCommand,
92
+ findVerifyEngine,
93
+ findPython,
94
+ runScan,
95
+ scanEngineForHub,
96
+ hubScanSkill,
97
+ };