[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-openclaw-openclaw-skills-session-logs":3},{"error":4,"detail":5,"metadata":23,"markdownContent":25,"rawMarkdown":20},false,{"repo_full_name":6,"owner":7,"repo_name":7,"repo_forks":8,"skill_path":9,"repo_stars":10,"name":11,"category_id":12,"description":13,"file_tree":14,"skill_md_content":20,"skill_id":21,"skill_key":22},"openclaw/openclaw","openclaw",64359,"skills/session-logs",330752,"session-logs",13,"Search and analyze your own session logs (older/parent conversations) using jq.",[15],{"name":16,"path":17,"size":18,"type":19},"SKILL.md","skills/session-logs/SKILL.md",3429,"file","---\nname: session-logs\ndescription: Search and analyze your own session logs (older/parent conversations) using jq.\nmetadata: { \"openclaw\": { \"emoji\": \"📜\", \"requires\": { \"bins\": [\"jq\", \"rg\"] } } }\n---\n\n# session-logs\n\nSearch your complete conversation history stored in session JSONL files. Use this when a user references older/parent conversations or asks what was said before.\n\n## Trigger\n\nUse this skill when the user asks about prior chats, parent conversations, or historical context that isn't in memory files.\n\n## Location\n\nSession logs live at: `~/.openclaw/agents/\u003CagentId>/sessions/` (use the `agent=\u003Cid>` value from the system prompt Runtime line).\n\n- **`sessions.json`** - Index mapping session keys to session IDs\n- **`\u003Csession-id>.jsonl`** - Full conversation transcript per session\n\n## Structure\n\nEach `.jsonl` file contains messages with:\n\n- `type`: \"session\" (metadata) or \"message\"\n- `timestamp`: ISO timestamp\n- `message.role`: \"user\", \"assistant\", or \"toolResult\"\n- `message.content[]`: Text, thinking, or tool calls (filter `type==\"text\"` for human-readable content)\n- `message.usage.cost.total`: Cost per response\n\n## Common Queries\n\n### List all sessions by date and size\n\n```bash\nfor f in ~/.openclaw/agents/\u003CagentId>/sessions/*.jsonl; do\n  date=$(head -1 \"$f\" | jq -r '.timestamp' | cut -dT -f1)\n  size=$(ls -lh \"$f\" | awk '{print $5}')\n  echo \"$date $size $(basename $f)\"\ndone | sort -r\n```\n\n### Find sessions from a specific day\n\n```bash\nfor f in ~/.openclaw/agents/\u003CagentId>/sessions/*.jsonl; do\n  head -1 \"$f\" | jq -r '.timestamp' | grep -q \"2026-01-06\" && echo \"$f\"\ndone\n```\n\n### Extract user messages from a session\n\n```bash\njq -r 'select(.message.role == \"user\") | .message.content[]? | select(.type == \"text\") | .text' \u003Csession>.jsonl\n```\n\n### Search for keyword in assistant responses\n\n```bash\njq -r 'select(.message.role == \"assistant\") | .message.content[]? | select(.type == \"text\") | .text' \u003Csession>.jsonl | rg -i \"keyword\"\n```\n\n### Get total cost for a session\n\n```bash\njq -s '[.[] | .message.usage.cost.total // 0] | add' \u003Csession>.jsonl\n```\n\n### Daily cost summary\n\n```bash\nfor f in ~/.openclaw/agents/\u003CagentId>/sessions/*.jsonl; do\n  date=$(head -1 \"$f\" | jq -r '.timestamp' | cut -dT -f1)\n  cost=$(jq -s '[.[] | .message.usage.cost.total // 0] | add' \"$f\")\n  echo \"$date $cost\"\ndone | awk '{a[$1]+=$2} END {for(d in a) print d, \"$\"a[d]}' | sort -r\n```\n\n### Count messages and tokens in a session\n\n```bash\njq -s '{\n  messages: length,\n  user: [.[] | select(.message.role == \"user\")] | length,\n  assistant: [.[] | select(.message.role == \"assistant\")] | length,\n  first: .[0].timestamp,\n  last: .[-1].timestamp\n}' \u003Csession>.jsonl\n```\n\n### Tool usage breakdown\n\n```bash\njq -r '.message.content[]? | select(.type == \"toolCall\") | .name' \u003Csession>.jsonl | sort | uniq -c | sort -rn\n```\n\n### Search across ALL sessions for a phrase\n\n```bash\nrg -l \"phrase\" ~/.openclaw/agents/\u003CagentId>/sessions/*.jsonl\n```\n\n## Tips\n\n- Sessions are append-only JSONL (one JSON object per line)\n- Large sessions can be several MB - use `head`/`tail` for sampling\n- The `sessions.json` index maps chat providers (discord, whatsapp, etc.) to session IDs\n- Deleted sessions have `.deleted.\u003Ctimestamp>` suffix\n\n## Fast text-only hint (low noise)\n\n```bash\njq -r 'select(.type==\"message\") | .message.content[]? | select(.type==\"text\") | .text' ~/.openclaw/agents/\u003CagentId>/sessions/\u003Cid>.jsonl | rg 'keyword'\n```\n","902add8d-6693-5191-9867-7a5381506d2e","openclaw-openclaw-skills-session-logs",{"name":11,"description":13,"metadata":24},"{ \"openclaw\": { \"emoji\": \"📜\", \"requires\": { \"bins\": [\"jq\", \"rg\"] } } }","\u003Ch1>session-logs\u003C/h1>\n\u003Cp>Search your complete conversation history stored in session JSONL files. Use this when a user references older/parent conversations or asks what was said before.\u003C/p>\n\u003Ch2>Trigger\u003C/h2>\n\u003Cp>Use this skill when the user asks about prior chats, parent conversations, or historical context that isn&#39;t in memory files.\u003C/p>\n\u003Ch2>Location\u003C/h2>\n\u003Cp>Session logs live at: \u003Ccode>~/.openclaw/agents/&lt;agentId&gt;/sessions/\u003C/code> (use the \u003Ccode>agent=&lt;id&gt;\u003C/code> value from the system prompt Runtime line).\u003C/p>\n\u003Cul>\n\u003Cli>\u003Cstrong>\u003Ccode>sessions.json\u003C/code>\u003C/strong> - Index mapping session keys to session IDs\u003C/li>\n\u003Cli>\u003Cstrong>\u003Ccode>&lt;session-id&gt;.jsonl\u003C/code>\u003C/strong> - Full conversation transcript per session\u003C/li>\n\u003C/ul>\n\u003Ch2>Structure\u003C/h2>\n\u003Cp>Each \u003Ccode>.jsonl\u003C/code> file contains messages with:\u003C/p>\n\u003Cul>\n\u003Cli>\u003Ccode>type\u003C/code>: &quot;session&quot; (metadata) or &quot;message&quot;\u003C/li>\n\u003Cli>\u003Ccode>timestamp\u003C/code>: ISO timestamp\u003C/li>\n\u003Cli>\u003Ccode>message.role\u003C/code>: &quot;user&quot;, &quot;assistant&quot;, or &quot;toolResult&quot;\u003C/li>\n\u003Cli>\u003Ccode>message.content[]\u003C/code>: Text, thinking, or tool calls (filter \u003Ccode>type==&quot;text&quot;\u003C/code> for human-readable content)\u003C/li>\n\u003Cli>\u003Ccode>message.usage.cost.total\u003C/code>: Cost per response\u003C/li>\n\u003C/ul>\n\u003Ch2>Common Queries\u003C/h2>\n\u003Ch3>List all sessions by date and size\u003C/h3>\n\u003Cdiv class=\"md-code-block\">\u003Cdiv class=\"md-code-lang\">bash\u003C/div>\u003Cpre>\u003Ccode class=\"hljs language-bash\">\u003Cspan class=\"hljs-keyword\">for\u003C/span> f \u003Cspan class=\"hljs-keyword\">in\u003C/span> ~/.openclaw/agents/&lt;agentId&gt;/sessions/*.jsonl; \u003Cspan class=\"hljs-keyword\">do\u003C/span>\n  \u003Cspan class=\"hljs-built_in\">date\u003C/span>=$(\u003Cspan class=\"hljs-built_in\">head\u003C/span> -1 \u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-variable\">$f\u003C/span>&quot;\u003C/span> | jq -r \u003Cspan class=\"hljs-string\">&#x27;.timestamp&#x27;\u003C/span> | \u003Cspan class=\"hljs-built_in\">cut\u003C/span> -dT -f1)\n  size=$(\u003Cspan class=\"hljs-built_in\">ls\u003C/span> -lh \u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-variable\">$f\u003C/span>&quot;\u003C/span> | awk \u003Cspan class=\"hljs-string\">&#x27;{print $5}&#x27;\u003C/span>)\n  \u003Cspan class=\"hljs-built_in\">echo\u003C/span> \u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-variable\">$date\u003C/span> \u003Cspan class=\"hljs-variable\">$size\u003C/span> \u003Cspan class=\"hljs-subst\">$(basename $f)\u003C/span>&quot;\u003C/span>\n\u003Cspan class=\"hljs-keyword\">done\u003C/span> | \u003Cspan class=\"hljs-built_in\">sort\u003C/span> -r\u003C/code>\u003C/pre>\u003C/div>\u003Ch3>Find sessions from a specific day\u003C/h3>\n\u003Cdiv class=\"md-code-block\">\u003Cdiv class=\"md-code-lang\">bash\u003C/div>\u003Cpre>\u003Ccode class=\"hljs language-bash\">\u003Cspan class=\"hljs-keyword\">for\u003C/span> f \u003Cspan class=\"hljs-keyword\">in\u003C/span> ~/.openclaw/agents/&lt;agentId&gt;/sessions/*.jsonl; \u003Cspan class=\"hljs-keyword\">do\u003C/span>\n  \u003Cspan class=\"hljs-built_in\">head\u003C/span> -1 \u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-variable\">$f\u003C/span>&quot;\u003C/span> | jq -r \u003Cspan class=\"hljs-string\">&#x27;.timestamp&#x27;\u003C/span> | grep -q \u003Cspan class=\"hljs-string\">&quot;2026-01-06&quot;\u003C/span> &amp;&amp; \u003Cspan class=\"hljs-built_in\">echo\u003C/span> \u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-variable\">$f\u003C/span>&quot;\u003C/span>\n\u003Cspan class=\"hljs-keyword\">done\u003C/span>\u003C/code>\u003C/pre>\u003C/div>\u003Ch3>Extract user messages from a session\u003C/h3>\n\u003Cdiv class=\"md-code-block\">\u003Cdiv class=\"md-code-lang\">bash\u003C/div>\u003Cpre>\u003Ccode class=\"hljs language-bash\">jq -r \u003Cspan class=\"hljs-string\">&#x27;select(.message.role == &quot;user&quot;) | .message.content[]? | select(.type == &quot;text&quot;) | .text&#x27;\u003C/span> &lt;session&gt;.jsonl\u003C/code>\u003C/pre>\u003C/div>\u003Ch3>Search for keyword in assistant responses\u003C/h3>\n\u003Cdiv class=\"md-code-block\">\u003Cdiv class=\"md-code-lang\">bash\u003C/div>\u003Cpre>\u003Ccode class=\"hljs language-bash\">jq -r \u003Cspan class=\"hljs-string\">&#x27;select(.message.role == &quot;assistant&quot;) | .message.content[]? | select(.type == &quot;text&quot;) | .text&#x27;\u003C/span> &lt;session&gt;.jsonl | rg -i \u003Cspan class=\"hljs-string\">&quot;keyword&quot;\u003C/span>\u003C/code>\u003C/pre>\u003C/div>\u003Ch3>Get total cost for a session\u003C/h3>\n\u003Cdiv class=\"md-code-block\">\u003Cdiv class=\"md-code-lang\">bash\u003C/div>\u003Cpre>\u003Ccode class=\"hljs language-bash\">jq -s \u003Cspan class=\"hljs-string\">&#x27;[.[] | .message.usage.cost.total // 0] | add&#x27;\u003C/span> &lt;session&gt;.jsonl\u003C/code>\u003C/pre>\u003C/div>\u003Ch3>Daily cost summary\u003C/h3>\n\u003Cdiv class=\"md-code-block\">\u003Cdiv class=\"md-code-lang\">bash\u003C/div>\u003Cpre>\u003Ccode class=\"hljs language-bash\">\u003Cspan class=\"hljs-keyword\">for\u003C/span> f \u003Cspan class=\"hljs-keyword\">in\u003C/span> ~/.openclaw/agents/&lt;agentId&gt;/sessions/*.jsonl; \u003Cspan class=\"hljs-keyword\">do\u003C/span>\n  \u003Cspan class=\"hljs-built_in\">date\u003C/span>=$(\u003Cspan class=\"hljs-built_in\">head\u003C/span> -1 \u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-variable\">$f\u003C/span>&quot;\u003C/span> | jq -r \u003Cspan class=\"hljs-string\">&#x27;.timestamp&#x27;\u003C/span> | \u003Cspan class=\"hljs-built_in\">cut\u003C/span> -dT -f1)\n  cost=$(jq -s \u003Cspan class=\"hljs-string\">&#x27;[.[] | .message.usage.cost.total // 0] | add&#x27;\u003C/span> \u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-variable\">$f\u003C/span>&quot;\u003C/span>)\n  \u003Cspan class=\"hljs-built_in\">echo\u003C/span> \u003Cspan class=\"hljs-string\">&quot;\u003Cspan class=\"hljs-variable\">$date\u003C/span> \u003Cspan class=\"hljs-variable\">$cost\u003C/span>&quot;\u003C/span>\n\u003Cspan class=\"hljs-keyword\">done\u003C/span> | awk \u003Cspan class=\"hljs-string\">&#x27;{a[$1]+=$2} END {for(d in a) print d, &quot;$&quot;a[d]}&#x27;\u003C/span> | \u003Cspan class=\"hljs-built_in\">sort\u003C/span> -r\u003C/code>\u003C/pre>\u003C/div>\u003Ch3>Count messages and tokens in a session\u003C/h3>\n\u003Cdiv class=\"md-code-block\">\u003Cdiv class=\"md-code-lang\">bash\u003C/div>\u003Cpre>\u003Ccode class=\"hljs language-bash\">jq -s \u003Cspan class=\"hljs-string\">&#x27;{\n  messages: length,\n  user: [.[] | select(.message.role == &quot;user&quot;)] | length,\n  assistant: [.[] | select(.message.role == &quot;assistant&quot;)] | length,\n  first: .[0].timestamp,\n  last: .[-1].timestamp\n}&#x27;\u003C/span> &lt;session&gt;.jsonl\u003C/code>\u003C/pre>\u003C/div>\u003Ch3>Tool usage breakdown\u003C/h3>\n\u003Cdiv class=\"md-code-block\">\u003Cdiv class=\"md-code-lang\">bash\u003C/div>\u003Cpre>\u003Ccode class=\"hljs language-bash\">jq -r \u003Cspan class=\"hljs-string\">&#x27;.message.content[]? | select(.type == &quot;toolCall&quot;) | .name&#x27;\u003C/span> &lt;session&gt;.jsonl | \u003Cspan class=\"hljs-built_in\">sort\u003C/span> | \u003Cspan class=\"hljs-built_in\">uniq\u003C/span> -c | \u003Cspan class=\"hljs-built_in\">sort\u003C/span> -rn\u003C/code>\u003C/pre>\u003C/div>\u003Ch3>Search across ALL sessions for a phrase\u003C/h3>\n\u003Cdiv class=\"md-code-block\">\u003Cdiv class=\"md-code-lang\">bash\u003C/div>\u003Cpre>\u003Ccode class=\"hljs language-bash\">rg -l \u003Cspan class=\"hljs-string\">&quot;phrase&quot;\u003C/span> ~/.openclaw/agents/&lt;agentId&gt;/sessions/*.jsonl\u003C/code>\u003C/pre>\u003C/div>\u003Ch2>Tips\u003C/h2>\n\u003Cul>\n\u003Cli>Sessions are append-only JSONL (one JSON object per line)\u003C/li>\n\u003Cli>Large sessions can be several MB - use \u003Ccode>head\u003C/code>/\u003Ccode>tail\u003C/code> for sampling\u003C/li>\n\u003Cli>The \u003Ccode>sessions.json\u003C/code> index maps chat providers (discord, whatsapp, etc.) to session IDs\u003C/li>\n\u003Cli>Deleted sessions have \u003Ccode>.deleted.&lt;timestamp&gt;\u003C/code> suffix\u003C/li>\n\u003C/ul>\n\u003Ch2>Fast text-only hint (low noise)\u003C/h2>\n\u003Cdiv class=\"md-code-block\">\u003Cdiv class=\"md-code-lang\">bash\u003C/div>\u003Cpre>\u003Ccode class=\"hljs language-bash\">jq -r \u003Cspan class=\"hljs-string\">&#x27;select(.type==&quot;message&quot;) | .message.content[]? | select(.type==&quot;text&quot;) | .text&#x27;\u003C/span> ~/.openclaw/agents/&lt;agentId&gt;/sessions/&lt;\u003Cspan class=\"hljs-built_in\">id\u003C/span>&gt;.jsonl | rg \u003Cspan class=\"hljs-string\">&#x27;keyword&#x27;\u003C/span>\u003C/code>\u003C/pre>\u003C/div>"]