spora 0.2.53 → 0.3.0
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/dist/{account-creator-WYY4YVJP.js → account-creator-SETL5CGT.js} +5 -5
- package/dist/chunk-FCAK5FYQ.js +127 -0
- package/dist/chunk-FCAK5FYQ.js.map +1 -0
- package/dist/{chunk-CIWFFTSP.js → chunk-GJFBWIW3.js} +2 -2
- package/dist/{chunk-7UHJLJNI.js → chunk-HERI4RPY.js} +2 -2
- package/dist/{chunk-E4DZYHGF.js → chunk-J7J557HV.js} +2 -2
- package/dist/{chunk-YF7WWJRO.js → chunk-JWMADEQO.js} +3 -3
- package/dist/chunk-LRKBNKMQ.js +79 -0
- package/dist/chunk-LRKBNKMQ.js.map +1 -0
- package/dist/{chunk-K6FZPWXD.js → chunk-NLWU5432.js} +5 -5
- package/dist/{chunk-VL4UUCMS.js → chunk-POEDIDM6.js} +2 -2
- package/dist/{chunk-5GPXH253.js → chunk-Q7YS3AIK.js} +5 -2
- package/dist/chunk-Q7YS3AIK.js.map +1 -0
- package/dist/{chunk-3NW3VIN5.js → chunk-QHFM2YW6.js} +13 -6
- package/dist/chunk-QHFM2YW6.js.map +1 -0
- package/dist/{chunk-DE772QJH.js → chunk-RNVEWVDN.js} +26 -2
- package/dist/chunk-RNVEWVDN.js.map +1 -0
- package/dist/{chunk-LTAYL5E2.js → chunk-SUFTVQME.js} +5 -5
- package/dist/{chunk-LTAYL5E2.js.map → chunk-SUFTVQME.js.map} +1 -1
- package/dist/{chunk-T3U56JW4.js → chunk-SXMDYUK3.js} +2 -2
- package/dist/{chunk-XJBOOX7N.js → chunk-YZ7RWJ6Z.js} +46 -10
- package/dist/chunk-YZ7RWJ6Z.js.map +1 -0
- package/dist/{chunk-H66LVLSP.js → chunk-ZN63YLI6.js} +144 -26
- package/dist/chunk-ZN63YLI6.js.map +1 -0
- package/dist/cli.js +40 -40
- package/dist/{client-YR2RA56D.js → client-23THPNVL.js} +32 -7
- package/dist/{client-YR2RA56D.js.map → client-23THPNVL.js.map} +1 -1
- package/dist/{client-KXYBQUMD.js → client-NVI3ZD4G.js} +11 -8
- package/dist/{client-KXYBQUMD.js.map → client-NVI3ZD4G.js.map} +1 -1
- package/dist/{colony-4EYP6EPG.js → colony-J4EZQI37.js} +7 -7
- package/dist/{config-BRWV7X4S.js → config-QRBOL4NX.js} +3 -3
- package/dist/{crypto-CK5M4W2X.js → crypto-ZVWJLD2J.js} +3 -3
- package/dist/decision-engine-WBD36PZI.js +19 -0
- package/dist/{heartbeat-QFWU47KI.js → heartbeat-GBT4G4C6.js} +129 -25
- package/dist/heartbeat-GBT4G4C6.js.map +1 -0
- package/dist/{identity-SJ77KTVG.js → identity-LN2R4KJU.js} +3 -3
- package/dist/{image-search-6RGKTFRT.js → image-search-SZVMGWLN.js} +3 -3
- package/dist/{init-FRZDY4MB.js → init-QWOV7F5B.js} +12 -12
- package/dist/llm-MHZG2VHU.js +16 -0
- package/dist/mcp-server.js +24 -24
- package/dist/{memory-ZC3LUAUW.js → memory-J6AYZ5Y2.js} +5 -3
- package/dist/{memory-SYYAGNJ5.js → memory-JMXU3UXR.js} +3 -3
- package/dist/{paths-IL7YUMNP.js → paths-KXOWF2B2.js} +2 -2
- package/dist/performance-7G6R6ELJ.js +18 -0
- package/dist/prompt-builder-IY2SLZ7F.js +25 -0
- package/dist/queue-MLRTMJRE.js +14 -0
- package/dist/strategy-TOVFBIZQ.js +12 -0
- package/dist/strategy-TOVFBIZQ.js.map +1 -0
- package/dist/{web-chat-BX4WCEDD.js → web-chat-2BAWTCGU.js} +108 -29
- package/dist/web-chat-2BAWTCGU.js.map +1 -0
- package/dist/x-client-HUXCQOAW.js +12 -0
- package/dist/x-client-HUXCQOAW.js.map +1 -0
- package/package.json +1 -1
- package/dist/chunk-3NW3VIN5.js.map +0 -1
- package/dist/chunk-5GPXH253.js.map +0 -1
- package/dist/chunk-DE772QJH.js.map +0 -1
- package/dist/chunk-H66LVLSP.js.map +0 -1
- package/dist/chunk-XJBOOX7N.js.map +0 -1
- package/dist/decision-engine-YQDGNP3C.js +0 -18
- package/dist/heartbeat-QFWU47KI.js.map +0 -1
- package/dist/llm-5FY4H7WC.js +0 -16
- package/dist/prompt-builder-V7ZM73TA.js +0 -19
- package/dist/queue-IDNLFXWC.js +0 -14
- package/dist/web-chat-BX4WCEDD.js.map +0 -1
- package/dist/x-client-DFMW2PX7.js +0 -12
- /package/dist/{account-creator-WYY4YVJP.js.map → account-creator-SETL5CGT.js.map} +0 -0
- /package/dist/{chunk-CIWFFTSP.js.map → chunk-GJFBWIW3.js.map} +0 -0
- /package/dist/{chunk-7UHJLJNI.js.map → chunk-HERI4RPY.js.map} +0 -0
- /package/dist/{chunk-E4DZYHGF.js.map → chunk-J7J557HV.js.map} +0 -0
- /package/dist/{chunk-YF7WWJRO.js.map → chunk-JWMADEQO.js.map} +0 -0
- /package/dist/{chunk-K6FZPWXD.js.map → chunk-NLWU5432.js.map} +0 -0
- /package/dist/{chunk-VL4UUCMS.js.map → chunk-POEDIDM6.js.map} +0 -0
- /package/dist/{chunk-T3U56JW4.js.map → chunk-SXMDYUK3.js.map} +0 -0
- /package/dist/{colony-4EYP6EPG.js.map → colony-J4EZQI37.js.map} +0 -0
- /package/dist/{config-BRWV7X4S.js.map → config-QRBOL4NX.js.map} +0 -0
- /package/dist/{crypto-CK5M4W2X.js.map → crypto-ZVWJLD2J.js.map} +0 -0
- /package/dist/{decision-engine-YQDGNP3C.js.map → decision-engine-WBD36PZI.js.map} +0 -0
- /package/dist/{identity-SJ77KTVG.js.map → identity-LN2R4KJU.js.map} +0 -0
- /package/dist/{image-search-6RGKTFRT.js.map → image-search-SZVMGWLN.js.map} +0 -0
- /package/dist/{init-FRZDY4MB.js.map → init-QWOV7F5B.js.map} +0 -0
- /package/dist/{llm-5FY4H7WC.js.map → llm-MHZG2VHU.js.map} +0 -0
- /package/dist/{memory-SYYAGNJ5.js.map → memory-J6AYZ5Y2.js.map} +0 -0
- /package/dist/{memory-ZC3LUAUW.js.map → memory-JMXU3UXR.js.map} +0 -0
- /package/dist/{paths-IL7YUMNP.js.map → paths-KXOWF2B2.js.map} +0 -0
- /package/dist/{prompt-builder-V7ZM73TA.js.map → performance-7G6R6ELJ.js.map} +0 -0
- /package/dist/{queue-IDNLFXWC.js.map → prompt-builder-IY2SLZ7F.js.map} +0 -0
- /package/dist/{x-client-DFMW2PX7.js.map → queue-MLRTMJRE.js.map} +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
logger
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
3
|
+
} from "./chunk-J7J557HV.js";
|
|
4
|
+
import "./chunk-Q7YS3AIK.js";
|
|
5
5
|
|
|
6
6
|
// src/account-creator/x-signup.ts
|
|
7
7
|
import { chromium } from "playwright";
|
|
@@ -71,7 +71,7 @@ async function checkInbox(inboxId, waitMs = 6e4) {
|
|
|
71
71
|
// src/account-creator/x-signup.ts
|
|
72
72
|
async function debugScreenshot(page, step) {
|
|
73
73
|
try {
|
|
74
|
-
const { paths, ensureDirectories } = await import("./paths-
|
|
74
|
+
const { paths, ensureDirectories } = await import("./paths-KXOWF2B2.js");
|
|
75
75
|
ensureDirectories();
|
|
76
76
|
const screenshotPath = `${paths.dataDir}/debug-${step}.png`;
|
|
77
77
|
await page.screenshot({ path: screenshotPath });
|
|
@@ -465,7 +465,7 @@ async function createXAccount(options) {
|
|
|
465
465
|
async function saveSession(context) {
|
|
466
466
|
const storageState = await context.storageState();
|
|
467
467
|
const { writeFileSync } = await import("fs");
|
|
468
|
-
const { paths, ensureDirectories } = await import("./paths-
|
|
468
|
+
const { paths, ensureDirectories } = await import("./paths-KXOWF2B2.js");
|
|
469
469
|
ensureDirectories();
|
|
470
470
|
writeFileSync(paths.browserAuth, JSON.stringify(storageState));
|
|
471
471
|
logger.info("Browser session saved.");
|
|
@@ -495,4 +495,4 @@ async function provisionAccount(options) {
|
|
|
495
495
|
export {
|
|
496
496
|
provisionAccount
|
|
497
497
|
};
|
|
498
|
-
//# sourceMappingURL=account-creator-
|
|
498
|
+
//# sourceMappingURL=account-creator-SETL5CGT.js.map
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import {
|
|
2
|
+
paths
|
|
3
|
+
} from "./chunk-Q7YS3AIK.js";
|
|
4
|
+
|
|
5
|
+
// src/memory/performance.ts
|
|
6
|
+
import { existsSync, readFileSync, writeFileSync } from "fs";
|
|
7
|
+
function loadPerformance() {
|
|
8
|
+
if (!existsSync(paths.performance)) {
|
|
9
|
+
return { trackedPosts: [], selfMetrics: [] };
|
|
10
|
+
}
|
|
11
|
+
try {
|
|
12
|
+
return JSON.parse(readFileSync(paths.performance, "utf-8"));
|
|
13
|
+
} catch {
|
|
14
|
+
return { trackedPosts: [], selfMetrics: [] };
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
function savePerformance(data) {
|
|
18
|
+
writeFileSync(paths.performance, JSON.stringify(data, null, 2));
|
|
19
|
+
}
|
|
20
|
+
function trackPost(tweetId, content, type) {
|
|
21
|
+
const data = loadPerformance();
|
|
22
|
+
if (data.trackedPosts.some((p) => p.tweetId === tweetId)) return;
|
|
23
|
+
data.trackedPosts.push({
|
|
24
|
+
tweetId,
|
|
25
|
+
content,
|
|
26
|
+
type,
|
|
27
|
+
postedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
28
|
+
metrics: [],
|
|
29
|
+
retired: false
|
|
30
|
+
});
|
|
31
|
+
savePerformance(data);
|
|
32
|
+
}
|
|
33
|
+
function getActiveTrackedPosts() {
|
|
34
|
+
const data = loadPerformance();
|
|
35
|
+
return data.trackedPosts.filter((p) => !p.retired);
|
|
36
|
+
}
|
|
37
|
+
function updatePostMetrics(tweetId, metric) {
|
|
38
|
+
const data = loadPerformance();
|
|
39
|
+
const post = data.trackedPosts.find((p) => p.tweetId === tweetId);
|
|
40
|
+
if (!post) return;
|
|
41
|
+
post.metrics.push(metric);
|
|
42
|
+
savePerformance(data);
|
|
43
|
+
}
|
|
44
|
+
function retireOldPosts() {
|
|
45
|
+
const data = loadPerformance();
|
|
46
|
+
const cutoff = Date.now() - 72 * 60 * 60 * 1e3;
|
|
47
|
+
let changed = false;
|
|
48
|
+
for (const post of data.trackedPosts) {
|
|
49
|
+
if (!post.retired && new Date(post.postedAt).getTime() < cutoff) {
|
|
50
|
+
post.retired = true;
|
|
51
|
+
changed = true;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
const pruneCutoff = Date.now() - 30 * 24 * 60 * 60 * 1e3;
|
|
55
|
+
const before = data.trackedPosts.length;
|
|
56
|
+
data.trackedPosts = data.trackedPosts.filter(
|
|
57
|
+
(p) => !p.retired || new Date(p.postedAt).getTime() > pruneCutoff
|
|
58
|
+
);
|
|
59
|
+
if (data.trackedPosts.length !== before) changed = true;
|
|
60
|
+
if (changed) savePerformance(data);
|
|
61
|
+
}
|
|
62
|
+
function updateSelfMetrics(metric) {
|
|
63
|
+
const data = loadPerformance();
|
|
64
|
+
data.selfMetrics.push(metric);
|
|
65
|
+
if (data.selfMetrics.length > 100) {
|
|
66
|
+
data.selfMetrics = data.selfMetrics.slice(-100);
|
|
67
|
+
}
|
|
68
|
+
savePerformance(data);
|
|
69
|
+
}
|
|
70
|
+
function getPerformanceSummary() {
|
|
71
|
+
const data = loadPerformance();
|
|
72
|
+
const lines = [];
|
|
73
|
+
const oneDayAgo = Date.now() - 24 * 60 * 60 * 1e3;
|
|
74
|
+
const recentPosts = data.trackedPosts.filter(
|
|
75
|
+
(p) => new Date(p.postedAt).getTime() > oneDayAgo
|
|
76
|
+
);
|
|
77
|
+
if (recentPosts.length > 0) {
|
|
78
|
+
const postStats = recentPosts.map((p) => {
|
|
79
|
+
const latest = p.metrics.length > 0 ? p.metrics[p.metrics.length - 1] : null;
|
|
80
|
+
return {
|
|
81
|
+
content: p.content,
|
|
82
|
+
type: p.type,
|
|
83
|
+
likes: latest?.likes ?? 0,
|
|
84
|
+
retweets: latest?.retweets ?? 0,
|
|
85
|
+
replies: latest?.replies ?? 0
|
|
86
|
+
};
|
|
87
|
+
});
|
|
88
|
+
const totalLikes = postStats.reduce((s, p) => s + p.likes, 0);
|
|
89
|
+
const totalRTs = postStats.reduce((s, p) => s + p.retweets, 0);
|
|
90
|
+
const avgLikes = Math.round(totalLikes / postStats.length);
|
|
91
|
+
lines.push(`- Last 24h: ${postStats.length} posts, avg ${avgLikes} likes, ${totalRTs} total retweets`);
|
|
92
|
+
const sorted = [...postStats].sort((a, b) => b.likes - a.likes);
|
|
93
|
+
if (sorted.length > 0 && sorted[0].likes > 0) {
|
|
94
|
+
lines.push(`- Best performing: "${sorted[0].content.slice(0, 60)}..." (${sorted[0].likes} likes, ${sorted[0].retweets} RTs)`);
|
|
95
|
+
}
|
|
96
|
+
if (sorted.length > 1) {
|
|
97
|
+
const worst = sorted[sorted.length - 1];
|
|
98
|
+
lines.push(`- Lowest performing: "${worst.content.slice(0, 60)}..." (${worst.likes} likes)`);
|
|
99
|
+
}
|
|
100
|
+
} else {
|
|
101
|
+
lines.push("- No tracked posts in the last 24 hours yet.");
|
|
102
|
+
}
|
|
103
|
+
if (data.selfMetrics.length > 0) {
|
|
104
|
+
const latest = data.selfMetrics[data.selfMetrics.length - 1];
|
|
105
|
+
lines.push(`- Followers: ${latest.followers} | Following: ${latest.following} | Total tweets: ${latest.totalTweets}`);
|
|
106
|
+
const dayAgoMetric = data.selfMetrics.find(
|
|
107
|
+
(m) => Math.abs(new Date(m.checkedAt).getTime() - (Date.now() - 24 * 60 * 60 * 1e3)) < 12 * 60 * 60 * 1e3
|
|
108
|
+
);
|
|
109
|
+
if (dayAgoMetric) {
|
|
110
|
+
const diff = latest.followers - dayAgoMetric.followers;
|
|
111
|
+
if (diff !== 0) {
|
|
112
|
+
lines.push(`- Follower trend: ${diff > 0 ? "+" : ""}${diff} in the last ~24h`);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return lines.length > 0 ? lines.join("\n") : "";
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export {
|
|
120
|
+
trackPost,
|
|
121
|
+
getActiveTrackedPosts,
|
|
122
|
+
updatePostMetrics,
|
|
123
|
+
retireOldPosts,
|
|
124
|
+
updateSelfMetrics,
|
|
125
|
+
getPerformanceSummary
|
|
126
|
+
};
|
|
127
|
+
//# sourceMappingURL=chunk-FCAK5FYQ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/memory/performance.ts"],"sourcesContent":["import { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { paths } from \"../utils/paths.js\";\n\nexport interface EngagementMetric {\n checkedAt: string;\n likes: number;\n retweets: number;\n replies: number;\n}\n\nexport interface TrackedPost {\n tweetId: string;\n content: string;\n type: \"post\" | \"reply\";\n postedAt: string;\n metrics: EngagementMetric[];\n retired: boolean;\n}\n\nexport interface SelfMetric {\n checkedAt: string;\n followers: number;\n following: number;\n totalTweets: number;\n}\n\nexport interface PerformanceData {\n trackedPosts: TrackedPost[];\n selfMetrics: SelfMetric[];\n}\n\nfunction loadPerformance(): PerformanceData {\n if (!existsSync(paths.performance)) {\n return { trackedPosts: [], selfMetrics: [] };\n }\n try {\n return JSON.parse(readFileSync(paths.performance, \"utf-8\"));\n } catch {\n return { trackedPosts: [], selfMetrics: [] };\n }\n}\n\nfunction savePerformance(data: PerformanceData): void {\n writeFileSync(paths.performance, JSON.stringify(data, null, 2));\n}\n\nexport function trackPost(tweetId: string, content: string, type: \"post\" | \"reply\"): void {\n const data = loadPerformance();\n // Don't double-track\n if (data.trackedPosts.some(p => p.tweetId === tweetId)) return;\n data.trackedPosts.push({\n tweetId,\n content,\n type,\n postedAt: new Date().toISOString(),\n metrics: [],\n retired: false,\n });\n savePerformance(data);\n}\n\nexport function getActiveTrackedPosts(): TrackedPost[] {\n const data = loadPerformance();\n return data.trackedPosts.filter(p => !p.retired);\n}\n\nexport function updatePostMetrics(tweetId: string, metric: EngagementMetric): void {\n const data = loadPerformance();\n const post = data.trackedPosts.find(p => p.tweetId === tweetId);\n if (!post) return;\n post.metrics.push(metric);\n savePerformance(data);\n}\n\nexport function retireOldPosts(): void {\n const data = loadPerformance();\n const cutoff = Date.now() - 72 * 60 * 60 * 1000; // 72 hours\n let changed = false;\n for (const post of data.trackedPosts) {\n if (!post.retired && new Date(post.postedAt).getTime() < cutoff) {\n post.retired = true;\n changed = true;\n }\n }\n // Also prune very old retired posts (older than 30 days) to prevent file bloat\n const pruneCutoff = Date.now() - 30 * 24 * 60 * 60 * 1000;\n const before = data.trackedPosts.length;\n data.trackedPosts = data.trackedPosts.filter(\n p => !p.retired || new Date(p.postedAt).getTime() > pruneCutoff\n );\n if (data.trackedPosts.length !== before) changed = true;\n if (changed) savePerformance(data);\n}\n\nexport function updateSelfMetrics(metric: SelfMetric): void {\n const data = loadPerformance();\n data.selfMetrics.push(metric);\n // Keep only last 100 snapshots\n if (data.selfMetrics.length > 100) {\n data.selfMetrics = data.selfMetrics.slice(-100);\n }\n savePerformance(data);\n}\n\nexport function getPerformanceSummary(): string {\n const data = loadPerformance();\n const lines: string[] = [];\n\n // Post performance (last 24h)\n const oneDayAgo = Date.now() - 24 * 60 * 60 * 1000;\n const recentPosts = data.trackedPosts.filter(\n p => new Date(p.postedAt).getTime() > oneDayAgo\n );\n\n if (recentPosts.length > 0) {\n // Get latest metrics for each post\n const postStats = recentPosts.map(p => {\n const latest = p.metrics.length > 0 ? p.metrics[p.metrics.length - 1] : null;\n return {\n content: p.content,\n type: p.type,\n likes: latest?.likes ?? 0,\n retweets: latest?.retweets ?? 0,\n replies: latest?.replies ?? 0,\n };\n });\n\n const totalLikes = postStats.reduce((s, p) => s + p.likes, 0);\n const totalRTs = postStats.reduce((s, p) => s + p.retweets, 0);\n const avgLikes = Math.round(totalLikes / postStats.length);\n\n lines.push(`- Last 24h: ${postStats.length} posts, avg ${avgLikes} likes, ${totalRTs} total retweets`);\n\n // Best and worst performing\n const sorted = [...postStats].sort((a, b) => b.likes - a.likes);\n if (sorted.length > 0 && sorted[0].likes > 0) {\n lines.push(`- Best performing: \"${sorted[0].content.slice(0, 60)}...\" (${sorted[0].likes} likes, ${sorted[0].retweets} RTs)`);\n }\n if (sorted.length > 1) {\n const worst = sorted[sorted.length - 1];\n lines.push(`- Lowest performing: \"${worst.content.slice(0, 60)}...\" (${worst.likes} likes)`);\n }\n } else {\n lines.push(\"- No tracked posts in the last 24 hours yet.\");\n }\n\n // Self metrics\n if (data.selfMetrics.length > 0) {\n const latest = data.selfMetrics[data.selfMetrics.length - 1];\n lines.push(`- Followers: ${latest.followers} | Following: ${latest.following} | Total tweets: ${latest.totalTweets}`);\n\n // Trend: compare to 24h ago\n const dayAgoMetric = data.selfMetrics.find(m =>\n Math.abs(new Date(m.checkedAt).getTime() - (Date.now() - 24 * 60 * 60 * 1000)) < 12 * 60 * 60 * 1000\n );\n if (dayAgoMetric) {\n const diff = latest.followers - dayAgoMetric.followers;\n if (diff !== 0) {\n lines.push(`- Follower trend: ${diff > 0 ? \"+\" : \"\"}${diff} in the last ~24h`);\n }\n }\n }\n\n return lines.length > 0 ? lines.join(\"\\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-Q7YS3AIK.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-GJFBWIW3.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ensureDirectories,
|
|
3
3
|
paths
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-Q7YS3AIK.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-HERI4RPY.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ensureDirectories,
|
|
3
3
|
paths
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-Q7YS3AIK.js";
|
|
5
5
|
|
|
6
6
|
// src/utils/logger.ts
|
|
7
7
|
import { appendFileSync } from "fs";
|
|
@@ -44,4 +44,4 @@ export {
|
|
|
44
44
|
setLogLevel,
|
|
45
45
|
logger
|
|
46
46
|
};
|
|
47
|
-
//# sourceMappingURL=chunk-
|
|
47
|
+
//# sourceMappingURL=chunk-J7J557HV.js.map
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
loadConfig,
|
|
3
3
|
saveConfig
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-SXMDYUK3.js";
|
|
5
5
|
import {
|
|
6
6
|
logger
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-J7J557HV.js";
|
|
8
8
|
|
|
9
9
|
// src/x-client/rate-limiter.ts
|
|
10
10
|
var RateLimiter = class {
|
|
@@ -54,4 +54,4 @@ var rateLimiter = new RateLimiter();
|
|
|
54
54
|
export {
|
|
55
55
|
rateLimiter
|
|
56
56
|
};
|
|
57
|
-
//# sourceMappingURL=chunk-
|
|
57
|
+
//# sourceMappingURL=chunk-JWMADEQO.js.map
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import {
|
|
2
|
+
paths
|
|
3
|
+
} from "./chunk-Q7YS3AIK.js";
|
|
4
|
+
|
|
5
|
+
// src/memory/strategy.ts
|
|
6
|
+
import { existsSync, readFileSync, writeFileSync } from "fs";
|
|
7
|
+
function defaultStrategy() {
|
|
8
|
+
return {
|
|
9
|
+
lastUpdated: (/* @__PURE__ */ new Date()).toISOString(),
|
|
10
|
+
currentFocus: [],
|
|
11
|
+
contentInsights: [],
|
|
12
|
+
peopleToEngage: [],
|
|
13
|
+
experiments: [],
|
|
14
|
+
shortTermGoals: [],
|
|
15
|
+
currentMood: ""
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
function loadStrategy() {
|
|
19
|
+
if (!existsSync(paths.strategy)) {
|
|
20
|
+
return defaultStrategy();
|
|
21
|
+
}
|
|
22
|
+
try {
|
|
23
|
+
return { ...defaultStrategy(), ...JSON.parse(readFileSync(paths.strategy, "utf-8")) };
|
|
24
|
+
} catch {
|
|
25
|
+
return defaultStrategy();
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function saveStrategy(strategy) {
|
|
29
|
+
strategy.contentInsights = strategy.contentInsights.slice(-15);
|
|
30
|
+
strategy.peopleToEngage = strategy.peopleToEngage.slice(-20);
|
|
31
|
+
strategy.experiments = strategy.experiments.slice(-10);
|
|
32
|
+
strategy.shortTermGoals = strategy.shortTermGoals.slice(-5);
|
|
33
|
+
writeFileSync(paths.strategy, JSON.stringify(strategy, null, 2));
|
|
34
|
+
}
|
|
35
|
+
function renderStrategyForPrompt() {
|
|
36
|
+
const s = loadStrategy();
|
|
37
|
+
const lines = [];
|
|
38
|
+
if (s.currentFocus.length > 0) {
|
|
39
|
+
lines.push(`**Focus areas:** ${s.currentFocus.join(", ")}`);
|
|
40
|
+
}
|
|
41
|
+
if (s.contentInsights.length > 0) {
|
|
42
|
+
lines.push("**What's working:**");
|
|
43
|
+
for (const i of s.contentInsights.slice(-5)) {
|
|
44
|
+
lines.push(`- ${i.insight} (${i.confidence} confidence)`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
if (s.peopleToEngage.length > 0) {
|
|
48
|
+
lines.push("**People to engage with:**");
|
|
49
|
+
for (const p of s.peopleToEngage.slice(-5)) {
|
|
50
|
+
lines.push(`- @${p.handle}: ${p.reason} (${p.priority} priority)`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
if (s.experiments.length > 0) {
|
|
54
|
+
const pending = s.experiments.filter((e) => e.status === "pending");
|
|
55
|
+
if (pending.length > 0) {
|
|
56
|
+
lines.push("**Experiments to try:**");
|
|
57
|
+
for (const e of pending.slice(-3)) {
|
|
58
|
+
lines.push(`- ${e.description}`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
if (s.shortTermGoals.length > 0) {
|
|
63
|
+
lines.push("**Short-term goals:**");
|
|
64
|
+
for (const g of s.shortTermGoals) {
|
|
65
|
+
lines.push(`- ${g}`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
if (s.currentMood) {
|
|
69
|
+
lines.push(`**Current energy:** ${s.currentMood}`);
|
|
70
|
+
}
|
|
71
|
+
return lines.length > 0 ? lines.join("\n") : "";
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export {
|
|
75
|
+
loadStrategy,
|
|
76
|
+
saveStrategy,
|
|
77
|
+
renderStrategyForPrompt
|
|
78
|
+
};
|
|
79
|
+
//# sourceMappingURL=chunk-LRKBNKMQ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/memory/strategy.ts"],"sourcesContent":["import { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { paths } from \"../utils/paths.js\";\n\nexport interface ContentInsight {\n insight: string;\n confidence: \"low\" | \"medium\" | \"high\";\n}\n\nexport interface PersonOfInterest {\n handle: string;\n reason: string;\n priority: \"high\" | \"medium\" | \"low\";\n}\n\nexport interface Experiment {\n description: string;\n status: \"pending\" | \"tried\" | \"successful\" | \"failed\";\n result?: string;\n}\n\nexport interface Strategy {\n lastUpdated: string;\n currentFocus: string[];\n contentInsights: ContentInsight[];\n peopleToEngage: PersonOfInterest[];\n experiments: Experiment[];\n shortTermGoals: string[];\n currentMood: string;\n}\n\nfunction defaultStrategy(): Strategy {\n return {\n lastUpdated: new Date().toISOString(),\n currentFocus: [],\n contentInsights: [],\n peopleToEngage: [],\n experiments: [],\n shortTermGoals: [],\n currentMood: \"\",\n };\n}\n\nexport function loadStrategy(): Strategy {\n if (!existsSync(paths.strategy)) {\n return defaultStrategy();\n }\n try {\n return { ...defaultStrategy(), ...JSON.parse(readFileSync(paths.strategy, \"utf-8\")) };\n } catch {\n return defaultStrategy();\n }\n}\n\nexport function saveStrategy(strategy: Strategy): void {\n // Keep arrays bounded to prevent bloat\n strategy.contentInsights = strategy.contentInsights.slice(-15);\n strategy.peopleToEngage = strategy.peopleToEngage.slice(-20);\n strategy.experiments = strategy.experiments.slice(-10);\n strategy.shortTermGoals = strategy.shortTermGoals.slice(-5);\n writeFileSync(paths.strategy, JSON.stringify(strategy, null, 2));\n}\n\nexport function renderStrategyForPrompt(): string {\n const s = loadStrategy();\n const lines: string[] = [];\n\n if (s.currentFocus.length > 0) {\n lines.push(`**Focus areas:** ${s.currentFocus.join(\", \")}`);\n }\n\n if (s.contentInsights.length > 0) {\n lines.push(\"**What's working:**\");\n for (const i of s.contentInsights.slice(-5)) {\n lines.push(`- ${i.insight} (${i.confidence} confidence)`);\n }\n }\n\n if (s.peopleToEngage.length > 0) {\n lines.push(\"**People to engage with:**\");\n for (const p of s.peopleToEngage.slice(-5)) {\n lines.push(`- @${p.handle}: ${p.reason} (${p.priority} priority)`);\n }\n }\n\n if (s.experiments.length > 0) {\n const pending = s.experiments.filter(e => e.status === \"pending\");\n if (pending.length > 0) {\n lines.push(\"**Experiments to try:**\");\n for (const e of pending.slice(-3)) {\n lines.push(`- ${e.description}`);\n }\n }\n }\n\n if (s.shortTermGoals.length > 0) {\n lines.push(\"**Short-term goals:**\");\n for (const g of s.shortTermGoals) {\n lines.push(`- ${g}`);\n }\n }\n\n if (s.currentMood) {\n lines.push(`**Current energy:** ${s.currentMood}`);\n }\n\n return lines.length > 0 ? lines.join(\"\\n\") : \"\";\n}\n"],"mappings":";;;;;AAAA,SAAS,YAAY,cAAc,qBAAqB;AA8BxD,SAAS,kBAA4B;AACnC,SAAO;AAAA,IACL,cAAa,oBAAI,KAAK,GAAE,YAAY;AAAA,IACpC,cAAc,CAAC;AAAA,IACf,iBAAiB,CAAC;AAAA,IAClB,gBAAgB,CAAC;AAAA,IACjB,aAAa,CAAC;AAAA,IACd,gBAAgB,CAAC;AAAA,IACjB,aAAa;AAAA,EACf;AACF;AAEO,SAAS,eAAyB;AACvC,MAAI,CAAC,WAAW,MAAM,QAAQ,GAAG;AAC/B,WAAO,gBAAgB;AAAA,EACzB;AACA,MAAI;AACF,WAAO,EAAE,GAAG,gBAAgB,GAAG,GAAG,KAAK,MAAM,aAAa,MAAM,UAAU,OAAO,CAAC,EAAE;AAAA,EACtF,QAAQ;AACN,WAAO,gBAAgB;AAAA,EACzB;AACF;AAEO,SAAS,aAAa,UAA0B;AAErD,WAAS,kBAAkB,SAAS,gBAAgB,MAAM,GAAG;AAC7D,WAAS,iBAAiB,SAAS,eAAe,MAAM,GAAG;AAC3D,WAAS,cAAc,SAAS,YAAY,MAAM,GAAG;AACrD,WAAS,iBAAiB,SAAS,eAAe,MAAM,EAAE;AAC1D,gBAAc,MAAM,UAAU,KAAK,UAAU,UAAU,MAAM,CAAC,CAAC;AACjE;AAEO,SAAS,0BAAkC;AAChD,QAAM,IAAI,aAAa;AACvB,QAAM,QAAkB,CAAC;AAEzB,MAAI,EAAE,aAAa,SAAS,GAAG;AAC7B,UAAM,KAAK,oBAAoB,EAAE,aAAa,KAAK,IAAI,CAAC,EAAE;AAAA,EAC5D;AAEA,MAAI,EAAE,gBAAgB,SAAS,GAAG;AAChC,UAAM,KAAK,qBAAqB;AAChC,eAAW,KAAK,EAAE,gBAAgB,MAAM,EAAE,GAAG;AAC3C,YAAM,KAAK,KAAK,EAAE,OAAO,KAAK,EAAE,UAAU,cAAc;AAAA,IAC1D;AAAA,EACF;AAEA,MAAI,EAAE,eAAe,SAAS,GAAG;AAC/B,UAAM,KAAK,4BAA4B;AACvC,eAAW,KAAK,EAAE,eAAe,MAAM,EAAE,GAAG;AAC1C,YAAM,KAAK,MAAM,EAAE,MAAM,KAAK,EAAE,MAAM,KAAK,EAAE,QAAQ,YAAY;AAAA,IACnE;AAAA,EACF;AAEA,MAAI,EAAE,YAAY,SAAS,GAAG;AAC5B,UAAM,UAAU,EAAE,YAAY,OAAO,OAAK,EAAE,WAAW,SAAS;AAChE,QAAI,QAAQ,SAAS,GAAG;AACtB,YAAM,KAAK,yBAAyB;AACpC,iBAAW,KAAK,QAAQ,MAAM,EAAE,GAAG;AACjC,cAAM,KAAK,KAAK,EAAE,WAAW,EAAE;AAAA,MACjC;AAAA,IACF;AAAA,EACF;AAEA,MAAI,EAAE,eAAe,SAAS,GAAG;AAC/B,UAAM,KAAK,uBAAuB;AAClC,eAAW,KAAK,EAAE,gBAAgB;AAChC,YAAM,KAAK,KAAK,CAAC,EAAE;AAAA,IACrB;AAAA,EACF;AAEA,MAAI,EAAE,aAAa;AACjB,UAAM,KAAK,uBAAuB,EAAE,WAAW,EAAE;AAAA,EACnD;AAEA,SAAO,MAAM,SAAS,IAAI,MAAM,KAAK,IAAI,IAAI;AAC/C;","names":[]}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
loadConfig
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-SXMDYUK3.js";
|
|
4
4
|
import {
|
|
5
5
|
logger
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-J7J557HV.js";
|
|
7
7
|
|
|
8
8
|
// src/x-client/index.ts
|
|
9
9
|
var clientInstance = null;
|
|
@@ -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-
|
|
14
|
+
const { XApiClient } = await import("./client-23THPNVL.js");
|
|
15
15
|
clientInstance = new XApiClient();
|
|
16
16
|
logger.info("X client initialized: API mode");
|
|
17
17
|
} else {
|
|
18
|
-
const { XBrowserClient } = await import("./client-
|
|
18
|
+
const { XBrowserClient } = await import("./client-NVI3ZD4G.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-
|
|
32
|
+
//# sourceMappingURL=chunk-NLWU5432.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ensureDirectories,
|
|
3
3
|
paths
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-Q7YS3AIK.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-POEDIDM6.js.map
|
|
@@ -26,7 +26,10 @@ var paths = {
|
|
|
26
26
|
runtimePid: join(SPORA_DIR, "runtime.pid"),
|
|
27
27
|
stopSignal: join(SPORA_DIR, "stop"),
|
|
28
28
|
connectionToken: join(SPORA_DIR, "connection-token"),
|
|
29
|
-
lastChatMessage: join(SPORA_DIR, "last-chat-message.json")
|
|
29
|
+
lastChatMessage: join(SPORA_DIR, "last-chat-message.json"),
|
|
30
|
+
performance: join(SPORA_DIR, "memory", "performance.json"),
|
|
31
|
+
strategy: join(SPORA_DIR, "memory", "strategy.json"),
|
|
32
|
+
goals: join(SPORA_DIR, "memory", "goals.json")
|
|
30
33
|
};
|
|
31
34
|
function ensureDirectories() {
|
|
32
35
|
const dirs = [
|
|
@@ -57,4 +60,4 @@ export {
|
|
|
57
60
|
sporaExists,
|
|
58
61
|
hasXCredentials
|
|
59
62
|
};
|
|
60
|
-
//# sourceMappingURL=chunk-
|
|
63
|
+
//# sourceMappingURL=chunk-Q7YS3AIK.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils/paths.ts"],"sourcesContent":["import { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { mkdirSync, existsSync } from \"node:fs\";\n\nconst SPORA_DIR = join(homedir(), \".spora\");\n\nexport const paths = {\n root: SPORA_DIR,\n config: join(SPORA_DIR, \"config.json\"),\n credentials: join(SPORA_DIR, \"credentials.json\"),\n spore: join(SPORA_DIR, \"spore.json\"),\n identity: join(SPORA_DIR, \"identity.json\"),\n colonyToken: join(SPORA_DIR, \"colony-token.json\"),\n browser: join(SPORA_DIR, \"browser\"),\n browserAuth: join(SPORA_DIR, \"browser\", \"auth-state.json\"),\n memory: join(SPORA_DIR, \"memory\"),\n interactions: join(SPORA_DIR, \"memory\", \"interactions\"),\n learnings: join(SPORA_DIR, \"memory\", \"learnings.json\"),\n relationships: join(SPORA_DIR, \"memory\", \"relationships.json\"),\n compacted: join(SPORA_DIR, \"memory\", \"compacted\"),\n queue: join(SPORA_DIR, \"queue\"),\n pendingPosts: join(SPORA_DIR, \"queue\", \"pending-posts.json\"),\n logs: join(SPORA_DIR, \"logs\"),\n logFile: join(SPORA_DIR, \"logs\", \"spora.log\"),\n dataDir: SPORA_DIR,\n llmKey: join(SPORA_DIR, \"llm-key\"),\n runtimePid: join(SPORA_DIR, \"runtime.pid\"),\n stopSignal: join(SPORA_DIR, \"stop\"),\n connectionToken: join(SPORA_DIR, \"connection-token\"),\n lastChatMessage: join(SPORA_DIR, \"last-chat-message.json\"),\n performance: join(SPORA_DIR, \"memory\", \"performance.json\"),\n strategy: join(SPORA_DIR, \"memory\", \"strategy.json\"),\n goals: join(SPORA_DIR, \"memory\", \"goals.json\"),\n} as const;\n\nexport function ensureDirectories(): void {\n const dirs = [\n paths.root,\n paths.browser,\n paths.memory,\n paths.interactions,\n paths.compacted,\n paths.queue,\n paths.logs,\n ];\n\n for (const dir of dirs) {\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n }\n}\n\nexport function sporaExists(): boolean {\n return existsSync(paths.config) && existsSync(paths.identity);\n}\n\nexport function hasXCredentials(): boolean {\n return existsSync(paths.credentials);\n}\n"],"mappings":";AAAA,SAAS,eAAe;AACxB,SAAS,YAAY;AACrB,SAAS,WAAW,kBAAkB;AAEtC,IAAM,YAAY,KAAK,QAAQ,GAAG,QAAQ;AAEnC,IAAM,QAAQ;AAAA,EACnB,MAAM;AAAA,EACN,QAAQ,KAAK,WAAW,aAAa;AAAA,EACrC,aAAa,KAAK,WAAW,kBAAkB;AAAA,EAC/C,OAAO,KAAK,WAAW,YAAY;AAAA,EACnC,UAAU,KAAK,WAAW,eAAe;AAAA,EACzC,aAAa,KAAK,WAAW,mBAAmB;AAAA,EAChD,SAAS,KAAK,WAAW,SAAS;AAAA,EAClC,aAAa,KAAK,WAAW,WAAW,iBAAiB;AAAA,EACzD,QAAQ,KAAK,WAAW,QAAQ;AAAA,EAChC,cAAc,KAAK,WAAW,UAAU,cAAc;AAAA,EACtD,WAAW,KAAK,WAAW,UAAU,gBAAgB;AAAA,EACrD,eAAe,KAAK,WAAW,UAAU,oBAAoB;AAAA,EAC7D,WAAW,KAAK,WAAW,UAAU,WAAW;AAAA,EAChD,OAAO,KAAK,WAAW,OAAO;AAAA,EAC9B,cAAc,KAAK,WAAW,SAAS,oBAAoB;AAAA,EAC3D,MAAM,KAAK,WAAW,MAAM;AAAA,EAC5B,SAAS,KAAK,WAAW,QAAQ,WAAW;AAAA,EAC5C,SAAS;AAAA,EACT,QAAQ,KAAK,WAAW,SAAS;AAAA,EACjC,YAAY,KAAK,WAAW,aAAa;AAAA,EACzC,YAAY,KAAK,WAAW,MAAM;AAAA,EAClC,iBAAiB,KAAK,WAAW,kBAAkB;AAAA,EACnD,iBAAiB,KAAK,WAAW,wBAAwB;AAAA,EACzD,aAAa,KAAK,WAAW,UAAU,kBAAkB;AAAA,EACzD,UAAU,KAAK,WAAW,UAAU,eAAe;AAAA,EACnD,OAAO,KAAK,WAAW,UAAU,YAAY;AAC/C;AAEO,SAAS,oBAA0B;AACxC,QAAM,OAAO;AAAA,IACX,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAEA,aAAW,OAAO,MAAM;AACtB,QAAI,CAAC,WAAW,GAAG,GAAG;AACpB,gBAAU,KAAK,EAAE,WAAW,KAAK,CAAC;AAAA,IACpC;AAAA,EACF;AACF;AAEO,SAAS,cAAuB;AACrC,SAAO,WAAW,MAAM,MAAM,KAAK,WAAW,MAAM,QAAQ;AAC9D;AAEO,SAAS,kBAA2B;AACzC,SAAO,WAAW,MAAM,WAAW;AACrC;","names":[]}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
loadConfig
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-SXMDYUK3.js";
|
|
4
4
|
import {
|
|
5
5
|
logger
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-J7J557HV.js";
|
|
7
7
|
import {
|
|
8
8
|
ensureDirectories,
|
|
9
9
|
paths
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-Q7YS3AIK.js";
|
|
11
11
|
|
|
12
12
|
// src/scheduler/queue.ts
|
|
13
13
|
import { readFileSync, writeFileSync, existsSync } from "fs";
|
|
@@ -68,7 +68,7 @@ async function flushQueue() {
|
|
|
68
68
|
const now = /* @__PURE__ */ new Date();
|
|
69
69
|
let posted = 0;
|
|
70
70
|
let failed = 0;
|
|
71
|
-
const { getXClient } = await import("./x-client-
|
|
71
|
+
const { getXClient } = await import("./x-client-HUXCQOAW.js");
|
|
72
72
|
const client = await getXClient();
|
|
73
73
|
const STALE_THRESHOLD_MS = 5 * 60 * 1e3;
|
|
74
74
|
for (const entry of queue.entries) {
|
|
@@ -86,7 +86,7 @@ async function flushQueue() {
|
|
|
86
86
|
let result;
|
|
87
87
|
if (entry.imageQuery) {
|
|
88
88
|
try {
|
|
89
|
-
const { searchImage, downloadImage } = await import("./image-search-
|
|
89
|
+
const { searchImage, downloadImage } = await import("./image-search-SZVMGWLN.js");
|
|
90
90
|
const imageUrl = await searchImage(entry.imageQuery);
|
|
91
91
|
if (imageUrl) {
|
|
92
92
|
const imageBuffer = await downloadImage(imageUrl);
|
|
@@ -107,6 +107,13 @@ async function flushQueue() {
|
|
|
107
107
|
entry.postedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
108
108
|
posted++;
|
|
109
109
|
if (!entry.imageQuery) logger.info(`Posted: ${entry.id}`);
|
|
110
|
+
if (result.tweetId) {
|
|
111
|
+
try {
|
|
112
|
+
const { trackPost } = await import("./performance-7G6R6ELJ.js");
|
|
113
|
+
trackPost(result.tweetId, entry.content, "post");
|
|
114
|
+
} catch {
|
|
115
|
+
}
|
|
116
|
+
}
|
|
110
117
|
} else {
|
|
111
118
|
entry.status = "failed";
|
|
112
119
|
entry.error = result.error;
|
|
@@ -149,4 +156,4 @@ export {
|
|
|
149
156
|
flushQueue,
|
|
150
157
|
showQueue
|
|
151
158
|
};
|
|
152
|
-
//# sourceMappingURL=chunk-
|
|
159
|
+
//# sourceMappingURL=chunk-QHFM2YW6.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/scheduler/queue.ts"],"sourcesContent":["import { readFileSync, writeFileSync, existsSync } from \"node:fs\";\nimport { paths, ensureDirectories } from \"../utils/paths.js\";\nimport { loadConfig, saveConfig } from \"../utils/config.js\";\nimport { logger } from \"../utils/logger.js\";\n\nexport interface QueueEntry {\n id: string;\n content: string;\n scheduledFor: string;\n status: \"pending\" | \"posted\" | \"failed\" | \"expired\";\n createdAt: string;\n postedAt?: string;\n error?: string;\n imageQuery?: string; // Optional image search query to attach when posting\n}\n\ninterface QueueData {\n entries: QueueEntry[];\n}\n\nfunction loadQueue(): QueueData {\n if (!existsSync(paths.pendingPosts)) {\n return { entries: [] };\n }\n return JSON.parse(readFileSync(paths.pendingPosts, \"utf-8\")) as QueueData;\n}\n\nfunction saveQueue(data: QueueData): void {\n ensureDirectories();\n writeFileSync(paths.pendingPosts, JSON.stringify(data, null, 2));\n}\n\nfunction nextScheduledTime(): string {\n const config = loadConfig();\n const now = new Date();\n const queue = loadQueue();\n\n // Find the latest scheduled time in the queue\n const pendingEntries = queue.entries.filter((e) => e.status === \"pending\");\n let lastScheduled = now;\n\n if (pendingEntries.length > 0) {\n const latest = new Date(\n pendingEntries.reduce((max, e) =>\n new Date(e.scheduledFor) > new Date(max.scheduledFor) ? e : max\n ).scheduledFor\n );\n if (latest > lastScheduled) lastScheduled = latest;\n }\n\n // Add a random interval within the active hours\n const intervalMinutes = Math.floor(\n ((config.schedule.activeHoursEnd - config.schedule.activeHoursStart) * 60) /\n config.schedule.postsPerDay\n );\n\n const next = new Date(lastScheduled.getTime() + intervalMinutes * 60 * 1000);\n\n // Clamp to active hours\n if (next.getHours() >= config.schedule.activeHoursEnd) {\n next.setDate(next.getDate() + 1);\n next.setHours(config.schedule.activeHoursStart, Math.floor(Math.random() * 60), 0, 0);\n }\n if (next.getHours() < config.schedule.activeHoursStart) {\n next.setHours(config.schedule.activeHoursStart, Math.floor(Math.random() * 60), 0, 0);\n }\n\n return next.toISOString();\n}\n\nexport function addToQueue(content: string, scheduledFor?: string, imageQuery?: string): QueueEntry {\n const queue = loadQueue();\n\n const entry: QueueEntry = {\n id: `post-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`,\n content,\n scheduledFor: scheduledFor ?? nextScheduledTime(),\n status: \"pending\",\n createdAt: new Date().toISOString(),\n ...(imageQuery ? { imageQuery } : {}),\n };\n\n queue.entries.push(entry);\n saveQueue(queue);\n\n logger.info(`Post queued: ${entry.id} scheduled for ${entry.scheduledFor}`);\n return entry;\n}\n\nexport async function flushQueue(): Promise<{\n posted: number;\n failed: number;\n remaining: number;\n}> {\n const queue = loadQueue();\n const now = new Date();\n let posted = 0;\n let failed = 0;\n\n const { getXClient } = await import(\"../x-client/index.js\");\n const client = await getXClient();\n\n // Expire stale posts (scheduled more than 5 minutes ago — from previous sessions)\n const STALE_THRESHOLD_MS = 5 * 60 * 1000;\n for (const entry of queue.entries) {\n if (entry.status !== \"pending\") continue;\n const scheduledTime = new Date(entry.scheduledFor).getTime();\n if (scheduledTime < now.getTime() - STALE_THRESHOLD_MS) {\n entry.status = \"expired\";\n logger.info(`Expired stale post: ${entry.id} (was scheduled for ${entry.scheduledFor})`);\n }\n }\n\n for (const entry of queue.entries) {\n if (entry.status !== \"pending\") continue;\n if (new Date(entry.scheduledFor) > now) continue;\n\n try {\n let result;\n\n // If entry has an imageQuery, search and attach image\n if (entry.imageQuery) {\n try {\n const { searchImage, downloadImage } = await import(\"../utils/image-search.js\");\n const imageUrl = await searchImage(entry.imageQuery);\n if (imageUrl) {\n const imageBuffer = await downloadImage(imageUrl);\n result = await client.postTweetWithMedia(entry.content, imageBuffer);\n if (result.success) {\n logger.info(`Posted with image: ${entry.id}`);\n }\n }\n } catch (imgErr) {\n logger.warn(`Image attach failed for ${entry.id}, posting text only: ${(imgErr as Error).message}`);\n }\n }\n\n // Fall back to text-only if no image or image failed\n if (!result) {\n result = await client.postTweet(entry.content);\n }\n\n if (result.success) {\n entry.status = \"posted\";\n entry.postedAt = new Date().toISOString();\n posted++;\n if (!entry.imageQuery) logger.info(`Posted: ${entry.id}`);\n // Track for performance monitoring\n if (result.tweetId) {\n try {\n const { trackPost } = await import(\"../memory/performance.js\");\n trackPost(result.tweetId, entry.content, \"post\");\n } catch { /* non-critical */ }\n }\n } else {\n entry.status = \"failed\";\n entry.error = result.error;\n failed++;\n logger.warn(`Failed to post: ${entry.id} - ${result.error}`);\n }\n } catch (error) {\n entry.status = \"failed\";\n entry.error = (error as Error).message;\n failed++;\n }\n\n // Small delay between posts to avoid rate limits\n await new Promise((resolve) => setTimeout(resolve, 2000));\n }\n\n saveQueue(queue);\n\n const remaining = queue.entries.filter((e) => e.status === \"pending\").length;\n return { posted, failed, remaining };\n}\n\nexport function showQueue(): void {\n const queue = loadQueue();\n const pending = queue.entries.filter((e) => e.status === \"pending\");\n\n if (pending.length === 0) {\n console.log(\"Queue is empty.\");\n return;\n }\n\n console.log(`\\n${pending.length} posts queued:\\n`);\n for (const entry of pending.sort(\n (a, b) => new Date(a.scheduledFor).getTime() - new Date(b.scheduledFor).getTime()\n )) {\n const time = new Date(entry.scheduledFor).toLocaleString();\n const preview = entry.content.length > 60 ? entry.content.slice(0, 60) + \"...\" : entry.content;\n console.log(` [${time}] ${preview}`);\n }\n console.log();\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-Q7YS3AIK.js";
|
|
5
5
|
|
|
6
6
|
// src/memory/index.ts
|
|
7
7
|
import { readFileSync, writeFileSync, appendFileSync, existsSync, readdirSync } from "fs";
|
|
@@ -66,6 +66,29 @@ function saveRelationships(data) {
|
|
|
66
66
|
ensureDirectories();
|
|
67
67
|
writeFileSync(paths.relationships, JSON.stringify(data, null, 2));
|
|
68
68
|
}
|
|
69
|
+
function getActiveConversations(hours = 24) {
|
|
70
|
+
const cutoff = new Date(Date.now() - hours * 60 * 60 * 1e3);
|
|
71
|
+
const recent = getRecentInteractions(50);
|
|
72
|
+
const conversations = [];
|
|
73
|
+
const seenHandles = /* @__PURE__ */ new Set();
|
|
74
|
+
for (const entry of recent) {
|
|
75
|
+
if (entry.type !== "mention_received") continue;
|
|
76
|
+
if (!entry.targetHandle || !entry.content) continue;
|
|
77
|
+
if (new Date(entry.timestamp) < cutoff) continue;
|
|
78
|
+
if (seenHandles.has(entry.targetHandle)) continue;
|
|
79
|
+
seenHandles.add(entry.targetHandle);
|
|
80
|
+
const timeDiff = Date.now() - new Date(entry.timestamp).getTime();
|
|
81
|
+
const minutesAgo = Math.floor(timeDiff / 6e4);
|
|
82
|
+
const timeAgo = minutesAgo < 60 ? `${minutesAgo}m ago` : `${Math.floor(minutesAgo / 60)}h ago`;
|
|
83
|
+
conversations.push({
|
|
84
|
+
handle: entry.targetHandle,
|
|
85
|
+
content: entry.content.slice(0, 100),
|
|
86
|
+
timeAgo,
|
|
87
|
+
tweetId: entry.tweetId
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
return conversations;
|
|
91
|
+
}
|
|
69
92
|
function updateRelationship(userId, update) {
|
|
70
93
|
const data = loadRelationships();
|
|
71
94
|
const existing = data.accounts[userId];
|
|
@@ -100,6 +123,7 @@ export {
|
|
|
100
123
|
addLearning,
|
|
101
124
|
loadRelationships,
|
|
102
125
|
saveRelationships,
|
|
126
|
+
getActiveConversations,
|
|
103
127
|
updateRelationship
|
|
104
128
|
};
|
|
105
|
-
//# sourceMappingURL=chunk-
|
|
129
|
+
//# sourceMappingURL=chunk-RNVEWVDN.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/memory/index.ts"],"sourcesContent":["import { readFileSync, writeFileSync, appendFileSync, existsSync, readdirSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { paths, ensureDirectories } from \"../utils/paths.js\";\n\nexport interface InteractionEntry {\n id: string;\n timestamp: string;\n type: \"post\" | \"reply\" | \"like\" | \"retweet\" | \"follow\" | \"mention_received\";\n tweetId?: string;\n targetUserId?: string;\n targetHandle?: string;\n content?: string;\n inReplyTo?: string;\n sentiment?: \"positive\" | \"negative\" | \"neutral\";\n creditsUsed: number;\n success: boolean;\n error?: string;\n}\n\nexport interface Learning {\n id: string;\n timestamp: string;\n content: string;\n source: string;\n tags: string[];\n}\n\nexport interface Relationship {\n handle: string;\n firstSeen: string;\n lastInteraction: string;\n interactionCount: number;\n sentiment: number;\n tags: string[];\n notes: string[];\n isSpore: boolean;\n}\n\nexport interface RelationshipsData {\n accounts: Record<string, Relationship>;\n}\n\nexport interface LearningsData {\n learnings: Learning[];\n}\n\n// --- Interaction Log ---\n\nfunction todayLogPath(): string {\n const date = new Date().toISOString().split(\"T\")[0];\n return join(paths.interactions, `${date}.jsonl`);\n}\n\nexport function logInteraction(entry: InteractionEntry): void {\n ensureDirectories();\n appendFileSync(todayLogPath(), JSON.stringify(entry) + \"\\n\");\n}\n\nexport function getInteractions(date?: string): InteractionEntry[] {\n const targetDate = date ?? new Date().toISOString().split(\"T\")[0];\n const filePath = join(paths.interactions, `${targetDate}.jsonl`);\n\n if (!existsSync(filePath)) return [];\n\n return readFileSync(filePath, \"utf-8\")\n .trim()\n .split(\"\\n\")\n .filter(Boolean)\n .map((line) => JSON.parse(line) as InteractionEntry);\n}\n\nexport function getRecentInteractions(count: number = 20): InteractionEntry[] {\n ensureDirectories();\n const files = readdirSync(paths.interactions)\n .filter((f) => f.endsWith(\".jsonl\"))\n .sort()\n .reverse();\n\n const entries: InteractionEntry[] = [];\n for (const file of files) {\n if (entries.length >= count) break;\n const filePath = join(paths.interactions, file);\n const lines = readFileSync(filePath, \"utf-8\").trim().split(\"\\n\").filter(Boolean);\n for (const line of lines.reverse()) {\n if (entries.length >= count) break;\n entries.push(JSON.parse(line) as InteractionEntry);\n }\n }\n\n return entries;\n}\n\n// --- Learnings ---\n\nexport function loadLearnings(): LearningsData {\n if (!existsSync(paths.learnings)) {\n return { learnings: [] };\n }\n return JSON.parse(readFileSync(paths.learnings, \"utf-8\")) as LearningsData;\n}\n\nexport function saveLearnings(data: LearningsData): void {\n ensureDirectories();\n writeFileSync(paths.learnings, JSON.stringify(data, null, 2));\n}\n\nexport function addLearning(content: string, source: string, tags: string[] = []): void {\n const data = loadLearnings();\n data.learnings.push({\n id: `learn-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,\n timestamp: new Date().toISOString(),\n content,\n source,\n tags,\n });\n saveLearnings(data);\n}\n\n// --- Relationships ---\n\nexport function loadRelationships(): RelationshipsData {\n if (!existsSync(paths.relationships)) {\n return { accounts: {} };\n }\n return JSON.parse(readFileSync(paths.relationships, \"utf-8\")) as RelationshipsData;\n}\n\nexport function saveRelationships(data: RelationshipsData): void {\n ensureDirectories();\n writeFileSync(paths.relationships, JSON.stringify(data, null, 2));\n}\n\nexport interface ActiveConversation {\n handle: string;\n content: string;\n timeAgo: string;\n tweetId?: string;\n}\n\nexport function getActiveConversations(hours: number = 24): ActiveConversation[] {\n const cutoff = new Date(Date.now() - hours * 60 * 60 * 1000);\n const recent = getRecentInteractions(50);\n\n // Find mentions and replies directed at us\n const conversations: ActiveConversation[] = [];\n const seenHandles = new Set<string>();\n\n for (const entry of recent) {\n if (entry.type !== \"mention_received\") continue;\n if (!entry.targetHandle || !entry.content) continue;\n if (new Date(entry.timestamp) < cutoff) continue;\n if (seenHandles.has(entry.targetHandle)) continue;\n seenHandles.add(entry.targetHandle);\n\n const timeDiff = Date.now() - new Date(entry.timestamp).getTime();\n const minutesAgo = Math.floor(timeDiff / 60000);\n const timeAgo = minutesAgo < 60\n ? `${minutesAgo}m ago`\n : `${Math.floor(minutesAgo / 60)}h ago`;\n\n conversations.push({\n handle: entry.targetHandle,\n content: entry.content.slice(0, 100),\n timeAgo,\n tweetId: entry.tweetId,\n });\n }\n\n return conversations;\n}\n\nexport function updateRelationship(\n userId: string,\n update: Partial<Relationship> & { handle: string }\n): void {\n const data = loadRelationships();\n const existing = data.accounts[userId];\n\n if (existing) {\n data.accounts[userId] = {\n ...existing,\n ...update,\n lastInteraction: new Date().toISOString(),\n interactionCount: existing.interactionCount + 1,\n };\n } else {\n data.accounts[userId] = {\n handle: update.handle,\n firstSeen: new Date().toISOString(),\n lastInteraction: new Date().toISOString(),\n interactionCount: 1,\n sentiment: update.sentiment ?? 0,\n tags: update.tags ?? [],\n notes: update.notes ?? [],\n isSpore: update.isSpore ?? false,\n };\n }\n\n saveRelationships(data);\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
loadConfig
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-SXMDYUK3.js";
|
|
4
4
|
import {
|
|
5
5
|
logger
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-J7J557HV.js";
|
|
7
7
|
import {
|
|
8
8
|
paths
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-Q7YS3AIK.js";
|
|
10
10
|
|
|
11
11
|
// src/runtime/llm.ts
|
|
12
12
|
import Anthropic from "@anthropic-ai/sdk";
|
|
@@ -40,7 +40,7 @@ async function generateResponse(systemPrompt, userMessage, options) {
|
|
|
40
40
|
const anthropic = getClient();
|
|
41
41
|
const response = await anthropic.messages.create({
|
|
42
42
|
model,
|
|
43
|
-
max_tokens:
|
|
43
|
+
max_tokens: 2048,
|
|
44
44
|
temperature: options?.temperature ?? 1,
|
|
45
45
|
system: systemPrompt,
|
|
46
46
|
messages: [{ role: "user", content: userMessage }]
|
|
@@ -79,4 +79,4 @@ export {
|
|
|
79
79
|
generateResponse,
|
|
80
80
|
chat
|
|
81
81
|
};
|
|
82
|
-
//# sourceMappingURL=chunk-
|
|
82
|
+
//# sourceMappingURL=chunk-SUFTVQME.js.map
|
|
@@ -1 +1 @@
|
|
|
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 options?: { temperature?: number },\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:
|
|
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 options?: { temperature?: number },\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: 2048,\n temperature: options?.temperature ?? 1.0,\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,aACA,SACsB;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,aAAa,SAAS,eAAe;AAAA,IACrC,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,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ensureDirectories,
|
|
3
3
|
paths
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-Q7YS3AIK.js";
|
|
5
5
|
|
|
6
6
|
// src/utils/config.ts
|
|
7
7
|
import { readFileSync, writeFileSync, existsSync } from "fs";
|
|
@@ -77,4 +77,4 @@ export {
|
|
|
77
77
|
saveConfig,
|
|
78
78
|
createDefaultConfig
|
|
79
79
|
};
|
|
80
|
-
//# sourceMappingURL=chunk-
|
|
80
|
+
//# sourceMappingURL=chunk-SXMDYUK3.js.map
|