npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@lucasschirm/claude-session-sync

v0.2.16

Published

Claude Code plugin adapter for the @lucasschirm/sal-sync session data sync engine.

Readme

@lucasschirm/claude-session-sync

A Claude Code plugin that synchronizes your session data — transcripts, workspace configuration, and session telemetry — to S3-compatible storage via the @lucasschirm/sal-sync engine.

What it does

Every Claude Code session goes through a lifecycle: start, tool calls, context compaction, subagent spawns, and stop. This plugin hooks into those lifecycle events to capture and upload session artifacts so they can be analyzed later by the Agentic Sessions Dashboard (or any consumer of the sync engine's output).

Hooks

The plugin registers hooks for the following Claude Code lifecycle events (defined in hooks/hooks.json):

| Event | What happens | | -------------- | ----------------------------------------------------------------------------------------------------- | | SessionStart | Records the session, spawns a detached transcript watcher that uploads incremental transcript deltas. | | PreCompact | Flushes pending transcript deltas before context compaction. | | PostCompact | Resumes capture after compaction. | | Stop | Flushes a final delta when the turn ends. | | StopFailure | Flushes a final delta when the turn ends due to an API error. | | SubagentStop | Flushes subagent transcript deltas when a subagent finishes. | | SessionEnd | Performs the final sync: flushes remaining deltas, uploads the session manifest, and shuts down. |

All hooks except SessionEnd run asynchronously ("async": true) so they never block Claude. SessionEnd has a 60-second timeout to ensure the final manifest is uploaded before the process exits.

What gets captured

The sync engine captures only the artifacts in its versioned allowlist:

  • Session & subagent transcript JSONL files — captured raw by default, subject to size limits. Opt out with SAL_CAPTURE_TRANSCRIPTS=false.
  • Workspace configurationCLAUDE.md, .mcp.json, .claude/settings.json, .claude/settings.local.json, .claude/agents/**, .claude/skills/**, .claude/rules/**.
  • Global configuration~/.claude/settings.json, ~/.claude/CLAUDE.md, ~/.claude/agents/**, ~/.claude.json.
  • Session telemetrysessionId, projectId, harness, harnessVersion, model, startedAt, endedAt, durationMs, endReason.

Configuration artifacts are sanitized before upload: known sensitive fields (env, password, secret, token, apiKey, authorization, etc.) are redacted, and bearer tokens, credential-bearing URLs, and private-key blocks are stripped. See the full privacy policy.

Installation

The plugin is distributed through the session-analyzer marketplace, which is hosted in this repository at .claude-plugin/marketplace.json. Installation is a two-step process: first add the marketplace, then install the plugin.

Step 1 — Add the marketplace

You can add the marketplace from GitHub, a git URL, or a local clone.

From GitHub (recommended)

Use the owner/repo shorthand:

claude plugin marketplace add lucasschirm/session-analyzer

Pin to a specific branch or tag with @ref:

claude plugin marketplace add lucasschirm/session-analyzer@feature/claude-session-sync

From a git URL

For non-GitHub hosts or explicit HTTPS cloning:

claude plugin marketplace add https://github.com/lucasschirm/session-analyzer.git

From a local clone (for development)

If you have this repo cloned locally:

claude plugin marketplace add ./path/to/session-analyzer

Marketplace scope

The --scope flag controls who sees the marketplace declaration:

| Scope | Setting file | Shared with team? | | --------- | ------------------------------ | ----------------- | | user | ~/.claude/settings.json | No (personal) | | project | .claude/settings.json | Yes (committed) | | local | .claude/settings.local.json | No (gitignored) |

# Share the marketplace with your team
claude plugin marketplace add lucasschirm/session-analyzer --scope project

Step 2 — Install the plugin

Once the marketplace is added, install the plugin:

claude plugin install claude-session-sync@session-analyzer

Or from inside an interactive Claude Code session:

/plugin install claude-session-sync@session-analyzer

The install command opens a details view where you select an installation scope (user, project, or local — same semantics as above). After installing, run /reload-plugins if prompted.

From source (local development)

For local development, build the plugin bundle first, then add the marketplace from your local clone:

# Build the plugin bundle (esbuild single-file executables)
pnpm --filter @lucasschirm/claude-session-sync build

# Add the local marketplace and install
claude plugin marketplace add .
claude plugin install claude-session-sync@session-analyzer

The build produces self-contained executables in bin/ (no node_modules required at runtime):

bin/session-start        # SessionStart hook entry point
bin/session-end          # SessionEnd hook entry point
bin/hook                 # PreCompact/PostCompact/Stop/StopFailure/SubagentStop
bin/transcript-watcher   # Detached watcher process spawned by session-start
bin/claude-sync          # Standalone CLI for manual sync/list/download

Standalone CLI

In addition to the Claude Code hooks, this package ships a standalone CLI binary (claude-sync) that lets you manually upload, list, and download sessions from S3 storage. It's useful for backfilling historical sessions, inspecting what's been synced, or restoring sessions to a new machine.

Installation

The CLI is included in the same npm package. You can run it via npx without installing anything:

npx @lucasschirm/claude-session-sync sync

Or install it globally for a shorter claude-sync command:

npm install -g @lucasschirm/claude-session-sync
claude-sync sync

Commands

sync

Upload all local Claude Code sessions for the current project to S3.

claude-sync sync

From the project directory, the CLI:

  1. Finds the corresponding Claude Code project folder in ~/.claude/projects/.
  2. Lists all local .jsonl transcript files.
  3. For each session, checks if it already exists in S3 — if so, skips it.
  4. The first session uploaded captures workspace + global + session config. Subsequent sessions capture only session-scoped transcripts (config is uploaded once).
  5. Prints a per-session summary and a total.

list

List objects in the configured storage. Supports five forms:

# List all projects in storage
claude-sync list

# List sessions for the current project (requires SAL_PROJECT_ID)
claude-sync list --current

# List sessions for a specific project
claude-sync list <project-id>

# List files in a session
claude-sync list <project-id> --session=<session-id>

# List files under a session sub-path
claude-sync list <project-id> --session=<session-id> --path=<path>

--path is relative to the session folder. For example, --path=session lists all files under the session/ scope, and --path=session/configs lists files under that sub-path.

Examples:

PROJECT ID        SESSIONS  FILES  SIZE       LAST MODIFIED
-------------------------------------------------------------------------
session-analyzer  12        410    84.3 MB    2026-08-18 19:36
my-other-project  3         18     2.1 MB     2026-08-17 10:11

2 project(s), 410 files, 86.4 MB total
SESSION ID                              FILES  SIZE        LAST MODIFIED
-------------------------------------------------------------------------
d1acf718-cd8d-4c1d-84fd-b074d231995b    43     21.1 MB     2026-08-18 19:36
test-summary-001                        8      119.6 KB    2026-08-18 19:35

2 session(s), 51 files, 21.2 MB total
KEY                                     SIZE       LAST MODIFIED
-------------------------------------------------------------------------
manifest.json                           2.4 KB     2026-08-18 19:36
session/transcript.jsonl                1.1 MB     2026-08-18 19:36
workspace/package.json                  3.2 KB     2026-08-18 19:35

3 file(s), 1.1 MB total

download

Download session files from S3 to a local directory.

# Download a specific session
claude-sync download --session-id=<session-id> --output=<dir>

# Download all sessions for the project
claude-sync download all --output=<dir>

Files are restored to <output>/<projectId>/<sessionId>/<scope>/<relativePath>.

Configuration

The CLI reads configuration from environment variables, falling back to .claude/settings.local.json env key for any variables not set in the process environment. This means you can configure it once in .claude/settings.local.json and the CLI will pick it up automatically.

See the Configuration section below for the full list of required and optional variables.

If required variables are missing, the CLI prints an error with example export commands and a .claude/settings.local.json template:

Error: required configuration is missing or incomplete.

The following environment variables must be set:
  SAL_PROJECT_ID — Unique identifier for the project.
  ...

Set them via environment variables before running the CLI:

  export SAL_PROJECT_ID=session-analyzer
  export SAL_STORAGE_TYPE=s3
  ...
  npx @lucasschirm/claude-session-sync sync

Or add them to .claude/settings.local.json:

{
  "env": {
    "SAL_PROJECT_ID": "session-analyzer",
    ...
  }
}

Updating

To pull the latest version from the marketplace:

claude plugin marketplace update session-analyzer
claude plugin update claude-session-sync@session-analyzer

Or inside an interactive session:

/plugin marketplace update session-analyzer
/plugin update claude-session-sync@session-analyzer

Uninstalling

claude plugin uninstall claude-session-sync@session-analyzer
claude plugin marketplace remove session-analyzer

Configuration

The sync engine is configured entirely through environment variables. Set them in one of the Claude Code settings files (see below), or export them in your shell before launching claude.

Required

| Variable | Description | | -------------------- | ----------------------------------------------------- | | SAL_PROJECT_ID | Unique identifier for the project (e.g. my-app). | | SAL_STORAGE_TYPE | Storage backend. Currently only s3 is supported. | | SAL_STORAGE_BUCKET | S3 bucket name. | | SAL_STORAGE_REGION | AWS region (e.g. us-east-1). | | SAL_STORAGE_ACCESS_KEY_ID | AWS access key ID. | | SAL_STORAGE_SECRET_ACCESS_KEY | AWS secret access key. |

Optional

| Variable | Default | Description | | ------------------------------ | ----------- | ------------------------------------------------------------------ | | SAL_STORAGE_ENDPOINT | (none) | Custom S3-compatible endpoint (e.g. http://localhost:4566 for LocalStack). | | SAL_STORAGE_SESSION_TOKEN | (none) | Temporary AWS session token (for STS credentials). | | SAL_SYNC_DISABLED | false | Set to true to fully disable synchronization. | | SAL_CAPTURE_TRANSCRIPTS | true | Set to false to skip transcript capture (config still syncs). | | SAL_SYNC_TIMEOUT | 30000 | Per-upload timeout in milliseconds. | | SAL_SYNC_RETRIES | 3 | Number of retry attempts on upload failure. | | SAL_SESSION_END_BUDGET_MS | 120000 | Time budget for the final SessionEnd sync in milliseconds. | | SAL_HOOK_UPLOAD_TIMEOUT | 10000 | Per-hook upload timeout in milliseconds. | | SAL_MAX_FILE_BYTES | 10485760 | Max size per uploaded file (10 MB). | | SAL_MAX_TOTAL_BYTES | 104857600 | Max total bytes per sync run (100 MB). | | SAL_MAX_FILES | 1000 | Max files per sync run. | | SAL_MAX_TRANSCRIPT_BYTES | 52428800 | Max transcript file size (50 MB). | | SAL_MAX_JSON_DEPTH | 128 | Max JSON nesting depth for sanitization. | | SAL_MAX_JSONL_LINE_BYTES | 1048576 | Max bytes per JSONL line (1 MB). |

Configuring via Claude Code settings

Claude Code reads environment variables from the env key in its settings files. There are three relevant scopes:

| File | Scope | Commit to git? | | ----------------------------- | ------------------------------ | -------------- | | ~/.claude/settings.json | You, in every project | No | | .claude/settings.json | Everyone in the project | Yes | | .claude/settings.local.json | You, in this project only | No (gitignored)|

Option A: User-wide (recommended for personal use)

Edit ~/.claude/settings.json:

{
  "env": {
    "SAL_PROJECT_ID": "my-app",
    "SAL_STORAGE_TYPE": "s3",
    "SAL_STORAGE_BUCKET": "my-session-bucket",
    "SAL_STORAGE_REGION": "us-east-1",
    "SAL_STORAGE_ACCESS_KEY_ID": "AKIAIOSFODNN7EXAMPLE",
    "SAL_STORAGE_SECRET_ACCESS_KEY": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
  },
  "enabledPlugins": {
    "claude-session-sync@session-analyzer": true
  }
}

Option B: Project-local (per-project credentials)

Create .claude/settings.local.json in your project root (this file is gitignored by default, so credentials stay local):

{
  "env": {
    "SAL_PROJECT_ID": "my-app",
    "SAL_STORAGE_TYPE": "s3",
    "SAL_STORAGE_BUCKET": "my-session-bucket",
    "SAL_STORAGE_REGION": "us-east-1",
    "SAL_STORAGE_ACCESS_KEY_ID": "AKIAIOSFODNN7EXAMPLE",
    "SAL_STORAGE_SECRET_ACCESS_KEY": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
    "SAL_STORAGE_ENDPOINT": "http://localhost:4566"
  }
}

Note: pluginConfigs values are only read from user settings (~/.claude/settings.json), --settings, and managed settings — not from project or local settings files. However, the env key is read from all settings scopes, so environment variables in .claude/settings.local.json work correctly for plugin configuration.

Option C: Shell environment

Export the variables before launching Claude Code:

export SAL_PROJECT_ID="my-app"
export SAL_STORAGE_TYPE="s3"
export SAL_STORAGE_BUCKET="my-session-bucket"
export SAL_STORAGE_REGION="us-east-1"
export SAL_STORAGE_ACCESS_KEY_ID="AKIAIOSFODNN7EXAMPLE"
export SAL_STORAGE_SECRET_ACCESS_KEY="wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
claude

Using LocalStack for local development

For local testing without a real AWS account, run LocalStack and point the plugin at it:

{
  "env": {
    "SAL_PROJECT_ID": "local-dev",
    "SAL_STORAGE_TYPE": "s3",
    "SAL_STORAGE_BUCKET": "sal-sessions",
    "SAL_STORAGE_REGION": "us-east-1",
    "SAL_STORAGE_ENDPOINT": "http://localhost:4566",
    "SAL_STORAGE_ACCESS_KEY_ID": "test",
    "SAL_STORAGE_SECRET_ACCESS_KEY": "test"
  }
}

Opting out

| Goal | Setting | | ----------------------------- | -------------------------------- | | Disable transcript capture | SAL_CAPTURE_TRANSCRIPTS=false | | Fully disable synchronization | SAL_SYNC_DISABLED=true |

When fully disabled, the engine performs no filesystem discovery beyond the minimum required to determine that synchronization is disabled, and SessionStart does not spawn the watcher.

Development

# Build the plugin
pnpm --filter @lucasschirm/claude-session-sync build

# Run tests
pnpm --filter @lucasschirm/claude-session-sync test

# Typecheck
pnpm --filter @lucasschirm/claude-session-sync typecheck

# Lint
pnpm --filter @lucasschirm/claude-session-sync lint

Package structure

packages/plugins/claude-session-sync/
├── .claude-plugin/
│   └── plugin.json          # Plugin manifest
├── hooks/
│   └── hooks.json           # Lifecycle hook definitions
├── src/
│   ├── claude.ts            # Hook input parsing + Claude session mapping
│   ├── hook.ts              # Generic hook entry (PreCompact/PostCompact/Stop/...)
│   ├── session-start.ts     # SessionStart entry point
│   ├── session-end.ts       # SessionEnd entry point
│   ├── transcript-watcher.ts # Detached watcher spawner
│   ├── cli.ts               # Standalone CLI entry point (claude-sync)
│   ├── cli/                 # CLI command modules
│   │   ├── env.ts           # Environment resolution (process.env + settings.local.json)
│   │   ├── config.ts        # Config validation with example error messages
│   │   ├── project.ts       # Claude project folder resolution
│   │   ├── sync-command.ts  # "sync" command
│   │   ├── list-command.ts  # "list" command
│   │   └── download-command.ts # "download" command
│   └── index.ts             # Public API barrel
├── bin/                     # Built executables (esbuild single-file bundles)
├── build.mjs                # esbuild bundling script
├── tests/
│   ├── unit/                # Unit tests
│   └── e2e/                 # End-to-end plugin lifecycle tests
└── package.json

License

ISC