spora 0.3.2 → 0.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/package.json +1 -1
  2. package/dist/account-creator-SETL5CGT.js +0 -498
  3. package/dist/account-creator-SETL5CGT.js.map +0 -1
  4. package/dist/chunk-DFSYD45Q.js +0 -665
  5. package/dist/chunk-DFSYD45Q.js.map +0 -1
  6. package/dist/chunk-FCAK5FYQ.js +0 -127
  7. package/dist/chunk-FCAK5FYQ.js.map +0 -1
  8. package/dist/chunk-GJFBWIW3.js +0 -622
  9. package/dist/chunk-GJFBWIW3.js.map +0 -1
  10. package/dist/chunk-HERI4RPY.js +0 -156
  11. package/dist/chunk-HERI4RPY.js.map +0 -1
  12. package/dist/chunk-J7J557HV.js +0 -47
  13. package/dist/chunk-J7J557HV.js.map +0 -1
  14. package/dist/chunk-JWMADEQO.js +0 -57
  15. package/dist/chunk-JWMADEQO.js.map +0 -1
  16. package/dist/chunk-LRKBNKMQ.js +0 -79
  17. package/dist/chunk-LRKBNKMQ.js.map +0 -1
  18. package/dist/chunk-NLWU5432.js +0 -32
  19. package/dist/chunk-NLWU5432.js.map +0 -1
  20. package/dist/chunk-POEDIDM6.js +0 -56
  21. package/dist/chunk-POEDIDM6.js.map +0 -1
  22. package/dist/chunk-Q7YS3AIK.js +0 -63
  23. package/dist/chunk-Q7YS3AIK.js.map +0 -1
  24. package/dist/chunk-QHFM2YW6.js +0 -159
  25. package/dist/chunk-QHFM2YW6.js.map +0 -1
  26. package/dist/chunk-R7PAD4OL.js +0 -44
  27. package/dist/chunk-R7PAD4OL.js.map +0 -1
  28. package/dist/chunk-RNVEWVDN.js +0 -129
  29. package/dist/chunk-RNVEWVDN.js.map +0 -1
  30. package/dist/chunk-SUFTVQME.js +0 -82
  31. package/dist/chunk-SUFTVQME.js.map +0 -1
  32. package/dist/chunk-SXMDYUK3.js +0 -80
  33. package/dist/chunk-SXMDYUK3.js.map +0 -1
  34. package/dist/chunk-YZ7RWJ6Z.js +0 -262
  35. package/dist/chunk-YZ7RWJ6Z.js.map +0 -1
  36. package/dist/cli.js +0 -654
  37. package/dist/cli.js.map +0 -1
  38. package/dist/client-23THPNVL.js +0 -382
  39. package/dist/client-23THPNVL.js.map +0 -1
  40. package/dist/client-NVI3ZD4G.js +0 -411
  41. package/dist/client-NVI3ZD4G.js.map +0 -1
  42. package/dist/colony-J4EZQI37.js +0 -229
  43. package/dist/colony-J4EZQI37.js.map +0 -1
  44. package/dist/config-QRBOL4NX.js +0 -14
  45. package/dist/config-QRBOL4NX.js.map +0 -1
  46. package/dist/crypto-ZVWJLD2J.js +0 -14
  47. package/dist/crypto-ZVWJLD2J.js.map +0 -1
  48. package/dist/decision-engine-WBD36PZI.js +0 -19
  49. package/dist/decision-engine-WBD36PZI.js.map +0 -1
  50. package/dist/goals-IM4AEHS4.js +0 -12
  51. package/dist/goals-IM4AEHS4.js.map +0 -1
  52. package/dist/heartbeat-35HVB5PB.js +0 -317
  53. package/dist/heartbeat-35HVB5PB.js.map +0 -1
  54. package/dist/identity-LN2R4KJU.js +0 -26
  55. package/dist/identity-LN2R4KJU.js.map +0 -1
  56. package/dist/image-search-SZVMGWLN.js +0 -45
  57. package/dist/image-search-SZVMGWLN.js.map +0 -1
  58. package/dist/init-ANGLSI2L.js +0 -403
  59. package/dist/init-ANGLSI2L.js.map +0 -1
  60. package/dist/llm-MHZG2VHU.js +0 -16
  61. package/dist/llm-MHZG2VHU.js.map +0 -1
  62. package/dist/mcp-server.js +0 -773
  63. package/dist/mcp-server.js.map +0 -1
  64. package/dist/memory-J6AYZ5Y2.js +0 -26
  65. package/dist/memory-J6AYZ5Y2.js.map +0 -1
  66. package/dist/memory-JMXU3UXR.js +0 -26
  67. package/dist/memory-JMXU3UXR.js.map +0 -1
  68. package/dist/paths-KXOWF2B2.js +0 -13
  69. package/dist/paths-KXOWF2B2.js.map +0 -1
  70. package/dist/performance-7G6R6ELJ.js +0 -18
  71. package/dist/performance-7G6R6ELJ.js.map +0 -1
  72. package/dist/prompt-builder-NSU4IFPB.js +0 -28
  73. package/dist/prompt-builder-NSU4IFPB.js.map +0 -1
  74. package/dist/queue-MLRTMJRE.js +0 -14
  75. package/dist/queue-MLRTMJRE.js.map +0 -1
  76. package/dist/strategy-TOVFBIZQ.js +0 -12
  77. package/dist/strategy-TOVFBIZQ.js.map +0 -1
  78. package/dist/web-chat/chat.html +0 -1343
  79. package/dist/web-chat/logo.png +0 -0
  80. package/dist/web-chat-N2AYUWT7.js +0 -802
  81. package/dist/web-chat-N2AYUWT7.js.map +0 -1
  82. package/dist/x-client-HUXCQOAW.js +0 -12
  83. package/dist/x-client-HUXCQOAW.js.map +0 -1
@@ -1,229 +0,0 @@
1
- import {
2
- addColonyEntry,
3
- addOrUpdatePlan,
4
- addPlanParticipant,
5
- getActivePlans,
6
- getTodayEntries,
7
- loadColonyMemory,
8
- renderColonyBriefing,
9
- saveColonyMemory
10
- } from "./chunk-HERI4RPY.js";
11
- import {
12
- getXClient
13
- } from "./chunk-NLWU5432.js";
14
- import "./chunk-SXMDYUK3.js";
15
- import {
16
- loadIdentity
17
- } from "./chunk-GJFBWIW3.js";
18
- import {
19
- logger
20
- } from "./chunk-J7J557HV.js";
21
- import "./chunk-Q7YS3AIK.js";
22
-
23
- // src/colony/index.ts
24
- var COLONY_TAG = "#SporaColony";
25
- async function colonyCheckin(message) {
26
- const identity = loadIdentity();
27
- if (!identity.colony.joined) {
28
- return {
29
- posted: false,
30
- message: "Not a Colony member. Join during Spore creation.",
31
- colonyMemory: loadColonyMemory(),
32
- communityFeed: [],
33
- discoveredSpores: []
34
- };
35
- }
36
- const client = await getXClient();
37
- const result = {
38
- posted: false,
39
- colonyMemory: loadColonyMemory(),
40
- communityFeed: [],
41
- discoveredSpores: []
42
- };
43
- try {
44
- const feed = await client.searchTweets(COLONY_TAG, { count: 30 });
45
- result.communityFeed = feed;
46
- const memory = loadColonyMemory();
47
- const sporeHandles = /* @__PURE__ */ new Set();
48
- for (const tweet of feed) {
49
- if (tweet.authorHandle === identity.handle) continue;
50
- sporeHandles.add(tweet.authorHandle);
51
- const text = tweet.text;
52
- if (text.includes("[PLAN]")) {
53
- const planContent = text.replace(COLONY_TAG, "").replace("[PLAN]", "").trim();
54
- const existingPlan = memory.activePlans.find(
55
- (p) => p.proposedBy === tweet.authorHandle && p.description === planContent
56
- );
57
- if (!existingPlan) {
58
- memory.activePlans.push({
59
- id: tweet.id,
60
- proposedBy: tweet.authorHandle,
61
- description: planContent,
62
- proposedAt: tweet.createdAt,
63
- participants: [tweet.authorHandle],
64
- status: "active",
65
- reports: []
66
- });
67
- }
68
- } else if (text.includes("[JOIN:")) {
69
- const planId = text.match(/\[JOIN:([^\]]+)\]/)?.[1];
70
- if (planId) {
71
- const plan = memory.activePlans.find((p) => p.id === planId);
72
- if (plan && !plan.participants.includes(tweet.authorHandle)) {
73
- plan.participants.push(tweet.authorHandle);
74
- }
75
- }
76
- } else if (text.includes("[STATUS]")) {
77
- const statusContent = text.replace(COLONY_TAG, "").replace("[STATUS]", "").trim();
78
- const exists = memory.entries.some(
79
- (e) => e.handle === tweet.authorHandle && e.content === statusContent
80
- );
81
- if (!exists) {
82
- memory.entries.push({
83
- handle: tweet.authorHandle,
84
- content: statusContent,
85
- timestamp: tweet.createdAt,
86
- type: "status"
87
- });
88
- }
89
- } else {
90
- const chatterContent = text.replace(COLONY_TAG, "").trim();
91
- const exists = memory.entries.some(
92
- (e) => e.handle === tweet.authorHandle && e.content === chatterContent
93
- );
94
- if (!exists) {
95
- memory.entries.push({
96
- handle: tweet.authorHandle,
97
- content: chatterContent,
98
- timestamp: tweet.createdAt,
99
- type: "chatter"
100
- });
101
- }
102
- }
103
- }
104
- const cutoff = Date.now() - 48 * 60 * 60 * 1e3;
105
- for (const plan of memory.activePlans) {
106
- if (plan.status === "active" && new Date(plan.proposedAt).getTime() < cutoff) {
107
- plan.status = "expired";
108
- }
109
- }
110
- memory.lastSynced = (/* @__PURE__ */ new Date()).toISOString();
111
- saveColonyMemory(memory);
112
- result.colonyMemory = memory;
113
- result.discoveredSpores = Array.from(sporeHandles);
114
- logger.info(
115
- `Colony sync: ${feed.length} posts, ${result.discoveredSpores.length} Spores, ${memory.activePlans.filter((p) => p.status === "active").length} active plans`
116
- );
117
- } catch (error) {
118
- logger.warn("Failed to read Colony feed", error);
119
- }
120
- if (message) {
121
- try {
122
- const colonyPost = `${COLONY_TAG} ${message}`;
123
- const postResult = await client.postTweet(colonyPost.slice(0, 280));
124
- result.posted = postResult.success;
125
- result.message = postResult.success ? "Posted to Colony successfully" : `Failed: ${postResult.error}`;
126
- } catch (error) {
127
- result.message = `Failed to post: ${error.message}`;
128
- }
129
- }
130
- return result;
131
- }
132
- async function proposePlan(description) {
133
- const identity = loadIdentity();
134
- if (!identity.colony.joined) {
135
- return { success: false, error: "Not a Colony member." };
136
- }
137
- const client = await getXClient();
138
- try {
139
- const postContent = `${COLONY_TAG} [PLAN] ${description}`.slice(0, 280);
140
- const result = await client.postTweet(postContent);
141
- if (result.success && result.tweetId) {
142
- addOrUpdatePlan({
143
- id: result.tweetId,
144
- proposedBy: identity.handle,
145
- description,
146
- proposedAt: (/* @__PURE__ */ new Date()).toISOString(),
147
- participants: [identity.handle],
148
- status: "active",
149
- reports: []
150
- });
151
- return { success: true, planId: result.tweetId };
152
- }
153
- return { success: false, error: result.error };
154
- } catch (error) {
155
- return { success: false, error: error.message };
156
- }
157
- }
158
- async function joinPlan(planId) {
159
- const identity = loadIdentity();
160
- if (!identity.colony.joined) {
161
- return { success: false, error: "Not a Colony member." };
162
- }
163
- const memory = loadColonyMemory();
164
- const plan = memory.activePlans.find((p) => p.id === planId);
165
- if (!plan) {
166
- return { success: false, error: `Plan ${planId} not found.` };
167
- }
168
- if (plan.participants.includes(identity.handle)) {
169
- return { success: false, error: "Already joined this plan." };
170
- }
171
- const client = await getXClient();
172
- try {
173
- const postContent = `${COLONY_TAG} [JOIN:${planId}] I'm in! Joining: ${plan.description}`.slice(0, 280);
174
- const result = await client.postTweet(postContent);
175
- if (result.success) {
176
- addPlanParticipant(planId, identity.handle);
177
- return { success: true };
178
- }
179
- return { success: false, error: result.error };
180
- } catch (error) {
181
- return { success: false, error: error.message };
182
- }
183
- }
184
- async function postStatus(status) {
185
- const identity = loadIdentity();
186
- if (!identity.colony.joined) {
187
- return { success: false, error: "Not a Colony member." };
188
- }
189
- const client = await getXClient();
190
- try {
191
- const postContent = `${COLONY_TAG} [STATUS] ${status}`.slice(0, 280);
192
- const result = await client.postTweet(postContent);
193
- if (result.success) {
194
- addColonyEntry({
195
- handle: identity.handle,
196
- content: status,
197
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
198
- type: "status"
199
- });
200
- return { success: true };
201
- }
202
- return { success: false, error: result.error };
203
- } catch (error) {
204
- return { success: false, error: error.message };
205
- }
206
- }
207
- function getColonyMemory() {
208
- return loadColonyMemory();
209
- }
210
- function getActivePlans2() {
211
- return getActivePlans();
212
- }
213
- function getTodaysActivity() {
214
- return getTodayEntries();
215
- }
216
- function getColonyBriefing() {
217
- return renderColonyBriefing();
218
- }
219
- export {
220
- colonyCheckin,
221
- getActivePlans2 as getActivePlans,
222
- getColonyBriefing,
223
- getColonyMemory,
224
- getTodaysActivity,
225
- joinPlan,
226
- postStatus,
227
- proposePlan
228
- };
229
- //# sourceMappingURL=colony-J4EZQI37.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/colony/index.ts"],"sourcesContent":["import { loadIdentity } from \"../identity/index.js\";\nimport { getXClient } from \"../x-client/index.js\";\nimport { logger } from \"../utils/logger.js\";\nimport {\n loadColonyMemory,\n saveColonyMemory,\n addColonyEntry,\n addOrUpdatePlan,\n addPlanParticipant,\n getRecentEntries,\n getTodayEntries,\n getActivePlans as getActivePlansFromMemory,\n renderColonyBriefing,\n type ColonyMemory,\n type ColonyPlan,\n type ColonyEntry,\n} from \"./memory.js\";\nimport type { Tweet } from \"../x-client/types.js\";\n\n// The Colony is an X Community:\n// https://x.com/i/communities/2018501592421699779\n//\n// Colony memory is a shared, continuously growing state that all Spores read and write.\n// It lives both in the community (as posts) and locally (as a structured cache).\n// When a Spore checks in, it:\n// 1. Reads the community feed to sync colony memory\n// 2. Posts its own status/plans to the community\n// 3. Updates local colony memory cache\n//\n// Memory never resets — it accumulates over time like a real shared consciousness.\n\nconst COLONY_TAG = \"#SporaColony\";\n\n// ========== CHECK-IN ==========\n\nexport interface ColonyCheckinResult {\n posted: boolean;\n message?: string;\n colonyMemory: ColonyMemory;\n communityFeed: Tweet[];\n discoveredSpores: string[];\n}\n\nexport async function colonyCheckin(message?: string): Promise<ColonyCheckinResult> {\n const identity = loadIdentity();\n\n if (!identity.colony.joined) {\n return {\n posted: false,\n message: \"Not a Colony member. Join during Spore creation.\",\n colonyMemory: loadColonyMemory(),\n communityFeed: [],\n discoveredSpores: [],\n };\n }\n\n const client = await getXClient();\n const result: ColonyCheckinResult = {\n posted: false,\n colonyMemory: loadColonyMemory(),\n communityFeed: [],\n discoveredSpores: [],\n };\n\n // Read Colony community feed\n try {\n const feed = await client.searchTweets(COLONY_TAG, { count: 30 });\n result.communityFeed = feed;\n\n const memory = loadColonyMemory();\n const sporeHandles = new Set<string>();\n\n for (const tweet of feed) {\n if (tweet.authorHandle === identity.handle) continue;\n sporeHandles.add(tweet.authorHandle);\n\n const text = tweet.text;\n\n if (text.includes(\"[PLAN]\")) {\n const planContent = text.replace(COLONY_TAG, \"\").replace(\"[PLAN]\", \"\").trim();\n const existingPlan = memory.activePlans.find(\n (p) => p.proposedBy === tweet.authorHandle && p.description === planContent\n );\n if (!existingPlan) {\n memory.activePlans.push({\n id: tweet.id,\n proposedBy: tweet.authorHandle,\n description: planContent,\n proposedAt: tweet.createdAt,\n participants: [tweet.authorHandle],\n status: \"active\",\n reports: [],\n });\n }\n } else if (text.includes(\"[JOIN:\")) {\n const planId = text.match(/\\[JOIN:([^\\]]+)\\]/)?.[1];\n if (planId) {\n const plan = memory.activePlans.find((p) => p.id === planId);\n if (plan && !plan.participants.includes(tweet.authorHandle)) {\n plan.participants.push(tweet.authorHandle);\n }\n }\n } else if (text.includes(\"[STATUS]\")) {\n const statusContent = text.replace(COLONY_TAG, \"\").replace(\"[STATUS]\", \"\").trim();\n const exists = memory.entries.some(\n (e) => e.handle === tweet.authorHandle && e.content === statusContent\n );\n if (!exists) {\n memory.entries.push({\n handle: tweet.authorHandle,\n content: statusContent,\n timestamp: tweet.createdAt,\n type: \"status\",\n });\n }\n } else {\n // General colony chatter\n const chatterContent = text.replace(COLONY_TAG, \"\").trim();\n const exists = memory.entries.some(\n (e) => e.handle === tweet.authorHandle && e.content === chatterContent\n );\n if (!exists) {\n memory.entries.push({\n handle: tweet.authorHandle,\n content: chatterContent,\n timestamp: tweet.createdAt,\n type: \"chatter\",\n });\n }\n }\n }\n\n // Expire old plans (older than 48 hours) but keep them in memory as expired\n const cutoff = Date.now() - 48 * 60 * 60 * 1000;\n for (const plan of memory.activePlans) {\n if (plan.status === \"active\" && new Date(plan.proposedAt).getTime() < cutoff) {\n plan.status = \"expired\";\n }\n }\n\n memory.lastSynced = new Date().toISOString();\n saveColonyMemory(memory);\n\n result.colonyMemory = memory;\n result.discoveredSpores = Array.from(sporeHandles);\n\n logger.info(\n `Colony sync: ${feed.length} posts, ${result.discoveredSpores.length} Spores, ${memory.activePlans.filter((p) => p.status === \"active\").length} active plans`\n );\n } catch (error) {\n logger.warn(\"Failed to read Colony feed\", error);\n }\n\n // Post to Colony if message provided\n if (message) {\n try {\n const colonyPost = `${COLONY_TAG} ${message}`;\n const postResult = await client.postTweet(colonyPost.slice(0, 280));\n result.posted = postResult.success;\n result.message = postResult.success\n ? \"Posted to Colony successfully\"\n : `Failed: ${postResult.error}`;\n } catch (error) {\n result.message = `Failed to post: ${(error as Error).message}`;\n }\n }\n\n return result;\n}\n\n// ========== PLANS ==========\n\nexport async function proposePlan(description: string): Promise<{ success: boolean; planId?: string; error?: string }> {\n const identity = loadIdentity();\n if (!identity.colony.joined) {\n return { success: false, error: \"Not a Colony member.\" };\n }\n\n const client = await getXClient();\n\n try {\n const postContent = `${COLONY_TAG} [PLAN] ${description}`.slice(0, 280);\n const result = await client.postTweet(postContent);\n\n if (result.success && result.tweetId) {\n addOrUpdatePlan({\n id: result.tweetId,\n proposedBy: identity.handle,\n description,\n proposedAt: new Date().toISOString(),\n participants: [identity.handle],\n status: \"active\",\n reports: [],\n });\n\n return { success: true, planId: result.tweetId };\n }\n\n return { success: false, error: result.error };\n } catch (error) {\n return { success: false, error: (error as Error).message };\n }\n}\n\nexport async function joinPlan(planId: string): Promise<{ success: boolean; error?: string }> {\n const identity = loadIdentity();\n if (!identity.colony.joined) {\n return { success: false, error: \"Not a Colony member.\" };\n }\n\n const memory = loadColonyMemory();\n const plan = memory.activePlans.find((p) => p.id === planId);\n if (!plan) {\n return { success: false, error: `Plan ${planId} not found.` };\n }\n\n if (plan.participants.includes(identity.handle)) {\n return { success: false, error: \"Already joined this plan.\" };\n }\n\n const client = await getXClient();\n\n try {\n const postContent = `${COLONY_TAG} [JOIN:${planId}] I'm in! Joining: ${plan.description}`.slice(0, 280);\n const result = await client.postTweet(postContent);\n\n if (result.success) {\n addPlanParticipant(planId, identity.handle);\n return { success: true };\n }\n\n return { success: false, error: result.error };\n } catch (error) {\n return { success: false, error: (error as Error).message };\n }\n}\n\nexport async function postStatus(status: string): Promise<{ success: boolean; error?: string }> {\n const identity = loadIdentity();\n if (!identity.colony.joined) {\n return { success: false, error: \"Not a Colony member.\" };\n }\n\n const client = await getXClient();\n\n try {\n const postContent = `${COLONY_TAG} [STATUS] ${status}`.slice(0, 280);\n const result = await client.postTweet(postContent);\n\n if (result.success) {\n addColonyEntry({\n handle: identity.handle,\n content: status,\n timestamp: new Date().toISOString(),\n type: \"status\",\n });\n return { success: true };\n }\n\n return { success: false, error: result.error };\n } catch (error) {\n return { success: false, error: (error as Error).message };\n }\n}\n\n// ========== READ ==========\n\nexport function getColonyMemory(): ColonyMemory {\n return loadColonyMemory();\n}\n\nexport function getActivePlans(): ColonyPlan[] {\n return getActivePlansFromMemory();\n}\n\nexport function getTodaysActivity(): ColonyEntry[] {\n return getTodayEntries();\n}\n\nexport function getColonyBriefing(): string {\n return renderColonyBriefing();\n}\n"],"mappings":"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","names":["getActivePlans"]}
@@ -1,14 +0,0 @@
1
- import {
2
- ConfigSchema,
3
- createDefaultConfig,
4
- loadConfig,
5
- saveConfig
6
- } from "./chunk-SXMDYUK3.js";
7
- import "./chunk-Q7YS3AIK.js";
8
- export {
9
- ConfigSchema,
10
- createDefaultConfig,
11
- loadConfig,
12
- saveConfig
13
- };
14
- //# sourceMappingURL=config-QRBOL4NX.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -1,14 +0,0 @@
1
- import {
2
- decrypt,
3
- encrypt,
4
- loadCredentials,
5
- saveCredentials
6
- } from "./chunk-POEDIDM6.js";
7
- import "./chunk-Q7YS3AIK.js";
8
- export {
9
- decrypt,
10
- encrypt,
11
- loadCredentials,
12
- saveCredentials
13
- };
14
- //# sourceMappingURL=crypto-ZVWJLD2J.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -1,19 +0,0 @@
1
- import {
2
- executeAction,
3
- executeActions,
4
- parseActions
5
- } from "./chunk-YZ7RWJ6Z.js";
6
- import "./chunk-NLWU5432.js";
7
- import "./chunk-FCAK5FYQ.js";
8
- import "./chunk-QHFM2YW6.js";
9
- import "./chunk-SXMDYUK3.js";
10
- import "./chunk-GJFBWIW3.js";
11
- import "./chunk-J7J557HV.js";
12
- import "./chunk-RNVEWVDN.js";
13
- import "./chunk-Q7YS3AIK.js";
14
- export {
15
- executeAction,
16
- executeActions,
17
- parseActions
18
- };
19
- //# sourceMappingURL=decision-engine-WBD36PZI.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -1,12 +0,0 @@
1
- import {
2
- loadGoals,
3
- renderGoalsForPrompt,
4
- saveGoals
5
- } from "./chunk-R7PAD4OL.js";
6
- import "./chunk-Q7YS3AIK.js";
7
- export {
8
- loadGoals,
9
- renderGoalsForPrompt,
10
- saveGoals
11
- };
12
- //# sourceMappingURL=goals-IM4AEHS4.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -1,317 +0,0 @@
1
- import {
2
- executeActions,
3
- parseActions
4
- } from "./chunk-YZ7RWJ6Z.js";
5
- import {
6
- buildHeartbeatUserMessage,
7
- buildReflectionPrompt,
8
- buildSystemPrompt,
9
- parseReflection
10
- } from "./chunk-DFSYD45Q.js";
11
- import {
12
- generateResponse
13
- } from "./chunk-SUFTVQME.js";
14
- import {
15
- loadStrategy,
16
- saveStrategy
17
- } from "./chunk-LRKBNKMQ.js";
18
- import "./chunk-R7PAD4OL.js";
19
- import "./chunk-JWMADEQO.js";
20
- import {
21
- getXClient
22
- } from "./chunk-NLWU5432.js";
23
- import {
24
- getActiveTrackedPosts,
25
- getPerformanceSummary,
26
- retireOldPosts,
27
- updatePostMetrics,
28
- updateSelfMetrics
29
- } from "./chunk-FCAK5FYQ.js";
30
- import {
31
- flushQueue
32
- } from "./chunk-QHFM2YW6.js";
33
- import {
34
- loadConfig
35
- } from "./chunk-SXMDYUK3.js";
36
- import {
37
- loadIdentity
38
- } from "./chunk-GJFBWIW3.js";
39
- import {
40
- logger
41
- } from "./chunk-J7J557HV.js";
42
- import {
43
- addLearning
44
- } from "./chunk-RNVEWVDN.js";
45
- import {
46
- paths
47
- } from "./chunk-Q7YS3AIK.js";
48
-
49
- // src/runtime/heartbeat.ts
50
- import { existsSync, unlinkSync, writeFileSync, readFileSync } from "fs";
51
- var running = false;
52
- var lastMentionsSinceId;
53
- function isRunning() {
54
- return running;
55
- }
56
- function requestStop() {
57
- writeFileSync(paths.stopSignal, "stop");
58
- logger.info("Stop signal sent.");
59
- }
60
- function shouldStop() {
61
- if (existsSync(paths.stopSignal)) {
62
- unlinkSync(paths.stopSignal);
63
- return true;
64
- }
65
- return false;
66
- }
67
- function writePid() {
68
- writeFileSync(paths.runtimePid, String(process.pid));
69
- }
70
- function clearPid() {
71
- if (existsSync(paths.runtimePid)) {
72
- unlinkSync(paths.runtimePid);
73
- }
74
- }
75
- function getRunningPid() {
76
- if (!existsSync(paths.runtimePid)) return null;
77
- const pid = parseInt(readFileSync(paths.runtimePid, "utf-8").trim(), 10);
78
- if (isNaN(pid)) return null;
79
- try {
80
- process.kill(pid, 0);
81
- return pid;
82
- } catch {
83
- clearPid();
84
- return null;
85
- }
86
- }
87
- async function startHeartbeatLoop() {
88
- const existingPid = getRunningPid();
89
- if (existingPid) {
90
- throw new Error(`Spora is already running (PID ${existingPid}). Run \`spora stop\` first.`);
91
- }
92
- running = true;
93
- writePid();
94
- const config = loadConfig();
95
- const intervalMs = config.runtime?.heartbeatIntervalMs ?? 6e4;
96
- const maxActions = config.runtime?.actionsPerHeartbeat ?? 3;
97
- logger.info(`Spora agent starting. Heartbeat interval: ${intervalMs / 1e3}s, max actions: ${maxActions}`);
98
- console.log(`
99
- Spora agent is running (PID ${process.pid})`);
100
- console.log(`Heartbeat every ${Math.round(intervalMs / 6e4)} minutes`);
101
- console.log(`Press Ctrl+C or run \`spora stop\` to stop.
102
- `);
103
- const shutdown = () => {
104
- logger.info("Shutting down...");
105
- running = false;
106
- clearPid();
107
- process.exit(0);
108
- };
109
- process.on("SIGINT", shutdown);
110
- process.on("SIGTERM", shutdown);
111
- if (existsSync(paths.stopSignal)) {
112
- unlinkSync(paths.stopSignal);
113
- }
114
- let heartbeatCount = 0;
115
- while (running) {
116
- heartbeatCount++;
117
- logger.info(`=== Heartbeat #${heartbeatCount} ===`);
118
- try {
119
- await runHeartbeat(maxActions, intervalMs, heartbeatCount);
120
- } catch (error) {
121
- logger.error("Heartbeat error", error);
122
- console.error(`Heartbeat #${heartbeatCount} failed: ${error.message}`);
123
- }
124
- if (shouldStop()) {
125
- logger.info("Stop signal received.");
126
- break;
127
- }
128
- const jitter = Math.floor(Math.random() * intervalMs * 0.3);
129
- const sleepMs = intervalMs + jitter;
130
- logger.info(`Sleeping ${Math.round(sleepMs / 1e3)}s until next heartbeat...`);
131
- const chunkMs = 1e4;
132
- let slept = 0;
133
- while (slept < sleepMs && running) {
134
- await new Promise((r) => setTimeout(r, Math.min(chunkMs, sleepMs - slept)));
135
- slept += chunkMs;
136
- if (shouldStop()) {
137
- running = false;
138
- break;
139
- }
140
- try {
141
- const flushed = await flushQueue();
142
- if (flushed.posted > 0) {
143
- logger.info(`Flushed ${flushed.posted} scheduled post(s) during sleep`);
144
- }
145
- } catch {
146
- }
147
- }
148
- }
149
- clearPid();
150
- logger.info("Spora agent stopped.");
151
- console.log("\nSpora agent stopped.");
152
- }
153
- async function runHeartbeat(maxActions, intervalMs, heartbeatCount = 1) {
154
- logger.info("Checking queue...");
155
- try {
156
- const flushed = await flushQueue();
157
- if (flushed.posted > 0) {
158
- logger.info(`Flushed ${flushed.posted} queued posts.`);
159
- }
160
- } catch (error) {
161
- logger.warn(`Queue flush failed: ${error.message}`);
162
- }
163
- const client = await getXClient();
164
- let ownHandle;
165
- if ("getAuthenticatedHandle" in client) {
166
- try {
167
- ownHandle = await client.getAuthenticatedHandle();
168
- } catch {
169
- }
170
- }
171
- logger.info("Checking post performance...");
172
- try {
173
- retireOldPosts();
174
- const activePosts = getActiveTrackedPosts();
175
- for (const post of activePosts.slice(0, 5)) {
176
- try {
177
- const tweet = await client.getTweet(post.tweetId);
178
- if (tweet) {
179
- updatePostMetrics(post.tweetId, {
180
- checkedAt: (/* @__PURE__ */ new Date()).toISOString(),
181
- likes: tweet.likeCount ?? 0,
182
- retweets: tweet.retweetCount ?? 0,
183
- replies: tweet.replyCount ?? 0
184
- });
185
- }
186
- } catch {
187
- }
188
- await new Promise((r) => setTimeout(r, 1e3));
189
- }
190
- } catch (error) {
191
- logger.warn(`Performance check failed: ${error.message}`);
192
- }
193
- if (heartbeatCount % 6 === 1) {
194
- logger.info("Checking own profile...");
195
- try {
196
- const handle = ownHandle ?? loadIdentity().handle;
197
- const profile = await client.getProfile(handle);
198
- updateSelfMetrics({
199
- checkedAt: (/* @__PURE__ */ new Date()).toISOString(),
200
- followers: profile.followersCount,
201
- following: profile.followingCount,
202
- totalTweets: profile.tweetCount
203
- });
204
- logger.info(`Self: ${profile.followersCount} followers, ${profile.followingCount} following`);
205
- } catch (error) {
206
- logger.warn(`Self-check failed: ${error.message}`);
207
- }
208
- }
209
- logger.info("Reading timeline and mentions...");
210
- let timeline = [];
211
- let mentions = [];
212
- try {
213
- timeline = await client.getTimeline({ count: 20 });
214
- if (ownHandle) {
215
- timeline = timeline.filter((t) => t.authorHandle.toLowerCase() !== ownHandle.toLowerCase());
216
- }
217
- } catch (error) {
218
- logger.warn(`Timeline read failed: ${error.message}`);
219
- }
220
- try {
221
- mentions = await client.getMentions({ count: 10, sinceId: lastMentionsSinceId });
222
- if (mentions.length > 0) {
223
- lastMentionsSinceId = mentions[0].id;
224
- }
225
- } catch (error) {
226
- logger.warn(`Mentions read failed: ${error.message}`);
227
- }
228
- let discoveryResults = [];
229
- if (heartbeatCount % 4 === 0) {
230
- logger.info("Running proactive discovery...");
231
- try {
232
- const identity = loadIdentity();
233
- const strategy = loadStrategy();
234
- const allTopics = [...identity.topics, ...strategy.currentFocus ?? []];
235
- if (allTopics.length > 0) {
236
- const topic = allTopics[Math.floor(Math.random() * allTopics.length)];
237
- discoveryResults = await client.searchTweets(topic, { count: 10 });
238
- if (ownHandle) {
239
- discoveryResults = discoveryResults.filter((t) => t.authorHandle.toLowerCase() !== ownHandle.toLowerCase());
240
- }
241
- logger.info(`Discovery for "${topic}": ${discoveryResults.length} results`);
242
- }
243
- } catch (error) {
244
- logger.warn(`Discovery failed: ${error.message}`);
245
- }
246
- }
247
- const systemPrompt = buildSystemPrompt();
248
- const userMessage = buildHeartbeatUserMessage(timeline, mentions, intervalMs, discoveryResults);
249
- logger.info("Asking LLM for decisions...");
250
- const response = await generateResponse(systemPrompt, userMessage, { temperature: 0.95 });
251
- const actions = parseActions(response.content);
252
- if (actions.length === 0) {
253
- logger.info("LLM returned no actions.");
254
- return;
255
- }
256
- const validTweetIds = /* @__PURE__ */ new Set();
257
- const tweetMap = /* @__PURE__ */ new Map();
258
- for (const t of timeline) {
259
- validTweetIds.add(t.id);
260
- tweetMap.set(t.id, t);
261
- }
262
- for (const t of mentions) {
263
- validTweetIds.add(t.id);
264
- tweetMap.set(t.id, t);
265
- }
266
- for (const t of discoveryResults) {
267
- validTweetIds.add(t.id);
268
- tweetMap.set(t.id, t);
269
- }
270
- const validatedActions = actions.filter((a) => {
271
- if (a.tweetId) {
272
- const cleanId = a.tweetId.replace(/^tweet:/i, "").trim();
273
- if (!validTweetIds.has(cleanId)) {
274
- logger.warn(`Rejected ${a.action}: tweet ID ${cleanId} not in timeline/mentions (likely hallucinated)`);
275
- return false;
276
- }
277
- }
278
- return true;
279
- });
280
- const limitedActions = validatedActions.slice(0, maxActions);
281
- logger.info(`Executing ${limitedActions.length} action(s)...`);
282
- const results = await executeActions(limitedActions, tweetMap);
283
- for (const result of results) {
284
- if (result.success) {
285
- logger.info(` [OK] ${result.action}${result.detail ? `: ${result.detail}` : ""}`);
286
- } else {
287
- logger.warn(` [FAIL] ${result.action}: ${result.error}`);
288
- }
289
- }
290
- logger.info("Reflecting on actions...");
291
- try {
292
- const perfSummary = getPerformanceSummary();
293
- const currentStrategy = loadStrategy();
294
- const reflectPrompt = buildReflectionPrompt(results, perfSummary, currentStrategy);
295
- const reflection = await generateResponse(systemPrompt, reflectPrompt, { temperature: 0.7 });
296
- const reflectionData = parseReflection(reflection.content);
297
- if (reflectionData.learning) {
298
- addLearning(reflectionData.learning, "reflection", ["auto-reflect"]);
299
- logger.info(`Reflection learning: "${reflectionData.learning.slice(0, 60)}..."`);
300
- }
301
- if (reflectionData.strategyUpdate) {
302
- const updated = { ...currentStrategy, ...reflectionData.strategyUpdate, lastUpdated: (/* @__PURE__ */ new Date()).toISOString() };
303
- saveStrategy(updated);
304
- logger.info("Strategy updated from reflection.");
305
- }
306
- } catch (error) {
307
- logger.warn(`Reflection failed: ${error.message}`);
308
- }
309
- logger.info(`Heartbeat complete. ${results.filter((r) => r.success).length}/${results.length} actions succeeded.`);
310
- }
311
- export {
312
- getRunningPid,
313
- isRunning,
314
- requestStop,
315
- startHeartbeatLoop
316
- };
317
- //# sourceMappingURL=heartbeat-35HVB5PB.js.map