@aikdna/kdna-cli 0.16.10 → 0.18.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/README.md +158 -75
- package/package.json +5 -5
- package/skills/kdna-loader/SKILL.md +5 -6
- package/src/agent.js +489 -79
- package/src/cli.js +112 -62
- package/src/cmds/_common.js +32 -16
- package/src/cmds/badge.js +7 -7
- package/src/cmds/changelog.js +1 -1
- package/src/cmds/cluster.js +16 -48
- package/src/cmds/doctor.js +10 -27
- package/src/cmds/domain.js +213 -443
- package/src/cmds/explain.js +122 -0
- package/src/cmds/legacy.js +8 -8
- package/src/cmds/license.js +483 -26
- package/src/cmds/quality.js +14 -2
- package/src/cmds/registry.js +15 -67
- package/src/cmds/studio.js +4 -5
- package/src/cmds/test.js +4 -4
- package/src/cmds/trace.js +11 -7
- package/src/compare.js +28 -22
- package/src/diff.js +11 -13
- package/src/init.js +2 -2
- package/src/install.js +138 -460
- package/src/loader.js +10 -10
- package/src/package-store.js +229 -0
- package/src/paths.js +44 -0
- package/src/publish.js +184 -22
- package/src/registry.js +76 -9
- package/src/setup.js +19 -20
- package/src/verify.js +275 -121
- package/templates/standard-domain/kdna.json +2 -1
- package/validators/kdna-lint.js +37 -3
- package/validators/kdna-validate.js +3 -2
- package/src/cmds/encrypt.js +0 -199
package/src/cli.js
CHANGED
|
@@ -10,9 +10,7 @@ const { error, EXIT, setQuiet, setExitCodeOnly } = require('./cmds/_common');
|
|
|
10
10
|
const {
|
|
11
11
|
cmdValidate,
|
|
12
12
|
cmdPack,
|
|
13
|
-
cmdPackEncrypt,
|
|
14
13
|
cmdUnpack,
|
|
15
|
-
cmdUnpackEncrypt,
|
|
16
14
|
cmdInspect,
|
|
17
15
|
cmdCard,
|
|
18
16
|
} = require('./cmds/domain');
|
|
@@ -26,6 +24,7 @@ const {
|
|
|
26
24
|
cmdSelect,
|
|
27
25
|
cmdLoad,
|
|
28
26
|
cmdPostvalidate,
|
|
27
|
+
cmdRoute,
|
|
29
28
|
} = require('./cmds/quality');
|
|
30
29
|
const { cmdCluster } = require('./cmds/cluster');
|
|
31
30
|
const { cmdIdentity } = require('./cmds/identity');
|
|
@@ -38,6 +37,9 @@ const {
|
|
|
38
37
|
cmdLicenseBind,
|
|
39
38
|
cmdLicenseShow,
|
|
40
39
|
cmdLicenseInstall,
|
|
40
|
+
cmdLicenseStatus,
|
|
41
|
+
cmdLicenseActivate,
|
|
42
|
+
cmdLicenseSync,
|
|
41
43
|
} = require('./cmds/license');
|
|
42
44
|
const { cmdPreview, cmdProject, cmdEval, cmdExport, cmdDemo } = require('./cmds/legacy');
|
|
43
45
|
const {
|
|
@@ -57,7 +59,8 @@ const {
|
|
|
57
59
|
cmdEvolution,
|
|
58
60
|
cmdRegression,
|
|
59
61
|
} = require('./cmds/governance');
|
|
60
|
-
const { cmdBadgeCompute, cmdRegistryAudit
|
|
62
|
+
const { cmdBadgeCompute, cmdRegistryAudit } = require('./cmds/badge');
|
|
63
|
+
const { cmdExplain } = require('./cmds/explain');
|
|
61
64
|
|
|
62
65
|
// ─── Main ─────────────────────────────────────────────────────────────
|
|
63
66
|
|
|
@@ -79,15 +82,14 @@ Usage: kdna <command> [options]
|
|
|
79
82
|
|
|
80
83
|
Domain Authoring:
|
|
81
84
|
init <name> Scaffold a new domain from template
|
|
82
|
-
validate <path>
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
card <path> [--locale zh-CN] Display KDNA Card (governance metadata)
|
|
85
|
+
dev validate <path> Validate a dev source directory
|
|
86
|
+
dev pack <path> Build a dev source directory into .kdna
|
|
87
|
+
dev unpack <file> Unpack .kdna into a dev source directory
|
|
88
|
+
dev inspect <path> Inspect a dev source directory
|
|
89
|
+
dev card <path> Display KDNA Card from a dev source directory
|
|
90
|
+
inspect <file.kdna> Inspect a .kdna asset
|
|
91
|
+
card <file.kdna> [--locale zh-CN] Display KDNA Card from a .kdna asset
|
|
92
|
+
explain <name> Natural language summary: axioms, terms, scenarios
|
|
91
93
|
publish <path> Pack + sign + publish
|
|
92
94
|
publish --check <path> Quality gate check only
|
|
93
95
|
version bump <level> [path] Bump domain version
|
|
@@ -101,21 +103,22 @@ Studio Integration (Phase 1):
|
|
|
101
103
|
studio readiness <project.json> Generate domain readiness card
|
|
102
104
|
|
|
103
105
|
Agent Runtime:
|
|
106
|
+
route "<task>" [--json] [--discover] 5-Gate 7-State routing decision
|
|
104
107
|
available [--json] List installed domains with v2.1 fields
|
|
105
108
|
match "<task>" [--json] Signal matching — find relevant domains
|
|
106
109
|
select --input "..." [--json] Selection policy — decide which domains to load
|
|
107
|
-
load <name> [--as=prompt|json|raw] Emit
|
|
108
|
-
load <name> --profile=index|compact|scenario|full Load profiles (Phase 2)
|
|
110
|
+
load <name|file.kdna> [--as=prompt|json|raw] Emit asset in agent-ready format
|
|
111
|
+
load <name|file.kdna> --profile=index|compact|scenario|full Load profiles (Phase 2)
|
|
109
112
|
postvalidate <name> --output <file> Post-generation judgment check
|
|
110
113
|
|
|
111
114
|
Testing & Verification:
|
|
112
|
-
verify <name>
|
|
113
|
-
verify <name> --i18n
|
|
114
|
-
verify <name> --governance
|
|
115
|
-
verify <name> --judgment --run-tests Judgment validation with eval cases
|
|
116
|
-
compare <name> --input "..." With/without KDNA reasoning diff
|
|
117
|
-
compare <name> --input "..." --report-md Markdown report format
|
|
118
|
-
compare <name> --input "..." --report-json JSON report with scoring
|
|
115
|
+
verify <name|file.kdna> 3-layer: structure + trust + judgment
|
|
116
|
+
verify <name|file.kdna> --i18n I18N verification: locales, overlays, card completeness
|
|
117
|
+
verify <name|file.kdna> --governance Governance verification: risk_level, KDNA_CARD, provenance
|
|
118
|
+
verify <name|file.kdna> --judgment --run-tests Judgment validation with eval cases
|
|
119
|
+
compare <name|file.kdna> --input "..." With/without KDNA reasoning diff
|
|
120
|
+
compare <name|file.kdna> --input "..." --report-md Markdown report format
|
|
121
|
+
compare <name|file.kdna> --input "..." --report-json JSON report with scoring
|
|
119
122
|
diff <name>@<v1> <name>@<v2> Judgment-level diff between versions
|
|
120
123
|
test run <name> --input <file> Record test result against domain
|
|
121
124
|
test import <run> --as-eval Convert test result to eval card
|
|
@@ -146,6 +149,7 @@ Quality & Distribution (Phase 7):
|
|
|
146
149
|
|
|
147
150
|
Registry & Distribution:
|
|
148
151
|
install <name> Install domain from registry
|
|
152
|
+
install <file.kdna> Install a local .kdna asset
|
|
149
153
|
remove <name> Uninstall a domain
|
|
150
154
|
update <name> Update installed domain
|
|
151
155
|
info <name> Show domain metadata and trust status
|
|
@@ -170,9 +174,12 @@ Trace & Diagnostics:
|
|
|
170
174
|
License & Authorization:
|
|
171
175
|
license generate <domain> --to <email> Generate signed license
|
|
172
176
|
license install <license.json> Register license for auto-decrypt
|
|
177
|
+
license activate <domain> --key --server Activate license from entitlement source
|
|
178
|
+
license sync [domain] [--server] Refresh entitlement / revocation status
|
|
173
179
|
license verify <license.json> Verify license signature
|
|
174
180
|
license bind <license.json> Bind license to this machine
|
|
175
181
|
license show <license.json> Display license details
|
|
182
|
+
license status [domain] [--json] Show installed license activation status
|
|
176
183
|
|
|
177
184
|
Flags:
|
|
178
185
|
--json Structured JSON output (machine-readable)
|
|
@@ -188,41 +195,69 @@ Exit Codes:
|
|
|
188
195
|
const cmd = args[0];
|
|
189
196
|
|
|
190
197
|
switch (cmd) {
|
|
198
|
+
case 'dev': {
|
|
199
|
+
const sub = args[1];
|
|
200
|
+
if (sub === 'validate') {
|
|
201
|
+
const schemaFlag = args.includes('--schema');
|
|
202
|
+
const jsonFlag = args.includes('--json');
|
|
203
|
+
const target = args.filter((a, i) => i > 1 && a !== '--schema' && a !== '--json')[0];
|
|
204
|
+
if (!target) error('Usage: kdna dev validate <source-dir>');
|
|
205
|
+
cmdValidate(target, schemaFlag, jsonFlag);
|
|
206
|
+
break;
|
|
207
|
+
}
|
|
208
|
+
if (sub === 'pack') {
|
|
209
|
+
let output = null;
|
|
210
|
+
let target = null;
|
|
211
|
+
for (let i = 2; i < args.length; i++) {
|
|
212
|
+
if (args[i] === '--output' || args[i] === '-o') {
|
|
213
|
+
output = args[i + 1];
|
|
214
|
+
i++;
|
|
215
|
+
} else if (args[i].startsWith('-')) {
|
|
216
|
+
error(`Unknown option for kdna dev pack: ${args[i]}`, EXIT.INPUT_ERROR);
|
|
217
|
+
} else if (!target) {
|
|
218
|
+
target = args[i];
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
if (!target) error('Usage: kdna dev pack <source-dir>');
|
|
222
|
+
cmdPack(target, output);
|
|
223
|
+
break;
|
|
224
|
+
}
|
|
225
|
+
if (sub === 'unpack') {
|
|
226
|
+
const target = args[2];
|
|
227
|
+
if (!target) error('Usage: kdna dev unpack <file.kdna>');
|
|
228
|
+
if (!target.endsWith('.kdna')) error('Not a .kdna asset.', EXIT.INPUT_ERROR);
|
|
229
|
+
cmdUnpack(target, args.includes('--force'));
|
|
230
|
+
break;
|
|
231
|
+
}
|
|
232
|
+
if (sub === 'inspect') {
|
|
233
|
+
const target = args.filter((a, i) => i > 1 && !a.startsWith('--'))[0];
|
|
234
|
+
if (!target) error('Usage: kdna dev inspect <source-dir> [--json] [--locale zh-CN]');
|
|
235
|
+
const localeIdx = args.indexOf('--locale');
|
|
236
|
+
const locale = localeIdx >= 0 ? args[localeIdx + 1] : null;
|
|
237
|
+
cmdInspect(target, args.includes('--json'), locale, { allowDirectory: true });
|
|
238
|
+
break;
|
|
239
|
+
}
|
|
240
|
+
if (sub === 'card') {
|
|
241
|
+
const target = args.filter((a, i) => i > 1 && !a.startsWith('--'))[0];
|
|
242
|
+
if (!target) error('Usage: kdna dev card <source-dir> [--json] [--locale zh-CN]');
|
|
243
|
+
const localeIdx = args.indexOf('--locale');
|
|
244
|
+
const locale = localeIdx >= 0 ? args[localeIdx + 1] : null;
|
|
245
|
+
cmdCard(target, args.includes('--json'), locale, { allowDirectory: true });
|
|
246
|
+
break;
|
|
247
|
+
}
|
|
248
|
+
error('Usage: kdna dev <validate|pack|unpack|inspect|card> ...', EXIT.INPUT_ERROR);
|
|
249
|
+
break;
|
|
250
|
+
}
|
|
191
251
|
case 'validate': {
|
|
192
|
-
|
|
193
|
-
const jsonFlag = args.includes('--json');
|
|
194
|
-
const target = args.filter((a, i) => i > 0 && a !== '--schema' && a !== '--json')[0];
|
|
195
|
-
if (!target) error('Usage: kdna validate <path>');
|
|
196
|
-
cmdValidate(target, schemaFlag, jsonFlag);
|
|
252
|
+
error('Directory validation is a dev-only operation. Use: kdna dev validate <source-dir>', EXIT.INPUT_ERROR);
|
|
197
253
|
break;
|
|
198
254
|
}
|
|
199
255
|
case 'pack': {
|
|
200
|
-
|
|
201
|
-
let target = null;
|
|
202
|
-
for (let i = 1; i < args.length; i++) {
|
|
203
|
-
if (args[i] === '--output' || args[i] === '-o') {
|
|
204
|
-
output = args[i + 1];
|
|
205
|
-
i++;
|
|
206
|
-
} else if (!target) {
|
|
207
|
-
target = args[i];
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
if (!target) error('Usage: kdna pack <path>');
|
|
211
|
-
if (args.includes('--encrypt')) {
|
|
212
|
-
cmdPackEncrypt(target, args);
|
|
213
|
-
} else {
|
|
214
|
-
cmdPack(target, output);
|
|
215
|
-
}
|
|
256
|
+
error('Directory packaging is a dev-only operation. Use: kdna dev pack <source-dir>', EXIT.INPUT_ERROR);
|
|
216
257
|
break;
|
|
217
258
|
}
|
|
218
259
|
case 'unpack': {
|
|
219
|
-
|
|
220
|
-
if (!target) error('Usage: kdna unpack <file.kdna|file.kdnae>');
|
|
221
|
-
if (target.endsWith('.kdnae')) {
|
|
222
|
-
cmdUnpackEncrypt(target, args);
|
|
223
|
-
} else {
|
|
224
|
-
cmdUnpack(target, args.includes('--force'));
|
|
225
|
-
}
|
|
260
|
+
error('Unpacking exposes internal files and is dev-only. Use: kdna dev unpack <file.kdna>', EXIT.INPUT_ERROR);
|
|
226
261
|
break;
|
|
227
262
|
}
|
|
228
263
|
case 'preview': {
|
|
@@ -240,7 +275,7 @@ switch (cmd) {
|
|
|
240
275
|
domainId = args[i];
|
|
241
276
|
}
|
|
242
277
|
}
|
|
243
|
-
if (!domainId) error('Usage: kdna install <domain-id|
|
|
278
|
+
if (!domainId) error('Usage: kdna install <domain-id|file.kdna>');
|
|
244
279
|
|
|
245
280
|
const { cmdInstallExtended } = require('./install');
|
|
246
281
|
if (fromGit) {
|
|
@@ -283,7 +318,7 @@ switch (cmd) {
|
|
|
283
318
|
}
|
|
284
319
|
case 'inspect': {
|
|
285
320
|
const target = args.filter((a) => !a.startsWith('--'))[1];
|
|
286
|
-
if (!target) error('Usage: kdna inspect <
|
|
321
|
+
if (!target) error('Usage: kdna inspect <file.kdna> [--json] [--locale zh-CN]');
|
|
287
322
|
const localeIdx = args.indexOf('--locale');
|
|
288
323
|
const locale = localeIdx >= 0 ? args[localeIdx + 1] : null;
|
|
289
324
|
cmdInspect(target, args.includes('--json'), locale);
|
|
@@ -291,10 +326,10 @@ switch (cmd) {
|
|
|
291
326
|
}
|
|
292
327
|
case 'card': {
|
|
293
328
|
const target = args.filter((a) => !a.startsWith('--'))[1];
|
|
294
|
-
if (!target) error('Usage: kdna card <
|
|
329
|
+
if (!target) error('Usage: kdna card <file.kdna> [--json] [--locale zh-CN]');
|
|
295
330
|
const localeIdx = args.indexOf('--locale');
|
|
296
331
|
const locale = localeIdx >= 0 ? args[localeIdx + 1] : null;
|
|
297
|
-
cmdCard(target, locale);
|
|
332
|
+
cmdCard(target, args.includes('--json'), locale);
|
|
298
333
|
break;
|
|
299
334
|
}
|
|
300
335
|
case 'verify': {
|
|
@@ -303,10 +338,10 @@ switch (cmd) {
|
|
|
303
338
|
if (!target) {
|
|
304
339
|
error(
|
|
305
340
|
'Usage:\n' +
|
|
306
|
-
' kdna verify <name> Run all three layers (structure / trust / judgment)\n' +
|
|
307
|
-
' kdna verify <name> --structure Files + schema only\n' +
|
|
308
|
-
' kdna verify <name> --trust Signature + scope + Ed25519 only\n' +
|
|
309
|
-
' kdna verify <name> --judgment v2.1 governance fields + eval cases only',
|
|
341
|
+
' kdna verify <name|file.kdna> Run all three layers (structure / trust / judgment)\n' +
|
|
342
|
+
' kdna verify <name|file.kdna> --structure Files + schema only\n' +
|
|
343
|
+
' kdna verify <name|file.kdna> --trust Signature + scope + Ed25519 only\n' +
|
|
344
|
+
' kdna verify <name|file.kdna> --judgment v2.1 governance fields + eval cases only',
|
|
310
345
|
);
|
|
311
346
|
}
|
|
312
347
|
cmdVerify(target, args);
|
|
@@ -340,6 +375,10 @@ switch (cmd) {
|
|
|
340
375
|
cmdSelect(args);
|
|
341
376
|
break;
|
|
342
377
|
}
|
|
378
|
+
case 'route': {
|
|
379
|
+
cmdRoute(args);
|
|
380
|
+
break;
|
|
381
|
+
}
|
|
343
382
|
case 'postvalidate': {
|
|
344
383
|
cmdPostvalidate(args);
|
|
345
384
|
break;
|
|
@@ -424,9 +463,7 @@ switch (cmd) {
|
|
|
424
463
|
break;
|
|
425
464
|
}
|
|
426
465
|
case 'package': {
|
|
427
|
-
|
|
428
|
-
if (!target) error('Usage: kdna package <domain> --format=kdna');
|
|
429
|
-
cmdPackage(target, args);
|
|
466
|
+
error('Directory packaging is a dev-only operation. Use: kdna dev pack <source-dir>', EXIT.INPUT_ERROR);
|
|
430
467
|
break;
|
|
431
468
|
}
|
|
432
469
|
// Legacy (removed) commands
|
|
@@ -446,6 +483,10 @@ switch (cmd) {
|
|
|
446
483
|
cmdDemo();
|
|
447
484
|
break;
|
|
448
485
|
}
|
|
486
|
+
case 'explain': {
|
|
487
|
+
cmdExplain(args);
|
|
488
|
+
break;
|
|
489
|
+
}
|
|
449
490
|
case 'list': {
|
|
450
491
|
const localeIdx = args.indexOf('--locale');
|
|
451
492
|
const locale = localeIdx >= 0 ? args[localeIdx + 1] : null;
|
|
@@ -485,14 +526,23 @@ switch (cmd) {
|
|
|
485
526
|
cmdLicenseShow(rest);
|
|
486
527
|
} else if (sub === 'install') {
|
|
487
528
|
cmdLicenseInstall(rest);
|
|
529
|
+
} else if (sub === 'status') {
|
|
530
|
+
cmdLicenseStatus(rest);
|
|
531
|
+
} else if (sub === 'activate') {
|
|
532
|
+
cmdLicenseActivate(rest).catch((e) => error(e.message, EXIT.TRUST_FAILED));
|
|
533
|
+
} else if (sub === 'sync') {
|
|
534
|
+
cmdLicenseSync(rest).catch((e) => error(e.message, EXIT.TRUST_FAILED));
|
|
488
535
|
} else {
|
|
489
536
|
error(
|
|
490
537
|
'Usage:\n' +
|
|
491
538
|
' kdna license generate <domain> --to <email> [--expires <date>]\n' +
|
|
492
539
|
' kdna license install <license.json>\n' +
|
|
540
|
+
' kdna license activate <domain> --key <license-key> --server <url>\n' +
|
|
541
|
+
' kdna license sync [domain] [--server <url>]\n' +
|
|
493
542
|
' kdna license verify <license.json>\n' +
|
|
494
543
|
' kdna license bind <license.json>\n' +
|
|
495
|
-
' kdna license show <license.json
|
|
544
|
+
' kdna license show <license.json>\n' +
|
|
545
|
+
' kdna license status [domain] [--json]',
|
|
496
546
|
EXIT.INPUT_ERROR,
|
|
497
547
|
);
|
|
498
548
|
}
|
|
@@ -513,7 +563,7 @@ switch (cmd) {
|
|
|
513
563
|
const idx = args.indexOf('--check');
|
|
514
564
|
const target = args[idx + 1] || args.filter((a) => !a.startsWith('--'))[1] || '.';
|
|
515
565
|
if (!target || target.startsWith('--')) error('Usage: kdna publish --check <path>');
|
|
516
|
-
cmdPublishCheck(target);
|
|
566
|
+
cmdPublishCheck(target, args);
|
|
517
567
|
} else {
|
|
518
568
|
const { cmdPublish } = require('./publish');
|
|
519
569
|
const target = args.filter((a) => !a.startsWith('--'))[1];
|
package/src/cmds/_common.js
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
const fs = require('fs');
|
|
2
|
-
const path = require('path');
|
|
3
2
|
const { loadRegistry: loadCanonicalRegistry } = require('../registry');
|
|
4
|
-
|
|
5
|
-
const USER_KDNA_DIR = path.join(process.env.HOME || process.env.USERPROFILE || '.', '.kdna');
|
|
6
|
-
const INSTALL_DIR = path.join(USER_KDNA_DIR, 'domains');
|
|
3
|
+
const { USER_KDNA_DIR, INSTALL_DIR } = require('../paths');
|
|
7
4
|
|
|
8
5
|
// ─── Global flags ──────────────────────────────────────────────────────
|
|
9
6
|
|
|
@@ -54,14 +51,13 @@ Usage:
|
|
|
54
51
|
|
|
55
52
|
--- Domain authors ---
|
|
56
53
|
kdna init <name> Scaffold a new KDNA domain from template
|
|
57
|
-
kdna validate <path>
|
|
58
|
-
kdna
|
|
59
|
-
kdna
|
|
60
|
-
kdna
|
|
61
|
-
kdna
|
|
62
|
-
kdna
|
|
63
|
-
kdna
|
|
64
|
-
kdna publish <path> Pack + sign + output registry patch
|
|
54
|
+
kdna dev validate <path> Validate a dev source directory
|
|
55
|
+
kdna dev pack <path> Build a dev source directory into .kdna
|
|
56
|
+
kdna dev unpack <path> Unpack .kdna into a dev source directory
|
|
57
|
+
kdna dev inspect <path> Inspect a dev source directory
|
|
58
|
+
kdna dev card <path> Display KDNA Card from a dev source directory
|
|
59
|
+
kdna inspect <file.kdna> Inspect a .kdna asset
|
|
60
|
+
kdna publish <path> Pack + sign a dev source directory
|
|
65
61
|
kdna publish <path> --release-tag <tag> --repo <o/r> ...also upload to GitHub
|
|
66
62
|
kdna publish --check <path> Run quality gate only (no pack/upload)
|
|
67
63
|
kdna version bump <patch|minor|major> [path] Bump domain version
|
|
@@ -72,7 +68,6 @@ Usage:
|
|
|
72
68
|
kdna install @scope/name Install any scoped domain
|
|
73
69
|
kdna install @aikdna/animation Install a cluster (installs all sub-domains)
|
|
74
70
|
kdna install ./file.kdna Install from a local .kdna file
|
|
75
|
-
kdna install ./folder Install from a local directory (dev)
|
|
76
71
|
kdna remove <name> Uninstall a domain
|
|
77
72
|
kdna update <name> Update an installed domain
|
|
78
73
|
kdna update --all Update all installed domains
|
|
@@ -83,14 +78,14 @@ Usage:
|
|
|
83
78
|
kdna registry refresh Refresh the canonical registry cache
|
|
84
79
|
|
|
85
80
|
--- Quality + judgment ---
|
|
86
|
-
kdna verify <name>
|
|
87
|
-
kdna compare <name> --input "<text>" With/without KDNA reasoning diff
|
|
81
|
+
kdna verify <name|file.kdna> Quality check: structure + trust + judgment
|
|
82
|
+
kdna compare <name|file.kdna> --input "<text>" With/without KDNA reasoning diff
|
|
88
83
|
kdna diff <name>@<v1> <name>@<v2> Judgment-level diff between versions
|
|
89
84
|
|
|
90
85
|
--- Agent-facing (called by the kdna-loader skill) ---
|
|
91
86
|
kdna available [--json] List installed domains + v2.1 fields
|
|
92
87
|
kdna match "<task>" [--json] Hint signals (dropped + weak overlap)
|
|
93
|
-
kdna load <name> [--as=prompt|json|raw] Emit
|
|
88
|
+
kdna load <name|file.kdna> [--as=prompt|json|raw] Emit asset in agent-ready format
|
|
94
89
|
|
|
95
90
|
--- Identity ---
|
|
96
91
|
kdna identity init Generate Ed25519 identity key pair
|
|
@@ -144,6 +139,25 @@ function writeJson(file, data) {
|
|
|
144
139
|
fs.writeFileSync(file, JSON.stringify(data, null, 2) + '\n');
|
|
145
140
|
}
|
|
146
141
|
|
|
142
|
+
function selfCheckText(item) {
|
|
143
|
+
if (typeof item === 'string') return item;
|
|
144
|
+
if (item && typeof item === 'object' && typeof item.question === 'string') return item.question;
|
|
145
|
+
return '';
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function isYesNoSelfCheck(item) {
|
|
149
|
+
const raw = selfCheckText(item).trim();
|
|
150
|
+
if (!raw) return false;
|
|
151
|
+
const lower = raw.toLowerCase();
|
|
152
|
+
return (
|
|
153
|
+
lower.endsWith('?') ||
|
|
154
|
+
raw.endsWith('?') ||
|
|
155
|
+
raw.endsWith('吗') ||
|
|
156
|
+
raw.includes('是否') ||
|
|
157
|
+
/^(have|has|can|does|do|is|are|did|was|were|should|will|would|could|might|can not|cannot|能不能|会不会|有没有|要不要|是不是)/.test(lower)
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
|
|
147
161
|
function loadRegistry() {
|
|
148
162
|
return loadCanonicalRegistry({ allowNetwork: true });
|
|
149
163
|
}
|
|
@@ -162,5 +176,7 @@ module.exports = {
|
|
|
162
176
|
isExitCodeOnly,
|
|
163
177
|
readJson,
|
|
164
178
|
writeJson,
|
|
179
|
+
selfCheckText,
|
|
180
|
+
isYesNoSelfCheck,
|
|
165
181
|
loadRegistry,
|
|
166
182
|
};
|
package/src/cmds/badge.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* kdna badge compute <domain> [--json]
|
|
5
5
|
* kdna registry audit --scope <scope> [--json]
|
|
6
|
-
* kdna
|
|
6
|
+
* kdna dev pack <domain>
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
const fs = require('fs');
|
|
@@ -142,9 +142,9 @@ function cmdRegistryAudit(args = []) {
|
|
|
142
142
|
status: d.status || 'experimental',
|
|
143
143
|
yanked: d.yanked || false,
|
|
144
144
|
deprecated: d.deprecated || false,
|
|
145
|
-
|
|
145
|
+
has_asset_url: !!d.asset_url,
|
|
146
146
|
has_signature: !!d.signature,
|
|
147
|
-
|
|
147
|
+
has_asset_digest: !!d.asset_digest,
|
|
148
148
|
})),
|
|
149
149
|
issues: [],
|
|
150
150
|
};
|
|
@@ -152,12 +152,12 @@ function cmdRegistryAudit(args = []) {
|
|
|
152
152
|
// Detect issues
|
|
153
153
|
const yanked = scopeDomains.filter((d) => d.yanked);
|
|
154
154
|
const deprecated = scopeDomains.filter((d) => d.deprecated);
|
|
155
|
-
const noPackage = scopeDomains.filter((d) => !d.
|
|
155
|
+
const noPackage = scopeDomains.filter((d) => !d.asset_url);
|
|
156
156
|
const noSignature = scopeDomains.filter((d) => !d.signature);
|
|
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) audit.issues.push(`${noPackage.length} domain(s) without .kdna package`);
|
|
160
|
+
if (noPackage.length) audit.issues.push(`${noPackage.length} domain(s) without .kdna dev package`);
|
|
161
161
|
if (noSignature.length) audit.issues.push(`${noSignature.length} domain(s) without signature`);
|
|
162
162
|
|
|
163
163
|
audit.healthy = audit.issues.length === 0;
|
|
@@ -183,7 +183,7 @@ function cmdRegistryAudit(args = []) {
|
|
|
183
183
|
const flags = [];
|
|
184
184
|
if (d.yanked) flags.push('yanked');
|
|
185
185
|
if (d.deprecated) flags.push('deprecated');
|
|
186
|
-
if (!d.
|
|
186
|
+
if (!d.has_asset_url) flags.push('no-package');
|
|
187
187
|
console.log(` ${d.name.padEnd(36)} v${d.version || '?'} ${flags.length ? `[${flags.join(', ')}]` : '✓'}`);
|
|
188
188
|
}
|
|
189
189
|
}
|
|
@@ -205,7 +205,7 @@ function cmdPackage(domainPath, args = []) {
|
|
|
205
205
|
}
|
|
206
206
|
|
|
207
207
|
const manifest = readJson(path.join(abs, 'kdna.json'));
|
|
208
|
-
if (!manifest) error(`No kdna.json found in ${abs}. Run: kdna pack`, EXIT.INPUT_ERROR);
|
|
208
|
+
if (!manifest) error(`No kdna.json found in ${abs}. Run: kdna dev pack`, EXIT.INPUT_ERROR);
|
|
209
209
|
|
|
210
210
|
const domainName = manifest.name?.split('/')?.[1] || path.basename(abs);
|
|
211
211
|
const outFile = path.join(abs, 'dist', `${domainName}-${manifest.version || '0.1.0'}.kdna`);
|
package/src/cmds/changelog.js
CHANGED
|
@@ -18,7 +18,7 @@ function downloadVersion(entry, version, destDir) {
|
|
|
18
18
|
const { execSync, execFileSync } = require('child_process');
|
|
19
19
|
const tmpFile = `${destDir}.kdna.tmp`;
|
|
20
20
|
try {
|
|
21
|
-
execFileSync('curl', ['-fsSL', '--retry', '2', '-o', tmpFile, entry.
|
|
21
|
+
execFileSync('curl', ['-fsSL', '--retry', '2', '-o', tmpFile, entry.asset_url], {
|
|
22
22
|
timeout: 60000,
|
|
23
23
|
stdio: 'pipe',
|
|
24
24
|
});
|
package/src/cmds/cluster.js
CHANGED
|
@@ -8,6 +8,16 @@ const {
|
|
|
8
8
|
detectDomainConflicts,
|
|
9
9
|
generateClusterTrace,
|
|
10
10
|
} = require('@aikdna/kdna-core');
|
|
11
|
+
const { getInstalled, readContainer } = require('../package-store');
|
|
12
|
+
|
|
13
|
+
function loadInstalledDomain(domainId) {
|
|
14
|
+
const full = domainId.startsWith('@') ? domainId : `@aikdna/${domainId}`;
|
|
15
|
+
const installed = getInstalled(full);
|
|
16
|
+
if (!installed) return null;
|
|
17
|
+
const { core, patterns } = readContainer(installed.asset_path);
|
|
18
|
+
if (!core || !patterns) return null;
|
|
19
|
+
return { core, patterns };
|
|
20
|
+
}
|
|
11
21
|
|
|
12
22
|
function cmdCluster(args) {
|
|
13
23
|
const { cmdClusterLint } = require('../cluster');
|
|
@@ -101,7 +111,7 @@ function cmdClusterInfo(target, _format = 'human') {
|
|
|
101
111
|
}
|
|
102
112
|
|
|
103
113
|
/**
|
|
104
|
-
* Load a cluster: resolve domains from installed
|
|
114
|
+
* Load a cluster: resolve domains from installed .kdna assets,
|
|
105
115
|
* classify input signals, compose context with attribution, detect
|
|
106
116
|
* conflicts, and emit the composed context.
|
|
107
117
|
*/
|
|
@@ -116,23 +126,7 @@ function cmdClusterLoad(target, args = []) {
|
|
|
116
126
|
const manifest = readJson(abs);
|
|
117
127
|
if (!manifest || !manifest.cluster_id) error('Not a valid cluster manifest');
|
|
118
128
|
|
|
119
|
-
const
|
|
120
|
-
process.env.HOME || process.env.USERPROFILE || '.',
|
|
121
|
-
'.kdna',
|
|
122
|
-
'domains',
|
|
123
|
-
);
|
|
124
|
-
|
|
125
|
-
// Domain loader: resolve from installed ~/.kdna/domains/
|
|
126
|
-
const domainLoader = (domainId) => {
|
|
127
|
-
const [scope, ident] = domainId.startsWith('@')
|
|
128
|
-
? [domainId.slice(0, domainId.indexOf('/')), domainId.slice(domainId.indexOf('/') + 1)]
|
|
129
|
-
: ['@aikdna', domainId];
|
|
130
|
-
const dir = path.join(INSTALL_DIR, scope, ident);
|
|
131
|
-
const core = readJson(path.join(dir, 'KDNA_Core.json'));
|
|
132
|
-
const pat = readJson(path.join(dir, 'KDNA_Patterns.json'));
|
|
133
|
-
if (!core || !pat) return null;
|
|
134
|
-
return { core, patterns: pat };
|
|
135
|
-
};
|
|
129
|
+
const domainLoader = loadInstalledDomain;
|
|
136
130
|
|
|
137
131
|
const result = loadCluster(abs, domainLoader);
|
|
138
132
|
if (result.errors.length) {
|
|
@@ -208,22 +202,7 @@ function cmdClusterMatch(target, args = []) {
|
|
|
208
202
|
const manifest = readJson(abs);
|
|
209
203
|
if (!manifest || !manifest.cluster_id) error('Not a valid cluster manifest');
|
|
210
204
|
|
|
211
|
-
const
|
|
212
|
-
process.env.HOME || process.env.USERPROFILE || '.',
|
|
213
|
-
'.kdna',
|
|
214
|
-
'domains',
|
|
215
|
-
);
|
|
216
|
-
|
|
217
|
-
const domainLoader = (domainId) => {
|
|
218
|
-
const [scope, ident] = domainId.startsWith('@')
|
|
219
|
-
? [domainId.slice(0, domainId.indexOf('/')), domainId.slice(domainId.indexOf('/') + 1)]
|
|
220
|
-
: ['@aikdna', domainId];
|
|
221
|
-
const dir = path.join(INSTALL_DIR, scope, ident);
|
|
222
|
-
const core = readJson(path.join(dir, 'KDNA_Core.json'));
|
|
223
|
-
const pat = readJson(path.join(dir, 'KDNA_Patterns.json'));
|
|
224
|
-
if (!core || !pat) return null;
|
|
225
|
-
return { core, patterns: pat };
|
|
226
|
-
};
|
|
205
|
+
const domainLoader = loadInstalledDomain;
|
|
227
206
|
|
|
228
207
|
const result = loadCluster(abs, domainLoader);
|
|
229
208
|
const classification = classifySignalsAcrossDomains(input, result.domains);
|
|
@@ -423,23 +402,12 @@ function cmdClusterGraph(target, args = []) {
|
|
|
423
402
|
* Shared domain loader for cluster commands.
|
|
424
403
|
*/
|
|
425
404
|
function loadClusterDomains(manifest) {
|
|
426
|
-
const INSTALL_DIR = path.join(
|
|
427
|
-
process.env.HOME || process.env.USERPROFILE || '.',
|
|
428
|
-
'.kdna',
|
|
429
|
-
'domains',
|
|
430
|
-
);
|
|
431
|
-
|
|
432
405
|
return (manifest.domains || []).map((d) => {
|
|
433
406
|
const domainId = d.id;
|
|
434
407
|
if (!domainId) return null;
|
|
435
|
-
const
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
const dir = path.join(INSTALL_DIR, scope, ident);
|
|
439
|
-
const core = readJson(path.join(dir, 'KDNA_Core.json'));
|
|
440
|
-
const pat = readJson(path.join(dir, 'KDNA_Patterns.json'));
|
|
441
|
-
if (!core || !pat) return null;
|
|
442
|
-
return { id: domainId, role: d.role, required: d.required !== false, core, patterns: pat };
|
|
408
|
+
const loaded = loadInstalledDomain(domainId);
|
|
409
|
+
if (!loaded) return null;
|
|
410
|
+
return { id: domainId, role: d.role, required: d.required !== false, ...loaded };
|
|
443
411
|
}).filter(Boolean);
|
|
444
412
|
}
|
|
445
413
|
|
package/src/cmds/doctor.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
const fs = require('fs');
|
|
2
2
|
const path = require('path');
|
|
3
|
-
const { EXIT
|
|
3
|
+
const { EXIT } = require('./_common');
|
|
4
4
|
const USER_KDNA_DIR = path.join(process.env.HOME || process.env.USERPROFILE || '.', '.kdna');
|
|
5
|
-
const
|
|
5
|
+
const PATHS = require('../paths');
|
|
6
|
+
const { listInstalled } = require('../package-store');
|
|
6
7
|
|
|
7
8
|
const AGENTS = [
|
|
8
9
|
{ name: 'OpenCode', dir: path.join(process.env.HOME || '', '.agents'), skillsDir: 'skills' },
|
|
@@ -17,11 +18,6 @@ const AGENTS = [
|
|
|
17
18
|
];
|
|
18
19
|
|
|
19
20
|
const V2_1_MARKER = 'kdna available';
|
|
20
|
-
|
|
21
|
-
function detectAgents() {
|
|
22
|
-
return AGENTS.filter((a) => fs.existsSync(a.dir));
|
|
23
|
-
}
|
|
24
|
-
|
|
25
21
|
function checkAgentSkill(agent) {
|
|
26
22
|
const skillPath = path.join(agent.dir, agent.skillsDir, 'kdna-loader', 'SKILL.md');
|
|
27
23
|
if (!fs.existsSync(skillPath)) return { installed: false, version: null, path: skillPath };
|
|
@@ -74,38 +70,25 @@ function cmdDoctor(args) {
|
|
|
74
70
|
checks.push({ name: 'KDNA data directory', status: 'warn', detail: '~/.kdna/ not found' });
|
|
75
71
|
}
|
|
76
72
|
|
|
77
|
-
// 4. ~/.kdna/
|
|
78
|
-
if (fs.existsSync(
|
|
79
|
-
const domains =
|
|
80
|
-
.readdirSync(INSTALL_DIR, { withFileTypes: true })
|
|
81
|
-
.filter((d) => d.isDirectory())
|
|
82
|
-
.reduce((acc, scopeDir) => {
|
|
83
|
-
if (scopeDir.name.startsWith('@')) {
|
|
84
|
-
try {
|
|
85
|
-
return acc + fs.readdirSync(path.join(INSTALL_DIR, scopeDir.name)).length;
|
|
86
|
-
} catch {
|
|
87
|
-
return acc;
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
return acc + 1;
|
|
91
|
-
}, 0);
|
|
73
|
+
// 4. ~/.kdna/packages/ exists and has .kdna assets
|
|
74
|
+
if (fs.existsSync(PATHS.packages)) {
|
|
75
|
+
const domains = listInstalled().length;
|
|
92
76
|
checks.push({
|
|
93
|
-
name: 'Installed
|
|
77
|
+
name: 'Installed assets',
|
|
94
78
|
status: domains > 0 ? 'ok' : 'warn',
|
|
95
|
-
detail: `${domains}
|
|
79
|
+
detail: `${domains} .kdna asset${domains !== 1 ? 's' : ''} installed`,
|
|
96
80
|
});
|
|
97
81
|
} else {
|
|
98
82
|
checks.push({
|
|
99
|
-
name: '
|
|
83
|
+
name: 'Package asset store',
|
|
100
84
|
status: 'warn',
|
|
101
|
-
detail: '~/.kdna/
|
|
85
|
+
detail: '~/.kdna/packages/ not found',
|
|
102
86
|
});
|
|
103
87
|
}
|
|
104
88
|
}
|
|
105
89
|
|
|
106
90
|
if (!domainsOnly) {
|
|
107
91
|
// 5. Agent integration check
|
|
108
|
-
const detected = detectAgents();
|
|
109
92
|
for (const agent of AGENTS) {
|
|
110
93
|
const agentDirExists = fs.existsSync(agent.dir);
|
|
111
94
|
const skill = agentDirExists
|