claude-telegram-bot 0.3.1 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bot.mjs +55 -3
- package/package.json +1 -1
package/bot.mjs
CHANGED
|
@@ -83,6 +83,7 @@ const stateFile = stateBase === "config" ? "state.json" : `${stateBase}.state.js
|
|
|
83
83
|
const BOT_DIR = join(DATA_DIR, ".claude-bot");
|
|
84
84
|
const STATE_PATH = join(BOT_DIR, stateFile);
|
|
85
85
|
const ATTACH_DIR = join(BOT_DIR, "attachments");
|
|
86
|
+
const MEMORY_PATH = join(BOT_DIR, "memory.md"); // /new 로 초기화해도 유지되는 퍼시스턴트 메모리
|
|
86
87
|
const LEGACY_STATE_PATH = join(DATA_DIR, stateFile); // 구버전(루트 직하) 호환
|
|
87
88
|
const LEGACY_ATTACH_DIR = join(DATA_DIR, "attachments");
|
|
88
89
|
|
|
@@ -130,6 +131,8 @@ const STR = {
|
|
|
130
131
|
"• /new — reset conversation context (new session)\n" +
|
|
131
132
|
"• /stop — stop the current task · /stop --reset to also roll back the session\n" +
|
|
132
133
|
"• /cron — list tasks · /cron add <natural language> to add · /cron rm <id> to remove\n" +
|
|
134
|
+
"• /remember <text> — save to persistent memory (survives /new)\n" +
|
|
135
|
+
"• /memory — view memory · /memory clear to wipe\n" +
|
|
133
136
|
"• /restart — restart the bot (after a syntax check)\n" +
|
|
134
137
|
"• /status — bot status & version\n" +
|
|
135
138
|
"• /model — view / switch the model\n" +
|
|
@@ -183,6 +186,12 @@ const STR = {
|
|
|
183
186
|
`/model default — clear the override`,
|
|
184
187
|
modelSet: (m) => `🧠 Model set to: ${m}`,
|
|
185
188
|
modelReset: (def) => `🧠 Model reset to default (${def}).`,
|
|
189
|
+
memoryEmpty: "No memory yet. Use `/remember <text>` to add.",
|
|
190
|
+
memoryShow: (m) => `💾 Memory:\n\`\`\`\n${m}\n\`\`\``,
|
|
191
|
+
memoryCleared: "🧹 Memory cleared.",
|
|
192
|
+
remembered: "💾 Saved to memory.",
|
|
193
|
+
rememberUsage: "Usage: /remember <text to remember>",
|
|
194
|
+
memoryUsage: "Usage: /memory · /memory clear",
|
|
186
195
|
},
|
|
187
196
|
ko: {
|
|
188
197
|
help: () =>
|
|
@@ -191,6 +200,8 @@ const STR = {
|
|
|
191
200
|
"• /new — 대화 맥락 초기화 (새 세션)\n" +
|
|
192
201
|
"• /stop — 진행 중인 작업 중단 · /stop --reset 으로 세션도 되돌리기\n" +
|
|
193
202
|
"• /cron — 예약 작업 보기 · /cron add <자연어>로 추가 · /cron rm <번호>로 삭제\n" +
|
|
203
|
+
"• /remember <내용> — 퍼시스턴트 메모리에 저장 (/new 로 초기화해도 유지)\n" +
|
|
204
|
+
"• /memory — 메모리 보기 · /memory clear 로 삭제\n" +
|
|
194
205
|
"• /restart — 봇 재시작 (문법 검사 후 안전하게)\n" +
|
|
195
206
|
"• /status — 봇 상태·버전 보기\n" +
|
|
196
207
|
"• /model — 모델 보기·전환\n" +
|
|
@@ -243,6 +254,12 @@ const STR = {
|
|
|
243
254
|
`/model default — 오버라이드 해제`,
|
|
244
255
|
modelSet: (m) => `🧠 모델을 ${m} (으)로 설정했습니다.`,
|
|
245
256
|
modelReset: (def) => `🧠 모델을 기본값(${def})으로 되돌렸습니다.`,
|
|
257
|
+
memoryEmpty: "저장된 메모리가 없습니다. `/remember <내용>`으로 추가하세요.",
|
|
258
|
+
memoryShow: (m) => `💾 메모리:\n\`\`\`\n${m}\n\`\`\``,
|
|
259
|
+
memoryCleared: "🧹 메모리를 삭제했습니다.",
|
|
260
|
+
remembered: "💾 메모리에 저장했습니다.",
|
|
261
|
+
rememberUsage: "사용법: /remember <기억할 내용>",
|
|
262
|
+
memoryUsage: "사용법: /memory · /memory clear",
|
|
246
263
|
},
|
|
247
264
|
};
|
|
248
265
|
const t = (l, key, ...a) => {
|
|
@@ -258,6 +275,8 @@ const COMMANDS = {
|
|
|
258
275
|
en: [
|
|
259
276
|
{ command: "new", description: "Reset context (new session)" },
|
|
260
277
|
{ command: "stop", description: "Stop the current task (--reset to roll back session)" },
|
|
278
|
+
{ command: "remember", description: "Save to persistent memory (survives /new)" },
|
|
279
|
+
{ command: "memory", description: "View or clear persistent memory" },
|
|
261
280
|
{ command: "cron", description: "List / add / remove scheduled tasks" },
|
|
262
281
|
{ command: "restart", description: "Restart the bot (after syntax check)" },
|
|
263
282
|
{ command: "status", description: "Bot status / version" },
|
|
@@ -268,6 +287,8 @@ const COMMANDS = {
|
|
|
268
287
|
ko: [
|
|
269
288
|
{ command: "new", description: "대화 맥락 초기화 (새 세션)" },
|
|
270
289
|
{ command: "stop", description: "작업 중단 (--reset 으로 세션 되돌리기)" },
|
|
290
|
+
{ command: "remember", description: "퍼시스턴트 메모리에 저장 (/new 후에도 유지)" },
|
|
291
|
+
{ command: "memory", description: "메모리 보기·삭제" },
|
|
271
292
|
{ command: "cron", description: "예약 작업 보기·추가·삭제" },
|
|
272
293
|
{ command: "restart", description: "봇 재시작 (문법 검사 후)" },
|
|
273
294
|
{ command: "status", description: "봇 상태·버전 보기" },
|
|
@@ -294,6 +315,15 @@ function checkLocalLock() {
|
|
|
294
315
|
}
|
|
295
316
|
}
|
|
296
317
|
|
|
318
|
+
// ── 퍼시스턴트 메모리 ─────────────────────────────────────────────────────
|
|
319
|
+
// /new 로 세션을 초기화해도 유지되는 메모리. runClaude 시 시스템 프롬프트에 주입.
|
|
320
|
+
function loadMemory() {
|
|
321
|
+
try { return readFileSync(MEMORY_PATH, "utf8").trim(); } catch { return ""; }
|
|
322
|
+
}
|
|
323
|
+
function saveMemory(content) {
|
|
324
|
+
writeFileSync(MEMORY_PATH, content);
|
|
325
|
+
}
|
|
326
|
+
|
|
297
327
|
// ── 상태 (세션 이어가기용) ────────────────────────────────────────────────
|
|
298
328
|
function loadState() {
|
|
299
329
|
// 새 경로(.claude-bot/) 우선, 없으면 구버전 루트 경로로 폴백(이주 실패 시 안전망).
|
|
@@ -430,8 +460,11 @@ function runClaude(prompt, sessionId, opts = {}) {
|
|
|
430
460
|
const modelHint = opts.modelHint
|
|
431
461
|
? `Current model: ${model || "claude (default)"}. Model tiers (low→high): haiku → sonnet → opus → fable. If this question seems to require more capability than the current model, append one short line at the very end of your reply: 💡 \`/model sonnet\` (or \`/model opus\`, \`/model fable\`) for a stronger answer. Omit the suggestion for simple questions.`
|
|
432
462
|
: null;
|
|
433
|
-
//
|
|
434
|
-
const
|
|
463
|
+
// opts.injectMemory: 퍼시스턴트 메모리를 시스템 프롬프트에 주입 (/new 로 초기화해도 유지)
|
|
464
|
+
const mem = opts.injectMemory ? loadMemory() : "";
|
|
465
|
+
const memoryBlock = mem ? `## Persistent memory (survives /new)\n${mem}` : null;
|
|
466
|
+
// 페르소나(cfg.persona) + 간결 지침 + 모델 힌트 + 메모리를 함께 주입
|
|
467
|
+
const appendSys = [cfg.persona, brevity, modelHint, memoryBlock].filter(Boolean).join("\n\n");
|
|
435
468
|
if (appendSys) args.push("--append-system-prompt", appendSys);
|
|
436
469
|
if (model) args.push("--model", model);
|
|
437
470
|
if (sessionId) args.push("--resume", sessionId);
|
|
@@ -821,6 +854,25 @@ async function handle(msg) {
|
|
|
821
854
|
await send(chatId, t(l, reset ? "stopReset" : "stopOk"));
|
|
822
855
|
return;
|
|
823
856
|
}
|
|
857
|
+
if (text.startsWith("/remember ")) {
|
|
858
|
+
const content = text.slice(10).trim();
|
|
859
|
+
if (!content) { await send(chatId, t(l, "rememberUsage")); return; }
|
|
860
|
+
const existing = loadMemory();
|
|
861
|
+
saveMemory(existing ? `${existing}\n- ${content}` : `- ${content}`);
|
|
862
|
+
await send(chatId, t(l, "remembered"));
|
|
863
|
+
return;
|
|
864
|
+
}
|
|
865
|
+
if (text === "/memory" || text.startsWith("/memory ")) {
|
|
866
|
+
const arg = text.slice(7).trim();
|
|
867
|
+
if (arg === "clear") {
|
|
868
|
+
saveMemory("");
|
|
869
|
+
await send(chatId, t(l, "memoryCleared"));
|
|
870
|
+
return;
|
|
871
|
+
}
|
|
872
|
+
const mem = loadMemory();
|
|
873
|
+
await send(chatId, mem ? t(l, "memoryShow", mem) : t(l, "memoryEmpty"));
|
|
874
|
+
return;
|
|
875
|
+
}
|
|
824
876
|
|
|
825
877
|
if (busy) {
|
|
826
878
|
msgQueue.push({ msg, receivedAt: Date.now() });
|
|
@@ -855,7 +907,7 @@ async function handle(msg) {
|
|
|
855
907
|
}
|
|
856
908
|
}
|
|
857
909
|
prevSessionId = state.sessionId; // /stop --reset 복원 대상 저장
|
|
858
|
-
const res = await runClaude(prompt, state.sessionId, { modelHint: true, trackChild: true });
|
|
910
|
+
const res = await runClaude(prompt, state.sessionId, { modelHint: true, trackChild: true, injectMemory: true });
|
|
859
911
|
if (res.sessionId) {
|
|
860
912
|
state.sessionId = res.sessionId;
|
|
861
913
|
saveState(state);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-telegram-bot",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.2",
|
|
4
4
|
"description": "Drive Claude Code from Telegram — messages run headless `claude -p` in a project dir and replies come back to the chat. Zero dependencies.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|