# whatsapp-pi Development Guidelines

Auto-generated from all feature plans. Last updated: 2026-04-28

## Active Technologies
- [e.g., Python 3.11, Swift 5.9, Rust 1.75 or NEEDS CLARIFICATION] + [e.g., FastAPI, UIKit, LLVM or NEEDS CLARIFICATION] (002-manual-whatsapp-connection)
- [if applicable, e.g., PostgreSQL, CoreData, files or N/A] (002-manual-whatsapp-connection)
- Local file-based multi-file auth state (baileys) (002-manual-whatsapp-connection)
- N/A (memory-based queuing) (003-whatsapp-messaging-refactor)
- TypeScript 5.x / Node.js 20+ + `@whiskeysockets/baileys`, `pi-agent-sdk` (004-blocked-numbers-management)
- `config.json` (Local persistent storage in `.pi-data/`) (004-blocked-numbers-management)
- TypeScript 5.x / Node.js 20+ + `@whiskeysockets/baileys`, `pi-agent-sdk`, `pino` (005-verbose-mode-support)
- Memory-based configuration (005-verbose-mode-support)
- TypeScript 5.x / Node.js 20+ + `pi-agent-sdk` (006-auto-connect-flag)
- Memory-based flag detection (`--whatsapp-pi-online`, `--verbose`); depends on existing `.pi-data/` auth state. (006-auto-connect-flag)
- TypeScript 5.x / Node.js 20+ + `@whiskeysockets/baileys` (007-image-recognition)
- Forwarding images as base64 to Pi (007-image-recognition)
- TypeScript 5.x / Node.js 20+ + `@whiskeysockets/baileys`, `pi-agent-sdk` (Extension API) (008-document-message-support)
- Local filesystem persistent storage in `.pi-data/whatsapp/documents/` (008-document-message-support)
- N/A (String constants) (009-localize-system-messages)
- TypeScript 5.x on Node.js 20+ + `@whiskeysockets/baileys`, `pino`, `qrcode-terminal`, existing Pi extension APIs (011-whatsapp-recents)
- Local file-based persistence under the existing user data directory (`~/.pi/whatsapp-pi/`), with a dedicated recents store for conversation summaries and message history (011-whatsapp-recents)
- TypeScript 5.x / Node.js 20+ + `@whiskeysockets/baileys`, `@mariozechner/pi-coding-agent`, `@mariozechner/pi-tui`, `pino`, `qrcode-terminal` (016-message-detail-view)
- Existing local recents store at `~/.pi/whatsapp-pi/recents/recents.json`; no new persistent storage (016-message-detail-view)
- TypeScript 5.x on Node.js 20+ + `@whiskeysockets/baileys`, `@mariozechner/pi-coding-agent`, `@mariozechner/pi-tui`, `pino`, `qrcode-terminal` (019-seria-possivel-fazer)
- Local file-based recents store under `~/.pi/whatsapp-pi/recents/recents.json` (019-seria-possivel-fazer)
- TypeScript 5.x / Node.js 20+ + `@whiskeysockets/baileys`, `vitest`, `typescript`, Node built-ins (`fs`, `fs/promises`, `child_process`, `os`, `path`) (021-increase-unit-test)
- Existing local media directory under `~/.pi/whatsapp-medias`; tests should mock file access and not depend on real files (021-increase-unit-test)

- TypeScript 5.x / Node.js 20+ + `@whiskeysockets/baileys`, `qrcode-terminal`, `pi-agent-sdk` (assumed name for Pi extension API) (001-whatsapp-tui-integration)

## Project Structure

```text
src/
tests/
```

## Commands

npm test; npm run lint

## Code Style

TypeScript 5.x / Node.js 20+: Follow standard conventions

## Recent Changes
- 021-increase-unit-test: Added TypeScript 5.x / Node.js 20+ + `@whiskeysockets/baileys`, `vitest`, `typescript`, Node built-ins (`fs`, `fs/promises`, `child_process`, `os`, `path`)
- 019-seria-possivel-fazer: Added TypeScript 5.x on Node.js 20+ + `@whiskeysockets/baileys`, `@mariozechner/pi-coding-agent`, `@mariozechner/pi-tui`, `pino`, `qrcode-terminal`
- 017-message-reply: Added TypeScript 5.x / Node.js 20+ + `@whiskeysockets/baileys`, `@mariozechner/pi-coding-agent`, `@mariozechner/pi-tui`, `pino`, `qrcode-terminal`

<!-- MANUAL ADDITIONS START -->
<!-- MANUAL ADDITIONS END -->


import { downloadContentFromMessage } from '@whiskeysockets/baileys';
import { mkdir, writeFile } from 'node:fs/promises';
import { join } from 'node:path';
import { AudioService } from './audio.service.js';
import type { IncomingResolution } from './incoming-message.resolver.js';
import { WhatsAppPiLogger } from './whatsapp-pi.logger.js';

export interface ProcessedIncomingContent {
    text: string;
    imageBuffer?: Buffer;
    imageMimeType?: string;
}

export class IncomingMediaService {
    constructor(
        private readonly audioService: AudioService,
        private readonly logger = new WhatsAppPiLogger(false)
    ) {}

    async process(resolved: IncomingResolution, pushName: string): Promise<ProcessedIncomingContent> {
        if (resolved.kind === 'audio') {
            return this.processAudio(resolved.audioMessage, pushName);
        }

        if (resolved.kind === 'image') {
            return this.processImage(resolved.imageMessage, resolved.text, pushName);
        }

        if (resolved.kind === 'document') {
            return this.processDocument(resolved.documentMessage, pushName);
        }

        return { text: resolved.text };
    }

    private async processAudio(audioMessage: any, pushName: string): Promise<ProcessedIncomingContent> {
        this.logger.log(`[WhatsApp-Pi] Transcribing audio from ${pushName}...`);
        const transcription = await this.audioService.transcribe(audioMessage);
        return { text: `[Transcribed Audio]: ${transcription}` };
    }

    private async processImage(imageMessage: any, fallbackText: string, pushName: string): Promise<ProcessedIncomingContent> {
        this.logger.log(`[WhatsApp-Pi] Downloading image from ${pushName}...`);

        try {
            const imageBuffer = await this.downloadMessage(imageMessage, 'image');
            const rawMime = imageMessage.mimetype || 'image/jpeg';
            let imageMimeType = rawMime.toLowerCase().split(';')[0].trim();
            if (imageMimeType === 'image/jpg') imageMimeType = 'image/jpeg';

            this.logger.log(`[WhatsApp-Pi] Image downloaded. MIME: ${imageMimeType} (original: ${rawMime}), Size: ${imageBuffer.length} bytes`);

            return {
                text: fallbackText || '[Image]',
                imageBuffer,
                imageMimeType
            };
        } catch (error) {
            this.logger.error('[WhatsApp-Pi] Failed to download image:', error);
            return { text: '[Image (download failed)]' };
        }
    }

    private async processDocument(documentMessage: any, pushName: string): Promise<ProcessedIncomingContent> {
        const fileName = documentMessage.fileName || 'unnamed_document';
        const mimeType = documentMessage.mimetype || 'application/octet-stream';
        const fileSize = documentMessage.fileLength ? Number(documentMessage.fileLength) : 0;

        this.logger.log(`[WhatsApp-Pi] Downloading document from ${pushName}: ${fileName}...`);

        try {
            const buffer = await this.downloadMessage(documentMessage, 'document');
            const relativePath = await this.saveDocument(fileName, buffer);

            this.logger.log(`[WhatsApp-Pi] Document saved to ${relativePath} (${buffer.length} bytes)`);

            let text = `[Document Received: ${fileName}]\n`
                + `MIME Type: ${mimeType}\n`
                + `Size: ${this.formatFileSize(fileSize)}\n`
                + `Location: ${relativePath}`;

            if (documentMessage.caption) {
                text += `\n\nDescription: ${documentMessage.caption}`;
            }

            return { text };
        } catch (error) {
            this.logger.error('[WhatsApp-Pi] Failed to download document:', error);
            return { text: `[Document: ${fileName} (download failed)]` };
        }
    }

    private async downloadMessage(message: any, type: 'image' | 'document'): Promise<Buffer> {
        const stream = await downloadContentFromMessage(message, type);
        let buffer = Buffer.from([]);

        for await (const chunk of stream) {
            buffer = Buffer.concat([buffer, chunk]);
        }

        return buffer;
    }

    private async saveDocument(fileName: string, buffer: Buffer): Promise<string> {
        const sanitized = fileName.replace(/[^a-z0-9\._-]/gi, '_');
        const savedFileName = `${Date.now()}_${sanitized}`;
        const documentDir = join(process.cwd(), '.pi-data', 'whatsapp', 'documents');
        const absolutePath = join(documentDir, savedFileName);

        await mkdir(documentDir, { recursive: true });
        await writeFile(absolutePath, buffer);

        return `./.pi-data/whatsapp/documents/${savedFileName}`;
    }

    private formatFileSize(fileSize: number): string {
        if (fileSize > 1024 * 1024) {
            return `${(fileSize / (1024 * 1024)).toFixed(1)} MB`;
        }

        return `${(fileSize / 1024).toFixed(1)} KB`;
    }
}


import { downloadContentFromMessage } from '@whiskeysockets/baileys';
import { exec } from 'node:child_process';
import { promisify } from 'node:util';
import { writeFile, mkdir } from 'node:fs/promises';
import { join } from 'node:path';
import { existsSync } from 'node:fs';
import { homedir } from 'node:os';

const execAsync = promisify(exec);

export class AudioService {
    private readonly mediaDir = join(homedir(), '.pi', 'whatsapp-medias');
    private readonly whisperPath = process.platform === 'win32' ? 'python -m whisper' : join(homedir(), '.local', 'bin', 'whisper');

    constructor() {
        if (!existsSync(this.mediaDir)) {
            mkdir(this.mediaDir, { recursive: true }).catch(() => {});
        }
    }

    async transcribe(audioMessage: any): Promise<string> {
        try {
            const filename = `audio_${Date.now()}`;
            const inputPath = join(this.mediaDir, `${filename}.ogg`);

            // Download audio content
            const stream = await downloadContentFromMessage(audioMessage, 'audio');
            let buffer = Buffer.from([]);
            for await (const chunk of stream) {
                buffer = Buffer.concat([buffer, chunk]);
            }

            await writeFile(inputPath, buffer);

            // Transcribe using Whisper
            // Using small model for better accuracy
            const command = `${this.whisperPath} "${inputPath}" --model small --language pt --output_format txt --output_dir "${this.mediaDir}" --fp16 False`;

            await execAsync(command);

            const txtPath = join(this.mediaDir, `${filename}.txt`);
            if (existsSync(txtPath)) {
                const fs = await import('node:fs/promises');
                const text = await fs.readFile(txtPath, 'utf8');
                return text.trim();
            }

            return '[Empty transcription]';
        } catch (error) {
            console.error('[AudioService] Transcription error:', error);
            return `[Transcription error: ${error instanceof Error ? error.message : String(error)}]`;
        }
    }
}


import { WhatsAppService } from './whatsapp.service.js';
import { MessageRequest, MessageResult, WhatsAppError } from '../models/whatsapp.types.js';

export class MessageSender {
    private whatsappService: WhatsAppService;

    constructor(whatsappService: WhatsAppService) {
        this.whatsappService = whatsappService;
    }

    /**
     * Pauses execution for the specified time.
     * @param ms Milliseconds to sleep.
     */
    private async sleep(ms: number) {
        return new Promise(resolve => setTimeout(resolve, ms));
    }

    /**
     * Waits for the WhatsApp connection to be active.
     * @param timeoutMs Maximum time to wait in milliseconds.
     * @throws {WhatsAppError} If connection is not established within timeout.
     */
    private async waitIfOffline(timeoutMs: number = 30000): Promise<void> {
        const start = Date.now();
        while (this.whatsappService.getStatus() !== 'connected') {
            if (Date.now() - start > timeoutMs) {
                throw new WhatsAppError('TIMEOUT', 'Timed out waiting for WhatsApp connection');
            }
            await this.sleep(1000);
        }
    }

    /**
     * Sends a message with retry logic and connection awareness.
     * @param request The message recipient and content.
     * @returns Promise resolving to a result object indicating success or failure.
     */
    public async send(request: MessageRequest): Promise<MessageResult> {
        const maxRetries = request.options?.maxRetries ?? 3;
        let attempts = 0;
        let lastError: unknown = null;

        while (attempts < maxRetries) {
            attempts++;
            try {
                // 1. Ensure we are online
                await this.waitIfOffline();

                // 2. Get active socket
                const socket = this.whatsappService.getSocket();
                if (!socket) {
                    throw new WhatsAppError('SOCKET_NOT_INIT', 'WhatsApp socket not initialized');
                }

                // 3. Send the message
                // Note: Branding π is applied here to ensure consistency
                const response = await socket.sendMessage(request.recipientJid, {
                    text: `${request.text} π`
                });

                return {
                    success: true,
                    messageId: response?.key?.id,
                    attempts
                };
            } catch (error: unknown) {
                lastError = error;
                console.error(`[MessageSender] Attempt ${attempts} failed for ${request.recipientJid}: ${error instanceof Error ? error.message : String(error)}`);

                // Specific handling for non-retryable errors
                if (error instanceof WhatsAppError && error.code === 'TIMEOUT') {
                    break;
                }

                // 4. Backoff before retry
                if (attempts < maxRetries) {
                    const backoff = Math.pow(2, attempts) * 1000;
                    if (this.whatsappService.isVerbose()) {
                        console.log(`[MessageSender] Retrying in ${backoff}ms...`);
                    }
                    await this.sleep(backoff);
                }
            }
        }

        return {
            success: false,
            error: lastError instanceof Error ? lastError.message : 'Unknown error',
            attempts
        };
    }
}


import { homedir } from 'os';
import { join } from 'path';
import { mkdir, readFile, writeFile } from 'fs/promises';
import type {
    MessageDirection,
    RecentConversationMessage,
    RecentConversationSummary,
    RecentsStore
} from '../models/whatsapp.types.js';
import { SessionManager } from './session.manager.js';

export interface RecentsMessageInput {
    messageId: string;
    senderNumber: string;
    senderName?: string;
    text: string;
    direction: MessageDirection;
    timestamp: number;
}

export class RecentsService {
    private readonly baseDir = join(homedir(), '.pi', 'whatsapp-pi');
    private readonly dataDir = join(this.baseDir, 'recents');
    private readonly storePath = join(this.dataDir, 'recents.json');
    private store: RecentsStore = {
        conversations: [],
        messagesBySender: {},
        updatedAt: Date.now()
    };

    constructor(private readonly sessionManager: SessionManager) {}

    async ensureInitialized() {
        await mkdir(this.dataDir, { recursive: true });
        await this.loadStore();
    }

    private async loadStore() {
        try {
            const content = await readFile(this.storePath, 'utf-8');
            const parsed = JSON.parse(content) as Partial<RecentsStore>;

            this.store = {
                conversations: Array.isArray(parsed.conversations) ? parsed.conversations.slice(0, 20) : [],
                messagesBySender: parsed.messagesBySender && typeof parsed.messagesBySender === 'object'
                    ? this.normalizeMessagesMap(parsed.messagesBySender)
                    : {},
                updatedAt: typeof parsed.updatedAt === 'number' ? parsed.updatedAt : Date.now()
            };

            this.rebuildConversationState();
        } catch {
            this.store = {
                conversations: [],
                messagesBySender: {},
                updatedAt: Date.now()
            };
        }
    }

    private normalizeMessagesMap(messagesBySender: RecentsStore['messagesBySender']): RecentsStore['messagesBySender'] {
        const normalized: RecentsStore['messagesBySender'] = {};

        for (const [senderNumber, messages] of Object.entries(messagesBySender)) {
            if (!Array.isArray(messages)) continue;
            normalized[senderNumber] = messages
                .filter((message): message is RecentConversationMessage => this.isValidMessage(message))
                .map(message => ({ ...message, timestamp: this.normalizeTimestamp(message.timestamp) }))
                .sort((left, right) => left.timestamp - right.timestamp)
                .slice(-20);
        }

        return normalized;
    }

    private isValidMessage(message: unknown): message is RecentConversationMessage {
        return Boolean(
            message &&
            typeof message === 'object' &&
            typeof (message as RecentConversationMessage).messageId === 'string' &&
            typeof (message as RecentConversationMessage).senderNumber === 'string' &&
            typeof (message as RecentConversationMessage).text === 'string' &&
            (message as RecentConversationMessage).text.trim().length > 0 &&
            ((message as RecentConversationMessage).direction === 'incoming' || (message as RecentConversationMessage).direction === 'outgoing') &&
            typeof (message as RecentConversationMessage).timestamp === 'number'
        );
    }

    private rebuildConversationState() {
        const previousNames = new Map(
            this.store.conversations.map(conversation => [conversation.senderNumber, conversation.senderName] as const)
        );
        const summaries = new Map<string, RecentConversationSummary>();

        for (const [senderNumber, messages] of Object.entries(this.store.messagesBySender)) {
            const latestMessage = this.getLatestConversationMessage(messages);
            if (!latestMessage) continue;

            summaries.set(senderNumber, {
                senderNumber,
                senderName: previousNames.get(senderNumber),
                lastMessagePreview: this.buildPreview(latestMessage.text),
                lastMessageTime: latestMessage.timestamp,
                lastMessageDirection: latestMessage.direction,
                messageCount: messages.length,
                isAllowed: this.sessionManager.isAllowed(senderNumber)
            });
        }

        this.store.conversations = this.sortConversationsByLatestMessage(Array.from(summaries.values()))
            .slice(0, 20);
    }

    private getLatestConversationMessage(messages: RecentConversationMessage[]): RecentConversationMessage | undefined {
        return messages[messages.length - 1];
    }

    private sortConversationsByLatestMessage(conversations: RecentConversationSummary[]): RecentConversationSummary[] {
        return [...conversations].sort((left, right) => {
            if (right.lastMessageTime !== left.lastMessageTime) {
                return right.lastMessageTime - left.lastMessageTime;
            }

            return left.senderNumber.localeCompare(right.senderNumber);
        });
    }

    private buildPreview(text: string): string {
        const normalized = text.trim().replace(/\s+/g, ' ');
        if (normalized.length <= 80) return normalized;
        return `${normalized.slice(0, 77)}...`;
    }

    private async persistStore() {
        this.store.updatedAt = Date.now();
        await writeFile(this.storePath, JSON.stringify(this.store, null, 2));
    }

    private normalizeNumber(input: string): string {
        const cleaned = input.replace(/@s\.whatsapp\.net$/, '');
        if (cleaned.startsWith('+')) {
            return cleaned;
        }
        if (/^\d+$/.test(cleaned)) {
            return `+${cleaned}`;
        }
        return cleaned;
    }

    private normalizeTimestamp(timestamp: number): number {
        return timestamp < 1_000_000_000_000 ? timestamp * 1000 : timestamp;
    }

    async recordMessage(input: RecentsMessageInput) {
        const senderNumber = this.normalizeNumber(input.senderNumber);
        if (!senderNumber) return;

        const normalizedTimestamp = this.normalizeTimestamp(input.timestamp);
        const normalizedText = input.text.trim().replace(/\s+/g, ' ');
        if (!normalizedText) return;

        const existing = this.store.messagesBySender[senderNumber] ?? [];
        const nextMessage: RecentConversationMessage = {
            messageId: input.messageId,
            senderNumber,
            text: normalizedText,
            direction: input.direction,
            timestamp: normalizedTimestamp
        };

        const filtered = existing.filter(message => message.messageId !== nextMessage.messageId);
        filtered.push(nextMessage);

        this.store.messagesBySender[senderNumber] = filtered
            .sort((left, right) => left.timestamp - right.timestamp)
            .slice(-20);

        const existingConversation = this.store.conversations.find(conversation => conversation.senderNumber === senderNumber);
        const summary: RecentConversationSummary = {
            senderNumber,
            senderName: input.senderName ?? existingConversation?.senderName,
            lastMessagePreview: this.buildPreview(input.text),
            lastMessageTime: normalizedTimestamp,
            lastMessageDirection: input.direction,
            messageCount: this.store.messagesBySender[senderNumber].length,
            isAllowed: this.sessionManager.isAllowed(senderNumber)
        };

        this.store.conversations = this.sortConversationsByLatestMessage([
            summary,
            ...this.store.conversations.filter(item => item.senderNumber !== senderNumber)
        ]).slice(0, 20);

        await this.persistStore();
    }

    async getRecentConversations(): Promise<RecentConversationSummary[]> {
        this.rebuildConversationState();
        return [...this.store.conversations];
    }

    async getConversationHistory(senderNumber: string): Promise<RecentConversationMessage[]> {
        const normalizedNumber = this.normalizeNumber(senderNumber);
        const messages = this.store.messagesBySender[normalizedNumber] ?? [];
        return [...messages]
            .sort((left, right) => left.timestamp - right.timestamp)
            .slice(-20);
    }

    async hasRecentConversations(): Promise<boolean> {
        const conversations = await this.getRecentConversations();
        return conversations.length > 0;
    }
}


bash

cd /tmp/whatsapp-pi-audit-4Dzv9j/repo && npm ci && npm test && npm run typecheck


npm warn deprecated inflight@1.0.6: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.
npm warn deprecated node-domexception@1.0.0: Use your platform's native DOMException instead
npm warn deprecated glob@7.2.3: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me
npm warn deprecated @whiskeysockets/baileys@6.17.16: The new official package name for the Baileys package is "baileys". Please use that package name going forward. This version may stop receiving updates in the future.

added 580 packages, and audited 581 packages in 10s

120 packages are looking for funding
  run `npm fund` for details

16 vulnerabilities (11 moderate, 3 high, 2 critical)

To address issues that do not require attention, run:
  npm audit fix

To address all issues (including breaking changes), run:
  npm audit fix --force

Run `npm audit` for details.

> whatsapp-pi@1.0.43 test
> vitest run

 RUN  v1.6.1 /tmp/whatsapp-pi-audit-4Dzv9j/repo

 ✓ tests/unit/send-wa-message.tool.test.ts  (6 tests) 51ms
 ✓ tests/unit/menu.handler.test.ts  (13 tests) 146ms
 ✓ tests/unit/whatsapp-pi.extension.test.ts  (7 tests) 250ms
 ✓ tests/unit/audio.service.test.ts  (7 tests) 31ms
 ❯ tests/unit/recents.service.test.ts  (5 tests | 1 failed) 49ms
   ❯ tests/unit/recents.service.test.ts > RecentsService > initializes an empty store when no recents file exists
     → expected "spy" to be called with arguments: [ …(2) ]

Received:

  1st spy call:

  Array [
-   "C:\\Users\\test\\.pi\\whatsapp-pi\\recents",
+   "C:\\Users\\test/.pi/whatsapp-pi/recents",
    Object {
      "recursive": true,
    },
  ]

Number of calls: 1

 ✓ tests/unit/whatsapp.service.auth-failure.test.ts  (2 tests) 125ms
 ❯ tests/unit/incoming-media.service.test.ts  (5 tests | 1 failed) 35ms
   ❯ tests/unit/incoming-media.service.test.ts > IncomingMediaService > saves documents with sanitized filenames and metadata text
     → expected "spy" to be called with arguments: [ StringContaining{…}, …(1) ]

Received:

  1st spy call:

  Array [
-   StringContaining ".pi-data\\whatsapp\\documents",
+   "/tmp/whatsapp-pi-audit-4Dzv9j/repo/.pi-data/whatsapp/documents",
    Object {
      "recursive": true,
    },
  ]

Number of calls: 1

 ✓ tests/unit/message-reply.view.test.ts  (3 tests) 18ms
 ✓ tests/unit/whatsapp.service.console-filter.test.ts  (2 tests) 48ms
stderr | tests/unit/session.manager.test.ts > SessionManager > should set and get status
Failed to save config: Error: ENOENT: no such file or directory, open '/home/sebas/.pi/whatsapp-pi/config.json'
    at open (node:internal/fs/promises:636:25)
    at Proxy.writeFile (node:internal/fs/promises:1205:14)
    at SessionManager.saveConfig (/tmp/whatsapp-pi-audit-4Dzv9j/repo/src/services/session.manager.ts:82:13)
    at SessionManager.setStatus (/tmp/whatsapp-pi-audit-4Dzv9j/repo/src/services/session.manager.ts:264:9)
    at /tmp/whatsapp-pi-audit-4Dzv9j/repo/tests/unit/session.manager.test.ts:18:9
    at runTest (file:///tmp/whatsapp-pi-audit-4Dzv9j/repo/node_modules/@vitest/runner/dist/index.js:781:11)
    at runSuite (file:///tmp/whatsapp-pi-audit-4Dzv9j/repo/node_modules/@vitest/runner/dist/index.js:909:15)
    at runSuite (file:///tmp/whatsapp-pi-audit-4Dzv9j/repo/node_modules/@vitest/runner/dist/index.js:909:15)
    at runFiles (file:///tmp/whatsapp-pi-audit-4Dzv9j/repo/node_modules/@vitest/runner/dist/index.js:958:5)
    at startTests (file:///tmp/whatsapp-pi-audit-4Dzv9j/repo/node_modules/@vitest/runner/dist/index.js:967:3) {
  errno: -2,
  code: 'ENOENT',
  syscall: 'open',
  path: '/home/sebas/.pi/whatsapp-pi/config.json'
}

stderr | tests/unit/session.manager.test.ts > SessionManager > should clear session directory and recreate auth folder
Failed to save config: Error: ENOENT: no such file or directory, open '/home/sebas/.pi/whatsapp-pi/config.json'
    at open (node:internal/fs/promises:636:25)
    at Proxy.writeFile (node:internal/fs/promises:1205:14)
    at SessionManager.saveConfig (/tmp/whatsapp-pi-audit-4Dzv9j/repo/src/services/session.manager.ts:82:13)
    at SessionManager.setStatus (/tmp/whatsapp-pi-audit-4Dzv9j/repo/src/services/session.manager.ts:264:9) {
  errno: -2,
  code: 'ENOENT',
  syscall: 'open',
  path: '/home/sebas/.pi/whatsapp-pi/config.json'
}

 ✓ tests/unit/session.manager.test.ts  (9 tests) 75ms
 ✓ tests/unit/whatsapp.service.test.ts  (5 tests) 18ms
 ✓ tests/unit/baileys-console-filter.test.ts  (5 tests) 20ms
 ✓ tests/unit/message.sender.test.ts  (3 tests) 15ms
 ✓ tests/unit/whatsapp-pi.logger.test.ts  (3 tests) 10ms
 ✓ tests/unit/message-detail.view.test.ts  (3 tests) 125ms
 ✓ tests/unit/incoming-message.resolver.test.ts  (5 tests) 6ms
 ✓ tests/unit/logger.test.ts  (2 tests) 4ms

⎯⎯⎯⎯⎯⎯⎯ Failed Tests 2 ⎯⎯⎯⎯⎯⎯⎯

 FAIL  tests/unit/incoming-media.service.test.ts > IncomingMediaService > saves documents with sanitized filenames and metadata text
AssertionError: expected "spy" to be called with arguments: [ StringContaining{…}, …(1) ]

Received:

  1st spy call:

  Array [
-   StringContaining ".pi-data\\whatsapp\\documents",
+   "/tmp/whatsapp-pi-audit-4Dzv9j/repo/.pi-data/whatsapp/documents",
    Object {
      "recursive": true,
    },
  ]

Number of calls: 1

 ❯ tests/unit/incoming-media.service.test.ts:110:29
    108|             'document'
    109|         );
    110|         expect(mocks.mkdir).toHaveBeenCalledWith(
       |                             ^
    111|             expect.stringContaining('.pi-data\\whatsapp\\documents'),
    112|             { recursive: true }

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/2]⎯

 FAIL  tests/unit/recents.service.test.ts > RecentsService > initializes an empty store when no recents file exists
AssertionError: expected "spy" to be called with arguments: [ …(2) ]

Received:

  1st spy call:

  Array [
-   "C:\\Users\\test\\.pi\\whatsapp-pi\\recents",
+   "C:\\Users\\test/.pi/whatsapp-pi/recents",
    Object {
      "recursive": true,
    },
  ]

Number of calls: 1

 ❯ tests/unit/recents.service.test.ts:37:31
     35|         await service.ensureInitialized();
     36|
     37|         expect(fsMocks.mkdir).toHaveBeenCalledWith(
       |                               ^
     38|             'C:\\Users\\test\\.pi\\whatsapp-pi\\recents',
     39|             { recursive: true }

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[2/2]⎯

 Test Files  2 failed | 15 passed (17)
      Tests  2 failed | 83 passed (85)
   Start at  16:06:28
   Duration  4.69s (transform 805ms, setup 9ms, collect 3.54s, tests 1.03s, environment 5ms, prepare 3.03s)

Command exited with code 1


**Evaluating npm audit**

I’m thinking about whether I need to check npm audit details. Should I install it even if there are minor test failures? I guess I need to run `npm audit --omit dev` to focus on runtime vulnerabilities. It's tricky balancing getting things installed and ensuring everything's in order, and I want to make sure I'm addressing any issues. Let’s figure out the best path forward while keeping everything secure!

cd /tmp/whatsapp-pi-audit-4Dzv9j/repo && npm audit --json --omit=dev > /tmp/whatsapp-pi-audit-4Dzv9j/audit-runtime.json || true && node -e 'const a=require("/tmp/whatsapp-pi-audit-4Dzv9j/audit-runtime.json"); console.log(JSON.stringify(a.metadata,null,2)); console.log("advisories", Object.keys(a.vulnerabilities||{})); for (const [k,v] of Object.entries(a.vulnerabilities||{})) console.log("\n##",k,"severity=",v.severity,"via=",JSON.stringify(v.via).slice(0,400),"effects=",v.effects);'


{
  "vulnerabilities": {
    "info": 0,
    "low": 0,
    "moderate": 3,
    "high": 1,
    "critical": 3,
    "total": 7
  },
  "dependencies": {
    "prod": 167,
    "dev": 420,
    "optional": 89,
    "peer": 73,
    "peerOptional": 0,
    "total": 659
  }
}
advisories [
  '@whiskeysockets/baileys',
  '@whiskeysockets/libsignal-node',
  'file-type',
  'follow-redirects',
  'music-metadata',
  'protobufjs',
  'uuid'
]

## @whiskeysockets/baileys severity= critical via= ["@whiskeysockets/libsignal-node","music-metadata","uuid"] effects= []

## @whiskeysockets/libsignal-node severity= critical via= ["protobufjs"] effects= [ '@whiskeysockets/baileys' ]

## file-type severity= moderate via= [{"source":1114301,"name":"file-type","dependency":"file-type","title":"file-type affected by infinite loop in ASF parser on malformed input with zero-size sub-header","url":"https://github.com/advisories/GHSA-5v7r-6r5c-r473","severity":"moderate","cwe":["CWE-835"],"cvss":{"score":5.3,"vectorString":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L"},"range":">=13.0.0 <21.3.1"}] effects= [ 'music-metadata' ]

## follow-redirects severity= moderate via= [{"source":1116560,"name":"follow-redirects","dependency":"follow-redirects","title":"follow-redirects leaks Custom Authentication Headers to Cross-Domain Redirect Targets","url":"https://github.com/advisories/GHSA-r4q5-vmmm-2653","severity":"moderate","cwe":["CWE-200"],"cvss":{"score":0,"vectorString":null},"range":"<=1.15.11"}] effects= []

## music-metadata severity= high via= [{"source":1114969,"name":"music-metadata","dependency":"music-metadata","title":"music-metadata has an infinite loop vulnerability in ASF parser","url":"https://github.com/advisories/GHSA-v6c2-xwv6-8xf7","severity":"high","cwe":["CWE-835"],"cvss":{"score":7.5,"vectorString":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"},"range":"<=11.12.1"},"file-type"] effects= [ '@whiskeysockets/baileys' ]

## protobufjs severity= critical via= [{"source":1117042,"name":"protobufjs","dependency":"protobufjs","title":"Arbitrary code execution in protobufjs","url":"https://github.com/advisories/GHSA-xq3m-2v4x-88gg","severity":"critical","cwe":["CWE-94"],"cvss":{"score":9.8,"vectorString":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H"},"range":"<7.5.5"}] effects= [ '@whiskeysockets/libsignal-node' ]

## uuid severity= moderate via= [{"source":1116970,"name":"uuid","dependency":"uuid","title":"uuid: Missing buffer bounds check in v3/v5/v6 when buf is provided","url":"https://github.com/advisories/GHSA-w5hq-g745-h8pq","severity":"moderate","cwe":["CWE-787","CWE-1285"],"cvss":{"score":0,"vectorString":null},"range":"<14.0.0"}] effects= [ '@whiskeysockets/baileys' ]


**Summarizing weird stuff**

It looks like I need to summarize some unusual technical details. First, there's no post-install or shell fetch, and it stores authentication and logs in /.pi/whatsapp-pi while audio files go in /.pi/whatsapp-medias. It uses a local whisper binary for audio transcription. WhatsApp messages and media are forwarded to the Pi, with documents saved under cwd/.pi-data. However, the runtime dependencies are vulnerable, and I see that 83 out of 85 tests pass, with two failures related to Windows path assertions. Maybe I shouldn't install or complete that update?


Updated #1 (pending → completed)

Audit whatsapp-pi repo and install if acceptable

Clone the GitHub repo, scan for suspicious or risky behavior, summarize findings, and install locally if no major issues are found.


Scan done. Not installing.

Findings:
- No obvious malware patterns.
- No `postinstall` / install-time scripts.
- No curl/wget/ssh/webhook/exfil code in repo.
- Main behavior is expected: connect to WhatsApp via Baileys, inject incoming messages into Pi, send Pi replies back.

Notable stuff:
- Saves auth/config/recents in `~/.pi/whatsapp-pi/`
- Saves audio temp files in `~/.pi/whatsapp-medias`
- Saves received docs in `./.pi-data/whatsapp/documents/`
- Runs local Whisper via shell for audio transcription:
  - `~/.local/bin/whisper "...file..." --model small ...`
  - input path is generated locally, so not blatant command injection
- It can auto-forward WhatsApp images/docs/text into Pi context. Expected, but privacy-sensitive.

Risk:
- Runtime deps are not clean:
  - `7` prod vulns from `npm audit --omit=dev`
  - includes `3 critical`, `1 high`
  - mainly through `@whiskeysockets/baileys` chain:
    - `protobufjs` RCE advisory
    - `music-metadata` DoS
    - `follow-redirects`, `uuid`, etc.
- Tests:
  - `83/85` pass
  - 2 failures are weak Windows path assertions, not core runtime breakage

Call:
- Repo itself does not look malicious.
- Dependency risk is real enough that I would not call it “good” cleanly.

If you still want, I can install it anyway with eyes open:
- `pi install npm:whatsapp-pi`

Say:
- `install anyway`
- or `find safer alternative`


find pi extensions for this and audit them


**Exploring pi extension packages**

I think I need to use the pi-extension-search skill, and I might need to read up more on that skill. It's possible my memory function isn't necessary here. I should search through npm for pi extensions or packages to see what’s available. Maybe I can use a specific skill file for that. I’m curious about what I might find!


---
name: pi-extension-search
description: Search npm for Pi extensions/packages when evaluating add-ons or orchestration tools
---

# pi-extension-search

## Use When

- user asks for Pi extensions, Pi packages, or add-ons
- you need alternatives to an installed extension
- you need to discover packages for orchestration, search, memory, UI, or workflow support in Pi

## Workflow

1. Confirm whether built-in Pi CLI supports package search:
   - `pi --help`
   - If no search command exists, use npm search.
2. Run focused npm searches with Pi package keywords:
   - `npm search --long --searchlimit=50 keywords:pi-package`
   - `npm search --long --searchlimit=50 keywords:pi-coding-agent`
   - `npm search --long --searchlimit=50 pi-coding-agent <topic>`
3. Narrow by topic as needed:
   - orchestration: `npm search --long --searchlimit=50 pi orchestration agent`
   - subagents: `npm search --long --searchlimit=50 pi subagents`
   - memory: `npm search --long --searchlimit=50 pi memory`
   - search/web: `npm search --long --searchlimit=50 pi web search`
4. Return:
   - package name
   - one-line fit summary from npm output
   - why it may fit the user goal
   - top candidates with tradeoffs
5. If the user wants installation, suggest:
   - `pi install npm:<package-name>`

## Notes

- Pi CLI here exposes install/remove/update/list/config, not package search.
- `npm search` is the practical discovery path.


**Searching for WhatsApp PI Extensions**

I need to look for WhatsApp PI extensions, but I should definitely put that on my to-do list. There seem to be different options available, so I want to ensure that I'm covering all my bases. It's important to find the right extensions that meet my needs and work well with WhatsApp. I’ll make sure I don’t miss anything, so let me get that organized!

todo

Find and audit Pi extensions for WhatsApp integration

Search npm/GitHub for Pi extensions/packages related to WhatsApp, shortlist realistic candidates, audit their repos/packages for weird behavior and dependency risk, and summarize tradeoffs.


Created #2: Find and audit Pi extensions for WhatsApp integration (pending)


bash

set -e
pi --help | sed -n '1,220p'
printf '\n== npm search: keywords:pi-package whatsapp ==\n'
npm search --long --searchlimit=30 keywords:pi-package whatsapp || true
printf '\n== npm search: keywords:pi-coding-agent whatsapp ==\n'
npm search --long --searchlimit=30 keywords:pi-coding-agent whatsapp || true
printf '\n== npm search: pi-coding-agent whatsapp ==\n'
npm search --long --searchlimit=30 pi-coding-agent whatsapp || true
printf '\n== npm search: keywords:pi-package ==\n'
npm search --long --searchlimit=80 keywords:pi-package | rg -i 'whatsapp|wa|message|chat|telegram|signal|sms' || true


Warning: No models match pattern "google-gemini-cli/gemini-3-flash-preview"
Warning: No models match pattern "nvidia/nvidia/nemotron-4-340b-instruct"
pi - AI coding assistant with read, bash, edit, write tools

Usage:
  pi [options] [@files...] [messages...]

Commands:
  pi install <source> [-l]     Install extension source and add to settings
  pi remove <source> [-l]      Remove extension source from settings
  pi uninstall <source> [-l]   Alias for remove
  pi update [source|self|pi]   Update pi and installed extensions
  pi list                      List installed extensions from settings
  pi config                    Open TUI to enable/disable package resources
  pi <command> --help          Show help for install/remove/uninstall/update/list

Options:
  --provider <name>              Provider name (default: google)
  --model <pattern>              Model pattern or ID (supports "provider/id" and optional ":<thinking>")
  --api-key <key>                API key (defaults to env vars)
  --system-prompt <text>         System prompt (default: coding assistant prompt)
  --append-system-prompt <text>  Append text or file contents to the system prompt (can be used multiple times)
  --mode <mode>                  Output mode: text (default), json, or rpc
  --print, -p                    Non-interactive mode: process prompt and exit
  --continue, -c                 Continue previous session
  --resume, -r                   Select a session to resume
  --session <path|id>            Use specific session file or partial UUID
  --fork <path|id>               Fork specific session file or partial UUID into a new session
  --session-dir <dir>            Directory for session storage and lookup
  --no-session                   Don't save session (ephemeral)
  --models <patterns>            Comma-separated model patterns for Ctrl+P cycling
                                 Supports globs (anthropic/*, *sonnet*) and fuzzy matching
  --no-tools, -nt                Disable all tools by default (built-in and extension)
  --no-builtin-tools, -nbt       Disable built-in tools by default but keep extension/custom tools enabled
  --tools, -t <tools>            Comma-separated allowlist of tool names to enable
                                 Applies to built-in, extension, and custom tools
  --thinking <level>             Set thinking level: off, minimal, low, medium, high, xhigh
  --extension, -e <path>         Load an extension file (can be used multiple times)
  --no-extensions, -ne           Disable extension discovery (explicit -e paths still work)
  --skill <path>                 Load a skill file or directory (can be used multiple times)
  --no-skills, -ns               Disable skills discovery and loading
  --prompt-template <path>       Load a prompt template file or directory (can be used multiple times)
  --no-prompt-templates, -np     Disable prompt template discovery and loading
  --theme <path>                 Load a theme file or directory (can be used multiple times)
  --no-themes                    Disable theme discovery and loading
  --no-context-files, -nc        Disable AGENTS.md and CLAUDE.md discovery and loading
  --export <file>                Export session file to HTML and exit
  --list-models [search]         List available models (with optional fuzzy search)
  --verbose                      Force verbose startup (overrides quietStartup setting)
  --offline                      Disable startup network operations (same as PI_OFFLINE=1)
  --help, -h                     Show this help
  --version, -v                  Show version number

Extensions can register additional flags (e.g., --plan from plan-mode extension).
Extension CLI Flags:
  --switch-session            Open the session-switch picker after startup, then relaunch into the selected session

Examples:
  # Interactive mode
  pi

  # Interactive mode with initial prompt
  pi "List all .ts files in src/"

  # Include files in initial message
  pi @prompt.md @image.png "What color is the sky?"

  # Non-interactive mode (process and exit)
  pi -p "List all .ts files in src/"

  # Multiple messages (interactive)
  pi "Read package.json" "What dependencies do we have?"

  # Continue previous session
  pi --continue "What did we discuss?"

  # Use different model
  pi --provider openai --model gpt-4o-mini "Help me refactor this code"

  # Use model with provider prefix (no --provider needed)
  pi --model openai/gpt-4o "Help me refactor this code"

  # Use model with thinking level shorthand
  pi --model sonnet:high "Solve this complex problem"

  # Limit model cycling to specific models
  pi --models claude-sonnet,claude-haiku,gpt-4o

  # Limit to a specific provider with glob pattern
  pi --models "github-copilot/*"

  # Cycle models with fixed thinking levels
  pi --models sonnet:high,haiku:low

  # Start with a specific thinking level
  pi --thinking high "Solve this complex problem"

  # Read-only mode (no file modifications possible)
  pi --tools read,grep,find,ls -p "Review the code in src/"

  # Export a session file to HTML
  pi --export ~/.pi/agent/sessions/--path--/session.jsonl
  pi --export session.jsonl output.html

Environment Variables:
  ANTHROPIC_API_KEY                - Anthropic Claude API key
  ANTHROPIC_OAUTH_TOKEN            - Anthropic OAuth token (alternative to API key)
  OPENAI_API_KEY                   - OpenAI GPT API key
  AZURE_OPENAI_API_KEY             - Azure OpenAI API key
  AZURE_OPENAI_BASE_URL            - Azure OpenAI/Cognitive Services base URL (e.g. https://{resource}.openai.azure.com)
  AZURE_OPENAI_RESOURCE_NAME       - Azure OpenAI resource name (alternative to base URL)
  AZURE_OPENAI_API_VERSION         - Azure OpenAI API version (default: v1)
  AZURE_OPENAI_DEPLOYMENT_NAME_MAP - Azure OpenAI model=deployment map (comma-separated)
  DEEPSEEK_API_KEY                 - DeepSeek API key
  GEMINI_API_KEY                   - Google Gemini API key
  GROQ_API_KEY                     - Groq API key
  CEREBRAS_API_KEY                 - Cerebras API key
  XAI_API_KEY                      - xAI Grok API key
  FIREWORKS_API_KEY                - Fireworks API key
  OPENROUTER_API_KEY               - OpenRouter API key
  AI_GATEWAY_API_KEY               - Vercel AI Gateway API key
  ZAI_API_KEY                      - ZAI API key
  MISTRAL_API_KEY                  - Mistral API key
  MINIMAX_API_KEY                  - MiniMax API key
  MOONSHOT_API_KEY                 - Moonshot AI API key
  OPENCODE_API_KEY                 - OpenCode Zen/OpenCode Go API key
  KIMI_API_KEY                     - Kimi For Coding API key
  CLOUDFLARE_API_KEY               - Cloudflare API token (Workers AI and AI Gateway)
  CLOUDFLARE_ACCOUNT_ID            - Cloudflare account id (required for both)
  CLOUDFLARE_GATEWAY_ID            - Cloudflare AI Gateway slug (required for AI Gateway)
  AWS_PROFILE                      - AWS profile for Amazon Bedrock
  AWS_ACCESS_KEY_ID                - AWS access key for Amazon Bedrock
  AWS_SECRET_ACCESS_KEY            - AWS secret key for Amazon Bedrock
  AWS_BEARER_TOKEN_BEDROCK         - Bedrock API key (bearer token)
  AWS_REGION                       - AWS region for Amazon Bedrock (e.g., us-east-1)
  PI_CODING_AGENT_DIR              - Config directory (default: ~/.pi/agent)
  PI_CODING_AGENT_SESSION_DIR      - Session storage directory (overridden by --session-dir)
  PI_PACKAGE_DIR                   - Override package directory (for Nix/Guix store paths)
  PI_OFFLINE                       - Disable startup network operations when set to 1/true/yes
  PI_TELEMETRY                     - Override install telemetry when set to 1/true/yes or 0/false/no
  PI_SHARE_VIEWER_URL              - Base URL for /share command (default: https://pi.dev/session/)

Built-in Tool Names:
  read   - Read file contents
  bash   - Execute bash commands
  edit   - Edit files with find/replace
  write  - Write files (creates/overwrites)
  grep   - Search file contents (read-only, off by default)
  find   - Find files by glob pattern (read-only, off by default)
  ls     - List directory contents (read-only, off by default)

== npm search: keywords:pi-package whatsapp ==
whatsapp-piwhatsapp-pi
WhatsApp integration extension for PiWhatsApp integration extension for Pi
Version 1.0.43 published 2026-04-29 by castelloes
Maintainers: castelloes
Keywords: pi pi-package pi-extension whatsapp baileys agent
https://npm.im/whatsapp-pi

pi-messenger-bridgepi-messenger-bridge
Bridge common messengers (Telegram, WhatsApp, Slack, Discord) into piBridge common messengers (Telegram, WhatsApp, Slack, Discord) into pi
Version 0.3.0 published 2026-03-25 by tintinweb
Maintainers: tintinweb
Keywords: pi-package pi pi-extension telegram whatsapp slack discord messenger bridge bot remote chat messaging coding-agent
https://npm.im/pi-messenger-bridge

@0xkobold/pi-gateway@0xkobold/pi-gateway
Hermes-style messaging gateway for pi - multi-platform agent with sessions, security, and background tasksHermes-style messaging gateway for pi - multi-platform agent with sessions, security, and background tasks
Version 0.6.0 published 2026-04-09 by moikapy
Maintainers: moikapy
Keywords: pi-package pi-extension gateway messaging hermes multi-platform
https://npm.im/@0xkobold/pi-gateway

context-modecontext-mode
MCP plugin that saves 98% of your context window. Works with Claude Code, Gemini CLI, VS Code Copilot, OpenCode, and Codex CLI. Sandboxed code execution, FTS5 knowledge base, and intent-driven search.MCP plugin that saves 98% of your context window. Works with Claude Code, Gemini CLI, VS Code Copilot, OpenCode, and Codex CLI. Sandboxed code execution, FTS5 knowledge base, and intent-driven search.
Version 1.0.103 published 2026-04-28 by mksglu
Maintainers: mksglu
Keywords: mcp model-context-protocol claude claude-code gemini-cli vscode-copilot opencode openclaw codex-cli context-window sandbox code-execution fts5 bm25 pi-package
https://npm.im/context-mode

pi-subagentspi-subagents
Pi extension for delegating tasks to subagents with chains, parallel execution, and TUI clarificationPi extension for delegating tasks to subagents with chains, parallel execution, and TUI clarification
Version 0.21.4 published 2026-05-01 by nicopreme
Maintainers: nicopreme
Keywords: pi-package pi pi-coding-agent subagents ai agents cli
https://npm.im/pi-subagents

pi-mcp-adapterpi-mcp-adapter
MCP (Model Context Protocol) adapter extension for Pi coding agentMCP (Model Context Protocol) adapter extension for Pi coding agent
Version 2.5.3 published 2026-05-01 by nicopreme
Maintainers: nicopreme
Keywords: pi-package pi mcp model-context-protocol ai coding-agent extension claude llm
https://npm.im/pi-mcp-adapter

@a5c-ai/babysitter-pi@a5c-ai/babysitter-pi
Babysitter package for Pi Coding AgentBabysitter package for Pi Coding Agent
Version 0.1.3 published 2026-04-04 by tmuskal
Maintainers: tmuskal benihak
Keywords: pi pi-package babysitter orchestration ai-agent
https://npm.im/@a5c-ai/babysitter-pi

@ollama/pi-web-search@ollama/pi-web-search
Web search and fetch tools for Pi agent - uses Ollama's web search and fetch APIsWeb search and fetch tools for Pi agent - uses Ollama's web search and fetch APIs
Version 0.0.5 published 2026-03-28 by parthollama
Maintainers: jmorgan mchiang0610 drifkin bruce-ollama parthollama
Keywords: pi-package pi-extension web-search ollama
https://npm.im/@ollama/pi-web-search

@plannotator/pi-extension@plannotator/pi-extension
Plannotator extension for Pi coding agent - interactive plan review with visual annotationPlannotator extension for Pi coding agent - interactive plan review with visual annotation
Version 0.19.5 published 2026-05-01 by GitHub Actions
Maintainers: backnotprop
Keywords: pi-package plannotator plan-review ai-agent coding-agent
https://npm.im/@plannotator/pi-extension

pi-web-accesspi-web-access
Web search, URL fetching, GitHub repo cloning, PDF extraction, YouTube video understanding, and local video analysis for Pi coding agentWeb search, URL fetching, GitHub repo cloning, PDF extraction, YouTube video understanding, and local video analysis for Pi coding agent
Version 0.10.6 published 2026-04-04 by nicopreme
Maintainers: nicopreme
Keywords: pi-package pi pi-coding-agent extension web-search perplexity fetch scraping
https://npm.im/pi-web-access

taskplanetaskplane
AI agent orchestration for pi — parallel task execution with checkpoint disciplineAI agent orchestration for pi — parallel task execution with checkpoint discipline
Version 0.28.4 published 2026-04-21 by henrylach
Maintainers: henrylach
Keywords: pi-package ai agent orchestration task-runner parallel
https://npm.im/taskplane

pi-markdown-previewpi-markdown-preview
Rendered markdown + LaTeX preview for pi, with terminal, browser, and PDF outputRendered markdown + LaTeX preview for pi, with terminal, browser, and PDF output
Version 0.9.7 published 2026-04-29 by omacl
Maintainers: omacl
Keywords: pi-package
https://npm.im/pi-markdown-preview

pi-lenspi-lens
Real-time code feedback for pi — LSP, linters, formatters, type-checking, structural analysis & boobooReal-time code feedback for pi — LSP, linters, formatters, type-checking, structural analysis & booboo
Version 3.8.34 published 2026-05-01 by apmantza
Maintainers: apmantza
Keywords: pi pi-extension pi-package linter biome ast-grep ruff typescript code-quality feedback type-coverage jscpd knip
https://npm.im/pi-lens

pi-gsdpi-gsd
Get Shit Done - Unofficial port of the renowned AI-native project-planning spec-driven toolkitGet Shit Done - Unofficial port of the renowned AI-native project-planning spec-driven toolkit
Version 2.1.4 published 2026-04-26 by GitHub Actions
Maintainers: fulgidus
Keywords: ai agent planning cli workflow get-shit-done gsd productivity project-management milestones phases spec pi-package
https://npm.im/pi-gsd

pi-powerline-footerpi-powerline-footer
Powerline-style status bar extension for pi coding agentPowerline-style status bar extension for pi coding agent
Version 0.4.20 published 2026-04-26 by nicopreme
Maintainers: nicopreme
Keywords: pi-package pi coding-agent powerline status-bar extension
https://npm.im/pi-powerline-footer

@aliou/pi-processes@aliou/pi-processes
![banner](https://assets.aliou.me/pi-extensions/banners/pi-processes.png)![banner](https://assets.aliou.me/pi-extensions/banners/pi-processes.png)
Version 0.8.1 published 2026-04-23 by GitHub Actions
Maintainers: aliou
Keywords: pi-package pi-extension pi processes
https://npm.im/@aliou/pi-processes

pi-btwpi-btw
A pi extension for parallel side conversations with /btwA pi extension for parallel side conversations with /btw
Version 0.3.8 published 2026-04-30 by GitHub Actions
Maintainers: dbachelder
Keywords: pi-package pi-extension pi-coding-agent agent tui
https://npm.im/pi-btw

@juicesharp/rpiv-todo@juicesharp/rpiv-todo
Pi extension: gives the model a todo list with a live overlay that survives /reload and compactionPi extension: gives the model a todo list with a live overlay that survives /reload and compaction
Version 1.0.13 published 2026-05-01 by juicesharp
Maintainers: juicesharp
Keywords: pi-package pi-extension rpiv todo
https://npm.im/@juicesharp/rpiv-todo

@juicesharp/rpiv-ask-user-question@juicesharp/rpiv-ask-user-question
Pi extension: lets the model ask you a clarifying question with structured options instead of guessingPi extension: lets the model ask you a clarifying question with structured options instead of guessing
Version 1.0.13 published 2026-05-01 by juicesharp
Maintainers: juicesharp
Keywords: pi-package pi-extension rpiv
https://npm.im/@juicesharp/rpiv-ask-user-question

@callumvass/forgeflow-dev@callumvass/forgeflow-dev
Dev pipeline for Pi — TDD implementation, code review, architecture, and Datadog investigations.Dev pipeline for Pi — TDD implementation, code review, architecture, and Datadog investigations.
Version 0.36.0 published 2026-04-12 by GitHub Actions
Maintainers: callumvass
Keywords: pi-package
https://npm.im/@callumvass/forgeflow-dev

@samfp/pi-memory@samfp/pi-memory
Persistent memory for pi — learns corrections, preferences, and patterns from sessions and injects them into future conversations.Persistent memory for pi — learns corrections, preferences, and patterns from sessions and injects them into future conversations.
Version 1.0.2 published 2026-04-24 by samfp
Maintainers: samfp
Keywords: pi-package extension memory learning preferences
https://npm.im/@samfp/pi-memory

@heart-of-gold/toolkit@heart-of-gold/toolkit
Cross-platform installer for Heart of Gold skills — works with Codex, OpenCode, Pi, Claude Code, and moreCross-platform installer for Heart of Gold skills — works with Codex, OpenCode, Pi, Claude Code, and more
Version 0.1.50 published 2026-04-26 by ondrejsvec
Maintainers: ondrejsvec
Keywords: codex claude-code opencode pi pi-package ai-agents skills agents-md agentskills harness-engineering heart-of-gold
https://npm.im/@heart-of-gold/toolkit

glimpseuiglimpseui
Native micro-UI for scripts and agents — cross-platform WebView windows with bidirectional JSON communicationNative micro-UI for scripts and agents — cross-platform WebView windows with bidirectional JSON communication
Version 0.8.0 published 2026-04-19 by haza
Maintainers: haza
Keywords: macos linux windows webview native ui webkit wkwebview webview2 gtk swift gui agent dialog prompt overlay pi-package
https://npm.im/glimpseui

driplinedripline
Query anything, one drip at a timeQuery anything, one drip at a time
Version 0.9.12 published 2026-04-29 by miclivs
Maintainers: miclivs
Keywords: pi-package sql cloud api query steampipe cli
https://npm.im/dripline

@runfusion/fusion@runfusion/fusion
Fusion CLI: HTTP API server, daemon, dashboard launcher, and task tooling for the Fusion AI coding agent.Fusion CLI: HTTP API server, daemon, dashboard launcher, and task tooling for the Fusion AI coding agent.
Version 0.13.0 published 2026-05-01 by gsxdsm
Maintainers: gsxdsm
Keywords: pi-package
https://npm.im/@runfusion/fusion

@juicesharp/rpiv-pi@juicesharp/rpiv-pi
Skill-based development workflow for Pi Agent — discover, research, design, plan, implement, validateSkill-based development workflow for Pi Agent — discover, research, design, plan, implement, validate
Version 1.0.13 published 2026-05-01 by juicesharp
Maintainers: juicesharp
Keywords: pi-package pi-extension rpiv skills workflow
https://npm.im/@juicesharp/rpiv-pi

@juicesharp/rpiv-btw@juicesharp/rpiv-btw
Pi extension: /btw side-question slash command — ask the same primary model a one-off side question without polluting the main conversationPi extension: /btw side-question slash command — ask the same primary model a one-off side question without polluting the main conversation
Version 1.0.13 published 2026-05-01 by juicesharp
Maintainers: juicesharp
Keywords: pi-package pi-extension rpiv btw side-question overlay
https://npm.im/@juicesharp/rpiv-btw

@juicesharp/rpiv-advisor@juicesharp/rpiv-advisor
Pi extension: lets the model ask a stronger reviewer model for a second opinion before it actsPi extension: lets the model ask a stronger reviewer model for a second opinion before it acts
Version 1.0.13 published 2026-05-01 by juicesharp
Maintainers: juicesharp
Keywords: pi-package pi-extension rpiv advisor
https://npm.im/@juicesharp/rpiv-advisor

pi-studiopi-studio
Two-pane browser workspace for pi with prompt/response editing, annotations, critiques, prompt/response history, and live Markdown/LaTeX/code previewTwo-pane browser workspace for pi with prompt/response editing, annotations, critiques, prompt/response history, and live Markdown/LaTeX/code preview
Version 0.6.9 published 2026-05-01 by omacl
Maintainers: omacl
Keywords: pi-package pi-extension pi-theme
https://npm.im/pi-studio

pi-docparserpi-docparser
Pi package that adds a document_parse tool and companion skill for parsing PDFs, Office documents, spreadsheets, and images with LiteParse.Pi package that adds a document_parse tool and companion skill for parsing PDFs, Office documents, spreadsheets, and images with LiteParse.
Version 1.1.1 published 2026-03-21 by maxedapps
Maintainers: maxedapps
Keywords: document-parse documents extension liteparse ocr pdf pi pi-package skill
https://npm.im/pi-docparser

== npm search: keywords:pi-coding-agent whatsapp ==
pi-subagentspi-subagents
Pi extension for delegating tasks to subagents with chains, parallel execution, and TUI clarificationPi extension for delegating tasks to subagents with chains, parallel execution, and TUI clarification
Version 0.21.4 published 2026-05-01 by nicopreme
Maintainers: nicopreme
Keywords: pi-package pi pi-coding-agent subagents ai agents cli
https://npm.im/pi-subagents

pi-acppi-acp
ACP adapter for pi coding agentACP adapter for pi coding agent
Version 0.0.26 published 2026-04-18 by deepstereo
Maintainers: deepstereo
Keywords: acp agent-client-protocol pi-coding-agent adapter
https://npm.im/pi-acp

pi-web-accesspi-web-access
Web search, URL fetching, GitHub repo cloning, PDF extraction, YouTube video understanding, and local video analysis for Pi coding agentWeb search, URL fetching, GitHub repo cloning, PDF extraction, YouTube video understanding, and local video analysis for Pi coding agent
Version 0.10.6 published 2026-04-04 by nicopreme
Maintainers: nicopreme
Keywords: pi-package pi pi-coding-agent extension web-search perplexity fetch scraping
https://npm.im/pi-web-access

@rynfar/meridian@rynfar/meridian
Local Anthropic API powered by your Claude Max subscription. One subscription, every agent.Local Anthropic API powered by your Claude Max subscription. One subscription, every agent.
Version 1.41.0 published 2026-05-01 by rynfar
Maintainers: rynfar
Keywords: meridian claude claude-max claude-code anthropic anthropic-api claude-agent-sdk ai-coding ai-assistant proxy opencode cline aider crush charmbracelet droid factory-ai pi-coding-agent open-webui llm coding-assistant opencode-claude-max-proxy
https://npm.im/@rynfar/meridian

pi-btwpi-btw
A pi extension for parallel side conversations with /btwA pi extension for parallel side conversations with /btw
Version 0.3.8 published 2026-04-30 by GitHub Actions
Maintainers: dbachelder
Keywords: pi-package pi-extension pi-coding-agent agent tui
https://npm.im/pi-btw

pi-crewpi-crew
Pi extension for coordinated AI teams, workflows, worktrees, and async task orchestrationPi extension for coordinated AI teams, workflows, worktrees, and async task orchestration
Version 0.1.41 published 2026-04-30 by bom0792
Maintainers: bom0792
Keywords: pi-package pi pi-coding-agent teams agents multi-agent orchestration
https://npm.im/pi-crew

pi-interactive-shellpi-interactive-shell
Run AI coding agents in pi TUI overlays with interactive, hands-free, and dispatch supervisionRun AI coding agents in pi TUI overlays with interactive, hands-free, and dispatch supervision
Version 0.13.0 published 2026-04-23 by nicopreme
Maintainers: nicopreme
Keywords: pi-package pi pi-coding-agent extension interactive shell terminal tui subagent claude gemini codex
https://npm.im/pi-interactive-shell

@feniix/pi-notion@feniix/pi-notion
Notion API extension for pi — read, search, and manage Notion pages, databases, and contentNotion API extension for pi — read, search, and manage Notion pages, databases, and content
Version 2.2.2 published 2026-04-22 by feniix
Maintainers: feniix
Keywords: pi pi-package pi-extension pi-coding-agent ai notion productivity
https://npm.im/@feniix/pi-notion

pi-ask-userpi-ask-user
Interactive ask_user tool for pi-coding-agent with searchable split-pane selection UI, multi-select, and freeform inputInteractive ask_user tool for pi-coding-agent with searchable split-pane selection UI, multi-select, and freeform input
Version 0.8.0 published 2026-05-01 by edlsh
Maintainers: edlsh
Keywords: pi-package pi pi-coding-agent extension ask ask_user interactive
https://npm.im/pi-ask-user

pi-prompt-template-modelpi-prompt-template-model
Prompt template model selector extension for pi coding agentPrompt template model selector extension for pi coding agent
Version 0.9.3 published 2026-04-29 by nicopreme
Maintainers: nicopreme
Keywords: pi-package pi pi-coding-agent prompt-template model-selector extension
https://npm.im/pi-prompt-template-model

@walterra/pi-charts@walterra/pi-charts
Vega-Lite chart extension for pi coding agent - render data visualizations as inline imagesVega-Lite chart extension for pi coding agent - render data visualizations as inline images
Version 0.0.5 published 2026-03-23 by GitHub Actions
Maintainers: walterra
Keywords: pi-package pi pi-coding-agent extension vega-lite charts visualization data-viz
https://npm.im/@walterra/pi-charts

pi-convexpi-convex
Pi extension for Convex Cloud - queries, mutations, project management, and best practices validationPi extension for Convex Cloud - queries, mutations, project management, and best practices validation
Version 1.5.8 published 2026-04-27 by serlismaldonado
Maintainers: serlismaldonado
Keywords: pi-extension pi-package pi pi-coding-agent convex database backend
https://npm.im/pi-convex

@kaiserlich-dev/pi-session-search@kaiserlich-dev/pi-session-search
Full-text search across pi sessions with FTS5 index and overlay UIFull-text search across pi sessions with FTS5 index and overlay UI
Version 1.1.1 published 2026-02-25 by jksr194
Maintainers: jksr194
Keywords: pi-package pi-coding-agent search sessions fts5 sqlite
https://npm.im/@kaiserlich-dev/pi-session-search

pi-messenger-swarmpi-messenger-swarm
Swarm-first multi-agent messaging and task orchestration extension for PiSwarm-first multi-agent messaging and task orchestration extension for Pi
Version 0.25.4 published 2026-04-26 by monotykamary
Maintainers: monotykamary
Keywords: pi-package pi pi-coding-agent extension swarm multi-agent agent-mesh task-orchestration subagents cli
https://npm.im/pi-messenger-swarm

mypensievemypensieve
A general-purpose, self-evolving autonomous agent OS with persistent memory across sessionsA general-purpose, self-evolving autonomous agent OS with persistent memory across sessions
Version 0.3.6 published 2026-04-22 by GitHub Actions
Maintainers: huntersreeni
Keywords: agent ai memory autonomous pensieve pi-coding-agent llm cli telegram
https://npm.im/mypensieve

@victor-software-house/pi-openai-proxy@victor-software-house/pi-openai-proxy
OpenAI-compatible HTTP proxy for pi's multi-provider model registryOpenAI-compatible HTTP proxy for pi's multi-provider model registry
Version 4.9.3 published 2026-03-29 by GitHub Actions
Maintainers: victor-founder victoraraujo105
Keywords: openai proxy pi-coding-agent pi-package llm gateway
https://npm.im/@victor-software-house/pi-openai-proxy

@ifi/pi-shared-qna@ifi/pi-shared-qna
Shared TUI question-and-answer component for pi extensions.Shared TUI question-and-answer component for pi extensions.
Version 0.5.1 published 2026-04-28 by ifiokjr
Maintainers: ifiokjr
Keywords: components extension-library pi pi-coding-agent qna tui
https://npm.im/@ifi/pi-shared-qna

pi-interviewpi-interview
Interactive interview form extension for pi coding agentInteractive interview form extension for pi coding agent
Version 0.8.7 published 2026-05-01 by nicopreme
Maintainers: nicopreme
Keywords: pi pi-coding-agent pi-package interview form extension cli
https://npm.im/pi-interview

@feniix/pi-specdocs@feniix/pi-specdocs
Structured spec documentation — PRDs, ADRs, and implementation plans with cross-referencingStructured spec documentation — PRDs, ADRs, and implementation plans with cross-referencing
Version 2.4.4 published 2026-04-23 by GitHub Actions
Maintainers: feniix
Keywords: pi pi-package pi-extension pi-coding-agent ai prd adr architecture requirements specs
https://npm.im/@feniix/pi-specdocs

pi-antigravity-rotatorpi-antigravity-rotator
Multi-account rotation proxy for Google Antigravity with per-model routing, real-time quota tracking, and infringement detectionMulti-account rotation proxy for Google Antigravity with per-model routing, real-time quota tracking, and infringement detection
Version 1.10.1 published 2026-04-30 by tuxevil
Maintainers: tuxevil
Keywords: pi-package pi pi-coding pi-coding-agent antigravity proxy rotation google quota gemini
https://npm.im/pi-antigravity-rotator

@ifi/oh-pi-core@ifi/oh-pi-core
Shared types, registries, and i18n for oh-pi packages.Shared types, registries, and i18n for oh-pi packages.
Version 0.5.1 published 2026-04-28 by ifiokjr
Maintainers: ifiokjr
Keywords: core i18n oh-pi pi pi-coding-agent registry types
https://npm.im/@ifi/oh-pi-core

@howaboua/pi-codex-conversion@howaboua/pi-codex-conversion
Codex-oriented tool and prompt adapter for pi coding agentCodex-oriented tool and prompt adapter for pi coding agent
Version 1.0.28 published 2026-04-28 by howaboua
Maintainers: howaboua
Keywords: pi-package pi pi-coding-agent extension codex adapter apply-patch
https://npm.im/@howaboua/pi-codex-conversion

@ifi/pi-extension-subagents@ifi/pi-extension-subagents
Full-featured subagent orchestration extension for pi, built on top of nicobailon/pi-subagents.Full-featured subagent orchestration extension for pi, built on top of nicobailon/pi-subagents.
Version 0.5.1 published 2026-04-28 by ifiokjr
Maintainers: ifiokjr
Keywords: chains delegation multi-agent pi pi-coding-agent pi-package subagents
https://npm.im/@ifi/pi-extension-subagents

pi-depopi-depo
Declarative package manager for Pi Coding Agent - skills, extensions, hooks, MCP serversDeclarative package manager for Pi Coding Agent - skills, extensions, hooks, MCP servers
Version 0.1.42 published 2026-04-24 by GitHub Actions
Maintainers: fulgidus
Keywords: pi-package pi-coding-agent package-manager
https://npm.im/pi-depo

pi-tool-displaypi-tool-display
Compact tool call rendering, diff visualization, and output truncation extension for Pi coding agent. Hides, collapses, and truncates verbose tool output for cleaner TUI display.Compact tool call rendering, diff visualization, and output truncation extension for Pi coding agent. Hides, collapses, and truncates verbose tool output for cleaner TUI display.
Version 0.3.5 published 2026-04-27 by masurii
Maintainers: masurii
Keywords: pi-package pi pi-extension pi-coding-agent pi-tui coding-agent tui tool-rendering tool-output diff-visualization output-truncation hide collapse truncate compact diff output-mode
https://npm.im/pi-tool-display

@ifi/pi-plan@ifi/pi-plan
Planning mode extension for pi with persistent plan files, branch-aware planning, and delegated research tasks.Planning mode extension for pi with persistent plan files, branch-aware planning, and delegated research tasks.
Version 0.5.1 published 2026-04-28 by ifiokjr
Maintainers: ifiokjr
Keywords: branch-planning pi pi-coding-agent pi-package plan-mode planning research
https://npm.im/@ifi/pi-plan

@pi-unipi/info-screen@pi-unipi/info-screen
Dashboard and module registry for Unipi — configurable info overlay with tabbed groupsDashboard and module registry for Unipi — configurable info overlay with tabbed groups
Version 0.1.21 published 2026-05-01 by neuron-mr-white
Maintainers: neuron-mr-white
Keywords: pi-package pi-extension pi-coding-agent unipi info-screen dashboard
https://npm.im/@pi-unipi/info-screen

@feniix/pi-exa@feniix/pi-exa
Exa API extension for pi — web search, content fetching, and advanced search via Exa AIExa API extension for pi — web search, content fetching, and advanced search via Exa AI
Version 3.4.2 published 2026-04-27 by GitHub Actions
Maintainers: feniix
Keywords: pi pi-package pi-extension pi-coding-agent ai exa search websearch
https://npm.im/@feniix/pi-exa

pi-extension-managerpi-extension-manager
Interactive extension and package manager for PiInteractive extension and package manager for Pi
Version 0.8.2 published 2026-03-31 by GitHub Actions
Maintainers: victor-founder
Keywords: pi-package pi-extension pi-coding-agent extensions manager
https://npm.im/pi-extension-manager

@robzolkos/lazypi@robzolkos/lazypi
Opinionated one-shot installer for a full-featured Pi coding agent setup.Opinionated one-shot installer for a full-featured Pi coding agent setup.
Version 0.5.0 published 2026-04-30 by GitHub Actions
Maintainers: robzolkos
Keywords: pi pi-mono pi-coding-agent installer npx extensions
https://npm.im/@robzolkos/lazypi

== npm search: pi-coding-agent whatsapp ==
@mariozechner/pi-coding-agent@mariozechner/pi-coding-agent
Coding agent CLI with read, bash, edit, write tools and session managementCoding agent CLI with read, bash, edit, write tools and session management
Version 0.71.1 published 2026-05-01 by badlogic
Maintainers: badlogic mitsuhiko
Keywords: coding-agent ai llm cli tui agent
https://npm.im/@mariozechner/pi-coding-agent

whatsapp-piwhatsapp-pi
WhatsApp integration extension for PiWhatsApp integration extension for Pi
Version 1.0.43 published 2026-04-29 by castelloes
Maintainers: castelloes
Keywords: pi pi-package pi-extension whatsapp baileys agent
https://npm.im/whatsapp-pi

@oh-my-pi/pi-coding-agent@oh-my-pi/pi-coding-agent
Coding agent CLI with read, bash, edit, write tools and session managementCoding agent CLI with read, bash, edit, write tools and session management
Version 14.5.14 published 2026-05-01 by can1357
Maintainers: can1357
Keywords: coding-agent ai llm cli tui agent
https://npm.im/@oh-my-pi/pi-coding-agent

@mariozechner/pi-agent-core@mariozechner/pi-agent-core
General-purpose agent with transport abstraction, state management, and attachment supportGeneral-purpose agent with transport abstraction, state management, and attachment support
Version 0.71.1 published 2026-05-01 by badlogic
Maintainers: badlogic mitsuhiko
Keywords: ai agent llm transport state-management
https://npm.im/@mariozechner/pi-agent-core

pi-acppi-acp
ACP adapter for pi coding agentACP adapter for pi coding agent
Version 0.0.26 published 2026-04-18 by deepstereo
Maintainers: deepstereo
Keywords: acp agent-client-protocol pi-coding-agent adapter
https://npm.im/pi-acp

react-doctorreact-doctor
Diagnose and fix React codebases for security, performance, correctness, accessibility, bundle-size, and architecture issuesDiagnose and fix React codebases for security, performance, correctness, accessibility, bundle-size, and architecture issues
Version 0.0.47 published 2026-05-01 by abai
Maintainers: abai
Keywords: accessibility diagnostics knip linter nextjs oxlint performance react react-compiler react-native security tanstack typescript
https://npm.im/react-doctor

@ollama/pi-web-search@ollama/pi-web-search
Web search and fetch tools for Pi agent - uses Ollama's web search and fetch APIsWeb search and fetch tools for Pi agent - uses Ollama's web search and fetch APIs
Version 0.0.5 published 2026-03-28 by parthollama
Maintainers: jmorgan mchiang0610 drifkin bruce-ollama parthollama
Keywords: pi-package pi-extension web-search ollama
https://npm.im/@ollama/pi-web-search

@rivet-dev/agent-os-core@rivet-dev/agent-os-core
A high-level SDK for running coding agents in isolated VMs. agentOS manages the full lifecycle of virtual machines — from filesystem setup and process management to launching AI agents via the Agent Communication Protocol (ACP).A high-level SDK for running coding agents in isolated VMs. agentOS manages the full lifecycle of virtual machines — from filesystem setup and process management to launching AI agents via the Agent Communication Protocol (ACP).
Version 0.1.1 published 2026-04-02 by nathanflurry
Maintainers: nathanflurry
https://npm.im/@rivet-dev/agent-os-core

acpxacpx
Headless CLI client for the Agent Client Protocol (ACP) — talk to coding agents from the command lineHeadless CLI client for the Agent Client Protocol (ACP) — talk to coding agents from the command line
Version 0.6.1 published 2026-04-25 by steipete
Maintainers: steipete osolmaz
Keywords: acp agent-client-protocol ai claude-code cli codex coding-agent
https://npm.im/acpx

@plannotator/pi-extension@plannotator/pi-extension
Plannotator extension for Pi coding agent - interactive plan review with visual annotationPlannotator extension for Pi coding agent - interactive plan review with visual annotation
Version 0.19.5 published 2026-05-01 by GitHub Actions
Maintainers: backnotprop
Keywords: pi-package plannotator plan-review ai-agent coding-agent
https://npm.im/@plannotator/pi-extension

@cleocode/cleo-os@cleocode/cleo-os
CleoOS — the batteries-included agentic development environment wrapping PiCleoOS — the batteries-included agentic development environment wrapping Pi
Version 2026.5.0 published 2026-05-01 by kryptobaseddev
Maintainers: kryptobaseddev
https://npm.im/@cleocode/cleo-os

gsd-pigsd-pi
GSD — Get Shit Done coding agentGSD — Get Shit Done coding agent
Version 2.78.1 published 2026-04-25 by glittercowboy
Maintainers: glittercowboy
https://npm.im/gsd-pi

gitnexusgitnexus
Graph-powered code intelligence for AI agents. Index any codebase, query via MCP or CLI.Graph-powered code intelligence for AI agents. Index any codebase, query via MCP or CLI.
Version 1.6.3 published 2026-04-24 by abhigyanpatwari
Maintainers: abhigyanpatwari
Keywords: mcp model-context-protocol code-intelligence knowledge-graph cursor claude codex ai-agent gitnexus static-analysis codebase-indexing
https://npm.im/gitnexus

@lenylvt/pi-coding-agent@lenylvt/pi-coding-agent
Coding agent CLI with read, bash, edit, write tools and session managementCoding agent CLI with read, bash, edit, write tools and session management
Version 0.70.1 published 2026-04-21 by lleny
Maintainers: lleny
Keywords: coding-agent ai llm cli tui agent
https://npm.im/@lenylvt/pi-coding-agent

@whiskeysockets/baileys@whiskeysockets/baileys
A WebSockets library for interacting with WhatsApp WebA WebSockets library for interacting with WhatsApp Web
Version 7.0.0-rc.9 published 2025-11-21 by purpshell
Maintainers: purpshell auties00 shelltear
Keywords: whatsapp automation
https://npm.im/@whiskeysockets/baileys

@github/copilot@github/copilot
GitHub Copilot CLI brings the power of Copilot coding agent directly to your terminal.GitHub Copilot CLI brings the power of Copilot coding agent directly to your terminal.
Version 1.0.40 published 2026-05-01 by GitHub Actions
Maintainers: mxie-github tidy-dev croffz devm33 manuelpuyol jonrohan primer-css gracepark jibrangarcia arelia tylerthedev smockle simurai khiga8 dustin.greif srt32 githubbot jfuchs andrialexandrou bteng22 dustin.savery ncalteen
https://npm.im/@github/copilot

@codex-infinity/pi-infinity@codex-infinity/pi-infinity
Coding agent CLI with read, bash, edit, write tools and session managementCoding agent CLI with read, bash, edit, write tools and session management
Version 0.70.8 published 2026-04-29 by lee101-3
Maintainers: lee101-3
Keywords: coding-agent ai llm cli tui agent
https://npm.im/@codex-infinity/pi-infinity

@juicesharp/rpiv-pi@juicesharp/rpiv-pi
Skill-based development workflow for Pi Agent — discover, research, design, plan, implement, validateSkill-based development workflow for Pi Agent — discover, research, design, plan, implement, validate
Version 1.0.13 published 2026-05-01 by juicesharp
Maintainers: juicesharp
Keywords: pi-package pi-extension rpiv skills workflow
https://npm.im/@juicesharp/rpiv-pi

@heart-of-gold/toolkit@heart-of-gold/toolkit
Cross-platform installer for Heart of Gold skills — works with Codex, OpenCode, Pi, Claude Code, and moreCross-platform installer for Heart of Gold skills — works with Codex, OpenCode, Pi, Claude Code, and more
Version 0.1.50 published 2026-04-26 by ondrejsvec
Maintainers: ondrejsvec
Keywords: codex claude-code opencode pi pi-package ai-agents skills agents-md agentskills harness-engineering heart-of-gold
https://npm.im/@heart-of-gold/toolkit

@agentuity/coder-tui@agentuity/coder-tui
Agentuity Coder Hub extension for Pi coding agentAgentuity Coder Hub extension for Pi coding agent
Version 2.0.12 published 2026-04-28 by jhaynie
Maintainers: p0tofpie huijiro jhaynie robindiddams
https://npm.im/@agentuity/coder-tui

@avadisabelle/ava-pi-coding-agent@avadisabelle/ava-pi-coding-agent
Coding agent CLI with read, bash, edit, write tools and session managementCoding agent CLI with read, bash, edit, write tools and session management
Version 0.65.2 published 2026-04-27 by avadisabelle
Maintainers: avadisabelle
Keywords: coding-agent ai llm cli tui agent
https://npm.im/@avadisabelle/ava-pi-coding-agent

storybook-builder-rsbuildstorybook-builder-rsbuild
Rsbuild builder for StorybookRsbuild builder for Storybook
Version 3.3.3 published 2026-04-11 by GitHub Actions
Maintainers: fi3ework
Keywords: storybook rsbuild rspack
https://npm.im/storybook-builder-rsbuild

@hyperspaceng/neural-coding-agent@hyperspaceng/neural-coding-agent
Coding agent CLI with read, bash, edit, write tools and session managementCoding agent CLI with read, bash, edit, write tools and session management
Version 0.70.7 published 2026-04-30 by hyperspaceng
Maintainers: hyperspaceng
Keywords: coding-agent ai llm cli tui agent
https://npm.im/@hyperspaceng/neural-coding-agent

@foxxytux/buddy-coding-agent@foxxytux/buddy-coding-agent
General agent CLI with read, bash, edit, write tools and session managementGeneral agent CLI with read, bash, edit, write tools and session management
Version 4.1.28 published 2026-04-24 by foxxytux
Maintainers: foxxytux
Keywords: general-agent agent-cli ai llm cli tui agent
https://npm.im/@foxxytux/buddy-coding-agent

storybook-react-rsbuildstorybook-react-rsbuild
Storybook for React and Rsbuild: Develop React components in isolation with Hot Reloading.Storybook for React and Rsbuild: Develop React components in isolation with Hot Reloading.
Version 3.3.3 published 2026-04-11 by GitHub Actions
Maintainers: fi3ework
Keywords: storybook rsbuild rspack react
https://npm.im/storybook-react-rsbuild

@elizaos/plugin-agent-orchestrator@elizaos/plugin-agent-orchestrator
Coding agent orchestration plugin - spawn and manage CLI coding agents via PTYCoding agent orchestration plugin - spawn and manage CLI coding agents via PTY
Version 0.3.9 published 2026-03-06 by haruhunab1320
Maintainers: haruhunab1320 shawticus odilitime
https://npm.im/@elizaos/plugin-agent-orchestrator

@elizaos/plugin-coding-agent@elizaos/plugin-coding-agent
Coding agent orchestration plugin - spawn and manage CLI coding agents via PTYCoding agent orchestration plugin - spawn and manage CLI coding agents via PTY
Version 0.1.0-next.0 published 2026-02-27 by shawticus
Maintainers: haruhunab1320 shawticus odilitime
Keywords: elizaos plugin coding-agent pty swarm claude-code aider
https://npm.im/@elizaos/plugin-coding-agent

@zenai/playwright-coding-agent-reporter@zenai/playwright-coding-agent-reporter
A coding agent friendly reporter for playwright, so that your coding agent finally really understands what is going wrongA coding agent friendly reporter for playwright, so that your coding agent finally really understands what is going wrong
Version 1.2.1 published 2025-09-27 by fabian_zenai
Maintainers: fabian_zenai
Keywords: playwright reporter testing llm agent ai
https://npm.im/@zenai/playwright-coding-agent-reporter

skillflagskillflag
Skillflag producer CLI reference implementation.Skillflag producer CLI reference implementation.
Version 0.1.4 published 2026-02-20 by GitHub Actions
Maintainers: osolmaz
https://npm.im/skillflag

claude-recallclaude-recall
Persistent memory for Claude Code and Pi with native Skills integration, automatic capture, failure learning, and project scopingPersistent memory for Claude Code and Pi with native Skills integration, automatic capture, failure learning, and project scoping
Version 0.25.1 published 2026-04-28 by genaisolutions
Maintainers: genaisolutions
Keywords: claude-code mcp memory ai claude anthropic model-context-protocol
https://npm.im/claude-recall

== npm search: keywords:pi-package ==
whatsapp-pi
WhatsApp integration extension for Pi
Keywords: pi pi-package pi-extension whatsapp baileys agent
https://npm.im/whatsapp-pi
Version 0.1.0 published 2026-02-28 by fywang96
Maintainers: fywang96
Maintainers: advaitpaliwal hariva.sh
ChatGPT web-oracle extension for pi with isolated browser auth, async jobs, and project-context archives.
Keywords: pi-package pi pi-extension extension chatgpt oracle
@walterra/pi-charts
Maintainers: walterra
https://npm.im/@walterra/pi-charts
pi-messenger-swarm
Swarm-first multi-agent messaging and task orchestration extension for Pi
Keywords: pi-package pi pi-coding-agent extension swarm multi-agent agent-mesh task-orchestration subagents cli
https://npm.im/pi-messenger-swarm
@victor-software-house/pi-openai-proxy
Keywords: openai proxy pi-coding-agent pi-package llm gateway
https://npm.im/@victor-software-house/pi-openai-proxy
Behavior monitors for pi that watch agent activity and steer corrections
Pair programming with Pi, be aware of every change made to the codebase.
@howaboua/pi-codex-conversion
Version 1.0.28 published 2026-04-28 by howaboua
Maintainers: howaboua
https://npm.im/@howaboua/pi-codex-conversion


**Considering messaging options**

I need to create a shortlist of likely relevant options, such as whatsapp-pi, pi-messenger-bridge, and possibly @0xkobold/pi-gateway for multi-platform messaging. It’s clear that I’ll need to audit these options. I'll check out the npm view for each package repository and consider cloning them for a closer look. This way, I can make sure I'm selecting the best tools for the project. Let's dive in!

set -e
for pkg in whatsapp-pi pi-messenger-bridge @0xkobold/pi-gateway; do
  echo "== $pkg =="
  npm view "$pkg" version repository homepage description dist.unpackedSize dist.tarball maintainers --json
  echo
done


== whatsapp-pi ==
{
  "version": "1.0.43",
  "repository": {
    "type": "git",
    "url": "git+https://github.com/RaphaCastelloes/whatsapp-pi.git"
  },
  "homepage": "https://github.com/RaphaCastelloes/whatsapp-pi#readme",
  "description": "WhatsApp integration extension for Pi",
  "dist.unpackedSize": 109793,
  "dist.tarball": "https://registry.npmjs.org/whatsapp-pi/-/whatsapp-pi-1.0.43.tgz",
  "maintainers": [
    "castelloes <castelloesjf@hotmail.com>"
  ]
}

== pi-messenger-bridge ==
{
  "version": "0.3.0",
  "repository": {
    "type": "git",
    "url": "git+https://github.com/tintinweb/pi-messenger-bridge.git"
  },
  "homepage": "https://github.com/tintinweb/pi-messenger-bridge#readme",
  "description": "Bridge common messengers (Telegram, WhatsApp, Slack, Discord) into pi",
  "dist.unpackedSize": 188060,
  "dist.tarball": "https://registry.npmjs.org/pi-messenger-bridge/-/pi-messenger-bridge-0.3.0.tgz",
  "maintainers": [
    "tintinweb <tintinweb@oststrom.com>"
  ]
}

== @0xkobold/pi-gateway ==
{
  "version": "0.6.0",
  "repository": {
    "type": "git",
    "url": "git+https://github.com/0xKobold/pi-gateway.git"
  },
  "homepage": "https://github.com/0xKobold/pi-gateway#readme",
  "description": "Hermes-style messaging gateway for pi - multi-platform agent with sessions, security, and background tasks",
  "dist.unpackedSize": 338523,
  "dist.tarball": "https://registry.npmjs.org/@0xkobold/pi-gateway/-/pi-gateway-0.6.0.tgz",
  "maintainers": [
    "moikapy <warrenckhan@gmail.com>"
  ]
}


**Evaluating package security**

I'm thinking it’s time to audit some unusual stuff. I should clone the repositories and take a closer look at the scripts in package.json. There might be suspicious patterns that need addressing. I could also run an npm audit at runtime to see if any vulnerabilities pop up. It's just crucial to make sure everything is safe and secure! Let’s keep a keen eye on this.

set -e
base=$(mktemp -d /tmp/pi-messaging-audit-XXXXXX)
echo "$base"
cd "$base"
for repo in \
  https://github.com/RaphaCastelloes/whatsapp-pi \
  https://github.com/tintinweb/pi-messenger-bridge \
  https://github.com/0xKobold/pi-gateway
 do
  name=$(basename "$repo")
  git clone --depth 1 "$repo" "$name" >/dev/null 2>&1 || echo "clone failed: $repo"
done
for dir in whatsapp-pi pi-messenger-bridge pi-gateway; do
  [ -d "$dir" ] || continue
  echo "\n===== $dir ====="
  cd "$base/$dir"
  echo "-- recent commits --"
  git log --oneline -n 6 || true
  echo "-- package.json --"
  [ -f package.json ] && node -e 'const p=require("./package.json"); console.log(JSON.stringify({name:p.name,version:p.version,scripts:p.scripts,dependencies:p.dependencies,devDependencies:p.devDependencies,pi:p.pi},null,2))'
  echo "-- suspicious search --"
  rg -n --hidden -S "postinstall|preinstall|curl |wget |child_process|exec\(|spawn\(|fork\(|eval\(|new Function|http://|https://|webhook|discord|telegram|slack|ngrok|tailscale|ssh |scp |rsync |netcat|nc |sudo |rm -rf|chmod 777|process\.env|openai|anthropic|gemini|fetch\(|axios|request\(|bot token|api key|Bearer " . || true
  echo "-- top files --"
  find . -maxdepth 3 -type f | sed 's#^./##' | sort | head -120
 done