@aikdna/kdna-cli 0.26.3 → 0.26.5
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/package.json +2 -2
- package/src/cli.js +2 -2
- package/src/cmds/_common.js +15 -42
- package/src/cmds/demo.js +3 -0
- package/src/cmds/studio.js +17 -17
- package/src/init.js +5 -5
- package/src/publish.js +26 -23
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aikdna/kdna-cli",
|
|
3
|
-
"version": "0.26.
|
|
4
|
-
"description": "KDNA CLI — runtime control plane for
|
|
3
|
+
"version": "0.26.5",
|
|
4
|
+
"description": "KDNA CLI — runtime control plane for inspecting, validating, planning, packing, unpacking, and loading local .kdna assets.",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"bin": {
|
|
7
7
|
"kdna": "src/cli.js",
|
package/src/cli.js
CHANGED
|
@@ -873,10 +873,10 @@ switch (cmd) {
|
|
|
873
873
|
case 'studio': {
|
|
874
874
|
error(
|
|
875
875
|
'kdna studio has been removed from the runtime CLI.\n' +
|
|
876
|
-
'
|
|
876
|
+
'Studio project authoring belongs to the standalone Studio CLI:\n' +
|
|
877
877
|
' npm install -g @aikdna/kdna-studio-cli\n' +
|
|
878
878
|
' kdna-studio create <project>\n' +
|
|
879
|
-
' kdna-studio export <project> --out <file.kdna>
|
|
879
|
+
' kdna-studio export <project> --out <file.kdna>',
|
|
880
880
|
EXIT.INPUT_ERROR,
|
|
881
881
|
);
|
|
882
882
|
break;
|
package/src/cmds/_common.js
CHANGED
|
@@ -49,69 +49,42 @@ function warn(...args) {
|
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
function usage() {
|
|
52
|
-
console.log(`kdna — KDNA
|
|
52
|
+
console.log(`kdna — KDNA .kdna file tool
|
|
53
53
|
|
|
54
54
|
Usage:
|
|
55
55
|
|
|
56
|
-
---
|
|
56
|
+
--- Current Core v1 path ---
|
|
57
|
+
kdna inspect <file.kdna> Inspect a local .kdna asset
|
|
58
|
+
kdna validate <file.kdna> Validate a local .kdna asset
|
|
59
|
+
kdna plan-load <file.kdna> Produce the required LoadPlan
|
|
60
|
+
kdna load <file.kdna> [--as=prompt|json|raw] Load only when LoadPlan allows it
|
|
61
|
+
|
|
62
|
+
--- Dev source utilities (creator/debug path) ---
|
|
57
63
|
kdna init <name> Deprecated alias for kdna dev scaffold <name>
|
|
58
64
|
kdna dev scaffold <name> Scaffold a non-canonical dev source workspace
|
|
59
65
|
kdna dev validate <path> Validate a dev source directory
|
|
60
|
-
kdna dev pack <path> Build a dev-only
|
|
66
|
+
kdna dev pack <path> Build a dev-only diagnostic .kdna bundle
|
|
61
67
|
kdna dev unpack <path> Unpack .kdna into a dev source directory
|
|
62
68
|
kdna dev inspect <path> Inspect a dev source directory
|
|
63
69
|
kdna dev card <path> Display KDNA Card from a dev source directory
|
|
64
|
-
kdna inspect <file.kdna> Inspect a .kdna asset
|
|
65
|
-
kdna publish <file.kdna> Publish an existing Studio-compiled .kdna asset
|
|
66
|
-
kdna publish <file.kdna> --release-tag <tag> --repo <o/r> ...also upload to GitHub
|
|
67
|
-
kdna publish --check <path> Run dev source readiness checks only
|
|
68
70
|
kdna version bump <patch|minor|major> [path] Bump domain version
|
|
69
71
|
kdna cluster lint <path> Validate a cluster manifest
|
|
70
72
|
|
|
71
|
-
--- Domain consumers ---
|
|
72
|
-
kdna install <name> Install official domain: @aikdna/<name>
|
|
73
|
-
kdna install @scope/name Install any scoped domain
|
|
74
|
-
kdna install @aikdna/animation Install a cluster (installs all sub-domains)
|
|
75
|
-
kdna install ./file.kdna Install from a local .kdna file
|
|
76
|
-
kdna remove <name> Uninstall a domain
|
|
77
|
-
kdna update <name> Update an installed domain
|
|
78
|
-
kdna update --all Update all installed domains
|
|
79
|
-
kdna info <name> Show version, signature, governance, risks
|
|
80
|
-
kdna list List installed domains
|
|
81
|
-
kdna list --available List available domains from registry
|
|
82
|
-
kdna search <keyword> Search registry by name/keywords/insight
|
|
83
|
-
kdna registry refresh Refresh the canonical registry cache
|
|
84
|
-
|
|
85
|
-
--- Quality + judgment ---
|
|
86
|
-
kdna verify <name|file.kdna> Quality check: structure + trust + judgment
|
|
87
|
-
kdna compare <name|file.kdna> --input "<text>" With/without KDNA reasoning diff
|
|
88
|
-
kdna diff <name>@<v1> <name>@<v2> Judgment-level diff between versions
|
|
89
|
-
|
|
90
73
|
--- Agent-facing (called by the kdna-loader skill) ---
|
|
91
|
-
kdna available [--json]
|
|
92
|
-
kdna match "<task>" [--json]
|
|
93
|
-
kdna load <name|file.kdna> [--as=prompt|json|raw] Emit asset in agent-ready format
|
|
94
|
-
|
|
95
|
-
--- Identity ---
|
|
96
|
-
kdna identity init Generate Ed25519 identity key pair
|
|
97
|
-
kdna identity show Display public key and buyer ID
|
|
98
|
-
kdna identity export [--out] Backup private key (passphrase-encrypted)
|
|
99
|
-
kdna identity import <file> Restore identity from backup
|
|
74
|
+
kdna available [--json] List locally available assets
|
|
75
|
+
kdna match "<task>" [--json] Hint signals for local assets
|
|
100
76
|
|
|
101
77
|
--- Other ---
|
|
102
78
|
kdna setup One-command setup: CLI + skill + data root
|
|
103
79
|
kdna doctor [--agents] [--domains] [--json] System health check
|
|
104
|
-
kdna trace [--json] [--since 7d] [--export <file>] Agent judgment trace
|
|
105
|
-
kdna history [--stats] [--domain <name>] [--agent <name>] Recent usage
|
|
106
80
|
kdna version Show kdna CLI version
|
|
107
81
|
kdna help Show this help
|
|
82
|
+
kdna help legacy Show legacy / experimental commands
|
|
108
83
|
|
|
109
84
|
Examples:
|
|
110
|
-
kdna
|
|
111
|
-
kdna
|
|
112
|
-
kdna
|
|
113
|
-
kdna dev scaffold my_domain
|
|
114
|
-
kdna publish ./dist/my_domain.kdna --release-tag v0.1.0 --repo yourname/kdna-my_domain`);
|
|
85
|
+
kdna validate example.kdna
|
|
86
|
+
kdna plan-load example.kdna
|
|
87
|
+
kdna load example.kdna --profile=compact --as=prompt`);
|
|
115
88
|
}
|
|
116
89
|
|
|
117
90
|
// Exit codes — semantic exit codes for all KDNA CLI commands
|
package/src/cmds/demo.js
CHANGED
|
@@ -52,6 +52,9 @@ function cmdDemo(args) {
|
|
|
52
52
|
process.stdout.write(` kdna inspect ${dest}\n`);
|
|
53
53
|
process.stdout.write(` kdna validate ${dest}\n`);
|
|
54
54
|
process.stdout.write(` kdna pack ${dest} ${dest}.kdna\n`);
|
|
55
|
+
process.stdout.write(` kdna validate ${dest}.kdna\n`);
|
|
56
|
+
process.stdout.write(` kdna plan-load ${dest}.kdna\n`);
|
|
57
|
+
process.stdout.write(` kdna load ${dest}.kdna --profile=compact --as=prompt\n`);
|
|
55
58
|
}
|
|
56
59
|
|
|
57
60
|
module.exports = { cmdDemo };
|
package/src/cmds/studio.js
CHANGED
|
@@ -366,13 +366,13 @@ function cmdLockVerify(projectPath, args = []) {
|
|
|
366
366
|
}
|
|
367
367
|
}
|
|
368
368
|
} else {
|
|
369
|
-
|
|
370
|
-
|
|
369
|
+
unlocked.push(label);
|
|
370
|
+
blocking.push(`${label} requires Studio review approval`);
|
|
371
371
|
}
|
|
372
372
|
}
|
|
373
373
|
}
|
|
374
374
|
|
|
375
|
-
const
|
|
375
|
+
const exportReady = blocking.length === 0 && locked.length > 0;
|
|
376
376
|
|
|
377
377
|
if (jsonMode) {
|
|
378
378
|
console.log(
|
|
@@ -381,7 +381,7 @@ function cmdLockVerify(projectPath, args = []) {
|
|
|
381
381
|
project: path.basename(abs),
|
|
382
382
|
locked_cards: locked.length,
|
|
383
383
|
unlocked_cards: unlocked.length,
|
|
384
|
-
|
|
384
|
+
export_ready: exportReady,
|
|
385
385
|
blocking,
|
|
386
386
|
locked: locked.sort(),
|
|
387
387
|
unlocked: unlocked.sort(),
|
|
@@ -390,14 +390,14 @@ function cmdLockVerify(projectPath, args = []) {
|
|
|
390
390
|
2,
|
|
391
391
|
),
|
|
392
392
|
);
|
|
393
|
-
process.exit(
|
|
393
|
+
process.exit(exportReady ? EXIT.OK : EXIT.HUMAN_LOCK_REQUIRED);
|
|
394
394
|
}
|
|
395
395
|
|
|
396
|
-
console.log(`
|
|
396
|
+
console.log(`Studio review status for: ${path.basename(abs)}`);
|
|
397
397
|
console.log('');
|
|
398
|
-
console.log(`
|
|
399
|
-
console.log(`
|
|
400
|
-
console.log(`
|
|
398
|
+
console.log(` Approved: ${locked.length}`);
|
|
399
|
+
console.log(` Pending: ${unlocked.length}`);
|
|
400
|
+
console.log(` Export ready: ${exportReady ? '✓ yes' : '✗ no'}`);
|
|
401
401
|
console.log('');
|
|
402
402
|
|
|
403
403
|
if (blocking.length) {
|
|
@@ -407,11 +407,11 @@ function cmdLockVerify(projectPath, args = []) {
|
|
|
407
407
|
}
|
|
408
408
|
|
|
409
409
|
if (locked.length) {
|
|
410
|
-
console.log('
|
|
410
|
+
console.log('Approved cards:');
|
|
411
411
|
locked.forEach((l) => console.log(` ✓ ${l}`));
|
|
412
412
|
}
|
|
413
413
|
|
|
414
|
-
process.exit(
|
|
414
|
+
process.exit(exportReady ? EXIT.OK : EXIT.HUMAN_LOCK_REQUIRED);
|
|
415
415
|
}
|
|
416
416
|
|
|
417
417
|
// ─── Studio Compile ───────────────────────────────────────────────────
|
|
@@ -577,20 +577,20 @@ function cmdStudioReadiness(projectPath, args = []) {
|
|
|
577
577
|
self_checks: loadCardStats(project, path.dirname(abs), 'self_checks'),
|
|
578
578
|
test_cases: 0,
|
|
579
579
|
human_pass: '0/0',
|
|
580
|
-
|
|
580
|
+
export_ready: false,
|
|
581
581
|
};
|
|
582
582
|
|
|
583
|
-
// Determine
|
|
583
|
+
// Determine Studio export readiness.
|
|
584
584
|
const allTypes = Object.values(readiness).filter(
|
|
585
585
|
(v) => v && typeof v === 'object' && 'total' in v,
|
|
586
586
|
);
|
|
587
587
|
let allLocked = allTypes.every((t) => t.total > 0 && t.total === t.locked);
|
|
588
588
|
if (allTypes.length === 0) allLocked = false;
|
|
589
|
-
readiness.
|
|
589
|
+
readiness.export_ready = allLocked;
|
|
590
590
|
|
|
591
591
|
if (jsonMode) {
|
|
592
592
|
console.log(JSON.stringify(readiness, null, 2));
|
|
593
|
-
process.exit(readiness.
|
|
593
|
+
process.exit(readiness.export_ready ? EXIT.OK : EXIT.HUMAN_LOCK_REQUIRED);
|
|
594
594
|
}
|
|
595
595
|
|
|
596
596
|
console.log(`Domain Readiness: ${project.name}`);
|
|
@@ -605,8 +605,8 @@ function cmdStudioReadiness(projectPath, args = []) {
|
|
|
605
605
|
}
|
|
606
606
|
|
|
607
607
|
console.log('');
|
|
608
|
-
console.log(`
|
|
609
|
-
process.exit(readiness.
|
|
608
|
+
console.log(` Export ready: ${readiness.export_ready ? '✓ yes' : '✗ no'}`);
|
|
609
|
+
process.exit(readiness.export_ready ? EXIT.OK : EXIT.HUMAN_LOCK_REQUIRED);
|
|
610
610
|
}
|
|
611
611
|
|
|
612
612
|
function loadCardStats(project, projectDir, cardType) {
|
package/src/init.js
CHANGED
|
@@ -64,11 +64,11 @@ function cmdInit(name, options = {}) {
|
|
|
64
64
|
}
|
|
65
65
|
console.log(`✓ Created non-canonical KDNA dev source workspace: ${targetDir}/`);
|
|
66
66
|
console.log(` Files: KDNA_Core.json, KDNA_Patterns.json, kdna.json, tests/before-after.json`);
|
|
67
|
-
console.log(' This workspace is not a
|
|
68
|
-
console.log(' To create a
|
|
67
|
+
console.log(' This workspace is an authoring/editing view, not a public KDNA asset.');
|
|
68
|
+
console.log(' To create a runtime .kdna file, export through KDNA Studio or kdna dev pack.');
|
|
69
69
|
|
|
70
70
|
// Run structural validation (lint + schema only). Content quality checks
|
|
71
|
-
// are for
|
|
71
|
+
// are for release-evidence time, not scaffold time — the template contains placeholders
|
|
72
72
|
// marked [TODO] that the author is expected to replace.
|
|
73
73
|
try {
|
|
74
74
|
const { execSync } = require('child_process');
|
|
@@ -100,8 +100,8 @@ function cmdInit(name, options = {}) {
|
|
|
100
100
|
);
|
|
101
101
|
console.log(` 3. Edit ${targetDir}/kdna.json — set author, description, repo`);
|
|
102
102
|
console.log(` 4. Run: kdna dev validate ${name} (structural check)`);
|
|
103
|
-
console.log(` 5. Run: kdna
|
|
104
|
-
console.log(` 6.
|
|
103
|
+
console.log(` 5. Run: kdna dev pack ${name} --out dist/${name}.kdna`);
|
|
104
|
+
console.log(` 6. Run: kdna validate dist/${name}.kdna && kdna plan-load dist/${name}.kdna`);
|
|
105
105
|
}
|
|
106
106
|
|
|
107
107
|
/**
|
package/src/publish.js
CHANGED
|
@@ -175,17 +175,17 @@ function checkHumanLock(domainPath) {
|
|
|
175
175
|
if (cards.length === 0) return { passed: true, issues: [] };
|
|
176
176
|
|
|
177
177
|
for (const card of cards) {
|
|
178
|
-
// Rule 1:
|
|
178
|
+
// Rule 1: Legacy publish evidence requires Studio approval.
|
|
179
179
|
if (!card.status || !['locked', 'tested', 'published'].includes(card.status)) {
|
|
180
|
-
issues.push(`${card.type} "${card.id}" is not
|
|
180
|
+
issues.push(`${card.type} "${card.id}" is not approved for legacy publish evidence.`);
|
|
181
181
|
continue;
|
|
182
182
|
}
|
|
183
|
-
// Rule 2:
|
|
183
|
+
// Rule 2: Legacy publish evidence requires a human_lock record.
|
|
184
184
|
if (!card.human_lock || !card.human_lock.by || !card.human_lock.statement) {
|
|
185
185
|
issues.push(`${card.type} "${card.id}" is locked but has no valid Human Lock record.`);
|
|
186
186
|
continue;
|
|
187
187
|
}
|
|
188
|
-
// Rule 3: Lock must confirm judgment fields were reviewed
|
|
188
|
+
// Rule 3: Legacy Human Lock evidence must confirm judgment fields were reviewed.
|
|
189
189
|
const checked = card.human_lock.checked || {};
|
|
190
190
|
if (!checked.applies_when) {
|
|
191
191
|
issues.push(
|
|
@@ -218,32 +218,35 @@ function cmdPublishCheck(domainPath, args = []) {
|
|
|
218
218
|
console.log('═'.repeat(60));
|
|
219
219
|
console.log('');
|
|
220
220
|
|
|
221
|
-
// ─── Human Lock
|
|
221
|
+
// ─── Legacy Human Lock evidence gate ──────────────────────────────
|
|
222
222
|
const hl = checkHumanLock(abs);
|
|
223
223
|
if (!hl.passed) {
|
|
224
224
|
if (args.includes('--force')) {
|
|
225
|
-
console.warn(' ⚠
|
|
226
|
-
console.warn(` ${hl.issues.length} unresolved
|
|
225
|
+
console.warn(' ⚠ Legacy publish evidence gate: OVERRIDDEN (--force). Proceeding with checks.');
|
|
226
|
+
console.warn(` ${hl.issues.length} unresolved publish-evidence issue(s):`);
|
|
227
227
|
for (const issue of hl.issues) {
|
|
228
228
|
console.warn(` ${issue}`);
|
|
229
229
|
}
|
|
230
230
|
console.warn('');
|
|
231
231
|
} else {
|
|
232
|
-
console.error('
|
|
232
|
+
console.error(' Legacy publish evidence gate: BLOCKED');
|
|
233
233
|
console.error(` ${hl.issues.length} issue(s) found:`);
|
|
234
234
|
for (const issue of hl.issues) {
|
|
235
235
|
console.error(` ✗ ${issue}`);
|
|
236
236
|
}
|
|
237
237
|
console.error('');
|
|
238
|
-
console.error('
|
|
239
|
-
console.error('
|
|
240
|
-
console.error('
|
|
238
|
+
console.error(' This legacy publish check expects reviewed judgment-class cards');
|
|
239
|
+
console.error(' with Human Lock records as release evidence. This is not a');
|
|
240
|
+
console.error(' KDNA Core v1 format-validity requirement.');
|
|
241
|
+
console.error(' For current public consumption, export a .kdna file and run:');
|
|
242
|
+
console.error(' kdna validate <file.kdna>');
|
|
243
|
+
console.error(' kdna plan-load <file.kdna>');
|
|
241
244
|
console.error(' Use --force for emergency override (audited).');
|
|
242
245
|
console.error('');
|
|
243
246
|
process.exit(EXIT.HUMAN_LOCK_REQUIRED);
|
|
244
247
|
}
|
|
245
248
|
} else {
|
|
246
|
-
console.log(' ✓
|
|
249
|
+
console.log(' ✓ Legacy publish evidence gate: passed');
|
|
247
250
|
console.log('');
|
|
248
251
|
}
|
|
249
252
|
|
|
@@ -607,15 +610,15 @@ function publicKeyToScopeFormat(publicKeyPem) {
|
|
|
607
610
|
* kdna publish <file.kdna> — Publish an existing Studio-compiled asset.
|
|
608
611
|
*
|
|
609
612
|
* Publishing no longer packs arbitrary source directories. Source directories
|
|
610
|
-
* are non-canonical dev workspaces;
|
|
611
|
-
* compile/export pipelines.
|
|
613
|
+
* are non-canonical dev workspaces; release-evidence assets come from
|
|
614
|
+
* Studio-compatible compile/export pipelines.
|
|
612
615
|
*/
|
|
613
616
|
function cmdPublish(assetPath, args = []) {
|
|
614
617
|
const abs = path.resolve(assetPath);
|
|
615
618
|
if (!fs.existsSync(abs)) error(`Path not found: ${abs}`, EXIT.INPUT_ERROR);
|
|
616
619
|
if (fs.statSync(abs).isDirectory()) {
|
|
617
620
|
error(
|
|
618
|
-
'kdna publish only accepts existing .kdna assets. Source directories are non-canonical; use KDNA Studio compile/export, then run kdna publish <file.kdna
|
|
621
|
+
'kdna publish only accepts existing .kdna assets. Source directories are non-canonical; use KDNA Studio compile/export, then run kdna publish <file.kdna> for legacy publish compatibility.',
|
|
619
622
|
EXIT.INPUT_ERROR,
|
|
620
623
|
);
|
|
621
624
|
}
|
|
@@ -728,28 +731,28 @@ function validateAuthoringProvenance(manifest) {
|
|
|
728
731
|
);
|
|
729
732
|
}
|
|
730
733
|
if (!conformance || !conformance.spec_version) {
|
|
731
|
-
issues.push('
|
|
734
|
+
issues.push('release-evidence assets require authoring.conformance.spec_version');
|
|
732
735
|
}
|
|
733
736
|
}
|
|
734
|
-
if (highTrust && !authoring.compiler) issues.push('
|
|
737
|
+
if (highTrust && !authoring.compiler) issues.push('release-evidence assets require authoring.compiler');
|
|
735
738
|
if (highTrust && !authoring.compiler_version) {
|
|
736
|
-
issues.push('
|
|
739
|
+
issues.push('release-evidence assets require authoring.compiler_version');
|
|
737
740
|
}
|
|
738
741
|
if (highTrust && !authoring.compiled_at)
|
|
739
|
-
issues.push('
|
|
742
|
+
issues.push('release-evidence assets require authoring.compiled_at');
|
|
740
743
|
for (const field of ['asset_uid', 'project_uid', 'build_id', 'domain_id', 'content_digest']) {
|
|
741
744
|
if (highTrust && !authoring[field] && !manifest[field]) {
|
|
742
|
-
issues.push(`
|
|
745
|
+
issues.push(`release-evidence assets require ${field} in authoring provenance or manifest`);
|
|
743
746
|
}
|
|
744
747
|
}
|
|
745
748
|
if (highTrust && authoring.human_confirmed !== true) {
|
|
746
|
-
issues.push('
|
|
749
|
+
issues.push('release-evidence assets require authoring.human_confirmed = true');
|
|
747
750
|
}
|
|
748
751
|
if (highTrust && !Number.isInteger(authoring.human_lock_count)) {
|
|
749
|
-
issues.push('
|
|
752
|
+
issues.push('release-evidence assets require authoring.human_lock_count');
|
|
750
753
|
}
|
|
751
754
|
if (highTrust && Number.isInteger(authoring.human_lock_count) && authoring.human_lock_count < 1) {
|
|
752
|
-
issues.push('
|
|
755
|
+
issues.push('release-evidence assets require at least one Human Lock when that claim is made');
|
|
753
756
|
}
|
|
754
757
|
return issues;
|
|
755
758
|
}
|