@aikdna/kdna-core 0.4.0 → 0.6.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 +119 -3
- package/package.json +3 -3
- package/schema/KDNA_Scenarios.schema.json +2 -2
- package/schema/kdna-file.schema.json +16 -6
- package/schema/kdna-manifest-v1rc.json +241 -0
- package/src/asset-reader.js +619 -0
- package/src/crypto-profile.js +106 -0
- package/src/index.js +6 -0
- package/src/index.mjs +11 -0
- package/src/lint-pure.js +41 -10
- package/src/public-api.js +323 -0
- package/src/types.d.ts +247 -4
- package/src/validate-pure.js +1 -7
package/src/types.d.ts
CHANGED
|
@@ -203,15 +203,29 @@ export interface KDNAFileDataMap {
|
|
|
203
203
|
}
|
|
204
204
|
|
|
205
205
|
export interface KDNAManifest {
|
|
206
|
-
|
|
206
|
+
format: 'kdna';
|
|
207
|
+
format_version: '1.0';
|
|
208
|
+
spec_version: string;
|
|
207
209
|
name: string;
|
|
208
210
|
version: string;
|
|
209
|
-
|
|
211
|
+
judgment_version: string;
|
|
212
|
+
status: 'draft' | 'experimental' | 'stable' | 'deprecated' | 'staging';
|
|
213
|
+
quality_badge: 'untested' | 'tested' | 'validated' | 'expert_reviewed' | 'production_ready';
|
|
210
214
|
access: 'open' | 'licensed' | 'runtime';
|
|
211
|
-
language
|
|
212
|
-
|
|
215
|
+
language?: string;
|
|
216
|
+
default_language: string;
|
|
217
|
+
languages: string[];
|
|
218
|
+
author: { name: string; id?: string; pubkey?: string; public_key_pem?: string };
|
|
213
219
|
license: { type: string; url?: string };
|
|
214
220
|
description: string;
|
|
221
|
+
keywords?: string[];
|
|
222
|
+
encryption?: {
|
|
223
|
+
profile?: string;
|
|
224
|
+
encrypted_entries?: string[];
|
|
225
|
+
[key: string]: any;
|
|
226
|
+
};
|
|
227
|
+
content_digest?: string;
|
|
228
|
+
signature?: string;
|
|
215
229
|
}
|
|
216
230
|
|
|
217
231
|
export interface LintResult {
|
|
@@ -241,6 +255,235 @@ export function formatContext(domain: LoadedDomain): string;
|
|
|
241
255
|
|
|
242
256
|
export const FILE_MAP: Record<string, string>;
|
|
243
257
|
|
|
258
|
+
// Asset reader — direct .kdna API
|
|
259
|
+
export const STANDARD_ENTRIES: string[];
|
|
260
|
+
|
|
261
|
+
export interface KdnaAsset {
|
|
262
|
+
path: string | null;
|
|
263
|
+
size: number;
|
|
264
|
+
asset_digest: string;
|
|
265
|
+
entries: Map<string, unknown>;
|
|
266
|
+
readEntry(name: string): Uint8Array;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
export interface KdnaAssetVerifyResult {
|
|
270
|
+
ok: boolean;
|
|
271
|
+
errors: string[];
|
|
272
|
+
warnings: string[];
|
|
273
|
+
entries: string[];
|
|
274
|
+
manifest: KDNAManifest | null;
|
|
275
|
+
asset_digest: string;
|
|
276
|
+
content_digest: string;
|
|
277
|
+
signature_valid: boolean | null;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
export interface KdnaAssetIndexProfile {
|
|
281
|
+
profile: 'index';
|
|
282
|
+
manifest: KDNAManifest;
|
|
283
|
+
asset_digest: string;
|
|
284
|
+
content_digest: string;
|
|
285
|
+
entries: string[];
|
|
286
|
+
name: string | null;
|
|
287
|
+
version: string | null;
|
|
288
|
+
judgment_version: string | null;
|
|
289
|
+
keywords: string[];
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
export interface KdnaAssetLoadProfile {
|
|
293
|
+
profile: string;
|
|
294
|
+
manifest: KDNAManifest;
|
|
295
|
+
domain: LoadedDomain | null;
|
|
296
|
+
context: string | null;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
export interface KdnaAssetReader {
|
|
300
|
+
openSync(input: string | Uint8Array): KdnaAsset;
|
|
301
|
+
open(input: string | Uint8Array): Promise<KdnaAsset>;
|
|
302
|
+
listEntriesSync(asset: KdnaAsset): string[];
|
|
303
|
+
listEntries(asset: KdnaAsset): Promise<string[]>;
|
|
304
|
+
readEntrySync(asset: KdnaAsset, entryName: string): Uint8Array;
|
|
305
|
+
readEntrySync(asset: KdnaAsset, entryName: string, encoding: string): string;
|
|
306
|
+
readEntry(asset: KdnaAsset, entryName: string): Promise<Uint8Array>;
|
|
307
|
+
readEntry(asset: KdnaAsset, entryName: string, encoding: string): Promise<string>;
|
|
308
|
+
readJsonSync(asset: KdnaAsset, entryName: string, options?: KdnaDecryptOptions): any;
|
|
309
|
+
readJson(asset: KdnaAsset, entryName: string, options?: KdnaDecryptOptions): Promise<any>;
|
|
310
|
+
readManifestSync(asset: KdnaAsset): KDNAManifest;
|
|
311
|
+
readManifest(asset: KdnaAsset): Promise<KDNAManifest>;
|
|
312
|
+
readDataMapSync(
|
|
313
|
+
asset: KdnaAsset,
|
|
314
|
+
entries?: string[],
|
|
315
|
+
options?: KdnaDecryptOptions,
|
|
316
|
+
): KDNAFileDataMap;
|
|
317
|
+
readDataMap(
|
|
318
|
+
asset: KdnaAsset,
|
|
319
|
+
entries?: string[],
|
|
320
|
+
options?: KdnaDecryptOptions,
|
|
321
|
+
): Promise<KDNAFileDataMap>;
|
|
322
|
+
contentDigestSync(asset: KdnaAsset): string;
|
|
323
|
+
contentDigest(asset: KdnaAsset): Promise<string>;
|
|
324
|
+
verifySync(
|
|
325
|
+
asset: KdnaAsset,
|
|
326
|
+
options?: {
|
|
327
|
+
asset_digest?: string;
|
|
328
|
+
content_digest?: string;
|
|
329
|
+
requireSignature?: boolean;
|
|
330
|
+
requireDecryption?: boolean;
|
|
331
|
+
} & KdnaDecryptOptions,
|
|
332
|
+
): KdnaAssetVerifyResult;
|
|
333
|
+
verify(
|
|
334
|
+
asset: KdnaAsset,
|
|
335
|
+
options?: {
|
|
336
|
+
asset_digest?: string;
|
|
337
|
+
content_digest?: string;
|
|
338
|
+
requireSignature?: boolean;
|
|
339
|
+
requireDecryption?: boolean;
|
|
340
|
+
} & KdnaDecryptOptions,
|
|
341
|
+
): Promise<KdnaAssetVerifyResult>;
|
|
342
|
+
loadProfileSync(
|
|
343
|
+
asset: KdnaAsset,
|
|
344
|
+
profile: 'index',
|
|
345
|
+
options?: { input?: string; context?: boolean } & KdnaDecryptOptions,
|
|
346
|
+
): KdnaAssetIndexProfile;
|
|
347
|
+
loadProfileSync(
|
|
348
|
+
asset: KdnaAsset,
|
|
349
|
+
profile?: 'compact' | 'scenario' | 'full' | string,
|
|
350
|
+
options?: { input?: string; context?: boolean } & KdnaDecryptOptions,
|
|
351
|
+
): KdnaAssetLoadProfile;
|
|
352
|
+
loadProfile(
|
|
353
|
+
asset: KdnaAsset,
|
|
354
|
+
profile: 'index',
|
|
355
|
+
options?: { input?: string; context?: boolean } & KdnaDecryptOptions,
|
|
356
|
+
): Promise<KdnaAssetIndexProfile>;
|
|
357
|
+
loadProfile(
|
|
358
|
+
asset: KdnaAsset,
|
|
359
|
+
profile?: 'compact' | 'scenario' | 'full' | string,
|
|
360
|
+
options?: { input?: string; context?: boolean } & KdnaDecryptOptions,
|
|
361
|
+
): Promise<KdnaAssetLoadProfile>;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
export interface KdnaDecryptOptions {
|
|
365
|
+
decryptEntry?: (args: {
|
|
366
|
+
asset: KdnaAsset;
|
|
367
|
+
manifest: KDNAManifest;
|
|
368
|
+
entryName: string;
|
|
369
|
+
ciphertext: Uint8Array;
|
|
370
|
+
}) => string | Uint8Array | Promise<string | Uint8Array>;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
export function createKdnaAssetReader(): KdnaAssetReader;
|
|
374
|
+
|
|
375
|
+
export const LICENSED_ENTRY_PROFILE: string;
|
|
376
|
+
|
|
377
|
+
export interface LicensedEntryEnvelope {
|
|
378
|
+
profile: string;
|
|
379
|
+
alg: 'AES-256-GCM';
|
|
380
|
+
kdf: 'scrypt-sha256';
|
|
381
|
+
salt: string;
|
|
382
|
+
iv: string;
|
|
383
|
+
tag: string;
|
|
384
|
+
ciphertext: string;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
export function deriveLicensedEntryKey(options: {
|
|
388
|
+
licenseKey: string;
|
|
389
|
+
machineFingerprint: string;
|
|
390
|
+
salt: string | Uint8Array;
|
|
391
|
+
keyLength?: number;
|
|
392
|
+
}): Uint8Array;
|
|
393
|
+
|
|
394
|
+
export function encryptLicensedEntry(
|
|
395
|
+
plaintext: string | Uint8Array,
|
|
396
|
+
options: {
|
|
397
|
+
entryName: string;
|
|
398
|
+
manifest?: KDNAManifest;
|
|
399
|
+
licenseKey: string;
|
|
400
|
+
machineFingerprint: string;
|
|
401
|
+
},
|
|
402
|
+
): LicensedEntryEnvelope;
|
|
403
|
+
|
|
404
|
+
export function decryptLicensedEntry(
|
|
405
|
+
envelope: string | Uint8Array | LicensedEntryEnvelope,
|
|
406
|
+
options: {
|
|
407
|
+
entryName: string;
|
|
408
|
+
manifest?: KDNAManifest;
|
|
409
|
+
licenseKey: string;
|
|
410
|
+
machineFingerprint: string;
|
|
411
|
+
},
|
|
412
|
+
): Uint8Array;
|
|
413
|
+
|
|
414
|
+
export function createLicensedDecryptEntry(options: {
|
|
415
|
+
licenseKey: string;
|
|
416
|
+
machineFingerprint: string;
|
|
417
|
+
}): NonNullable<KdnaDecryptOptions['decryptEntry']>;
|
|
418
|
+
|
|
419
|
+
// Stable public API — preferred entry points for third-party integrations.
|
|
420
|
+
export type KDNAAssetInput = string | Uint8Array | KdnaAsset;
|
|
421
|
+
|
|
422
|
+
export interface KDNAInspectResult {
|
|
423
|
+
name: string | null;
|
|
424
|
+
version: string | null;
|
|
425
|
+
judgment_version: string | null;
|
|
426
|
+
access: string;
|
|
427
|
+
status: string | null;
|
|
428
|
+
quality_badge: string | null;
|
|
429
|
+
risk_level: string | null;
|
|
430
|
+
keywords: string[];
|
|
431
|
+
entries: string[];
|
|
432
|
+
asset_digest: string;
|
|
433
|
+
content_digest: string;
|
|
434
|
+
signature_valid: boolean | null;
|
|
435
|
+
ok: boolean | null;
|
|
436
|
+
errors: string[];
|
|
437
|
+
warnings: string[];
|
|
438
|
+
manifest: KDNAManifest;
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
export interface KDNAValidationReport {
|
|
442
|
+
ok: boolean;
|
|
443
|
+
errors: string[];
|
|
444
|
+
warnings: string[];
|
|
445
|
+
asset: KdnaAssetVerifyResult;
|
|
446
|
+
lint: LintResult;
|
|
447
|
+
schema: ValidationResult;
|
|
448
|
+
cross_file: ValidationResult;
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
export interface KDNAMatchResult extends KDNAInspectResult {
|
|
452
|
+
score: number;
|
|
453
|
+
matched: string[];
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
export interface KDNAComposeResult {
|
|
457
|
+
domains: Array<LoadedDomain & { id?: string; name?: string; manifest?: KDNAManifest }>;
|
|
458
|
+
activeDomains: Array<LoadedDomain & { id?: string; name?: string; manifest?: KDNAManifest }>;
|
|
459
|
+
selected: Array<{ id: string; name?: string; role?: string; reason: string }>;
|
|
460
|
+
excluded: Array<{ id: string; name?: string; role?: string; reason: string }>;
|
|
461
|
+
conflicts: Array<{ type: string; domains: string[]; description: string }>;
|
|
462
|
+
context: string;
|
|
463
|
+
attributionMap: Record<string, any>;
|
|
464
|
+
trace: Record<string, any>;
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
export function openKDNA(input: KDNAAssetInput): Promise<KdnaAsset>;
|
|
468
|
+
export function openKDNASync(input: KDNAAssetInput): KdnaAsset;
|
|
469
|
+
export function inspectKDNA(input: KDNAAssetInput, options?: { verify?: boolean } & KdnaDecryptOptions): Promise<KDNAInspectResult>;
|
|
470
|
+
export function inspectKDNASync(input: KDNAAssetInput, options?: { verify?: boolean } & KdnaDecryptOptions): KDNAInspectResult;
|
|
471
|
+
export function loadKDNA(input: KDNAAssetInput, options?: { profile?: 'index' | 'compact' | 'scenario' | 'full' | string; input?: string; context?: boolean } & KdnaDecryptOptions): Promise<KdnaAssetIndexProfile | KdnaAssetLoadProfile>;
|
|
472
|
+
export function loadKDNASync(input: KDNAAssetInput, options?: { profile?: 'index' | 'compact' | 'scenario' | 'full' | string; input?: string; context?: boolean } & KdnaDecryptOptions): KdnaAssetIndexProfile | KdnaAssetLoadProfile;
|
|
473
|
+
export function validateKDNA(input: KDNAAssetInput, options?: { schemas?: Record<string, any>; requireSignature?: boolean; requireDecryption?: boolean } & KdnaDecryptOptions): Promise<KDNAValidationReport>;
|
|
474
|
+
export function validateKDNASync(input: KDNAAssetInput, options?: { schemas?: Record<string, any>; requireSignature?: boolean; requireDecryption?: boolean } & KdnaDecryptOptions): KDNAValidationReport;
|
|
475
|
+
export function renderForAgent(input: KDNAAssetInput, options?: { profile?: 'compact' | 'scenario' | 'full' | string; input?: string } & KdnaDecryptOptions): Promise<string>;
|
|
476
|
+
export function renderForAgentSync(input: KDNAAssetInput, options?: { profile?: 'compact' | 'scenario' | 'full' | string; input?: string } & KdnaDecryptOptions): string;
|
|
477
|
+
export function verifyAsset(input: KDNAAssetInput, options?: { asset_digest?: string; content_digest?: string; requireSignature?: boolean; requireDecryption?: boolean } & KdnaDecryptOptions): Promise<KdnaAssetVerifyResult>;
|
|
478
|
+
export function verifyAssetSync(input: KDNAAssetInput, options?: { asset_digest?: string; content_digest?: string; requireSignature?: boolean; requireDecryption?: boolean } & KdnaDecryptOptions): KdnaAssetVerifyResult;
|
|
479
|
+
export function verifyDigest(input: KDNAAssetInput, expectedDigest: string, options?: KdnaDecryptOptions): Promise<KdnaAssetVerifyResult>;
|
|
480
|
+
export function verifyDigestSync(input: KDNAAssetInput, expectedDigest: string, options?: KdnaDecryptOptions): KdnaAssetVerifyResult;
|
|
481
|
+
export function verifySignature(input: KDNAAssetInput, options?: KdnaDecryptOptions): Promise<KdnaAssetVerifyResult>;
|
|
482
|
+
export function verifySignatureSync(input: KDNAAssetInput, options?: KdnaDecryptOptions): KdnaAssetVerifyResult;
|
|
483
|
+
export function matchDomain(input: string, candidates: Array<KDNAAssetInput | KDNAInspectResult>, options?: KdnaDecryptOptions): Promise<KDNAMatchResult[]>;
|
|
484
|
+
export function matchDomainSync(input: string, candidates: Array<KDNAAssetInput | KDNAInspectResult>, options?: KdnaDecryptOptions): KDNAMatchResult[];
|
|
485
|
+
export function composeKDNA(inputs: KDNAAssetInput[], options?: { input?: string; profile?: 'compact' | 'scenario' | 'full' | string; separator?: string } & KdnaDecryptOptions): Promise<KDNAComposeResult>;
|
|
486
|
+
|
|
244
487
|
// Lint
|
|
245
488
|
export function lintDomain(dataMap: KDNAFileDataMap): LintResult;
|
|
246
489
|
|
package/src/validate-pure.js
CHANGED
|
@@ -45,9 +45,6 @@ function validateDomainSchema(dataMap, schemaMap) {
|
|
|
45
45
|
return { valid: true, errors: [], warnings };
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
let validCount = 0;
|
|
49
|
-
let failCount = 0;
|
|
50
|
-
|
|
51
48
|
for (const [file, schemaFile] of Object.entries(FILE_TO_SCHEMA)) {
|
|
52
49
|
if (!dataMap[file]) continue;
|
|
53
50
|
if (!schemaMap[schemaFile]) {
|
|
@@ -69,10 +66,7 @@ function validateDomainSchema(dataMap, schemaMap) {
|
|
|
69
66
|
const validate = ajvInstance.compile(schema);
|
|
70
67
|
const valid = validate(dataMap[file]);
|
|
71
68
|
|
|
72
|
-
if (valid) {
|
|
73
|
-
validCount++;
|
|
74
|
-
} else {
|
|
75
|
-
failCount++;
|
|
69
|
+
if (!valid) {
|
|
76
70
|
for (const err of validate.errors || []) {
|
|
77
71
|
const instancePath = err.instancePath || '/';
|
|
78
72
|
errors.push(`${file}${instancePath}: ${err.message} (${err.keyword})`);
|