{"id":50234707,"url":"https://github.com/spences10/pirecall","last_synced_at":"2026-07-04T17:30:39.254Z","repository":{"id":351629718,"uuid":"1208680347","full_name":"spences10/pirecall","owner":"spences10","description":"🔄️ Sync pi.dev agent sessions to SQLite for analytics, uses node:sqlite","archived":false,"fork":false,"pushed_at":"2026-06-28T11:41:45.000Z","size":160,"stargazers_count":3,"open_issues_count":2,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-28T13:19:52.217Z","etag":null,"topics":["node-sqlite","pi-coding-agent","pi-dev","sqlite"],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/spences10.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-12T15:57:50.000Z","updated_at":"2026-06-28T11:41:46.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/spences10/pirecall","commit_stats":null,"previous_names":["spences10/pirecall"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/spences10/pirecall","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spences10%2Fpirecall","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spences10%2Fpirecall/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spences10%2Fpirecall/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spences10%2Fpirecall/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/spences10","download_url":"https://codeload.github.com/spences10/pirecall/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spences10%2Fpirecall/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35130722,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-04T02:00:05.987Z","response_time":113,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["node-sqlite","pi-coding-agent","pi-dev","sqlite"],"created_at":"2026-05-26T19:00:32.278Z","updated_at":"2026-07-04T17:30:39.249Z","avatar_url":"https://github.com/spences10.png","language":"TypeScript","funding_links":[],"categories":["Miscellaneous"],"sub_categories":[],"readme":"# pirecall\n\n[![built with vite+](https://img.shields.io/badge/built%20with-Vite+-646CFF?logo=vite\u0026logoColor=white)](https://viteplus.dev)\n[![tested with vitest](https://img.shields.io/badge/tested%20with-Vitest-6E9F18?logo=vitest\u0026logoColor=white)](https://vitest.dev)\n\nSync [pi.dev](https://pi.dev) agent sessions to SQLite for analytics.\nQuery your session history, token usage, tool calls, cost, and model\nswitches.\n\n## Quick Start\n\nUse pirecall inline in pi sessions. Tell the agent:\n\n```\n\"run npx pirecall sync then show me my top 5 projects by token usage\"\n\n\"use npx pirecall search to find sessions where we discussed database migrations\"\n\n\"run npx pirecall stats and tell me how much I've spent this week\"\n```\n\nThe agent runs the command, gets structured output, and can answer\nfollow-up questions about your session history.\n\n## How It Works\n\nPi stores sessions as JSONL files in `~/.pi/agent/sessions/`. pirecall\nparses these into a SQLite database so you can query across all\nsessions.\n\n**Step 1.** Sync your sessions:\n\n```bash\nnpx pirecall sync\n```\n\n**Step 2.** pirecall incrementally imports new content and reports\nwhat it found:\n\n```\nSynced 24 sessions, 136 messages, 22 tool calls, 59 model changes\n```\n\n**Step 3.** Query the database using any pirecall command or raw SQL:\n\n```bash\nnpx pirecall stats\nnpx pirecall search \"database migration\"\nnpx pirecall query \"SELECT project_path, SUM(cost_total) FROM sessions s JOIN messages m ON m.session_id = s.id GROUP BY project_path ORDER BY 2 DESC LIMIT 5\"\n```\n\n\u003e **Important:** The agent doesn't know about pirecall unless you\n\u003e mention it. Just mention `{npx,pnpx,bunx} pirecall` and the agent\n\u003e will discover subcommands and flags from the CLI output.\n\n## Commands\n\n```bash\nnpx pirecall sync                  # Import sessions (incremental)\nnpx pirecall stats                 # Session/message/token/cost counts\nnpx pirecall sessions              # List recent sessions\nnpx pirecall search \u003cterm\u003e         # Full-text search across messages\nnpx pirecall tools                 # Most-used tools\nnpx pirecall recall \u003cterm\u003e         # LLM-optimised context retrieval\nnpx pirecall query \"\u003csql\u003e\"         # Raw SQL against the database\nnpx pirecall schema                # Show database table structure\nnpx pirecall compact               # Prune old tool results\n```\n\nAll commands support `--json` for programmatic output and\n`-d, --db \u003cpath\u003e` to use a custom database path (default:\n`~/.pi/pirecall.db`).\n\n## Database Schema\n\n```mermaid\nerDiagram\n    sessions ||--o{ messages : contains\n    sessions ||--o{ tool_calls : contains\n    sessions ||--o{ tool_results : contains\n    sessions ||--o{ model_changes : tracks\n    messages ||--o{ tool_calls : has\n    messages ||--o{ tool_results : has\n    tool_calls ||--o{ tool_results : produces\n\n    sessions {\n        text id PK\n        text project_path\n        text cwd\n        int first_timestamp\n        int last_timestamp\n    }\n\n    messages {\n        text id PK\n        text session_id FK\n        text parent_id\n        text type\n        text provider\n        text model\n        text content_text\n        text content_json\n        text thinking\n        int timestamp\n        int input_tokens\n        int output_tokens\n        int cache_read_tokens\n        int cache_write_tokens\n        real cost_total\n    }\n\n    tool_calls {\n        text id PK\n        text message_id FK\n        text session_id FK\n        text tool_name\n        text tool_input\n        int timestamp\n    }\n\n    tool_results {\n        int id PK\n        text tool_call_id FK\n        text message_id FK\n        text session_id FK\n        text content\n        int is_error\n        int timestamp\n    }\n\n    model_changes {\n        text id PK\n        text session_id FK\n        text parent_id\n        text provider\n        text model_id\n        int timestamp\n    }\n\n    sync_state {\n        text file_path PK\n        int last_modified\n        int last_byte_offset\n    }\n```\n\n### Model/Provider Tracking\n\nTracks mid-session model switches from `~/.pi/agent/sessions/`. Pi\nsupports multiple providers (Anthropic, Mistral, etc.) and pirecall\nrecords every switch with provider and model ID.\n\n**Why track model changes?**\n\n- See which models you actually use vs which you think you use\n- Compare cost across providers for similar tasks\n- Debug sessions where model switches caused behaviour changes\n\n## Example Queries\n\n```sql\n-- Cost by session\nSELECT s.project_path, s.id, SUM(m.cost_total) as cost\nFROM sessions s\nJOIN messages m ON m.session_id = s.id\nGROUP BY s.id\nORDER BY cost DESC\nLIMIT 10;\n\n-- Token usage by day\nSELECT DATE(timestamp/1000, 'unixepoch') as day,\n  SUM(input_tokens + output_tokens) as tokens,\n  ROUND(SUM(cost_total), 4) as cost\nFROM messages\nGROUP BY day\nORDER BY day DESC;\n\n-- Model usage across providers\nSELECT provider, model_id, COUNT(*) as switches\nFROM model_changes\nGROUP BY 1, 2\nORDER BY switches DESC;\n\n-- Most used models\nSELECT model, COUNT(*) as count\nFROM messages\nWHERE model IS NOT NULL\nGROUP BY model\nORDER BY count DESC;\n\n-- Tool usage breakdown\nSELECT tool_name, COUNT(*) as count\nFROM tool_calls\nGROUP BY tool_name\nORDER BY count DESC;\n\n-- Files read in a session\nSELECT tc.tool_name, json_extract(tc.tool_input, '$.file_path') as file\nFROM tool_calls tc\nWHERE tc.tool_name = 'read' AND tc.session_id = 'your-session-id';\n\n-- Cost by provider\nSELECT m.provider, ROUND(SUM(m.cost_total), 4) as cost,\n  SUM(m.input_tokens + m.output_tokens) as tokens\nFROM messages m\nWHERE m.provider IS NOT NULL\nGROUP BY m.provider\nORDER BY cost DESC;\n```\n\n## Requirements\n\n- Node.js 22+\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fspences10%2Fpirecall","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fspences10%2Fpirecall","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fspences10%2Fpirecall/lists"}