[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-1677":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":8,"htmlUrl":8,"language":9,"languages":8,"totalLinesOfCode":8,"stars":10,"forks":11,"watchers":12,"openIssues":13,"contributorsCount":14,"subscribersCount":14,"size":14,"stars1d":15,"stars7d":16,"stars30d":17,"stars90d":14,"forks30d":14,"starsTrendScore":18,"compositeScore":19,"rankGlobal":8,"rankLanguage":8,"license":8,"archived":20,"fork":20,"defaultBranch":21,"hasWiki":22,"hasPages":20,"topics":23,"createdAt":8,"pushedAt":8,"updatedAt":25,"readmeContent":26,"aiSummary":27,"trendingCount":14,"starSnapshotCount":14,"syncStatus":28,"lastSyncTime":29,"discoverSource":30},1677,"pi-chat","earendil-works\u002Fpi-chat","earendil-works",null,"TypeScript",288,41,4,9,0,10,20,54,30,4.87,false,"main",true,[24],"slop","2026-06-12 02:00:31","# pi-chat\n\nA pi extension that bridges Discord and Telegram channels to a sandboxed pi session. Each connected channel gets its own [Gondolin](https:\u002F\u002Fgithub.com\u002Fearendil-works\u002Fgondolin) micro-VM with persistent workspace, shared storage, memory, and skills.\n\n## Quick Start\n\n```bash\n# Install\npi install \u002Fpath\u002Fto\u002Fpi-chat\n# or\npi -e \u002Fpath\u002Fto\u002Fpi-chat\n\n# Configure accounts and channels\n\u002Fchat-config\n\n# Connect\n\u002Fchat-connect\n```\n\n### Requirements\n\n- [QEMU](https:\u002F\u002Fwww.qemu.org\u002F) installed (`brew install qemu` on macOS)\n- Gondolin guest image (downloaded automatically on first connect)\n- A Discord bot token or Telegram bot token\n- `tmux` for multi-channel worker orchestration\n\n---\n\n## Features\n\n- **Discord server channels** and **Telegram DMs\u002Fgroups**\n- **Gondolin VM sandbox** per connection — tools run inside an isolated Alpine Linux micro-VM\n- **Persistent workspace** and **shared storage** across sessions\n- **Streamed preview** responses with edit-in-place\n- **Reply-to-trigger** — bot replies are attached to the triggering message\n- **Durable memory** — account-wide and channel-specific memory files\n- **Skills** — agent-created reusable tools, auto-discovered and injected into the prompt\n- **Encrypted secret exchange** — securely pass credentials via browser-based encryption\n- **Remote control** — stop, compact, new session, and status via chat commands\n- **Chat history** tool for searching older messages\n- **File attachments** — send and receive files between chat and the VM\n\n---\n\n## Setup\n\n### Discord\n\n1. Create a bot at [Discord Developer Portal](https:\u002F\u002Fdiscord.com\u002Fdevelopers\u002Fapplications)\n2. Enable **Message Content Intent** under Bot settings\n3. Run `\u002Fchat-config` → Create account → Discord\n4. Enter your bot token\n5. Invite the bot to a server (the setup flow provides the invite URL)\n6. Select a server and configure channels\n\n### Telegram\n\n1. Create a bot via [@BotFather](https:\u002F\u002Ft.me\u002FBotFather)\n2. Run `\u002Fchat-config` → Create account → Telegram\n3. Enter your bot token\n4. Add DMs or groups through the guided setup\n\n---\n\n## Commands\n\n| Command | Description |\n|---------|-------------|\n| `\u002Fchat-config` | Configure accounts, channels, and secrets |\n| `\u002Fchat-connect` | Connect to a configured channel |\n| `\u002Fchat-disconnect` | Disconnect the current channel |\n| `\u002Fchat-status` | Show connection status, model, usage, context |\n| `\u002Fchat-list` | List configured channels |\n| `\u002Fchat-spawn-all` | Spawn every configured channel in detached tmux\u002Fpi sessions |\n| `\u002Fchat-spawn-all --restart` | Restart those tmux\u002Fpi sessions |\n| `\u002Fchat-workers` | Show managed tmux\u002Fpi worker status |\n| `\u002Fchat-open-all` | Open running workers in a tiled tmux dashboard |\n| `\u002Fchat-kill-all` | Kill all managed tmux\u002Fpi workers |\n| `\u002Fchat-new` | Start a new pi session, keeping the chat connection |\n\nWorkers also write status snapshots every 15 seconds under `~\u002F.pi\u002Fagent\u002Fchat\u002Fworker-status\u002F`. The `chat_workers` tool exposes the same status to an orchestrating pi agent.\n\n---\n\n## Remote Control\n\nUsers in the connected chat can send these commands (with or without mentioning the bot):\n\n| Command | Effect |\n|---------|--------|\n| `stop` | Abort the current turn |\n| `status` | Show model, usage, context stats |\n| `compact` | Trigger context compaction |\n| `new` | Start a new pi session |\n\n---\n\n## Storage Layout\n\nEverything lives under `~\u002F.pi\u002Fagent\u002Fchat\u002F`:\n\n```\n~\u002F.pi\u002Fagent\u002Fchat\u002F\n├── config.json                          # Accounts, channels, secrets\n├── cache\u002F                               # Discovery cache\n└── accounts\u002F\u003Caccount>\u002F\n    ├── shared\u002F                          # Mounted as \u002Fshared in VM\n    │   ├── memory.md                    # Account-wide persistent memory\n    │   └── skills\u002F                      # Account-wide skills\n    └── channels\u002F\u003Cchannel>\u002F\n        ├── channel.jsonl                # Chat log\n        ├── .lock                        # Runtime lock\n        ├── workspace\u002F                   # Mounted as \u002Fworkspace in VM\n        │   ├── memory.md                # Channel-specific persistent memory\n        │   ├── skills\u002F                  # Channel-specific skills\n        │   ├── incoming\u002F                # Downloaded attachments\n        │   ├── .secrets\u002F                # Encrypted secrets\n        │   └── SYSTEM.md                # Environment modification log\n        └── gondolin\u002F                    # VM state\n            └── session.json\n```\n\n---\n\n## VM Environment\n\nEach connection starts a Gondolin micro-VM with:\n\n- **Alpine Linux** with bash pre-installed\n- `\u002Fworkspace` → channel workspace directory\n- `\u002Fshared` → account shared directory\n- Tools: `read`, `write`, `edit`, `bash`\n- All outbound HTTP\u002FTLS open by default\n\nThe agent sees `\u002Fworkspace` as its working directory.\n\n---\n\n## Memory\n\nTwo persistent memory files, injected into the system prompt on every turn:\n\n| File | VM Path | Scope |\n|------|---------|-------|\n| Account memory | `\u002Fshared\u002Fmemory.md` | Shared across all channels for this account |\n| Channel memory | `\u002Fworkspace\u002Fmemory.md` | Specific to this channel |\n\nThe agent is instructed to write durable facts and preferences to these files when asked to remember something. Account-wide goes to `\u002Fshared\u002Fmemory.md`, channel-specific to `\u002Fworkspace\u002Fmemory.md`.\n\n---\n\n## Skills\n\nThe agent can create reusable tools as skills, following the [Agent Skills standard](https:\u002F\u002Fagentskills.io):\n\n- **Account-wide:** `\u002Fshared\u002Fskills\u002F`\n- **Channel-specific:** `\u002Fworkspace\u002Fskills\u002F`\n\nA skill is either a single `.md` file (e.g. `skills\u002Ffoo.md`) or a directory with `SKILL.md` plus supporting files (e.g. `skills\u002Ffoo\u002FSKILL.md`, `skills\u002Ffoo\u002Frun.sh`).\n\nEach skill needs YAML frontmatter:\n\n```yaml\n---\nname: skill-name\ndescription: Short description of what this skill does\n---\n```\n\nSkills are automatically discovered and listed in the system prompt. The agent reads the full skill file before using it.\n\n---\n\n## Secrets\n\n### Config Secrets (Gondolin HTTP hooks)\n\nConfigure secrets at three levels via `\u002Fchat-config`:\n\n- **Global** — shared across all accounts\n- **Per account** — shared across channels of that account\n- **Per channel** — specific to one channel\n\nEach secret has a value and allowed host patterns. Gondolin replaces placeholder env vars with real values only for outbound HTTP requests to allowed hosts. The agent never sees the real secret value.\n\n### Runtime Secrets (encrypted exchange)\n\nFor credentials the agent needs at runtime (API keys for skills, OAuth files, etc.):\n\n1. Agent calls the `chat_request_secret` tool\n2. A link to `pi.dev\u002Fsecret` is sent to the chat with an embedded public key\n3. User clicks, pastes the secret, and gets an encrypted blob\n4. User pastes the blob back into chat\n5. pi-chat decrypts it (RSA-OAEP + AES-256-GCM) and stores it at `\u002Fworkspace\u002F.secrets\u002F\u003Cname>`\n6. Agent is notified and can use the file\n\nThe encrypted blob is useless without the ephemeral private key held in pi-chat's memory.\n\n---\n\n## Tools\n\n| Tool | Description |\n|------|-------------|\n| `read` | Read files (routed through Gondolin VM) |\n| `write` | Create\u002Foverwrite files |\n| `edit` | Precise in-place edits |\n| `bash` | Execute commands (runs `\u002Fbin\u002Fbash` in the VM) |\n| `chat_history` | Search older messages from the chat log |\n| `chat_attach` | Queue files to send with the next reply |\n| `chat_request_secret` | Request a secret from the user via encrypted exchange |\n\n---\n\n## Credits\n\npi-chat includes vendored\u002Fadapted logic inspired by [Vercel Chat SDK](https:\u002F\u002Fgithub.com\u002Fvercel\u002Fai) (MIT):\n\n- `src\u002Frender\u002Fformat.ts`\n- `src\u002Frender\u002Fstreaming-markdown.ts`\n- `src\u002Frender\u002Fstreaming.ts`\n\n---\n\n## License\n\nMIT\n","pi-chat 是一个将 Discord 和 Telegram 频道连接到沙盒化的 pi 会话的扩展工具。每个连接的频道都会获得一个基于 Gondolin 微虚拟机的独立工作空间，支持持久化存储、共享存储和技能。项目使用 TypeScript 编写，并且为每个连接提供了隔离的 Alpine Linux 微虚拟机环境，确保了安全性和稳定性。它适合需要跨平台聊天服务集成并希望在这些平台上运行特定任务或工具的场景，如自动化管理、开发协作等。此外，pi-chat 还支持加密的秘密交换、远程控制以及文件附件功能，使得用户可以方便地通过聊天命令进行高级操作。",2,"2026-06-11 02:45:23","CREATED_QUERY"]