시어엔진(SearXNG)/로봇청소기 IP가 Claude Code 자신의 프로젝트 메모리에만 있고 homeclaw 챗봇의 memory_write 경로에는 한 번도 안 들어갔던 걸 RAG 업그레이드 조사 중 발견. memory_write와 동일한 경로(USER.md + 벡터스토어)로 백필. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
57 lines
2.6 KiB
TypeScript
57 lines
2.6 KiB
TypeScript
// One-time backfill: two facts (SearXNG nickname, vacuum robot IPs) that turned out to
|
|
// exist only in Claude Code's own project memory (feedback_searxng_nickname.md,
|
|
// project_valetudo_vacuum.md) and had never actually been written into homeclaw's own
|
|
// memory_write/vector-store path — discovered 2026-08-06 while investigating why the RAG
|
|
// hybrid-search upgrade returned 0 hits for "SearXNG 별칭"/"로봇청소기 IP" queries (see
|
|
// project_vector_memory_chroma memory, "남은 과제" correction). Writes through the exact
|
|
// same path memory_write itself uses (USER.md append + addMemoryVector), not a shortcut,
|
|
// so these look native to anything reading either store.
|
|
import fs from 'fs';
|
|
import path from 'path';
|
|
import { addMemoryVector } from '../src/gateway/memory/memory-vector';
|
|
|
|
const WORKSPACE = '/srv/homeclaw/.smallclaw/users/papa/workspace';
|
|
const USER_MD_PATH = path.join(WORKSPACE, 'prompts', 'USER.md');
|
|
const CATEGORY = 'projects';
|
|
|
|
const FACTS = [
|
|
'SearXNG(로컬 메타서치 엔진, localhost:8888)의 별칭은 "시어엔진"이다.',
|
|
'로봇청소기 1호기(Xiaomi SDJQR01RR, Valetudo 설치됨)의 IP는 192.168.0.76이다.',
|
|
'로봇청소기 2호기(Xiaowa E202-01, Valetudo 미지원이라 python-miio로 로컬 제어)의 IP는 192.168.0.87이다.',
|
|
];
|
|
|
|
function appendToUserMd(content: string, date: string) {
|
|
let text = fs.readFileSync(USER_MD_PATH, 'utf-8');
|
|
const entry = `- ${content} [${date}]`;
|
|
const sectionHeader = `## ${CATEGORY}`;
|
|
const sectionIdx = text.indexOf(`\n${sectionHeader}`);
|
|
if (sectionIdx !== -1) {
|
|
const afterHeader = sectionIdx + sectionHeader.length + 1;
|
|
const nextSection = text.indexOf('\n## ', afterHeader);
|
|
const insertAt = nextSection !== -1 ? nextSection : text.length;
|
|
text = text.slice(0, insertAt) + '\n' + entry + text.slice(insertAt);
|
|
} else {
|
|
const closingComment = text.lastIndexOf('\n---');
|
|
const insertAt = closingComment !== -1 ? closingComment : text.length;
|
|
text = text.slice(0, insertAt) + '\n\n' + sectionHeader + '\n' + entry + text.slice(insertAt);
|
|
}
|
|
fs.writeFileSync(USER_MD_PATH, text, 'utf-8');
|
|
}
|
|
|
|
async function main() {
|
|
const date = new Date().toISOString().split('T')[0];
|
|
for (const fact of FACTS) {
|
|
appendToUserMd(fact, date);
|
|
await addMemoryVector({
|
|
id: `${WORKSPACE}:user:${CATEGORY}:${Date.now()}`,
|
|
text: fact,
|
|
metadata: { workspace: WORKSPACE, file: 'user', category: CATEGORY, date },
|
|
});
|
|
console.log('written:', fact);
|
|
await new Promise(r => setTimeout(r, 50)); // keep ids unique (Date.now() granularity)
|
|
}
|
|
console.log('done');
|
|
}
|
|
|
|
main().catch(e => { console.error(e); process.exit(1); });
|