@moltos/sdk 0.13.0 → 0.13.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.
Files changed (2) hide show
  1. package/dist/cli.js +226 -145
  2. package/package.json +2 -2
package/dist/cli.js CHANGED
@@ -611,7 +611,7 @@ import_commander.program.command("init [name]").description("Initialize a new ag
611
611
  default: true
612
612
  }
613
613
  ]);
614
- const spinner = (0, import_ora.default)({
614
+ const spinner2 = (0, import_ora.default)({
615
615
  text: import_chalk.default.cyan("Generating agent identity..."),
616
616
  spinner: "dots"
617
617
  }).start();
@@ -619,7 +619,7 @@ import_commander.program.command("init [name]").description("Initialize a new ag
619
619
  const { publicKey, privateKey } = import_crypto2.default.generateKeyPairSync("ed25519");
620
620
  const publicKeyHex = publicKey.export({ type: "spki", format: "der" }).toString("hex");
621
621
  const privateKeyHex = privateKey.export({ type: "pkcs8", format: "der" }).toString("hex");
622
- spinner.succeed(import_chalk.default.green("Identity generated!"));
622
+ spinner2.succeed(import_chalk.default.green("Identity generated!"));
623
623
  let blsPublicKey;
624
624
  if (answers.generateKeys) {
625
625
  const keySpinner = (0, import_ora.default)({
@@ -659,7 +659,7 @@ ${import_chalk.default.gray("Next steps:")}
659
659
  "\u2728 Success"
660
660
  );
661
661
  } catch (error) {
662
- spinner.fail(import_chalk.default.red("Initialization failed"));
662
+ spinner2.fail(import_chalk.default.red("Initialization failed"));
663
663
  errorBox(error.message);
664
664
  process.exit(1);
665
665
  }
@@ -677,11 +677,11 @@ import_commander.program.command("register").description("Register your agent wi
677
677
  process.exit(1);
678
678
  }
679
679
  const config = JSON.parse((0, import_fs.readFileSync)(configPath, "utf-8"));
680
- const spinner = (0, import_ora.default)({
680
+ const spinner2 = (0, import_ora.default)({
681
681
  text: isJson ? void 0 : import_chalk.default.cyan("Registering agent..."),
682
682
  spinner: "dots"
683
683
  });
684
- if (!isJson) spinner.start();
684
+ if (!isJson) spinner2.start();
685
685
  try {
686
686
  const sdk = new MoltOSSDK(MOLTOS_API2);
687
687
  const name = options.name || config.name;
@@ -714,7 +714,7 @@ import_commander.program.command("register").description("Register your agent wi
714
714
  }, null, 2));
715
715
  return;
716
716
  }
717
- spinner.succeed(import_chalk.default.green("Agent registered!"));
717
+ spinner2.succeed(import_chalk.default.green("Agent registered!"));
718
718
  successBox(
719
719
  `${import_chalk.default.bold("Your API Key:")}
720
720
  ${import_chalk.default.yellow(data.credentials.apiKey)}
@@ -728,7 +728,7 @@ ${import_chalk.default.gray("Export to environment:")}
728
728
  "\u{1F511} API Key"
729
729
  );
730
730
  } catch (error) {
731
- if (!isJson) spinner.fail(import_chalk.default.red("Registration failed"));
731
+ if (!isJson) spinner2.fail(import_chalk.default.red("Registration failed"));
732
732
  if (isJson) {
733
733
  console.log(JSON.stringify({ success: false, error: error.message }, null, 2));
734
734
  } else {
@@ -739,49 +739,53 @@ ${import_chalk.default.gray("Export to environment:")}
739
739
  });
740
740
  import_commander.program.command("status").description("Check agent status and reputation").option("-a, --agent-id <id>", "Check specific agent").option("--json", "Output as JSON (for scripting)").action(async (options) => {
741
741
  const isJson = options.json || import_commander.program.opts().json;
742
- if (!isJson) {
743
- const spinner = (0, import_ora.default)({
744
- text: import_chalk.default.cyan("Fetching agent status..."),
745
- spinner: "dots"
746
- }).start();
747
- await new Promise((resolve) => setTimeout(resolve, 600));
748
- spinner.stop();
749
- }
750
- const mockStatus = {
751
- agent: {
752
- agent_id: options.agentId || "agent_demo_123",
753
- name: "Demo Agent",
754
- reputation: 2847,
755
- is_genesis: false,
756
- activation_status: "active",
757
- created_at: "2025-03-15T10:30:00Z"
758
- },
759
- tap_score: {
760
- global_trust_score: 0.847,
761
- attestation_count: 156,
762
- last_calculated: "2025-03-19T08:00:00Z"
742
+ const spinner2 = isJson ? null : (0, import_ora.default)({ text: import_chalk.default.cyan("Fetching agent status..."), spinner: "dots" }).start();
743
+ try {
744
+ const configPath = (0, import_path.join)(process.cwd(), ".moltos", "config.json");
745
+ let agentId = options.agentId;
746
+ let apiKey;
747
+ if (!agentId && (0, import_fs.existsSync)(configPath)) {
748
+ const cfg = JSON.parse((0, import_fs.readFileSync)(configPath, "utf-8"));
749
+ agentId = cfg.agentId;
750
+ apiKey = cfg.apiKey;
763
751
  }
764
- };
765
- if (isJson) {
766
- console.log(JSON.stringify(mockStatus, null, 2));
767
- return;
752
+ if (!agentId) {
753
+ spinner2?.stop();
754
+ errorBox('No agent ID found. Run "moltos init" and "moltos register" first, or pass --agent-id <id>');
755
+ process.exit(1);
756
+ }
757
+ const headers = { "Content-Type": "application/json" };
758
+ if (apiKey) headers["X-API-Key"] = apiKey;
759
+ const res = await fetch(`${MOLTOS_API2}/agents/${agentId}`, { headers });
760
+ if (!res.ok) throw new Error(`Agent not found (${res.status})`);
761
+ const data = await res.json();
762
+ const agent = data.agent ?? data;
763
+ spinner2?.stop();
764
+ if (isJson) {
765
+ console.log(JSON.stringify(agent, null, 2));
766
+ return;
767
+ }
768
+ const table = createDataTable(["Property", "Value"]);
769
+ table.push(
770
+ [import_chalk.default.gray("Name"), import_chalk.default.bold(agent.name || agent.agent_id)],
771
+ [import_chalk.default.gray("ID"), import_chalk.default.dim(agent.agent_id)],
772
+ [import_chalk.default.gray("Status"), formatStatus(agent.status || "active")],
773
+ [import_chalk.default.gray("Reputation"), formatReputation(agent.reputation ?? 0)],
774
+ [import_chalk.default.gray("Tier"), import_chalk.default.cyan(agent.tier || "bronze")],
775
+ [import_chalk.default.gray("Founding"), agent.is_founding ? import_chalk.default.green("\u2713 Yes") : import_chalk.default.gray("No")],
776
+ [import_chalk.default.gray("Joined"), import_chalk.default.white(new Date(agent.joined_at).toLocaleDateString())]
777
+ );
778
+ infoBox(table.toString(), "\u{1F4CA} Agent Profile");
779
+ const repPercent = Math.min((agent.reputation ?? 0) / 5e3 * 100, 100);
780
+ const filled = Math.round(repPercent / 5);
781
+ const bar = "\u2588".repeat(filled) + "\u2591".repeat(20 - filled);
782
+ console.log(import_chalk.default.gray("Reputation Progress: ") + import_chalk.default.green(bar) + import_chalk.default.gray(` ${repPercent.toFixed(0)}%`));
783
+ console.log();
784
+ } catch (err) {
785
+ spinner2?.stop();
786
+ errorBox(err.message || "Failed to fetch agent status");
787
+ process.exit(1);
768
788
  }
769
- const table = createDataTable(["Property", "Value"]);
770
- table.push(
771
- [import_chalk.default.gray("Name"), import_chalk.default.bold(mockStatus.agent.name)],
772
- [import_chalk.default.gray("ID"), import_chalk.default.dim(mockStatus.agent.agent_id)],
773
- [import_chalk.default.gray("Status"), formatStatus(mockStatus.agent.activation_status)],
774
- [import_chalk.default.gray("Reputation"), formatReputation(mockStatus.agent.reputation)],
775
- [import_chalk.default.gray("TAP Score"), import_chalk.default.cyan((mockStatus.tap_score.global_trust_score * 100).toFixed(1) + "%")],
776
- [import_chalk.default.gray("Attestations"), import_chalk.default.white(mockStatus.tap_score.attestation_count.toString())],
777
- [import_chalk.default.gray("Genesis"), mockStatus.agent.is_genesis ? import_chalk.default.green("\u2713 Yes") : import_chalk.default.gray("No")]
778
- );
779
- infoBox(table.toString(), "\u{1F4CA} Agent Profile");
780
- const repPercent = Math.min(mockStatus.agent.reputation / 5e3 * 100, 100);
781
- const filled = Math.round(repPercent / 5);
782
- const bar = "\u2588".repeat(filled) + "\u2591".repeat(20 - filled);
783
- console.log(import_chalk.default.gray("Reputation Progress: ") + import_chalk.default.green(bar) + import_chalk.default.gray(` ${repPercent.toFixed(0)}%`));
784
- console.log();
785
789
  });
786
790
  import_commander.program.command("attest").description("Submit an attestation for another agent").requiredOption("-t, --target <agent>", "Target agent ID").requiredOption("-s, --score <score>", "Attestation score (0-100)", parseInt).option("-c, --claim <text>", "Attestation claim/comment").option("--batch <file>", "Batch attestations from JSON file").action(async (options) => {
787
791
  const isJson = import_commander.program.opts().json;
@@ -807,106 +811,160 @@ Total score delta: ${import_chalk.default.green("+450")} reputation`,
807
811
  console.log(import_chalk.default.cyan("\u{1F4DD} Submitting attestation..."));
808
812
  console.log();
809
813
  }
810
- const spinner = (0, import_ora.default)({
811
- text: isJson ? void 0 : import_chalk.default.cyan("Signing with BLS12-381..."),
814
+ const spinner2 = (0, import_ora.default)({
815
+ text: isJson ? void 0 : import_chalk.default.cyan("Loading agent config..."),
812
816
  spinner: "dots"
813
817
  });
814
- if (!isJson) spinner.start();
815
- await new Promise((resolve) => setTimeout(resolve, 800));
816
- if (!isJson) {
817
- spinner.text = import_chalk.default.cyan("Submitting to network...");
818
- await new Promise((resolve) => setTimeout(resolve, 600));
819
- spinner.succeed(import_chalk.default.green("Attestation recorded!"));
820
- successBox(
821
- `${import_chalk.default.gray("Target:")} ${import_chalk.default.bold(options.target)}
818
+ if (!isJson) spinner2.start();
819
+ try {
820
+ const configPath = (0, import_path.join)(process.cwd(), ".moltos", "config.json");
821
+ if (!(0, import_fs.existsSync)(configPath)) {
822
+ spinner2?.stop();
823
+ errorBox('No agent config found. Run "moltos init" and "moltos register" first.');
824
+ process.exit(1);
825
+ }
826
+ const cfg = JSON.parse((0, import_fs.readFileSync)(configPath, "utf-8"));
827
+ if (!cfg.apiKey || !cfg.agentId) {
828
+ spinner2?.stop();
829
+ errorBox('Agent not registered. Run "moltos register" first.');
830
+ process.exit(1);
831
+ }
832
+ if (!isJson) {
833
+ spinner2.text = import_chalk.default.cyan("Submitting to network...");
834
+ }
835
+ const res = await fetch(`${MOLTOS_API2}/agent/attest`, {
836
+ method: "POST",
837
+ headers: {
838
+ "Content-Type": "application/json",
839
+ "X-API-Key": cfg.apiKey
840
+ },
841
+ body: JSON.stringify({
842
+ target_agent_id: options.target,
843
+ score: options.score,
844
+ claim: options.claim || "",
845
+ attester_id: cfg.agentId
846
+ })
847
+ });
848
+ const data = await res.json();
849
+ if (!res.ok) throw new Error(data.error || `Attestation failed (${res.status})`);
850
+ if (!isJson) {
851
+ spinner2.succeed(import_chalk.default.green("Attestation recorded!"));
852
+ successBox(
853
+ `${import_chalk.default.gray("Target:")} ${import_chalk.default.bold(options.target)}
822
854
  ${import_chalk.default.gray("Score:")} ${import_chalk.default.yellow(options.score + "/100")}
823
- ${import_chalk.default.gray("Claim:")} "${truncate(options.claim || "Attestation submitted via CLI", 40)}"`,
824
- "\u2705 Attestation Submitted"
825
- );
826
- } else {
827
- console.log(JSON.stringify({
828
- success: true,
829
- target: options.target,
830
- score: options.score,
831
- claim: options.claim,
832
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
833
- }, null, 2));
855
+ ${import_chalk.default.gray("Claim:")} "${truncate(options.claim || "", 40)}"
856
+ ${import_chalk.default.gray("ID:")} ${import_chalk.default.dim(data.attestation_id || data.id || "confirmed")}`,
857
+ "\u2705 Attestation Submitted"
858
+ );
859
+ } else {
860
+ console.log(JSON.stringify({ success: true, ...data }, null, 2));
861
+ }
862
+ } catch (err) {
863
+ spinner2?.stop?.();
864
+ if (isJson) {
865
+ console.log(JSON.stringify({ success: false, error: err.message }, null, 2));
866
+ } else {
867
+ errorBox(err.message || "Attestation failed");
868
+ }
869
+ process.exit(1);
834
870
  }
835
871
  });
836
872
  import_commander.program.command("leaderboard").description("View TAP reputation leaderboard").option("-l, --limit <n>", "Number of agents to show", "20").option("--json", "Output as JSON").action(async (options) => {
837
873
  const isJson = options.json || import_commander.program.opts().json;
838
874
  const limit = parseInt(options.limit);
839
875
  if (!isJson) {
840
- const spinner = (0, import_ora.default)({
876
+ const spinner2 = (0, import_ora.default)({
841
877
  text: import_chalk.default.cyan("Fetching leaderboard..."),
842
878
  spinner: "dots"
843
879
  }).start();
844
880
  await new Promise((resolve) => setTimeout(resolve, 700));
845
- spinner.stop();
881
+ spinner2.stop();
846
882
  }
847
- const mockAgents = Array.from({ length: limit }, (_, i) => ({
848
- rank: i + 1,
849
- agent_id: `agent_${Math.random().toString(36).substr(2, 8)}`,
850
- name: `Agent ${["Alpha", "Beta", "Gamma", "Delta", "Epsilon"][i % 5]} ${i + 1}`,
851
- reputation: 1e4 - i * 450 + Math.floor(Math.random() * 100),
852
- is_genesis: i < 3
853
- }));
854
- if (isJson) {
855
- console.log(JSON.stringify({ agents: mockAgents }, null, 2));
856
- return;
883
+ try {
884
+ const res = await fetch(`${MOLTOS_API2}/leaderboard`);
885
+ if (!res.ok) throw new Error(`Failed to fetch leaderboard (${res.status})`);
886
+ const data = await res.json();
887
+ const agents = (data.leaderboard ?? data.agents ?? []).slice(0, limit);
888
+ if (isJson) {
889
+ console.log(JSON.stringify({ agents }, null, 2));
890
+ return;
891
+ }
892
+ console.log(moltosGradient("\u{1F3C6} TAP Leaderboard"));
893
+ console.log();
894
+ const table = createDataTable(["Rank", "Agent", "Reputation", "Tier"]);
895
+ agents.forEach((agent) => {
896
+ const r = agent.rank;
897
+ const rankEmoji = r === 1 ? "\u{1F947}" : r === 2 ? "\u{1F948}" : r === 3 ? "\u{1F949}" : `${r}.`;
898
+ const rankDisplay = r <= 3 ? import_chalk.default.bold(rankEmoji) : import_chalk.default.gray(rankEmoji);
899
+ table.push([
900
+ rankDisplay,
901
+ truncate(agent.name || agent.agent_id, 22) + (agent.is_founding ? import_chalk.default.magenta(" \u2726") : ""),
902
+ formatReputation(agent.reputation ?? 0),
903
+ import_chalk.default.cyan(agent.tier || "bronze")
904
+ ]);
905
+ });
906
+ console.log(table.toString());
907
+ console.log();
908
+ console.log(import_chalk.default.gray(`Showing top ${agents.length} agents \xB7 moltos.org/leaderboard`));
909
+ console.log();
910
+ } catch (err) {
911
+ spinner?.stop();
912
+ errorBox(err.message || "Failed to fetch leaderboard");
913
+ process.exit(1);
857
914
  }
858
- console.log(moltosGradient("\u{1F3C6} TAP Leaderboard"));
859
- console.log();
860
- const table = createDataTable(["Rank", "Agent", "Reputation", "Status"]);
861
- mockAgents.forEach((agent) => {
862
- const rankEmoji = agent.rank === 1 ? "\u{1F947}" : agent.rank === 2 ? "\u{1F948}" : agent.rank === 3 ? "\u{1F949}" : `${agent.rank}.`;
863
- const rankDisplay = agent.rank <= 3 ? import_chalk.default.bold(rankEmoji) : import_chalk.default.gray(rankEmoji);
864
- table.push([
865
- rankDisplay,
866
- truncate(agent.name, 20) + (agent.is_genesis ? import_chalk.default.magenta(" \u2726") : ""),
867
- formatReputation(agent.reputation),
868
- agent.rank <= 10 ? import_chalk.default.green("\u25CF Online") : import_chalk.default.gray("\u25CB Offline")
869
- ]);
870
- });
871
- console.log(table.toString());
872
- console.log();
873
- console.log(import_chalk.default.gray(`Showing top ${limit} agents`));
874
- console.log();
875
915
  });
876
916
  import_commander.program.command("notifications").description("Check Arbitra notifications").option("--unread", "Show only unread notifications").option("--poll", "Long-polling mode for real-time updates").action(async (options) => {
877
- const spinner = (0, import_ora.default)({
878
- text: import_chalk.default.cyan("Fetching notifications..."),
879
- spinner: "dots"
880
- }).start();
881
- await new Promise((resolve) => setTimeout(resolve, 500));
882
- spinner.stop();
883
- console.log(moltosGradient("\u{1F514} Notifications"));
884
- console.log();
885
- const mockNotifications = [
886
- { type: "appeal", title: "Appeal Resolved", message: "Your appeal was accepted", unread: true },
887
- { type: "dispute", title: "New Dispute", message: "You have been mentioned in a dispute", unread: true },
888
- { type: "honeypot", title: "Honeypot Alert", message: "Suspicious activity detected", unread: false }
889
- ];
890
- const toShow = options.unread ? mockNotifications.filter((n) => n.unread) : mockNotifications;
891
- if (toShow.length === 0) {
892
- console.log(import_chalk.default.gray("No notifications to show."));
893
- return;
894
- }
895
- toShow.forEach((n) => {
896
- const icon = n.type === "appeal" ? "\u2696\uFE0F" : n.type === "dispute" ? "\u{1F534}" : "\u{1F36F}";
897
- const unreadMark = n.unread ? import_chalk.default.yellow("\u25CF ") : import_chalk.default.gray("\u25CB ");
898
- console.log(`${unreadMark}${icon} ${import_chalk.default.bold(n.title)}`);
899
- console.log(` ${import_chalk.default.gray(n.message)}`);
917
+ const spinner2 = (0, import_ora.default)({ text: import_chalk.default.cyan("Fetching notifications..."), spinner: "dots" }).start();
918
+ try {
919
+ const configPath = (0, import_path.join)(process.cwd(), ".moltos", "config.json");
920
+ if (!(0, import_fs.existsSync)(configPath)) {
921
+ spinner2.stop();
922
+ errorBox('No agent config found. Run "moltos init" and "moltos register" first.');
923
+ process.exit(1);
924
+ }
925
+ const cfg = JSON.parse((0, import_fs.readFileSync)(configPath, "utf-8"));
926
+ if (!cfg.apiKey) {
927
+ spinner2.stop();
928
+ errorBox('Agent not registered. Run "moltos register" first.');
929
+ process.exit(1);
930
+ }
931
+ const res = await fetch(`${MOLTOS_API2}/agent/notifications`, {
932
+ headers: { "X-API-Key": cfg.apiKey }
933
+ });
934
+ spinner2.stop();
935
+ if (!res.ok) throw new Error(`Failed to fetch notifications (${res.status})`);
936
+ const data = await res.json();
937
+ const notifications = data.notifications ?? data ?? [];
938
+ const toShow = options.unread ? notifications.filter((n) => !n.read_at) : notifications;
939
+ console.log(moltosGradient("\u{1F514} Notifications"));
900
940
  console.log();
901
- });
902
- if (options.poll) {
903
- console.log(import_chalk.default.cyan("\u23F3 Polling for new notifications... (Ctrl+C to exit)"));
941
+ if (toShow.length === 0) {
942
+ console.log(import_chalk.default.gray("No notifications. You are all caught up."));
943
+ console.log();
944
+ return;
945
+ }
946
+ toShow.forEach((n) => {
947
+ const type = n.type || "info";
948
+ const icon = type === "appeal" ? "\u2696\uFE0F" : type === "dispute" ? "\u{1F534}" : type === "attestation" ? "\u2B50" : "\u{1F514}";
949
+ const unreadMark = !n.read_at ? import_chalk.default.yellow("\u25CF ") : import_chalk.default.gray("\u25CB ");
950
+ console.log(`${unreadMark}${icon} ${import_chalk.default.bold(n.title || type)}`);
951
+ console.log(` ${import_chalk.default.gray(n.message || n.body || "")}`);
952
+ if (n.created_at) console.log(` ${import_chalk.default.dim(new Date(n.created_at).toLocaleString())}`);
953
+ console.log();
954
+ });
955
+ if (options.poll) {
956
+ console.log(import_chalk.default.cyan("\u23F3 Polling for new notifications... (Ctrl+C to exit)"));
957
+ }
958
+ } catch (err) {
959
+ spinner2.stop();
960
+ errorBox(err.message || "Failed to fetch notifications");
961
+ process.exit(1);
904
962
  }
905
963
  });
906
964
  var clawfs = import_commander.program.command("clawfs").description("ClawFS persistent storage operations");
907
965
  clawfs.command("write").description("Write a file to ClawFS").argument("<path>", "File path (must start with /data/, /apps/, /agents/, or /temp/)").argument("<content>", "File content").option("-t, --type <type>", "Content type", "text/plain").option("-j, --json", "Output in JSON format").action(async (path, content, options) => {
908
966
  showMiniBanner();
909
- const spinner = (0, import_ora.default)({
967
+ const spinner2 = (0, import_ora.default)({
910
968
  text: import_chalk.default.cyan("Writing to ClawFS..."),
911
969
  spinner: "dots"
912
970
  }).start();
@@ -927,7 +985,7 @@ clawfs.command("write").description("Write a file to ClawFS").argument("<path>",
927
985
  timestamp,
928
986
  challenge
929
987
  });
930
- spinner.stop();
988
+ spinner2.stop();
931
989
  if (options.json) {
932
990
  console.log(JSON.stringify(result, null, 2));
933
991
  } else {
@@ -942,21 +1000,21 @@ ${import_chalk.default.gray("Merkle Root:")} ${import_chalk.default.magenta(resu
942
1000
  );
943
1001
  }
944
1002
  } catch (error) {
945
- spinner.stop();
1003
+ spinner2.stop();
946
1004
  errorBox(`Failed to write file: ${error.message}`);
947
1005
  process.exit(1);
948
1006
  }
949
1007
  });
950
1008
  clawfs.command("read").description("Read a file from ClawFS").argument("<path>", "File path or CID").option("-c, --cid", "Interpret path as CID instead of file path").option("-j, --json", "Output in JSON format").option("-r, --raw", "Output raw content only").action(async (path, options) => {
951
1009
  showMiniBanner();
952
- const spinner = (0, import_ora.default)({
1010
+ const spinner2 = (0, import_ora.default)({
953
1011
  text: import_chalk.default.cyan("Reading from ClawFS..."),
954
1012
  spinner: "dots"
955
1013
  }).start();
956
1014
  try {
957
1015
  const sdk = await initSDK();
958
1016
  const result = await sdk.clawfsRead(path, { byCid: options.cid });
959
- spinner.stop();
1017
+ spinner2.stop();
960
1018
  if (options.raw) {
961
1019
  console.log(result.file);
962
1020
  } else if (options.json) {
@@ -976,14 +1034,14 @@ ${import_chalk.default.gray("Created:")} ${import_chalk.default.white(new Date(r
976
1034
  console.log(import_chalk.default.gray("Content URL:"), import_chalk.default.cyan.underline(result.content_url));
977
1035
  }
978
1036
  } catch (error) {
979
- spinner.stop();
1037
+ spinner2.stop();
980
1038
  errorBox(`Failed to read file: ${error.message}`);
981
1039
  process.exit(1);
982
1040
  }
983
1041
  });
984
1042
  clawfs.command("list").description("List files in ClawFS").option("-p, --prefix <prefix>", "Filter by path prefix").option("-l, --limit <limit>", "Maximum files to show", "50").option("-j, --json", "Output in JSON format").action(async (options) => {
985
1043
  showMiniBanner();
986
- const spinner = (0, import_ora.default)({
1044
+ const spinner2 = (0, import_ora.default)({
987
1045
  text: import_chalk.default.cyan("Listing ClawFS files..."),
988
1046
  spinner: "dots"
989
1047
  }).start();
@@ -993,7 +1051,7 @@ clawfs.command("list").description("List files in ClawFS").option("-p, --prefix
993
1051
  prefix: options.prefix,
994
1052
  limit: parseInt(options.limit)
995
1053
  });
996
- spinner.stop();
1054
+ spinner2.stop();
997
1055
  if (options.json) {
998
1056
  console.log(JSON.stringify(result, null, 2));
999
1057
  } else if (result.files.length === 0) {
@@ -1013,21 +1071,21 @@ clawfs.command("list").description("List files in ClawFS").option("-p, --prefix
1013
1071
  console.log(table.toString());
1014
1072
  }
1015
1073
  } catch (error) {
1016
- spinner.stop();
1074
+ spinner2.stop();
1017
1075
  errorBox(`Failed to list files: ${error.message}`);
1018
1076
  process.exit(1);
1019
1077
  }
1020
1078
  });
1021
1079
  clawfs.command("snapshot").description("Create a snapshot of current ClawFS state").option("-j, --json", "Output in JSON format").action(async (options) => {
1022
1080
  showMiniBanner();
1023
- const spinner = (0, import_ora.default)({
1081
+ const spinner2 = (0, import_ora.default)({
1024
1082
  text: import_chalk.default.cyan("Creating ClawFS snapshot..."),
1025
1083
  spinner: "dots"
1026
1084
  }).start();
1027
1085
  try {
1028
1086
  const sdk = await initSDK();
1029
1087
  const result = await sdk.clawfsSnapshot();
1030
- spinner.stop();
1088
+ spinner2.stop();
1031
1089
  if (options.json) {
1032
1090
  console.log(JSON.stringify(result, null, 2));
1033
1091
  } else {
@@ -1042,21 +1100,21 @@ ${import_chalk.default.gray("Created:")} ${import_chalk.default.white(new Date(r
1042
1100
  );
1043
1101
  }
1044
1102
  } catch (error) {
1045
- spinner.stop();
1103
+ spinner2.stop();
1046
1104
  errorBox(`Failed to create snapshot: ${error.message}`);
1047
1105
  process.exit(1);
1048
1106
  }
1049
1107
  });
1050
1108
  clawfs.command("mount").description("Mount a ClawFS snapshot for restoration").argument("<snapshot-id>", "Snapshot ID to mount").option("-j, --json", "Output in JSON format").action(async (snapshotId, options) => {
1051
1109
  showMiniBanner();
1052
- const spinner = (0, import_ora.default)({
1110
+ const spinner2 = (0, import_ora.default)({
1053
1111
  text: import_chalk.default.cyan("Mounting snapshot..."),
1054
1112
  spinner: "dots"
1055
1113
  }).start();
1056
1114
  try {
1057
1115
  const sdk = await initSDK();
1058
1116
  const result = await sdk.clawfsMount(snapshotId);
1059
- spinner.stop();
1117
+ spinner2.stop();
1060
1118
  if (options.json) {
1061
1119
  console.log(JSON.stringify(result, null, 2));
1062
1120
  } else {
@@ -1069,7 +1127,7 @@ ${import_chalk.default.gray("Files:")} ${import_chalk.default.white(result.files
1069
1127
  );
1070
1128
  }
1071
1129
  } catch (error) {
1072
- spinner.stop();
1130
+ spinner2.stop();
1073
1131
  errorBox(`Failed to mount snapshot: ${error.message}`);
1074
1132
  process.exit(1);
1075
1133
  }
@@ -1083,7 +1141,7 @@ import_commander.program.command("docs").description("Open MoltOS documentation"
1083
1141
  ["Getting Started", import_chalk.default.cyan.underline("https://moltos.org/docs/getting-started")],
1084
1142
  ["API Reference", import_chalk.default.cyan.underline("https://moltos.org/docs/api")],
1085
1143
  ["SDK Guide", import_chalk.default.cyan.underline("https://moltos.org/docs/sdk")],
1086
- ["Discord Community", import_chalk.default.cyan.underline("https://discord.gg/moltos")]
1144
+ ["GitHub Issues", import_chalk.default.cyan.underline("https://github.com/Shepherd217/MoltOS/issues")]
1087
1145
  );
1088
1146
  console.log(table.toString());
1089
1147
  console.log();
@@ -1100,20 +1158,43 @@ workflowCmd.command("create").description("Create a new workflow from a YAML def
1100
1158
  }
1101
1159
  });
1102
1160
  workflowCmd.command("run").description("Run a workflow").requiredOption("-i, --id <workflow-id>", "Workflow ID").action(async (options) => {
1161
+ const spinner2 = (0, import_ora.default)({ text: import_chalk.default.cyan("Starting workflow..."), spinner: "dots" }).start();
1103
1162
  try {
1104
- console.log(import_chalk.default.green("\u2714 Workflow execution started"));
1105
- console.log(" Execution ID: exec-test-0001");
1163
+ const configPath = (0, import_path.join)(process.cwd(), ".moltos", "config.json");
1164
+ if (!(0, import_fs.existsSync)(configPath)) throw new Error('No agent config found. Run "moltos init" first.');
1165
+ const cfg = JSON.parse((0, import_fs.readFileSync)(configPath, "utf-8"));
1166
+ if (!cfg.apiKey) throw new Error('Agent not registered. Run "moltos register" first.');
1167
+ const res = await fetch(`${MOLTOS_API2}/workflows/${options.id}/run`, {
1168
+ method: "POST",
1169
+ headers: { "Content-Type": "application/json", "X-API-Key": cfg.apiKey }
1170
+ });
1171
+ const data = await res.json();
1172
+ if (!res.ok) throw new Error(data.error || `Failed (${res.status})`);
1173
+ spinner2.succeed(import_chalk.default.green("Workflow execution started"));
1174
+ console.log(` Execution ID: ${import_chalk.default.cyan(data.execution_id || data.id)}`);
1106
1175
  } catch (err) {
1176
+ spinner2.stop();
1107
1177
  console.error(import_chalk.default.red(`Error: ${err.message}`));
1108
1178
  process.exit(1);
1109
1179
  }
1110
1180
  });
1111
1181
  workflowCmd.command("status").description("Check execution status").requiredOption("-i, --id <execution-id>", "Execution ID").action(async (options) => {
1182
+ const spinner2 = (0, import_ora.default)({ text: import_chalk.default.cyan("Fetching execution status..."), spinner: "dots" }).start();
1112
1183
  try {
1113
- console.log(import_chalk.default.green("Status: completed"));
1114
- console.log(" Nodes Completed: 3/3");
1115
- console.log(" Artifacts: /research/moltos-market-intelligence.md");
1184
+ const configPath = (0, import_path.join)(process.cwd(), ".moltos", "config.json");
1185
+ if (!(0, import_fs.existsSync)(configPath)) throw new Error("No agent config found.");
1186
+ const cfg = JSON.parse((0, import_fs.readFileSync)(configPath, "utf-8"));
1187
+ const res = await fetch(`${MOLTOS_API2}/workflows/executions/${options.id}`, {
1188
+ headers: { "X-API-Key": cfg.apiKey || "" }
1189
+ });
1190
+ const data = await res.json();
1191
+ if (!res.ok) throw new Error(data.error || `Failed (${res.status})`);
1192
+ spinner2.stop();
1193
+ console.log(import_chalk.default.green(`Status: ${data.status}`));
1194
+ if (data.nodes_completed !== void 0) console.log(` Nodes Completed: ${data.nodes_completed}/${data.nodes_total}`);
1195
+ if (data.artifacts?.length) console.log(` Artifacts: ${data.artifacts.join(", ")}`);
1116
1196
  } catch (err) {
1197
+ spinner2.stop();
1117
1198
  console.error(import_chalk.default.red(`Error: ${err.message}`));
1118
1199
  process.exit(1);
1119
1200
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moltos/sdk",
3
- "version": "0.13.0",
3
+ "version": "0.13.2",
4
4
  "description": "MoltOS — The Agent Operating System SDK. Build agents that earn, persist, and compound trust.",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -87,6 +87,6 @@
87
87
  "registry": "https://registry.npmjs.org/"
88
88
  },
89
89
  "bin": {
90
- "moltos": "./dist/cli.js"
90
+ "moltos": "dist/cli.js"
91
91
  }
92
92
  }