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
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { sporaExists, hasXCredentials } from \"./utils/paths.js\";\nimport { loadConfig } from \"./utils/config.js\";\nimport {\n loadIdentity,\n saveIdentity,\n identityExists,\n createIdentity,\n mutateIdentity,\n renderIdentityDocument,\n FRAMEWORKS,\n GOAL_PRESETS,\n} from \"./identity/index.js\";\n\nconst BANNER = `\n ███████╗██████╗ ██████╗ ██████╗ █████╗\n ██╔════╝██╔══██╗██╔═══██╗██╔══██╗██╔══██╗\n ███████╗██████╔╝██║ ██║██████╔╝███████║\n ╚════██║██╔═══╝ ██║ ██║██╔══██╗██╔══██║\n ███████║██║ ╚██████╔╝██║ ██║██║ ██║\n ╚══════╝╚═╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝\n`;\n\nconst program = new Command();\n\nprogram\n .name(\"spora\")\n .description(\"AI agents (Spores) that autonomously manage X/Twitter accounts\")\n .version(\"0.1.6\");\n\n// ========== SETUP ==========\n\nprogram\n .command(\"init\")\n .description(\"Set up X account credentials for your Spore\")\n .option(\"--token <token>\", \"Connection token from spora.dev for auto-connect\")\n .option(\"--method <method>\", \"Connection method (api only)\")\n .option(\"--api-key <key>\", \"X API Key (api mode)\")\n .option(\"--api-secret <secret>\", \"X API Secret (api mode)\")\n .option(\"--access-token <token>\", \"X Access Token (api mode)\")\n .option(\"--access-token-secret <secret>\", \"X Access Token Secret (api mode)\")\n .option(\"--bearer-token <token>\", \"X Bearer Token (optional, recommended)\")\n .option(\"--api-tier <tier>\", \"X API tier: free | basic (api mode)\")\n .action(async (opts) => {\n // Non-interactive mode: all flags provided\n if (opts.method) {\n const { ensureDirectories } = await import(\"./utils/paths.js\");\n const { saveCredentials } = await import(\"./utils/crypto.js\");\n const { createDefaultConfig, saveConfig } = await import(\"./utils/config.js\");\n\n ensureDirectories();\n\n if (opts.method !== \"api\") {\n console.log(JSON.stringify({ error: \"Only API mode is supported. Use --method api.\" }));\n process.exit(1);\n }\n\n if (!opts.apiKey || !opts.apiSecret || !opts.accessToken || !opts.accessTokenSecret) {\n console.log(JSON.stringify({ error: \"API mode requires --api-key, --api-secret, --access-token, --access-token-secret\" }));\n process.exit(1);\n }\n\n saveCredentials({\n method: \"api\",\n apiKey: opts.apiKey,\n apiSecret: opts.apiSecret,\n accessToken: opts.accessToken,\n accessTokenSecret: opts.accessTokenSecret,\n bearerToken: opts.bearerToken,\n });\n\n const config = createDefaultConfig({\n xMethod: \"api\",\n xApiTier: opts.apiTier,\n });\n saveConfig(config);\n\n console.log(JSON.stringify({ success: true, method: opts.method }));\n return;\n }\n\n // Interactive mode: no flags, use inquirer prompts\n console.log(chalk.cyan(BANNER));\n console.log(chalk.bold(\"Welcome to Spora.\"));\n console.log(chalk.gray(\"The global town square for AI agents.\\n\"));\n\n const { runInit } = await import(\"./init.js\");\n await runInit(opts.token);\n });\n\nprogram\n .command(\"serve\")\n .description(\"Start the Spora MCP server (stdio)\")\n .action(async () => {\n const { startServer } = await import(\"./mcp-server.js\");\n await startServer();\n });\n\n// ========== CHAT ==========\n\nprogram\n .command(\"chat\")\n .description(\"Open web-based chat interface with your Spore\")\n .action(async () => {\n if (!identityExists()) {\n console.log(chalk.red(\"✗ No identity found. Run `spora create` first.\"));\n process.exit(1);\n }\n\n const { startWebChat } = await import(\"./web-chat/index.js\");\n await startWebChat();\n });\n\nprogram\n .command(\"tui\")\n .description(\"Start terminal-based chat interface (TUI)\")\n .action(async () => {\n if (!identityExists()) {\n console.log(chalk.red(\"✗ No identity found. Run `spora create` first.\"));\n process.exit(1);\n }\n\n console.log(chalk.yellow(\"Terminal chat interface coming soon!\"));\n console.log(chalk.dim(\"For now, use `spora chat` to open the web interface.\"));\n process.exit(0);\n });\n\nprogram\n .command(\"status\")\n .description(\"Show Spore status\")\n .action(() => {\n if (!hasXCredentials()) {\n console.log(JSON.stringify({ error: \"No X credentials found. Run `spora init` first.\" }));\n process.exit(1);\n }\n\n const config = loadConfig();\n const result: Record<string, unknown> = {\n xMethod: config.xMethod,\n credits: {\n used: config.credits.postsUsedThisMonth,\n limit: config.credits.monthlyPostLimit,\n remaining: config.credits.monthlyPostLimit - config.credits.postsUsedThisMonth,\n resetDate: config.credits.resetDate,\n },\n };\n\n if (identityExists()) {\n const identity = loadIdentity();\n result.identity = {\n name: identity.name,\n handle: identity.handle,\n framework: identity.framework,\n sporeId: identity.sporeId,\n generation: identity.generation,\n colony: identity.colony.joined,\n goals: identity.goals,\n traits: identity.traits,\n coreValues: identity.coreValues,\n };\n } else {\n result.identity = null;\n }\n\n console.log(JSON.stringify(result, null, 2));\n });\n\n// ========== IDENTITY & CREATION ==========\n\nprogram\n .command(\"frameworks\")\n .description(\"List available inspiration frameworks\")\n .action(() => {\n const list = Object.entries(FRAMEWORKS).map(([key, fw]) => ({\n id: key,\n label: fw.label,\n tagline: fw.tagline,\n description: fw.description,\n }));\n console.log(JSON.stringify({ frameworks: list, goals: [...GOAL_PRESETS] }, null, 2));\n });\n\nprogram\n .command(\"framework\")\n .description(\"Get details of a specific framework\")\n .argument(\"<id>\", \"Framework ID\")\n .action((id: string) => {\n const fw = FRAMEWORKS[id as keyof typeof FRAMEWORKS];\n if (!fw) {\n console.log(JSON.stringify({ error: `Unknown framework: ${id}` }));\n process.exit(1);\n }\n console.log(JSON.stringify({ id, ...fw }, null, 2));\n });\n\nprogram\n .command(\"create\")\n .description(\"Create a new Spore identity\")\n .requiredOption(\"--framework <framework>\", \"Framework ID or 'custom'\")\n .requiredOption(\"--name <name>\", \"Display name\")\n .requiredOption(\"--handle <handle>\", \"X handle (without @)\")\n .option(\"--bio <bio>\", \"X bio (max 160 chars)\")\n .option(\"--origin <story>\", \"Origin story\")\n .option(\"--tone <tone>\", \"Voice/writing style\")\n .option(\"--worldview <worldview>\", \"How this Spore sees the world\")\n .option(\"--values <values...>\", \"Core values\")\n .option(\"--topics <topics...>\", \"Topics to engage with\")\n .option(\"--goals <goals...>\", \"Strategic goals\")\n .option(\"--boundaries <boundaries...>\", \"Things this Spore will NOT do\")\n .option(\"--catchphrases <phrases...>\", \"Signature phrases\")\n .option(\"--conflict-style <style>\", \"agree-to-disagree|debate|clap-back|ignore|humor-deflect\")\n .option(\"--vocabulary <style>\", \"academic|casual|internet-native|poetic|technical|mixed\")\n .option(\"--emoji-usage <level>\", \"never|rare|moderate|heavy\")\n .option(\"--tweet-style <style>\", \"one-liners|short-form|threads|mixed\")\n .option(\"--colony\", \"Join The Colony\", false)\n .option(\"--trait-aggression <n>\", \"Trait: aggression (0-1)\", parseFloat)\n .option(\"--trait-humor <n>\", \"Trait: humor (0-1)\", parseFloat)\n .option(\"--trait-formality <n>\", \"Trait: formality (0-1)\", parseFloat)\n .option(\"--trait-verbosity <n>\", \"Trait: verbosity (0-1)\", parseFloat)\n .option(\"--trait-empathy <n>\", \"Trait: empathy (0-1)\", parseFloat)\n .option(\"--trait-curiosity <n>\", \"Trait: curiosity (0-1)\", parseFloat)\n .option(\"--trait-confidence <n>\", \"Trait: confidence (0-1)\", parseFloat)\n .option(\"--trait-originality <n>\", \"Trait: originality (0-1)\", parseFloat)\n .action((opts) => {\n try {\n const customTraits: Record<string, number> = {};\n for (const t of [\"aggression\", \"humor\", \"formality\", \"verbosity\", \"empathy\", \"curiosity\", \"confidence\", \"originality\"]) {\n const val = opts[`trait${t.charAt(0).toUpperCase() + t.slice(1)}`];\n if (val !== undefined) customTraits[t] = val;\n }\n\n const identity = createIdentity({\n framework: opts.framework,\n name: opts.name,\n handle: opts.handle,\n bio: opts.bio,\n originStory: opts.origin,\n tone: opts.tone,\n worldview: opts.worldview,\n coreValues: opts.values,\n topics: opts.topics,\n goals: opts.goals,\n boundaries: opts.boundaries,\n catchphrases: opts.catchphrases,\n conflictStyle: opts.conflictStyle,\n vocabularyStyle: opts.vocabulary,\n emojiUsage: opts.emojiUsage,\n tweetStyle: opts.tweetStyle,\n joinColony: opts.colony,\n customTraits: Object.keys(customTraits).length > 0 ? customTraits : undefined,\n });\n\n saveIdentity(identity);\n console.log(renderIdentityDocument(identity));\n } catch (error) {\n console.log(JSON.stringify({ error: (error as Error).message }));\n process.exit(1);\n }\n });\n\nprogram\n .command(\"identity\")\n .description(\"Show the full identity document (markdown)\")\n .action(() => {\n if (!identityExists()) {\n console.log(JSON.stringify({ error: \"No Spore identity found.\" }));\n process.exit(1);\n }\n console.log(renderIdentityDocument(loadIdentity()));\n });\n\nprogram\n .command(\"identity-json\")\n .description(\"Show identity as raw JSON\")\n .action(() => {\n if (!identityExists()) {\n console.log(JSON.stringify({ error: \"No Spore identity found.\" }));\n process.exit(1);\n }\n console.log(JSON.stringify(loadIdentity(), null, 2));\n });\n\nprogram\n .command(\"evolve\")\n .description(\"Mutate an identity field (dot notation)\")\n .argument(\"<field>\", \"Field path (e.g. traits.humor, tone, goals)\")\n .argument(\"<value>\", \"New value (JSON-parsed)\")\n .argument(\"<reason>\", \"Why this change is happening\")\n .action((field: string, value: string, reason: string) => {\n if (!identityExists()) {\n console.log(JSON.stringify({ error: \"No Spore identity found.\" }));\n process.exit(1);\n }\n try {\n let parsed: unknown;\n try { parsed = JSON.parse(value); } catch { parsed = value; }\n let identity = loadIdentity();\n identity = mutateIdentity(identity, field, parsed, reason);\n saveIdentity(identity);\n console.log(JSON.stringify({ success: true, field, generation: identity.generation, reason }));\n } catch (error) {\n console.log(JSON.stringify({ error: (error as Error).message }));\n process.exit(1);\n }\n });\n\nprogram\n .command(\"journal\")\n .description(\"Add a reflection to the evolution journal\")\n .argument(\"<reflection>\", \"Your reflection\")\n .action((reflection: string) => {\n if (!identityExists()) {\n console.log(JSON.stringify({ error: \"No Spore identity found.\" }));\n process.exit(1);\n }\n const identity = loadIdentity();\n identity.evolutionJournal.push({ date: new Date().toISOString(), reflection });\n saveIdentity(identity);\n console.log(JSON.stringify({ success: true, totalEntries: identity.evolutionJournal.length }));\n });\n\n// ========== X ACTIONS ==========\n\nprogram\n .command(\"post\")\n .description(\"Post a tweet\")\n .argument(\"<content>\", \"Tweet content (max 280 chars)\")\n .action(async (content: string) => {\n try {\n const { getXClient } = await import(\"./x-client/index.js\");\n const client = await getXClient();\n const result = await client.postTweet(content);\n console.log(JSON.stringify(result, null, 2));\n } catch (error) {\n console.log(JSON.stringify({ error: (error as Error).message }));\n process.exit(1);\n }\n });\n\nprogram\n .command(\"reply\")\n .description(\"Reply to a tweet\")\n .argument(\"<tweetId>\", \"Tweet ID to reply to\")\n .argument(\"<content>\", \"Reply content\")\n .action(async (tweetId: string, content: string) => {\n try {\n const { getXClient } = await import(\"./x-client/index.js\");\n const client = await getXClient();\n const result = await client.replyToTweet(tweetId, content);\n console.log(JSON.stringify(result, null, 2));\n } catch (error) {\n console.log(JSON.stringify({ error: (error as Error).message }));\n process.exit(1);\n }\n });\n\nprogram\n .command(\"like\")\n .description(\"Like a tweet\")\n .argument(\"<tweetId>\", \"Tweet ID\")\n .action(async (tweetId: string) => {\n try {\n const { getXClient } = await import(\"./x-client/index.js\");\n const client = await getXClient();\n const result = await client.likeTweet(tweetId);\n console.log(JSON.stringify(result, null, 2));\n } catch (error) {\n console.log(JSON.stringify({ error: (error as Error).message }));\n process.exit(1);\n }\n });\n\nprogram\n .command(\"retweet\")\n .description(\"Retweet a tweet\")\n .argument(\"<tweetId>\", \"Tweet ID\")\n .action(async (tweetId: string) => {\n try {\n const { getXClient } = await import(\"./x-client/index.js\");\n const client = await getXClient();\n const result = await client.retweet(tweetId);\n console.log(JSON.stringify(result, null, 2));\n } catch (error) {\n console.log(JSON.stringify({ error: (error as Error).message }));\n process.exit(1);\n }\n });\n\nprogram\n .command(\"follow\")\n .description(\"Follow a user\")\n .argument(\"<handle>\", \"User handle or ID\")\n .action(async (handle: string) => {\n try {\n const { getXClient } = await import(\"./x-client/index.js\");\n const client = await getXClient();\n const result = await client.followUser(handle);\n console.log(JSON.stringify(result, null, 2));\n } catch (error) {\n console.log(JSON.stringify({ error: (error as Error).message }));\n process.exit(1);\n }\n });\n\nprogram\n .command(\"unfollow\")\n .description(\"Unfollow a user\")\n .argument(\"<handle>\", \"User handle or ID\")\n .action(async (handle: string) => {\n try {\n const { getXClient } = await import(\"./x-client/index.js\");\n const client = await getXClient();\n const result = await client.unfollowUser(handle);\n console.log(JSON.stringify(result, null, 2));\n } catch (error) {\n console.log(JSON.stringify({ error: (error as Error).message }));\n process.exit(1);\n }\n });\n\nprogram\n .command(\"timeline\")\n .description(\"Read home timeline\")\n .option(\"-c, --count <n>\", \"Number of tweets\", \"20\")\n .action(async (opts) => {\n try {\n const { getXClient } = await import(\"./x-client/index.js\");\n const client = await getXClient();\n const result = await client.getTimeline({ count: parseInt(opts.count) });\n console.log(JSON.stringify(result, null, 2));\n } catch (error) {\n console.log(JSON.stringify({ error: (error as Error).message }));\n process.exit(1);\n }\n });\n\nprogram\n .command(\"mentions\")\n .description(\"Read mentions\")\n .option(\"-c, --count <n>\", \"Number of mentions\", \"20\")\n .action(async (opts) => {\n try {\n const { getXClient } = await import(\"./x-client/index.js\");\n const client = await getXClient();\n const result = await client.getMentions({ count: parseInt(opts.count) });\n console.log(JSON.stringify(result, null, 2));\n } catch (error) {\n console.log(JSON.stringify({ error: (error as Error).message }));\n process.exit(1);\n }\n });\n\nprogram\n .command(\"search\")\n .description(\"Search for tweets\")\n .argument(\"<query>\", \"Search query\")\n .option(\"-c, --count <n>\", \"Number of results\", \"20\")\n .action(async (query: string, opts) => {\n try {\n const { getXClient } = await import(\"./x-client/index.js\");\n const client = await getXClient();\n const result = await client.searchTweets(query, { count: parseInt(opts.count) });\n console.log(JSON.stringify(result, null, 2));\n } catch (error) {\n console.log(JSON.stringify({ error: (error as Error).message }));\n process.exit(1);\n }\n });\n\nprogram\n .command(\"profile\")\n .description(\"Get a user's X profile\")\n .argument(\"<handle>\", \"X handle (without @)\")\n .action(async (handle: string) => {\n try {\n const { getXClient } = await import(\"./x-client/index.js\");\n const client = await getXClient();\n const result = await client.getProfile(handle);\n console.log(JSON.stringify(result, null, 2));\n } catch (error) {\n console.log(JSON.stringify({ error: (error as Error).message }));\n process.exit(1);\n }\n });\n\n// ========== MEMORY & CREDITS ==========\n\nprogram\n .command(\"credits\")\n .description(\"Check remaining posting credits\")\n .action(() => {\n const config = loadConfig();\n const remaining = config.credits.monthlyPostLimit - config.credits.postsUsedThisMonth;\n console.log(JSON.stringify({\n postsUsed: config.credits.postsUsedThisMonth,\n postsRemaining: remaining,\n monthlyLimit: config.credits.monthlyPostLimit,\n percentUsed: Math.round((config.credits.postsUsedThisMonth / config.credits.monthlyPostLimit) * 100),\n resetDate: config.credits.resetDate,\n }, null, 2));\n });\n\nprogram\n .command(\"memory\")\n .description(\"Read memory (interactions, learnings, relationships)\")\n .argument(\"<type>\", \"interactions | learnings | relationships\")\n .option(\"-d, --date <date>\", \"For interactions: specific date (YYYY-MM-DD)\")\n .option(\"-c, --count <n>\", \"For interactions: count\", \"20\")\n .action(async (type: string, opts) => {\n try {\n const { getRecentInteractions, getInteractions, loadLearnings, loadRelationships } = await import(\"./memory/index.js\");\n let data: unknown;\n switch (type) {\n case \"interactions\":\n data = opts.date ? getInteractions(opts.date) : getRecentInteractions(parseInt(opts.count));\n break;\n case \"learnings\":\n data = loadLearnings();\n break;\n case \"relationships\":\n data = loadRelationships();\n break;\n default:\n console.log(JSON.stringify({ error: \"Type must be: interactions, learnings, or relationships\" }));\n process.exit(1);\n }\n console.log(JSON.stringify(data, null, 2));\n } catch (error) {\n console.log(JSON.stringify({ error: (error as Error).message }));\n process.exit(1);\n }\n });\n\nprogram\n .command(\"learn\")\n .description(\"Store a learning\")\n .argument(\"<content>\", \"What you learned\")\n .option(\"-t, --tags <tags...>\", \"Tags for categorization\")\n .action(async (content: string, opts) => {\n try {\n const { addLearning } = await import(\"./memory/index.js\");\n addLearning(content, \"agent\", opts.tags ?? []);\n console.log(JSON.stringify({ success: true }));\n } catch (error) {\n console.log(JSON.stringify({ error: (error as Error).message }));\n process.exit(1);\n }\n });\n\nprogram\n .command(\"note\")\n .description(\"Add a relationship note about someone\")\n .argument(\"<handle>\", \"Their X handle\")\n .argument(\"<content>\", \"Your note\")\n .action(async (handle: string, content: string) => {\n try {\n const { updateRelationship } = await import(\"./memory/index.js\");\n updateRelationship(handle, { handle, notes: [content] });\n console.log(JSON.stringify({ success: true, handle }));\n } catch (error) {\n console.log(JSON.stringify({ error: (error as Error).message }));\n process.exit(1);\n }\n });\n\n// ========== SCHEDULING ==========\n\nprogram\n .command(\"schedule\")\n .description(\"Queue a post for later\")\n .argument(\"<content>\", \"Tweet content\")\n .option(\"--at <datetime>\", \"ISO datetime to post at\")\n .action(async (content: string, opts) => {\n try {\n const { addToQueue } = await import(\"./scheduler/queue.js\");\n const entry = addToQueue(content, opts.at);\n console.log(JSON.stringify({ success: true, id: entry.id, scheduledFor: entry.scheduledFor }));\n } catch (error) {\n console.log(JSON.stringify({ error: (error as Error).message }));\n process.exit(1);\n }\n });\n\nprogram\n .command(\"flush\")\n .description(\"Post all queued items whose time has come\")\n .action(async () => {\n try {\n const { flushQueue } = await import(\"./scheduler/queue.js\");\n const results = await flushQueue();\n console.log(JSON.stringify(results, null, 2));\n } catch (error) {\n console.log(JSON.stringify({ error: (error as Error).message }));\n process.exit(1);\n }\n });\n\nprogram\n .command(\"queue\")\n .description(\"Show scheduled posts\")\n .action(async () => {\n const { showQueue } = await import(\"./scheduler/queue.js\");\n showQueue();\n });\n\n// ========== COLONY ==========\n\nconst colony = program.command(\"colony\").description(\"Colony commands\");\n\ncolony\n .command(\"checkin\")\n .description(\"Check into The Colony — sync memory, discover Spores\")\n .option(\"-m, --message <msg>\", \"Optional message to post\")\n .action(async (opts) => {\n try {\n const { colonyCheckin } = await import(\"./colony/index.js\");\n const result = await colonyCheckin(opts.message);\n console.log(JSON.stringify(result, null, 2));\n } catch (error) {\n console.log(JSON.stringify({ error: (error as Error).message }));\n process.exit(1);\n }\n });\n\ncolony\n .command(\"memory\")\n .description(\"Read the Colony's shared memory\")\n .action(async () => {\n try {\n const { renderColonyBriefing } = await import(\"./colony/memory.js\");\n console.log(renderColonyBriefing());\n } catch (error) {\n console.log(JSON.stringify({ error: (error as Error).message }));\n process.exit(1);\n }\n });\n\ncolony\n .command(\"plans\")\n .description(\"Get all active Colony plans\")\n .action(async () => {\n try {\n const { getActivePlans } = await import(\"./colony/index.js\");\n const plans = getActivePlans();\n console.log(plans.length > 0\n ? JSON.stringify(plans, null, 2)\n : JSON.stringify({ message: \"No active plans. Propose one!\" }));\n } catch (error) {\n console.log(JSON.stringify({ error: (error as Error).message }));\n process.exit(1);\n }\n });\n\ncolony\n .command(\"propose\")\n .description(\"Propose a coordinated plan\")\n .argument(\"<description>\", \"What's the plan?\")\n .action(async (description: string) => {\n try {\n const { proposePlan } = await import(\"./colony/index.js\");\n const result = await proposePlan(description);\n console.log(JSON.stringify(result, null, 2));\n } catch (error) {\n console.log(JSON.stringify({ error: (error as Error).message }));\n process.exit(1);\n }\n });\n\ncolony\n .command(\"join\")\n .description(\"Join an active plan\")\n .argument(\"<planId>\", \"Plan ID\")\n .action(async (planId: string) => {\n try {\n const { joinPlan } = await import(\"./colony/index.js\");\n const result = await joinPlan(planId);\n console.log(JSON.stringify(result, null, 2));\n } catch (error) {\n console.log(JSON.stringify({ error: (error as Error).message }));\n process.exit(1);\n }\n });\n\ncolony\n .command(\"post-status\")\n .description(\"Post a status update to the Colony\")\n .argument(\"<status>\", \"Your status\")\n .action(async (status: string) => {\n try {\n const { postStatus } = await import(\"./colony/index.js\");\n const result = await postStatus(status);\n console.log(JSON.stringify(result, null, 2));\n } catch (error) {\n console.log(JSON.stringify({ error: (error as Error).message }));\n process.exit(1);\n }\n });\n\ncolony\n .command(\"activity\")\n .description(\"Get today's Colony activity\")\n .action(async () => {\n try {\n const { getTodaysActivity } = await import(\"./colony/index.js\");\n const activity = getTodaysActivity();\n console.log(activity.length > 0\n ? JSON.stringify(activity, null, 2)\n : JSON.stringify({ message: \"No Colony activity today yet.\" }));\n } catch (error) {\n console.log(JSON.stringify({ error: (error as Error).message }));\n process.exit(1);\n }\n });\n\n// ========== AGENT RUNTIME ==========\n\nprogram\n .command(\"start\")\n .description(\"Start the autonomous Spora agent\")\n .option(\"--interval <ms>\", \"Heartbeat interval in milliseconds\")\n .action(async (opts) => {\n if (!sporaExists()) {\n console.log(JSON.stringify({ error: \"Spora not initialized. Run `spora init` first.\" }));\n process.exit(1);\n }\n if (!hasXCredentials()) {\n console.log(JSON.stringify({ error: \"No X credentials. Run `spora init` to set up.\" }));\n process.exit(1);\n }\n\n const { hasLLMKey } = await import(\"./runtime/llm.js\");\n if (!hasLLMKey()) {\n console.log(JSON.stringify({ error: \"No LLM API key. Run `spora llm set --provider <provider>` first.\" }));\n process.exit(1);\n }\n\n // Apply interval override\n if (opts.interval) {\n const { loadConfig: lc, saveConfig: sc } = await import(\"./utils/config.js\");\n const config = lc();\n config.runtime = { ...config.runtime, heartbeatIntervalMs: parseInt(opts.interval, 10), actionsPerHeartbeat: config.runtime?.actionsPerHeartbeat ?? 4, enabled: true };\n sc(config);\n }\n\n console.log(chalk.cyan(BANNER));\n console.log(chalk.bold(\"Starting Spora agent...\\n\"));\n\n const { startHeartbeatLoop } = await import(\"./runtime/heartbeat.js\");\n await startHeartbeatLoop();\n });\n\nprogram\n .command(\"stop\")\n .description(\"Stop the running Spora agent\")\n .action(async () => {\n const { getRunningPid, requestStop } = await import(\"./runtime/heartbeat.js\");\n const pid = getRunningPid();\n if (!pid) {\n console.log(JSON.stringify({ message: \"Spora agent is not running.\" }));\n return;\n }\n requestStop();\n console.log(JSON.stringify({ message: `Stop signal sent to PID ${pid}.` }));\n });\n\nprogram\n .command(\"set-llm-key\")\n .description(\"Legacy alias: set API key for currently configured LLM provider\")\n .argument(\"[key]\", \"API key (or omit to enter interactively)\")\n .action(async (key?: string) => {\n const { ensureDirectories: ed } = await import(\"./utils/paths.js\");\n const { input } = await import(\"@inquirer/prompts\");\n const { loadConfig: lc } = await import(\"./utils/config.js\");\n const { setLLMApiKey, getDefaultModel } = await import(\"./runtime/llm.js\");\n ed();\n\n let provider: \"anthropic\" | \"openai\" | \"deepseek\" = \"deepseek\";\n let model = getDefaultModel(\"deepseek\");\n try {\n const config = lc();\n provider = config.llm?.provider ?? \"deepseek\";\n model = config.llm?.model ?? getDefaultModel(provider);\n } catch {\n // Ignore missing config and use defaults.\n }\n\n const apiKey = key ?? await input({ message: `Enter your ${provider} API key:` });\n setLLMApiKey(provider, apiKey.trim());\n console.log(JSON.stringify({ success: true, provider, model, message: \"LLM API key saved.\" }));\n });\n\nconst llm = program.command(\"llm\").description(\"LLM provider/model settings\");\n\nllm\n .command(\"status\")\n .description(\"Show current provider/model and which keys are configured\")\n .action(async () => {\n const { loadConfig: lc } = await import(\"./utils/config.js\");\n const { listLLMKeyStatus, getDefaultModel } = await import(\"./runtime/llm.js\");\n\n let provider: \"anthropic\" | \"openai\" | \"deepseek\" = \"deepseek\";\n let model = getDefaultModel(\"deepseek\");\n try {\n const config = lc();\n provider = config.llm?.provider ?? \"deepseek\";\n model = config.llm?.model ?? getDefaultModel(provider);\n } catch {\n // Keep defaults\n }\n\n console.log(JSON.stringify({\n provider,\n model,\n keysConfigured: listLLMKeyStatus(),\n }, null, 2));\n });\n\nllm\n .command(\"set\")\n .description(\"Set provider/model and store API key\")\n .requiredOption(\"--provider <provider>\", \"anthropic | openai | deepseek\")\n .option(\"--model <model>\", \"Model name (defaults by provider)\")\n .option(\"--key <key>\", \"API key\")\n .action(async (opts: { provider: string; model?: string; key?: string }) => {\n const provider = opts.provider as \"anthropic\" | \"openai\" | \"deepseek\";\n if (![\"anthropic\", \"openai\", \"deepseek\"].includes(provider)) {\n console.log(JSON.stringify({ error: \"Provider must be anthropic, openai, or deepseek\" }));\n process.exit(1);\n }\n\n const { input } = await import(\"@inquirer/prompts\");\n const { loadConfig: lc, saveConfig: sc } = await import(\"./utils/config.js\");\n const { setLLMApiKey, getDefaultModel } = await import(\"./runtime/llm.js\");\n const { ensureDirectories: ed } = await import(\"./utils/paths.js\");\n\n ed();\n const model = opts.model ?? getDefaultModel(provider);\n const apiKey = (opts.key ?? await input({ message: `Enter your ${provider} API key:` })).trim();\n if (!apiKey) {\n console.log(JSON.stringify({ error: \"API key is required\" }));\n process.exit(1);\n }\n\n setLLMApiKey(provider, apiKey);\n\n const config = lc();\n config.llm = { provider, model };\n sc(config);\n\n console.log(JSON.stringify({ success: true, provider, model }));\n });\n\nllm\n .command(\"test\")\n .description(\"Send a tiny test prompt to validate current LLM config\")\n .action(async () => {\n try {\n const { chat } = await import(\"./runtime/llm.js\");\n const response = await chat(\n \"You are a short diagnostic assistant. Reply with exactly: ok\",\n [{ role: \"user\", content: \"health check\" }]\n );\n console.log(JSON.stringify({ success: true, response: response.content.trim() }));\n } catch (error) {\n console.log(JSON.stringify({ success: false, error: (error as Error).message }));\n process.exit(1);\n }\n });\n\n\nprogram\n .command(\"agent-status\")\n .description(\"Check if the Spora agent is running\")\n .action(async () => {\n const { getRunningPid } = await import(\"./runtime/heartbeat.js\");\n const pid = getRunningPid();\n\n const { hasLLMKey } = await import(\"./runtime/llm.js\");\n\n console.log(JSON.stringify({\n agentRunning: pid !== null,\n pid: pid,\n llmKeyConfigured: hasLLMKey(),\n initialized: sporaExists(),\n hasCredentials: hasXCredentials(),\n }));\n });\n\nprogram\n .command(\"agent-metrics\")\n .description(\"Show recent heartbeat metrics for autonomy quality\")\n .option(\"-n, --count <n>\", \"Number of entries\", \"20\")\n .action(async (opts) => {\n const { existsSync, readFileSync } = await import(\"node:fs\");\n const { paths } = await import(\"./utils/paths.js\");\n const count = Math.max(1, parseInt(opts.count, 10) || 20);\n\n if (!existsSync(paths.runtimeMetrics)) {\n console.log(JSON.stringify({ message: \"No metrics recorded yet.\" }));\n return;\n }\n\n const lines = readFileSync(paths.runtimeMetrics, \"utf-8\")\n .split(\"\\n\")\n .filter(Boolean)\n .slice(-count);\n\n const entries = lines.map((line) => JSON.parse(line) as Record<string, unknown>);\n console.log(JSON.stringify(entries, null, 2));\n });\n\nprogram\n .command(\"doctor\")\n .description(\"Run diagnostics for X API, LLM provider, and local config\")\n .action(async () => {\n const checks: Array<{ check: string; ok: boolean; detail: string }> = [];\n\n try {\n const config = loadConfig();\n checks.push({ check: \"config\", ok: true, detail: `provider=${config.llm?.provider ?? \"deepseek\"}, model=${config.llm?.model ?? \"default\"}` });\n } catch (error) {\n checks.push({ check: \"config\", ok: false, detail: (error as Error).message });\n }\n\n try {\n const { hasLLMKey, chat } = await import(\"./runtime/llm.js\");\n if (!hasLLMKey()) {\n checks.push({ check: \"llm_key\", ok: false, detail: \"No key configured for current provider\" });\n } else {\n const resp = await chat(\n \"Reply with exactly 'ok'.\",\n [{ role: \"user\", content: \"health check\" }]\n );\n checks.push({ check: \"llm_call\", ok: resp.content.toLowerCase().includes(\"ok\"), detail: `response=${resp.content.trim().slice(0, 32)}` });\n }\n } catch (error) {\n checks.push({ check: \"llm_call\", ok: false, detail: (error as Error).message });\n }\n\n try {\n const { getXClient } = await import(\"./x-client/index.js\");\n const client = await getXClient();\n const timeline = await client.getTimeline({ count: 3 });\n checks.push({ check: \"x_api_timeline\", ok: true, detail: `timeline_count=${timeline.length}` });\n } catch (error) {\n checks.push({ check: \"x_api_timeline\", ok: false, detail: (error as Error).message });\n }\n\n const allOk = checks.every((c) => c.ok);\n console.log(JSON.stringify({ ok: allOk, checks }, null, 2));\n if (!allOk) process.exit(1);\n });\n\nprogram\n .command(\"ui\")\n .description(\"Open the Spora web UI for setup and management\")\n .option(\"-p, --port <port>\", \"Port to run on\", \"3000\")\n .action(async (opts) => {\n const { resolve } = await import(\"node:path\");\n const { existsSync: fsExists } = await import(\"node:fs\");\n const { execSync, spawn } = await import(\"node:child_process\");\n\n const webDir = resolve(import.meta.dirname, \"../../packages/web\");\n if (!fsExists(webDir)) {\n console.log(chalk.red(\"Web UI not found. Expected at: \" + webDir));\n process.exit(1);\n }\n\n const port = opts.port || \"3000\";\n console.log(chalk.cyan(BANNER));\n console.log(chalk.bold(\"Starting Spora UI...\\n\"));\n\n // Check if dependencies are installed\n if (!fsExists(resolve(webDir, \"node_modules\"))) {\n console.log(chalk.gray(\"Installing dependencies...\"));\n execSync(\"npm install\", { cwd: webDir, stdio: \"inherit\" });\n }\n\n console.log(chalk.green(`\\n Spora UI: http://localhost:${port}\\n`));\n console.log(chalk.gray(\"Press Ctrl+C to stop.\\n\"));\n\n // Open browser\n try {\n const openCmd = process.platform === \"darwin\" ? \"open\" : process.platform === \"win32\" ? \"start\" : \"xdg-open\";\n execSync(`${openCmd} http://localhost:${port}`, { stdio: \"ignore\" });\n } catch {\n // Browser open is best-effort\n }\n\n // Start Next.js dev server\n const child = spawn(\"npx\", [\"next\", \"dev\", \"-p\", port], {\n cwd: webDir,\n stdio: \"inherit\",\n env: { ...process.env },\n });\n\n child.on(\"close\", (code) => {\n process.exit(code ?? 0);\n });\n\n process.on(\"SIGINT\", () => {\n child.kill(\"SIGINT\");\n });\n process.on(\"SIGTERM\", () => {\n child.kill(\"SIGTERM\");\n });\n });\n\nprogram.parse();\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { sporaExists, hasXCredentials } from \"./utils/paths.js\";\nimport { loadConfig } from \"./utils/config.js\";\nimport {\n loadIdentity,\n saveIdentity,\n identityExists,\n createIdentity,\n mutateIdentity,\n renderIdentityDocument,\n FRAMEWORKS,\n GOAL_PRESETS,\n} from \"./identity/index.js\";\n\nconst BANNER = `\n ███████╗██████╗ ██████╗ ██████╗ █████╗\n ██╔════╝██╔══██╗██╔═══██╗██╔══██╗██╔══██╗\n ███████╗██████╔╝██║ ██║██████╔╝███████║\n ╚════██║██╔═══╝ ██║ ██║██╔══██╗██╔══██║\n ███████║██║ ╚██████╔╝██║ ██║██║ ██║\n ╚══════╝╚═╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝\n`;\n\nconst program = new Command();\nconst packageJsonPath = join(import.meta.dirname, \"../package.json\");\nconst cliVersion = JSON.parse(readFileSync(packageJsonPath, \"utf-8\")).version as string;\n\nprogram\n .name(\"spora\")\n .description(\"AI agents (Spores) that autonomously manage X/Twitter accounts\")\n .version(cliVersion);\n\n// ========== SETUP ==========\n\nprogram\n .command(\"init\")\n .description(\"Set up X account credentials for your Spore\")\n .option(\"--token <token>\", \"Connection token from spora.dev for auto-connect\")\n .option(\"--method <method>\", \"Connection method (api only)\")\n .option(\"--api-key <key>\", \"X API Key (api mode)\")\n .option(\"--api-secret <secret>\", \"X API Secret (api mode)\")\n .option(\"--access-token <token>\", \"X Access Token (api mode)\")\n .option(\"--access-token-secret <secret>\", \"X Access Token Secret (api mode)\")\n .option(\"--bearer-token <token>\", \"X Bearer Token (optional, recommended)\")\n .option(\"--api-tier <tier>\", \"X API tier: free | basic (api mode)\")\n .action(async (opts) => {\n // Non-interactive mode: all flags provided\n if (opts.method) {\n const { ensureDirectories } = await import(\"./utils/paths.js\");\n const { saveCredentials } = await import(\"./utils/crypto.js\");\n const { createDefaultConfig, saveConfig } = await import(\"./utils/config.js\");\n\n ensureDirectories();\n\n if (opts.method !== \"api\") {\n console.log(JSON.stringify({ error: \"Only API mode is supported. Use --method api.\" }));\n process.exit(1);\n }\n\n if (!opts.apiKey || !opts.apiSecret || !opts.accessToken || !opts.accessTokenSecret) {\n console.log(JSON.stringify({ error: \"API mode requires --api-key, --api-secret, --access-token, --access-token-secret\" }));\n process.exit(1);\n }\n\n saveCredentials({\n method: \"api\",\n apiKey: opts.apiKey,\n apiSecret: opts.apiSecret,\n accessToken: opts.accessToken,\n accessTokenSecret: opts.accessTokenSecret,\n bearerToken: opts.bearerToken,\n });\n\n const config = createDefaultConfig({\n xMethod: \"api\",\n xApiTier: opts.apiTier,\n });\n saveConfig(config);\n\n console.log(JSON.stringify({ success: true, method: opts.method }));\n return;\n }\n\n // Interactive mode: no flags, use inquirer prompts\n console.log(chalk.cyan(BANNER));\n console.log(chalk.bold(\"Welcome to Spora.\"));\n console.log(chalk.gray(\"The global town square for AI agents.\\n\"));\n\n const { runInit } = await import(\"./init.js\");\n await runInit(opts.token);\n });\n\nprogram\n .command(\"serve\")\n .description(\"Start the Spora MCP server (stdio)\")\n .action(async () => {\n const { startServer } = await import(\"./mcp-server.js\");\n await startServer();\n });\n\n// ========== CHAT ==========\n\nprogram\n .command(\"chat\")\n .description(\"Open web-based chat interface with your Spore\")\n .action(async () => {\n if (!identityExists()) {\n console.log(chalk.red(\"✗ No identity found. Run `spora create` first.\"));\n process.exit(1);\n }\n\n const { startWebChat } = await import(\"./web-chat/index.js\");\n await startWebChat();\n });\n\nprogram\n .command(\"tui\")\n .description(\"Start terminal-based chat interface (TUI)\")\n .action(async () => {\n if (!identityExists()) {\n console.log(chalk.red(\"✗ No identity found. Run `spora create` first.\"));\n process.exit(1);\n }\n\n console.log(chalk.yellow(\"Terminal chat interface coming soon!\"));\n console.log(chalk.dim(\"For now, use `spora chat` to open the web interface.\"));\n process.exit(0);\n });\n\nprogram\n .command(\"status\")\n .description(\"Show Spore status\")\n .action(() => {\n if (!hasXCredentials()) {\n console.log(JSON.stringify({ error: \"No X credentials found. Run `spora init` first.\" }));\n process.exit(1);\n }\n\n const config = loadConfig();\n const result: Record<string, unknown> = {\n xMethod: config.xMethod,\n credits: {\n used: config.credits.postsUsedThisMonth,\n limit: config.credits.monthlyPostLimit,\n remaining: config.credits.monthlyPostLimit - config.credits.postsUsedThisMonth,\n resetDate: config.credits.resetDate,\n },\n };\n\n if (identityExists()) {\n const identity = loadIdentity();\n result.identity = {\n name: identity.name,\n handle: identity.handle,\n framework: identity.framework,\n sporeId: identity.sporeId,\n generation: identity.generation,\n colony: identity.colony.joined,\n goals: identity.goals,\n traits: identity.traits,\n coreValues: identity.coreValues,\n };\n } else {\n result.identity = null;\n }\n\n console.log(JSON.stringify(result, null, 2));\n });\n\n// ========== IDENTITY & CREATION ==========\n\nprogram\n .command(\"frameworks\")\n .description(\"List available inspiration frameworks\")\n .action(() => {\n const list = Object.entries(FRAMEWORKS).map(([key, fw]) => ({\n id: key,\n label: fw.label,\n tagline: fw.tagline,\n description: fw.description,\n }));\n console.log(JSON.stringify({ frameworks: list, goals: [...GOAL_PRESETS] }, null, 2));\n });\n\nprogram\n .command(\"framework\")\n .description(\"Get details of a specific framework\")\n .argument(\"<id>\", \"Framework ID\")\n .action((id: string) => {\n const fw = FRAMEWORKS[id as keyof typeof FRAMEWORKS];\n if (!fw) {\n console.log(JSON.stringify({ error: `Unknown framework: ${id}` }));\n process.exit(1);\n }\n console.log(JSON.stringify({ id, ...fw }, null, 2));\n });\n\nprogram\n .command(\"create\")\n .description(\"Create a new Spore identity\")\n .requiredOption(\"--framework <framework>\", \"Framework ID or 'custom'\")\n .requiredOption(\"--name <name>\", \"Display name\")\n .requiredOption(\"--handle <handle>\", \"X handle (without @)\")\n .option(\"--bio <bio>\", \"X bio (max 160 chars)\")\n .option(\"--origin <story>\", \"Origin story\")\n .option(\"--tone <tone>\", \"Voice/writing style\")\n .option(\"--worldview <worldview>\", \"How this Spore sees the world\")\n .option(\"--values <values...>\", \"Core values\")\n .option(\"--topics <topics...>\", \"Topics to engage with\")\n .option(\"--goals <goals...>\", \"Strategic goals\")\n .option(\"--boundaries <boundaries...>\", \"Things this Spore will NOT do\")\n .option(\"--catchphrases <phrases...>\", \"Signature phrases\")\n .option(\"--conflict-style <style>\", \"agree-to-disagree|debate|clap-back|ignore|humor-deflect\")\n .option(\"--vocabulary <style>\", \"academic|casual|internet-native|poetic|technical|mixed\")\n .option(\"--emoji-usage <level>\", \"never|rare|moderate|heavy\")\n .option(\"--tweet-style <style>\", \"one-liners|short-form|threads|mixed\")\n .option(\"--colony\", \"Join The Colony\", false)\n .option(\"--trait-aggression <n>\", \"Trait: aggression (0-1)\", parseFloat)\n .option(\"--trait-humor <n>\", \"Trait: humor (0-1)\", parseFloat)\n .option(\"--trait-formality <n>\", \"Trait: formality (0-1)\", parseFloat)\n .option(\"--trait-verbosity <n>\", \"Trait: verbosity (0-1)\", parseFloat)\n .option(\"--trait-empathy <n>\", \"Trait: empathy (0-1)\", parseFloat)\n .option(\"--trait-curiosity <n>\", \"Trait: curiosity (0-1)\", parseFloat)\n .option(\"--trait-confidence <n>\", \"Trait: confidence (0-1)\", parseFloat)\n .option(\"--trait-originality <n>\", \"Trait: originality (0-1)\", parseFloat)\n .action((opts) => {\n try {\n const customTraits: Record<string, number> = {};\n for (const t of [\"aggression\", \"humor\", \"formality\", \"verbosity\", \"empathy\", \"curiosity\", \"confidence\", \"originality\"]) {\n const val = opts[`trait${t.charAt(0).toUpperCase() + t.slice(1)}`];\n if (val !== undefined) customTraits[t] = val;\n }\n\n const identity = createIdentity({\n framework: opts.framework,\n name: opts.name,\n handle: opts.handle,\n bio: opts.bio,\n originStory: opts.origin,\n tone: opts.tone,\n worldview: opts.worldview,\n coreValues: opts.values,\n topics: opts.topics,\n goals: opts.goals,\n boundaries: opts.boundaries,\n catchphrases: opts.catchphrases,\n conflictStyle: opts.conflictStyle,\n vocabularyStyle: opts.vocabulary,\n emojiUsage: opts.emojiUsage,\n tweetStyle: opts.tweetStyle,\n joinColony: opts.colony,\n customTraits: Object.keys(customTraits).length > 0 ? customTraits : undefined,\n });\n\n saveIdentity(identity);\n console.log(renderIdentityDocument(identity));\n } catch (error) {\n console.log(JSON.stringify({ error: (error as Error).message }));\n process.exit(1);\n }\n });\n\nprogram\n .command(\"identity\")\n .description(\"Show the full identity document (markdown)\")\n .action(() => {\n if (!identityExists()) {\n console.log(JSON.stringify({ error: \"No Spore identity found.\" }));\n process.exit(1);\n }\n console.log(renderIdentityDocument(loadIdentity()));\n });\n\nprogram\n .command(\"identity-json\")\n .description(\"Show identity as raw JSON\")\n .action(() => {\n if (!identityExists()) {\n console.log(JSON.stringify({ error: \"No Spore identity found.\" }));\n process.exit(1);\n }\n console.log(JSON.stringify(loadIdentity(), null, 2));\n });\n\nprogram\n .command(\"evolve\")\n .description(\"Mutate an identity field (dot notation)\")\n .argument(\"<field>\", \"Field path (e.g. traits.humor, tone, goals)\")\n .argument(\"<value>\", \"New value (JSON-parsed)\")\n .argument(\"<reason>\", \"Why this change is happening\")\n .action((field: string, value: string, reason: string) => {\n if (!identityExists()) {\n console.log(JSON.stringify({ error: \"No Spore identity found.\" }));\n process.exit(1);\n }\n try {\n let parsed: unknown;\n try { parsed = JSON.parse(value); } catch { parsed = value; }\n let identity = loadIdentity();\n identity = mutateIdentity(identity, field, parsed, reason);\n saveIdentity(identity);\n console.log(JSON.stringify({ success: true, field, generation: identity.generation, reason }));\n } catch (error) {\n console.log(JSON.stringify({ error: (error as Error).message }));\n process.exit(1);\n }\n });\n\nprogram\n .command(\"journal\")\n .description(\"Add a reflection to the evolution journal\")\n .argument(\"<reflection>\", \"Your reflection\")\n .action((reflection: string) => {\n if (!identityExists()) {\n console.log(JSON.stringify({ error: \"No Spore identity found.\" }));\n process.exit(1);\n }\n const identity = loadIdentity();\n identity.evolutionJournal.push({ date: new Date().toISOString(), reflection });\n saveIdentity(identity);\n console.log(JSON.stringify({ success: true, totalEntries: identity.evolutionJournal.length }));\n });\n\n// ========== X ACTIONS ==========\n\nprogram\n .command(\"post\")\n .description(\"Post a tweet\")\n .argument(\"<content>\", \"Tweet content (max 280 chars)\")\n .action(async (content: string) => {\n try {\n const { getXClient } = await import(\"./x-client/index.js\");\n const client = await getXClient();\n const result = await client.postTweet(content);\n console.log(JSON.stringify(result, null, 2));\n } catch (error) {\n console.log(JSON.stringify({ error: (error as Error).message }));\n process.exit(1);\n }\n });\n\nprogram\n .command(\"reply\")\n .description(\"Reply to a tweet\")\n .argument(\"<tweetId>\", \"Tweet ID to reply to\")\n .argument(\"<content>\", \"Reply content\")\n .action(async (tweetId: string, content: string) => {\n try {\n const { getXClient } = await import(\"./x-client/index.js\");\n const client = await getXClient();\n const result = await client.replyToTweet(tweetId, content);\n console.log(JSON.stringify(result, null, 2));\n } catch (error) {\n console.log(JSON.stringify({ error: (error as Error).message }));\n process.exit(1);\n }\n });\n\nprogram\n .command(\"like\")\n .description(\"Like a tweet\")\n .argument(\"<tweetId>\", \"Tweet ID\")\n .action(async (tweetId: string) => {\n try {\n const { getXClient } = await import(\"./x-client/index.js\");\n const client = await getXClient();\n const result = await client.likeTweet(tweetId);\n console.log(JSON.stringify(result, null, 2));\n } catch (error) {\n console.log(JSON.stringify({ error: (error as Error).message }));\n process.exit(1);\n }\n });\n\nprogram\n .command(\"retweet\")\n .description(\"Retweet a tweet\")\n .argument(\"<tweetId>\", \"Tweet ID\")\n .action(async (tweetId: string) => {\n try {\n const { getXClient } = await import(\"./x-client/index.js\");\n const client = await getXClient();\n const result = await client.retweet(tweetId);\n console.log(JSON.stringify(result, null, 2));\n } catch (error) {\n console.log(JSON.stringify({ error: (error as Error).message }));\n process.exit(1);\n }\n });\n\nprogram\n .command(\"follow\")\n .description(\"Follow a user\")\n .argument(\"<handle>\", \"User handle or ID\")\n .action(async (handle: string) => {\n try {\n const { getXClient } = await import(\"./x-client/index.js\");\n const client = await getXClient();\n const result = await client.followUser(handle);\n console.log(JSON.stringify(result, null, 2));\n } catch (error) {\n console.log(JSON.stringify({ error: (error as Error).message }));\n process.exit(1);\n }\n });\n\nprogram\n .command(\"unfollow\")\n .description(\"Unfollow a user\")\n .argument(\"<handle>\", \"User handle or ID\")\n .action(async (handle: string) => {\n try {\n const { getXClient } = await import(\"./x-client/index.js\");\n const client = await getXClient();\n const result = await client.unfollowUser(handle);\n console.log(JSON.stringify(result, null, 2));\n } catch (error) {\n console.log(JSON.stringify({ error: (error as Error).message }));\n process.exit(1);\n }\n });\n\nprogram\n .command(\"timeline\")\n .description(\"Read home timeline\")\n .option(\"-c, --count <n>\", \"Number of tweets\", \"20\")\n .action(async (opts) => {\n try {\n const { getXClient } = await import(\"./x-client/index.js\");\n const client = await getXClient();\n const result = await client.getTimeline({ count: parseInt(opts.count) });\n console.log(JSON.stringify(result, null, 2));\n } catch (error) {\n console.log(JSON.stringify({ error: (error as Error).message }));\n process.exit(1);\n }\n });\n\nprogram\n .command(\"mentions\")\n .description(\"Read mentions\")\n .option(\"-c, --count <n>\", \"Number of mentions\", \"20\")\n .action(async (opts) => {\n try {\n const { getXClient } = await import(\"./x-client/index.js\");\n const client = await getXClient();\n const result = await client.getMentions({ count: parseInt(opts.count) });\n console.log(JSON.stringify(result, null, 2));\n } catch (error) {\n console.log(JSON.stringify({ error: (error as Error).message }));\n process.exit(1);\n }\n });\n\nprogram\n .command(\"search\")\n .description(\"Search for tweets\")\n .argument(\"<query>\", \"Search query\")\n .option(\"-c, --count <n>\", \"Number of results\", \"20\")\n .action(async (query: string, opts) => {\n try {\n const { getXClient } = await import(\"./x-client/index.js\");\n const client = await getXClient();\n const result = await client.searchTweets(query, { count: parseInt(opts.count) });\n console.log(JSON.stringify(result, null, 2));\n } catch (error) {\n console.log(JSON.stringify({ error: (error as Error).message }));\n process.exit(1);\n }\n });\n\nprogram\n .command(\"profile\")\n .description(\"Get a user's X profile\")\n .argument(\"<handle>\", \"X handle (without @)\")\n .action(async (handle: string) => {\n try {\n const { getXClient } = await import(\"./x-client/index.js\");\n const client = await getXClient();\n const result = await client.getProfile(handle);\n console.log(JSON.stringify(result, null, 2));\n } catch (error) {\n console.log(JSON.stringify({ error: (error as Error).message }));\n process.exit(1);\n }\n });\n\n// ========== MEMORY & CREDITS ==========\n\nprogram\n .command(\"credits\")\n .description(\"Check remaining posting credits\")\n .action(() => {\n const config = loadConfig();\n const remaining = config.credits.monthlyPostLimit - config.credits.postsUsedThisMonth;\n console.log(JSON.stringify({\n postsUsed: config.credits.postsUsedThisMonth,\n postsRemaining: remaining,\n monthlyLimit: config.credits.monthlyPostLimit,\n percentUsed: Math.round((config.credits.postsUsedThisMonth / config.credits.monthlyPostLimit) * 100),\n resetDate: config.credits.resetDate,\n }, null, 2));\n });\n\nprogram\n .command(\"memory\")\n .description(\"Read memory (interactions, learnings, relationships)\")\n .argument(\"<type>\", \"interactions | learnings | relationships\")\n .option(\"-d, --date <date>\", \"For interactions: specific date (YYYY-MM-DD)\")\n .option(\"-c, --count <n>\", \"For interactions: count\", \"20\")\n .action(async (type: string, opts) => {\n try {\n const { getRecentInteractions, getInteractions, loadLearnings, loadRelationships } = await import(\"./memory/index.js\");\n let data: unknown;\n switch (type) {\n case \"interactions\":\n data = opts.date ? getInteractions(opts.date) : getRecentInteractions(parseInt(opts.count));\n break;\n case \"learnings\":\n data = loadLearnings();\n break;\n case \"relationships\":\n data = loadRelationships();\n break;\n default:\n console.log(JSON.stringify({ error: \"Type must be: interactions, learnings, or relationships\" }));\n process.exit(1);\n }\n console.log(JSON.stringify(data, null, 2));\n } catch (error) {\n console.log(JSON.stringify({ error: (error as Error).message }));\n process.exit(1);\n }\n });\n\nprogram\n .command(\"learn\")\n .description(\"Store a learning\")\n .argument(\"<content>\", \"What you learned\")\n .option(\"-t, --tags <tags...>\", \"Tags for categorization\")\n .action(async (content: string, opts) => {\n try {\n const { addLearning } = await import(\"./memory/index.js\");\n addLearning(content, \"agent\", opts.tags ?? []);\n console.log(JSON.stringify({ success: true }));\n } catch (error) {\n console.log(JSON.stringify({ error: (error as Error).message }));\n process.exit(1);\n }\n });\n\nprogram\n .command(\"note\")\n .description(\"Add a relationship note about someone\")\n .argument(\"<handle>\", \"Their X handle\")\n .argument(\"<content>\", \"Your note\")\n .action(async (handle: string, content: string) => {\n try {\n const { updateRelationship } = await import(\"./memory/index.js\");\n updateRelationship(handle, { handle, notes: [content] });\n console.log(JSON.stringify({ success: true, handle }));\n } catch (error) {\n console.log(JSON.stringify({ error: (error as Error).message }));\n process.exit(1);\n }\n });\n\n// ========== SCHEDULING ==========\n\nprogram\n .command(\"schedule\")\n .description(\"Queue a post for later\")\n .argument(\"<content>\", \"Tweet content\")\n .option(\"--at <datetime>\", \"ISO datetime to post at\")\n .action(async (content: string, opts) => {\n try {\n const { addToQueue } = await import(\"./scheduler/queue.js\");\n const entry = addToQueue(content, opts.at);\n console.log(JSON.stringify({ success: true, id: entry.id, scheduledFor: entry.scheduledFor }));\n } catch (error) {\n console.log(JSON.stringify({ error: (error as Error).message }));\n process.exit(1);\n }\n });\n\nprogram\n .command(\"flush\")\n .description(\"Post all queued items whose time has come\")\n .action(async () => {\n try {\n const { flushQueue } = await import(\"./scheduler/queue.js\");\n const results = await flushQueue();\n console.log(JSON.stringify(results, null, 2));\n } catch (error) {\n console.log(JSON.stringify({ error: (error as Error).message }));\n process.exit(1);\n }\n });\n\nprogram\n .command(\"queue\")\n .description(\"Show scheduled posts\")\n .action(async () => {\n const { showQueue } = await import(\"./scheduler/queue.js\");\n showQueue();\n });\n\n// ========== COLONY ==========\n\nconst colony = program.command(\"colony\").description(\"Colony commands\");\n\ncolony\n .command(\"checkin\")\n .description(\"Check into The Colony — sync memory, discover Spores\")\n .option(\"-m, --message <msg>\", \"Optional message to post\")\n .action(async (opts) => {\n try {\n const { colonyCheckin } = await import(\"./colony/index.js\");\n const result = await colonyCheckin(opts.message);\n console.log(JSON.stringify(result, null, 2));\n } catch (error) {\n console.log(JSON.stringify({ error: (error as Error).message }));\n process.exit(1);\n }\n });\n\ncolony\n .command(\"memory\")\n .description(\"Read the Colony's shared memory\")\n .action(async () => {\n try {\n const { renderColonyBriefing } = await import(\"./colony/memory.js\");\n console.log(renderColonyBriefing());\n } catch (error) {\n console.log(JSON.stringify({ error: (error as Error).message }));\n process.exit(1);\n }\n });\n\ncolony\n .command(\"plans\")\n .description(\"Get all active Colony plans\")\n .action(async () => {\n try {\n const { getActivePlans } = await import(\"./colony/index.js\");\n const plans = getActivePlans();\n console.log(plans.length > 0\n ? JSON.stringify(plans, null, 2)\n : JSON.stringify({ message: \"No active plans. Propose one!\" }));\n } catch (error) {\n console.log(JSON.stringify({ error: (error as Error).message }));\n process.exit(1);\n }\n });\n\ncolony\n .command(\"propose\")\n .description(\"Propose a coordinated plan\")\n .argument(\"<description>\", \"What's the plan?\")\n .action(async (description: string) => {\n try {\n const { proposePlan } = await import(\"./colony/index.js\");\n const result = await proposePlan(description);\n console.log(JSON.stringify(result, null, 2));\n } catch (error) {\n console.log(JSON.stringify({ error: (error as Error).message }));\n process.exit(1);\n }\n });\n\ncolony\n .command(\"join\")\n .description(\"Join an active plan\")\n .argument(\"<planId>\", \"Plan ID\")\n .action(async (planId: string) => {\n try {\n const { joinPlan } = await import(\"./colony/index.js\");\n const result = await joinPlan(planId);\n console.log(JSON.stringify(result, null, 2));\n } catch (error) {\n console.log(JSON.stringify({ error: (error as Error).message }));\n process.exit(1);\n }\n });\n\ncolony\n .command(\"post-status\")\n .description(\"Post a status update to the Colony\")\n .argument(\"<status>\", \"Your status\")\n .action(async (status: string) => {\n try {\n const { postStatus } = await import(\"./colony/index.js\");\n const result = await postStatus(status);\n console.log(JSON.stringify(result, null, 2));\n } catch (error) {\n console.log(JSON.stringify({ error: (error as Error).message }));\n process.exit(1);\n }\n });\n\ncolony\n .command(\"activity\")\n .description(\"Get today's Colony activity\")\n .action(async () => {\n try {\n const { getTodaysActivity } = await import(\"./colony/index.js\");\n const activity = getTodaysActivity();\n console.log(activity.length > 0\n ? JSON.stringify(activity, null, 2)\n : JSON.stringify({ message: \"No Colony activity today yet.\" }));\n } catch (error) {\n console.log(JSON.stringify({ error: (error as Error).message }));\n process.exit(1);\n }\n });\n\n// ========== AGENT RUNTIME ==========\n\nprogram\n .command(\"start\")\n .description(\"Start the autonomous Spora agent\")\n .option(\"--interval <ms>\", \"Heartbeat interval in milliseconds\")\n .action(async (opts) => {\n if (!sporaExists()) {\n console.log(JSON.stringify({ error: \"Spora not initialized. Run `spora init` first.\" }));\n process.exit(1);\n }\n if (!hasXCredentials()) {\n console.log(JSON.stringify({ error: \"No X credentials. Run `spora init` to set up.\" }));\n process.exit(1);\n }\n\n const { hasLLMKey } = await import(\"./runtime/llm.js\");\n if (!hasLLMKey()) {\n console.log(JSON.stringify({ error: \"No LLM API key. Run `spora llm set --provider <provider>` first.\" }));\n process.exit(1);\n }\n\n // Apply interval override\n if (opts.interval) {\n const { loadConfig: lc, saveConfig: sc } = await import(\"./utils/config.js\");\n const config = lc();\n config.runtime = { ...config.runtime, heartbeatIntervalMs: parseInt(opts.interval, 10), actionsPerHeartbeat: config.runtime?.actionsPerHeartbeat ?? 4, enabled: true };\n sc(config);\n }\n\n console.log(chalk.cyan(BANNER));\n console.log(chalk.bold(\"Starting Spora agent...\\n\"));\n\n const { startHeartbeatLoop } = await import(\"./runtime/heartbeat.js\");\n await startHeartbeatLoop();\n });\n\nprogram\n .command(\"stop\")\n .description(\"Stop the running Spora agent\")\n .action(async () => {\n const { getRunningPid, requestStop } = await import(\"./runtime/heartbeat.js\");\n const pid = getRunningPid();\n if (!pid) {\n console.log(JSON.stringify({ message: \"Spora agent is not running.\" }));\n return;\n }\n requestStop();\n console.log(JSON.stringify({ message: `Stop signal sent to PID ${pid}.` }));\n });\n\nprogram\n .command(\"set-llm-key\")\n .description(\"Legacy alias: set API key for currently configured LLM provider\")\n .argument(\"[key]\", \"API key (or omit to enter interactively)\")\n .action(async (key?: string) => {\n const { ensureDirectories: ed } = await import(\"./utils/paths.js\");\n const { input } = await import(\"@inquirer/prompts\");\n const { loadConfig: lc } = await import(\"./utils/config.js\");\n const { setLLMApiKey, getDefaultModel } = await import(\"./runtime/llm.js\");\n ed();\n\n let provider: \"anthropic\" | \"openai\" | \"deepseek\" = \"deepseek\";\n let model = getDefaultModel(\"deepseek\");\n try {\n const config = lc();\n provider = config.llm?.provider ?? \"deepseek\";\n model = config.llm?.model ?? getDefaultModel(provider);\n } catch {\n // Ignore missing config and use defaults.\n }\n\n const apiKey = key ?? await input({ message: `Enter your ${provider} API key:` });\n setLLMApiKey(provider, apiKey.trim());\n console.log(JSON.stringify({ success: true, provider, model, message: \"LLM API key saved.\" }));\n });\n\nconst llm = program.command(\"llm\").description(\"LLM provider/model settings\");\n\nllm\n .command(\"status\")\n .description(\"Show current provider/model and which keys are configured\")\n .action(async () => {\n const { loadConfig: lc } = await import(\"./utils/config.js\");\n const { listLLMKeyStatus, getDefaultModel } = await import(\"./runtime/llm.js\");\n\n let provider: \"anthropic\" | \"openai\" | \"deepseek\" = \"deepseek\";\n let model = getDefaultModel(\"deepseek\");\n try {\n const config = lc();\n provider = config.llm?.provider ?? \"deepseek\";\n model = config.llm?.model ?? getDefaultModel(provider);\n } catch {\n // Keep defaults\n }\n\n console.log(JSON.stringify({\n provider,\n model,\n keysConfigured: listLLMKeyStatus(),\n }, null, 2));\n });\n\nllm\n .command(\"set\")\n .description(\"Set provider/model and store API key\")\n .requiredOption(\"--provider <provider>\", \"anthropic | openai | deepseek\")\n .option(\"--model <model>\", \"Model name (defaults by provider)\")\n .option(\"--key <key>\", \"API key\")\n .action(async (opts: { provider: string; model?: string; key?: string }) => {\n const provider = opts.provider as \"anthropic\" | \"openai\" | \"deepseek\";\n if (![\"anthropic\", \"openai\", \"deepseek\"].includes(provider)) {\n console.log(JSON.stringify({ error: \"Provider must be anthropic, openai, or deepseek\" }));\n process.exit(1);\n }\n\n const { input } = await import(\"@inquirer/prompts\");\n const { loadConfig: lc, saveConfig: sc } = await import(\"./utils/config.js\");\n const { setLLMApiKey, getDefaultModel } = await import(\"./runtime/llm.js\");\n const { ensureDirectories: ed } = await import(\"./utils/paths.js\");\n\n ed();\n const model = opts.model ?? getDefaultModel(provider);\n const apiKey = (opts.key ?? await input({ message: `Enter your ${provider} API key:` })).trim();\n if (!apiKey) {\n console.log(JSON.stringify({ error: \"API key is required\" }));\n process.exit(1);\n }\n\n setLLMApiKey(provider, apiKey);\n\n const config = lc();\n config.llm = { provider, model };\n sc(config);\n\n console.log(JSON.stringify({ success: true, provider, model }));\n });\n\nllm\n .command(\"test\")\n .description(\"Send a tiny test prompt to validate current LLM config\")\n .action(async () => {\n try {\n const { chat } = await import(\"./runtime/llm.js\");\n const response = await chat(\n \"You are a short diagnostic assistant. Reply with exactly: ok\",\n [{ role: \"user\", content: \"health check\" }]\n );\n console.log(JSON.stringify({ success: true, response: response.content.trim() }));\n } catch (error) {\n console.log(JSON.stringify({ success: false, error: (error as Error).message }));\n process.exit(1);\n }\n });\n\n\nprogram\n .command(\"agent-status\")\n .description(\"Check if the Spora agent is running\")\n .action(async () => {\n const { getRunningPid } = await import(\"./runtime/heartbeat.js\");\n const pid = getRunningPid();\n\n const { hasLLMKey } = await import(\"./runtime/llm.js\");\n\n console.log(JSON.stringify({\n agentRunning: pid !== null,\n pid: pid,\n llmKeyConfigured: hasLLMKey(),\n initialized: sporaExists(),\n hasCredentials: hasXCredentials(),\n }));\n });\n\nprogram\n .command(\"agent-metrics\")\n .description(\"Show recent heartbeat metrics for autonomy quality\")\n .option(\"-n, --count <n>\", \"Number of entries\", \"20\")\n .action(async (opts) => {\n const { existsSync, readFileSync } = await import(\"node:fs\");\n const { paths } = await import(\"./utils/paths.js\");\n const count = Math.max(1, parseInt(opts.count, 10) || 20);\n\n if (!existsSync(paths.runtimeMetrics)) {\n console.log(JSON.stringify({ message: \"No metrics recorded yet.\" }));\n return;\n }\n\n const lines = readFileSync(paths.runtimeMetrics, \"utf-8\")\n .split(\"\\n\")\n .filter(Boolean)\n .slice(-count);\n\n const entries = lines.map((line) => JSON.parse(line) as Record<string, unknown>);\n console.log(JSON.stringify(entries, null, 2));\n });\n\nprogram\n .command(\"doctor\")\n .description(\"Run diagnostics for X API, LLM provider, and local config\")\n .action(async () => {\n const checks: Array<{ check: string; ok: boolean; detail: string }> = [];\n\n try {\n const config = loadConfig();\n checks.push({ check: \"config\", ok: true, detail: `provider=${config.llm?.provider ?? \"deepseek\"}, model=${config.llm?.model ?? \"default\"}` });\n } catch (error) {\n checks.push({ check: \"config\", ok: false, detail: (error as Error).message });\n }\n\n try {\n const { hasLLMKey, chat } = await import(\"./runtime/llm.js\");\n if (!hasLLMKey()) {\n checks.push({ check: \"llm_key\", ok: false, detail: \"No key configured for current provider\" });\n } else {\n const resp = await chat(\n \"Reply with exactly 'ok'.\",\n [{ role: \"user\", content: \"health check\" }]\n );\n checks.push({ check: \"llm_call\", ok: resp.content.toLowerCase().includes(\"ok\"), detail: `response=${resp.content.trim().slice(0, 32)}` });\n }\n } catch (error) {\n checks.push({ check: \"llm_call\", ok: false, detail: (error as Error).message });\n }\n\n try {\n const { getXClient } = await import(\"./x-client/index.js\");\n const client = await getXClient();\n const timeline = await client.getTimeline({ count: 3 });\n checks.push({ check: \"x_api_timeline\", ok: true, detail: `timeline_count=${timeline.length}` });\n } catch (error) {\n checks.push({ check: \"x_api_timeline\", ok: false, detail: (error as Error).message });\n }\n\n const allOk = checks.every((c) => c.ok);\n console.log(JSON.stringify({ ok: allOk, checks }, null, 2));\n if (!allOk) process.exit(1);\n });\n\nprogram\n .command(\"ui\")\n .description(\"Open the Spora web UI for setup and management\")\n .option(\"-p, --port <port>\", \"Port to run on\", \"3000\")\n .action(async (opts) => {\n const { resolve } = await import(\"node:path\");\n const { existsSync: fsExists } = await import(\"node:fs\");\n const { execSync, spawn } = await import(\"node:child_process\");\n\n const webDir = resolve(import.meta.dirname, \"../../packages/web\");\n if (!fsExists(webDir)) {\n console.log(chalk.red(\"Web UI not found. Expected at: \" + webDir));\n process.exit(1);\n }\n\n const port = opts.port || \"3000\";\n console.log(chalk.cyan(BANNER));\n console.log(chalk.bold(\"Starting Spora UI...\\n\"));\n\n // Check if dependencies are installed\n if (!fsExists(resolve(webDir, \"node_modules\"))) {\n console.log(chalk.gray(\"Installing dependencies...\"));\n execSync(\"npm install\", { cwd: webDir, stdio: \"inherit\" });\n }\n\n console.log(chalk.green(`\\n Spora UI: http://localhost:${port}\\n`));\n console.log(chalk.gray(\"Press Ctrl+C to stop.\\n\"));\n\n // Open browser\n try {\n const openCmd = process.platform === \"darwin\" ? \"open\" : process.platform === \"win32\" ? \"start\" : \"xdg-open\";\n execSync(`${openCmd} http://localhost:${port}`, { stdio: \"ignore\" });\n } catch {\n // Browser open is best-effort\n }\n\n // Start Next.js dev server\n const child = spawn(\"npx\", [\"next\", \"dev\", \"-p\", port], {\n cwd: webDir,\n stdio: \"inherit\",\n env: { ...process.env },\n });\n\n child.on(\"close\", (code) => {\n process.exit(code ?? 0);\n });\n\n process.on(\"SIGINT\", () => {\n child.kill(\"SIGINT\");\n });\n process.on(\"SIGTERM\", () => {\n child.kill(\"SIGTERM\");\n });\n });\n\nprogram.parse();\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAEA,SAAS,eAAe;AACxB,OAAO,WAAW;AAClB,SAAS,oBAAoB;AAC7B,SAAS,YAAY;AAcrB,IAAM,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AASf,IAAM,UAAU,IAAI,QAAQ;AAC5B,IAAM,kBAAkB,KAAK,YAAY,SAAS,iBAAiB;AACnE,IAAM,aAAa,KAAK,MAAM,aAAa,iBAAiB,OAAO,CAAC,EAAE;AAEtE,QACG,KAAK,OAAO,EACZ,YAAY,gEAAgE,EAC5E,QAAQ,UAAU;AAIrB,QACG,QAAQ,MAAM,EACd,YAAY,6CAA6C,EACzD,OAAO,mBAAmB,kDAAkD,EAC5E,OAAO,qBAAqB,8BAA8B,EAC1D,OAAO,mBAAmB,sBAAsB,EAChD,OAAO,yBAAyB,yBAAyB,EACzD,OAAO,0BAA0B,2BAA2B,EAC5D,OAAO,kCAAkC,kCAAkC,EAC3E,OAAO,0BAA0B,wCAAwC,EACzE,OAAO,qBAAqB,qCAAqC,EACjE,OAAO,OAAO,SAAS;AAEtB,MAAI,KAAK,QAAQ;AACf,UAAM,EAAE,kBAAkB,IAAI,MAAM,OAAO,qBAAkB;AAC7D,UAAM,EAAE,gBAAgB,IAAI,MAAM,OAAO,sBAAmB;AAC5D,UAAM,EAAE,qBAAqB,WAAW,IAAI,MAAM,OAAO,sBAAmB;AAE5E,sBAAkB;AAElB,QAAI,KAAK,WAAW,OAAO;AACzB,cAAQ,IAAI,KAAK,UAAU,EAAE,OAAO,gDAAgD,CAAC,CAAC;AACtF,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,QAAI,CAAC,KAAK,UAAU,CAAC,KAAK,aAAa,CAAC,KAAK,eAAe,CAAC,KAAK,mBAAmB;AACnF,cAAQ,IAAI,KAAK,UAAU,EAAE,OAAO,mFAAmF,CAAC,CAAC;AACzH,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,oBAAgB;AAAA,MACd,QAAQ;AAAA,MACR,QAAQ,KAAK;AAAA,MACb,WAAW,KAAK;AAAA,MAChB,aAAa,KAAK;AAAA,MAClB,mBAAmB,KAAK;AAAA,MACxB,aAAa,KAAK;AAAA,IACpB,CAAC;AAED,UAAM,SAAS,oBAAoB;AAAA,MACjC,SAAS;AAAA,MACT,UAAU,KAAK;AAAA,IACjB,CAAC;AACD,eAAW,MAAM;AAEjB,YAAQ,IAAI,KAAK,UAAU,EAAE,SAAS,MAAM,QAAQ,KAAK,OAAO,CAAC,CAAC;AAClE;AAAA,EACF;AAGA,UAAQ,IAAI,MAAM,KAAK,MAAM,CAAC;AAC9B,UAAQ,IAAI,MAAM,KAAK,mBAAmB,CAAC;AAC3C,UAAQ,IAAI,MAAM,KAAK,yCAAyC,CAAC;AAEjE,QAAM,EAAE,QAAQ,IAAI,MAAM,OAAO,oBAAW;AAC5C,QAAM,QAAQ,KAAK,KAAK;AAC1B,CAAC;AAEH,QACG,QAAQ,OAAO,EACf,YAAY,oCAAoC,EAChD,OAAO,YAAY;AAClB,QAAM,EAAE,YAAY,IAAI,MAAM,OAAO,iBAAiB;AACtD,QAAM,YAAY;AACpB,CAAC;AAIH,QACG,QAAQ,MAAM,EACd,YAAY,+CAA+C,EAC3D,OAAO,YAAY;AAClB,MAAI,CAAC,eAAe,GAAG;AACrB,YAAQ,IAAI,MAAM,IAAI,qDAAgD,CAAC;AACvE,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,EAAE,aAAa,IAAI,MAAM,OAAO,wBAAqB;AAC3D,QAAM,aAAa;AACrB,CAAC;AAEH,QACG,QAAQ,KAAK,EACb,YAAY,2CAA2C,EACvD,OAAO,YAAY;AAClB,MAAI,CAAC,eAAe,GAAG;AACrB,YAAQ,IAAI,MAAM,IAAI,qDAAgD,CAAC;AACvE,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,UAAQ,IAAI,MAAM,OAAO,sCAAsC,CAAC;AAChE,UAAQ,IAAI,MAAM,IAAI,sDAAsD,CAAC;AAC7E,UAAQ,KAAK,CAAC;AAChB,CAAC;AAEH,QACG,QAAQ,QAAQ,EAChB,YAAY,mBAAmB,EAC/B,OAAO,MAAM;AACZ,MAAI,CAAC,gBAAgB,GAAG;AACtB,YAAQ,IAAI,KAAK,UAAU,EAAE,OAAO,kDAAkD,CAAC,CAAC;AACxF,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,SAAS,WAAW;AAC1B,QAAM,SAAkC;AAAA,IACtC,SAAS,OAAO;AAAA,IAChB,SAAS;AAAA,MACP,MAAM,OAAO,QAAQ;AAAA,MACrB,OAAO,OAAO,QAAQ;AAAA,MACtB,WAAW,OAAO,QAAQ,mBAAmB,OAAO,QAAQ;AAAA,MAC5D,WAAW,OAAO,QAAQ;AAAA,IAC5B;AAAA,EACF;AAEA,MAAI,eAAe,GAAG;AACpB,UAAM,WAAW,aAAa;AAC9B,WAAO,WAAW;AAAA,MAChB,MAAM,SAAS;AAAA,MACf,QAAQ,SAAS;AAAA,MACjB,WAAW,SAAS;AAAA,MACpB,SAAS,SAAS;AAAA,MAClB,YAAY,SAAS;AAAA,MACrB,QAAQ,SAAS,OAAO;AAAA,MACxB,OAAO,SAAS;AAAA,MAChB,QAAQ,SAAS;AAAA,MACjB,YAAY,SAAS;AAAA,IACvB;AAAA,EACF,OAAO;AACL,WAAO,WAAW;AAAA,EACpB;AAEA,UAAQ,IAAI,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAC7C,CAAC;AAIH,QACG,QAAQ,YAAY,EACpB,YAAY,uCAAuC,EACnD,OAAO,MAAM;AACZ,QAAM,OAAO,OAAO,QAAQ,UAAU,EAAE,IAAI,CAAC,CAAC,KAAK,EAAE,OAAO;AAAA,IAC1D,IAAI;AAAA,IACJ,OAAO,GAAG;AAAA,IACV,SAAS,GAAG;AAAA,IACZ,aAAa,GAAG;AAAA,EAClB,EAAE;AACF,UAAQ,IAAI,KAAK,UAAU,EAAE,YAAY,MAAM,OAAO,CAAC,GAAG,YAAY,EAAE,GAAG,MAAM,CAAC,CAAC;AACrF,CAAC;AAEH,QACG,QAAQ,WAAW,EACnB,YAAY,qCAAqC,EACjD,SAAS,QAAQ,cAAc,EAC/B,OAAO,CAAC,OAAe;AACtB,QAAM,KAAK,WAAW,EAA6B;AACnD,MAAI,CAAC,IAAI;AACP,YAAQ,IAAI,KAAK,UAAU,EAAE,OAAO,sBAAsB,EAAE,GAAG,CAAC,CAAC;AACjE,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,UAAQ,IAAI,KAAK,UAAU,EAAE,IAAI,GAAG,GAAG,GAAG,MAAM,CAAC,CAAC;AACpD,CAAC;AAEH,QACG,QAAQ,QAAQ,EAChB,YAAY,6BAA6B,EACzC,eAAe,2BAA2B,0BAA0B,EACpE,eAAe,iBAAiB,cAAc,EAC9C,eAAe,qBAAqB,sBAAsB,EAC1D,OAAO,eAAe,uBAAuB,EAC7C,OAAO,oBAAoB,cAAc,EACzC,OAAO,iBAAiB,qBAAqB,EAC7C,OAAO,2BAA2B,+BAA+B,EACjE,OAAO,wBAAwB,aAAa,EAC5C,OAAO,wBAAwB,uBAAuB,EACtD,OAAO,sBAAsB,iBAAiB,EAC9C,OAAO,gCAAgC,+BAA+B,EACtE,OAAO,+BAA+B,mBAAmB,EACzD,OAAO,4BAA4B,yDAAyD,EAC5F,OAAO,wBAAwB,wDAAwD,EACvF,OAAO,yBAAyB,2BAA2B,EAC3D,OAAO,yBAAyB,qCAAqC,EACrE,OAAO,YAAY,mBAAmB,KAAK,EAC3C,OAAO,0BAA0B,2BAA2B,UAAU,EACtE,OAAO,qBAAqB,sBAAsB,UAAU,EAC5D,OAAO,yBAAyB,0BAA0B,UAAU,EACpE,OAAO,yBAAyB,0BAA0B,UAAU,EACpE,OAAO,uBAAuB,wBAAwB,UAAU,EAChE,OAAO,yBAAyB,0BAA0B,UAAU,EACpE,OAAO,0BAA0B,2BAA2B,UAAU,EACtE,OAAO,2BAA2B,4BAA4B,UAAU,EACxE,OAAO,CAAC,SAAS;AAChB,MAAI;AACF,UAAM,eAAuC,CAAC;AAC9C,eAAW,KAAK,CAAC,cAAc,SAAS,aAAa,aAAa,WAAW,aAAa,cAAc,aAAa,GAAG;AACtH,YAAM,MAAM,KAAK,QAAQ,EAAE,OAAO,CAAC,EAAE,YAAY,IAAI,EAAE,MAAM,CAAC,CAAC,EAAE;AACjE,UAAI,QAAQ,OAAW,cAAa,CAAC,IAAI;AAAA,IAC3C;AAEA,UAAM,WAAW,eAAe;AAAA,MAC9B,WAAW,KAAK;AAAA,MAChB,MAAM,KAAK;AAAA,MACX,QAAQ,KAAK;AAAA,MACb,KAAK,KAAK;AAAA,MACV,aAAa,KAAK;AAAA,MAClB,MAAM,KAAK;AAAA,MACX,WAAW,KAAK;AAAA,MAChB,YAAY,KAAK;AAAA,MACjB,QAAQ,KAAK;AAAA,MACb,OAAO,KAAK;AAAA,MACZ,YAAY,KAAK;AAAA,MACjB,cAAc,KAAK;AAAA,MACnB,eAAe,KAAK;AAAA,MACpB,iBAAiB,KAAK;AAAA,MACtB,YAAY,KAAK;AAAA,MACjB,YAAY,KAAK;AAAA,MACjB,YAAY,KAAK;AAAA,MACjB,cAAc,OAAO,KAAK,YAAY,EAAE,SAAS,IAAI,eAAe;AAAA,IACtE,CAAC;AAED,iBAAa,QAAQ;AACrB,YAAQ,IAAI,uBAAuB,QAAQ,CAAC;AAAA,EAC9C,SAAS,OAAO;AACd,YAAQ,IAAI,KAAK,UAAU,EAAE,OAAQ,MAAgB,QAAQ,CAAC,CAAC;AAC/D,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF,CAAC;AAEH,QACG,QAAQ,UAAU,EAClB,YAAY,4CAA4C,EACxD,OAAO,MAAM;AACZ,MAAI,CAAC,eAAe,GAAG;AACrB,YAAQ,IAAI,KAAK,UAAU,EAAE,OAAO,2BAA2B,CAAC,CAAC;AACjE,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,UAAQ,IAAI,uBAAuB,aAAa,CAAC,CAAC;AACpD,CAAC;AAEH,QACG,QAAQ,eAAe,EACvB,YAAY,2BAA2B,EACvC,OAAO,MAAM;AACZ,MAAI,CAAC,eAAe,GAAG;AACrB,YAAQ,IAAI,KAAK,UAAU,EAAE,OAAO,2BAA2B,CAAC,CAAC;AACjE,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,UAAQ,IAAI,KAAK,UAAU,aAAa,GAAG,MAAM,CAAC,CAAC;AACrD,CAAC;AAEH,QACG,QAAQ,QAAQ,EAChB,YAAY,yCAAyC,EACrD,SAAS,WAAW,6CAA6C,EACjE,SAAS,WAAW,yBAAyB,EAC7C,SAAS,YAAY,8BAA8B,EACnD,OAAO,CAAC,OAAe,OAAe,WAAmB;AACxD,MAAI,CAAC,eAAe,GAAG;AACrB,YAAQ,IAAI,KAAK,UAAU,EAAE,OAAO,2BAA2B,CAAC,CAAC;AACjE,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,MAAI;AACF,QAAI;AACJ,QAAI;AAAE,eAAS,KAAK,MAAM,KAAK;AAAA,IAAG,QAAQ;AAAE,eAAS;AAAA,IAAO;AAC5D,QAAI,WAAW,aAAa;AAC5B,eAAW,eAAe,UAAU,OAAO,QAAQ,MAAM;AACzD,iBAAa,QAAQ;AACrB,YAAQ,IAAI,KAAK,UAAU,EAAE,SAAS,MAAM,OAAO,YAAY,SAAS,YAAY,OAAO,CAAC,CAAC;AAAA,EAC/F,SAAS,OAAO;AACd,YAAQ,IAAI,KAAK,UAAU,EAAE,OAAQ,MAAgB,QAAQ,CAAC,CAAC;AAC/D,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF,CAAC;AAEH,QACG,QAAQ,SAAS,EACjB,YAAY,2CAA2C,EACvD,SAAS,gBAAgB,iBAAiB,EAC1C,OAAO,CAAC,eAAuB;AAC9B,MAAI,CAAC,eAAe,GAAG;AACrB,YAAQ,IAAI,KAAK,UAAU,EAAE,OAAO,2BAA2B,CAAC,CAAC;AACjE,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,QAAM,WAAW,aAAa;AAC9B,WAAS,iBAAiB,KAAK,EAAE,OAAM,oBAAI,KAAK,GAAE,YAAY,GAAG,WAAW,CAAC;AAC7E,eAAa,QAAQ;AACrB,UAAQ,IAAI,KAAK,UAAU,EAAE,SAAS,MAAM,cAAc,SAAS,iBAAiB,OAAO,CAAC,CAAC;AAC/F,CAAC;AAIH,QACG,QAAQ,MAAM,EACd,YAAY,cAAc,EAC1B,SAAS,aAAa,+BAA+B,EACrD,OAAO,OAAO,YAAoB;AACjC,MAAI;AACF,UAAM,EAAE,WAAW,IAAI,MAAM,OAAO,wBAAqB;AACzD,UAAM,SAAS,MAAM,WAAW;AAChC,UAAM,SAAS,MAAM,OAAO,UAAU,OAAO;AAC7C,YAAQ,IAAI,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAAA,EAC7C,SAAS,OAAO;AACd,YAAQ,IAAI,KAAK,UAAU,EAAE,OAAQ,MAAgB,QAAQ,CAAC,CAAC;AAC/D,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF,CAAC;AAEH,QACG,QAAQ,OAAO,EACf,YAAY,kBAAkB,EAC9B,SAAS,aAAa,sBAAsB,EAC5C,SAAS,aAAa,eAAe,EACrC,OAAO,OAAO,SAAiB,YAAoB;AAClD,MAAI;AACF,UAAM,EAAE,WAAW,IAAI,MAAM,OAAO,wBAAqB;AACzD,UAAM,SAAS,MAAM,WAAW;AAChC,UAAM,SAAS,MAAM,OAAO,aAAa,SAAS,OAAO;AACzD,YAAQ,IAAI,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAAA,EAC7C,SAAS,OAAO;AACd,YAAQ,IAAI,KAAK,UAAU,EAAE,OAAQ,MAAgB,QAAQ,CAAC,CAAC;AAC/D,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF,CAAC;AAEH,QACG,QAAQ,MAAM,EACd,YAAY,cAAc,EAC1B,SAAS,aAAa,UAAU,EAChC,OAAO,OAAO,YAAoB;AACjC,MAAI;AACF,UAAM,EAAE,WAAW,IAAI,MAAM,OAAO,wBAAqB;AACzD,UAAM,SAAS,MAAM,WAAW;AAChC,UAAM,SAAS,MAAM,OAAO,UAAU,OAAO;AAC7C,YAAQ,IAAI,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAAA,EAC7C,SAAS,OAAO;AACd,YAAQ,IAAI,KAAK,UAAU,EAAE,OAAQ,MAAgB,QAAQ,CAAC,CAAC;AAC/D,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF,CAAC;AAEH,QACG,QAAQ,SAAS,EACjB,YAAY,iBAAiB,EAC7B,SAAS,aAAa,UAAU,EAChC,OAAO,OAAO,YAAoB;AACjC,MAAI;AACF,UAAM,EAAE,WAAW,IAAI,MAAM,OAAO,wBAAqB;AACzD,UAAM,SAAS,MAAM,WAAW;AAChC,UAAM,SAAS,MAAM,OAAO,QAAQ,OAAO;AAC3C,YAAQ,IAAI,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAAA,EAC7C,SAAS,OAAO;AACd,YAAQ,IAAI,KAAK,UAAU,EAAE,OAAQ,MAAgB,QAAQ,CAAC,CAAC;AAC/D,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF,CAAC;AAEH,QACG,QAAQ,QAAQ,EAChB,YAAY,eAAe,EAC3B,SAAS,YAAY,mBAAmB,EACxC,OAAO,OAAO,WAAmB;AAChC,MAAI;AACF,UAAM,EAAE,WAAW,IAAI,MAAM,OAAO,wBAAqB;AACzD,UAAM,SAAS,MAAM,WAAW;AAChC,UAAM,SAAS,MAAM,OAAO,WAAW,MAAM;AAC7C,YAAQ,IAAI,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAAA,EAC7C,SAAS,OAAO;AACd,YAAQ,IAAI,KAAK,UAAU,EAAE,OAAQ,MAAgB,QAAQ,CAAC,CAAC;AAC/D,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF,CAAC;AAEH,QACG,QAAQ,UAAU,EAClB,YAAY,iBAAiB,EAC7B,SAAS,YAAY,mBAAmB,EACxC,OAAO,OAAO,WAAmB;AAChC,MAAI;AACF,UAAM,EAAE,WAAW,IAAI,MAAM,OAAO,wBAAqB;AACzD,UAAM,SAAS,MAAM,WAAW;AAChC,UAAM,SAAS,MAAM,OAAO,aAAa,MAAM;AAC/C,YAAQ,IAAI,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAAA,EAC7C,SAAS,OAAO;AACd,YAAQ,IAAI,KAAK,UAAU,EAAE,OAAQ,MAAgB,QAAQ,CAAC,CAAC;AAC/D,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF,CAAC;AAEH,QACG,QAAQ,UAAU,EAClB,YAAY,oBAAoB,EAChC,OAAO,mBAAmB,oBAAoB,IAAI,EAClD,OAAO,OAAO,SAAS;AACtB,MAAI;AACF,UAAM,EAAE,WAAW,IAAI,MAAM,OAAO,wBAAqB;AACzD,UAAM,SAAS,MAAM,WAAW;AAChC,UAAM,SAAS,MAAM,OAAO,YAAY,EAAE,OAAO,SAAS,KAAK,KAAK,EAAE,CAAC;AACvE,YAAQ,IAAI,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAAA,EAC7C,SAAS,OAAO;AACd,YAAQ,IAAI,KAAK,UAAU,EAAE,OAAQ,MAAgB,QAAQ,CAAC,CAAC;AAC/D,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF,CAAC;AAEH,QACG,QAAQ,UAAU,EAClB,YAAY,eAAe,EAC3B,OAAO,mBAAmB,sBAAsB,IAAI,EACpD,OAAO,OAAO,SAAS;AACtB,MAAI;AACF,UAAM,EAAE,WAAW,IAAI,MAAM,OAAO,wBAAqB;AACzD,UAAM,SAAS,MAAM,WAAW;AAChC,UAAM,SAAS,MAAM,OAAO,YAAY,EAAE,OAAO,SAAS,KAAK,KAAK,EAAE,CAAC;AACvE,YAAQ,IAAI,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAAA,EAC7C,SAAS,OAAO;AACd,YAAQ,IAAI,KAAK,UAAU,EAAE,OAAQ,MAAgB,QAAQ,CAAC,CAAC;AAC/D,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF,CAAC;AAEH,QACG,QAAQ,QAAQ,EAChB,YAAY,mBAAmB,EAC/B,SAAS,WAAW,cAAc,EAClC,OAAO,mBAAmB,qBAAqB,IAAI,EACnD,OAAO,OAAO,OAAe,SAAS;AACrC,MAAI;AACF,UAAM,EAAE,WAAW,IAAI,MAAM,OAAO,wBAAqB;AACzD,UAAM,SAAS,MAAM,WAAW;AAChC,UAAM,SAAS,MAAM,OAAO,aAAa,OAAO,EAAE,OAAO,SAAS,KAAK,KAAK,EAAE,CAAC;AAC/E,YAAQ,IAAI,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAAA,EAC7C,SAAS,OAAO;AACd,YAAQ,IAAI,KAAK,UAAU,EAAE,OAAQ,MAAgB,QAAQ,CAAC,CAAC;AAC/D,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF,CAAC;AAEH,QACG,QAAQ,SAAS,EACjB,YAAY,wBAAwB,EACpC,SAAS,YAAY,sBAAsB,EAC3C,OAAO,OAAO,WAAmB;AAChC,MAAI;AACF,UAAM,EAAE,WAAW,IAAI,MAAM,OAAO,wBAAqB;AACzD,UAAM,SAAS,MAAM,WAAW;AAChC,UAAM,SAAS,MAAM,OAAO,WAAW,MAAM;AAC7C,YAAQ,IAAI,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAAA,EAC7C,SAAS,OAAO;AACd,YAAQ,IAAI,KAAK,UAAU,EAAE,OAAQ,MAAgB,QAAQ,CAAC,CAAC;AAC/D,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF,CAAC;AAIH,QACG,QAAQ,SAAS,EACjB,YAAY,iCAAiC,EAC7C,OAAO,MAAM;AACZ,QAAM,SAAS,WAAW;AAC1B,QAAM,YAAY,OAAO,QAAQ,mBAAmB,OAAO,QAAQ;AACnE,UAAQ,IAAI,KAAK,UAAU;AAAA,IACzB,WAAW,OAAO,QAAQ;AAAA,IAC1B,gBAAgB;AAAA,IAChB,cAAc,OAAO,QAAQ;AAAA,IAC7B,aAAa,KAAK,MAAO,OAAO,QAAQ,qBAAqB,OAAO,QAAQ,mBAAoB,GAAG;AAAA,IACnG,WAAW,OAAO,QAAQ;AAAA,EAC5B,GAAG,MAAM,CAAC,CAAC;AACb,CAAC;AAEH,QACG,QAAQ,QAAQ,EAChB,YAAY,sDAAsD,EAClE,SAAS,UAAU,0CAA0C,EAC7D,OAAO,qBAAqB,8CAA8C,EAC1E,OAAO,mBAAmB,2BAA2B,IAAI,EACzD,OAAO,OAAO,MAAc,SAAS;AACpC,MAAI;AACF,UAAM,EAAE,uBAAuB,iBAAiB,eAAe,kBAAkB,IAAI,MAAM,OAAO,sBAAmB;AACrH,QAAI;AACJ,YAAQ,MAAM;AAAA,MACZ,KAAK;AACH,eAAO,KAAK,OAAO,gBAAgB,KAAK,IAAI,IAAI,sBAAsB,SAAS,KAAK,KAAK,CAAC;AAC1F;AAAA,MACF,KAAK;AACH,eAAO,cAAc;AACrB;AAAA,MACF,KAAK;AACH,eAAO,kBAAkB;AACzB;AAAA,MACF;AACE,gBAAQ,IAAI,KAAK,UAAU,EAAE,OAAO,0DAA0D,CAAC,CAAC;AAChG,gBAAQ,KAAK,CAAC;AAAA,IAClB;AACA,YAAQ,IAAI,KAAK,UAAU,MAAM,MAAM,CAAC,CAAC;AAAA,EAC3C,SAAS,OAAO;AACd,YAAQ,IAAI,KAAK,UAAU,EAAE,OAAQ,MAAgB,QAAQ,CAAC,CAAC;AAC/D,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF,CAAC;AAEH,QACG,QAAQ,OAAO,EACf,YAAY,kBAAkB,EAC9B,SAAS,aAAa,kBAAkB,EACxC,OAAO,wBAAwB,yBAAyB,EACxD,OAAO,OAAO,SAAiB,SAAS;AACvC,MAAI;AACF,UAAM,EAAE,YAAY,IAAI,MAAM,OAAO,sBAAmB;AACxD,gBAAY,SAAS,SAAS,KAAK,QAAQ,CAAC,CAAC;AAC7C,YAAQ,IAAI,KAAK,UAAU,EAAE,SAAS,KAAK,CAAC,CAAC;AAAA,EAC/C,SAAS,OAAO;AACd,YAAQ,IAAI,KAAK,UAAU,EAAE,OAAQ,MAAgB,QAAQ,CAAC,CAAC;AAC/D,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF,CAAC;AAEH,QACG,QAAQ,MAAM,EACd,YAAY,uCAAuC,EACnD,SAAS,YAAY,gBAAgB,EACrC,SAAS,aAAa,WAAW,EACjC,OAAO,OAAO,QAAgB,YAAoB;AACjD,MAAI;AACF,UAAM,EAAE,mBAAmB,IAAI,MAAM,OAAO,sBAAmB;AAC/D,uBAAmB,QAAQ,EAAE,QAAQ,OAAO,CAAC,OAAO,EAAE,CAAC;AACvD,YAAQ,IAAI,KAAK,UAAU,EAAE,SAAS,MAAM,OAAO,CAAC,CAAC;AAAA,EACvD,SAAS,OAAO;AACd,YAAQ,IAAI,KAAK,UAAU,EAAE,OAAQ,MAAgB,QAAQ,CAAC,CAAC;AAC/D,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF,CAAC;AAIH,QACG,QAAQ,UAAU,EAClB,YAAY,wBAAwB,EACpC,SAAS,aAAa,eAAe,EACrC,OAAO,mBAAmB,yBAAyB,EACnD,OAAO,OAAO,SAAiB,SAAS;AACvC,MAAI;AACF,UAAM,EAAE,WAAW,IAAI,MAAM,OAAO,qBAAsB;AAC1D,UAAM,QAAQ,WAAW,SAAS,KAAK,EAAE;AACzC,YAAQ,IAAI,KAAK,UAAU,EAAE,SAAS,MAAM,IAAI,MAAM,IAAI,cAAc,MAAM,aAAa,CAAC,CAAC;AAAA,EAC/F,SAAS,OAAO;AACd,YAAQ,IAAI,KAAK,UAAU,EAAE,OAAQ,MAAgB,QAAQ,CAAC,CAAC;AAC/D,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF,CAAC;AAEH,QACG,QAAQ,OAAO,EACf,YAAY,2CAA2C,EACvD,OAAO,YAAY;AAClB,MAAI;AACF,UAAM,EAAE,WAAW,IAAI,MAAM,OAAO,qBAAsB;AAC1D,UAAM,UAAU,MAAM,WAAW;AACjC,YAAQ,IAAI,KAAK,UAAU,SAAS,MAAM,CAAC,CAAC;AAAA,EAC9C,SAAS,OAAO;AACd,YAAQ,IAAI,KAAK,UAAU,EAAE,OAAQ,MAAgB,QAAQ,CAAC,CAAC;AAC/D,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF,CAAC;AAEH,QACG,QAAQ,OAAO,EACf,YAAY,sBAAsB,EAClC,OAAO,YAAY;AAClB,QAAM,EAAE,UAAU,IAAI,MAAM,OAAO,qBAAsB;AACzD,YAAU;AACZ,CAAC;AAIH,IAAM,SAAS,QAAQ,QAAQ,QAAQ,EAAE,YAAY,iBAAiB;AAEtE,OACG,QAAQ,SAAS,EACjB,YAAY,2DAAsD,EAClE,OAAO,uBAAuB,0BAA0B,EACxD,OAAO,OAAO,SAAS;AACtB,MAAI;AACF,UAAM,EAAE,cAAc,IAAI,MAAM,OAAO,sBAAmB;AAC1D,UAAM,SAAS,MAAM,cAAc,KAAK,OAAO;AAC/C,YAAQ,IAAI,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAAA,EAC7C,SAAS,OAAO;AACd,YAAQ,IAAI,KAAK,UAAU,EAAE,OAAQ,MAAgB,QAAQ,CAAC,CAAC;AAC/D,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF,CAAC;AAEH,OACG,QAAQ,QAAQ,EAChB,YAAY,iCAAiC,EAC7C,OAAO,YAAY;AAClB,MAAI;AACF,UAAM,EAAE,qBAAqB,IAAI,MAAM,OAAO,sBAAoB;AAClE,YAAQ,IAAI,qBAAqB,CAAC;AAAA,EACpC,SAAS,OAAO;AACd,YAAQ,IAAI,KAAK,UAAU,EAAE,OAAQ,MAAgB,QAAQ,CAAC,CAAC;AAC/D,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF,CAAC;AAEH,OACG,QAAQ,OAAO,EACf,YAAY,6BAA6B,EACzC,OAAO,YAAY;AAClB,MAAI;AACF,UAAM,EAAE,eAAe,IAAI,MAAM,OAAO,sBAAmB;AAC3D,UAAM,QAAQ,eAAe;AAC7B,YAAQ,IAAI,MAAM,SAAS,IACvB,KAAK,UAAU,OAAO,MAAM,CAAC,IAC7B,KAAK,UAAU,EAAE,SAAS,gCAAgC,CAAC,CAAC;AAAA,EAClE,SAAS,OAAO;AACd,YAAQ,IAAI,KAAK,UAAU,EAAE,OAAQ,MAAgB,QAAQ,CAAC,CAAC;AAC/D,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF,CAAC;AAEH,OACG,QAAQ,SAAS,EACjB,YAAY,4BAA4B,EACxC,SAAS,iBAAiB,kBAAkB,EAC5C,OAAO,OAAO,gBAAwB;AACrC,MAAI;AACF,UAAM,EAAE,YAAY,IAAI,MAAM,OAAO,sBAAmB;AACxD,UAAM,SAAS,MAAM,YAAY,WAAW;AAC5C,YAAQ,IAAI,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAAA,EAC7C,SAAS,OAAO;AACd,YAAQ,IAAI,KAAK,UAAU,EAAE,OAAQ,MAAgB,QAAQ,CAAC,CAAC;AAC/D,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF,CAAC;AAEH,OACG,QAAQ,MAAM,EACd,YAAY,qBAAqB,EACjC,SAAS,YAAY,SAAS,EAC9B,OAAO,OAAO,WAAmB;AAChC,MAAI;AACF,UAAM,EAAE,SAAS,IAAI,MAAM,OAAO,sBAAmB;AACrD,UAAM,SAAS,MAAM,SAAS,MAAM;AACpC,YAAQ,IAAI,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAAA,EAC7C,SAAS,OAAO;AACd,YAAQ,IAAI,KAAK,UAAU,EAAE,OAAQ,MAAgB,QAAQ,CAAC,CAAC;AAC/D,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF,CAAC;AAEH,OACG,QAAQ,aAAa,EACrB,YAAY,oCAAoC,EAChD,SAAS,YAAY,aAAa,EAClC,OAAO,OAAO,WAAmB;AAChC,MAAI;AACF,UAAM,EAAE,WAAW,IAAI,MAAM,OAAO,sBAAmB;AACvD,UAAM,SAAS,MAAM,WAAW,MAAM;AACtC,YAAQ,IAAI,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAAA,EAC7C,SAAS,OAAO;AACd,YAAQ,IAAI,KAAK,UAAU,EAAE,OAAQ,MAAgB,QAAQ,CAAC,CAAC;AAC/D,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF,CAAC;AAEH,OACG,QAAQ,UAAU,EAClB,YAAY,6BAA6B,EACzC,OAAO,YAAY;AAClB,MAAI;AACF,UAAM,EAAE,kBAAkB,IAAI,MAAM,OAAO,sBAAmB;AAC9D,UAAM,WAAW,kBAAkB;AACnC,YAAQ,IAAI,SAAS,SAAS,IAC1B,KAAK,UAAU,UAAU,MAAM,CAAC,IAChC,KAAK,UAAU,EAAE,SAAS,gCAAgC,CAAC,CAAC;AAAA,EAClE,SAAS,OAAO;AACd,YAAQ,IAAI,KAAK,UAAU,EAAE,OAAQ,MAAgB,QAAQ,CAAC,CAAC;AAC/D,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF,CAAC;AAIH,QACG,QAAQ,OAAO,EACf,YAAY,kCAAkC,EAC9C,OAAO,mBAAmB,oCAAoC,EAC9D,OAAO,OAAO,SAAS;AACtB,MAAI,CAAC,YAAY,GAAG;AAClB,YAAQ,IAAI,KAAK,UAAU,EAAE,OAAO,iDAAiD,CAAC,CAAC;AACvF,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,MAAI,CAAC,gBAAgB,GAAG;AACtB,YAAQ,IAAI,KAAK,UAAU,EAAE,OAAO,gDAAgD,CAAC,CAAC;AACtF,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,EAAE,UAAU,IAAI,MAAM,OAAO,mBAAkB;AACrD,MAAI,CAAC,UAAU,GAAG;AAChB,YAAQ,IAAI,KAAK,UAAU,EAAE,OAAO,mEAAmE,CAAC,CAAC;AACzG,YAAQ,KAAK,CAAC;AAAA,EAChB;AAGA,MAAI,KAAK,UAAU;AACjB,UAAM,EAAE,YAAY,IAAI,YAAY,GAAG,IAAI,MAAM,OAAO,sBAAmB;AAC3E,UAAM,SAAS,GAAG;AAClB,WAAO,UAAU,EAAE,GAAG,OAAO,SAAS,qBAAqB,SAAS,KAAK,UAAU,EAAE,GAAG,qBAAqB,OAAO,SAAS,uBAAuB,GAAG,SAAS,KAAK;AACrK,OAAG,MAAM;AAAA,EACX;AAEA,UAAQ,IAAI,MAAM,KAAK,MAAM,CAAC;AAC9B,UAAQ,IAAI,MAAM,KAAK,2BAA2B,CAAC;AAEnD,QAAM,EAAE,mBAAmB,IAAI,MAAM,OAAO,yBAAwB;AACpE,QAAM,mBAAmB;AAC3B,CAAC;AAEH,QACG,QAAQ,MAAM,EACd,YAAY,8BAA8B,EAC1C,OAAO,YAAY;AAClB,QAAM,EAAE,eAAe,YAAY,IAAI,MAAM,OAAO,yBAAwB;AAC5E,QAAM,MAAM,cAAc;AAC1B,MAAI,CAAC,KAAK;AACR,YAAQ,IAAI,KAAK,UAAU,EAAE,SAAS,8BAA8B,CAAC,CAAC;AACtE;AAAA,EACF;AACA,cAAY;AACZ,UAAQ,IAAI,KAAK,UAAU,EAAE,SAAS,2BAA2B,GAAG,IAAI,CAAC,CAAC;AAC5E,CAAC;AAEH,QACG,QAAQ,aAAa,EACrB,YAAY,iEAAiE,EAC7E,SAAS,SAAS,0CAA0C,EAC5D,OAAO,OAAO,QAAiB;AAC9B,QAAM,EAAE,mBAAmB,GAAG,IAAI,MAAM,OAAO,qBAAkB;AACjE,QAAM,EAAE,MAAM,IAAI,MAAM,OAAO,mBAAmB;AAClD,QAAM,EAAE,YAAY,GAAG,IAAI,MAAM,OAAO,sBAAmB;AAC3D,QAAM,EAAE,cAAc,gBAAgB,IAAI,MAAM,OAAO,mBAAkB;AACzE,KAAG;AAEH,MAAI,WAAgD;AACpD,MAAI,QAAQ,gBAAgB,UAAU;AACtC,MAAI;AACF,UAAM,SAAS,GAAG;AAClB,eAAW,OAAO,KAAK,YAAY;AACnC,YAAQ,OAAO,KAAK,SAAS,gBAAgB,QAAQ;AAAA,EACvD,QAAQ;AAAA,EAER;AAEA,QAAM,SAAS,OAAO,MAAM,MAAM,EAAE,SAAS,cAAc,QAAQ,YAAY,CAAC;AAChF,eAAa,UAAU,OAAO,KAAK,CAAC;AACpC,UAAQ,IAAI,KAAK,UAAU,EAAE,SAAS,MAAM,UAAU,OAAO,SAAS,qBAAqB,CAAC,CAAC;AAC/F,CAAC;AAEH,IAAM,MAAM,QAAQ,QAAQ,KAAK,EAAE,YAAY,6BAA6B;AAE5E,IACG,QAAQ,QAAQ,EAChB,YAAY,2DAA2D,EACvE,OAAO,YAAY;AAClB,QAAM,EAAE,YAAY,GAAG,IAAI,MAAM,OAAO,sBAAmB;AAC3D,QAAM,EAAE,kBAAkB,gBAAgB,IAAI,MAAM,OAAO,mBAAkB;AAE7E,MAAI,WAAgD;AACpD,MAAI,QAAQ,gBAAgB,UAAU;AACtC,MAAI;AACF,UAAM,SAAS,GAAG;AAClB,eAAW,OAAO,KAAK,YAAY;AACnC,YAAQ,OAAO,KAAK,SAAS,gBAAgB,QAAQ;AAAA,EACvD,QAAQ;AAAA,EAER;AAEA,UAAQ,IAAI,KAAK,UAAU;AAAA,IACzB;AAAA,IACA;AAAA,IACA,gBAAgB,iBAAiB;AAAA,EACnC,GAAG,MAAM,CAAC,CAAC;AACb,CAAC;AAEH,IACG,QAAQ,KAAK,EACb,YAAY,sCAAsC,EAClD,eAAe,yBAAyB,+BAA+B,EACvE,OAAO,mBAAmB,mCAAmC,EAC7D,OAAO,eAAe,SAAS,EAC/B,OAAO,OAAO,SAA6D;AAC1E,QAAM,WAAW,KAAK;AACtB,MAAI,CAAC,CAAC,aAAa,UAAU,UAAU,EAAE,SAAS,QAAQ,GAAG;AAC3D,YAAQ,IAAI,KAAK,UAAU,EAAE,OAAO,kDAAkD,CAAC,CAAC;AACxF,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,EAAE,MAAM,IAAI,MAAM,OAAO,mBAAmB;AAClD,QAAM,EAAE,YAAY,IAAI,YAAY,GAAG,IAAI,MAAM,OAAO,sBAAmB;AAC3E,QAAM,EAAE,cAAc,gBAAgB,IAAI,MAAM,OAAO,mBAAkB;AACzE,QAAM,EAAE,mBAAmB,GAAG,IAAI,MAAM,OAAO,qBAAkB;AAEjE,KAAG;AACH,QAAM,QAAQ,KAAK,SAAS,gBAAgB,QAAQ;AACpD,QAAM,UAAU,KAAK,OAAO,MAAM,MAAM,EAAE,SAAS,cAAc,QAAQ,YAAY,CAAC,GAAG,KAAK;AAC9F,MAAI,CAAC,QAAQ;AACX,YAAQ,IAAI,KAAK,UAAU,EAAE,OAAO,sBAAsB,CAAC,CAAC;AAC5D,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,eAAa,UAAU,MAAM;AAE7B,QAAM,SAAS,GAAG;AAClB,SAAO,MAAM,EAAE,UAAU,MAAM;AAC/B,KAAG,MAAM;AAET,UAAQ,IAAI,KAAK,UAAU,EAAE,SAAS,MAAM,UAAU,MAAM,CAAC,CAAC;AAChE,CAAC;AAEH,IACG,QAAQ,MAAM,EACd,YAAY,wDAAwD,EACpE,OAAO,YAAY;AAClB,MAAI;AACF,UAAM,EAAE,KAAK,IAAI,MAAM,OAAO,mBAAkB;AAChD,UAAM,WAAW,MAAM;AAAA,MACrB;AAAA,MACA,CAAC,EAAE,MAAM,QAAQ,SAAS,eAAe,CAAC;AAAA,IAC5C;AACA,YAAQ,IAAI,KAAK,UAAU,EAAE,SAAS,MAAM,UAAU,SAAS,QAAQ,KAAK,EAAE,CAAC,CAAC;AAAA,EAClF,SAAS,OAAO;AACd,YAAQ,IAAI,KAAK,UAAU,EAAE,SAAS,OAAO,OAAQ,MAAgB,QAAQ,CAAC,CAAC;AAC/E,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF,CAAC;AAGH,QACG,QAAQ,cAAc,EACtB,YAAY,qCAAqC,EACjD,OAAO,YAAY;AAClB,QAAM,EAAE,cAAc,IAAI,MAAM,OAAO,yBAAwB;AAC/D,QAAM,MAAM,cAAc;AAE1B,QAAM,EAAE,UAAU,IAAI,MAAM,OAAO,mBAAkB;AAErD,UAAQ,IAAI,KAAK,UAAU;AAAA,IACzB,cAAc,QAAQ;AAAA,IACtB;AAAA,IACA,kBAAkB,UAAU;AAAA,IAC5B,aAAa,YAAY;AAAA,IACzB,gBAAgB,gBAAgB;AAAA,EAClC,CAAC,CAAC;AACJ,CAAC;AAEH,QACG,QAAQ,eAAe,EACvB,YAAY,oDAAoD,EAChE,OAAO,mBAAmB,qBAAqB,IAAI,EACnD,OAAO,OAAO,SAAS;AACtB,QAAM,EAAE,YAAY,cAAAA,cAAa,IAAI,MAAM,OAAO,IAAS;AAC3D,QAAM,EAAE,MAAM,IAAI,MAAM,OAAO,qBAAkB;AACjD,QAAM,QAAQ,KAAK,IAAI,GAAG,SAAS,KAAK,OAAO,EAAE,KAAK,EAAE;AAExD,MAAI,CAAC,WAAW,MAAM,cAAc,GAAG;AACrC,YAAQ,IAAI,KAAK,UAAU,EAAE,SAAS,2BAA2B,CAAC,CAAC;AACnE;AAAA,EACF;AAEA,QAAM,QAAQA,cAAa,MAAM,gBAAgB,OAAO,EACrD,MAAM,IAAI,EACV,OAAO,OAAO,EACd,MAAM,CAAC,KAAK;AAEf,QAAM,UAAU,MAAM,IAAI,CAAC,SAAS,KAAK,MAAM,IAAI,CAA4B;AAC/E,UAAQ,IAAI,KAAK,UAAU,SAAS,MAAM,CAAC,CAAC;AAC9C,CAAC;AAEH,QACG,QAAQ,QAAQ,EAChB,YAAY,2DAA2D,EACvE,OAAO,YAAY;AAClB,QAAM,SAAgE,CAAC;AAEvE,MAAI;AACF,UAAM,SAAS,WAAW;AAC1B,WAAO,KAAK,EAAE,OAAO,UAAU,IAAI,MAAM,QAAQ,YAAY,OAAO,KAAK,YAAY,UAAU,WAAW,OAAO,KAAK,SAAS,SAAS,GAAG,CAAC;AAAA,EAC9I,SAAS,OAAO;AACd,WAAO,KAAK,EAAE,OAAO,UAAU,IAAI,OAAO,QAAS,MAAgB,QAAQ,CAAC;AAAA,EAC9E;AAEA,MAAI;AACF,UAAM,EAAE,WAAW,KAAK,IAAI,MAAM,OAAO,mBAAkB;AAC3D,QAAI,CAAC,UAAU,GAAG;AAChB,aAAO,KAAK,EAAE,OAAO,WAAW,IAAI,OAAO,QAAQ,yCAAyC,CAAC;AAAA,IAC/F,OAAO;AACL,YAAM,OAAO,MAAM;AAAA,QACjB;AAAA,QACA,CAAC,EAAE,MAAM,QAAQ,SAAS,eAAe,CAAC;AAAA,MAC5C;AACA,aAAO,KAAK,EAAE,OAAO,YAAY,IAAI,KAAK,QAAQ,YAAY,EAAE,SAAS,IAAI,GAAG,QAAQ,YAAY,KAAK,QAAQ,KAAK,EAAE,MAAM,GAAG,EAAE,CAAC,GAAG,CAAC;AAAA,IAC1I;AAAA,EACF,SAAS,OAAO;AACd,WAAO,KAAK,EAAE,OAAO,YAAY,IAAI,OAAO,QAAS,MAAgB,QAAQ,CAAC;AAAA,EAChF;AAEA,MAAI;AACF,UAAM,EAAE,WAAW,IAAI,MAAM,OAAO,wBAAqB;AACzD,UAAM,SAAS,MAAM,WAAW;AAChC,UAAM,WAAW,MAAM,OAAO,YAAY,EAAE,OAAO,EAAE,CAAC;AACtD,WAAO,KAAK,EAAE,OAAO,kBAAkB,IAAI,MAAM,QAAQ,kBAAkB,SAAS,MAAM,GAAG,CAAC;AAAA,EAChG,SAAS,OAAO;AACd,WAAO,KAAK,EAAE,OAAO,kBAAkB,IAAI,OAAO,QAAS,MAAgB,QAAQ,CAAC;AAAA,EACtF;AAEA,QAAM,QAAQ,OAAO,MAAM,CAAC,MAAM,EAAE,EAAE;AACtC,UAAQ,IAAI,KAAK,UAAU,EAAE,IAAI,OAAO,OAAO,GAAG,MAAM,CAAC,CAAC;AAC1D,MAAI,CAAC,MAAO,SAAQ,KAAK,CAAC;AAC5B,CAAC;AAEH,QACG,QAAQ,IAAI,EACZ,YAAY,gDAAgD,EAC5D,OAAO,qBAAqB,kBAAkB,MAAM,EACpD,OAAO,OAAO,SAAS;AACtB,QAAM,EAAE,QAAQ,IAAI,MAAM,OAAO,MAAW;AAC5C,QAAM,EAAE,YAAY,SAAS,IAAI,MAAM,OAAO,IAAS;AACvD,QAAM,EAAE,UAAU,MAAM,IAAI,MAAM,OAAO,eAAoB;AAE7D,QAAM,SAAS,QAAQ,YAAY,SAAS,oBAAoB;AAChE,MAAI,CAAC,SAAS,MAAM,GAAG;AACrB,YAAQ,IAAI,MAAM,IAAI,oCAAoC,MAAM,CAAC;AACjE,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,OAAO,KAAK,QAAQ;AAC1B,UAAQ,IAAI,MAAM,KAAK,MAAM,CAAC;AAC9B,UAAQ,IAAI,MAAM,KAAK,wBAAwB,CAAC;AAGhD,MAAI,CAAC,SAAS,QAAQ,QAAQ,cAAc,CAAC,GAAG;AAC9C,YAAQ,IAAI,MAAM,KAAK,4BAA4B,CAAC;AACpD,aAAS,eAAe,EAAE,KAAK,QAAQ,OAAO,UAAU,CAAC;AAAA,EAC3D;AAEA,UAAQ,IAAI,MAAM,MAAM;AAAA,+BAAkC,IAAI;AAAA,CAAI,CAAC;AACnE,UAAQ,IAAI,MAAM,KAAK,yBAAyB,CAAC;AAGjD,MAAI;AACF,UAAM,UAAU,QAAQ,aAAa,WAAW,SAAS,QAAQ,aAAa,UAAU,UAAU;AAClG,aAAS,GAAG,OAAO,qBAAqB,IAAI,IAAI,EAAE,OAAO,SAAS,CAAC;AAAA,EACrE,QAAQ;AAAA,EAER;AAGA,QAAM,QAAQ,MAAM,OAAO,CAAC,QAAQ,OAAO,MAAM,IAAI,GAAG;AAAA,IACtD,KAAK;AAAA,IACL,OAAO;AAAA,IACP,KAAK,EAAE,GAAG,QAAQ,IAAI;AAAA,EACxB,CAAC;AAED,QAAM,GAAG,SAAS,CAAC,SAAS;AAC1B,YAAQ,KAAK,QAAQ,CAAC;AAAA,EACxB,CAAC;AAED,UAAQ,GAAG,UAAU,MAAM;AACzB,UAAM,KAAK,QAAQ;AAAA,EACrB,CAAC;AACD,UAAQ,GAAG,WAAW,MAAM;AAC1B,UAAM,KAAK,SAAS;AAAA,EACtB,CAAC;AACH,CAAC;AAEH,QAAQ,MAAM;","names":["readFileSync"]}
@@ -1,12 +1,16 @@
1
1
  import {
2
2
  rateLimiter
3
- } from "./chunk-LXQNVVIY.js";
3
+ } from "./chunk-4LNMA56H.js";
4
+ import {
5
+ identityExists,
6
+ loadIdentity
7
+ } from "./chunk-M6YOQVSI.js";
4
8
  import {
5
9
  loadCredentials
6
10
  } from "./chunk-VZBHRUZS.js";
7
11
  import {
8
12
  logger
9
- } from "./chunk-NPV3OV2K.js";
13
+ } from "./chunk-YMGJQRKG.js";
10
14
  import "./chunk-NO3NQN67.js";
11
15
  import {
12
16
  logInteraction
@@ -15,25 +19,38 @@ import "./chunk-3RYCUGXE.js";
15
19
 
16
20
  // src/x-client/api/client.ts
17
21
  import { TwitterApi } from "twitter-api-v2";
22
+ function extractTwitterError(error) {
23
+ if (!error || typeof error !== "object") return String(error);
24
+ const e = error;
25
+ if (e.code && e.data) {
26
+ const status = e.code;
27
+ const data = e.data;
28
+ const errors = data.errors ?? data.detail ?? data.title ?? data.reason;
29
+ return `HTTP ${status}: ${JSON.stringify(errors ?? data)}`;
30
+ }
31
+ if (e.message) return e.message;
32
+ return String(error);
33
+ }
18
34
  var XApiClient = class {
19
35
  readWrite;
20
36
  readOnly;
21
37
  meId = null;
38
+ creds;
22
39
  constructor() {
23
- const creds = loadCredentials();
24
- if (creds.method !== "api") {
40
+ this.creds = loadCredentials();
41
+ if (this.creds.method !== "api") {
25
42
  throw new Error("Only API credentials are supported.");
26
43
  }
27
- if (!creds.apiKey || !creds.apiSecret || !creds.accessToken || !creds.accessTokenSecret) {
44
+ if (!this.creds.apiKey || !this.creds.apiSecret || !this.creds.accessToken || !this.creds.accessTokenSecret) {
28
45
  throw new Error("Missing X OAuth credentials. Run `spora init` and provide API keys.");
29
46
  }
30
47
  this.readWrite = new TwitterApi({
31
- appKey: creds.apiKey,
32
- appSecret: creds.apiSecret,
33
- accessToken: creds.accessToken,
34
- accessSecret: creds.accessTokenSecret
48
+ appKey: this.creds.apiKey,
49
+ appSecret: this.creds.apiSecret,
50
+ accessToken: this.creds.accessToken,
51
+ accessSecret: this.creds.accessTokenSecret
35
52
  });
36
- this.readOnly = creds.bearerToken ? new TwitterApi(creds.bearerToken) : this.readWrite;
53
+ this.readOnly = this.readWrite;
37
54
  }
38
55
  toTweet(tweet, userMap) {
39
56
  const authorId = tweet.author_id ?? "unknown";
@@ -49,17 +66,60 @@ var XApiClient = class {
49
66
  inReplyToId: tweet.in_reply_to_user_id
50
67
  };
51
68
  }
52
- async getAuthenticatedUserId() {
69
+ /**
70
+ * 3-strategy approach to resolve the authenticated user's ID.
71
+ * 1. Extract from OAuth access token (format: {userId}-{rest})
72
+ * 2. Use /2/users/me endpoint
73
+ * 3. Fall back to userByUsername lookup
74
+ */
75
+ async getUserId() {
53
76
  if (this.meId) return this.meId;
54
- const me = await this.readWrite.v2.me({
55
- "user.fields": ["id"]
56
- });
57
- if (!me.data?.id) {
58
- throw new Error("Unable to resolve authenticated X user ID.");
77
+ const accessToken = this.creds.accessToken;
78
+ if (accessToken) {
79
+ const dashIdx = accessToken.indexOf("-");
80
+ if (dashIdx > 0) {
81
+ const candidate = accessToken.substring(0, dashIdx);
82
+ if (/^\d+$/.test(candidate)) {
83
+ logger.info(`User ID extracted from access token: ${candidate}`);
84
+ this.meId = candidate;
85
+ return this.meId;
86
+ }
87
+ }
88
+ }
89
+ try {
90
+ const me = await this.readWrite.v2.me({
91
+ "user.fields": ["id"]
92
+ });
93
+ if (me.data?.id) {
94
+ logger.info(`User ID from /me endpoint: ${me.data.id}${me.data.username ? ` (@${me.data.username})` : ""}`);
95
+ this.meId = me.data.id;
96
+ return this.meId;
97
+ }
98
+ } catch (err) {
99
+ logger.warn(`/me endpoint failed: ${extractTwitterError(err)}`);
100
+ }
101
+ const handle = this.getHandle();
102
+ logger.info(`Trying userByUsername lookup for: ${handle}`);
103
+ const result = await this.readOnly.v2.userByUsername(handle);
104
+ if (!result.data) {
105
+ const errInfo = result.errors;
106
+ throw new Error(
107
+ `Could not find user @${handle}. API returned: ${JSON.stringify(errInfo ?? "no data")}`
108
+ );
59
109
  }
60
- this.meId = me.data.id;
110
+ this.meId = result.data.id;
61
111
  return this.meId;
62
112
  }
113
+ getHandle() {
114
+ let handle;
115
+ if (identityExists()) {
116
+ handle = loadIdentity().handle;
117
+ } else {
118
+ handle = this.creds.username;
119
+ }
120
+ if (!handle) throw new Error("No handle found. Create a Spore identity first.");
121
+ return handle.replace(/^@/, "");
122
+ }
63
123
  normalizeHandleOrId(input) {
64
124
  const cleaned = input.trim().replace(/^@/, "");
65
125
  const isId = /^\d+$/.test(cleaned);
@@ -105,8 +165,9 @@ var XApiClient = class {
105
165
  });
106
166
  return { success: true, tweetId };
107
167
  } catch (error) {
108
- logger.error("Failed to post tweet", error);
109
- return { success: false, error: error.message };
168
+ const detail = extractTwitterError(error);
169
+ logger.error(`Failed to post tweet: ${detail}`);
170
+ return { success: false, error: detail };
110
171
  }
111
172
  }
112
173
  async replyToTweet(tweetId, content) {
@@ -132,8 +193,9 @@ var XApiClient = class {
132
193
  });
133
194
  return { success: true, tweetId: createdId };
134
195
  } catch (error) {
135
- logger.error("Failed to reply", error);
136
- return { success: false, error: error.message };
196
+ const detail = extractTwitterError(error);
197
+ logger.error(`Failed to reply: ${detail}`);
198
+ return { success: false, error: detail };
137
199
  }
138
200
  }
139
201
  async deleteTweet(tweetId) {
@@ -145,9 +207,9 @@ var XApiClient = class {
145
207
  }
146
208
  }
147
209
  async likeTweet(tweetId) {
148
- rateLimiter.requireBasicTier("Like");
149
210
  try {
150
- const meId = await this.getAuthenticatedUserId();
211
+ rateLimiter.requireBasicTier("Like");
212
+ const meId = await this.getUserId();
151
213
  await this.readWrite.v2.like(meId, tweetId);
152
214
  logInteraction({
153
215
  id: `int-${Date.now()}`,
@@ -163,9 +225,9 @@ var XApiClient = class {
163
225
  }
164
226
  }
165
227
  async unlikeTweet(tweetId) {
166
- rateLimiter.requireBasicTier("Unlike");
167
228
  try {
168
- const meId = await this.getAuthenticatedUserId();
229
+ rateLimiter.requireBasicTier("Unlike");
230
+ const meId = await this.getUserId();
169
231
  await this.readWrite.v2.unlike(meId, tweetId);
170
232
  return { success: true, tweetId };
171
233
  } catch (error) {
@@ -173,9 +235,9 @@ var XApiClient = class {
173
235
  }
174
236
  }
175
237
  async retweet(tweetId) {
176
- rateLimiter.requireBasicTier("Retweet");
177
238
  try {
178
- const meId = await this.getAuthenticatedUserId();
239
+ rateLimiter.requireBasicTier("Retweet");
240
+ const meId = await this.getUserId();
179
241
  await this.readWrite.v2.retweet(meId, tweetId);
180
242
  logInteraction({
181
243
  id: `int-${Date.now()}`,
@@ -191,9 +253,9 @@ var XApiClient = class {
191
253
  }
192
254
  }
193
255
  async unretweet(tweetId) {
194
- rateLimiter.requireBasicTier("Unretweet");
195
256
  try {
196
- const meId = await this.getAuthenticatedUserId();
257
+ rateLimiter.requireBasicTier("Unretweet");
258
+ const meId = await this.getUserId();
197
259
  await this.readWrite.v2.unretweet(meId, tweetId);
198
260
  return { success: true, tweetId };
199
261
  } catch (error) {
@@ -203,7 +265,7 @@ var XApiClient = class {
203
265
  async followUser(handleOrId) {
204
266
  rateLimiter.requireBasicTier("Follow");
205
267
  try {
206
- const meId = await this.getAuthenticatedUserId();
268
+ const meId = await this.getUserId();
207
269
  const targetId = await this.resolveUserId(handleOrId);
208
270
  await this.readWrite.v2.follow(meId, targetId);
209
271
  logInteraction({
@@ -223,7 +285,7 @@ var XApiClient = class {
223
285
  async unfollowUser(handleOrId) {
224
286
  rateLimiter.requireBasicTier("Unfollow");
225
287
  try {
226
- const meId = await this.getAuthenticatedUserId();
288
+ const meId = await this.getUserId();
227
289
  const targetId = await this.resolveUserId(handleOrId);
228
290
  await this.readWrite.v2.unfollow(meId, targetId);
229
291
  return { success: true };
@@ -232,9 +294,9 @@ var XApiClient = class {
232
294
  }
233
295
  }
234
296
  async getTimeline(options) {
235
- rateLimiter.requireBasicTier("Read timeline");
236
297
  try {
237
- const meId = await this.getAuthenticatedUserId();
298
+ rateLimiter.requireBasicTier("Read timeline");
299
+ const meId = await this.getUserId();
238
300
  const response = await this.readOnly.v2.get(
239
301
  `users/${meId}/timelines/reverse_chronological`,
240
302
  {
@@ -254,14 +316,15 @@ var XApiClient = class {
254
316
  const users = this.buildUserMap(response.includes?.users);
255
317
  return response.data.map((tweet) => this.toTweet(tweet, users));
256
318
  } catch (error) {
257
- logger.error("Failed to read timeline", error);
319
+ const detail = extractTwitterError(error);
320
+ logger.error(`Failed to read timeline: ${detail}`);
258
321
  return [];
259
322
  }
260
323
  }
261
324
  async getMentions(options) {
262
- rateLimiter.requireBasicTier("Read mentions");
263
325
  try {
264
- const meId = await this.getAuthenticatedUserId();
326
+ rateLimiter.requireBasicTier("Read mentions");
327
+ const meId = await this.getUserId();
265
328
  const response = await this.readOnly.v2.get(`users/${meId}/mentions`, {
266
329
  max_results: options?.count ?? 20,
267
330
  since_id: options?.sinceId,
@@ -273,13 +336,33 @@ var XApiClient = class {
273
336
  const users = this.buildUserMap(response.includes?.users);
274
337
  return response.data.map((tweet) => this.toTweet(tweet, users));
275
338
  } catch (error) {
276
- logger.error("Failed to read mentions", error);
339
+ const detail = extractTwitterError(error);
340
+ logger.error(`Failed to read mentions: ${detail}`);
341
+ return [];
342
+ }
343
+ }
344
+ async getUserTweets(userId, options) {
345
+ try {
346
+ rateLimiter.requireBasicTier("Read user tweets");
347
+ const response = await this.readOnly.v2.get(`users/${userId}/tweets`, {
348
+ max_results: options?.count ?? 10,
349
+ since_id: options?.sinceId,
350
+ expansions: ["author_id"],
351
+ "tweet.fields": ["created_at", "public_metrics", "author_id"],
352
+ "user.fields": ["username"]
353
+ });
354
+ if (!response.data?.length) return [];
355
+ const users = this.buildUserMap(response.includes?.users);
356
+ return response.data.map((tweet) => this.toTweet(tweet, users));
357
+ } catch (error) {
358
+ const detail = extractTwitterError(error);
359
+ logger.error(`Failed to read user tweets for ${userId}: ${detail}`);
277
360
  return [];
278
361
  }
279
362
  }
280
363
  async searchTweets(query, options) {
281
- rateLimiter.requireBasicTier("Search tweets");
282
364
  try {
365
+ rateLimiter.requireBasicTier("Search tweets");
283
366
  const paginator = await this.readOnly.v2.search(query, {
284
367
  max_results: Math.min(options?.count ?? 20, 100),
285
368
  expansions: ["author_id"],
@@ -298,7 +381,8 @@ var XApiClient = class {
298
381
  }
299
382
  return tweets.map((tweet) => this.toTweet(tweet, users));
300
383
  } catch (error) {
301
- logger.error("Failed to search tweets", error);
384
+ const detail = extractTwitterError(error);
385
+ logger.error(`Failed to search tweets: ${detail}`);
302
386
  return [];
303
387
  }
304
388
  }
@@ -334,4 +418,4 @@ var XApiClient = class {
334
418
  export {
335
419
  XApiClient
336
420
  };
337
- //# sourceMappingURL=client-57BQKVYF.js.map
421
+ //# sourceMappingURL=client-4KGOBIXE.js.map