@sofer_agent/cli 0.3.0 → 0.3.1

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.
@@ -1 +1 @@
1
- {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"AAyCA;;;;;GAKG;AACH,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAsKjD"}
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"AA2BA;;;;;GAKG;AACH,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAkLjD"}
package/dist/init.js CHANGED
@@ -1,22 +1,5 @@
1
+ import { cancel, intro, isCancel, note, outro, password, select, spinner, } from "@clack/prompts";
1
2
  import { AgentClient, agentPaths, generateKeypair, keypairFromSecret, loadConfig, makeSuiClient, provisionMemwal, requestFaucet, shortAgentId, suiBalance, waitForBalance, writePersistedConfig, writeSecret, } from "@sofer_agent/core";
2
- /** Simple spinner that logs to stdout. */
3
- function spin(label, fn) {
4
- process.stdout.write(`${label}… `);
5
- return fn().then((result) => {
6
- console.log("done");
7
- return result;
8
- }, (err) => {
9
- console.log("failed");
10
- throw err;
11
- });
12
- }
13
- async function ask(question) {
14
- const rl = await import("node:readline/promises");
15
- const iface = rl.createInterface({ input: process.stdin, output: process.stdout });
16
- const answer = await iface.question(question);
17
- iface.close();
18
- return answer.trim();
19
- }
20
3
  /**
21
4
  * Interactive init wizard — mint the agent + provision Walrus memory.
22
5
  * Stores config to ~/.sofer/config.json and secrets to ~/.sofer/{sui,brain}.key
@@ -32,37 +15,52 @@ export async function initCommand() {
32
15
  console.log(` sui key: ${agentPaths.suiKey}`);
33
16
  console.log(` brain key: ${agentPaths.brainKey}`);
34
17
  console.log(` agent: ${existing.agentObjectId}`);
35
- console.log(` address: ${existing.memwal.accountId}`);
36
- console.log(`\nRun \`sofer\` to chat. To start fresh, delete ~/.sofer/.`);
18
+ console.log(` memory: ${existing.memwal.accountId}`);
19
+ console.log(`\nRun \`sofer\` to chat. To start fresh, delete ${agentPaths.root}/.`);
37
20
  return;
38
21
  }
39
- console.log("╔══════════════════════════════════════════╗");
40
- console.log("║ sofer init — agent setup ║");
41
- console.log("╚══════════════════════════════════════════╝\n");
22
+ intro("sofer init");
42
23
  // ── 1. Network ─────────────────────────────────────────────────────────
43
- const network = (await ask("Network? [testnet/mainnet] (testnet): ")) || "testnet";
24
+ const network = (await select({
25
+ message: "Which network?",
26
+ options: [
27
+ { value: "testnet", label: "Sui Testnet" },
28
+ { value: "mainnet", label: "Sui Mainnet" },
29
+ ],
30
+ initialValue: "testnet",
31
+ }));
32
+ if (isCancel(network)) {
33
+ cancel("Aborted.");
34
+ return;
35
+ }
44
36
  const net = network === "mainnet" ? "mainnet" : "testnet";
45
- console.log(` → ${net}\n`);
46
37
  // ── 2. Anthropic API key ───────────────────────────────────────────────
47
- const apiKey = await ask("Anthropic API key: ");
48
- if (!apiKey)
49
- throw new Error("ANTHROPIC_API_KEY is required");
50
- console.log(" → saved (encrypted to disk)\n");
38
+ const apiKey = (await password({
39
+ message: "Anthropic API key (stored in ~/.sofer/brain.key, never in .env)",
40
+ mask: "*",
41
+ }));
42
+ if (isCancel(apiKey) || !apiKey) {
43
+ cancel("API key is required.");
44
+ return;
45
+ }
51
46
  // ── 3. Sui wallet ─────────────────────────────────────────────────────
52
47
  const existingSecret = process.env.SOFER_SUI_SECRET_KEY;
48
+ const sGen = spinner();
53
49
  let secret;
54
50
  let address;
55
51
  if (existingSecret) {
52
+ sGen.start("Loading wallet from SOFER_SUI_SECRET_KEY");
56
53
  const kp = keypairFromSecret(existingSecret);
57
54
  secret = existingSecret;
58
55
  address = kp.toSuiAddress();
59
- console.log(` wallet: ${address} (from env)\n`);
56
+ sGen.stop(`wallet: ${address} (from env)`);
60
57
  }
61
58
  else {
59
+ sGen.start("Generating new Sui wallet");
62
60
  const kp = generateKeypair();
63
61
  secret = kp.getSecretKey();
64
62
  address = kp.toSuiAddress();
65
- console.log(` wallet: ${address} (new)\n`);
63
+ sGen.stop(`wallet: ${address} (new)`);
66
64
  }
67
65
  const config = loadConfig();
68
66
  const sui = makeSuiClient(config.network);
@@ -70,82 +68,87 @@ export async function initCommand() {
70
68
  if (net !== "mainnet") {
71
69
  const bal = await suiBalance(sui, address);
72
70
  if (bal === 0n) {
73
- console.log("Requesting testnet faucet…");
71
+ const sFund = spinner();
72
+ sFund.start("Requesting testnet faucet");
74
73
  try {
75
74
  await requestFaucet(config.network, address);
76
75
  await waitForBalance(sui, address, 1n);
77
- console.log("funded\n");
76
+ sFund.stop("funded");
78
77
  }
79
78
  catch (e) {
80
- console.warn(` faucet failed: ${String(e).slice(0, 80)}`);
81
- console.warn(` fund ${address} at https://faucet.sui.io/ and re-run\n`);
79
+ sFund.stop(`faucet failed: ${String(e).slice(0, 80)}`);
80
+ note(`Fund ${address} at https://faucet.sui.io/ and re-run.`, "manual funding needed");
82
81
  }
83
82
  }
84
83
  else {
85
- console.log(` balance: ${(Number(bal) / 1e9).toFixed(4)} SUI\n`);
84
+ note(`${(Number(bal) / 1e9).toFixed(4)} SUI on ${address}`, "wallet balance");
86
85
  }
87
86
  }
88
87
  const agents = new AgentClient(sui, config.packageId);
89
88
  // ── 5. Mint agent ─────────────────────────────────────────────────────
90
- let agentId = config.agentObjectId;
89
+ let agentId = existing.agentObjectId;
91
90
  if (!agentId) {
92
- console.log("Minting agent identity object on-chain…");
91
+ const sMint = spinner();
92
+ sMint.start("Minting agent identity object on-chain");
93
93
  try {
94
94
  const keypair = keypairFromSecret(secret);
95
- const minted = await spin(" minting", () => agents.mint(keypair, "Sofer", "a sovereign AI agent on Sui with encrypted memory on Walrus", new TextEncoder().encode("sofer")));
95
+ const minted = await agents.mint(keypair, "Sofer", "a sovereign AI agent on Sui with encrypted memory on Walrus", new TextEncoder().encode("sofer"));
96
96
  agentId = minted.agentId;
97
- console.log(`agent: ${agentId}\n`);
97
+ sMint.stop(`agent: ${agentId}`);
98
98
  }
99
99
  catch (e) {
100
- console.error(` mint failed: ${String(e).slice(0, 120)}`);
101
- console.error(" (maybe already minted? set SOFER_AGENT_OBJECT_ID and re-run)");
100
+ sMint.stop(`mint failed: ${String(e).slice(0, 120)}`);
101
+ cancel("Mint failed. Is the wallet funded?");
102
102
  return;
103
103
  }
104
104
  }
105
105
  else {
106
- console.log(` reusing agent: ${agentId}\n`);
106
+ note(agentId, "reusing agent");
107
107
  }
108
108
  // ── 6. Provision MemWal memory ────────────────────────────────────────
109
- let accountId = config.memwal.accountId;
110
- let delegateKey = config.memwal.delegateKey;
109
+ let accountId = existing.memwal.accountId;
110
+ let delegateKey = existing.memwal.delegateKey;
111
111
  if (!accountId || !delegateKey) {
112
- console.log("Provisioning Walrus memory (MemWal)…");
112
+ const sMem = spinner();
113
+ sMem.start("Provisioning Walrus memory (MemWal)");
113
114
  try {
114
- const prov = await spin(" provisioning", () => provisionMemwal({
115
+ const prov = await provisionMemwal({
115
116
  ownerSecret: secret,
116
117
  packageId: config.memwal.packageId,
117
118
  registryId: config.memwal.registryId,
118
119
  network: net,
119
120
  label: "sofer-cli",
120
- }));
121
+ });
121
122
  accountId = prov.accountId;
122
123
  delegateKey = prov.delegateKey;
123
- console.log(`account: ${accountId}\n`);
124
+ sMem.stop(`account: ${accountId}`);
124
125
  }
125
126
  catch (e) {
127
+ sMem.stop(`provision failed: ${String(e).slice(0, 120)}`);
126
128
  const msg = String(e);
127
129
  if (msg.includes("abort code: 3") || msg.includes("create_account")) {
128
- throw new Error("This wallet already owns a MemWal account (one per address).\n" +
129
- "Delete ~/.sofer/ and re-run `sofer init`, or set the env vars manually.");
130
+ cancel("This wallet already owns a MemWal account.\nDelete ~/.sofer/ and re-run, or set env vars manually.");
130
131
  }
131
- throw e;
132
+ return;
132
133
  }
133
134
  }
134
135
  else {
135
- console.log(` reusing memory account: ${accountId}\n`);
136
+ note(accountId, "reusing memory account");
136
137
  }
137
138
  // ── 7. Link memory to agent on-chain ───────────────────────────────────
138
- console.log("Linking memory account to agent on-chain…");
139
+ const sLink = spinner();
140
+ sLink.start("Linking memory account to agent on-chain");
139
141
  try {
140
142
  const keypair = keypairFromSecret(secret);
141
- await spin(" linking", () => agents.setMemoryAccount(keypair, agentId, accountId));
142
- console.log("linked\n");
143
+ await agents.setMemoryAccount(keypair, agentId, accountId);
144
+ sLink.stop("linked");
143
145
  }
144
146
  catch (e) {
145
- console.warn(` link failed (may already be linked): ${String(e).slice(0, 80)}\n`);
147
+ sLink.stop(`link failed (may already be linked): ${String(e).slice(0, 80)}`);
146
148
  }
147
149
  // ── 8. Persist config + secrets to ~/.sofer/ ───────────────────────────
148
- console.log("Saving config to ~/.sofer/…");
150
+ const sSave = spinner();
151
+ sSave.start("Saving to ~/.sofer/");
149
152
  writeSecret(agentPaths.suiKey, secret);
150
153
  writeSecret(agentPaths.brainKey, apiKey);
151
154
  const persisted = {
@@ -159,18 +162,16 @@ export async function initCommand() {
159
162
  },
160
163
  };
161
164
  writePersistedConfig(persisted);
162
- const agentDir = agentPaths.agent(shortAgentId(address));
163
- console.log(` config: ${agentPaths.config}`);
164
- console.log(` keys: ${agentPaths.suiKey} / ${agentPaths.brainKey}`);
165
- console.log(` agent: ${agentDir.dir}\n`);
165
+ sSave.stop(`config: ${agentPaths.config}`);
166
166
  // ── 9. Summary ────────────────────────────────────────────────────────
167
- console.log("┌─────────────────────────────────────────┐");
168
- console.log(`│ agent id ${agentId.slice(0, 30)}… │`);
169
- console.log(`│ address ${address.slice(0, 10)}… │`);
170
- console.log(`│ network ${net.padEnd(23)} │`);
171
- console.log(`│ memory ${accountId.slice(0, 10)}… │`);
172
- console.log("├─────────────────────────────────────────┤");
173
- console.log("Run `sofer` to chat with your agent.");
174
- console.log("└─────────────────────────────────────────┘");
167
+ const lines = [
168
+ `agent ${agentId.slice(0, 30)}…`,
169
+ `address ${address.slice(0, 10)}…`,
170
+ `network ${net}`,
171
+ `memory ${accountId.slice(0, 10)}…`,
172
+ "",
173
+ "Run `sofer` to chat with your agent.",
174
+ ];
175
+ outro(lines.join("\n"));
175
176
  }
176
177
  //# sourceMappingURL=init.js.map
package/dist/init.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"init.js","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sofer_agent/cli",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "sofer": "./dist/bin.js"
@@ -25,6 +25,7 @@
25
25
  "cli"
26
26
  ],
27
27
  "dependencies": {
28
+ "@clack/prompts": "^1.5.1",
28
29
  "@sofer_agent/core": "0.3.0"
29
30
  },
30
31
  "devDependencies": {
package/src/init.ts CHANGED
@@ -1,6 +1,15 @@
1
+ import {
2
+ cancel,
3
+ intro,
4
+ isCancel,
5
+ note,
6
+ outro,
7
+ password,
8
+ select,
9
+ spinner,
10
+ } from "@clack/prompts";
1
11
  import {
2
12
  type PersistedConfig,
3
- type SoferConfig,
4
13
  AgentClient,
5
14
  agentPaths,
6
15
  generateKeypair,
@@ -16,29 +25,6 @@ import {
16
25
  writeSecret,
17
26
  } from "@sofer_agent/core";
18
27
 
19
- /** Simple spinner that logs to stdout. */
20
- function spin<T>(label: string, fn: () => Promise<T>): Promise<T> {
21
- process.stdout.write(`${label}… `);
22
- return fn().then(
23
- (result) => {
24
- console.log("done");
25
- return result;
26
- },
27
- (err) => {
28
- console.log("failed");
29
- throw err;
30
- },
31
- );
32
- }
33
-
34
- async function ask(question: string): Promise<string> {
35
- const rl = await import("node:readline/promises");
36
- const iface = rl.createInterface({ input: process.stdin, output: process.stdout });
37
- const answer = await iface.question(question);
38
- iface.close();
39
- return answer.trim();
40
- }
41
-
42
28
  /**
43
29
  * Interactive init wizard — mint the agent + provision Walrus memory.
44
30
  * Stores config to ~/.sofer/config.json and secrets to ~/.sofer/{sui,brain}.key
@@ -54,39 +40,55 @@ export async function initCommand(): Promise<void> {
54
40
  console.log(` sui key: ${agentPaths.suiKey}`);
55
41
  console.log(` brain key: ${agentPaths.brainKey}`);
56
42
  console.log(` agent: ${existing.agentObjectId}`);
57
- console.log(` address: ${existing.memwal.accountId}`);
58
- console.log(`\nRun \`sofer\` to chat. To start fresh, delete ~/.sofer/.`);
43
+ console.log(` memory: ${existing.memwal.accountId}`);
44
+ console.log(`\nRun \`sofer\` to chat. To start fresh, delete ${agentPaths.root}/.`);
59
45
  return;
60
46
  }
61
47
 
62
- console.log("╔══════════════════════════════════════════╗");
63
- console.log("║ sofer init — agent setup ║");
64
- console.log("╚══════════════════════════════════════════╝\n");
48
+ intro("sofer init");
65
49
 
66
50
  // ── 1. Network ─────────────────────────────────────────────────────────
67
- const network = (await ask("Network? [testnet/mainnet] (testnet): ")) || "testnet";
51
+ const network = (await select({
52
+ message: "Which network?",
53
+ options: [
54
+ { value: "testnet", label: "Sui Testnet" },
55
+ { value: "mainnet", label: "Sui Mainnet" },
56
+ ],
57
+ initialValue: "testnet",
58
+ })) as string | symbol;
59
+ if (isCancel(network)) {
60
+ cancel("Aborted.");
61
+ return;
62
+ }
68
63
  const net = network === "mainnet" ? "mainnet" : "testnet";
69
- console.log(` → ${net}\n`);
70
64
 
71
65
  // ── 2. Anthropic API key ───────────────────────────────────────────────
72
- const apiKey = await ask("Anthropic API key: ");
73
- if (!apiKey) throw new Error("ANTHROPIC_API_KEY is required");
74
- console.log(" → saved (encrypted to disk)\n");
66
+ const apiKey = (await password({
67
+ message: "Anthropic API key (stored in ~/.sofer/brain.key, never in .env)",
68
+ mask: "*",
69
+ })) as string | symbol;
70
+ if (isCancel(apiKey) || !apiKey) {
71
+ cancel("API key is required.");
72
+ return;
73
+ }
75
74
 
76
75
  // ── 3. Sui wallet ─────────────────────────────────────────────────────
77
76
  const existingSecret = process.env.SOFER_SUI_SECRET_KEY;
77
+ const sGen = spinner();
78
78
  let secret: string;
79
79
  let address: string;
80
80
  if (existingSecret) {
81
+ sGen.start("Loading wallet from SOFER_SUI_SECRET_KEY");
81
82
  const kp = keypairFromSecret(existingSecret);
82
83
  secret = existingSecret;
83
84
  address = kp.toSuiAddress();
84
- console.log(` wallet: ${address} (from env)\n`);
85
+ sGen.stop(`wallet: ${address} (from env)`);
85
86
  } else {
87
+ sGen.start("Generating new Sui wallet");
86
88
  const kp = generateKeypair();
87
89
  secret = kp.getSecretKey();
88
90
  address = kp.toSuiAddress();
89
- console.log(` wallet: ${address} (new)\n`);
91
+ sGen.stop(`wallet: ${address} (new)`);
90
92
  }
91
93
 
92
94
  const config = loadConfig();
@@ -96,95 +98,94 @@ export async function initCommand(): Promise<void> {
96
98
  if (net !== "mainnet") {
97
99
  const bal = await suiBalance(sui, address);
98
100
  if (bal === 0n) {
99
- console.log("Requesting testnet faucet…");
101
+ const sFund = spinner();
102
+ sFund.start("Requesting testnet faucet");
100
103
  try {
101
104
  await requestFaucet(config.network, address);
102
105
  await waitForBalance(sui, address, 1n);
103
- console.log("funded\n");
106
+ sFund.stop("funded");
104
107
  } catch (e) {
105
- console.warn(` faucet failed: ${String(e).slice(0, 80)}`);
106
- console.warn(` fund ${address} at https://faucet.sui.io/ and re-run\n`);
108
+ sFund.stop(`faucet failed: ${String(e).slice(0, 80)}`);
109
+ note(`Fund ${address} at https://faucet.sui.io/ and re-run.`, "manual funding needed");
107
110
  }
108
111
  } else {
109
- console.log(` balance: ${(Number(bal) / 1e9).toFixed(4)} SUI\n`);
112
+ note(`${(Number(bal) / 1e9).toFixed(4)} SUI on ${address}`, "wallet balance");
110
113
  }
111
114
  }
112
115
 
113
116
  const agents = new AgentClient(sui, config.packageId);
114
117
 
115
118
  // ── 5. Mint agent ─────────────────────────────────────────────────────
116
- let agentId = config.agentObjectId;
119
+ let agentId = existing.agentObjectId;
117
120
  if (!agentId) {
118
- console.log("Minting agent identity object on-chain…");
121
+ const sMint = spinner();
122
+ sMint.start("Minting agent identity object on-chain");
119
123
  try {
120
124
  const keypair = keypairFromSecret(secret);
121
- const minted = await spin(" minting", () =>
122
- agents.mint(
123
- keypair,
124
- "Sofer",
125
- "a sovereign AI agent on Sui with encrypted memory on Walrus",
126
- new TextEncoder().encode("sofer"),
127
- ),
125
+ const minted = await agents.mint(
126
+ keypair,
127
+ "Sofer",
128
+ "a sovereign AI agent on Sui with encrypted memory on Walrus",
129
+ new TextEncoder().encode("sofer"),
128
130
  );
129
131
  agentId = minted.agentId;
130
- console.log(`agent: ${agentId}\n`);
132
+ sMint.stop(`agent: ${agentId}`);
131
133
  } catch (e) {
132
- console.error(` mint failed: ${String(e).slice(0, 120)}`);
133
- console.error(" (maybe already minted? set SOFER_AGENT_OBJECT_ID and re-run)");
134
+ sMint.stop(`mint failed: ${String(e).slice(0, 120)}`);
135
+ cancel("Mint failed. Is the wallet funded?");
134
136
  return;
135
137
  }
136
138
  } else {
137
- console.log(` reusing agent: ${agentId}\n`);
139
+ note(agentId, "reusing agent");
138
140
  }
139
141
 
140
142
  // ── 6. Provision MemWal memory ────────────────────────────────────────
141
- let accountId = config.memwal.accountId;
142
- let delegateKey = config.memwal.delegateKey;
143
+ let accountId = existing.memwal.accountId;
144
+ let delegateKey = existing.memwal.delegateKey;
143
145
  if (!accountId || !delegateKey) {
144
- console.log("Provisioning Walrus memory (MemWal)…");
146
+ const sMem = spinner();
147
+ sMem.start("Provisioning Walrus memory (MemWal)");
145
148
  try {
146
- const prov = await spin(" provisioning", () =>
147
- provisionMemwal({
148
- ownerSecret: secret,
149
- packageId: config.memwal.packageId,
150
- registryId: config.memwal.registryId,
151
- network: net,
152
- label: "sofer-cli",
153
- }),
154
- );
149
+ const prov = await provisionMemwal({
150
+ ownerSecret: secret,
151
+ packageId: config.memwal.packageId,
152
+ registryId: config.memwal.registryId,
153
+ network: net,
154
+ label: "sofer-cli",
155
+ });
155
156
  accountId = prov.accountId;
156
157
  delegateKey = prov.delegateKey;
157
- console.log(`account: ${accountId}\n`);
158
+ sMem.stop(`account: ${accountId}`);
158
159
  } catch (e) {
160
+ sMem.stop(`provision failed: ${String(e).slice(0, 120)}`);
159
161
  const msg = String(e);
160
162
  if (msg.includes("abort code: 3") || msg.includes("create_account")) {
161
- throw new Error(
162
- "This wallet already owns a MemWal account (one per address).\n" +
163
- "Delete ~/.sofer/ and re-run `sofer init`, or set the env vars manually.",
163
+ cancel(
164
+ "This wallet already owns a MemWal account.\nDelete ~/.sofer/ and re-run, or set env vars manually.",
164
165
  );
165
166
  }
166
- throw e;
167
+ return;
167
168
  }
168
169
  } else {
169
- console.log(` reusing memory account: ${accountId}\n`);
170
+ note(accountId, "reusing memory account");
170
171
  }
171
172
 
172
173
  // ── 7. Link memory to agent on-chain ───────────────────────────────────
173
- console.log("Linking memory account to agent on-chain…");
174
+ const sLink = spinner();
175
+ sLink.start("Linking memory account to agent on-chain");
174
176
  try {
175
177
  const keypair = keypairFromSecret(secret);
176
- await spin(" linking", () => agents.setMemoryAccount(keypair, agentId!, accountId!));
177
- console.log("linked\n");
178
+ await agents.setMemoryAccount(keypair, agentId!, accountId!);
179
+ sLink.stop("linked");
178
180
  } catch (e) {
179
- console.warn(` link failed (may already be linked): ${String(e).slice(0, 80)}\n`);
181
+ sLink.stop(`link failed (may already be linked): ${String(e).slice(0, 80)}`);
180
182
  }
181
183
 
182
184
  // ── 8. Persist config + secrets to ~/.sofer/ ───────────────────────────
183
- console.log("Saving config to ~/.sofer/…");
184
-
185
+ const sSave = spinner();
186
+ sSave.start("Saving to ~/.sofer/");
185
187
  writeSecret(agentPaths.suiKey, secret);
186
188
  writeSecret(agentPaths.brainKey, apiKey);
187
-
188
189
  const persisted: PersistedConfig = {
189
190
  network: net,
190
191
  agentObjectId: agentId!,
@@ -196,19 +197,16 @@ export async function initCommand(): Promise<void> {
196
197
  },
197
198
  };
198
199
  writePersistedConfig(persisted);
199
-
200
- const agentDir = agentPaths.agent(shortAgentId(address));
201
- console.log(` config: ${agentPaths.config}`);
202
- console.log(` keys: ${agentPaths.suiKey} / ${agentPaths.brainKey}`);
203
- console.log(` agent: ${agentDir.dir}\n`);
200
+ sSave.stop(`config: ${agentPaths.config}`);
204
201
 
205
202
  // ── 9. Summary ────────────────────────────────────────────────────────
206
- console.log("┌─────────────────────────────────────────┐");
207
- console.log(`│ agent id ${agentId!.slice(0, 30)}… │`);
208
- console.log(`│ address ${address.slice(0, 10)}… │`);
209
- console.log(`│ network ${net.padEnd(23)} │`);
210
- console.log(`│ memory ${accountId!.slice(0, 10)}… │`);
211
- console.log("├─────────────────────────────────────────┤");
212
- console.log("Run `sofer` to chat with your agent.");
213
- console.log("└─────────────────────────────────────────┘");
203
+ const lines = [
204
+ `agent ${agentId!.slice(0, 30)}…`,
205
+ `address ${address.slice(0, 10)}…`,
206
+ `network ${net}`,
207
+ `memory ${accountId!.slice(0, 10)}…`,
208
+ "",
209
+ "Run `sofer` to chat with your agent.",
210
+ ];
211
+ outro(lines.join("\n"));
214
212
  }