polydev-ai 1.4.0 → 1.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,289 +0,0 @@
1
- "use strict";
2
- /**
3
- * Zero-Knowledge Client-Side Encryption System
4
- * All encryption keys never leave the user's browser
5
- * Enterprise-grade AES-256-GCM encryption with automatic key rotation
6
- */
7
- Object.defineProperty(exports, "__esModule", { value: true });
8
- exports.zkEncryption = exports.ZeroKnowledgeEncryption = void 0;
9
- class ZeroKnowledgeEncryption {
10
- constructor() {
11
- this.db = null;
12
- this.activeKey = null;
13
- }
14
- /**
15
- * Initialize the encryption system
16
- */
17
- async initialize() {
18
- await this.initializeIndexedDB();
19
- await this.loadOrCreateActiveKey();
20
- }
21
- /**
22
- * Initialize IndexedDB for local key storage
23
- */
24
- async initializeIndexedDB() {
25
- return new Promise((resolve, reject) => {
26
- const request = indexedDB.open(ZeroKnowledgeEncryption.DB_NAME, ZeroKnowledgeEncryption.DB_VERSION);
27
- request.onerror = () => reject(request.error);
28
- request.onsuccess = () => {
29
- this.db = request.result;
30
- resolve();
31
- };
32
- request.onupgradeneeded = (event) => {
33
- const db = event.target.result;
34
- // Store for encryption keys (never synchronized)
35
- if (!db.objectStoreNames.contains('keys')) {
36
- const keyStore = db.createObjectStore('keys', { keyPath: 'keyId' });
37
- keyStore.createIndex('created', 'created', { unique: false });
38
- }
39
- // Cache for encrypted data
40
- if (!db.objectStoreNames.contains('cache')) {
41
- const cacheStore = db.createObjectStore('cache', { keyPath: 'id' });
42
- cacheStore.createIndex('expires', 'expires', { unique: false });
43
- }
44
- };
45
- });
46
- }
47
- /**
48
- * Generate new AES-256-GCM encryption key
49
- */
50
- async generateKey() {
51
- const keyId = this.generateKeyId();
52
- const key = await window.crypto.subtle.generateKey({
53
- name: ZeroKnowledgeEncryption.ALGORITHM,
54
- length: ZeroKnowledgeEncryption.KEY_LENGTH,
55
- }, true, // extractable for storage
56
- ['encrypt', 'decrypt']);
57
- const now = new Date();
58
- const rotationDue = new Date(now.getTime() + (ZeroKnowledgeEncryption.KEY_ROTATION_DAYS * 24 * 60 * 60 * 1000));
59
- return {
60
- keyId,
61
- key,
62
- created: now,
63
- rotationDue
64
- };
65
- }
66
- /**
67
- * Load active key or create new one
68
- */
69
- async loadOrCreateActiveKey() {
70
- if (!this.db)
71
- throw new Error('Database not initialized');
72
- const transaction = this.db.transaction(['keys'], 'readonly');
73
- const store = transaction.objectStore('keys');
74
- // Get the most recent key
75
- const index = store.index('created');
76
- const request = index.openCursor(null, 'prev');
77
- return new Promise((resolve) => {
78
- request.onsuccess = async (event) => {
79
- const cursor = event.target.result;
80
- if (cursor) {
81
- const keyData = cursor.value;
82
- // Check if key needs rotation
83
- if (new Date() > new Date(keyData.rotationDue)) {
84
- console.log('[ZK Encryption] Key rotation needed, generating new key');
85
- await this.createAndStoreKey();
86
- }
87
- else {
88
- // Import existing key
89
- const keyBuffer = new Uint8Array(keyData.keyBuffer);
90
- this.activeKey = {
91
- keyId: keyData.keyId,
92
- key: await window.crypto.subtle.importKey('raw', keyBuffer, { name: ZeroKnowledgeEncryption.ALGORITHM }, true, ['encrypt', 'decrypt']),
93
- created: new Date(keyData.created),
94
- rotationDue: new Date(keyData.rotationDue)
95
- };
96
- }
97
- }
98
- else {
99
- // No keys exist, create first one
100
- await this.createAndStoreKey();
101
- }
102
- resolve();
103
- };
104
- });
105
- }
106
- /**
107
- * Create and store new key
108
- */
109
- async createAndStoreKey() {
110
- this.activeKey = await this.generateKey();
111
- await this.storeKey(this.activeKey);
112
- }
113
- /**
114
- * Store key in IndexedDB
115
- */
116
- async storeKey(userKey) {
117
- if (!this.db)
118
- throw new Error('Database not initialized');
119
- const keyBuffer = await window.crypto.subtle.exportKey('raw', userKey.key);
120
- const transaction = this.db.transaction(['keys'], 'readwrite');
121
- const store = transaction.objectStore('keys');
122
- await store.put({
123
- keyId: userKey.keyId,
124
- keyBuffer: Array.from(new Uint8Array(keyBuffer)),
125
- created: userKey.created.toISOString(),
126
- rotationDue: userKey.rotationDue.toISOString()
127
- });
128
- }
129
- /**
130
- * Encrypt sensitive data
131
- */
132
- async encrypt(plaintext) {
133
- if (!this.activeKey)
134
- throw new Error('Encryption key not available');
135
- const encoder = new TextEncoder();
136
- const data = encoder.encode(plaintext);
137
- const iv = window.crypto.getRandomValues(new Uint8Array(ZeroKnowledgeEncryption.IV_LENGTH));
138
- const encrypted = await window.crypto.subtle.encrypt({
139
- name: ZeroKnowledgeEncryption.ALGORITHM,
140
- iv: iv,
141
- }, this.activeKey.key, data);
142
- const encryptedArray = new Uint8Array(encrypted);
143
- const ciphertext = encryptedArray.slice(0, -ZeroKnowledgeEncryption.AUTH_TAG_LENGTH);
144
- const authTag = encryptedArray.slice(-ZeroKnowledgeEncryption.AUTH_TAG_LENGTH);
145
- return {
146
- ciphertext: this.arrayBufferToBase64(ciphertext.buffer),
147
- iv: this.arrayBufferToBase64(iv.buffer),
148
- authTag: this.arrayBufferToBase64(authTag.buffer),
149
- keyId: this.activeKey.keyId,
150
- version: 1
151
- };
152
- }
153
- /**
154
- * Decrypt sensitive data
155
- */
156
- async decrypt(encryptedData) {
157
- const key = await this.getKeyById(encryptedData.keyId);
158
- if (!key)
159
- throw new Error(`Encryption key ${encryptedData.keyId} not found`);
160
- const ciphertext = this.base64ToArrayBuffer(encryptedData.ciphertext);
161
- const iv = this.base64ToArrayBuffer(encryptedData.iv);
162
- const authTag = this.base64ToArrayBuffer(encryptedData.authTag);
163
- // Combine ciphertext and auth tag for Web Crypto API
164
- const combined = new Uint8Array(ciphertext.byteLength + authTag.byteLength);
165
- combined.set(new Uint8Array(ciphertext));
166
- combined.set(new Uint8Array(authTag), ciphertext.byteLength);
167
- const decrypted = await window.crypto.subtle.decrypt({
168
- name: ZeroKnowledgeEncryption.ALGORITHM,
169
- iv: new Uint8Array(iv),
170
- }, key, combined);
171
- const decoder = new TextDecoder();
172
- return decoder.decode(decrypted);
173
- }
174
- /**
175
- * Get encryption key by ID
176
- */
177
- async getKeyById(keyId) {
178
- if (!this.db)
179
- return null;
180
- const transaction = this.db.transaction(['keys'], 'readonly');
181
- const store = transaction.objectStore('keys');
182
- const request = store.get(keyId);
183
- return new Promise((resolve) => {
184
- request.onsuccess = async () => {
185
- if (request.result) {
186
- const keyBuffer = new Uint8Array(request.result.keyBuffer);
187
- const key = await window.crypto.subtle.importKey('raw', keyBuffer, { name: ZeroKnowledgeEncryption.ALGORITHM }, true, ['encrypt', 'decrypt']);
188
- resolve(key);
189
- }
190
- else {
191
- resolve(null);
192
- }
193
- };
194
- request.onerror = () => resolve(null);
195
- });
196
- }
197
- /**
198
- * Create SHA-256 hash for content deduplication
199
- */
200
- async createContentHash(content) {
201
- const encoder = new TextEncoder();
202
- const data = encoder.encode(content);
203
- const hashBuffer = await window.crypto.subtle.digest('SHA-256', data);
204
- return this.arrayBufferToHex(hashBuffer);
205
- }
206
- /**
207
- * Check if key rotation is needed
208
- */
209
- isRotationDue() {
210
- return this.activeKey ? new Date() > this.activeKey.rotationDue : true;
211
- }
212
- /**
213
- * Force key rotation
214
- */
215
- async rotateKeys() {
216
- await this.createAndStoreKey();
217
- console.log('[ZK Encryption] Key rotation completed');
218
- }
219
- /**
220
- * Generate unique key ID
221
- */
222
- generateKeyId() {
223
- const timestamp = Date.now().toString(36);
224
- const random = Math.random().toString(36).substr(2, 9);
225
- return `zk_${timestamp}_${random}`;
226
- }
227
- /**
228
- * Utility: ArrayBuffer to Base64
229
- */
230
- arrayBufferToBase64(buffer) {
231
- const bytes = new Uint8Array(buffer);
232
- let binary = '';
233
- for (let i = 0; i < bytes.byteLength; i++) {
234
- binary += String.fromCharCode(bytes[i]);
235
- }
236
- return btoa(binary);
237
- }
238
- /**
239
- * Utility: Base64 to ArrayBuffer
240
- */
241
- base64ToArrayBuffer(base64) {
242
- const binary = atob(base64);
243
- const bytes = new Uint8Array(binary.length);
244
- for (let i = 0; i < binary.length; i++) {
245
- bytes[i] = binary.charCodeAt(i);
246
- }
247
- return bytes.buffer;
248
- }
249
- /**
250
- * Utility: ArrayBuffer to Hex
251
- */
252
- arrayBufferToHex(buffer) {
253
- const bytes = new Uint8Array(buffer);
254
- return Array.from(bytes, byte => byte.toString(16).padStart(2, '0')).join('');
255
- }
256
- /**
257
- * Get encryption status for dashboard
258
- */
259
- getEncryptionStatus() {
260
- return {
261
- keyId: this.activeKey?.keyId || null,
262
- created: this.activeKey?.created || null,
263
- rotationDue: this.activeKey?.rotationDue || null,
264
- rotationNeeded: this.isRotationDue()
265
- };
266
- }
267
- /**
268
- * Clear all keys (for user logout/reset)
269
- */
270
- async clearAllKeys() {
271
- if (!this.db)
272
- return;
273
- const transaction = this.db.transaction(['keys', 'cache'], 'readwrite');
274
- await transaction.objectStore('keys').clear();
275
- await transaction.objectStore('cache').clear();
276
- this.activeKey = null;
277
- console.log('[ZK Encryption] All keys cleared');
278
- }
279
- }
280
- exports.ZeroKnowledgeEncryption = ZeroKnowledgeEncryption;
281
- ZeroKnowledgeEncryption.ALGORITHM = 'AES-GCM';
282
- ZeroKnowledgeEncryption.KEY_LENGTH = 256;
283
- ZeroKnowledgeEncryption.IV_LENGTH = 12;
284
- ZeroKnowledgeEncryption.AUTH_TAG_LENGTH = 16;
285
- ZeroKnowledgeEncryption.KEY_ROTATION_DAYS = 30;
286
- ZeroKnowledgeEncryption.DB_NAME = 'PolydevZKMemory';
287
- ZeroKnowledgeEncryption.DB_VERSION = 1;
288
- // Export singleton instance
289
- exports.zkEncryption = new ZeroKnowledgeEncryption();
package/mcp/README.md DELETED
@@ -1,160 +0,0 @@
1
- # Polydev AI MCP Server
2
-
3
- Get diverse AI perspectives from multiple LLMs via Model Context Protocol (MCP). Supports Cline, Claude Code, and other MCP clients with local CLI detection and remote AI perspectives.
4
-
5
- ## Features
6
-
7
- - 🤖 **Multi-Model AI Perspectives**: Get responses from GPT-4, Claude, Gemini, and more
8
- - 🔧 **Local CLI Detection**: Automatically detect and use Claude Code, Codex CLI, Gemini CLI
9
- - ⚡ **Smart Caching**: Intelligent refresh intervals based on CLI status
10
- - 🔄 **Fallback Support**: Local CLI + remote perspectives for comprehensive responses
11
- - 🔐 **Secure**: Token-based authentication with your Polydev account
12
-
13
- ## Installation
14
-
15
- ### For Claude Code Users
16
-
17
- ```bash
18
- # Install globally
19
- npm install -g polydev-ai
20
-
21
- # Or use directly with npx
22
- npx polydev-ai
23
- ```
24
-
25
- ### For Cline Users
26
-
27
- Add to your MCP settings (`.cline/mcp_servers.json`):
28
-
29
- ```json
30
- {
31
- "mcpServers": {
32
- "polydev": {
33
- "command": "npx",
34
- "args": ["polydev-ai"],
35
- "env": {
36
- "POLYDEV_USER_TOKEN": "your_token_here"
37
- }
38
- }
39
- }
40
- }
41
- ```
42
-
43
- ## Configuration
44
-
45
- ### Get Your Token
46
-
47
- 1. Sign up at [polydev.ai](https://polydev.ai)
48
- 2. Go to your dashboard and copy your MCP token
49
- 3. Set the environment variable:
50
-
51
- ```bash
52
- export POLYDEV_USER_TOKEN="pd_your_token_here"
53
- ```
54
-
55
- ### Claude Code Integration
56
-
57
- Add to your Claude Code MCP configuration:
58
-
59
- ```json
60
- "polydev": {
61
- "disabled": false,
62
- "timeout": 120,
63
- "type": "http",
64
- "url": "https://www.polydev.ai/api/mcp"
65
- },
66
- ```
67
-
68
- ## Available Tools
69
-
70
- - `get_perspectives` - Get AI responses from multiple models
71
- - `force_cli_detection` - Force detection of local CLI tools
72
- - `get_cli_status` - Check status of CLI tools (Claude Code, Codex, Gemini)
73
- - `send_cli_prompt` - Send prompts to local CLI with perspectives fallback
74
-
75
- ## Usage Examples
76
-
77
- ### Get Multi-Model Perspectives
78
-
79
- ```typescript
80
- // Use the get_perspectives tool
81
- {
82
- "prompt": "How do I optimize React performance?",
83
- "models": ["gpt-4", "claude-3-sonnet", "gemini-pro"]
84
- }
85
- ```
86
-
87
- ### Check CLI Status
88
-
89
- ```typescript
90
- // Check all CLI tools
91
- await get_cli_status({})
92
-
93
- // Check specific tool
94
- await get_cli_status({ provider_id: "claude_code" })
95
- ```
96
-
97
- ### Send CLI Prompt with Fallback
98
-
99
- ```typescript
100
- await send_cli_prompt({
101
- provider_id: "claude_code",
102
- prompt: "Write a Python function to parse JSON",
103
- mode: "args"
104
- })
105
- ```
106
-
107
- ## Supported CLI Tools
108
-
109
- - **Claude Code** (`claude`) - Anthropic's official CLI
110
- - **Codex CLI** (`codex`) - OpenAI's code CLI
111
- - **Gemini CLI** (`gemini`) - Google's Gemini CLI
112
-
113
- ## Smart Refresh System
114
-
115
- The MCP server automatically detects CLI status changes:
116
-
117
- - **Unavailable CLIs**: Check every 2 minutes
118
- - **Unauthenticated CLIs**: Check every 3 minutes
119
- - **Working CLIs**: Check every 10 minutes
120
- - **Fallback detection**: Check every 5 minutes
121
-
122
- ## Environment Variables
123
-
124
- - `POLYDEV_USER_TOKEN` - Your Polydev authentication token (required)
125
- - `POLYDEV_CLI_DEBUG` - Enable CLI debugging output
126
- - `CLAUDE_CODE_PATH` - Custom path to Claude Code CLI
127
- - `CODEX_CLI_PATH` - Custom path to Codex CLI
128
- - `GEMINI_CLI_PATH` - Custom path to Gemini CLI
129
-
130
- ## Troubleshooting
131
-
132
- ### CLI Not Detected
133
-
134
- 1. Ensure the CLI is installed and in your PATH
135
- 2. Check authentication: `claude auth status` / `codex login status`
136
- 3. Enable debugging: `export POLYDEV_CLI_DEBUG=1`
137
-
138
- ### Token Issues
139
-
140
- 1. Verify your token at [polydev.ai/dashboard](https://polydev.ai/dashboard)
141
- 2. Ensure the token starts with `pd_`
142
- 3. Check environment variable is set correctly
143
-
144
- ### Permission Errors
145
-
146
- ```bash
147
- # Fix npm permissions
148
- npm config set prefix '~/.npm-global'
149
- export PATH=~/.npm-global/bin:$PATH
150
- ```
151
-
152
- ## Support
153
-
154
- - 📧 Email: [support@polydev.ai](mailto:support@polydev.ai)
155
- - 📖 Docs: [polydev.ai/docs](https://polydev.ai/docs)
156
- - 🐛 Issues: [GitHub Issues](https://github.com/backspacevenkat/polydev-website/issues)
157
-
158
- ## License
159
-
160
- MIT License - see LICENSE file for details.
package/mcp/package.json DELETED
@@ -1,46 +0,0 @@
1
- {
2
- "name": "polydev-ai",
3
- "version": "1.2.6",
4
- "description": "Get diverse AI perspectives from multiple LLMs via MCP - supports Cline, Claude Code, and other MCP clients",
5
- "main": "stdio-wrapper.js",
6
- "bin": {
7
- "polydev-ai": "./stdio-wrapper.js"
8
- },
9
- "scripts": {
10
- "start": "node server.js",
11
- "test": "node server.js --help"
12
- },
13
- "keywords": [
14
- "mcp",
15
- "model-context-protocol",
16
- "ai",
17
- "llm",
18
- "perspectives",
19
- "multi-model",
20
- "cline",
21
- "claude",
22
- "openai",
23
- "anthropic",
24
- "gemini",
25
- "polydev"
26
- ],
27
- "author": "Polydev AI <support@polydev.ai>",
28
- "license": "MIT",
29
- "engines": {
30
- "node": ">=16.0.0"
31
- },
32
- "files": [
33
- "stdio-wrapper.js",
34
- "manifest.json",
35
- "README.md"
36
- ],
37
- "repository": {
38
- "type": "git",
39
- "url": "https://github.com/backspacevenkat/polydev-website.git",
40
- "directory": "mcp"
41
- },
42
- "homepage": "https://polydev.ai/docs/mcp-integration",
43
- "bugs": {
44
- "url": "https://github.com/backspacevenkat/polydev-website/issues"
45
- }
46
- }