4runr-os 2.10.85 → 2.10.86
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/SETUP.md +2 -2
- package/USER-PRIVACY.md +2 -2
- package/apps/os-server/DEPLOYMENT.md +426 -0
- package/apps/os-server/JWT-RATE-LIMIT-VALIDATION.md +462 -0
- package/apps/os-server/PERSISTENCE-AND-AUTH.md +227 -0
- package/apps/os-server/PHASE5-TESTING.md +222 -0
- package/apps/os-server/README.md +368 -0
- package/apps/os-server/TROUBLESHOOTING.md +541 -0
- package/apps/os-server/dist/apps/os-server/src/adapters/gateway-cancel-adapter.d.ts +3 -0
- package/apps/os-server/dist/apps/os-server/src/adapters/gateway-cancel-adapter.d.ts.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/adapters/gateway-cancel-adapter.js +28 -0
- package/apps/os-server/dist/apps/os-server/src/adapters/gateway-cancel-adapter.js.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/adapters/redis-sentinel-publisher.d.ts +23 -0
- package/apps/os-server/dist/apps/os-server/src/adapters/redis-sentinel-publisher.d.ts.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/adapters/redis-sentinel-publisher.js +95 -0
- package/apps/os-server/dist/apps/os-server/src/adapters/redis-sentinel-publisher.js.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/adapters/sentinel-event-stream.d.ts +14 -0
- package/apps/os-server/dist/apps/os-server/src/adapters/sentinel-event-stream.d.ts.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/adapters/sentinel-event-stream.js +69 -0
- package/apps/os-server/dist/apps/os-server/src/adapters/sentinel-event-stream.js.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/agents/definitions-simple.d.ts +10 -0
- package/apps/os-server/dist/apps/os-server/src/agents/definitions-simple.d.ts.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/agents/definitions-simple.js +377 -0
- package/apps/os-server/dist/apps/os-server/src/agents/definitions-simple.js.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/agents/definitions.d.ts +14 -0
- package/apps/os-server/dist/apps/os-server/src/agents/definitions.d.ts.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/agents/definitions.js +210 -0
- package/apps/os-server/dist/apps/os-server/src/agents/definitions.js.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/agents/local-model-provider.d.ts +25 -0
- package/apps/os-server/dist/apps/os-server/src/agents/local-model-provider.d.ts.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/agents/local-model-provider.js +144 -0
- package/apps/os-server/dist/apps/os-server/src/agents/local-model-provider.js.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/agents/tools.d.ts +24 -0
- package/apps/os-server/dist/apps/os-server/src/agents/tools.d.ts.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/agents/tools.js +110 -0
- package/apps/os-server/dist/apps/os-server/src/agents/tools.js.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/ai-providers/anthropic-provider.d.ts +14 -0
- package/apps/os-server/dist/apps/os-server/src/ai-providers/anthropic-provider.d.ts.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/ai-providers/anthropic-provider.js +139 -0
- package/apps/os-server/dist/apps/os-server/src/ai-providers/anthropic-provider.js.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/ai-providers/index.d.ts +6 -0
- package/apps/os-server/dist/apps/os-server/src/ai-providers/index.d.ts.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/ai-providers/index.js +6 -0
- package/apps/os-server/dist/apps/os-server/src/ai-providers/index.js.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/ai-providers/openai-provider.d.ts +14 -0
- package/apps/os-server/dist/apps/os-server/src/ai-providers/openai-provider.d.ts.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/ai-providers/openai-provider.js +136 -0
- package/apps/os-server/dist/apps/os-server/src/ai-providers/openai-provider.js.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/ai-providers/provider-manager.d.ts +18 -0
- package/apps/os-server/dist/apps/os-server/src/ai-providers/provider-manager.d.ts.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/ai-providers/provider-manager.js +91 -0
- package/apps/os-server/dist/apps/os-server/src/ai-providers/provider-manager.js.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/ai-providers/redis-credentials-store.d.ts +15 -0
- package/apps/os-server/dist/apps/os-server/src/ai-providers/redis-credentials-store.d.ts.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/ai-providers/redis-credentials-store.js +181 -0
- package/apps/os-server/dist/apps/os-server/src/ai-providers/redis-credentials-store.js.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/ai-providers/types.d.ts +54 -0
- package/apps/os-server/dist/apps/os-server/src/ai-providers/types.d.ts.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/ai-providers/types.js +2 -0
- package/apps/os-server/dist/apps/os-server/src/ai-providers/types.js.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/config/persistence.d.ts +5 -0
- package/apps/os-server/dist/apps/os-server/src/config/persistence.d.ts.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/config/persistence.js +14 -0
- package/apps/os-server/dist/apps/os-server/src/config/persistence.js.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/crypto/envelope.d.ts +28 -0
- package/apps/os-server/dist/apps/os-server/src/crypto/envelope.d.ts.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/crypto/envelope.js +111 -0
- package/apps/os-server/dist/apps/os-server/src/crypto/envelope.js.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/crypto/mfa-storage.d.ts +6 -0
- package/apps/os-server/dist/apps/os-server/src/crypto/mfa-storage.d.ts.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/crypto/mfa-storage.js +61 -0
- package/apps/os-server/dist/apps/os-server/src/crypto/mfa-storage.js.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/db/docker-manager.d.ts +21 -0
- package/apps/os-server/dist/apps/os-server/src/db/docker-manager.d.ts.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/db/docker-manager.js +166 -0
- package/apps/os-server/dist/apps/os-server/src/db/docker-manager.js.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/db/init.d.ts +11 -0
- package/apps/os-server/dist/apps/os-server/src/db/init.d.ts.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/db/init.js +202 -0
- package/apps/os-server/dist/apps/os-server/src/db/init.js.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/db/memory-db.d.ts +149 -0
- package/apps/os-server/dist/apps/os-server/src/db/memory-db.d.ts.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/db/memory-db.js +295 -0
- package/apps/os-server/dist/apps/os-server/src/db/memory-db.js.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/db/prisma.d.ts +4 -0
- package/apps/os-server/dist/apps/os-server/src/db/prisma.d.ts.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/db/prisma.js +31 -0
- package/apps/os-server/dist/apps/os-server/src/db/prisma.js.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/db/redis.d.ts +5 -0
- package/apps/os-server/dist/apps/os-server/src/db/redis.d.ts.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/db/redis.js +69 -0
- package/apps/os-server/dist/apps/os-server/src/db/redis.js.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/devkit/agents-api.d.ts +3 -0
- package/apps/os-server/dist/apps/os-server/src/devkit/agents-api.d.ts.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/devkit/agents-api.js +369 -0
- package/apps/os-server/dist/apps/os-server/src/devkit/agents-api.js.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/devkit/metrics-parser.d.ts +46 -0
- package/apps/os-server/dist/apps/os-server/src/devkit/metrics-parser.d.ts.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/devkit/metrics-parser.js +114 -0
- package/apps/os-server/dist/apps/os-server/src/devkit/metrics-parser.js.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/devkit/middleware.d.ts +9 -0
- package/apps/os-server/dist/apps/os-server/src/devkit/middleware.d.ts.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/devkit/middleware.js +23 -0
- package/apps/os-server/dist/apps/os-server/src/devkit/middleware.js.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/devkit/routes.d.ts +3 -0
- package/apps/os-server/dist/apps/os-server/src/devkit/routes.d.ts.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/devkit/routes.js +270 -0
- package/apps/os-server/dist/apps/os-server/src/devkit/routes.js.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/devkit/tools-api.d.ts +3 -0
- package/apps/os-server/dist/apps/os-server/src/devkit/tools-api.d.ts.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/devkit/tools-api.js +183 -0
- package/apps/os-server/dist/apps/os-server/src/devkit/tools-api.js.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/health/index.d.ts +36 -0
- package/apps/os-server/dist/apps/os-server/src/health/index.d.ts.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/health/index.js +275 -0
- package/apps/os-server/dist/apps/os-server/src/health/index.js.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/index.d.ts +2 -0
- package/apps/os-server/dist/apps/os-server/src/index.d.ts.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/index.js +1131 -0
- package/apps/os-server/dist/apps/os-server/src/index.js.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/metrics/index.d.ts +48 -0
- package/apps/os-server/dist/apps/os-server/src/metrics/index.d.ts.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/metrics/index.js +296 -0
- package/apps/os-server/dist/apps/os-server/src/metrics/index.js.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/metrics/monitoring-detail.d.ts +18 -0
- package/apps/os-server/dist/apps/os-server/src/metrics/monitoring-detail.d.ts.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/metrics/monitoring-detail.js +117 -0
- package/apps/os-server/dist/apps/os-server/src/metrics/monitoring-detail.js.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/middleware/auth.d.ts +5 -0
- package/apps/os-server/dist/apps/os-server/src/middleware/auth.d.ts.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/middleware/auth.js +64 -0
- package/apps/os-server/dist/apps/os-server/src/middleware/auth.js.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/middleware/authApiKey.d.ts +4 -0
- package/apps/os-server/dist/apps/os-server/src/middleware/authApiKey.d.ts.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/middleware/authApiKey.js +105 -0
- package/apps/os-server/dist/apps/os-server/src/middleware/authApiKey.js.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/middleware/authJwt.d.ts +12 -0
- package/apps/os-server/dist/apps/os-server/src/middleware/authJwt.d.ts.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/middleware/authJwt.js +75 -0
- package/apps/os-server/dist/apps/os-server/src/middleware/authJwt.js.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/middleware/correlationId.d.ts +6 -0
- package/apps/os-server/dist/apps/os-server/src/middleware/correlationId.d.ts.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/middleware/correlationId.js +21 -0
- package/apps/os-server/dist/apps/os-server/src/middleware/correlationId.js.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/middleware/ddos-protection.d.ts +13 -0
- package/apps/os-server/dist/apps/os-server/src/middleware/ddos-protection.d.ts.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/middleware/ddos-protection.js +202 -0
- package/apps/os-server/dist/apps/os-server/src/middleware/ddos-protection.js.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/middleware/errorHandler.d.ts +14 -0
- package/apps/os-server/dist/apps/os-server/src/middleware/errorHandler.d.ts.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/middleware/errorHandler.js +98 -0
- package/apps/os-server/dist/apps/os-server/src/middleware/errorHandler.js.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/middleware/log-capture.d.ts +2 -0
- package/apps/os-server/dist/apps/os-server/src/middleware/log-capture.d.ts.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/middleware/log-capture.js +63 -0
- package/apps/os-server/dist/apps/os-server/src/middleware/log-capture.js.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/middleware/mfa.d.ts +3 -0
- package/apps/os-server/dist/apps/os-server/src/middleware/mfa.d.ts.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/middleware/mfa.js +96 -0
- package/apps/os-server/dist/apps/os-server/src/middleware/mfa.js.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/middleware/rateLimit.d.ts +6 -0
- package/apps/os-server/dist/apps/os-server/src/middleware/rateLimit.d.ts.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/middleware/rateLimit.js +54 -0
- package/apps/os-server/dist/apps/os-server/src/middleware/rateLimit.js.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/middleware/rbac.d.ts +19 -0
- package/apps/os-server/dist/apps/os-server/src/middleware/rbac.d.ts.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/middleware/rbac.js +229 -0
- package/apps/os-server/dist/apps/os-server/src/middleware/rbac.js.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/middleware/security.d.ts +10 -0
- package/apps/os-server/dist/apps/os-server/src/middleware/security.d.ts.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/middleware/security.js +146 -0
- package/apps/os-server/dist/apps/os-server/src/middleware/security.js.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/middleware/validate.d.ts +7 -0
- package/apps/os-server/dist/apps/os-server/src/middleware/validate.d.ts.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/middleware/validate.js +156 -0
- package/apps/os-server/dist/apps/os-server/src/middleware/validate.js.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/queue/config.d.ts +26 -0
- package/apps/os-server/dist/apps/os-server/src/queue/config.d.ts.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/queue/config.js +21 -0
- package/apps/os-server/dist/apps/os-server/src/queue/config.js.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/queue/index.d.ts +13 -0
- package/apps/os-server/dist/apps/os-server/src/queue/index.d.ts.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/queue/index.js +152 -0
- package/apps/os-server/dist/apps/os-server/src/queue/index.js.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/queue/processor.d.ts +16 -0
- package/apps/os-server/dist/apps/os-server/src/queue/processor.d.ts.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/queue/processor.js +378 -0
- package/apps/os-server/dist/apps/os-server/src/queue/processor.js.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/queue/sentinel-execute-watch.d.ts +7 -0
- package/apps/os-server/dist/apps/os-server/src/queue/sentinel-execute-watch.d.ts.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/queue/sentinel-execute-watch.js +22 -0
- package/apps/os-server/dist/apps/os-server/src/queue/sentinel-execute-watch.js.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/routes/ai-providers-simple.d.ts +3 -0
- package/apps/os-server/dist/apps/os-server/src/routes/ai-providers-simple.d.ts.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/routes/ai-providers-simple.js +175 -0
- package/apps/os-server/dist/apps/os-server/src/routes/ai-providers-simple.js.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/routes/chats.d.ts +3 -0
- package/apps/os-server/dist/apps/os-server/src/routes/chats.d.ts.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/routes/chats.js +150 -0
- package/apps/os-server/dist/apps/os-server/src/routes/chats.js.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/routes/gdpr.d.ts +3 -0
- package/apps/os-server/dist/apps/os-server/src/routes/gdpr.d.ts.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/routes/gdpr.js +252 -0
- package/apps/os-server/dist/apps/os-server/src/routes/gdpr.js.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/routes/mfa.d.ts +3 -0
- package/apps/os-server/dist/apps/os-server/src/routes/mfa.d.ts.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/routes/mfa.js +240 -0
- package/apps/os-server/dist/apps/os-server/src/routes/mfa.js.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/routes/monitoring.d.ts +16 -0
- package/apps/os-server/dist/apps/os-server/src/routes/monitoring.d.ts.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/routes/monitoring.js +168 -0
- package/apps/os-server/dist/apps/os-server/src/routes/monitoring.js.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/routes/sentinel-policies.d.ts +3 -0
- package/apps/os-server/dist/apps/os-server/src/routes/sentinel-policies.d.ts.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/routes/sentinel-policies.js +209 -0
- package/apps/os-server/dist/apps/os-server/src/routes/sentinel-policies.js.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/routes/sentinel-predictive.d.ts +3 -0
- package/apps/os-server/dist/apps/os-server/src/routes/sentinel-predictive.d.ts.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/routes/sentinel-predictive.js +88 -0
- package/apps/os-server/dist/apps/os-server/src/routes/sentinel-predictive.js.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/routes/shield.d.ts +3 -0
- package/apps/os-server/dist/apps/os-server/src/routes/shield.d.ts.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/routes/shield.js +85 -0
- package/apps/os-server/dist/apps/os-server/src/routes/shield.js.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/routes/tool-credentials.d.ts +3 -0
- package/apps/os-server/dist/apps/os-server/src/routes/tool-credentials.d.ts.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/routes/tool-credentials.js +209 -0
- package/apps/os-server/dist/apps/os-server/src/routes/tool-credentials.js.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/routes/tool-proxy.d.ts +3 -0
- package/apps/os-server/dist/apps/os-server/src/routes/tool-proxy.d.ts.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/routes/tool-proxy.js +206 -0
- package/apps/os-server/dist/apps/os-server/src/routes/tool-proxy.js.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/runs/index.d.ts +5 -0
- package/apps/os-server/dist/apps/os-server/src/runs/index.d.ts.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/runs/index.js +19 -0
- package/apps/os-server/dist/apps/os-server/src/runs/index.js.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/runs/memoryRunStore.d.ts +12 -0
- package/apps/os-server/dist/apps/os-server/src/runs/memoryRunStore.d.ts.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/runs/memoryRunStore.js +78 -0
- package/apps/os-server/dist/apps/os-server/src/runs/memoryRunStore.js.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/runs/postgresRunStore.d.ts +15 -0
- package/apps/os-server/dist/apps/os-server/src/runs/postgresRunStore.d.ts.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/runs/postgresRunStore.js +148 -0
- package/apps/os-server/dist/apps/os-server/src/runs/postgresRunStore.js.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/runs/run-kill.d.ts +20 -0
- package/apps/os-server/dist/apps/os-server/src/runs/run-kill.d.ts.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/runs/run-kill.js +69 -0
- package/apps/os-server/dist/apps/os-server/src/runs/run-kill.js.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/runs/run-retention.d.ts +17 -0
- package/apps/os-server/dist/apps/os-server/src/runs/run-retention.d.ts.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/runs/run-retention.js +124 -0
- package/apps/os-server/dist/apps/os-server/src/runs/run-retention.js.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/runs/runStore.d.ts +10 -0
- package/apps/os-server/dist/apps/os-server/src/runs/runStore.d.ts.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/runs/runStore.js +2 -0
- package/apps/os-server/dist/apps/os-server/src/runs/runStore.js.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/runs/types.d.ts +44 -0
- package/apps/os-server/dist/apps/os-server/src/runs/types.d.ts.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/runs/types.js +2 -0
- package/apps/os-server/dist/apps/os-server/src/runs/types.js.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/schemas/runs.d.ts +126 -0
- package/apps/os-server/dist/apps/os-server/src/schemas/runs.d.ts.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/schemas/runs.js +63 -0
- package/apps/os-server/dist/apps/os-server/src/schemas/runs.js.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/security/agent-token.d.ts +51 -0
- package/apps/os-server/dist/apps/os-server/src/security/agent-token.d.ts.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/security/agent-token.js +161 -0
- package/apps/os-server/dist/apps/os-server/src/security/agent-token.js.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/security/outbound-url.d.ts +2 -0
- package/apps/os-server/dist/apps/os-server/src/security/outbound-url.d.ts.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/security/outbound-url.js +65 -0
- package/apps/os-server/dist/apps/os-server/src/security/outbound-url.js.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/security/sentinel-config-store.d.ts +14 -0
- package/apps/os-server/dist/apps/os-server/src/security/sentinel-config-store.d.ts.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/security/sentinel-config-store.js +168 -0
- package/apps/os-server/dist/apps/os-server/src/security/sentinel-config-store.js.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/security/sentinel-run-failure.d.ts +25 -0
- package/apps/os-server/dist/apps/os-server/src/security/sentinel-run-failure.d.ts.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/security/sentinel-run-failure.js +46 -0
- package/apps/os-server/dist/apps/os-server/src/security/sentinel-run-failure.js.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/security/shield-config.d.ts +14 -0
- package/apps/os-server/dist/apps/os-server/src/security/shield-config.d.ts.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/security/shield-config.js +70 -0
- package/apps/os-server/dist/apps/os-server/src/security/shield-config.js.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/utils/circuit-breaker.d.ts +13 -0
- package/apps/os-server/dist/apps/os-server/src/utils/circuit-breaker.d.ts.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/utils/circuit-breaker.js +72 -0
- package/apps/os-server/dist/apps/os-server/src/utils/circuit-breaker.js.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/utils/log-encryption.d.ts +10 -0
- package/apps/os-server/dist/apps/os-server/src/utils/log-encryption.d.ts.map +1 -0
- package/apps/os-server/dist/apps/os-server/src/utils/log-encryption.js +140 -0
- package/apps/os-server/dist/apps/os-server/src/utils/log-encryption.js.map +1 -0
- package/apps/os-server/docker-compose.local.yml +46 -0
- package/apps/os-server/find-gateway.sh +37 -0
- package/apps/os-server/jest.config.cjs +52 -0
- package/apps/os-server/package-lock.json +8809 -0
- package/apps/os-server/package.json +66 -0
- package/apps/os-server/scripts/setup-test-env.sh +67 -0
- package/apps/os-server/src/__tests__/integration/README.md +92 -0
- package/apps/os-server/src/__tests__/integration/helpers/test-server.ts +178 -0
- package/apps/os-server/src/__tests__/integration/sentinel.test.ts +364 -0
- package/apps/os-server/src/adapters/redis-sentinel-publisher.ts +176 -0
- package/apps/os-server/src/agents/definitions-simple.ts +536 -0
- package/apps/os-server/src/ai-providers/anthropic-provider.ts +194 -0
- package/apps/os-server/src/ai-providers/openai-provider.ts +193 -0
- package/apps/os-server/src/ai-providers/redis-credentials-store.ts +224 -0
- package/apps/os-server/src/db/docker-manager.ts +262 -0
- package/apps/os-server/src/db/init.ts +292 -0
- package/apps/os-server/src/devkit/routes.ts +349 -0
- package/apps/os-server/src/health/index.ts +375 -0
- package/apps/os-server/src/index.ts +1506 -0
- package/apps/os-server/src/middleware/correlationId.ts +56 -0
- package/apps/os-server/src/middleware/ddos-protection.ts +318 -0
- package/apps/os-server/src/middleware/log-capture.ts +92 -0
- package/apps/os-server/src/middleware/security.ts +222 -0
- package/apps/os-server/src/routes/ai-providers-simple.ts +220 -0
- package/apps/os-server/src/routes/gdpr.ts +337 -0
- package/apps/os-server/src/routes/monitoring.ts +315 -0
- package/apps/os-server/src/routes/sentinel-policies.ts +293 -0
- package/apps/os-server/src/routes/sentinel-predictive.ts +129 -0
- package/apps/os-server/src/routes/tool-proxy.ts +285 -0
- package/apps/os-server/src/security/outbound-url.ts +83 -0
- package/apps/os-server/update-and-test.sh +36 -0
- package/dist/boot-sequence.js +1 -1
- package/dist/boot-sequence.js.map +1 -1
- package/dist/gateway-api-key-bootstrap.js +1 -1
- package/dist/gateway-api-key-bootstrap.js.map +1 -1
- package/dist/gateway-prisma-bootstrap.d.ts +1 -1
- package/dist/gateway-prisma-bootstrap.js +1 -1
- package/dist/index.js +8 -8
- package/dist/index.js.map +1 -1
- package/dist/local-gateway-pid.d.ts +1 -1
- package/dist/local-gateway-pid.js +1 -1
- package/dist/os-tui-binary-bootstrap.d.ts +18 -0
- package/dist/os-tui-binary-bootstrap.d.ts.map +1 -0
- package/dist/os-tui-binary-bootstrap.js +175 -0
- package/dist/os-tui-binary-bootstrap.js.map +1 -0
- package/dist/rust-check.js +2 -2
- package/dist/rust-check.js.map +1 -1
- package/dist/system-verify.js +8 -8
- package/dist/system-verify.js.map +1 -1
- package/dist/tui-handlers.js +12 -12
- package/dist/tui-handlers.js.map +1 -1
- package/dist/watchdog.js +73 -73
- package/os-tui/Cargo.lock +1118 -0
- package/os-tui/Cargo.toml +17 -0
- package/os-tui/bin/os-tui.js +63 -0
- package/os-tui/binaries/win32-x64/os-tui.exe +0 -0
- package/os-tui/src/app/render_scheduler.rs +111 -0
- package/os-tui/src/app.rs +3814 -0
- package/os-tui/src/debug_log.rs +131 -0
- package/os-tui/src/io/mod.rs +63 -0
- package/os-tui/src/io/protocol.rs +14 -0
- package/os-tui/src/io/stdio.rs +31 -0
- package/os-tui/src/io/ws.rs +25 -0
- package/os-tui/src/main.rs +2090 -0
- package/os-tui/src/monitoring/mod.rs +439 -0
- package/os-tui/src/screens/mod.rs +254 -0
- package/os-tui/src/storage/cache.rs +221 -0
- package/os-tui/src/storage/mod.rs +5 -0
- package/os-tui/src/ui/agent_builder.rs +1148 -0
- package/os-tui/src/ui/agent_list.rs +344 -0
- package/os-tui/src/ui/boot.rs +145 -0
- package/os-tui/src/ui/connection_portal.rs +839 -0
- package/os-tui/src/ui/help.rs +340 -0
- package/os-tui/src/ui/layout.rs +978 -0
- package/os-tui/src/ui/mod.rs +13 -0
- package/os-tui/src/ui/portal_monitoring.rs +1128 -0
- package/os-tui/src/ui/run_manager.rs +922 -0
- package/os-tui/src/ui/safe_viewport.rs +236 -0
- package/os-tui/src/ui/sentinel_config.rs +828 -0
- package/os-tui/src/ui/settings.rs +414 -0
- package/os-tui/src/ui/setup_portal.rs +547 -0
- package/os-tui/src/ui/shield_dashboard.rs +1081 -0
- package/os-tui/src/websocket.rs +315 -0
- package/package.json +121 -121
- package/prisma/schema.prisma +470 -470
- package/scripts/cleanup-build-artifacts.js +2 -2
- package/scripts/os-tools-smoke.cjs +549 -549
- package/scripts/postinstall-os-server.js +63 -0
- package/scripts/postinstall-os-tui.js +64 -0
- package/scripts/seed-os-server-api-key.cjs +77 -0
- package/scripts/setup.js +11 -11
- package/src/security/package-integrity.ts +188 -188
- package/src/security/ssrf-protection.ts +147 -147
- package/apps/gateway/DEPLOYMENT.md +0 -426
- package/apps/gateway/JWT-RATE-LIMIT-VALIDATION.md +0 -462
- package/apps/gateway/PERSISTENCE-AND-AUTH.md +0 -227
- package/apps/gateway/PHASE5-TESTING.md +0 -222
- package/apps/gateway/README.md +0 -368
- package/apps/gateway/TROUBLESHOOTING.md +0 -541
- package/apps/gateway/docker-compose.local.yml +0 -46
- package/apps/gateway/find-gateway.sh +0 -37
- package/apps/gateway/jest.config.cjs +0 -52
- package/apps/gateway/package-lock.json +0 -8810
- package/apps/gateway/package.json +0 -66
- package/apps/gateway/scripts/setup-test-env.sh +0 -67
- package/apps/gateway/src/__tests__/integration/README.md +0 -92
- package/apps/gateway/src/__tests__/integration/helpers/test-server.ts +0 -178
- package/apps/gateway/src/__tests__/integration/sentinel.test.ts +0 -364
- package/apps/gateway/src/adapters/redis-sentinel-publisher.ts +0 -176
- package/apps/gateway/src/agents/definitions-simple.ts +0 -536
- package/apps/gateway/src/ai-providers/anthropic-provider.ts +0 -194
- package/apps/gateway/src/ai-providers/openai-provider.ts +0 -193
- package/apps/gateway/src/ai-providers/redis-credentials-store.ts +0 -224
- package/apps/gateway/src/db/docker-manager.ts +0 -262
- package/apps/gateway/src/db/init.ts +0 -292
- package/apps/gateway/src/devkit/routes.ts +0 -349
- package/apps/gateway/src/health/index.ts +0 -375
- package/apps/gateway/src/index.ts +0 -1506
- package/apps/gateway/src/middleware/correlationId.ts +0 -56
- package/apps/gateway/src/middleware/ddos-protection.ts +0 -318
- package/apps/gateway/src/middleware/log-capture.ts +0 -92
- package/apps/gateway/src/middleware/security.ts +0 -222
- package/apps/gateway/src/routes/ai-providers-simple.ts +0 -220
- package/apps/gateway/src/routes/gdpr.ts +0 -337
- package/apps/gateway/src/routes/monitoring.ts +0 -315
- package/apps/gateway/src/routes/sentinel-policies.ts +0 -293
- package/apps/gateway/src/routes/sentinel-predictive.ts +0 -129
- package/apps/gateway/src/routes/tool-proxy.ts +0 -285
- package/apps/gateway/src/security/outbound-url.ts +0 -83
- package/apps/gateway/update-and-test.sh +0 -36
- package/mk3-tui/Cargo.lock +0 -1118
- package/mk3-tui/Cargo.toml +0 -17
- package/mk3-tui/bin/mk3-tui.js +0 -63
- package/mk3-tui/binaries/win32-x64/mk3-tui.exe +0 -0
- package/mk3-tui/src/app/render_scheduler.rs +0 -111
- package/mk3-tui/src/app.rs +0 -3813
- package/mk3-tui/src/debug_log.rs +0 -131
- package/mk3-tui/src/io/mod.rs +0 -63
- package/mk3-tui/src/io/protocol.rs +0 -14
- package/mk3-tui/src/io/stdio.rs +0 -31
- package/mk3-tui/src/io/ws.rs +0 -25
- package/mk3-tui/src/main.rs +0 -2090
- package/mk3-tui/src/monitoring/mod.rs +0 -439
- package/mk3-tui/src/screens/mod.rs +0 -254
- package/mk3-tui/src/storage/cache.rs +0 -221
- package/mk3-tui/src/storage/mod.rs +0 -5
- package/mk3-tui/src/ui/agent_builder.rs +0 -1148
- package/mk3-tui/src/ui/agent_list.rs +0 -344
- package/mk3-tui/src/ui/boot.rs +0 -145
- package/mk3-tui/src/ui/connection_portal.rs +0 -839
- package/mk3-tui/src/ui/help.rs +0 -340
- package/mk3-tui/src/ui/layout.rs +0 -978
- package/mk3-tui/src/ui/mod.rs +0 -13
- package/mk3-tui/src/ui/portal_monitoring.rs +0 -1128
- package/mk3-tui/src/ui/run_manager.rs +0 -913
- package/mk3-tui/src/ui/safe_viewport.rs +0 -236
- package/mk3-tui/src/ui/sentinel_config.rs +0 -828
- package/mk3-tui/src/ui/settings.rs +0 -414
- package/mk3-tui/src/ui/setup_portal.rs +0 -547
- package/mk3-tui/src/ui/shield_dashboard.rs +0 -1081
- package/mk3-tui/src/websocket.rs +0 -315
- package/scripts/postinstall-gateway.js +0 -63
- package/scripts/postinstall-mk3.js +0 -64
- package/scripts/seed-gateway-api-key.cjs +0 -77
- /package/apps/{gateway → os-server}/.dockerignore +0 -0
- /package/apps/{gateway → os-server}/.eslintrc.json +0 -0
- /package/apps/{gateway → os-server}/Dockerfile +0 -0
- /package/apps/{gateway → os-server}/Dockerfile.bak +0 -0
- /package/apps/{gateway → os-server}/ENV_VARIABLES.md +0 -0
- /package/apps/{gateway → os-server}/create-test-script.sh +0 -0
- /package/apps/{gateway → os-server}/debug-api-responses.sh +0 -0
- /package/apps/{gateway → os-server}/debug-failing-tests-v2.sh +0 -0
- /package/apps/{gateway → os-server}/debug-failing-tests.sh +0 -0
- /package/apps/{gateway → os-server}/debug-responses.sh +0 -0
- /package/apps/{gateway → os-server}/debug-test-responses.sh +0 -0
- /package/apps/{gateway → os-server}/debug-tests.sh +0 -0
- /package/apps/{gateway → os-server}/diagnose-test-failure.sh +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/adapters/gateway-cancel-adapter.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/adapters/gateway-cancel-adapter.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/adapters/gateway-cancel-adapter.js +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/adapters/gateway-cancel-adapter.js.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/adapters/redis-sentinel-publisher.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/adapters/redis-sentinel-publisher.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/adapters/redis-sentinel-publisher.js +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/adapters/redis-sentinel-publisher.js.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/adapters/sentinel-event-stream.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/adapters/sentinel-event-stream.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/adapters/sentinel-event-stream.js +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/adapters/sentinel-event-stream.js.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/agents/definitions-simple.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/agents/definitions-simple.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/agents/definitions-simple.js +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/agents/definitions-simple.js.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/agents/definitions.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/agents/definitions.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/agents/definitions.js +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/agents/definitions.js.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/agents/local-model-provider.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/agents/local-model-provider.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/agents/local-model-provider.js +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/agents/local-model-provider.js.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/agents/tools.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/agents/tools.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/agents/tools.js +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/agents/tools.js.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/ai-providers/anthropic-provider.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/ai-providers/anthropic-provider.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/ai-providers/anthropic-provider.js +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/ai-providers/anthropic-provider.js.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/ai-providers/index.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/ai-providers/index.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/ai-providers/index.js +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/ai-providers/index.js.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/ai-providers/openai-provider.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/ai-providers/openai-provider.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/ai-providers/openai-provider.js +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/ai-providers/openai-provider.js.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/ai-providers/provider-manager.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/ai-providers/provider-manager.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/ai-providers/provider-manager.js +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/ai-providers/provider-manager.js.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/ai-providers/redis-credentials-store.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/ai-providers/redis-credentials-store.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/ai-providers/redis-credentials-store.js +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/ai-providers/redis-credentials-store.js.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/ai-providers/types.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/ai-providers/types.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/ai-providers/types.js +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/ai-providers/types.js.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/config/persistence.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/config/persistence.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/config/persistence.js +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/config/persistence.js.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/crypto/envelope.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/crypto/envelope.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/crypto/envelope.js +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/crypto/envelope.js.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/crypto/mfa-storage.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/crypto/mfa-storage.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/crypto/mfa-storage.js +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/crypto/mfa-storage.js.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/db/docker-manager.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/db/docker-manager.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/db/docker-manager.js +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/db/docker-manager.js.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/db/init.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/db/init.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/db/init.js +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/db/init.js.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/db/memory-db.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/db/memory-db.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/db/memory-db.js +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/db/memory-db.js.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/db/prisma.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/db/prisma.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/db/prisma.js +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/db/prisma.js.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/db/redis.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/db/redis.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/db/redis.js +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/db/redis.js.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/devkit/agents-api.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/devkit/agents-api.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/devkit/agents-api.js +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/devkit/agents-api.js.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/devkit/metrics-parser.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/devkit/metrics-parser.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/devkit/metrics-parser.js +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/devkit/metrics-parser.js.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/devkit/middleware.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/devkit/middleware.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/devkit/middleware.js +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/devkit/middleware.js.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/devkit/routes.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/devkit/routes.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/devkit/routes.js +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/devkit/routes.js.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/devkit/tools-api.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/devkit/tools-api.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/devkit/tools-api.js +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/devkit/tools-api.js.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/health/index.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/health/index.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/health/index.js +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/health/index.js.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/index.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/index.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/index.js +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/index.js.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/metrics/index.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/metrics/index.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/metrics/index.js +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/metrics/index.js.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/metrics/monitoring-detail.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/metrics/monitoring-detail.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/metrics/monitoring-detail.js +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/metrics/monitoring-detail.js.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/middleware/auth.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/middleware/auth.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/middleware/auth.js +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/middleware/auth.js.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/middleware/authApiKey.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/middleware/authApiKey.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/middleware/authApiKey.js +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/middleware/authApiKey.js.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/middleware/authJwt.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/middleware/authJwt.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/middleware/authJwt.js +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/middleware/authJwt.js.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/middleware/correlationId.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/middleware/correlationId.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/middleware/correlationId.js +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/middleware/correlationId.js.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/middleware/ddos-protection.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/middleware/ddos-protection.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/middleware/ddos-protection.js +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/middleware/ddos-protection.js.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/middleware/errorHandler.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/middleware/errorHandler.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/middleware/errorHandler.js +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/middleware/errorHandler.js.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/middleware/log-capture.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/middleware/log-capture.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/middleware/log-capture.js +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/middleware/log-capture.js.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/middleware/mfa.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/middleware/mfa.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/middleware/mfa.js +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/middleware/mfa.js.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/middleware/rateLimit.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/middleware/rateLimit.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/middleware/rateLimit.js +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/middleware/rateLimit.js.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/middleware/rbac.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/middleware/rbac.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/middleware/rbac.js +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/middleware/rbac.js.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/middleware/security.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/middleware/security.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/middleware/security.js +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/middleware/security.js.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/middleware/validate.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/middleware/validate.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/middleware/validate.js +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/middleware/validate.js.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/queue/config.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/queue/config.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/queue/config.js +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/queue/config.js.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/queue/index.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/queue/index.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/queue/index.js +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/queue/index.js.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/queue/processor.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/queue/processor.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/queue/processor.js +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/queue/processor.js.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/queue/sentinel-execute-watch.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/queue/sentinel-execute-watch.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/queue/sentinel-execute-watch.js +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/queue/sentinel-execute-watch.js.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/routes/ai-providers-simple.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/routes/ai-providers-simple.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/routes/ai-providers-simple.js +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/routes/ai-providers-simple.js.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/routes/chats.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/routes/chats.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/routes/chats.js +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/routes/chats.js.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/routes/gdpr.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/routes/gdpr.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/routes/gdpr.js +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/routes/gdpr.js.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/routes/mfa.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/routes/mfa.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/routes/mfa.js +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/routes/mfa.js.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/routes/monitoring.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/routes/monitoring.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/routes/monitoring.js +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/routes/monitoring.js.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/routes/sentinel-policies.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/routes/sentinel-policies.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/routes/sentinel-policies.js +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/routes/sentinel-policies.js.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/routes/sentinel-predictive.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/routes/sentinel-predictive.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/routes/sentinel-predictive.js +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/routes/sentinel-predictive.js.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/routes/shield.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/routes/shield.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/routes/shield.js +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/routes/shield.js.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/routes/tool-credentials.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/routes/tool-credentials.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/routes/tool-credentials.js +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/routes/tool-credentials.js.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/routes/tool-proxy.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/routes/tool-proxy.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/routes/tool-proxy.js +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/routes/tool-proxy.js.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/runs/index.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/runs/index.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/runs/index.js +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/runs/index.js.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/runs/memoryRunStore.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/runs/memoryRunStore.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/runs/memoryRunStore.js +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/runs/memoryRunStore.js.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/runs/postgresRunStore.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/runs/postgresRunStore.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/runs/postgresRunStore.js +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/runs/postgresRunStore.js.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/runs/run-kill.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/runs/run-kill.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/runs/run-kill.js +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/runs/run-kill.js.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/runs/run-retention.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/runs/run-retention.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/runs/run-retention.js +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/runs/run-retention.js.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/runs/runStore.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/runs/runStore.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/runs/runStore.js +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/runs/runStore.js.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/runs/types.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/runs/types.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/runs/types.js +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/runs/types.js.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/schemas/runs.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/schemas/runs.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/schemas/runs.js +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/schemas/runs.js.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/security/agent-token.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/security/agent-token.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/security/agent-token.js +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/security/agent-token.js.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/security/outbound-url.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/security/outbound-url.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/security/outbound-url.js +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/security/outbound-url.js.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/security/sentinel-config-store.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/security/sentinel-config-store.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/security/sentinel-config-store.js +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/security/sentinel-config-store.js.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/security/sentinel-run-failure.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/security/sentinel-run-failure.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/security/sentinel-run-failure.js +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/security/sentinel-run-failure.js.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/security/shield-config.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/security/shield-config.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/security/shield-config.js +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/security/shield-config.js.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/utils/circuit-breaker.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/utils/circuit-breaker.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/utils/circuit-breaker.js +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/utils/circuit-breaker.js.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/utils/log-encryption.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/utils/log-encryption.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/utils/log-encryption.js +0 -0
- /package/apps/{gateway → os-server}/dist/apps/gateway/src/utils/log-encryption.js.map +0 -0
- /package/apps/{gateway → os-server}/dist/index.js +0 -0
- /package/apps/{gateway → os-server}/dist/packages/adapters/redis/IdempotencyStore.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/packages/adapters/redis/IdempotencyStore.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/packages/adapters/redis/IdempotencyStore.js +0 -0
- /package/apps/{gateway → os-server}/dist/packages/adapters/redis/IdempotencyStore.js.map +0 -0
- /package/apps/{gateway → os-server}/dist/packages/middleware/idempotency/idempotency.d.ts +0 -0
- /package/apps/{gateway → os-server}/dist/packages/middleware/idempotency/idempotency.d.ts.map +0 -0
- /package/apps/{gateway → os-server}/dist/packages/middleware/idempotency/idempotency.js +0 -0
- /package/apps/{gateway → os-server}/dist/packages/middleware/idempotency/idempotency.js.map +0 -0
- /package/apps/{gateway → os-server}/load-tests/README.md +0 -0
- /package/apps/{gateway → os-server}/load-tests/k6-basic.js +0 -0
- /package/apps/{gateway → os-server}/load-tests/k6-rate-limit.js +0 -0
- /package/apps/{gateway → os-server}/minimal-test.sh +0 -0
- /package/apps/{gateway → os-server}/public/sentinel-dashboard.html +0 -0
- /package/apps/{gateway → os-server}/quick-debug.sh +0 -0
- /package/apps/{gateway → os-server}/scripts/seed-api-key.ts +0 -0
- /package/apps/{gateway → os-server}/scripts/verify-sentinel-persist.mjs +0 -0
- /package/apps/{gateway → os-server}/simple-test.sh +0 -0
- /package/apps/{gateway → os-server}/src/__tests__/agent-token.test.ts +0 -0
- /package/apps/{gateway → os-server}/src/__tests__/auth.test.ts +0 -0
- /package/apps/{gateway → os-server}/src/__tests__/correlationId.test.ts +0 -0
- /package/apps/{gateway → os-server}/src/__tests__/devkit-api.test.ts +0 -0
- /package/apps/{gateway → os-server}/src/__tests__/integration/authentication.test.ts +0 -0
- /package/apps/{gateway → os-server}/src/__tests__/integration/e2e-comprehensive-fixed.test.ts +0 -0
- /package/apps/{gateway → os-server}/src/__tests__/integration/e2e-workflow.test.ts +0 -0
- /package/apps/{gateway → os-server}/src/__tests__/integration/idempotency.test.ts +0 -0
- /package/apps/{gateway → os-server}/src/__tests__/integration/postgres-persistence.test.ts +0 -0
- /package/apps/{gateway → os-server}/src/__tests__/integration/rate-limiting.test.ts +0 -0
- /package/apps/{gateway → os-server}/src/__tests__/integration/shield.test.ts +0 -0
- /package/apps/{gateway → os-server}/src/__tests__/log-capture.test.ts +0 -0
- /package/apps/{gateway → os-server}/src/__tests__/no-persistence-mode.test.ts +0 -0
- /package/apps/{gateway → os-server}/src/__tests__/outbound-url.test.ts +0 -0
- /package/apps/{gateway → os-server}/src/__tests__/rateLimit.test.ts +0 -0
- /package/apps/{gateway → os-server}/src/__tests__/run-kill.test.ts +0 -0
- /package/apps/{gateway → os-server}/src/__tests__/run-retention.test.ts +0 -0
- /package/apps/{gateway → os-server}/src/__tests__/sentinel-config-persist-http.test.ts +0 -0
- /package/apps/{gateway → os-server}/src/__tests__/sentinel-config-store.test.ts +0 -0
- /package/apps/{gateway → os-server}/src/__tests__/sentinel-events.test.ts +0 -0
- /package/apps/{gateway → os-server}/src/__tests__/sentinel-execute-watch.test.ts +0 -0
- /package/apps/{gateway → os-server}/src/__tests__/sentinel-policies.test.ts +0 -0
- /package/apps/{gateway → os-server}/src/__tests__/sentinel-publish-kill.test.ts +0 -0
- /package/apps/{gateway → os-server}/src/__tests__/sentinel-run-failure.test.ts +0 -0
- /package/apps/{gateway → os-server}/src/__tests__/shield-config.test.ts +0 -0
- /package/apps/{gateway → os-server}/src/__tests__/shield-health.test.ts +0 -0
- /package/apps/{gateway → os-server}/src/__tests__/shield-metrics.test.ts +0 -0
- /package/apps/{gateway → os-server}/src/__tests__/tool-proxy.test.ts +0 -0
- /package/apps/{gateway → os-server}/src/__tests__/validateSecrets.test.ts +0 -0
- /package/apps/{gateway → os-server}/src/__tests__/validation.test.ts +0 -0
- /package/apps/{gateway → os-server}/src/adapters/gateway-cancel-adapter.ts +0 -0
- /package/apps/{gateway → os-server}/src/adapters/sentinel-event-stream.ts +0 -0
- /package/apps/{gateway → os-server}/src/agents/definitions.ts +0 -0
- /package/apps/{gateway → os-server}/src/agents/local-model-provider.ts +0 -0
- /package/apps/{gateway → os-server}/src/agents/tools.ts +0 -0
- /package/apps/{gateway → os-server}/src/ai-providers/index.ts +0 -0
- /package/apps/{gateway → os-server}/src/ai-providers/provider-manager.ts +0 -0
- /package/apps/{gateway → os-server}/src/ai-providers/types.ts +0 -0
- /package/apps/{gateway → os-server}/src/config/persistence.ts +0 -0
- /package/apps/{gateway → os-server}/src/crypto/envelope.ts +0 -0
- /package/apps/{gateway → os-server}/src/crypto/mfa-storage.ts +0 -0
- /package/apps/{gateway → os-server}/src/db/memory-db.ts +0 -0
- /package/apps/{gateway → os-server}/src/db/prisma.ts +0 -0
- /package/apps/{gateway → os-server}/src/db/redis.ts +0 -0
- /package/apps/{gateway → os-server}/src/devkit/agents-api.ts +0 -0
- /package/apps/{gateway → os-server}/src/devkit/metrics-parser.ts +0 -0
- /package/apps/{gateway → os-server}/src/devkit/middleware.ts +0 -0
- /package/apps/{gateway → os-server}/src/devkit/tools-api.ts +0 -0
- /package/apps/{gateway → os-server}/src/metrics/index.ts +0 -0
- /package/apps/{gateway → os-server}/src/metrics/monitoring-detail.ts +0 -0
- /package/apps/{gateway → os-server}/src/middleware/auth.ts +0 -0
- /package/apps/{gateway → os-server}/src/middleware/authApiKey.ts +0 -0
- /package/apps/{gateway → os-server}/src/middleware/authJwt.ts +0 -0
- /package/apps/{gateway → os-server}/src/middleware/errorHandler.ts +0 -0
- /package/apps/{gateway → os-server}/src/middleware/mfa.ts +0 -0
- /package/apps/{gateway → os-server}/src/middleware/rateLimit.ts +0 -0
- /package/apps/{gateway → os-server}/src/middleware/rbac.ts +0 -0
- /package/apps/{gateway → os-server}/src/middleware/validate.ts +0 -0
- /package/apps/{gateway → os-server}/src/middleware/validate.ts.backup +0 -0
- /package/apps/{gateway → os-server}/src/queue/config.ts +0 -0
- /package/apps/{gateway → os-server}/src/queue/index.ts +0 -0
- /package/apps/{gateway → os-server}/src/queue/processor.ts +0 -0
- /package/apps/{gateway → os-server}/src/queue/sentinel-execute-watch.ts +0 -0
- /package/apps/{gateway → os-server}/src/routes/chats.ts +0 -0
- /package/apps/{gateway → os-server}/src/routes/mfa.ts +0 -0
- /package/apps/{gateway → os-server}/src/routes/shield.ts +0 -0
- /package/apps/{gateway → os-server}/src/routes/tool-credentials.ts +0 -0
- /package/apps/{gateway → os-server}/src/runs/index.ts +0 -0
- /package/apps/{gateway → os-server}/src/runs/memoryRunStore.ts +0 -0
- /package/apps/{gateway → os-server}/src/runs/postgresRunStore.ts +0 -0
- /package/apps/{gateway → os-server}/src/runs/run-kill.ts +0 -0
- /package/apps/{gateway → os-server}/src/runs/run-retention.ts +0 -0
- /package/apps/{gateway → os-server}/src/runs/runStore.ts +0 -0
- /package/apps/{gateway → os-server}/src/runs/types.ts +0 -0
- /package/apps/{gateway → os-server}/src/schemas/runs.ts +0 -0
- /package/apps/{gateway → os-server}/src/security/agent-token.ts +0 -0
- /package/apps/{gateway → os-server}/src/security/sentinel-config-store.ts +0 -0
- /package/apps/{gateway → os-server}/src/security/sentinel-run-failure.ts +0 -0
- /package/apps/{gateway → os-server}/src/security/shield-config.ts +0 -0
- /package/apps/{gateway → os-server}/src/types/fastify-rate-limit.d.ts +0 -0
- /package/apps/{gateway → os-server}/src/utils/circuit-breaker.ts +0 -0
- /package/apps/{gateway → os-server}/src/utils/log-encryption.ts +0 -0
- /package/apps/{gateway → os-server}/test-all-individual.sh +0 -0
- /package/apps/{gateway → os-server}/test-all-phases-final.sh +0 -0
- /package/apps/{gateway → os-server}/test-all-phases-fixed-v2.sh +0 -0
- /package/apps/{gateway → os-server}/test-all-phases-fixed.sh +0 -0
- /package/apps/{gateway → os-server}/test-all-phases.sh +0 -0
- /package/apps/{gateway → os-server}/test-concurrency.sh +0 -0
- /package/apps/{gateway → os-server}/test-debug.sh +0 -0
- /package/apps/{gateway → os-server}/test-e2e.sh +0 -0
- /package/apps/{gateway → os-server}/test-extraction.sh +0 -0
- /package/apps/{gateway → os-server}/test-full-operations-final.sh +0 -0
- /package/apps/{gateway → os-server}/test-full-operations.sh +0 -0
- /package/apps/{gateway → os-server}/test-idempotency-only.sh +0 -0
- /package/apps/{gateway → os-server}/test-idempotency.sh +0 -0
- /package/apps/{gateway → os-server}/test-individual.sh +0 -0
- /package/apps/{gateway → os-server}/test-queue.sh +0 -0
- /package/apps/{gateway → os-server}/tsconfig.json +0 -0
- /package/{mk3-tui → os-tui}/src/ui/connection_portal.rs.backup +0 -0
package/mk3-tui/src/main.rs
DELETED
|
@@ -1,2090 +0,0 @@
|
|
|
1
|
-
use anyhow::Result;
|
|
2
|
-
use crossterm::cursor;
|
|
3
|
-
use crossterm::event::{self, Event, KeyCode, KeyEventKind, MouseEventKind};
|
|
4
|
-
use crossterm::execute;
|
|
5
|
-
use crossterm::terminal::{
|
|
6
|
-
disable_raw_mode, enable_raw_mode, Clear, ClearType, EnterAlternateScreen,
|
|
7
|
-
LeaveAlternateScreen, SetTitle,
|
|
8
|
-
};
|
|
9
|
-
use ratatui::prelude::*;
|
|
10
|
-
use std::time::{Duration, Instant};
|
|
11
|
-
|
|
12
|
-
mod app;
|
|
13
|
-
mod debug_log;
|
|
14
|
-
mod io;
|
|
15
|
-
mod monitoring;
|
|
16
|
-
mod screens;
|
|
17
|
-
mod storage;
|
|
18
|
-
mod ui;
|
|
19
|
-
mod websocket;
|
|
20
|
-
|
|
21
|
-
use app::{App, OperationMode};
|
|
22
|
-
use io::IoHandler;
|
|
23
|
-
use websocket::{WebSocketClient, WsClientMessage};
|
|
24
|
-
|
|
25
|
-
/// Default local WebSocket port for TUI ↔ Node (keep in sync with `DEFAULT_TUI_WS_PORT` in `packages/os-cli/src/tui-defaults.ts`).
|
|
26
|
-
const DEFAULT_TUI_WS_PORT: u16 = 8081;
|
|
27
|
-
|
|
28
|
-
fn sanitize_monitoring_line(raw: &str) -> String {
|
|
29
|
-
let mut line: String = raw
|
|
30
|
-
.chars()
|
|
31
|
-
.map(|ch| match ch {
|
|
32
|
-
'\r' | '\n' => ' ',
|
|
33
|
-
ch if ch.is_control() && ch != '\t' => ' ',
|
|
34
|
-
ch => ch,
|
|
35
|
-
})
|
|
36
|
-
.collect();
|
|
37
|
-
if line.chars().count() > 500 {
|
|
38
|
-
line = line.chars().take(500).collect();
|
|
39
|
-
line.push('…');
|
|
40
|
-
}
|
|
41
|
-
line
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
fn main() -> Result<()> {
|
|
45
|
-
// Window / tab title (otherwise hosts often show the executable name, e.g. mk3-tui)
|
|
46
|
-
let window_title = match std::env::var("4RUNR_CLI_VERSION") {
|
|
47
|
-
Ok(v) if !v.trim().is_empty() => format!("4Runr OS v{}", v.trim()),
|
|
48
|
-
_ => "4Runr OS".to_string(),
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
// Setup terminal (boot screen is now part of TUI)
|
|
52
|
-
enable_raw_mode()?;
|
|
53
|
-
let mut stdout = std::io::stdout();
|
|
54
|
-
|
|
55
|
-
// Enter alternate screen, hide cursor, clear screen, move to top-left
|
|
56
|
-
execute!(
|
|
57
|
-
stdout,
|
|
58
|
-
EnterAlternateScreen,
|
|
59
|
-
SetTitle(window_title),
|
|
60
|
-
cursor::Hide,
|
|
61
|
-
Clear(ClearType::All),
|
|
62
|
-
cursor::MoveTo(0, 0)
|
|
63
|
-
)?;
|
|
64
|
-
|
|
65
|
-
let backend = CrosstermBackend::new(stdout);
|
|
66
|
-
let mut terminal = Terminal::new(backend)?;
|
|
67
|
-
|
|
68
|
-
// Clear the terminal buffer to ensure no artifacts
|
|
69
|
-
terminal.clear()?;
|
|
70
|
-
|
|
71
|
-
// Create app
|
|
72
|
-
let mut app = App::new();
|
|
73
|
-
let mut io_handler = IoHandler::new()?;
|
|
74
|
-
|
|
75
|
-
// Create runtime for async WebSocket client
|
|
76
|
-
let rt = tokio::runtime::Runtime::new()?;
|
|
77
|
-
|
|
78
|
-
// Get TUI port from environment variable or default (see DEFAULT_TUI_WS_PORT)
|
|
79
|
-
let tui_port = std::env::var("TUI_PORT")
|
|
80
|
-
.ok()
|
|
81
|
-
.and_then(|p| p.parse::<u16>().ok())
|
|
82
|
-
.unwrap_or(DEFAULT_TUI_WS_PORT);
|
|
83
|
-
|
|
84
|
-
// Try to connect to WebSocket server
|
|
85
|
-
let ws_url = format!("ws://localhost:{}", tui_port);
|
|
86
|
-
let ws_client = rt.block_on(async {
|
|
87
|
-
match WebSocketClient::connect(&ws_url).await {
|
|
88
|
-
Ok(client) => {
|
|
89
|
-
eprintln!("[4Runr] Connected to WebSocket server");
|
|
90
|
-
Some(client)
|
|
91
|
-
}
|
|
92
|
-
Err(e) => {
|
|
93
|
-
eprintln!("[4Runr] WebSocket connection failed: {}", e);
|
|
94
|
-
eprintln!("[4Runr] Falling back to stdio mode");
|
|
95
|
-
None
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
// Track real time for uptime (not from tick counter)
|
|
101
|
-
let start_time = Instant::now();
|
|
102
|
-
let mut last_tick = Instant::now();
|
|
103
|
-
let mut portal_connect_ui_tick = Instant::now();
|
|
104
|
-
|
|
105
|
-
// Track previous screen to detect portal navigation
|
|
106
|
-
let mut previous_screen: Option<crate::screens::Screen> = None;
|
|
107
|
-
// Last terminal size while Connection or Setup portal is visible (windowed hosts: sync buffer + clear on dimension drift).
|
|
108
|
-
let mut standalone_portal_last_terminal_dims: Option<(u16, u16)> = None;
|
|
109
|
-
|
|
110
|
-
// Force initial render
|
|
111
|
-
app.request_render("initial");
|
|
112
|
-
|
|
113
|
-
// Main loop - CRITICAL FIX: Animations run EVERY iteration, not just when no input!
|
|
114
|
-
// Per instructions Bug 1 fix: Move tick() and uptime OUTSIDE poll block
|
|
115
|
-
loop {
|
|
116
|
-
// ┌─────────────────────────────────────────────────────────┐
|
|
117
|
-
// │ STEP 1: UPDATE ANIMATIONS (runs EVERY loop iteration) │
|
|
118
|
-
// └─────────────────────────────────────────────────────────┘
|
|
119
|
-
|
|
120
|
-
// Check if portal is active - if so, skip base screen state updates
|
|
121
|
-
// This prevents base screen from affecting portal performance
|
|
122
|
-
use crate::screens::Screen;
|
|
123
|
-
let current_screen = app.state.navigation.current_screen().clone();
|
|
124
|
-
let is_portal_active = matches!(
|
|
125
|
-
current_screen,
|
|
126
|
-
Screen::ConnectionPortal | Screen::SetupPortal | Screen::PortalMonitoring
|
|
127
|
-
);
|
|
128
|
-
|
|
129
|
-
// DEBUG: Log portal detection
|
|
130
|
-
#[cfg(debug_assertions)]
|
|
131
|
-
{
|
|
132
|
-
static mut LOG_COUNT: u64 = 0;
|
|
133
|
-
unsafe {
|
|
134
|
-
LOG_COUNT += 1;
|
|
135
|
-
if LOG_COUNT % 100 == 0 {
|
|
136
|
-
eprintln!(
|
|
137
|
-
"[MAIN] Current screen: {:?}, Is portal active: {}",
|
|
138
|
-
current_screen, is_portal_active
|
|
139
|
-
);
|
|
140
|
-
eprintln!(
|
|
141
|
-
"[MAIN] Base screen: {:?}, Overlay stack: {:?}",
|
|
142
|
-
app.state.navigation.base_screen, app.state.navigation.overlay_stack
|
|
143
|
-
);
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
// Only update base screen state when NOT in a portal
|
|
149
|
-
// Portals are standalone screens and don't need base screen updates
|
|
150
|
-
if !is_portal_active {
|
|
151
|
-
// Uptime - always update from real clock (OUTSIDE poll block)
|
|
152
|
-
app.state.uptime_secs = start_time.elapsed().as_secs();
|
|
153
|
-
|
|
154
|
-
// Spinner - update on timer (every 150ms) - OUTSIDE poll block
|
|
155
|
-
if last_tick.elapsed() >= Duration::from_millis(150) {
|
|
156
|
-
app.tick(); // Advances spinner_frame
|
|
157
|
-
last_tick = Instant::now();
|
|
158
|
-
app.request_render("animation_tick"); // Request render for animation update
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
// Connection Portal: redraw while waiting on gateway.connect so the elapsed timer advances
|
|
163
|
-
if matches!(current_screen, Screen::ConnectionPortal)
|
|
164
|
-
&& app.state.connection_portal.connecting
|
|
165
|
-
{
|
|
166
|
-
if portal_connect_ui_tick.elapsed() >= Duration::from_millis(500) {
|
|
167
|
-
portal_connect_ui_tick = Instant::now();
|
|
168
|
-
app.request_immediate_render("portal_connecting_tick");
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
// Portal Monitoring: auto-refresh every 5 seconds when enabled
|
|
173
|
-
if matches!(current_screen, Screen::PortalMonitoring) {
|
|
174
|
-
let should_auto_refresh = {
|
|
175
|
-
let pm = &app.state.portal_monitoring;
|
|
176
|
-
pm.auto_refresh_enabled
|
|
177
|
-
&& !pm.loading
|
|
178
|
-
&& pm
|
|
179
|
-
.last_refresh
|
|
180
|
-
.map(|lr| lr.elapsed() >= pm.auto_refresh_interval)
|
|
181
|
-
.unwrap_or(true)
|
|
182
|
-
};
|
|
183
|
-
|
|
184
|
-
if should_auto_refresh {
|
|
185
|
-
if let Some(ws) = &ws_client {
|
|
186
|
-
app.state.portal_monitoring.last_refresh = Some(Instant::now());
|
|
187
|
-
app.begin_portal_observability_request(ws);
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
// Shield dashboard: live poll shield.load every ~5s when enabled
|
|
193
|
-
if matches!(current_screen, Screen::ShieldDashboard)
|
|
194
|
-
&& app.state.operation_mode == OperationMode::Connected
|
|
195
|
-
{
|
|
196
|
-
let shield_poll = {
|
|
197
|
-
let sd = &app.state.shield_dashboard;
|
|
198
|
-
if !sd.auto_refresh_enabled || sd.loading {
|
|
199
|
-
false
|
|
200
|
-
} else {
|
|
201
|
-
sd.last_refresh
|
|
202
|
-
.map(|lr| lr.elapsed() >= sd.auto_refresh_interval)
|
|
203
|
-
.unwrap_or(true)
|
|
204
|
-
}
|
|
205
|
-
};
|
|
206
|
-
if shield_poll {
|
|
207
|
-
if let Some(ws) = &ws_client {
|
|
208
|
-
app.begin_shield_load_request(ws, false);
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
// Loading timeout — never spin forever if CLI deduped or dropped a response
|
|
213
|
-
let loading_stuck = {
|
|
214
|
-
let sd = &app.state.shield_dashboard;
|
|
215
|
-
sd.loading
|
|
216
|
-
&& sd
|
|
217
|
-
.loading_started
|
|
218
|
-
.map(|t| t.elapsed() >= std::time::Duration::from_secs(12))
|
|
219
|
-
.unwrap_or(false)
|
|
220
|
-
};
|
|
221
|
-
if loading_stuck {
|
|
222
|
-
app.state.shield_dashboard.fail_loading(
|
|
223
|
-
"Shield load timed out — press R to refresh.".to_string(),
|
|
224
|
-
);
|
|
225
|
-
app.state.pending_shield_load_id = None;
|
|
226
|
-
app.request_render("shield_load_timeout");
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
// Run Manager: live poll run.list every ~3s when enabled (no manual R)
|
|
231
|
-
if matches!(current_screen, Screen::RunManager)
|
|
232
|
-
&& app.state.operation_mode == OperationMode::Connected
|
|
233
|
-
{
|
|
234
|
-
let run_poll = {
|
|
235
|
-
let rm = &app.state.run_manager;
|
|
236
|
-
if !rm.auto_refresh_enabled {
|
|
237
|
-
None
|
|
238
|
-
} else {
|
|
239
|
-
let due = rm
|
|
240
|
-
.last_refresh
|
|
241
|
-
.map(|lr| lr.elapsed() >= rm.auto_refresh_interval)
|
|
242
|
-
.unwrap_or(true);
|
|
243
|
-
if !due {
|
|
244
|
-
None
|
|
245
|
-
} else {
|
|
246
|
-
let detail_run_id = rm.detail_run_id.clone();
|
|
247
|
-
Some(detail_run_id)
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
};
|
|
251
|
-
if let Some(detail_run_id) = run_poll {
|
|
252
|
-
if let Some(ws) = &ws_client {
|
|
253
|
-
app.state.run_manager.last_refresh = Some(Instant::now());
|
|
254
|
-
app.begin_run_list_request(ws, true);
|
|
255
|
-
if let Some(run_id) = detail_run_id {
|
|
256
|
-
app.begin_run_get_request(ws, &run_id);
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
// ┌─────────────────────────────────────────────────────────┐
|
|
263
|
-
// │ STEP 2: CHECK WEBSOCKET MESSAGES │
|
|
264
|
-
// └─────────────────────────────────────────────────────────┘
|
|
265
|
-
if let Some(ref client) = ws_client {
|
|
266
|
-
while let Some(msg) = client.try_recv() {
|
|
267
|
-
match msg {
|
|
268
|
-
WsClientMessage::Connected => {
|
|
269
|
-
app.add_log("WebSocket connected".to_string());
|
|
270
|
-
|
|
271
|
-
// Step 4.9: Send startup commands to load real data
|
|
272
|
-
if let Ok(id) = client.send_command("system.status", None) {
|
|
273
|
-
app.add_log(format!(
|
|
274
|
-
"Sent system.status (id: {})",
|
|
275
|
-
&id[id.len().saturating_sub(8)..]
|
|
276
|
-
));
|
|
277
|
-
}
|
|
278
|
-
if let Ok(id) = client.send_command("agent.list", None) {
|
|
279
|
-
app.add_log(format!(
|
|
280
|
-
"Sent agent.list (id: {})",
|
|
281
|
-
&id[id.len().saturating_sub(8)..]
|
|
282
|
-
));
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
WsClientMessage::Disconnected => {
|
|
286
|
-
app.add_log(
|
|
287
|
-
"[WEBSOCKET] Disconnected from CLI backend — Gateway link cleared"
|
|
288
|
-
.to_string(),
|
|
289
|
-
);
|
|
290
|
-
app.on_cli_backend_disconnect();
|
|
291
|
-
}
|
|
292
|
-
WsClientMessage::ConnectionLost => {
|
|
293
|
-
app.add_log("[WEBSOCKET] Connection lost — Gateway link cleared (reconnect may restore)".to_string());
|
|
294
|
-
app.on_cli_backend_disconnect();
|
|
295
|
-
}
|
|
296
|
-
WsClientMessage::Reconnecting => {
|
|
297
|
-
app.add_log("[WEBSOCKET] Reconnecting...".to_string());
|
|
298
|
-
}
|
|
299
|
-
WsClientMessage::ReconnectFailed(reason) => {
|
|
300
|
-
app.add_log(format!("[WEBSOCKET] Reconnection failed: {}", reason));
|
|
301
|
-
}
|
|
302
|
-
WsClientMessage::Response(resp) => {
|
|
303
|
-
if resp.payload.success {
|
|
304
|
-
// Format response nicely and update state based on command
|
|
305
|
-
let short_id = &resp.id[resp.id.len().saturating_sub(8)..];
|
|
306
|
-
|
|
307
|
-
// Try to extract and apply data to state
|
|
308
|
-
if let Some(data) = &resp.payload.data {
|
|
309
|
-
if let Some(obj) = data.as_object() {
|
|
310
|
-
// Handle system.status response
|
|
311
|
-
if let Some(mode) = obj.get("mode") {
|
|
312
|
-
if let Some(mode_str) = mode.as_str() {
|
|
313
|
-
app.state.network_status = mode_str.to_string();
|
|
314
|
-
}
|
|
315
|
-
if let Some(posture) = obj.get("posture") {
|
|
316
|
-
if let Some(posture_str) = posture.as_str() {
|
|
317
|
-
app.state.posture_status = posture_str.to_string();
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
if let Some(sh) =
|
|
321
|
-
obj.get("shield").and_then(|v| v.as_object())
|
|
322
|
-
{
|
|
323
|
-
if let Some(m) =
|
|
324
|
-
sh.get("mode").and_then(|v| v.as_str())
|
|
325
|
-
{
|
|
326
|
-
app.state.shield_mode = m.to_string();
|
|
327
|
-
}
|
|
328
|
-
if let Some(dets) =
|
|
329
|
-
sh.get("detectors").and_then(|v| v.as_array())
|
|
330
|
-
{
|
|
331
|
-
app.state.shield_detectors = dets
|
|
332
|
-
.iter()
|
|
333
|
-
.filter_map(|v| {
|
|
334
|
-
v.as_str().map(|s| s.to_string())
|
|
335
|
-
})
|
|
336
|
-
.collect();
|
|
337
|
-
}
|
|
338
|
-
app.state.shield_blocks_total = sh
|
|
339
|
-
.get("blocksTotal")
|
|
340
|
-
.and_then(|v| v.as_u64())
|
|
341
|
-
.unwrap_or(0);
|
|
342
|
-
app.state.shield_masks_total = sh
|
|
343
|
-
.get("masksTotal")
|
|
344
|
-
.and_then(|v| v.as_u64())
|
|
345
|
-
.unwrap_or(0);
|
|
346
|
-
}
|
|
347
|
-
if let Some(sent) =
|
|
348
|
-
obj.get("sentinel").and_then(|v| v.as_object())
|
|
349
|
-
{
|
|
350
|
-
app.state.sentinel_active_runs = sent
|
|
351
|
-
.get("watchedRuns")
|
|
352
|
-
.and_then(|v| v.as_u64())
|
|
353
|
-
.unwrap_or(0) as usize;
|
|
354
|
-
let enabled = sent
|
|
355
|
-
.get("enabled")
|
|
356
|
-
.and_then(|v| v.as_bool())
|
|
357
|
-
.unwrap_or(false);
|
|
358
|
-
let healthy = sent
|
|
359
|
-
.get("healthy")
|
|
360
|
-
.and_then(|v| v.as_bool())
|
|
361
|
-
.unwrap_or(false);
|
|
362
|
-
app.state.sentinel_state = if !enabled {
|
|
363
|
-
"off".to_string()
|
|
364
|
-
} else if app.state.sentinel_active_runs > 0 {
|
|
365
|
-
"watching".to_string()
|
|
366
|
-
} else if healthy {
|
|
367
|
-
"idle".to_string()
|
|
368
|
-
} else {
|
|
369
|
-
"degraded".to_string()
|
|
370
|
-
};
|
|
371
|
-
}
|
|
372
|
-
app.add_log(format!(
|
|
373
|
-
"✓ [{}] Mode: {}, Posture: {}",
|
|
374
|
-
short_id,
|
|
375
|
-
mode.as_str().unwrap_or("?"),
|
|
376
|
-
obj.get("posture")
|
|
377
|
-
.and_then(|p| p.as_str())
|
|
378
|
-
.unwrap_or("?")
|
|
379
|
-
));
|
|
380
|
-
}
|
|
381
|
-
// Shield dashboard — match pending id before legacy shieldStatus branch
|
|
382
|
-
else if Some(&resp.id)
|
|
383
|
-
== app.state.pending_shield_load_id.as_ref()
|
|
384
|
-
{
|
|
385
|
-
app.state.pending_shield_load_id = None;
|
|
386
|
-
if obj.get("shieldLoad").and_then(|v| v.as_bool()) == Some(true)
|
|
387
|
-
{
|
|
388
|
-
use crate::ui::shield_dashboard::{
|
|
389
|
-
parse_shield_activity, parse_shield_breakdown,
|
|
390
|
-
parse_shield_load,
|
|
391
|
-
};
|
|
392
|
-
let health_val = obj
|
|
393
|
-
.get("health")
|
|
394
|
-
.cloned()
|
|
395
|
-
.unwrap_or(serde_json::Value::Null);
|
|
396
|
-
let config_val = obj
|
|
397
|
-
.get("config")
|
|
398
|
-
.cloned()
|
|
399
|
-
.unwrap_or(serde_json::Value::Null);
|
|
400
|
-
let metrics_val = obj
|
|
401
|
-
.get("metrics")
|
|
402
|
-
.cloned()
|
|
403
|
-
.unwrap_or(serde_json::Value::Null);
|
|
404
|
-
let gateway_health_val = obj
|
|
405
|
-
.get("gatewayHealth")
|
|
406
|
-
.cloned()
|
|
407
|
-
.unwrap_or(serde_json::Value::Null);
|
|
408
|
-
let runs_val = obj
|
|
409
|
-
.get("recentRuns")
|
|
410
|
-
.cloned()
|
|
411
|
-
.unwrap_or(serde_json::Value::Null);
|
|
412
|
-
let warnings_vec: Vec<String> = obj
|
|
413
|
-
.get("warnings")
|
|
414
|
-
.and_then(|v| v.as_array())
|
|
415
|
-
.map(|a| {
|
|
416
|
-
a.iter()
|
|
417
|
-
.filter_map(|w| {
|
|
418
|
-
w.as_str().map(|s| s.to_string())
|
|
419
|
-
})
|
|
420
|
-
.collect()
|
|
421
|
-
})
|
|
422
|
-
.unwrap_or_default();
|
|
423
|
-
let activity_val = obj
|
|
424
|
-
.get("activity")
|
|
425
|
-
.cloned()
|
|
426
|
-
.unwrap_or(serde_json::Value::Null);
|
|
427
|
-
let breakdown_val = obj
|
|
428
|
-
.get("shieldBreakdown")
|
|
429
|
-
.cloned()
|
|
430
|
-
.unwrap_or(serde_json::Value::Null);
|
|
431
|
-
let snapshot_at = obj
|
|
432
|
-
.get("snapshotAt")
|
|
433
|
-
.and_then(|v| v.as_str())
|
|
434
|
-
.unwrap_or("")
|
|
435
|
-
.to_string();
|
|
436
|
-
let (h, c, m, mut w, recent) = parse_shield_load(
|
|
437
|
-
&health_val,
|
|
438
|
-
&config_val,
|
|
439
|
-
&metrics_val,
|
|
440
|
-
&gateway_health_val,
|
|
441
|
-
&runs_val,
|
|
442
|
-
);
|
|
443
|
-
w.extend(warnings_vec);
|
|
444
|
-
let activity = parse_shield_activity(&activity_val);
|
|
445
|
-
let breakdown_lines =
|
|
446
|
-
parse_shield_breakdown(&breakdown_val);
|
|
447
|
-
app.state.shield_dashboard.apply_load(
|
|
448
|
-
&h,
|
|
449
|
-
&c,
|
|
450
|
-
&m,
|
|
451
|
-
w,
|
|
452
|
-
recent,
|
|
453
|
-
activity,
|
|
454
|
-
breakdown_lines,
|
|
455
|
-
snapshot_at,
|
|
456
|
-
);
|
|
457
|
-
app.state.shield_mode = h.mode.clone();
|
|
458
|
-
app.state.shield_blocks_total = m.blocks;
|
|
459
|
-
app.state.shield_masks_total = m.masks;
|
|
460
|
-
app.add_log(format!(
|
|
461
|
-
"✓ [{}] Shield loaded — {} block(s), {} mask(s)",
|
|
462
|
-
short_id, m.blocks, m.masks
|
|
463
|
-
));
|
|
464
|
-
} else {
|
|
465
|
-
app.state.shield_dashboard.fail_loading(
|
|
466
|
-
"Shield load: unexpected response shape".to_string(),
|
|
467
|
-
);
|
|
468
|
-
}
|
|
469
|
-
app.request_render("shield_loaded");
|
|
470
|
-
}
|
|
471
|
-
else if obj.get("shieldDemo").and_then(|v| v.as_bool())
|
|
472
|
-
== Some(true)
|
|
473
|
-
{
|
|
474
|
-
let msg = obj
|
|
475
|
-
.get("message")
|
|
476
|
-
.and_then(|v| v.as_str())
|
|
477
|
-
.unwrap_or("Shield demo run started");
|
|
478
|
-
app.add_log(format!("✓ [{}] {}", short_id, msg));
|
|
479
|
-
if let Some(rid) =
|
|
480
|
-
obj.get("runId").and_then(|v| v.as_str())
|
|
481
|
-
{
|
|
482
|
-
app.add_log(format!(
|
|
483
|
-
"[SHIELD] Demo run id: {} — open Run Manager",
|
|
484
|
-
rid
|
|
485
|
-
));
|
|
486
|
-
}
|
|
487
|
-
}
|
|
488
|
-
else if obj.get("shieldProbe").and_then(|v| v.as_bool())
|
|
489
|
-
== Some(true)
|
|
490
|
-
{
|
|
491
|
-
let result = obj.get("result");
|
|
492
|
-
let action = result
|
|
493
|
-
.and_then(|r| r.get("decision"))
|
|
494
|
-
.and_then(|d| d.get("action"))
|
|
495
|
-
.and_then(|a| a.as_str())
|
|
496
|
-
.unwrap_or("?");
|
|
497
|
-
app.add_log(format!(
|
|
498
|
-
"✓ [{}] Shield probe: action={}",
|
|
499
|
-
short_id, action
|
|
500
|
-
));
|
|
501
|
-
}
|
|
502
|
-
else if obj.get("shieldStatus").and_then(|v| v.as_bool())
|
|
503
|
-
== Some(true)
|
|
504
|
-
{
|
|
505
|
-
let metrics = obj.get("metrics").and_then(|v| v.as_object());
|
|
506
|
-
let blocks = metrics
|
|
507
|
-
.and_then(|m| m.get("blocks"))
|
|
508
|
-
.and_then(|v| v.as_u64())
|
|
509
|
-
.unwrap_or(0);
|
|
510
|
-
let masks = metrics
|
|
511
|
-
.and_then(|m| m.get("masks"))
|
|
512
|
-
.and_then(|v| v.as_u64())
|
|
513
|
-
.unwrap_or(0);
|
|
514
|
-
app.state.shield_blocks_total = blocks;
|
|
515
|
-
app.state.shield_masks_total = masks;
|
|
516
|
-
let mode = obj
|
|
517
|
-
.get("health")
|
|
518
|
-
.and_then(|h| h.get("mode"))
|
|
519
|
-
.and_then(|v| v.as_str())
|
|
520
|
-
.unwrap_or("?");
|
|
521
|
-
app.add_log(format!(
|
|
522
|
-
"✓ [{}] Shield {} — {} block(s), {} mask(s)",
|
|
523
|
-
short_id, mode, blocks, masks
|
|
524
|
-
));
|
|
525
|
-
}
|
|
526
|
-
// Handle agent.list response
|
|
527
|
-
else if let Some(agents_data) = obj.get("agents") {
|
|
528
|
-
if let Some(agents_array) = agents_data.as_array() {
|
|
529
|
-
// Parse agents into AgentInfo structs
|
|
530
|
-
use crate::app::AgentInfo;
|
|
531
|
-
let agents: Vec<AgentInfo> = agents_array
|
|
532
|
-
.iter()
|
|
533
|
-
.filter_map(|agent| {
|
|
534
|
-
let obj = agent.as_object()?;
|
|
535
|
-
Some(AgentInfo {
|
|
536
|
-
name: obj
|
|
537
|
-
.get("name")?
|
|
538
|
-
.as_str()?
|
|
539
|
-
.to_string(),
|
|
540
|
-
description: obj
|
|
541
|
-
.get("description")
|
|
542
|
-
.and_then(|d| d.as_str())
|
|
543
|
-
.map(|s| s.to_string()),
|
|
544
|
-
model: obj
|
|
545
|
-
.get("model")
|
|
546
|
-
.and_then(|m| m.as_str())
|
|
547
|
-
.unwrap_or("unknown")
|
|
548
|
-
.to_string(),
|
|
549
|
-
provider: obj
|
|
550
|
-
.get("provider")
|
|
551
|
-
.and_then(|p| p.as_str())
|
|
552
|
-
.unwrap_or("unknown")
|
|
553
|
-
.to_string(),
|
|
554
|
-
system_prompt: obj
|
|
555
|
-
.get("systemPrompt")
|
|
556
|
-
.and_then(|sp| sp.as_str())
|
|
557
|
-
.map(|s| s.to_string()),
|
|
558
|
-
temperature: obj
|
|
559
|
-
.get("temperature")
|
|
560
|
-
.and_then(|t| t.as_f64())
|
|
561
|
-
.map(|f| f as f32),
|
|
562
|
-
max_tokens: obj
|
|
563
|
-
.get("maxTokens")
|
|
564
|
-
.and_then(|mt| mt.as_u64())
|
|
565
|
-
.map(|u| u as u32),
|
|
566
|
-
tools: obj
|
|
567
|
-
.get("tools")
|
|
568
|
-
.and_then(|t| t.as_array())
|
|
569
|
-
.map(|arr| {
|
|
570
|
-
arr.iter()
|
|
571
|
-
.filter_map(|v| {
|
|
572
|
-
v.as_str()
|
|
573
|
-
.map(|s| s.to_string())
|
|
574
|
-
})
|
|
575
|
-
.collect()
|
|
576
|
-
})
|
|
577
|
-
.unwrap_or_default(),
|
|
578
|
-
})
|
|
579
|
-
})
|
|
580
|
-
.collect();
|
|
581
|
-
|
|
582
|
-
// Update capabilities with agent names
|
|
583
|
-
app.state.capabilities =
|
|
584
|
-
agents.iter().map(|a| a.name.clone()).collect();
|
|
585
|
-
|
|
586
|
-
// Update cache with agent data
|
|
587
|
-
if let Some(cache) = &mut app.state.cache {
|
|
588
|
-
use crate::storage::cache::AgentData;
|
|
589
|
-
use std::time::{SystemTime, UNIX_EPOCH};
|
|
590
|
-
|
|
591
|
-
let cache_agents: Vec<AgentData> = agents
|
|
592
|
-
.iter()
|
|
593
|
-
.map(|agent| AgentData {
|
|
594
|
-
name: agent.name.clone(),
|
|
595
|
-
description: agent.description.clone(),
|
|
596
|
-
model: agent.model.clone(),
|
|
597
|
-
provider: agent.provider.clone(),
|
|
598
|
-
created_at: SystemTime::now()
|
|
599
|
-
.duration_since(UNIX_EPOCH)
|
|
600
|
-
.unwrap()
|
|
601
|
-
.as_secs(),
|
|
602
|
-
})
|
|
603
|
-
.collect();
|
|
604
|
-
|
|
605
|
-
let _ = cache.update_agents(cache_agents);
|
|
606
|
-
}
|
|
607
|
-
|
|
608
|
-
// Update agent list state
|
|
609
|
-
app.state.agent_list.agents = agents;
|
|
610
|
-
app.state.agent_list.selected_index = 0;
|
|
611
|
-
app.state.agent_list.detail_view = None;
|
|
612
|
-
|
|
613
|
-
// Clear pending agent.list ID if this response matches (Step 5.2)
|
|
614
|
-
if Some(&resp.id)
|
|
615
|
-
== app.state.pending_agent_list_id.as_ref()
|
|
616
|
-
{
|
|
617
|
-
app.state.pending_agent_list_id = None;
|
|
618
|
-
}
|
|
619
|
-
|
|
620
|
-
// Only open AgentList overlay if we're on Main screen (not during boot)
|
|
621
|
-
use crate::screens::Screen;
|
|
622
|
-
if app.state.navigation.current_screen()
|
|
623
|
-
== &Screen::Main
|
|
624
|
-
{
|
|
625
|
-
app.push_overlay(Screen::AgentList);
|
|
626
|
-
app.request_render("agent_list_opened");
|
|
627
|
-
}
|
|
628
|
-
}
|
|
629
|
-
}
|
|
630
|
-
// Handle agent.create response (Step 5.1)
|
|
631
|
-
else if let Some(agent) = obj.get("agent") {
|
|
632
|
-
// Check if this is a response to our agent.create command
|
|
633
|
-
if Some(&resp.id)
|
|
634
|
-
== app.state.pending_agent_create_id.as_ref()
|
|
635
|
-
{
|
|
636
|
-
app.state.pending_agent_create_id = None;
|
|
637
|
-
|
|
638
|
-
// Extract agent name for success message
|
|
639
|
-
let agent_name = agent
|
|
640
|
-
.as_object()
|
|
641
|
-
.and_then(|a| a.get("name"))
|
|
642
|
-
.and_then(|n| n.as_str())
|
|
643
|
-
.unwrap_or("unknown");
|
|
644
|
-
|
|
645
|
-
app.add_log(format!(
|
|
646
|
-
"✓ [{}] Agent '{}' created successfully",
|
|
647
|
-
short_id, agent_name
|
|
648
|
-
));
|
|
649
|
-
|
|
650
|
-
// Refresh agent list (Step 5.3)
|
|
651
|
-
if let Some(ref ws) = ws_client {
|
|
652
|
-
if let Ok(list_id) =
|
|
653
|
-
ws.send_command("agent.list", None)
|
|
654
|
-
{
|
|
655
|
-
app.state.pending_agent_list_id = Some(list_id);
|
|
656
|
-
}
|
|
657
|
-
}
|
|
658
|
-
} else {
|
|
659
|
-
app.add_log(format!(
|
|
660
|
-
"✓ [{}] Agent response received",
|
|
661
|
-
short_id
|
|
662
|
-
));
|
|
663
|
-
}
|
|
664
|
-
}
|
|
665
|
-
// Handle agent.delete response (Step 5.5)
|
|
666
|
-
else if let Some(deleted) = obj.get("deleted") {
|
|
667
|
-
if deleted.as_bool().unwrap_or(false) {
|
|
668
|
-
if Some(&resp.id)
|
|
669
|
-
== app.state.pending_agent_delete_id.as_ref()
|
|
670
|
-
{
|
|
671
|
-
app.state.pending_agent_delete_id = None;
|
|
672
|
-
app.add_log(format!(
|
|
673
|
-
"✓ [{}] Agent deleted successfully",
|
|
674
|
-
short_id
|
|
675
|
-
));
|
|
676
|
-
|
|
677
|
-
// Refresh agent list (Step 5.5)
|
|
678
|
-
if let Some(ref ws) = ws_client {
|
|
679
|
-
if let Ok(list_id) =
|
|
680
|
-
ws.send_command("agent.list", None)
|
|
681
|
-
{
|
|
682
|
-
app.state.pending_agent_list_id =
|
|
683
|
-
Some(list_id);
|
|
684
|
-
}
|
|
685
|
-
}
|
|
686
|
-
}
|
|
687
|
-
}
|
|
688
|
-
}
|
|
689
|
-
// Step 6: run.list (match pending id first — avoids stealing the chain on unrelated `runs` keys)
|
|
690
|
-
else if Some(&resp.id)
|
|
691
|
-
== app.state.pending_run_list_id.as_ref()
|
|
692
|
-
{
|
|
693
|
-
let silent = app.state.pending_run_list_silent;
|
|
694
|
-
app.state.pending_run_list_id = None;
|
|
695
|
-
app.state.pending_run_list_silent = false;
|
|
696
|
-
app.state.run_manager.loading = false;
|
|
697
|
-
if let Some(runs_arr) =
|
|
698
|
-
obj.get("runs").and_then(|r| r.as_array())
|
|
699
|
-
{
|
|
700
|
-
use crate::ui::run_manager::run_info_from_gateway_value;
|
|
701
|
-
let mut parsed = Vec::new();
|
|
702
|
-
for item in runs_arr {
|
|
703
|
-
if let Some(info) =
|
|
704
|
-
run_info_from_gateway_value(item)
|
|
705
|
-
{
|
|
706
|
-
parsed.push(info);
|
|
707
|
-
}
|
|
708
|
-
}
|
|
709
|
-
let preserve =
|
|
710
|
-
!app.state.run_manager.runs.is_empty();
|
|
711
|
-
if preserve {
|
|
712
|
-
app.state
|
|
713
|
-
.run_manager
|
|
714
|
-
.replace_runs_preserve(parsed);
|
|
715
|
-
} else {
|
|
716
|
-
app.state.run_manager.replace_runs(parsed);
|
|
717
|
-
}
|
|
718
|
-
if !silent {
|
|
719
|
-
app.add_log(format!(
|
|
720
|
-
"✓ [{}] Loaded {} run(s) from Gateway",
|
|
721
|
-
short_id,
|
|
722
|
-
app.state.run_manager.runs.len()
|
|
723
|
-
));
|
|
724
|
-
}
|
|
725
|
-
app.request_render("run_list_loaded");
|
|
726
|
-
} else {
|
|
727
|
-
app.add_log(format!(
|
|
728
|
-
"⚠ [{}] run.list: missing or invalid `runs` array",
|
|
729
|
-
short_id
|
|
730
|
-
));
|
|
731
|
-
}
|
|
732
|
-
}
|
|
733
|
-
// Step 6: run.get (detail) — pending id first so `run` never blocks other handlers
|
|
734
|
-
else if Some(&resp.id)
|
|
735
|
-
== app.state.pending_run_get_id.as_ref()
|
|
736
|
-
{
|
|
737
|
-
app.state.pending_run_get_id = None;
|
|
738
|
-
if let Some(run_val) = obj.get("run") {
|
|
739
|
-
use crate::ui::run_manager::run_info_from_gateway_value;
|
|
740
|
-
if let Some(info) = run_info_from_gateway_value(run_val)
|
|
741
|
-
{
|
|
742
|
-
app.state.run_manager.merge_run_detail(info);
|
|
743
|
-
}
|
|
744
|
-
}
|
|
745
|
-
app.request_render("run_detail_loaded");
|
|
746
|
-
}
|
|
747
|
-
// Step 6: run.cancel
|
|
748
|
-
else if Some(&resp.id)
|
|
749
|
-
== app.state.pending_run_cancel_id.as_ref()
|
|
750
|
-
{
|
|
751
|
-
app.state.pending_run_cancel_id = None;
|
|
752
|
-
if let (Some(rid), Some(st)) = (
|
|
753
|
-
obj.get("runId").and_then(|v| v.as_str()),
|
|
754
|
-
obj.get("status").and_then(|v| v.as_str()),
|
|
755
|
-
) {
|
|
756
|
-
app.add_log(format!(
|
|
757
|
-
"✓ [{}] Run {} cancelled ({})",
|
|
758
|
-
short_id, rid, st
|
|
759
|
-
));
|
|
760
|
-
} else {
|
|
761
|
-
app.add_log(format!(
|
|
762
|
-
"✓ [{}] Run cancel acknowledged",
|
|
763
|
-
short_id
|
|
764
|
-
));
|
|
765
|
-
}
|
|
766
|
-
if let Some(ref ws) = ws_client {
|
|
767
|
-
let data = serde_json::json!({ "limit": 50 });
|
|
768
|
-
if let Ok(lid) = ws.send_command("run.list", Some(data))
|
|
769
|
-
{
|
|
770
|
-
app.state.pending_run_list_id = Some(lid);
|
|
771
|
-
}
|
|
772
|
-
}
|
|
773
|
-
app.request_render("run_cancelled");
|
|
774
|
-
}
|
|
775
|
-
// Step 6: run.quick
|
|
776
|
-
else if Some(&resp.id)
|
|
777
|
-
== app.state.pending_run_quick_id.as_ref()
|
|
778
|
-
{
|
|
779
|
-
app.state.pending_run_quick_id = None;
|
|
780
|
-
if let (Some(rid), Some(st)) = (
|
|
781
|
-
obj.get("runId").and_then(|v| v.as_str()),
|
|
782
|
-
obj.get("status").and_then(|v| v.as_str()),
|
|
783
|
-
) {
|
|
784
|
-
app.add_log(format!(
|
|
785
|
-
"✓ [{}] Run {} queued ({})",
|
|
786
|
-
short_id, rid, st
|
|
787
|
-
));
|
|
788
|
-
} else {
|
|
789
|
-
app.add_log(format!("✓ [{}] Run queued", short_id));
|
|
790
|
-
}
|
|
791
|
-
if let Some(ref ws) = ws_client {
|
|
792
|
-
let data = serde_json::json!({ "limit": 50 });
|
|
793
|
-
if let Ok(lid) = ws.send_command("run.list", Some(data))
|
|
794
|
-
{
|
|
795
|
-
app.state.pending_run_list_id = Some(lid);
|
|
796
|
-
}
|
|
797
|
-
}
|
|
798
|
-
app.request_render("run_quick_ok");
|
|
799
|
-
}
|
|
800
|
-
// Sentinel config: load templates + current + health
|
|
801
|
-
else if Some(&resp.id)
|
|
802
|
-
== app.state.pending_sentinel_load_id.as_ref()
|
|
803
|
-
{
|
|
804
|
-
app.state.pending_sentinel_load_id = None;
|
|
805
|
-
if obj.get("sentinelLoad").and_then(|v| v.as_bool()) == Some(true)
|
|
806
|
-
{
|
|
807
|
-
use crate::ui::sentinel_config::{
|
|
808
|
-
parse_current_config, parse_health,
|
|
809
|
-
parse_sentinel_load,
|
|
810
|
-
};
|
|
811
|
-
let templates_vec: Vec<serde_json::Value> = obj
|
|
812
|
-
.get("templates")
|
|
813
|
-
.and_then(|v| v.as_array())
|
|
814
|
-
.map(|a| a.clone())
|
|
815
|
-
.unwrap_or_default();
|
|
816
|
-
let current_val = obj
|
|
817
|
-
.get("current")
|
|
818
|
-
.cloned()
|
|
819
|
-
.unwrap_or(serde_json::Value::Null);
|
|
820
|
-
let health_val = obj
|
|
821
|
-
.get("health")
|
|
822
|
-
.cloned()
|
|
823
|
-
.unwrap_or(serde_json::Value::Null);
|
|
824
|
-
let (rows, cur, h) = parse_sentinel_load(
|
|
825
|
-
&templates_vec,
|
|
826
|
-
¤t_val,
|
|
827
|
-
&health_val,
|
|
828
|
-
);
|
|
829
|
-
app.state.sentinel_config.apply_load(rows, &cur, &h);
|
|
830
|
-
app.state.sentinel_active_runs = h.watched_runs as usize;
|
|
831
|
-
app.state.sentinel_state = if h.watched_runs > 0 {
|
|
832
|
-
"watching".to_string()
|
|
833
|
-
} else if h.status == "healthy" {
|
|
834
|
-
"ready".to_string()
|
|
835
|
-
} else {
|
|
836
|
-
h.status.clone()
|
|
837
|
-
};
|
|
838
|
-
app.add_log(format!(
|
|
839
|
-
"✓ [{}] Sentinel config loaded (idle {}ms)",
|
|
840
|
-
short_id, cur.idle_ms
|
|
841
|
-
));
|
|
842
|
-
}
|
|
843
|
-
app.request_render("sentinel_loaded");
|
|
844
|
-
}
|
|
845
|
-
// Sentinel config: apply template
|
|
846
|
-
else if Some(&resp.id)
|
|
847
|
-
== app.state.pending_sentinel_apply_id.as_ref()
|
|
848
|
-
{
|
|
849
|
-
app.state.pending_sentinel_apply_id = None;
|
|
850
|
-
if obj.get("sentinelApply").and_then(|v| v.as_bool())
|
|
851
|
-
== Some(true)
|
|
852
|
-
{
|
|
853
|
-
use crate::ui::sentinel_config::parse_current_config;
|
|
854
|
-
let current_val = obj
|
|
855
|
-
.get("current")
|
|
856
|
-
.cloned()
|
|
857
|
-
.unwrap_or(serde_json::Value::Null);
|
|
858
|
-
let cur = parse_current_config(¤t_val);
|
|
859
|
-
let msg = obj
|
|
860
|
-
.get("message")
|
|
861
|
-
.and_then(|v| v.as_str())
|
|
862
|
-
.map(|s| s.to_string());
|
|
863
|
-
app.state
|
|
864
|
-
.sentinel_config
|
|
865
|
-
.apply_current(&cur, msg.clone());
|
|
866
|
-
if let Some(m) = msg {
|
|
867
|
-
app.add_log(format!("✓ [{}] {}", short_id, m));
|
|
868
|
-
}
|
|
869
|
-
}
|
|
870
|
-
app.request_render("sentinel_applied");
|
|
871
|
-
}
|
|
872
|
-
// Portal Monitoring Phase 2: monitoring.refresh (section slice)
|
|
873
|
-
else if Some(&resp.id)
|
|
874
|
-
== app.state.pending_monitoring_refresh_id.as_ref()
|
|
875
|
-
{
|
|
876
|
-
app.state.pending_monitoring_refresh_id = None;
|
|
877
|
-
app.state.portal_monitoring.section_refresh_loading = None;
|
|
878
|
-
if obj.get("monitoringRefresh").and_then(|v| v.as_bool())
|
|
879
|
-
== Some(true)
|
|
880
|
-
{
|
|
881
|
-
let section_str = obj
|
|
882
|
-
.get("section")
|
|
883
|
-
.and_then(|v| v.as_str())
|
|
884
|
-
.unwrap_or("");
|
|
885
|
-
use crate::monitoring::MonitoringSection;
|
|
886
|
-
if let Some(sec) =
|
|
887
|
-
MonitoringSection::from_cli_slug(section_str)
|
|
888
|
-
{
|
|
889
|
-
let lines: Vec<String> = obj
|
|
890
|
-
.get("lines")
|
|
891
|
-
.and_then(|a| a.as_array())
|
|
892
|
-
.map(|arr| {
|
|
893
|
-
arr.iter()
|
|
894
|
-
.filter_map(|v| {
|
|
895
|
-
v.as_str()
|
|
896
|
-
.map(sanitize_monitoring_line)
|
|
897
|
-
})
|
|
898
|
-
.collect()
|
|
899
|
-
})
|
|
900
|
-
.unwrap_or_default();
|
|
901
|
-
app.state
|
|
902
|
-
.portal_monitoring
|
|
903
|
-
.section_overrides
|
|
904
|
-
.insert(sec, lines);
|
|
905
|
-
}
|
|
906
|
-
}
|
|
907
|
-
app.request_render("monitoring_refresh_ok");
|
|
908
|
-
}
|
|
909
|
-
// Portal Monitoring Phase 2: monitoring.logs
|
|
910
|
-
else if Some(&resp.id)
|
|
911
|
-
== app.state.pending_monitoring_logs_id.as_ref()
|
|
912
|
-
{
|
|
913
|
-
app.state.pending_monitoring_logs_id = None;
|
|
914
|
-
app.state.portal_monitoring.logs_fetch_loading = false;
|
|
915
|
-
if obj.get("monitoringLogs").and_then(|v| v.as_bool())
|
|
916
|
-
== Some(true)
|
|
917
|
-
{
|
|
918
|
-
let lines: Vec<String> = obj
|
|
919
|
-
.get("logs")
|
|
920
|
-
.and_then(|a| a.as_array())
|
|
921
|
-
.map(|arr| {
|
|
922
|
-
arr.iter()
|
|
923
|
-
.filter_map(|entry| {
|
|
924
|
-
let e = entry.as_object()?;
|
|
925
|
-
let ts = e
|
|
926
|
-
.get("timestamp")
|
|
927
|
-
.and_then(|v| v.as_str())
|
|
928
|
-
.unwrap_or("");
|
|
929
|
-
let lvl = e
|
|
930
|
-
.get("level")
|
|
931
|
-
.and_then(|v| v.as_str())
|
|
932
|
-
.unwrap_or("");
|
|
933
|
-
let msg = e
|
|
934
|
-
.get("message")
|
|
935
|
-
.and_then(|v| v.as_str())
|
|
936
|
-
.unwrap_or("");
|
|
937
|
-
if ts.is_empty()
|
|
938
|
-
&& lvl.is_empty()
|
|
939
|
-
&& msg.is_empty()
|
|
940
|
-
{
|
|
941
|
-
return None;
|
|
942
|
-
}
|
|
943
|
-
Some(sanitize_monitoring_line(
|
|
944
|
-
&format!(
|
|
945
|
-
"{} [{}] {}",
|
|
946
|
-
ts, lvl, msg
|
|
947
|
-
),
|
|
948
|
-
))
|
|
949
|
-
})
|
|
950
|
-
.collect()
|
|
951
|
-
})
|
|
952
|
-
.unwrap_or_default();
|
|
953
|
-
use crate::monitoring::MonitoringSection;
|
|
954
|
-
app.state
|
|
955
|
-
.portal_monitoring
|
|
956
|
-
.section_overrides
|
|
957
|
-
.insert(MonitoringSection::Logs, lines);
|
|
958
|
-
}
|
|
959
|
-
app.request_render("monitoring_logs_ok");
|
|
960
|
-
}
|
|
961
|
-
// Portal Monitoring Phase 3: monitoring.drill (metrics sub-panels / dependency detail)
|
|
962
|
-
else if Some(&resp.id)
|
|
963
|
-
== app.state.pending_monitoring_drill_id.as_ref()
|
|
964
|
-
{
|
|
965
|
-
app.state.pending_monitoring_drill_id = None;
|
|
966
|
-
app.state.portal_monitoring.metrics_drill_loading = false;
|
|
967
|
-
app.state.portal_monitoring.section_refresh_loading = None;
|
|
968
|
-
if obj.get("monitoringDrill").and_then(|v| v.as_bool())
|
|
969
|
-
== Some(true)
|
|
970
|
-
{
|
|
971
|
-
let target = obj
|
|
972
|
-
.get("target")
|
|
973
|
-
.and_then(|v| v.as_str())
|
|
974
|
-
.unwrap_or("");
|
|
975
|
-
let lines: Vec<String> = obj
|
|
976
|
-
.get("lines")
|
|
977
|
-
.and_then(|a| a.as_array())
|
|
978
|
-
.map(|arr| {
|
|
979
|
-
arr.iter()
|
|
980
|
-
.filter_map(|v| {
|
|
981
|
-
v.as_str().map(sanitize_monitoring_line)
|
|
982
|
-
})
|
|
983
|
-
.collect()
|
|
984
|
-
})
|
|
985
|
-
.unwrap_or_default();
|
|
986
|
-
use crate::monitoring::{
|
|
987
|
-
MetricsDrillPanel, MonitoringSection,
|
|
988
|
-
};
|
|
989
|
-
if target == "dependencies_detail" {
|
|
990
|
-
app.state
|
|
991
|
-
.portal_monitoring
|
|
992
|
-
.section_overrides
|
|
993
|
-
.insert(MonitoringSection::Dependencies, lines);
|
|
994
|
-
} else if target == "system_diagnostics" {
|
|
995
|
-
app.state
|
|
996
|
-
.portal_monitoring
|
|
997
|
-
.section_overrides
|
|
998
|
-
.insert(MonitoringSection::System, lines);
|
|
999
|
-
} else if let Some(panel) =
|
|
1000
|
-
MetricsDrillPanel::from_cli_target(target)
|
|
1001
|
-
{
|
|
1002
|
-
app.state.portal_monitoring.metrics_drill =
|
|
1003
|
-
Some(panel);
|
|
1004
|
-
app.state.portal_monitoring.metrics_drill_lines =
|
|
1005
|
-
lines;
|
|
1006
|
-
}
|
|
1007
|
-
}
|
|
1008
|
-
app.request_render("monitoring_drill_ok");
|
|
1009
|
-
}
|
|
1010
|
-
// Portal Monitoring: gateway.observability (/metrics snapshot)
|
|
1011
|
-
else if Some(&resp.id)
|
|
1012
|
-
== app.state.pending_gateway_observability_id.as_ref()
|
|
1013
|
-
{
|
|
1014
|
-
app.state.pending_gateway_observability_id = None;
|
|
1015
|
-
app.state.portal_monitoring.loading = false;
|
|
1016
|
-
app.state.portal_observability_last_poll =
|
|
1017
|
-
Some(Instant::now());
|
|
1018
|
-
if obj.get("observability").and_then(|v| v.as_bool())
|
|
1019
|
-
== Some(true)
|
|
1020
|
-
{
|
|
1021
|
-
let snapshot = obj
|
|
1022
|
-
.get("snapshotAt")
|
|
1023
|
-
.and_then(|v| v.as_str())
|
|
1024
|
-
.unwrap_or("")
|
|
1025
|
-
.to_string();
|
|
1026
|
-
// Snapshot markers — keep substring order compatible with
|
|
1027
|
-
// `portal_monitoring::SNAPSHOT_MARKER_*` (CLI healthLines + layout below).
|
|
1028
|
-
let mut lines: Vec<String> = vec![
|
|
1029
|
-
"Portal snapshot (health + metrics on each refresh / auto poll)."
|
|
1030
|
-
.to_string(),
|
|
1031
|
-
format!("Fetched: {}", if snapshot.is_empty() { "—" } else { snapshot.as_str() }),
|
|
1032
|
-
String::new(),
|
|
1033
|
-
];
|
|
1034
|
-
if let Some(tot) = obj
|
|
1035
|
-
.get("totals")
|
|
1036
|
-
.and_then(|v| v.get("httpRequests"))
|
|
1037
|
-
{
|
|
1038
|
-
let current = tot
|
|
1039
|
-
.as_u64()
|
|
1040
|
-
.or_else(|| tot.as_f64().map(|f| f as u64));
|
|
1041
|
-
if let Some(c) = current {
|
|
1042
|
-
if let (Some(prev), Some(last_t)) = (
|
|
1043
|
-
app.state
|
|
1044
|
-
.portal_monitoring
|
|
1045
|
-
.last_http_for_delta,
|
|
1046
|
-
app.state
|
|
1047
|
-
.portal_monitoring
|
|
1048
|
-
.last_instant_for_delta,
|
|
1049
|
-
) {
|
|
1050
|
-
let d = c.saturating_sub(prev);
|
|
1051
|
-
let el =
|
|
1052
|
-
last_t.elapsed().as_secs_f32().max(0.1);
|
|
1053
|
-
let per_min = (d as f32 / el) * 60.0;
|
|
1054
|
-
let pulse =
|
|
1055
|
-
if d > 0 { " *" } else { " --" };
|
|
1056
|
-
lines.push(format!(
|
|
1057
|
-
"LIVE: +{} HTTP since last screen refresh (~{:.0}/min){}",
|
|
1058
|
-
d, per_min, pulse
|
|
1059
|
-
));
|
|
1060
|
-
} else {
|
|
1061
|
-
lines.push("LIVE: first sample — next refresh shows HTTP request rate (poll interval).".to_string());
|
|
1062
|
-
}
|
|
1063
|
-
app.state
|
|
1064
|
-
.portal_monitoring
|
|
1065
|
-
.last_http_for_delta = Some(c);
|
|
1066
|
-
app.state
|
|
1067
|
-
.portal_monitoring
|
|
1068
|
-
.last_instant_for_delta =
|
|
1069
|
-
Some(std::time::Instant::now());
|
|
1070
|
-
app.state
|
|
1071
|
-
.portal_monitoring
|
|
1072
|
-
.http_total_sparkline
|
|
1073
|
-
.push_back(c);
|
|
1074
|
-
while app
|
|
1075
|
-
.state
|
|
1076
|
-
.portal_monitoring
|
|
1077
|
-
.http_total_sparkline
|
|
1078
|
-
.len()
|
|
1079
|
-
> 48
|
|
1080
|
-
{
|
|
1081
|
-
app.state
|
|
1082
|
-
.portal_monitoring
|
|
1083
|
-
.http_total_sparkline
|
|
1084
|
-
.pop_front();
|
|
1085
|
-
}
|
|
1086
|
-
}
|
|
1087
|
-
}
|
|
1088
|
-
if let Some(totals) =
|
|
1089
|
-
obj.get("totals").and_then(|v| v.as_object())
|
|
1090
|
-
{
|
|
1091
|
-
app.state
|
|
1092
|
-
.portal_monitoring
|
|
1093
|
-
.metric_history
|
|
1094
|
-
.push_back(
|
|
1095
|
-
crate::app::metric_history_entry_from_totals(
|
|
1096
|
-
if snapshot.is_empty() {
|
|
1097
|
-
"—".to_string()
|
|
1098
|
-
} else {
|
|
1099
|
-
snapshot.clone()
|
|
1100
|
-
},
|
|
1101
|
-
totals,
|
|
1102
|
-
),
|
|
1103
|
-
);
|
|
1104
|
-
while app
|
|
1105
|
-
.state
|
|
1106
|
-
.portal_monitoring
|
|
1107
|
-
.metric_history
|
|
1108
|
-
.len()
|
|
1109
|
-
> 720
|
|
1110
|
-
{
|
|
1111
|
-
app.state
|
|
1112
|
-
.portal_monitoring
|
|
1113
|
-
.metric_history
|
|
1114
|
-
.pop_front();
|
|
1115
|
-
}
|
|
1116
|
-
}
|
|
1117
|
-
// Phase 5 v1: dependency alerts are text-derived from
|
|
1118
|
-
// observability health lines, not a structured readiness enum.
|
|
1119
|
-
let dependency_status = {
|
|
1120
|
-
let mut status = if obj
|
|
1121
|
-
.get("healthOk")
|
|
1122
|
-
.and_then(|v| v.as_bool())
|
|
1123
|
-
== Some(false)
|
|
1124
|
-
{
|
|
1125
|
-
"unhealthy"
|
|
1126
|
-
} else {
|
|
1127
|
-
"healthy"
|
|
1128
|
-
};
|
|
1129
|
-
if let Some(arr) = obj
|
|
1130
|
-
.get("healthLines")
|
|
1131
|
-
.and_then(|a| a.as_array())
|
|
1132
|
-
{
|
|
1133
|
-
for v in arr {
|
|
1134
|
-
if let Some(s) = v.as_str() {
|
|
1135
|
-
let l = s.to_lowercase();
|
|
1136
|
-
if l.contains("✗")
|
|
1137
|
-
|| l.contains(": down")
|
|
1138
|
-
|| l.contains("not ready")
|
|
1139
|
-
{
|
|
1140
|
-
status = "unhealthy";
|
|
1141
|
-
break;
|
|
1142
|
-
}
|
|
1143
|
-
if l.contains("⚠")
|
|
1144
|
-
|| l.contains("degraded")
|
|
1145
|
-
|| l.contains("warning")
|
|
1146
|
-
{
|
|
1147
|
-
status = "degraded";
|
|
1148
|
-
}
|
|
1149
|
-
}
|
|
1150
|
-
}
|
|
1151
|
-
}
|
|
1152
|
-
status.to_string()
|
|
1153
|
-
};
|
|
1154
|
-
if let Some(prev) = app
|
|
1155
|
-
.state
|
|
1156
|
-
.portal_monitoring
|
|
1157
|
-
.last_dependency_status
|
|
1158
|
-
.clone()
|
|
1159
|
-
{
|
|
1160
|
-
if prev != dependency_status {
|
|
1161
|
-
app.state
|
|
1162
|
-
.portal_monitoring
|
|
1163
|
-
.dependency_alerts
|
|
1164
|
-
.push_back(
|
|
1165
|
-
crate::app::DependencyAlertEntry {
|
|
1166
|
-
timestamp: if snapshot.is_empty() {
|
|
1167
|
-
"—".to_string()
|
|
1168
|
-
} else {
|
|
1169
|
-
snapshot.clone()
|
|
1170
|
-
},
|
|
1171
|
-
previous: prev,
|
|
1172
|
-
current: dependency_status.clone(),
|
|
1173
|
-
},
|
|
1174
|
-
);
|
|
1175
|
-
while app
|
|
1176
|
-
.state
|
|
1177
|
-
.portal_monitoring
|
|
1178
|
-
.dependency_alerts
|
|
1179
|
-
.len()
|
|
1180
|
-
> 10
|
|
1181
|
-
{
|
|
1182
|
-
app.state
|
|
1183
|
-
.portal_monitoring
|
|
1184
|
-
.dependency_alerts
|
|
1185
|
-
.pop_front();
|
|
1186
|
-
}
|
|
1187
|
-
}
|
|
1188
|
-
}
|
|
1189
|
-
app.state.portal_monitoring.last_dependency_status =
|
|
1190
|
-
Some(dependency_status);
|
|
1191
|
-
lines.push(String::new());
|
|
1192
|
-
if let Some(arr) =
|
|
1193
|
-
obj.get("healthLines").and_then(|a| a.as_array())
|
|
1194
|
-
{
|
|
1195
|
-
for v in arr {
|
|
1196
|
-
if let Some(s) = v.as_str() {
|
|
1197
|
-
lines.push(s.to_string());
|
|
1198
|
-
}
|
|
1199
|
-
}
|
|
1200
|
-
lines.push(String::new());
|
|
1201
|
-
}
|
|
1202
|
-
lines.push(
|
|
1203
|
-
"Prometheus /metrics (HTTP total includes this screen’s /health, /ready, and /metrics polls; add API/agent traffic for runs/queue/SSE)."
|
|
1204
|
-
.to_string(),
|
|
1205
|
-
);
|
|
1206
|
-
lines.push(String::new());
|
|
1207
|
-
if let Some(arr) =
|
|
1208
|
-
obj.get("statsLines").and_then(|a| a.as_array())
|
|
1209
|
-
{
|
|
1210
|
-
for v in arr {
|
|
1211
|
-
if let Some(s) = v.as_str() {
|
|
1212
|
-
lines.push(s.to_string());
|
|
1213
|
-
}
|
|
1214
|
-
}
|
|
1215
|
-
}
|
|
1216
|
-
lines.push(String::new());
|
|
1217
|
-
lines.push(
|
|
1218
|
-
"Top HTTP routes (from http_requests_total labels)"
|
|
1219
|
-
.to_string(),
|
|
1220
|
-
);
|
|
1221
|
-
if let Some(arr) =
|
|
1222
|
-
obj.get("routeLines").and_then(|a| a.as_array())
|
|
1223
|
-
{
|
|
1224
|
-
if !arr.is_empty() {
|
|
1225
|
-
lines.push(
|
|
1226
|
-
" (method route) count".to_string(),
|
|
1227
|
-
);
|
|
1228
|
-
for v in arr {
|
|
1229
|
-
if let Some(s) = v.as_str() {
|
|
1230
|
-
lines.push(format!(" {}", s));
|
|
1231
|
-
}
|
|
1232
|
-
}
|
|
1233
|
-
} else {
|
|
1234
|
-
lines.push(
|
|
1235
|
-
" (no labeled requests yet — exercise the Gateway to populate.)"
|
|
1236
|
-
.to_string(),
|
|
1237
|
-
);
|
|
1238
|
-
}
|
|
1239
|
-
} else {
|
|
1240
|
-
lines.push(
|
|
1241
|
-
" (no route breakdown in response.)"
|
|
1242
|
-
.to_string(),
|
|
1243
|
-
);
|
|
1244
|
-
}
|
|
1245
|
-
let preserve_scroll =
|
|
1246
|
-
app.state.portal_monitoring.scroll_offset;
|
|
1247
|
-
let preserve_metrics_drill =
|
|
1248
|
-
app.state.portal_monitoring.metrics_drill;
|
|
1249
|
-
let preserve_metrics_drill_lines = app
|
|
1250
|
-
.state
|
|
1251
|
-
.portal_monitoring
|
|
1252
|
-
.metrics_drill_lines
|
|
1253
|
-
.clone();
|
|
1254
|
-
let preserve_logs = app
|
|
1255
|
-
.state
|
|
1256
|
-
.portal_monitoring
|
|
1257
|
-
.section_overrides
|
|
1258
|
-
.get(&crate::monitoring::MonitoringSection::Logs)
|
|
1259
|
-
.cloned();
|
|
1260
|
-
// System diagnostics (`S`) and dependency drill (`T`) live in
|
|
1261
|
-
// `section_overrides`. Full observability runs as soon as no pending
|
|
1262
|
-
// drill id exists, so we must restore these or the UI "blinks closed".
|
|
1263
|
-
let preserve_system = app
|
|
1264
|
-
.state
|
|
1265
|
-
.portal_monitoring
|
|
1266
|
-
.section_overrides
|
|
1267
|
-
.get(
|
|
1268
|
-
&crate::monitoring::MonitoringSection::System,
|
|
1269
|
-
)
|
|
1270
|
-
.cloned();
|
|
1271
|
-
let preserve_dependencies = app
|
|
1272
|
-
.state
|
|
1273
|
-
.portal_monitoring
|
|
1274
|
-
.section_overrides
|
|
1275
|
-
.get(
|
|
1276
|
-
&crate::monitoring::MonitoringSection::Dependencies,
|
|
1277
|
-
)
|
|
1278
|
-
.cloned();
|
|
1279
|
-
app.state.portal_monitoring.last_updated =
|
|
1280
|
-
Some(snapshot);
|
|
1281
|
-
app.state.portal_monitoring.content_lines = lines;
|
|
1282
|
-
app.state.portal_monitoring.section_overrides.clear();
|
|
1283
|
-
if let Some(logs) = preserve_logs {
|
|
1284
|
-
app.state
|
|
1285
|
-
.portal_monitoring
|
|
1286
|
-
.section_overrides
|
|
1287
|
-
.insert(
|
|
1288
|
-
crate::monitoring::MonitoringSection::Logs,
|
|
1289
|
-
logs,
|
|
1290
|
-
);
|
|
1291
|
-
}
|
|
1292
|
-
if let Some(system) = preserve_system {
|
|
1293
|
-
app.state
|
|
1294
|
-
.portal_monitoring
|
|
1295
|
-
.section_overrides
|
|
1296
|
-
.insert(
|
|
1297
|
-
crate::monitoring::MonitoringSection::System,
|
|
1298
|
-
system,
|
|
1299
|
-
);
|
|
1300
|
-
}
|
|
1301
|
-
if let Some(deps) = preserve_dependencies {
|
|
1302
|
-
app.state
|
|
1303
|
-
.portal_monitoring
|
|
1304
|
-
.section_overrides
|
|
1305
|
-
.insert(
|
|
1306
|
-
crate::monitoring::MonitoringSection::Dependencies,
|
|
1307
|
-
deps,
|
|
1308
|
-
);
|
|
1309
|
-
}
|
|
1310
|
-
app.state.portal_monitoring.section_refresh_loading =
|
|
1311
|
-
None;
|
|
1312
|
-
app.state.portal_monitoring.logs_fetch_loading = false;
|
|
1313
|
-
app.state.portal_monitoring.metrics_drill =
|
|
1314
|
-
preserve_metrics_drill;
|
|
1315
|
-
app.state.portal_monitoring.metrics_drill_lines =
|
|
1316
|
-
preserve_metrics_drill_lines;
|
|
1317
|
-
app.state.portal_monitoring.metrics_drill_loading =
|
|
1318
|
-
false;
|
|
1319
|
-
app.state.portal_monitoring.error = None;
|
|
1320
|
-
app.state.portal_monitoring.scroll_offset =
|
|
1321
|
-
preserve_scroll;
|
|
1322
|
-
} else {
|
|
1323
|
-
app.state.portal_monitoring.error = Some(
|
|
1324
|
-
"Unexpected observability response.".to_string(),
|
|
1325
|
-
);
|
|
1326
|
-
}
|
|
1327
|
-
app.request_render("portal_observability_ok");
|
|
1328
|
-
}
|
|
1329
|
-
// Handle gateway.connect response (Step 7.5)
|
|
1330
|
-
else if let Some(connected) = obj.get("connected") {
|
|
1331
|
-
if connected.as_bool().unwrap_or(false) {
|
|
1332
|
-
if Some(&resp.id)
|
|
1333
|
-
== app.state.pending_gateway_connect_id.as_ref()
|
|
1334
|
-
{
|
|
1335
|
-
app.state.pending_gateway_connect_id = None;
|
|
1336
|
-
|
|
1337
|
-
use crate::app::OperationMode;
|
|
1338
|
-
app.state.operation_mode = OperationMode::Connected;
|
|
1339
|
-
|
|
1340
|
-
let url = obj
|
|
1341
|
-
.get("url")
|
|
1342
|
-
.and_then(|v| v.as_str())
|
|
1343
|
-
.unwrap_or("unknown");
|
|
1344
|
-
|
|
1345
|
-
app.state.gateway_url = Some(url.to_string());
|
|
1346
|
-
app.state.connection_portal.last_successful_url =
|
|
1347
|
-
Some(url.to_string());
|
|
1348
|
-
app.state.connection_portal.finish_connecting();
|
|
1349
|
-
app.state.connection_portal.connection_success =
|
|
1350
|
-
true; // Phase 1.3: Set success flag
|
|
1351
|
-
// Dashboard "Demo Mode / NET" used `connected`, which was never set — align with Gateway link
|
|
1352
|
-
app.state.connected = true;
|
|
1353
|
-
|
|
1354
|
-
// Parse activity log if present
|
|
1355
|
-
if let Some(activity_log) = obj.get("activityLog") {
|
|
1356
|
-
if let Some(log_array) = activity_log.as_array()
|
|
1357
|
-
{
|
|
1358
|
-
app.state
|
|
1359
|
-
.connection_portal
|
|
1360
|
-
.activity_log
|
|
1361
|
-
.clear();
|
|
1362
|
-
for entry in log_array {
|
|
1363
|
-
if let Some(entry_obj) =
|
|
1364
|
-
entry.as_object()
|
|
1365
|
-
{
|
|
1366
|
-
let timestamp = entry_obj
|
|
1367
|
-
.get("timestamp")
|
|
1368
|
-
.and_then(|v| v.as_str())
|
|
1369
|
-
.unwrap_or("")
|
|
1370
|
-
.to_string();
|
|
1371
|
-
let level_str = entry_obj
|
|
1372
|
-
.get("level")
|
|
1373
|
-
.and_then(|v| v.as_str())
|
|
1374
|
-
.unwrap_or("info");
|
|
1375
|
-
let message = entry_obj
|
|
1376
|
-
.get("message")
|
|
1377
|
-
.and_then(|v| v.as_str())
|
|
1378
|
-
.unwrap_or("")
|
|
1379
|
-
.to_string();
|
|
1380
|
-
|
|
1381
|
-
use crate::app::LogLevel;
|
|
1382
|
-
let level = match level_str {
|
|
1383
|
-
"success" => LogLevel::Success,
|
|
1384
|
-
"warning" => LogLevel::Warning,
|
|
1385
|
-
"error" => LogLevel::Error,
|
|
1386
|
-
_ => LogLevel::Info,
|
|
1387
|
-
};
|
|
1388
|
-
|
|
1389
|
-
app.state
|
|
1390
|
-
.connection_portal
|
|
1391
|
-
.add_log_entry(
|
|
1392
|
-
timestamp, level, message,
|
|
1393
|
-
);
|
|
1394
|
-
}
|
|
1395
|
-
}
|
|
1396
|
-
}
|
|
1397
|
-
}
|
|
1398
|
-
|
|
1399
|
-
// Phase 1.2: Prominent connection success notification
|
|
1400
|
-
app.add_log(
|
|
1401
|
-
"═══════════════════════════════════════════"
|
|
1402
|
-
.to_string(),
|
|
1403
|
-
);
|
|
1404
|
-
app.add_log(format!("✅ CONNECTED TO GATEWAY"));
|
|
1405
|
-
app.add_log(format!(" URL: {}", url));
|
|
1406
|
-
app.add_log(format!(" Status: Connected"));
|
|
1407
|
-
app.add_log(" Note: connect checks /health + /ready; Shield/Sentinel run on the Gateway during jobs.".to_string());
|
|
1408
|
-
app.add_log(
|
|
1409
|
-
"═══════════════════════════════════════════"
|
|
1410
|
-
.to_string(),
|
|
1411
|
-
);
|
|
1412
|
-
app.add_log(format!(
|
|
1413
|
-
"[MODE] Switched to CONNECTED mode"
|
|
1414
|
-
));
|
|
1415
|
-
|
|
1416
|
-
// Phase 2.1: Immediately verify connection with health check
|
|
1417
|
-
app.add_log(format!(
|
|
1418
|
-
"[GATEWAY] Verifying connection health..."
|
|
1419
|
-
));
|
|
1420
|
-
if let Some(ref ws) = ws_client {
|
|
1421
|
-
if let Ok(health_id) =
|
|
1422
|
-
ws.send_command("gateway.health", None)
|
|
1423
|
-
{
|
|
1424
|
-
app.state.pending_gateway_health_id =
|
|
1425
|
-
Some(health_id);
|
|
1426
|
-
}
|
|
1427
|
-
// Refresh posture / NET labels from CLI (matches gateway-backed system.status)
|
|
1428
|
-
let _ = ws.send_command("system.status", None);
|
|
1429
|
-
}
|
|
1430
|
-
|
|
1431
|
-
// CRITICAL: Request render after state change to update UI
|
|
1432
|
-
// CRITICAL: Use immediate render for instant success display
|
|
1433
|
-
app.request_immediate_render(
|
|
1434
|
-
"gateway_connect_success",
|
|
1435
|
-
);
|
|
1436
|
-
|
|
1437
|
-
// Phase 1.3: Portal will show success state (user closes with ESC)
|
|
1438
|
-
// Don't auto-close - let user see success message
|
|
1439
|
-
}
|
|
1440
|
-
} else {
|
|
1441
|
-
// Handle disconnect response (Step 7.8)
|
|
1442
|
-
use crate::app::OperationMode;
|
|
1443
|
-
app.state.operation_mode = OperationMode::Local;
|
|
1444
|
-
app.state.gateway_url = None;
|
|
1445
|
-
app.state.connected = false;
|
|
1446
|
-
app.state.gateway_healthy = false;
|
|
1447
|
-
app.state.gateway_db_summary = None;
|
|
1448
|
-
app.add_log(format!(
|
|
1449
|
-
"✓ [{}] Disconnected from Gateway",
|
|
1450
|
-
short_id
|
|
1451
|
-
));
|
|
1452
|
-
if let Some(msg) =
|
|
1453
|
-
obj.get("message").and_then(|v| v.as_str())
|
|
1454
|
-
{
|
|
1455
|
-
if !msg.is_empty() {
|
|
1456
|
-
app.add_log(msg.to_string());
|
|
1457
|
-
}
|
|
1458
|
-
}
|
|
1459
|
-
app.add_log(format!("[MODE] Switched to LOCAL mode"));
|
|
1460
|
-
app.state.pending_gateway_observability_id = None;
|
|
1461
|
-
app.state.pending_monitoring_refresh_id = None;
|
|
1462
|
-
app.state.pending_monitoring_logs_id = None;
|
|
1463
|
-
app.state.pending_monitoring_drill_id = None;
|
|
1464
|
-
app.state.portal_observability_last_poll = None;
|
|
1465
|
-
app.state.portal_monitoring =
|
|
1466
|
-
crate::app::PortalMonitoringState::default();
|
|
1467
|
-
app.state.advanced_monitoring =
|
|
1468
|
-
crate::app::AdvancedMonitoringState::default();
|
|
1469
|
-
app.state.connection_portal.finish_connecting();
|
|
1470
|
-
app.state.connection_portal.connection_success = false;
|
|
1471
|
-
app.state.connection_portal.error = None;
|
|
1472
|
-
app.state.run_manager.clear_runs();
|
|
1473
|
-
if let Some(ref ws) = ws_client {
|
|
1474
|
-
let _ = ws.send_command("system.status", None);
|
|
1475
|
-
}
|
|
1476
|
-
}
|
|
1477
|
-
}
|
|
1478
|
-
// Handle setup.detect response
|
|
1479
|
-
else if let Some(local_bundle) = obj.get("localBundle") {
|
|
1480
|
-
if Some(&resp.id)
|
|
1481
|
-
== app.state.pending_setup_detect_id.as_ref()
|
|
1482
|
-
{
|
|
1483
|
-
app.state.pending_setup_detect_id = None;
|
|
1484
|
-
app.state.setup_portal.detecting = false;
|
|
1485
|
-
app.state.setup_portal.detecting_since = None;
|
|
1486
|
-
|
|
1487
|
-
use crate::app::{
|
|
1488
|
-
BundleStatus, CloudStatus, DetectionResult,
|
|
1489
|
-
};
|
|
1490
|
-
|
|
1491
|
-
let bundle_status = if let Some(bundle_obj) =
|
|
1492
|
-
local_bundle.as_object()
|
|
1493
|
-
{
|
|
1494
|
-
BundleStatus {
|
|
1495
|
-
available: bundle_obj
|
|
1496
|
-
.get("available")
|
|
1497
|
-
.and_then(|v| v.as_bool())
|
|
1498
|
-
.unwrap_or(false),
|
|
1499
|
-
running: bundle_obj
|
|
1500
|
-
.get("running")
|
|
1501
|
-
.and_then(|v| v.as_bool())
|
|
1502
|
-
.unwrap_or(false),
|
|
1503
|
-
path: bundle_obj
|
|
1504
|
-
.get("path")
|
|
1505
|
-
.and_then(|v| v.as_str())
|
|
1506
|
-
.map(|s| s.to_string()),
|
|
1507
|
-
}
|
|
1508
|
-
} else {
|
|
1509
|
-
app.state.setup_portal.error = Some(
|
|
1510
|
-
"Invalid setup.detect response (localBundle). Try setup portal again.".into(),
|
|
1511
|
-
);
|
|
1512
|
-
BundleStatus {
|
|
1513
|
-
available: false,
|
|
1514
|
-
running: false,
|
|
1515
|
-
path: None,
|
|
1516
|
-
}
|
|
1517
|
-
};
|
|
1518
|
-
|
|
1519
|
-
let cloud_obj =
|
|
1520
|
-
obj.get("cloudServer").and_then(|v| v.as_object());
|
|
1521
|
-
let cloud_status = CloudStatus {
|
|
1522
|
-
available: cloud_obj
|
|
1523
|
-
.and_then(|o| o.get("available"))
|
|
1524
|
-
.and_then(|v| v.as_bool())
|
|
1525
|
-
.unwrap_or(false),
|
|
1526
|
-
status: cloud_obj
|
|
1527
|
-
.and_then(|o| o.get("status"))
|
|
1528
|
-
.and_then(|v| v.as_str())
|
|
1529
|
-
.unwrap_or("Unknown")
|
|
1530
|
-
.to_string(),
|
|
1531
|
-
};
|
|
1532
|
-
|
|
1533
|
-
app.state.setup_portal.detection_result =
|
|
1534
|
-
Some(DetectionResult {
|
|
1535
|
-
local_bundle: bundle_status,
|
|
1536
|
-
cloud_server: cloud_status,
|
|
1537
|
-
});
|
|
1538
|
-
|
|
1539
|
-
app.add_log(
|
|
1540
|
-
"[SETUP] Gateway detection complete".to_string(),
|
|
1541
|
-
);
|
|
1542
|
-
}
|
|
1543
|
-
}
|
|
1544
|
-
// Phase 2.1: Handle gateway.health response
|
|
1545
|
-
else if let Some(healthy) = obj.get("healthy") {
|
|
1546
|
-
if Some(&resp.id)
|
|
1547
|
-
== app.state.pending_gateway_health_id.as_ref()
|
|
1548
|
-
{
|
|
1549
|
-
app.state.pending_gateway_health_id = None;
|
|
1550
|
-
|
|
1551
|
-
let is_healthy = healthy.as_bool().unwrap_or(false);
|
|
1552
|
-
let latency = obj
|
|
1553
|
-
.get("latency")
|
|
1554
|
-
.and_then(|v| v.as_u64())
|
|
1555
|
-
.unwrap_or(0);
|
|
1556
|
-
let deps_ready =
|
|
1557
|
-
obj.get("ready").and_then(|v| v.as_bool());
|
|
1558
|
-
|
|
1559
|
-
let mut db_summary: Option<String> = None;
|
|
1560
|
-
if let Some(h) =
|
|
1561
|
-
obj.get("health").and_then(|v| v.as_object())
|
|
1562
|
-
{
|
|
1563
|
-
if let Some(fr) =
|
|
1564
|
-
h.get("fourRunrDb").and_then(|v| v.as_object())
|
|
1565
|
-
{
|
|
1566
|
-
let mode = fr
|
|
1567
|
-
.get("mode")
|
|
1568
|
-
.and_then(|v| v.as_str())
|
|
1569
|
-
.unwrap_or("?");
|
|
1570
|
-
let pc = fr
|
|
1571
|
-
.get("prismaConnected")
|
|
1572
|
-
.and_then(|v| v.as_bool())
|
|
1573
|
-
.unwrap_or(false);
|
|
1574
|
-
db_summary = Some(format!(
|
|
1575
|
-
"{} · Prisma {}",
|
|
1576
|
-
mode,
|
|
1577
|
-
if pc {
|
|
1578
|
-
"connected"
|
|
1579
|
-
} else {
|
|
1580
|
-
"not connected"
|
|
1581
|
-
}
|
|
1582
|
-
));
|
|
1583
|
-
}
|
|
1584
|
-
}
|
|
1585
|
-
app.state.gateway_db_summary = db_summary;
|
|
1586
|
-
|
|
1587
|
-
if is_healthy {
|
|
1588
|
-
app.state.gateway_healthy = true;
|
|
1589
|
-
app.state.connection_portal.finish_connecting();
|
|
1590
|
-
let suffix = match deps_ready {
|
|
1591
|
-
Some(true) => " — dependencies ready",
|
|
1592
|
-
Some(false) => " — Gateway up; /ready not OK (see Portal Monitoring)",
|
|
1593
|
-
None => "",
|
|
1594
|
-
};
|
|
1595
|
-
app.add_log(format!(
|
|
1596
|
-
"✓ [{}] Gateway verified{} ({}ms)",
|
|
1597
|
-
short_id, suffix, latency
|
|
1598
|
-
));
|
|
1599
|
-
} else {
|
|
1600
|
-
app.state.gateway_healthy = false;
|
|
1601
|
-
app.state.gateway_db_summary = None;
|
|
1602
|
-
app.state.connection_portal.finish_connecting();
|
|
1603
|
-
let error = obj
|
|
1604
|
-
.get("error")
|
|
1605
|
-
.and_then(|v| v.as_str())
|
|
1606
|
-
.unwrap_or("Unknown error");
|
|
1607
|
-
app.add_log(format!(
|
|
1608
|
-
"⚠ [{}] Gateway health check failed: {} ({}ms)",
|
|
1609
|
-
short_id, error, latency
|
|
1610
|
-
));
|
|
1611
|
-
}
|
|
1612
|
-
|
|
1613
|
-
// CRITICAL: Request render after health state change
|
|
1614
|
-
app.request_render("gateway_health_update");
|
|
1615
|
-
}
|
|
1616
|
-
} else {
|
|
1617
|
-
app.add_log(format!("✓ [{}] Success", short_id));
|
|
1618
|
-
}
|
|
1619
|
-
} else {
|
|
1620
|
-
app.add_log(format!("✓ [{}] Success", short_id));
|
|
1621
|
-
}
|
|
1622
|
-
} else {
|
|
1623
|
-
app.add_log(format!("✓ [{}] Success", short_id));
|
|
1624
|
-
}
|
|
1625
|
-
} else {
|
|
1626
|
-
let short_id = &resp.id[resp.id.len().saturating_sub(8)..];
|
|
1627
|
-
let error_msg = resp
|
|
1628
|
-
.payload
|
|
1629
|
-
.error
|
|
1630
|
-
.unwrap_or_else(|| "Unknown error".to_string());
|
|
1631
|
-
|
|
1632
|
-
// Check if this is a response to agent.create command (Step 5.1)
|
|
1633
|
-
if Some(&resp.id) == app.state.pending_agent_create_id.as_ref() {
|
|
1634
|
-
app.state.pending_agent_create_id = None;
|
|
1635
|
-
app.add_log(format!(
|
|
1636
|
-
"✗ [{}] Agent creation failed: {}",
|
|
1637
|
-
short_id, error_msg
|
|
1638
|
-
));
|
|
1639
|
-
}
|
|
1640
|
-
// Check if this is a response to agent.delete command (Step 5.5)
|
|
1641
|
-
else if Some(&resp.id) == app.state.pending_agent_delete_id.as_ref() {
|
|
1642
|
-
app.state.pending_agent_delete_id = None;
|
|
1643
|
-
app.add_log(format!(
|
|
1644
|
-
"✗ [{}] Agent deletion failed: {}",
|
|
1645
|
-
short_id, error_msg
|
|
1646
|
-
));
|
|
1647
|
-
} else if Some(&resp.id) == app.state.pending_run_list_id.as_ref() {
|
|
1648
|
-
app.state.pending_run_list_id = None;
|
|
1649
|
-
app.state.pending_run_list_silent = false;
|
|
1650
|
-
app.state.run_manager.loading = false;
|
|
1651
|
-
app.add_log(format!(
|
|
1652
|
-
"✗ [{}] run.list failed: {}",
|
|
1653
|
-
short_id, error_msg
|
|
1654
|
-
));
|
|
1655
|
-
} else if Some(&resp.id) == app.state.pending_run_get_id.as_ref() {
|
|
1656
|
-
app.state.pending_run_get_id = None;
|
|
1657
|
-
app.add_log(format!(
|
|
1658
|
-
"✗ [{}] run.get failed: {}",
|
|
1659
|
-
short_id, error_msg
|
|
1660
|
-
));
|
|
1661
|
-
} else if Some(&resp.id) == app.state.pending_run_cancel_id.as_ref() {
|
|
1662
|
-
app.state.pending_run_cancel_id = None;
|
|
1663
|
-
app.add_log(format!(
|
|
1664
|
-
"✗ [{}] run.cancel failed: {}",
|
|
1665
|
-
short_id, error_msg
|
|
1666
|
-
));
|
|
1667
|
-
} else if Some(&resp.id) == app.state.pending_run_quick_id.as_ref() {
|
|
1668
|
-
app.state.pending_run_quick_id = None;
|
|
1669
|
-
app.add_log(format!(
|
|
1670
|
-
"✗ [{}] run.quick failed: {}",
|
|
1671
|
-
short_id, error_msg
|
|
1672
|
-
));
|
|
1673
|
-
} else if Some(&resp.id) == app.state.pending_shield_load_id.as_ref() {
|
|
1674
|
-
app.state.pending_shield_load_id = None;
|
|
1675
|
-
app.state
|
|
1676
|
-
.shield_dashboard
|
|
1677
|
-
.fail_loading(error_msg.clone());
|
|
1678
|
-
app.add_log(format!(
|
|
1679
|
-
"✗ [{}] shield.load failed: {}",
|
|
1680
|
-
short_id, error_msg
|
|
1681
|
-
));
|
|
1682
|
-
} else if Some(&resp.id) == app.state.pending_sentinel_load_id.as_ref()
|
|
1683
|
-
{
|
|
1684
|
-
app.state.pending_sentinel_load_id = None;
|
|
1685
|
-
app.state.sentinel_config.loading = false;
|
|
1686
|
-
app.state.sentinel_config.error = Some(error_msg.clone());
|
|
1687
|
-
app.add_log(format!(
|
|
1688
|
-
"✗ [{}] sentinel.load failed: {}",
|
|
1689
|
-
short_id, error_msg
|
|
1690
|
-
));
|
|
1691
|
-
} else if Some(&resp.id) == app.state.pending_sentinel_apply_id.as_ref()
|
|
1692
|
-
{
|
|
1693
|
-
app.state.pending_sentinel_apply_id = None;
|
|
1694
|
-
app.state.sentinel_config.applying = false;
|
|
1695
|
-
app.state.sentinel_config.error = Some(error_msg.clone());
|
|
1696
|
-
app.add_log(format!(
|
|
1697
|
-
"✗ [{}] sentinel.apply failed: {}",
|
|
1698
|
-
short_id, error_msg
|
|
1699
|
-
));
|
|
1700
|
-
}
|
|
1701
|
-
// Check if this is a response to gateway.connect command (Step 7.5)
|
|
1702
|
-
else if Some(&resp.id)
|
|
1703
|
-
== app.state.pending_gateway_connect_id.as_ref()
|
|
1704
|
-
{
|
|
1705
|
-
app.state.pending_gateway_connect_id = None;
|
|
1706
|
-
app.state.connection_portal.finish_connecting();
|
|
1707
|
-
app.state.connection_portal.error = Some(error_msg.clone());
|
|
1708
|
-
|
|
1709
|
-
// Parse activity log from error response if present
|
|
1710
|
-
if let Some(data_value) = &resp.payload.data {
|
|
1711
|
-
if let Some(obj) = data_value.as_object() {
|
|
1712
|
-
if let Some(activity_log) = obj.get("activityLog") {
|
|
1713
|
-
if let Some(log_array) = activity_log.as_array() {
|
|
1714
|
-
app.state.connection_portal.activity_log.clear();
|
|
1715
|
-
for entry in log_array {
|
|
1716
|
-
if let Some(entry_obj) = entry.as_object() {
|
|
1717
|
-
let timestamp = entry_obj
|
|
1718
|
-
.get("timestamp")
|
|
1719
|
-
.and_then(|v| v.as_str())
|
|
1720
|
-
.unwrap_or("")
|
|
1721
|
-
.to_string();
|
|
1722
|
-
let level_str = entry_obj
|
|
1723
|
-
.get("level")
|
|
1724
|
-
.and_then(|v| v.as_str())
|
|
1725
|
-
.unwrap_or("info");
|
|
1726
|
-
let message = entry_obj
|
|
1727
|
-
.get("message")
|
|
1728
|
-
.and_then(|v| v.as_str())
|
|
1729
|
-
.unwrap_or("")
|
|
1730
|
-
.to_string();
|
|
1731
|
-
|
|
1732
|
-
use crate::app::LogLevel;
|
|
1733
|
-
let level = match level_str {
|
|
1734
|
-
"success" => LogLevel::Success,
|
|
1735
|
-
"warning" => LogLevel::Warning,
|
|
1736
|
-
"error" => LogLevel::Error,
|
|
1737
|
-
_ => LogLevel::Info,
|
|
1738
|
-
};
|
|
1739
|
-
|
|
1740
|
-
app.state.connection_portal.add_log_entry(
|
|
1741
|
-
timestamp, level, message,
|
|
1742
|
-
);
|
|
1743
|
-
}
|
|
1744
|
-
}
|
|
1745
|
-
}
|
|
1746
|
-
}
|
|
1747
|
-
}
|
|
1748
|
-
}
|
|
1749
|
-
|
|
1750
|
-
app.add_log(format!(
|
|
1751
|
-
"✗ [{}] Gateway connection failed: {}",
|
|
1752
|
-
short_id, error_msg
|
|
1753
|
-
));
|
|
1754
|
-
|
|
1755
|
-
// CRITICAL: Use immediate render for instant error display
|
|
1756
|
-
app.request_immediate_render("gateway_connect_error");
|
|
1757
|
-
}
|
|
1758
|
-
// Check if this is a response to setup.detect command
|
|
1759
|
-
else if Some(&resp.id) == app.state.pending_setup_detect_id.as_ref() {
|
|
1760
|
-
app.state.pending_setup_detect_id = None;
|
|
1761
|
-
app.state.setup_portal.detecting = false;
|
|
1762
|
-
app.state.setup_portal.detecting_since = None;
|
|
1763
|
-
app.state.setup_portal.error = Some(error_msg.clone());
|
|
1764
|
-
app.add_log(format!(
|
|
1765
|
-
"✗ [{}] Setup detection failed: {}",
|
|
1766
|
-
short_id, error_msg
|
|
1767
|
-
));
|
|
1768
|
-
}
|
|
1769
|
-
// Phase 2.1: Check if this is a response to gateway.health command
|
|
1770
|
-
else if Some(&resp.id) == app.state.pending_gateway_health_id.as_ref()
|
|
1771
|
-
{
|
|
1772
|
-
app.state.pending_gateway_health_id = None;
|
|
1773
|
-
app.state.gateway_healthy = false;
|
|
1774
|
-
app.state.gateway_db_summary = None;
|
|
1775
|
-
app.add_log(format!(
|
|
1776
|
-
"⚠ [{}] Gateway health check failed: {}",
|
|
1777
|
-
short_id, error_msg
|
|
1778
|
-
));
|
|
1779
|
-
|
|
1780
|
-
// CRITICAL: Request render after health state change
|
|
1781
|
-
app.request_render("gateway_health_error");
|
|
1782
|
-
} else if Some(&resp.id)
|
|
1783
|
-
== app.state.pending_gateway_observability_id.as_ref()
|
|
1784
|
-
{
|
|
1785
|
-
app.state.pending_gateway_observability_id = None;
|
|
1786
|
-
app.state.portal_monitoring.loading = false;
|
|
1787
|
-
app.state.portal_observability_last_poll = Some(Instant::now());
|
|
1788
|
-
app.state.portal_monitoring.error = Some(error_msg.clone());
|
|
1789
|
-
app.request_render("portal_observability_err");
|
|
1790
|
-
} else if Some(&resp.id)
|
|
1791
|
-
== app.state.pending_monitoring_refresh_id.as_ref()
|
|
1792
|
-
{
|
|
1793
|
-
app.state.pending_monitoring_refresh_id = None;
|
|
1794
|
-
app.state.portal_monitoring.section_refresh_loading = None;
|
|
1795
|
-
app.state.portal_monitoring.error =
|
|
1796
|
-
Some(format!("monitoring.refresh failed: {}", error_msg));
|
|
1797
|
-
app.add_log(format!(
|
|
1798
|
-
"✗ [{}] monitoring.refresh failed: {}",
|
|
1799
|
-
short_id, error_msg
|
|
1800
|
-
));
|
|
1801
|
-
app.request_render("monitoring_refresh_err");
|
|
1802
|
-
} else if Some(&resp.id)
|
|
1803
|
-
== app.state.pending_monitoring_logs_id.as_ref()
|
|
1804
|
-
{
|
|
1805
|
-
app.state.pending_monitoring_logs_id = None;
|
|
1806
|
-
app.state.portal_monitoring.logs_fetch_loading = false;
|
|
1807
|
-
app.state.portal_monitoring.error =
|
|
1808
|
-
Some(format!("monitoring.logs failed: {}", error_msg));
|
|
1809
|
-
app.add_log(format!(
|
|
1810
|
-
"✗ [{}] monitoring.logs failed: {}",
|
|
1811
|
-
short_id, error_msg
|
|
1812
|
-
));
|
|
1813
|
-
app.request_render("monitoring_logs_err");
|
|
1814
|
-
} else if Some(&resp.id)
|
|
1815
|
-
== app.state.pending_monitoring_drill_id.as_ref()
|
|
1816
|
-
{
|
|
1817
|
-
app.state.pending_monitoring_drill_id = None;
|
|
1818
|
-
app.state.portal_monitoring.metrics_drill_loading = false;
|
|
1819
|
-
app.state.portal_monitoring.section_refresh_loading = None;
|
|
1820
|
-
app.state.portal_monitoring.error =
|
|
1821
|
-
Some(format!("monitoring.drill failed: {}", error_msg));
|
|
1822
|
-
app.add_log(format!(
|
|
1823
|
-
"✗ [{}] monitoring.drill failed: {}",
|
|
1824
|
-
short_id, error_msg
|
|
1825
|
-
));
|
|
1826
|
-
app.request_render("monitoring_drill_err");
|
|
1827
|
-
}
|
|
1828
|
-
// Generic error handling
|
|
1829
|
-
else {
|
|
1830
|
-
// Try to extract command name from response for better error messages
|
|
1831
|
-
let command_hint = if resp.id.contains("agent") {
|
|
1832
|
-
" (agent command)"
|
|
1833
|
-
} else if resp.id.contains("system") {
|
|
1834
|
-
" (system command)"
|
|
1835
|
-
} else if resp.id.contains("run") {
|
|
1836
|
-
" (run command)"
|
|
1837
|
-
} else if resp.id.contains("tool") {
|
|
1838
|
-
" (tool command)"
|
|
1839
|
-
} else {
|
|
1840
|
-
""
|
|
1841
|
-
};
|
|
1842
|
-
|
|
1843
|
-
app.add_log(format!(
|
|
1844
|
-
"✗ [{}]{} Error: {}",
|
|
1845
|
-
short_id, command_hint, error_msg
|
|
1846
|
-
));
|
|
1847
|
-
}
|
|
1848
|
-
}
|
|
1849
|
-
}
|
|
1850
|
-
WsClientMessage::Event(event) => {
|
|
1851
|
-
app.add_log(format!(
|
|
1852
|
-
"Event {}: {}",
|
|
1853
|
-
event.payload.event,
|
|
1854
|
-
serde_json::to_string(&event.payload.data).unwrap_or_default()
|
|
1855
|
-
));
|
|
1856
|
-
}
|
|
1857
|
-
WsClientMessage::Error(err) => {
|
|
1858
|
-
app.add_log(format!("[WEBSOCKET] ✗ Error: {}", err));
|
|
1859
|
-
app.state.connected = false;
|
|
1860
|
-
}
|
|
1861
|
-
}
|
|
1862
|
-
}
|
|
1863
|
-
}
|
|
1864
|
-
|
|
1865
|
-
// Portal Monitoring: auto-refresh Gateway /metrics while the screen is open
|
|
1866
|
-
{
|
|
1867
|
-
use crate::app::OperationMode;
|
|
1868
|
-
use crate::screens::Screen;
|
|
1869
|
-
if let Some(ref ws) = ws_client {
|
|
1870
|
-
if app.state.navigation.current_screen() == &Screen::PortalMonitoring
|
|
1871
|
-
&& app.state.operation_mode == OperationMode::Connected
|
|
1872
|
-
&& app.state.pending_gateway_observability_id.is_none()
|
|
1873
|
-
&& app.state.pending_monitoring_refresh_id.is_none()
|
|
1874
|
-
&& app.state.pending_monitoring_logs_id.is_none()
|
|
1875
|
-
&& app.state.pending_monitoring_drill_id.is_none()
|
|
1876
|
-
{
|
|
1877
|
-
let interval = Duration::from_secs(5);
|
|
1878
|
-
let due = app
|
|
1879
|
-
.state
|
|
1880
|
-
.portal_observability_last_poll
|
|
1881
|
-
.map(|t| t.elapsed() >= interval)
|
|
1882
|
-
.unwrap_or(true);
|
|
1883
|
-
if due {
|
|
1884
|
-
app.begin_portal_observability_request(ws);
|
|
1885
|
-
}
|
|
1886
|
-
}
|
|
1887
|
-
}
|
|
1888
|
-
}
|
|
1889
|
-
|
|
1890
|
-
// ┌─────────────────────────────────────────────────────────┐
|
|
1891
|
-
// │ STEP 3: RENDER (conditional - only when needed) │
|
|
1892
|
-
// └─────────────────────────────────────────────────────────┘
|
|
1893
|
-
// Check if render is scheduled and throttle limit has passed
|
|
1894
|
-
// OPTIMIZATION: Removed input debounce check - using immediate render for typing
|
|
1895
|
-
if app.should_render() {
|
|
1896
|
-
// Clone current screen before mutable borrow
|
|
1897
|
-
let current_screen = app.state.navigation.current_screen().clone();
|
|
1898
|
-
if !matches!(
|
|
1899
|
-
current_screen,
|
|
1900
|
-
crate::screens::Screen::ConnectionPortal
|
|
1901
|
-
| crate::screens::Screen::SetupPortal
|
|
1902
|
-
| crate::screens::Screen::PortalMonitoring
|
|
1903
|
-
) {
|
|
1904
|
-
standalone_portal_last_terminal_dims = None;
|
|
1905
|
-
}
|
|
1906
|
-
let _is_portal_active = matches!(
|
|
1907
|
-
current_screen,
|
|
1908
|
-
crate::screens::Screen::ConnectionPortal
|
|
1909
|
-
| crate::screens::Screen::SetupPortal
|
|
1910
|
-
| crate::screens::Screen::PortalMonitoring
|
|
1911
|
-
);
|
|
1912
|
-
|
|
1913
|
-
// Clear only on screen switch (but not when switching TO Setup Portal; we'll clear after autoresize)
|
|
1914
|
-
let is_switching = match (&previous_screen, ¤t_screen) {
|
|
1915
|
-
(Some(prev), current) => prev != current,
|
|
1916
|
-
(None, _) => true,
|
|
1917
|
-
};
|
|
1918
|
-
let switching_to_setup_portal =
|
|
1919
|
-
is_switching && matches!(current_screen, crate::screens::Screen::SetupPortal);
|
|
1920
|
-
|
|
1921
|
-
if is_switching && !switching_to_setup_portal {
|
|
1922
|
-
#[cfg(debug_assertions)]
|
|
1923
|
-
eprintln!(
|
|
1924
|
-
"[MAIN] SCREEN SWITCH: {:?} -> {:?} (clearing)",
|
|
1925
|
-
previous_screen, current_screen
|
|
1926
|
-
);
|
|
1927
|
-
debug_log::log_screen(
|
|
1928
|
-
&format!("{:?}", previous_screen.as_ref().unwrap_or(¤t_screen)),
|
|
1929
|
-
&format!("{:?}", current_screen),
|
|
1930
|
-
);
|
|
1931
|
-
terminal.clear()?;
|
|
1932
|
-
}
|
|
1933
|
-
|
|
1934
|
-
// Connection + Setup portals: autoresize every frame (windowed CMD/conhost buffer vs viewport drift).
|
|
1935
|
-
// Clear on Setup entry (generic switch clear is skipped for Setup); clear when terminal dimensions
|
|
1936
|
-
// change while either portal is open. See docs/SETUP-PORTAL-WINDOWED-FIX-PLAN.md.
|
|
1937
|
-
let on_standalone_portal = matches!(
|
|
1938
|
-
current_screen,
|
|
1939
|
-
crate::screens::Screen::ConnectionPortal
|
|
1940
|
-
| crate::screens::Screen::SetupPortal
|
|
1941
|
-
| crate::screens::Screen::PortalMonitoring
|
|
1942
|
-
);
|
|
1943
|
-
if on_standalone_portal {
|
|
1944
|
-
terminal.autoresize()?;
|
|
1945
|
-
let dims = match terminal.size() {
|
|
1946
|
-
Ok(s) => (s.width, s.height),
|
|
1947
|
-
Err(_) => (0, 0),
|
|
1948
|
-
};
|
|
1949
|
-
if switching_to_setup_portal {
|
|
1950
|
-
debug_log::log_flicker_debug("CLEAR_BEFORE", "enter_setup");
|
|
1951
|
-
terminal.clear()?;
|
|
1952
|
-
#[cfg(debug_assertions)]
|
|
1953
|
-
eprintln!("[MAIN] ENTERED Setup Portal (autoresize + clear)");
|
|
1954
|
-
debug_log::log_screen(
|
|
1955
|
-
&format!("{:?}", previous_screen.as_ref().unwrap_or(¤t_screen)),
|
|
1956
|
-
&format!("{:?}", current_screen),
|
|
1957
|
-
);
|
|
1958
|
-
standalone_portal_last_terminal_dims = Some(dims);
|
|
1959
|
-
} else if let Some(last) = standalone_portal_last_terminal_dims {
|
|
1960
|
-
if last != dims {
|
|
1961
|
-
debug_log::log_flicker_debug("CLEAR_BEFORE", "size_change");
|
|
1962
|
-
terminal.clear()?;
|
|
1963
|
-
}
|
|
1964
|
-
standalone_portal_last_terminal_dims = Some(dims);
|
|
1965
|
-
} else {
|
|
1966
|
-
standalone_portal_last_terminal_dims = Some(dims);
|
|
1967
|
-
}
|
|
1968
|
-
}
|
|
1969
|
-
|
|
1970
|
-
let render_start = Instant::now();
|
|
1971
|
-
terminal.draw(|f| app.render(f))?;
|
|
1972
|
-
let render_duration = render_start.elapsed().as_millis() as u64;
|
|
1973
|
-
app.record_render(render_duration);
|
|
1974
|
-
if on_standalone_portal {
|
|
1975
|
-
debug_log::log_flicker_debug("DRAW_DONE", &format!("ms={}", render_duration));
|
|
1976
|
-
}
|
|
1977
|
-
|
|
1978
|
-
// Update previous screen tracking
|
|
1979
|
-
previous_screen = Some(current_screen);
|
|
1980
|
-
}
|
|
1981
|
-
|
|
1982
|
-
// Setup Portal: if detection has been running too long, unstick so user can ESC or retry
|
|
1983
|
-
if app.state.navigation.current_screen() == &screens::Screen::SetupPortal
|
|
1984
|
-
&& app.state.setup_portal.detecting
|
|
1985
|
-
{
|
|
1986
|
-
if let Some(since) = app.state.setup_portal.detecting_since {
|
|
1987
|
-
if since.elapsed() >= Duration::from_secs(8) {
|
|
1988
|
-
app.state.setup_portal.detecting = false;
|
|
1989
|
-
app.state.setup_portal.detecting_since = None;
|
|
1990
|
-
app.state.setup_portal.error =
|
|
1991
|
-
Some("Detection timed out. Press ESC to close or try again.".to_string());
|
|
1992
|
-
app.add_log("[SETUP] Detection timed out".to_string());
|
|
1993
|
-
app.request_immediate_render("setup_detect_timeout");
|
|
1994
|
-
}
|
|
1995
|
-
}
|
|
1996
|
-
}
|
|
1997
|
-
|
|
1998
|
-
// ┌─────────────────────────────────────────────────────────┐
|
|
1999
|
-
// │ STEP 4: CHECK FOR INPUT (non-blocking with timeout) │
|
|
2000
|
-
// └─────────────────────────────────────────────────────────┘
|
|
2001
|
-
// OPTIMIZATION: Reduced poll timeout to 1ms for faster input detection
|
|
2002
|
-
// This allows loop to run ~1000 times/second when idle, but input is detected immediately
|
|
2003
|
-
// Handle ESC on both Press and Release so we never miss it (e.g. when stuck on "Detecting...")
|
|
2004
|
-
if crossterm::event::poll(Duration::from_millis(1))? {
|
|
2005
|
-
let on_setup = app.state.navigation.current_screen() == &screens::Screen::SetupPortal;
|
|
2006
|
-
let on_portal_monitoring =
|
|
2007
|
-
app.state.navigation.current_screen() == &screens::Screen::PortalMonitoring;
|
|
2008
|
-
let on_standalone_input = matches!(
|
|
2009
|
-
app.state.navigation.current_screen(),
|
|
2010
|
-
&screens::Screen::ConnectionPortal
|
|
2011
|
-
| &screens::Screen::SetupPortal
|
|
2012
|
-
| &screens::Screen::PortalMonitoring
|
|
2013
|
-
);
|
|
2014
|
-
match event::read()? {
|
|
2015
|
-
Event::Key(key) => {
|
|
2016
|
-
if on_standalone_input {
|
|
2017
|
-
debug_log::log_input("Key", &format!("{:?}", key));
|
|
2018
|
-
}
|
|
2019
|
-
let should_handle = key.kind == KeyEventKind::Press
|
|
2020
|
-
|| (key.code == KeyCode::Esc && key.kind == KeyEventKind::Release);
|
|
2021
|
-
if should_handle {
|
|
2022
|
-
if app.handle_input(key, &mut io_handler, ws_client.as_ref())? {
|
|
2023
|
-
break; // Exit requested
|
|
2024
|
-
}
|
|
2025
|
-
}
|
|
2026
|
-
}
|
|
2027
|
-
Event::Mouse(mouse) => {
|
|
2028
|
-
if on_standalone_input {
|
|
2029
|
-
debug_log::log_input("Mouse", &format!("{:?}", mouse));
|
|
2030
|
-
}
|
|
2031
|
-
// Handle mouse scroll events for standalone portals
|
|
2032
|
-
if on_portal_monitoring {
|
|
2033
|
-
match mouse.kind {
|
|
2034
|
-
MouseEventKind::ScrollUp => app.scroll_portal_monitoring_by(-3),
|
|
2035
|
-
MouseEventKind::ScrollDown => app.scroll_portal_monitoring_by(3),
|
|
2036
|
-
_ => {}
|
|
2037
|
-
}
|
|
2038
|
-
} else if on_setup {
|
|
2039
|
-
if !app.state.setup_portal.detecting {
|
|
2040
|
-
match mouse.kind {
|
|
2041
|
-
MouseEventKind::ScrollUp => {
|
|
2042
|
-
app.state.setup_portal.cycle_option(-1);
|
|
2043
|
-
app.request_immediate_render("setup_portal_scroll_up");
|
|
2044
|
-
}
|
|
2045
|
-
MouseEventKind::ScrollDown => {
|
|
2046
|
-
app.state.setup_portal.cycle_option(1);
|
|
2047
|
-
app.request_immediate_render("setup_portal_scroll_down");
|
|
2048
|
-
}
|
|
2049
|
-
_ => {}
|
|
2050
|
-
}
|
|
2051
|
-
}
|
|
2052
|
-
} else if app.state.navigation.current_screen()
|
|
2053
|
-
== &screens::Screen::SentinelConfig
|
|
2054
|
-
{
|
|
2055
|
-
match mouse.kind {
|
|
2056
|
-
MouseEventKind::ScrollUp => app.sentinel_scroll_custom_value(true),
|
|
2057
|
-
MouseEventKind::ScrollDown => app.sentinel_scroll_custom_value(false),
|
|
2058
|
-
_ => {}
|
|
2059
|
-
}
|
|
2060
|
-
}
|
|
2061
|
-
}
|
|
2062
|
-
Event::Resize(w, h) => {
|
|
2063
|
-
if on_standalone_input {
|
|
2064
|
-
debug_log::log_input("Resize", &format!("{}x{}", w, h));
|
|
2065
|
-
}
|
|
2066
|
-
// Terminal was resized - force immediate re-render with correct dimensions
|
|
2067
|
-
terminal.clear()?;
|
|
2068
|
-
app.request_immediate_render("terminal_resize");
|
|
2069
|
-
}
|
|
2070
|
-
_ => {}
|
|
2071
|
-
}
|
|
2072
|
-
}
|
|
2073
|
-
// If no input, loop continues immediately - animations keep running!
|
|
2074
|
-
|
|
2075
|
-
// Check for pending agent deletion (Step 5.5)
|
|
2076
|
-
if app.state.agent_delete_requested {
|
|
2077
|
-
app.state.agent_delete_requested = false;
|
|
2078
|
-
app.delete_selected_agent(&ws_client);
|
|
2079
|
-
}
|
|
2080
|
-
|
|
2081
|
-
// Check for IO updates (non-blocking)
|
|
2082
|
-
io_handler.update(&mut app).ok();
|
|
2083
|
-
}
|
|
2084
|
-
|
|
2085
|
-
// Restore terminal
|
|
2086
|
-
disable_raw_mode()?;
|
|
2087
|
-
execute!(terminal.backend_mut(), cursor::Show, LeaveAlternateScreen)?;
|
|
2088
|
-
|
|
2089
|
-
Ok(())
|
|
2090
|
-
}
|