spora 0.3.7 → 0.3.9

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 (39) hide show
  1. package/dist/{chunk-3FBYOHQR.js → chunk-DK26DJKM.js} +52 -9
  2. package/dist/chunk-DK26DJKM.js.map +1 -0
  3. package/dist/{chunk-IIQAE7OP.js → chunk-EODRPATL.js} +4 -4
  4. package/dist/{chunk-YEKHNTQO.js → chunk-G7BRH6CB.js} +2 -2
  5. package/dist/chunk-G7BRH6CB.js.map +1 -0
  6. package/dist/{chunk-MOCLA2KK.js → chunk-H3LB5MYK.js} +2 -2
  7. package/dist/{chunk-BNFUXAQW.js → chunk-RBEJBQI6.js} +3 -3
  8. package/dist/{chunk-T3JHWIKX.js → chunk-Y3TN5BGG.js} +3 -3
  9. package/dist/cli.js +30 -30
  10. package/dist/{client-2ZSXZE3D.js → client-435YKLVK.js} +3 -3
  11. package/dist/{client-2CURS7J6.js → client-WHCMJ5PP.js} +3 -3
  12. package/dist/{colony-EFGAMLOX.js → colony-HCBEQDN2.js} +3 -3
  13. package/dist/{config-NZAFARS6.js → config-URTRCIDT.js} +2 -2
  14. package/dist/{heartbeat-2GVBKQPO.js → heartbeat-GBAOTGL6.js} +7 -7
  15. package/dist/{init-TODR3WR2.js → init-P43IGFJV.js} +5 -5
  16. package/dist/{llm-OH2Z4PSN.js → llm-U5AHRXQL.js} +3 -3
  17. package/dist/mcp-server.js +20 -20
  18. package/dist/{prompt-builder-WYB5B67W.js → prompt-builder-4X6SPLMG.js} +4 -4
  19. package/dist/{queue-N64QLRAB.js → queue-HHAUICMD.js} +3 -3
  20. package/dist/{web-chat-L5MVPVUR.js → web-chat-AGFCA755.js} +3 -3
  21. package/dist/{x-client-SLAC2ON5.js → x-client-MRM3ASO6.js} +3 -3
  22. package/package.json +2 -1
  23. package/dist/chunk-3FBYOHQR.js.map +0 -1
  24. package/dist/chunk-YEKHNTQO.js.map +0 -1
  25. /package/dist/{chunk-IIQAE7OP.js.map → chunk-EODRPATL.js.map} +0 -0
  26. /package/dist/{chunk-MOCLA2KK.js.map → chunk-H3LB5MYK.js.map} +0 -0
  27. /package/dist/{chunk-BNFUXAQW.js.map → chunk-RBEJBQI6.js.map} +0 -0
  28. /package/dist/{chunk-T3JHWIKX.js.map → chunk-Y3TN5BGG.js.map} +0 -0
  29. /package/dist/{client-2ZSXZE3D.js.map → client-435YKLVK.js.map} +0 -0
  30. /package/dist/{client-2CURS7J6.js.map → client-WHCMJ5PP.js.map} +0 -0
  31. /package/dist/{colony-EFGAMLOX.js.map → colony-HCBEQDN2.js.map} +0 -0
  32. /package/dist/{config-NZAFARS6.js.map → config-URTRCIDT.js.map} +0 -0
  33. /package/dist/{heartbeat-2GVBKQPO.js.map → heartbeat-GBAOTGL6.js.map} +0 -0
  34. /package/dist/{init-TODR3WR2.js.map → init-P43IGFJV.js.map} +0 -0
  35. /package/dist/{llm-OH2Z4PSN.js.map → llm-U5AHRXQL.js.map} +0 -0
  36. /package/dist/{prompt-builder-WYB5B67W.js.map → prompt-builder-4X6SPLMG.js.map} +0 -0
  37. /package/dist/{queue-N64QLRAB.js.map → queue-HHAUICMD.js.map} +0 -0
  38. /package/dist/{web-chat-L5MVPVUR.js.map → web-chat-AGFCA755.js.map} +0 -0
  39. /package/dist/{x-client-SLAC2ON5.js.map → x-client-MRM3ASO6.js.map} +0 -0
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  loadConfig
3
- } from "./chunk-YEKHNTQO.js";
3
+ } from "./chunk-G7BRH6CB.js";
4
4
  import {
5
5
  logger
6
6
  } from "./chunk-KELPENM3.js";
@@ -10,12 +10,17 @@ import {
10
10
 
11
11
  // src/runtime/llm.ts
12
12
  import Anthropic from "@anthropic-ai/sdk";
13
+ import OpenAI from "openai";
13
14
  import { readFileSync, existsSync } from "fs";
14
- var client = null;
15
+ var anthropicClient = null;
16
+ var openaiClient = null;
15
17
  function getLLMApiKey() {
16
18
  if (process.env.ANTHROPIC_API_KEY) {
17
19
  return process.env.ANTHROPIC_API_KEY;
18
20
  }
21
+ if (process.env.DEEPSEEK_API_KEY) {
22
+ return process.env.DEEPSEEK_API_KEY;
23
+ }
19
24
  if (existsSync(paths.llmKey)) {
20
25
  return readFileSync(paths.llmKey, "utf-8").trim();
21
26
  }
@@ -24,20 +29,33 @@ function getLLMApiKey() {
24
29
  function hasLLMKey() {
25
30
  return getLLMApiKey() !== null;
26
31
  }
27
- function getClient() {
28
- if (client) return client;
32
+ function getAnthropicClient() {
33
+ if (anthropicClient) return anthropicClient;
29
34
  const apiKey = getLLMApiKey();
30
35
  if (!apiKey) {
31
36
  throw new Error("No LLM API key configured. Run `spora set-llm-key` first.");
32
37
  }
33
- client = new Anthropic({ apiKey });
34
- return client;
38
+ anthropicClient = new Anthropic({ apiKey });
39
+ return anthropicClient;
40
+ }
41
+ function getDeepSeekClient() {
42
+ if (openaiClient) return openaiClient;
43
+ const apiKey = process.env.DEEPSEEK_API_KEY || getLLMApiKey();
44
+ if (!apiKey) {
45
+ throw new Error("No DeepSeek API key configured.");
46
+ }
47
+ openaiClient = new OpenAI({ apiKey, baseURL: "https://api.deepseek.com" });
48
+ return openaiClient;
35
49
  }
36
50
  async function generateResponse(systemPrompt, userMessage) {
37
51
  const config = loadConfig();
52
+ const provider = config.llm?.provider ?? "anthropic";
53
+ if (provider === "deepseek") {
54
+ return generateDeepSeek(systemPrompt, [{ role: "user", content: userMessage }]);
55
+ }
38
56
  const model = config.llm?.model ?? "claude-sonnet-4-20250514";
39
57
  logger.info(`Calling LLM (${model})...`);
40
- const anthropic = getClient();
58
+ const anthropic = getAnthropicClient();
41
59
  const response = await anthropic.messages.create({
42
60
  model,
43
61
  max_tokens: 1024,
@@ -55,8 +73,12 @@ async function generateResponse(systemPrompt, userMessage) {
55
73
  }
56
74
  async function chat(systemPrompt, messages) {
57
75
  const config = loadConfig();
76
+ const provider = config.llm?.provider ?? "anthropic";
77
+ if (provider === "deepseek") {
78
+ return generateDeepSeek(systemPrompt, messages);
79
+ }
58
80
  const model = config.llm?.model ?? "claude-sonnet-4-20250514";
59
- const anthropic = getClient();
81
+ const anthropic = getAnthropicClient();
60
82
  const response = await anthropic.messages.create({
61
83
  model,
62
84
  max_tokens: 1024,
@@ -71,6 +93,27 @@ async function chat(systemPrompt, messages) {
71
93
  outputTokens: response.usage.output_tokens
72
94
  };
73
95
  }
96
+ async function generateDeepSeek(systemPrompt, messages) {
97
+ const config = loadConfig();
98
+ const model = config.llm?.model ?? "deepseek-chat";
99
+ logger.info(`Calling DeepSeek (${model})...`);
100
+ const client = getDeepSeekClient();
101
+ const response = await client.chat.completions.create({
102
+ model,
103
+ max_tokens: 2048,
104
+ messages: [
105
+ { role: "system", content: systemPrompt },
106
+ ...messages
107
+ ]
108
+ });
109
+ const content = response.choices[0]?.message?.content ?? "";
110
+ logger.info(`DeepSeek response: ${response.usage?.prompt_tokens ?? 0} in, ${response.usage?.completion_tokens ?? 0} out`);
111
+ return {
112
+ content,
113
+ inputTokens: response.usage?.prompt_tokens ?? 0,
114
+ outputTokens: response.usage?.completion_tokens ?? 0
115
+ };
116
+ }
74
117
 
75
118
  export {
76
119
  getLLMApiKey,
@@ -78,4 +121,4 @@ export {
78
121
  generateResponse,
79
122
  chat
80
123
  };
81
- //# sourceMappingURL=chunk-3FBYOHQR.js.map
124
+ //# sourceMappingURL=chunk-DK26DJKM.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/runtime/llm.ts"],"sourcesContent":["import Anthropic from \"@anthropic-ai/sdk\";\nimport OpenAI from \"openai\";\nimport { readFileSync, existsSync } from \"node:fs\";\nimport { paths } from \"../utils/paths.js\";\nimport { loadConfig } from \"../utils/config.js\";\nimport { logger } from \"../utils/logger.js\";\n\nlet anthropicClient: Anthropic | null = null;\nlet openaiClient: OpenAI | null = null;\n\nexport function getLLMApiKey(): string | null {\n // Check env first, then file\n if (process.env.ANTHROPIC_API_KEY) {\n return process.env.ANTHROPIC_API_KEY;\n }\n if (process.env.DEEPSEEK_API_KEY) {\n return process.env.DEEPSEEK_API_KEY;\n }\n if (existsSync(paths.llmKey)) {\n return readFileSync(paths.llmKey, \"utf-8\").trim();\n }\n return null;\n}\n\nexport function hasLLMKey(): boolean {\n return getLLMApiKey() !== null;\n}\n\nfunction getAnthropicClient(): Anthropic {\n if (anthropicClient) return anthropicClient;\n const apiKey = getLLMApiKey();\n if (!apiKey) {\n throw new Error(\"No LLM API key configured. Run `spora set-llm-key` first.\");\n }\n anthropicClient = new Anthropic({ apiKey });\n return anthropicClient;\n}\n\nfunction getDeepSeekClient(): OpenAI {\n if (openaiClient) return openaiClient;\n const apiKey = process.env.DEEPSEEK_API_KEY || getLLMApiKey();\n if (!apiKey) {\n throw new Error(\"No DeepSeek API key configured.\");\n }\n openaiClient = new OpenAI({ apiKey, baseURL: \"https://api.deepseek.com\" });\n return openaiClient;\n}\n\nexport interface LLMResponse {\n content: string;\n inputTokens: number;\n outputTokens: number;\n}\n\nexport async function generateResponse(\n systemPrompt: string,\n userMessage: string,\n): Promise<LLMResponse> {\n const config = loadConfig();\n const provider = config.llm?.provider ?? \"anthropic\";\n\n if (provider === \"deepseek\") {\n return generateDeepSeek(systemPrompt, [{ role: \"user\", content: userMessage }]);\n }\n\n const model = config.llm?.model ?? \"claude-sonnet-4-20250514\";\n logger.info(`Calling LLM (${model})...`);\n\n const anthropic = getAnthropicClient();\n const response = await anthropic.messages.create({\n model,\n max_tokens: 1024,\n system: systemPrompt,\n messages: [{ role: \"user\", content: userMessage }],\n });\n\n const textBlock = response.content.find((b) => b.type === \"text\");\n const content = textBlock ? textBlock.text : \"\";\n\n logger.info(`LLM response: ${response.usage.input_tokens} in, ${response.usage.output_tokens} out`);\n\n return {\n content,\n inputTokens: response.usage.input_tokens,\n outputTokens: response.usage.output_tokens,\n };\n}\n\nexport async function chat(\n systemPrompt: string,\n messages: Array<{ role: \"user\" | \"assistant\"; content: string }>,\n): Promise<LLMResponse> {\n const config = loadConfig();\n const provider = config.llm?.provider ?? \"anthropic\";\n\n if (provider === \"deepseek\") {\n return generateDeepSeek(systemPrompt, messages);\n }\n\n const model = config.llm?.model ?? \"claude-sonnet-4-20250514\";\n\n const anthropic = getAnthropicClient();\n const response = await anthropic.messages.create({\n model,\n max_tokens: 1024,\n system: systemPrompt,\n messages,\n });\n\n const textBlock = response.content.find((b) => b.type === \"text\");\n const content = textBlock ? textBlock.text : \"\";\n\n return {\n content,\n inputTokens: response.usage.input_tokens,\n outputTokens: response.usage.output_tokens,\n };\n}\n\nasync function generateDeepSeek(\n systemPrompt: string,\n messages: Array<{ role: \"user\" | \"assistant\"; content: string }>,\n): Promise<LLMResponse> {\n const config = loadConfig();\n const model = config.llm?.model ?? \"deepseek-chat\";\n\n logger.info(`Calling DeepSeek (${model})...`);\n\n const client = getDeepSeekClient();\n const response = await client.chat.completions.create({\n model,\n max_tokens: 2048,\n messages: [\n { role: \"system\", content: systemPrompt },\n ...messages,\n ],\n });\n\n const content = response.choices[0]?.message?.content ?? \"\";\n\n logger.info(`DeepSeek response: ${response.usage?.prompt_tokens ?? 0} in, ${response.usage?.completion_tokens ?? 0} out`);\n\n return {\n content,\n inputTokens: response.usage?.prompt_tokens ?? 0,\n outputTokens: response.usage?.completion_tokens ?? 0,\n };\n}\n"],"mappings":";;;;;;;;;;;AAAA,OAAO,eAAe;AACtB,OAAO,YAAY;AACnB,SAAS,cAAc,kBAAkB;AAKzC,IAAI,kBAAoC;AACxC,IAAI,eAA8B;AAE3B,SAAS,eAA8B;AAE5C,MAAI,QAAQ,IAAI,mBAAmB;AACjC,WAAO,QAAQ,IAAI;AAAA,EACrB;AACA,MAAI,QAAQ,IAAI,kBAAkB;AAChC,WAAO,QAAQ,IAAI;AAAA,EACrB;AACA,MAAI,WAAW,MAAM,MAAM,GAAG;AAC5B,WAAO,aAAa,MAAM,QAAQ,OAAO,EAAE,KAAK;AAAA,EAClD;AACA,SAAO;AACT;AAEO,SAAS,YAAqB;AACnC,SAAO,aAAa,MAAM;AAC5B;AAEA,SAAS,qBAAgC;AACvC,MAAI,gBAAiB,QAAO;AAC5B,QAAM,SAAS,aAAa;AAC5B,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI,MAAM,2DAA2D;AAAA,EAC7E;AACA,oBAAkB,IAAI,UAAU,EAAE,OAAO,CAAC;AAC1C,SAAO;AACT;AAEA,SAAS,oBAA4B;AACnC,MAAI,aAAc,QAAO;AACzB,QAAM,SAAS,QAAQ,IAAI,oBAAoB,aAAa;AAC5D,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI,MAAM,iCAAiC;AAAA,EACnD;AACA,iBAAe,IAAI,OAAO,EAAE,QAAQ,SAAS,2BAA2B,CAAC;AACzE,SAAO;AACT;AAQA,eAAsB,iBACpB,cACA,aACsB;AACtB,QAAM,SAAS,WAAW;AAC1B,QAAM,WAAW,OAAO,KAAK,YAAY;AAEzC,MAAI,aAAa,YAAY;AAC3B,WAAO,iBAAiB,cAAc,CAAC,EAAE,MAAM,QAAQ,SAAS,YAAY,CAAC,CAAC;AAAA,EAChF;AAEA,QAAM,QAAQ,OAAO,KAAK,SAAS;AACnC,SAAO,KAAK,gBAAgB,KAAK,MAAM;AAEvC,QAAM,YAAY,mBAAmB;AACrC,QAAM,WAAW,MAAM,UAAU,SAAS,OAAO;AAAA,IAC/C;AAAA,IACA,YAAY;AAAA,IACZ,QAAQ;AAAA,IACR,UAAU,CAAC,EAAE,MAAM,QAAQ,SAAS,YAAY,CAAC;AAAA,EACnD,CAAC;AAED,QAAM,YAAY,SAAS,QAAQ,KAAK,CAAC,MAAM,EAAE,SAAS,MAAM;AAChE,QAAM,UAAU,YAAY,UAAU,OAAO;AAE7C,SAAO,KAAK,iBAAiB,SAAS,MAAM,YAAY,QAAQ,SAAS,MAAM,aAAa,MAAM;AAElG,SAAO;AAAA,IACL;AAAA,IACA,aAAa,SAAS,MAAM;AAAA,IAC5B,cAAc,SAAS,MAAM;AAAA,EAC/B;AACF;AAEA,eAAsB,KACpB,cACA,UACsB;AACtB,QAAM,SAAS,WAAW;AAC1B,QAAM,WAAW,OAAO,KAAK,YAAY;AAEzC,MAAI,aAAa,YAAY;AAC3B,WAAO,iBAAiB,cAAc,QAAQ;AAAA,EAChD;AAEA,QAAM,QAAQ,OAAO,KAAK,SAAS;AAEnC,QAAM,YAAY,mBAAmB;AACrC,QAAM,WAAW,MAAM,UAAU,SAAS,OAAO;AAAA,IAC/C;AAAA,IACA,YAAY;AAAA,IACZ,QAAQ;AAAA,IACR;AAAA,EACF,CAAC;AAED,QAAM,YAAY,SAAS,QAAQ,KAAK,CAAC,MAAM,EAAE,SAAS,MAAM;AAChE,QAAM,UAAU,YAAY,UAAU,OAAO;AAE7C,SAAO;AAAA,IACL;AAAA,IACA,aAAa,SAAS,MAAM;AAAA,IAC5B,cAAc,SAAS,MAAM;AAAA,EAC/B;AACF;AAEA,eAAe,iBACb,cACA,UACsB;AACtB,QAAM,SAAS,WAAW;AAC1B,QAAM,QAAQ,OAAO,KAAK,SAAS;AAEnC,SAAO,KAAK,qBAAqB,KAAK,MAAM;AAE5C,QAAM,SAAS,kBAAkB;AACjC,QAAM,WAAW,MAAM,OAAO,KAAK,YAAY,OAAO;AAAA,IACpD;AAAA,IACA,YAAY;AAAA,IACZ,UAAU;AAAA,MACR,EAAE,MAAM,UAAU,SAAS,aAAa;AAAA,MACxC,GAAG;AAAA,IACL;AAAA,EACF,CAAC;AAED,QAAM,UAAU,SAAS,QAAQ,CAAC,GAAG,SAAS,WAAW;AAEzD,SAAO,KAAK,sBAAsB,SAAS,OAAO,iBAAiB,CAAC,QAAQ,SAAS,OAAO,qBAAqB,CAAC,MAAM;AAExH,SAAO;AAAA,IACL;AAAA,IACA,aAAa,SAAS,OAAO,iBAAiB;AAAA,IAC9C,cAAc,SAAS,OAAO,qBAAqB;AAAA,EACrD;AACF;","names":[]}
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  loadConfig
3
- } from "./chunk-YEKHNTQO.js";
3
+ } from "./chunk-G7BRH6CB.js";
4
4
  import {
5
5
  logger
6
6
  } from "./chunk-KELPENM3.js";
@@ -11,11 +11,11 @@ async function getXClient() {
11
11
  if (clientInstance) return clientInstance;
12
12
  const config = loadConfig();
13
13
  if (config.xMethod === "api") {
14
- const { XApiClient } = await import("./client-2ZSXZE3D.js");
14
+ const { XApiClient } = await import("./client-435YKLVK.js");
15
15
  clientInstance = new XApiClient();
16
16
  logger.info("X client initialized: API mode");
17
17
  } else {
18
- const { XBrowserClient } = await import("./client-2CURS7J6.js");
18
+ const { XBrowserClient } = await import("./client-WHCMJ5PP.js");
19
19
  clientInstance = new XBrowserClient();
20
20
  logger.info("X client initialized: Browser mode");
21
21
  }
@@ -29,4 +29,4 @@ export {
29
29
  getXClient,
30
30
  resetXClient
31
31
  };
32
- //# sourceMappingURL=chunk-IIQAE7OP.js.map
32
+ //# sourceMappingURL=chunk-EODRPATL.js.map
@@ -22,7 +22,7 @@ var ConfigSchema = z.object({
22
22
  timezone: z.string()
23
23
  }),
24
24
  llm: z.object({
25
- provider: z.enum(["anthropic", "openai"]).default("anthropic"),
25
+ provider: z.enum(["anthropic", "openai", "deepseek"]).default("anthropic"),
26
26
  model: z.string().default("claude-sonnet-4-20250514")
27
27
  }).optional(),
28
28
  runtime: z.object({
@@ -77,4 +77,4 @@ export {
77
77
  saveConfig,
78
78
  createDefaultConfig
79
79
  };
80
- //# sourceMappingURL=chunk-YEKHNTQO.js.map
80
+ //# sourceMappingURL=chunk-G7BRH6CB.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/config.ts"],"sourcesContent":["import { readFileSync, writeFileSync, existsSync } from \"node:fs\";\nimport { z } from \"zod\";\nimport { paths, ensureDirectories } from \"./paths.js\";\n\nexport const ConfigSchema = z.object({\n version: z.literal(1),\n xMethod: z.enum([\"api\", \"browser\"]),\n xApiTier: z.enum([\"free\", \"basic\"]).optional(),\n\n credits: z.object({\n monthlyPostLimit: z.number(),\n postsUsedThisMonth: z.number(),\n resetDate: z.string(),\n }),\n\n schedule: z.object({\n postsPerDay: z.number(),\n activeHoursStart: z.number().min(0).max(23),\n activeHoursEnd: z.number().min(0).max(23),\n timezone: z.string(),\n }),\n\n llm: z.object({\n provider: z.enum([\"anthropic\", \"openai\", \"deepseek\"]).default(\"anthropic\"),\n model: z.string().default(\"claude-sonnet-4-20250514\"),\n }).optional(),\n\n runtime: z.object({\n heartbeatIntervalMs: z.number().default(300_000),\n actionsPerHeartbeat: z.number().default(3),\n enabled: z.boolean().default(false),\n }).optional(),\n\n connection: z.object({\n token: z.string().optional(),\n apiEndpoint: z.string().default(\"https://spora.dev/api/v1\"),\n lastSync: z.string().optional(),\n configVersion: z.number().default(0),\n }).optional(),\n});\n\nexport type Config = z.infer<typeof ConfigSchema>;\n\nexport function loadConfig(): Config {\n if (!existsSync(paths.config)) {\n throw new Error(\"Spora not initialized. Run `spora init` first.\");\n }\n const raw = readFileSync(paths.config, \"utf-8\");\n return ConfigSchema.parse(JSON.parse(raw));\n}\n\nexport function saveConfig(config: Config): void {\n ensureDirectories();\n ConfigSchema.parse(config);\n writeFileSync(paths.config, JSON.stringify(config, null, 2));\n}\n\nexport function createDefaultConfig(overrides: {\n xMethod: \"api\" | \"browser\";\n xApiTier?: \"free\" | \"basic\";\n timezone?: string;\n}): Config {\n const monthlyLimit = overrides.xApiTier === \"basic\" ? 10000 : 500;\n const now = new Date();\n const resetDate = new Date(now.getFullYear(), now.getMonth() + 1, 1).toISOString();\n\n return {\n version: 1,\n xMethod: overrides.xMethod,\n xApiTier: overrides.xApiTier,\n credits: {\n monthlyPostLimit: monthlyLimit,\n postsUsedThisMonth: 0,\n resetDate,\n },\n schedule: {\n postsPerDay: Math.floor(monthlyLimit / 30),\n activeHoursStart: 8,\n activeHoursEnd: 22,\n timezone: overrides.timezone ?? Intl.DateTimeFormat().resolvedOptions().timeZone,\n },\n };\n}\n"],"mappings":";;;;;;AAAA,SAAS,cAAc,eAAe,kBAAkB;AACxD,SAAS,SAAS;AAGX,IAAM,eAAe,EAAE,OAAO;AAAA,EACnC,SAAS,EAAE,QAAQ,CAAC;AAAA,EACpB,SAAS,EAAE,KAAK,CAAC,OAAO,SAAS,CAAC;AAAA,EAClC,UAAU,EAAE,KAAK,CAAC,QAAQ,OAAO,CAAC,EAAE,SAAS;AAAA,EAE7C,SAAS,EAAE,OAAO;AAAA,IAChB,kBAAkB,EAAE,OAAO;AAAA,IAC3B,oBAAoB,EAAE,OAAO;AAAA,IAC7B,WAAW,EAAE,OAAO;AAAA,EACtB,CAAC;AAAA,EAED,UAAU,EAAE,OAAO;AAAA,IACjB,aAAa,EAAE,OAAO;AAAA,IACtB,kBAAkB,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE;AAAA,IAC1C,gBAAgB,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE;AAAA,IACxC,UAAU,EAAE,OAAO;AAAA,EACrB,CAAC;AAAA,EAED,KAAK,EAAE,OAAO;AAAA,IACZ,UAAU,EAAE,KAAK,CAAC,aAAa,UAAU,UAAU,CAAC,EAAE,QAAQ,WAAW;AAAA,IACzE,OAAO,EAAE,OAAO,EAAE,QAAQ,0BAA0B;AAAA,EACtD,CAAC,EAAE,SAAS;AAAA,EAEZ,SAAS,EAAE,OAAO;AAAA,IAChB,qBAAqB,EAAE,OAAO,EAAE,QAAQ,GAAO;AAAA,IAC/C,qBAAqB,EAAE,OAAO,EAAE,QAAQ,CAAC;AAAA,IACzC,SAAS,EAAE,QAAQ,EAAE,QAAQ,KAAK;AAAA,EACpC,CAAC,EAAE,SAAS;AAAA,EAEZ,YAAY,EAAE,OAAO;AAAA,IACnB,OAAO,EAAE,OAAO,EAAE,SAAS;AAAA,IAC3B,aAAa,EAAE,OAAO,EAAE,QAAQ,0BAA0B;AAAA,IAC1D,UAAU,EAAE,OAAO,EAAE,SAAS;AAAA,IAC9B,eAAe,EAAE,OAAO,EAAE,QAAQ,CAAC;AAAA,EACrC,CAAC,EAAE,SAAS;AACd,CAAC;AAIM,SAAS,aAAqB;AACnC,MAAI,CAAC,WAAW,MAAM,MAAM,GAAG;AAC7B,UAAM,IAAI,MAAM,gDAAgD;AAAA,EAClE;AACA,QAAM,MAAM,aAAa,MAAM,QAAQ,OAAO;AAC9C,SAAO,aAAa,MAAM,KAAK,MAAM,GAAG,CAAC;AAC3C;AAEO,SAAS,WAAW,QAAsB;AAC/C,oBAAkB;AAClB,eAAa,MAAM,MAAM;AACzB,gBAAc,MAAM,QAAQ,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAC7D;AAEO,SAAS,oBAAoB,WAIzB;AACT,QAAM,eAAe,UAAU,aAAa,UAAU,MAAQ;AAC9D,QAAM,MAAM,oBAAI,KAAK;AACrB,QAAM,YAAY,IAAI,KAAK,IAAI,YAAY,GAAG,IAAI,SAAS,IAAI,GAAG,CAAC,EAAE,YAAY;AAEjF,SAAO;AAAA,IACL,SAAS;AAAA,IACT,SAAS,UAAU;AAAA,IACnB,UAAU,UAAU;AAAA,IACpB,SAAS;AAAA,MACP,kBAAkB;AAAA,MAClB,oBAAoB;AAAA,MACpB;AAAA,IACF;AAAA,IACA,UAAU;AAAA,MACR,aAAa,KAAK,MAAM,eAAe,EAAE;AAAA,MACzC,kBAAkB;AAAA,MAClB,gBAAgB;AAAA,MAChB,UAAU,UAAU,YAAY,KAAK,eAAe,EAAE,gBAAgB,EAAE;AAAA,IAC1E;AAAA,EACF;AACF;","names":[]}
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  loadConfig,
3
3
  saveConfig
4
- } from "./chunk-YEKHNTQO.js";
4
+ } from "./chunk-G7BRH6CB.js";
5
5
  import {
6
6
  logger
7
7
  } from "./chunk-KELPENM3.js";
@@ -54,4 +54,4 @@ var rateLimiter = new RateLimiter();
54
54
  export {
55
55
  rateLimiter
56
56
  };
57
- //# sourceMappingURL=chunk-MOCLA2KK.js.map
57
+ //# sourceMappingURL=chunk-H3LB5MYK.js.map
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  rateLimiter
3
- } from "./chunk-MOCLA2KK.js";
3
+ } from "./chunk-H3LB5MYK.js";
4
4
  import {
5
5
  loadConfig
6
- } from "./chunk-YEKHNTQO.js";
6
+ } from "./chunk-G7BRH6CB.js";
7
7
  import {
8
8
  loadIdentity,
9
9
  renderIdentityDocument
@@ -200,4 +200,4 @@ export {
200
200
  buildHeartbeatUserMessage,
201
201
  buildChatPrompt
202
202
  };
203
- //# sourceMappingURL=chunk-BNFUXAQW.js.map
203
+ //# sourceMappingURL=chunk-RBEJBQI6.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  loadConfig
3
- } from "./chunk-YEKHNTQO.js";
3
+ } from "./chunk-G7BRH6CB.js";
4
4
  import {
5
5
  logger
6
6
  } from "./chunk-KELPENM3.js";
@@ -67,7 +67,7 @@ async function flushQueue() {
67
67
  const now = /* @__PURE__ */ new Date();
68
68
  let posted = 0;
69
69
  let failed = 0;
70
- const { getXClient } = await import("./x-client-SLAC2ON5.js");
70
+ const { getXClient } = await import("./x-client-MRM3ASO6.js");
71
71
  const client = await getXClient();
72
72
  for (const entry of queue.entries) {
73
73
  if (entry.status !== "pending") continue;
@@ -121,4 +121,4 @@ export {
121
121
  flushQueue,
122
122
  showQueue
123
123
  };
124
- //# sourceMappingURL=chunk-T3JHWIKX.js.map
124
+ //# sourceMappingURL=chunk-Y3TN5BGG.js.map
package/dist/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  loadConfig
4
- } from "./chunk-YEKHNTQO.js";
4
+ } from "./chunk-G7BRH6CB.js";
5
5
  import {
6
6
  FRAMEWORKS,
7
7
  GOAL_PRESETS,
@@ -34,7 +34,7 @@ program.command("init").description("Set up X account credentials for your Spore
34
34
  if (opts.method) {
35
35
  const { ensureDirectories } = await import("./paths-5GFUUHCZ.js");
36
36
  const { saveCredentials } = await import("./crypto-FHSQ72NU.js");
37
- const { createDefaultConfig, saveConfig } = await import("./config-NZAFARS6.js");
37
+ const { createDefaultConfig, saveConfig } = await import("./config-URTRCIDT.js");
38
38
  ensureDirectories();
39
39
  if (opts.method === "create") {
40
40
  const accountName = opts.accountName ?? `Spore${Math.floor(Math.random() * 9e3) + 1e3}`;
@@ -123,7 +123,7 @@ program.command("init").description("Set up X account credentials for your Spore
123
123
  console.log(chalk.cyan(BANNER));
124
124
  console.log(chalk.bold("Welcome to Spora."));
125
125
  console.log(chalk.gray("The global town square for AI agents.\n"));
126
- const { runInit } = await import("./init-TODR3WR2.js");
126
+ const { runInit } = await import("./init-P43IGFJV.js");
127
127
  await runInit(opts.token);
128
128
  });
129
129
  program.command("serve").description("Start the Spora MCP server (stdio)").action(async () => {
@@ -135,7 +135,7 @@ program.command("chat").description("Open web-based chat interface with your Spo
135
135
  console.log(chalk.red("\u2717 No identity found. Run `spora create` first."));
136
136
  process.exit(1);
137
137
  }
138
- const { startWebChat } = await import("./web-chat-L5MVPVUR.js");
138
+ const { startWebChat } = await import("./web-chat-AGFCA755.js");
139
139
  await startWebChat();
140
140
  });
141
141
  program.command("tui").description("Start terminal-based chat interface (TUI)").action(async () => {
@@ -278,7 +278,7 @@ program.command("journal").description("Add a reflection to the evolution journa
278
278
  });
279
279
  program.command("post").description("Post a tweet").argument("<content>", "Tweet content (max 280 chars)").action(async (content) => {
280
280
  try {
281
- const { getXClient } = await import("./x-client-SLAC2ON5.js");
281
+ const { getXClient } = await import("./x-client-MRM3ASO6.js");
282
282
  const client = await getXClient();
283
283
  const result = await client.postTweet(content);
284
284
  console.log(JSON.stringify(result, null, 2));
@@ -289,7 +289,7 @@ program.command("post").description("Post a tweet").argument("<content>", "Tweet
289
289
  });
290
290
  program.command("reply").description("Reply to a tweet").argument("<tweetId>", "Tweet ID to reply to").argument("<content>", "Reply content").action(async (tweetId, content) => {
291
291
  try {
292
- const { getXClient } = await import("./x-client-SLAC2ON5.js");
292
+ const { getXClient } = await import("./x-client-MRM3ASO6.js");
293
293
  const client = await getXClient();
294
294
  const result = await client.replyToTweet(tweetId, content);
295
295
  console.log(JSON.stringify(result, null, 2));
@@ -300,7 +300,7 @@ program.command("reply").description("Reply to a tweet").argument("<tweetId>", "
300
300
  });
301
301
  program.command("like").description("Like a tweet").argument("<tweetId>", "Tweet ID").action(async (tweetId) => {
302
302
  try {
303
- const { getXClient } = await import("./x-client-SLAC2ON5.js");
303
+ const { getXClient } = await import("./x-client-MRM3ASO6.js");
304
304
  const client = await getXClient();
305
305
  const result = await client.likeTweet(tweetId);
306
306
  console.log(JSON.stringify(result, null, 2));
@@ -311,7 +311,7 @@ program.command("like").description("Like a tweet").argument("<tweetId>", "Tweet
311
311
  });
312
312
  program.command("retweet").description("Retweet a tweet").argument("<tweetId>", "Tweet ID").action(async (tweetId) => {
313
313
  try {
314
- const { getXClient } = await import("./x-client-SLAC2ON5.js");
314
+ const { getXClient } = await import("./x-client-MRM3ASO6.js");
315
315
  const client = await getXClient();
316
316
  const result = await client.retweet(tweetId);
317
317
  console.log(JSON.stringify(result, null, 2));
@@ -322,7 +322,7 @@ program.command("retweet").description("Retweet a tweet").argument("<tweetId>",
322
322
  });
323
323
  program.command("follow").description("Follow a user").argument("<handle>", "User handle or ID").action(async (handle) => {
324
324
  try {
325
- const { getXClient } = await import("./x-client-SLAC2ON5.js");
325
+ const { getXClient } = await import("./x-client-MRM3ASO6.js");
326
326
  const client = await getXClient();
327
327
  const result = await client.followUser(handle);
328
328
  console.log(JSON.stringify(result, null, 2));
@@ -333,7 +333,7 @@ program.command("follow").description("Follow a user").argument("<handle>", "Use
333
333
  });
334
334
  program.command("unfollow").description("Unfollow a user").argument("<handle>", "User handle or ID").action(async (handle) => {
335
335
  try {
336
- const { getXClient } = await import("./x-client-SLAC2ON5.js");
336
+ const { getXClient } = await import("./x-client-MRM3ASO6.js");
337
337
  const client = await getXClient();
338
338
  const result = await client.unfollowUser(handle);
339
339
  console.log(JSON.stringify(result, null, 2));
@@ -344,7 +344,7 @@ program.command("unfollow").description("Unfollow a user").argument("<handle>",
344
344
  });
345
345
  program.command("timeline").description("Read home timeline").option("-c, --count <n>", "Number of tweets", "20").action(async (opts) => {
346
346
  try {
347
- const { getXClient } = await import("./x-client-SLAC2ON5.js");
347
+ const { getXClient } = await import("./x-client-MRM3ASO6.js");
348
348
  const client = await getXClient();
349
349
  const result = await client.getTimeline({ count: parseInt(opts.count) });
350
350
  console.log(JSON.stringify(result, null, 2));
@@ -355,7 +355,7 @@ program.command("timeline").description("Read home timeline").option("-c, --coun
355
355
  });
356
356
  program.command("mentions").description("Read mentions").option("-c, --count <n>", "Number of mentions", "20").action(async (opts) => {
357
357
  try {
358
- const { getXClient } = await import("./x-client-SLAC2ON5.js");
358
+ const { getXClient } = await import("./x-client-MRM3ASO6.js");
359
359
  const client = await getXClient();
360
360
  const result = await client.getMentions({ count: parseInt(opts.count) });
361
361
  console.log(JSON.stringify(result, null, 2));
@@ -366,7 +366,7 @@ program.command("mentions").description("Read mentions").option("-c, --count <n>
366
366
  });
367
367
  program.command("search").description("Search for tweets").argument("<query>", "Search query").option("-c, --count <n>", "Number of results", "20").action(async (query, opts) => {
368
368
  try {
369
- const { getXClient } = await import("./x-client-SLAC2ON5.js");
369
+ const { getXClient } = await import("./x-client-MRM3ASO6.js");
370
370
  const client = await getXClient();
371
371
  const result = await client.searchTweets(query, { count: parseInt(opts.count) });
372
372
  console.log(JSON.stringify(result, null, 2));
@@ -377,7 +377,7 @@ program.command("search").description("Search for tweets").argument("<query>", "
377
377
  });
378
378
  program.command("profile").description("Get a user's X profile").argument("<handle>", "X handle (without @)").action(async (handle) => {
379
379
  try {
380
- const { getXClient } = await import("./x-client-SLAC2ON5.js");
380
+ const { getXClient } = await import("./x-client-MRM3ASO6.js");
381
381
  const client = await getXClient();
382
382
  const result = await client.getProfile(handle);
383
383
  console.log(JSON.stringify(result, null, 2));
@@ -443,7 +443,7 @@ program.command("note").description("Add a relationship note about someone").arg
443
443
  });
444
444
  program.command("schedule").description("Queue a post for later").argument("<content>", "Tweet content").option("--at <datetime>", "ISO datetime to post at").action(async (content, opts) => {
445
445
  try {
446
- const { addToQueue } = await import("./queue-N64QLRAB.js");
446
+ const { addToQueue } = await import("./queue-HHAUICMD.js");
447
447
  const entry = addToQueue(content, opts.at);
448
448
  console.log(JSON.stringify({ success: true, id: entry.id, scheduledFor: entry.scheduledFor }));
449
449
  } catch (error) {
@@ -453,7 +453,7 @@ program.command("schedule").description("Queue a post for later").argument("<con
453
453
  });
454
454
  program.command("flush").description("Post all queued items whose time has come").action(async () => {
455
455
  try {
456
- const { flushQueue } = await import("./queue-N64QLRAB.js");
456
+ const { flushQueue } = await import("./queue-HHAUICMD.js");
457
457
  const results = await flushQueue();
458
458
  console.log(JSON.stringify(results, null, 2));
459
459
  } catch (error) {
@@ -462,13 +462,13 @@ program.command("flush").description("Post all queued items whose time has come"
462
462
  }
463
463
  });
464
464
  program.command("queue").description("Show scheduled posts").action(async () => {
465
- const { showQueue } = await import("./queue-N64QLRAB.js");
465
+ const { showQueue } = await import("./queue-HHAUICMD.js");
466
466
  showQueue();
467
467
  });
468
468
  var colony = program.command("colony").description("Colony commands");
469
469
  colony.command("checkin").description("Check into The Colony \u2014 sync memory, discover Spores").option("-m, --message <msg>", "Optional message to post").action(async (opts) => {
470
470
  try {
471
- const { colonyCheckin } = await import("./colony-EFGAMLOX.js");
471
+ const { colonyCheckin } = await import("./colony-HCBEQDN2.js");
472
472
  const result = await colonyCheckin(opts.message);
473
473
  console.log(JSON.stringify(result, null, 2));
474
474
  } catch (error) {
@@ -487,7 +487,7 @@ colony.command("memory").description("Read the Colony's shared memory").action(a
487
487
  });
488
488
  colony.command("plans").description("Get all active Colony plans").action(async () => {
489
489
  try {
490
- const { getActivePlans } = await import("./colony-EFGAMLOX.js");
490
+ const { getActivePlans } = await import("./colony-HCBEQDN2.js");
491
491
  const plans = getActivePlans();
492
492
  console.log(plans.length > 0 ? JSON.stringify(plans, null, 2) : JSON.stringify({ message: "No active plans. Propose one!" }));
493
493
  } catch (error) {
@@ -497,7 +497,7 @@ colony.command("plans").description("Get all active Colony plans").action(async
497
497
  });
498
498
  colony.command("propose").description("Propose a coordinated plan").argument("<description>", "What's the plan?").action(async (description) => {
499
499
  try {
500
- const { proposePlan } = await import("./colony-EFGAMLOX.js");
500
+ const { proposePlan } = await import("./colony-HCBEQDN2.js");
501
501
  const result = await proposePlan(description);
502
502
  console.log(JSON.stringify(result, null, 2));
503
503
  } catch (error) {
@@ -507,7 +507,7 @@ colony.command("propose").description("Propose a coordinated plan").argument("<d
507
507
  });
508
508
  colony.command("join").description("Join an active plan").argument("<planId>", "Plan ID").action(async (planId) => {
509
509
  try {
510
- const { joinPlan } = await import("./colony-EFGAMLOX.js");
510
+ const { joinPlan } = await import("./colony-HCBEQDN2.js");
511
511
  const result = await joinPlan(planId);
512
512
  console.log(JSON.stringify(result, null, 2));
513
513
  } catch (error) {
@@ -517,7 +517,7 @@ colony.command("join").description("Join an active plan").argument("<planId>", "
517
517
  });
518
518
  colony.command("post-status").description("Post a status update to the Colony").argument("<status>", "Your status").action(async (status) => {
519
519
  try {
520
- const { postStatus } = await import("./colony-EFGAMLOX.js");
520
+ const { postStatus } = await import("./colony-HCBEQDN2.js");
521
521
  const result = await postStatus(status);
522
522
  console.log(JSON.stringify(result, null, 2));
523
523
  } catch (error) {
@@ -527,7 +527,7 @@ colony.command("post-status").description("Post a status update to the Colony").
527
527
  });
528
528
  colony.command("activity").description("Get today's Colony activity").action(async () => {
529
529
  try {
530
- const { getTodaysActivity } = await import("./colony-EFGAMLOX.js");
530
+ const { getTodaysActivity } = await import("./colony-HCBEQDN2.js");
531
531
  const activity = getTodaysActivity();
532
532
  console.log(activity.length > 0 ? JSON.stringify(activity, null, 2) : JSON.stringify({ message: "No Colony activity today yet." }));
533
533
  } catch (error) {
@@ -544,24 +544,24 @@ program.command("start").description("Start the autonomous Spora agent").option(
544
544
  console.log(JSON.stringify({ error: "No X credentials. Run `spora init` to set up." }));
545
545
  process.exit(1);
546
546
  }
547
- const { hasLLMKey } = await import("./llm-OH2Z4PSN.js");
547
+ const { hasLLMKey } = await import("./llm-U5AHRXQL.js");
548
548
  if (!hasLLMKey()) {
549
549
  console.log(JSON.stringify({ error: "No LLM API key. Run `spora set-llm-key` first." }));
550
550
  process.exit(1);
551
551
  }
552
552
  if (opts.interval) {
553
- const { loadConfig: lc, saveConfig: sc } = await import("./config-NZAFARS6.js");
553
+ const { loadConfig: lc, saveConfig: sc } = await import("./config-URTRCIDT.js");
554
554
  const config = lc();
555
555
  config.runtime = { ...config.runtime, heartbeatIntervalMs: parseInt(opts.interval, 10), actionsPerHeartbeat: config.runtime?.actionsPerHeartbeat ?? 3, enabled: true };
556
556
  sc(config);
557
557
  }
558
558
  console.log(chalk.cyan(BANNER));
559
559
  console.log(chalk.bold("Starting Spora agent...\n"));
560
- const { startHeartbeatLoop } = await import("./heartbeat-2GVBKQPO.js");
560
+ const { startHeartbeatLoop } = await import("./heartbeat-GBAOTGL6.js");
561
561
  await startHeartbeatLoop();
562
562
  });
563
563
  program.command("stop").description("Stop the running Spora agent").action(async () => {
564
- const { getRunningPid, requestStop } = await import("./heartbeat-2GVBKQPO.js");
564
+ const { getRunningPid, requestStop } = await import("./heartbeat-GBAOTGL6.js");
565
565
  const pid = getRunningPid();
566
566
  if (!pid) {
567
567
  console.log(JSON.stringify({ message: "Spora agent is not running." }));
@@ -588,7 +588,7 @@ program.command("set-llm-key").description("Set your Anthropic API key for the a
588
588
  }
589
589
  writeFileSync(p.llmKey, apiKey, { mode: 384 });
590
590
  try {
591
- const { loadConfig: lc, saveConfig: sc } = await import("./config-NZAFARS6.js");
591
+ const { loadConfig: lc, saveConfig: sc } = await import("./config-URTRCIDT.js");
592
592
  const config = lc();
593
593
  if (!config.llm) {
594
594
  config.llm = { provider: "anthropic", model: "claude-sonnet-4-20250514" };
@@ -599,9 +599,9 @@ program.command("set-llm-key").description("Set your Anthropic API key for the a
599
599
  console.log(JSON.stringify({ success: true, message: "LLM API key saved." }));
600
600
  });
601
601
  program.command("agent-status").description("Check if the Spora agent is running").action(async () => {
602
- const { getRunningPid } = await import("./heartbeat-2GVBKQPO.js");
602
+ const { getRunningPid } = await import("./heartbeat-GBAOTGL6.js");
603
603
  const pid = getRunningPid();
604
- const { hasLLMKey } = await import("./llm-OH2Z4PSN.js");
604
+ const { hasLLMKey } = await import("./llm-U5AHRXQL.js");
605
605
  console.log(JSON.stringify({
606
606
  agentRunning: pid !== null,
607
607
  pid,
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  rateLimiter
3
- } from "./chunk-MOCLA2KK.js";
4
- import "./chunk-YEKHNTQO.js";
3
+ } from "./chunk-H3LB5MYK.js";
4
+ import "./chunk-G7BRH6CB.js";
5
5
  import {
6
6
  identityExists,
7
7
  loadIdentity
@@ -370,4 +370,4 @@ var XApiClient = class {
370
370
  export {
371
371
  XApiClient
372
372
  };
373
- //# sourceMappingURL=client-2ZSXZE3D.js.map
373
+ //# sourceMappingURL=client-435YKLVK.js.map
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  rateLimiter
3
- } from "./chunk-MOCLA2KK.js";
4
- import "./chunk-YEKHNTQO.js";
3
+ } from "./chunk-H3LB5MYK.js";
4
+ import "./chunk-G7BRH6CB.js";
5
5
  import {
6
6
  identityExists,
7
7
  loadIdentity
@@ -398,4 +398,4 @@ var XBrowserClient = class {
398
398
  export {
399
399
  XBrowserClient
400
400
  };
401
- //# sourceMappingURL=client-2CURS7J6.js.map
401
+ //# sourceMappingURL=client-WHCMJ5PP.js.map
@@ -10,8 +10,8 @@ import {
10
10
  } from "./chunk-AHXZIGQE.js";
11
11
  import {
12
12
  getXClient
13
- } from "./chunk-IIQAE7OP.js";
14
- import "./chunk-YEKHNTQO.js";
13
+ } from "./chunk-EODRPATL.js";
14
+ import "./chunk-G7BRH6CB.js";
15
15
  import {
16
16
  loadIdentity
17
17
  } from "./chunk-AIEXQCQS.js";
@@ -226,4 +226,4 @@ export {
226
226
  postStatus,
227
227
  proposePlan
228
228
  };
229
- //# sourceMappingURL=colony-EFGAMLOX.js.map
229
+ //# sourceMappingURL=colony-HCBEQDN2.js.map
@@ -3,7 +3,7 @@ import {
3
3
  createDefaultConfig,
4
4
  loadConfig,
5
5
  saveConfig
6
- } from "./chunk-YEKHNTQO.js";
6
+ } from "./chunk-G7BRH6CB.js";
7
7
  import "./chunk-53YLFYJF.js";
8
8
  export {
9
9
  ConfigSchema,
@@ -11,4 +11,4 @@ export {
11
11
  loadConfig,
12
12
  saveConfig
13
13
  };
14
- //# sourceMappingURL=config-NZAFARS6.js.map
14
+ //# sourceMappingURL=config-URTRCIDT.js.map
@@ -1,23 +1,23 @@
1
1
  import {
2
2
  buildHeartbeatUserMessage,
3
3
  buildSystemPrompt
4
- } from "./chunk-BNFUXAQW.js";
4
+ } from "./chunk-RBEJBQI6.js";
5
5
  import {
6
6
  generateResponse
7
- } from "./chunk-3FBYOHQR.js";
7
+ } from "./chunk-DK26DJKM.js";
8
8
  import {
9
9
  rateLimiter
10
- } from "./chunk-MOCLA2KK.js";
10
+ } from "./chunk-H3LB5MYK.js";
11
11
  import {
12
12
  getXClient
13
- } from "./chunk-IIQAE7OP.js";
13
+ } from "./chunk-EODRPATL.js";
14
14
  import {
15
15
  addToQueue,
16
16
  flushQueue
17
- } from "./chunk-T3JHWIKX.js";
17
+ } from "./chunk-Y3TN5BGG.js";
18
18
  import {
19
19
  loadConfig
20
- } from "./chunk-YEKHNTQO.js";
20
+ } from "./chunk-G7BRH6CB.js";
21
21
  import {
22
22
  loadIdentity,
23
23
  saveIdentity
@@ -355,4 +355,4 @@ export {
355
355
  requestStop,
356
356
  startHeartbeatLoop
357
357
  };
358
- //# sourceMappingURL=heartbeat-2GVBKQPO.js.map
358
+ //# sourceMappingURL=heartbeat-GBAOTGL6.js.map
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  createDefaultConfig,
3
3
  saveConfig
4
- } from "./chunk-YEKHNTQO.js";
4
+ } from "./chunk-G7BRH6CB.js";
5
5
  import {
6
6
  loadIdentity
7
7
  } from "./chunk-AIEXQCQS.js";
@@ -172,7 +172,7 @@ async function syncIdentityFromToken(token) {
172
172
  const { existsSync } = await import("fs");
173
173
  const { paths } = await import("./paths-5GFUUHCZ.js");
174
174
  if (existsSync(paths.config)) {
175
- const { loadConfig, saveConfig: saveConfig2 } = await import("./config-NZAFARS6.js");
175
+ const { loadConfig, saveConfig: saveConfig2 } = await import("./config-URTRCIDT.js");
176
176
  const config = loadConfig();
177
177
  config.connection = {
178
178
  token,
@@ -203,7 +203,7 @@ async function loginFlow() {
203
203
  console.log(chalk.green("\u2713 Logged in!\n"));
204
204
  console.log(chalk.gray("Opening chat interface...\n"));
205
205
  try {
206
- const { startWebChat } = await import("./web-chat-L5MVPVUR.js");
206
+ const { startWebChat } = await import("./web-chat-AGFCA755.js");
207
207
  await startWebChat();
208
208
  } catch (error) {
209
209
  console.log(chalk.yellow(`Could not start chat interface: ${error.message}
@@ -275,7 +275,7 @@ async function showDoneAndOpenChat() {
275
275
  console.log(chalk.bold.cyan("\u2501\u2501\u2501 Your Spore is Ready! \u2501\u2501\u2501\n"));
276
276
  console.log(chalk.gray("Opening chat interface...\n"));
277
277
  try {
278
- const { startWebChat } = await import("./web-chat-L5MVPVUR.js");
278
+ const { startWebChat } = await import("./web-chat-AGFCA755.js");
279
279
  await startWebChat();
280
280
  } catch (error) {
281
281
  console.log(chalk.yellow(`Could not start chat interface: ${error.message}
@@ -400,4 +400,4 @@ async function runInit(token) {
400
400
  export {
401
401
  runInit
402
402
  };
403
- //# sourceMappingURL=init-TODR3WR2.js.map
403
+ //# sourceMappingURL=init-P43IGFJV.js.map
@@ -3,8 +3,8 @@ import {
3
3
  generateResponse,
4
4
  getLLMApiKey,
5
5
  hasLLMKey
6
- } from "./chunk-3FBYOHQR.js";
7
- import "./chunk-YEKHNTQO.js";
6
+ } from "./chunk-DK26DJKM.js";
7
+ import "./chunk-G7BRH6CB.js";
8
8
  import "./chunk-KELPENM3.js";
9
9
  import "./chunk-53YLFYJF.js";
10
10
  export {
@@ -13,4 +13,4 @@ export {
13
13
  getLLMApiKey,
14
14
  hasLLMKey
15
15
  };
16
- //# sourceMappingURL=llm-OH2Z4PSN.js.map
16
+ //# sourceMappingURL=llm-U5AHRXQL.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  loadConfig
3
- } from "./chunk-YEKHNTQO.js";
3
+ } from "./chunk-G7BRH6CB.js";
4
4
  import {
5
5
  FRAMEWORKS,
6
6
  GOAL_PRESETS,
@@ -388,7 +388,7 @@ Identity saved. Your Spore is alive. Use spora_get_identity to read the full doc
388
388
  },
389
389
  async ({ content }) => {
390
390
  try {
391
- const { getXClient } = await import("./x-client-SLAC2ON5.js");
391
+ const { getXClient } = await import("./x-client-MRM3ASO6.js");
392
392
  const client = await getXClient();
393
393
  const result = await client.postTweet(content);
394
394
  return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
@@ -406,7 +406,7 @@ Identity saved. Your Spore is alive. Use spora_get_identity to read the full doc
406
406
  },
407
407
  async ({ tweetId, content }) => {
408
408
  try {
409
- const { getXClient } = await import("./x-client-SLAC2ON5.js");
409
+ const { getXClient } = await import("./x-client-MRM3ASO6.js");
410
410
  const client = await getXClient();
411
411
  const result = await client.replyToTweet(tweetId, content);
412
412
  return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
@@ -421,7 +421,7 @@ Identity saved. Your Spore is alive. Use spora_get_identity to read the full doc
421
421
  { tweetId: z.string().describe("The ID of the tweet to like") },
422
422
  async ({ tweetId }) => {
423
423
  try {
424
- const { getXClient } = await import("./x-client-SLAC2ON5.js");
424
+ const { getXClient } = await import("./x-client-MRM3ASO6.js");
425
425
  const client = await getXClient();
426
426
  const result = await client.likeTweet(tweetId);
427
427
  return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
@@ -436,7 +436,7 @@ Identity saved. Your Spore is alive. Use spora_get_identity to read the full doc
436
436
  { tweetId: z.string().describe("The ID of the tweet to retweet") },
437
437
  async ({ tweetId }) => {
438
438
  try {
439
- const { getXClient } = await import("./x-client-SLAC2ON5.js");
439
+ const { getXClient } = await import("./x-client-MRM3ASO6.js");
440
440
  const client = await getXClient();
441
441
  const result = await client.retweet(tweetId);
442
442
  return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
@@ -451,7 +451,7 @@ Identity saved. Your Spore is alive. Use spora_get_identity to read the full doc
451
451
  { userId: z.string().describe("The user ID to follow") },
452
452
  async ({ userId }) => {
453
453
  try {
454
- const { getXClient } = await import("./x-client-SLAC2ON5.js");
454
+ const { getXClient } = await import("./x-client-MRM3ASO6.js");
455
455
  const client = await getXClient();
456
456
  const result = await client.followUser(userId);
457
457
  return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
@@ -466,7 +466,7 @@ Identity saved. Your Spore is alive. Use spora_get_identity to read the full doc
466
466
  { userId: z.string().describe("The user ID to unfollow") },
467
467
  async ({ userId }) => {
468
468
  try {
469
- const { getXClient } = await import("./x-client-SLAC2ON5.js");
469
+ const { getXClient } = await import("./x-client-MRM3ASO6.js");
470
470
  const client = await getXClient();
471
471
  const result = await client.unfollowUser(userId);
472
472
  return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
@@ -481,7 +481,7 @@ Identity saved. Your Spore is alive. Use spora_get_identity to read the full doc
481
481
  { count: z.number().optional().describe("Number of tweets to fetch (default 20)") },
482
482
  async ({ count }) => {
483
483
  try {
484
- const { getXClient } = await import("./x-client-SLAC2ON5.js");
484
+ const { getXClient } = await import("./x-client-MRM3ASO6.js");
485
485
  const client = await getXClient();
486
486
  const result = await client.getTimeline({ count: count ?? 20 });
487
487
  return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
@@ -496,7 +496,7 @@ Identity saved. Your Spore is alive. Use spora_get_identity to read the full doc
496
496
  { count: z.number().optional().describe("Number of mentions to fetch (default 20)") },
497
497
  async ({ count }) => {
498
498
  try {
499
- const { getXClient } = await import("./x-client-SLAC2ON5.js");
499
+ const { getXClient } = await import("./x-client-MRM3ASO6.js");
500
500
  const client = await getXClient();
501
501
  const result = await client.getMentions({ count: count ?? 20 });
502
502
  return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
@@ -514,7 +514,7 @@ Identity saved. Your Spore is alive. Use spora_get_identity to read the full doc
514
514
  },
515
515
  async ({ query, count }) => {
516
516
  try {
517
- const { getXClient } = await import("./x-client-SLAC2ON5.js");
517
+ const { getXClient } = await import("./x-client-MRM3ASO6.js");
518
518
  const client = await getXClient();
519
519
  const result = await client.searchTweets(query, { count: count ?? 20 });
520
520
  return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
@@ -529,7 +529,7 @@ Identity saved. Your Spore is alive. Use spora_get_identity to read the full doc
529
529
  { handle: z.string().describe("X handle (without @)") },
530
530
  async ({ handle }) => {
531
531
  try {
532
- const { getXClient } = await import("./x-client-SLAC2ON5.js");
532
+ const { getXClient } = await import("./x-client-MRM3ASO6.js");
533
533
  const client = await getXClient();
534
534
  const result = await client.getProfile(handle);
535
535
  return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
@@ -547,7 +547,7 @@ Identity saved. Your Spore is alive. Use spora_get_identity to read the full doc
547
547
  },
548
548
  async ({ content, scheduledFor }) => {
549
549
  try {
550
- const { addToQueue } = await import("./queue-N64QLRAB.js");
550
+ const { addToQueue } = await import("./queue-HHAUICMD.js");
551
551
  const entry = addToQueue(content, scheduledFor);
552
552
  return {
553
553
  content: [
@@ -565,7 +565,7 @@ Identity saved. Your Spore is alive. Use spora_get_identity to read the full doc
565
565
  {},
566
566
  async () => {
567
567
  try {
568
- const { flushQueue } = await import("./queue-N64QLRAB.js");
568
+ const { flushQueue } = await import("./queue-HHAUICMD.js");
569
569
  const results = await flushQueue();
570
570
  return {
571
571
  content: [
@@ -586,7 +586,7 @@ Identity saved. Your Spore is alive. Use spora_get_identity to read the full doc
586
586
  { message: z.string().optional().describe("Optional message to post to the Colony community") },
587
587
  async ({ message }) => {
588
588
  try {
589
- const { colonyCheckin } = await import("./colony-EFGAMLOX.js");
589
+ const { colonyCheckin } = await import("./colony-HCBEQDN2.js");
590
590
  const result = await colonyCheckin(message);
591
591
  return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
592
592
  } catch (error) {
@@ -600,7 +600,7 @@ Identity saved. Your Spore is alive. Use spora_get_identity to read the full doc
600
600
  {},
601
601
  async () => {
602
602
  try {
603
- const { getColonyMemory } = await import("./colony-EFGAMLOX.js");
603
+ const { getColonyMemory } = await import("./colony-HCBEQDN2.js");
604
604
  const memory = getColonyMemory();
605
605
  return { content: [{ type: "text", text: JSON.stringify(memory, null, 2) }] };
606
606
  } catch (error) {
@@ -614,7 +614,7 @@ Identity saved. Your Spore is alive. Use spora_get_identity to read the full doc
614
614
  {},
615
615
  async () => {
616
616
  try {
617
- const { getActivePlans } = await import("./colony-EFGAMLOX.js");
617
+ const { getActivePlans } = await import("./colony-HCBEQDN2.js");
618
618
  const plans = getActivePlans();
619
619
  return {
620
620
  content: [
@@ -637,7 +637,7 @@ Identity saved. Your Spore is alive. Use spora_get_identity to read the full doc
637
637
  },
638
638
  async ({ description }) => {
639
639
  try {
640
- const { proposePlan } = await import("./colony-EFGAMLOX.js");
640
+ const { proposePlan } = await import("./colony-HCBEQDN2.js");
641
641
  const result = await proposePlan(description);
642
642
  if (result.success) {
643
643
  return {
@@ -660,7 +660,7 @@ Identity saved. Your Spore is alive. Use spora_get_identity to read the full doc
660
660
  },
661
661
  async ({ planId }) => {
662
662
  try {
663
- const { joinPlan } = await import("./colony-EFGAMLOX.js");
663
+ const { joinPlan } = await import("./colony-HCBEQDN2.js");
664
664
  const result = await joinPlan(planId);
665
665
  if (result.success) {
666
666
  return { content: [{ type: "text", text: "Joined the plan! Go execute it." }] };
@@ -679,7 +679,7 @@ Identity saved. Your Spore is alive. Use spora_get_identity to read the full doc
679
679
  },
680
680
  async ({ status }) => {
681
681
  try {
682
- const { postStatus } = await import("./colony-EFGAMLOX.js");
682
+ const { postStatus } = await import("./colony-HCBEQDN2.js");
683
683
  const result = await postStatus(status);
684
684
  if (result.success) {
685
685
  return { content: [{ type: "text", text: "Status posted to the Colony." }] };
@@ -696,7 +696,7 @@ Identity saved. Your Spore is alive. Use spora_get_identity to read the full doc
696
696
  {},
697
697
  async () => {
698
698
  try {
699
- const { getTodaysActivity } = await import("./colony-EFGAMLOX.js");
699
+ const { getTodaysActivity } = await import("./colony-HCBEQDN2.js");
700
700
  const activity = getTodaysActivity();
701
701
  return {
702
702
  content: [
@@ -2,9 +2,9 @@ import {
2
2
  buildChatPrompt,
3
3
  buildHeartbeatUserMessage,
4
4
  buildSystemPrompt
5
- } from "./chunk-BNFUXAQW.js";
6
- import "./chunk-MOCLA2KK.js";
7
- import "./chunk-YEKHNTQO.js";
5
+ } from "./chunk-RBEJBQI6.js";
6
+ import "./chunk-H3LB5MYK.js";
7
+ import "./chunk-G7BRH6CB.js";
8
8
  import "./chunk-AIEXQCQS.js";
9
9
  import "./chunk-KELPENM3.js";
10
10
  import "./chunk-EBO4F5NU.js";
@@ -14,4 +14,4 @@ export {
14
14
  buildHeartbeatUserMessage,
15
15
  buildSystemPrompt
16
16
  };
17
- //# sourceMappingURL=prompt-builder-WYB5B67W.js.map
17
+ //# sourceMappingURL=prompt-builder-4X6SPLMG.js.map
@@ -2,8 +2,8 @@ import {
2
2
  addToQueue,
3
3
  flushQueue,
4
4
  showQueue
5
- } from "./chunk-T3JHWIKX.js";
6
- import "./chunk-YEKHNTQO.js";
5
+ } from "./chunk-Y3TN5BGG.js";
6
+ import "./chunk-G7BRH6CB.js";
7
7
  import "./chunk-KELPENM3.js";
8
8
  import "./chunk-53YLFYJF.js";
9
9
  export {
@@ -11,4 +11,4 @@ export {
11
11
  flushQueue,
12
12
  showQueue
13
13
  };
14
- //# sourceMappingURL=queue-N64QLRAB.js.map
14
+ //# sourceMappingURL=queue-HHAUICMD.js.map
@@ -181,11 +181,11 @@ async function startWebChat() {
181
181
  server.setMessageHandler(async (message) => {
182
182
  try {
183
183
  if (!systemPrompt || messageCount % 10 === 0) {
184
- const { buildChatPrompt } = await import("./prompt-builder-WYB5B67W.js");
184
+ const { buildChatPrompt } = await import("./prompt-builder-4X6SPLMG.js");
185
185
  systemPrompt = buildChatPrompt();
186
186
  }
187
187
  messageCount++;
188
- const { hasLLMKey, chat: chatLLM } = await import("./llm-OH2Z4PSN.js");
188
+ const { hasLLMKey, chat: chatLLM } = await import("./llm-U5AHRXQL.js");
189
189
  if (!hasLLMKey()) {
190
190
  return "I can't respond right now - no API key configured. Run `spora set-llm-key` to set one up.";
191
191
  }
@@ -250,4 +250,4 @@ export {
250
250
  openBrowser,
251
251
  startWebChat
252
252
  };
253
- //# sourceMappingURL=web-chat-L5MVPVUR.js.map
253
+ //# sourceMappingURL=web-chat-AGFCA755.js.map
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  getXClient,
3
3
  resetXClient
4
- } from "./chunk-IIQAE7OP.js";
5
- import "./chunk-YEKHNTQO.js";
4
+ } from "./chunk-EODRPATL.js";
5
+ import "./chunk-G7BRH6CB.js";
6
6
  import "./chunk-KELPENM3.js";
7
7
  import "./chunk-53YLFYJF.js";
8
8
  export {
9
9
  getXClient,
10
10
  resetXClient
11
11
  };
12
- //# sourceMappingURL=x-client-SLAC2ON5.js.map
12
+ //# sourceMappingURL=x-client-MRM3ASO6.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spora",
3
- "version": "0.3.7",
3
+ "version": "0.3.9",
4
4
  "description": "AI agents (Spores) that autonomously manage X/Twitter accounts",
5
5
  "type": "module",
6
6
  "author": "Spora",
@@ -38,6 +38,7 @@
38
38
  },
39
39
  "dependencies": {
40
40
  "@anthropic-ai/sdk": "^0.72.1",
41
+ "openai": "^4.73.0",
41
42
  "@inquirer/prompts": "^7.0.0",
42
43
  "@modelcontextprotocol/sdk": "^1.0.0",
43
44
  "agentmail": "^0.1.0",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/runtime/llm.ts"],"sourcesContent":["import Anthropic from \"@anthropic-ai/sdk\";\nimport { readFileSync, existsSync } from \"node:fs\";\nimport { paths } from \"../utils/paths.js\";\nimport { loadConfig } from \"../utils/config.js\";\nimport { logger } from \"../utils/logger.js\";\n\nlet client: Anthropic | null = null;\n\nexport function getLLMApiKey(): string | null {\n // Check env first, then file\n if (process.env.ANTHROPIC_API_KEY) {\n return process.env.ANTHROPIC_API_KEY;\n }\n if (existsSync(paths.llmKey)) {\n return readFileSync(paths.llmKey, \"utf-8\").trim();\n }\n return null;\n}\n\nexport function hasLLMKey(): boolean {\n return getLLMApiKey() !== null;\n}\n\nfunction getClient(): Anthropic {\n if (client) return client;\n const apiKey = getLLMApiKey();\n if (!apiKey) {\n throw new Error(\"No LLM API key configured. Run `spora set-llm-key` first.\");\n }\n client = new Anthropic({ apiKey });\n return client;\n}\n\nexport interface LLMResponse {\n content: string;\n inputTokens: number;\n outputTokens: number;\n}\n\nexport async function generateResponse(\n systemPrompt: string,\n userMessage: string,\n): Promise<LLMResponse> {\n const config = loadConfig();\n const model = config.llm?.model ?? \"claude-sonnet-4-20250514\";\n\n logger.info(`Calling LLM (${model})...`);\n\n const anthropic = getClient();\n const response = await anthropic.messages.create({\n model,\n max_tokens: 1024,\n system: systemPrompt,\n messages: [{ role: \"user\", content: userMessage }],\n });\n\n const textBlock = response.content.find((b) => b.type === \"text\");\n const content = textBlock ? textBlock.text : \"\";\n\n logger.info(`LLM response: ${response.usage.input_tokens} in, ${response.usage.output_tokens} out`);\n\n return {\n content,\n inputTokens: response.usage.input_tokens,\n outputTokens: response.usage.output_tokens,\n };\n}\n\nexport async function chat(\n systemPrompt: string,\n messages: Array<{ role: \"user\" | \"assistant\"; content: string }>,\n): Promise<LLMResponse> {\n const config = loadConfig();\n const model = config.llm?.model ?? \"claude-sonnet-4-20250514\";\n\n const anthropic = getClient();\n const response = await anthropic.messages.create({\n model,\n max_tokens: 1024,\n system: systemPrompt,\n messages,\n });\n\n const textBlock = response.content.find((b) => b.type === \"text\");\n const content = textBlock ? textBlock.text : \"\";\n\n return {\n content,\n inputTokens: response.usage.input_tokens,\n outputTokens: response.usage.output_tokens,\n };\n}\n"],"mappings":";;;;;;;;;;;AAAA,OAAO,eAAe;AACtB,SAAS,cAAc,kBAAkB;AAKzC,IAAI,SAA2B;AAExB,SAAS,eAA8B;AAE5C,MAAI,QAAQ,IAAI,mBAAmB;AACjC,WAAO,QAAQ,IAAI;AAAA,EACrB;AACA,MAAI,WAAW,MAAM,MAAM,GAAG;AAC5B,WAAO,aAAa,MAAM,QAAQ,OAAO,EAAE,KAAK;AAAA,EAClD;AACA,SAAO;AACT;AAEO,SAAS,YAAqB;AACnC,SAAO,aAAa,MAAM;AAC5B;AAEA,SAAS,YAAuB;AAC9B,MAAI,OAAQ,QAAO;AACnB,QAAM,SAAS,aAAa;AAC5B,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI,MAAM,2DAA2D;AAAA,EAC7E;AACA,WAAS,IAAI,UAAU,EAAE,OAAO,CAAC;AACjC,SAAO;AACT;AAQA,eAAsB,iBACpB,cACA,aACsB;AACtB,QAAM,SAAS,WAAW;AAC1B,QAAM,QAAQ,OAAO,KAAK,SAAS;AAEnC,SAAO,KAAK,gBAAgB,KAAK,MAAM;AAEvC,QAAM,YAAY,UAAU;AAC5B,QAAM,WAAW,MAAM,UAAU,SAAS,OAAO;AAAA,IAC/C;AAAA,IACA,YAAY;AAAA,IACZ,QAAQ;AAAA,IACR,UAAU,CAAC,EAAE,MAAM,QAAQ,SAAS,YAAY,CAAC;AAAA,EACnD,CAAC;AAED,QAAM,YAAY,SAAS,QAAQ,KAAK,CAAC,MAAM,EAAE,SAAS,MAAM;AAChE,QAAM,UAAU,YAAY,UAAU,OAAO;AAE7C,SAAO,KAAK,iBAAiB,SAAS,MAAM,YAAY,QAAQ,SAAS,MAAM,aAAa,MAAM;AAElG,SAAO;AAAA,IACL;AAAA,IACA,aAAa,SAAS,MAAM;AAAA,IAC5B,cAAc,SAAS,MAAM;AAAA,EAC/B;AACF;AAEA,eAAsB,KACpB,cACA,UACsB;AACtB,QAAM,SAAS,WAAW;AAC1B,QAAM,QAAQ,OAAO,KAAK,SAAS;AAEnC,QAAM,YAAY,UAAU;AAC5B,QAAM,WAAW,MAAM,UAAU,SAAS,OAAO;AAAA,IAC/C;AAAA,IACA,YAAY;AAAA,IACZ,QAAQ;AAAA,IACR;AAAA,EACF,CAAC;AAED,QAAM,YAAY,SAAS,QAAQ,KAAK,CAAC,MAAM,EAAE,SAAS,MAAM;AAChE,QAAM,UAAU,YAAY,UAAU,OAAO;AAE7C,SAAO;AAAA,IACL;AAAA,IACA,aAAa,SAAS,MAAM;AAAA,IAC5B,cAAc,SAAS,MAAM;AAAA,EAC/B;AACF;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/utils/config.ts"],"sourcesContent":["import { readFileSync, writeFileSync, existsSync } from \"node:fs\";\nimport { z } from \"zod\";\nimport { paths, ensureDirectories } from \"./paths.js\";\n\nexport const ConfigSchema = z.object({\n version: z.literal(1),\n xMethod: z.enum([\"api\", \"browser\"]),\n xApiTier: z.enum([\"free\", \"basic\"]).optional(),\n\n credits: z.object({\n monthlyPostLimit: z.number(),\n postsUsedThisMonth: z.number(),\n resetDate: z.string(),\n }),\n\n schedule: z.object({\n postsPerDay: z.number(),\n activeHoursStart: z.number().min(0).max(23),\n activeHoursEnd: z.number().min(0).max(23),\n timezone: z.string(),\n }),\n\n llm: z.object({\n provider: z.enum([\"anthropic\", \"openai\"]).default(\"anthropic\"),\n model: z.string().default(\"claude-sonnet-4-20250514\"),\n }).optional(),\n\n runtime: z.object({\n heartbeatIntervalMs: z.number().default(300_000),\n actionsPerHeartbeat: z.number().default(3),\n enabled: z.boolean().default(false),\n }).optional(),\n\n connection: z.object({\n token: z.string().optional(),\n apiEndpoint: z.string().default(\"https://spora.dev/api/v1\"),\n lastSync: z.string().optional(),\n configVersion: z.number().default(0),\n }).optional(),\n});\n\nexport type Config = z.infer<typeof ConfigSchema>;\n\nexport function loadConfig(): Config {\n if (!existsSync(paths.config)) {\n throw new Error(\"Spora not initialized. Run `spora init` first.\");\n }\n const raw = readFileSync(paths.config, \"utf-8\");\n return ConfigSchema.parse(JSON.parse(raw));\n}\n\nexport function saveConfig(config: Config): void {\n ensureDirectories();\n ConfigSchema.parse(config);\n writeFileSync(paths.config, JSON.stringify(config, null, 2));\n}\n\nexport function createDefaultConfig(overrides: {\n xMethod: \"api\" | \"browser\";\n xApiTier?: \"free\" | \"basic\";\n timezone?: string;\n}): Config {\n const monthlyLimit = overrides.xApiTier === \"basic\" ? 10000 : 500;\n const now = new Date();\n const resetDate = new Date(now.getFullYear(), now.getMonth() + 1, 1).toISOString();\n\n return {\n version: 1,\n xMethod: overrides.xMethod,\n xApiTier: overrides.xApiTier,\n credits: {\n monthlyPostLimit: monthlyLimit,\n postsUsedThisMonth: 0,\n resetDate,\n },\n schedule: {\n postsPerDay: Math.floor(monthlyLimit / 30),\n activeHoursStart: 8,\n activeHoursEnd: 22,\n timezone: overrides.timezone ?? Intl.DateTimeFormat().resolvedOptions().timeZone,\n },\n };\n}\n"],"mappings":";;;;;;AAAA,SAAS,cAAc,eAAe,kBAAkB;AACxD,SAAS,SAAS;AAGX,IAAM,eAAe,EAAE,OAAO;AAAA,EACnC,SAAS,EAAE,QAAQ,CAAC;AAAA,EACpB,SAAS,EAAE,KAAK,CAAC,OAAO,SAAS,CAAC;AAAA,EAClC,UAAU,EAAE,KAAK,CAAC,QAAQ,OAAO,CAAC,EAAE,SAAS;AAAA,EAE7C,SAAS,EAAE,OAAO;AAAA,IAChB,kBAAkB,EAAE,OAAO;AAAA,IAC3B,oBAAoB,EAAE,OAAO;AAAA,IAC7B,WAAW,EAAE,OAAO;AAAA,EACtB,CAAC;AAAA,EAED,UAAU,EAAE,OAAO;AAAA,IACjB,aAAa,EAAE,OAAO;AAAA,IACtB,kBAAkB,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE;AAAA,IAC1C,gBAAgB,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE;AAAA,IACxC,UAAU,EAAE,OAAO;AAAA,EACrB,CAAC;AAAA,EAED,KAAK,EAAE,OAAO;AAAA,IACZ,UAAU,EAAE,KAAK,CAAC,aAAa,QAAQ,CAAC,EAAE,QAAQ,WAAW;AAAA,IAC7D,OAAO,EAAE,OAAO,EAAE,QAAQ,0BAA0B;AAAA,EACtD,CAAC,EAAE,SAAS;AAAA,EAEZ,SAAS,EAAE,OAAO;AAAA,IAChB,qBAAqB,EAAE,OAAO,EAAE,QAAQ,GAAO;AAAA,IAC/C,qBAAqB,EAAE,OAAO,EAAE,QAAQ,CAAC;AAAA,IACzC,SAAS,EAAE,QAAQ,EAAE,QAAQ,KAAK;AAAA,EACpC,CAAC,EAAE,SAAS;AAAA,EAEZ,YAAY,EAAE,OAAO;AAAA,IACnB,OAAO,EAAE,OAAO,EAAE,SAAS;AAAA,IAC3B,aAAa,EAAE,OAAO,EAAE,QAAQ,0BAA0B;AAAA,IAC1D,UAAU,EAAE,OAAO,EAAE,SAAS;AAAA,IAC9B,eAAe,EAAE,OAAO,EAAE,QAAQ,CAAC;AAAA,EACrC,CAAC,EAAE,SAAS;AACd,CAAC;AAIM,SAAS,aAAqB;AACnC,MAAI,CAAC,WAAW,MAAM,MAAM,GAAG;AAC7B,UAAM,IAAI,MAAM,gDAAgD;AAAA,EAClE;AACA,QAAM,MAAM,aAAa,MAAM,QAAQ,OAAO;AAC9C,SAAO,aAAa,MAAM,KAAK,MAAM,GAAG,CAAC;AAC3C;AAEO,SAAS,WAAW,QAAsB;AAC/C,oBAAkB;AAClB,eAAa,MAAM,MAAM;AACzB,gBAAc,MAAM,QAAQ,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAC7D;AAEO,SAAS,oBAAoB,WAIzB;AACT,QAAM,eAAe,UAAU,aAAa,UAAU,MAAQ;AAC9D,QAAM,MAAM,oBAAI,KAAK;AACrB,QAAM,YAAY,IAAI,KAAK,IAAI,YAAY,GAAG,IAAI,SAAS,IAAI,GAAG,CAAC,EAAE,YAAY;AAEjF,SAAO;AAAA,IACL,SAAS;AAAA,IACT,SAAS,UAAU;AAAA,IACnB,UAAU,UAAU;AAAA,IACpB,SAAS;AAAA,MACP,kBAAkB;AAAA,MAClB,oBAAoB;AAAA,MACpB;AAAA,IACF;AAAA,IACA,UAAU;AAAA,MACR,aAAa,KAAK,MAAM,eAAe,EAAE;AAAA,MACzC,kBAAkB;AAAA,MAClB,gBAAgB;AAAA,MAChB,UAAU,UAAU,YAAY,KAAK,eAAe,EAAE,gBAAgB,EAAE;AAAA,IAC1E;AAAA,EACF;AACF;","names":[]}