diff --git a/README.md b/README.md
index 77cbea9..ecf4f8e 100644
--- a/README.md
+++ b/README.md
@@ -1,500 +1,508 @@
-# 🛡️ APort Integrations
-
-
-
-
-
-**Community-built integrations, SDKs, and tools for the APort ecosystem**
-
-[](https://github.com/aporthq/aport-integrations/issues)
-[](https://github.com/aporthq/aport-integrations/pulls)
-[](LICENSE)
-[](https://hacktoberfest.digitalocean.com/)
-
-[🌐 APort Website](https://aport.io) • [📚 Documentation](https://aport.io/docs) • [🚀 Try APort](https://aport.io/dashboard) • [💬 Discord](https://discord.gg/aport)
-
-
-
----
-
-## 🎯 About APort Integrations
-
-This repository houses community-contributed integrations, SDKs, middleware, and tools that extend APort's capabilities across different platforms, frameworks, and use cases. Each integration demonstrates how to implement APort's agent identity verification and policy enforcement in real-world scenarios.
-
-### 🏆 What Makes APort Special?
-
-- **🆔 Agent Identity**: Portable passports with capabilities & limits
-- **📋 Policy Packs**: Pre-built policies for common actions (refunds, data export, PR merges)
-- **⚡ Real-time Verify**: Sub-100ms policy checks with global suspend capability
-- **🔐 Multi-level Assurance**: Email, GitHub, Domain verification levels
-- **🌐 Platform Agnostic**: Works across all platforms and frameworks
-
----
-
-
-## 📦 Official SDKs
-
-The official APort SDKs are maintained in the [aport-sdks repository](https://github.com/aporthq/aport-sdks).
-
-### ✅ Currently Available
-
-#### Node.js/JavaScript
-- **Core SDK**: [@aporthq/sdk-node](https://github.com/aporthq/aport-sdks/tree/main/javascript) - Core Node.js SDK
-- **Express Middleware**: [@aporthq/middleware-express](https://github.com/aporthq/aport-sdks/tree/main/express) - Express.js middleware
-
-#### Python
-- **Core SDK**: [aporthq-sdk-python](https://github.com/aporthq/aport-sdks/tree/main/python) - Core Python SDK
-- **FastAPI Middleware**: [agent-passport-middleware-fastapi](https://github.com/aporthq/aport-sdks/tree/main/fastapi) - FastAPI middleware
-
-### 🚧 In Development (Hacktoberfest 2025)
-
-We're actively building more SDKs and integrations! Check out our [open issues](https://github.com/aporthq/aport-integrations/issues) to contribute:
-
-#### High Priority SDKs
-- **Go SDK** - Core Go SDK with Gin, Echo, Fiber middleware
-- **PHP SDK** - Core PHP SDK with Laravel middleware
-- **Ruby SDK** - Core Ruby SDK with Rails gem
-
-#### Agent Framework Integrations
-- **LangChain Integration** - Tool guard for LangChain
-- **CrewAI Integration** - Task verification decorator
-- **n8n Workflow Node** - Custom n8n node for policy checks
-
-#### Platform Integrations
-- **Zapier App** - Custom Zapier app for APort verification
-- **GitHub App** - PR/Merge verification
-- **Discord Bot** - Team verification workflows
-
-#### Developer Experience
-- **VS Code Extension** - Code snippets and syntax highlighting
-- **Postman Collection** - API testing and CI/CD integration
-- **CLI Tool** - Quick integration setup
-
-#### E-commerce & Financial
-- **Shopify App** - Refund protection for e-commerce
-- **Stripe Integration** - Payment verification
-- **Banking APIs** - Financial services integration
-
-#### Protocol Bridges
-- **OpenAPI Spec** - OpenAPI 3.1 specification for APort API
-- **AP2 Bridge** - AP2 payment authorization bridge
-- **SPIFFE/SPIRE** - Enterprise identity integration
-
-## 🎉 Hacktoberfest 2025 Progress
-
-We're actively building the APort ecosystem with **22+ open issues** and **6 issues already picked up** by contributors!
-
-### 📊 Current Status
-- **Total Issues**: 22 open issues
-- **Issues Picked Up**: 6 (27% pickup rate in 8 hours!)
-- **Total Bounty Pool**: $175+ USD
-- **Categories**: 10+ different integration types
-
-### 🏆 Most Popular Issues (Already Picked Up)
-1. **Blog Post Tutorial** - 2 assignees
-2. **n8n Workflow Node** - 1 assignee
-3. **Go SDK** - 1 assignee
-4. **Next.js Middleware** - 2 assignees
-5. **AP2 Payment Bridge** - 2 assignees
-6. **Zapier Custom App** - 1 assignee
-
-### 🎯 Strategic Need for Comprehensive SDK Coverage
-
-
-### **Agent Framework Coverage** (Highest Priority)
-- **LangChain**: Most popular AI framework - needs tool guard integration
-- **CrewAI**: Multi-agent orchestration - needs task verification decorator
-- **n8n**: Low-code automation - needs custom verification node
-- **LangGraph**: State machine workflows - needs checkpoint integration
-- **Zapier**: No-code automation - needs custom app
-
-### **E-commerce Platform Integration** (Design Partner Demos)
-- **Shopify**: Complete app with refund guardrails
-- **WooCommerce**: WordPress plugin for order verification
-- **Stripe**: Connect payout verification
-
-### **Developer Experience Tools** (Reduce Integration Friction)
-- **CLI Tool**: `npx create-aport-integration` scaffolding
-- **VS Code Extension**: Policy development with IntelliSense
-- **Postman Collection**: Complete API testing suite
-
-### **Framework Middleware** (Native Support)
-- **Next.js**: App Router and Pages Router support
-- **Django**: Python web framework middleware
-- **Laravel**: PHP framework with Artisan commands
-- **Rails**: Ruby gem with generators
-- **Go Frameworks**: Gin, Echo, Fiber middleware
-
-### **Protocol Bridges** (Universal Interoperability)
-- **OpenAPI 3.1**: Complete API specification
-- **AP2 Bridge**: Payment authorization integration
-- **SPIFFE/SPIRE**: Enterprise identity federation
-
-## 🚀 Quick Start
-
-### 1. Browse Available Integrations
-
-```bash
-# Clone the repository
-git clone https://github.com/aporthq/aport-integrations.git
-cd aport-integrations
-
-# Explore integrations by category
-ls examples/
-# agent-frameworks/ ecommerce/ developer-tools/ middleware/ protocol-bridges/
-```
-
-### 2. Try an Integration
-
-```bash
-# Example: LangChain Tool Guard
-cd examples/agent-frameworks/langchain
-npm install
-npm run example
-
-# Example: Express.js Middleware
-cd examples/middleware/express
-npm install
-npm start
-```
-
-### 3. Create Your Own Integration
-
-```bash
-# Use our CLI to scaffold a new integration
-npx create-aport-integration my-integration
-cd my-integration
-npm install
-```
-
----
-
-## 📁 Repository Structure
-
-```
-aport-integrations/
-├── examples/ # Working integration examples
+# 🛡️ APort Integrations
+
+
+
+
+
+**Community-built integrations, SDKs, and tools for the APort ecosystem**
+
+[](https://github.com/aporthq/aport-integrations/issues)
+[](https://github.com/aporthq/aport-integrations/pulls)
+[](LICENSE)
+[](https://hacktoberfest.digitalocean.com/)
+
+[🌐 APort Website](https://aport.io) • [📚 Documentation](https://aport.io/docs) • [🚀 Try APort](https://aport.io/dashboard) • [💬 Discord](https://discord.gg/aport)
+
+
+
+---
+
+## 🎯 About APort Integrations
+
+This repository houses community-contributed integrations, SDKs, middleware, and tools that extend APort's capabilities across different platforms, frameworks, and use cases. Each integration demonstrates how to implement APort's agent identity verification and policy enforcement in real-world scenarios.
+
+### 🏆 What Makes APort Special?
+
+- **🆔 Agent Identity**: Portable passports with capabilities & limits
+- **📋 Policy Packs**: Pre-built policies for common actions (refunds, data export, PR merges)
+- **⚡ Real-time Verify**: Sub-100ms policy checks with global suspend capability
+- **🔐 Multi-level Assurance**: Email, GitHub, Domain verification levels
+- **🌐 Platform Agnostic**: Works across all platforms and frameworks
+
+---
+
+
+## 📦 Official SDKs
+
+The official APort SDKs are maintained in the [aport-sdks repository](https://github.com/aporthq/aport-sdks).
+
+### ✅ Currently Available
+
+#### Node.js/JavaScript
+- **Core SDK**: [@aporthq/sdk-node](https://github.com/aporthq/aport-sdks/tree/main/javascript) - Core Node.js SDK
+- **Express Middleware**: [@aporthq/middleware-express](https://github.com/aporthq/aport-sdks/tree/main/express) - Express.js middleware
+
+#### Python
+- **Core SDK**: [aporthq-sdk-python](https://github.com/aporthq/aport-sdks/tree/main/python) - Core Python SDK
+- **FastAPI Middleware**: [agent-passport-middleware-fastapi](https://github.com/aporthq/aport-sdks/tree/main/fastapi) - FastAPI middleware
+
+### 🚧 In Development (Hacktoberfest 2025)
+
+We're actively building more SDKs and integrations! Check out our [open issues](https://github.com/aporthq/aport-integrations/issues) to contribute:
+
+#### High Priority SDKs
+- **Go SDK** - Core Go SDK with Gin, Echo, Fiber middleware
+- **PHP SDK** - Core PHP SDK with Laravel middleware
+- **Ruby SDK** - Core Ruby SDK with Rails gem
+
+#### Agent Framework Integrations
+- **LangChain Integration** - Tool guard for LangChain
+- **CrewAI Integration** - Task verification decorator
+- **n8n Workflow Node** - Custom n8n node for policy checks
+
+#### Platform Integrations
+- **Zapier App** - Custom Zapier app for APort verification
+- **GitHub App** - PR/Merge verification
+- **Discord Bot** - Team verification workflows
+
+#### Developer Experience
+- **VS Code Extension** - Code snippets and syntax highlighting
+- **Postman Collection** - API testing and CI/CD integration
+- **CLI Tool** - Quick integration setup
+
+#### E-commerce & Financial
+- **Shopify App** - Refund protection for e-commerce
+- **Stripe Integration** - Payment verification
+- **Banking APIs** - Financial services integration
+
+#### Protocol Bridges
+- **OpenAPI Spec** - OpenAPI 3.1 specification for APort API
+- **AP2 Bridge** - AP2 payment authorization bridge
+- **SPIFFE/SPIRE** - Enterprise identity integration
+
+## 🎉 Hacktoberfest 2025 Progress
+
+We're actively building the APort ecosystem with **22+ open issues** and **6 issues already picked up** by contributors!
+
+### 📊 Current Status
+- **Total Issues**: 22 open issues
+- **Issues Picked Up**: 6 (27% pickup rate in 8 hours!)
+- **Total Bounty Pool**: $175+ USD
+- **Categories**: 10+ different integration types
+
+### 🏆 Most Popular Issues (Already Picked Up)
+1. **Blog Post Tutorial** - 2 assignees
+2. **n8n Workflow Node** - 1 assignee
+3. **Go SDK** - 1 assignee
+4. **Next.js Middleware** - 2 assignees
+5. **AP2 Payment Bridge** - 2 assignees
+6. **Zapier Custom App** - 1 assignee
+
+### 🎯 Strategic Need for Comprehensive SDK Coverage
+
+
+### **Agent Framework Coverage** (Highest Priority)
+- **LangChain**: Most popular AI framework - needs tool guard integration
+- **CrewAI**: Multi-agent orchestration - needs task verification decorator
+- **n8n**: Low-code automation - needs custom verification node
+- **LangGraph**: State machine workflows - needs checkpoint integration
+- **Zapier**: No-code automation - needs custom app
+
+### **E-commerce Platform Integration** (Design Partner Demos)
+- **Shopify**: Complete app with refund guardrails
+- **WooCommerce**: WordPress plugin for order verification
+- **Stripe**: Connect payout verification
+
+### **Developer Experience Tools** (Reduce Integration Friction)
+- **CLI Tool**: `npx create-aport-integration` scaffolding
+- **VS Code Extension**: Policy development with IntelliSense
+- **Postman Collection**: Complete API testing suite
+
+### **Framework Middleware** (Native Support)
+- **Next.js**: App Router and Pages Router support
+- **Django**: Python web framework middleware
+- **Laravel**: PHP framework with Artisan commands
+- **Rails**: Ruby gem with generators
+- **Go Frameworks**: Gin, Echo, Fiber middleware
+
+### **Protocol Bridges** (Universal Interoperability)
+- **OpenAPI 3.1**: Complete API specification
+- **AP2 Bridge**: Payment authorization integration
+- **SPIFFE/SPIRE**: Enterprise identity federation
+
+## 🚀 Quick Start
+
+### 1. Browse Available Integrations
+
+```bash
+# Clone the repository
+git clone https://github.com/aporthq/aport-integrations.git
+cd aport-integrations
+
+# Explore integrations by category
+ls examples/
+# agent-frameworks/ ecommerce/ developer-tools/ middleware/ protocol-bridges/
+```
+
+### 2. Try an Integration
+
+```bash
+# Example: LangChain Tool Guard
+cd examples/agent-frameworks/langchain
+npm install
+npm run example
+
+# Example: Express.js Middleware
+cd examples/middleware/express
+npm install
+npm start
+```
+
+### 3. Create Your Own Integration
+
+```bash
+# Use our CLI to scaffold a new integration
+npx create-aport-integration my-integration
+cd my-integration
+npm install
+```
+
+---
+
+## 📁 Repository Structure
+
+```
+aport-integrations/
+├── examples/ # Working integration examples
│ ├── agent-frameworks/ # LangChain, CrewAI, n8n, etc.
+│ ├── platform-integrations/ # Discord, GitHub, Zapier, etc.
│ ├── ecommerce/ # Shopify, WooCommerce, Stripe
│ ├── middleware/ # Express, FastAPI, Django, etc.
│ └── protocol-bridges/ # OpenAPI, AP2, SPIFFE/SPIRE
-├── tools/ # Developer tools and utilities
-│ ├── cli/ # APort CLI for scaffolding
-│ ├── vscode-extension/ # VS Code extension
-│ └── postman-collection/ # Postman collection
-├── templates/ # Integration scaffolding templates
-│ ├── javascript-middleware/ # Express.js template
-│ └── python-middleware/ # FastAPI template
-├── sdk/ # References to official SDKs
-│ └── README.md # Links to aport-sdks repository
-└── docs/ # Integration documentation
-```
-
-### 📋 Directory Purposes
-
-- **`examples/`** - **Working integration examples** that demonstrate real-world usage of APort
-- **`tools/`** - **Developer tools and utilities** (CLI, VS Code extension, Postman collection)
-- **`templates/`** - **Scaffolding templates** for quick integration development and consistent structure
-- **`sdk/`** - **References to official APort SDKs** maintained in the aport-sdks repository
-
----
-
-## 🎨 Integration Categories
-
-### 🤖 **Agent Framework Integrations**
-Make APort the default trust layer for AI agent frameworks.
-
-| Integration | Description | Status | Maintainer |
-|-------------|-------------|--------|------------|
-| [LangChain Tool Guard](examples/agent-frameworks/langchain/) | Secure LangChain tools with APort verification | ✅ Active | Community |
-| [CrewAI Task Decorator](examples/agent-frameworks/crewai/) | `@aport_verify` decorator for CrewAI tasks | ✅ Active | Community |
-| [n8n APort Node](examples/agent-frameworks/n8n/) | Custom n8n node for APort verification | 🚧 In Progress | Community |
-| [LangGraph Checkpoints](examples/agent-frameworks/langgraph/) | APort verification in LangGraph state machines | 📋 Planned | Community |
+├── tools/ # Developer tools and utilities
+│ ├── cli/ # APort CLI for scaffolding
+│ ├── vscode-extension/ # VS Code extension
+│ └── postman-collection/ # Postman collection
+├── templates/ # Integration scaffolding templates
+│ ├── javascript-middleware/ # Express.js template
+│ └── python-middleware/ # FastAPI template
+├── sdk/ # References to official SDKs
+│ └── README.md # Links to aport-sdks repository
+└── docs/ # Integration documentation
+```
+
+### 📋 Directory Purposes
+
+- **`examples/`** - **Working integration examples** that demonstrate real-world usage of APort
+- **`tools/`** - **Developer tools and utilities** (CLI, VS Code extension, Postman collection)
+- **`templates/`** - **Scaffolding templates** for quick integration development and consistent structure
+- **`sdk/`** - **References to official APort SDKs** maintained in the aport-sdks repository
+
+---
+
+## 🎨 Integration Categories
+
+### 🤖 **Agent Framework Integrations**
+Make APort the default trust layer for AI agent frameworks.
+
+| Integration | Description | Status | Maintainer |
+|-------------|-------------|--------|------------|
+| [LangChain Tool Guard](examples/agent-frameworks/langchain/) | Secure LangChain tools with APort verification | ✅ Active | Community |
+| [CrewAI Task Decorator](examples/agent-frameworks/crewai/) | `@aport_verify` decorator for CrewAI tasks | ✅ Active | Community |
+| [n8n APort Node](examples/agent-frameworks/n8n/) | Custom n8n node for APort verification | 🚧 In Progress | Community |
+| [LangGraph Checkpoints](examples/agent-frameworks/langgraph/) | APort verification in LangGraph state machines | 📋 Planned | Community |
+
+### 🛒 **E-commerce Platform Guardrails**
+Prove the refund use case with working platform integrations.
+
+| Integration | Description | Status | Maintainer |
+|-------------|-------------|--------|------------|
+| [Shopify Refund Guardrail](examples/ecommerce/shopify/) | Complete Shopify app with APort verification | ✅ Active | Community |
+| [WooCommerce Plugin](examples/ecommerce/woocommerce/) | WordPress plugin for order/refund verification | 🚧 In Progress | Community |
+| [Stripe Connect Verification](examples/ecommerce/stripe/) | Webhook handler for Stripe Connect payouts | 📋 Planned | Community |
-### 🛒 **E-commerce Platform Guardrails**
-Prove the refund use case with working platform integrations.
+### 💬 **Team Workflow Integrations**
+Bring APort verification into collaboration tools.
| Integration | Description | Status | Maintainer |
|-------------|-------------|--------|------------|
-| [Shopify Refund Guardrail](examples/ecommerce/shopify/) | Complete Shopify app with APort verification | ✅ Active | Community |
-| [WooCommerce Plugin](examples/ecommerce/woocommerce/) | WordPress plugin for order/refund verification | 🚧 In Progress | Community |
-| [Stripe Connect Verification](examples/ecommerce/stripe/) | Webhook handler for Stripe Connect payouts | 📋 Planned | Community |
+| [Discord Verification Bot](examples/platform-integrations/discord-bot/) | Slash-command bot for verifying team actions with APort | ✅ Active | Community |
### 🔧 **Developer Experience Tools**
Reduce APort integration time from hours to minutes.
-
-| Tool | Description | Status | Maintainer |
-|------|-------------|--------|------------|
-| [APort CLI](tools/cli/) | `npx create-aport-integration` scaffolding tool | ✅ Active | Community |
-| [VS Code Extension](tools/vscode-extension/) | Policy development with IntelliSense | 🚧 In Progress | Community |
-| [Postman Collection](tools/postman-collection/) | Complete API testing collection | ✅ Active | Community |
-
-### 🌉 **Protocol Bridges & Standards**
-Position APort as the universal verify layer.
-
-| Bridge | Description | Status | Maintainer |
-|--------|-------------|--------|------------|
-| [OpenAPI 3.1 Spec](examples/protocol-bridges/openapi/) | Complete OpenAPI specification | ✅ Active | Community |
-| [AP2 Bridge](examples/protocol-bridges/ap2/) | APort passport authorization for AP2 payments | 📋 Planned | Community |
-| [SPIFFE/SPIRE Integration](examples/protocol-bridges/spiffe/) | Enterprise identity federation | 📋 Planned | Community |
-
-### 🛠️ **Core Framework SDKs & Middleware**
-Native support for popular web frameworks.
-
-| Framework | SDK/Middleware | Status | Maintainer |
-|-----------|----------------|--------|------------|
-| Next.js | Middleware package | ✅ Active | Community |
-| Express.js | Middleware package | ✅ Active | Community |
-| FastAPI | Middleware package | ✅ Active | Community |
-| Django | Middleware package | 🚧 In Progress | Community |
-| Laravel | Composer package | 📋 Planned | Community |
-| Rails | Ruby gem | 📋 Planned | Community |
-| Go | Official SDK | 🚧 In Progress | Community |
-
----
-
-## 🎯 Real-World Examples
-
-### 💳 E-commerce Refund Protection
-
-```javascript
-// Express.js with APort middleware
-const { createAPortMiddleware } = require("@aporthq/middleware-express");
-
-const aportMiddleware = createAPortMiddleware({
- apiKey: process.env.APORT_API_KEY
-});
-
-app.post("/api/refunds",
- aportMiddleware("finance.payment.refund.v1"),
- async (req, res) => {
- // Policy already verified! Check specific limits
- const passport = req.aport.passport;
-
- if (req.body.amount > passport.limits.refund_amount_max_per_tx) {
- return res.status(403).json({
- error: "Refund exceeds limit",
- requested: req.body.amount,
- limit: passport.limits.refund_amount_max_per_tx
- });
- }
-
- // Process refund safely
- const refund = await stripe.refunds.create({
- amount: req.body.amount,
- payment_intent: req.body.payment_intent
- });
-
- res.json({ success: true, refund });
- }
-);
-```
-
-### 🤖 LangChain Tool Protection
-
-```python
-# LangChain with APort Tool Guard
-from aporthq_sdk import APortClient
-from langchain.tools import Tool
-
-def refund_tool(order_id: str, amount: float) -> str:
- return f"Refunded ${amount} for order {order_id}"
-
-# Initialize APort client
-aport_client = APortClient(api_key=os.getenv("APORT_API_KEY"))
-
-# Create protected tool wrapper
-class APortToolGuard:
- def __init__(self, tool, policy_pack, agent_id):
- self.tool = tool
- self.policy_pack = policy_pack
- self.agent_id = agent_id
-
- async def __call__(self, *args, **kwargs):
- # Verify agent before tool execution
- result = await aport_client.verify(self.policy_pack, self.agent_id)
- if not result.verified:
- raise Exception("Agent verification failed")
-
- # Execute tool if verified
- return self.tool(*args, **kwargs)
-
-# Wrap tool with APort verification
-protected_refund_tool = APortToolGuard(
- tool=Tool(
- name="refund_tool",
- description="Process customer refunds",
- func=refund_tool
- ),
- policy_pack="finance.payment.refund.v1",
- agent_id="agt_inst_xyz789"
-)
-
-# Use in agent
-agent = initialize_agent([protected_refund_tool], llm, agent_type="zero-shot-react-description")
-```
-
-### 🔀 GitHub Actions Integration
-
-```yaml
-# .github/workflows/aport-verify.yml
-name: APort Verify PR
-on: [pull_request]
-
-jobs:
- verify:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v4
- - uses: aporthq/policy-verify-action@v1
- with:
- agent-id: ${{ secrets.APORT_AGENT_ID }}
- policy-pack: 'code.repository.merge.v1'
- context: |
- {
- "repo": "${{ github.repository }}",
- "base": "${{ github.event.pull_request.base.ref }}",
- "head": "${{ github.event.pull_request.head.ref }}",
- "files_changed": ${{ toJson(github.event.pull_request.changed_files) }}
- }
-```
-
----
-
-## 🏆 Hacktoberfest 2025
-
-We're participating in [Hacktoberfest 2025](https://hacktoberfest.digitalocean.com/)! Join us in building the future of AI agent security.
-
-### 🎁 Rewards & Recognition
-
-- **💰 Bounties**: $15-$50 per merged PR
-- **👕 Swag**: APort Champion T-shirts for contributors
-- **🏆 Grand Prizes**: Up to $150 for exceptional contributions
-- **🌟 Recognition**: Featured on our website and social media
-
-### 🚀 How to Participate
-
-1. **Fork** this repository
-2. **Browse** [open issues](https://github.com/aporthq/aport-integrations/issues) labeled `hacktoberfest`
-3. **Claim** an issue by commenting "I'd like to work on this"
-4. **Build** your integration following our [contribution guidelines](CONTRIBUTING.md)
-5. **Submit** a pull request with your implementation
-6. **Get paid** via Chimoney when your PR is merged!
-
-### 🎯 Priority Issues
-
-- [ ] [LangChain Tool Guard](https://github.com/aporthq/aport-integrations/issues/1) - $50
-- [ ] [CrewAI Task Decorator](https://github.com/aporthq/aport-integrations/issues/2) - $50
-- [ ] [Shopify Refund Guardrail](https://github.com/aporthq/aport-integrations/issues/3) - $50
-- [ ] [APort CLI Tool](https://github.com/aporthq/aport-integrations/issues/4) - $50
-
-[View all Hacktoberfest issues →](https://github.com/aporthq/aport-integrations/issues?q=is:issue+is:open+label:hacktoberfest)
-
-## 📈 Key Insights from Issue Pickup Analysis
-
-### What Contributors Want:
-1. **"Good First Issue" Label** - 4/6 picked issues have this label
-2. **Content Creation** - Blog posts and tutorials are highly attractive
-3. **Integration & Middleware** - 5/6 issues are integration-related
-4. **Automation Tools** - n8n and Zapier appeal to no-code audience
-5. **Financial Use Cases** - Payment/AP2 bridge resonates strongly
-
-### Best Practices for New Issues:
-- Use `good-first-issue` label for beginner-friendly tasks
-- Focus on content creation and developer experience
-- Target specific frameworks (Next.js, Go, n8n, Zapier)
-- Include clear success criteria and bounty amounts
-- Provide scaffolding templates for complex integrations
-
----
-
-## 🤝 Contributing
-
-We love contributions! Whether you're fixing bugs, adding features, or creating new integrations, your work helps make APort better for everyone.
-
-### 🚀 Quick Contribution Guide
-
-1. **Browse Issues**: Check our [open Hacktoberfest issues](https://github.com/aporthq/aport-integrations/issues?q=is:issue+is:open+label:hacktoberfest)
-2. **Use Templates**: Copy scaffolding templates from `/templates/` directory
-3. **Follow Guidelines**: See [CONTRIBUTING.md](CONTRIBUTING.md) for detailed instructions
-4. **Get Rewarded**: Earn $5-$40 USD per completed issue!
-
-### 🎯 High-Impact Areas
-- **Agent Framework Integrations** (LangChain, CrewAI, n8n)
-- **Platform Integrations** (Zapier, GitHub, Discord)
-- **Developer Experience** (VS Code, CLI, Postman)
-- **Content Creation** (Tutorials, blog posts, videos)
-
-### 📋 Integration Requirements
-
-- ✅ **Working Example**: Must include a complete, runnable example
-- ✅ **Documentation**: Clear README with setup instructions
-- ✅ **Tests**: Unit tests for core functionality
-- ✅ **Error Handling**: Graceful failure modes
-- ✅ **Security**: No hardcoded secrets or credentials
-
-### 🎨 Code Standards
-
-- **Language-specific**: Follow standard conventions (ESLint, Black, gofmt)
-- **Documentation**: Include docstrings and comments
-- **Testing**: Minimum 80% code coverage
-- **Security**: Use environment variables for secrets
-
-[Read our full Contributing Guide →](CONTRIBUTING.md)
-
----
-
-## 📚 Resources
-
-### 🔗 **APort Resources**
-- [📖 Core Features](https://aport.io/features) - Complete list of APort Features
-- [📖 Documentation](https://aport.io/docs) - Complete guides and API reference
-- [🎮 Swagger Documentation](https://aport.io/api/swagger-ui) - Try APort in your browser
-- [💡 Examples](https://github.com/aporthq/aport-examples) - Real-world implementations
-
-### 🛠️ **Development Resources**
-- [API Reference](https://aport.io/docs/) - Complete API documentation
-- [Policy Packs](https://github.com/aporthq/aport-policies) - Pre-built policy definitions
-- [SDKs](https://github.com/aporthq/aport-sdks) - Language-specific SDKs
-- [Specification](https://github.com/aporthq/aport-spec) - AI Passport Specification
-- [GitHub Actions](https://github.com/aporthq/policy-verify-action) - CI/CD integrations
-
-### 💬 **Community**
-- [GitHub Discussions](https://github.com/aporthq/aport-integrations/discussions) - Ask questions
-
----
-
-## 📊 Project Status
-
-
-
-| **Metric** | **Count** | **Status** |
-|------------|-----------|------------|
-| **🔧 Integrations** | 15+ | ✅ Active |
-| **📦 SDKs** | 5+ | ✅ Active |
-| **🛠️ Tools** | 8+ | ✅ Active |
-| **👥 Contributors** | 25+ | 🌟 Growing |
-| **⭐ Stars** | 100+ | 🚀 Rising |
-
-
-
----
-
-## 📄 License
-
-This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
-
----
-
-
-
-**🛡️ Secure your AI agents. Trust but verify.**
-
-[](https://github.com/aporthq)
-[](https://twitter.com/aporthq)
-[](https://linkedin.com/company/aporthq)
-[](https://discord.gg/aport)
-
-Made with ❤️ by the APort community
-
-
+
+| Tool | Description | Status | Maintainer |
+|------|-------------|--------|------------|
+| [APort CLI](tools/cli/) | `npx create-aport-integration` scaffolding tool | ✅ Active | Community |
+| [VS Code Extension](tools/vscode-extension/) | Policy development with IntelliSense | 🚧 In Progress | Community |
+| [Postman Collection](tools/postman-collection/) | Complete API testing collection | ✅ Active | Community |
+
+### 🌉 **Protocol Bridges & Standards**
+Position APort as the universal verify layer.
+
+| Bridge | Description | Status | Maintainer |
+|--------|-------------|--------|------------|
+| [OpenAPI 3.1 Spec](examples/protocol-bridges/openapi/) | Complete OpenAPI specification | ✅ Active | Community |
+| [AP2 Bridge](examples/protocol-bridges/ap2/) | APort passport authorization for AP2 payments | 📋 Planned | Community |
+| [SPIFFE/SPIRE Integration](examples/protocol-bridges/spiffe/) | Enterprise identity federation | 📋 Planned | Community |
+
+### 🛠️ **Core Framework SDKs & Middleware**
+Native support for popular web frameworks.
+
+| Framework | SDK/Middleware | Status | Maintainer |
+|-----------|----------------|--------|------------|
+| Next.js | Middleware package | ✅ Active | Community |
+| Express.js | Middleware package | ✅ Active | Community |
+| FastAPI | Middleware package | ✅ Active | Community |
+| Django | Middleware package | 🚧 In Progress | Community |
+| Laravel | Composer package | 📋 Planned | Community |
+| Rails | Ruby gem | 📋 Planned | Community |
+| Go | Official SDK | 🚧 In Progress | Community |
+
+---
+
+## 🎯 Real-World Examples
+
+### 💳 E-commerce Refund Protection
+
+```javascript
+// Express.js with APort middleware
+const { createAPortMiddleware } = require("@aporthq/middleware-express");
+
+const aportMiddleware = createAPortMiddleware({
+ apiKey: process.env.APORT_API_KEY
+});
+
+app.post("/api/refunds",
+ aportMiddleware("finance.payment.refund.v1"),
+ async (req, res) => {
+ // Policy already verified! Check specific limits
+ const passport = req.aport.passport;
+
+ if (req.body.amount > passport.limits.refund_amount_max_per_tx) {
+ return res.status(403).json({
+ error: "Refund exceeds limit",
+ requested: req.body.amount,
+ limit: passport.limits.refund_amount_max_per_tx
+ });
+ }
+
+ // Process refund safely
+ const refund = await stripe.refunds.create({
+ amount: req.body.amount,
+ payment_intent: req.body.payment_intent
+ });
+
+ res.json({ success: true, refund });
+ }
+);
+```
+
+### 🤖 LangChain Tool Protection
+
+```python
+# LangChain with APort Tool Guard
+from aporthq_sdk import APortClient
+from langchain.tools import Tool
+
+def refund_tool(order_id: str, amount: float) -> str:
+ return f"Refunded ${amount} for order {order_id}"
+
+# Initialize APort client
+aport_client = APortClient(api_key=os.getenv("APORT_API_KEY"))
+
+# Create protected tool wrapper
+class APortToolGuard:
+ def __init__(self, tool, policy_pack, agent_id):
+ self.tool = tool
+ self.policy_pack = policy_pack
+ self.agent_id = agent_id
+
+ async def __call__(self, *args, **kwargs):
+ # Verify agent before tool execution
+ result = await aport_client.verify(self.policy_pack, self.agent_id)
+ if not result.verified:
+ raise Exception("Agent verification failed")
+
+ # Execute tool if verified
+ return self.tool(*args, **kwargs)
+
+# Wrap tool with APort verification
+protected_refund_tool = APortToolGuard(
+ tool=Tool(
+ name="refund_tool",
+ description="Process customer refunds",
+ func=refund_tool
+ ),
+ policy_pack="finance.payment.refund.v1",
+ agent_id="agt_inst_xyz789"
+)
+
+# Use in agent
+agent = initialize_agent([protected_refund_tool], llm, agent_type="zero-shot-react-description")
+```
+
+### 🔀 GitHub Actions Integration
+
+```yaml
+# .github/workflows/aport-verify.yml
+name: APort Verify PR
+on: [pull_request]
+
+jobs:
+ verify:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - uses: aporthq/policy-verify-action@v1
+ with:
+ agent-id: ${{ secrets.APORT_AGENT_ID }}
+ policy-pack: 'code.repository.merge.v1'
+ context: |
+ {
+ "repo": "${{ github.repository }}",
+ "base": "${{ github.event.pull_request.base.ref }}",
+ "head": "${{ github.event.pull_request.head.ref }}",
+ "files_changed": ${{ toJson(github.event.pull_request.changed_files) }}
+ }
+```
+
+---
+
+## 🏆 Hacktoberfest 2025
+
+We're participating in [Hacktoberfest 2025](https://hacktoberfest.digitalocean.com/)! Join us in building the future of AI agent security.
+
+### 🎁 Rewards & Recognition
+
+- **💰 Bounties**: $15-$50 per merged PR
+- **👕 Swag**: APort Champion T-shirts for contributors
+- **🏆 Grand Prizes**: Up to $150 for exceptional contributions
+- **🌟 Recognition**: Featured on our website and social media
+
+### 🚀 How to Participate
+
+1. **Fork** this repository
+2. **Browse** [open issues](https://github.com/aporthq/aport-integrations/issues) labeled `hacktoberfest`
+3. **Claim** an issue by commenting "I'd like to work on this"
+4. **Build** your integration following our [contribution guidelines](CONTRIBUTING.md)
+5. **Submit** a pull request with your implementation
+6. **Get paid** via Chimoney when your PR is merged!
+
+### 🎯 Priority Issues
+
+- [ ] [LangChain Tool Guard](https://github.com/aporthq/aport-integrations/issues/1) - $50
+- [ ] [CrewAI Task Decorator](https://github.com/aporthq/aport-integrations/issues/2) - $50
+- [ ] [Shopify Refund Guardrail](https://github.com/aporthq/aport-integrations/issues/3) - $50
+- [ ] [APort CLI Tool](https://github.com/aporthq/aport-integrations/issues/4) - $50
+
+[View all Hacktoberfest issues →](https://github.com/aporthq/aport-integrations/issues?q=is:issue+is:open+label:hacktoberfest)
+
+## 📈 Key Insights from Issue Pickup Analysis
+
+### What Contributors Want:
+1. **"Good First Issue" Label** - 4/6 picked issues have this label
+2. **Content Creation** - Blog posts and tutorials are highly attractive
+3. **Integration & Middleware** - 5/6 issues are integration-related
+4. **Automation Tools** - n8n and Zapier appeal to no-code audience
+5. **Financial Use Cases** - Payment/AP2 bridge resonates strongly
+
+### Best Practices for New Issues:
+- Use `good-first-issue` label for beginner-friendly tasks
+- Focus on content creation and developer experience
+- Target specific frameworks (Next.js, Go, n8n, Zapier)
+- Include clear success criteria and bounty amounts
+- Provide scaffolding templates for complex integrations
+
+---
+
+## 🤝 Contributing
+
+We love contributions! Whether you're fixing bugs, adding features, or creating new integrations, your work helps make APort better for everyone.
+
+### 🚀 Quick Contribution Guide
+
+1. **Browse Issues**: Check our [open Hacktoberfest issues](https://github.com/aporthq/aport-integrations/issues?q=is:issue+is:open+label:hacktoberfest)
+2. **Use Templates**: Copy scaffolding templates from `/templates/` directory
+3. **Follow Guidelines**: See [CONTRIBUTING.md](CONTRIBUTING.md) for detailed instructions
+4. **Get Rewarded**: Earn $5-$40 USD per completed issue!
+
+### 🎯 High-Impact Areas
+- **Agent Framework Integrations** (LangChain, CrewAI, n8n)
+- **Platform Integrations** (Zapier, GitHub, Discord)
+- **Developer Experience** (VS Code, CLI, Postman)
+- **Content Creation** (Tutorials, blog posts, videos)
+
+### 📋 Integration Requirements
+
+- ✅ **Working Example**: Must include a complete, runnable example
+- ✅ **Documentation**: Clear README with setup instructions
+- ✅ **Tests**: Unit tests for core functionality
+- ✅ **Error Handling**: Graceful failure modes
+- ✅ **Security**: No hardcoded secrets or credentials
+
+### 🎨 Code Standards
+
+- **Language-specific**: Follow standard conventions (ESLint, Black, gofmt)
+- **Documentation**: Include docstrings and comments
+- **Testing**: Minimum 80% code coverage
+- **Security**: Use environment variables for secrets
+
+[Read our full Contributing Guide →](CONTRIBUTING.md)
+
+---
+
+## 📚 Resources
+
+### 🔗 **APort Resources**
+- [📖 Core Features](https://aport.io/features) - Complete list of APort Features
+- [📖 Documentation](https://aport.io/docs) - Complete guides and API reference
+- [🎮 Swagger Documentation](https://aport.io/api/swagger-ui) - Try APort in your browser
+- [💡 Examples](https://github.com/aporthq/aport-examples) - Real-world implementations
+
+### 🛠️ **Development Resources**
+- [API Reference](https://aport.io/docs/) - Complete API documentation
+- [Policy Packs](https://github.com/aporthq/aport-policies) - Pre-built policy definitions
+- [SDKs](https://github.com/aporthq/aport-sdks) - Language-specific SDKs
+- [Specification](https://github.com/aporthq/aport-spec) - AI Passport Specification
+- [GitHub Actions](https://github.com/aporthq/policy-verify-action) - CI/CD integrations
+
+### 💬 **Community**
+- [GitHub Discussions](https://github.com/aporthq/aport-integrations/discussions) - Ask questions
+
+---
+
+## 📊 Project Status
+
+
+
+| **Metric** | **Count** | **Status** |
+|------------|-----------|------------|
+| **🔧 Integrations** | 15+ | ✅ Active |
+| **📦 SDKs** | 5+ | ✅ Active |
+| **🛠️ Tools** | 8+ | ✅ Active |
+| **👥 Contributors** | 25+ | 🌟 Growing |
+| **⭐ Stars** | 100+ | 🚀 Rising |
+
+
+
+---
+
+## 📄 License
+
+This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
+
+---
+
+
+
+**🛡️ Secure your AI agents. Trust but verify.**
+
+[](https://github.com/aporthq)
+[](https://twitter.com/aporthq)
+[](https://linkedin.com/company/aporthq)
+[](https://discord.gg/aport)
+
+Made with ❤️ by the APort community
+
+
diff --git a/examples/platform-integrations/discord-bot/.env.example b/examples/platform-integrations/discord-bot/.env.example
new file mode 100644
index 0000000..c918e8c
--- /dev/null
+++ b/examples/platform-integrations/discord-bot/.env.example
@@ -0,0 +1,6 @@
+DISCORD_TOKEN=your_discord_bot_token
+DISCORD_CLIENT_ID=your_discord_application_client_id
+DISCORD_GUILD_ID=optional_test_guild_id
+APORT_API_KEY=your_aport_api_key
+APORT_API_URL=https://aport.io/api/verify
+APORT_POLICY_PACK=code.repository.merge.v1
diff --git a/examples/platform-integrations/discord-bot/README.md b/examples/platform-integrations/discord-bot/README.md
new file mode 100644
index 0000000..f66d63c
--- /dev/null
+++ b/examples/platform-integrations/discord-bot/README.md
@@ -0,0 +1,58 @@
+# APort Discord Verification Bot
+
+This example shows how to verify team actions from Discord slash commands before a workflow continues.
+
+## Commands
+
+- `/aport-verify action: resource: reason:` calls APort and returns the allow/deny decision.
+- `/aport-status` shows the configured policy pack.
+
+## Setup
+
+1. Create a Discord application and bot in the Discord Developer Portal.
+2. Copy `.env.example` to `.env`.
+3. Fill in `DISCORD_TOKEN`, `DISCORD_CLIENT_ID`, and `APORT_POLICY_PACK`.
+4. Optional: set `DISCORD_GUILD_ID` for fast command registration in one test server.
+
+```bash
+npm install
+npm run register
+npm start
+```
+
+## Example
+
+```text
+/aport-verify action:merge_pr resource:aporthq/aport-integrations#116 reason:approved review
+```
+
+The bot sends this context to APort:
+
+```json
+{
+ "actor": {
+ "type": "discord_user",
+ "id": "1234567890"
+ },
+ "action": "merge_pr",
+ "resource": "aporthq/aport-integrations#116",
+ "reason": "approved review"
+}
+```
+
+## Configuration
+
+| Variable | Description |
+| --- | --- |
+| `DISCORD_TOKEN` | Discord bot token. |
+| `DISCORD_CLIENT_ID` | Discord application client id. |
+| `DISCORD_GUILD_ID` | Optional guild id for test-server command registration. |
+| `APORT_API_KEY` | APort API key when your policy requires authentication. |
+| `APORT_API_URL` | APort verification endpoint. Defaults to `https://aport.io/api/verify`. |
+| `APORT_POLICY_PACK` | Policy pack used for team action checks. |
+
+## Test
+
+```bash
+npm test
+```
diff --git a/examples/platform-integrations/discord-bot/package-lock.json b/examples/platform-integrations/discord-bot/package-lock.json
new file mode 100644
index 0000000..2dbb04e
--- /dev/null
+++ b/examples/platform-integrations/discord-bot/package-lock.json
@@ -0,0 +1,341 @@
+{
+ "name": "aport-discord-verification-bot",
+ "version": "0.1.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "aport-discord-verification-bot",
+ "version": "0.1.0",
+ "license": "MIT",
+ "dependencies": {
+ "discord.js": "^14.16.3",
+ "dotenv": "^16.4.5"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@discordjs/builders": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@discordjs/builders/-/builders-1.14.1.tgz",
+ "integrity": "sha512-gSKkhXLqs96TCzk66VZuHHl8z2bQMJFGwrXC0f33ngK+FLNau4hU1PYny3DNJfNdSH+gVMzE85/d5FQ2BpcNwQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@discordjs/formatters": "^0.6.2",
+ "@discordjs/util": "^1.2.0",
+ "@sapphire/shapeshift": "^4.0.0",
+ "discord-api-types": "^0.38.40",
+ "fast-deep-equal": "^3.1.3",
+ "ts-mixer": "^6.0.4",
+ "tslib": "^2.6.3"
+ },
+ "engines": {
+ "node": ">=16.11.0"
+ },
+ "funding": {
+ "url": "https://github.com/discordjs/discord.js?sponsor"
+ }
+ },
+ "node_modules/@discordjs/collection": {
+ "version": "1.5.3",
+ "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-1.5.3.tgz",
+ "integrity": "sha512-SVb428OMd3WO1paV3rm6tSjM4wC+Kecaa1EUGX7vc6/fddvw/6lg90z4QtCqm21zvVe92vMMDt9+DkIvjXImQQ==",
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=16.11.0"
+ }
+ },
+ "node_modules/@discordjs/formatters": {
+ "version": "0.6.2",
+ "resolved": "https://registry.npmjs.org/@discordjs/formatters/-/formatters-0.6.2.tgz",
+ "integrity": "sha512-y4UPwWhH6vChKRkGdMB4odasUbHOUwy7KL+OVwF86PvT6QVOwElx+TiI1/6kcmcEe+g5YRXJFiXSXUdabqZOvQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "discord-api-types": "^0.38.33"
+ },
+ "engines": {
+ "node": ">=16.11.0"
+ },
+ "funding": {
+ "url": "https://github.com/discordjs/discord.js?sponsor"
+ }
+ },
+ "node_modules/@discordjs/rest": {
+ "version": "2.6.1",
+ "resolved": "https://registry.npmjs.org/@discordjs/rest/-/rest-2.6.1.tgz",
+ "integrity": "sha512-wwQdgjeaoYFiaG+atbqx6aJDpqW7JHAo0HrQkBTbYzM3/PJ3GweQIpgElNcGZ26DCUOXMyawYd0YF7vtr+fZXg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@discordjs/collection": "^2.1.1",
+ "@discordjs/util": "^1.2.0",
+ "@sapphire/async-queue": "^1.5.3",
+ "@sapphire/snowflake": "^3.5.5",
+ "@vladfrangu/async_event_emitter": "^2.4.6",
+ "discord-api-types": "^0.38.40",
+ "magic-bytes.js": "^1.13.0",
+ "tslib": "^2.6.3",
+ "undici": "6.24.1"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/discordjs/discord.js?sponsor"
+ }
+ },
+ "node_modules/@discordjs/rest/node_modules/@discordjs/collection": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-2.1.1.tgz",
+ "integrity": "sha512-LiSusze9Tc7qF03sLCujF5iZp7K+vRNEDBZ86FT9aQAv3vxMLihUvKvpsCWiQ2DJq1tVckopKm1rxomgNUc9hg==",
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/discordjs/discord.js?sponsor"
+ }
+ },
+ "node_modules/@discordjs/rest/node_modules/@sapphire/snowflake": {
+ "version": "3.5.5",
+ "resolved": "https://registry.npmjs.org/@sapphire/snowflake/-/snowflake-3.5.5.tgz",
+ "integrity": "sha512-xzvBr1Q1c4lCe7i6sRnrofxeO1QTP/LKQ6A6qy0iB4x5yfiSfARMEQEghojzTNALDTcv8En04qYNIco9/K9eZQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=v14.0.0",
+ "npm": ">=7.0.0"
+ }
+ },
+ "node_modules/@discordjs/util": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@discordjs/util/-/util-1.2.0.tgz",
+ "integrity": "sha512-3LKP7F2+atl9vJFhaBjn4nOaSWahZ/yWjOvA4e5pnXkt2qyXRCHLxoBQy81GFtLGCq7K9lPm9R517M1U+/90Qg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "discord-api-types": "^0.38.33"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/discordjs/discord.js?sponsor"
+ }
+ },
+ "node_modules/@discordjs/ws": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/@discordjs/ws/-/ws-1.2.3.tgz",
+ "integrity": "sha512-wPlQDxEmlDg5IxhJPuxXr3Vy9AjYq5xCvFWGJyD7w7Np8ZGu+Mc+97LCoEc/+AYCo2IDpKioiH0/c/mj5ZR9Uw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@discordjs/collection": "^2.1.0",
+ "@discordjs/rest": "^2.5.1",
+ "@discordjs/util": "^1.1.0",
+ "@sapphire/async-queue": "^1.5.2",
+ "@types/ws": "^8.5.10",
+ "@vladfrangu/async_event_emitter": "^2.2.4",
+ "discord-api-types": "^0.38.1",
+ "tslib": "^2.6.2",
+ "ws": "^8.17.0"
+ },
+ "engines": {
+ "node": ">=16.11.0"
+ },
+ "funding": {
+ "url": "https://github.com/discordjs/discord.js?sponsor"
+ }
+ },
+ "node_modules/@discordjs/ws/node_modules/@discordjs/collection": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-2.1.1.tgz",
+ "integrity": "sha512-LiSusze9Tc7qF03sLCujF5iZp7K+vRNEDBZ86FT9aQAv3vxMLihUvKvpsCWiQ2DJq1tVckopKm1rxomgNUc9hg==",
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/discordjs/discord.js?sponsor"
+ }
+ },
+ "node_modules/@sapphire/async-queue": {
+ "version": "1.5.5",
+ "resolved": "https://registry.npmjs.org/@sapphire/async-queue/-/async-queue-1.5.5.tgz",
+ "integrity": "sha512-cvGzxbba6sav2zZkH8GPf2oGk9yYoD5qrNWdu9fRehifgnFZJMV+nuy2nON2roRO4yQQ+v7MK/Pktl/HgfsUXg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=v14.0.0",
+ "npm": ">=7.0.0"
+ }
+ },
+ "node_modules/@sapphire/shapeshift": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@sapphire/shapeshift/-/shapeshift-4.0.0.tgz",
+ "integrity": "sha512-d9dUmWVA7MMiKobL3VpLF8P2aeanRTu6ypG2OIaEv/ZHH/SUQ2iHOVyi5wAPjQ+HmnMuL0whK9ez8I/raWbtIg==",
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.3",
+ "lodash": "^4.17.21"
+ },
+ "engines": {
+ "node": ">=v16"
+ }
+ },
+ "node_modules/@sapphire/snowflake": {
+ "version": "3.5.3",
+ "resolved": "https://registry.npmjs.org/@sapphire/snowflake/-/snowflake-3.5.3.tgz",
+ "integrity": "sha512-jjmJywLAFoWeBi1W7994zZyiNWPIiqRRNAmSERxyg93xRGzNYvGjlZ0gR6x0F4gPRi2+0O6S71kOZYyr3cxaIQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=v14.0.0",
+ "npm": ">=7.0.0"
+ }
+ },
+ "node_modules/@types/node": {
+ "version": "25.9.2",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-25.9.2.tgz",
+ "integrity": "sha512-G05zqtJhcDLb8uslf5EjCxXg9G1KQxiV8OS0R26IC//Eoyitzqe8z37I7cqvnZlrlSfgocQRfSn/AHBZJJFyGw==",
+ "license": "MIT",
+ "dependencies": {
+ "undici-types": ">=7.24.0 <7.24.7"
+ }
+ },
+ "node_modules/@types/ws": {
+ "version": "8.18.1",
+ "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz",
+ "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@vladfrangu/async_event_emitter": {
+ "version": "2.4.7",
+ "resolved": "https://registry.npmjs.org/@vladfrangu/async_event_emitter/-/async_event_emitter-2.4.7.tgz",
+ "integrity": "sha512-Xfe6rpCTxSxfbswi/W/Pz7zp1WWSNn4A0eW4mLkQUewCrXXtMj31lCg+iQyTkh/CkusZSq9eDflu7tjEDXUY6g==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=v14.0.0",
+ "npm": ">=7.0.0"
+ }
+ },
+ "node_modules/discord-api-types": {
+ "version": "0.38.48",
+ "resolved": "https://registry.npmjs.org/discord-api-types/-/discord-api-types-0.38.48.tgz",
+ "integrity": "sha512-WFUE/2o0lBlLeCQonQ+Pu2RqHAqbytBJ2RlXR91gzk05InSS6k9ShzzLYoymrA4c2oRgRKGE7/VqQJNNdGWSxQ==",
+ "license": "MIT",
+ "workspaces": [
+ "scripts/actions/documentation"
+ ]
+ },
+ "node_modules/discord.js": {
+ "version": "14.26.4",
+ "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-14.26.4.tgz",
+ "integrity": "sha512-4oBp8tc6Kf8IDBwAHhbsMaAqx1b5fob9SNasZT7V6yyyUydoO5i5fGuX7TmvRtR+q/WgKRnRViRoAWnG7fNyvA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@discordjs/builders": "^1.14.1",
+ "@discordjs/collection": "1.5.3",
+ "@discordjs/formatters": "^0.6.2",
+ "@discordjs/rest": "^2.6.1",
+ "@discordjs/util": "^1.2.0",
+ "@discordjs/ws": "^1.2.3",
+ "@sapphire/snowflake": "3.5.3",
+ "discord-api-types": "^0.38.40",
+ "fast-deep-equal": "3.1.3",
+ "lodash.snakecase": "4.1.1",
+ "magic-bytes.js": "^1.13.0",
+ "tslib": "^2.6.3",
+ "undici": "6.24.1"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/discordjs/discord.js?sponsor"
+ }
+ },
+ "node_modules/dotenv": {
+ "version": "16.6.1",
+ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz",
+ "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==",
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://dotenvx.com"
+ }
+ },
+ "node_modules/fast-deep-equal": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+ "license": "MIT"
+ },
+ "node_modules/lodash": {
+ "version": "4.18.1",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz",
+ "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==",
+ "license": "MIT"
+ },
+ "node_modules/lodash.snakecase": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz",
+ "integrity": "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==",
+ "license": "MIT"
+ },
+ "node_modules/magic-bytes.js": {
+ "version": "1.13.0",
+ "resolved": "https://registry.npmjs.org/magic-bytes.js/-/magic-bytes.js-1.13.0.tgz",
+ "integrity": "sha512-afO2mnxW7GDTXMm5/AoN1WuOcdoKhtgXjIvHmobqTD1grNplhGdv3PFOyjCVmrnOZBIT/gD/koDKpYG+0mvHcg==",
+ "license": "MIT"
+ },
+ "node_modules/ts-mixer": {
+ "version": "6.0.4",
+ "resolved": "https://registry.npmjs.org/ts-mixer/-/ts-mixer-6.0.4.tgz",
+ "integrity": "sha512-ufKpbmrugz5Aou4wcr5Wc1UUFWOLhq+Fm6qa6P0w0K5Qw2yhaUoiWszhCVuNQyNwrlGiscHOmqYoAox1PtvgjA==",
+ "license": "MIT"
+ },
+ "node_modules/tslib": {
+ "version": "2.8.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
+ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
+ "license": "0BSD"
+ },
+ "node_modules/undici": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/undici/-/undici-6.24.1.tgz",
+ "integrity": "sha512-sC+b0tB1whOCzbtlx20fx3WgCXwkW627p4EA9uM+/tNNPkSS+eSEld6pAs9nDv7WbY1UUljBMYPtu9BCOrCWKA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18.17"
+ }
+ },
+ "node_modules/undici-types": {
+ "version": "7.24.6",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.24.6.tgz",
+ "integrity": "sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==",
+ "license": "MIT"
+ },
+ "node_modules/ws": {
+ "version": "8.21.0",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.0.tgz",
+ "integrity": "sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10.0.0"
+ },
+ "peerDependencies": {
+ "bufferutil": "^4.0.1",
+ "utf-8-validate": ">=5.0.2"
+ },
+ "peerDependenciesMeta": {
+ "bufferutil": {
+ "optional": true
+ },
+ "utf-8-validate": {
+ "optional": true
+ }
+ }
+ }
+ }
+}
diff --git a/examples/platform-integrations/discord-bot/package.json b/examples/platform-integrations/discord-bot/package.json
new file mode 100644
index 0000000..b035947
--- /dev/null
+++ b/examples/platform-integrations/discord-bot/package.json
@@ -0,0 +1,27 @@
+{
+ "name": "aport-discord-verification-bot",
+ "version": "0.1.0",
+ "private": true,
+ "description": "Discord bot example for verifying team actions with APort",
+ "main": "src/bot.js",
+ "scripts": {
+ "start": "node src/bot.js",
+ "register": "node src/register-commands.js",
+ "test": "node --test"
+ },
+ "keywords": [
+ "aport",
+ "discord",
+ "bot",
+ "verification"
+ ],
+ "author": "APort Community",
+ "license": "MIT",
+ "dependencies": {
+ "discord.js": "^14.16.3",
+ "dotenv": "^16.4.5"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+}
diff --git a/examples/platform-integrations/discord-bot/src/aport.js b/examples/platform-integrations/discord-bot/src/aport.js
new file mode 100644
index 0000000..4825673
--- /dev/null
+++ b/examples/platform-integrations/discord-bot/src/aport.js
@@ -0,0 +1,81 @@
+function buildVerificationPayload({ userId, action, resource, reason, policyPack }) {
+ if (!userId) {
+ throw new Error("Discord user id is required");
+ }
+
+ if (!action) {
+ throw new Error("Action is required");
+ }
+
+ return {
+ policy_pack: policyPack,
+ context: {
+ actor: {
+ type: "discord_user",
+ id: userId,
+ },
+ action,
+ resource,
+ reason,
+ requested_at: new Date().toISOString(),
+ },
+ };
+}
+
+function parseDecision(result) {
+ return result?.data?.decision || result?.decision || result;
+}
+
+async function verifyAction(options) {
+ const { apiKey, apiUrl = "https://aport.io/api/verify" } = options;
+ const payload = buildVerificationPayload(options);
+
+ const response = await fetch(apiUrl, {
+ method: "POST",
+ headers: {
+ "content-type": "application/json",
+ authorization: `Bearer ${apiKey || ""}`,
+ },
+ body: JSON.stringify(payload),
+ });
+
+ if (!response.ok) {
+ throw new Error(`APort verification failed with HTTP ${response.status}`);
+ }
+
+ const result = await response.json();
+ return parseDecision(result);
+}
+
+function formatDecision(decision) {
+ if (!decision) {
+ return {
+ allow: false,
+ text: "APort did not return a decision.",
+ };
+ }
+
+ const reasons = Array.isArray(decision.reasons)
+ ? decision.reasons
+ .map((reason) => reason.message || reason.code || String(reason))
+ .filter(Boolean)
+ : [];
+
+ return {
+ allow: Boolean(decision.allow),
+ text: [
+ `Allow: ${decision.allow ? "yes" : "no"}`,
+ reasons.length > 0 ? `Reasons: ${reasons.join("; ")}` : null,
+ decision.decision_id ? `Decision: ${decision.decision_id}` : null,
+ ]
+ .filter(Boolean)
+ .join("\n"),
+ };
+}
+
+module.exports = {
+ buildVerificationPayload,
+ formatDecision,
+ parseDecision,
+ verifyAction,
+};
diff --git a/examples/platform-integrations/discord-bot/src/bot.js b/examples/platform-integrations/discord-bot/src/bot.js
new file mode 100644
index 0000000..207633e
--- /dev/null
+++ b/examples/platform-integrations/discord-bot/src/bot.js
@@ -0,0 +1,60 @@
+require("dotenv").config();
+
+const { Client, Events, GatewayIntentBits } = require("discord.js");
+
+const { formatDecision, verifyAction } = require("./aport");
+
+const requiredEnv = ["DISCORD_TOKEN", "APORT_POLICY_PACK"];
+const missingEnv = requiredEnv.filter((name) => !process.env[name]);
+
+if (missingEnv.length > 0) {
+ console.error(`Missing required environment variables: ${missingEnv.join(", ")}`);
+ process.exit(1);
+}
+
+const client = new Client({
+ intents: [GatewayIntentBits.Guilds],
+});
+
+client.once(Events.ClientReady, (readyClient) => {
+ console.log(`APort Discord bot signed in as ${readyClient.user.tag}`);
+});
+
+client.on(Events.InteractionCreate, async (interaction) => {
+ if (!interaction.isChatInputCommand()) {
+ return;
+ }
+
+ if (interaction.commandName === "aport-status") {
+ await interaction.reply({
+ ephemeral: true,
+ content: `APort policy pack: ${process.env.APORT_POLICY_PACK}`,
+ });
+ return;
+ }
+
+ if (interaction.commandName !== "aport-verify") {
+ return;
+ }
+
+ await interaction.deferReply({ ephemeral: true });
+
+ try {
+ const decision = await verifyAction({
+ apiKey: process.env.APORT_API_KEY,
+ apiUrl: process.env.APORT_API_URL,
+ policyPack: process.env.APORT_POLICY_PACK,
+ userId: interaction.user.id,
+ action: interaction.options.getString("action", true),
+ resource: interaction.options.getString("resource", true),
+ reason: interaction.options.getString("reason") || "",
+ });
+
+ const formatted = formatDecision(decision);
+ await interaction.editReply(formatted.text);
+ } catch (error) {
+ await interaction.editReply(`Verification error: ${error.message}`);
+ }
+});
+
+client.login(process.env.DISCORD_TOKEN);
diff --git a/examples/platform-integrations/discord-bot/src/commands.js b/examples/platform-integrations/discord-bot/src/commands.js
new file mode 100644
index 0000000..d04c2e4
--- /dev/null
+++ b/examples/platform-integrations/discord-bot/src/commands.js
@@ -0,0 +1,35 @@
+const { SlashCommandBuilder } = require("discord.js");
+
+const verifyCommand = new SlashCommandBuilder()
+ .setName("aport-verify")
+ .setDescription("Verify a team action with APort")
+ .addStringOption((option) =>
+ option
+ .setName("action")
+ .setDescription("Action to verify, such as merge_pr or approve_refund")
+ .setRequired(true)
+ )
+ .addStringOption((option) =>
+ option
+ .setName("resource")
+ .setDescription("Resource affected by the action")
+ .setRequired(true)
+ )
+ .addStringOption((option) =>
+ option
+ .setName("reason")
+ .setDescription("Short business reason for the action")
+ .setRequired(false)
+ );
+
+const statusCommand = new SlashCommandBuilder()
+ .setName("aport-status")
+ .setDescription("Show the configured APort policy pack for this bot");
+
+function getCommands() {
+ return [verifyCommand, statusCommand].map((command) => command.toJSON());
+}
+
+module.exports = {
+ getCommands,
+};
diff --git a/examples/platform-integrations/discord-bot/src/register-commands.js b/examples/platform-integrations/discord-bot/src/register-commands.js
new file mode 100644
index 0000000..d563522
--- /dev/null
+++ b/examples/platform-integrations/discord-bot/src/register-commands.js
@@ -0,0 +1,40 @@
+require("dotenv").config();
+
+const { REST, Routes } = require("discord.js");
+
+const { getCommands } = require("./commands");
+
+const requiredEnv = ["DISCORD_TOKEN", "DISCORD_CLIENT_ID"];
+const missingEnv = requiredEnv.filter((name) => !process.env[name]);
+
+if (missingEnv.length > 0) {
+ console.error(`Missing required environment variables: ${missingEnv.join(", ")}`);
+ process.exit(1);
+}
+
+async function registerCommands() {
+ const rest = new REST({ version: "10" }).setToken(process.env.DISCORD_TOKEN);
+ const commands = getCommands();
+
+ if (process.env.DISCORD_GUILD_ID) {
+ await rest.put(
+ Routes.applicationGuildCommands(
+ process.env.DISCORD_CLIENT_ID,
+ process.env.DISCORD_GUILD_ID
+ ),
+ { body: commands }
+ );
+ console.log("Registered guild commands.");
+ return;
+ }
+
+ await rest.put(Routes.applicationCommands(process.env.DISCORD_CLIENT_ID), {
+ body: commands,
+ });
+ console.log("Registered global commands.");
+}
+
+registerCommands().catch((error) => {
+ console.error(`Failed to register commands: ${error.message}`);
+ process.exit(1);
+});
diff --git a/examples/platform-integrations/discord-bot/test/aport.test.js b/examples/platform-integrations/discord-bot/test/aport.test.js
new file mode 100644
index 0000000..78acc94
--- /dev/null
+++ b/examples/platform-integrations/discord-bot/test/aport.test.js
@@ -0,0 +1,65 @@
+const assert = require("node:assert/strict");
+const test = require("node:test");
+
+const {
+ buildVerificationPayload,
+ formatDecision,
+ parseDecision,
+} = require("../src/aport");
+
+test("builds an APort verification payload from Discord context", () => {
+ const payload = buildVerificationPayload({
+ userId: "123",
+ action: "merge_pr",
+ resource: "aporthq/aport-integrations#116",
+ reason: "approved review",
+ policyPack: "code.repository.merge.v1",
+ });
+
+ assert.equal(payload.policy_pack, "code.repository.merge.v1");
+ assert.equal(payload.context.actor.type, "discord_user");
+ assert.equal(payload.context.actor.id, "123");
+ assert.equal(payload.context.action, "merge_pr");
+ assert.equal(payload.context.resource, "aporthq/aport-integrations#116");
+});
+
+test("validates required payload fields", () => {
+ assert.throws(
+ () =>
+ buildVerificationPayload({
+ action: "merge_pr",
+ policyPack: "code.repository.merge.v1",
+ }),
+ /Discord user id/
+ );
+
+ assert.throws(
+ () =>
+ buildVerificationPayload({
+ userId: "123",
+ policyPack: "code.repository.merge.v1",
+ }),
+ /Action is required/
+ );
+});
+
+test("parses nested and direct APort decisions", () => {
+ const nested = { data: { decision: { allow: true, decision_id: "dec_1" } } };
+ const direct = { allow: false, decision_id: "dec_2" };
+
+ assert.equal(parseDecision(nested).decision_id, "dec_1");
+ assert.equal(parseDecision(direct).decision_id, "dec_2");
+});
+
+test("formats decision output for Discord replies", () => {
+ const formatted = formatDecision({
+ allow: false,
+ decision_id: "dec_123",
+ reasons: [{ message: "limit exceeded" }],
+ });
+
+ assert.equal(formatted.allow, false);
+ assert.match(formatted.text, /Allow: no/);
+ assert.match(formatted.text, /limit exceeded/);
+ assert.match(formatted.text, /dec_123/);
+});