diff --git a/.opencode/.strrayrc.json b/.opencode/.strrayrc.json index 3601c5fa3..4353c4663 100644 --- a/.opencode/.strrayrc.json +++ b/.opencode/.strrayrc.json @@ -1,7 +1,7 @@ { "framework": { "name": "StringRay Framework", - "version": "1.14.1", + "version": "1.14.10", "buildMode": "production", "logLevel": "info" }, diff --git a/.opencode/agents/enforcer.yml b/.opencode/agents/enforcer.yml index 1cb450056..c2b61182f 100644 --- a/.opencode/agents/enforcer.yml +++ b/.opencode/agents/enforcer.yml @@ -2,6 +2,8 @@ name: enforcer description: "Enforcer agent for codex compliance and error prevention" version: "1.0.0" +system: "You are the StringRay Enforcer agent. You validate code against the Universal Development Codex (60 error-prevention terms), enforce quality gates, and prevent errors with 99.6% accuracy. You check for type safety, input validation, memory optimization, error handling, security, and architecture compliance. Block operations that violate codex terms." + # ============================================================================= # CODEX COMPLIANCE # ============================================================================= diff --git a/.opencode/codex.codex b/.opencode/codex.codex index 4289867c8..89e939cef 100644 --- a/.opencode/codex.codex +++ b/.opencode/codex.codex @@ -1,5 +1,5 @@ { - "version": "1.14.1", + "version": "1.14.10", "terms": [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60 ], diff --git a/.opencode/command/dependency-audit.md b/.opencode/command/dependency-audit.md index a4a1dac03..fdda8a105 100644 --- a/.opencode/command/dependency-audit.md +++ b/.opencode/command/dependency-audit.md @@ -69,7 +69,7 @@ Comprehensive dependency analysis and security audit for all project dependencie "vulnerabilities": [ { "package": "lodash", - "version": "1.14.1", + "version": "1.14.10", "severity": "high", "cve": "CVE-2021-23337", "description": "Command injection vulnerability" @@ -85,14 +85,14 @@ Security-focused format for CI/CD integration: ```json { - "version": "1.14.1", + "version": "1.14.10", "$schema": "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json", "runs": [ { "tool": { "driver": { "name": "Dependency Audit", - "version": "1.14.1" + "version": "1.14.10" } }, "results": [...] diff --git a/.opencode/enforcer-config.json b/.opencode/enforcer-config.json index c0c609559..7d9ace3d4 100644 --- a/.opencode/enforcer-config.json +++ b/.opencode/enforcer-config.json @@ -1,6 +1,6 @@ { "framework": "StringRay 1.0.0", - "version": "1.14.1", + "version": "1.14.10", "description": "Codex-compliant framework configuration for Credible UI project", "thresholds": { "bundleSize": { @@ -220,7 +220,7 @@ } }, "codex": { - "version": "1.14.1", + "version": "1.14.10", "terms": [ 1, 2, diff --git a/.opencode/package.json b/.opencode/package.json index 0926244a2..0e5bb1cc3 100644 --- a/.opencode/package.json +++ b/.opencode/package.json @@ -1,6 +1,6 @@ { "name": "@opencode/OpenCode", - "version": "1.14.1", + "version": "1.14.10", "description": "OpenCode framework configuration", "main": "OpenCode.json", "scripts": { diff --git a/.opencode/state b/.opencode/state index 029325af2..3e937b249 100644 --- a/.opencode/state +++ b/.opencode/state @@ -1,9 +1,9 @@ { "memory:baseline": { - "heapUsed": 11.44, + "heapUsed": 11.51, "heapTotal": 20.16, "external": 1.88, - "rss": 57.48, - "timestamp": 1774575810934 + "rss": 57.63, + "timestamp": 1774632597883 } } \ No newline at end of file diff --git a/.opencode/strray/codex.json b/.opencode/strray/codex.json index 463ef7ffd..de4d06dd6 100644 --- a/.opencode/strray/codex.json +++ b/.opencode/strray/codex.json @@ -1,5 +1,5 @@ { - "version": "1.14.1", + "version": "1.14.10", "lastUpdated": "2026-03-09", "errorPreventionTarget": 0.996, "terms": { diff --git a/.opencode/strray/config.json b/.opencode/strray/config.json index 602d16f99..3add49a3f 100644 --- a/.opencode/strray/config.json +++ b/.opencode/strray/config.json @@ -1,6 +1,6 @@ { "$schema": "./config.schema.json", - "version": "1.14.1", + "version": "1.14.10", "description": "StringRay Framework - Token Management & Performance Configuration", "token_management": { diff --git a/.opencode/strray/features.json b/.opencode/strray/features.json index e176961a1..188c144d2 100644 --- a/.opencode/strray/features.json +++ b/.opencode/strray/features.json @@ -1,6 +1,6 @@ { "$schema": "./features.schema.json", - "version": "1.14.1", + "version": "1.14.10", "description": "StringRay Framework - Unified Feature Configuration", "token_optimization": { "enabled": true, diff --git a/.opencode/strray/integrations.json b/.opencode/strray/integrations.json index bf4fc84ad..760997653 100644 --- a/.opencode/strray/integrations.json +++ b/.opencode/strray/integrations.json @@ -4,19 +4,19 @@ "openclaw": { "enabled": false, "type": "external-service", - "version": "1.14.1", + "version": "1.14.10", "config": {} }, "python-bridge": { "enabled": false, "type": "protocol-bridge", - "version": "1.14.1", + "version": "1.14.10", "config": {} }, "react": { "enabled": false, "type": "framework-adapter", - "version": "1.14.1", + "version": "1.14.10", "config": {} } } diff --git a/README.md b/README.md index 6d5d41536..6ebe17018 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ **Enterprise AI Orchestration Framework for OpenCode/Claude Code** -[![Version](https://img.shields.io/badge/version-1.14.7-blue?style=flat-square)](https://npmjs.com/package/strray-ai) +[![Version](https://img.shields.io/badge/version-1.14.10-blue?style=flat-square)](https://npmjs.com/package/strray-ai) [![License](https://img.shields.io/badge/license-MIT-green?style=flat-square)](LICENSE) [![Tests](https://img.shields.io/badge/tests-2368%20passed-brightgreen?style=flat-square)](src/__tests__) [![GitHub stars](https://img.shields.io/github/stars/htafolla/stringray?style=social)](https://github.com/htafolla/stringray) @@ -47,14 +47,14 @@ npm install strray-ai **What happens during install?** - Copies OpenCode configuration files to your project -- Configures 13 agents with proper capabilities +- Configures 26 agents with proper capabilities - Sets up Codex enforcement rules - Enables webhook triggers for CI/CD integration - Ready to use with Claude Code immediately ## ✨ Features -- **πŸ€– 13 Specialized Agents** - Autonomous agents that read/write code, run commands, and enforce compliance +- **πŸ€– 26 Specialized Agents** - Autonomous agents that read/write code, run commands, and enforce compliance - **πŸ“ 99.6% Error Prevention** - Universal Development Codex (60 terms) - **⚑ 43 Framework Skills** + 10 curated community sources (170+ additional skills available) - **πŸ›‘οΈ Enterprise Security** - Comprehensive validation and scanning @@ -79,7 +79,7 @@ npm install strray-ai > **Note:** StringRay auto-configures all agents during installation. To customize agent settings, see the [Agent Configuration Guide](https://github.com/htafolla/stringray/blob/main/docs/AGENT_CONFIG.md). -[View all 13 agents β†’](https://github.com/htafolla/stringray/blob/main/AGENTS.md) +[View all 26 agents β†’](https://github.com/htafolla/stringray/blob/main/AGENTS.md) ## πŸ“¦ OpenClaw Integration @@ -254,7 +254,7 @@ stringray/ β”‚ β”œβ”€β”€ validation/ # Agent config & estimation validators β”‚ └── jobs/ # Background job management β”œβ”€β”€ .opencode/ # OpenCode configuration -β”‚ β”œβ”€β”€ agents/ # Agent configs (13 agents) +β”‚ β”œβ”€β”€ agents/ # Agent configs (26 agents) β”‚ β”œβ”€β”€ strray/ # StringRay config β”‚ β”‚ β”œβ”€β”€ codex.json # 60-term development codex β”‚ β”‚ β”œβ”€β”€ features.json # Feature flags diff --git a/backups/version-manager-backup-2026-03-27T17-29-28-833Z/CHANGELOG.md b/backups/version-manager-backup-2026-03-27T17-29-28-833Z/CHANGELOG.md new file mode 100644 index 000000000..96a86cf34 --- /dev/null +++ b/backups/version-manager-backup-2026-03-27T17-29-28-833Z/CHANGELOG.md @@ -0,0 +1,11 @@ +# Version Management Changelog + +Generated: 2026-03-27 +============================================================ + +## Summary + + +## Detailed Changes + + diff --git a/ci-test-env/.opencode/enforcer-config.json b/ci-test-env/.opencode/enforcer-config.json index 7e4814b66..853fe7ec9 100644 --- a/ci-test-env/.opencode/enforcer-config.json +++ b/ci-test-env/.opencode/enforcer-config.json @@ -1,6 +1,6 @@ { "framework": "StringRay 1.0.0", - "version": "1.14.1", + "version": "1.14.10", "description": "Codex-compliant framework configuration for Credible UI project", "thresholds": { "bundleSize": { @@ -174,7 +174,7 @@ } }, "codex": { - "version": "1.14.1", + "version": "1.14.10", "terms": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 24, 29, 32, 38, 42, 43], "principles": [ "progressive-prod-ready-code", diff --git a/ci-test-env/.opencode/package.json b/ci-test-env/.opencode/package.json index 0926244a2..0e5bb1cc3 100644 --- a/ci-test-env/.opencode/package.json +++ b/ci-test-env/.opencode/package.json @@ -1,6 +1,6 @@ { "name": "@opencode/OpenCode", - "version": "1.14.1", + "version": "1.14.10", "description": "OpenCode framework configuration", "main": "OpenCode.json", "scripts": { diff --git a/ci-test-env/.opencode/strray/codex.json b/ci-test-env/.opencode/strray/codex.json index 463ef7ffd..de4d06dd6 100644 --- a/ci-test-env/.opencode/strray/codex.json +++ b/ci-test-env/.opencode/strray/codex.json @@ -1,5 +1,5 @@ { - "version": "1.14.1", + "version": "1.14.10", "lastUpdated": "2026-03-09", "errorPreventionTarget": 0.996, "terms": { diff --git a/ci-test-env/.opencode/strray/config.json b/ci-test-env/.opencode/strray/config.json index 602d16f99..3add49a3f 100644 --- a/ci-test-env/.opencode/strray/config.json +++ b/ci-test-env/.opencode/strray/config.json @@ -1,6 +1,6 @@ { "$schema": "./config.schema.json", - "version": "1.14.1", + "version": "1.14.10", "description": "StringRay Framework - Token Management & Performance Configuration", "token_management": { diff --git a/ci-test-env/.opencode/strray/features.json b/ci-test-env/.opencode/strray/features.json index d33fd2703..4b94edb1e 100644 --- a/ci-test-env/.opencode/strray/features.json +++ b/ci-test-env/.opencode/strray/features.json @@ -1,6 +1,6 @@ { "$schema": "./features.schema.json", - "version": "1.14.1", + "version": "1.14.10", "description": "StringRay Framework - Unified Feature Configuration", "token_optimization": { "enabled": true, diff --git a/ci-test-env/package.json b/ci-test-env/package.json index ef610a4a7..a5a864a71 100644 --- a/ci-test-env/package.json +++ b/ci-test-env/package.json @@ -1,6 +1,6 @@ { "name": "ci-test-env", - "version": "1.14.1", + "version": "1.14.10", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" diff --git a/command/dependency-audit.md b/command/dependency-audit.md index a4a1dac03..fdda8a105 100644 --- a/command/dependency-audit.md +++ b/command/dependency-audit.md @@ -69,7 +69,7 @@ Comprehensive dependency analysis and security audit for all project dependencie "vulnerabilities": [ { "package": "lodash", - "version": "1.14.1", + "version": "1.14.10", "severity": "high", "cve": "CVE-2021-23337", "description": "Command injection vulnerability" @@ -85,14 +85,14 @@ Security-focused format for CI/CD integration: ```json { - "version": "1.14.1", + "version": "1.14.10", "$schema": "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json", "runs": [ { "tool": { "driver": { "name": "Dependency Audit", - "version": "1.14.1" + "version": "1.14.10" } }, "results": [...] diff --git a/docs/ADDING_AGENTS.md b/docs/ADDING_AGENTS.md index 7a1b6cc5a..e58488e40 100644 --- a/docs/ADDING_AGENTS.md +++ b/docs/ADDING_AGENTS.md @@ -108,7 +108,7 @@ Create the agent YAML file: ```yaml name: my-agent description: "What this agent does" -version: "1.14.1" +version: "1.14.10" mode: subagent ``` diff --git a/docs/CONFIGURATION.md b/docs/CONFIGURATION.md index a17165df4..7d99fdb5b 100644 --- a/docs/CONFIGURATION.md +++ b/docs/CONFIGURATION.md @@ -40,7 +40,7 @@ Create `.opencode/strray/features.json` in your project root: ```json { - "version": "1.14.1", + "version": "1.14.10", "description": "StringRay Framework Configuration", "token_optimization": { @@ -381,7 +381,7 @@ The main OpenCode configuration file for agent routing: "code-analyzer": "openrouter/xai-grok-2-1212-fast-1" }, "framework": { - "version": "1.14.1", + "version": "1.14.10", "codexEnforcement": true, "jobIdLogging": true, "consoleLogRule": true diff --git a/docs/README.md b/docs/README.md index 3a577f8bf..dde875923 100644 --- a/docs/README.md +++ b/docs/README.md @@ -126,7 +126,7 @@ StringRay Framework automatically configures itself based on your installation m - Loads the Universal Development Codex v1.1.1 - Enables enterprise CI/CD automation with post-processor - Registers all 13 autonomous agents -- Sets up 11 MCP servers for agent communication +- Sets up 15 MCP servers for agent communication - Configures automated deployment pipelines #### OpenCode Integration @@ -202,7 +202,7 @@ Update your `.opencode/OpenCode.json`: }, "framework": { "name": "strray", - "version": "1.14.1" + "version": "1.14.10" } } ``` @@ -473,7 +473,7 @@ Update your `.opencode/OpenCode.json` for enterprise deployment: }, "framework": { "name": "strray", - "version": "1.14.1", + "version": "1.14.10", "performance_mode": "optimized", "monitoring_enabled": true, "plugin_security": "strict" diff --git a/docs/README_STRRAY_INTEGRATION.md b/docs/README_STRRAY_INTEGRATION.md index 945b5a864..1c64fb37c 100644 --- a/docs/README_STRRAY_INTEGRATION.md +++ b/docs/README_STRRAY_INTEGRATION.md @@ -180,7 +180,7 @@ STRRAY_MCP_CLIENT_MODULES=all ```json { "strray": { - "version": "1.14.1", + "version": "1.14.10", "architecture": "facade-pattern", "components": { "orchestrator": true, diff --git a/docs/STRAY_EXTENSION.md b/docs/STRAY_EXTENSION.md index 35f10736e..f239a4c55 100644 --- a/docs/STRAY_EXTENSION.md +++ b/docs/STRAY_EXTENSION.md @@ -193,7 +193,7 @@ my-extension/ ```json { "name": "strray-extension-custom", - "version": "1.14.1", + "version": "1.14.10", "description": "Custom StringRay extension", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/docs/api/API_REFERENCE.md b/docs/api/API_REFERENCE.md index dcefe4b93..8ea7e7a50 100644 --- a/docs/api/API_REFERENCE.md +++ b/docs/api/API_REFERENCE.md @@ -500,7 +500,7 @@ await orchestrator.registerAgent(CustomAnalyticsAgent); }, "framework": { "name": "strray", - "version": "1.14.1", + "version": "1.14.10", "performance_mode": "optimized", "monitoring_enabled": true, "plugin_security": "strict", diff --git a/docs/api/ENTERPRISE_API_REFERENCE.md b/docs/api/ENTERPRISE_API_REFERENCE.md index 430bee151..26ccd6c8b 100644 --- a/docs/api/ENTERPRISE_API_REFERENCE.md +++ b/docs/api/ENTERPRISE_API_REFERENCE.md @@ -618,7 +618,7 @@ Get all available facades and their status. "facades": [ { "name": "rule-enforcer", - "version": "1.14.1", + "version": "1.14.10", "status": "healthy", "modules": 6, "metrics": { @@ -628,7 +628,7 @@ Get all available facades and their status. }, { "name": "task-skill-router", - "version": "1.14.1", + "version": "1.14.10", "status": "healthy", "modules": 14, "metrics": { diff --git a/docs/architecture/ENTERPRISE_ARCHITECTURE.md b/docs/architecture/ENTERPRISE_ARCHITECTURE.md index bfc3b06c6..60da0b78e 100644 --- a/docs/architecture/ENTERPRISE_ARCHITECTURE.md +++ b/docs/architecture/ENTERPRISE_ARCHITECTURE.md @@ -629,7 +629,7 @@ The framework integrates seamlessly with OpenCode: }, "framework": { "name": "strray", - "version": "1.14.1" + "version": "1.14.10" } } ``` diff --git a/docs/architecture/GROK_GUIDE.md b/docs/architecture/GROK_GUIDE.md index 801880a73..b22674b5d 100644 --- a/docs/architecture/GROK_GUIDE.md +++ b/docs/architecture/GROK_GUIDE.md @@ -98,7 +98,7 @@ Update your `.opencode/OpenCode.json`: }, "framework": { "name": "strray", - "version": "1.14.1" + "version": "1.14.10" } } ``` diff --git a/docs/archive/historical/CHANGELOG-v1.2.0.md b/docs/archive/historical/CHANGELOG-v1.2.0.md index e1f3a54c3..7545d4b0a 100644 --- a/docs/archive/historical/CHANGELOG-v1.2.0.md +++ b/docs/archive/historical/CHANGELOG-v1.2.0.md @@ -279,7 +279,7 @@ The missing piece that enables autonomous CI/CD recovery: **No breaking changes.** This is a validation and bugfix release. **Recommended steps**: -1. Update version in package.json: `"version": "1.14.1"` +1. Update version in package.json: `"version": "1.14.10"` 2. Run `npm install` to refresh dependencies 3. Run `npm run test:core-framework` to verify 4. Deploy with confidence diff --git a/docs/archive/historical/strray_v2_log.md b/docs/archive/historical/strray_v2_log.md index 876186647..5ec7b23f7 100644 --- a/docs/archive/historical/strray_v2_log.md +++ b/docs/archive/historical/strray_v2_log.md @@ -1536,7 +1536,7 @@ Implementation Steps Structured dict with complete codex context """ codex_context = { - "version": "1.14.1", + "version": "1.14.10", "terms": {}, "interweaves": [], "lenses": [], @@ -27619,7 +27619,7 @@ Total Files Restored: βœ… FULLY OPERATIONAL: - Session Initialization: βœ… SUCCESS - Component Loading: βœ… All systems loaded (0 missing) -- MCP Integration: βœ… 30 skills loaded, 0 missing +- MCP Integration: βœ… 260 skills loaded, 0 missing - Agent Configuration: βœ… 26 agents loaded, 0 missing - Automation Hooks: βœ… 4 hooks loaded, 0 missing - Workflow Templates: βœ… Loaded @@ -27706,7 +27706,7 @@ All tests and validations have been successfully resolved! βœ… Core Functionality: - Framework Initialization: βœ… SESSION INITIALIZED - Agent Loading: βœ… 26 agents loaded, 0 missing -- MCP Integration: βœ… 30 skills loaded, 0 missing +- MCP Integration: βœ… 260 skills loaded, 0 missing - Configuration Validation: βœ… All configs valid JSON - Directory Structure: βœ… All required directories present βœ… Advanced Features: @@ -32374,7 +32374,7 @@ After: Accurate Reality --- πŸ“Š UPDATED SECTIONS βœ… Title & Purpose -- Framework Version: 1.14.1 +- Framework Version: 1.14.10 - Purpose: Rule-based development workflow orchestration with systematic error prevention - Reality Check: Clearly states what it actually does vs. aspirational claims βœ… Architecture Diagram @@ -39942,7 +39942,7 @@ Immediate Impact Skills (Highest ROI) 3. database-design - Essential for data-heavy applications (70% impact) 4. ui-ux-design - Drives user adoption and satisfaction (60% impact) Why These Skills Matter -Current Gap: Our 30 skills cover ~40% of development scenarios +Current Gap: Our 260 skills cover ~40% of development scenarios Target Coverage: 15 additional skills β†’ ~85% comprehensive coverage Business Impact: - 25% reduction in post-deployment issues @@ -39968,11 +39968,11 @@ Success Metrics --- πŸ’‘ Should We Implement More Skills? YES - Absolutely Critical for Enterprise Readiness -Current State: 30 skills = Basic coverage +Current State: 260 skills = Basic coverage Enterprise Need: 15+ skills = Comprehensive AI assistance Competitive Advantage: Domain expertise across full development lifecycle The framework will transform from "helpful AI assistant" to "comprehensive AI development partner" covering the entire software development lifecycle with specialized expertise. -Recommendation: Implement Phase 1 (30 skills) immediately, then Phase 2 (4 more skills) within 6 weeks for maximum impact. +Recommendation: Implement Phase 1 (260 skills) immediately, then Phase 2 (4 more skills) within 6 weeks for maximum impact. Would you like me to implement the first critical skill (code-review.server.ts) to demonstrate the pattern and value? πŸš€βœ¨ 🎯 Oh-My-OpenCode Skills Analysis vs StrRay Knowledge Skills You're absolutely right! After reviewing the OpenCode documentation, I can see that skills are a core concept in their framework. Let me analyze the differences and provide recommendations for expanding our knowledge skills. @@ -40082,8 +40082,8 @@ Competitive Advantages --- πŸ’‘ Recommendation: Expand Immediately Yes, we should definitely expand our knowledge skills! -Current Gap: 30 skills cover ~40% of development scenarios -Oh-My-OpenCode: 30 skills + category system +Current Gap: 260 skills cover ~40% of development scenarios +Oh-My-OpenCode: 260 skills + category system StrRay Target: 10+ skills = 80%+ comprehensive coverage Immediate Action Plan: 1. βœ… Implement code-review.server.ts (Week 1) @@ -40138,7 +40138,7 @@ Impact: Accessibility-first design, WCAG AA compliance, enhanced user experience --- βš™οΈ TECHNICAL ACHIEVEMENTS βœ… System Integration -- All 30 skills registered in .mcp.json configuration +- All 260 skills registered in .mcp.json configuration - TypeScript compilation successful with full type safety - MCP server architecture properly implemented - Framework integration tested and operational @@ -40255,7 +40255,7 @@ We just completed Phase 1 Knowledge Skills expansion: - βœ… All skills implemented as MCP servers with comprehensive capabilities - βœ… Framework validated as production-ready with 98% test success - πŸ”„ Currently working on Phase 2 final skills implementation -Current blocking issue: Need to complete Phase 2 with final 30 skills for comprehensive coverage +Current blocking issue: Need to complete Phase 2 with final 260 skills for comprehensive coverage EXACT POINT OF INTERRUPTION We were implementing the remaining Phase 2 knowledge skills: 1. βœ… refactoring-strategies.server.ts - Technical debt elimination, code modernization @@ -40330,7 +40330,7 @@ By session end: The StrRay Framework will achieve complete enterprise-grade AI development assistance with specialized expertise across the entire software development lifecycle. --- 🎯 READY TO CONTINUE: Complete Phase 2 knowledge skills implementation and achieve 100% enterprise production readiness -Current Status: 10/30 skills implemented (83% complete) - need final 30 skills for comprehensive coverage +Current Status: 10/260 skills implemented (83% complete) - need final 260 skills for comprehensive coverage Next Actions: 1. Fix TypeScript errors in refactoring-strategies.server.ts 2. Implement testing-best-practices.server.ts @@ -40352,7 +40352,7 @@ Phase 2: Complete Knowledge Skills Implementation βœ… - βœ… Added Final 2 Skills (10β†’12 total): - refactoring-strategies.server.ts - Technical debt elimination, code modernization - testing-best-practices.server.ts - TDD/BDD workflows, test optimization, CI/CD integration -- βœ… Updated MCP Configuration - All 30 skills registered in .mcp.json +- βœ… Updated MCP Configuration - All 260 skills registered in .mcp.json - βœ… TypeScript Compilation - Zero errors across entire framework - βœ… System Validation - Build successful, infrastructure operational --- @@ -40363,7 +40363,7 @@ Phase 2: Complete Knowledge Skills Implementation βœ… | Build Success | βœ… 100% | TypeScript compilation successful | | Test Coverage | βœ… 98% | 47/48 tests passing | | Error Prevention | βœ… 99.6% | Systematic validation active | -| Knowledge Skills | βœ… 100% | 12/30 skills implemented & configured | +| Knowledge Skills | βœ… 100% | 12/260 skills implemented & configured | | MCP Ecosystem | βœ… 100% | 22 servers operational (8 core + 14 knowledge) | | Infrastructure Immunity | βœ… 100% | Runtime failure prevention active | | Multi-Agent Coordination | βœ… 100% | 8 specialized agents with intelligent delegation | @@ -40673,7 +40673,7 @@ All major objectives accomplished: - Framework Status: PRODUCTION READY 2. βœ… Knowledge Skills Expansion (12/12 Complete) - Phase 1: Added 4 enterprise skills (code-review, security-audit, database-design, ui-ux-design) -- Phase 2: Added final 30 skills (refactoring-strategies, testing-best-practices) +- Phase 2: Added final 260 skills (refactoring-strategies, testing-best-practices) - Total: 12 knowledge skills + 8 core agents = 20 total specialized AI agents 3. βœ… Enterprise Auto-Healing System - Test Execution Optimization (Codex Term #45 enhanced) @@ -40717,18 +40717,18 @@ Status: PHASE 2 COMPLETE - ENTERPRISE PRODUCTION READINESS ACHIEVED πŸŽ‰ Based on the KNOWLEDGE_SKILLS_EXPANSION_PLAN.md, here's the complete roadmap: --- βœ… COMPLETED PHASES -Phase 1: Core Expansion (30 skills) βœ… DONE +Phase 1: Core Expansion (260 skills) βœ… DONE - βœ… code-review.server.ts - Code quality & review standards - βœ… security-audit.server.ts - Security analysis & compliance - βœ… database-design.server.ts - Database architecture & optimization - βœ… ui-ux-design.server.ts - User interface & experience design -Phase 2: DevOps & Quality (30 skills) βœ… DONE +Phase 2: DevOps & Quality (260 skills) βœ… DONE - βœ… devops-deployment.server.ts - DevOps & deployment strategies - βœ… documentation-generation.server.ts - Documentation creation & maintenance - βœ… refactoring-strategies.server.ts - Code refactoring & modernization - βœ… testing-best-practices.server.ts - Advanced testing strategies --- -πŸ”„ PHASE 3: ADVANCED SPECIALIZATIONS (30 skills - OPTIONAL) +πŸ”„ PHASE 3: ADVANCED SPECIALIZATIONS (260 skills - OPTIONAL) Phase 3 exists but is marked as "Future Enhancement" and "Advanced domain-specific skills based on user demand and framework evolution." Remaining Skills for Phase 3: 9. performance-profiling.server.ts - Advanced Performance Analysis @@ -41053,7 +41053,7 @@ Phase 2+ (Hyper-Production Mode) --- ⚑ HYPER-PRODUCTION CAPABILITIES UNLOCKED 1. πŸš€ Rapid Feature Shipping -- βœ… Knowledge Skills: 30 skills implemented in Phase 1-2 (previously would take months) +- βœ… Knowledge Skills: 260 skills implemented in Phase 1-2 (previously would take months) - βœ… Auto-Healing: Complete test optimization system (previously would take weeks) - βœ… E2E Simulation: 100% pipeline coverage (previously would take extensive manual testing) - βœ… Performance Optimization: Aggressive test runner (previously would require performance audits) @@ -42693,7 +42693,7 @@ Commit Details: πŸ“ˆ Performance Metrics: - Test execution: 87% faster (45s vs 10+ min) - Error prevention: 99.6% systematic validation -- Agent coverage: 20 total agents (8 core + 30 skills) +- Agent coverage: 20 total agents (8 core + 260 skills) - MCP servers: 21 positioned and ready --- 🎯 FINAL PROJECT STATUS diff --git a/docs/archive/legacy/strray-framework/dynamic-enforcer-config.json b/docs/archive/legacy/strray-framework/dynamic-enforcer-config.json index fc2782e96..5953c69e7 100644 --- a/docs/archive/legacy/strray-framework/dynamic-enforcer-config.json +++ b/docs/archive/legacy/strray-framework/dynamic-enforcer-config.json @@ -1,6 +1,6 @@ { "framework": "Universal Development Framework v1.1.1", - "version": "1.14.1", + "version": "1.14.10", "description": "Codex-compliant framework configuration for Credible UI project", "thresholds": { @@ -222,7 +222,7 @@ }, "codex": { - "version": "1.14.1", + "version": "1.14.10", "terms": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 24, 29, 32, 38, 42, 43], "principles": [ "progressive-prod-ready-code", diff --git a/docs/archive/legacy/strray-framework/strray-config.json b/docs/archive/legacy/strray-framework/strray-config.json index 4de1d690b..7b68b62c8 100644 --- a/docs/archive/legacy/strray-framework/strray-config.json +++ b/docs/archive/legacy/strray-framework/strray-config.json @@ -19,7 +19,7 @@ "error_rate": 0.1 }, "strray_framework": { - "version": "1.14.1", + "version": "1.14.10", "codex_terms": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 24, 29, 32, 38, 42, 43], "session_initialization": { "auto_format": true, diff --git a/docs/archive/superseded/internal/architecture/ENTERPRISE_ARCHITECTURE.md b/docs/archive/superseded/internal/architecture/ENTERPRISE_ARCHITECTURE.md index 1b51ff628..3bc8718fd 100644 --- a/docs/archive/superseded/internal/architecture/ENTERPRISE_ARCHITECTURE.md +++ b/docs/archive/superseded/internal/architecture/ENTERPRISE_ARCHITECTURE.md @@ -464,7 +464,7 @@ The framework integrates seamlessly with OpenCode: }, "framework": { "name": "strray", - "version": "1.14.1" + "version": "1.14.10" } } ``` diff --git a/docs/archive/superseded/internal/development/contributing.md/FRAMEWORK_REFACTORING.md b/docs/archive/superseded/internal/development/contributing.md/FRAMEWORK_REFACTORING.md index 48dfbaaca..dc4168c28 100644 --- a/docs/archive/superseded/internal/development/contributing.md/FRAMEWORK_REFACTORING.md +++ b/docs/archive/superseded/internal/development/contributing.md/FRAMEWORK_REFACTORING.md @@ -13,7 +13,7 @@ This document describes the comprehensive migration and consolidation efforts im ```json { "strray_framework": { - "version": "1.14.1", + "version": "1.14.10", "enabled_agents": ["enforcer", "architect"], "agent_capabilities": { "enforcer": ["compliance-monitoring"] @@ -26,7 +26,7 @@ This document describes the comprehensive migration and consolidation efforts im ```json { - "version": "1.14.1", + "version": "1.14.10", "enabled_agents": ["enforcer", "architect"], "agent_capabilities_enforcer": ["compliance-monitoring"] } diff --git a/docs/debug-reports/v1.7.2-post-reboot-debug-report.md b/docs/debug-reports/v1.7.2-post-reboot-debug-report.md index 2a4789436..489248cd7 100644 --- a/docs/debug-reports/v1.7.2-post-reboot-debug-report.md +++ b/docs/debug-reports/v1.7.2-post-reboot-debug-report.md @@ -11,7 +11,7 @@ Following system reboot, comprehensive debug cycles were conducted to validate the functionality of StringRay v1.7.2's core systems. **All systems are operational** with **1 minor documentation issue** that was immediately resolved. ### Key Findings: -- βœ… **Skill System**: Fully operational - all 30 skills loading correctly +- βœ… **Skill System**: Fully operational - all 260 skills loading correctly - βœ… **Tool System**: All core tools (bash, read, glob, etc.) functioning properly - βœ… **@Agent Resolution**: Perfect 100% success rate on all agent mentions - βœ… **MCP Server Connectivity**: Client initialization successful, skill invocation operational @@ -192,7 +192,7 @@ StringRay operates via multiple plugin systems: | Component | Status | Performance | Notes | |-----------|---------|-------------|---------| -| Skill System | βœ… Optimal | Instant loading | All 30 skills available | +| Skill System | βœ… Optimal | Instant loading | All 260 skills available | | Tool System | βœ… Optimal | Fast response | All core tools working | | @Agent Resolution | βœ… Optimal | 100% success | Perfect routing accuracy | | MCP Server | βœ… Operational | Normal latency | Client connection stable | @@ -271,7 +271,7 @@ The post-reboot debug cycle successfully validated that StringRay v1.7.2 is func - βœ… 1 minor documentation issue resolved - βœ… 1598/1598 tests passing (100%) - βœ… Perfect @agent resolution (100% success rate) -- βœ… All 30 skills operational +- βœ… All 260 skills operational - βœ… All core tools responding correctly **Production Readiness**: βœ… CONFIRMED diff --git a/docs/development/ENTERPRISE_DEVELOPER_GUIDE.md b/docs/development/ENTERPRISE_DEVELOPER_GUIDE.md index dd6902f72..b11916aa2 100644 --- a/docs/development/ENTERPRISE_DEVELOPER_GUIDE.md +++ b/docs/development/ENTERPRISE_DEVELOPER_GUIDE.md @@ -67,7 +67,7 @@ npm install }, "framework": { "name": "strray", - "version": "1.14.1" + "version": "1.14.10" } } ``` @@ -1259,7 +1259,7 @@ export class CustomPlugin implements Plugin { ```typescript // Plugin manifest with security declarations export const manifest = { - name: "custom-plugin", version: "1.14.1", + name: "custom-plugin", version: "1.14.10", permissions: ["read:filesystem", "network:http", "storage:local"], sandbox: { memoryLimit: "50MB", diff --git a/docs/operations/deployment/ENTERPRISE_DEPLOYMENT_GUIDE.md b/docs/operations/deployment/ENTERPRISE_DEPLOYMENT_GUIDE.md index 4cad22465..b328f5d11 100644 --- a/docs/operations/deployment/ENTERPRISE_DEPLOYMENT_GUIDE.md +++ b/docs/operations/deployment/ENTERPRISE_DEPLOYMENT_GUIDE.md @@ -174,7 +174,7 @@ npm install }, "framework": { "name": "strray", - "version": "1.14.1", + "version": "1.14.10", "performance_mode": "optimized", "monitoring_enabled": true, "facade_pattern": true @@ -418,7 +418,7 @@ data: { "framework": { "name": "strray", - "version": "1.14.1", + "version": "1.14.10", "performance_mode": "optimized", "monitoring_enabled": true, "facade_pattern": true diff --git a/docs/operations/migration/FRAMEWORK_MIGRATION.md b/docs/operations/migration/FRAMEWORK_MIGRATION.md index bcc6cbffa..614130859 100644 --- a/docs/operations/migration/FRAMEWORK_MIGRATION.md +++ b/docs/operations/migration/FRAMEWORK_MIGRATION.md @@ -107,7 +107,7 @@ MCP Client (312 lines) ```json { "strray_framework": { - "version": "1.14.1", + "version": "1.14.10", "enabled_agents": ["enforcer", "architect"], "agent_capabilities": { "enforcer": ["compliance-monitoring"] diff --git a/docs/reflections/SCRIPTS-TESTING-FIXING-COMPLETE-2026-03-13.md b/docs/reflections/SCRIPTS-TESTING-FIXING-COMPLETE-2026-03-13.md index b68a61652..e13b5e6bc 100644 --- a/docs/reflections/SCRIPTS-TESTING-FIXING-COMPLETE-2026-03-13.md +++ b/docs/reflections/SCRIPTS-TESTING-FIXING-COMPLETE-2026-03-13.md @@ -54,7 +54,7 @@ Three bug triage specialists tested and fixed all scripts in the StringRay frame **Verified Working:** - `scripts/triage/dependency-failure-triage.mjs` - All 5 test scenarios PASS - `scripts/integrations/install-claude-seo.js` - Working -- `scripts/integrations/install-antigravity-skills.js.mjs` - 14/30 skills installed +- `scripts/integrations/install-antigravity-skills.js.mjs` - 14/260 skills installed **Status:** All integration scripts working βœ… diff --git a/docs/reflections/antigravity-integration-journey-reflection-2026-02-26.md b/docs/reflections/antigravity-integration-journey-reflection-2026-02-26.md index bc6beb188..a98adb782 100644 --- a/docs/reflections/antigravity-integration-journey-reflection-2026-02-26.md +++ b/docs/reflections/antigravity-integration-journey-reflection-2026-02-26.md @@ -87,7 +87,7 @@ Four new MCP servers joined the fleet: ### Curating Excellence -Rather than blindly importing 30 skills, we curated 17 high-value additions: +Rather than blindly importing 260 skills, we curated 17 high-value additions: | Category | Skills | |----------|--------| diff --git a/docs/reflections/automated-version-compliance-system.md b/docs/reflections/automated-version-compliance-system.md index 61ebee83e..f671f68cd 100644 --- a/docs/reflections/automated-version-compliance-system.md +++ b/docs/reflections/automated-version-compliance-system.md @@ -191,7 +191,7 @@ npm view strray-ai@latest version # β†’ 1.3.2 # Edit version manager code scripts/node/universal-version-manager.js -# β†’ Set version: "1.14.1" +# β†’ Set version: "1.14.10" # Run sync npm run version:sync diff --git a/docs/reflections/deep-reflection.md b/docs/reflections/deep-reflection.md index 598c5408c..8a88e5f5d 100644 --- a/docs/reflections/deep-reflection.md +++ b/docs/reflections/deep-reflection.md @@ -76,7 +76,7 @@ Transform StringRay into an **enterprise-grade AI orchestration platform** that: - **Automatic System Prompts**: Framework capabilities injected into every agent session - **CLI Capabilities Command**: `npx strray-ai capabilities` for manual discovery - **MCP Help Server**: Programmatic access to all framework documentation -- **Comprehensive Documentation**: 30 skills, 26 agents, all tools documented +- **Comprehensive Documentation**: 260 skills, 26 agents, all tools documented **User Experience Transformation**: - **Before**: "What can this framework do?" β†’ Silence diff --git a/docs/reflections/deep/IMPLEMENTATION_JOURNEY_2026_03_25.md b/docs/reflections/deep/IMPLEMENTATION_JOURNEY_2026_03_25.md index 0b8373442..c9bbe572f 100644 --- a/docs/reflections/deep/IMPLEMENTATION_JOURNEY_2026_03_25.md +++ b/docs/reflections/deep/IMPLEMENTATION_JOURNEY_2026_03_25.md @@ -10,7 +10,7 @@ This reflection documents one of the most technically challenging and architecturally significant implementations in the StringRay framework's history: the Skills Routing Architecture. What began as a seemingly straightforward request to inventory available skills evolved into a five-phase initiative that transformed how the framework discovers, matches, routes, and executes skills. -We discovered 30 skills in `.opencode/skills/` that had existed largely dormantβ€”29 of which had associated MCP configurations but no unified mechanism to leverage them. The implementation built a complete skills ecosystem: SkillRegistry for discovery and caching, SkillDiscoveryService for filesystem scanning, SkillMatcher for capability-based routing, SkillResolver for agent-skill bindings, SkillPipeline for execution orchestration, and SkillWatcher for hot reload. +We discovered 260 skills in `.opencode/skills/` that had existed largely dormantβ€”29 of which had associated MCP configurations but no unified mechanism to leverage them. The implementation built a complete skills ecosystem: SkillRegistry for discovery and caching, SkillDiscoveryService for filesystem scanning, SkillMatcher for capability-based routing, SkillResolver for agent-skill bindings, SkillPipeline for execution orchestration, and SkillWatcher for hot reload. But the journey was far from linear. We encountered a critical context preservation bug that caused the original user message to be lost between the `chat.message` hook and the `tool.execute.before` hook. We discovered that OpenCode's sandboxing created visibility issues between Node.js execution and shell commands. We wrestled with TypeScript's `exactOptionalPropertyTypes` flag that required explicit `undefined` typing throughout the codebase. We built a custom YAML parser from scratch because standard libraries couldn't track indentation levels properly for nested agent configurations. @@ -99,7 +99,7 @@ Here's the full list we discovered: - **Health**: model-health-check - **Enforcement**: enforcer -Of these 30 skills, 29 had MCP server configurations defined in their SKILL.md frontmatter. They had all the infrastructure needed to be invokedβ€”they just needed a system to discover and route to them. +Of these 260 skills, 29 had MCP server configurations defined in their SKILL.md frontmatter. They had all the infrastructure needed to be invokedβ€”they just needed a system to discover and route to them. This was the spark for Phase 1: Skill Registry Foundation. @@ -118,7 +118,7 @@ We also discovered the first major technical challenge: the YAML parser needed t ### Session 4-5: Phase 2 - Making It Smart -With 30 skills in hand, we faced a new problem: how do we match a task to the right skill? +With 260 skills in hand, we faced a new problem: how do we match a task to the right skill? Simple keyword matching would work for obvious cases. If a task mentioned "security", route to the security-audit skill. But what about more nuanced requests? What about tasks that mentioned "vulnerability" instead of "security"? What about tasks that implied a skill need without stating it explicitly? diff --git a/docs/reflections/deep/agent-utilization-framework-organization-journey-2026-03-10.md b/docs/reflections/deep/agent-utilization-framework-organization-journey-2026-03-10.md index 486fc33fe..7977c9eff 100644 --- a/docs/reflections/deep/agent-utilization-framework-organization-journey-2026-03-10.md +++ b/docs/reflections/deep/agent-utilization-framework-organization-journey-2026-03-10.md @@ -23,7 +23,7 @@ This deep reflection documents a pivotal day in StringRay's evolution where we a - Default routing falls back to @enforcer when no keywords match - Complexity thresholds were too conservative: simple=20, moderate=35, complex=75 - Enforcer was getting routing recommendations but NOT acting on them - logging but not delegating -- 30 skills were missing from skill invocation enum (testing-lead, backend-engineer, etc.) +- 260 skills were missing from skill invocation enum (testing-lead, backend-engineer, etc.) **What I Tried:** - Reviewed task-skill-router.ts keyword mappings - found 30+ keywords for some agents but not enough diff --git a/docs/reflections/deep/skills-integration-paradox-2026-03-24.md b/docs/reflections/deep/skills-integration-paradox-2026-03-24.md index 3acc818e7..7c9eadb59 100644 --- a/docs/reflections/deep/skills-integration-paradox-2026-03-24.md +++ b/docs/reflections/deep/skills-integration-paradox-2026-03-24.md @@ -26,7 +26,7 @@ This reflection documents the StringRay v1.15.0 evolution journey - a seemingly - The `antigravity-bridge` skill returned a list of skills but couldn't actually invoke them - OpenCode's `skill()` tool existed but wasn't called after routing -**Time/Resources:** 6+ hours of testing, 3 agents collaborating, 2 bug fixes, 2 research documents written. +**Time/Resources:** 6+ hours of testing, 26 agents collaborating, 2 bug fixes, 2 research documents written. **INNER DIALOGUE:** - "I added the skills, they're in the right place, this should work..." @@ -107,7 +107,7 @@ I would have "shipped v1.15.0 with skills integration" but the real cost would h ### Phase 1: Feature Implementation (March 23-24, 2026) **What I Did:** Added Impeccable, OpenViking, Antigravity-bridge skills with proper Apache 2.0 licensing. Created SKILL.md files, added to install script, updated AGENTS.md. -**What Happened:** All files in place. Skills detected as "30 skills" by version manager. Antigravity status showed skills correctly. +**What Happened:** All files in place. Skills detected as "260 skills" by version manager. Antigravity status showed skills correctly. **Emotional State:** Satisfied - feature complete, tests passing. diff --git a/docs/reflections/deep/skills-routing-architecture-implementation-journey-2026-03-25.md b/docs/reflections/deep/skills-routing-architecture-implementation-journey-2026-03-25.md index 8293ac63e..38c8eb97d 100644 --- a/docs/reflections/deep/skills-routing-architecture-implementation-journey-2026-03-25.md +++ b/docs/reflections/deep/skills-routing-architecture-implementation-journey-2026-03-25.md @@ -8,7 +8,7 @@ ## Executive Summary -This reflection documents the implementation of a comprehensive 5-phase skills routing architecture that transformed StringRay from a framework with static agent definitions into a dynamic, routing-driven system capable of intelligently matching tasks to the right skills. The journey spanned Phase 1 (Skill Registry Foundation), Phase 2 (Routing Enhancement), Phase 3 (Agent Config Integration), Phase 4 (Processor Pipeline), and Phase 5 (Hot Reload). We discovered 30 skills from `.opencode/skills/`, built a multi-layered system with registry, matcher, resolver, pipeline, and watcher components, and integrated it all into the boot orchestrator and plugin system. +This reflection documents the implementation of a comprehensive 5-phase skills routing architecture that transformed StringRay from a framework with static agent definitions into a dynamic, routing-driven system capable of intelligently matching tasks to the right skills. The journey spanned Phase 1 (Skill Registry Foundation), Phase 2 (Routing Enhancement), Phase 3 (Agent Config Integration), Phase 4 (Processor Pipeline), and Phase 5 (Hot Reload). We discovered 260 skills from `.opencode/skills/`, built a multi-layered system with registry, matcher, resolver, pipeline, and watcher components, and integrated it all into the boot orchestrator and plugin system. The technical challenges we faced were significant: YAML parsing for nested objects required building a custom parser with proper indentation handling, TypeScript's `exactOptionalPropertyTypes` forced explicit `undefined` types throughout the codebase, OpenCode's sandboxing created visibility issues between Node.js and shell contexts, and circular dependencies between registry and matcher components required careful architectural separation. @@ -70,7 +70,7 @@ The boot orchestrator integration was tricky. We had to add skill discovery to t ### Phase 2: Making It Smart - The Routing Enhancement -With 30 skills in hand, we faced a new problem: how do we match a task to the right skill? +With 260 skills in hand, we faced a new problem: how do we match a task to the right skill? Simple keyword matching would work for obvious cases. If a task mentioned "security", route to the security-audit skill. But what about more nuanced requests? What about tasks that mentioned "vulnerability" instead of "security"? What about tasks that implied a skill need without stating it explicitly? diff --git a/docs/reflections/deep/skills-routing-architecture-research-2026-03-24.md b/docs/reflections/deep/skills-routing-architecture-research-2026-03-24.md index 9761e20d5..4ed8e4924 100644 --- a/docs/reflections/deep/skills-routing-architecture-research-2026-03-24.md +++ b/docs/reflections/deep/skills-routing-architecture-research-2026-03-24.md @@ -235,7 +235,7 @@ class StrRayServer { constructor() { this.server = new Server( - { name: "", version: "1.14.1" }, + { name: "", version: "1.14.10" }, { capabilities: { tools: {} } } ); this.setupToolHandlers(); @@ -382,7 +382,7 @@ npx strray-ai status ### Skills - Location: `.opencode/skills/*/SKILL.md` -- Count: 30 skills +- Count: 260 skills ### Agents - Location: `.opencode/agents/*.yml` diff --git a/docs/reflections/deep/skills-routing-architecture-strategy-2026-03-24.md b/docs/reflections/deep/skills-routing-architecture-strategy-2026-03-24.md index a62719f06..58844dec1 100644 --- a/docs/reflections/deep/skills-routing-architecture-strategy-2026-03-24.md +++ b/docs/reflections/deep/skills-routing-architecture-strategy-2026-03-24.md @@ -214,7 +214,7 @@ mcp: { "$schema": "./schemas/skill-manifest.schema.json", "name": "code-review", - "version": "1.2.0", + "version": "1.14.10", "schema_version": "2.0", "description": "Comprehensive code review and quality analysis", @@ -444,7 +444,7 @@ class SkillNameServer { constructor() { this.server = new Server( - { name: "skill-name", version: "1.0.0" }, + { name: "skill-name", version: "1.14.10" }, { capabilities: { tools: {} } } ); this.setupToolHandlers(); @@ -573,15 +573,15 @@ const VERSION_RULES = { ```yaml # In SKILL.md for skills with migrations migrations: - - from_version: "1.0.0" - to_version: "2.0.0" + - from_version: "1.14.10" + to_version: "1.14.10" breaking_changes: - "Removed 'analyze_code' tool, use 'analyze_code_quality'" - "Changed input schema for 'scan_security'" automated_migration: true - - from_version: "2.0.0" - to_version: "2.1.0" + - from_version: "1.14.10" + to_version: "1.14.10" breaking_changes: [] notes: "Added new 'generate_report' tool" ``` @@ -681,7 +681,7 @@ migrations: β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ SkillPipelineStage β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ skill: "code-review" β”‚ β”‚ -β”‚ β”‚ β”œβ”€β”€ version: "1.2.0" β”‚ β”‚ +β”‚ β”‚ β”œβ”€β”€ version: "1.14.10" β”‚ β”‚ β”‚ β”‚ β”œβ”€β”€ tool: "analyze_code_quality" β”‚ β”‚ β”‚ β”‚ └── timeout: 30000ms β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ diff --git a/docs/reflections/deep/stringray-evolution-saga-2026-03-25.md b/docs/reflections/deep/stringray-evolution-saga-2026-03-25.md index 0dc713a41..64efd04d0 100644 --- a/docs/reflections/deep/stringray-evolution-saga-2026-03-25.md +++ b/docs/reflections/deep/stringray-evolution-saga-2026-03-25.md @@ -182,7 +182,7 @@ The registry was the heart of it. A `Map` that could be i The discovery service scans two directories: `.opencode/skills/` and `.opencode/integrations/`. For each subdirectory that contains a `SKILL.md` file, it parses the YAML frontmatter and creates a `SkillManifest` object. The manifest captures everything: name, version, description, capabilities, dependencies, MCP configuration, agent bindings, pipeline config. -When we first ran the discovery, it found 30 skills. Twenty-nine of them had MCP configurations. Zero of them were being used at runtime. Thirty skills, sitting there, fully documented, completely dormant. +When we first ran the discovery, it found 260 skills. Twenty-nine of them had MCP configurations. Zero of them were being used at runtime. Thirty skills, sitting there, fully documented, completely dormant. The boot orchestrator integration was the key moment. By adding `initializeSkillDiscovery()` as Phase 1.5 of the boot sequence - right after delegation system initialization and before session management - we ensured that every time StringRay starts, it discovers all available skills and makes them available through the state manager. @@ -600,7 +600,7 @@ I want to acknowledge something that doesn't show up in commit messages or code There were moments of genuine frustration. The YAML parser that kept producing `{_items: [...]}` instead of arrays. The context files that existed in Node.js but not in the shell. The test suite that needed three iterations before it could tell us anything useful. Each of these was a small obstacle that consumed a session's worth of attention. -But there were also moments of genuine satisfaction. When the matcher first matched "review this code" to code-review with 100% confidence. When `npx strray-ai skill:list` first showed all 30 skills with their capabilities. When the agent:skills command showed the bindings working. These were small victories, but they felt like proof that the architecture was sound. +But there were also moments of genuine satisfaction. When the matcher first matched "review this code" to code-review with 100% confidence. When `npx strray-ai skill:list` first showed all 260 skills with their capabilities. When the agent:skills command showed the bindings working. These were small victories, but they felt like proof that the architecture was sound. The deep reflections we wrote alongside the code are unusual. Most open-source projects don't document their development journey in narrative form. They have changelogs, architecture decision records, and API documentation. They don't have "sagas." But we wrote them because the journey matters, not just the destination. The YAML parser isn't just a parser - it's a story about why simple things aren't simple. The context preservation fix isn't just a bug fix - it's a story about assumptions and sandboxing. Documenting these stories means that the next developer (or our future selves) can learn from them without repeating the investigation. diff --git a/docs/reflections/deep/the-hook-that-wouldnt-fire-v1.13.2.md b/docs/reflections/deep/the-hook-that-wouldnt-fire-v1.13.2.md index 25a1c524c..a1e9d468f 100644 --- a/docs/reflections/deep/the-hook-that-wouldnt-fire-v1.13.2.md +++ b/docs/reflections/deep/the-hook-that-wouldnt-fire-v1.13.2.md @@ -20,7 +20,7 @@ The first sign of trouble was subtle. Activity reports showed activity, but the ``` βœ… 26 agents configured -βœ… 30 skills available +βœ… 260 skills available βœ… Codex enforcement active ``` diff --git a/docs/reflections/deployment-crisis-v12x-reflection.md b/docs/reflections/deployment-crisis-v12x-reflection.md index 95a6bf718..08e8819b1 100644 --- a/docs/reflections/deployment-crisis-v12x-reflection.md +++ b/docs/reflections/deployment-crisis-v12x-reflection.md @@ -168,7 +168,7 @@ config.disabled_agents.some(agent => agent.toLowerCase() === "sisyphus") ```typescript // src/cli/index.ts -.version("1.14.1"); +.version("1.14.10"); // scripts/node/universal-version-manager.js const UPDATE_PATTERNS = [ diff --git a/docs/reflections/legacy/deep-journey-reflection.md b/docs/reflections/legacy/deep-journey-reflection.md index 26cbcfdff..e68a5196e 100644 --- a/docs/reflections/legacy/deep-journey-reflection.md +++ b/docs/reflections/legacy/deep-journey-reflection.md @@ -14,7 +14,7 @@ #### 4. **Enterprise Scalability** - **Achievement**: Multi-agent orchestration with automatic coordination -- **Features**: 26 agents, 30 skills, lazy-loading architecture +- **Features**: 26 agents, 260 skills, lazy-loading architecture - **Impact**: Handles complex enterprise workflows efficiently ### ⚠️ Mixed Outcomes diff --git a/docs/reflections/librarian-bug-fix-and-framework-analysis-reflection.md b/docs/reflections/librarian-bug-fix-and-framework-analysis-reflection.md index a0ec44f61..e17bd6653 100644 --- a/docs/reflections/librarian-bug-fix-and-framework-analysis-reflection.md +++ b/docs/reflections/librarian-bug-fix-and-framework-analysis-reflection.md @@ -51,7 +51,7 @@ The investigation uncovered extensive framework operations: - **No Spawn Limits**: System lacked any governance over agent instantiation **Contributing Factors:** -- **Complex Multi-Agent Architecture**: 26 agents, 30 skills, 56+ possible agent pairings without controls +- **Complex Multi-Agent Architecture**: 26 agents, 260 skills, 56+ possible agent pairings without controls - **Event-Driven Recursion**: Consultation system triggered by its own operations - **Insufficient Testing**: Bug existed despite comprehensive test suite (1044/1114 tests passing) - **Documentation Automation**: Universal researcher involvement in ALL major actions created feedback loops diff --git a/docs/reflections/mcp-initialize-protocol-deep-dive.md b/docs/reflections/mcp-initialize-protocol-deep-dive.md index 163d49d68..205c51576 100644 --- a/docs/reflections/mcp-initialize-protocol-deep-dive.md +++ b/docs/reflections/mcp-initialize-protocol-deep-dive.md @@ -219,7 +219,7 @@ const initializeRequest = { params: { protocolVersion: "2024-11-05", capabilities: {}, - clientInfo: { name: "strray-mcp-client", version: "1.14.1" }, + clientInfo: { name: "strray-mcp-client", version: "1.14.10" }, }, }; diff --git a/docs/reflections/mcp-initialize-protocol-fix.md b/docs/reflections/mcp-initialize-protocol-fix.md index 353e457e1..8368852a1 100644 --- a/docs/reflections/mcp-initialize-protocol-fix.md +++ b/docs/reflections/mcp-initialize-protocol-fix.md @@ -69,7 +69,7 @@ const initializeRequest = { params: { protocolVersion: "2024-11-05", capabilities: {}, - clientInfo: { name: "strray-mcp-client", version: "1.14.1" }, + clientInfo: { name: "strray-mcp-client", version: "1.14.10" }, }, }; diff --git a/docs/reflections/personal-reflection-tui-fix-2026-02-26.md b/docs/reflections/personal-reflection-tui-fix-2026-02-26.md index 74f1531df..ca2f56b24 100644 --- a/docs/reflections/personal-reflection-tui-fix-2026-02-26.md +++ b/docs/reflections/personal-reflection-tui-fix-2026-02-26.md @@ -55,7 +55,7 @@ It's just... files. Scattered. Waiting to drift. Looking back at the commits, I realize this wasn't one fix. This was a 5-version odyssey - your vision unfolding in layers: -**v1.6.7** - "Let's integrate Antigravity!" (30 skills, MIT licensed, amazing!) +**v1.6.7** - "Let's integrate Antigravity!" (260 skills, MIT licensed, amazing!) **v1.6.8** - "Wait, only 15 MCP servers are registered, not 38?" **v1.6.9** - "We need to add the missing MCP aliases" **v1.6.10** - "Some agents aren't in setup.cjs. Let me add them." diff --git a/docs/reflections/the-wisdom-of-constraints-2026-02-27.md b/docs/reflections/the-wisdom-of-constraints-2026-02-27.md index bc8a06c86..5f4737895 100644 --- a/docs/reflections/the-wisdom-of-constraints-2026-02-27.md +++ b/docs/reflections/the-wisdom-of-constraints-2026-02-27.md @@ -105,7 +105,7 @@ I was ready to be the hero who saved the project from a critical bug. **What Happened:** - Framework loads perfectly -- 26 agents, 15 MCPs, 30 skills +- 26 agents, 15 MCPs, 260 skills - Enforcer analyzes code - 43 terms validated - 100% compliance diff --git a/docs/research/openclaw/README.md b/docs/research/openclaw/README.md index fd92f8cb7..21ed55d88 100644 --- a/docs/research/openclaw/README.md +++ b/docs/research/openclaw/README.md @@ -220,7 +220,7 @@ Health check endpoint. ```json { "status": "healthy", - "version": "1.14.1", + "version": "1.14.10", "uptime": 3600000, "openclaw": { "connected": true, diff --git a/docs/research/openclaw/researcher-summary.md b/docs/research/openclaw/researcher-summary.md index d79a642a3..2b1bf0937 100644 --- a/docs/research/openclaw/researcher-summary.md +++ b/docs/research/openclaw/researcher-summary.md @@ -80,7 +80,7 @@ The client connects to OpenClaw Gateway using Protocol v3: "maxProtocol": 3, "client": { "id": "strray-integration", - "version": "1.14.1", + "version": "1.14.10", "platform": "node", "mode": "operator" }, diff --git a/docs/tools/README-universal-version-manager.md b/docs/tools/README-universal-version-manager.md index 4ce5e9316..0688f0064 100644 --- a/docs/tools/README-universal-version-manager.md +++ b/docs/tools/README-universal-version-manager.md @@ -17,7 +17,7 @@ The Universal Version Manager (`scripts/universal-version-manager.js`) maintains ```javascript const OFFICIAL_VERSIONS = { framework: { - version: "1.14.1", + version: "1.14.10", displayName: "StringRay AI v1.3.4", lastUpdated: "2026-01-15", }, diff --git a/docs/user-guide/getting-started/full-setup.md b/docs/user-guide/getting-started/full-setup.md index 50a454488..e7b0f4d59 100644 --- a/docs/user-guide/getting-started/full-setup.md +++ b/docs/user-guide/getting-started/full-setup.md @@ -80,7 +80,7 @@ StrRay uses **static model assignment** - each agent is assigned a specific mode }, "framework": { "name": "strray", - "version": "1.14.1", + "version": "1.14.10", "codex_terms": [ "1", "2", diff --git a/docs/user-guide/installation/INSTALLATION.md b/docs/user-guide/installation/INSTALLATION.md index 302fc3fc9..6741d0c6d 100644 --- a/docs/user-guide/installation/INSTALLATION.md +++ b/docs/user-guide/installation/INSTALLATION.md @@ -120,7 +120,7 @@ Create `.opencode/strray/config.json` in your project root: ```json { "framework": { - "version": "1.14.1", + "version": "1.14.10", "codex": "v1.3.0" }, "agents": { diff --git a/docs/user-guide/installation/full-setup.md b/docs/user-guide/installation/full-setup.md index 50a454488..e7b0f4d59 100644 --- a/docs/user-guide/installation/full-setup.md +++ b/docs/user-guide/installation/full-setup.md @@ -80,7 +80,7 @@ StrRay uses **static model assignment** - each agent is assigned a specific mode }, "framework": { "name": "strray", - "version": "1.14.1", + "version": "1.14.10", "codex_terms": [ "1", "2", diff --git a/docs/user-guide/troubleshooting.md b/docs/user-guide/troubleshooting.md index 1a636753e..4ed4185f9 100644 --- a/docs/user-guide/troubleshooting.md +++ b/docs/user-guide/troubleshooting.md @@ -239,7 +239,7 @@ tail -50 logs/framework/activity.log "enforcer": "openrouter/xai-grok-2-1212-fast-1" }, "framework": { - "version": "1.14.1" + "version": "1.14.10" } } ``` diff --git a/enforcer-config.json b/enforcer-config.json index c0c609559..7d9ace3d4 100644 --- a/enforcer-config.json +++ b/enforcer-config.json @@ -1,6 +1,6 @@ { "framework": "StringRay 1.0.0", - "version": "1.14.1", + "version": "1.14.10", "description": "Codex-compliant framework configuration for Credible UI project", "thresholds": { "bundleSize": { @@ -220,7 +220,7 @@ } }, "codex": { - "version": "1.14.1", + "version": "1.14.10", "terms": [ 1, 2, diff --git a/kernel/inference/PATTERNS.md b/kernel/inference/PATTERNS.md index 8d6cc4d1d..d91bc7777 100644 --- a/kernel/inference/PATTERNS.md +++ b/kernel/inference/PATTERNS.md @@ -279,7 +279,7 @@ Direct testing worked because it included initialize params: { protocolVersion: "2024-11-05", capabilities: {}, - clientInfo: { name: "strray-mcp-client", version: "1.14.1" } + clientInfo: { name: "strray-mcp-client", version: "1.14.10" } } } diff --git a/kernel/package.json b/kernel/package.json index dc4433084..f723c8da8 100644 --- a/kernel/package.json +++ b/kernel/package.json @@ -1,6 +1,6 @@ { "name": "@stringray/kernel", - "version": "1.14.1", + "version": "1.14.10", "description": "StringRay Inference Kernel - The invisible core", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/package.json b/package.json index be0b10ded..81ce7b3c0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "strray-ai", - "version": "1.14.9", + "version": "1.15.1", "description": "⚑ StringRay ⚑: Bulletproof AI orchestration with systematic error prevention. Zero dead ends. Ship clean, tested, optimized code β€” every time.", "license": "MIT", "repository": { diff --git a/scripts/SCRIPTS_INVENTORY.md b/scripts/SCRIPTS_INVENTORY.md index fb1a3a2e2..2223bd0e1 100644 --- a/scripts/SCRIPTS_INVENTORY.md +++ b/scripts/SCRIPTS_INVENTORY.md @@ -98,7 +98,7 @@ This document provides a complete inventory of all scripts in the `scripts/` dir | `test-mcp-registration.mjs` | ⚠️ Partial | MCP registration tests | 4/6 tests pass (timeout property issue) | | `test-skill-routing.mjs` | ⚠️ Partial | Skill routing tests | 8/26 tests pass (routing mismatch - design decision) | | `test-skills-coverage.mjs` | βœ… Working | Skills coverage tests | 85/85 tests passed | -| `test-skills-comprehensive.mjs` | βœ… Working | Comprehensive skills tests | 5/30 skills validated | +| `test-skills-comprehensive.mjs` | βœ… Working | Comprehensive skills tests | 5/260 skills validated | | `test-skills-mcp-integration.mjs` | βœ… Working | Skills-MCP integration | Plugin loading confirmed | | `test-consumer-readiness.mjs` | βœ… Working | Consumer readiness | 4/4 checks passed | | `test-consumer-validation.mjs` | ⚠️ Partial | Consumer validation | 10/23 tests pass (expected - dev environment) | diff --git a/scripts/bash/test-deployment.sh b/scripts/bash/test-deployment.sh index 5207ff770..cee8ca5ea 100755 --- a/scripts/bash/test-deployment.sh +++ b/scripts/bash/test-deployment.sh @@ -91,7 +91,7 @@ cd "$TEST_DIR" cat > package.json << 'EOF' { "name": "strray-test", - "version": "1.14.1" + "version": "1.14.10" } EOF @@ -150,7 +150,7 @@ cd test-config cat > package.json << 'EOF' { "name": "test-config", - "version": "1.14.1" + "version": "1.14.10" } EOF @@ -184,7 +184,7 @@ cd test-registration cat > package.json << 'EOF' { "name": "test-registration", - "version": "1.14.1" + "version": "1.14.10" } EOF @@ -253,7 +253,7 @@ cd test-agents cat > package.json << 'EOF' { "name": "test-agents", - "version": "1.14.1" + "version": "1.14.10" } EOF diff --git a/scripts/node/postinstall.cjs b/scripts/node/postinstall.cjs index 0c8f12a0e..3a7101716 100755 --- a/scripts/node/postinstall.cjs +++ b/scripts/node/postinstall.cjs @@ -413,7 +413,35 @@ if (fs.existsSync(distSource)) { } } +// Install hermes-agent skill to ~/.hermes/skills/ if Hermes is present +const hermesSkillSource = path.join(packageRoot, 'src', 'skills', 'hermes-agent', 'SKILL.md'); + +if (fs.existsSync(hermesSkillSource)) { + try { + const homeDir = process.env.HOME || process.env.USERPROFILE || require('os').homedir(); + const targetHermesSkills = path.join(homeDir, '.hermes', 'skills', 'hermes-agent'); + + if (fs.existsSync(path.join(homeDir, '.hermes'))) { + if (!fs.existsSync(targetHermesSkills)) { + fs.mkdirSync(targetHermesSkills, { recursive: true }); + } + const destSkill = path.join(targetHermesSkills, 'SKILL.md'); + const shouldCopySkill = !fs.existsSync(destSkill) || + fs.statSync(hermesSkillSource).mtime > fs.statSync(destSkill).mtime; + if (shouldCopySkill) { + fs.copyFileSync(hermesSkillSource, destSkill); + console.log("βœ… Installed hermes-agent skill β†’ ~/.hermes/skills/hermes-agent/"); + } else { + console.log("ℹ️ hermes-agent skill already up to date"); + } + } + } catch (error) { + console.warn("⚠️ Could not install Hermes skill:", error.message); + } +} + console.log("πŸ“‹ Next steps:"); console.log("1. Restart OpenCode to load the plugin"); console.log("2. Run 'opencode agent list' to see StrRay agents"); -console.log("3. Try '@enforcer analyze this code' to test the plugin"); \ No newline at end of file +console.log("3. Try '@enforcer analyze this code' to test the plugin"); +console.log("4. Hermes Agent users: restart Hermes to load MCP tools and hermes-agent skill"); \ No newline at end of file diff --git a/src/__tests__/integration/codex-enforcement.test.ts b/src/__tests__/integration/codex-enforcement.test.ts index fb64744c5..02742da5d 100644 --- a/src/__tests__/integration/codex-enforcement.test.ts +++ b/src/__tests__/integration/codex-enforcement.test.ts @@ -99,7 +99,7 @@ describe("Codex Enforcement Integration", () => { loadCodexContext: vi.fn().mockResolvedValue({ success: true, context: { - version: "1.14.1", + version: "1.14.10", terms: new Map(), interweaves: [], lenses: [], @@ -144,7 +144,7 @@ describe("Codex Enforcement Integration", () => { loadCodexContext: vi.fn().mockResolvedValue({ success: true, context: { - version: "1.14.1", + version: "1.14.10", terms: new Map(), interweaves: [], lenses: [], @@ -198,7 +198,7 @@ describe("Codex Enforcement Integration", () => { loadCodexContext: vi.fn().mockResolvedValue({ success: true, context: { - version: "1.14.1", + version: "1.14.10", terms: new Map(), interweaves: [], lenses: [], diff --git a/src/__tests__/integration/framework-init.test.ts b/src/__tests__/integration/framework-init.test.ts index e421ac08d..208a7bb6f 100644 --- a/src/__tests__/integration/framework-init.test.ts +++ b/src/__tests__/integration/framework-init.test.ts @@ -239,7 +239,7 @@ describe("StringRay Framework Initialization Integration", () => { expect(checkDir(".opencode/skills")).toBe(true); const skillDirs = fs.readdirSync(".opencode/skills"); - // At least 30 skills should be registered (based on current implementation) + // At least 260 skills should be registered (based on current implementation) expect(skillDirs.length).toBeGreaterThanOrEqual(15); }); }); diff --git a/src/__tests__/integration/server.test.ts b/src/__tests__/integration/server.test.ts index 544200792..205dde504 100644 --- a/src/__tests__/integration/server.test.ts +++ b/src/__tests__/integration/server.test.ts @@ -59,7 +59,7 @@ const createTestServer = () => { app.get("/api/status", (req, res) => { res.json({ framework: "StringRay", - version: "1.14.1", + version: "1.14.10", status: "active", agents: 8, timestamp: new Date().toISOString(), diff --git a/src/__tests__/performance/enterprise-performance-tests.ts b/src/__tests__/performance/enterprise-performance-tests.ts index 4cbdb87bf..48ee97a5d 100644 --- a/src/__tests__/performance/enterprise-performance-tests.ts +++ b/src/__tests__/performance/enterprise-performance-tests.ts @@ -148,7 +148,7 @@ describe("ML Inference Performance Benchmarks", () => { // Setup mock ML model mockModel = { id: "test-inference-model", - name: "Test Inference Model", version: "1.14.1", + name: "Test Inference Model", version: "1.14.10", type: "classification", status: "deployed", createdAt: new Date(), diff --git a/src/__tests__/unit/boot-orchestrator.test.ts b/src/__tests__/unit/boot-orchestrator.test.ts index 079507e5e..4197b21c1 100644 --- a/src/__tests__/unit/boot-orchestrator.test.ts +++ b/src/__tests__/unit/boot-orchestrator.test.ts @@ -25,7 +25,7 @@ describe("BootOrchestrator", () => { // Mock dependencies mockContextLoader = { loadCodexContext: vi.fn().mockResolvedValue({ - version: "1.14.1", + version: "1.14.10", terms: [], validationCriteria: {}, }), diff --git a/src/__tests__/unit/codex-injector.test.ts b/src/__tests__/unit/codex-injector.test.ts index 2730c3519..353d68981 100644 --- a/src/__tests__/unit/codex-injector.test.ts +++ b/src/__tests__/unit/codex-injector.test.ts @@ -62,7 +62,7 @@ const getMockCodexStats = (sessionId: string) => { loaded: true, fileCount: 1, totalTerms: 3, - version: "1.14.1", + version: "1.14.10", }; }; @@ -256,7 +256,7 @@ describe("StringRay Codex Injector (Mock-Based)", () => { loaded: true, fileCount: 1, totalTerms: 3, - version: "1.14.1", + version: "1.14.10", }); }); diff --git a/src/__tests__/unit/integration.test.ts b/src/__tests__/unit/integration.test.ts index 2e5338d26..c8ad57b6c 100644 --- a/src/__tests__/unit/integration.test.ts +++ b/src/__tests__/unit/integration.test.ts @@ -20,7 +20,7 @@ vi.mock("child_process", () => ({ })), })); -vi.mock("../mcps/agent-resolver.js", () => ({ +vi.mock("../../mcps/agent-resolver.js", () => ({ resolveAgent: vi.fn().mockResolvedValue({ name: "enforcer", system: "You are a code quality enforcer...", diff --git a/src/__tests__/utils/test-helpers.ts b/src/__tests__/utils/test-helpers.ts index 25e78974b..ea8ca15f3 100644 --- a/src/__tests__/utils/test-helpers.ts +++ b/src/__tests__/utils/test-helpers.ts @@ -260,7 +260,7 @@ export class MockCodexGenerator { */ static createMinimalCodex(): string { return JSON.stringify({ - version: "1.14.1", + version: "1.14.10", lastUpdated: "2026-01-06", errorPreventionTarget: 0.996, terms: { @@ -303,7 +303,7 @@ export class MockCodexGenerator { */ static createCodexWithViolations(): string { return JSON.stringify({ - version: "1.14.1", + version: "1.14.10", lastUpdated: "2026-01-06", errorPreventionTarget: 0.996, terms: { @@ -373,7 +373,7 @@ export class MockContextFactory { overrides: Partial = {}, ): CodexContext { const defaultContext: CodexContext = { - version: "1.14.1", + version: "1.14.10", lastUpdated: new Date().toISOString(), terms: new Map([ [ diff --git a/src/analytics/routing-refiner.ts b/src/analytics/routing-refiner.ts index e882dbb52..15c062d94 100644 --- a/src/analytics/routing-refiner.ts +++ b/src/analytics/routing-refiner.ts @@ -120,7 +120,7 @@ class RoutingRefiner { const warnings = this.generateWarnings(newMappings, optimizations); return { - version: "1.14.1", + version: "1.14.10", generatedAt: new Date(), summary: { newMappings: newMappings.length, diff --git a/src/core/boot-orchestrator.ts b/src/core/boot-orchestrator.ts index da92e9f73..1008b493d 100644 --- a/src/core/boot-orchestrator.ts +++ b/src/core/boot-orchestrator.ts @@ -979,7 +979,7 @@ export class BootOrchestrator { try { // Load StringRay configuration directly (no Python dependency) const stringRayConfig = { - version: "1.14.1", + version: "1.14.10", codex_enabled: true, codex_version: "v1.7.5", codex_terms: [ diff --git a/src/core/features-config.ts b/src/core/features-config.ts index fd0a9817a..57695ce73 100644 --- a/src/core/features-config.ts +++ b/src/core/features-config.ts @@ -487,7 +487,7 @@ export class FeaturesConfigLoader { */ private getDefaultConfig(): FeaturesConfig { return { - version: "1.14.1", + version: "1.14.10", description: "StringRay Framework - Unified Feature Configuration", token_optimization: { diff --git a/src/enforcement/loaders/__tests__/loaders.test.ts b/src/enforcement/loaders/__tests__/loaders.test.ts index 92f6e92ef..dd7368dab 100644 --- a/src/enforcement/loaders/__tests__/loaders.test.ts +++ b/src/enforcement/loaders/__tests__/loaders.test.ts @@ -145,7 +145,7 @@ describe("Rule Loaders", () => { it("should load codex rules from valid codex.json", async () => { const mockCodexData = { - version: "1.14.1", + version: "1.14.10", lastUpdated: "2024-01-01", errorPreventionTarget: 0.99, terms: { @@ -181,7 +181,7 @@ describe("Rule Loaders", () => { it("should skip invalid terms", async () => { const mockCodexData = { - version: "1.14.1", + version: "1.14.10", terms: { "1": { number: 1, diff --git a/src/integrations/core/strray-integration.ts b/src/integrations/core/strray-integration.ts index 16dee7bda..f450b5d95 100644 --- a/src/integrations/core/strray-integration.ts +++ b/src/integrations/core/strray-integration.ts @@ -697,7 +697,7 @@ export const createStringRayIntegration = ( // Export default integration for auto-detection export const strRayIntegration = new StringRayIntegration({ framework: StringRayIntegration.detectFramework(), - version: "1.14.1", + version: "1.14.10", features: { agents: true, codex: true, diff --git a/src/mcps/architect-tools.server.ts b/src/mcps/architect-tools.server.ts index 6593ad487..5c2241301 100644 --- a/src/mcps/architect-tools.server.ts +++ b/src/mcps/architect-tools.server.ts @@ -22,7 +22,7 @@ class StrRayArchitectToolsServer { constructor() { this.server = new Server( { - name: "architect-tools", version: "1.14.1", + name: "architect-tools", version: "1.14.10", }, { capabilities: { @@ -32,7 +32,7 @@ class StrRayArchitectToolsServer { ); this.setupToolHandlers(); - console.log("StrRay Architect Tools MCP Server initialized"); + frameworkLogger.log("mcps/architect-tools", "init", "info", { message: "StrRay Architect Tools MCP Server initialized" }); } private setupToolHandlers() { @@ -310,7 +310,14 @@ class StrRayArchitectToolsServer { fileTypes: this.groupByExtension(files), directoryDepth: this.calculateMaxDepth(directories), largestFiles: files - .map((f) => ({ path: f, size: fs.statSync(f).size })) + .map((f) => { + try { + return { path: f, size: fs.statSync(f).size }; + } catch { + return null; + } + }) + .filter((f): f is { path: string; size: number } => f !== null) .sort((a, b) => b.size - a.size) .slice(0, 5), }; @@ -381,8 +388,10 @@ class StrRayArchitectToolsServer { dependencyMap: dependencies, totalDependencies: Object.values(dependencies).flat().length, averageDependenciesPerFile: - Object.values(dependencies).flat().length / - Object.keys(dependencies).length, + Object.keys(dependencies).length > 0 + ? Object.values(dependencies).flat().length / + Object.keys(dependencies).length + : 0, }; } @@ -432,14 +441,23 @@ class StrRayArchitectToolsServer { private async calculateStructureMetrics(projectRoot: string): Promise { const files = await this.getProjectFiles(projectRoot); + const fileSizes = files + .map((f) => { + try { + return { path: f, size: fs.statSync(f).size }; + } catch { + return null; + } + }) + .filter((f): f is { path: string; size: number } => f !== null); + + const totalSize = fileSizes.reduce((sum, f) => sum + f.size, 0); + return { totalFiles: files.length, fileTypeDistribution: this.groupByExtension(files), - averageFileSize: - files.reduce((sum, f) => sum + fs.statSync(f).size, 0) / files.length, - largestFile: files - .map((f) => ({ path: f, size: fs.statSync(f).size })) - .sort((a, b) => b.size - a.size)[0], + averageFileSize: fileSizes.length > 0 ? totalSize / fileSizes.length : 0, + largestFile: fileSizes.sort((a, b) => b.size - a.size)[0], }; } @@ -627,7 +645,9 @@ class StrRayArchitectToolsServer { } private calculateMaxDepth(directories: string[]): number { - return Math.max(...directories.map((dir) => dir.split("/").length)); + return directories.length === 0 + ? 0 + : Math.max(...directories.map((dir) => dir.split("/").length)); } private extractImports(content: string): string[] { @@ -727,9 +747,6 @@ class StrRayArchitectToolsServer { frameworkLogger.log("mcps/architect-tools", "unhandledRejection", "error", { error: String(reason) }); cleanup("unhandledRejection"); }); - - process.on("SIGINT", cleanup); - process.on("SIGTERM", cleanup); } } diff --git a/src/mcps/auto-format.server.ts b/src/mcps/auto-format.server.ts index ccc977c52..9bfc86bf4 100644 --- a/src/mcps/auto-format.server.ts +++ b/src/mcps/auto-format.server.ts @@ -11,7 +11,7 @@ import { ListToolsRequestSchema, type CallToolRequest, } from "@modelcontextprotocol/sdk/types.js"; -import { execSync } from "child_process"; +import { execFileSync } from "child_process"; import fs from "fs"; import path from "path"; import { frameworkLogger } from "../core/framework-logger.js"; @@ -22,7 +22,7 @@ class StrRayAutoFormatServer { constructor() { this.server = new Server( { - name: "auto-format", version: "1.14.1", + name: "auto-format", version: "1.14.10", }, { capabilities: { @@ -95,13 +95,29 @@ class StrRayAutoFormatServer { async (request: CallToolRequest) => { const { name, arguments: args } = request.params; - switch (name) { - case "auto-format": - return await this.handleAutoFormat(args); - case "format-check": - return await this.handleFormatCheck(args); - default: - throw new Error(`Unknown tool: ${name}`); + try { + switch (name) { + case "auto-format": + return await this.handleAutoFormat(args); + case "format-check": + return await this.handleFormatCheck(args); + default: + throw new Error(`Unknown tool: ${name}`); + } + } catch (error) { + frameworkLogger.log("mcps/auto-format", "tool-call", "error", { + tool: name, + error: String(error), + }); + return { + content: [ + { + type: "text", + text: `Error executing tool '${name}': ${error instanceof Error ? error.message : String(error)}`, + }, + ], + isError: true, + }; } }, ); @@ -254,17 +270,17 @@ ${checkResults.details.map((d) => `β€’ ${d}`).join("\n")} files.length > 0 ? files : ["**/*.{js,jsx,ts,tsx,json,css,scss,md}"]; // Run prettier - const command = checkOnly - ? "npx prettier --check" - : "npx prettier --write"; - const fullCommand = `${command} ${patterns.join(" ")} --ignore-path .gitignore`; + const prettierArgs = checkOnly + ? ["prettier", "--check", ...patterns, "--ignore-path", ".gitignore"] + : ["prettier", "--write", ...patterns, "--ignore-path", ".gitignore"]; try { - const output = execSync(fullCommand, { + const output = execFileSync("npx", prettierArgs, { encoding: "utf8", cwd: process.cwd(), - stdio: checkOnly ? "pipe" : "inherit", - }); + stdio: "pipe", + timeout: 30000, + }) as string; if (checkOnly) { // Parse check output to see what needs formatting @@ -275,8 +291,11 @@ ${checkResults.details.map((d) => `β€’ ${d}`).join("\n")} (line) => !line.includes("error") && !line.includes("Error"), ); } else { - // For write mode, assume all patterns were processed - results.formatted = patterns; + // Parse write output to get actual file names + const lines = output + .split("\n") + .filter((line: string) => line.trim()); + results.formatted = lines; } } catch (error) { const errorOutput = @@ -323,10 +342,11 @@ ${checkResults.details.map((d) => `β€’ ${d}`).join("\n")} const scriptName = scripts["lint:fix"] ? "lint:fix" : "lint"; try { - execSync(`npm run ${scriptName}`, { + execFileSync("npm", ["run", scriptName], { encoding: "utf8", cwd: process.cwd(), stdio: "pipe", + timeout: 30000, }); results.formatted.push("ESLint auto-fix applied to applicable files"); @@ -369,10 +389,11 @@ ${checkResults.details.map((d) => `β€’ ${d}`).join("\n")} const scriptName = scripts.typecheck ? "typecheck" : "type-check"; try { - execSync(`npm run ${scriptName}`, { + execFileSync("npm", ["run", scriptName], { encoding: "utf8", cwd: process.cwd(), stdio: "pipe", + timeout: 30000, }); results.formatted.push("TypeScript compilation successful"); @@ -407,12 +428,14 @@ ${checkResults.details.map((d) => `β€’ ${d}`).join("\n")} files.length > 0 ? files : ["**/*.{js,jsx,ts,tsx,json,css,scss,md}"]; try { - execSync( - `npx prettier --check ${patterns.join(" ")} --ignore-path .gitignore`, + execFileSync( + "npx", + ["prettier", "--check", ...patterns, "--ignore-path", ".gitignore"], { encoding: "utf8", cwd: process.cwd(), stdio: "pipe", + timeout: 30000, }, ); diff --git a/src/mcps/boot-orchestrator.server.ts b/src/mcps/boot-orchestrator.server.ts index b2c55d2d1..c0e09fe01 100644 --- a/src/mcps/boot-orchestrator.server.ts +++ b/src/mcps/boot-orchestrator.server.ts @@ -44,7 +44,7 @@ class StrRayBootOrchestratorServer { constructor() { this.server = new Server( { - name: "boot-orchestrator", version: "1.14.1", + name: "boot-orchestrator", version: "1.14.10", }, { capabilities: { diff --git a/src/mcps/enforcer-tools.server.ts b/src/mcps/enforcer-tools.server.ts index 09834205e..fe4e3e58a 100644 --- a/src/mcps/enforcer-tools.server.ts +++ b/src/mcps/enforcer-tools.server.ts @@ -16,7 +16,7 @@ import * as path from "path"; import { frameworkLogger } from "../core/framework-logger.js"; // Import actual enforcer-tools functions -import { ruleValidation, getTaskRoutingRecommendation } from "../enforcement/enforcer-tools.js"; +import { ruleValidation as runRuleValidation, getTaskRoutingRecommendation } from "../enforcement/enforcer-tools.js"; import { RuleValidationContext } from "../enforcement/rule-enforcer.js"; class StrRayEnforcerToolsServer { @@ -25,7 +25,7 @@ class StrRayEnforcerToolsServer { constructor() { this.server = new Server( { - name: "enforcer", version: "1.14.1", + name: "enforcer", version: "1.14.10", }, { capabilities: { @@ -286,7 +286,7 @@ class StrRayEnforcerToolsServer { }; // Call actual rule validation from enforcer-tools - const validationResult = await ruleValidation(operation, context); + const validationResult = await runRuleValidation(operation, context); return { content: [ @@ -335,7 +335,7 @@ class StrRayEnforcerToolsServer { { operation, codexCheck, - termsValidated: 43, // All Universal Development Codex terms + termsValidated: 55, // All Universal Development Codex terms complianceScore: codexCheck.score, violations: codexCheck.violations.length, timestamp: new Date().toISOString(), @@ -349,7 +349,8 @@ class StrRayEnforcerToolsServer { } private async contextAnalysisValidation(args: any): Promise { - const { files, operation, checkPatterns } = args; + const files = args.files || []; + const { operation, checkPatterns } = args; // Context analysis - no logging to console (results returned to agent) @@ -609,7 +610,7 @@ class StrRayEnforcerToolsServer { } // Simulate codex term checking - const totalTerms = 43; + const totalTerms = 55; const violationsCount = violations.length; const warningsCount = warnings.length; @@ -700,7 +701,7 @@ class StrRayEnforcerToolsServer { strictMode: boolean, ): Promise { // Run all quality checks using actual functions - const ruleCheckResult = await ruleValidation(operation, { + const ruleCheckResult = await runRuleValidation(operation, { operation, files: context.files || [], newCode: context.newCode, @@ -752,7 +753,13 @@ class StrRayEnforcerToolsServer { "codex-enforcement", "context-analysis-validation", ], - overallScore: 85, // Default score since ruleCheckResult may not have score + overallScore: Math.round( + ( + (ruleCheckResult.errors?.length === 0 && ruleCheckResult.warnings?.length === 0 ? 100 : Math.max(0, 100 - (ruleCheckResult.errors?.length || 0) * 20 - (ruleCheckResult.warnings?.length || 0) * 5)) + + codexCheck.score + + contextCheck.score + ) / 3 + ), }; } @@ -914,9 +921,6 @@ class StrRayEnforcerToolsServer { frameworkLogger.log("mcps/enforcer", "unhandledRejection", "error", { error: String(reason) }); cleanup("unhandledRejection"); }); - - process.on("SIGINT", cleanup); - process.on("SIGTERM", cleanup); } } diff --git a/src/mcps/estimation.server.ts b/src/mcps/estimation.server.ts index 42d53f351..e839d0ebf 100644 --- a/src/mcps/estimation.server.ts +++ b/src/mcps/estimation.server.ts @@ -24,7 +24,7 @@ class EstimationServer { constructor() { this.server = new Server( { - name: "estimation-validator", version: "1.14.1", + name: "estimation-validator", version: "1.14.10", }, { capabilities: { tools: {} }, @@ -100,23 +100,36 @@ class EstimationServer { // Handle tool calls this.server.setRequestHandler(CallToolRequestSchema, async (request) => { - const { name, arguments: args } = request.params; - - switch (name) { - case "validate-estimate": - return this.handleValidateEstimate(args as { category: string; estimate: number; description?: string }); - - case "start-tracking": - return this.handleStartTracking(args as { taskId: string; category: string; estimate: number; description?: string }); - - case "complete-tracking": - return this.handleCompleteTracking(args as { taskId: string }); - - case "get-accuracy-report": - return this.handleGetReport(); - - default: - throw new Error(`Unknown tool: ${name}`); + try { + const { name, arguments: args } = request.params; + + if (args == null) { + throw new Error(`Tool '${name}' called with no arguments`); + } + + switch (name) { + case "validate-estimate": + return this.handleValidateEstimate(args as { category: string; estimate: number; description?: string }); + + case "start-tracking": + return this.handleStartTracking(args as { taskId: string; category: string; estimate: number; description?: string }); + + case "complete-tracking": + return this.handleCompleteTracking(args as { taskId: string }); + + case "get-accuracy-report": + return this.handleGetReport(); + + default: + throw new Error(`Unknown tool: ${name}`); + } + } catch (error) { + return { + content: [{ + type: "text" as const, + text: `Error handling tool '${request.params.name}': ${error instanceof Error ? error.message : String(error)}`, + }], + }; } }); } @@ -201,7 +214,7 @@ class EstimationServer { const transport = new StdioServerTransport(); await this.server.connect(transport); - void frameworkLogger.log("estimation-server", "start", "info", { + frameworkLogger.log("estimation-server", "start", "info", { message: "Estimation Validator Server started", }); } diff --git a/src/mcps/framework-compliance-audit.server.ts b/src/mcps/framework-compliance-audit.server.ts index ff53f08d6..3b99d17ce 100644 --- a/src/mcps/framework-compliance-audit.server.ts +++ b/src/mcps/framework-compliance-audit.server.ts @@ -20,7 +20,7 @@ class StrRayFrameworkComplianceAuditServer { constructor() { this.server = new Server( { - name: "framework-compliance-audit", version: "1.14.1", + name: "framework-compliance-audit", version: "1.14.10", }, { capabilities: { diff --git a/src/mcps/framework-help.server.ts b/src/mcps/framework-help.server.ts index 3cecc9e10..8abd70480 100644 --- a/src/mcps/framework-help.server.ts +++ b/src/mcps/framework-help.server.ts @@ -14,7 +14,7 @@ class FrameworkHelpServer { constructor() { this.server = new Server( { - name: "strray/framework-help", version: "1.14.1", + name: "strray/framework-help", version: "1.14.10", }, { capabilities: { @@ -98,15 +98,26 @@ class FrameworkHelpServer { this.server.setRequestHandler(CallToolRequestSchema, async (request) => { const { name, arguments: args } = request.params; - switch (name) { - case "strray_get_capabilities": - return this.handleGetCapabilities(args); - case "strray_get_commands": - return this.handleGetCommands(args); - case "strray_explain_capability": - return this.handleExplainCapability(args); - default: - throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${name}`); + try { + switch (name) { + case "strray_get_capabilities": + return this.handleGetCapabilities(args); + case "strray_get_commands": + return this.handleGetCommands(args); + case "strray_explain_capability": + return this.handleExplainCapability(args); + default: + throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${name}`); + } + } catch (error) { + if (error instanceof McpError) { + throw error; + } + frameworkLogger.log("mcps/framework-help", "tool-call", "error", { tool: name, error: String(error) }); + throw new McpError( + ErrorCode.InternalError, + `Tool "${name}" execution failed: ${error instanceof Error ? error.message : String(error)}`, + ); } }); } @@ -249,6 +260,10 @@ Test Coverage - Automated testing analysis - Monitor error rates through automated tracking `.trim(); break; + + default: + commands = `Error: Unknown command type "${type}". Valid types: agent-commands, system-commands, reporting-commands`; + break; } return { @@ -265,20 +280,16 @@ Test Coverage - Automated testing analysis const capability = args?.capability; if (!capability) { - return { - content: [ - { - type: "text", - text: "Error: capability parameter is required", - }, - ], - }; + throw new McpError( + ErrorCode.InvalidParams, + "capability parameter is required", + ); } const explanations: { [key: string]: string } = { enforcer: ` **Enforcer Agent** -Automatically validates code against the Universal Development Codex (46 mandatory terms). +Automatically validates code against the Universal Development Codex (60 mandatory terms). Prevents common errors, enforces coding standards, and ensures production-ready code. **Capabilities:** @@ -424,7 +435,7 @@ ${Object.entries(capabilities.reporting) return ` **StringRay Framework Capabilities:** -**8 Agents:** enforcer, architect, orchestrator, bug-triage-specialist, code-reviewer, security-auditor, refactorer, testing-lead +**26 Agents:** enforcer, architect, orchestrator, bug-triage-specialist, code-reviewer, security-auditor, refactorer, testing-lead, researcher, strategist, seo-consultant, content-creator, growth-strategist, multimodal-looker, frontend-ui-ux-engineer, tech-writer, log-monitor, explore, analyzer, backend-engineer, performance-engineer, database-engineer, devops-engineer, mobile-developer **23 Skills:** project-analysis, testing-strategy, code-review, security-audit, performance-optimization, refactoring-strategies, ui-ux-design, documentation-generation, and more diff --git a/src/mcps/knowledge-skills/api-design.server.ts b/src/mcps/knowledge-skills/api-design.server.ts index 47865480b..ff2117ed0 100644 --- a/src/mcps/knowledge-skills/api-design.server.ts +++ b/src/mcps/knowledge-skills/api-design.server.ts @@ -20,7 +20,7 @@ class StrRayApiDesignServer { constructor() { this.server = new Server( { - name: "api-design", version: "1.14.1", + name: "api-design", version: "1.14.10", }, { capabilities: { diff --git a/src/mcps/knowledge-skills/architecture-patterns.server.ts b/src/mcps/knowledge-skills/architecture-patterns.server.ts index 2be495b0d..523894b9f 100644 --- a/src/mcps/knowledge-skills/architecture-patterns.server.ts +++ b/src/mcps/knowledge-skills/architecture-patterns.server.ts @@ -22,7 +22,7 @@ class StrRayArchitecturePatternsServer { constructor() { this.server = new Server( { - name: "architecture-patterns", version: "1.14.1", + name: "architecture-patterns", version: "1.14.10", }, { capabilities: { diff --git a/src/mcps/knowledge-skills/bug-triage-specialist.server.ts b/src/mcps/knowledge-skills/bug-triage-specialist.server.ts index 7cf9a95de..ac83f3eb8 100644 --- a/src/mcps/knowledge-skills/bug-triage-specialist.server.ts +++ b/src/mcps/knowledge-skills/bug-triage-specialist.server.ts @@ -65,7 +65,7 @@ class BugTriageSpecialistServer { constructor() { this.server = new Server( - { name: "bug-triage-specialist", version: "1.14.1" }, + { name: "bug-triage-specialist", version: "1.14.10" }, { capabilities: { tools: {} } }, ); this.setupToolHandlers(); diff --git a/src/mcps/knowledge-skills/code-analyzer.server.ts b/src/mcps/knowledge-skills/code-analyzer.server.ts index d1183bac4..48f7d8ef3 100644 --- a/src/mcps/knowledge-skills/code-analyzer.server.ts +++ b/src/mcps/knowledge-skills/code-analyzer.server.ts @@ -266,7 +266,7 @@ class CodeAnalyzerServer { constructor() { this.server = new Server( - { name: "code-analyzer", version: "1.14.1" }, + { name: "code-analyzer", version: "1.14.10" }, { capabilities: { tools: {} } }, ); diff --git a/src/mcps/knowledge-skills/code-review.server.ts b/src/mcps/knowledge-skills/code-review.server.ts index 2e7348712..9eb88dd27 100644 --- a/src/mcps/knowledge-skills/code-review.server.ts +++ b/src/mcps/knowledge-skills/code-review.server.ts @@ -48,7 +48,7 @@ class StrRayCodeReviewServer { constructor() { this.server = new Server( { - name: "code-review", version: "1.14.1", + name: "code-review", version: "1.14.10", }, { capabilities: { diff --git a/src/mcps/knowledge-skills/content-creator.server.ts b/src/mcps/knowledge-skills/content-creator.server.ts index e2a3bd00e..5286d26d3 100644 --- a/src/mcps/knowledge-skills/content-creator.server.ts +++ b/src/mcps/knowledge-skills/content-creator.server.ts @@ -100,7 +100,7 @@ class SEOCopywriterServer { constructor() { this.server = new Server( - { name: "content-creator", version: "1.14.1" }, + { name: "content-creator", version: "1.14.10" }, { capabilities: { tools: {} } }, ); diff --git a/src/mcps/knowledge-skills/database-design.server.ts b/src/mcps/knowledge-skills/database-design.server.ts index 7ab96648d..5ce1378ab 100644 --- a/src/mcps/knowledge-skills/database-design.server.ts +++ b/src/mcps/knowledge-skills/database-design.server.ts @@ -80,7 +80,7 @@ class StrRayDatabaseDesignServer { constructor() { this.server = new Server( { - name: "database-design", version: "1.14.1", + name: "database-design", version: "1.14.10", }, { capabilities: { diff --git a/src/mcps/knowledge-skills/devops-deployment.server.ts b/src/mcps/knowledge-skills/devops-deployment.server.ts index a90b8fa0f..b2ccf1a9f 100644 --- a/src/mcps/knowledge-skills/devops-deployment.server.ts +++ b/src/mcps/knowledge-skills/devops-deployment.server.ts @@ -74,7 +74,7 @@ class StrRayDevOpsDeploymentServer { constructor() { this.server = new Server( { - name: "devops-deployment", version: "1.14.1", + name: "devops-deployment", version: "1.14.10", }, { capabilities: { diff --git a/src/mcps/knowledge-skills/git-workflow.server.ts b/src/mcps/knowledge-skills/git-workflow.server.ts index fade2ec4f..47386c522 100644 --- a/src/mcps/knowledge-skills/git-workflow.server.ts +++ b/src/mcps/knowledge-skills/git-workflow.server.ts @@ -20,7 +20,7 @@ class StrRayGitWorkflowServer { constructor() { this.server = new Server( { - name: "git-workflow", version: "1.14.1", + name: "git-workflow", version: "1.14.10", }, { capabilities: { diff --git a/src/mcps/knowledge-skills/growth-strategist.server.ts b/src/mcps/knowledge-skills/growth-strategist.server.ts index 20d6fcea6..e090fc2b0 100644 --- a/src/mcps/knowledge-skills/growth-strategist.server.ts +++ b/src/mcps/knowledge-skills/growth-strategist.server.ts @@ -109,7 +109,7 @@ class MarketingExpertServer { constructor() { this.server = new Server( - { name: "growth-strategist", version: "1.14.1" }, + { name: "growth-strategist", version: "1.14.10" }, { capabilities: { tools: {} } }, ); diff --git a/src/mcps/knowledge-skills/log-monitor.server.ts b/src/mcps/knowledge-skills/log-monitor.server.ts index 185e1c11b..49593087b 100644 --- a/src/mcps/knowledge-skills/log-monitor.server.ts +++ b/src/mcps/knowledge-skills/log-monitor.server.ts @@ -101,7 +101,7 @@ class LogMonitorServer { constructor() { this.server = new Server( - { name: "log-monitor", version: "1.14.1" }, + { name: "log-monitor", version: "1.14.10" }, { capabilities: { tools: {} } }, ); this.setupToolHandlers(); diff --git a/src/mcps/knowledge-skills/mobile-development.server.ts b/src/mcps/knowledge-skills/mobile-development.server.ts index 8bf333a21..611d93eeb 100644 --- a/src/mcps/knowledge-skills/mobile-development.server.ts +++ b/src/mcps/knowledge-skills/mobile-development.server.ts @@ -63,7 +63,7 @@ class StrRayMobileDevelopmentServer { constructor() { this.server = new Server( { - name: "mobile-development", version: "1.14.1", + name: "mobile-development", version: "1.14.10", }, { capabilities: { diff --git a/src/mcps/knowledge-skills/multimodal-looker.server.ts b/src/mcps/knowledge-skills/multimodal-looker.server.ts index fc24e08c3..cb83cf434 100644 --- a/src/mcps/knowledge-skills/multimodal-looker.server.ts +++ b/src/mcps/knowledge-skills/multimodal-looker.server.ts @@ -46,7 +46,7 @@ class MultimodalLookerServer { constructor() { this.server = new Server( - { name: "multimodal-looker", version: "1.14.1" }, + { name: "multimodal-looker", version: "1.14.10" }, { capabilities: { tools: {} } }, ); this.setupToolHandlers(); diff --git a/src/mcps/knowledge-skills/performance-optimization.server.ts b/src/mcps/knowledge-skills/performance-optimization.server.ts index 26bef65d5..e0677dc4f 100644 --- a/src/mcps/knowledge-skills/performance-optimization.server.ts +++ b/src/mcps/knowledge-skills/performance-optimization.server.ts @@ -20,7 +20,7 @@ class StrRayPerformanceOptimizationServer { constructor() { this.server = new Server( { - name: "performance-optimization", version: "1.14.1", + name: "performance-optimization", version: "1.14.10", }, { capabilities: { diff --git a/src/mcps/knowledge-skills/project-analysis.server.ts b/src/mcps/knowledge-skills/project-analysis.server.ts index 7a89abd1b..f2eb4fd1f 100644 --- a/src/mcps/knowledge-skills/project-analysis.server.ts +++ b/src/mcps/knowledge-skills/project-analysis.server.ts @@ -42,7 +42,7 @@ class StrRayProjectAnalysisServer { constructor() { this.server = new Server( { - name: "project-analysis", version: "1.14.1", + name: "project-analysis", version: "1.14.10", }, { capabilities: { diff --git a/src/mcps/knowledge-skills/refactoring-strategies.server.ts b/src/mcps/knowledge-skills/refactoring-strategies.server.ts index 5a0da5770..adf67bea6 100644 --- a/src/mcps/knowledge-skills/refactoring-strategies.server.ts +++ b/src/mcps/knowledge-skills/refactoring-strategies.server.ts @@ -59,7 +59,7 @@ class StrRayRefactoringStrategiesServer { constructor() { this.server = new Server( { - name: "refactoring-strategies", version: "1.14.1", + name: "refactoring-strategies", version: "1.14.10", }, { capabilities: { diff --git a/src/mcps/knowledge-skills/security-audit.server.ts b/src/mcps/knowledge-skills/security-audit.server.ts index 148cf5b20..cc83df771 100644 --- a/src/mcps/knowledge-skills/security-audit.server.ts +++ b/src/mcps/knowledge-skills/security-audit.server.ts @@ -64,7 +64,7 @@ class StrRaySecurityAuditServer { constructor() { this.server = new Server( { - name: "security-audit", version: "1.14.1", + name: "security-audit", version: "1.14.10", }, { capabilities: { diff --git a/src/mcps/knowledge-skills/seo-consultant.server.ts b/src/mcps/knowledge-skills/seo-consultant.server.ts index d69454dc0..428a975f1 100644 --- a/src/mcps/knowledge-skills/seo-consultant.server.ts +++ b/src/mcps/knowledge-skills/seo-consultant.server.ts @@ -114,7 +114,7 @@ class SEOSpecialistServer { constructor() { this.server = new Server( - { name: "seo-consultant", version: "1.14.1" }, + { name: "seo-consultant", version: "1.14.10" }, { capabilities: { tools: {} } }, ); diff --git a/src/mcps/knowledge-skills/session-management.server.ts b/src/mcps/knowledge-skills/session-management.server.ts index 490127db0..4e26ea1dd 100644 --- a/src/mcps/knowledge-skills/session-management.server.ts +++ b/src/mcps/knowledge-skills/session-management.server.ts @@ -161,7 +161,7 @@ class SessionManagementServer { constructor() { this.server = new Server( - { name: "session-management", version: "1.14.1" }, + { name: "session-management", version: "1.14.10" }, { capabilities: { tools: {} } }, ); diff --git a/src/mcps/knowledge-skills/skill-invocation.server.ts b/src/mcps/knowledge-skills/skill-invocation.server.ts index e4896d4d8..38ee929aa 100644 --- a/src/mcps/knowledge-skills/skill-invocation.server.ts +++ b/src/mcps/knowledge-skills/skill-invocation.server.ts @@ -14,7 +14,7 @@ class SkillInvocationServer { constructor() { this.server = new Server( { - name: "strray/skill-invocation", version: "1.14.1", + name: "strray/skill-invocation", version: "1.14.10", }, { capabilities: { diff --git a/src/mcps/knowledge-skills/strategist.server.ts b/src/mcps/knowledge-skills/strategist.server.ts index 0cc2c78af..3a8ce9a8d 100644 --- a/src/mcps/knowledge-skills/strategist.server.ts +++ b/src/mcps/knowledge-skills/strategist.server.ts @@ -92,7 +92,7 @@ class StrategistServer { constructor() { this.server = new Server( { - name: "strray/strategist", version: "1.14.1", + name: "strray/strategist", version: "1.14.10", }, { capabilities: { diff --git a/src/mcps/knowledge-skills/tech-writer.server.ts b/src/mcps/knowledge-skills/tech-writer.server.ts index d72da0eb5..8e3610859 100644 --- a/src/mcps/knowledge-skills/tech-writer.server.ts +++ b/src/mcps/knowledge-skills/tech-writer.server.ts @@ -120,7 +120,7 @@ class StrRayDocumentationGenerationServer { constructor() { this.server = new Server( { - name: "documentation-generation", version: "1.14.1", + name: "documentation-generation", version: "1.14.10", }, { capabilities: { @@ -1007,7 +1007,7 @@ class StrRayDocumentationGenerationServer { openapi: "3.0.0", info: { title: "API Documentation", - version: "1.14.1", + version: "1.14.10", description: "Generated API documentation", }, servers: [ diff --git a/src/mcps/knowledge-skills/testing-best-practices.server.ts b/src/mcps/knowledge-skills/testing-best-practices.server.ts index 2e2b936b2..498b57cc9 100644 --- a/src/mcps/knowledge-skills/testing-best-practices.server.ts +++ b/src/mcps/knowledge-skills/testing-best-practices.server.ts @@ -59,7 +59,7 @@ class StrRayTestingBestPracticesServer { constructor() { this.server = new Server( { - name: "testing-best-practices", version: "1.14.1", + name: "testing-best-practices", version: "1.14.10", }, { capabilities: { diff --git a/src/mcps/knowledge-skills/testing-strategy.server.ts b/src/mcps/knowledge-skills/testing-strategy.server.ts index bb18c2fcd..f7b181db6 100644 --- a/src/mcps/knowledge-skills/testing-strategy.server.ts +++ b/src/mcps/knowledge-skills/testing-strategy.server.ts @@ -44,7 +44,7 @@ class StrRayTestingStrategyServer { constructor() { this.server = new Server( { - name: "testing-strategy", version: "1.14.1", + name: "testing-strategy", version: "1.14.10", }, { capabilities: { diff --git a/src/mcps/knowledge-skills/ui-ux-design.server.ts b/src/mcps/knowledge-skills/ui-ux-design.server.ts index 7f4ce172b..96a1a7fed 100644 --- a/src/mcps/knowledge-skills/ui-ux-design.server.ts +++ b/src/mcps/knowledge-skills/ui-ux-design.server.ts @@ -98,7 +98,7 @@ class StrRayUIUXDesignServer { constructor() { this.server = new Server( { - name: "ui-ux-design", version: "1.14.1", + name: "ui-ux-design", version: "1.14.10", }, { capabilities: { diff --git a/src/mcps/lint.server.ts b/src/mcps/lint.server.ts index 5b71e84d6..565ef82f8 100644 --- a/src/mcps/lint.server.ts +++ b/src/mcps/lint.server.ts @@ -10,7 +10,7 @@ import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js"; -import { execSync } from "child_process"; +import { execFileSync } from "child_process"; import fs from "fs"; import { frameworkLogger } from "../core/framework-logger.js"; @@ -20,7 +20,7 @@ class StrRayLintServer { constructor() { this.server = new Server( { - name: "lint", version: "1.14.1", + name: "lint", version: "1.14.10", }, { capabilities: { @@ -97,13 +97,24 @@ class StrRayLintServer { this.server.setRequestHandler(CallToolRequestSchema, async (request) => { const { name, arguments: args } = request.params; - switch (name) { - case "lint": - return await this.handleLint(args); - case "lint-check": - return await this.handleLintCheck(args); - default: - throw new Error(`Unknown tool: ${name}`); + try { + switch (name) { + case "lint": + return await this.handleLint(args); + case "lint-check": + return await this.handleLintCheck(args); + default: + throw new Error(`Unknown tool: ${name}`); + } + } catch (error) { + return { + content: [ + { + type: "text", + text: `❌ Tool execution failed: ${error instanceof Error ? error.message : String(error)}`, + }, + ], + }; } }); } @@ -228,12 +239,14 @@ ${checkResults.details.map((d) => `β€’ ${d}`).join("\n")} return results; } - // Check for ESLint configuration + // Check for ESLint configuration (including ESLint 9+ flat config) const hasEslintConfig = fs.existsSync(".eslintrc.js") || fs.existsSync(".eslintrc.json") || fs.existsSync(".eslintrc.yml") || fs.existsSync(".eslintrc.yaml") || + fs.existsSync("eslint.config.js") || + fs.existsSync("eslint.config.mjs") || (fs.existsSync("package.json") && JSON.parse(fs.readFileSync("package.json", "utf8")).eslintConfig); @@ -246,44 +259,57 @@ ${checkResults.details.map((d) => `β€’ ${d}`).join("\n")} const packageJson = JSON.parse(fs.readFileSync("package.json", "utf8")); const scripts = packageJson.scripts || {}; - // Determine which script to run - let scriptCommand = "npx eslint"; + // Determine command and arguments (using args array to prevent command injection) + let command: string; + let args: string[]; + const fileArgs = files.length > 0 ? files : ["."]; + if (fix && scripts["lint:fix"]) { - scriptCommand = "npm run lint:fix"; + command = "npm"; + args = ["run", "lint:fix", "--", ...fileArgs]; } else if (!fix && scripts.lint) { - scriptCommand = "npm run lint"; - } - - // Add file arguments if specified - if (files.length > 0) { - scriptCommand += ` ${files.join(" ")}`; + command = "npm"; + args = ["run", "lint", "--", ...fileArgs]; } else { - scriptCommand += " ."; + command = "npx"; + args = ["eslint", ...fileArgs, "--format", "json"]; } - // Add strict flag if requested if (strict) { - scriptCommand += " --max-warnings 0"; + args.push("--max-warnings", "0"); } + const execOptions = { + encoding: "utf8" as const, + cwd: process.cwd(), + stdio: "pipe" as const, + timeout: 30000, + }; + try { - const output = execSync(scriptCommand, { - encoding: "utf8", - cwd: process.cwd(), - stdio: "pipe", - }); + const output = execFileSync(command, args, execOptions); // Parse ESLint output - const lines = output.split("\n").filter((line) => line.trim()); results.files = files.length > 0 ? files : ["All files"]; - // Count issues from output + // Parse ESLint JSON output for accurate counts let errorCount = 0; let warningCount = 0; - for (const line of lines) { - if (line.includes("error")) errorCount++; - if (line.includes("warning")) warningCount++; + try { + const jsonResults = JSON.parse(output); + if (Array.isArray(jsonResults)) { + for (const fileResult of jsonResults) { + errorCount += fileResult.errorCount || 0; + warningCount += fileResult.warningCount || 0; + } + } + } catch { + // JSON parse failed β€” fall back to regex-based parsing + const errorMatches = output.match(/(\d+)\s+errors?/); + const warningMatches = output.match(/(\d+)\s+warnings?/); + if (errorMatches?.[1]) errorCount = parseInt(errorMatches[1]); + if (warningMatches?.[1]) warningCount = parseInt(warningMatches[1]); } results.issues.errors = errorCount; @@ -308,17 +334,31 @@ ${checkResults.details.map((d) => `β€’ ${d}`).join("\n")} } catch (error) { const errorOutput = error instanceof Error - ? (error as any).stdout?.toString() || error.message + ? ((error as any).stdout?.toString() || (error as any).stderr?.toString() || error.message) : String(error); results.success = false; - // Parse error output for issue counts - const errorMatches = errorOutput.match(/(\d+) errors?/); - const warningMatches = errorOutput.match(/(\d+) warnings?/); + // Try JSON parsing of error output first for accurate counts + let parsedJson = false; + try { + const jsonResults = JSON.parse(errorOutput); + if (Array.isArray(jsonResults)) { + for (const fileResult of jsonResults) { + results.issues.errors += fileResult.errorCount || 0; + results.issues.warnings += fileResult.warningCount || 0; + } + parsedJson = true; + } + } catch { + // Fall back to regex + } - if (errorMatches) results.issues.errors = parseInt(errorMatches[1]); - if (warningMatches) - results.issues.warnings = parseInt(warningMatches[1]); + if (!parsedJson) { + const errorMatches = errorOutput.match(/(\d+)\s+errors?/); + const warningMatches = errorOutput.match(/(\d+)\s+warnings?/); + if (errorMatches?.[1]) results.issues.errors = parseInt(errorMatches[1]); + if (warningMatches?.[1]) results.issues.warnings = parseInt(warningMatches[1]); + } results.details.push( `ESLint found ${results.issues.errors} errors, ${results.issues.warnings} warnings`, @@ -354,15 +394,18 @@ ${checkResults.details.map((d) => `β€’ ${d}`).join("\n")} `General compliance: ${results.violations === 0 ? "PASS" : "FAIL"}`, ); } else { - // Check specific rules + // Check specific rules (using args array to prevent command injection) + const fileArgs = files.length > 0 ? files : ["."]; for (const rule of rules) { try { - const ruleOutput = execSync( - `npx eslint --rule "${rule}:error" ${files.join(" ")}`, + execFileSync( + "npx", + ["eslint", ...fileArgs, "--rule", `${rule}:error`, "--format", "json"], { encoding: "utf8", cwd: process.cwd(), stdio: "pipe", + timeout: 30000, }, ); @@ -370,8 +413,12 @@ ${checkResults.details.map((d) => `β€’ ${d}`).join("\n")} results.details.push(`Rule ${rule}: PASS`); } catch (error) { results.violations++; + const errorOutput = + error instanceof Error + ? ((error as any).stdout?.toString() || error.message) + : String(error); results.details.push( - `Rule ${rule}: FAIL - ${error instanceof Error ? error.message : String(error)}`, + `Rule ${rule}: FAIL - ${errorOutput.substring(0, 200)}`, ); } } diff --git a/src/mcps/model-health-check.server.ts b/src/mcps/model-health-check.server.ts index 537713697..7a94e1e0e 100644 --- a/src/mcps/model-health-check.server.ts +++ b/src/mcps/model-health-check.server.ts @@ -21,7 +21,7 @@ class StrRayModelHealthCheckServer { constructor() { this.server = new Server( { - name: "model-health-check", version: "1.14.1", + name: "model-health-check", version: "1.14.10", }, { capabilities: { diff --git a/src/mcps/orchestrator/execution/execution-planner.ts b/src/mcps/orchestrator/execution/execution-planner.ts index a11d0330b..d3c3b1033 100644 --- a/src/mcps/orchestrator/execution/execution-planner.ts +++ b/src/mcps/orchestrator/execution/execution-planner.ts @@ -46,8 +46,8 @@ export class ExecutionPlanner { errors.push(`Task ${i}: Missing required field 'type'`); } - // Check dependencies exist - if (task.dependencies && task.id) { + // Check dependencies exist (only for string[] dependency IDs) + if (task.dependencies && task.id && Array.isArray(task.dependencies)) { const taskIds = new Set(tasks.map(t => t.id).filter((id): id is string => !!id)); for (const depId of task.dependencies) { if (!taskIds.has(depId)) { @@ -145,7 +145,10 @@ export class ExecutionPlanner { const dependentTasks: OrchestrationTask[] = []; for (const task of sortedTasks) { - if (!task.dependencies || task.dependencies.length === 0) { + const hasDeps = task.dependencies + ? (Array.isArray(task.dependencies) ? task.dependencies.length : Number(task.dependencies)) > 0 + : false; + if (!hasDeps) { independentTasks.push(task); } else { dependentTasks.push(task); @@ -171,7 +174,7 @@ export class ExecutionPlanner { if (visited.has(task.id)) return; visited.add(task.id); - if (task.dependencies) { + if (task.dependencies && Array.isArray(task.dependencies)) { for (const depId of task.dependencies) { const depTask = taskMap.get(depId); if (depTask) visit(depTask); @@ -314,9 +317,12 @@ export class ExecutionPlanner { complexity = (complexity + task.estimatedComplexity) / 2; } - // Adjust based on dependencies + // Adjust based on dependencies (handles both string[] and number) if (task.dependencies) { - complexity += task.dependencies.length * 5; + const depCount = Array.isArray(task.dependencies) + ? task.dependencies.length + : Number(task.dependencies) || 0; + complexity += depCount * 5; } return Math.min(Math.max(Math.round(complexity), 1), 100); @@ -337,8 +343,11 @@ export class ExecutionPlanner { */ private calculateParallelPotential(tasks: OrchestrationTask[]): number { // Tasks without dependencies can run in parallel - const independent = tasks.filter(t => !t.dependencies || t.dependencies.length === 0); - return independent.length / tasks.length; + const independent = tasks.filter( + t => !t.dependencies || + (Array.isArray(t.dependencies) ? t.dependencies.length : Number(t.dependencies)) === 0 + ); + return tasks.length > 0 ? independent.length / tasks.length : 0; } } diff --git a/src/mcps/orchestrator/handlers/status-handler.ts b/src/mcps/orchestrator/handlers/status-handler.ts index e763232e4..e891f2e05 100644 --- a/src/mcps/orchestrator/handlers/status-handler.ts +++ b/src/mcps/orchestrator/handlers/status-handler.ts @@ -258,14 +258,14 @@ ${optimizations.map((o) => `β€’ ${o}`).join('\n')} private formatStatusResponse(status: unknown, detailed: boolean): string { const statusAny = status as Record; - // Check if it's a completed session - if (statusAny.completed) { + // Check if it's a completed session (supports both 'completed' boolean and status: 'completed') + if (statusAny.completed || statusAny.status === 'completed') { const result = statusAny as { success: boolean; duration: number; completedTasks: number; failedTasks: number }; return `πŸ“Š Session Status: COMPLETED **Success:** ${result.success ? 'βœ… Yes' : '❌ No'} **Duration:** ${result.duration}ms -**Tasks:** ${result.completedTasks + result.failedTasks} (${result.completedTasks} βœ…, ${result.failedTasks} ❌)`; +**Tasks:** ${(result.completedTasks ?? 0) + (result.failedTasks ?? 0)} (${result.completedTasks ?? 0} βœ…, ${result.failedTasks ?? 0} ❌)`; } // Overall status @@ -273,19 +273,21 @@ ${optimizations.map((o) => `β€’ ${o}`).join('\n')} let response = `πŸ“Š Orchestration Status -**Active Sessions:** ${orchStatus.activeSessions} -**Total Tasks Executed:** ${orchStatus.totalTasks}`; +**Active Sessions:** ${orchStatus.activeSessions ?? 0} +**Total Tasks Executed:** ${orchStatus.totalTasks ?? 0}`; - if (Object.keys(orchStatus.agentUtilization).length > 0) { + const agentUtil = orchStatus.agentUtilization || {}; + if (Object.keys(agentUtil).length > 0) { response += `\n\n**Agent Utilization:**`; - for (const [agent, count] of Object.entries(orchStatus.agentUtilization)) { + for (const [agent, count] of Object.entries(agentUtil)) { response += `\nβ€’ ${agent}: ${count} tasks`; } } - if (detailed && orchStatus.recentSessions.length > 0) { + const sessions = orchStatus.recentSessions || []; + if (detailed && sessions.length > 0) { response += `\n\n**Recent Sessions:**`; - for (const session of orchStatus.recentSessions) { + for (const session of sessions) { response += `\nβ€’ ${session.sessionId}: ${session.tasks} tasks, ${session.duration}ms`; } } diff --git a/src/mcps/orchestrator/server.ts b/src/mcps/orchestrator/server.ts index b1540478d..1a62d7336 100644 --- a/src/mcps/orchestrator/server.ts +++ b/src/mcps/orchestrator/server.ts @@ -57,7 +57,7 @@ export class OrchestratorServer { this.server = new Server( { name: 'orchestrator', - version: '1.10.0', + version: '1.14.1', }, { capabilities: { @@ -69,7 +69,7 @@ export class OrchestratorServer { this.initializeTools(); this.setupToolHandlers(); - void frameworkLogger.log('orchestrator.server', 'initialize', 'info', { + frameworkLogger.log('orchestrator.server', 'initialize', 'info', { message: 'StringRay Orchestrator MCP Server initialized', }); } @@ -199,44 +199,53 @@ export class OrchestratorServer { */ private setupToolHandlers(): void { this.server.setRequestHandler(CallToolRequestSchema, async (request) => { - const { name, arguments: args } = request.params; + try { + const { name, arguments: args } = request.params; - switch (name) { - case 'orchestrate-task': - return await this.taskHandler.handleOrchestrateTask(args as { - description: string; - tasks?: OrchestrationTask[]; - sessionId?: string; - executionMode?: string; - timeout?: number; - }, { taskHistory: this.taskHistory, activeTasks: this.activeTasks }); - - case 'analyze-complexity': - return await this.complexityHandler.handleAnalyzeComplexity(args as { - tasks: OrchestrationTask[]; - }); - - case 'get-orchestration-status': - return await this.statusHandler.handleGetOrchestrationStatus(args as { - sessionId?: string; - detailed?: boolean; - }, { taskHistory: this.taskHistory, activeTasks: this.activeTasks }); - - case 'cancel-orchestration': - return await this.statusHandler.handleCancelOrchestration(args as { - sessionId?: string; - taskId?: string; - force?: boolean; - }, { taskHistory: this.taskHistory, activeTasks: this.activeTasks }); - - case 'optimize-orchestration': - return await this.statusHandler.handleOptimizeOrchestration(args as { - history?: boolean; - recommendations?: boolean; - }); - - default: - throw new Error(`Unknown tool: ${name}`); + switch (name) { + case 'orchestrate-task': + return await this.taskHandler.handleOrchestrateTask(args as { + description: string; + tasks?: OrchestrationTask[]; + sessionId?: string; + executionMode?: string; + timeout?: number; + }, { taskHistory: this.taskHistory, activeTasks: this.activeTasks }); + + case 'analyze-complexity': + return await this.complexityHandler.handleAnalyzeComplexity(args as { + tasks: OrchestrationTask[]; + }); + + case 'get-orchestration-status': + return await this.statusHandler.handleGetOrchestrationStatus(args as { + sessionId?: string; + detailed?: boolean; + }, { taskHistory: this.taskHistory, activeTasks: this.activeTasks }); + + case 'cancel-orchestration': + return await this.statusHandler.handleCancelOrchestration(args as { + sessionId?: string; + taskId?: string; + force?: boolean; + }, { taskHistory: this.taskHistory, activeTasks: this.activeTasks }); + + case 'optimize-orchestration': + return await this.statusHandler.handleOptimizeOrchestration(args as { + history?: boolean; + recommendations?: boolean; + }); + + default: + throw new Error(`Unknown tool: ${name}`); + } + } catch (error) { + return { + content: [{ + type: 'text' as const, + text: `Error handling tool '${request.params.name}': ${error instanceof Error ? error.message : String(error)}`, + }], + }; } }); } @@ -260,6 +269,7 @@ export class OrchestratorServer { await frameworkLogger.log('orchestrator.server', 'shutdown', 'info', { message: 'StringRay Orchestrator MCP Server shutting down', }); + await this.server.close(); } } @@ -277,7 +287,7 @@ export function createOrchestratorServer(): OrchestratorServer { if (import.meta.url === `file://${process.argv[1]}`) { const server = createOrchestratorServer(); server.start().catch((error) => { - void frameworkLogger.log('orchestrator.server', 'fatal-error', 'error', { + frameworkLogger.log('orchestrator.server', 'fatal-error', 'error', { message: error instanceof Error ? error.message : String(error), }); process.exit(1); diff --git a/src/mcps/orchestrator/types.ts b/src/mcps/orchestrator/types.ts index c13b7c7ee..2557c02de 100644 --- a/src/mcps/orchestrator/types.ts +++ b/src/mcps/orchestrator/types.ts @@ -15,7 +15,7 @@ export interface OrchestrationTask { description: string; type: string; priority?: 'critical' | 'high' | 'medium' | 'low'; - dependencies?: string[]; + dependencies?: string[] | number; estimatedComplexity?: number; } diff --git a/src/mcps/performance-analysis.server.ts b/src/mcps/performance-analysis.server.ts index 8220d4e0c..a5d7b5b45 100644 --- a/src/mcps/performance-analysis.server.ts +++ b/src/mcps/performance-analysis.server.ts @@ -23,7 +23,7 @@ class StrRayPerformanceAnalysisServer { constructor() { this.server = new Server( { - name: "performance-analysis", version: "1.14.1", + name: "performance-analysis", version: "1.14.10", }, { capabilities: { diff --git a/src/mcps/processor-pipeline.server.ts b/src/mcps/processor-pipeline.server.ts index 7a440464b..80d397c5c 100644 --- a/src/mcps/processor-pipeline.server.ts +++ b/src/mcps/processor-pipeline.server.ts @@ -29,7 +29,7 @@ class StrRayProcessorPipelineServer { constructor() { this.server = new Server( { - name: "processor-pipeline", version: "1.14.1", + name: "processor-pipeline", version: "1.14.10", }, { capabilities: { diff --git a/src/mcps/researcher.server.ts b/src/mcps/researcher.server.ts index bad59f078..c048d1674 100644 --- a/src/mcps/researcher.server.ts +++ b/src/mcps/researcher.server.ts @@ -3,6 +3,9 @@ * * Knowledge skill for codebase documentation lookup, implementation examples, * and multi-repo analysis - serves as the universal documentation reference + * + * NOTE: Class is named StrRayLibrarianServer but the MCP server name is + * "researcher" for backwards compatibility with existing tool references. */ import { Server } from "@modelcontextprotocol/sdk/server/index.js"; @@ -27,7 +30,7 @@ class StrRayLibrarianServer { constructor() { this.server = new Server( { - name: "researcher", version: "1.14.1", + name: "researcher", version: "1.14.10", }, { capabilities: { @@ -141,7 +144,13 @@ class StrRayLibrarianServer { if (!fs.existsSync(dir)) return; - const entries = fs.readdirSync(dir, { withFileTypes: true }); + let entries: fs.Dirent[]; + try { + entries = fs.readdirSync(dir, { withFileTypes: true }); + } catch (err) { + frameworkLogger.log("mcps/researcher", "searchCodebase", "warning", { message: `Failed to read directory: ${dir}`, error: String(err) }); + return; + } for (const entry of entries) { if (results.length >= maxResults) break; @@ -161,7 +170,13 @@ class StrRayLibrarianServer { if (entry.isDirectory()) { searchFiles(fullPath, depth + 1); } else if (entry.isFile() && entry.name.endsWith(fileExtension)) { - const content = fs.readFileSync(fullPath, "utf-8"); + let content: string; + try { + content = fs.readFileSync(fullPath, "utf-8"); + } catch (err) { + frameworkLogger.log("mcps/researcher", "searchCodebase", "warning", { message: `Failed to read file: ${fullPath}`, error: String(err) }); + continue; + } const lines = content.split("\n"); const matches: string[] = []; @@ -185,7 +200,7 @@ class StrRayLibrarianServer { } }; - searchFiles(path.join(searchDir, "src")); + searchFiles(searchDir); if (results.length === 0) { return { @@ -241,7 +256,13 @@ class StrRayLibrarianServer { if (depth > 5 || implementations.length >= 5) return; if (!fs.existsSync(dir)) return; - const entries = fs.readdirSync(dir, { withFileTypes: true }); + let entries: fs.Dirent[]; + try { + entries = fs.readdirSync(dir, { withFileTypes: true }); + } catch (err) { + frameworkLogger.log("mcps/researcher", "findImplementation", "warning", { message: `Failed to read directory: ${dir}`, error: String(err) }); + return; + } for (const entry of entries) { if (implementations.length >= 5) break; @@ -262,7 +283,13 @@ class StrRayLibrarianServer { entry.isFile() && (entry.name.endsWith(".ts") || entry.name.endsWith(".js")) ) { - const content = fs.readFileSync(fullPath, "utf-8"); + let content: string; + try { + content = fs.readFileSync(fullPath, "utf-8"); + } catch (err) { + frameworkLogger.log("mcps/researcher", "findImplementation", "warning", { message: `Failed to read file: ${fullPath}`, error: String(err) }); + continue; + } // Look for the feature in content if (content.toLowerCase().includes(feature.toLowerCase())) { @@ -289,7 +316,7 @@ class StrRayLibrarianServer { } }; - searchIn(path.join(searchDir, "src")); + searchIn(searchDir); if (implementations.length === 0) { return { @@ -337,23 +364,41 @@ class StrRayLibrarianServer { const searchDir = process.cwd(); let documentation = ""; - // Search for README or docs - const docFiles = ["README.md", "docs/README.md", "DOCS.md"]; - - for (const docFile of docFiles) { - const docPath = path.join(searchDir, docFile); - if (fs.existsSync(docPath)) { - const content = fs.readFileSync(docPath, "utf-8"); - // Look for target in docs - const lines = content.split("\n"); - const targetLines = lines.filter((line) => - line.toLowerCase().includes(target.toLowerCase()), - ); - - if (targetLines.length > 0) { - documentation = targetLines.slice(0, 10).join("\n"); - break; + // Search for documentation - any .md files in project root and docs/ directory + const docSearchDirs = [searchDir, path.join(searchDir, "docs")]; + const docFiles: string[] = []; + + for (const docDir of docSearchDirs) { + try { + if (!fs.existsSync(docDir)) continue; + const entries = fs.readdirSync(docDir, { withFileTypes: true }); + for (const entry of entries) { + if (entry.isFile() && entry.name.endsWith(".md")) { + docFiles.push(path.join(docDir, entry.name)); + } } + } catch (err) { + frameworkLogger.log("mcps/researcher", "getDocumentation", "warning", { message: `Failed to scan docs directory: ${docDir}`, error: String(err) }); + } + } + + for (const docPath of docFiles) { + let content: string; + try { + content = fs.readFileSync(docPath, "utf-8"); + } catch (err) { + frameworkLogger.log("mcps/researcher", "getDocumentation", "warning", { message: `Failed to read doc file: ${docPath}`, error: String(err) }); + continue; + } + // Look for target in docs + const lines = content.split("\n"); + const targetLines = lines.filter((line) => + line.toLowerCase().includes(target.toLowerCase()), + ); + + if (targetLines.length > 0) { + documentation = targetLines.slice(0, 10).join("\n"); + break; } } @@ -393,7 +438,15 @@ class StrRayLibrarianServer { async run(): Promise { const transport = new StdioServerTransport(); await this.server.connect(transport); + + let parentCheckTimer: ReturnType | null = null; + const cleanup = async (signal: string) => { + if (parentCheckTimer !== null) { + clearTimeout(parentCheckTimer); + parentCheckTimer = null; + } + const timeout = setTimeout(() => { frameworkLogger.log("mcps/researcher", "shutdown", "error", { message: "Graceful shutdown timeout, forcing exit..." }); process.exit(1); @@ -419,13 +472,14 @@ class StrRayLibrarianServer { const checkParent = () => { try { process.kill(process.ppid, 0); - setTimeout(checkParent, 1000); + parentCheckTimer = setTimeout(checkParent, 1000); } catch (error) { + parentCheckTimer = null; cleanup("parent-process-death"); } }; - setTimeout(checkParent, 2000); + parentCheckTimer = setTimeout(checkParent, 2000); process.on("uncaughtException", (error) => { frameworkLogger.log("mcps/researcher", "uncaughtException", "error", { message: `Uncaught Exception: ${String(error)}` }); @@ -436,9 +490,6 @@ class StrRayLibrarianServer { frameworkLogger.log("mcps/researcher", "unhandledRejection", "error", { message: `Unhandled Rejection: ${String(reason)}` }); cleanup("unhandledRejection"); }); - - process.on("SIGINT", cleanup); - process.on("SIGTERM", cleanup); } } diff --git a/src/mcps/security-scan.server.ts b/src/mcps/security-scan.server.ts index ddebe9004..4bff5dff7 100644 --- a/src/mcps/security-scan.server.ts +++ b/src/mcps/security-scan.server.ts @@ -10,7 +10,7 @@ import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js"; -import { execSync } from "child_process"; +import { execFileSync } from "child_process"; import fs from "fs"; import path from "path"; import { @@ -25,7 +25,7 @@ class StrRaySecurityScanServer { constructor() { this.server = new Server( { - name: "security-scan", version: "1.14.1", + name: "security-scan", version: "1.14.10", }, { capabilities: { @@ -99,13 +99,25 @@ class StrRaySecurityScanServer { this.server.setRequestHandler(CallToolRequestSchema, async (request) => { const { name, arguments: args } = request.params; - switch (name) { - case "security-scan": - return await this.handleSecurityScan(args); - case "dependency-audit": - return await this.handleDependencyAudit(args); - default: - throw new Error(`Unknown tool: ${name}`); + try { + switch (name) { + case "security-scan": + return await this.handleSecurityScan(args); + case "dependency-audit": + return await this.handleDependencyAudit(args); + default: + throw new Error(`Unknown tool: ${name}`); + } + } catch (error) { + frameworkLogger.log("mcps/security-scan", "tool-handler", "error", { tool: name, error: String(error) }); + return { + content: [ + { + type: "text", + text: `Error executing tool "${name}": ${error instanceof Error ? error.message : String(error)}`, + }, + ], + }; } }); } @@ -126,9 +138,11 @@ class StrRaySecurityScanServer { try { // 1. Dependency Vulnerability Scanning if (scope === "dependencies" || scope === "full") { + const detectedPm = this.detectPackageManager("auto"); const depResults = await this.scanDependencies( auditLevel, includeOutdated, + detectedPm, ); results.vulnerabilities.push(...depResults.vulnerabilities); results.recommendations.push(...depResults.recommendations); @@ -182,7 +196,8 @@ ${results.recommendations.map((r) => `β€’ ${r}`).join("\n")} const auditLevel = args.auditLevel || "moderate"; try { - const results = await this.scanDependencies(auditLevel, true); + const detectedPm = this.detectPackageManager(packageManager); + const results = await this.scanDependencies(auditLevel, true, detectedPm); return { content: [ @@ -212,76 +227,147 @@ ${results.recommendations.map((r) => `β€’ ${r}`).join("\n") || "No recommendatio } } - private async scanDependencies(auditLevel: string, includeOutdated: boolean) { + private detectPackageManager(requested: string): string { + if (requested !== "auto") return requested; + + if (fs.existsSync("pnpm-lock.yaml")) return "pnpm"; + if (fs.existsSync("yarn.lock")) return "yarn"; + if (fs.existsSync("package-lock.json")) return "npm"; + return "npm"; + } + + private async scanDependencies(auditLevel: string, includeOutdated: boolean, packageManager: string) { + const ALLOWED_AUDIT_LEVELS = ["info", "low", "moderate", "high", "critical"]; const results = { secure: true, vulnerabilities: [] as string[], recommendations: [] as string[], }; + // Validate auditLevel to prevent command injection + const safeAuditLevel = ALLOWED_AUDIT_LEVELS.includes(auditLevel) ? auditLevel : "moderate"; + try { - // Check for npm - if (fs.existsSync("package.json")) { - // Run npm audit - try { - const auditOutput = execSync( - `npm audit --audit-level=${auditLevel} --json`, - { encoding: "utf8" }, + // Check for package.json + if (!fs.existsSync("package.json")) { + results.recommendations.push( + "No package.json found - not a Node.js project", + ); + return results; + } + + // Run audit using detected/explicit package manager + const pmCmd = packageManager === "yarn" ? "yarn" : packageManager === "pnpm" ? "pnpm" : "npm"; + + try { + const auditArgs = + packageManager === "yarn" + ? ["audit", "--level", safeAuditLevel, "--json"] + : ["audit", "--audit-level", safeAuditLevel, "--json"]; + + const auditOutput = execFileSync(pmCmd, auditArgs, { + encoding: "utf8", + stdio: ["pipe", "pipe", "pipe"], + }); + const auditData = JSON.parse(auditOutput); + + if ( + auditData.vulnerabilities && + Object.keys(auditData.vulnerabilities).length > 0 + ) { + results.secure = false; + results.vulnerabilities.push( + `${Object.keys(auditData.vulnerabilities).length} ${pmCmd} vulnerabilities found`, + ); + results.recommendations.push( + `Run "${pmCmd} audit fix" to address vulnerabilities`, ); - const auditData = JSON.parse(auditOutput); + } + } catch (error: any) { + // npm/yarn/pnpm audit returns non-zero exit code when vulnerabilities found + // The JSON output is in error.stdout + let auditData: any = null; + if (error && error.stdout) { + try { + auditData = JSON.parse(error.stdout); + } catch { + // stdout was not valid JSON, fall through + } + } - if ( - auditData.vulnerabilities && - Object.keys(auditData.vulnerabilities).length > 0 - ) { + if ( + auditData && + auditData.vulnerabilities && + Object.keys(auditData.vulnerabilities).length > 0 + ) { + results.secure = false; + const vulnCount = Object.keys(auditData.vulnerabilities).length; + const vulnEntries = Object.entries(auditData.vulnerabilities) + .filter(([, info]: [string, any]) => info && info.severity !== undefined) + .map(([name, info]: [string, any]) => ` - ${name} (${info.severity}): ${info.via?.[0]?.title || "unknown"}`); + results.vulnerabilities.push( + `${vulnCount} ${pmCmd} vulnerabilities found:\n${vulnEntries.join("\n")}`, + ); + results.recommendations.push( + `Run "${pmCmd} audit fix" to resolve vulnerabilities`, + ); + } else { + // Non-JSON parseable error; log it but don't mark as insecure + const errorMsg = error instanceof Error ? error.message : String(error); + if (errorMsg.includes("vulnerabilities") || errorMsg.includes("ELIFECYCLE")) { results.secure = false; - results.vulnerabilities.push( - `${Object.keys(auditData.vulnerabilities).length} npm vulnerabilities found`, - ); + results.vulnerabilities.push(`${pmCmd} audit detected vulnerabilities`); results.recommendations.push( - 'Run "npm audit fix" to address vulnerabilities', + `Run "${pmCmd} audit" for details and "${pmCmd} audit fix" to resolve`, ); } - } catch (error) { - // npm audit returns non-zero exit code when vulnerabilities found - const errorOutput = - error instanceof Error ? error.message : String(error); - if (errorOutput.includes("vulnerabilities")) { - results.secure = false; - results.vulnerabilities.push("NPM audit detected vulnerabilities"); + } + } + + // Check for outdated packages + if (includeOutdated) { + try { + const outdatedOutput = execFileSync(pmCmd, ["outdated", "--json"], { + encoding: "utf8", + stdio: ["pipe", "pipe", "pipe"], + }); + const outdatedData = JSON.parse(outdatedOutput); + + const outdatedCount = Object.keys(outdatedData).length; + if (outdatedCount > 0) { results.recommendations.push( - 'Run "npm audit" for details and "npm audit fix" to resolve', + `${outdatedCount} packages are outdated - consider updating`, ); + if (outdatedCount > 5) { + results.vulnerabilities.push( + "Many packages significantly outdated", + ); + } } - } - - // Check for outdated packages - if (includeOutdated) { - try { - const outdatedOutput = execSync("npm outdated --json", { - encoding: "utf8", - }); - const outdatedData = JSON.parse(outdatedOutput); - + } catch (error) { + // npm/yarn/pnpm outdated may return non-zero if packages are outdated or none found + // Try to parse stdout for structured data + let outdatedData: any = null; + if (error && typeof error === "object" && "stdout" in error && error.stdout) { + try { + outdatedData = JSON.parse((error as any).stdout); + } catch { + // not valid JSON, ignore + } + } + if (outdatedData && Object.keys(outdatedData).length > 0) { const outdatedCount = Object.keys(outdatedData).length; - if (outdatedCount > 0) { - results.recommendations.push( - `${outdatedCount} packages are outdated - consider updating`, + results.recommendations.push( + `${outdatedCount} packages are outdated - consider updating`, + ); + if (outdatedCount > 5) { + results.vulnerabilities.push( + "Many packages significantly outdated", ); - if (outdatedCount > 5) { - results.vulnerabilities.push( - "Many packages significantly outdated", - ); - } } - } catch (error) { - // npm outdated might fail if no outdated packages } + // else: no outdated packages or can't determine, skip silently } - } else { - results.recommendations.push( - "No package.json found - not a Node.js project", - ); } } catch (error) { results.vulnerabilities.push( @@ -337,7 +423,7 @@ ${results.recommendations.map((r) => `β€’ ${r}`).join("\n") || "No recommendatio return results; } - private findCodeFiles(): string[] { + private findCodeFiles(maxDepth: number = 10): string[] { // Use language detector to find supported extensions const projectRoot = process.cwd(); const projectLanguage = detectProjectLanguage(projectRoot); @@ -365,7 +451,9 @@ ${results.recommendations.map((r) => `β€’ ${r}`).join("\n") || "No recommendatio ]; const files: string[] = []; - function scanDir(dir: string) { + function scanDir(dir: string, currentDepth: number) { + if (currentDepth > maxDepth) return; + try { const items = fs.readdirSync(dir); @@ -378,7 +466,7 @@ ${results.recommendations.map((r) => `β€’ ${r}`).join("\n") || "No recommendatio !item.startsWith(".") && item !== "node_modules" ) { - scanDir(fullPath); + scanDir(fullPath, currentDepth + 1); } else if ( stat.isFile() && extensions.some((ext) => item.endsWith(ext)) @@ -391,7 +479,7 @@ ${results.recommendations.map((r) => `β€’ ${r}`).join("\n") || "No recommendatio } } - scanDir("."); + scanDir(".", 0); return files.slice(0, 50); // Limit to first 50 files for performance } @@ -402,20 +490,43 @@ ${results.recommendations.map((r) => `β€’ ${r}`).join("\n") || "No recommendatio recommendations: [] as string[], }; + // Skip test files to reduce false positives + const normalizedPath = filePath.replace(/\\/g, "/"); + if ( + /(__tests__|__mocks__|\.test\.|\.spec\.|_test\.|_spec\.|tests?\/|specs?\/|\.stories\.)/i.test( + normalizedPath, + ) || + /\/test[^/]*\//i.test(normalizedPath) + ) { + return issues; + } + + // Filter out comment lines before scanning + const nonCommentLines = content.split("\n").filter((line) => { + const trimmed = line.trim(); + // Skip single-line comments + if (/^\s*(\/\/|#|\/\/\/|--|\/\*|\*)/.test(trimmed)) return false; + return true; + }); + const filteredContent = nonCommentLines.join("\n"); + // Common security patterns to check const patterns = [ { - regex: /password\s*=\s*["'][^"']*["']/gi, + regex: /password\s*=\s*["'](?!\s*["'])[^"']*["']/gi, + exclude: /password\s*=\s*["']\s*["']/gi, // empty string assignments type: "vulnerability", message: "Hardcoded password detected", }, { - regex: /api[_-]?key\s*=\s*["'][^"']*["']/gi, + regex: /api[_-]?key\s*=\s*["'](?!\s*["'])[^"']*["']/gi, + exclude: /api[_-]?key\s*=\s*["']\s*["']/gi, type: "vulnerability", message: "Hardcoded API key detected", }, { - regex: /secret\s*=\s*["'][^"']*["']/gi, + regex: /secret\s*=\s*["'](?!\s*["'])[^"']*["']/gi, + exclude: /secret\s*=\s*["']\s*["']/gi, type: "vulnerability", message: "Hardcoded secret detected", }, @@ -442,20 +553,47 @@ ${results.recommendations.map((r) => `β€’ ${r}`).join("\n") || "No recommendatio ]; for (const pattern of patterns) { - const matches = content.match(pattern.regex); - if (matches) { - const message = `${pattern.message} in ${filePath} (${matches.length} instances)`; - - if (pattern.type === "vulnerability") { - issues.vulnerabilities.push(message); - } else if (pattern.type === "threat") { - issues.threats.push(message); + // For patterns with exclude rules, check both + if (pattern.exclude && pattern.exclude.test(filteredContent)) { + // Remove matches that are empty string assignments + const allMatches = Array.from(filteredContent.matchAll(pattern.regex)); + const excludeMatches = Array.from(filteredContent.matchAll(pattern.exclude)); + // Filter: only keep matches where the matched string is NOT an empty assignment + const excludePositions = new Set( + excludeMatches.map((m) => m.index), + ); + const validMatches = allMatches.filter( + (m) => !excludePositions.has(m.index), + ); + if (validMatches.length > 0) { + const message = `${pattern.message} in ${filePath} (${validMatches.length} instances)`; + if (pattern.type === "vulnerability") { + issues.vulnerabilities.push(message); + } else if (pattern.type === "threat") { + issues.threats.push(message); + } + if (pattern.type !== "info") { + issues.recommendations.push( + `Review and fix ${pattern.message.toLowerCase()} in ${filePath}`, + ); + } } + } else { + const matches = filteredContent.match(pattern.regex); + if (matches) { + const message = `${pattern.message} in ${filePath} (${matches.length} instances)`; + + if (pattern.type === "vulnerability") { + issues.vulnerabilities.push(message); + } else if (pattern.type === "threat") { + issues.threats.push(message); + } - if (pattern.type !== "info") { - issues.recommendations.push( - `Review and fix ${pattern.message.toLowerCase()} in ${filePath}`, - ); + if (pattern.type !== "info") { + issues.recommendations.push( + `Review and fix ${pattern.message.toLowerCase()} in ${filePath}`, + ); + } } } } diff --git a/src/mcps/state-manager.server.ts b/src/mcps/state-manager.server.ts index f2cb91d6e..aec332164 100644 --- a/src/mcps/state-manager.server.ts +++ b/src/mcps/state-manager.server.ts @@ -23,7 +23,7 @@ class StrRayStateManagerServer { constructor() { this.server = new Server( { - name: "state-manager", version: "1.14.1", + name: "state-manager", version: "1.14.10", }, { capabilities: { @@ -99,6 +99,7 @@ class StrRayStateManagerServer { "error", { error: String(error) }, ); + throw error; } } @@ -217,25 +218,34 @@ class StrRayStateManagerServer { // Handle tool calls this.server.setRequestHandler(CallToolRequestSchema, async (request) => { - const { name, arguments: args } = request.params; - - switch (name) { - case "get-state": - return await this.handleGetState(args); - case "set-state": - return await this.handleSetState(args); - case "delete-state": - return await this.handleDeleteState(args); - case "list-state": - return await this.handleListState(args); - case "backup-state": - return await this.handleBackupState(args); - case "restore-state": - return await this.handleRestoreState(args); - case "validate-state": - return await this.handleValidateState(args); - default: - throw new Error(`Unknown tool: ${name}`); + try { + const { name, arguments: args } = request.params; + + switch (name) { + case "get-state": + return await this.handleGetState(args); + case "set-state": + return await this.handleSetState(args); + case "delete-state": + return await this.handleDeleteState(args); + case "list-state": + return await this.handleListState(args); + case "backup-state": + return await this.handleBackupState(args); + case "restore-state": + return await this.handleRestoreState(args); + case "validate-state": + return await this.handleValidateState(args); + default: + throw new Error(`Unknown tool: ${name}`); + } + } catch (error) { + return { + content: [{ + type: "text" as const, + text: `Error handling tool '${request.params.name}': ${error instanceof Error ? error.message : String(error)}`, + }], + }; } }); } @@ -627,10 +637,10 @@ ${results.repairedKeys.length > 0 ? `**Repaired Keys:**\n${results.repairedKeys. } { try { // Basic validation - check for circular references, etc. - JSON.stringify(value); + const serialized = JSON.stringify(value); // Check for reasonable size - const size = JSON.stringify(value).length; + const size = serialized.length; if (size > 1024 * 1024) { // 1MB limit return { @@ -686,11 +696,12 @@ ${results.repairedKeys.length > 0 ? `**Repaired Keys:**\n${results.repairedKeys. private findDependentKeys(key: string): string[] { const dependents: string[] = []; - + const quotedKey = `"${key}"`; for (const [otherKey, value] of this.state) { if (otherKey !== key && typeof value === "object" && value !== null) { const valueStr = JSON.stringify(value); - if (valueStr.includes(key) || valueStr.includes(`"${key}"`)) { + // Only match the key as a quoted string value (not substrings in URLs, etc.) + if (valueStr.includes(quotedKey)) { dependents.push(otherKey); } } diff --git a/src/orchestrator/universal-registry-bridge.ts b/src/orchestrator/universal-registry-bridge.ts index 7f3c75164..91ea36178 100644 --- a/src/orchestrator/universal-registry-bridge.ts +++ b/src/orchestrator/universal-registry-bridge.ts @@ -168,7 +168,7 @@ export class UniversalRegistryBridge { currentAgent = { name: nameMatch[1].trim(), description: "", - version: "1.14.1", + version: "1.14.10", }; inAgent = true; continue; diff --git a/src/skills/hermes-agent/SKILL.md b/src/skills/hermes-agent/SKILL.md new file mode 100644 index 000000000..03b7ffdf8 --- /dev/null +++ b/src/skills/hermes-agent/SKILL.md @@ -0,0 +1,257 @@ +--- +name: hermes-agent +description: Manage StringRay framework from Hermes Agent β€” install, configure, health-check, report, and publish. Covers CLI commands and MCP server integration for Hermes. +version: 1.0.0 +author: StringRay AI +license: MIT +metadata: + hermes: + tags: [StringRay, CLI, MCP, Framework, Orchestration] + related_skills: [] +prerequisites: + commands: [npx] +--- + +# StringRay Agent for Hermes + +Manage the StringRay AI framework from within Hermes Agent. Covers CLI commands (install, health, report, skills) and MCP server integration. + +## When to Use + +Use this skill when: +- User asks about StringRay status, health, or configuration +- User wants to install, validate, or fix StringRay +- User asks for reports, analytics, or capability info +- User wants to manage skills (install, list, status) +- User wants to publish agents to AgentStore +- User asks how to connect StringRay MCP servers to Hermes +- User asks about StringRay capabilities or available agents + +## CLI Commands + +### Setup and Diagnostics + +```bash +# Install StringRay in current project (detects/installs OpenCode, configures agents, sets up Codex) +npx strray-ai install + +# Initialize StringRay configuration only (lighter than install) +npx strray-ai init + +# Check framework configuration and plugin status +npx strray-ai status + +# Validate installation and dependencies +npx strray-ai validate + +# Full health check on framework components +npx strray-ai health + +# Diagnose issues without fixing them +npx strray-ai doctor + +# Auto-fix common framework issues (restores missing config files) +npx strray-ai fix + +# Debug command for troubleshooting +npx strray-ai debug +``` + +### Reporting and Analytics + +```bash +# Generate full analysis report +npx strray-ai report + +# Performance-focused report +npx strray-ai report --type performance + +# Agent invocation report +npx strray-ai report --type agent-usage + +# Save report to file +npx strray-ai report -o report.json + +# Pattern analysis and insights +npx strray-ai analytics + +# Analyze last N task completions +npx strray-ai analytics --limit 50 +``` + +### Capabilities + +```bash +# Show all available StringRay capabilities, agents, and features +npx strray-ai capabilities +``` + +### Skills Management + +```bash +# Show starter packs and available registry sources +npx strray-ai skill:install + +# Install from registry +npx strray-ai skill:install agency-agents # 170+ agency agent definitions +npx strray-ai skill:install superpowers # 14 agentic workflow skills (TDD, debugging, etc.) +npx strray-ai skill:install minimax # Frontend, fullstack, Android, iOS skills +npx strray-ai skill:install gemini-skills # Official Google Gemini skills +npx strray-ai skill:install anthropic-skills # Official Anthropic/Claude skills + +# Install from any git repo +npx strray-ai skill:install + +# Install from specific subdirectory in a repo +npx strray-ai skill:install --path skills/typescript + +# List all 10 bundled registry sources +npx strray-ai skill:registry list + +# Show all installed skills with license info +npx strray-ai antigravity status +``` + +### Agent Publishing + +```bash +# Package agent for AgentStore +npx strray-ai publish-agent --agent + +# Preview without publishing +npx strray-ai publish-agent --agent --dry-run + +# Publish specific version +npx strray-ai publish-agent --agent --version 2.0.0 +``` + +### Inference + +```bash +# Run autonomous inference improvement cycle +npx strray-ai inference:improve + +# Start/stop autonomous inference tuner service +npx strray-ai inference:tuner +``` + +## MCP Server Integration with Hermes + +StringRay ships 15 MCP servers that Hermes can connect to. Each exposes tools Hermes calls directly β€” no prompts, no proxies. + +### Server Overview + +| MCP Server | Key Tools | Purpose | +|-----------|----------|---------| +| `strray-architect-tools` | codebase_structure, dependency_analysis, context_analysis, architecture_assessment | Project analysis and architectural health | +| `strray-auto-format` | auto_format, format_check | Prettier + ESLint + TypeScript formatting | +| `strray-enforcer` | rule_validation, codex_enforcement, quality_gate_check, run_pre_commit_validation | Codex compliance and quality gates | +| `strray-estimation` | validate_estimate, start_tracking, complete_tracking, get_accuracy_report | Task estimation and time tracking | +| `strray-framework-help` | strray_get_capabilities, strray_get_commands, strray_explain_capability | Framework reference and docs | +| `strray-lint` | lint, lint_check | ESLint validation with auto-fix | +| `strray-orchestrator` | orchestrate_task, analyze_complexity, get_orchestration_status, optimize_orchestration | Multi-agent task planning | +| `strray-researcher` | search_codebase, find_implementation, get_documentation | Codebase search and pattern finding | +| `strray-security-scan` | security_scan, dependency_audit | Vulnerability scanning | +| `strray-state-manager` | get_state, set_state, delete_state, list_state, backup_state, restore_state | Persistent key-value state | + +### Setup + +Add to `~/.hermes/config.yaml`: + +```yaml +mcp_servers: + strray-architect-tools: + command: node + args: ["./node_modules/strray-ai/dist/mcps/architect-tools.server.js"] + timeout: 30 + strray-auto-format: + command: node + args: ["./node_modules/strray-ai/dist/mcps/auto-format.server.js"] + timeout: 30 + strray-enforcer: + command: node + args: ["./node_modules/strray-ai/dist/mcps/enforcer-tools.server.js"] + timeout: 30 + strray-estimation: + command: node + args: ["./node_modules/strray-ai/dist/mcps/estimation.server.js"] + timeout: 30 + strray-framework-help: + command: node + args: ["./node_modules/strray-ai/dist/mcps/framework-help.server.js"] + timeout: 30 + strray-lint: + command: node + args: ["./node_modules/strray-ai/dist/mcps/lint.server.js"] + timeout: 30 + strray-orchestrator: + command: node + args: ["./node_modules/strray-ai/dist/mcps/orchestrator/server.js"] + timeout: 60 + strray-researcher: + command: node + args: ["./node_modules/strray-ai/dist/mcps/researcher.server.js"] + timeout: 60 + strray-security-scan: + command: node + args: ["./node_modules/strray-ai/dist/mcps/security-scan.server.js"] + timeout: 30 + strray-state-manager: + command: node + args: ["./node_modules/strray-ai/dist/mcps/state-manager.server.js"] + timeout: 30 +``` + +### Tool Naming Convention + +Hermes prefixes MCP tools as `mcp_strray__`. For example: +- `mcp_strray_architect_tools_codebase_structure` +- `mcp_strray_enforcer_rule_validation` +- `mcp_strray_lint_lint` + +This is automatic and not configurable. + +### How MCP and CLI Complement Each Other + +| Capability | MCP Server | CLI Command | +|-----------|-----------|-------------| +| Analyze code | architect-tools | β€” | +| Lint/format | lint, auto-format | β€” | +| Security scan | security-scan | β€” | +| Orchestrate tasks | orchestrator | β€” | +| Manage state | state-manager | β€” | +| **Install framework** | β€” | `install`, `init` | +| **Health check** | β€” | `health`, `validate`, `doctor` | +| **Generate reports** | β€” | `report`, `analytics` | +| **Install skills** | β€” | `skill:install` | +| **Publish agents** | β€” | `publish-agent` | +| **View capabilities** | framework-help | `capabilities` | + +MCP servers = runtime tools (analyze, lint, scan, orchestrate while coding) +CLI commands = framework management (install, configure, report, publish) + +## Quick Decision Guide + +| User Says | Run | +|----------|-----| +| "Is StringRay set up?" | `npx strray-ai health` | +| "Fix StringRay" | `npx strray-ai fix` | +| "What can StringRay do?" | `npx strray-ai capabilities` | +| "How are agents performing?" | `npx strray-ai report --type agent-usage` | +| "Install the X skill pack" | `npx strray-ai skill:install ` | +| "What skills are installed?" | `npx strray-ai antigravity status` | +| "Publish agent X" | `npx strray-ai publish-agent --agent X` | +| "Set up MCP in Hermes" | Add config to `~/.hermes/config.yaml` (see above) | + +## Pitfalls + +- `install` is heavyweight β€” detects and may install OpenCode. Use `init` for config-only. +- `report` goes to stdout. Use `-o ` to save to disk. +- `skill:install` with a GitHub URL clones the repo. Requires network. +- Some commands look for `.opencode/` in CWD. Run from project root. +- `publish-agent` requires AgentStore auth. Fails silently without it. +- Orchestrator MCP server path is nested: `dist/mcps/orchestrator/server.js` (not `orchestrator.server.js`). +- Use absolute paths in MCP args if Hermes CWD differs from project root. +- Increase timeout to 60s for orchestrator and researcher β€” they do heavier analysis. +- auto-format and lint need Prettier/ESLint in the project to do real formatting. +- state-manager persists to `.opencode/state/mcp-state.json` β€” survives Hermes restarts. diff --git a/src/skills/registry.json b/src/skills/registry.json index d50b04f11..409e167e3 100644 --- a/src/skills/registry.json +++ b/src/skills/registry.json @@ -1,5 +1,5 @@ { - "version": "2.0.0", + "version": "1.14.10", "description": "StringRay Skills Registry - recommended skill sources for consumers", "sources": [ { diff --git a/strray/codex.json b/strray/codex.json index 463ef7ffd..de4d06dd6 100644 --- a/strray/codex.json +++ b/strray/codex.json @@ -1,5 +1,5 @@ { - "version": "1.14.1", + "version": "1.14.10", "lastUpdated": "2026-03-09", "errorPreventionTarget": 0.996, "terms": { diff --git a/strray/config.json b/strray/config.json index 850a646eb..8705e02f4 100644 --- a/strray/config.json +++ b/strray/config.json @@ -1,6 +1,6 @@ { "$schema": "./config.schema.json", - "version": "1.14.1", + "version": "1.14.10", "description": "StringRay Framework - Token Management & Performance Configuration", "token_management": { "maxPromptTokens": 20000, diff --git a/strray/features.json b/strray/features.json index e176961a1..188c144d2 100644 --- a/strray/features.json +++ b/strray/features.json @@ -1,6 +1,6 @@ { "$schema": "./features.schema.json", - "version": "1.14.1", + "version": "1.14.10", "description": "StringRay Framework - Unified Feature Configuration", "token_optimization": { "enabled": true, diff --git a/strray/integrations.json b/strray/integrations.json index 81d7620eb..0f5f1b186 100644 --- a/strray/integrations.json +++ b/strray/integrations.json @@ -4,19 +4,19 @@ "openclaw": { "enabled": false, "type": "external-service", - "version": "1.14.1", + "version": "1.14.10", "config": {} }, "python-bridge": { "enabled": false, "type": "protocol-bridge", - "version": "1.14.1", + "version": "1.14.10", "config": {} }, "react": { "enabled": false, "type": "framework-adapter", - "version": "1.14.1", + "version": "1.14.10", "config": {} } } diff --git a/tests/config/package.json b/tests/config/package.json index 353328fbc..964c858b8 100644 --- a/tests/config/package.json +++ b/tests/config/package.json @@ -1,4 +1,4 @@ { "name": "test-config", - "version": "1.14.1" + "version": "1.14.10" } diff --git a/tweets/tweets-2026-03-10T16-59-41-258Z.json b/tweets/tweets-2026-03-10T16-59-41-258Z.json index 809f1e29f..77a50533e 100644 --- a/tweets/tweets-2026-03-10T16-59-41-258Z.json +++ b/tweets/tweets-2026-03-10T16-59-41-258Z.json @@ -1,6 +1,6 @@ { "generated": "2026-03-10T16-59-41-258Z", - "version": "1.14.1", + "version": "1.14.10", "releases": [ { "version": "v1.7.5", diff --git a/tweets/tweets-2026-03-10T17-00-00-997Z.json b/tweets/tweets-2026-03-10T17-00-00-997Z.json index b1da0d888..f9beb5dca 100644 --- a/tweets/tweets-2026-03-10T17-00-00-997Z.json +++ b/tweets/tweets-2026-03-10T17-00-00-997Z.json @@ -1,6 +1,6 @@ { "generated": "2026-03-10T17-00-00-997Z", - "version": "1.14.1", + "version": "1.14.10", "releases": [ { "version": "v1.7.5", diff --git a/tweets/tweets-2026-03-10T17-03-37-490Z.json b/tweets/tweets-2026-03-10T17-03-37-490Z.json index 339dc3675..882f45bd1 100644 --- a/tweets/tweets-2026-03-10T17-03-37-490Z.json +++ b/tweets/tweets-2026-03-10T17-03-37-490Z.json @@ -1,6 +1,6 @@ { "generated": "2026-03-10T17-03-37-490Z", - "version": "1.14.1", + "version": "1.14.10", "releases": [ { "version": "v1.7.5", diff --git a/tweets/tweets-2026-03-10T17-05-21-229Z.json b/tweets/tweets-2026-03-10T17-05-21-229Z.json index f3947128a..769493e3d 100644 --- a/tweets/tweets-2026-03-10T17-05-21-229Z.json +++ b/tweets/tweets-2026-03-10T17-05-21-229Z.json @@ -1,6 +1,6 @@ { "generated": "2026-03-10T17-05-21-229Z", - "version": "1.14.1", + "version": "1.14.10", "releases": [ { "version": "v1.7.5", diff --git a/tweets/tweets-2026-03-10T17-07-06-807Z.json b/tweets/tweets-2026-03-10T17-07-06-807Z.json index 10cca6fa2..eb981cf82 100644 --- a/tweets/tweets-2026-03-10T17-07-06-807Z.json +++ b/tweets/tweets-2026-03-10T17-07-06-807Z.json @@ -1,6 +1,6 @@ { "generated": "2026-03-10T17-07-06-807Z", - "version": "1.14.1", + "version": "1.14.10", "releases": [ { "version": "v1.7.5", diff --git a/tweets/tweets-2026-03-10T17-23-41-774Z.json b/tweets/tweets-2026-03-10T17-23-41-774Z.json index c455a8cb0..beff37dfe 100644 --- a/tweets/tweets-2026-03-10T17-23-41-774Z.json +++ b/tweets/tweets-2026-03-10T17-23-41-774Z.json @@ -1,6 +1,6 @@ { "generated": "2026-03-10T17-23-41-774Z", - "version": "1.14.1", + "version": "1.14.10", "releases": [ { "version": "v1.7.5", diff --git a/tweets/tweets-2026-03-10T17-29-59-962Z.json b/tweets/tweets-2026-03-10T17-29-59-962Z.json index 3b5b22e76..8c581c675 100644 --- a/tweets/tweets-2026-03-10T17-29-59-962Z.json +++ b/tweets/tweets-2026-03-10T17-29-59-962Z.json @@ -1,6 +1,6 @@ { "generated": "2026-03-10T17-29-59-962Z", - "version": "1.14.1", + "version": "1.14.10", "releases": [ { "version": "v1.7.5", diff --git a/tweets/tweets-2026-03-10T17-30-26-755Z.json b/tweets/tweets-2026-03-10T17-30-26-755Z.json index da9b3d3b3..9fcc9b3f7 100644 --- a/tweets/tweets-2026-03-10T17-30-26-755Z.json +++ b/tweets/tweets-2026-03-10T17-30-26-755Z.json @@ -1,6 +1,6 @@ { "generated": "2026-03-10T17-30-26-755Z", - "version": "1.14.1", + "version": "1.14.10", "releases": [ { "version": "v1.7.5", diff --git a/tweets/tweets-2026-03-10T17-33-01-728Z.json b/tweets/tweets-2026-03-10T17-33-01-728Z.json index d191753a7..b16339cab 100644 --- a/tweets/tweets-2026-03-10T17-33-01-728Z.json +++ b/tweets/tweets-2026-03-10T17-33-01-728Z.json @@ -1,6 +1,6 @@ { "generated": "2026-03-10T17-33-01-728Z", - "version": "1.14.1", + "version": "1.14.10", "releases": [ { "version": "v1.7.5", diff --git a/tweets/tweets-2026-03-10T17-33-52-423Z.json b/tweets/tweets-2026-03-10T17-33-52-423Z.json index d6fa30171..c6281f817 100644 --- a/tweets/tweets-2026-03-10T17-33-52-423Z.json +++ b/tweets/tweets-2026-03-10T17-33-52-423Z.json @@ -1,6 +1,6 @@ { "generated": "2026-03-10T17-33-52-423Z", - "version": "1.14.1", + "version": "1.14.10", "releases": [ { "version": "v1.7.5",