feat: per-agent, per-device import profiles#240
Merged
Conversation
Add Session.Profile with the DefaultProfile constant and ProfileOrDefault helper, plus a profile field on the wire Session, ListRequest, and SearchRequest messages (regenerated). Empty normalises to "default", so existing rows and older clients keep working; no projection bump is needed. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add RootsUnder(base) to the Importer contract so each importer derives its own scan subpath from a profile's base directory; DefaultRoots now delegates to it. ImportOptions.Profile carries the source profile, which the shared single-file helper and the bespoke Hermes path stamp onto each session. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Local migration 0009 adds sessions.profile (default 'default') plus a (device_id, agent, profile) index. Read and write the column, filter ListSessions by profile, and add ProfileCounts plus the analytics "profiles" report. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Server migration 0011 mirrors the local column. Push upserts it; List, Search, Get, and ListChildren select, group, scan, and filter by profile (single and multi-select), and a new "profiles" analytics report breaks sessions down by device, agent, and profile. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
New internal/profiles config (profiles.json) resolves each agent's effective profiles: a synthesized default plus configured extras. prosa profiles list/add/remove/set-path manages them; sync threads the per-profile name into each import; and a global --profile filter narrows the timeline, search, and analytics. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add a profile multi-select to the Sessions filter, a Profile row in the session side panel, and a /profiles breakdown page (device x agent x profile) linking into filtered session views. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Update INTENT, the importer/canonical-session/store/cli architecture docs, the Codex source notes (CODEX_HOME example), and the usage guide for the profiles concept, the prosa profiles command, and the --profile filter. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Trim the profiles feature's comments to the repo's sparse style: drop narration of self-evident code and compress multi-line docstrings to one or two lines. No behaviour change. gen/ regenerated from the trimmed proto. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…36.0 The committed file was generated by a newer protoc-gen-go than the v1.36.0 pinned in .justfile, so CI's gen-check (which regenerates with the pinned toolchain) saw a diff and failed. Regenerate with v1.36.0. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
# Conflicts: # internal/server/handlers/analytics.go
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Each importer only ever read one location per agent (e.g. Codex →
~/.codex/sessions), so sessions from a secondCODEX_HOME, workspace, or config dir were invisible. This adds a generic profile concept: a named per-agent, per-device location. Every agent keeps adefaultprofile pointing at its current path, so behaviour is unchanged until you configure more.What
Profileon the canonical session + aprofilecolumn on both schemas (local/0009,server/0011, default'default', indexed by(device_id, agent, profile)) and on the protoSession. NoProjectionVersionbump — the column default backfills existing rows.Importer.RootsUnder(base)lets each importer derive its own scan subpath from a profile's home dir (codex→/sessions, claude→/projects, …). No Codex-specific code in the sync/config layers.profiles.json(internal/profiles) — the name→path registry; only the name is pushed to the server.prosa profiles list | add | remove | set-pathand a global--profilefilter (timeline, search, analytics; local + remote).profilesanalytics report (device × agent × profile).Profilerow in session detail, and a/profilesbreakdown page.Decisions
profiles.json+ aprofilename column on sessions (no DB table)idstays the global PK; raw paths unchangedCompatibility
profiles.json→ only the synthesizeddefault→ identical to today.defaultvia the column default.prosa sync --overwrite(the raw hash is unchanged otherwise).Verification
just gen-check,vet,golangci-lint,test-race,lint-md,tidy-check, and the CLI integration test all pass. Verified end-to-end: a configuredworkprofile imports from its own dir, sessions are tagged,--profile work/--profile defaultfilter correctly, andanalytics profilesshows the device × agent × profile breakdown.🤖 Generated with Claude Code
Need help on this PR? Tag
/codesmithwith what you need. Autofix is disabled.