{"_id":"@alta-foundation/plaud-extractor","_rev":"3-02f4ada0084d31c615a5a60f52f49cbe","name":"@alta-foundation/plaud-extractor","dist-tags":{"latest":"1.0.8"},"versions":{"1.0.0":{"name":"@alta-foundation/plaud-extractor","version":"1.0.0","_id":"@alta-foundation/plaud-extractor@1.0.0","maintainers":[{"name":"altais42","email":"cervantescedric@gmail.com"}],"bin":{"alta-plaud":"dist/cli/bin.js","alta-plaud-mcp":"dist/mcp/server.js"},"dist":{"shasum":"1353125ddc89ec01fa08b26f03e18a05e44d9a22","tarball":"https://registry.npmjs.org/@alta-foundation/plaud-extractor/-/plaud-extractor-1.0.0.tgz","fileCount":163,"integrity":"sha512-4c9NR1mRRfs4MU4fyCxClt9EgUq6TuGukJhS/DJTdU1AdHxHbqe1dqrPcnws57xDErA9MFE+cXtlDMdAvqs1uw==","signatures":[{"sig":"MEYCIQD2hae4ORNw58zXbk6o9wOihvftS7aEkYyqt6W+Arjr3AIhAJ2oixu9xkgNprp1+VrU/ZOWTIsQktaz6EVI6ooef4L/","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":347248},"main":"./dist/index.js","type":"module","_from":"file:alta-foundation-plaud-extractor-1.0.0.tgz","types":"./dist/index.d.ts","engines":{"node":">=20.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"scripts":{"dev":"tsx src/cli/bin.ts","build":"tsc -p tsconfig.build.json","dev:mcp":"tsx src/mcp/server.ts","typecheck":"tsc --noEmit"},"_npmUser":{"name":"altais42","email":"cervantescedric@gmail.com"},"_resolved":"/private/var/folders/4g/05c1lkdn5yvdz84khj58_wbm0000gn/T/0cd920c37fc2059b9bc41176b19e0f9a/alta-foundation-plaud-extractor-1.0.0.tgz","_integrity":"sha512-4c9NR1mRRfs4MU4fyCxClt9EgUq6TuGukJhS/DJTdU1AdHxHbqe1dqrPcnws57xDErA9MFE+cXtlDMdAvqs1uw==","_npmVersion":"10.9.4","description":"Export recordings, transcripts, and metadata from Plaud — SDK + CLI","directories":{},"_nodeVersion":"22.22.0","dependencies":{"zod":"^3.23.8","pino":"^9.5.0","undici":"^6.21.0","commander":"^12.1.0","playwright":"^1.49.0","pino-pretty":"^11.3.0","@modelcontextprotocol/sdk":"^1.27.1"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.19.0","typescript":"^5.7.0","@types/node":"^20.17.0"},"_npmOperationalInternal":{"tmp":"tmp/plaud-extractor_1.0.0_1772109435192_0.20551691112617565","host":"s3://npm-registry-packages-npm-production"}},"1.0.7":{"name":"@alta-foundation/plaud-extractor","version":"1.0.7","_id":"@alta-foundation/plaud-extractor@1.0.7","maintainers":[{"name":"altais42","email":"cervantescedric@gmail.com"}],"homepage":"https://github.com/alta-foundation/plaud-extractor#readme","bugs":{"url":"https://github.com/alta-foundation/plaud-extractor/issues"},"bin":{"alta-plaud":"dist/cli/bin.js","alta-plaud-mcp":"dist/mcp/server.js"},"dist":{"shasum":"663b286bd3458dbcdff60a4f76edc0e060f9900d","tarball":"https://registry.npmjs.org/@alta-foundation/plaud-extractor/-/plaud-extractor-1.0.7.tgz","fileCount":163,"integrity":"sha512-AAj+m4SfoY5kR7IdmYLAUHMwBC8vyBOtTfem6XDBlSwp8TMELB786Fxvfj9hQNyXEOzpSq11bPSWy/YvZkZW9w==","signatures":[{"sig":"MEYCIQCH6mHjyvCo/lBGSIlIfSHhCXxcUQ1ozD0NzsYb5wNnPQIhAKT0hvQxj7ucr9Rdl1pFzObp6CixshMZaD6E8Ezg+JQb","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@alta-foundation%2fplaud-extractor@1.0.7","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":347866},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=20.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"64e0f7633350d57166f82cca27db2ae25c584c0b","scripts":{"dev":"tsx src/cli/bin.ts","build":"tsc -p tsconfig.build.json","dev:mcp":"tsx src/mcp/server.ts","typecheck":"tsc --noEmit"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:f9217002-78d5-4de5-8389-3453eb979164"}},"repository":{"url":"git+https://github.com/alta-foundation/plaud-extractor.git","type":"git"},"_npmVersion":"11.11.0","description":"Export recordings, transcripts, and metadata from Plaud — SDK + CLI","directories":{},"_nodeVersion":"24.13.1","dependencies":{"zod":"^3.23.8","pino":"^9.5.0","undici":"^6.21.0","commander":"^12.1.0","playwright":"^1.49.0","pino-pretty":"^11.3.0","@modelcontextprotocol/sdk":"^1.27.1"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.19.0","typescript":"^5.7.0","@types/node":"^20.17.0"},"_npmOperationalInternal":{"tmp":"tmp/plaud-extractor_1.0.7_1772116222531_0.747161385622451","host":"s3://npm-registry-packages-npm-production"}},"1.0.8":{"name":"@alta-foundation/plaud-extractor","version":"1.0.8","description":"Export recordings, transcripts, and metadata from Plaud — SDK + CLI","repository":{"type":"git","url":"git+https://github.com/alta-foundation/plaud-extractor.git"},"type":"module","main":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"import":"./dist/index.js","types":"./dist/index.d.ts"}},"bin":{"alta-plaud":"dist/cli/bin.js","alta-plaud-mcp":"dist/mcp/server.js"},"scripts":{"build":"tsc -p tsconfig.build.json","dev":"tsx src/cli/bin.ts","dev:mcp":"tsx src/mcp/server.ts","typecheck":"tsc --noEmit"},"dependencies":{"@modelcontextprotocol/sdk":"^1.27.1","commander":"^12.1.0","pino":"^9.5.0","pino-pretty":"^11.3.0","playwright":"^1.49.0","undici":"^6.21.0","zod":"^3.23.8"},"devDependencies":{"@types/node":"^20.17.0","tsx":"^4.19.0","typescript":"^5.7.0"},"engines":{"node":">=20.0.0"},"gitHead":"47c1da916fc71680a063a1017d5bcb882c544d42","_id":"@alta-foundation/plaud-extractor@1.0.8","bugs":{"url":"https://github.com/alta-foundation/plaud-extractor/issues"},"homepage":"https://github.com/alta-foundation/plaud-extractor#readme","_nodeVersion":"24.13.1","_npmVersion":"11.11.0","dist":{"integrity":"sha512-ykXW7GI5fsC4jrdakX3JnM8G+6R0paiH+XxcYkR3VudhNG4Ua8PpelgaenBEFIW8Y1Pfy2Vw4x5u8y3XwJsKeg==","shasum":"e66f31a1d412b628ef1f0159dda3ee15c0535066","tarball":"https://registry.npmjs.org/@alta-foundation/plaud-extractor/-/plaud-extractor-1.0.8.tgz","fileCount":163,"unpackedSize":347866,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@alta-foundation%2fplaud-extractor@1.0.8","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCcHZ2Ugzkd7XOFjRgImjy2Nz5BMo8e7fCuFvnyc8uK5wIgVy0FTQioiEd4FOQt6yS7zHmTxHCuquqAkgjBYMW5+j0="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:f9217002-78d5-4de5-8389-3453eb979164"}},"directories":{},"maintainers":[{"name":"altais42","email":"cervantescedric@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/plaud-extractor_1.0.8_1772116224209_0.281996626598781"},"_hasShrinkwrap":false}},"time":{"created":"2026-02-26T12:37:15.083Z","modified":"2026-02-26T14:30:24.663Z","1.0.0":"2026-02-26T12:37:15.334Z","1.0.7":"2026-02-26T14:30:22.680Z","1.0.8":"2026-02-26T14:30:24.370Z"},"bugs":{"url":"https://github.com/alta-foundation/plaud-extractor/issues"},"homepage":"https://github.com/alta-foundation/plaud-extractor#readme","repository":{"type":"git","url":"git+https://github.com/alta-foundation/plaud-extractor.git"},"description":"Export recordings, transcripts, and metadata from Plaud — SDK + CLI","maintainers":[{"name":"altais42","email":"cervantescedric@gmail.com"}],"readme":"# @alta-foundation/plaud-extractor\n\nSDK + CLI to pull all recordings, transcripts, and metadata from a [Plaud](https://www.plaud.ai) account into a structured local-first dataset. Designed as a building block for Alta | CORE.\n\n---\n\n## Contents\n\n- [Prerequisites](#prerequisites)\n- [Installation](#installation)\n- [Authentication](#authentication)\n- [CLI](#cli)\n- [SDK](#sdk)\n- [MCP Server](#mcp-server)\n- [Output Structure](#output-structure)\n- [Environment Variables](#environment-variables)\n\n---\n\n## Prerequisites\n\n- Node.js 20+\n- pnpm (or npm/yarn)\n- Google Chrome installed on the machine (used for auth — bypasses Google's automation detection)\n\n---\n\n## Installation\n\n```bash\n# As a CLI tool\npnpm add -g @alta-foundation/plaud-extractor\n\n# As an SDK dependency\npnpm add @alta-foundation/plaud-extractor\n```\n\n---\n\n## Authentication\n\nAuthentication is required once. It opens a real Chrome browser, you log in to Plaud, and the session is saved to `~/.alta/plaud-auth.json`.\n\n```bash\nalta-plaud auth\n```\n\nThe browser closes automatically once logged in. Credentials include a JWT valid for ~1 year — you won't need to repeat this often.\n\n---\n\n## CLI\n\n### `alta-plaud sync`\n\nIncremental sync — only downloads new or changed recordings since the last run.\n\n```bash\nalta-plaud sync [options]\n\nOptions:\n  --out <dir>          Output directory (default: ~/alta/data/plaud)\n  --since <iso>        Only sync recordings after this ISO date\n  --limit <n>          Max number of recordings to process\n  --concurrency <n>    Parallel downloads (default: 3)\n  --formats <list>     Transcript formats: json,txt,md (default: all)\n  --no-dataset         Skip appending to datasets/plaud_transcripts.jsonl\n  --dry-run            Print what would be downloaded without doing it\n  --verbose            Verbose logging\n  --redact             Redact tokens from logs\n```\n\n```bash\n# Preview what would sync\nalta-plaud sync --dry-run\n\n# Sync last 7 days only\nalta-plaud sync --since $(date -v-7d +%Y-%m-%d)\n\n# Sync to a custom directory\nalta-plaud sync --out ~/my-recordings\n```\n\nIf the session token expires mid-sync, re-authentication is triggered automatically.\n\n---\n\n### `alta-plaud backfill`\n\nFull re-evaluation of all recordings, regardless of incremental state. Useful after a schema change or to repair gaps.\n\n```bash\nalta-plaud backfill [options]\n\nOptions:\n  --out <dir>          Output directory (default: ~/alta/data/plaud)\n  --since <iso>        Only backfill recordings after this ISO date\n  --limit <n>          Max number of recordings to process\n  --concurrency <n>    Parallel downloads (default: 3)\n  --formats <list>     Transcript formats: json,txt,md (default: all)\n  --no-dataset         Skip dataset output\n  --dry-run            Print plan without downloading\n  --yes                Skip confirmation prompt\n  --verbose            Verbose logging\n```\n\n```bash\n# Backfill first 10 recordings (useful for testing)\nalta-plaud backfill --limit 10 --yes\n```\n\n---\n\n### `alta-plaud verify`\n\nWalk all downloaded recordings and verify checksums. Detects missing or corrupted files.\n\n```bash\nalta-plaud verify [options]\n\nOptions:\n  --out <dir>    Output directory (default: ~/alta/data/plaud)\n  --repair       Re-download files with checksum mismatches\n  --verbose      Verbose logging\n```\n\n---\n\n### `alta-plaud auth`\n\nLaunch browser for (re-)authentication.\n\n```bash\nalta-plaud auth [options]\n\nOptions:\n  --out <dir>      Data directory for logs\n```\n\n---\n\n## SDK\n\n```typescript\nimport { PlaudExtractor } from '@alta-foundation/plaud-extractor'\n\nconst extractor = new PlaudExtractor({\n  outDir: '~/alta/data/plaud',  // default\n  verbose: false,\n  redact: false,\n})\n\n// One-time auth (opens browser)\nawait extractor.authenticate()\n\n// Incremental sync\nconst result = await extractor.sync({ since: new Date('2026-01-01') })\nconsole.log(`${result.succeeded} downloaded, ${result.failed} failed`)\n\n// Full backfill\nawait extractor.backfill({ limit: 50 })\n\n// Verify checksums\nconst verify = await extractor.verify({ repair: false })\n\n// Export JSONL dataset\nconst datasetPath = await extractor.exportDataset()\n```\n\n**Types available:**\n\n```typescript\nimport type {\n  SyncOptions,\n  SyncResult,\n  BackfillOptions,\n  VerifyResult,\n  PlaudRecording,\n  PlaudTranscript,\n  AuthSession,\n} from '@alta-foundation/plaud-extractor'\n```\n\n**Error handling:**\n\n```typescript\nimport { AuthError, ApiError, StorageError } from '@alta-foundation/plaud-extractor'\n\ntry {\n  await extractor.sync()\n} catch (err) {\n  if (err instanceof AuthError) {\n    // Token expired or invalid — re-authenticate\n  }\n}\n```\n\n---\n\n## MCP Server\n\nThe MCP server exposes Plaud data as tools for Claude (or any MCP client). Read operations (list, transcript) are synchronous and work offline from local files. Sync/backfill run in the background and return a job ID for polling.\n\n### Tools\n\n| Tool | Type | Description |\n|---|---|---|\n| `plaud_status` | sync | Auth status, last sync time, recording count |\n| `plaud_list_recordings` | sync | List local recordings — filter by date or title |\n| `plaud_get_transcript` | sync | Full transcript by recording ID or partial title |\n| `plaud_sync` | async | Start incremental sync → returns `jobId` |\n| `plaud_backfill` | async | Start full backfill → returns `jobId` |\n| `plaud_job_status` | sync | Poll status of a background job |\n\n### Configuration\n\nAdd to Claude Code settings (`~/.claude/settings.json`) or your MCP client config:\n\n```json\n{\n  \"mcpServers\": {\n    \"alta-plaud\": {\n      \"command\": \"alta-plaud-mcp\",\n      \"env\": {\n        \"ALTA_DATA_DIR\": \"/Users/you/alta/data/plaud\"\n      }\n    }\n  }\n}\n```\n\nIf running from source:\n\n```json\n{\n  \"mcpServers\": {\n    \"alta-plaud\": {\n      \"command\": \"node\",\n      \"args\": [\"/path/to/plaud-extractor/dist/mcp/server.js\"],\n      \"env\": {\n        \"ALTA_DATA_DIR\": \"/Users/you/alta/data/plaud\"\n      }\n    }\n  }\n}\n```\n\n### Async job flow\n\n```\nClaude: plaud_sync({ since: \"2026-02-01\" })\n→ { jobId: \"sync_20260226_a1b2c3\", status: \"running\" }\n\nClaude: plaud_job_status({ jobId: \"sync_20260226_a1b2c3\" })\n→ { status: \"completed\", result: { succeeded: 12, failed: 0, ... } }\n```\n\n---\n\n## Output Structure\n\n```\n~/alta/data/plaud/\n├── recordings/\n│   └── 2026/\n│       └── 02/\n│           └── 20260224T083012Z__plaud_<id>/\n│               ├── meta.json          # Recording metadata\n│               ├── transcript.json    # Structured transcript with segments\n│               ├── transcript.txt     # Plain text transcript\n│               ├── transcript.md      # Markdown with YAML frontmatter + timestamps\n│               ├── audio.ogg          # Original audio file\n│               └── checksums.json     # SHA-256 hashes for all files\n├── datasets/\n│   └── plaud_transcripts.jsonl        # All recordings as JSONL (append-only)\n└── _state/\n    ├── sync_state.json                # Incremental sync state\n    ├── run_logs.ndjson                # Structured logs (pino NDJSON)\n    └── jobs/\n        └── sync_<id>.json             # Background job state (MCP async)\n```\n\n---\n\n## Environment Variables\n\n| Variable | Description |\n|---|---|\n| `ALTA_DATA_DIR` | Override default output directory (`~/alta/data/plaud`) |\n| `LOG_LEVEL` | Pino log level: `debug`, `info`, `warn`, `error` (default: `info`) |\n| `DEBUG` | Print full stack traces on CLI errors |\n\n---\n\n## Development\n\n```bash\n# Install dependencies\npnpm install\n\n# First-time auth\npnpm dev -- auth\n\n# Preview sync\npnpm dev -- sync --dry-run\n\n# Sync with verbose logging\npnpm dev -- sync --verbose\n\n# Run MCP server locally\npnpm dev:mcp\n\n# Build to dist/\npnpm build\n\n# Type-check without emitting\npnpm typecheck\n```\n\n### Releasing\n\nPublishing is handled by GitHub Actions using [npm Trusted Publishers (OIDC)](https://docs.npmjs.com/trusted-publishers) — no long-lived `NPM_TOKEN` secret required.\n\n```bash\n# 1. Bump version (patch / minor / major)\npnpm version patch   # or: minor, major\n\n# 2. Push the commit + tag — CI publishes automatically\ngit push --follow-tags\n```\n\nThe `publish.yml` workflow triggers on `v*` tags, runs typecheck + build, then publishes with `--provenance` via OIDC.\n\n**First publish:** if the package has never been published, run `pnpm publish --access public` locally once to create it on npm, then configure the Trusted Publisher in the npm package settings.\n","readmeFilename":"README.md"}