(config)
| 34 | const SOUL_CACHE_TTL = 5000 // Re-read every 5s (hot-reload) |
| 35 | |
| 36 | function loadSoulPrefix(config) { |
| 37 | const workspaceDir = config.workspaceDir || process.env.CLAW_WORKSPACE_DIR || '' |
| 38 | if (!workspaceDir) return '' |
| 39 | |
| 40 | const now = Date.now() |
| 41 | if (_soulCache && now - _soulLastRead < SOUL_CACHE_TTL) return _soulCache |
| 42 | |
| 43 | const bootstrapDir = path.join(workspaceDir, '.claw', 'bootstrap') |
| 44 | const priority = ['SOUL.md', 'IDENTITY.md', 'USER.md', 'CONTEXT.md'] |
| 45 | |
| 46 | try { |
| 47 | const files = fs.readdirSync(bootstrapDir).filter(f => f.endsWith('.md')) |
| 48 | const sorted = [ |
| 49 | ...priority.filter(p => files.includes(p)), |
| 50 | ...files.filter(f => !priority.includes(f)).sort(), |
| 51 | ] |
| 52 | |
| 53 | let assembled = '' |
| 54 | for (const name of sorted) { |
| 55 | try { |
| 56 | let content = fs.readFileSync(path.join(bootstrapDir, name), 'utf8') |
| 57 | if (content.length > 20000) content = content.slice(0, 20000) + '\n[...truncated]' |
| 58 | assembled += content + '\n\n' |
| 59 | if (assembled.length > 80000) break |
| 60 | } catch { /* skip */ } |
| 61 | } |
| 62 | _soulCache = assembled.trim() |
| 63 | _soulLastRead = now |
| 64 | return _soulCache |
| 65 | } catch { |
| 66 | return '' |
| 67 | } |
| 68 | } |
| 69 | |
| 70 | // ── Memory injection ──────────────────────────────────── |
| 71 | // Reads .claw/memory/MEMORY.md index + topics/*.md + recent daily logs. |
no outgoing calls
no test coverage detected