@aikdna/kdna-cli 0.15.0 → 0.16.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 CHANGED
@@ -4,24 +4,24 @@
4
4
 
5
5
  KDNA CLI 是 AI Agent 加载、验证、组合、测试和治理领域判断的运行控制平面。
6
6
 
7
- CLI 不是 Studio,不是 Chat,不是 Governance Console。它是这些产品共同依赖的底层协议接口。
8
-
9
7
  Part of the [KDNA](https://github.com/knowledge-dna/KDNA) ecosystem.
10
8
 
11
9
  ## Install
12
10
 
13
11
  ```bash
14
12
  npm install -g @aikdna/kdna-cli
13
+ kdna setup
15
14
  ```
16
15
 
17
- ## Quick Start
16
+ ## Quick Start (5 minutes)
18
17
 
19
18
  ```bash
20
- kdna install @aikdna/writing # Install a domain
21
- kdna verify @aikdna/writing # 3-layer verification
22
- kdna available # List installed domains
23
- kdna match "improve this post" # Find relevant domains
24
- kdna load @aikdna/writing # Load for agent consumption
19
+ npm install -g @aikdna/kdna-cli
20
+ kdna setup
21
+ kdna install @aikdna/writing
22
+ kdna verify @aikdna/writing --judgment
23
+ kdna compare @aikdna/writing --input "help me improve this post"
24
+ kdna doctor --agents
25
25
  ```
26
26
 
27
27
  ## Commands by Role
@@ -34,7 +34,8 @@ kdna load @aikdna/writing # Load for agent consumption
34
34
  | `kdna validate <path>` | Validate domain structure |
35
35
  | `kdna validate --schema <path>` | Schema-only validation |
36
36
  | `kdna pack <path>` | Pack into .kdna container |
37
- | `kdna unpack <file>` | Unpack .kdna container |
37
+ | `kdna pack <path> --encrypt --license <file>` | Pack encrypted .kdnae container |
38
+ | `kdna unpack <file>` | Unpack .kdna or .kdnae container |
38
39
  | `kdna inspect <path>` | Inspect domain or .kdna file |
39
40
  | `kdna publish <path>` | Pack + sign + publish to registry |
40
41
  | `kdna publish --check <path>` | Quality gate check only |
@@ -47,15 +48,42 @@ kdna load @aikdna/writing # Load for agent consumption
47
48
  | `kdna available [--json]` | List installed domains with v2.1 fields |
48
49
  | `kdna match "<task>" [--json]` | Signal matching — find relevant domains |
49
50
  | `kdna load <name> [--as=prompt\|json\|raw]` | Emit domain in agent-ready format |
51
+ | `kdna postvalidate <name> --output <file>` | Post-generation judgment check |
50
52
 
51
53
  ### Testing & Verification
52
54
 
53
55
  | Command | Description |
54
56
  |---------|-------------|
55
- | `kdna verify <name>` | 3-layer verification: structure + trust + judgment |
57
+ | `kdna verify <name>` | 3-layer: structure + trust + judgment |
56
58
  | `kdna compare <name> --input "..."` | With/without KDNA reasoning diff |
59
+ | `kdna compare <name> --input "..." --report-md` | Markdown report with scoring |
60
+ | `kdna compare <name> --input "..." --report-json` | JSON report with scoring |
57
61
  | `kdna diff <name>@<v1> <name>@<v2>` | Judgment-level diff between versions |
58
- | `kdna doctor` | Check runtime environment health |
62
+
63
+ ### Diagnostics & Trace
64
+
65
+ | Command | Description |
66
+ |---------|-------------|
67
+ | `kdna doctor` | System health check |
68
+ | `kdna doctor --agents` | Agent integration check (Codex/Claude/OpenCode/Cursor/Gemini) |
69
+ | `kdna doctor --json` | Machine-readable health report |
70
+ | `kdna trace` | View recent load/postvalidate traces |
71
+ | `kdna trace --json` | Machine-readable trace output |
72
+ | `kdna trace --export <file>` | Export traces for audit |
73
+ | `kdna trace --since 7d\|30d\|90d` | Filter by time range |
74
+ | `kdna history` | Recent domain usage (last 20) |
75
+ | `kdna history --stats` | Aggregate by domain and agent |
76
+ | `kdna history --domain <name>` | Filter by domain |
77
+
78
+ ### License & Authorization
79
+
80
+ | Command | Description |
81
+ |---------|-------------|
82
+ | `kdna license generate <domain> --to <email>` | Generate signed license |
83
+ | `kdna license install <license.json>` | Register license for auto-decrypt |
84
+ | `kdna license verify <license.json>` | Verify license signature and validity |
85
+ | `kdna license bind <license.json>` | Bind license to this machine |
86
+ | `kdna license show <license.json>` | Display license details |
59
87
 
60
88
  ### Cluster Composition
61
89
 
@@ -68,6 +96,8 @@ kdna load @aikdna/writing # Load for agent consumption
68
96
  | Command | Description |
69
97
  |---------|-------------|
70
98
  | `kdna install <name>` | Install domain from registry |
99
+ | `kdna install ./file.kdna` | Install from local .kdna file |
100
+ | `kdna install ./file.kdnae` | Install from encrypted .kdnae (auto-decrypt with license) |
71
101
  | `kdna remove <name>` | Uninstall a domain |
72
102
  | `kdna update <name>` | Update installed domain |
73
103
  | `kdna info <name>` | Show domain metadata and trust status |
@@ -90,6 +120,14 @@ kdna load @aikdna/writing # Load for agent consumption
90
120
  |---------|-------------|
91
121
  | `kdna setup` | One-command setup: CLI + skill + data root |
92
122
 
123
+ ### Environment Variables
124
+
125
+ | Variable | Purpose |
126
+ |----------|---------|
127
+ | `KDNA_AGENT` | Override agent name in trace logs (e.g. `claude_code`, `codex`, `opencode`) |
128
+ | `KDNA_REGISTRY_URL` | Override canonical registry URL |
129
+ | `KDNA_IDENTITY_DIR` | Override identity key directory |
130
+
93
131
  ## Exit Codes
94
132
 
95
133
  | Code | Name | Meaning |
@@ -111,10 +149,10 @@ Machine-consumable commands support `--json` for structured output:
111
149
  ```bash
112
150
  kdna verify @aikdna/writing --json
113
151
  kdna available --json
114
- kdna match "help me write" --json
115
- kdna search writing --json
116
- kdna info @aikdna/writing --json
117
- kdna doctor --json
152
+ kdna doctor --agents --json
153
+ kdna trace --json
154
+ kdna history --json
155
+ kdna license verify --json <file>
118
156
  ```
119
157
 
120
158
  ## Product Matrix
@@ -123,14 +161,12 @@ kdna doctor --json
123
161
  |-------|---------|---------------|
124
162
  | Protocol | KDNA SPEC | Define judgment asset format |
125
163
  | Core Library | @aikdna/kdna-core | load / validate / compose / render |
126
- | Runtime | @aikdna/kdna-cli | Agent runtime + compile + verify + test + publish |
164
+ | Runtime | @aikdna/kdna-cli | Agent runtime + compile + verify + test + publish + license |
127
165
  | Authoring | KDNA Studio | Human-led judgment production |
128
166
  | Consumption | KDNAChat | Load, use, compare |
129
167
  | Governance | KDNA Governance Console | Approve, release, audit |
130
168
  | Distribution | Registry | Discover, install, trade |
131
169
 
132
- CLI 不应该成为一个"命令行 Studio",而是所有 KDNA 产品共同依赖的协议控制平面。
133
-
134
170
  ## Development
135
171
 
136
172
  ```bash
@@ -144,6 +180,7 @@ npm test
144
180
 
145
181
  - [@aikdna/kdna-core](https://github.com/knowledge-dna/KDNA/tree/main/packages/kdna-core) — Pure logic library
146
182
  - [KDNA Registry](https://github.com/knowledge-dna/kdna-registry) — Domain catalog
183
+ - [KDNA SPEC](https://github.com/knowledge-dna/KDNA) — Protocol specification
147
184
  - [aikdna.com](https://aikdna.com) — Website
148
185
 
149
186
  ## License
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aikdna/kdna-cli",
3
- "version": "0.15.0",
3
+ "version": "0.16.1",
4
4
  "description": "KDNA CLI — create, validate, install, and manage domain cognition packages for AI agents.",
5
5
  "type": "commonjs",
6
6
  "bin": {
@@ -21,7 +21,9 @@
21
21
  "lint": "eslint src/ validators/ tests/",
22
22
  "format": "prettier --write .",
23
23
  "format:check": "prettier --check .",
24
- "test": "node --test tests/v07-commands.test.js tests/validator.test.js",
24
+ "test": "node --test tests/v07-commands.test.js tests/v012-commands.test.js",
25
+ "test:integration": "node --test tests/integration.test.js",
26
+ "test:all": "node --test tests/*.test.js",
25
27
  "pretest": "npm install --ignore-scripts"
26
28
  },
27
29
  "keywords": [
package/src/agent.js CHANGED
@@ -34,6 +34,10 @@ const path = require('path');
34
34
  const { parseName } = require('./registry');
35
35
  const { recordTrace } = require('./cmds/trace');
36
36
 
37
+ function detectAgent() {
38
+ return process.env.KDNA_AGENT || 'cli';
39
+ }
40
+
37
41
  const USER_KDNA_DIR = path.join(process.env.HOME || process.env.USERPROFILE || '.', '.kdna');
38
42
  const INSTALL_DIR = path.join(USER_KDNA_DIR, 'domains');
39
43
 
@@ -367,7 +371,7 @@ function cmdLoad(input, args = []) {
367
371
  // JSON format
368
372
  if (format === 'json') {
369
373
  process.stdout.write(JSON.stringify({ manifest, core, patterns: pat }, null, 2) + '\n');
370
- recordTrace({ timestamp: new Date().toISOString(), agent: 'cli', domain: parsed.full, format: 'json' });
374
+ recordTrace({ timestamp: new Date().toISOString(), agent: detectAgent(), domain: parsed.full, format: 'json' });
371
375
  return;
372
376
  }
373
377
 
@@ -380,20 +384,20 @@ function cmdLoad(input, args = []) {
380
384
  process.stdout.write(fs.readFileSync(p, 'utf8'));
381
385
  }
382
386
  }
383
- recordTrace({ timestamp: new Date().toISOString(), agent: 'cli', domain: parsed.full, format: 'raw' });
387
+ recordTrace({ timestamp: new Date().toISOString(), agent: detectAgent(), domain: parsed.full, format: 'raw' });
384
388
  return;
385
389
  }
386
390
 
387
391
  // Load profiles
388
392
  if (profile) {
389
393
  emitProfile(parsed, manifest, core, pat, profile, profileInput);
390
- recordTrace({ timestamp: new Date().toISOString(), agent: 'cli', domain: parsed.full, format: `profile:${profile}` });
394
+ recordTrace({ timestamp: new Date().toISOString(), agent: detectAgent(), domain: parsed.full, format: `profile:${profile}` });
391
395
  return;
392
396
  }
393
397
 
394
398
  // Default: --as=prompt — compact text optimized for system-prompt injection.
395
399
  emitCompact(parsed, manifest, core, pat);
396
- recordTrace({ timestamp: new Date().toISOString(), agent: 'cli', domain: parsed.full, format: 'prompt' });
400
+ recordTrace({ timestamp: new Date().toISOString(), agent: detectAgent(), domain: parsed.full, format: 'prompt' });
397
401
  }
398
402
 
399
403
  // ─── Load profiles ─────────────────────────────────────────────────────
@@ -821,7 +825,7 @@ function cmdPostvalidate(args = []) {
821
825
  console.log(JSON.stringify(result, null, 2));
822
826
  recordTrace({
823
827
  timestamp: new Date().toISOString(),
824
- agent: 'cli',
828
+ agent: detectAgent(),
825
829
  domain: parsed.full,
826
830
  type: 'postvalidate',
827
831
  postvalidate: { result: results.violations.length ? 'fail' : 'pass', violations: results.violations.length, passed: results.passed.length },
@@ -851,7 +855,7 @@ function cmdPostvalidate(args = []) {
851
855
 
852
856
  recordTrace({
853
857
  timestamp: new Date().toISOString(),
854
- agent: 'cli',
858
+ agent: detectAgent(),
855
859
  domain: parsed.full,
856
860
  type: 'postvalidate',
857
861
  postvalidate: { result: results.violations.length ? 'fail' : 'pass', violations: results.violations.length, passed: results.passed.length },
@@ -81,7 +81,9 @@ function cmdLicenseGenerate(args) {
81
81
  }
82
82
 
83
83
  function cmdLicenseVerify(args) {
84
- const licensePath = args[0];
84
+ const jsonMode = args.includes('--json');
85
+ const filtered = args.filter(a => !a.startsWith('--'));
86
+ const licensePath = filtered[0];
85
87
  if (!licensePath) error('Usage: kdna license verify <license.json>', EXIT.INPUT_ERROR);
86
88
 
87
89
  let license;
@@ -96,8 +98,6 @@ function cmdLicenseVerify(args) {
96
98
  const fp = machineFingerprint();
97
99
  const result = verifyLicense(license, publicKey, fp);
98
100
 
99
- const jsonMode = args.includes('--json');
100
-
101
101
  if (jsonMode) {
102
102
  console.log(JSON.stringify({
103
103
  domain: license.domain,
@@ -135,7 +135,8 @@ function cmdLicenseVerify(args) {
135
135
  }
136
136
 
137
137
  function cmdLicenseBind(args) {
138
- const licensePath = args[0];
138
+ const filtered = args.filter(a => !a.startsWith('--'));
139
+ const licensePath = filtered[0];
139
140
  if (!licensePath) error('Usage: kdna license bind <license.json>', EXIT.INPUT_ERROR);
140
141
 
141
142
  let license;
@@ -165,7 +166,8 @@ function cmdLicenseBind(args) {
165
166
  }
166
167
 
167
168
  function cmdLicenseShow(args) {
168
- const licensePath = args[0];
169
+ const filtered = args.filter(a => !a.startsWith('--'));
170
+ const licensePath = filtered[0];
169
171
  if (!licensePath) {
170
172
  const local = path.join(process.cwd(), 'license.json');
171
173
  if (fs.existsSync(local)) return cmdLicenseVerify([local, ...args.slice(1)]);