Skip to content

Instantly share code, notes, and snippets.

@bdougie
Created February 15, 2026 18:46
Show Gist options
  • Select an option

  • Save bdougie/ab2de478cf21b307826420f4fa1eccb1 to your computer and use it in GitHub Desktop.

Select an option

Save bdougie/ab2de478cf21b307826420f4fa1eccb1 to your computer and use it in GitHub Desktop.
RFC: Tapes Team Session Sharing

RFC: Tapes Team Session Sharing

Status: Draft
Author: @bdougie
Date: 2026-02-15

Summary

Add team-based session sharing to Tapes, enabling collaborative observability across engineering teams. This includes search capabilities to discover sessions worth sharing, bulk export by day/project, and a dedicated shared sessions view in the deck.


Motivation

Tapes captures valuable context about how teams interact with AI agents—prompts that worked, debugging sessions, cost patterns. Currently this knowledge is siloed per-developer. Teams need to:

  • Learn from each other: See how teammates prompt effectively
  • Debug collaboratively: Share problematic sessions for review
  • Track team usage: Aggregate costs and model preferences
  • Export for analysis: Pull sessions by day or project for reporting

Phase 1: Session Discovery & Export

Goal: Find and export sessions before sharing them.

1.1 Session Search in Deck

Add search to the deck TUI and web UI, mirroring CLI capabilities:

┌─────────────────────────────────────────────────────────────────┐
│ 🔍 Search: contributor.info refactor                            │
├─────────────────────────────────────────────────────────────────┤
│ Filters: [Model ▾] [Project ▾] [Date Range ▾] [Status ▾]       │
├─────────────────────────────────────────────────────────────────┤
│ ● Feb 15  contributor.info  claude-sonnet  $0.42  "refactor..." │
│ ○ Feb 14  contributor.info  gpt-4o         $0.18  "help me..."  │
│ ○ Feb 12  tapes             claude-sonnet  $0.31  "add search"  │
└─────────────────────────────────────────────────────────────────┘
         [Export Selected]  [Share Selected]  [Cancel]

Search capabilities:

  • Full-text search across message content
  • Filter by model, project, date range, status, cost range
  • Sort by date, cost, duration, tokens
  • Multi-select for bulk operations

CLI equivalent:

# Search sessions
tapes search "refactor" --project contributor.info --since 7d

# Interactive search with fuzzy finder
tapes search -i

1.2 Bulk Export

Export sessions by day, project, or custom filter:

# Export all sessions from a specific day
tapes export --date 2026-02-14 -o feb-14-sessions.tape

# Export all sessions for a project
tapes export --project contributor.info -o contributor-sessions.tape

# Export with filters
tapes export --model claude-sonnet --since 30d -o sonnet-sessions.tape

# Export search results
tapes search "debugging" | tapes export -o debug-sessions.tape

Export formats:

  • .tape - Native bundle (gzipped JSON, includes merkle nodes)
  • .json - Plain JSON for analysis
  • .csv - Spreadsheet-friendly (metadata only)

Bundle structure:

{
  "version": 1,
  "format": "tape-bundle",
  "exported_at": "2026-02-15T18:00:00Z",
  "exported_by": "bdougie",
  "filter": {
    "project": "contributor.info",
    "date": "2026-02-14"
  },
  "sessions": [
    {
      "id": "abc123",
      "project": "contributor.info",
      "model": "claude-sonnet-4-20250514",
      "start_time": "2026-02-14T09:30:00Z",
      "end_time": "2026-02-14T09:45:00Z",
      "total_cost": 0.42,
      "input_tokens": 12500,
      "output_tokens": 3200,
      "nodes": [/* merkle nodes with content */],
      "facets": {/* extracted facets */}
    }
  ],
  "checksum": "sha256:..."
}

Phase 2: Team Sharing

Goal: Share sessions with teammates and track what's been shared.

2.1 Data Model

-- Users (synced from auth provider)
CREATE TABLE users (
  id TEXT PRIMARY KEY,
  email TEXT UNIQUE NOT NULL,
  name TEXT,
  avatar_url TEXT,
  github_username TEXT,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- Teams
CREATE TABLE teams (
  id TEXT PRIMARY KEY,
  name TEXT NOT NULL,
  slug TEXT UNIQUE NOT NULL,
  owner_id TEXT NOT NULL REFERENCES users(id),
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- Team membership
CREATE TABLE team_members (
  team_id TEXT NOT NULL REFERENCES teams(id) ON DELETE CASCADE,
  user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
  role TEXT NOT NULL DEFAULT 'member', -- 'owner', 'admin', 'member'
  joined_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (team_id, user_id)
);

-- Team invites
CREATE TABLE team_invites (
  code TEXT PRIMARY KEY,
  team_id TEXT NOT NULL REFERENCES teams(id) ON DELETE CASCADE,
  created_by TEXT NOT NULL REFERENCES users(id),
  email TEXT, -- optional: restrict to specific email
  expires_at TIMESTAMP NOT NULL,
  max_uses INTEGER DEFAULT 1,
  uses INTEGER DEFAULT 0,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- Shared sessions (tracks what's been shared)
CREATE TABLE shared_sessions (
  id TEXT PRIMARY KEY,
  session_id TEXT NOT NULL, -- reference to local session root hash
  team_id TEXT NOT NULL REFERENCES teams(id) ON DELETE CASCADE,
  shared_by TEXT NOT NULL REFERENCES users(id),
  title TEXT, -- optional title/description
  note TEXT, -- optional sharing note
  visibility TEXT NOT NULL DEFAULT 'team', -- 'team', 'public'
  shared_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  expires_at TIMESTAMP, -- optional expiry
  view_count INTEGER DEFAULT 0,
  UNIQUE(session_id, team_id)
);

-- Session sync state (for pulling shared sessions locally)
CREATE TABLE session_sync (
  session_id TEXT PRIMARY KEY,
  team_id TEXT NOT NULL,
  shared_by TEXT NOT NULL,
  synced_at TIMESTAMP,
  local_path TEXT -- path to local .tape file if downloaded
);

2.2 Sharing Flow

Share a session:

# Share to your team
tapes share <session-id>
# → Shared to "Paper Compute" team
# → https://tapes.dev/t/papercompute/s/Xk9mZ2

# Share with a note
tapes share <session-id> --note "Good example of multi-file refactor"

# Share publicly (anyone with link)
tapes share <session-id> --public

# Share with expiry
tapes share <session-id> --expires 7d

# Bulk share from search
tapes search "debugging" --since 7d | tapes share --note "Debug sessions this week"

In Deck UI:

┌─ Session: abc123 ─────────────────────────────────────────────┐
│ contributor.info • claude-sonnet • $0.42 • 15 min            │
├───────────────────────────────────────────────────────────────┤
│ [Share to Team] [Export] [Copy Link] [Delete]                │
│                                                               │
│ Share to: [Paper Compute ▾]                                  │
│ Note: Good example of multi-file refactor___________         │
│ Visibility: ○ Team only  ● Anyone with link                  │
│ Expires: [Never ▾]                                           │
│                                                               │
│                              [Cancel] [Share]                │
└───────────────────────────────────────────────────────────────┘

2.3 Shared Sessions View in Deck

New tab/section in deck showing sessions shared with you:

┌─ Deck ──────────────────────────────────────────────────────────┐
│ [My Sessions] [Shared with Me] [Team Activity]                  │
├─────────────────────────────────────────────────────────────────┤
│ 🔍 Search shared sessions...                                    │
├─────────────────────────────────────────────────────────────────┤
│ TODAY                                                           │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ 👤 alice shared "Debug session for issue #423"              │ │
│ │    tapes • claude-sonnet • $0.31 • 2h ago                   │ │
│ │    "Check out how I traced the race condition"              │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ 👤 bob shared "Cost optimization experiment"                │ │
│ │    api-service • gpt-4o-mini • $0.08 • 5h ago               │ │
│ └─────────────────────────────────────────────────────────────┘ │
│                                                                 │
│ THIS WEEK                                                       │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ 👤 alice shared 3 sessions from contributor.info            │ │
│ │    Feb 12 • Total: $1.24                                    │ │
│ └─────────────────────────────────────────────────────────────┘ │
├─────────────────────────────────────────────────────────────────┤
│ [Import All] [Mark as Read]                    Showing 5 of 12 │
└─────────────────────────────────────────────────────────────────┘

Features:

  • Chronological feed of shared sessions
  • Inline notes from sharer
  • One-click import to local deck
  • Filter by teammate, project, date
  • Unread indicators
  • Search within shared sessions

2.4 Team Management

# Create a team
tapes team create "Paper Compute"
# → Team created! Invite link: https://tapes.dev/join/abc123

# Generate invite link
tapes team invite
# → https://tapes.dev/join/xyz789 (expires in 7 days)

# Invite by email
tapes team invite alice@example.com

# Join a team
tapes team join <code>

# List teams
tapes team list

# List members
tapes team members

# Leave a team  
tapes team leave

# Remove member (admin/owner only)
tapes team remove alice@example.com

2.5 Visibility & Access Control

Visibility levels:

Level Who can view
private Only you
team Team members only
public Anyone with the link

Auto-visibility (optional, configurable):

# Set default visibility for a project
tapes config set default-visibility.contributor.info team
tapes config set default-visibility.personal-notes private

Access control logic:

func canViewSession(viewer User, session SharedSession) bool {
    // Owner can always view
    if session.SharedBy == viewer.ID {
        return true
    }
    
    // Check visibility
    switch session.Visibility {
    case "public":
        return true
    case "team":
        return isTeamMember(viewer.ID, session.TeamID)
    default:
        return false
    }
}

Phase 3: Team Analytics Dashboard

Goal: Aggregate insights across the team.

3.1 Team Dashboard

┌─ Team: Paper Compute ───────────────────────────────────────────┐
│ [Overview] [Members] [Shared Sessions] [Settings]               │
├─────────────────────────────────────────────────────────────────┤
│ 📊 Last 30 Days                                    [▾ 30 days] │
├──────────────┬──────────────┬──────────────┬───────────────────┤
│ Sessions     │ Total Cost   │ Avg/Session  │ Total Tokens      │
│ 247          │ $142.50      │ $0.58        │ 2.4M              │
│ ↑ 23%        │ ↑ 15%        │ ↓ 8%         │ ↑ 31%             │
├──────────────┴──────────────┴──────────────┴───────────────────┤
│                                                                 │
│ Activity by Member            │ Model Usage                     │
│ ████████████ alice    42%     │ ████████ claude-sonnet   58%   │
│ ████████ bob          31%     │ ████ gpt-4o              24%   │
│ ████ charlie          18%     │ ██ gpt-4o-mini           12%   │
│ ██ you                 9%     │ █ claude-haiku            6%   │
│                               │                                 │
├───────────────────────────────┴─────────────────────────────────┤
│ 📈 Daily Activity                                               │
│     ▂▃▅▇█▆▄▃▂▃▄▅▆▇█▇▅▄▃▂▁▂▃▄▅▆▇█▆                              │
│     |-------- Feb --------|                                     │
├─────────────────────────────────────────────────────────────────┤
│ Top Projects                  │ Recent Shared                   │
│ 1. contributor.info   $45.20 │ • alice: "Debug #423" 2h ago    │
│ 2. tapes              $38.90 │ • bob: "Cost exp" 5h ago        │
│ 3. api-service        $22.15 │ • alice: 3 sessions Feb 12      │
└─────────────────────────────────────────────────────────────────┘

3.2 Dashboard Queries

type TeamStats struct {
    TotalSessions    int           `json:"total_sessions"`
    TotalCost        float64       `json:"total_cost"`
    TotalTokens      int64         `json:"total_tokens"`
    AvgSessionCost   float64       `json:"avg_session_cost"`
    PreviousPeriod   *TeamStats    `json:"previous_period,omitempty"`
}

type MemberStats struct {
    UserID       string  `json:"user_id"`
    Name         string  `json:"name"`
    Sessions     int     `json:"sessions"`
    TotalCost    float64 `json:"total_cost"`
    TopModel     string  `json:"top_model"`
    TopProject   string  `json:"top_project"`
    SharedCount  int     `json:"shared_count"`
}

func (q *Query) TeamDashboard(ctx context.Context, teamID string, period time.Duration) (*TeamDashboard, error) {
    // Parallel queries for efficiency
    var stats TeamStats
    var members []MemberStats
    var modelUsage []ModelUsage
    var activity []DayActivity
    var recentShared []SharedSession
    
    // ... aggregate from shared_sessions joined with session data
}

Implementation Plan

Phase 1: Session Discovery & Export (2-3 weeks)

  • Add search to deck TUI (filter bar, fuzzy search)
  • Add search to deck web UI
  • Implement bulk export command (--date, --project, --since)
  • Support export formats: .tape, .json, .csv
  • Pipe support: tapes search | tapes export

Phase 2: Team Sharing (4-5 weeks)

  • User accounts with GitHub OAuth
  • Teams CRUD (create, invite, join, leave)
  • shared_sessions table and sync
  • tapes share command
  • Share modal in deck UI
  • "Shared with Me" view in deck
  • Web viewer at tapes.dev/t//s/

Phase 3: Team Analytics (3-4 weeks)

  • Team dashboard queries
  • Dashboard UI in deck (TUI + web)
  • Activity charts by member
  • Model/project breakdowns
  • Export team reports

API Endpoints

# Auth
POST   /auth/github          GitHub OAuth callback
GET    /auth/me              Current user info

# Teams
POST   /teams                Create team
GET    /teams                List user's teams
GET    /teams/:id            Get team details
PATCH  /teams/:id            Update team
DELETE /teams/:id            Delete team

# Members
GET    /teams/:id/members    List members
POST   /teams/:id/invite     Create invite
DELETE /teams/:id/members/:uid  Remove member

# Sharing
POST   /sessions/share       Share a session
GET    /shared               List sessions shared with me
GET    /shared/:id           Get shared session details
DELETE /shared/:id           Unshare a session

# Dashboard
GET    /teams/:id/stats      Team statistics
GET    /teams/:id/activity   Activity timeline

Open Questions

  1. Sync model: Pull-on-demand vs. background sync for shared sessions?
  2. Storage: Shared sessions stored on tapes.dev, or P2P between team members?
  3. Content privacy: Share full message content or metadata only by default?
  4. Notifications: How to notify when someone shares a session? (email, in-app, webhook)
  5. Offline: How do shared sessions work when offline?

Security Considerations

  • Sessions may contain sensitive data (API keys, internal URLs, proprietary code)
  • Sharing should require explicit action, never automatic
  • Team admins can audit shared sessions
  • Support for redacting sensitive content before sharing
  • Shared sessions should be deletable by sharer

References

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment