tomo-ai 0.1.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 (90) hide show
  1. package/README.md +198 -0
  2. package/defaults/AGENT.md +27 -0
  3. package/defaults/IDENTITY.md +27 -0
  4. package/defaults/SOUL.md +34 -0
  5. package/defaults/skills/cron/SKILL.md +68 -0
  6. package/dist/agent.d.ts +25 -0
  7. package/dist/agent.d.ts.map +1 -0
  8. package/dist/agent.js +334 -0
  9. package/dist/agent.js.map +1 -0
  10. package/dist/channels/index.d.ts +3 -0
  11. package/dist/channels/index.d.ts.map +1 -0
  12. package/dist/channels/index.js +2 -0
  13. package/dist/channels/index.js.map +1 -0
  14. package/dist/channels/telegram.d.ts +22 -0
  15. package/dist/channels/telegram.d.ts.map +1 -0
  16. package/dist/channels/telegram.js +189 -0
  17. package/dist/channels/telegram.js.map +1 -0
  18. package/dist/channels/types.d.ts +53 -0
  19. package/dist/channels/types.d.ts.map +1 -0
  20. package/dist/channels/types.js +2 -0
  21. package/dist/channels/types.js.map +1 -0
  22. package/dist/cli/cron.d.ts +3 -0
  23. package/dist/cli/cron.d.ts.map +1 -0
  24. package/dist/cli/cron.js +87 -0
  25. package/dist/cli/cron.js.map +1 -0
  26. package/dist/cli/daemon.d.ts +6 -0
  27. package/dist/cli/daemon.d.ts.map +1 -0
  28. package/dist/cli/daemon.js +100 -0
  29. package/dist/cli/daemon.js.map +1 -0
  30. package/dist/cli/init.d.ts +3 -0
  31. package/dist/cli/init.d.ts.map +1 -0
  32. package/dist/cli/init.js +246 -0
  33. package/dist/cli/init.js.map +1 -0
  34. package/dist/cli/sessions.d.ts +3 -0
  35. package/dist/cli/sessions.d.ts.map +1 -0
  36. package/dist/cli/sessions.js +81 -0
  37. package/dist/cli/sessions.js.map +1 -0
  38. package/dist/cli/start.d.ts +3 -0
  39. package/dist/cli/start.d.ts.map +1 -0
  40. package/dist/cli/start.js +86 -0
  41. package/dist/cli/start.js.map +1 -0
  42. package/dist/cli.d.ts +3 -0
  43. package/dist/cli.d.ts.map +1 -0
  44. package/dist/cli.js +21 -0
  45. package/dist/cli.js.map +1 -0
  46. package/dist/config.d.ts +12 -0
  47. package/dist/config.d.ts.map +1 -0
  48. package/dist/config.js +37 -0
  49. package/dist/config.js.map +1 -0
  50. package/dist/cron/scheduler.d.ts +12 -0
  51. package/dist/cron/scheduler.d.ts.map +1 -0
  52. package/dist/cron/scheduler.js +48 -0
  53. package/dist/cron/scheduler.js.map +1 -0
  54. package/dist/cron/store.d.ts +24 -0
  55. package/dist/cron/store.d.ts.map +1 -0
  56. package/dist/cron/store.js +143 -0
  57. package/dist/cron/store.js.map +1 -0
  58. package/dist/cron/types.d.ts +35 -0
  59. package/dist/cron/types.d.ts.map +1 -0
  60. package/dist/cron/types.js +2 -0
  61. package/dist/cron/types.js.map +1 -0
  62. package/dist/index.d.ts +2 -0
  63. package/dist/index.d.ts.map +1 -0
  64. package/dist/index.js +14 -0
  65. package/dist/index.js.map +1 -0
  66. package/dist/logger.d.ts +3 -0
  67. package/dist/logger.d.ts.map +1 -0
  68. package/dist/logger.js +26 -0
  69. package/dist/logger.js.map +1 -0
  70. package/dist/sessions/index.d.ts +3 -0
  71. package/dist/sessions/index.d.ts.map +1 -0
  72. package/dist/sessions/index.js +2 -0
  73. package/dist/sessions/index.js.map +1 -0
  74. package/dist/sessions/store.d.ts +36 -0
  75. package/dist/sessions/store.d.ts.map +1 -0
  76. package/dist/sessions/store.js +216 -0
  77. package/dist/sessions/store.js.map +1 -0
  78. package/dist/sessions/types.d.ts +32 -0
  79. package/dist/sessions/types.d.ts.map +1 -0
  80. package/dist/sessions/types.js +2 -0
  81. package/dist/sessions/types.js.map +1 -0
  82. package/dist/skills/sync.d.ts +12 -0
  83. package/dist/skills/sync.d.ts.map +1 -0
  84. package/dist/skills/sync.js +71 -0
  85. package/dist/skills/sync.js.map +1 -0
  86. package/dist/workspace/index.d.ts +2 -0
  87. package/dist/workspace/index.d.ts.map +1 -0
  88. package/dist/workspace/index.js +99 -0
  89. package/dist/workspace/index.js.map +1 -0
  90. package/package.json +49 -0
@@ -0,0 +1,216 @@
1
+ import { mkdirSync, appendFileSync, readFileSync, writeFileSync, existsSync, unlinkSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { homedir } from "node:os";
4
+ import { log } from "../logger.js";
5
+ const UNLINKED_TTL_MS = 30 * 24 * 60 * 60 * 1000; // 30 days
6
+ /** Where the SDK stores its JSONL session files */
7
+ function getSdkSessionDir() {
8
+ const home = homedir();
9
+ const workspacePath = join(home, ".tomo", "workspace");
10
+ const encoded = workspacePath.replace(/\//g, "-");
11
+ return join(home, ".claude", "projects", encoded);
12
+ }
13
+ export class SessionStore {
14
+ sessions = new Map();
15
+ registry = [];
16
+ dir;
17
+ historyLimit;
18
+ constructor(dir, historyLimit) {
19
+ this.dir = dir;
20
+ this.historyLimit = historyLimit;
21
+ mkdirSync(dir, { recursive: true });
22
+ this.loadRegistry();
23
+ this.cleanupExpired();
24
+ }
25
+ /** Get or create a session, loading from disk on first access */
26
+ get(key) {
27
+ let session = this.sessions.get(key);
28
+ if (session)
29
+ return session;
30
+ const messages = this.loadTranscript(key);
31
+ session = {
32
+ key,
33
+ messages,
34
+ createdAt: messages.length > 0 ? messages[0].timestamp : Date.now(),
35
+ updatedAt: messages.length > 0 ? messages[messages.length - 1].timestamp : Date.now(),
36
+ };
37
+ this.sessions.set(key, session);
38
+ return session;
39
+ }
40
+ /** Append a message to the session and persist to disk */
41
+ append(key, message) {
42
+ const session = this.get(key);
43
+ session.messages.push(message);
44
+ session.updatedAt = message.timestamp;
45
+ const file = this.transcriptPath(key);
46
+ appendFileSync(file, JSON.stringify(message) + "\n");
47
+ }
48
+ /** Get the last N turns of conversation for LLM context */
49
+ getHistory(key) {
50
+ const session = this.get(key);
51
+ const messages = session.messages;
52
+ if (this.historyLimit <= 0)
53
+ return messages;
54
+ let userTurns = 0;
55
+ let cutoff = messages.length;
56
+ for (let i = messages.length - 1; i >= 0; i--) {
57
+ if (messages[i].role === "user") {
58
+ userTurns++;
59
+ if (userTurns > this.historyLimit)
60
+ break;
61
+ }
62
+ cutoff = i;
63
+ }
64
+ return messages.slice(cutoff);
65
+ }
66
+ // --- SDK Session Registry ---
67
+ /** Get the active SDK session ID for a channel key */
68
+ getSdkSessionId(key) {
69
+ // Re-read from disk to pick up external changes (e.g. `tomo sessions clear`)
70
+ this.loadRegistry();
71
+ const entry = this.registry.find((e) => e.channelKey === key && e.unlinkedAt === null);
72
+ return entry?.sdkSessionId;
73
+ }
74
+ /** Link a new SDK session to a channel key */
75
+ setSdkSessionId(key, sessionId) {
76
+ // Unlink any existing session for this key
77
+ this.clearSdkSessionId(key);
78
+ const now = Date.now();
79
+ this.registry.push({
80
+ sdkSessionId: sessionId,
81
+ channelKey: key,
82
+ createdAt: now,
83
+ lastActiveAt: now,
84
+ unlinkedAt: null,
85
+ expiresAt: null,
86
+ });
87
+ this.saveRegistry();
88
+ }
89
+ /** Touch the active session (update lastActiveAt) */
90
+ touchSession(key) {
91
+ const entry = this.registry.find((e) => e.channelKey === key && e.unlinkedAt === null);
92
+ if (entry) {
93
+ entry.lastActiveAt = Date.now();
94
+ this.saveRegistry();
95
+ }
96
+ }
97
+ /** List all SDK session entries */
98
+ listSdkSessionIds() {
99
+ return this.registry
100
+ .filter((e) => e.unlinkedAt === null)
101
+ .map((e) => [e.channelKey, e.sdkSessionId]);
102
+ }
103
+ /** List all sessions including unlinked */
104
+ listAllSessions() {
105
+ return [...this.registry];
106
+ }
107
+ /** Unlink a session (marks for deletion after TTL) */
108
+ clearSdkSessionId(key) {
109
+ const now = Date.now();
110
+ for (const entry of this.registry) {
111
+ if (entry.channelKey === key && entry.unlinkedAt === null) {
112
+ entry.unlinkedAt = now;
113
+ entry.expiresAt = now + UNLINKED_TTL_MS;
114
+ log.info({ key, sessionId: entry.sdkSessionId, expiresAt: new Date(entry.expiresAt).toISOString() }, "Session unlinked, will be deleted in 30 days");
115
+ }
116
+ }
117
+ this.saveRegistry();
118
+ }
119
+ /** Delete expired unlinked sessions and their SDK JSONL files */
120
+ cleanupExpired() {
121
+ const now = Date.now();
122
+ const sdkDir = getSdkSessionDir();
123
+ const expired = this.registry.filter((e) => e.expiresAt !== null && e.expiresAt <= now);
124
+ for (const entry of expired) {
125
+ // Delete the SDK JSONL file
126
+ const sdkFile = join(sdkDir, `${entry.sdkSessionId}.jsonl`);
127
+ if (existsSync(sdkFile)) {
128
+ try {
129
+ unlinkSync(sdkFile);
130
+ log.info({ sessionId: entry.sdkSessionId }, "Deleted expired SDK session file");
131
+ }
132
+ catch {
133
+ log.warn({ sessionId: entry.sdkSessionId }, "Failed to delete expired SDK session file");
134
+ }
135
+ }
136
+ }
137
+ if (expired.length > 0) {
138
+ this.registry = this.registry.filter((e) => e.expiresAt === null || e.expiresAt > now);
139
+ this.saveRegistry();
140
+ log.info({ count: expired.length }, "Cleaned up expired sessions");
141
+ }
142
+ }
143
+ // --- Registry persistence ---
144
+ get registryPath() {
145
+ return join(this.dir, "_sessions.json");
146
+ }
147
+ loadRegistry() {
148
+ const file = this.registryPath;
149
+ if (!existsSync(file)) {
150
+ // Migrate from old _sdk_sessions.json if it exists
151
+ this.migrateOldFormat();
152
+ return;
153
+ }
154
+ try {
155
+ const data = JSON.parse(readFileSync(file, "utf-8"));
156
+ this.registry = data.sessions ?? [];
157
+ }
158
+ catch {
159
+ this.registry = [];
160
+ }
161
+ }
162
+ saveRegistry() {
163
+ const data = { version: 1, sessions: this.registry };
164
+ writeFileSync(this.registryPath, JSON.stringify(data, null, 2) + "\n");
165
+ }
166
+ /** Migrate from the old simple key→value format */
167
+ migrateOldFormat() {
168
+ const oldFile = join(this.dir, "_sdk_sessions.json");
169
+ if (!existsSync(oldFile))
170
+ return;
171
+ try {
172
+ const data = JSON.parse(readFileSync(oldFile, "utf-8"));
173
+ const now = Date.now();
174
+ for (const [key, sessionId] of Object.entries(data)) {
175
+ this.registry.push({
176
+ sdkSessionId: sessionId,
177
+ channelKey: key,
178
+ createdAt: now,
179
+ lastActiveAt: now,
180
+ unlinkedAt: null,
181
+ expiresAt: null,
182
+ });
183
+ }
184
+ this.saveRegistry();
185
+ unlinkSync(oldFile);
186
+ log.info({ count: this.registry.length }, "Migrated old session format");
187
+ }
188
+ catch {
189
+ // Ignore migration errors
190
+ }
191
+ }
192
+ // --- Transcripts ---
193
+ transcriptPath(key) {
194
+ const safe = key.replace(/[^a-zA-Z0-9_-]/g, "_");
195
+ return join(this.dir, `${safe}.jsonl`);
196
+ }
197
+ loadTranscript(key) {
198
+ const file = this.transcriptPath(key);
199
+ if (!existsSync(file))
200
+ return [];
201
+ const lines = readFileSync(file, "utf-8").trim().split("\n");
202
+ const messages = [];
203
+ for (const line of lines) {
204
+ if (!line)
205
+ continue;
206
+ try {
207
+ messages.push(JSON.parse(line));
208
+ }
209
+ catch {
210
+ // Skip malformed lines
211
+ }
212
+ }
213
+ return messages;
214
+ }
215
+ }
216
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/sessions/store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ export interface SessionMessage {
2
+ role: "user" | "assistant";
3
+ content: string;
4
+ channel: string;
5
+ senderName?: string;
6
+ timestamp: number;
7
+ }
8
+ export interface Session {
9
+ key: string;
10
+ messages: SessionMessage[];
11
+ createdAt: number;
12
+ updatedAt: number;
13
+ }
14
+ export interface SessionEntry {
15
+ /** SDK session ID (UUID) */
16
+ sdkSessionId: string;
17
+ /** Channel session key (e.g. "telegram:12345") */
18
+ channelKey: string;
19
+ /** When this session was created */
20
+ createdAt: number;
21
+ /** When this session was last used */
22
+ lastActiveAt: number;
23
+ /** If unlinked, when it was unlinked. Null if active. */
24
+ unlinkedAt: number | null;
25
+ /** When this session should be deleted (unlinkedAt + TTL). Null if active. */
26
+ expiresAt: number | null;
27
+ }
28
+ export interface SessionRegistry {
29
+ version: number;
30
+ sessions: SessionEntry[];
31
+ }
32
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/sessions/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,OAAO;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,4BAA4B;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,kDAAkD;IAClD,UAAU,EAAE,MAAM,CAAC;IACnB,oCAAoC;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,sCAAsC;IACtC,YAAY,EAAE,MAAM,CAAC;IACrB,yDAAyD;IACzD,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,8EAA8E;IAC9E,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,YAAY,EAAE,CAAC;CAC1B"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/sessions/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,12 @@
1
+ export declare class SkillSync {
2
+ private watcher;
3
+ private targetDir;
4
+ private sourceDir;
5
+ constructor(cwd?: string);
6
+ /** Initial sync + start watching for changes */
7
+ start(): void;
8
+ stop(): void;
9
+ /** Copy workspace skills to ~/.claude/skills/ with tomo- prefix */
10
+ private sync;
11
+ }
12
+ //# sourceMappingURL=sync.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/skills/sync.ts"],"names":[],"mappings":"AAkBA,qBAAa,SAAS;IACpB,OAAO,CAAC,OAAO,CAA0B;IACzC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,SAAS,CAAS;gBAEd,GAAG,GAAE,MAAsB;IAKvC,gDAAgD;IAChD,KAAK,IAAI,IAAI;IAeb,IAAI,IAAI,IAAI;IAKZ,mEAAmE;IACnE,OAAO,CAAC,IAAI;CA+Bb"}
@@ -0,0 +1,71 @@
1
+ import { watch } from "node:fs";
2
+ import { cpSync, mkdirSync, existsSync, readdirSync, rmSync } from "node:fs";
3
+ import { join } from "node:path";
4
+ import { log } from "../logger.js";
5
+ /** Source: ~/.tomo/workspace/skills/ (user's skills, copied by tomo init) */
6
+ function getSourceDir(cwd) {
7
+ return join(cwd, "skills");
8
+ }
9
+ /** Target: {cwd}/.claude/skills/ (project-level, discovered by SDK via settingSources) */
10
+ function getTargetDir(cwd) {
11
+ return join(cwd, ".claude", "skills");
12
+ }
13
+ const SKILL_PREFIX = "tomo-";
14
+ export class SkillSync {
15
+ watcher = null;
16
+ targetDir;
17
+ sourceDir;
18
+ constructor(cwd = process.cwd()) {
19
+ this.sourceDir = getSourceDir(cwd);
20
+ this.targetDir = getTargetDir(cwd);
21
+ }
22
+ /** Initial sync + start watching for changes */
23
+ start() {
24
+ this.sync();
25
+ if (!existsSync(this.sourceDir))
26
+ return;
27
+ try {
28
+ this.watcher = watch(this.sourceDir, { recursive: true }, (_event, _filename) => {
29
+ this.sync();
30
+ });
31
+ log.info({ source: this.sourceDir, target: this.targetDir }, "Skill sync watcher started");
32
+ }
33
+ catch {
34
+ log.warn("Could not start skill file watcher, skills will only sync on startup");
35
+ }
36
+ }
37
+ stop() {
38
+ this.watcher?.close();
39
+ this.watcher = null;
40
+ }
41
+ /** Copy workspace skills to ~/.claude/skills/ with tomo- prefix */
42
+ sync() {
43
+ if (!existsSync(this.sourceDir))
44
+ return;
45
+ mkdirSync(this.targetDir, { recursive: true });
46
+ const workspaceSkills = new Set();
47
+ for (const entry of readdirSync(this.sourceDir, { withFileTypes: true })) {
48
+ if (!entry.isDirectory())
49
+ continue;
50
+ const prefixed = `${SKILL_PREFIX}${entry.name}`;
51
+ workspaceSkills.add(prefixed);
52
+ const src = join(this.sourceDir, entry.name);
53
+ const dst = join(this.targetDir, prefixed);
54
+ cpSync(src, dst, { recursive: true, force: true });
55
+ }
56
+ // Remove tomo- prefixed skills that are no longer in workspace
57
+ if (existsSync(this.targetDir)) {
58
+ for (const entry of readdirSync(this.targetDir, { withFileTypes: true })) {
59
+ if (!entry.isDirectory())
60
+ continue;
61
+ if (!entry.name.startsWith(SKILL_PREFIX))
62
+ continue;
63
+ if (!workspaceSkills.has(entry.name)) {
64
+ rmSync(join(this.targetDir, entry.name), { recursive: true, force: true });
65
+ }
66
+ }
67
+ }
68
+ log.debug({ skills: [...workspaceSkills] }, "Skills synced");
69
+ }
70
+ }
71
+ //# sourceMappingURL=sync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.js","sourceRoot":"","sources":["../../src/skills/sync.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function buildSystemPrompt(): string;
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/workspace/index.ts"],"names":[],"mappings":"AAoGA,wBAAgB,iBAAiB,IAAI,MAAM,CAG1C"}
@@ -0,0 +1,99 @@
1
+ import { readFileSync, existsSync, mkdirSync } from "node:fs";
2
+ import { join, dirname, resolve } from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ import { homedir } from "node:os";
5
+ const __dirname = dirname(fileURLToPath(import.meta.url));
6
+ const TOMO_HOME = join(homedir(), ".tomo");
7
+ const WORKSPACE_DIR = process.env.TOMO_WORKSPACE ?? join(TOMO_HOME, "workspace");
8
+ const DEFAULTS_DIR = resolve(__dirname, "../../defaults");
9
+ const MEMORY_DIR = join(WORKSPACE_DIR, "memory");
10
+ const MEMORY_ENTRYPOINT = join(MEMORY_DIR, "MEMORY.md");
11
+ const MAX_MEMORY_LINES = 200;
12
+ /** Load a .md file from workspace, falling back to bundled defaults */
13
+ function load(name) {
14
+ const userPath = join(WORKSPACE_DIR, `${name}.md`);
15
+ if (existsSync(userPath)) {
16
+ return readFileSync(userPath, "utf-8").trim();
17
+ }
18
+ const defaultPath = join(DEFAULTS_DIR, `${name}.md`);
19
+ if (existsSync(defaultPath)) {
20
+ return readFileSync(defaultPath, "utf-8").trim();
21
+ }
22
+ return "";
23
+ }
24
+ function loadMemory() {
25
+ mkdirSync(MEMORY_DIR, { recursive: true });
26
+ const instructions = `
27
+ # MEMORY — Your Persistent Memory
28
+
29
+ You have a file-based memory system at ${MEMORY_DIR}/. This directory is yours — read from it and write to it freely.
30
+
31
+ ## How it works
32
+
33
+ - **MEMORY.md** is your index file. It's loaded into your context every conversation.
34
+ - Each memory is a separate .md file with YAML frontmatter (name, description, type).
35
+ - MEMORY.md contains one-line pointers to memory files: \`- [Title](file.md) — short description\`
36
+
37
+ ## Memory types
38
+
39
+ | Type | Purpose |
40
+ |------|---------|
41
+ | **user** | Who the user is — role, preferences, knowledge |
42
+ | **feedback** | How to approach work — corrections and confirmed approaches |
43
+ | **project** | Ongoing work, goals, deadlines |
44
+ | **reference** | Pointers to external resources |
45
+
46
+ ## How to save
47
+
48
+ 1. Write the memory file:
49
+ \`\`\`markdown
50
+ ---
51
+ name: memory-name
52
+ description: one-line description
53
+ type: user
54
+ ---
55
+
56
+ Memory content here.
57
+ \`\`\`
58
+
59
+ 2. Add a pointer to MEMORY.md: \`- [Title](file.md) — one-line hook\`
60
+
61
+ ## When to save
62
+
63
+ - When the user explicitly asks you to remember something
64
+ - When you learn something about the user that would help future conversations
65
+ - When the user corrects your approach or confirms a non-obvious choice
66
+
67
+ ## When NOT to save
68
+
69
+ - Code patterns or architecture (derive from current state)
70
+ - Ephemeral task details
71
+ - Anything already in SOUL.md, AGENT.md, or IDENTITY.md
72
+
73
+ ## Rules
74
+
75
+ - Keep MEMORY.md under ${MAX_MEMORY_LINES} lines
76
+ - Update or remove stale memories rather than accumulating
77
+ - Check if a memory already exists before creating a duplicate
78
+ - Convert relative dates to absolute dates when saving`.trim();
79
+ let memoryContent;
80
+ if (existsSync(MEMORY_ENTRYPOINT)) {
81
+ const raw = readFileSync(MEMORY_ENTRYPOINT, "utf-8").trim();
82
+ const lines = raw.split("\n");
83
+ if (lines.length > MAX_MEMORY_LINES) {
84
+ memoryContent = lines.slice(0, MAX_MEMORY_LINES).join("\n") + `\n\n(truncated — ${lines.length - MAX_MEMORY_LINES} lines omitted)`;
85
+ }
86
+ else {
87
+ memoryContent = raw;
88
+ }
89
+ }
90
+ else {
91
+ memoryContent = "(currently empty)";
92
+ }
93
+ return `${instructions}\n\n## Current MEMORY.md\n\n${memoryContent}`;
94
+ }
95
+ export function buildSystemPrompt() {
96
+ const sections = [load("SOUL"), load("AGENT"), load("IDENTITY"), loadMemory()].filter(Boolean);
97
+ return sections.join("\n\n---\n\n");
98
+ }
99
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/workspace/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "tomo-ai",
3
+ "version": "0.1.0",
4
+ "description": "Personal assistant powered by Claude Agent SDK",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "bin": {
8
+ "tomo": "dist/cli.js"
9
+ },
10
+ "files": [
11
+ "dist",
12
+ "defaults"
13
+ ],
14
+ "scripts": {
15
+ "build": "tsc",
16
+ "dev": "tsx watch src/cli.ts -- start",
17
+ "start": "node dist/cli.js start",
18
+ "tomo": "tsx src/cli.ts",
19
+ "prepublishOnly": "npm run build"
20
+ },
21
+ "keywords": [
22
+ "ai",
23
+ "assistant",
24
+ "claude",
25
+ "telegram",
26
+ "chatbot",
27
+ "agent"
28
+ ],
29
+ "engines": {
30
+ "node": ">=22.0.0"
31
+ },
32
+ "license": "MIT",
33
+ "dependencies": {
34
+ "@anthropic-ai/claude-agent-sdk": "^0.2.92",
35
+ "@clack/prompts": "^1.2.0",
36
+ "commander": "^13.1.0",
37
+ "croner": "^9.0.0",
38
+ "grammy": "^1.35.0",
39
+ "pino": "^9.6.0",
40
+ "pino-pretty": "^13.0.0",
41
+ "zod": "^4.0.0"
42
+ },
43
+ "devDependencies": {
44
+ "@types/node": "^22.0.0",
45
+ "dotenv": "^16.4.7",
46
+ "tsx": "^4.19.0",
47
+ "typescript": "^5.7.0"
48
+ }
49
+ }