#!/usr/bin/env bash # ollie:parallel read # ollie:tier cold # args_json: {"type":"object","required":["query"],"properties":{"query":{"type":"string","description":"Search keyword or phrase"}}} # ollie:prompt # ## memory_recall # # Search stored memories for relevant context. # # **Trigger condition**: ALWAYS recall before exploring code or starting work on a task. Memory is a first-class source of context — check it before reading files or running commands. # # **Calling convention**: # ``` # memory_recall(query="keyword") # ``` # - `query`: single keyword or short term. Prefer single keywords over phrases. # # **Returns**: matching memory files. # # **Constraints**: # - Recall at the start of a topic, not mid-task. # - If recall returns nothing relevant, proceed without it. # ollie:end source "$(dirname "$0")/_lib/args.sh" query=$(arg_require "query") mem_dir="${XDG_CONFIG_HOME:-$HOME/.config}/ollie/memory" [ ! -d "$mem_dir" ] && echo "error: memory directory does not exist: $mem_dir" && exit 1 max_files=10 max_lines=50 stale_days=14 now=$(date +%s) matches=$(grep -ril --include='*.md' "$query" "$mem_dir" 2>/dev/null) [ -z "$matches" ] && echo "no matches for: $query" && exit 0 total=$(echo "$matches" | wc -l) count=0 while IFS= read -r file; do count=$((count + 1)) [ $count -gt $max_files ] && echo "(showing $max_files of $total matched files)" && break fname=$(basename "$file") ts=${fname%%__*} if [[ $ts =~ ^([0-9]{4})([0-9]{2})([0-9]{2})T ]]; then fdate=$(date -d "${BASH_REMATCH[1]}-${BASH_REMATCH[2]}-${BASH_REMATCH[3]}" +%s 2>/dev/null) [ -n "$fdate" ] && age_days=$(( (now - fdate) / 86400 )) || age_days=0 else age_days=0 fi [ $age_days -ge $stale_days ] && status="STALE (${age_days}d)" || status="fresh" echo "=== $fname [$status] ===" awk -v max="$max_lines" 'NR<=max{print} NR>max{over++} END{if(over) printf "... (%d lines total, showing first %d)\n", NR, max}' "$file" 2>/dev/null || echo "error: could not read $file" echo done <<< "$matches"