@xnetjs/cli 0.2.1 → 0.3.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.
@@ -0,0 +1,6 @@
1
+ import {
2
+ createLocalAgentBackend
3
+ } from "./chunk-NOYKKZDQ.js";
4
+ export {
5
+ createLocalAgentBackend
6
+ };
@@ -0,0 +1,90 @@
1
+ // src/utils/agent-local.ts
2
+ import { getSigningPublicKeyFromPrivate } from "@xnetjs/crypto";
3
+ import { SQLiteNodeStorageAdapter, builtInSchemas } from "@xnetjs/data";
4
+ import { createDID } from "@xnetjs/identity";
5
+ import { createXNetClient } from "@xnetjs/runtime";
6
+ var toNodeData = (node) => ({
7
+ id: node.id,
8
+ schemaId: node.schemaId,
9
+ properties: node.properties,
10
+ deleted: node.deleted ?? false,
11
+ createdAt: node.createdAt ?? 0,
12
+ updatedAt: node.updatedAt ?? 0
13
+ });
14
+ async function resolveStorage(db) {
15
+ if (db) {
16
+ const { createElectronSQLiteAdapter } = await import("@xnetjs/sqlite/electron");
17
+ const adapter2 = await createElectronSQLiteAdapter({
18
+ path: db,
19
+ busyTimeout: 5e3,
20
+ foreignKeys: true,
21
+ walMode: true
22
+ });
23
+ return new SQLiteNodeStorageAdapter(adapter2);
24
+ }
25
+ const { createMemorySQLiteAdapter } = await import("@xnetjs/sqlite/memory");
26
+ const adapter = await createMemorySQLiteAdapter();
27
+ return new SQLiteNodeStorageAdapter(adapter);
28
+ }
29
+ function builtInSchemaRegistry() {
30
+ const iris = Object.keys(builtInSchemas).filter((iri) => iri.includes("@"));
31
+ return {
32
+ getAllIRIs: () => iris,
33
+ get: async (iri) => {
34
+ const loader = builtInSchemas[iri];
35
+ if (!loader) return null;
36
+ const schema = await loader();
37
+ return {
38
+ iri,
39
+ name: schema.schema.name,
40
+ properties: schema.schema.properties
41
+ };
42
+ }
43
+ };
44
+ }
45
+ async function createLocalAgentBackend(options) {
46
+ const agentDID = createDID(getSigningPublicKeyFromPrivate(options.agentKey));
47
+ const nodeStorage = await resolveStorage(options.db);
48
+ const client = await createXNetClient({
49
+ nodeStorage,
50
+ authorDID: agentDID,
51
+ signingKey: options.agentKey
52
+ });
53
+ const store = {
54
+ get: async (id) => {
55
+ const node = await client.store.get(id);
56
+ return node ? toNodeData(node) : null;
57
+ },
58
+ list: async (opts) => {
59
+ const nodes = await client.store.list({
60
+ ...opts?.schemaId ? { schemaId: opts.schemaId } : {},
61
+ ...opts?.limit !== void 0 ? { limit: opts.limit } : {},
62
+ ...opts?.offset !== void 0 ? { offset: opts.offset } : {}
63
+ });
64
+ return nodes.map(toNodeData);
65
+ },
66
+ create: async (opts) => {
67
+ const node = await client.store.create({
68
+ ...opts.id ? { id: opts.id } : {},
69
+ schemaId: opts.schemaId,
70
+ properties: opts.properties
71
+ });
72
+ return toNodeData(node);
73
+ },
74
+ update: async (id, opts) => {
75
+ const node = await client.store.update(id, { properties: opts.properties });
76
+ return toNodeData(node);
77
+ },
78
+ delete: async (id) => {
79
+ await client.store.delete(id);
80
+ },
81
+ subscribe: (listener) => client.store.subscribe((event) => {
82
+ listener({ change: { type: event.change.type }, node: null, isRemote: false });
83
+ })
84
+ };
85
+ return { store, schemas: builtInSchemaRegistry(), client, agentDID };
86
+ }
87
+
88
+ export {
89
+ createLocalAgentBackend
90
+ };
package/dist/cli.js CHANGED
@@ -4,6 +4,9 @@ import {
4
4
  generateLensCode,
5
5
  generateLensSnippet
6
6
  } from "./chunk-IUOECMVU.js";
7
+ import {
8
+ createLocalAgentBackend
9
+ } from "./chunk-NOYKKZDQ.js";
7
10
 
8
11
  // src/cli.ts
9
12
  import { program } from "commander";
@@ -724,11 +727,82 @@ function registerConnectorCommand(program2) {
724
727
  }
725
728
 
726
729
  // src/commands/data.ts
727
- import { generateSigningKeyPair, getSigningPublicKeyFromPrivate } from "@xnetjs/crypto";
728
- import { defineSchema, SQLiteNodeStorageAdapter, text } from "@xnetjs/data";
730
+ import { generateSigningKeyPair, getSigningPublicKeyFromPrivate, sign } from "@xnetjs/crypto";
731
+ import {
732
+ applyBundle,
733
+ defineSchema,
734
+ SQLiteNodeStorageAdapter,
735
+ text,
736
+ verifyBundle,
737
+ writeBundle
738
+ } from "@xnetjs/data";
729
739
  import { createDID } from "@xnetjs/identity";
730
740
  import { createXNetClient } from "@xnetjs/runtime";
731
741
  import chalk from "chalk";
742
+ import { resolve as resolve5 } from "path";
743
+
744
+ // src/utils/fs-bundle.ts
745
+ import { createReadStream } from "fs";
746
+ import { mkdir as mkdir2, readdir, readFile as readFile2, stat, writeFile } from "fs/promises";
747
+ import { dirname as dirname3, join as join5, relative, sep } from "path";
748
+ import { createInterface } from "readline";
749
+ var FsBundleSink = class {
750
+ constructor(root) {
751
+ this.root = root;
752
+ }
753
+ async writeEntry(path, data) {
754
+ const target = join5(this.root, path);
755
+ await mkdir2(dirname3(target), { recursive: true });
756
+ await writeFile(target, data);
757
+ }
758
+ };
759
+ var FsBundleSource = class {
760
+ constructor(root) {
761
+ this.root = root;
762
+ }
763
+ async readEntry(path) {
764
+ try {
765
+ return new Uint8Array(await readFile2(join5(this.root, path)));
766
+ } catch {
767
+ return null;
768
+ }
769
+ }
770
+ async *readLines(path) {
771
+ const target = join5(this.root, path);
772
+ try {
773
+ await stat(target);
774
+ } catch {
775
+ return;
776
+ }
777
+ const rl = createInterface({ input: createReadStream(target), crlfDelay: Infinity });
778
+ for await (const line of rl) {
779
+ if (line.length > 0) yield line;
780
+ }
781
+ }
782
+ async listEntries(prefix) {
783
+ const results = [];
784
+ const walk = async (dir) => {
785
+ let entries;
786
+ try {
787
+ entries = await readdir(dir, { withFileTypes: true });
788
+ } catch {
789
+ return;
790
+ }
791
+ for (const entry of entries) {
792
+ const full = join5(dir, entry.name);
793
+ if (entry.isDirectory()) await walk(full);
794
+ else {
795
+ const rel = relative(this.root, full).split(sep).join("/");
796
+ if (rel.startsWith(prefix)) results.push(rel);
797
+ }
798
+ }
799
+ };
800
+ await walk(this.root);
801
+ return results.sort();
802
+ }
803
+ };
804
+
805
+ // src/commands/data.ts
732
806
  var NoteSchema = defineSchema({
733
807
  name: "Note",
734
808
  namespace: "xnet://cli/",
@@ -773,6 +847,35 @@ async function runCreateNote(client, input) {
773
847
  async function runListNotes(client) {
774
848
  return client.fetch(NoteSchema);
775
849
  }
850
+ function parseScope(opts) {
851
+ if (opts.space) return { kind: "space", spaceId: opts.space };
852
+ if (opts.schema?.length) return { kind: "schemas", schemaIds: opts.schema };
853
+ if (opts.node?.length) return { kind: "nodes", nodeIds: opts.node };
854
+ return { kind: "full" };
855
+ }
856
+ function printVerifyReport(report) {
857
+ const m = report.manifest;
858
+ if (m) {
859
+ console.log(` format: ${m.formatVersion} (change protocol v${m.protocolVersion.change})`);
860
+ console.log(` owner: ${m.ownerDid}`);
861
+ console.log(` scope: ${JSON.stringify(m.scope)}`);
862
+ console.log(
863
+ ` contents: ${m.counts.changes} changes, ${m.counts.blobs} blobs, ${m.counts.yjsDocs} yjs docs`
864
+ );
865
+ if (m.prerequisites) {
866
+ console.log(
867
+ ` requires: base bundle through lamport ${m.prerequisites.lamport} (incremental)`
868
+ );
869
+ }
870
+ }
871
+ for (const issue of report.issues) {
872
+ const paint = issue.severity === "error" ? chalk.red : chalk.yellow;
873
+ console.log(paint(` ${issue.severity}: [${issue.code}] ${issue.detail}`));
874
+ }
875
+ console.log(
876
+ report.ok ? chalk.green("\u2713 bundle verifies clean") : chalk.red("\u2717 bundle failed verification")
877
+ );
878
+ }
776
879
  function registerDataCommand(program2) {
777
880
  const data = program2.command("data").description("Read and write live nodes (runtime client)");
778
881
  data.command("add").description("Create a Note node").requiredOption("--title <title>", "Note title").option("--body <body>", "Note body", "").option("--db <path>", "SQLite file path (default: in-memory)").option("--key <hex>", "Ed25519 signing key (hex); falls back to $XNET_SIGNING_KEY").action(async (opts) => {
@@ -801,11 +904,123 @@ function registerDataCommand(program2) {
801
904
  await client.destroy();
802
905
  }
803
906
  });
907
+ data.command("export").description("Export the change log as an .xnetpack bundle directory (exploration 0344)").requiredOption("--out <dir>", "Bundle output directory").option("--db <path>", "SQLite file path (default: in-memory)").option("--key <hex>", "Ed25519 signing key (hex); falls back to $XNET_SIGNING_KEY").option("--space <id>", "Export one space (the space node plus its members)").option("--schema <iri...>", "Export nodes of the given schema IRI(s)").option("--node <id...>", "Export the given node id(s)").option("--since-lamport <n>", "Incremental: export changes after this lamport time").action(
908
+ async (opts) => {
909
+ const { signingKey, ephemeral } = resolveSigningKey(opts.key);
910
+ if (ephemeral) {
911
+ console.log(
912
+ chalk.yellow(
913
+ "\u26A0 no signing key provided \u2014 manifest will be signed by an ephemeral identity"
914
+ )
915
+ );
916
+ }
917
+ const client = await buildDataClient({
918
+ db: opts.db,
919
+ key: Buffer.from(signingKey).toString("hex")
920
+ });
921
+ try {
922
+ const scope = parseScope(opts);
923
+ const since = opts.sinceLamport ? { lamport: Number(opts.sinceLamport), heads: [], changeCount: 0 } : void 0;
924
+ const manifest = await writeBundle(client.store, scope, new FsBundleSink(opts.out), {
925
+ ownerDid: client.authorDID,
926
+ manifestSigner: (bytes) => sign(bytes, signingKey),
927
+ since
928
+ });
929
+ console.log(chalk.green(`\u2713 exported ${manifest.counts.changes} changes to ${opts.out}`));
930
+ console.log(chalk.dim(` owner: ${manifest.ownerDid}`));
931
+ console.log(chalk.dim(` frontier lamport: ${manifest.frontier.lamport}`));
932
+ } finally {
933
+ await client.destroy();
934
+ }
935
+ }
936
+ );
937
+ data.command("import").description("Verify and import an .xnetpack bundle directory").requiredOption("--in <dir>", "Bundle directory to import").option("--db <path>", "SQLite file path (default: in-memory)").option("--key <hex>", "Ed25519 signing key (hex); falls back to $XNET_SIGNING_KEY").option("--dry-run", "Verify and report only \u2014 write nothing").option("--allow-foreign-owner", "Import a bundle owned by another identity's DID").option("--allow-unsigned", "Import a bundle whose manifest is unsigned").action(
938
+ async (opts) => {
939
+ const source = new FsBundleSource(opts.in);
940
+ if (opts.dryRun) {
941
+ const report = await verifyBundle(source);
942
+ printVerifyReport(report);
943
+ if (!report.ok) process.exitCode = 1;
944
+ return;
945
+ }
946
+ const client = await buildDataClient({ db: opts.db, key: opts.key });
947
+ try {
948
+ const result = await applyBundle(client.store, source, {
949
+ importerDid: client.authorDID,
950
+ allowForeignOwner: opts.allowForeignOwner,
951
+ allowUnsigned: opts.allowUnsigned
952
+ });
953
+ console.log(
954
+ chalk.green(
955
+ `\u2713 applied ${result.applied} change(s), ${result.duplicates} duplicate(s) skipped`
956
+ )
957
+ );
958
+ if (result.quarantined.length > 0) {
959
+ console.log(chalk.yellow(`\u26A0 ${result.quarantined.length} record(s) quarantined:`));
960
+ for (const q of result.quarantined.slice(0, 20)) {
961
+ console.log(chalk.yellow(` [${q.kind}] ${q.subject}: ${q.reason}`));
962
+ }
963
+ }
964
+ } finally {
965
+ await client.destroy();
966
+ }
967
+ }
968
+ );
969
+ data.command("export-folder").description(
970
+ "Export the workspace as a human-readable folder: Pages/*.md, Databases/*.rows.jsonl,\nCanvases/*.canvas (Tier 2 \u2014 a projection in xNet's markdown dialect: wikilinks and\nschema JSON travel, history/signatures/comments do not; use `export` for the lossless bundle)"
971
+ ).requiredOption("--out <dir>", "Folder to write the projection into").option("--db <path>", "SQLite file path (default: in-memory)").option("--key <hex>", "Ed25519 signing key (hex); falls back to $XNET_SIGNING_KEY").action(async (opts) => {
972
+ const { signingKey } = resolveSigningKey(opts.key);
973
+ const [{ createLocalAgentBackend: createLocalAgentBackend2 }, plugins] = await Promise.all([
974
+ import("./agent-local-XRQV3OKU.js"),
975
+ import("@xnetjs/plugins/node")
976
+ ]);
977
+ const backend = await createLocalAgentBackend2({ db: opts.db, agentKey: signingKey });
978
+ try {
979
+ const aiSurface = plugins.createAiSurfaceService({
980
+ store: backend.store,
981
+ schemas: backend.schemas
982
+ });
983
+ const exporter = plugins.createAiWorkspaceExporter({ ...backend, aiSurface });
984
+ const result = await exporter.exportWorkspace({ rootDir: resolve5(opts.out) });
985
+ console.log(
986
+ chalk.green(`\u2713 exported ${result.manifestEntries.length} file(s) to ${opts.out}`)
987
+ );
988
+ console.log(
989
+ chalk.dim(
990
+ " note: this is a readable projection (markdown + JSONL); history, signatures,\n and comments do not survive \u2014 use `xnet data export` for the lossless bundle"
991
+ )
992
+ );
993
+ } finally {
994
+ await backend.client.destroy();
995
+ }
996
+ });
997
+ data.command("snapshot").description(
998
+ "Write a defragmented SQLite snapshot of the database (VACUUM INTO \u2014 Tier 2:\nmaterialized state for any SQLite tool; use 'export' for the lossless bundle)"
999
+ ).requiredOption("--db <path>", "SQLite file path to snapshot").requiredOption("--sqlite <out>", "Output .sqlite file path").action(async (opts) => {
1000
+ const { createElectronSQLiteAdapter } = await import("@xnetjs/sqlite/electron");
1001
+ const adapter = await createElectronSQLiteAdapter({
1002
+ path: opts.db,
1003
+ busyTimeout: 5e3,
1004
+ foreignKeys: true,
1005
+ walMode: true
1006
+ });
1007
+ try {
1008
+ await adapter.exec(`VACUUM INTO '${opts.sqlite.replace(/'/g, "''")}'`);
1009
+ console.log(chalk.green(`\u2713 snapshot written to ${opts.sqlite}`));
1010
+ console.log(
1011
+ chalk.dim(
1012
+ " note: a snapshot is materialized state (readable by any SQLite tool); it is not\n a signed bundle \u2014 use `xnet data export` for the lossless, verifiable artifact"
1013
+ )
1014
+ );
1015
+ } finally {
1016
+ await adapter.close();
1017
+ }
1018
+ });
804
1019
  }
805
1020
 
806
1021
  // src/commands/doctor.ts
807
1022
  import { writeFileSync as writeFileSync3, readFileSync, existsSync, readdirSync, statSync } from "fs";
808
- import { resolve as resolve5, join as join5 } from "path";
1023
+ import { resolve as resolve6, join as join6 } from "path";
809
1024
  import {
810
1025
  verifyIntegrity,
811
1026
  quickIntegrityCheck,
@@ -835,15 +1050,15 @@ async function getChalk() {
835
1050
  }
836
1051
  function findDataDir(providedDir) {
837
1052
  if (providedDir) {
838
- const resolved = resolve5(process.cwd(), providedDir);
1053
+ const resolved = resolve6(process.cwd(), providedDir);
839
1054
  if (existsSync(resolved)) {
840
1055
  return resolved;
841
1056
  }
842
1057
  throw new Error(`Data directory not found: ${resolved}`);
843
1058
  }
844
- const commonPaths = [".xnet/data", "data", ".data", resolve5(process.env.HOME ?? "", ".xnet/data")];
1059
+ const commonPaths = [".xnet/data", "data", ".data", resolve6(process.env.HOME ?? "", ".xnet/data")];
845
1060
  for (const path of commonPaths) {
846
- const resolved = resolve5(process.cwd(), path);
1061
+ const resolved = resolve6(process.cwd(), path);
847
1062
  if (existsSync(resolved)) {
848
1063
  return resolved;
849
1064
  }
@@ -854,7 +1069,7 @@ function loadChangesFromDir(dataDir) {
854
1069
  const changes = [];
855
1070
  const patterns = ["changes.json", "changes/*.json", "*.changes.json"];
856
1071
  for (const pattern of patterns) {
857
- const changesFile = join5(dataDir, pattern.split("/")[0]);
1072
+ const changesFile = join6(dataDir, pattern.split("/")[0]);
858
1073
  if (existsSync(changesFile) && statSync(changesFile).isFile()) {
859
1074
  try {
860
1075
  const content = readFileSync(changesFile, "utf-8");
@@ -868,12 +1083,12 @@ function loadChangesFromDir(dataDir) {
868
1083
  }
869
1084
  }
870
1085
  }
871
- const changesDir = join5(dataDir, "changes");
1086
+ const changesDir = join6(dataDir, "changes");
872
1087
  if (existsSync(changesDir) && statSync(changesDir).isDirectory()) {
873
1088
  const files = readdirSync(changesDir).filter((f) => f.endsWith(".json"));
874
1089
  for (const file of files) {
875
1090
  try {
876
- const content = readFileSync(join5(changesDir, file), "utf-8");
1091
+ const content = readFileSync(join6(changesDir, file), "utf-8");
877
1092
  const change = JSON.parse(content);
878
1093
  changes.push(change);
879
1094
  } catch {
@@ -1114,7 +1329,7 @@ async function exportCommand(options) {
1114
1329
  dataDir = "";
1115
1330
  changes = generateDemoChanges();
1116
1331
  }
1117
- const outputPath = resolve5(process.cwd(), options.output);
1332
+ const outputPath = resolve6(process.cwd(), options.output);
1118
1333
  console.log(chalk2.gray(`Source: ${dataDir || "demo data"}`));
1119
1334
  console.log(chalk2.gray(`Output: ${outputPath}`));
1120
1335
  console.log();
@@ -1153,7 +1368,7 @@ async function importCommand(options) {
1153
1368
  const chalk2 = await getChalk();
1154
1369
  console.log(chalk2.bold("\nxNet Data Import\n"));
1155
1370
  try {
1156
- const inputPath = resolve5(process.cwd(), options.input);
1371
+ const inputPath = resolve6(process.cwd(), options.input);
1157
1372
  if (!existsSync(inputPath)) {
1158
1373
  console.error(chalk2.red(`Error: Input file not found: ${inputPath}`));
1159
1374
  process.exit(1);
@@ -1236,29 +1451,29 @@ import { agentPassportId } from "@xnetjs/data";
1236
1451
  import { createDID as createDID2, mintAgentPassport } from "@xnetjs/identity";
1237
1452
 
1238
1453
  // src/utils/agent-passport-file.ts
1239
- import { mkdir as mkdir2, readFile as readFile2, writeFile, chmod, readdir } from "fs/promises";
1454
+ import { mkdir as mkdir3, readFile as readFile3, writeFile as writeFile2, chmod, readdir as readdir2 } from "fs/promises";
1240
1455
  import { homedir } from "os";
1241
- import { join as join6 } from "path";
1456
+ import { join as join7 } from "path";
1242
1457
  function agentPassportDir() {
1243
- return process.env.XNET_AGENT_DIR ?? join6(homedir(), ".xnet", "agents");
1458
+ return process.env.XNET_AGENT_DIR ?? join7(homedir(), ".xnet", "agents");
1244
1459
  }
1245
1460
  var passportPath = (name) => {
1246
1461
  if (!/^[a-zA-Z0-9_-]+$/.test(name)) {
1247
1462
  throw new Error(`Invalid agent name: ${name} (use letters, digits, - and _)`);
1248
1463
  }
1249
- return join6(agentPassportDir(), `${name}.json`);
1464
+ return join7(agentPassportDir(), `${name}.json`);
1250
1465
  };
1251
1466
  async function saveAgentPassportFile(file) {
1252
1467
  const dir = agentPassportDir();
1253
- await mkdir2(dir, { recursive: true, mode: 448 });
1468
+ await mkdir3(dir, { recursive: true, mode: 448 });
1254
1469
  const path = passportPath(file.name);
1255
- await writeFile(path, JSON.stringify(file, null, 2) + "\n", { mode: 384 });
1470
+ await writeFile2(path, JSON.stringify(file, null, 2) + "\n", { mode: 384 });
1256
1471
  await chmod(path, 384);
1257
1472
  return path;
1258
1473
  }
1259
1474
  async function loadAgentPassportFile(name) {
1260
1475
  try {
1261
- const raw = await readFile2(passportPath(name), "utf8");
1476
+ const raw = await readFile3(passportPath(name), "utf8");
1262
1477
  return JSON.parse(raw);
1263
1478
  } catch (err) {
1264
1479
  if (err.code === "ENOENT") return null;
@@ -1267,7 +1482,7 @@ async function loadAgentPassportFile(name) {
1267
1482
  }
1268
1483
  async function listAgentPassportNames() {
1269
1484
  try {
1270
- const entries = await readdir(agentPassportDir());
1485
+ const entries = await readdir2(agentPassportDir());
1271
1486
  return entries.filter((e) => e.endsWith(".json")).map((e) => e.slice(0, -5));
1272
1487
  } catch (err) {
1273
1488
  if (err.code === "ENOENT") return [];
@@ -1419,95 +1634,6 @@ import {
1419
1634
  createMCPServer,
1420
1635
  createMcpHttpServer
1421
1636
  } from "@xnetjs/plugins/node";
1422
-
1423
- // src/utils/agent-local.ts
1424
- import { getSigningPublicKeyFromPrivate as getSigningPublicKeyFromPrivate3 } from "@xnetjs/crypto";
1425
- import { SQLiteNodeStorageAdapter as SQLiteNodeStorageAdapter2, builtInSchemas } from "@xnetjs/data";
1426
- import { createDID as createDID3 } from "@xnetjs/identity";
1427
- import { createXNetClient as createXNetClient2 } from "@xnetjs/runtime";
1428
- var toNodeData = (node) => ({
1429
- id: node.id,
1430
- schemaId: node.schemaId,
1431
- properties: node.properties,
1432
- deleted: node.deleted ?? false,
1433
- createdAt: node.createdAt ?? 0,
1434
- updatedAt: node.updatedAt ?? 0
1435
- });
1436
- async function resolveStorage2(db) {
1437
- if (db) {
1438
- const { createElectronSQLiteAdapter } = await import("@xnetjs/sqlite/electron");
1439
- const adapter2 = await createElectronSQLiteAdapter({
1440
- path: db,
1441
- busyTimeout: 5e3,
1442
- foreignKeys: true,
1443
- walMode: true
1444
- });
1445
- return new SQLiteNodeStorageAdapter2(adapter2);
1446
- }
1447
- const { createMemorySQLiteAdapter } = await import("@xnetjs/sqlite/memory");
1448
- const adapter = await createMemorySQLiteAdapter();
1449
- return new SQLiteNodeStorageAdapter2(adapter);
1450
- }
1451
- function builtInSchemaRegistry() {
1452
- const iris = Object.keys(builtInSchemas).filter((iri) => iri.includes("@"));
1453
- return {
1454
- getAllIRIs: () => iris,
1455
- get: async (iri) => {
1456
- const loader = builtInSchemas[iri];
1457
- if (!loader) return null;
1458
- const schema = await loader();
1459
- return {
1460
- iri,
1461
- name: schema.schema.name,
1462
- properties: schema.schema.properties
1463
- };
1464
- }
1465
- };
1466
- }
1467
- async function createLocalAgentBackend(options) {
1468
- const agentDID = createDID3(getSigningPublicKeyFromPrivate3(options.agentKey));
1469
- const nodeStorage = await resolveStorage2(options.db);
1470
- const client = await createXNetClient2({
1471
- nodeStorage,
1472
- authorDID: agentDID,
1473
- signingKey: options.agentKey
1474
- });
1475
- const store = {
1476
- get: async (id) => {
1477
- const node = await client.store.get(id);
1478
- return node ? toNodeData(node) : null;
1479
- },
1480
- list: async (opts) => {
1481
- const nodes = await client.store.list({
1482
- ...opts?.schemaId ? { schemaId: opts.schemaId } : {},
1483
- ...opts?.limit !== void 0 ? { limit: opts.limit } : {},
1484
- ...opts?.offset !== void 0 ? { offset: opts.offset } : {}
1485
- });
1486
- return nodes.map(toNodeData);
1487
- },
1488
- create: async (opts) => {
1489
- const node = await client.store.create({
1490
- ...opts.id ? { id: opts.id } : {},
1491
- schemaId: opts.schemaId,
1492
- properties: opts.properties
1493
- });
1494
- return toNodeData(node);
1495
- },
1496
- update: async (id, opts) => {
1497
- const node = await client.store.update(id, { properties: opts.properties });
1498
- return toNodeData(node);
1499
- },
1500
- delete: async (id) => {
1501
- await client.store.delete(id);
1502
- },
1503
- subscribe: (listener) => client.store.subscribe((event) => {
1504
- listener({ change: { type: event.change.type }, node: null, isRemote: false });
1505
- })
1506
- };
1507
- return { store, schemas: builtInSchemaRegistry(), client, agentDID };
1508
- }
1509
-
1510
- // src/commands/mcp.ts
1511
1637
  var defaultBackendFactory = (options) => createRemoteAgentBackend(options);
1512
1638
  function buildMcpServer(backend, agent) {
1513
1639
  return createMCPServer({
@@ -1626,7 +1752,7 @@ function parseIntOption3(value) {
1626
1752
 
1627
1753
  // src/commands/migrate.ts
1628
1754
  import { writeFileSync as writeFileSync4, readFileSync as readFileSync2, existsSync as existsSync2 } from "fs";
1629
- import { resolve as resolve6 } from "path";
1755
+ import { resolve as resolve7 } from "path";
1630
1756
  async function getChalk2() {
1631
1757
  try {
1632
1758
  const chalk2 = await import("chalk");
@@ -1811,7 +1937,7 @@ async function generateCommand(options) {
1811
1937
  includeTodos: true
1812
1938
  });
1813
1939
  if (options.output) {
1814
- const outputPath = resolve6(process.cwd(), options.output);
1940
+ const outputPath = resolve7(process.cwd(), options.output);
1815
1941
  if (existsSync2(outputPath) && !options.force) {
1816
1942
  console.error(chalk2.red(`Error: File already exists: ${outputPath}`));
1817
1943
  console.error(chalk2.gray("Use --force to overwrite."));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xnetjs/cli",
3
- "version": "0.2.1",
3
+ "version": "0.3.0",
4
4
  "description": "xNet CLI - Schema migrations, diagnostics, and development tools",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -31,15 +31,15 @@
31
31
  "dependencies": {
32
32
  "chalk": "^5.3.0",
33
33
  "commander": "^12.0.0",
34
- "@xnetjs/core": "2.2.0",
35
- "@xnetjs/crypto": "2.2.0",
36
- "@xnetjs/data": "2.2.0",
34
+ "@xnetjs/core": "2.4.0",
35
+ "@xnetjs/crypto": "2.4.0",
36
+ "@xnetjs/data": "2.4.0",
37
37
  "@xnetjs/devkit": "1.0.0",
38
- "@xnetjs/identity": "2.2.0",
39
- "@xnetjs/plugins": "2.2.0",
40
- "@xnetjs/runtime": "0.5.2",
41
- "@xnetjs/sqlite": "2.2.0",
42
- "@xnetjs/sync": "2.2.0"
38
+ "@xnetjs/identity": "2.4.0",
39
+ "@xnetjs/plugins": "2.4.0",
40
+ "@xnetjs/runtime": "0.5.4",
41
+ "@xnetjs/sqlite": "2.4.0",
42
+ "@xnetjs/sync": "2.4.0"
43
43
  },
44
44
  "devDependencies": {
45
45
  "tsup": "^8.0.0",