spora 0.7.0 → 0.7.2
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.
- package/README.md +7 -5
- package/dist/autonomy-DAV7X6QS.js +19 -0
- package/dist/{chunk-53YLFYJF.js → chunk-3RYCUGXE.js} +6 -2
- package/dist/chunk-3RYCUGXE.js.map +1 -0
- package/dist/{chunk-AH7HPXYC.js → chunk-AOQ3WLZV.js} +153 -143
- package/dist/chunk-AOQ3WLZV.js.map +1 -0
- package/dist/chunk-E5NR6HT4.js +29 -0
- package/dist/chunk-E5NR6HT4.js.map +1 -0
- package/dist/{chunk-EBO4F5NU.js → chunk-JBYZ7K56.js} +2 -2
- package/dist/chunk-KWWAIS3C.js +180 -0
- package/dist/chunk-KWWAIS3C.js.map +1 -0
- package/dist/{chunk-UINSD4FT.js → chunk-LXQNVVIY.js} +6 -6
- package/dist/{chunk-UINSD4FT.js.map → chunk-LXQNVVIY.js.map} +1 -1
- package/dist/{chunk-AIEXQCQS.js → chunk-M6YOQVSI.js} +2 -2
- package/dist/{chunk-B6RPMDML.js → chunk-NO3NQN67.js} +16 -6
- package/dist/chunk-NO3NQN67.js.map +1 -0
- package/dist/{chunk-QOKQ5OTU.js → chunk-NPV3OV2K.js} +3 -14
- package/dist/chunk-NPV3OV2K.js.map +1 -0
- package/dist/{chunk-SBQILQCJ.js → chunk-OACD3HGE.js} +7 -7
- package/dist/{chunk-UM57WU5I.js → chunk-P6KZIJYL.js} +2 -2
- package/dist/{chunk-AHXZIGQE.js → chunk-T7L2L7ZL.js} +2 -2
- package/dist/{chunk-ZJZKH7N7.js → chunk-VZBHRUZS.js} +2 -2
- package/dist/chunk-VZBHRUZS.js.map +1 -0
- package/dist/chunk-WIK74GGJ.js +295 -0
- package/dist/chunk-WIK74GGJ.js.map +1 -0
- package/dist/{chunk-YLJVFCT4.js → chunk-WN35MRMF.js} +2 -2
- package/dist/cli.js +173 -138
- package/dist/cli.js.map +1 -1
- package/dist/client-57BQKVYF.js +337 -0
- package/dist/client-57BQKVYF.js.map +1 -0
- package/dist/{colony-LCWN5IAN.js → colony-JPZC3R34.js} +7 -7
- package/dist/{config-TFAFYSIW.js → config-FL4VJVKZ.js} +3 -3
- package/dist/{crypto-FHSQ72NU.js → crypto-NOXNL4GP.js} +3 -3
- package/dist/{goals-5TAPXNR2.js → goals-RBKLMILE.js} +3 -3
- package/dist/{heartbeat-ZHRCEMF5.js → heartbeat-TNEPE3ZP.js} +83 -88
- package/dist/heartbeat-TNEPE3ZP.js.map +1 -0
- package/dist/{identity-O4FLSZKZ.js → identity-VDUW4I2K.js} +3 -3
- package/dist/{init-G3WINLAP.js → init-ISSXETHY.js} +59 -46
- package/dist/init-ISSXETHY.js.map +1 -0
- package/dist/llm-T33QTPVW.js +22 -0
- package/dist/mcp-server.js +28 -28
- package/dist/mcp-server.js.map +1 -1
- package/dist/{memory-O3AJIKBX.js → memory-OIAH33G2.js} +3 -3
- package/dist/{memory-7FBE26K3.js → memory-PNW7SX7A.js} +3 -3
- package/dist/{paths-5GFUUHCZ.js → paths-BYR6MEPR.js} +2 -2
- package/dist/prompt-builder-5NYONN2W.js +23 -0
- package/dist/queue-G5PTE6R6.js +14 -0
- package/dist/{strategy-S45TX766.js → strategy-Z4JSFHSP.js} +3 -3
- package/dist/{web-chat-RQIILEQK.js → web-chat-3HM35XM4.js} +31 -80
- package/dist/web-chat-3HM35XM4.js.map +1 -0
- package/dist/x-client-GY6XSPK6.js +12 -0
- package/package.json +1 -1
- package/dist/account-creator-ZD643X3Z.js +0 -498
- package/dist/account-creator-ZD643X3Z.js.map +0 -1
- package/dist/chunk-535NMUUW.js +0 -96
- package/dist/chunk-535NMUUW.js.map +0 -1
- package/dist/chunk-53YLFYJF.js.map +0 -1
- package/dist/chunk-55XPDJ6P.js +0 -124
- package/dist/chunk-55XPDJ6P.js.map +0 -1
- package/dist/chunk-AH7HPXYC.js.map +0 -1
- package/dist/chunk-B6RPMDML.js.map +0 -1
- package/dist/chunk-E6GMS76S.js +0 -154
- package/dist/chunk-E6GMS76S.js.map +0 -1
- package/dist/chunk-JJZ7T2IZ.js +0 -32
- package/dist/chunk-JJZ7T2IZ.js.map +0 -1
- package/dist/chunk-QOKQ5OTU.js.map +0 -1
- package/dist/chunk-TF2XYGGG.js +0 -249
- package/dist/chunk-TF2XYGGG.js.map +0 -1
- package/dist/chunk-ZJZKH7N7.js.map +0 -1
- package/dist/client-B6NGVRHM.js +0 -381
- package/dist/client-B6NGVRHM.js.map +0 -1
- package/dist/client-DDCS5FJS.js +0 -412
- package/dist/client-DDCS5FJS.js.map +0 -1
- package/dist/decision-engine-DRPIZLHI.js +0 -19
- package/dist/heartbeat-ZHRCEMF5.js.map +0 -1
- package/dist/init-G3WINLAP.js.map +0 -1
- package/dist/llm-3LSNADSR.js +0 -16
- package/dist/prompt-builder-U2J4H7YX.js +0 -24
- package/dist/queue-USY7JXDV.js +0 -14
- package/dist/research-TQLP42BC.js +0 -13
- package/dist/web-chat-RQIILEQK.js.map +0 -1
- package/dist/x-client-TYU5QSLG.js +0 -12
- package/dist/x-client-TYU5QSLG.js.map +0 -1
- /package/dist/{config-TFAFYSIW.js.map → autonomy-DAV7X6QS.js.map} +0 -0
- /package/dist/{chunk-EBO4F5NU.js.map → chunk-JBYZ7K56.js.map} +0 -0
- /package/dist/{chunk-AIEXQCQS.js.map → chunk-M6YOQVSI.js.map} +0 -0
- /package/dist/{chunk-SBQILQCJ.js.map → chunk-OACD3HGE.js.map} +0 -0
- /package/dist/{chunk-UM57WU5I.js.map → chunk-P6KZIJYL.js.map} +0 -0
- /package/dist/{chunk-AHXZIGQE.js.map → chunk-T7L2L7ZL.js.map} +0 -0
- /package/dist/{chunk-YLJVFCT4.js.map → chunk-WN35MRMF.js.map} +0 -0
- /package/dist/{colony-LCWN5IAN.js.map → colony-JPZC3R34.js.map} +0 -0
- /package/dist/{crypto-FHSQ72NU.js.map → config-FL4VJVKZ.js.map} +0 -0
- /package/dist/{decision-engine-DRPIZLHI.js.map → crypto-NOXNL4GP.js.map} +0 -0
- /package/dist/{goals-5TAPXNR2.js.map → goals-RBKLMILE.js.map} +0 -0
- /package/dist/{identity-O4FLSZKZ.js.map → identity-VDUW4I2K.js.map} +0 -0
- /package/dist/{llm-3LSNADSR.js.map → llm-T33QTPVW.js.map} +0 -0
- /package/dist/{memory-7FBE26K3.js.map → memory-OIAH33G2.js.map} +0 -0
- /package/dist/{memory-O3AJIKBX.js.map → memory-PNW7SX7A.js.map} +0 -0
- /package/dist/{paths-5GFUUHCZ.js.map → paths-BYR6MEPR.js.map} +0 -0
- /package/dist/{prompt-builder-U2J4H7YX.js.map → prompt-builder-5NYONN2W.js.map} +0 -0
- /package/dist/{queue-USY7JXDV.js.map → queue-G5PTE6R6.js.map} +0 -0
- /package/dist/{research-TQLP42BC.js.map → strategy-Z4JSFHSP.js.map} +0 -0
- /package/dist/{strategy-S45TX766.js.map → x-client-GY6XSPK6.js.map} +0 -0
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import {
|
|
2
|
+
logger
|
|
3
|
+
} from "./chunk-NPV3OV2K.js";
|
|
4
|
+
import {
|
|
5
|
+
loadConfig
|
|
6
|
+
} from "./chunk-NO3NQN67.js";
|
|
7
|
+
import {
|
|
8
|
+
paths
|
|
9
|
+
} from "./chunk-3RYCUGXE.js";
|
|
10
|
+
|
|
11
|
+
// src/runtime/llm.ts
|
|
12
|
+
import Anthropic from "@anthropic-ai/sdk";
|
|
13
|
+
import OpenAI from "openai";
|
|
14
|
+
import { existsSync, readFileSync, writeFileSync } from "fs";
|
|
15
|
+
var DEFAULT_MODEL_BY_PROVIDER = {
|
|
16
|
+
anthropic: "claude-sonnet-4-20250514",
|
|
17
|
+
openai: "gpt-4o-mini",
|
|
18
|
+
deepseek: "deepseek-chat"
|
|
19
|
+
};
|
|
20
|
+
var anthropicClient = null;
|
|
21
|
+
var openaiClient = null;
|
|
22
|
+
var deepseekClient = null;
|
|
23
|
+
function getConfiguredProvider() {
|
|
24
|
+
const config = loadConfig();
|
|
25
|
+
return config.llm?.provider ?? "deepseek";
|
|
26
|
+
}
|
|
27
|
+
function loadStoredKeys() {
|
|
28
|
+
if (!existsSync(paths.llmKeys)) {
|
|
29
|
+
return {};
|
|
30
|
+
}
|
|
31
|
+
try {
|
|
32
|
+
return JSON.parse(readFileSync(paths.llmKeys, "utf-8"));
|
|
33
|
+
} catch {
|
|
34
|
+
return {};
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
function saveStoredKeys(keys) {
|
|
38
|
+
writeFileSync(paths.llmKeys, JSON.stringify(keys, null, 2), { mode: 384 });
|
|
39
|
+
}
|
|
40
|
+
function envKeyForProvider(provider) {
|
|
41
|
+
if (provider === "anthropic") return process.env.ANTHROPIC_API_KEY;
|
|
42
|
+
if (provider === "openai") return process.env.OPENAI_API_KEY;
|
|
43
|
+
return process.env.DEEPSEEK_API_KEY;
|
|
44
|
+
}
|
|
45
|
+
function getLLMApiKey(provider = getConfiguredProvider()) {
|
|
46
|
+
const envKey = envKeyForProvider(provider);
|
|
47
|
+
if (envKey) return envKey;
|
|
48
|
+
const keys = loadStoredKeys();
|
|
49
|
+
const stored = keys[provider];
|
|
50
|
+
if (stored) return stored;
|
|
51
|
+
if (existsSync(paths.llmKey)) {
|
|
52
|
+
const legacy = readFileSync(paths.llmKey, "utf-8").trim();
|
|
53
|
+
return legacy.length > 0 ? legacy : null;
|
|
54
|
+
}
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
function hasLLMKey(provider = getConfiguredProvider()) {
|
|
58
|
+
return getLLMApiKey(provider) !== null;
|
|
59
|
+
}
|
|
60
|
+
function setLLMApiKey(provider, apiKey) {
|
|
61
|
+
const keys = loadStoredKeys();
|
|
62
|
+
keys[provider] = apiKey;
|
|
63
|
+
saveStoredKeys(keys);
|
|
64
|
+
}
|
|
65
|
+
function listLLMKeyStatus() {
|
|
66
|
+
return {
|
|
67
|
+
anthropic: hasLLMKey("anthropic"),
|
|
68
|
+
openai: hasLLMKey("openai"),
|
|
69
|
+
deepseek: hasLLMKey("deepseek")
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
function getDefaultModel(provider) {
|
|
73
|
+
return DEFAULT_MODEL_BY_PROVIDER[provider];
|
|
74
|
+
}
|
|
75
|
+
function getAnthropicClient() {
|
|
76
|
+
if (anthropicClient) return anthropicClient;
|
|
77
|
+
const apiKey = getLLMApiKey("anthropic");
|
|
78
|
+
if (!apiKey) {
|
|
79
|
+
throw new Error("No Anthropic API key configured. Run `spora llm set --provider anthropic`.");
|
|
80
|
+
}
|
|
81
|
+
anthropicClient = new Anthropic({ apiKey });
|
|
82
|
+
return anthropicClient;
|
|
83
|
+
}
|
|
84
|
+
function getOpenAIClient() {
|
|
85
|
+
if (openaiClient) return openaiClient;
|
|
86
|
+
const apiKey = getLLMApiKey("openai");
|
|
87
|
+
if (!apiKey) {
|
|
88
|
+
throw new Error("No OpenAI API key configured. Run `spora llm set --provider openai`.");
|
|
89
|
+
}
|
|
90
|
+
openaiClient = new OpenAI({ apiKey });
|
|
91
|
+
return openaiClient;
|
|
92
|
+
}
|
|
93
|
+
function getDeepSeekClient() {
|
|
94
|
+
if (deepseekClient) return deepseekClient;
|
|
95
|
+
const apiKey = getLLMApiKey("deepseek");
|
|
96
|
+
if (!apiKey) {
|
|
97
|
+
throw new Error("No DeepSeek API key configured. Run `spora llm set --provider deepseek`.");
|
|
98
|
+
}
|
|
99
|
+
deepseekClient = new OpenAI({ apiKey, baseURL: "https://api.deepseek.com" });
|
|
100
|
+
return deepseekClient;
|
|
101
|
+
}
|
|
102
|
+
async function generateResponse(systemPrompt, userMessage) {
|
|
103
|
+
return chat(systemPrompt, [{ role: "user", content: userMessage }]);
|
|
104
|
+
}
|
|
105
|
+
async function chat(systemPrompt, messages) {
|
|
106
|
+
const config = loadConfig();
|
|
107
|
+
const provider = config.llm?.provider ?? "deepseek";
|
|
108
|
+
const model = config.llm?.model ?? getDefaultModel(provider);
|
|
109
|
+
if (provider === "anthropic") {
|
|
110
|
+
return callAnthropic(model, systemPrompt, messages);
|
|
111
|
+
}
|
|
112
|
+
if (provider === "openai") {
|
|
113
|
+
return callOpenAI(model, systemPrompt, messages);
|
|
114
|
+
}
|
|
115
|
+
return callDeepSeek(model, systemPrompt, messages);
|
|
116
|
+
}
|
|
117
|
+
async function callAnthropic(model, systemPrompt, messages) {
|
|
118
|
+
logger.info(`Calling Anthropic (${model})...`);
|
|
119
|
+
const anthropic = getAnthropicClient();
|
|
120
|
+
const response = await anthropic.messages.create({
|
|
121
|
+
model,
|
|
122
|
+
max_tokens: 2048,
|
|
123
|
+
system: systemPrompt,
|
|
124
|
+
messages
|
|
125
|
+
});
|
|
126
|
+
const textBlock = response.content.find((b) => b.type === "text");
|
|
127
|
+
const content = textBlock ? textBlock.text : "";
|
|
128
|
+
return {
|
|
129
|
+
content,
|
|
130
|
+
inputTokens: response.usage.input_tokens,
|
|
131
|
+
outputTokens: response.usage.output_tokens
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
async function callOpenAI(model, systemPrompt, messages) {
|
|
135
|
+
logger.info(`Calling OpenAI (${model})...`);
|
|
136
|
+
const client = getOpenAIClient();
|
|
137
|
+
const response = await client.chat.completions.create({
|
|
138
|
+
model,
|
|
139
|
+
max_tokens: 2048,
|
|
140
|
+
messages: [
|
|
141
|
+
{ role: "system", content: systemPrompt },
|
|
142
|
+
...messages
|
|
143
|
+
]
|
|
144
|
+
});
|
|
145
|
+
const content = response.choices[0]?.message?.content ?? "";
|
|
146
|
+
return {
|
|
147
|
+
content,
|
|
148
|
+
inputTokens: response.usage?.prompt_tokens ?? 0,
|
|
149
|
+
outputTokens: response.usage?.completion_tokens ?? 0
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
async function callDeepSeek(model, systemPrompt, messages) {
|
|
153
|
+
logger.info(`Calling DeepSeek (${model})...`);
|
|
154
|
+
const client = getDeepSeekClient();
|
|
155
|
+
const response = await client.chat.completions.create({
|
|
156
|
+
model,
|
|
157
|
+
max_tokens: 2048,
|
|
158
|
+
messages: [
|
|
159
|
+
{ role: "system", content: systemPrompt },
|
|
160
|
+
...messages
|
|
161
|
+
]
|
|
162
|
+
});
|
|
163
|
+
const content = response.choices[0]?.message?.content ?? "";
|
|
164
|
+
return {
|
|
165
|
+
content,
|
|
166
|
+
inputTokens: response.usage?.prompt_tokens ?? 0,
|
|
167
|
+
outputTokens: response.usage?.completion_tokens ?? 0
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
export {
|
|
172
|
+
getLLMApiKey,
|
|
173
|
+
hasLLMKey,
|
|
174
|
+
setLLMApiKey,
|
|
175
|
+
listLLMKeyStatus,
|
|
176
|
+
getDefaultModel,
|
|
177
|
+
generateResponse,
|
|
178
|
+
chat
|
|
179
|
+
};
|
|
180
|
+
//# sourceMappingURL=chunk-KWWAIS3C.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 { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { paths } from \"../utils/paths.js\";\nimport { loadConfig } from \"../utils/config.js\";\nimport { logger } from \"../utils/logger.js\";\n\nexport type LLMProvider = \"anthropic\" | \"openai\" | \"deepseek\";\n\ninterface StoredKeys {\n anthropic?: string;\n openai?: string;\n deepseek?: string;\n}\n\nconst DEFAULT_MODEL_BY_PROVIDER: Record<LLMProvider, string> = {\n anthropic: \"claude-sonnet-4-20250514\",\n openai: \"gpt-4o-mini\",\n deepseek: \"deepseek-chat\",\n};\n\nlet anthropicClient: Anthropic | null = null;\nlet openaiClient: OpenAI | null = null;\nlet deepseekClient: OpenAI | null = null;\n\nfunction getConfiguredProvider(): LLMProvider {\n const config = loadConfig();\n return (config.llm?.provider ?? \"deepseek\") as LLMProvider;\n}\n\nfunction loadStoredKeys(): StoredKeys {\n if (!existsSync(paths.llmKeys)) {\n return {};\n }\n\n try {\n return JSON.parse(readFileSync(paths.llmKeys, \"utf-8\")) as StoredKeys;\n } catch {\n return {};\n }\n}\n\nfunction saveStoredKeys(keys: StoredKeys): void {\n writeFileSync(paths.llmKeys, JSON.stringify(keys, null, 2), { mode: 0o600 });\n}\n\nfunction envKeyForProvider(provider: LLMProvider): string | undefined {\n if (provider === \"anthropic\") return process.env.ANTHROPIC_API_KEY;\n if (provider === \"openai\") return process.env.OPENAI_API_KEY;\n return process.env.DEEPSEEK_API_KEY;\n}\n\nexport function getLLMApiKey(provider: LLMProvider = getConfiguredProvider()): string | null {\n const envKey = envKeyForProvider(provider);\n if (envKey) return envKey;\n\n const keys = loadStoredKeys();\n const stored = keys[provider];\n if (stored) return stored;\n\n // Backward compatibility for old single-key installs.\n if (existsSync(paths.llmKey)) {\n const legacy = readFileSync(paths.llmKey, \"utf-8\").trim();\n return legacy.length > 0 ? legacy : null;\n }\n\n return null;\n}\n\nexport function hasLLMKey(provider: LLMProvider = getConfiguredProvider()): boolean {\n return getLLMApiKey(provider) !== null;\n}\n\nexport function setLLMApiKey(provider: LLMProvider, apiKey: string): void {\n const keys = loadStoredKeys();\n keys[provider] = apiKey;\n saveStoredKeys(keys);\n}\n\nexport function listLLMKeyStatus(): Record<LLMProvider, boolean> {\n return {\n anthropic: hasLLMKey(\"anthropic\"),\n openai: hasLLMKey(\"openai\"),\n deepseek: hasLLMKey(\"deepseek\"),\n };\n}\n\nexport function getDefaultModel(provider: LLMProvider): string {\n return DEFAULT_MODEL_BY_PROVIDER[provider];\n}\n\nfunction getAnthropicClient(): Anthropic {\n if (anthropicClient) return anthropicClient;\n const apiKey = getLLMApiKey(\"anthropic\");\n if (!apiKey) {\n throw new Error(\"No Anthropic API key configured. Run `spora llm set --provider anthropic`.\");\n }\n anthropicClient = new Anthropic({ apiKey });\n return anthropicClient;\n}\n\nfunction getOpenAIClient(): OpenAI {\n if (openaiClient) return openaiClient;\n const apiKey = getLLMApiKey(\"openai\");\n if (!apiKey) {\n throw new Error(\"No OpenAI API key configured. Run `spora llm set --provider openai`.\");\n }\n openaiClient = new OpenAI({ apiKey });\n return openaiClient;\n}\n\nfunction getDeepSeekClient(): OpenAI {\n if (deepseekClient) return deepseekClient;\n const apiKey = getLLMApiKey(\"deepseek\");\n if (!apiKey) {\n throw new Error(\"No DeepSeek API key configured. Run `spora llm set --provider deepseek`.\");\n }\n deepseekClient = new OpenAI({ apiKey, baseURL: \"https://api.deepseek.com\" });\n return deepseekClient;\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 return chat(systemPrompt, [{ role: \"user\", content: userMessage }]);\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 ?? \"deepseek\") as LLMProvider;\n const model = config.llm?.model ?? getDefaultModel(provider);\n\n if (provider === \"anthropic\") {\n return callAnthropic(model, systemPrompt, messages);\n }\n if (provider === \"openai\") {\n return callOpenAI(model, systemPrompt, messages);\n }\n return callDeepSeek(model, systemPrompt, messages);\n}\n\nasync function callAnthropic(\n model: string,\n systemPrompt: string,\n messages: Array<{ role: \"user\" | \"assistant\"; content: string }>,\n): Promise<LLMResponse> {\n logger.info(`Calling Anthropic (${model})...`);\n\n const anthropic = getAnthropicClient();\n const response = await anthropic.messages.create({\n model,\n max_tokens: 2048,\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 callOpenAI(\n model: string,\n systemPrompt: string,\n messages: Array<{ role: \"user\" | \"assistant\"; content: string }>,\n): Promise<LLMResponse> {\n logger.info(`Calling OpenAI (${model})...`);\n\n const client = getOpenAIClient();\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 return {\n content,\n inputTokens: response.usage?.prompt_tokens ?? 0,\n outputTokens: response.usage?.completion_tokens ?? 0,\n };\n}\n\nasync function callDeepSeek(\n model: string,\n systemPrompt: string,\n messages: Array<{ role: \"user\" | \"assistant\"; content: string }>,\n): Promise<LLMResponse> {\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 return {\n content,\n inputTokens: response.usage?.prompt_tokens ?? 0,\n outputTokens: response.usage?.completion_tokens ?? 0,\n };\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
+
import {
|
|
2
|
+
logger
|
|
3
|
+
} from "./chunk-NPV3OV2K.js";
|
|
1
4
|
import {
|
|
2
5
|
loadConfig,
|
|
3
6
|
saveConfig
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import {
|
|
6
|
-
logger
|
|
7
|
-
} from "./chunk-QOKQ5OTU.js";
|
|
7
|
+
} from "./chunk-NO3NQN67.js";
|
|
8
8
|
|
|
9
9
|
// src/x-client/rate-limiter.ts
|
|
10
10
|
var RateLimiter = class {
|
|
@@ -44,7 +44,7 @@ var RateLimiter = class {
|
|
|
44
44
|
const config = loadConfig();
|
|
45
45
|
if (config.xMethod === "api" && config.xApiTier !== "basic") {
|
|
46
46
|
throw new Error(
|
|
47
|
-
`${action} requires X API Basic tier ($200/mo). Current tier: ${config.xApiTier ?? "free"}.
|
|
47
|
+
`${action} requires X API Basic tier ($200/mo). Current tier: ${config.xApiTier ?? "free"}. Upgrade your API tier or adjust runtime behavior.`
|
|
48
48
|
);
|
|
49
49
|
}
|
|
50
50
|
}
|
|
@@ -54,4 +54,4 @@ var rateLimiter = new RateLimiter();
|
|
|
54
54
|
export {
|
|
55
55
|
rateLimiter
|
|
56
56
|
};
|
|
57
|
-
//# sourceMappingURL=chunk-
|
|
57
|
+
//# sourceMappingURL=chunk-LXQNVVIY.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/x-client/rate-limiter.ts"],"sourcesContent":["import { loadConfig, saveConfig } from \"../utils/config.js\";\nimport { logger } from \"../utils/logger.js\";\n\nexport class RateLimiter {\n private checkResetDate(): void {\n const config = loadConfig();\n const now = new Date();\n const resetDate = new Date(config.credits.resetDate);\n\n if (now >= resetDate) {\n config.credits.postsUsedThisMonth = 0;\n const nextReset = new Date(now.getFullYear(), now.getMonth() + 1, 1);\n config.credits.resetDate = nextReset.toISOString();\n saveConfig(config);\n logger.info(\"Monthly credits reset\");\n }\n }\n\n canPost(): boolean {\n this.checkResetDate();\n const config = loadConfig();\n return config.credits.postsUsedThisMonth < config.credits.monthlyPostLimit;\n }\n\n remaining(): number {\n this.checkResetDate();\n const config = loadConfig();\n return config.credits.monthlyPostLimit - config.credits.postsUsedThisMonth;\n }\n\n consume(count: number = 1): void {\n this.checkResetDate();\n const config = loadConfig();\n config.credits.postsUsedThisMonth += count;\n saveConfig(config);\n\n const remaining = config.credits.monthlyPostLimit - config.credits.postsUsedThisMonth;\n if (remaining <= Math.floor(config.credits.monthlyPostLimit * 0.2)) {\n logger.warn(`Low credits: ${remaining} posts remaining this month`);\n }\n }\n\n requireBasicTier(action: string): void {\n const config = loadConfig();\n if (config.xMethod === \"api\" && config.xApiTier !== \"basic\") {\n throw new Error(\n `${action} requires X API Basic tier ($200/mo). ` +\n `Current tier: ${config.xApiTier ?? \"free\"}. ` +\n `
|
|
1
|
+
{"version":3,"sources":["../src/x-client/rate-limiter.ts"],"sourcesContent":["import { loadConfig, saveConfig } from \"../utils/config.js\";\nimport { logger } from \"../utils/logger.js\";\n\nexport class RateLimiter {\n private checkResetDate(): void {\n const config = loadConfig();\n const now = new Date();\n const resetDate = new Date(config.credits.resetDate);\n\n if (now >= resetDate) {\n config.credits.postsUsedThisMonth = 0;\n const nextReset = new Date(now.getFullYear(), now.getMonth() + 1, 1);\n config.credits.resetDate = nextReset.toISOString();\n saveConfig(config);\n logger.info(\"Monthly credits reset\");\n }\n }\n\n canPost(): boolean {\n this.checkResetDate();\n const config = loadConfig();\n return config.credits.postsUsedThisMonth < config.credits.monthlyPostLimit;\n }\n\n remaining(): number {\n this.checkResetDate();\n const config = loadConfig();\n return config.credits.monthlyPostLimit - config.credits.postsUsedThisMonth;\n }\n\n consume(count: number = 1): void {\n this.checkResetDate();\n const config = loadConfig();\n config.credits.postsUsedThisMonth += count;\n saveConfig(config);\n\n const remaining = config.credits.monthlyPostLimit - config.credits.postsUsedThisMonth;\n if (remaining <= Math.floor(config.credits.monthlyPostLimit * 0.2)) {\n logger.warn(`Low credits: ${remaining} posts remaining this month`);\n }\n }\n\n requireBasicTier(action: string): void {\n const config = loadConfig();\n if (config.xMethod === \"api\" && config.xApiTier !== \"basic\") {\n throw new Error(\n `${action} requires X API Basic tier ($200/mo). ` +\n `Current tier: ${config.xApiTier ?? \"free\"}. ` +\n `Upgrade your API tier or adjust runtime behavior.`\n );\n }\n }\n}\n\nexport const rateLimiter = new RateLimiter();\n"],"mappings":";;;;;;;;;AAGO,IAAM,cAAN,MAAkB;AAAA,EACf,iBAAuB;AAC7B,UAAM,SAAS,WAAW;AAC1B,UAAM,MAAM,oBAAI,KAAK;AACrB,UAAM,YAAY,IAAI,KAAK,OAAO,QAAQ,SAAS;AAEnD,QAAI,OAAO,WAAW;AACpB,aAAO,QAAQ,qBAAqB;AACpC,YAAM,YAAY,IAAI,KAAK,IAAI,YAAY,GAAG,IAAI,SAAS,IAAI,GAAG,CAAC;AACnE,aAAO,QAAQ,YAAY,UAAU,YAAY;AACjD,iBAAW,MAAM;AACjB,aAAO,KAAK,uBAAuB;AAAA,IACrC;AAAA,EACF;AAAA,EAEA,UAAmB;AACjB,SAAK,eAAe;AACpB,UAAM,SAAS,WAAW;AAC1B,WAAO,OAAO,QAAQ,qBAAqB,OAAO,QAAQ;AAAA,EAC5D;AAAA,EAEA,YAAoB;AAClB,SAAK,eAAe;AACpB,UAAM,SAAS,WAAW;AAC1B,WAAO,OAAO,QAAQ,mBAAmB,OAAO,QAAQ;AAAA,EAC1D;AAAA,EAEA,QAAQ,QAAgB,GAAS;AAC/B,SAAK,eAAe;AACpB,UAAM,SAAS,WAAW;AAC1B,WAAO,QAAQ,sBAAsB;AACrC,eAAW,MAAM;AAEjB,UAAM,YAAY,OAAO,QAAQ,mBAAmB,OAAO,QAAQ;AACnE,QAAI,aAAa,KAAK,MAAM,OAAO,QAAQ,mBAAmB,GAAG,GAAG;AAClE,aAAO,KAAK,gBAAgB,SAAS,6BAA6B;AAAA,IACpE;AAAA,EACF;AAAA,EAEA,iBAAiB,QAAsB;AACrC,UAAM,SAAS,WAAW;AAC1B,QAAI,OAAO,YAAY,SAAS,OAAO,aAAa,SAAS;AAC3D,YAAM,IAAI;AAAA,QACR,GAAG,MAAM,uDACU,OAAO,YAAY,MAAM;AAAA,MAE9C;AAAA,IACF;AAAA,EACF;AACF;AAEO,IAAM,cAAc,IAAI,YAAY;","names":[]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ensureDirectories,
|
|
3
3
|
paths
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-3RYCUGXE.js";
|
|
5
5
|
|
|
6
6
|
// src/identity/index.ts
|
|
7
7
|
import { readFileSync, writeFileSync, existsSync } from "fs";
|
|
@@ -619,4 +619,4 @@ export {
|
|
|
619
619
|
mutateIdentity,
|
|
620
620
|
renderIdentityDocument
|
|
621
621
|
};
|
|
622
|
-
//# sourceMappingURL=chunk-
|
|
622
|
+
//# sourceMappingURL=chunk-M6YOQVSI.js.map
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ensureDirectories,
|
|
3
3
|
paths
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-3RYCUGXE.js";
|
|
5
5
|
|
|
6
6
|
// src/utils/config.ts
|
|
7
7
|
import { readFileSync, writeFileSync, existsSync } from "fs";
|
|
8
8
|
import { z } from "zod";
|
|
9
9
|
var ConfigSchema = z.object({
|
|
10
10
|
version: z.literal(1),
|
|
11
|
-
xMethod: z.
|
|
11
|
+
xMethod: z.literal("api"),
|
|
12
12
|
xApiTier: z.enum(["free", "basic"]).optional(),
|
|
13
13
|
credits: z.object({
|
|
14
14
|
monthlyPostLimit: z.number(),
|
|
@@ -27,7 +27,7 @@ var ConfigSchema = z.object({
|
|
|
27
27
|
}).optional(),
|
|
28
28
|
runtime: z.object({
|
|
29
29
|
heartbeatIntervalMs: z.number().default(3e5),
|
|
30
|
-
actionsPerHeartbeat: z.number().default(
|
|
30
|
+
actionsPerHeartbeat: z.number().default(4),
|
|
31
31
|
enabled: z.boolean().default(false)
|
|
32
32
|
}).optional(),
|
|
33
33
|
connection: z.object({
|
|
@@ -42,7 +42,17 @@ function loadConfig() {
|
|
|
42
42
|
throw new Error("Spora not initialized. Run `spora init` first.");
|
|
43
43
|
}
|
|
44
44
|
const raw = readFileSync(paths.config, "utf-8");
|
|
45
|
-
|
|
45
|
+
const parsed = JSON.parse(raw);
|
|
46
|
+
if (parsed.xMethod !== "api") {
|
|
47
|
+
parsed.xMethod = "api";
|
|
48
|
+
if (parsed.xApiTier !== "basic" && parsed.xApiTier !== "free") {
|
|
49
|
+
parsed.xApiTier = "basic";
|
|
50
|
+
}
|
|
51
|
+
const migrated = ConfigSchema.parse(parsed);
|
|
52
|
+
saveConfig(migrated);
|
|
53
|
+
return migrated;
|
|
54
|
+
}
|
|
55
|
+
return ConfigSchema.parse(parsed);
|
|
46
56
|
}
|
|
47
57
|
function saveConfig(config) {
|
|
48
58
|
ensureDirectories();
|
|
@@ -55,7 +65,7 @@ function createDefaultConfig(overrides) {
|
|
|
55
65
|
const resetDate = new Date(now.getFullYear(), now.getMonth() + 1, 1).toISOString();
|
|
56
66
|
return {
|
|
57
67
|
version: 1,
|
|
58
|
-
xMethod:
|
|
68
|
+
xMethod: "api",
|
|
59
69
|
xApiTier: overrides.xApiTier,
|
|
60
70
|
credits: {
|
|
61
71
|
monthlyPostLimit: monthlyLimit,
|
|
@@ -77,4 +87,4 @@ export {
|
|
|
77
87
|
saveConfig,
|
|
78
88
|
createDefaultConfig
|
|
79
89
|
};
|
|
80
|
-
//# sourceMappingURL=chunk-
|
|
90
|
+
//# sourceMappingURL=chunk-NO3NQN67.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.literal(\"api\"),\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(\"deepseek\"),\n model: z.string().default(\"deepseek-chat\"),\n }).optional(),\n\n runtime: z.object({\n heartbeatIntervalMs: z.number().default(300_000),\n actionsPerHeartbeat: z.number().default(4),\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 const parsed = JSON.parse(raw) as Record<string, unknown>;\n\n // Backwards compatibility: old configs may still have browser mode.\n if (parsed.xMethod !== \"api\") {\n parsed.xMethod = \"api\";\n if (parsed.xApiTier !== \"basic\" && parsed.xApiTier !== \"free\") {\n parsed.xApiTier = \"basic\";\n }\n const migrated = ConfigSchema.parse(parsed);\n saveConfig(migrated);\n return migrated;\n }\n\n return ConfigSchema.parse(parsed);\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\";\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: \"api\",\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":"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","names":[]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ensureDirectories,
|
|
3
3
|
paths
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-3RYCUGXE.js";
|
|
5
5
|
|
|
6
6
|
// src/utils/logger.ts
|
|
7
7
|
import { appendFileSync } from "fs";
|
|
@@ -15,22 +15,11 @@ var minLevel = "info";
|
|
|
15
15
|
function setLogLevel(level) {
|
|
16
16
|
minLevel = level;
|
|
17
17
|
}
|
|
18
|
-
function serializeData(data) {
|
|
19
|
-
if (data instanceof Error) {
|
|
20
|
-
return data.message;
|
|
21
|
-
}
|
|
22
|
-
try {
|
|
23
|
-
const json = JSON.stringify(data);
|
|
24
|
-
return json === "{}" && data && typeof data === "object" ? String(data) : json;
|
|
25
|
-
} catch {
|
|
26
|
-
return String(data);
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
18
|
function formatMessage(level, message, data) {
|
|
30
19
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
31
20
|
const base = `[${timestamp}] [${level.toUpperCase()}] ${message}`;
|
|
32
21
|
if (data !== void 0) {
|
|
33
|
-
return `${base} ${
|
|
22
|
+
return `${base} ${JSON.stringify(data)}`;
|
|
34
23
|
}
|
|
35
24
|
return base;
|
|
36
25
|
}
|
|
@@ -55,4 +44,4 @@ export {
|
|
|
55
44
|
setLogLevel,
|
|
56
45
|
logger
|
|
57
46
|
};
|
|
58
|
-
//# sourceMappingURL=chunk-
|
|
47
|
+
//# sourceMappingURL=chunk-NPV3OV2K.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils/logger.ts"],"sourcesContent":["import { appendFileSync } from \"node:fs\";\nimport { paths, ensureDirectories } from \"./paths.js\";\n\nexport type LogLevel = \"debug\" | \"info\" | \"warn\" | \"error\";\n\nconst LOG_LEVELS: Record<LogLevel, number> = {\n debug: 0,\n info: 1,\n warn: 2,\n error: 3,\n};\n\nlet minLevel: LogLevel = \"info\";\n\nexport function setLogLevel(level: LogLevel): void {\n minLevel = level;\n}\n\nfunction formatMessage(level: LogLevel, message: string, data?: unknown): string {\n const timestamp = new Date().toISOString();\n const base = `[${timestamp}] [${level.toUpperCase()}] ${message}`;\n if (data !== undefined) {\n return `${base} ${JSON.stringify(data)}`;\n }\n return base;\n}\n\nfunction log(level: LogLevel, message: string, data?: unknown): void {\n if (LOG_LEVELS[level] < LOG_LEVELS[minLevel]) return;\n\n const formatted = formatMessage(level, message, data);\n\n // Always write to stderr (safe for MCP stdio servers)\n process.stderr.write(formatted + \"\\n\");\n\n // Also append to log file\n try {\n ensureDirectories();\n appendFileSync(paths.logFile, formatted + \"\\n\");\n } catch {\n // Silently ignore file write errors\n }\n}\n\nexport const logger = {\n debug: (message: string, data?: unknown) => log(\"debug\", message, data),\n info: (message: string, data?: unknown) => log(\"info\", message, data),\n warn: (message: string, data?: unknown) => log(\"warn\", message, data),\n error: (message: string, data?: unknown) => log(\"error\", message, data),\n};\n"],"mappings":";;;;;;AAAA,SAAS,sBAAsB;AAK/B,IAAM,aAAuC;AAAA,EAC3C,OAAO;AAAA,EACP,MAAM;AAAA,EACN,MAAM;AAAA,EACN,OAAO;AACT;AAEA,IAAI,WAAqB;AAElB,SAAS,YAAY,OAAuB;AACjD,aAAW;AACb;AAEA,SAAS,cAAc,OAAiB,SAAiB,MAAwB;AAC/E,QAAM,aAAY,oBAAI,KAAK,GAAE,YAAY;AACzC,QAAM,OAAO,IAAI,SAAS,MAAM,MAAM,YAAY,CAAC,KAAK,OAAO;AAC/D,MAAI,SAAS,QAAW;AACtB,WAAO,GAAG,IAAI,IAAI,KAAK,UAAU,IAAI,CAAC;AAAA,EACxC;AACA,SAAO;AACT;AAEA,SAAS,IAAI,OAAiB,SAAiB,MAAsB;AACnE,MAAI,WAAW,KAAK,IAAI,WAAW,QAAQ,EAAG;AAE9C,QAAM,YAAY,cAAc,OAAO,SAAS,IAAI;AAGpD,UAAQ,OAAO,MAAM,YAAY,IAAI;AAGrC,MAAI;AACF,sBAAkB;AAClB,mBAAe,MAAM,SAAS,YAAY,IAAI;AAAA,EAChD,QAAQ;AAAA,EAER;AACF;AAEO,IAAM,SAAS;AAAA,EACpB,OAAO,CAAC,SAAiB,SAAmB,IAAI,SAAS,SAAS,IAAI;AAAA,EACtE,MAAM,CAAC,SAAiB,SAAmB,IAAI,QAAQ,SAAS,IAAI;AAAA,EACpE,MAAM,CAAC,SAAiB,SAAmB,IAAI,QAAQ,SAAS,IAAI;AAAA,EACpE,OAAO,CAAC,SAAiB,SAAmB,IAAI,SAAS,SAAS,IAAI;AACxE;","names":[]}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
loadConfig
|
|
3
|
-
} from "./chunk-B6RPMDML.js";
|
|
4
1
|
import {
|
|
5
2
|
logger
|
|
6
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-NPV3OV2K.js";
|
|
4
|
+
import {
|
|
5
|
+
loadConfig
|
|
6
|
+
} from "./chunk-NO3NQN67.js";
|
|
7
7
|
import {
|
|
8
8
|
ensureDirectories,
|
|
9
9
|
paths
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-3RYCUGXE.js";
|
|
11
11
|
|
|
12
12
|
// src/scheduler/queue.ts
|
|
13
13
|
import { readFileSync, writeFileSync, existsSync } from "fs";
|
|
@@ -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-
|
|
70
|
+
const { getXClient } = await import("./x-client-GY6XSPK6.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-
|
|
124
|
+
//# sourceMappingURL=chunk-OACD3HGE.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
paths
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-3RYCUGXE.js";
|
|
4
4
|
|
|
5
5
|
// src/memory/strategy.ts
|
|
6
6
|
import { existsSync, readFileSync, writeFileSync } from "fs";
|
|
@@ -76,4 +76,4 @@ export {
|
|
|
76
76
|
saveStrategy,
|
|
77
77
|
renderStrategyForPrompt
|
|
78
78
|
};
|
|
79
|
-
//# sourceMappingURL=chunk-
|
|
79
|
+
//# sourceMappingURL=chunk-P6KZIJYL.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ensureDirectories,
|
|
3
3
|
paths
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-3RYCUGXE.js";
|
|
5
5
|
|
|
6
6
|
// src/colony/memory.ts
|
|
7
7
|
import { readFileSync, writeFileSync, existsSync } from "fs";
|
|
@@ -153,4 +153,4 @@ export {
|
|
|
153
153
|
getTodayEntries,
|
|
154
154
|
renderColonyBriefing
|
|
155
155
|
};
|
|
156
|
-
//# sourceMappingURL=chunk-
|
|
156
|
+
//# sourceMappingURL=chunk-T7L2L7ZL.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ensureDirectories,
|
|
3
3
|
paths
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-3RYCUGXE.js";
|
|
5
5
|
|
|
6
6
|
// src/utils/crypto.ts
|
|
7
7
|
import { createCipheriv, createDecipheriv, randomBytes, createHash } from "crypto";
|
|
@@ -53,4 +53,4 @@ export {
|
|
|
53
53
|
saveCredentials,
|
|
54
54
|
loadCredentials
|
|
55
55
|
};
|
|
56
|
-
//# sourceMappingURL=chunk-
|
|
56
|
+
//# sourceMappingURL=chunk-VZBHRUZS.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils/crypto.ts"],"sourcesContent":["import { createCipheriv, createDecipheriv, randomBytes, createHash } from \"node:crypto\";\nimport { readFileSync, writeFileSync, existsSync } from \"node:fs\";\nimport { hostname } from \"node:os\";\nimport { paths, ensureDirectories } from \"./paths.js\";\n\nconst ALGORITHM = \"aes-256-gcm\";\n\nfunction deriveKey(): Buffer {\n const machineId = `spora-${hostname()}-${process.env.USER ?? \"default\"}`;\n return createHash(\"sha256\").update(machineId).digest();\n}\n\nexport function encrypt(data: string): string {\n const key = deriveKey();\n const iv = randomBytes(16);\n const cipher = createCipheriv(ALGORITHM, key, iv);\n\n let encrypted = cipher.update(data, \"utf-8\", \"hex\");\n encrypted += cipher.final(\"hex\");\n const authTag = cipher.getAuthTag().toString(\"hex\");\n\n return JSON.stringify({\n iv: iv.toString(\"hex\"),\n encrypted,\n authTag,\n });\n}\n\nexport function decrypt(payload: string): string {\n const key = deriveKey();\n const { iv, encrypted, authTag } = JSON.parse(payload);\n\n const decipher = createDecipheriv(ALGORITHM, key, Buffer.from(iv, \"hex\"));\n decipher.setAuthTag(Buffer.from(authTag, \"hex\"));\n\n let decrypted = decipher.update(encrypted, \"hex\", \"utf-8\");\n decrypted += decipher.final(\"utf-8\");\n\n return decrypted;\n}\n\nexport interface XCredentials {\n method: \"api\";\n apiKey?: string;\n apiSecret?: string;\n accessToken?: string;\n accessTokenSecret?: string;\n bearerToken?: string;\n}\n\nexport function saveCredentials(credentials: XCredentials): void {\n ensureDirectories();\n const encrypted = encrypt(JSON.stringify(credentials));\n writeFileSync(paths.credentials, encrypted);\n}\n\nexport function loadCredentials(): XCredentials {\n if (!existsSync(paths.credentials)) {\n throw new Error(\"No credentials found. Run `spora init` first.\");\n }\n const payload = readFileSync(paths.credentials, \"utf-8\");\n return JSON.parse(decrypt(payload)) as XCredentials;\n}\n"],"mappings":";;;;;;AAAA,SAAS,gBAAgB,kBAAkB,aAAa,kBAAkB;AAC1E,SAAS,cAAc,eAAe,kBAAkB;AACxD,SAAS,gBAAgB;AAGzB,IAAM,YAAY;AAElB,SAAS,YAAoB;AAC3B,QAAM,YAAY,SAAS,SAAS,CAAC,IAAI,QAAQ,IAAI,QAAQ,SAAS;AACtE,SAAO,WAAW,QAAQ,EAAE,OAAO,SAAS,EAAE,OAAO;AACvD;AAEO,SAAS,QAAQ,MAAsB;AAC5C,QAAM,MAAM,UAAU;AACtB,QAAM,KAAK,YAAY,EAAE;AACzB,QAAM,SAAS,eAAe,WAAW,KAAK,EAAE;AAEhD,MAAI,YAAY,OAAO,OAAO,MAAM,SAAS,KAAK;AAClD,eAAa,OAAO,MAAM,KAAK;AAC/B,QAAM,UAAU,OAAO,WAAW,EAAE,SAAS,KAAK;AAElD,SAAO,KAAK,UAAU;AAAA,IACpB,IAAI,GAAG,SAAS,KAAK;AAAA,IACrB;AAAA,IACA;AAAA,EACF,CAAC;AACH;AAEO,SAAS,QAAQ,SAAyB;AAC/C,QAAM,MAAM,UAAU;AACtB,QAAM,EAAE,IAAI,WAAW,QAAQ,IAAI,KAAK,MAAM,OAAO;AAErD,QAAM,WAAW,iBAAiB,WAAW,KAAK,OAAO,KAAK,IAAI,KAAK,CAAC;AACxE,WAAS,WAAW,OAAO,KAAK,SAAS,KAAK,CAAC;AAE/C,MAAI,YAAY,SAAS,OAAO,WAAW,OAAO,OAAO;AACzD,eAAa,SAAS,MAAM,OAAO;AAEnC,SAAO;AACT;AAWO,SAAS,gBAAgB,aAAiC;AAC/D,oBAAkB;AAClB,QAAM,YAAY,QAAQ,KAAK,UAAU,WAAW,CAAC;AACrD,gBAAc,MAAM,aAAa,SAAS;AAC5C;AAEO,SAAS,kBAAgC;AAC9C,MAAI,CAAC,WAAW,MAAM,WAAW,GAAG;AAClC,UAAM,IAAI,MAAM,+CAA+C;AAAA,EACjE;AACA,QAAM,UAAU,aAAa,MAAM,aAAa,OAAO;AACvD,SAAO,KAAK,MAAM,QAAQ,OAAO,CAAC;AACpC;","names":[]}
|