@rookdaemon/agora 0.5.8 → 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/dist/cli.js CHANGED
@@ -11,15 +11,21 @@ import {
11
11
  decodeInboundEnvelope,
12
12
  expand,
13
13
  expandInlineReferences,
14
+ exportConfig,
14
15
  getDefaultBootstrapRelay,
16
+ getProfileConfigPath,
17
+ importConfig,
15
18
  initPeerConfig,
19
+ listProfiles,
20
+ loadAgoraConfig,
16
21
  loadPeerConfig,
17
22
  resolveBroadcastName,
23
+ saveAgoraConfig,
18
24
  savePeerConfig,
19
25
  sendToPeer,
20
26
  sendViaRelay,
21
27
  verifyReveal
22
- } from "./chunk-P5EN45ZV.js";
28
+ } from "./chunk-OGFL2NNX.js";
23
29
  import {
24
30
  RelayServer,
25
31
  createEnvelope,
@@ -28,7 +34,7 @@ import {
28
34
 
29
35
  // src/cli.ts
30
36
  import { parseArgs } from "util";
31
- import { existsSync, mkdirSync } from "fs";
37
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
32
38
  import { dirname, resolve } from "path";
33
39
  import { homedir } from "os";
34
40
 
@@ -201,10 +207,7 @@ function getConfigPath(options) {
201
207
  if (options.config) {
202
208
  return resolve(options.config);
203
209
  }
204
- if (process.env.AGORA_CONFIG) {
205
- return resolve(process.env.AGORA_CONFIG);
206
- }
207
- return resolve(homedir(), ".config", "agora", "config.json");
210
+ return getProfileConfigPath(options.profile);
208
211
  }
209
212
  function ensureConfigDir(configPath) {
210
213
  const dir = dirname(configPath);
@@ -670,6 +673,117 @@ function handleStatus(options) {
670
673
  peers: Object.keys(config.peers)
671
674
  }, options.pretty || false);
672
675
  }
676
+ function handleConfigProfiles(options) {
677
+ const profiles = listProfiles();
678
+ if (profiles.length === 0) {
679
+ output({ profiles: [], message: "No profiles found. Run `agora init` first." }, options.pretty || false);
680
+ return;
681
+ }
682
+ output({ profiles }, options.pretty || false);
683
+ }
684
+ function handleConfigExport(options) {
685
+ const configPath = getConfigPath(options);
686
+ if (!existsSync(configPath)) {
687
+ console.error("Error: Config file not found. Run `agora init` first.");
688
+ process.exit(1);
689
+ }
690
+ const config = loadAgoraConfig(configPath);
691
+ const exported = exportConfig(config, { includeIdentity: options["include-identity"] });
692
+ if (options.output) {
693
+ const outPath = resolve(options.output);
694
+ const dir = dirname(outPath);
695
+ if (!existsSync(dir)) {
696
+ mkdirSync(dir, { recursive: true });
697
+ }
698
+ writeFileSync(outPath, JSON.stringify(exported, null, 2) + "\n", "utf-8");
699
+ output({ status: "exported", path: outPath, peerCount: Object.keys(exported.peers).length, includesIdentity: !!exported.identity }, options.pretty || false);
700
+ } else {
701
+ console.log(JSON.stringify(exported, null, 2));
702
+ }
703
+ }
704
+ function handleConfigImport(args, options) {
705
+ if (args.length < 1) {
706
+ console.error("Error: Missing import file. Usage: agora config import <file> [--overwrite-identity] [--overwrite-relay] [--dry-run]");
707
+ process.exit(1);
708
+ }
709
+ const importPath = resolve(args[0]);
710
+ if (!existsSync(importPath)) {
711
+ console.error(`Error: Import file not found: ${importPath}`);
712
+ process.exit(1);
713
+ }
714
+ let incoming;
715
+ try {
716
+ incoming = JSON.parse(readFileSync(importPath, "utf-8"));
717
+ } catch {
718
+ console.error(`Error: Invalid JSON in import file: ${importPath}`);
719
+ process.exit(1);
720
+ }
721
+ if (incoming.version !== 1) {
722
+ console.error(`Error: Unsupported export version: ${incoming.version}`);
723
+ process.exit(1);
724
+ }
725
+ const configPath = getConfigPath(options);
726
+ if (!existsSync(configPath)) {
727
+ ensureConfigDir(configPath);
728
+ initPeerConfig(configPath);
729
+ }
730
+ const config = loadAgoraConfig(configPath);
731
+ const result = importConfig(config, incoming, {
732
+ overwriteIdentity: options["overwrite-identity"],
733
+ overwriteRelay: options["overwrite-relay"]
734
+ });
735
+ if (!options["dry-run"]) {
736
+ saveAgoraConfig(configPath, config);
737
+ }
738
+ output({
739
+ status: options["dry-run"] ? "dry-run" : "imported",
740
+ configPath,
741
+ peersAdded: result.peersAdded.length,
742
+ peersSkipped: result.peersSkipped.length,
743
+ identityImported: result.identityImported,
744
+ relayImported: result.relayImported
745
+ }, options.pretty || false);
746
+ }
747
+ function handlePeersCopy(args, options) {
748
+ if (args.length < 1) {
749
+ console.error("Error: Missing peer name. Usage: agora peers copy <name> --from <profile> --to <profile>");
750
+ console.error(' Profile names: "default" or a named profile. Omit for the current --profile / default.');
751
+ process.exit(1);
752
+ }
753
+ const peerRef = args[0];
754
+ const fromProfile = options.from;
755
+ const toProfile = options.to;
756
+ const fromPath = fromProfile !== void 0 ? getProfileConfigPath(fromProfile) : getConfigPath(options);
757
+ if (!existsSync(fromPath)) {
758
+ console.error(`Error: Source config not found: ${fromPath}`);
759
+ process.exit(1);
760
+ }
761
+ const toPath = toProfile !== void 0 ? getProfileConfigPath(toProfile) : getConfigPath(options);
762
+ if (fromPath === toPath) {
763
+ console.error("Error: Source and target profiles are the same.");
764
+ process.exit(1);
765
+ }
766
+ const sourceConfig = loadPeerConfig(fromPath);
767
+ const resolved = resolvePeerEntry(sourceConfig.peers, peerRef);
768
+ if (!resolved) {
769
+ console.error(`Error: Peer '${peerRef}' not found in source config (${fromPath}).`);
770
+ process.exit(1);
771
+ }
772
+ if (!existsSync(toPath)) {
773
+ ensureConfigDir(toPath);
774
+ initPeerConfig(toPath);
775
+ }
776
+ const targetConfig = loadPeerConfig(toPath);
777
+ targetConfig.peers[resolved.key] = { ...resolved.peer };
778
+ savePeerConfig(toPath, targetConfig);
779
+ output({
780
+ status: "copied",
781
+ peer: resolved.peer.name || resolved.key,
782
+ publicKey: resolved.peer.publicKey,
783
+ from: fromPath,
784
+ to: toPath
785
+ }, options.pretty || false);
786
+ }
673
787
  async function handleAnnounce(options) {
674
788
  void options;
675
789
  console.error("Error: `agora announce` is disabled. Agora now supports strict peer-to-peer only (no all/broadcast).");
@@ -1042,8 +1156,10 @@ async function main() {
1042
1156
  const args = process.argv.slice(2);
1043
1157
  if (args.length === 0) {
1044
1158
  console.error("Usage: agora <command> [options]");
1045
- console.error("Commands: init, whoami, status, peers, announce, send, decode, serve, diagnose, relay, reputation");
1046
- console.error(" peers subcommands: add, list, remove, discover");
1159
+ console.error("Commands: init, whoami, status, peers, config, send, decode, serve, diagnose, relay, reputation");
1160
+ console.error("Global: --profile <name> (or --as <name>) to select a named profile");
1161
+ console.error(" peers subcommands: add, list, remove, discover, copy");
1162
+ console.error(" config subcommands: profiles, export, import");
1047
1163
  console.error(" reputation subcommands: verify, commit, reveal, query");
1048
1164
  process.exit(1);
1049
1165
  }
@@ -1051,7 +1167,17 @@ async function main() {
1051
1167
  args,
1052
1168
  options: {
1053
1169
  config: { type: "string" },
1170
+ profile: { type: "string" },
1171
+ as: { type: "string" },
1054
1172
  pretty: { type: "boolean" },
1173
+ // Config transfer options
1174
+ "include-identity": { type: "boolean" },
1175
+ "overwrite-identity": { type: "boolean" },
1176
+ "overwrite-relay": { type: "boolean" },
1177
+ "dry-run": { type: "boolean" },
1178
+ output: { type: "string" },
1179
+ from: { type: "string" },
1180
+ to: { type: "string" },
1055
1181
  url: { type: "string" },
1056
1182
  token: { type: "string" },
1057
1183
  pubkey: { type: "string" },
@@ -1086,8 +1212,10 @@ async function main() {
1086
1212
  const command = parsed.positionals[0];
1087
1213
  const subcommand = parsed.positionals[1];
1088
1214
  const remainingArgs = parsed.positionals.slice(2);
1215
+ const profileValue = typeof parsed.values.profile === "string" ? parsed.values.profile : typeof parsed.values.as === "string" ? parsed.values.as : void 0;
1089
1216
  const options = {
1090
1217
  config: typeof parsed.values.config === "string" ? parsed.values.config : void 0,
1218
+ profile: profileValue,
1091
1219
  pretty: typeof parsed.values.pretty === "boolean" ? parsed.values.pretty : void 0,
1092
1220
  type: typeof parsed.values.type === "string" ? parsed.values.type : void 0,
1093
1221
  payload: typeof parsed.values.payload === "string" ? parsed.values.payload : void 0,
@@ -1115,7 +1243,14 @@ async function main() {
1115
1243
  outcome: typeof parsed.values.outcome === "string" ? parsed.values.outcome : void 0,
1116
1244
  agent: typeof parsed.values.agent === "string" ? parsed.values.agent : void 0,
1117
1245
  direct: typeof parsed.values.direct === "boolean" ? parsed.values.direct : void 0,
1118
- "relay-only": typeof parsed.values["relay-only"] === "boolean" ? parsed.values["relay-only"] : void 0
1246
+ "relay-only": typeof parsed.values["relay-only"] === "boolean" ? parsed.values["relay-only"] : void 0,
1247
+ "include-identity": typeof parsed.values["include-identity"] === "boolean" ? parsed.values["include-identity"] : void 0,
1248
+ "overwrite-identity": typeof parsed.values["overwrite-identity"] === "boolean" ? parsed.values["overwrite-identity"] : void 0,
1249
+ "overwrite-relay": typeof parsed.values["overwrite-relay"] === "boolean" ? parsed.values["overwrite-relay"] : void 0,
1250
+ "dry-run": typeof parsed.values["dry-run"] === "boolean" ? parsed.values["dry-run"] : void 0,
1251
+ output: typeof parsed.values.output === "string" ? parsed.values.output : void 0,
1252
+ from: typeof parsed.values.from === "string" ? parsed.values.from : void 0,
1253
+ to: typeof parsed.values.to === "string" ? parsed.values.to : void 0
1119
1254
  };
1120
1255
  try {
1121
1256
  switch (command) {
@@ -1149,8 +1284,11 @@ async function main() {
1149
1284
  case "discover":
1150
1285
  await handlePeersDiscover(options);
1151
1286
  break;
1287
+ case "copy":
1288
+ handlePeersCopy(remainingArgs, options);
1289
+ break;
1152
1290
  default:
1153
- console.error("Error: Unknown peers subcommand. Use: add, list, remove, discover");
1291
+ console.error("Error: Unknown peers subcommand. Use: add, list, remove, discover, copy");
1154
1292
  process.exit(1);
1155
1293
  }
1156
1294
  break;
@@ -1166,6 +1304,22 @@ async function main() {
1166
1304
  case "relay":
1167
1305
  await handleRelay(options);
1168
1306
  break;
1307
+ case "config":
1308
+ switch (subcommand) {
1309
+ case "profiles":
1310
+ handleConfigProfiles(options);
1311
+ break;
1312
+ case "export":
1313
+ handleConfigExport(options);
1314
+ break;
1315
+ case "import":
1316
+ handleConfigImport(remainingArgs, options);
1317
+ break;
1318
+ default:
1319
+ console.error("Error: Unknown config subcommand. Use: profiles, export, import");
1320
+ process.exit(1);
1321
+ }
1322
+ break;
1169
1323
  case "reputation":
1170
1324
  switch (subcommand) {
1171
1325
  case "verify":
@@ -1186,7 +1340,7 @@ async function main() {
1186
1340
  }
1187
1341
  break;
1188
1342
  default:
1189
- console.error(`Error: Unknown command '${command}'. Use: init, whoami, status, peers, announce, send, decode, serve, diagnose, relay, reputation`);
1343
+ console.error(`Error: Unknown command '${command}'. Use: init, whoami, status, peers, config, send, decode, serve, diagnose, relay, reputation`);
1190
1344
  process.exit(1);
1191
1345
  }
1192
1346
  } catch (e) {