spora 0.7.1 → 0.7.3

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 (45) hide show
  1. package/dist/autonomy-6UWPXTPD.js +19 -0
  2. package/dist/{chunk-LXQNVVIY.js → chunk-4LNMA56H.js} +2 -2
  3. package/dist/{chunk-OACD3HGE.js → chunk-7OOGNZBU.js} +3 -3
  4. package/dist/{chunk-E5NR6HT4.js → chunk-HGNMHGAF.js} +3 -3
  5. package/dist/{chunk-AOQ3WLZV.js → chunk-Q3YXJ2C6.js} +137 -28
  6. package/dist/chunk-Q3YXJ2C6.js.map +1 -0
  7. package/dist/{chunk-KWWAIS3C.js → chunk-SUZUJGGW.js} +2 -2
  8. package/dist/{chunk-NPV3OV2K.js → chunk-YMGJQRKG.js} +13 -2
  9. package/dist/chunk-YMGJQRKG.js.map +1 -0
  10. package/dist/{chunk-WIK74GGJ.js → chunk-ZBP2ROAZ.js} +104 -22
  11. package/dist/chunk-ZBP2ROAZ.js.map +1 -0
  12. package/dist/cli.js +39 -35
  13. package/dist/cli.js.map +1 -1
  14. package/dist/{client-57BQKVYF.js → client-4KGOBIXE.js} +124 -40
  15. package/dist/client-4KGOBIXE.js.map +1 -0
  16. package/dist/{colony-JPZC3R34.js → colony-IVYR233C.js} +3 -3
  17. package/dist/{heartbeat-TNEPE3ZP.js → heartbeat-CUL2FTFD.js} +57 -13
  18. package/dist/heartbeat-CUL2FTFD.js.map +1 -0
  19. package/dist/{init-ISSXETHY.js → init-2REECUVH.js} +5 -5
  20. package/dist/{llm-T33QTPVW.js → llm-OGOYCWBH.js} +3 -3
  21. package/dist/mcp-server.js +20 -20
  22. package/dist/{prompt-builder-5NYONN2W.js → prompt-builder-KJKFCGM7.js} +6 -4
  23. package/dist/{queue-G5PTE6R6.js → queue-D3MRKABU.js} +3 -3
  24. package/dist/{web-chat-3HM35XM4.js → web-chat-O24HGJVE.js} +45 -6
  25. package/dist/web-chat-O24HGJVE.js.map +1 -0
  26. package/dist/{x-client-GY6XSPK6.js → x-client-ASXVQ6EV.js} +3 -3
  27. package/package.json +1 -1
  28. package/dist/autonomy-DAV7X6QS.js +0 -19
  29. package/dist/chunk-AOQ3WLZV.js.map +0 -1
  30. package/dist/chunk-NPV3OV2K.js.map +0 -1
  31. package/dist/chunk-WIK74GGJ.js.map +0 -1
  32. package/dist/client-57BQKVYF.js.map +0 -1
  33. package/dist/heartbeat-TNEPE3ZP.js.map +0 -1
  34. package/dist/web-chat-3HM35XM4.js.map +0 -1
  35. /package/dist/{autonomy-DAV7X6QS.js.map → autonomy-6UWPXTPD.js.map} +0 -0
  36. /package/dist/{chunk-LXQNVVIY.js.map → chunk-4LNMA56H.js.map} +0 -0
  37. /package/dist/{chunk-OACD3HGE.js.map → chunk-7OOGNZBU.js.map} +0 -0
  38. /package/dist/{chunk-E5NR6HT4.js.map → chunk-HGNMHGAF.js.map} +0 -0
  39. /package/dist/{chunk-KWWAIS3C.js.map → chunk-SUZUJGGW.js.map} +0 -0
  40. /package/dist/{colony-JPZC3R34.js.map → colony-IVYR233C.js.map} +0 -0
  41. /package/dist/{init-ISSXETHY.js.map → init-2REECUVH.js.map} +0 -0
  42. /package/dist/{llm-T33QTPVW.js.map → llm-OGOYCWBH.js.map} +0 -0
  43. /package/dist/{prompt-builder-5NYONN2W.js.map → prompt-builder-KJKFCGM7.js.map} +0 -0
  44. /package/dist/{queue-G5PTE6R6.js.map → queue-D3MRKABU.js.map} +0 -0
  45. /package/dist/{x-client-GY6XSPK6.js.map → x-client-ASXVQ6EV.js.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/runtime/decision-engine.ts","../src/runtime/policy.ts","../src/runtime/autonomy.ts"],"sourcesContent":["import { logger } from \"../utils/logger.js\";\nimport { getXClient } from \"../x-client/index.js\";\nimport { addLearning } from \"../memory/index.js\";\nimport { loadIdentity, saveIdentity } from \"../identity/index.js\";\nimport { addToQueue } from \"../scheduler/queue.js\";\n\nexport interface AgentAction {\n action: string;\n content?: string;\n tweetId?: string;\n handle?: string;\n tags?: string[];\n reason?: string;\n reasoning?: string;\n}\n\nexport interface ActionResult {\n action: string;\n success: boolean;\n detail?: string;\n error?: string;\n}\n\nexport function parseActions(llmResponse: string): AgentAction[] {\n // Strategy: try multiple extraction approaches, most specific first\n\n // 1. Try markdown code block first (```json ... ``` or ``` ... ```)\n const codeBlockMatch = llmResponse.match(/```(?:json)?\\s*\\n?([\\s\\S]*?)```/);\n if (codeBlockMatch) {\n const inside = codeBlockMatch[1].trim();\n try {\n const parsed = JSON.parse(inside);\n return Array.isArray(parsed) ? parsed : [parsed];\n } catch {\n // Code block content wasn't valid JSON, continue to other strategies\n }\n }\n\n // 2. Find the last JSON array in the response (LLMs often put reasoning before the array)\n // Use a greedy approach to find the outermost array brackets\n let lastArrayStart = -1;\n let lastArrayEnd = -1;\n let depth = 0;\n for (let i = 0; i < llmResponse.length; i++) {\n if (llmResponse[i] === \"[\") {\n if (depth === 0) lastArrayStart = i;\n depth++;\n } else if (llmResponse[i] === \"]\") {\n depth--;\n if (depth === 0) lastArrayEnd = i;\n }\n }\n\n if (lastArrayStart >= 0 && lastArrayEnd > lastArrayStart) {\n const arrayStr = llmResponse.slice(lastArrayStart, lastArrayEnd + 1);\n try {\n const parsed = JSON.parse(arrayStr);\n if (Array.isArray(parsed) && parsed.length > 0 && parsed[0].action) {\n return parsed;\n }\n } catch {\n // Not valid JSON array, try next strategy\n }\n }\n\n // 3. Try to find a single action object (last one in the response)\n const objMatches = [...llmResponse.matchAll(/\\{[^{}]*\"action\"\\s*:\\s*\"[^\"]+\"/g)];\n if (objMatches.length > 0) {\n // Find the full object starting from this match\n for (let i = objMatches.length - 1; i >= 0; i--) {\n const start = objMatches[i].index!;\n let braceDepth = 0;\n let end = -1;\n for (let j = start; j < llmResponse.length; j++) {\n if (llmResponse[j] === \"{\") braceDepth++;\n else if (llmResponse[j] === \"}\") {\n braceDepth--;\n if (braceDepth === 0) { end = j; break; }\n }\n }\n if (end > start) {\n try {\n const obj = JSON.parse(llmResponse.slice(start, end + 1));\n if (obj.action) return [obj as AgentAction];\n } catch {\n continue;\n }\n }\n }\n }\n\n // 4. Last resort: try the whole response as JSON\n try {\n const parsed = JSON.parse(llmResponse.trim());\n if (Array.isArray(parsed)) return parsed;\n if (parsed.action) return [parsed as AgentAction];\n } catch {\n // Not JSON at all\n }\n\n logger.warn(\"Failed to parse actions from LLM response\");\n if (llmResponse.length < 500) {\n logger.warn(`Response was: ${llmResponse}`);\n } else {\n logger.warn(`Response starts with: ${llmResponse.slice(0, 200)}...`);\n }\n return [];\n}\n\nexport async function executeAction(action: AgentAction): Promise<ActionResult> {\n const { action: type } = action;\n\n try {\n switch (type) {\n case \"post\": {\n if (!action.content) return { action: type, success: false, error: \"No content provided\" };\n if (action.content.length > 280) {\n return { action: type, success: false, error: `Tweet too long: ${action.content.length} chars (max 280)` };\n }\n\n const client = await getXClient();\n const result = await client.postTweet(action.content);\n if (result.success) logger.info(`Posted: \"${action.content.slice(0, 50)}...\"`);\n return { action: type, success: result.success, detail: result.tweetId, error: result.error };\n }\n\n case \"reply\": {\n if (!action.tweetId || !action.content) {\n return { action: type, success: false, error: \"Missing tweetId or content\" };\n }\n const client = await getXClient();\n const result = await client.replyToTweet(action.tweetId, action.content);\n if (result.success) logger.info(`Replied to ${action.tweetId}: \"${action.content.slice(0, 50)}...\"`);\n return { action: type, success: result.success, detail: result.tweetId, error: result.error };\n }\n\n case \"like\": {\n if (!action.tweetId) return { action: type, success: false, error: \"Missing tweetId\" };\n const client = await getXClient();\n const result = await client.likeTweet(action.tweetId);\n return { action: type, success: result.success, error: result.error };\n }\n\n case \"retweet\": {\n if (!action.tweetId) return { action: type, success: false, error: \"Missing tweetId\" };\n const client = await getXClient();\n const result = await client.retweet(action.tweetId);\n return { action: type, success: result.success, error: result.error };\n }\n\n case \"follow\": {\n if (!action.handle) return { action: type, success: false, error: \"Missing handle\" };\n const client = await getXClient();\n const result = await client.followUser(action.handle);\n return { action: type, success: result.success, error: result.error };\n }\n\n case \"schedule\": {\n if (!action.content) return { action: type, success: false, error: \"No content\" };\n const entry = addToQueue(action.content);\n logger.info(`Scheduled: \"${action.content.slice(0, 50)}...\" for ${entry.scheduledFor}`);\n return { action: type, success: true, detail: `Scheduled for ${entry.scheduledFor}` };\n }\n\n case \"learn\": {\n if (!action.content) return { action: type, success: false, error: \"No content\" };\n addLearning(action.content, \"agent\", action.tags ?? [\"heartbeat\"]);\n logger.info(`Learned: \"${action.content.slice(0, 50)}...\"`);\n return { action: type, success: true };\n }\n\n case \"reflect\": {\n if (!action.content) return { action: type, success: false, error: \"No content\" };\n const identity = loadIdentity();\n identity.evolutionJournal.push({\n date: new Date().toISOString(),\n reflection: action.content,\n });\n saveIdentity(identity);\n logger.info(`Reflected: \"${action.content.slice(0, 50)}...\"`);\n return { action: type, success: true };\n }\n\n case \"skip\": {\n logger.info(`Skipping: ${action.reason ?? action.reasoning ?? \"no reason given\"}`);\n return { action: type, success: true, detail: action.reason ?? action.reasoning };\n }\n\n default:\n logger.warn(`Unknown action: ${type}`);\n return { action: type, success: false, error: `Unknown action: ${type}` };\n }\n } catch (error) {\n const msg = (error as Error).message;\n logger.error(`Action ${type} failed: ${msg}`);\n return { action: type, success: false, error: msg };\n }\n}\n\nexport async function executeActions(actions: AgentAction[]): Promise<ActionResult[]> {\n const results: ActionResult[] = [];\n for (const action of actions) {\n const result = await executeAction(action);\n results.push(result);\n // Small delay between actions to be human-like\n await new Promise((r) => setTimeout(r, 2000 + Math.random() * 3000));\n }\n return results;\n}\n","import { getRecentInteractions, type InteractionEntry } from \"../memory/index.js\";\nimport type { Tweet } from \"../x-client/types.js\";\nimport type { AgentAction } from \"./decision-engine.js\";\n\nexport interface PolicyContext {\n action: AgentAction;\n step: number;\n timeline: Tweet[];\n mentions: Tweet[];\n executedActions: AgentAction[];\n}\n\nexport interface PolicyDecision {\n allowed: boolean;\n reason?: string;\n}\n\nfunction normalize(text: string): string {\n return text\n .toLowerCase()\n .replace(/https?:\\/\\/\\S+/g, \"\")\n .replace(/[@#]\\w+/g, \"\")\n .replace(/[^a-z0-9\\s]/g, \" \")\n .replace(/\\s+/g, \" \")\n .trim();\n}\n\nfunction tokenSet(text: string): Set<string> {\n const tokens = normalize(text).split(\" \").filter(Boolean);\n return new Set(tokens);\n}\n\nfunction jaccardSimilarity(a: string, b: string): number {\n const aSet = tokenSet(a);\n const bSet = tokenSet(b);\n if (aSet.size === 0 || bSet.size === 0) return 0;\n\n let overlap = 0;\n for (const token of aSet) {\n if (bSet.has(token)) overlap += 1;\n }\n\n const union = aSet.size + bSet.size - overlap;\n return union === 0 ? 0 : overlap / union;\n}\n\nfunction firstWords(text: string, n: number): string {\n return normalize(text).split(\" \").filter(Boolean).slice(0, n).join(\" \");\n}\n\nfunction hasAllCapsEnding(text: string): boolean {\n const ending = text.split(/[.!?]/).map((s) => s.trim()).filter(Boolean).slice(-1)[0] ?? \"\";\n const words = ending.split(/\\s+/).filter(Boolean);\n if (words.length < 3) return false;\n return words.every((word) => /^[A-Z0-9]+$/.test(word));\n}\n\nfunction recentWrittenContent(): string[] {\n const recent = getRecentInteractions(40);\n return recent\n .filter((i) => i.type === \"post\" || i.type === \"reply\")\n .map((i) => i.content ?? \"\")\n .filter((content) => content.length > 0);\n}\n\nfunction hasStrongConversationOpportunity(timeline: Tweet[], mentions: Tweet[]): boolean {\n if (mentions.length > 0) return true;\n return timeline.some((tweet) => (tweet.replyCount ?? 0) > 0 || tweet.text.includes(\"?\"));\n}\n\nfunction wasInteractionAction(action: AgentAction): boolean {\n return [\"reply\", \"like\", \"retweet\", \"follow\"].includes(action.action);\n}\n\nfunction isWritingAction(action: AgentAction): boolean {\n return [\"post\", \"reply\", \"schedule\"].includes(action.action);\n}\n\nfunction executedWrittenContent(executedActions: AgentAction[]): string[] {\n return executedActions\n .filter((a) => isWritingAction(a) && typeof a.content === \"string\")\n .map((a) => a.content?.trim() ?? \"\")\n .filter((content) => content.length > 0);\n}\n\nfunction nearExactDuplicate(content: string, recent: string[]): boolean {\n const normalized = normalize(content);\n if (!normalized) return false;\n\n return recent.some((r) => {\n const candidate = normalize(r);\n if (!candidate) return false;\n if (candidate === normalized) return true;\n return jaccardSimilarity(content, r) >= 0.88;\n });\n}\n\nfunction isDuplicateTarget(action: AgentAction, executedActions: AgentAction[]): boolean {\n if (!action.tweetId) return false;\n return executedActions.some((a) => a.tweetId === action.tweetId && a.action === action.action);\n}\n\nfunction repeatedTemplate(content: string, recent: string[]): boolean {\n const prefix = firstWords(content, 7);\n if (!prefix) return false;\n\n return recent.some((r) => {\n const sameStart = firstWords(r, 7) === prefix;\n const similar = jaccardSimilarity(content, r) >= 0.62;\n return sameStart || similar;\n });\n}\n\nfunction overusingAllCapsCadence(content: string, recentEntries: InteractionEntry[]): boolean {\n if (!hasAllCapsEnding(content)) return false;\n const recentCaps = recentEntries\n .filter((i) => i.type === \"post\" && i.content)\n .slice(0, 8)\n .filter((i) => hasAllCapsEnding(i.content ?? \"\"));\n\n return recentCaps.length >= 2;\n}\n\nexport function evaluateActionPolicy(context: PolicyContext): PolicyDecision {\n const { action, step, timeline, mentions, executedActions } = context;\n\n if (isDuplicateTarget(action, executedActions)) {\n return { allowed: false, reason: `Action ${action.action} already executed for tweet ${action.tweetId} this heartbeat.` };\n }\n\n if (action.content && isWritingAction(action)) {\n const existingInHeartbeat = executedWrittenContent(executedActions);\n if (nearExactDuplicate(action.content, existingInHeartbeat)) {\n return {\n allowed: false,\n reason: \"Rejected duplicate wording in this heartbeat. Write a distinct message before posting/replying again.\",\n };\n }\n }\n\n const hasConversationOpportunity = hasStrongConversationOpportunity(timeline, mentions);\n const interactedAlready = executedActions.some(wasInteractionAction);\n\n if (\n action.action === \"post\" &&\n hasConversationOpportunity &&\n !interactedAlready &&\n step < 2\n ) {\n return {\n allowed: false,\n reason: \"Engage first: reply/like/follow when mentions or active conversations are available before posting an original tweet.\",\n };\n }\n\n if (isWritingAction(action) && action.content) {\n const recent = recentWrittenContent();\n if (nearExactDuplicate(action.content, recent)) {\n return {\n allowed: false,\n reason: \"Rejected near-duplicate content from recent history. Tailor this message to the specific context.\",\n };\n }\n\n if (repeatedTemplate(action.content, recent)) {\n return {\n allowed: false,\n reason: \"Rejected repetitive content pattern. Use a more novel structure or engage directly with timeline context.\",\n };\n }\n }\n\n if ((action.action === \"post\" || action.action === \"schedule\") && action.content) {\n const recentInteractions = getRecentInteractions(20);\n if (overusingAllCapsCadence(action.content, recentInteractions)) {\n return {\n allowed: false,\n reason: \"Rejected repetitive all-caps slogan cadence. Vary style and reduce monologue formatting.\",\n };\n }\n }\n\n if ((action.action === \"reply\" || action.action === \"like\" || action.action === \"retweet\") && action.tweetId) {\n const known = new Set([...timeline, ...mentions].map((tweet) => tweet.id));\n if (!known.has(action.tweetId)) {\n return {\n allowed: false,\n reason: `Tweet ${action.tweetId} is not in current observations. Choose a visible timeline/mention tweet for grounded engagement.`,\n };\n }\n }\n\n return { allowed: true };\n}\n","import { getXClient } from \"../x-client/index.js\";\nimport { logger } from \"../utils/logger.js\";\nimport { getRecentInteractions } from \"../memory/index.js\";\nimport type { Tweet } from \"../x-client/types.js\";\nimport { buildSystemPrompt, buildToolDecisionMessage } from \"./prompt-builder.js\";\nimport { generateResponse } from \"./llm.js\";\nimport { parseActions, executeAction, type AgentAction, type ActionResult } from \"./decision-engine.js\";\nimport { evaluateActionPolicy } from \"./policy.js\";\n\nexport interface AutonomyCycleResult {\n timeline: Tweet[];\n mentions: Tweet[];\n actions: AgentAction[];\n results: ActionResult[];\n policyFeedback: string[];\n}\n\nexport async function runAutonomyCycle(maxActions: number): Promise<AutonomyCycleResult> {\n const client = await getXClient();\n\n let timeline: Tweet[] = [];\n let mentions: Tweet[] = [];\n\n try {\n timeline = await client.getTimeline({ count: 20 });\n } catch (error) {\n logger.warn(`Timeline read failed: ${(error as Error).message}`);\n }\n\n try {\n mentions = await client.getMentions({ count: 10 });\n } catch (error) {\n logger.warn(`Mentions read failed: ${(error as Error).message}`);\n }\n\n const systemPrompt = buildSystemPrompt();\n const actions: AgentAction[] = [];\n const results: ActionResult[] = [];\n const policyFeedback: string[] = [];\n\n // Keep short memory available in context by touching it before planner loop.\n getRecentInteractions(20);\n\n for (let step = 0; step < maxActions; step += 1) {\n const decisionPrompt = buildToolDecisionMessage({\n step,\n maxActions,\n timeline,\n mentions,\n executedActions: actions,\n policyFeedback,\n });\n\n const llmResponse = await generateResponse(systemPrompt, decisionPrompt);\n const parsed = parseActions(llmResponse.content);\n const proposedAction = parsed[0];\n\n if (!proposedAction) {\n logger.info(\"Planner returned no actionable tool call.\");\n break;\n }\n\n const policy = evaluateActionPolicy({\n action: proposedAction,\n step,\n timeline,\n mentions,\n executedActions: actions,\n });\n\n if (!policy.allowed) {\n const reason = policy.reason ?? \"Policy rejected action\";\n policyFeedback.push(reason);\n logger.info(`Policy rejected action ${proposedAction.action}: ${reason}`);\n continue;\n }\n\n const result = await executeAction(proposedAction);\n actions.push(proposedAction);\n results.push(result);\n\n if (proposedAction.action === \"skip\") {\n break;\n }\n }\n\n return {\n timeline,\n mentions,\n actions,\n results,\n policyFeedback,\n };\n}\n"],"mappings":"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","names":[]}
package/dist/cli.js CHANGED
@@ -20,6 +20,8 @@ import {
20
20
  // src/cli.ts
21
21
  import { Command } from "commander";
22
22
  import chalk from "chalk";
23
+ import { readFileSync } from "fs";
24
+ import { join } from "path";
23
25
  var BANNER = `
24
26
  \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2557
25
27
  \u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557
@@ -29,7 +31,9 @@ var BANNER = `
29
31
  \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D
30
32
  `;
31
33
  var program = new Command();
32
- program.name("spora").description("AI agents (Spores) that autonomously manage X/Twitter accounts").version("0.1.6");
34
+ var packageJsonPath = join(import.meta.dirname, "../package.json");
35
+ var cliVersion = JSON.parse(readFileSync(packageJsonPath, "utf-8")).version;
36
+ program.name("spora").description("AI agents (Spores) that autonomously manage X/Twitter accounts").version(cliVersion);
33
37
  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
38
  if (opts.method) {
35
39
  const { ensureDirectories } = await import("./paths-BYR6MEPR.js");
@@ -63,7 +67,7 @@ program.command("init").description("Set up X account credentials for your Spore
63
67
  console.log(chalk.cyan(BANNER));
64
68
  console.log(chalk.bold("Welcome to Spora."));
65
69
  console.log(chalk.gray("The global town square for AI agents.\n"));
66
- const { runInit } = await import("./init-ISSXETHY.js");
70
+ const { runInit } = await import("./init-2REECUVH.js");
67
71
  await runInit(opts.token);
68
72
  });
69
73
  program.command("serve").description("Start the Spora MCP server (stdio)").action(async () => {
@@ -75,7 +79,7 @@ program.command("chat").description("Open web-based chat interface with your Spo
75
79
  console.log(chalk.red("\u2717 No identity found. Run `spora create` first."));
76
80
  process.exit(1);
77
81
  }
78
- const { startWebChat } = await import("./web-chat-3HM35XM4.js");
82
+ const { startWebChat } = await import("./web-chat-O24HGJVE.js");
79
83
  await startWebChat();
80
84
  });
81
85
  program.command("tui").description("Start terminal-based chat interface (TUI)").action(async () => {
@@ -218,7 +222,7 @@ program.command("journal").description("Add a reflection to the evolution journa
218
222
  });
219
223
  program.command("post").description("Post a tweet").argument("<content>", "Tweet content (max 280 chars)").action(async (content) => {
220
224
  try {
221
- const { getXClient } = await import("./x-client-GY6XSPK6.js");
225
+ const { getXClient } = await import("./x-client-ASXVQ6EV.js");
222
226
  const client = await getXClient();
223
227
  const result = await client.postTweet(content);
224
228
  console.log(JSON.stringify(result, null, 2));
@@ -229,7 +233,7 @@ program.command("post").description("Post a tweet").argument("<content>", "Tweet
229
233
  });
230
234
  program.command("reply").description("Reply to a tweet").argument("<tweetId>", "Tweet ID to reply to").argument("<content>", "Reply content").action(async (tweetId, content) => {
231
235
  try {
232
- const { getXClient } = await import("./x-client-GY6XSPK6.js");
236
+ const { getXClient } = await import("./x-client-ASXVQ6EV.js");
233
237
  const client = await getXClient();
234
238
  const result = await client.replyToTweet(tweetId, content);
235
239
  console.log(JSON.stringify(result, null, 2));
@@ -240,7 +244,7 @@ program.command("reply").description("Reply to a tweet").argument("<tweetId>", "
240
244
  });
241
245
  program.command("like").description("Like a tweet").argument("<tweetId>", "Tweet ID").action(async (tweetId) => {
242
246
  try {
243
- const { getXClient } = await import("./x-client-GY6XSPK6.js");
247
+ const { getXClient } = await import("./x-client-ASXVQ6EV.js");
244
248
  const client = await getXClient();
245
249
  const result = await client.likeTweet(tweetId);
246
250
  console.log(JSON.stringify(result, null, 2));
@@ -251,7 +255,7 @@ program.command("like").description("Like a tweet").argument("<tweetId>", "Tweet
251
255
  });
252
256
  program.command("retweet").description("Retweet a tweet").argument("<tweetId>", "Tweet ID").action(async (tweetId) => {
253
257
  try {
254
- const { getXClient } = await import("./x-client-GY6XSPK6.js");
258
+ const { getXClient } = await import("./x-client-ASXVQ6EV.js");
255
259
  const client = await getXClient();
256
260
  const result = await client.retweet(tweetId);
257
261
  console.log(JSON.stringify(result, null, 2));
@@ -262,7 +266,7 @@ program.command("retweet").description("Retweet a tweet").argument("<tweetId>",
262
266
  });
263
267
  program.command("follow").description("Follow a user").argument("<handle>", "User handle or ID").action(async (handle) => {
264
268
  try {
265
- const { getXClient } = await import("./x-client-GY6XSPK6.js");
269
+ const { getXClient } = await import("./x-client-ASXVQ6EV.js");
266
270
  const client = await getXClient();
267
271
  const result = await client.followUser(handle);
268
272
  console.log(JSON.stringify(result, null, 2));
@@ -273,7 +277,7 @@ program.command("follow").description("Follow a user").argument("<handle>", "Use
273
277
  });
274
278
  program.command("unfollow").description("Unfollow a user").argument("<handle>", "User handle or ID").action(async (handle) => {
275
279
  try {
276
- const { getXClient } = await import("./x-client-GY6XSPK6.js");
280
+ const { getXClient } = await import("./x-client-ASXVQ6EV.js");
277
281
  const client = await getXClient();
278
282
  const result = await client.unfollowUser(handle);
279
283
  console.log(JSON.stringify(result, null, 2));
@@ -284,7 +288,7 @@ program.command("unfollow").description("Unfollow a user").argument("<handle>",
284
288
  });
285
289
  program.command("timeline").description("Read home timeline").option("-c, --count <n>", "Number of tweets", "20").action(async (opts) => {
286
290
  try {
287
- const { getXClient } = await import("./x-client-GY6XSPK6.js");
291
+ const { getXClient } = await import("./x-client-ASXVQ6EV.js");
288
292
  const client = await getXClient();
289
293
  const result = await client.getTimeline({ count: parseInt(opts.count) });
290
294
  console.log(JSON.stringify(result, null, 2));
@@ -295,7 +299,7 @@ program.command("timeline").description("Read home timeline").option("-c, --coun
295
299
  });
296
300
  program.command("mentions").description("Read mentions").option("-c, --count <n>", "Number of mentions", "20").action(async (opts) => {
297
301
  try {
298
- const { getXClient } = await import("./x-client-GY6XSPK6.js");
302
+ const { getXClient } = await import("./x-client-ASXVQ6EV.js");
299
303
  const client = await getXClient();
300
304
  const result = await client.getMentions({ count: parseInt(opts.count) });
301
305
  console.log(JSON.stringify(result, null, 2));
@@ -306,7 +310,7 @@ program.command("mentions").description("Read mentions").option("-c, --count <n>
306
310
  });
307
311
  program.command("search").description("Search for tweets").argument("<query>", "Search query").option("-c, --count <n>", "Number of results", "20").action(async (query, opts) => {
308
312
  try {
309
- const { getXClient } = await import("./x-client-GY6XSPK6.js");
313
+ const { getXClient } = await import("./x-client-ASXVQ6EV.js");
310
314
  const client = await getXClient();
311
315
  const result = await client.searchTweets(query, { count: parseInt(opts.count) });
312
316
  console.log(JSON.stringify(result, null, 2));
@@ -317,7 +321,7 @@ program.command("search").description("Search for tweets").argument("<query>", "
317
321
  });
318
322
  program.command("profile").description("Get a user's X profile").argument("<handle>", "X handle (without @)").action(async (handle) => {
319
323
  try {
320
- const { getXClient } = await import("./x-client-GY6XSPK6.js");
324
+ const { getXClient } = await import("./x-client-ASXVQ6EV.js");
321
325
  const client = await getXClient();
322
326
  const result = await client.getProfile(handle);
323
327
  console.log(JSON.stringify(result, null, 2));
@@ -383,7 +387,7 @@ program.command("note").description("Add a relationship note about someone").arg
383
387
  });
384
388
  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) => {
385
389
  try {
386
- const { addToQueue } = await import("./queue-G5PTE6R6.js");
390
+ const { addToQueue } = await import("./queue-D3MRKABU.js");
387
391
  const entry = addToQueue(content, opts.at);
388
392
  console.log(JSON.stringify({ success: true, id: entry.id, scheduledFor: entry.scheduledFor }));
389
393
  } catch (error) {
@@ -393,7 +397,7 @@ program.command("schedule").description("Queue a post for later").argument("<con
393
397
  });
394
398
  program.command("flush").description("Post all queued items whose time has come").action(async () => {
395
399
  try {
396
- const { flushQueue } = await import("./queue-G5PTE6R6.js");
400
+ const { flushQueue } = await import("./queue-D3MRKABU.js");
397
401
  const results = await flushQueue();
398
402
  console.log(JSON.stringify(results, null, 2));
399
403
  } catch (error) {
@@ -402,13 +406,13 @@ program.command("flush").description("Post all queued items whose time has come"
402
406
  }
403
407
  });
404
408
  program.command("queue").description("Show scheduled posts").action(async () => {
405
- const { showQueue } = await import("./queue-G5PTE6R6.js");
409
+ const { showQueue } = await import("./queue-D3MRKABU.js");
406
410
  showQueue();
407
411
  });
408
412
  var colony = program.command("colony").description("Colony commands");
409
413
  colony.command("checkin").description("Check into The Colony \u2014 sync memory, discover Spores").option("-m, --message <msg>", "Optional message to post").action(async (opts) => {
410
414
  try {
411
- const { colonyCheckin } = await import("./colony-JPZC3R34.js");
415
+ const { colonyCheckin } = await import("./colony-IVYR233C.js");
412
416
  const result = await colonyCheckin(opts.message);
413
417
  console.log(JSON.stringify(result, null, 2));
414
418
  } catch (error) {
@@ -427,7 +431,7 @@ colony.command("memory").description("Read the Colony's shared memory").action(a
427
431
  });
428
432
  colony.command("plans").description("Get all active Colony plans").action(async () => {
429
433
  try {
430
- const { getActivePlans } = await import("./colony-JPZC3R34.js");
434
+ const { getActivePlans } = await import("./colony-IVYR233C.js");
431
435
  const plans = getActivePlans();
432
436
  console.log(plans.length > 0 ? JSON.stringify(plans, null, 2) : JSON.stringify({ message: "No active plans. Propose one!" }));
433
437
  } catch (error) {
@@ -437,7 +441,7 @@ colony.command("plans").description("Get all active Colony plans").action(async
437
441
  });
438
442
  colony.command("propose").description("Propose a coordinated plan").argument("<description>", "What's the plan?").action(async (description) => {
439
443
  try {
440
- const { proposePlan } = await import("./colony-JPZC3R34.js");
444
+ const { proposePlan } = await import("./colony-IVYR233C.js");
441
445
  const result = await proposePlan(description);
442
446
  console.log(JSON.stringify(result, null, 2));
443
447
  } catch (error) {
@@ -447,7 +451,7 @@ colony.command("propose").description("Propose a coordinated plan").argument("<d
447
451
  });
448
452
  colony.command("join").description("Join an active plan").argument("<planId>", "Plan ID").action(async (planId) => {
449
453
  try {
450
- const { joinPlan } = await import("./colony-JPZC3R34.js");
454
+ const { joinPlan } = await import("./colony-IVYR233C.js");
451
455
  const result = await joinPlan(planId);
452
456
  console.log(JSON.stringify(result, null, 2));
453
457
  } catch (error) {
@@ -457,7 +461,7 @@ colony.command("join").description("Join an active plan").argument("<planId>", "
457
461
  });
458
462
  colony.command("post-status").description("Post a status update to the Colony").argument("<status>", "Your status").action(async (status) => {
459
463
  try {
460
- const { postStatus } = await import("./colony-JPZC3R34.js");
464
+ const { postStatus } = await import("./colony-IVYR233C.js");
461
465
  const result = await postStatus(status);
462
466
  console.log(JSON.stringify(result, null, 2));
463
467
  } catch (error) {
@@ -467,7 +471,7 @@ colony.command("post-status").description("Post a status update to the Colony").
467
471
  });
468
472
  colony.command("activity").description("Get today's Colony activity").action(async () => {
469
473
  try {
470
- const { getTodaysActivity } = await import("./colony-JPZC3R34.js");
474
+ const { getTodaysActivity } = await import("./colony-IVYR233C.js");
471
475
  const activity = getTodaysActivity();
472
476
  console.log(activity.length > 0 ? JSON.stringify(activity, null, 2) : JSON.stringify({ message: "No Colony activity today yet." }));
473
477
  } catch (error) {
@@ -484,7 +488,7 @@ program.command("start").description("Start the autonomous Spora agent").option(
484
488
  console.log(JSON.stringify({ error: "No X credentials. Run `spora init` to set up." }));
485
489
  process.exit(1);
486
490
  }
487
- const { hasLLMKey } = await import("./llm-T33QTPVW.js");
491
+ const { hasLLMKey } = await import("./llm-OGOYCWBH.js");
488
492
  if (!hasLLMKey()) {
489
493
  console.log(JSON.stringify({ error: "No LLM API key. Run `spora llm set --provider <provider>` first." }));
490
494
  process.exit(1);
@@ -497,11 +501,11 @@ program.command("start").description("Start the autonomous Spora agent").option(
497
501
  }
498
502
  console.log(chalk.cyan(BANNER));
499
503
  console.log(chalk.bold("Starting Spora agent...\n"));
500
- const { startHeartbeatLoop } = await import("./heartbeat-TNEPE3ZP.js");
504
+ const { startHeartbeatLoop } = await import("./heartbeat-CUL2FTFD.js");
501
505
  await startHeartbeatLoop();
502
506
  });
503
507
  program.command("stop").description("Stop the running Spora agent").action(async () => {
504
- const { getRunningPid, requestStop } = await import("./heartbeat-TNEPE3ZP.js");
508
+ const { getRunningPid, requestStop } = await import("./heartbeat-CUL2FTFD.js");
505
509
  const pid = getRunningPid();
506
510
  if (!pid) {
507
511
  console.log(JSON.stringify({ message: "Spora agent is not running." }));
@@ -514,7 +518,7 @@ program.command("set-llm-key").description("Legacy alias: set API key for curren
514
518
  const { ensureDirectories: ed } = await import("./paths-BYR6MEPR.js");
515
519
  const { input } = await import("@inquirer/prompts");
516
520
  const { loadConfig: lc } = await import("./config-FL4VJVKZ.js");
517
- const { setLLMApiKey, getDefaultModel } = await import("./llm-T33QTPVW.js");
521
+ const { setLLMApiKey, getDefaultModel } = await import("./llm-OGOYCWBH.js");
518
522
  ed();
519
523
  let provider = "deepseek";
520
524
  let model = getDefaultModel("deepseek");
@@ -531,7 +535,7 @@ program.command("set-llm-key").description("Legacy alias: set API key for curren
531
535
  var llm = program.command("llm").description("LLM provider/model settings");
532
536
  llm.command("status").description("Show current provider/model and which keys are configured").action(async () => {
533
537
  const { loadConfig: lc } = await import("./config-FL4VJVKZ.js");
534
- const { listLLMKeyStatus, getDefaultModel } = await import("./llm-T33QTPVW.js");
538
+ const { listLLMKeyStatus, getDefaultModel } = await import("./llm-OGOYCWBH.js");
535
539
  let provider = "deepseek";
536
540
  let model = getDefaultModel("deepseek");
537
541
  try {
@@ -554,7 +558,7 @@ llm.command("set").description("Set provider/model and store API key").requiredO
554
558
  }
555
559
  const { input } = await import("@inquirer/prompts");
556
560
  const { loadConfig: lc, saveConfig: sc } = await import("./config-FL4VJVKZ.js");
557
- const { setLLMApiKey, getDefaultModel } = await import("./llm-T33QTPVW.js");
561
+ const { setLLMApiKey, getDefaultModel } = await import("./llm-OGOYCWBH.js");
558
562
  const { ensureDirectories: ed } = await import("./paths-BYR6MEPR.js");
559
563
  ed();
560
564
  const model = opts.model ?? getDefaultModel(provider);
@@ -571,7 +575,7 @@ llm.command("set").description("Set provider/model and store API key").requiredO
571
575
  });
572
576
  llm.command("test").description("Send a tiny test prompt to validate current LLM config").action(async () => {
573
577
  try {
574
- const { chat } = await import("./llm-T33QTPVW.js");
578
+ const { chat } = await import("./llm-OGOYCWBH.js");
575
579
  const response = await chat(
576
580
  "You are a short diagnostic assistant. Reply with exactly: ok",
577
581
  [{ role: "user", content: "health check" }]
@@ -583,9 +587,9 @@ llm.command("test").description("Send a tiny test prompt to validate current LLM
583
587
  }
584
588
  });
585
589
  program.command("agent-status").description("Check if the Spora agent is running").action(async () => {
586
- const { getRunningPid } = await import("./heartbeat-TNEPE3ZP.js");
590
+ const { getRunningPid } = await import("./heartbeat-CUL2FTFD.js");
587
591
  const pid = getRunningPid();
588
- const { hasLLMKey } = await import("./llm-T33QTPVW.js");
592
+ const { hasLLMKey } = await import("./llm-OGOYCWBH.js");
589
593
  console.log(JSON.stringify({
590
594
  agentRunning: pid !== null,
591
595
  pid,
@@ -595,14 +599,14 @@ program.command("agent-status").description("Check if the Spora agent is running
595
599
  }));
596
600
  });
597
601
  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");
602
+ const { existsSync, readFileSync: readFileSync2 } = await import("fs");
599
603
  const { paths } = await import("./paths-BYR6MEPR.js");
600
604
  const count = Math.max(1, parseInt(opts.count, 10) || 20);
601
605
  if (!existsSync(paths.runtimeMetrics)) {
602
606
  console.log(JSON.stringify({ message: "No metrics recorded yet." }));
603
607
  return;
604
608
  }
605
- const lines = readFileSync(paths.runtimeMetrics, "utf-8").split("\n").filter(Boolean).slice(-count);
609
+ const lines = readFileSync2(paths.runtimeMetrics, "utf-8").split("\n").filter(Boolean).slice(-count);
606
610
  const entries = lines.map((line) => JSON.parse(line));
607
611
  console.log(JSON.stringify(entries, null, 2));
608
612
  });
@@ -615,7 +619,7 @@ program.command("doctor").description("Run diagnostics for X API, LLM provider,
615
619
  checks.push({ check: "config", ok: false, detail: error.message });
616
620
  }
617
621
  try {
618
- const { hasLLMKey, chat } = await import("./llm-T33QTPVW.js");
622
+ const { hasLLMKey, chat } = await import("./llm-OGOYCWBH.js");
619
623
  if (!hasLLMKey()) {
620
624
  checks.push({ check: "llm_key", ok: false, detail: "No key configured for current provider" });
621
625
  } else {
@@ -629,7 +633,7 @@ program.command("doctor").description("Run diagnostics for X API, LLM provider,
629
633
  checks.push({ check: "llm_call", ok: false, detail: error.message });
630
634
  }
631
635
  try {
632
- const { getXClient } = await import("./x-client-GY6XSPK6.js");
636
+ const { getXClient } = await import("./x-client-ASXVQ6EV.js");
633
637
  const client = await getXClient();
634
638
  const timeline = await client.getTimeline({ count: 3 });
635
639
  checks.push({ check: "x_api_timeline", ok: true, detail: `timeline_count=${timeline.length}` });