@aikdna/kdna-cli 0.20.0 → 0.20.2

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aikdna/kdna-cli",
3
- "version": "0.20.0",
3
+ "version": "0.20.2",
4
4
  "description": "KDNA CLI — runtime control plane for verifying, installing, loading, comparing, publishing, and auditing existing .kdna assets.",
5
5
  "type": "commonjs",
6
6
  "bin": {
@@ -52,7 +52,8 @@
52
52
  },
53
53
  "optionalDependencies": {
54
54
  "ajv": "^8.17.1",
55
- "ajv-formats": "^3.0.1"
55
+ "ajv-formats": "^3.0.1",
56
+ "cbor-x": "^1.6.4"
56
57
  },
57
58
  "devDependencies": {
58
59
  "@eslint/js": "^9.39.0",
@@ -307,6 +307,7 @@ function buildZip(entries) {
307
307
  }
308
308
 
309
309
  module.exports = {
310
+ buildZip,
310
311
  cmdProtect,
311
312
  cmdUnlock,
312
313
  cmdRecover,
@@ -85,6 +85,39 @@ function readContainerJson(kdnaPath, fileName, options = {}) {
85
85
  return assetReader.readJsonSync(asset, fileName, options);
86
86
  }
87
87
 
88
+ function readContainerDataMap(kdnaPath, options = {}) {
89
+ const asset = assetReader.openSync(kdnaPath);
90
+ if (asset.entries.has('payload.kdnab')) {
91
+ const dataMap = assetReader.readDataMapSync(asset, undefined, options);
92
+ // readDataMapSync only returns judgment files — add kdna.json explicitly
93
+ if (asset.entries.has('kdna.json')) {
94
+ dataMap['kdna.json'] = assetReader.readJsonSync(asset, 'kdna.json', options);
95
+ }
96
+ return dataMap;
97
+ }
98
+ // v1 fallback: read individual JSON files
99
+ const dataMap = {};
100
+ const v1Files = [
101
+ 'kdna.json',
102
+ 'KDNA_Core.json',
103
+ 'KDNA_Patterns.json',
104
+ 'KDNA_Scenarios.json',
105
+ 'KDNA_Cases.json',
106
+ 'KDNA_Reasoning.json',
107
+ 'KDNA_Evolution.json',
108
+ ];
109
+ for (const f of v1Files) {
110
+ if (asset.entries.has(f)) {
111
+ try {
112
+ dataMap[f] = assetReader.readJsonSync(asset, f, options);
113
+ } catch {
114
+ /* skip */
115
+ }
116
+ }
117
+ }
118
+ return dataMap;
119
+ }
120
+
88
121
  function readContainerEntry(kdnaPath, fileName) {
89
122
  const asset = assetReader.openSync(kdnaPath);
90
123
  return assetReader.readEntrySync(asset, fileName);
@@ -241,6 +274,7 @@ module.exports = {
241
274
  assetDigest,
242
275
  contentDigest,
243
276
  readContainer,
277
+ readContainerDataMap,
244
278
  readContainerEntry,
245
279
  readContainerJson,
246
280
  readAssetManifest,
package/src/verify.js CHANGED
@@ -26,6 +26,7 @@ const {
26
26
  listContainerEntries,
27
27
  readContainerEntry,
28
28
  readContainerJson,
29
+ readContainerDataMap,
29
30
  resolveAsset,
30
31
  verifyAsset,
31
32
  } = require('./package-store');
@@ -108,6 +109,61 @@ function directoryView(root) {
108
109
 
109
110
  function assetView(kdnaPath, options = {}) {
110
111
  const entries = new Set(listContainerEntries(kdnaPath));
112
+
113
+ // v2 container: synthesize view from CBOR payload
114
+ if (entries.has('payload.kdnab')) {
115
+ let dataMap = null;
116
+ const _ensureDataMap = () => {
117
+ if (!dataMap) dataMap = readContainerDataMap(kdnaPath, options);
118
+ return dataMap;
119
+ };
120
+
121
+ const v2Entries = new Set(entries);
122
+ v2Entries.add('KDNA_Core.json');
123
+ v2Entries.add('KDNA_Patterns.json');
124
+ if (dataMap) {
125
+ for (const k of [
126
+ 'KDNA_Scenarios.json',
127
+ 'KDNA_Cases.json',
128
+ 'KDNA_Reasoning.json',
129
+ 'KDNA_Evolution.json',
130
+ ]) {
131
+ if (dataMap[k]) v2Entries.add(k);
132
+ }
133
+ }
134
+
135
+ return {
136
+ kind: 'asset',
137
+ path: kdnaPath,
138
+ exists(name) {
139
+ if (v2Entries.has(name)) return true;
140
+ return entries.has(name);
141
+ },
142
+ readJson(name) {
143
+ if (entries.has(name)) return readContainerJson(kdnaPath, name, options);
144
+ const dm = _ensureDataMap();
145
+ return dm[name] || null;
146
+ },
147
+ readText(name) {
148
+ if (entries.has(name)) return readContainerEntry(kdnaPath, name).toString('utf8');
149
+ const dm = _ensureDataMap();
150
+ return dm[name] ? JSON.stringify(dm[name]) : '';
151
+ },
152
+ listDirFiles(dirName) {
153
+ const prefix = `${dirName.replace(/\/+$/, '')}/`;
154
+ const files = [];
155
+ for (const e of entries) {
156
+ if (e.startsWith(prefix)) {
157
+ const rest = e.slice(prefix.length);
158
+ if (rest && !rest.includes('/')) files.push(rest);
159
+ }
160
+ }
161
+ return files;
162
+ },
163
+ };
164
+ }
165
+
166
+ // v1 container: standard ZIP entry view
111
167
  return {
112
168
  kind: 'asset',
113
169
  path: kdnaPath,