@aikdna/kdna-cli 0.18.0 → 0.19.1
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/README.md +101 -101
- package/SECURITY.md +1 -1
- package/package.json +3 -2
- package/skills/kdna-loader/SKILL.md +18 -16
- package/src/agent.js +152 -57
- package/src/cli.js +17 -11
- package/src/cmds/_common.js +9 -3
- package/src/cmds/badge.js +8 -3
- package/src/cmds/changelog.js +31 -11
- package/src/cmds/cluster.js +67 -40
- package/src/cmds/domain.js +37 -27
- package/src/cmds/explain.js +1 -4
- package/src/cmds/governance.js +111 -42
- package/src/cmds/legacy.js +1 -2
- package/src/cmds/license.js +16 -8
- package/src/cmds/quality.js +9 -2
- package/src/cmds/registry.js +11 -5
- package/src/cmds/studio.js +95 -42
- package/src/cmds/test.js +5 -2
- package/src/compare.js +15 -2
- package/src/diff.js +27 -11
- package/src/identity.js +9 -7
- package/src/install.js +17 -7
- package/src/package-store.js +4 -1
- package/src/paths.js +2 -2
- package/src/publish.js +90 -42
- package/src/registry.js +13 -8
- package/src/search.js +4 -5
- package/src/verify.js +61 -17
- package/src/version.js +15 -7
- package/templates/minimal-domain/kdna.json +7 -7
- package/templates/standard-domain/README.md +10 -10
- package/templates/standard-domain/kdna.json +6 -3
- package/validators/kdna-lint.js +45 -11
package/src/agent.js
CHANGED
|
@@ -308,7 +308,9 @@ function cmdMatch(taskText, args = []) {
|
|
|
308
308
|
}
|
|
309
309
|
}
|
|
310
310
|
console.log('');
|
|
311
|
-
console.log(
|
|
311
|
+
console.log(
|
|
312
|
+
'To consider any of these, read its full data: kdna load <name|file.kdna> --as=json',
|
|
313
|
+
);
|
|
312
314
|
}
|
|
313
315
|
}
|
|
314
316
|
|
|
@@ -379,16 +381,24 @@ function cmdLoad(input, args = []) {
|
|
|
379
381
|
const signature = manifest.signature;
|
|
380
382
|
const isPlaceholder = !signature || signature === '' || signature.includes('placeholder');
|
|
381
383
|
if (isPlaceholder) {
|
|
382
|
-
loadWarnings.push(
|
|
384
|
+
loadWarnings.push(
|
|
385
|
+
'⚠ Domain is unsigned — no cryptographic proof of authorship. Trust depends on source.',
|
|
386
|
+
);
|
|
383
387
|
}
|
|
384
388
|
if (manifest.status === 'deprecated') {
|
|
385
|
-
loadWarnings.push(
|
|
389
|
+
loadWarnings.push(
|
|
390
|
+
`⚠ Domain is deprecated${manifest.replaced_by ? ', replaced by ' + manifest.replaced_by : ''}.`,
|
|
391
|
+
);
|
|
386
392
|
}
|
|
387
393
|
const riskLevel = manifest.risk_level || 'R1';
|
|
388
394
|
if (riskLevel === 'R3' || riskLevel === 'R4') {
|
|
389
|
-
loadWarnings.push(
|
|
395
|
+
loadWarnings.push(
|
|
396
|
+
`⚠ High risk domain (${riskLevel}) — may influence agent behavior in safety-critical ways.`,
|
|
397
|
+
);
|
|
390
398
|
if (manifest.quality_badge === 'untested' || !manifest.quality_badge) {
|
|
391
|
-
loadWarnings.push(
|
|
399
|
+
loadWarnings.push(
|
|
400
|
+
'⚠ High risk + untested — load only if you trust the source and understand the risks.',
|
|
401
|
+
);
|
|
392
402
|
}
|
|
393
403
|
}
|
|
394
404
|
if (loadWarnings.length > 0) {
|
|
@@ -399,21 +409,27 @@ function cmdLoad(input, args = []) {
|
|
|
399
409
|
|
|
400
410
|
// JSON format
|
|
401
411
|
if (format === 'json') {
|
|
402
|
-
process.stdout.write(
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
412
|
+
process.stdout.write(
|
|
413
|
+
JSON.stringify(
|
|
414
|
+
{
|
|
415
|
+
manifest,
|
|
416
|
+
core,
|
|
417
|
+
patterns: pat,
|
|
418
|
+
trust: {
|
|
419
|
+
signature: isPlaceholder ? 'unsigned' : 'present',
|
|
420
|
+
risk_level: riskLevel,
|
|
421
|
+
deprecated: manifest.status === 'deprecated',
|
|
422
|
+
yanked: false,
|
|
423
|
+
warnings: loadWarnings,
|
|
424
|
+
asset_digest: asset.asset_digest || null,
|
|
425
|
+
content_digest: asset.content_digest || null,
|
|
426
|
+
license_id: licenseActivation?.license_id || null,
|
|
427
|
+
},
|
|
428
|
+
},
|
|
429
|
+
null,
|
|
430
|
+
2,
|
|
431
|
+
) + '\n',
|
|
432
|
+
);
|
|
417
433
|
recordTrace({
|
|
418
434
|
timestamp: new Date().toISOString(),
|
|
419
435
|
agent: detectAgent(),
|
|
@@ -429,7 +445,9 @@ function cmdLoad(input, args = []) {
|
|
|
429
445
|
for (const f of ['KDNA_Core.json', 'KDNA_Patterns.json']) {
|
|
430
446
|
const encrypted = encryptedEntries.includes(f);
|
|
431
447
|
const buf = encrypted
|
|
432
|
-
? Buffer.from(
|
|
448
|
+
? Buffer.from(
|
|
449
|
+
JSON.stringify(container[f === 'KDNA_Core.json' ? 'core' : 'patterns'], null, 2),
|
|
450
|
+
)
|
|
433
451
|
: readContainerEntry(asset.asset_path, f);
|
|
434
452
|
if (buf) {
|
|
435
453
|
process.stdout.write(`\n=== ${f} ===\n`);
|
|
@@ -1004,7 +1022,10 @@ function cmdRoute(taskText, args = []) {
|
|
|
1004
1022
|
|
|
1005
1023
|
if (!taskText) {
|
|
1006
1024
|
const err = { error: 'Usage: kdna route "<task description>" [--json] [--discover]' };
|
|
1007
|
-
if (wantJson) {
|
|
1025
|
+
if (wantJson) {
|
|
1026
|
+
console.log(JSON.stringify(err));
|
|
1027
|
+
process.exit(2);
|
|
1028
|
+
}
|
|
1008
1029
|
console.error(err.error);
|
|
1009
1030
|
process.exit(2);
|
|
1010
1031
|
}
|
|
@@ -1031,19 +1052,53 @@ function cmdRoute(taskText, args = []) {
|
|
|
1031
1052
|
|
|
1032
1053
|
// ═══ Gate 1: Intent — does this task need domain judgment? ═══
|
|
1033
1054
|
const judgmentKeywords = [
|
|
1034
|
-
'review',
|
|
1035
|
-
'
|
|
1036
|
-
'
|
|
1055
|
+
'review',
|
|
1056
|
+
'diagnose',
|
|
1057
|
+
'critique',
|
|
1058
|
+
'evaluate',
|
|
1059
|
+
'assess',
|
|
1060
|
+
'judge',
|
|
1061
|
+
'should i',
|
|
1062
|
+
'is this good',
|
|
1063
|
+
'is this correct',
|
|
1064
|
+
'how would you rate',
|
|
1065
|
+
'分析',
|
|
1066
|
+
'诊断',
|
|
1067
|
+
'评估',
|
|
1068
|
+
'判断',
|
|
1069
|
+
'审查',
|
|
1070
|
+
'该怎么',
|
|
1071
|
+
'好不好',
|
|
1037
1072
|
];
|
|
1038
1073
|
const mechanicalKeywords = [
|
|
1039
|
-
'format',
|
|
1040
|
-
'
|
|
1041
|
-
'
|
|
1074
|
+
'format',
|
|
1075
|
+
'translate',
|
|
1076
|
+
'convert',
|
|
1077
|
+
'list',
|
|
1078
|
+
'find',
|
|
1079
|
+
'lookup',
|
|
1080
|
+
'search',
|
|
1081
|
+
'run',
|
|
1082
|
+
'execute',
|
|
1083
|
+
'compile',
|
|
1084
|
+
'build',
|
|
1085
|
+
'fix syntax',
|
|
1086
|
+
'fix the bug',
|
|
1087
|
+
'格式化',
|
|
1088
|
+
'翻译',
|
|
1089
|
+
'转换',
|
|
1090
|
+
'列出',
|
|
1091
|
+
'查找',
|
|
1092
|
+
'搜索',
|
|
1093
|
+
'运行',
|
|
1094
|
+
'执行',
|
|
1095
|
+
'编译',
|
|
1096
|
+
'修复语法',
|
|
1042
1097
|
];
|
|
1043
1098
|
|
|
1044
1099
|
const taskLower = taskText.toLowerCase();
|
|
1045
|
-
const hasJudgmentSignal = judgmentKeywords.some(k => taskLower.includes(k));
|
|
1046
|
-
const hasMechanicalSignal = mechanicalKeywords.some(k => taskLower.includes(k));
|
|
1100
|
+
const hasJudgmentSignal = judgmentKeywords.some((k) => taskLower.includes(k));
|
|
1101
|
+
const hasMechanicalSignal = mechanicalKeywords.some((k) => taskLower.includes(k));
|
|
1047
1102
|
|
|
1048
1103
|
result.needs_kdna = hasJudgmentSignal && !hasMechanicalSignal;
|
|
1049
1104
|
|
|
@@ -1053,7 +1108,10 @@ function cmdRoute(taskText, args = []) {
|
|
|
1053
1108
|
result.reason = hasMechanicalSignal
|
|
1054
1109
|
? 'task is mechanical — no domain judgment required'
|
|
1055
1110
|
: 'task does not appear to need domain judgment';
|
|
1056
|
-
if (wantJson) {
|
|
1111
|
+
if (wantJson) {
|
|
1112
|
+
console.log(JSON.stringify(result, null, 2));
|
|
1113
|
+
return;
|
|
1114
|
+
}
|
|
1057
1115
|
console.log('SKIP (no judgment needed)');
|
|
1058
1116
|
return;
|
|
1059
1117
|
}
|
|
@@ -1062,7 +1120,10 @@ function cmdRoute(taskText, args = []) {
|
|
|
1062
1120
|
result.status = 'SKIP_NO_LOCAL_DOMAIN';
|
|
1063
1121
|
result.action = 'skip';
|
|
1064
1122
|
result.reason = 'task may benefit from judgment, but no KDNA domains are installed';
|
|
1065
|
-
if (wantJson) {
|
|
1123
|
+
if (wantJson) {
|
|
1124
|
+
console.log(JSON.stringify(result, null, 2));
|
|
1125
|
+
return;
|
|
1126
|
+
}
|
|
1066
1127
|
console.log('SKIP (no domains installed)');
|
|
1067
1128
|
return;
|
|
1068
1129
|
}
|
|
@@ -1137,8 +1198,8 @@ function cmdRoute(taskText, args = []) {
|
|
|
1137
1198
|
candidates.sort((a, b) => b.score - a.score);
|
|
1138
1199
|
|
|
1139
1200
|
// ═══ Gate 4: Decision ═══
|
|
1140
|
-
const strongCandidates = candidates.filter(c => c.score >= 6);
|
|
1141
|
-
const weakCandidates = candidates.filter(c => c.score > 0 && c.score < 6);
|
|
1201
|
+
const strongCandidates = candidates.filter((c) => c.score >= 6);
|
|
1202
|
+
const weakCandidates = candidates.filter((c) => c.score > 0 && c.score < 6);
|
|
1142
1203
|
|
|
1143
1204
|
if (strongCandidates.length === 0 && weakCandidates.length === 0) {
|
|
1144
1205
|
// No matches at all
|
|
@@ -1148,7 +1209,7 @@ function cmdRoute(taskText, args = []) {
|
|
|
1148
1209
|
if (result.rejected_domains.length > 0) {
|
|
1149
1210
|
result.reason += ` (${result.rejected_domains.length} domains explicitly excluded by does_not_apply_when)`;
|
|
1150
1211
|
}
|
|
1151
|
-
result.candidates = candidates.map(c => ({
|
|
1212
|
+
result.candidates = candidates.map((c) => ({
|
|
1152
1213
|
domain: c.domain,
|
|
1153
1214
|
decision: 'rejected',
|
|
1154
1215
|
reason: 'insufficient match score',
|
|
@@ -1161,24 +1222,38 @@ function cmdRoute(taskText, args = []) {
|
|
|
1161
1222
|
result.reason = `${strongCandidates.length} domains strongly match this task with different judgment frames`;
|
|
1162
1223
|
|
|
1163
1224
|
result.ambiguity = {
|
|
1164
|
-
domains: strongCandidates.slice(0, 3).map(c => ({
|
|
1225
|
+
domains: strongCandidates.slice(0, 3).map((c) => ({
|
|
1165
1226
|
domain: c.domain,
|
|
1166
1227
|
description: c.description,
|
|
1167
1228
|
judgment_frame: c.reasons.length > 0 ? c.reasons[0].text : c.description,
|
|
1168
1229
|
risk_if_wrong: `may misclassify the task as a ${c.domain.split('/').pop()} problem`,
|
|
1169
1230
|
})),
|
|
1170
|
-
recommendation:
|
|
1231
|
+
recommendation:
|
|
1232
|
+
'Choose the domain whose judgment frame best matches the task intent. Do not blend domains.',
|
|
1171
1233
|
};
|
|
1172
1234
|
|
|
1173
|
-
result.candidates = strongCandidates.map(c => ({
|
|
1174
|
-
domain: c.domain,
|
|
1235
|
+
result.candidates = strongCandidates.map((c) => ({
|
|
1236
|
+
domain: c.domain,
|
|
1237
|
+
decision: 'ambiguous',
|
|
1238
|
+
reason: `score ${c.score}`,
|
|
1239
|
+
confidence: c.confidence,
|
|
1175
1240
|
}));
|
|
1176
1241
|
} else if (strongCandidates.length === 1) {
|
|
1177
1242
|
// One strong match + possible weak matches
|
|
1178
1243
|
const selected = strongCandidates[0];
|
|
1179
1244
|
result.candidates = [
|
|
1180
|
-
{
|
|
1181
|
-
|
|
1245
|
+
{
|
|
1246
|
+
domain: selected.domain,
|
|
1247
|
+
decision: 'strong_match',
|
|
1248
|
+
reason: `score ${selected.score}`,
|
|
1249
|
+
confidence: selected.confidence,
|
|
1250
|
+
},
|
|
1251
|
+
...weakCandidates.map((c) => ({
|
|
1252
|
+
domain: c.domain,
|
|
1253
|
+
decision: 'weak_match',
|
|
1254
|
+
reason: `score ${c.score}`,
|
|
1255
|
+
confidence: c.confidence,
|
|
1256
|
+
})),
|
|
1182
1257
|
];
|
|
1183
1258
|
|
|
1184
1259
|
// ═══ Trust Gate ═══
|
|
@@ -1200,11 +1275,15 @@ function cmdRoute(taskText, args = []) {
|
|
|
1200
1275
|
// Only weak matches — skip
|
|
1201
1276
|
result.status = 'SKIP_WEAK_FIT';
|
|
1202
1277
|
result.action = 'skip';
|
|
1203
|
-
result.reason =
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1278
|
+
result.reason =
|
|
1279
|
+
weakCandidates.length > 0
|
|
1280
|
+
? `${weakCandidates.length} domain(s) have weak match only — skipping to avoid contamination`
|
|
1281
|
+
: 'no installed domain matches this task';
|
|
1282
|
+
result.candidates = weakCandidates.map((c) => ({
|
|
1283
|
+
domain: c.domain,
|
|
1284
|
+
decision: 'weak_match',
|
|
1285
|
+
reason: `score ${c.score}`,
|
|
1286
|
+
confidence: c.confidence,
|
|
1208
1287
|
}));
|
|
1209
1288
|
}
|
|
1210
1289
|
|
|
@@ -1230,7 +1309,7 @@ function cmdRoute(taskText, args = []) {
|
|
|
1230
1309
|
if (result.reason) console.log(`Reason: ${result.reason}`);
|
|
1231
1310
|
if (result.selected_domain) console.log(`Domain: ${result.selected_domain}`);
|
|
1232
1311
|
if (result.rejected_domains.length) {
|
|
1233
|
-
console.log(`Rejected: ${result.rejected_domains.map(r => r.domain).join(', ')}`);
|
|
1312
|
+
console.log(`Rejected: ${result.rejected_domains.map((r) => r.domain).join(', ')}`);
|
|
1234
1313
|
}
|
|
1235
1314
|
}
|
|
1236
1315
|
|
|
@@ -1252,7 +1331,9 @@ function checkTrust(domainName) {
|
|
|
1252
1331
|
|
|
1253
1332
|
// 2. Deprecation check
|
|
1254
1333
|
if (manifest.status === 'deprecated') {
|
|
1255
|
-
warnings.push(
|
|
1334
|
+
warnings.push(
|
|
1335
|
+
`domain is deprecated${manifest.replaced_by ? ', replaced by ' + manifest.replaced_by : ''}`,
|
|
1336
|
+
);
|
|
1256
1337
|
}
|
|
1257
1338
|
|
|
1258
1339
|
// 3. Signature check
|
|
@@ -1271,14 +1352,18 @@ function checkTrust(domainName) {
|
|
|
1271
1352
|
const riskMap = { R0: 0, R1: 1, R2: 2, R3: 3, R4: 4 };
|
|
1272
1353
|
const riskNum = riskMap[riskLevel] || 1;
|
|
1273
1354
|
if (riskNum >= 3) {
|
|
1274
|
-
warnings.push(
|
|
1355
|
+
warnings.push(
|
|
1356
|
+
`domain risk level is ${riskLevel} — high-risk judgment may influence agent behavior`,
|
|
1357
|
+
);
|
|
1275
1358
|
}
|
|
1276
1359
|
if (riskNum >= 2 && (manifest.quality_badge === 'untested' || !manifest.quality_badge)) {
|
|
1277
|
-
warnings.push(
|
|
1360
|
+
warnings.push(
|
|
1361
|
+
`risk level ${riskLevel} with quality_badge '${manifest.quality_badge || 'none'}' — consider requiring review`,
|
|
1362
|
+
);
|
|
1278
1363
|
}
|
|
1279
1364
|
|
|
1280
1365
|
// 5. SPEC compatibility check
|
|
1281
|
-
const specVersion = manifest.spec_version ||
|
|
1366
|
+
const specVersion = manifest.spec_version || 'unknown';
|
|
1282
1367
|
const supportedSpecs = ['1.0-rc', '1.0', '0.7'];
|
|
1283
1368
|
if (!supportedSpecs.includes(specVersion)) {
|
|
1284
1369
|
warnings.push(`SPEC version '${specVersion}' may not be fully compatible with current loader`);
|
|
@@ -1290,8 +1375,8 @@ function checkTrust(domainName) {
|
|
|
1290
1375
|
if (!licenseCheck.ok) {
|
|
1291
1376
|
warnings.push(
|
|
1292
1377
|
'commercial domain has no active entitlement — run: kdna license activate ' +
|
|
1293
|
-
|
|
1294
|
-
|
|
1378
|
+
domainName +
|
|
1379
|
+
' --key <license-key> --server <url>',
|
|
1295
1380
|
);
|
|
1296
1381
|
}
|
|
1297
1382
|
}
|
|
@@ -1301,12 +1386,14 @@ function checkTrust(domainName) {
|
|
|
1301
1386
|
const hasJudgmentCards = axioms.length > 0;
|
|
1302
1387
|
if (hasJudgmentCards) {
|
|
1303
1388
|
const humanLocks = evolution.human_locks || [];
|
|
1304
|
-
const lockedAxioms = axioms.filter(a => {
|
|
1389
|
+
const lockedAxioms = axioms.filter((a) => {
|
|
1305
1390
|
// Check if axiom has a human_lock field OR if an evolution lock covers it
|
|
1306
|
-
return a.human_lock || humanLocks.some(hl => hl.lock_type === 'accept');
|
|
1391
|
+
return a.human_lock || humanLocks.some((hl) => hl.lock_type === 'accept');
|
|
1307
1392
|
}).length;
|
|
1308
1393
|
if (lockedAxioms === 0 && humanLocks.length === 0) {
|
|
1309
|
-
warnings.push(
|
|
1394
|
+
warnings.push(
|
|
1395
|
+
'domain has no Human Lock records — judgment-class content may not be human-verified',
|
|
1396
|
+
);
|
|
1310
1397
|
}
|
|
1311
1398
|
}
|
|
1312
1399
|
|
|
@@ -1320,4 +1407,12 @@ function checkTrust(domainName) {
|
|
|
1320
1407
|
};
|
|
1321
1408
|
}
|
|
1322
1409
|
|
|
1323
|
-
module.exports = {
|
|
1410
|
+
module.exports = {
|
|
1411
|
+
cmdAvailable,
|
|
1412
|
+
cmdMatch,
|
|
1413
|
+
cmdLoad,
|
|
1414
|
+
cmdSelect,
|
|
1415
|
+
cmdPostvalidate,
|
|
1416
|
+
cmdRoute,
|
|
1417
|
+
checkTrust,
|
|
1418
|
+
};
|
package/src/cli.js
CHANGED
|
@@ -7,13 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
const { error, EXIT, setQuiet, setExitCodeOnly } = require('./cmds/_common');
|
|
10
|
-
const {
|
|
11
|
-
cmdValidate,
|
|
12
|
-
cmdPack,
|
|
13
|
-
cmdUnpack,
|
|
14
|
-
cmdInspect,
|
|
15
|
-
cmdCard,
|
|
16
|
-
} = require('./cmds/domain');
|
|
10
|
+
const { cmdValidate, cmdPack, cmdUnpack, cmdInspect, cmdCard } = require('./cmds/domain');
|
|
17
11
|
const { cmdList, cmdRegistry } = require('./cmds/registry');
|
|
18
12
|
const {
|
|
19
13
|
cmdCompare,
|
|
@@ -249,15 +243,24 @@ switch (cmd) {
|
|
|
249
243
|
break;
|
|
250
244
|
}
|
|
251
245
|
case 'validate': {
|
|
252
|
-
error(
|
|
246
|
+
error(
|
|
247
|
+
'Directory validation is a dev-only operation. Use: kdna dev validate <source-dir>',
|
|
248
|
+
EXIT.INPUT_ERROR,
|
|
249
|
+
);
|
|
253
250
|
break;
|
|
254
251
|
}
|
|
255
252
|
case 'pack': {
|
|
256
|
-
error(
|
|
253
|
+
error(
|
|
254
|
+
'Directory packaging is a dev-only operation. Use: kdna dev pack <source-dir>',
|
|
255
|
+
EXIT.INPUT_ERROR,
|
|
256
|
+
);
|
|
257
257
|
break;
|
|
258
258
|
}
|
|
259
259
|
case 'unpack': {
|
|
260
|
-
error(
|
|
260
|
+
error(
|
|
261
|
+
'Unpacking exposes internal files and is dev-only. Use: kdna dev unpack <file.kdna>',
|
|
262
|
+
EXIT.INPUT_ERROR,
|
|
263
|
+
);
|
|
261
264
|
break;
|
|
262
265
|
}
|
|
263
266
|
case 'preview': {
|
|
@@ -463,7 +466,10 @@ switch (cmd) {
|
|
|
463
466
|
break;
|
|
464
467
|
}
|
|
465
468
|
case 'package': {
|
|
466
|
-
error(
|
|
469
|
+
error(
|
|
470
|
+
'Directory packaging is a dev-only operation. Use: kdna dev pack <source-dir>',
|
|
471
|
+
EXIT.INPUT_ERROR,
|
|
472
|
+
);
|
|
467
473
|
break;
|
|
468
474
|
}
|
|
469
475
|
// Legacy (removed) commands
|
package/src/cmds/_common.js
CHANGED
|
@@ -19,7 +19,9 @@ function setQuiet(val) {
|
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
function isQuiet() {
|
|
22
|
+
function isQuiet() {
|
|
23
|
+
return _quiet;
|
|
24
|
+
}
|
|
23
25
|
|
|
24
26
|
function setExitCodeOnly(val) {
|
|
25
27
|
_exitCodeOnly = val;
|
|
@@ -34,7 +36,9 @@ function setExitCodeOnly(val) {
|
|
|
34
36
|
}
|
|
35
37
|
}
|
|
36
38
|
|
|
37
|
-
function isExitCodeOnly() {
|
|
39
|
+
function isExitCodeOnly() {
|
|
40
|
+
return _exitCodeOnly;
|
|
41
|
+
}
|
|
38
42
|
|
|
39
43
|
function log(...args) {
|
|
40
44
|
if (!_quiet && !_exitCodeOnly) _originalLog(...args);
|
|
@@ -154,7 +158,9 @@ function isYesNoSelfCheck(item) {
|
|
|
154
158
|
raw.endsWith('?') ||
|
|
155
159
|
raw.endsWith('吗') ||
|
|
156
160
|
raw.includes('是否') ||
|
|
157
|
-
/^(have|has|can|does|do|is|are|did|was|were|should|will|would|could|might|can not|cannot|能不能|会不会|有没有|要不要|是不是)/.test(
|
|
161
|
+
/^(have|has|can|does|do|is|are|did|was|were|should|will|would|could|might|can not|cannot|能不能|会不会|有没有|要不要|是不是)/.test(
|
|
162
|
+
lower,
|
|
163
|
+
)
|
|
158
164
|
);
|
|
159
165
|
}
|
|
160
166
|
|
package/src/cmds/badge.js
CHANGED
|
@@ -157,7 +157,8 @@ function cmdRegistryAudit(args = []) {
|
|
|
157
157
|
|
|
158
158
|
if (yanked.length) audit.issues.push(`${yanked.length} yanked domain(s)`);
|
|
159
159
|
if (deprecated.length) audit.issues.push(`${deprecated.length} deprecated domain(s)`);
|
|
160
|
-
if (noPackage.length)
|
|
160
|
+
if (noPackage.length)
|
|
161
|
+
audit.issues.push(`${noPackage.length} domain(s) without .kdna dev package`);
|
|
161
162
|
if (noSignature.length) audit.issues.push(`${noSignature.length} domain(s) without signature`);
|
|
162
163
|
|
|
163
164
|
audit.healthy = audit.issues.length === 0;
|
|
@@ -184,7 +185,9 @@ function cmdRegistryAudit(args = []) {
|
|
|
184
185
|
if (d.yanked) flags.push('yanked');
|
|
185
186
|
if (d.deprecated) flags.push('deprecated');
|
|
186
187
|
if (!d.has_asset_url) flags.push('no-package');
|
|
187
|
-
console.log(
|
|
188
|
+
console.log(
|
|
189
|
+
` ${d.name.padEnd(36)} v${d.version || '?'} ${flags.length ? `[${flags.join(', ')}]` : '✓'}`,
|
|
190
|
+
);
|
|
188
191
|
}
|
|
189
192
|
}
|
|
190
193
|
|
|
@@ -230,7 +233,9 @@ function cmdPackage(domainPath, args = []) {
|
|
|
230
233
|
scenarios: readJson(path.join(abs, 'KDNA_Scenarios.json'))?.scenes?.length || 0,
|
|
231
234
|
cases: readJson(path.join(abs, 'KDNA_Cases.json'))?.cases?.length || 0,
|
|
232
235
|
},
|
|
233
|
-
files: fs
|
|
236
|
+
files: fs
|
|
237
|
+
.readdirSync(abs)
|
|
238
|
+
.filter((f) => f.endsWith('.json') || f === 'README.md' || f === 'LICENSE'),
|
|
234
239
|
};
|
|
235
240
|
|
|
236
241
|
// Actually pack
|
package/src/cmds/changelog.js
CHANGED
|
@@ -90,25 +90,43 @@ function cmdChangelog(args = []) {
|
|
|
90
90
|
// Diff maps
|
|
91
91
|
const axioms = diffSummary(oldJ.axioms || {}, newJ.axioms || {}, 'one_sentence');
|
|
92
92
|
const ontology = diffSummary(oldJ.ontology || {}, newJ.ontology || {}, 'concept');
|
|
93
|
-
const misunderstandings = diffSummary(
|
|
94
|
-
|
|
93
|
+
const misunderstandings = diffSummary(
|
|
94
|
+
oldJ.misunderstandings || {},
|
|
95
|
+
newJ.misunderstandings || {},
|
|
96
|
+
'wrong',
|
|
97
|
+
);
|
|
98
|
+
const bannedTerms = diffList(
|
|
99
|
+
Object.keys(oldJ.banned_terms || {}),
|
|
100
|
+
Object.keys(newJ.banned_terms || {}),
|
|
101
|
+
);
|
|
95
102
|
const stances = diffList(oldJ.stances || [], newJ.stances || []);
|
|
96
103
|
|
|
97
104
|
// Version bump suggestion
|
|
98
|
-
const hasRemoved =
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
105
|
+
const hasRemoved =
|
|
106
|
+
Object.values(axioms).some((a) => a.status === 'removed') ||
|
|
107
|
+
Object.values(misunderstandings).some((m) => m.status === 'removed');
|
|
108
|
+
const hasAdded =
|
|
109
|
+
Object.values(axioms).some((a) => a.status === 'added') ||
|
|
110
|
+
Object.values(misunderstandings).some((m) => m.status === 'added');
|
|
111
|
+
const hasChanged =
|
|
112
|
+
Object.values(axioms).some((a) => a.status === 'changed') ||
|
|
113
|
+
Object.values(misunderstandings).some((m) => m.status === 'changed');
|
|
104
114
|
let recommendedBump = 'none';
|
|
105
115
|
if (hasRemoved) recommendedBump = 'major';
|
|
106
116
|
else if (hasAdded || hasChanged) recommendedBump = 'minor';
|
|
107
117
|
else if (stances.added.length || stances.removed.length) recommendedBump = 'patch';
|
|
108
118
|
|
|
109
119
|
// Cleanup
|
|
110
|
-
try {
|
|
111
|
-
|
|
120
|
+
try {
|
|
121
|
+
fs.rmSync(tmpOld, { recursive: true, force: true });
|
|
122
|
+
} catch {
|
|
123
|
+
/* cleanup */
|
|
124
|
+
}
|
|
125
|
+
try {
|
|
126
|
+
fs.rmSync(tmpNew, { recursive: true, force: true });
|
|
127
|
+
} catch {
|
|
128
|
+
/* cleanup */
|
|
129
|
+
}
|
|
112
130
|
|
|
113
131
|
// Output
|
|
114
132
|
const changelog = {
|
|
@@ -139,7 +157,9 @@ function cmdChangelog(args = []) {
|
|
|
139
157
|
console.log(`## ${fromVersion} → ${toVersion}`);
|
|
140
158
|
console.log('');
|
|
141
159
|
if (oldJ.judgment_version || newJ.judgment_version) {
|
|
142
|
-
console.log(
|
|
160
|
+
console.log(
|
|
161
|
+
`Judgment version: ${oldJ.judgment_version || '(none)'} → ${newJ.judgment_version || '(none)'}`,
|
|
162
|
+
);
|
|
143
163
|
console.log('');
|
|
144
164
|
}
|
|
145
165
|
|