nap-sdk 0.2.4 → 0.2.6

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/dist/index.js CHANGED
@@ -1,32 +1,710 @@
1
+ /**
2
+ * NAP SDK — TypeScript bindings for the Narrative Addressing Protocol.
3
+ *
4
+ * Powered by Rust via NAPI-RS native addon. All functions that return
5
+ * structured data return plain objects (JSON-deserialized from the native
6
+ * layer).
7
+ *
8
+ * @module nap-sdk
9
+ */
1
10
  import { homedir } from "node:os";
2
11
  import { join } from "node:path";
3
12
  import native from "./native.js";
13
+ // ── Helpers ──────────────────────────────────────────────────────────
14
+ /** Resolve the NAP base directory from env or default. */
15
+ function resolveRepoPath(repoPath) {
16
+ return repoPath || process.env.NAP_DIR || join(homedir(), ".nap");
17
+ }
18
+ // ═══════════════════════════════════════════════════════════════════════
19
+ // URI Operations
20
+ // ═══════════════════════════════════════════════════════════════════════
21
+ /**
22
+ * Parse a `nap://` URI into its component parts.
23
+ *
24
+ * @param uri - A NAP URI (e.g. `"nap://starwars/character/lukeskywalker"`)
25
+ * @returns Parsed URI components
26
+ */
4
27
  export function parseUri(uri) {
5
28
  return JSON.parse(native.parseUri(uri));
6
29
  }
30
+ /**
31
+ * Construct a new NAP URI from components.
32
+ *
33
+ * @param universe - Universe name (e.g. `"starwars"`)
34
+ * @param entityType - Entity type (e.g. `"character"`)
35
+ * @param entityId - Entity ID slug (e.g. `"lukeskywalker"`)
36
+ * @param fragment - Optional query fragment
37
+ * @returns Parsed URI components
38
+ */
39
+ export function uriNew(universe, entityType, entityId, fragment) {
40
+ return JSON.parse(native.uriNew(universe, entityType, entityId, fragment));
41
+ }
42
+ /**
43
+ * Return the canonical identity URI (without fragment).
44
+ *
45
+ * @param uri - A NAP URI, possibly with a fragment
46
+ * @returns Identity URI string
47
+ */
48
+ export function uriIdentity(uri) {
49
+ return native.uriIdentity(uri);
50
+ }
51
+ /**
52
+ * Return the relative filesystem path for an entity's manifest.
53
+ *
54
+ * @param uri - A NAP URI
55
+ * @returns Relative path (e.g. `"characters/lukeskywalker.yaml"`)
56
+ */
57
+ export function uriManifestPath(uri) {
58
+ return native.uriManifestPath(uri);
59
+ }
60
+ /**
61
+ * Format URI components into a `nap://` URI string.
62
+ *
63
+ * @param universe - Universe name
64
+ * @param entityType - Entity type
65
+ * @param entityId - Entity ID
66
+ * @param fragment - Optional query fragment
67
+ * @returns Full NAP URI string
68
+ */
69
+ export function uriFormat(universe, entityType, entityId, fragment) {
70
+ return native.uriFormat(universe, entityType, entityId, fragment);
71
+ }
72
+ // ═══════════════════════════════════════════════════════════════════════
73
+ // EntityType Operations
74
+ // ═══════════════════════════════════════════════════════════════════════
75
+ /**
76
+ * Parse an entity type string.
77
+ *
78
+ * @param s - Type string (e.g. `"character"`, `"location"`, `"scene"`, `"prop"`, `"world"`)
79
+ * @returns The normalized entity type string
80
+ */
81
+ export function entityTypeParse(s) {
82
+ return JSON.parse(native.entityTypeParse(s));
83
+ }
84
+ /**
85
+ * Return the directory name used for this entity type in a repository.
86
+ *
87
+ * @param entityType - Type string
88
+ * @returns Directory name (e.g. `"characters"`)
89
+ */
90
+ export function entityTypeDirectoryName(entityType) {
91
+ return native.entityTypeDirectoryName(entityType);
92
+ }
93
+ /**
94
+ * Return all subdirectory entity types (character, location, scene, prop).
95
+ *
96
+ * @returns Array of entity type strings
97
+ */
98
+ export function entityTypeList() {
99
+ return JSON.parse(native.entityTypeList());
100
+ }
101
+ // ═══════════════════════════════════════════════════════════════════════
102
+ // Manifest Operations
103
+ // ═══════════════════════════════════════════════════════════════════════
104
+ /**
105
+ * Parse a YAML manifest string into a JSON-serializable object.
106
+ *
107
+ * @param yamlStr - YAML string representing a NAP manifest
108
+ * @returns Parsed manifest
109
+ */
7
110
  export function parseManifest(yamlStr) {
8
111
  return JSON.parse(native.parseManifest(yamlStr));
9
112
  }
10
- export function resolve(uri, repoPath) {
11
- if (!repoPath) {
12
- repoPath = process.env.NAP_DIR || join(homedir(), ".nap");
113
+ /**
114
+ * Create a new manifest with minimal required fields.
115
+ *
116
+ * @param universe - Universe name
117
+ * @param entityType - Entity type string
118
+ * @param entityId - Entity ID slug
119
+ * @param name - Human-readable name
120
+ * @returns New manifest
121
+ */
122
+ export function manifestNew(universe, entityType, entityId, name) {
123
+ return JSON.parse(native.manifestNew(universe, entityType, entityId, name));
124
+ }
125
+ /**
126
+ * Serialize a manifest object to YAML.
127
+ *
128
+ * @param manifest - Manifest object
129
+ * @returns YAML string representation
130
+ */
131
+ export function manifestToYaml(manifest) {
132
+ return native.manifestToYaml(JSON.stringify(manifest));
133
+ }
134
+ /**
135
+ * Read a manifest from a YAML string.
136
+ *
137
+ * @param yamlStr - YAML string
138
+ * @returns Parsed manifest
139
+ */
140
+ export function manifestFromYaml(yamlStr) {
141
+ return JSON.parse(native.manifestFromYaml(yamlStr));
142
+ }
143
+ /**
144
+ * Compute the SHA-256 content hash of a manifest.
145
+ *
146
+ * @param manifest - Manifest object
147
+ * @returns Content hash in `sha256:<hex>` format
148
+ */
149
+ export function manifestContentHash(manifest) {
150
+ return native.manifestContentHash(JSON.stringify(manifest));
151
+ }
152
+ /**
153
+ * Add or update a property on a manifest.
154
+ *
155
+ * @param manifest - Manifest object
156
+ * @param key - Property key
157
+ * @param value - Property value string (parsed as YAML)
158
+ * @returns Updated manifest
159
+ */
160
+ export function manifestSetProperty(manifest, key, value) {
161
+ return JSON.parse(native.manifestSetProperty(JSON.stringify(manifest), key, value));
162
+ }
163
+ /**
164
+ * Add a cross-reference to a manifest.
165
+ *
166
+ * @param manifest - Manifest object
167
+ * @param key - Reference key
168
+ * @param value - Reference value string (parsed as YAML)
169
+ * @returns Updated manifest
170
+ */
171
+ export function manifestAddReference(manifest, key, value) {
172
+ return JSON.parse(native.manifestAddReference(JSON.stringify(manifest), key, value));
173
+ }
174
+ /**
175
+ * Add or update a representation on a manifest.
176
+ *
177
+ * @param manifest - Manifest object
178
+ * @param key - Representation key
179
+ * @param hash - Content hash string
180
+ * @param format - File format (e.g. `"png"`, `"glb"`)
181
+ * @param uri - Optional storage URI
182
+ * @param tier - Optional quality tier
183
+ * @returns Updated manifest
184
+ */
185
+ export function manifestSetRepresentation(manifest, key, hash, format, uri, tier) {
186
+ return JSON.parse(native.manifestSetRepresentation(JSON.stringify(manifest), key, hash, format, uri, tier));
187
+ }
188
+ /**
189
+ * Increment the version counter on a manifest.
190
+ *
191
+ * @param manifest - Manifest object
192
+ * @returns Updated manifest with version incremented
193
+ */
194
+ export function manifestBumpVersion(manifest) {
195
+ return JSON.parse(native.manifestBumpVersion(JSON.stringify(manifest)));
196
+ }
197
+ // ═══════════════════════════════════════════════════════════════════════
198
+ // ContentHash Operations
199
+ // ═══════════════════════════════════════════════════════════════════════
200
+ /**
201
+ * Compute the SHA-256 content hash of raw bytes.
202
+ *
203
+ * @param data - Raw byte data
204
+ * @returns Content hash `sha256:<hex>`
205
+ */
206
+ export function contentHashFromBytes(data) {
207
+ return native.contentHashFromBytes(data);
208
+ }
209
+ /**
210
+ * Compute the SHA-256 content hash of a string.
211
+ *
212
+ * @param s - Input string
213
+ * @returns Content hash `sha256:<hex>`
214
+ */
215
+ export function contentHashFromString(s) {
216
+ return native.contentHashFromString(s);
217
+ }
218
+ /**
219
+ * Parse and validate a `sha256:<hex>` content hash string.
220
+ *
221
+ * @param s - Content hash string
222
+ * @returns The validated content hash
223
+ * @throws If the string is not a valid content hash
224
+ */
225
+ export function contentHashParse(s) {
226
+ return native.contentHashParse(s);
227
+ }
228
+ /**
229
+ * Verify that bytes match a content hash.
230
+ *
231
+ * @param hash - Content hash string
232
+ * @param data - Raw byte data to verify
233
+ * @returns `true` if the data matches the hash
234
+ */
235
+ export function contentHashVerify(hash, data) {
236
+ return native.contentHashVerify(hash, data);
237
+ }
238
+ /**
239
+ * Extract the hex digest from a content hash string.
240
+ *
241
+ * @param hash - Content hash string (`sha256:<hex>`)
242
+ * @returns The 64-character hex digest
243
+ */
244
+ export function contentHashHexDigest(hash) {
245
+ return native.contentHashHexDigest(hash);
246
+ }
247
+ // ═══════════════════════════════════════════════════════════════════════
248
+ // Commit / Change Operations
249
+ // ═══════════════════════════════════════════════════════════════════════
250
+ /**
251
+ * Create a "Set" change record.
252
+ *
253
+ * @param path - Dot-notation path (e.g. `"properties.species"`)
254
+ * @param newValue - New value string
255
+ * @param oldValue - Optional previous value string
256
+ * @returns Change object
257
+ */
258
+ export function changeSet(path, newValue, oldValue) {
259
+ return JSON.parse(native.changeSet(path, oldValue ?? null, newValue));
260
+ }
261
+ /**
262
+ * Create a "Delete" change record.
263
+ *
264
+ * @param path - Dot-notation path
265
+ * @param oldValue - Previous value string
266
+ * @returns Change object
267
+ */
268
+ export function changeDelete(path, oldValue) {
269
+ return JSON.parse(native.changeDelete(path, oldValue));
270
+ }
271
+ /**
272
+ * Create an "Append" change record.
273
+ *
274
+ * @param path - Dot-notation path
275
+ * @param newValue - New value to append
276
+ * @returns Change object
277
+ */
278
+ export function changeAppend(path, newValue) {
279
+ return JSON.parse(native.changeAppend(path, newValue));
280
+ }
281
+ /**
282
+ * Create a new NAP commit object.
283
+ *
284
+ * @param author - Author identifier
285
+ * @param message - Human-readable commit message
286
+ * @param manifestHash - SHA-256 hash of the resulting manifest
287
+ * @param changes - Array of change objects
288
+ * @param parent - Optional parent commit hash
289
+ * @returns Commit object with auto-computed `id`
290
+ */
291
+ export function commitNew(author, message, manifestHash, changes, parent) {
292
+ return JSON.parse(native.commitNew(parent ?? null, author, message, manifestHash, JSON.stringify(changes)));
293
+ }
294
+ /**
295
+ * Verify a commit's ID by re-computing the hash.
296
+ *
297
+ * @param commit - Commit object
298
+ * @returns `true` if the ID is valid
299
+ */
300
+ export function commitVerifyId(commit) {
301
+ return native.commitVerifyId(JSON.stringify(commit));
302
+ }
303
+ // ═══════════════════════════════════════════════════════════════════════
304
+ // Repository Operations
305
+ // ═══════════════════════════════════════════════════════════════════════
306
+ /**
307
+ * Initialize a new NAP universe repository.
308
+ *
309
+ * @param universe - Universe name
310
+ * @param basePath - Base directory (defaults to `$NAP_DIR` / `~/.nap`)
311
+ * @returns Repo info with `root` and `universe`
312
+ */
313
+ export function repoInit(universe, basePath) {
314
+ return JSON.parse(native.repoInit(resolveRepoPath(basePath), universe));
315
+ }
316
+ /**
317
+ * Open an existing NAP universe repository.
318
+ *
319
+ * @param universe - Universe name
320
+ * @param basePath - Base directory (defaults to `$NAP_DIR` / `~/.nap`)
321
+ * @returns Repo info
322
+ */
323
+ export function repoOpen(universe, basePath) {
324
+ return JSON.parse(native.repoOpen(resolveRepoPath(basePath), universe));
325
+ }
326
+ /**
327
+ * Create a new entity manifest and commit it.
328
+ *
329
+ * @param universe - Universe name
330
+ * @param entityType - Entity type string
331
+ * @param entityId - Entity ID slug
332
+ * @param name - Human-readable name
333
+ * @param author - Author identifier (default: `"nap-sdk"`)
334
+ * @param basePath - Base directory (defaults to `$NAP_DIR` / `~/.nap`)
335
+ * @returns Object with `manifest` and `commit_hash`
336
+ */
337
+ export function repoCreateEntity(universe, entityType, entityId, name, author = "nap-sdk", basePath) {
338
+ return JSON.parse(native.repoCreateEntity(resolveRepoPath(basePath), universe, entityType, entityId, name, author));
339
+ }
340
+ /**
341
+ * Read a manifest from the repository.
342
+ *
343
+ * @param universe - Universe name
344
+ * @param entityType - Entity type string
345
+ * @param entityId - Entity ID
346
+ * @param basePath - Base directory (defaults to `$NAP_DIR` / `~/.nap`)
347
+ * @returns Manifest object
348
+ */
349
+ export function repoReadManifest(universe, entityType, entityId, basePath) {
350
+ return JSON.parse(native.repoReadManifest(resolveRepoPath(basePath), universe, entityType, entityId));
351
+ }
352
+ /**
353
+ * Read a manifest at a specific VCS reference (commit, branch, tag).
354
+ *
355
+ * @param universe - Universe name
356
+ * @param entityType - Entity type string
357
+ * @param entityId - Entity ID
358
+ * @param reference - Git ref (commit hash, branch name, or tag)
359
+ * @param basePath - Base directory (defaults to `$NAP_DIR` / `~/.nap`)
360
+ * @returns Manifest object
361
+ */
362
+ export function repoReadManifestAtRef(universe, entityType, entityId, reference, basePath) {
363
+ return JSON.parse(native.repoReadManifestAtRef(resolveRepoPath(basePath), universe, entityType, entityId, reference));
364
+ }
365
+ /**
366
+ * Write a manifest to the repository (does NOT commit).
367
+ *
368
+ * @param universe - Universe name
369
+ * @param manifest - Manifest object
370
+ * @param basePath - Base directory (defaults to `$NAP_DIR` / `~/.nap`)
371
+ * @returns The filesystem path where the manifest was written
372
+ */
373
+ export function repoWriteManifest(universe, manifest, basePath) {
374
+ return native.repoWriteManifest(resolveRepoPath(basePath), universe, JSON.stringify(manifest));
375
+ }
376
+ /**
377
+ * Commit changes to a manifest.
378
+ *
379
+ * @param universe - Universe name
380
+ * @param entityType - Entity type string
381
+ * @param entityId - Entity ID
382
+ * @param message - Commit message
383
+ * @param author - Author identifier (default: `"nap-sdk"`)
384
+ * @param changes - Array of change objects
385
+ * @param basePath - Base directory (defaults to `$NAP_DIR` / `~/.nap`)
386
+ * @returns Object with `commit` and `version`
387
+ */
388
+ export function repoCommitManifest(universe, entityType, entityId, message, author = "nap-sdk", changes = [], basePath) {
389
+ return JSON.parse(native.repoCommitManifest(resolveRepoPath(basePath), universe, entityType, entityId, message, author, JSON.stringify(changes)));
390
+ }
391
+ /**
392
+ * Delete an entity manifest and commit the deletion.
393
+ *
394
+ * @param universe - Universe name
395
+ * @param entityType - Entity type string
396
+ * @param entityId - Entity ID
397
+ * @param author - Author identifier (default: `"nap-sdk"`)
398
+ * @param basePath - Base directory (defaults to `$NAP_DIR` / `~/.nap`)
399
+ * @returns The VCS commit hash of the deletion
400
+ */
401
+ export function repoDeleteEntity(universe, entityType, entityId, author = "nap-sdk", basePath) {
402
+ return native.repoDeleteEntity(resolveRepoPath(basePath), universe, entityType, entityId, author);
403
+ }
404
+ /**
405
+ * Get commit history for an entity.
406
+ *
407
+ * @param universe - Universe name
408
+ * @param entityType - Entity type string
409
+ * @param entityId - Entity ID
410
+ * @param limit - Maximum number of commits (default: 20)
411
+ * @param basePath - Base directory (defaults to `$NAP_DIR` / `~/.nap`)
412
+ * @returns Array of commit entries
413
+ */
414
+ export function repoHistory(universe, entityType, entityId, limit = 20, basePath) {
415
+ return JSON.parse(native.repoHistory(resolveRepoPath(basePath), universe, entityType, entityId, limit));
416
+ }
417
+ /**
418
+ * List all entity IDs of a given type in a universe.
419
+ *
420
+ * @param universe - Universe name
421
+ * @param entityType - Entity type string
422
+ * @param basePath - Base directory (defaults to `$NAP_DIR` / `~/.nap`)
423
+ * @returns Array of entity ID strings
424
+ */
425
+ export function repoListEntities(universe, entityType, basePath) {
426
+ return JSON.parse(native.repoListEntities(resolveRepoPath(basePath), universe, entityType));
427
+ }
428
+ /**
429
+ * Create a branch in a universe repository.
430
+ *
431
+ * @param universe - Universe name
432
+ * @param name - Branch name
433
+ * @param basePath - Base directory (defaults to `$NAP_DIR` / `~/.nap`)
434
+ * @returns Success response
435
+ */
436
+ export function repoCreateBranch(universe, name, basePath) {
437
+ return JSON.parse(native.repoCreateBranch(resolveRepoPath(basePath), universe, name));
438
+ }
439
+ /**
440
+ * Switch to a branch in a universe repository.
441
+ *
442
+ * @param universe - Universe name
443
+ * @param name - Branch name
444
+ * @param basePath - Base directory (defaults to `$NAP_DIR` / `~/.nap`)
445
+ * @returns Success response
446
+ */
447
+ export function repoSwitchBranch(universe, name, basePath) {
448
+ return JSON.parse(native.repoSwitchBranch(resolveRepoPath(basePath), universe, name));
449
+ }
450
+ /**
451
+ * List all branches in a universe repository.
452
+ *
453
+ * @param universe - Universe name
454
+ * @param basePath - Base directory (defaults to `$NAP_DIR` / `~/.nap`)
455
+ * @returns Array of branch names
456
+ */
457
+ export function repoListBranches(universe, basePath) {
458
+ return JSON.parse(native.repoListBranches(resolveRepoPath(basePath), universe));
459
+ }
460
+ /**
461
+ * Create a tag in a universe repository.
462
+ *
463
+ * @param universe - Universe name
464
+ * @param name - Tag name
465
+ * @param basePath - Base directory (defaults to `$NAP_DIR` / `~/.nap`)
466
+ * @returns Success response
467
+ */
468
+ export function repoCreateTag(universe, name, basePath) {
469
+ return JSON.parse(native.repoCreateTag(resolveRepoPath(basePath), universe, name));
470
+ }
471
+ /**
472
+ * List all tags in a universe repository.
473
+ *
474
+ * @param universe - Universe name
475
+ * @param basePath - Base directory (defaults to `$NAP_DIR` / `~/.nap`)
476
+ * @returns Array of tag names
477
+ */
478
+ export function repoListTags(universe, basePath) {
479
+ return JSON.parse(native.repoListTags(resolveRepoPath(basePath), universe));
480
+ }
481
+ /**
482
+ * Get the current HEAD hash of a universe repository.
483
+ *
484
+ * @param universe - Universe name
485
+ * @param basePath - Base directory (defaults to `$NAP_DIR` / `~/.nap`)
486
+ * @returns The HEAD commit hash
487
+ */
488
+ export function repoHeadHash(universe, basePath) {
489
+ return native.repoHeadHash(resolveRepoPath(basePath), universe);
490
+ }
491
+ /**
492
+ * Revert a commit across an entire universe.
493
+ *
494
+ * @param universe - Universe name
495
+ * @param commitHash - Hash of the commit to revert
496
+ * @param author - Author identifier (default: `"nap-sdk"`)
497
+ * @param basePath - Base directory (defaults to `$NAP_DIR` / `~/.nap`)
498
+ * @returns The new revert commit hash
499
+ */
500
+ export function repoRevertCommit(universe, commitHash, author = "nap-sdk", basePath) {
501
+ return native.repoRevertCommit(resolveRepoPath(basePath), universe, commitHash, author);
502
+ }
503
+ /**
504
+ * Add a remote to a universe repository.
505
+ *
506
+ * @param universe - Universe name
507
+ * @param name - Remote name (e.g. `"origin"`)
508
+ * @param url - Remote URL
509
+ * @param basePath - Base directory (defaults to `$NAP_DIR` / `~/.nap`)
510
+ * @returns Success response
511
+ */
512
+ export function repoAddRemote(universe, name, url, basePath) {
513
+ return JSON.parse(native.repoAddRemote(resolveRepoPath(basePath), universe, name, url));
514
+ }
515
+ /**
516
+ * Remove a remote from a universe repository.
517
+ *
518
+ * @param universe - Universe name
519
+ * @param name - Remote name to remove
520
+ * @param basePath - Base directory (defaults to `$NAP_DIR` / `~/.nap`)
521
+ * @returns Success response
522
+ */
523
+ export function repoRemoveRemote(universe, name, basePath) {
524
+ return JSON.parse(native.repoRemoveRemote(resolveRepoPath(basePath), universe, name));
525
+ }
526
+ /**
527
+ * List remotes on a universe repository.
528
+ *
529
+ * @param universe - Universe name
530
+ * @param basePath - Base directory (defaults to `$NAP_DIR` / `~/.nap`)
531
+ * @returns Array of `[name, url]` tuples
532
+ */
533
+ export function repoListRemotes(universe, basePath) {
534
+ return JSON.parse(native.repoListRemotes(resolveRepoPath(basePath), universe));
535
+ }
536
+ /**
537
+ * Push the current branch to a remote.
538
+ *
539
+ * @param universe - Universe name
540
+ * @param remote - Remote name (optional)
541
+ * @param branch - Branch to push (optional)
542
+ * @param basePath - Base directory (defaults to `$NAP_DIR` / `~/.nap`)
543
+ * @returns Success response
544
+ */
545
+ export function repoPush(universe, remote, branch, basePath) {
546
+ return JSON.parse(native.repoPush(resolveRepoPath(basePath), universe, remote, branch));
547
+ }
548
+ /**
549
+ * Pull the current branch from a remote.
550
+ *
551
+ * @param universe - Universe name
552
+ * @param remote - Remote name (optional)
553
+ * @param branch - Branch to pull (optional)
554
+ * @param basePath - Base directory (defaults to `$NAP_DIR` / `~/.nap`)
555
+ * @returns Success response
556
+ */
557
+ export function repoPull(universe, remote, branch, basePath) {
558
+ return JSON.parse(native.repoPull(resolveRepoPath(basePath), universe, remote, branch));
559
+ }
560
+ // ═══════════════════════════════════════════════════════════════════════
561
+ // Resolver Operations
562
+ // ═══════════════════════════════════════════════════════════════════════
563
+ /**
564
+ * Resolve a NAP URI to a manifest or subtree.
565
+ *
566
+ * @param uri - NAP URI (e.g. `"nap://starwars/character/lukeskywalker"`)
567
+ * @param repoPath - Base directory for universes (defaults to `$NAP_DIR` / `~/.nap`)
568
+ * @param branch - Optional branch selector
569
+ * @param commit - Optional commit hash selector
570
+ * @param tag - Optional tag selector
571
+ * @param path - Optional subtree query path
572
+ * @returns Resolved manifest or subtree value
573
+ */
574
+ export function resolve(uri, repoPath, branch, commit, tag, path) {
575
+ const rp = resolveRepoPath(repoPath);
576
+ if (branch !== undefined || commit !== undefined || tag !== undefined || path !== undefined) {
577
+ return JSON.parse(native.resolveWithOptions(uri, rp, branch, commit, tag, path));
13
578
  }
14
- return JSON.parse(native.resolve(uri, repoPath));
579
+ return JSON.parse(native.resolve(uri, rp));
15
580
  }
16
- export function version() {
17
- return native.version();
581
+ /**
582
+ * Query a specific subtree path from a manifest.
583
+ *
584
+ * This is the most efficient way to read a single property from an entity.
585
+ *
586
+ * @param uri - NAP URI
587
+ * @param path - Dot-notation query path (e.g. `"properties.species"`)
588
+ * @param repoPath - Base directory (defaults to `$NAP_DIR` / `~/.nap`)
589
+ * @returns The value at the given path
590
+ */
591
+ export function resolveQuery(uri, path, repoPath) {
592
+ return JSON.parse(native.resolveQuery(uri, resolveRepoPath(repoPath), path));
593
+ }
594
+ /**
595
+ * List all universe repositories available.
596
+ *
597
+ * @param repoPath - Base directory (defaults to `$NAP_DIR` / `~/.nap`)
598
+ * @returns Array of universe names
599
+ */
600
+ export function listUniverses(repoPath) {
601
+ return JSON.parse(native.listUniverses(resolveRepoPath(repoPath)));
602
+ }
603
+ // ═══════════════════════════════════════════════════════════════════════
604
+ // Schema Operations
605
+ // ═══════════════════════════════════════════════════════════════════════
606
+ /**
607
+ * Get the JSON Schema for a NAP manifest.
608
+ *
609
+ * @returns JSON Schema object
610
+ */
611
+ export function manifestSchema() {
612
+ return JSON.parse(native.manifestSchema());
613
+ }
614
+ /**
615
+ * Get the JSON Schema for a NAP commit.
616
+ *
617
+ * @returns JSON Schema object
618
+ */
619
+ export function commitSchema() {
620
+ return JSON.parse(native.commitSchema());
621
+ }
622
+ /**
623
+ * Validate a manifest against the manifest schema.
624
+ *
625
+ * @param manifest - Manifest object
626
+ * @returns Validation result with `valid` flag and optional `errors`
627
+ */
628
+ export function validateManifest(manifest) {
629
+ return JSON.parse(native.validateManifest(JSON.stringify(manifest)));
630
+ }
631
+ /**
632
+ * Validate a commit against the commit schema.
633
+ *
634
+ * @param commit - Commit object
635
+ * @returns Validation result with `valid` flag and optional `errors`
636
+ */
637
+ export function validateCommit(commit) {
638
+ return JSON.parse(native.validateCommit(JSON.stringify(commit)));
639
+ }
640
+ // ═══════════════════════════════════════════════════════════════════════
641
+ // Merge Operations
642
+ // ═══════════════════════════════════════════════════════════════════════
643
+ /**
644
+ * Three-way merge of manifest values.
645
+ *
646
+ * @param schema - The SDL schema document
647
+ * @param base - The base (common ancestor) value
648
+ * @param current - The current value
649
+ * @param proposed - The proposed new value
650
+ * @returns Merge result (either `Merged` or `Conflicts`)
651
+ */
652
+ export function mergeMerge(schema, base, current, proposed) {
653
+ return JSON.parse(native.mergeMerge(JSON.stringify(schema), JSON.stringify(base), JSON.stringify(current), JSON.stringify(proposed)));
654
+ }
655
+ /**
656
+ * Compute the diff between two manifest values.
657
+ *
658
+ * @param base - The base value
659
+ * @param candidate - The candidate value to compare against base
660
+ * @returns Array of change entries describing the differences
661
+ */
662
+ export function mergeDiff(base, candidate) {
663
+ return JSON.parse(native.mergeDiff(JSON.stringify(base), JSON.stringify(candidate)));
664
+ }
665
+ // ═══════════════════════════════════════════════════════════════════════
666
+ // Storage Engine Operations
667
+ // ═══════════════════════════════════════════════════════════════════════
668
+ /**
669
+ * Get the active storage engine configuration.
670
+ *
671
+ * @returns Storage config object
672
+ */
673
+ export function storageConfig() {
674
+ return JSON.parse(native.storageConfig());
18
675
  }
19
676
  /**
20
677
  * Ingest raw media bytes into the content-addressed storage engine.
21
678
  *
22
- * The storage backend is determined by the ``NAP_STORAGE_BACKEND``
23
- * environment variable at the Rust layer (``local`` or ``s3``).
679
+ * The storage backend is determined by the `NAP_STORAGE_BACKEND`
680
+ * environment variable at the Rust layer (`"local"` or `"s3"`).
24
681
  *
25
- * @param data - Raw bytes of the media asset (image, audio, mesh, etc.).
26
- * @param format - File extension without a leading dot (e.g. ``"png"``,
27
- * ``"jpg"``, ``"wav"``, ``"glb"``).
28
- * @returns A Promise resolving to the content-addressed hash ``sha256:<hex>``.
682
+ * @param data - Raw bytes of the media asset (image, audio, mesh, etc.)
683
+ * @param format - File extension without a leading dot (e.g. `"png"`, `"jpg"`, `"wav"`, `"glb"`)
684
+ * @returns Promise resolving to the content hash `sha256:<hex>`
29
685
  */
30
686
  export async function ingestMedia(data, format) {
31
687
  return native.ingestMedia(data, format);
32
688
  }
689
+ // ═══════════════════════════════════════════════════════════════════════
690
+ // VCS / Git Operations
691
+ // ═══════════════════════════════════════════════════════════════════════
692
+ /**
693
+ * Clone a Git repository.
694
+ *
695
+ * @param url - Git remote URL
696
+ * @param destPath - Local destination path
697
+ * @returns Success response
698
+ */
699
+ export function gitClone(url, destPath) {
700
+ return JSON.parse(native.gitClone(url, destPath));
701
+ }
702
+ // ═══════════════════════════════════════════════════════════════════════
703
+ // Version
704
+ // ═══════════════════════════════════════════════════════════════════════
705
+ /**
706
+ * Return the nap-sdk version string.
707
+ */
708
+ export function version() {
709
+ return native.version();
710
+ }