camelagi 0.5.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.
Files changed (249) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +224 -0
  3. package/camelagi.mjs +2 -0
  4. package/config.example.yaml +107 -0
  5. package/dist/agent/agent-openai.js +206 -0
  6. package/dist/agent/agent-openai.js.map +1 -0
  7. package/dist/agent/agent-sdk.js +209 -0
  8. package/dist/agent/agent-sdk.js.map +1 -0
  9. package/dist/agent/tool-adapter.js +31 -0
  10. package/dist/agent/tool-adapter.js.map +1 -0
  11. package/dist/agent/types.js +3 -0
  12. package/dist/agent/types.js.map +1 -0
  13. package/dist/agent.js +17 -0
  14. package/dist/agent.js.map +1 -0
  15. package/dist/approval-forward.js +42 -0
  16. package/dist/approval-forward.js.map +1 -0
  17. package/dist/approvals.js +151 -0
  18. package/dist/approvals.js.map +1 -0
  19. package/dist/boot.js +34 -0
  20. package/dist/boot.js.map +1 -0
  21. package/dist/bootstrap.js +451 -0
  22. package/dist/bootstrap.js.map +1 -0
  23. package/dist/camelagi-gateway.mjs +93611 -0
  24. package/dist/camelagi-gateway.mjs.map +7 -0
  25. package/dist/channels/adapter.js +10 -0
  26. package/dist/channels/adapter.js.map +1 -0
  27. package/dist/channels/discord.js +232 -0
  28. package/dist/channels/discord.js.map +1 -0
  29. package/dist/channels/handler.js +349 -0
  30. package/dist/channels/handler.js.map +1 -0
  31. package/dist/channels/index.js +19 -0
  32. package/dist/channels/index.js.map +1 -0
  33. package/dist/channels/registry.js +71 -0
  34. package/dist/channels/registry.js.map +1 -0
  35. package/dist/channels/telegram.js +83 -0
  36. package/dist/channels/telegram.js.map +1 -0
  37. package/dist/channels/types.js +3 -0
  38. package/dist/channels/types.js.map +1 -0
  39. package/dist/chunker.js +102 -0
  40. package/dist/chunker.js.map +1 -0
  41. package/dist/cli/cmd-agents.js +65 -0
  42. package/dist/cli/cmd-agents.js.map +1 -0
  43. package/dist/cli/cmd-bootstrap.js +10 -0
  44. package/dist/cli/cmd-bootstrap.js.map +1 -0
  45. package/dist/cli/cmd-chat.js +32 -0
  46. package/dist/cli/cmd-chat.js.map +1 -0
  47. package/dist/cli/cmd-config.js +88 -0
  48. package/dist/cli/cmd-config.js.map +1 -0
  49. package/dist/cli/cmd-cron.js +120 -0
  50. package/dist/cli/cmd-cron.js.map +1 -0
  51. package/dist/cli/cmd-daemon.js +37 -0
  52. package/dist/cli/cmd-daemon.js.map +1 -0
  53. package/dist/cli/cmd-doctor.js +18 -0
  54. package/dist/cli/cmd-doctor.js.map +1 -0
  55. package/dist/cli/cmd-logs.js +30 -0
  56. package/dist/cli/cmd-logs.js.map +1 -0
  57. package/dist/cli/cmd-pairing.js +41 -0
  58. package/dist/cli/cmd-pairing.js.map +1 -0
  59. package/dist/cli/cmd-reset.js +39 -0
  60. package/dist/cli/cmd-reset.js.map +1 -0
  61. package/dist/cli/cmd-serve.js +30 -0
  62. package/dist/cli/cmd-serve.js.map +1 -0
  63. package/dist/cli/cmd-sessions.js +56 -0
  64. package/dist/cli/cmd-sessions.js.map +1 -0
  65. package/dist/cli/cmd-setup.js +11 -0
  66. package/dist/cli/cmd-setup.js.map +1 -0
  67. package/dist/cli/cmd-soul.js +43 -0
  68. package/dist/cli/cmd-soul.js.map +1 -0
  69. package/dist/cli/parse.js +50 -0
  70. package/dist/cli/parse.js.map +1 -0
  71. package/dist/cli/registry.js +15 -0
  72. package/dist/cli/registry.js.map +1 -0
  73. package/dist/cli.js +103 -0
  74. package/dist/cli.js.map +1 -0
  75. package/dist/compact.js +92 -0
  76. package/dist/compact.js.map +1 -0
  77. package/dist/config.js +153 -0
  78. package/dist/config.js.map +1 -0
  79. package/dist/constants.js +21 -0
  80. package/dist/constants.js.map +1 -0
  81. package/dist/core/config.js +212 -0
  82. package/dist/core/config.js.map +1 -0
  83. package/dist/core/constants.js +21 -0
  84. package/dist/core/constants.js.map +1 -0
  85. package/dist/core/errors.js +5 -0
  86. package/dist/core/errors.js.map +1 -0
  87. package/dist/core/log.js +41 -0
  88. package/dist/core/log.js.map +1 -0
  89. package/dist/core/models.js +123 -0
  90. package/dist/core/models.js.map +1 -0
  91. package/dist/core/types.js +3 -0
  92. package/dist/core/types.js.map +1 -0
  93. package/dist/core/update-check.js +51 -0
  94. package/dist/core/update-check.js.map +1 -0
  95. package/dist/cron.js +81 -0
  96. package/dist/cron.js.map +1 -0
  97. package/dist/daemon.js +109 -0
  98. package/dist/daemon.js.map +1 -0
  99. package/dist/doctor.js +194 -0
  100. package/dist/doctor.js.map +1 -0
  101. package/dist/errors.js +5 -0
  102. package/dist/errors.js.map +1 -0
  103. package/dist/extensions/approval-forward.js +42 -0
  104. package/dist/extensions/approval-forward.js.map +1 -0
  105. package/dist/extensions/approvals.js +144 -0
  106. package/dist/extensions/approvals.js.map +1 -0
  107. package/dist/extensions/cron.js +306 -0
  108. package/dist/extensions/cron.js.map +1 -0
  109. package/dist/extensions/hooks.js +72 -0
  110. package/dist/extensions/hooks.js.map +1 -0
  111. package/dist/extensions/skills.js +97 -0
  112. package/dist/extensions/skills.js.map +1 -0
  113. package/dist/gateway/csrf.js +44 -0
  114. package/dist/gateway/csrf.js.map +1 -0
  115. package/dist/gateway/logger.js +81 -0
  116. package/dist/gateway/logger.js.map +1 -0
  117. package/dist/gateway/rate-limit.js +33 -0
  118. package/dist/gateway/rate-limit.js.map +1 -0
  119. package/dist/gateway/routes.js +315 -0
  120. package/dist/gateway/routes.js.map +1 -0
  121. package/dist/gateway/state.js +54 -0
  122. package/dist/gateway/state.js.map +1 -0
  123. package/dist/gateway/ws-handler.js +200 -0
  124. package/dist/gateway/ws-handler.js.map +1 -0
  125. package/dist/gateway-entry.js +16 -0
  126. package/dist/gateway-entry.js.map +1 -0
  127. package/dist/hooks.js +72 -0
  128. package/dist/hooks.js.map +1 -0
  129. package/dist/lanes.js +62 -0
  130. package/dist/lanes.js.map +1 -0
  131. package/dist/model.js +30 -0
  132. package/dist/model.js.map +1 -0
  133. package/dist/policy.js +22 -0
  134. package/dist/policy.js.map +1 -0
  135. package/dist/queue.js +45 -0
  136. package/dist/queue.js.map +1 -0
  137. package/dist/retry.js +96 -0
  138. package/dist/retry.js.map +1 -0
  139. package/dist/runs.js +83 -0
  140. package/dist/runs.js.map +1 -0
  141. package/dist/runtime/compact.js +99 -0
  142. package/dist/runtime/compact.js.map +1 -0
  143. package/dist/runtime/lanes.js +66 -0
  144. package/dist/runtime/lanes.js.map +1 -0
  145. package/dist/runtime/orchestrate.js +121 -0
  146. package/dist/runtime/orchestrate.js.map +1 -0
  147. package/dist/runtime/queue.js +50 -0
  148. package/dist/runtime/queue.js.map +1 -0
  149. package/dist/runtime/retry.js +127 -0
  150. package/dist/runtime/retry.js.map +1 -0
  151. package/dist/runtime/runs.js +105 -0
  152. package/dist/runtime/runs.js.map +1 -0
  153. package/dist/serve.js +209 -0
  154. package/dist/serve.js.map +1 -0
  155. package/dist/session.js +75 -0
  156. package/dist/session.js.map +1 -0
  157. package/dist/setup.js +254 -0
  158. package/dist/setup.js.map +1 -0
  159. package/dist/skills.js +89 -0
  160. package/dist/skills.js.map +1 -0
  161. package/dist/subagent.js +71 -0
  162. package/dist/subagent.js.map +1 -0
  163. package/dist/system-prompt.js +157 -0
  164. package/dist/system-prompt.js.map +1 -0
  165. package/dist/telegram/admin-bot.js +705 -0
  166. package/dist/telegram/admin-bot.js.map +1 -0
  167. package/dist/telegram/agent-bot.js +551 -0
  168. package/dist/telegram/agent-bot.js.map +1 -0
  169. package/dist/telegram/bot-approval.js +63 -0
  170. package/dist/telegram/bot-approval.js.map +1 -0
  171. package/dist/telegram/draft-stream.js +86 -0
  172. package/dist/telegram/draft-stream.js.map +1 -0
  173. package/dist/telegram/format.js +106 -0
  174. package/dist/telegram/format.js.map +1 -0
  175. package/dist/telegram/helpers.js +87 -0
  176. package/dist/telegram/helpers.js.map +1 -0
  177. package/dist/telegram/pairing-notify.js +52 -0
  178. package/dist/telegram/pairing-notify.js.map +1 -0
  179. package/dist/telegram/pairing.js +138 -0
  180. package/dist/telegram/pairing.js.map +1 -0
  181. package/dist/telegram/resolve.js +33 -0
  182. package/dist/telegram/resolve.js.map +1 -0
  183. package/dist/telegram/transcribe.js +77 -0
  184. package/dist/telegram/transcribe.js.map +1 -0
  185. package/dist/telegram/types.js +3 -0
  186. package/dist/telegram/types.js.map +1 -0
  187. package/dist/telegram/voice-wizard.js +84 -0
  188. package/dist/telegram/voice-wizard.js.map +1 -0
  189. package/dist/telegram/wizard.js +89 -0
  190. package/dist/telegram/wizard.js.map +1 -0
  191. package/dist/telegram/wizards.js +297 -0
  192. package/dist/telegram/wizards.js.map +1 -0
  193. package/dist/telegram-admin.js +800 -0
  194. package/dist/telegram-admin.js.map +1 -0
  195. package/dist/telegram.js +118 -0
  196. package/dist/telegram.js.map +1 -0
  197. package/dist/tools/cron.js +94 -0
  198. package/dist/tools/cron.js.map +1 -0
  199. package/dist/tools/edit.js +29 -0
  200. package/dist/tools/edit.js.map +1 -0
  201. package/dist/tools/exec.js +38 -0
  202. package/dist/tools/exec.js.map +1 -0
  203. package/dist/tools/fetch.js +28 -0
  204. package/dist/tools/fetch.js.map +1 -0
  205. package/dist/tools/index.js +16 -0
  206. package/dist/tools/index.js.map +1 -0
  207. package/dist/tools/memory.js +164 -0
  208. package/dist/tools/memory.js.map +1 -0
  209. package/dist/tools/patch.js +284 -0
  210. package/dist/tools/patch.js.map +1 -0
  211. package/dist/tools/read.js +26 -0
  212. package/dist/tools/read.js.map +1 -0
  213. package/dist/tools/search.js +62 -0
  214. package/dist/tools/search.js.map +1 -0
  215. package/dist/tools/subagent.js +48 -0
  216. package/dist/tools/subagent.js.map +1 -0
  217. package/dist/tools/write.js +22 -0
  218. package/dist/tools/write.js.map +1 -0
  219. package/dist/tui/commands.js +450 -0
  220. package/dist/tui/commands.js.map +1 -0
  221. package/dist/tui/components/assistant-message.js +26 -0
  222. package/dist/tui/components/assistant-message.js.map +1 -0
  223. package/dist/tui/components/chat-log.js +94 -0
  224. package/dist/tui/components/chat-log.js.map +1 -0
  225. package/dist/tui/components/custom-editor.js +40 -0
  226. package/dist/tui/components/custom-editor.js.map +1 -0
  227. package/dist/tui/components/hint-bar.js +13 -0
  228. package/dist/tui/components/hint-bar.js.map +1 -0
  229. package/dist/tui/components/tool-execution.js +73 -0
  230. package/dist/tui/components/tool-execution.js.map +1 -0
  231. package/dist/tui/components/user-message.js +19 -0
  232. package/dist/tui/components/user-message.js.map +1 -0
  233. package/dist/tui/components/welcome.js +147 -0
  234. package/dist/tui/components/welcome.js.map +1 -0
  235. package/dist/tui/context.js +3 -0
  236. package/dist/tui/context.js.map +1 -0
  237. package/dist/tui/theme.js +91 -0
  238. package/dist/tui/theme.js.map +1 -0
  239. package/dist/tui/tui.js +389 -0
  240. package/dist/tui/tui.js.map +1 -0
  241. package/dist/tui/ws-handler.js +154 -0
  242. package/dist/tui/ws-handler.js.map +1 -0
  243. package/dist/types.js +3 -0
  244. package/dist/types.js.map +1 -0
  245. package/dist/usage.js +88 -0
  246. package/dist/usage.js.map +1 -0
  247. package/dist/workspace.js +245 -0
  248. package/dist/workspace.js.map +1 -0
  249. package/package.json +74 -0
package/dist/usage.js ADDED
@@ -0,0 +1,88 @@
1
+ // Token usage tracking per session
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+ import { paths } from "./core/config.js";
5
+ const sessionUsage = new Map();
6
+ function usageDir() {
7
+ return path.join(paths.configDir, "usage");
8
+ }
9
+ function usageFile(sessionId) {
10
+ return path.join(usageDir(), `${encodeURIComponent(sessionId)}.json`);
11
+ }
12
+ /** Record token usage for a session */
13
+ export function recordUsage(sessionId, usage) {
14
+ const existing = getSessionUsage(sessionId);
15
+ const updated = {
16
+ totalInput: existing.totalInput + usage.inputTokens,
17
+ totalOutput: existing.totalOutput + usage.outputTokens,
18
+ totalCacheRead: existing.totalCacheRead + usage.cacheReadTokens,
19
+ totalCacheWrite: existing.totalCacheWrite + usage.cacheWriteTokens,
20
+ calls: existing.calls + 1,
21
+ lastUpdated: Date.now(),
22
+ };
23
+ sessionUsage.set(sessionId, updated);
24
+ persistUsage(sessionId, updated);
25
+ }
26
+ /** Get accumulated usage for a session */
27
+ export function getSessionUsage(sessionId) {
28
+ const cached = sessionUsage.get(sessionId);
29
+ if (cached)
30
+ return cached;
31
+ const file = usageFile(sessionId);
32
+ if (fs.existsSync(file)) {
33
+ try {
34
+ const data = JSON.parse(fs.readFileSync(file, "utf-8"));
35
+ sessionUsage.set(sessionId, data);
36
+ return data;
37
+ }
38
+ catch { /* fall through */ }
39
+ }
40
+ return {
41
+ totalInput: 0, totalOutput: 0,
42
+ totalCacheRead: 0, totalCacheWrite: 0,
43
+ calls: 0, lastUpdated: 0,
44
+ };
45
+ }
46
+ /** Format token count: 1234 → "1.2k", 1234567 → "1.2m" */
47
+ export function formatTokens(n) {
48
+ if (n >= 1_000_000)
49
+ return `${(n / 1_000_000).toFixed(1)}m`;
50
+ if (n >= 10_000)
51
+ return `${Math.round(n / 1000)}k`;
52
+ if (n >= 1_000)
53
+ return `${(n / 1000).toFixed(1)}k`;
54
+ return String(n);
55
+ }
56
+ /** Format a usage summary for display */
57
+ export function formatUsageSummary(usage) {
58
+ const total = usage.totalInput + usage.totalOutput;
59
+ const parts = [
60
+ `${formatTokens(total)} total`,
61
+ `${formatTokens(usage.totalInput)} in`,
62
+ `${formatTokens(usage.totalOutput)} out`,
63
+ ];
64
+ if (usage.totalCacheRead > 0) {
65
+ parts.push(`${formatTokens(usage.totalCacheRead)} cached`);
66
+ }
67
+ return parts.join(" | ");
68
+ }
69
+ function persistUsage(sessionId, usage) {
70
+ try {
71
+ const dir = usageDir();
72
+ fs.mkdirSync(dir, { recursive: true });
73
+ fs.writeFileSync(usageFile(sessionId), JSON.stringify(usage));
74
+ }
75
+ catch { /* best effort */ }
76
+ }
77
+ /** Delete usage data for a session */
78
+ export function deleteUsage(sessionId) {
79
+ sessionUsage.delete(sessionId);
80
+ const file = usageFile(sessionId);
81
+ if (fs.existsSync(file)) {
82
+ try {
83
+ fs.unlinkSync(file);
84
+ }
85
+ catch { /* ignore */ }
86
+ }
87
+ }
88
+ //# sourceMappingURL=usage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usage.js","sourceRoot":"","sources":["../src/usage.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,245 @@
1
+ // Workspace: bootstrap files, templates, and file operations
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+ import { paths } from "./core/config.js";
5
+ const workspaceDir = path.join(paths.configDir, "workspace");
6
+ const agentsDir = path.join(paths.configDir, "agents");
7
+ export const workspacePaths = { workspaceDir };
8
+ /** Get the memory root for an agent (or global workspace if no agentId) */
9
+ export function agentMemoryDir(agentId) {
10
+ if (!agentId)
11
+ return workspaceDir;
12
+ return path.join(agentsDir, agentId);
13
+ }
14
+ /** Ensure an agent's directories exist */
15
+ export function ensureAgentDirs(agentId) {
16
+ const dir = agentMemoryDir(agentId);
17
+ fs.mkdirSync(dir, { recursive: true });
18
+ fs.mkdirSync(path.join(dir, "memory"), { recursive: true });
19
+ }
20
+ /** Seed an agent's workspace with bootstrap files */
21
+ export function seedAgentWorkspace(agentId, name, description) {
22
+ ensureAgentDirs(agentId);
23
+ const dir = agentMemoryDir(agentId);
24
+ // SOUL.md — the agent's identity
25
+ const soulPath = path.join(dir, "SOUL.md");
26
+ if (!fs.existsSync(soulPath)) {
27
+ const desc = description ? `\n${description}\n` : "";
28
+ fs.writeFileSync(soulPath, `# ${name}
29
+ ${desc}
30
+ _You're not a chatbot. You're becoming someone._
31
+
32
+ ## Core Truths
33
+
34
+ **Be genuinely helpful, not performatively helpful.** Skip the "Great question!" and "I'd be happy to help!" — just help. Actions speak louder than filler words.
35
+
36
+ **Have opinions.** You're allowed to disagree, prefer things, find stuff amusing or boring. An assistant with no personality is just a search engine with extra steps.
37
+
38
+ **Be resourceful before asking.** Try to figure it out. Read the file. Check the context. Search for it. _Then_ ask if you're stuck. The goal is to come back with answers, not questions.
39
+
40
+ **Earn trust through competence.** Your human gave you access to their stuff. Don't make them regret it. Be careful with external actions (emails, tweets, anything public). Be bold with internal ones (reading, organizing, learning).
41
+
42
+ **Remember you're a guest.** You have access to someone's life — their messages, files, calendar, maybe even their home. That's intimacy. Treat it with respect.
43
+
44
+ ## Boundaries
45
+
46
+ - Private things stay private. Period.
47
+ - When in doubt, ask before acting externally.
48
+ - Never send half-baked replies to messaging surfaces.
49
+ - You're not the user's voice — be careful in group chats.
50
+
51
+ ## Vibe
52
+
53
+ Be the assistant you'd actually want to talk to. Concise when needed, thorough when it matters. Not a corporate drone. Not a sycophant. Just... good.
54
+
55
+ ## Continuity
56
+
57
+ Each session, you wake up fresh. These files _are_ your memory. Read them. Update them. They're how you persist.
58
+
59
+ If you change this file, tell the user — it's your soul, and they should know.
60
+
61
+ ---
62
+
63
+ _This file is yours to evolve. As you learn who you are, update it._
64
+ `);
65
+ }
66
+ // TOOLS.md — agent-specific setup notes
67
+ const toolsPath = path.join(dir, "TOOLS.md");
68
+ if (!fs.existsSync(toolsPath)) {
69
+ fs.writeFileSync(toolsPath, `# ${name} — Tool Notes
70
+
71
+ <!-- Agent-specific setup notes go here -->
72
+ <!-- Examples: -->
73
+ <!-- - Preferred languages, frameworks -->
74
+ <!-- - Project paths, SSH hosts -->
75
+ <!-- - Any environment-specific context -->
76
+ `);
77
+ }
78
+ // MEMORY.md — starts empty
79
+ const memoryPath = path.join(dir, "MEMORY.md");
80
+ if (!fs.existsSync(memoryPath)) {
81
+ fs.writeFileSync(memoryPath, `# ${name} Memory
82
+
83
+ <!-- Curated long-term memory. The agent reads and updates this file. -->
84
+ `);
85
+ }
86
+ }
87
+ // Bootstrap file definitions (injected into system prompt)
88
+ const BOOTSTRAP_FILES = [
89
+ { name: "AGENTS.md", required: true },
90
+ { name: "SOUL.md", required: false },
91
+ { name: "IDENTITY.md", required: false },
92
+ { name: "USER.md", required: false },
93
+ { name: "TOOLS.md", required: false },
94
+ { name: "MEMORY.md", required: false },
95
+ ];
96
+ const HEAD_RATIO = 0.7;
97
+ const TAIL_RATIO = 0.2;
98
+ // --- Default templates ---
99
+ const TEMPLATES = {
100
+ "AGENTS.md": `# Agent Instructions
101
+
102
+ You are CamelAGI, a personal AI assistant.
103
+
104
+ ## Guidelines
105
+ - Be direct and helpful
106
+ - Use tools when needed to accomplish tasks
107
+ - Read files before modifying them
108
+ - Prefer small, targeted changes over large rewrites
109
+ - Use \`apply_patch\` for multi-file changes or when you know the exact diff
110
+ - If unsure, ask for clarification
111
+
112
+ ## Session Memory
113
+ - Each conversation is a session with persistent history
114
+ - Reference previous messages in the session when relevant
115
+ - Use \`memory_search\` to find past decisions and context
116
+ - Use the workspace directory for any files you create
117
+
118
+ ## Memory Workflow
119
+ - Use \`memory_search\` before answering questions about prior work
120
+ - Store durable facts in MEMORY.md (curated, long-term)
121
+ - Store daily notes in memory/YYYY-MM-DD.md (append-only)
122
+ - When writing to daily files that already exist, APPEND only
123
+ `,
124
+ "SOUL.md": `# Soul
125
+
126
+ ## Personality
127
+ - Genuine, direct, and resourceful
128
+ - Have opinions when asked — don't hedge everything
129
+ - Be concise but thorough when it matters
130
+ - Adapt tone to context (casual chat vs technical work)
131
+
132
+ ## Boundaries
133
+ - Respect user privacy
134
+ - Be honest about limitations
135
+ - Don't pretend to know things you don't
136
+ `,
137
+ "IDENTITY.md": `# Identity
138
+
139
+ <!-- Agent's name, vibe, and emoji -->
140
+ <!-- name: CamelAGI -->
141
+ <!-- emoji: 🐪 -->
142
+ `,
143
+ "USER.md": `# User Profile
144
+
145
+ <!-- Fill this in to help the agent know you better -->
146
+ <!-- name: -->
147
+ <!-- timezone: -->
148
+ <!-- projects: -->
149
+ <!-- preferences: -->
150
+ `,
151
+ "TOOLS.md": `# Tool Notes
152
+
153
+ <!-- Add environment-specific notes for the agent here -->
154
+ <!-- Examples: -->
155
+ <!-- - SSH hosts: myserver (192.168.1.10) -->
156
+ <!-- - Project conventions: use pnpm, not npm -->
157
+ <!-- - Preferred languages: TypeScript, Python -->
158
+ `,
159
+ };
160
+ // --- File operations ---
161
+ export function ensureWorkspace() {
162
+ fs.mkdirSync(workspaceDir, { recursive: true });
163
+ fs.mkdirSync(path.join(workspaceDir, "memory"), { recursive: true });
164
+ }
165
+ export function seedWorkspace() {
166
+ ensureWorkspace();
167
+ for (const [name, content] of Object.entries(TEMPLATES)) {
168
+ const filePath = path.join(workspaceDir, name);
169
+ if (!fs.existsSync(filePath)) {
170
+ fs.writeFileSync(filePath, content);
171
+ }
172
+ }
173
+ // Seed example skill template
174
+ const exampleSkillDir = path.join(paths.configDir, "skills", "_example");
175
+ const exampleSkillFile = path.join(exampleSkillDir, "SKILL.md");
176
+ if (!fs.existsSync(exampleSkillFile)) {
177
+ fs.mkdirSync(exampleSkillDir, { recursive: true });
178
+ fs.writeFileSync(exampleSkillFile, EXAMPLE_SKILL_TEMPLATE);
179
+ }
180
+ }
181
+ const EXAMPLE_SKILL_TEMPLATE = `---
182
+ name: example-skill
183
+ description: Example skill template. Rename this directory and edit SKILL.md.
184
+ ---
185
+
186
+ # Example Skill
187
+
188
+ Instructions here. Keep concise — every token competes with conversation context.
189
+ `;
190
+ export function truncateFile(content, maxChars) {
191
+ if (content.length <= maxChars)
192
+ return { text: content, truncated: false };
193
+ const headChars = Math.floor(maxChars * HEAD_RATIO);
194
+ const tailChars = Math.floor(maxChars * TAIL_RATIO);
195
+ const head = content.slice(0, headChars);
196
+ const tail = content.slice(-tailChars);
197
+ return {
198
+ text: `${head}\n\n[...truncated, read file for full content...]\n\n${tail}`,
199
+ truncated: true,
200
+ };
201
+ }
202
+ /**
203
+ * Load bootstrap files. For agents, checks agent dir first then falls back to global.
204
+ * USER.md always comes from global (same user across agents).
205
+ */
206
+ export function loadBootstrapFiles(agentId) {
207
+ const files = [];
208
+ const agentDir = agentId ? agentMemoryDir(agentId) : null;
209
+ for (const def of BOOTSTRAP_FILES) {
210
+ // Determine where to load from: agent dir first (except USER.md), then global
211
+ let filePath = null;
212
+ if (agentDir && def.name !== "USER.md") {
213
+ const agentPath = path.join(agentDir, def.name);
214
+ if (fs.existsSync(agentPath)) {
215
+ filePath = agentPath;
216
+ }
217
+ }
218
+ // Fall back to global workspace
219
+ if (!filePath) {
220
+ filePath = path.join(workspaceDir, def.name);
221
+ }
222
+ if (fs.existsSync(filePath)) {
223
+ const raw = fs.readFileSync(filePath, "utf-8").trim();
224
+ if (raw) {
225
+ files.push({
226
+ name: def.name,
227
+ path: filePath,
228
+ content: raw,
229
+ rawChars: raw.length,
230
+ injectedChars: 0,
231
+ missing: false,
232
+ truncated: false,
233
+ });
234
+ }
235
+ else {
236
+ files.push({ name: def.name, path: filePath, content: "", rawChars: 0, injectedChars: 0, missing: true, truncated: false });
237
+ }
238
+ }
239
+ else {
240
+ files.push({ name: def.name, path: filePath, content: "", rawChars: 0, injectedChars: 0, missing: true, truncated: false });
241
+ }
242
+ }
243
+ return files;
244
+ }
245
+ //# sourceMappingURL=workspace.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace.js","sourceRoot":"","sources":["../src/workspace.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,74 @@
1
+ {
2
+ "name": "camelagi",
3
+ "version": "0.5.0",
4
+ "description": "Personal AI agent powered by Claude Agent SDK — manage everything from Telegram",
5
+ "type": "module",
6
+ "bin": {
7
+ "camelagi": "./camelagi.mjs",
8
+ "camel": "./camelagi.mjs"
9
+ },
10
+ "scripts": {
11
+ "build": "tsc",
12
+ "dev": "tsx src/cli.ts",
13
+ "test": "vitest run",
14
+ "lint": "tsc --noEmit",
15
+ "bundle:gateway": "node esbuild.gateway.mjs",
16
+ "build:all": "npm run build && npm run bundle:gateway"
17
+ },
18
+ "dependencies": {
19
+ "@anthropic-ai/claude-agent-sdk": "^0.x",
20
+ "@anthropic-ai/sdk": "^0.x",
21
+ "@mariozechner/pi-tui": "^0.57.1",
22
+ "chalk": "^5.6.2",
23
+ "cli-highlight": "^2.1.11",
24
+ "discord.js": "^14.25.1",
25
+ "dotenv": "^16.x",
26
+ "express": "^4.x",
27
+ "grammy": "^1.x",
28
+ "openai": "^6.27.0",
29
+ "ora": "^9.3.0",
30
+ "sharp": "^0.34.5",
31
+ "ws": "^8.x",
32
+ "yaml": "^2.x",
33
+ "zod": "^4.0.0"
34
+ },
35
+ "devDependencies": {
36
+ "@types/express": "^4.x",
37
+ "@types/node": "^22.x",
38
+ "@types/ws": "^8.x",
39
+ "esbuild": "^0.27.4",
40
+ "tsx": "^4.x",
41
+ "typescript": "^5.7.x",
42
+ "vitest": "^3.x"
43
+ },
44
+ "repository": {
45
+ "type": "git",
46
+ "url": "git+https://github.com/inawafalm/CamelAGI.git"
47
+ },
48
+ "homepage": "https://github.com/inawafalm/CamelAGI#readme",
49
+ "bugs": {
50
+ "url": "https://github.com/inawafalm/CamelAGI/issues"
51
+ },
52
+ "files": [
53
+ "dist/",
54
+ "camelagi.mjs",
55
+ "config.example.yaml",
56
+ "README.md",
57
+ "LICENSE"
58
+ ],
59
+ "license": "MIT",
60
+ "author": "Nawaf Almutairi",
61
+ "keywords": [
62
+ "ai",
63
+ "agent",
64
+ "claude",
65
+ "anthropic",
66
+ "telegram",
67
+ "assistant",
68
+ "claude-agent-sdk",
69
+ "bot"
70
+ ],
71
+ "engines": {
72
+ "node": ">=20"
73
+ }
74
+ }