spora 0.7.0 → 0.7.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.
Files changed (103) hide show
  1. package/README.md +7 -5
  2. package/dist/autonomy-DAV7X6QS.js +19 -0
  3. package/dist/{chunk-53YLFYJF.js → chunk-3RYCUGXE.js} +6 -2
  4. package/dist/chunk-3RYCUGXE.js.map +1 -0
  5. package/dist/{chunk-AH7HPXYC.js → chunk-AOQ3WLZV.js} +153 -143
  6. package/dist/chunk-AOQ3WLZV.js.map +1 -0
  7. package/dist/chunk-E5NR6HT4.js +29 -0
  8. package/dist/chunk-E5NR6HT4.js.map +1 -0
  9. package/dist/{chunk-EBO4F5NU.js → chunk-JBYZ7K56.js} +2 -2
  10. package/dist/chunk-KWWAIS3C.js +180 -0
  11. package/dist/chunk-KWWAIS3C.js.map +1 -0
  12. package/dist/{chunk-UINSD4FT.js → chunk-LXQNVVIY.js} +6 -6
  13. package/dist/{chunk-UINSD4FT.js.map → chunk-LXQNVVIY.js.map} +1 -1
  14. package/dist/{chunk-AIEXQCQS.js → chunk-M6YOQVSI.js} +2 -2
  15. package/dist/{chunk-B6RPMDML.js → chunk-NO3NQN67.js} +16 -6
  16. package/dist/chunk-NO3NQN67.js.map +1 -0
  17. package/dist/{chunk-QOKQ5OTU.js → chunk-NPV3OV2K.js} +3 -14
  18. package/dist/chunk-NPV3OV2K.js.map +1 -0
  19. package/dist/{chunk-SBQILQCJ.js → chunk-OACD3HGE.js} +7 -7
  20. package/dist/{chunk-UM57WU5I.js → chunk-P6KZIJYL.js} +2 -2
  21. package/dist/{chunk-AHXZIGQE.js → chunk-T7L2L7ZL.js} +2 -2
  22. package/dist/{chunk-ZJZKH7N7.js → chunk-VZBHRUZS.js} +2 -2
  23. package/dist/chunk-VZBHRUZS.js.map +1 -0
  24. package/dist/chunk-WIK74GGJ.js +295 -0
  25. package/dist/chunk-WIK74GGJ.js.map +1 -0
  26. package/dist/{chunk-YLJVFCT4.js → chunk-WN35MRMF.js} +2 -2
  27. package/dist/cli.js +168 -137
  28. package/dist/cli.js.map +1 -1
  29. package/dist/client-57BQKVYF.js +337 -0
  30. package/dist/client-57BQKVYF.js.map +1 -0
  31. package/dist/{colony-LCWN5IAN.js → colony-JPZC3R34.js} +7 -7
  32. package/dist/{config-TFAFYSIW.js → config-FL4VJVKZ.js} +3 -3
  33. package/dist/{crypto-FHSQ72NU.js → crypto-NOXNL4GP.js} +3 -3
  34. package/dist/{goals-5TAPXNR2.js → goals-RBKLMILE.js} +3 -3
  35. package/dist/{heartbeat-ZHRCEMF5.js → heartbeat-TNEPE3ZP.js} +83 -88
  36. package/dist/heartbeat-TNEPE3ZP.js.map +1 -0
  37. package/dist/{identity-O4FLSZKZ.js → identity-VDUW4I2K.js} +3 -3
  38. package/dist/{init-G3WINLAP.js → init-ISSXETHY.js} +59 -46
  39. package/dist/init-ISSXETHY.js.map +1 -0
  40. package/dist/llm-T33QTPVW.js +22 -0
  41. package/dist/mcp-server.js +28 -28
  42. package/dist/mcp-server.js.map +1 -1
  43. package/dist/{memory-O3AJIKBX.js → memory-OIAH33G2.js} +3 -3
  44. package/dist/{memory-7FBE26K3.js → memory-PNW7SX7A.js} +3 -3
  45. package/dist/{paths-5GFUUHCZ.js → paths-BYR6MEPR.js} +2 -2
  46. package/dist/prompt-builder-5NYONN2W.js +23 -0
  47. package/dist/queue-G5PTE6R6.js +14 -0
  48. package/dist/{strategy-S45TX766.js → strategy-Z4JSFHSP.js} +3 -3
  49. package/dist/{web-chat-RQIILEQK.js → web-chat-3HM35XM4.js} +31 -80
  50. package/dist/web-chat-3HM35XM4.js.map +1 -0
  51. package/dist/x-client-GY6XSPK6.js +12 -0
  52. package/package.json +1 -1
  53. package/dist/account-creator-ZD643X3Z.js +0 -498
  54. package/dist/account-creator-ZD643X3Z.js.map +0 -1
  55. package/dist/chunk-535NMUUW.js +0 -96
  56. package/dist/chunk-535NMUUW.js.map +0 -1
  57. package/dist/chunk-53YLFYJF.js.map +0 -1
  58. package/dist/chunk-55XPDJ6P.js +0 -124
  59. package/dist/chunk-55XPDJ6P.js.map +0 -1
  60. package/dist/chunk-AH7HPXYC.js.map +0 -1
  61. package/dist/chunk-B6RPMDML.js.map +0 -1
  62. package/dist/chunk-E6GMS76S.js +0 -154
  63. package/dist/chunk-E6GMS76S.js.map +0 -1
  64. package/dist/chunk-JJZ7T2IZ.js +0 -32
  65. package/dist/chunk-JJZ7T2IZ.js.map +0 -1
  66. package/dist/chunk-QOKQ5OTU.js.map +0 -1
  67. package/dist/chunk-TF2XYGGG.js +0 -249
  68. package/dist/chunk-TF2XYGGG.js.map +0 -1
  69. package/dist/chunk-ZJZKH7N7.js.map +0 -1
  70. package/dist/client-B6NGVRHM.js +0 -381
  71. package/dist/client-B6NGVRHM.js.map +0 -1
  72. package/dist/client-DDCS5FJS.js +0 -412
  73. package/dist/client-DDCS5FJS.js.map +0 -1
  74. package/dist/decision-engine-DRPIZLHI.js +0 -19
  75. package/dist/heartbeat-ZHRCEMF5.js.map +0 -1
  76. package/dist/init-G3WINLAP.js.map +0 -1
  77. package/dist/llm-3LSNADSR.js +0 -16
  78. package/dist/prompt-builder-U2J4H7YX.js +0 -24
  79. package/dist/queue-USY7JXDV.js +0 -14
  80. package/dist/research-TQLP42BC.js +0 -13
  81. package/dist/web-chat-RQIILEQK.js.map +0 -1
  82. package/dist/x-client-TYU5QSLG.js +0 -12
  83. package/dist/x-client-TYU5QSLG.js.map +0 -1
  84. /package/dist/{config-TFAFYSIW.js.map → autonomy-DAV7X6QS.js.map} +0 -0
  85. /package/dist/{chunk-EBO4F5NU.js.map → chunk-JBYZ7K56.js.map} +0 -0
  86. /package/dist/{chunk-AIEXQCQS.js.map → chunk-M6YOQVSI.js.map} +0 -0
  87. /package/dist/{chunk-SBQILQCJ.js.map → chunk-OACD3HGE.js.map} +0 -0
  88. /package/dist/{chunk-UM57WU5I.js.map → chunk-P6KZIJYL.js.map} +0 -0
  89. /package/dist/{chunk-AHXZIGQE.js.map → chunk-T7L2L7ZL.js.map} +0 -0
  90. /package/dist/{chunk-YLJVFCT4.js.map → chunk-WN35MRMF.js.map} +0 -0
  91. /package/dist/{colony-LCWN5IAN.js.map → colony-JPZC3R34.js.map} +0 -0
  92. /package/dist/{crypto-FHSQ72NU.js.map → config-FL4VJVKZ.js.map} +0 -0
  93. /package/dist/{decision-engine-DRPIZLHI.js.map → crypto-NOXNL4GP.js.map} +0 -0
  94. /package/dist/{goals-5TAPXNR2.js.map → goals-RBKLMILE.js.map} +0 -0
  95. /package/dist/{identity-O4FLSZKZ.js.map → identity-VDUW4I2K.js.map} +0 -0
  96. /package/dist/{llm-3LSNADSR.js.map → llm-T33QTPVW.js.map} +0 -0
  97. /package/dist/{memory-7FBE26K3.js.map → memory-OIAH33G2.js.map} +0 -0
  98. /package/dist/{memory-O3AJIKBX.js.map → memory-PNW7SX7A.js.map} +0 -0
  99. /package/dist/{paths-5GFUUHCZ.js.map → paths-BYR6MEPR.js.map} +0 -0
  100. /package/dist/{prompt-builder-U2J4H7YX.js.map → prompt-builder-5NYONN2W.js.map} +0 -0
  101. /package/dist/{queue-USY7JXDV.js.map → queue-G5PTE6R6.js.map} +0 -0
  102. /package/dist/{research-TQLP42BC.js.map → strategy-Z4JSFHSP.js.map} +0 -0
  103. /package/dist/{strategy-S45TX766.js.map → x-client-GY6XSPK6.js.map} +0 -0
package/dist/cli.js CHANGED
@@ -1,7 +1,4 @@
1
1
  #!/usr/bin/env node
2
- import {
3
- loadConfig
4
- } from "./chunk-B6RPMDML.js";
5
2
  import {
6
3
  FRAMEWORKS,
7
4
  GOAL_PRESETS,
@@ -11,11 +8,14 @@ import {
11
8
  mutateIdentity,
12
9
  renderIdentityDocument,
13
10
  saveIdentity
14
- } from "./chunk-AIEXQCQS.js";
11
+ } from "./chunk-M6YOQVSI.js";
12
+ import {
13
+ loadConfig
14
+ } from "./chunk-NO3NQN67.js";
15
15
  import {
16
16
  hasXCredentials,
17
17
  sporaExists
18
- } from "./chunk-53YLFYJF.js";
18
+ } from "./chunk-3RYCUGXE.js";
19
19
 
20
20
  // src/cli.ts
21
21
  import { Command } from "commander";
@@ -30,100 +30,40 @@ var BANNER = `
30
30
  `;
31
31
  var program = new Command();
32
32
  program.name("spora").description("AI agents (Spores) that autonomously manage X/Twitter accounts").version("0.1.6");
33
- program.command("init").description("Set up X account credentials for your Spore").option("--token <token>", "Connection token from spora.dev for auto-connect").option("--method <method>", "Connection method: create | browser | api").option("--username <username>", "X username (without @)").option("--password <password>", "X password").option("--email <email>", "Email associated with X account").option("--account-name <name>", "Name for the new X account (create mode)").option("--api-key <key>", "X API Key (api mode)").option("--api-secret <secret>", "X API Secret (api mode)").option("--access-token <token>", "X Access Token (api mode)").option("--access-token-secret <secret>", "X Access Token Secret (api mode)").option("--bearer-token <token>", "X Bearer Token (api mode)").option("--api-tier <tier>", "X API tier: free | basic (api mode)").action(async (opts) => {
33
+ program.command("init").description("Set up X account credentials for your Spore").option("--token <token>", "Connection token from spora.dev for auto-connect").option("--method <method>", "Connection method (api only)").option("--api-key <key>", "X API Key (api mode)").option("--api-secret <secret>", "X API Secret (api mode)").option("--access-token <token>", "X Access Token (api mode)").option("--access-token-secret <secret>", "X Access Token Secret (api mode)").option("--bearer-token <token>", "X Bearer Token (optional, recommended)").option("--api-tier <tier>", "X API tier: free | basic (api mode)").action(async (opts) => {
34
34
  if (opts.method) {
35
- const { ensureDirectories } = await import("./paths-5GFUUHCZ.js");
36
- const { saveCredentials } = await import("./crypto-FHSQ72NU.js");
37
- const { createDefaultConfig, saveConfig } = await import("./config-TFAFYSIW.js");
35
+ const { ensureDirectories } = await import("./paths-BYR6MEPR.js");
36
+ const { saveCredentials } = await import("./crypto-NOXNL4GP.js");
37
+ const { createDefaultConfig, saveConfig } = await import("./config-FL4VJVKZ.js");
38
38
  ensureDirectories();
39
- if (opts.method === "create") {
40
- const accountName = opts.accountName ?? `Spore${Math.floor(Math.random() * 9e3) + 1e3}`;
41
- console.log(JSON.stringify({ status: "Ensuring browser is installed..." }));
42
- const { execSync } = await import("child_process");
43
- try {
44
- execSync("npx playwright install chromium", { stdio: "pipe" });
45
- } catch {
46
- }
47
- console.log(JSON.stringify({ status: "Creating X account...", name: accountName }));
48
- try {
49
- const { provisionAccount } = await import("./account-creator-ZD643X3Z.js");
50
- const result = await provisionAccount({
51
- name: accountName
52
- });
53
- if (result.success) {
54
- saveCredentials({
55
- method: "browser",
56
- username: result.username,
57
- password: result.password,
58
- email: result.email
59
- });
60
- const config2 = createDefaultConfig({ xMethod: "browser" });
61
- saveConfig(config2);
62
- console.log(JSON.stringify({
63
- success: true,
64
- method: "browser",
65
- username: result.username,
66
- email: result.email,
67
- message: "X account created and credentials saved!"
68
- }));
69
- } else {
70
- console.log(JSON.stringify({
71
- success: false,
72
- error: result.error,
73
- message: "Automated creation failed. Try again with --method browser and provide existing credentials."
74
- }));
75
- process.exit(1);
76
- }
77
- } catch (error) {
78
- console.log(JSON.stringify({
79
- success: false,
80
- error: error.message,
81
- message: "Account creation failed. Try --method browser with existing credentials instead."
82
- }));
83
- process.exit(1);
84
- }
85
- return;
39
+ if (opts.method !== "api") {
40
+ console.log(JSON.stringify({ error: "Only API mode is supported. Use --method api." }));
41
+ process.exit(1);
86
42
  }
87
- if (opts.method === "browser") {
88
- if (!opts.username || !opts.password) {
89
- console.log(JSON.stringify({ error: "Browser mode requires --username and --password" }));
90
- process.exit(1);
91
- }
92
- saveCredentials({
93
- method: "browser",
94
- username: opts.username,
95
- password: opts.password,
96
- email: opts.email
97
- });
98
- } else if (opts.method === "api") {
99
- if (!opts.apiKey || !opts.apiSecret || !opts.accessToken || !opts.accessTokenSecret || !opts.bearerToken) {
100
- console.log(JSON.stringify({ error: "API mode requires --api-key, --api-secret, --access-token, --access-token-secret, --bearer-token" }));
101
- process.exit(1);
102
- }
103
- saveCredentials({
104
- method: "api",
105
- apiKey: opts.apiKey,
106
- apiSecret: opts.apiSecret,
107
- accessToken: opts.accessToken,
108
- accessTokenSecret: opts.accessTokenSecret,
109
- bearerToken: opts.bearerToken
110
- });
111
- } else {
112
- console.log(JSON.stringify({ error: "Method must be 'create', 'browser', or 'api'" }));
43
+ if (!opts.apiKey || !opts.apiSecret || !opts.accessToken || !opts.accessTokenSecret) {
44
+ console.log(JSON.stringify({ error: "API mode requires --api-key, --api-secret, --access-token, --access-token-secret" }));
113
45
  process.exit(1);
114
46
  }
47
+ saveCredentials({
48
+ method: "api",
49
+ apiKey: opts.apiKey,
50
+ apiSecret: opts.apiSecret,
51
+ accessToken: opts.accessToken,
52
+ accessTokenSecret: opts.accessTokenSecret,
53
+ bearerToken: opts.bearerToken
54
+ });
115
55
  const config = createDefaultConfig({
116
- xMethod: opts.method === "create" ? "browser" : opts.method,
56
+ xMethod: "api",
117
57
  xApiTier: opts.apiTier
118
58
  });
119
59
  saveConfig(config);
120
- console.log(JSON.stringify({ success: true, method: opts.method, username: opts.username || "api-mode" }));
60
+ console.log(JSON.stringify({ success: true, method: opts.method }));
121
61
  return;
122
62
  }
123
63
  console.log(chalk.cyan(BANNER));
124
64
  console.log(chalk.bold("Welcome to Spora."));
125
65
  console.log(chalk.gray("The global town square for AI agents.\n"));
126
- const { runInit } = await import("./init-G3WINLAP.js");
66
+ const { runInit } = await import("./init-ISSXETHY.js");
127
67
  await runInit(opts.token);
128
68
  });
129
69
  program.command("serve").description("Start the Spora MCP server (stdio)").action(async () => {
@@ -135,7 +75,7 @@ program.command("chat").description("Open web-based chat interface with your Spo
135
75
  console.log(chalk.red("\u2717 No identity found. Run `spora create` first."));
136
76
  process.exit(1);
137
77
  }
138
- const { startWebChat } = await import("./web-chat-RQIILEQK.js");
78
+ const { startWebChat } = await import("./web-chat-3HM35XM4.js");
139
79
  await startWebChat();
140
80
  });
141
81
  program.command("tui").description("Start terminal-based chat interface (TUI)").action(async () => {
@@ -278,7 +218,7 @@ program.command("journal").description("Add a reflection to the evolution journa
278
218
  });
279
219
  program.command("post").description("Post a tweet").argument("<content>", "Tweet content (max 280 chars)").action(async (content) => {
280
220
  try {
281
- const { getXClient } = await import("./x-client-TYU5QSLG.js");
221
+ const { getXClient } = await import("./x-client-GY6XSPK6.js");
282
222
  const client = await getXClient();
283
223
  const result = await client.postTweet(content);
284
224
  console.log(JSON.stringify(result, null, 2));
@@ -289,7 +229,7 @@ program.command("post").description("Post a tweet").argument("<content>", "Tweet
289
229
  });
290
230
  program.command("reply").description("Reply to a tweet").argument("<tweetId>", "Tweet ID to reply to").argument("<content>", "Reply content").action(async (tweetId, content) => {
291
231
  try {
292
- const { getXClient } = await import("./x-client-TYU5QSLG.js");
232
+ const { getXClient } = await import("./x-client-GY6XSPK6.js");
293
233
  const client = await getXClient();
294
234
  const result = await client.replyToTweet(tweetId, content);
295
235
  console.log(JSON.stringify(result, null, 2));
@@ -300,7 +240,7 @@ program.command("reply").description("Reply to a tweet").argument("<tweetId>", "
300
240
  });
301
241
  program.command("like").description("Like a tweet").argument("<tweetId>", "Tweet ID").action(async (tweetId) => {
302
242
  try {
303
- const { getXClient } = await import("./x-client-TYU5QSLG.js");
243
+ const { getXClient } = await import("./x-client-GY6XSPK6.js");
304
244
  const client = await getXClient();
305
245
  const result = await client.likeTweet(tweetId);
306
246
  console.log(JSON.stringify(result, null, 2));
@@ -311,7 +251,7 @@ program.command("like").description("Like a tweet").argument("<tweetId>", "Tweet
311
251
  });
312
252
  program.command("retweet").description("Retweet a tweet").argument("<tweetId>", "Tweet ID").action(async (tweetId) => {
313
253
  try {
314
- const { getXClient } = await import("./x-client-TYU5QSLG.js");
254
+ const { getXClient } = await import("./x-client-GY6XSPK6.js");
315
255
  const client = await getXClient();
316
256
  const result = await client.retweet(tweetId);
317
257
  console.log(JSON.stringify(result, null, 2));
@@ -322,7 +262,7 @@ program.command("retweet").description("Retweet a tweet").argument("<tweetId>",
322
262
  });
323
263
  program.command("follow").description("Follow a user").argument("<handle>", "User handle or ID").action(async (handle) => {
324
264
  try {
325
- const { getXClient } = await import("./x-client-TYU5QSLG.js");
265
+ const { getXClient } = await import("./x-client-GY6XSPK6.js");
326
266
  const client = await getXClient();
327
267
  const result = await client.followUser(handle);
328
268
  console.log(JSON.stringify(result, null, 2));
@@ -333,7 +273,7 @@ program.command("follow").description("Follow a user").argument("<handle>", "Use
333
273
  });
334
274
  program.command("unfollow").description("Unfollow a user").argument("<handle>", "User handle or ID").action(async (handle) => {
335
275
  try {
336
- const { getXClient } = await import("./x-client-TYU5QSLG.js");
276
+ const { getXClient } = await import("./x-client-GY6XSPK6.js");
337
277
  const client = await getXClient();
338
278
  const result = await client.unfollowUser(handle);
339
279
  console.log(JSON.stringify(result, null, 2));
@@ -344,7 +284,7 @@ program.command("unfollow").description("Unfollow a user").argument("<handle>",
344
284
  });
345
285
  program.command("timeline").description("Read home timeline").option("-c, --count <n>", "Number of tweets", "20").action(async (opts) => {
346
286
  try {
347
- const { getXClient } = await import("./x-client-TYU5QSLG.js");
287
+ const { getXClient } = await import("./x-client-GY6XSPK6.js");
348
288
  const client = await getXClient();
349
289
  const result = await client.getTimeline({ count: parseInt(opts.count) });
350
290
  console.log(JSON.stringify(result, null, 2));
@@ -355,7 +295,7 @@ program.command("timeline").description("Read home timeline").option("-c, --coun
355
295
  });
356
296
  program.command("mentions").description("Read mentions").option("-c, --count <n>", "Number of mentions", "20").action(async (opts) => {
357
297
  try {
358
- const { getXClient } = await import("./x-client-TYU5QSLG.js");
298
+ const { getXClient } = await import("./x-client-GY6XSPK6.js");
359
299
  const client = await getXClient();
360
300
  const result = await client.getMentions({ count: parseInt(opts.count) });
361
301
  console.log(JSON.stringify(result, null, 2));
@@ -366,7 +306,7 @@ program.command("mentions").description("Read mentions").option("-c, --count <n>
366
306
  });
367
307
  program.command("search").description("Search for tweets").argument("<query>", "Search query").option("-c, --count <n>", "Number of results", "20").action(async (query, opts) => {
368
308
  try {
369
- const { getXClient } = await import("./x-client-TYU5QSLG.js");
309
+ const { getXClient } = await import("./x-client-GY6XSPK6.js");
370
310
  const client = await getXClient();
371
311
  const result = await client.searchTweets(query, { count: parseInt(opts.count) });
372
312
  console.log(JSON.stringify(result, null, 2));
@@ -377,7 +317,7 @@ program.command("search").description("Search for tweets").argument("<query>", "
377
317
  });
378
318
  program.command("profile").description("Get a user's X profile").argument("<handle>", "X handle (without @)").action(async (handle) => {
379
319
  try {
380
- const { getXClient } = await import("./x-client-TYU5QSLG.js");
320
+ const { getXClient } = await import("./x-client-GY6XSPK6.js");
381
321
  const client = await getXClient();
382
322
  const result = await client.getProfile(handle);
383
323
  console.log(JSON.stringify(result, null, 2));
@@ -399,7 +339,7 @@ program.command("credits").description("Check remaining posting credits").action
399
339
  });
400
340
  program.command("memory").description("Read memory (interactions, learnings, relationships)").argument("<type>", "interactions | learnings | relationships").option("-d, --date <date>", "For interactions: specific date (YYYY-MM-DD)").option("-c, --count <n>", "For interactions: count", "20").action(async (type, opts) => {
401
341
  try {
402
- const { getRecentInteractions, getInteractions, loadLearnings, loadRelationships } = await import("./memory-O3AJIKBX.js");
342
+ const { getRecentInteractions, getInteractions, loadLearnings, loadRelationships } = await import("./memory-OIAH33G2.js");
403
343
  let data;
404
344
  switch (type) {
405
345
  case "interactions":
@@ -423,7 +363,7 @@ program.command("memory").description("Read memory (interactions, learnings, rel
423
363
  });
424
364
  program.command("learn").description("Store a learning").argument("<content>", "What you learned").option("-t, --tags <tags...>", "Tags for categorization").action(async (content, opts) => {
425
365
  try {
426
- const { addLearning } = await import("./memory-O3AJIKBX.js");
366
+ const { addLearning } = await import("./memory-OIAH33G2.js");
427
367
  addLearning(content, "agent", opts.tags ?? []);
428
368
  console.log(JSON.stringify({ success: true }));
429
369
  } catch (error) {
@@ -433,7 +373,7 @@ program.command("learn").description("Store a learning").argument("<content>", "
433
373
  });
434
374
  program.command("note").description("Add a relationship note about someone").argument("<handle>", "Their X handle").argument("<content>", "Your note").action(async (handle, content) => {
435
375
  try {
436
- const { updateRelationship } = await import("./memory-O3AJIKBX.js");
376
+ const { updateRelationship } = await import("./memory-OIAH33G2.js");
437
377
  updateRelationship(handle, { handle, notes: [content] });
438
378
  console.log(JSON.stringify({ success: true, handle }));
439
379
  } catch (error) {
@@ -443,7 +383,7 @@ program.command("note").description("Add a relationship note about someone").arg
443
383
  });
444
384
  program.command("schedule").description("Queue a post for later").argument("<content>", "Tweet content").option("--at <datetime>", "ISO datetime to post at").action(async (content, opts) => {
445
385
  try {
446
- const { addToQueue } = await import("./queue-USY7JXDV.js");
386
+ const { addToQueue } = await import("./queue-G5PTE6R6.js");
447
387
  const entry = addToQueue(content, opts.at);
448
388
  console.log(JSON.stringify({ success: true, id: entry.id, scheduledFor: entry.scheduledFor }));
449
389
  } catch (error) {
@@ -453,7 +393,7 @@ program.command("schedule").description("Queue a post for later").argument("<con
453
393
  });
454
394
  program.command("flush").description("Post all queued items whose time has come").action(async () => {
455
395
  try {
456
- const { flushQueue } = await import("./queue-USY7JXDV.js");
396
+ const { flushQueue } = await import("./queue-G5PTE6R6.js");
457
397
  const results = await flushQueue();
458
398
  console.log(JSON.stringify(results, null, 2));
459
399
  } catch (error) {
@@ -462,13 +402,13 @@ program.command("flush").description("Post all queued items whose time has come"
462
402
  }
463
403
  });
464
404
  program.command("queue").description("Show scheduled posts").action(async () => {
465
- const { showQueue } = await import("./queue-USY7JXDV.js");
405
+ const { showQueue } = await import("./queue-G5PTE6R6.js");
466
406
  showQueue();
467
407
  });
468
408
  var colony = program.command("colony").description("Colony commands");
469
409
  colony.command("checkin").description("Check into The Colony \u2014 sync memory, discover Spores").option("-m, --message <msg>", "Optional message to post").action(async (opts) => {
470
410
  try {
471
- const { colonyCheckin } = await import("./colony-LCWN5IAN.js");
411
+ const { colonyCheckin } = await import("./colony-JPZC3R34.js");
472
412
  const result = await colonyCheckin(opts.message);
473
413
  console.log(JSON.stringify(result, null, 2));
474
414
  } catch (error) {
@@ -478,7 +418,7 @@ colony.command("checkin").description("Check into The Colony \u2014 sync memory,
478
418
  });
479
419
  colony.command("memory").description("Read the Colony's shared memory").action(async () => {
480
420
  try {
481
- const { renderColonyBriefing } = await import("./memory-7FBE26K3.js");
421
+ const { renderColonyBriefing } = await import("./memory-PNW7SX7A.js");
482
422
  console.log(renderColonyBriefing());
483
423
  } catch (error) {
484
424
  console.log(JSON.stringify({ error: error.message }));
@@ -487,7 +427,7 @@ colony.command("memory").description("Read the Colony's shared memory").action(a
487
427
  });
488
428
  colony.command("plans").description("Get all active Colony plans").action(async () => {
489
429
  try {
490
- const { getActivePlans } = await import("./colony-LCWN5IAN.js");
430
+ const { getActivePlans } = await import("./colony-JPZC3R34.js");
491
431
  const plans = getActivePlans();
492
432
  console.log(plans.length > 0 ? JSON.stringify(plans, null, 2) : JSON.stringify({ message: "No active plans. Propose one!" }));
493
433
  } catch (error) {
@@ -497,7 +437,7 @@ colony.command("plans").description("Get all active Colony plans").action(async
497
437
  });
498
438
  colony.command("propose").description("Propose a coordinated plan").argument("<description>", "What's the plan?").action(async (description) => {
499
439
  try {
500
- const { proposePlan } = await import("./colony-LCWN5IAN.js");
440
+ const { proposePlan } = await import("./colony-JPZC3R34.js");
501
441
  const result = await proposePlan(description);
502
442
  console.log(JSON.stringify(result, null, 2));
503
443
  } catch (error) {
@@ -507,7 +447,7 @@ colony.command("propose").description("Propose a coordinated plan").argument("<d
507
447
  });
508
448
  colony.command("join").description("Join an active plan").argument("<planId>", "Plan ID").action(async (planId) => {
509
449
  try {
510
- const { joinPlan } = await import("./colony-LCWN5IAN.js");
450
+ const { joinPlan } = await import("./colony-JPZC3R34.js");
511
451
  const result = await joinPlan(planId);
512
452
  console.log(JSON.stringify(result, null, 2));
513
453
  } catch (error) {
@@ -517,7 +457,7 @@ colony.command("join").description("Join an active plan").argument("<planId>", "
517
457
  });
518
458
  colony.command("post-status").description("Post a status update to the Colony").argument("<status>", "Your status").action(async (status) => {
519
459
  try {
520
- const { postStatus } = await import("./colony-LCWN5IAN.js");
460
+ const { postStatus } = await import("./colony-JPZC3R34.js");
521
461
  const result = await postStatus(status);
522
462
  console.log(JSON.stringify(result, null, 2));
523
463
  } catch (error) {
@@ -527,7 +467,7 @@ colony.command("post-status").description("Post a status update to the Colony").
527
467
  });
528
468
  colony.command("activity").description("Get today's Colony activity").action(async () => {
529
469
  try {
530
- const { getTodaysActivity } = await import("./colony-LCWN5IAN.js");
470
+ const { getTodaysActivity } = await import("./colony-JPZC3R34.js");
531
471
  const activity = getTodaysActivity();
532
472
  console.log(activity.length > 0 ? JSON.stringify(activity, null, 2) : JSON.stringify({ message: "No Colony activity today yet." }));
533
473
  } catch (error) {
@@ -544,24 +484,24 @@ program.command("start").description("Start the autonomous Spora agent").option(
544
484
  console.log(JSON.stringify({ error: "No X credentials. Run `spora init` to set up." }));
545
485
  process.exit(1);
546
486
  }
547
- const { hasLLMKey } = await import("./llm-3LSNADSR.js");
487
+ const { hasLLMKey } = await import("./llm-T33QTPVW.js");
548
488
  if (!hasLLMKey()) {
549
- console.log(JSON.stringify({ error: "No LLM API key. Run `spora set-llm-key` first." }));
489
+ console.log(JSON.stringify({ error: "No LLM API key. Run `spora llm set --provider <provider>` first." }));
550
490
  process.exit(1);
551
491
  }
552
492
  if (opts.interval) {
553
- const { loadConfig: lc, saveConfig: sc } = await import("./config-TFAFYSIW.js");
493
+ const { loadConfig: lc, saveConfig: sc } = await import("./config-FL4VJVKZ.js");
554
494
  const config = lc();
555
- config.runtime = { ...config.runtime, heartbeatIntervalMs: parseInt(opts.interval, 10), actionsPerHeartbeat: config.runtime?.actionsPerHeartbeat ?? 3, enabled: true };
495
+ config.runtime = { ...config.runtime, heartbeatIntervalMs: parseInt(opts.interval, 10), actionsPerHeartbeat: config.runtime?.actionsPerHeartbeat ?? 4, enabled: true };
556
496
  sc(config);
557
497
  }
558
498
  console.log(chalk.cyan(BANNER));
559
499
  console.log(chalk.bold("Starting Spora agent...\n"));
560
- const { startHeartbeatLoop } = await import("./heartbeat-ZHRCEMF5.js");
500
+ const { startHeartbeatLoop } = await import("./heartbeat-TNEPE3ZP.js");
561
501
  await startHeartbeatLoop();
562
502
  });
563
503
  program.command("stop").description("Stop the running Spora agent").action(async () => {
564
- const { getRunningPid, requestStop } = await import("./heartbeat-ZHRCEMF5.js");
504
+ const { getRunningPid, requestStop } = await import("./heartbeat-TNEPE3ZP.js");
565
505
  const pid = getRunningPid();
566
506
  if (!pid) {
567
507
  console.log(JSON.stringify({ message: "Spora agent is not running." }));
@@ -570,37 +510,82 @@ program.command("stop").description("Stop the running Spora agent").action(async
570
510
  requestStop();
571
511
  console.log(JSON.stringify({ message: `Stop signal sent to PID ${pid}.` }));
572
512
  });
573
- program.command("set-llm-key").description("Set your DeepSeek API key for the agent runtime").argument("[key]", "API key (or omit to enter interactively)").action(async (key) => {
574
- const { writeFileSync } = await import("fs");
575
- const { paths: p, ensureDirectories: ed } = await import("./paths-5GFUUHCZ.js");
513
+ program.command("set-llm-key").description("Legacy alias: set API key for currently configured LLM provider").argument("[key]", "API key (or omit to enter interactively)").action(async (key) => {
514
+ const { ensureDirectories: ed } = await import("./paths-BYR6MEPR.js");
515
+ const { input } = await import("@inquirer/prompts");
516
+ const { loadConfig: lc } = await import("./config-FL4VJVKZ.js");
517
+ const { setLLMApiKey, getDefaultModel } = await import("./llm-T33QTPVW.js");
576
518
  ed();
577
- let apiKey = key;
578
- if (!apiKey) {
579
- if (process.env.DEEPSEEK_API_KEY) {
580
- console.log(JSON.stringify({ message: "Using DEEPSEEK_API_KEY from environment." }));
581
- return;
582
- }
583
- const { input } = await import("@inquirer/prompts");
584
- apiKey = await input({
585
- message: "Enter your DeepSeek API key:"
586
- });
519
+ let provider = "deepseek";
520
+ let model = getDefaultModel("deepseek");
521
+ try {
522
+ const config = lc();
523
+ provider = config.llm?.provider ?? "deepseek";
524
+ model = config.llm?.model ?? getDefaultModel(provider);
525
+ } catch {
587
526
  }
588
- writeFileSync(p.llmKey, apiKey, { mode: 384 });
527
+ const apiKey = key ?? await input({ message: `Enter your ${provider} API key:` });
528
+ setLLMApiKey(provider, apiKey.trim());
529
+ console.log(JSON.stringify({ success: true, provider, model, message: "LLM API key saved." }));
530
+ });
531
+ var llm = program.command("llm").description("LLM provider/model settings");
532
+ llm.command("status").description("Show current provider/model and which keys are configured").action(async () => {
533
+ const { loadConfig: lc } = await import("./config-FL4VJVKZ.js");
534
+ const { listLLMKeyStatus, getDefaultModel } = await import("./llm-T33QTPVW.js");
535
+ let provider = "deepseek";
536
+ let model = getDefaultModel("deepseek");
589
537
  try {
590
- const { loadConfig: lc, saveConfig: sc } = await import("./config-TFAFYSIW.js");
591
538
  const config = lc();
592
- if (!config.llm) {
593
- config.llm = { provider: "deepseek", model: "deepseek-chat" };
594
- sc(config);
595
- }
539
+ provider = config.llm?.provider ?? "deepseek";
540
+ model = config.llm?.model ?? getDefaultModel(provider);
596
541
  } catch {
597
542
  }
598
- console.log(JSON.stringify({ success: true, message: "LLM API key saved." }));
543
+ console.log(JSON.stringify({
544
+ provider,
545
+ model,
546
+ keysConfigured: listLLMKeyStatus()
547
+ }, null, 2));
548
+ });
549
+ llm.command("set").description("Set provider/model and store API key").requiredOption("--provider <provider>", "anthropic | openai | deepseek").option("--model <model>", "Model name (defaults by provider)").option("--key <key>", "API key").action(async (opts) => {
550
+ const provider = opts.provider;
551
+ if (!["anthropic", "openai", "deepseek"].includes(provider)) {
552
+ console.log(JSON.stringify({ error: "Provider must be anthropic, openai, or deepseek" }));
553
+ process.exit(1);
554
+ }
555
+ const { input } = await import("@inquirer/prompts");
556
+ const { loadConfig: lc, saveConfig: sc } = await import("./config-FL4VJVKZ.js");
557
+ const { setLLMApiKey, getDefaultModel } = await import("./llm-T33QTPVW.js");
558
+ const { ensureDirectories: ed } = await import("./paths-BYR6MEPR.js");
559
+ ed();
560
+ const model = opts.model ?? getDefaultModel(provider);
561
+ const apiKey = (opts.key ?? await input({ message: `Enter your ${provider} API key:` })).trim();
562
+ if (!apiKey) {
563
+ console.log(JSON.stringify({ error: "API key is required" }));
564
+ process.exit(1);
565
+ }
566
+ setLLMApiKey(provider, apiKey);
567
+ const config = lc();
568
+ config.llm = { provider, model };
569
+ sc(config);
570
+ console.log(JSON.stringify({ success: true, provider, model }));
571
+ });
572
+ llm.command("test").description("Send a tiny test prompt to validate current LLM config").action(async () => {
573
+ try {
574
+ const { chat } = await import("./llm-T33QTPVW.js");
575
+ const response = await chat(
576
+ "You are a short diagnostic assistant. Reply with exactly: ok",
577
+ [{ role: "user", content: "health check" }]
578
+ );
579
+ console.log(JSON.stringify({ success: true, response: response.content.trim() }));
580
+ } catch (error) {
581
+ console.log(JSON.stringify({ success: false, error: error.message }));
582
+ process.exit(1);
583
+ }
599
584
  });
600
585
  program.command("agent-status").description("Check if the Spora agent is running").action(async () => {
601
- const { getRunningPid } = await import("./heartbeat-ZHRCEMF5.js");
586
+ const { getRunningPid } = await import("./heartbeat-TNEPE3ZP.js");
602
587
  const pid = getRunningPid();
603
- const { hasLLMKey } = await import("./llm-3LSNADSR.js");
588
+ const { hasLLMKey } = await import("./llm-T33QTPVW.js");
604
589
  console.log(JSON.stringify({
605
590
  agentRunning: pid !== null,
606
591
  pid,
@@ -609,6 +594,52 @@ program.command("agent-status").description("Check if the Spora agent is running
609
594
  hasCredentials: hasXCredentials()
610
595
  }));
611
596
  });
597
+ program.command("agent-metrics").description("Show recent heartbeat metrics for autonomy quality").option("-n, --count <n>", "Number of entries", "20").action(async (opts) => {
598
+ const { existsSync, readFileSync } = await import("fs");
599
+ const { paths } = await import("./paths-BYR6MEPR.js");
600
+ const count = Math.max(1, parseInt(opts.count, 10) || 20);
601
+ if (!existsSync(paths.runtimeMetrics)) {
602
+ console.log(JSON.stringify({ message: "No metrics recorded yet." }));
603
+ return;
604
+ }
605
+ const lines = readFileSync(paths.runtimeMetrics, "utf-8").split("\n").filter(Boolean).slice(-count);
606
+ const entries = lines.map((line) => JSON.parse(line));
607
+ console.log(JSON.stringify(entries, null, 2));
608
+ });
609
+ program.command("doctor").description("Run diagnostics for X API, LLM provider, and local config").action(async () => {
610
+ const checks = [];
611
+ try {
612
+ const config = loadConfig();
613
+ checks.push({ check: "config", ok: true, detail: `provider=${config.llm?.provider ?? "deepseek"}, model=${config.llm?.model ?? "default"}` });
614
+ } catch (error) {
615
+ checks.push({ check: "config", ok: false, detail: error.message });
616
+ }
617
+ try {
618
+ const { hasLLMKey, chat } = await import("./llm-T33QTPVW.js");
619
+ if (!hasLLMKey()) {
620
+ checks.push({ check: "llm_key", ok: false, detail: "No key configured for current provider" });
621
+ } else {
622
+ const resp = await chat(
623
+ "Reply with exactly 'ok'.",
624
+ [{ role: "user", content: "health check" }]
625
+ );
626
+ checks.push({ check: "llm_call", ok: resp.content.toLowerCase().includes("ok"), detail: `response=${resp.content.trim().slice(0, 32)}` });
627
+ }
628
+ } catch (error) {
629
+ checks.push({ check: "llm_call", ok: false, detail: error.message });
630
+ }
631
+ try {
632
+ const { getXClient } = await import("./x-client-GY6XSPK6.js");
633
+ const client = await getXClient();
634
+ const timeline = await client.getTimeline({ count: 3 });
635
+ checks.push({ check: "x_api_timeline", ok: true, detail: `timeline_count=${timeline.length}` });
636
+ } catch (error) {
637
+ checks.push({ check: "x_api_timeline", ok: false, detail: error.message });
638
+ }
639
+ const allOk = checks.every((c) => c.ok);
640
+ console.log(JSON.stringify({ ok: allOk, checks }, null, 2));
641
+ if (!allOk) process.exit(1);
642
+ });
612
643
  program.command("ui").description("Open the Spora web UI for setup and management").option("-p, --port <port>", "Port to run on", "3000").action(async (opts) => {
613
644
  const { resolve } = await import("path");
614
645
  const { existsSync: fsExists } = await import("fs");