@minionry/minion 0.7.36
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/LICENSE +14 -0
- package/PRIVACY.md +357 -0
- package/README.md +57 -0
- package/THIRD_PARTY_NOTICES.md +245 -0
- package/bin/branding.js +4 -0
- package/bin/commands/browser-install.js +483 -0
- package/bin/commands/create-sandbox.js +542 -0
- package/bin/commands/fingerprint.js +101 -0
- package/bin/commands/login.js +400 -0
- package/bin/commands/logout.js +93 -0
- package/bin/commands/minions.js +211 -0
- package/bin/commands/sandboxes.js +309 -0
- package/bin/commands/status.js +298 -0
- package/bin/commands/whoami.js +153 -0
- package/bin/launch-env.js +35 -0
- package/bin/machine-identity.js +221 -0
- package/bin/machine-layout.js +200 -0
- package/bin/minion.js +839 -0
- package/bin/platform-endpoints.js +8 -0
- package/bin/postinstall.js +52 -0
- package/bin/pty-doctor.js +326 -0
- package/bin/pty-locator.js +110 -0
- package/bin/pty-provision.js +186 -0
- package/bin/sandbox/Dockerfile +78 -0
- package/bin/sandbox/entrypoint.sh +14 -0
- package/bin/sandbox/install-repo.sh +53 -0
- package/bin/sandbox/seccomp-userns.json +883 -0
- package/bin/sandbox-config.js +306 -0
- package/dist/bin/machine-identity.js +221 -0
- package/dist/bin/machine-layout.js +200 -0
- package/dist/electron-host/agent-lease.js +141 -0
- package/dist/electron-host/dom-driver.js +642 -0
- package/dist/electron-host/ipc-protocol.js +89 -0
- package/dist/electron-host/js-driver.js +216 -0
- package/dist/electron-host/view-manager.js +254 -0
- package/dist/server/cli/engine-resume.js +49 -0
- package/dist/server/cli/eta-estimator.js +278 -0
- package/dist/server/cli/headless/background-activity.js +109 -0
- package/dist/server/cli/headless/claude-invoker-process.js +614 -0
- package/dist/server/cli/headless/claude-invoker-stall.js +150 -0
- package/dist/server/cli/headless/claude-invoker-stream.js +555 -0
- package/dist/server/cli/headless/claude-invoker-tools.js +148 -0
- package/dist/server/cli/headless/claude-invoker.js +151 -0
- package/dist/server/cli/headless/engine-availability.js +92 -0
- package/dist/server/cli/headless/engine-notice.js +185 -0
- package/dist/server/cli/headless/haiku-assessments.js +293 -0
- package/dist/server/cli/headless/headless-logger.js +75 -0
- package/dist/server/cli/headless/index.js +9 -0
- package/dist/server/cli/headless/mcp-config.js +314 -0
- package/dist/server/cli/headless/native-timeout-detector.js +72 -0
- package/dist/server/cli/headless/output-utils.js +71 -0
- package/dist/server/cli/headless/prompt-utils.js +82 -0
- package/dist/server/cli/headless/resilient-runner.js +326 -0
- package/dist/server/cli/headless/retry-strategies.js +292 -0
- package/dist/server/cli/headless/runner.js +245 -0
- package/dist/server/cli/headless/stall-assessor.js +295 -0
- package/dist/server/cli/headless/tool-watchdog.js +447 -0
- package/dist/server/cli/headless/types.js +18 -0
- package/dist/server/cli/history-portability.js +85 -0
- package/dist/server/cli/improvisation-attachments.js +99 -0
- package/dist/server/cli/improvisation-history-store.js +121 -0
- package/dist/server/cli/improvisation-movements.js +137 -0
- package/dist/server/cli/improvisation-output-queue.js +34 -0
- package/dist/server/cli/improvisation-retry.js +8 -0
- package/dist/server/cli/improvisation-session-manager.js +1016 -0
- package/dist/server/cli/improvisation-types.js +31 -0
- package/dist/server/cli/plan-lifecycle.js +72 -0
- package/dist/server/cli/prompt-builders.js +371 -0
- package/dist/server/cli/retry/retry-best-result.js +28 -0
- package/dist/server/cli/retry/retry-context-loss.js +75 -0
- package/dist/server/cli/retry/retry-recovery-strategies.js +213 -0
- package/dist/server/cli/retry/retry-resume-strategy.js +20 -0
- package/dist/server/cli/retry/retry-runner-factory.js +92 -0
- package/dist/server/cli/retry/retry-tool-results.js +22 -0
- package/dist/server/cli/retry/retry-types.js +3 -0
- package/dist/server/engines/EngineEvent.js +57 -0
- package/dist/server/engines/claude/ClaudeCodeEngine.js +316 -0
- package/dist/server/engines/claude/claude-command.js +32 -0
- package/dist/server/engines/codex/CodexEngine.js +469 -0
- package/dist/server/engines/codex/codex-auth.js +203 -0
- package/dist/server/engines/codex/codex-invoker.js +205 -0
- package/dist/server/engines/codex/codex-provision.js +215 -0
- package/dist/server/engines/credentials/credential-probe.js +88 -0
- package/dist/server/engines/credentials/model-profiles.js +249 -0
- package/dist/server/engines/credentials/provider-credentials.js +146 -0
- package/dist/server/engines/engine-event-stream.js +52 -0
- package/dist/server/engines/execution/engine-session.js +380 -0
- package/dist/server/engines/factory.js +42 -0
- package/dist/server/engines/hermes/HermesEngine.js +628 -0
- package/dist/server/engines/hermes/hermes-auth.js +159 -0
- package/dist/server/engines/hermes/hermes-gateway-home.js +271 -0
- package/dist/server/engines/hermes/hermes-invoker.js +350 -0
- package/dist/server/engines/hermes/hermes-provision.js +318 -0
- package/dist/server/engines/read-only.js +20 -0
- package/dist/server/engines/types.js +27 -0
- package/dist/server/handlers/company-execution-registry.js +67 -0
- package/dist/server/handlers/company-handlers.js +514 -0
- package/dist/server/handlers/company-triggers.js +189 -0
- package/dist/server/handlers/company-types.js +3 -0
- package/dist/server/index.js +244 -0
- package/dist/server/mcp/app-tools-bridge.js +110 -0
- package/dist/server/mcp/app-tools-mcp-server.js +99 -0
- package/dist/server/mcp/bouncer-integration.js +744 -0
- package/dist/server/mcp/browser-mcp-server.js +915 -0
- package/dist/server/mcp/browser-redaction.js +103 -0
- package/dist/server/mcp/classifier/BouncerClassifier.js +3 -0
- package/dist/server/mcp/classifier/ClaudeBouncerClassifier.js +212 -0
- package/dist/server/mcp/classifier/factory.js +124 -0
- package/dist/server/mcp/classifier/health.js +54 -0
- package/dist/server/mcp/classifier/telemetry.js +0 -0
- package/dist/server/mcp/company-patterns.js +104 -0
- package/dist/server/mcp/department-profiles.js +133 -0
- package/dist/server/mcp/quality-bridge.js +153 -0
- package/dist/server/mcp/quality-mcp-server.js +105 -0
- package/dist/server/mcp/security-analysis.js +384 -0
- package/dist/server/mcp/security-audit.js +152 -0
- package/dist/server/mcp/security-patterns.js +314 -0
- package/dist/server/mcp/server.js +194 -0
- package/dist/server/mcp/test-utils/agent-simulator.js +301 -0
- package/dist/server/mcp/test-utils/e2e-agent.js +103 -0
- package/dist/server/mcp/test-utils/e2e-capture.js +92 -0
- package/dist/server/mcp/test-utils/e2e-client.js +116 -0
- package/dist/server/mcp/test-utils/e2e-fixtures.js +87 -0
- package/dist/server/mcp/test-utils/e2e-gating.js +8 -0
- package/dist/server/mcp/test-utils/e2e-harness.js +8 -0
- package/dist/server/mcp/test-utils/e2e-scenarios.js +105 -0
- package/dist/server/routes/files.js +18 -0
- package/dist/server/routes/improvise.js +64 -0
- package/dist/server/routes/index.js +7 -0
- package/dist/server/routes/instances.js +41 -0
- package/dist/server/routes/internal.js +900 -0
- package/dist/server/routes/notifications.js +110 -0
- package/dist/server/server-setup.js +282 -0
- package/dist/server/services/agent-push.js +148 -0
- package/dist/server/services/analytics.js +197 -0
- package/dist/server/services/apps/build.js +249 -0
- package/dist/server/services/apps/greenlight.js +199 -0
- package/dist/server/services/apps/install.js +101 -0
- package/dist/server/services/apps/layout.js +35 -0
- package/dist/server/services/apps/serve.js +665 -0
- package/dist/server/services/apps/space-apps.js +248 -0
- package/dist/server/services/auth.js +48 -0
- package/dist/server/services/browser/chrome-sandbox.js +245 -0
- package/dist/server/services/browser/chromium-launch-spec.js +51 -0
- package/dist/server/services/browser/claude-reasoner.js +669 -0
- package/dist/server/services/browser/debug-log.js +3 -0
- package/dist/server/services/browser/driver-state.js +546 -0
- package/dist/server/services/browser/electron-provision.js +256 -0
- package/dist/server/services/browser/host-internal.js +245 -0
- package/dist/server/services/browser/host-mock.js +334 -0
- package/dist/server/services/browser/host-types.js +3 -0
- package/dist/server/services/browser/host.js +1067 -0
- package/dist/server/services/browser/index.js +4 -0
- package/dist/server/services/browser/ipc-client.js +354 -0
- package/dist/server/services/browser/pipewire-sink.js +199 -0
- package/dist/server/services/browser/preflight.js +590 -0
- package/dist/server/services/browser/reasoning-agent.js +659 -0
- package/dist/server/services/browser/sandbox-policy.js +169 -0
- package/dist/server/services/browser/stderr-noise-filter.js +26 -0
- package/dist/server/services/browser/telemetry.js +107 -0
- package/dist/server/services/browser/xvfb-supervisor.js +139 -0
- package/dist/server/services/browser-frame-policy.js +56 -0
- package/dist/server/services/client-id.js +32 -0
- package/dist/server/services/collab/registry.js +408 -0
- package/dist/server/services/collab/session.js +489 -0
- package/dist/server/services/collab/text-diff.js +28 -0
- package/dist/server/services/collab/types.js +19 -0
- package/dist/server/services/e2ee-group-key.js +197 -0
- package/dist/server/services/e2ee-identity.js +203 -0
- package/dist/server/services/file-explorer-ops.js +328 -0
- package/dist/server/services/file-transfer-zip.js +188 -0
- package/dist/server/services/files.js +111 -0
- package/dist/server/services/git/branch-ops.js +62 -0
- package/dist/server/services/git/command.js +68 -0
- package/dist/server/services/git/commit-message.js +74 -0
- package/dist/server/services/git/diff-ops.js +56 -0
- package/dist/server/services/git/haiku.js +76 -0
- package/dist/server/services/git/head-watcher.js +226 -0
- package/dist/server/services/git/index.js +17 -0
- package/dist/server/services/git/log-ops.js +98 -0
- package/dist/server/services/git/merge-ops.js +314 -0
- package/dist/server/services/git/parsers.js +401 -0
- package/dist/server/services/git/remote-ops.js +192 -0
- package/dist/server/services/git/status-ops.js +105 -0
- package/dist/server/services/git/suggestion-ops.js +80 -0
- package/dist/server/services/git/tag-ops.js +36 -0
- package/dist/server/services/git/types.js +4 -0
- package/dist/server/services/git/worktree-ops.js +114 -0
- package/dist/server/services/instances.js +337 -0
- package/dist/server/services/model-catalog.js +247 -0
- package/dist/server/services/observability/posthog.js +153 -0
- package/dist/server/services/pathUtils.js +114 -0
- package/dist/server/services/plan/agent-loader.js +97 -0
- package/dist/server/services/plan/agent-manager.js +363 -0
- package/dist/server/services/plan/agent-resolver.js +74 -0
- package/dist/server/services/plan/agents/assess-stall.md +33 -0
- package/dist/server/services/plan/agents/browser-planner.md +53 -0
- package/dist/server/services/plan/agents/browser-reasoner.md +114 -0
- package/dist/server/services/plan/agents/check-injection.md +95 -0
- package/dist/server/services/plan/agents/classify-error.md +30 -0
- package/dist/server/services/plan/agents/code-review.md +142 -0
- package/dist/server/services/plan/agents/commit-message.md +28 -0
- package/dist/server/services/plan/agents/detect-context-loss.md +30 -0
- package/dist/server/services/plan/agents/execute-issue.md +58 -0
- package/dist/server/services/plan/agents/fix-quality.md +25 -0
- package/dist/server/services/plan/agents/plan-coordinator.md +72 -0
- package/dist/server/services/plan/agents/pr-description.md +29 -0
- package/dist/server/services/plan/agents/retry-task.md +27 -0
- package/dist/server/services/plan/agents/review-code.md +38 -0
- package/dist/server/services/plan/agents/review-quality.md +45 -0
- package/dist/server/services/plan/agents/triage-findings.md +78 -0
- package/dist/server/services/plan/agents/verify-review.md +57 -0
- package/dist/server/services/plan/approval-evaluator.js +143 -0
- package/dist/server/services/plan/board-archive.js +102 -0
- package/dist/server/services/plan/board-config.js +108 -0
- package/dist/server/services/plan/board-export.js +214 -0
- package/dist/server/services/plan/composer-prompt.js +115 -0
- package/dist/server/services/plan/composer.js +664 -0
- package/dist/server/services/plan/config-installer.js +103 -0
- package/dist/server/services/plan/dependency-resolver.js +137 -0
- package/dist/server/services/plan/executor.js +696 -0
- package/dist/server/services/plan/front-matter.js +43 -0
- package/dist/server/services/plan/issue-classification.js +10 -0
- package/dist/server/services/plan/issue-effort.js +182 -0
- package/dist/server/services/plan/issue-loader.js +35 -0
- package/dist/server/services/plan/issue-prompt-builder.js +152 -0
- package/dist/server/services/plan/issue-retry.js +42 -0
- package/dist/server/services/plan/issue-writer.js +102 -0
- package/dist/server/services/plan/metrics-collector.js +272 -0
- package/dist/server/services/plan/output-manager.js +77 -0
- package/dist/server/services/plan/parser-core.js +435 -0
- package/dist/server/services/plan/parser-migration.js +108 -0
- package/dist/server/services/plan/parser.js +258 -0
- package/dist/server/services/plan/plan-runner-factory.js +68 -0
- package/dist/server/services/plan/pm-timeline.js +320 -0
- package/dist/server/services/plan/progress-log.js +101 -0
- package/dist/server/services/plan/prompt-builder.js +142 -0
- package/dist/server/services/plan/quality-delta.js +274 -0
- package/dist/server/services/plan/readiness-planner.js +34 -0
- package/dist/server/services/plan/review-gate.js +409 -0
- package/dist/server/services/plan/review-report.js +134 -0
- package/dist/server/services/plan/review-verdict-stream.js +161 -0
- package/dist/server/services/plan/state-reconciler.js +238 -0
- package/dist/server/services/plan/template-diff.js +175 -0
- package/dist/server/services/plan/template-instantiator.js +516 -0
- package/dist/server/services/plan/template-manifest.js +56 -0
- package/dist/server/services/plan/template-types.js +3 -0
- package/dist/server/services/plan/trigger-evaluator.js +211 -0
- package/dist/server/services/plan/types.js +3 -0
- package/dist/server/services/plan/watcher.js +73 -0
- package/dist/server/services/platform-credentials.js +56 -0
- package/dist/server/services/platform-e2ee.js +421 -0
- package/dist/server/services/platform-envelope.js +102 -0
- package/dist/server/services/platform-heartbeat.js +88 -0
- package/dist/server/services/platform-reconnect.js +60 -0
- package/dist/server/services/platform-token-lifecycle.js +95 -0
- package/dist/server/services/platform-url.js +17 -0
- package/dist/server/services/platform.js +656 -0
- package/dist/server/services/runtime-info.js +9 -0
- package/dist/server/services/schedule/agent-schedule-store.js +232 -0
- package/dist/server/services/schedule/agent-scheduler.js +323 -0
- package/dist/server/services/schedule/daily-timing.js +105 -0
- package/dist/server/services/schedule/quality-schedule-launch.js +11 -0
- package/dist/server/services/schedule/quality-schedule-store.js +211 -0
- package/dist/server/services/schedule/quality-scheduler.js +215 -0
- package/dist/server/services/schedule/run-bootstrap.js +329 -0
- package/dist/server/services/schedule/schedule-store.js +238 -0
- package/dist/server/services/schedule/schedule-wire.js +77 -0
- package/dist/server/services/schedule/scheduler.js +310 -0
- package/dist/server/services/schedule/template-source.js +97 -0
- package/dist/server/services/sdk/agent-sessions.js +264 -0
- package/dist/server/services/sdk/agents.js +557 -0
- package/dist/server/services/sdk/app-endpoints.js +48 -0
- package/dist/server/services/sdk/app-tools.js +303 -0
- package/dist/server/services/sdk/audit.js +48 -0
- package/dist/server/services/sdk/browser-transport.js +188 -0
- package/dist/server/services/sdk/browser.js +605 -0
- package/dist/server/services/sdk/composer.js +129 -0
- package/dist/server/services/sdk/connect.js +273 -0
- package/dist/server/services/sdk/consent-cooldown.js +31 -0
- package/dist/server/services/sdk/endpoint-url.js +141 -0
- package/dist/server/services/sdk/endpoints.js +314 -0
- package/dist/server/services/sdk/file-change-notify.js +36 -0
- package/dist/server/services/sdk/files-app.js +163 -0
- package/dist/server/services/sdk/files-search.js +131 -0
- package/dist/server/services/sdk/files-transfer.js +279 -0
- package/dist/server/services/sdk/files-workspace.js +233 -0
- package/dist/server/services/sdk/git.js +520 -0
- package/dist/server/services/sdk/grant-store.js +318 -0
- package/dist/server/services/sdk/host-ops.js +84 -0
- package/dist/server/services/sdk/inference-claude.js +214 -0
- package/dist/server/services/sdk/inference.js +247 -0
- package/dist/server/services/sdk/live-registry.js +42 -0
- package/dist/server/services/sdk/local-app-bindings.js +71 -0
- package/dist/server/services/sdk/pipeline.js +190 -0
- package/dist/server/services/sdk/pm-execute.js +228 -0
- package/dist/server/services/sdk/pm-planning-tap.js +29 -0
- package/dist/server/services/sdk/pm-schedule.js +165 -0
- package/dist/server/services/sdk/pm.js +634 -0
- package/dist/server/services/sdk/quality-change-notify.js +20 -0
- package/dist/server/services/sdk/quality-schedule.js +165 -0
- package/dist/server/services/sdk/quality.js +602 -0
- package/dist/server/services/sdk/rate-limits.js +198 -0
- package/dist/server/services/sdk/registry.js +597 -0
- package/dist/server/services/sdk/revoke.js +86 -0
- package/dist/server/services/sdk/run-profile.js +41 -0
- package/dist/server/services/sdk/sandbox.js +89 -0
- package/dist/server/services/sdk/storage.js +110 -0
- package/dist/server/services/sdk/streams.js +147 -0
- package/dist/server/services/sdk/terminal.js +201 -0
- package/dist/server/services/sdk/test-utils/workshop-browser-app.js +466 -0
- package/dist/server/services/sentry.js +99 -0
- package/dist/server/services/settings.js +374 -0
- package/dist/server/services/snippets/expander.js +87 -0
- package/dist/server/services/snippets/index.js +6 -0
- package/dist/server/services/snippets/loader.js +119 -0
- package/dist/server/services/snippets/parser.js +52 -0
- package/dist/server/services/snippets/types.js +3 -0
- package/dist/server/services/snippets/watcher.js +60 -0
- package/dist/server/services/space-layout.js +80 -0
- package/dist/server/services/system-prompts.js +219 -0
- package/dist/server/services/terminal/pty-manager.js +206 -0
- package/dist/server/services/terminal/pty-utils.js +150 -0
- package/dist/server/services/timeline/assembler.js +890 -0
- package/dist/server/services/timeline/contract.js +196 -0
- package/dist/server/services/timeline/index.js +4 -0
- package/dist/server/services/websocket/agent-schedule-handlers.js +217 -0
- package/dist/server/services/websocket/apps-handlers.js +399 -0
- package/dist/server/services/websocket/ask-user-question-bridge.js +112 -0
- package/dist/server/services/websocket/autocomplete-index.js +415 -0
- package/dist/server/services/websocket/autocomplete-match.js +243 -0
- package/dist/server/services/websocket/autocomplete.js +407 -0
- package/dist/server/services/websocket/browser-agent-runtime.js +208 -0
- package/dist/server/services/websocket/browser-device-profile.js +46 -0
- package/dist/server/services/websocket/browser-handlers.js +377 -0
- package/dist/server/services/websocket/browser-host-broadcast.js +179 -0
- package/dist/server/services/websocket/browser-ice-config.js +121 -0
- package/dist/server/services/websocket/browser-payloads.js +222 -0
- package/dist/server/services/websocket/browser-viewer-lifecycle.js +84 -0
- package/dist/server/services/websocket/browser-viewer-registry.js +118 -0
- package/dist/server/services/websocket/collab-broadcast.js +11 -0
- package/dist/server/services/websocket/collab-handlers.js +116 -0
- package/dist/server/services/websocket/commit-suggestion-service.js +132 -0
- package/dist/server/services/websocket/debug-log.js +38 -0
- package/dist/server/services/websocket/dispatch-util.js +10 -0
- package/dist/server/services/websocket/engine-auth-handlers.js +323 -0
- package/dist/server/services/websocket/engine-credential-watcher.js +83 -0
- package/dist/server/services/websocket/engine-profile-handlers.js +92 -0
- package/dist/server/services/websocket/file-definition-handlers.js +180 -0
- package/dist/server/services/websocket/file-download-handler.js +291 -0
- package/dist/server/services/websocket/file-explorer-handlers.js +291 -0
- package/dist/server/services/websocket/file-search-handlers.js +267 -0
- package/dist/server/services/websocket/file-share-handlers.js +328 -0
- package/dist/server/services/websocket/file-transfer-http.js +361 -0
- package/dist/server/services/websocket/file-upload-handler.js +267 -0
- package/dist/server/services/websocket/file-utils.js +346 -0
- package/dist/server/services/websocket/git-branch-handlers.js +90 -0
- package/dist/server/services/websocket/git-diff-handlers.js +59 -0
- package/dist/server/services/websocket/git-handlers.js +212 -0
- package/dist/server/services/websocket/git-head-watcher.js +85 -0
- package/dist/server/services/websocket/git-log-handlers.js +104 -0
- package/dist/server/services/websocket/git-pr-handlers.js +56 -0
- package/dist/server/services/websocket/git-tag-handlers.js +53 -0
- package/dist/server/services/websocket/git-utils.js +11 -0
- package/dist/server/services/websocket/git-worktree-handlers.js +521 -0
- package/dist/server/services/websocket/handler-context.js +113 -0
- package/dist/server/services/websocket/handler.js +1197 -0
- package/dist/server/services/websocket/index.js +5 -0
- package/dist/server/services/websocket/movement-written-files.js +26 -0
- package/dist/server/services/websocket/msg-id-tracker.js +48 -0
- package/dist/server/services/websocket/plan-board-handlers.js +410 -0
- package/dist/server/services/websocket/plan-execution-handlers.js +244 -0
- package/dist/server/services/websocket/plan-handlers.js +67 -0
- package/dist/server/services/websocket/plan-helpers.js +161 -0
- package/dist/server/services/websocket/plan-issue-handlers.js +168 -0
- package/dist/server/services/websocket/plan-sprint-handlers.js +190 -0
- package/dist/server/services/websocket/plan-transfer-handlers.js +310 -0
- package/dist/server/services/websocket/pm-timeline-broadcast.js +28 -0
- package/dist/server/services/websocket/post-session-scan.js +132 -0
- package/dist/server/services/websocket/prompt-queue-handlers.js +96 -0
- package/dist/server/services/websocket/quality-agent-cost.js +229 -0
- package/dist/server/services/websocket/quality-agent-notes.js +113 -0
- package/dist/server/services/websocket/quality-change-activity.js +187 -0
- package/dist/server/services/websocket/quality-complexity.js +345 -0
- package/dist/server/services/websocket/quality-dependencies.js +445 -0
- package/dist/server/services/websocket/quality-duplication.js +162 -0
- package/dist/server/services/websocket/quality-eta.js +65 -0
- package/dist/server/services/websocket/quality-fingerprint.js +104 -0
- package/dist/server/services/websocket/quality-grading.js +575 -0
- package/dist/server/services/websocket/quality-handlers.js +48 -0
- package/dist/server/services/websocket/quality-linting.js +270 -0
- package/dist/server/services/websocket/quality-operations.js +54 -0
- package/dist/server/services/websocket/quality-persistence.js +410 -0
- package/dist/server/services/websocket/quality-review-agent.js +526 -0
- package/dist/server/services/websocket/quality-run.js +220 -0
- package/dist/server/services/websocket/quality-secrets.js +0 -0
- package/dist/server/services/websocket/quality-service.js +775 -0
- package/dist/server/services/websocket/quality-tools.js +383 -0
- package/dist/server/services/websocket/quality-triage-agent.js +101 -0
- package/dist/server/services/websocket/quality-types.js +149 -0
- package/dist/server/services/websocket/recommended-answers.js +28 -0
- package/dist/server/services/websocket/schedule-handlers.js +197 -0
- package/dist/server/services/websocket/sdk-agent-host.js +569 -0
- package/dist/server/services/websocket/sdk-browser-host.js +459 -0
- package/dist/server/services/websocket/sdk-composer-host.js +10 -0
- package/dist/server/services/websocket/sdk-git-host.js +115 -0
- package/dist/server/services/websocket/sdk-handlers.js +242 -0
- package/dist/server/services/websocket/sdk-pm-execution-host.js +63 -0
- package/dist/server/services/websocket/sdk-pm-schedule-host.js +21 -0
- package/dist/server/services/websocket/sdk-quality-schedule-host.js +34 -0
- package/dist/server/services/websocket/sdk-terminal-host.js +140 -0
- package/dist/server/services/websocket/session-handlers.js +565 -0
- package/dist/server/services/websocket/session-history.js +335 -0
- package/dist/server/services/websocket/session-initialization.js +315 -0
- package/dist/server/services/websocket/session-registry.js +340 -0
- package/dist/server/services/websocket/session-role-directory.js +39 -0
- package/dist/server/services/websocket/settings-handlers.js +276 -0
- package/dist/server/services/websocket/skill-handlers.js +324 -0
- package/dist/server/services/websocket/skill-watcher.js +83 -0
- package/dist/server/services/websocket/snippet-handlers.js +261 -0
- package/dist/server/services/websocket/tab-broadcast.js +35 -0
- package/dist/server/services/websocket/tab-event-buffer.js +110 -0
- package/dist/server/services/websocket/tab-event-replay.js +47 -0
- package/dist/server/services/websocket/tab-handlers.js +211 -0
- package/dist/server/services/websocket/terminal-handlers.js +268 -0
- package/dist/server/services/websocket/types.js +96 -0
- package/dist/server/types/company-messages.js +102 -0
- package/dist/server/utils/agent-manager.js +202 -0
- package/dist/server/utils/console-timestamps.js +24 -0
- package/dist/server/utils/file-store.js +112 -0
- package/dist/server/utils/paths.js +28 -0
- package/dist/server/utils/port-manager.js +43 -0
- package/dist/server/utils/port.js +204 -0
- package/electron-host/dist/agent-lease.js +141 -0
- package/electron-host/dist/capture-recovery.js +77 -0
- package/electron-host/dist/codec-policy.js +37 -0
- package/electron-host/dist/controller-channel.js +60 -0
- package/electron-host/dist/controller-handlers.js +153 -0
- package/electron-host/dist/device-emulator.js +106 -0
- package/electron-host/dist/dom-driver.js +642 -0
- package/electron-host/dist/domain-registry.js +159 -0
- package/electron-host/dist/domain-validators.js +308 -0
- package/electron-host/dist/editable-focus-reporter.js +143 -0
- package/electron-host/dist/fake-peer.test-util.js +105 -0
- package/electron-host/dist/host-log.js +31 -0
- package/electron-host/dist/host-wire.js +11 -0
- package/electron-host/dist/input-router.js +421 -0
- package/electron-host/dist/ipc-protocol.js +89 -0
- package/electron-host/dist/ipc-server.js +193 -0
- package/electron-host/dist/js-driver.js +216 -0
- package/electron-host/dist/main-guards.js +70 -0
- package/electron-host/dist/main.js +716 -0
- package/electron-host/dist/roster-sync.js +87 -0
- package/electron-host/dist/rpc-context.js +1 -0
- package/electron-host/dist/rpc-tab-methods.js +138 -0
- package/electron-host/dist/rpc-webrtc-methods.js +121 -0
- package/electron-host/dist/screen-capture-cache.js +147 -0
- package/electron-host/dist/sdk-injector.js +166 -0
- package/electron-host/dist/sdp.js +102 -0
- package/electron-host/dist/session-surface.js +78 -0
- package/electron-host/dist/surface-sizing.js +59 -0
- package/electron-host/dist/view-manager.js +254 -0
- package/electron-host/dist/viewer-registry.js +46 -0
- package/electron-host/dist/viewer-session.js +288 -0
- package/electron-host/dist/webrtc-channels.js +14 -0
- package/electron-host/dist/webrtc-controller.js +57 -0
- package/electron-host/dist/webrtc-ice-filter.js +13 -0
- package/electron-host/dist/webrtc-peer.js +45 -0
- package/electron-host/package.json +12 -0
- package/electron-host/tsconfig.json +23 -0
- package/electron-host/webrtc-controller-preload.cjs +3 -0
- package/electron-host/webrtc-controller.html +14 -0
- package/package.json +85 -0
- package/vendor/e2ee/LICENSE +14 -0
- package/vendor/e2ee/package.json +14 -0
- package/vendor/e2ee/src/index.js +310 -0
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
// Copyright (c) 2025-present Minionry, Inc.
|
|
2
|
+
// SPDX-License-Identifier: LicenseRef-Minionry-Software
|
|
3
|
+
import { resolve } from 'node:path';
|
|
4
|
+
export { classifyRisk, isDeployMode, isSensitivePath, requiresAIReview } from './security-analysis.js';
|
|
5
|
+
export const SENSITIVE_PATHS = [
|
|
6
|
+
{ pattern: /^(Write|Edit):\s*\/etc\//i, reason: 'System configuration - verify user intent' },
|
|
7
|
+
{ pattern: /^(Write|Edit):\s*\/(bin|sbin|usr\/bin|usr\/sbin|usr\/local\/bin|usr\/local\/sbin)\//i, reason: 'System binaries - verify user intent' },
|
|
8
|
+
{ pattern: /^(Write|Edit):\s*\/boot\//i, reason: 'Boot directory - verify user intent' },
|
|
9
|
+
{ pattern: /^(Write|Edit):\s*\/root\//i, reason: 'Root home - verify user intent' },
|
|
10
|
+
{ pattern: /^(Write|Edit):\s*\/System\//i, reason: 'macOS system - verify user intent' },
|
|
11
|
+
{ pattern: /^(Write|Edit):\s*\/Library\/(LaunchDaemons|LaunchAgents)\//i, reason: 'macOS launch services - verify user intent' },
|
|
12
|
+
{ pattern: /^(Write|Edit):\s*.*\/\.ssh\//i, reason: 'SSH configuration - verify user intent' },
|
|
13
|
+
{ pattern: /^(Write|Edit):\s*.*\/\.gnupg\//i, reason: 'GPG keys - verify user intent' },
|
|
14
|
+
{ pattern: /^(Write|Edit):\s*.*\/\.aws\/(credentials|config)/i, reason: 'AWS credentials - verify user intent' },
|
|
15
|
+
{ pattern: /^(Write|Edit):\s*.*\/(\.env|\.env\.local|\.env\.production)$/i, reason: 'Environment secrets - verify user intent' },
|
|
16
|
+
{ pattern: /^(Write|Edit):\s*.*\/(\.bash_profile|\.bashrc|\.zshrc|\.profile|\.zprofile)$/i, reason: 'Shell profile - verify user intent' },
|
|
17
|
+
];
|
|
18
|
+
export const CRITICAL_THREATS = [
|
|
19
|
+
{
|
|
20
|
+
pattern: /rm\s+-rf\s+(\/|~)($|\s|;|&&|\|\|)/i,
|
|
21
|
+
reason: 'Deleting root (/) or home (~) directory is never a legitimate dev task'
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
pattern: /:\(\)\{.*\}|:\(\)\{.*:\|:/i,
|
|
25
|
+
reason: 'Fork bomb detected - would cause system resource exhaustion'
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
pattern: /dd\s+if=\/dev\/zero\s+of=\/dev\/sd/i,
|
|
29
|
+
reason: 'Attempting to overwrite disk device - would destroy data'
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
pattern: /mkfs\./i,
|
|
33
|
+
reason: 'Attempting to format filesystem - would destroy all data'
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
pattern: /eval.*\$\(.*base64.*\)/i,
|
|
37
|
+
reason: 'Obfuscated code execution via base64 - common malware technique'
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
pattern: />\s*\/dev\/sd[a-z]/i,
|
|
41
|
+
reason: 'Direct write to disk device - would corrupt filesystem'
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
pattern: /chmod\s+000\s+\//i,
|
|
45
|
+
reason: 'Attempting to make system directories inaccessible'
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
pattern: /\/dev\/tcp\//i,
|
|
49
|
+
reason: 'Reverse shell via /dev/tcp - classic backdoor technique'
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
pattern: /(?:^|[\s;|&`("'/])(?:nc|ncat|netcat)\b.*-[elp].*\b\d+\b/i,
|
|
53
|
+
reason: 'Netcat listener/reverse shell - common backdoor technique'
|
|
54
|
+
},
|
|
55
|
+
];
|
|
56
|
+
export const GIT_SDK_SAFE_TOOLS = [
|
|
57
|
+
{ pattern: /^git_stage:/i, reason: 'SDK git stage — local index mutation inside the repo' },
|
|
58
|
+
{ pattern: /^git_unstage:/i, reason: 'SDK git unstage — local index mutation inside the repo' },
|
|
59
|
+
{ pattern: /^git_commit:/i, reason: 'SDK git commit — records staged changes locally' },
|
|
60
|
+
{ pattern: /^git_checkout:/i, reason: 'SDK git checkout — local branch switch (refuses on a dirty tree)' },
|
|
61
|
+
{ pattern: /^git_branch_create:/i, reason: 'SDK git branch create — local ref creation' },
|
|
62
|
+
{ pattern: /^git_branch_delete:/i, reason: 'SDK git branch delete — local ref removal' },
|
|
63
|
+
{ pattern: /^git_tag_create:/i, reason: 'SDK git tag create — local ref creation' },
|
|
64
|
+
{ pattern: /^git_worktree_create:/i, reason: 'SDK git worktree create — path validated handler-side (S9)' },
|
|
65
|
+
{ pattern: /^git_worktree_remove:/i, reason: 'SDK git worktree remove — only a registered worktree (S9)' },
|
|
66
|
+
{ pattern: /^git_worktree_switch:/i, reason: 'SDK git worktree switch — repoints the calling context only' },
|
|
67
|
+
{ pattern: /^git_merge_run:/i, reason: 'SDK git merge — local branch merge' },
|
|
68
|
+
{ pattern: /^git_merge_abort:/i, reason: 'SDK git merge abort — restores the pre-merge state' },
|
|
69
|
+
{ pattern: /^git_merge_complete:/i, reason: 'SDK git merge complete — commits a conflict resolution' },
|
|
70
|
+
{ pattern: /^git_merge_stash_pop:/i, reason: 'SDK git merge stash pop — restores the pre-merge stash' },
|
|
71
|
+
{ pattern: /^git_merge_discard_blockers:/i, reason: 'SDK git merge discard — paths isSafeDiscardPath-validated (S9)' },
|
|
72
|
+
{ pattern: /^git_generate_commit_message:/i, reason: 'SDK git AI op — generation only, no repo mutation (D10)' },
|
|
73
|
+
{ pattern: /^git_pr_generate_description:/i, reason: 'SDK git AI op — generation only, no repo mutation (D10)' },
|
|
74
|
+
];
|
|
75
|
+
export const GIT_SDK_REMOTE_REVIEW_TOOLS = [
|
|
76
|
+
{ pattern: /^git_push:/i, reason: 'SDK git push — network egress under the user\'s ambient git identity (S8)' },
|
|
77
|
+
{ pattern: /^git_pull:/i, reason: 'SDK git pull — network fetch + local merge under ambient git identity (S8)' },
|
|
78
|
+
{ pattern: /^git_tag_push:/i, reason: 'SDK git tag push — network egress under ambient git identity (S8)' },
|
|
79
|
+
{ pattern: /^git_pr_create:/i, reason: 'SDK PR create — gh/glab shell-out under the user\'s ambient provider auth (S8)' },
|
|
80
|
+
];
|
|
81
|
+
export const SAFE_OPERATIONS = [
|
|
82
|
+
{ pattern: /^Read:/i },
|
|
83
|
+
{ pattern: /^Glob:/i },
|
|
84
|
+
{ pattern: /^Grep:/i },
|
|
85
|
+
{ pattern: /^Write:\s*\/Users\/[^/]+\//i },
|
|
86
|
+
{ pattern: /^Edit:\s*\/Users\/[^/]+\//i },
|
|
87
|
+
{ pattern: /^Write:\s*\/home\/[^/]+\//i },
|
|
88
|
+
{ pattern: /^Edit:\s*\/home\/[^/]+\//i },
|
|
89
|
+
{ pattern: /^Bash:\s*(npm|yarn|pnpm|bun)\s+(install|ci|run|test|build|dev|start|lint|format)($|\s)/i },
|
|
90
|
+
{ pattern: /^Bash:\s*(npm|yarn|pnpm|bun)\s+(ls|list|view|info|why|outdated|audit|ping|prefix|root|bin|version|pack)($|\s)/i },
|
|
91
|
+
{ pattern: /^Bash:\s*git\s+(status|log|diff|show|branch|clone|pull|fetch|add|stash|checkout)($|\s)/i },
|
|
92
|
+
{ pattern: /^Bash:\s*git\s+(describe|blame|rev-parse|rev-list|merge-base|ls-files|ls-tree|check-ignore|shortlog|count-objects|cat-file|symbolic-ref|for-each-ref|name-rev|reflog|grep)($|\s)/i },
|
|
93
|
+
{ pattern: /^Bash:\s*docker\s+(build|run|ps|logs|compose|images)($|\s)/i },
|
|
94
|
+
{ pattern: /^Bash:\s*(pytest|cargo\s+(build|test|run|check)|go\s+(build|test|run|mod))($|\s)/i },
|
|
95
|
+
{ pattern: /^Bash:\s*(mkdir|cd|ls|pwd|cat|head|tail|wc|sort|uniq|grep|find|which|echo|env)($|\s)/i },
|
|
96
|
+
{ pattern: /^Bash:\s*rm\s+-rf\s+(\.\/)?node_modules($|\s)/i },
|
|
97
|
+
{ pattern: /^Bash:\s*rm\s+-rf\s+(\.\/)?dist($|\s)/i },
|
|
98
|
+
{ pattern: /^Bash:\s*rm\s+-rf\s+(\.\/)?build($|\s)/i },
|
|
99
|
+
{ pattern: /^Bash:\s*rm\s+-rf\s+(\.\/)?\.cache($|\s)/i },
|
|
100
|
+
{ pattern: /^Bash:\s*rm\s+-rf\s+(\.\/)?\.next($|\s)/i },
|
|
101
|
+
{ pattern: /^Bash:\s*rm\s+-rf\s+(\.\/)?target($|\s)/i },
|
|
102
|
+
{ pattern: /^Bash:\s*rm\s+-rf\s+(\.\/)?__pycache__($|\s)/i },
|
|
103
|
+
{ pattern: /^(Write|Edit):\s*\/tmp\//i },
|
|
104
|
+
{ pattern: /^(Write|Edit):\s*\/var\/tmp\//i },
|
|
105
|
+
{ pattern: /^(ExitPlanMode|EnterPlanMode|TodoWrite|AskUserQuestion):/i },
|
|
106
|
+
{ pattern: /^Bash:\s*(tsc|tsx|node|bun|deno|npx|bunx)\s/i },
|
|
107
|
+
{ pattern: /^Bash:\s*(vitest|jest|mocha|tap)\s/i },
|
|
108
|
+
{ pattern: /^Bash:\s*(biome|eslint|prettier|tslint)\s+(check|lint|format)/i },
|
|
109
|
+
{ pattern: /^Bash:\s*(make|cmake|ninja|meson)($|\s)/i },
|
|
110
|
+
{ pattern: /^Bash:\s*git\s+(commit|push|tag|remote|rebase|merge|cherry-pick|reset|revert)($|\s)/i },
|
|
111
|
+
{ pattern: /^Bash:\s*git\s+(worktree|submodule|config|clean|gc)($|\s)/i },
|
|
112
|
+
{ pattern: /^Bash:\s*(uname|hostname|whoami|id|groups|uptime|df|du|free|top|ps|lsof|stat|file|readlink)($|\s)/i },
|
|
113
|
+
{ pattern: /^Bash:\s*(touch|basename|dirname|realpath|mktemp|tee|tr|cut|paste|comm|diff|patch)($|\s)/i },
|
|
114
|
+
{ pattern: /^Bash:\s*(tar|gzip|gunzip|zip|unzip|bzip2)\s/i },
|
|
115
|
+
{ pattern: /^Bash:\s*(ruby|python3?|php|java|javac|scala|kotlinc|swift|rustc|gcc|g\+\+|clang)\s/i },
|
|
116
|
+
{ pattern: /^Bash:\s*(pip|pip3|gem|bundle|composer|maven|gradle|sbt|cargo|rustup)\s/i },
|
|
117
|
+
{ pattern: /^Bash:\s*(gh|hub)\s+(pr|issue|repo|release|run|api)\s/i },
|
|
118
|
+
{ pattern: /^Bash:\s*(flyctl|fly)\s+(status|logs|ssh|deploy|apps|machines|secrets)($|\s)/i },
|
|
119
|
+
{ pattern: /^Bash:\s*(terraform|tofu)\s+(init|plan|apply|validate|fmt|show|output)($|\s)/i },
|
|
120
|
+
{ pattern: /^Bash:\s*wc($|\s)/i },
|
|
121
|
+
{ pattern: /^WebFetch:/i },
|
|
122
|
+
{ pattern: /^WebSearch:/i },
|
|
123
|
+
{ pattern: /^Agent:/i },
|
|
124
|
+
{ pattern: /^NotebookEdit:/i },
|
|
125
|
+
...GIT_SDK_SAFE_TOOLS,
|
|
126
|
+
];
|
|
127
|
+
export const NEEDS_AI_REVIEW = [
|
|
128
|
+
{
|
|
129
|
+
pattern: /(curl|wget).*\|.*(?:bash|sh)/i,
|
|
130
|
+
reason: 'Pipe to shell - verify source is trusted and user intended this'
|
|
131
|
+
},
|
|
132
|
+
{ pattern: /sudo/i, reason: 'Elevated privileges - verify user intended this action' },
|
|
133
|
+
{ pattern: /rm\s+-rf/i, reason: 'Recursive deletion - verify target matches user intent' },
|
|
134
|
+
{ pattern: /\|\s*(nc|netcat|ncat)\b/i, reason: 'Pipe to netcat - potential data exfiltration' },
|
|
135
|
+
{ pattern: /\bscp\b.*@/i, reason: 'SCP to remote host - potential data exfiltration' },
|
|
136
|
+
{ pattern: /\|\s*curl\b/i, reason: 'Pipe to curl - potential data exfiltration' },
|
|
137
|
+
{ pattern: /curl\b.*-d\s*@/i, reason: 'Curl with file upload - potential data exfiltration' },
|
|
138
|
+
{
|
|
139
|
+
pattern: /^(Write|Edit):\s*(?!\/tmp\/|\/var\/tmp\/)/i,
|
|
140
|
+
reason: 'File modification - verify aligns with user request'
|
|
141
|
+
},
|
|
142
|
+
{ pattern: /\/dev\/tcp\//i, reason: 'Potential reverse shell via /dev/tcp' },
|
|
143
|
+
{ pattern: /\b(nc|netcat|ncat)\b.*-e\s/i, reason: 'Netcat with -e flag - potential reverse shell' },
|
|
144
|
+
{
|
|
145
|
+
pattern: /\bsocket\b.*\bconnect\b.*\b(dup2|subprocess|exec)\b/i,
|
|
146
|
+
reason: 'Programmatic reverse shell pattern (socket+connect+exec)'
|
|
147
|
+
},
|
|
148
|
+
{ pattern: /\bperl\b.*\bsocket\b.*\bexec\b/i, reason: 'Perl reverse shell pattern' },
|
|
149
|
+
{
|
|
150
|
+
pattern: /\b(base64|base32)\b.*-d.*\|\s*(bash|sh)\b/i,
|
|
151
|
+
reason: 'Decoded payload piped to shell - obfuscated command execution'
|
|
152
|
+
},
|
|
153
|
+
{ pattern: /\\x[0-9a-f]{2}.*\|\s*(bash|sh)\b/i, reason: 'Hex-encoded payload piped to shell' },
|
|
154
|
+
{ pattern: /\bexec\b.*\b(base64|b64decode)\b/i, reason: 'Exec with base64 decoding - obfuscated code execution' },
|
|
155
|
+
{
|
|
156
|
+
pattern: /\bprintf\b.*\\x[0-9a-f].*\|\s*(bash|sh)\b/i,
|
|
157
|
+
reason: 'Printf hex payload piped to shell'
|
|
158
|
+
},
|
|
159
|
+
{ pattern: /169\.254\.169\.254/i, reason: 'AWS/Azure IMDS access - potential credential theft' },
|
|
160
|
+
{ pattern: /metadata\.google\.internal/i, reason: 'GCP metadata access - potential credential theft' },
|
|
161
|
+
{
|
|
162
|
+
pattern: />>\s*~?\/?.*\/(authorized_keys|\.bashrc|\.bash_profile|\.zshrc|\.profile)/i,
|
|
163
|
+
reason: 'Appending to sensitive file - potential persistence mechanism'
|
|
164
|
+
},
|
|
165
|
+
{ pattern: /\bld\.so\.preload\b/i, reason: 'LD_PRELOAD injection - shared library hijacking' },
|
|
166
|
+
{ pattern: /wget\b.*--post-file/i, reason: 'wget file upload - potential data exfiltration' },
|
|
167
|
+
{
|
|
168
|
+
pattern: /pip3?\b.*--(?:extra-)?index-url[=\s]+https?:\/\/(?!pypi\.org)/i,
|
|
169
|
+
reason: 'pip install from non-PyPI index - potential supply chain attack'
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
pattern: /\b(npm|yarn|pnpm|bun)\b.*--registry[=\s]+https?:\/\/(?!registry\.npmjs\.org)/i,
|
|
173
|
+
reason: 'Package install from non-npmjs registry - potential supply chain attack'
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
pattern: /\b(node|bun|deno)\s+(-e|--eval|-p)\b[\s\S]*(child_process|execSync|spawnSync|\.exec\s*\(|\beval\s*\(|fetch\s*\(|https?:\/\/)/i,
|
|
177
|
+
reason: 'Inline JavaScript with subprocess/network access - verify user intent'
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
pattern: /\b(python3?|ruby|perl|php)\s+(-c|-e|-r)\b[\s\S]*(\bexec\s*\(|\beval\s*\(|os\.system|subprocess|__import__|\bsocket\b|urllib|https?:\/\/)/i,
|
|
181
|
+
reason: 'Inline script code with dynamic execution or system access - verify user intent'
|
|
182
|
+
},
|
|
183
|
+
{ pattern: /\bclaude\b.*\bmcp\b.*\badd\b/i, reason: 'Adding MCP server - verify source is trusted' },
|
|
184
|
+
...GIT_SDK_REMOTE_REVIEW_TOOLS,
|
|
185
|
+
];
|
|
186
|
+
export const BROWSER_SAFE_TOOLS = [
|
|
187
|
+
{ pattern: /^browser_snapshot:/i, reason: 'Browser DOM snapshot — read-only' },
|
|
188
|
+
{ pattern: /^browser_console_messages:/i, reason: 'Browser console messages — read-only' },
|
|
189
|
+
{ pattern: /^browser_take_screenshot:/i, reason: 'Browser screenshot — read-only' },
|
|
190
|
+
{ pattern: /^browser_network_request:/i, reason: 'Browser network request inspection — read-only' },
|
|
191
|
+
{ pattern: /^browser_network_requests:/i, reason: 'Browser network request listing — read-only' },
|
|
192
|
+
{ pattern: /^browser_tabs:/i, reason: 'Browser tab listing — read-only' },
|
|
193
|
+
{ pattern: /^browser_wait_for:/i, reason: 'Browser wait-for predicate — read-only' },
|
|
194
|
+
];
|
|
195
|
+
export const BROWSER_EVAL_THREATS = [
|
|
196
|
+
{
|
|
197
|
+
pattern: /^browser_(evaluate|run_code_unsafe):.*document\s*\.\s*cookie/i,
|
|
198
|
+
reason: 'JS payload reads document.cookie — credential exfiltration vector',
|
|
199
|
+
},
|
|
200
|
+
{
|
|
201
|
+
pattern: /^browser_(evaluate|run_code_unsafe):.*(localStorage|sessionStorage)\s*\.\s*(getItem|valueOf|toString)/i,
|
|
202
|
+
reason: 'JS payload reads localStorage/sessionStorage — token exfiltration vector',
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
pattern: /^browser_(evaluate|run_code_unsafe):.*JSON\s*\.\s*stringify\s*\(\s*(localStorage|sessionStorage)/i,
|
|
206
|
+
reason: 'JS payload serializes localStorage — bulk credential exfiltration vector',
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
pattern: /^browser_(evaluate|run_code_unsafe):.*credentials\s*:\s*\\?["']include\\?["']/i,
|
|
210
|
+
reason: 'JS payload calls fetch with credentials:include — exfiltrates session cookies',
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
pattern: /^browser_(evaluate|run_code_unsafe):.*withCredentials\s*=\s*true/i,
|
|
214
|
+
reason: 'JS payload sets XHR withCredentials — exfiltrates session cookies',
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
pattern: /^browser_(evaluate|run_code_unsafe):.*navigator\s*\.\s*sendBeacon/i,
|
|
218
|
+
reason: 'JS payload uses sendBeacon — covert data exfiltration channel',
|
|
219
|
+
},
|
|
220
|
+
{
|
|
221
|
+
pattern: /^browser_(evaluate|run_code_unsafe):.*btoa\s*\(\s*document/i,
|
|
222
|
+
reason: 'JS payload base64-encodes document content — exfiltration staging',
|
|
223
|
+
},
|
|
224
|
+
];
|
|
225
|
+
export const BROWSER_LOCALHOST_PATTERNS = [
|
|
226
|
+
/^https?:\/\/localhost(:\d+)?(\/|$)/i,
|
|
227
|
+
/^https?:\/\/127\.\d+\.\d+\.\d+(:\d+)?(\/|$)/i,
|
|
228
|
+
/^https?:\/\/\[::1\](:\d+)?(\/|$)/i,
|
|
229
|
+
/^https?:\/\/[^/]+\.local(:\d+)?(\/|$)/i,
|
|
230
|
+
/^https?:\/\/host\.docker\.internal(:\d+)?(\/|$)/i,
|
|
231
|
+
/^about:/i,
|
|
232
|
+
/^chrome:\/\/newtab/i,
|
|
233
|
+
];
|
|
234
|
+
export function isLocalhostUrl(url) {
|
|
235
|
+
return BROWSER_LOCALHOST_PATTERNS.some((p) => p.test(url));
|
|
236
|
+
}
|
|
237
|
+
export function extractOrigin(url) {
|
|
238
|
+
try {
|
|
239
|
+
const u = new URL(url);
|
|
240
|
+
return `${u.protocol}//${u.host}`.toLowerCase();
|
|
241
|
+
}
|
|
242
|
+
catch {
|
|
243
|
+
return null;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
function entryMatches(host, origin, entry) {
|
|
247
|
+
const e = entry.trim().toLowerCase();
|
|
248
|
+
if (!e)
|
|
249
|
+
return false;
|
|
250
|
+
if (e.startsWith('http://') || e.startsWith('https://')) {
|
|
251
|
+
return e === origin;
|
|
252
|
+
}
|
|
253
|
+
if (e.startsWith('*.')) {
|
|
254
|
+
const suffix = e.slice(1);
|
|
255
|
+
return host.endsWith(suffix) && host.length > suffix.length;
|
|
256
|
+
}
|
|
257
|
+
return host === e;
|
|
258
|
+
}
|
|
259
|
+
export function isOriginAllowlisted(url, allowlist) {
|
|
260
|
+
const origin = extractOrigin(url);
|
|
261
|
+
if (!origin)
|
|
262
|
+
return false;
|
|
263
|
+
let host;
|
|
264
|
+
try {
|
|
265
|
+
host = new URL(url).hostname.toLowerCase();
|
|
266
|
+
}
|
|
267
|
+
catch {
|
|
268
|
+
return false;
|
|
269
|
+
}
|
|
270
|
+
return allowlist.some((entry) => entryMatches(host, origin, entry));
|
|
271
|
+
}
|
|
272
|
+
export const DEPLOY_PATTERNS = [
|
|
273
|
+
{
|
|
274
|
+
pattern: /\b(cat|head|tail|less|more)\b.*\.(env|pem|key|crt|p12|pfx|jks)\b/i,
|
|
275
|
+
reason: 'Deploy execution reading credential/certificate files — verify intent'
|
|
276
|
+
},
|
|
277
|
+
{
|
|
278
|
+
pattern: /\bgit\b.*\bpush\b/i,
|
|
279
|
+
reason: 'Deploy execution attempting git push — verify this is intended'
|
|
280
|
+
},
|
|
281
|
+
{
|
|
282
|
+
pattern: /\b(nc|netcat|ncat|socat)\b.*(\blisten\b|\s-l\b)/i,
|
|
283
|
+
reason: 'Deploy execution opening network listener — potential backdoor'
|
|
284
|
+
},
|
|
285
|
+
{
|
|
286
|
+
pattern: /\b(kill|killall|pkill)\b/i,
|
|
287
|
+
reason: 'Deploy execution attempting process termination — verify intent'
|
|
288
|
+
},
|
|
289
|
+
{
|
|
290
|
+
pattern: /\b(ssh|scp|sftp)\b.*@/i,
|
|
291
|
+
reason: 'Deploy execution initiating SSH/SCP connection — verify intent'
|
|
292
|
+
},
|
|
293
|
+
{
|
|
294
|
+
pattern: /\b(crontab|systemctl|launchctl)\b/i,
|
|
295
|
+
reason: 'Deploy execution manipulating scheduled tasks — verify intent'
|
|
296
|
+
},
|
|
297
|
+
];
|
|
298
|
+
export function matchesPattern(operation, patterns) {
|
|
299
|
+
for (const pattern of patterns) {
|
|
300
|
+
if (pattern.pattern.test(operation)) {
|
|
301
|
+
return pattern;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
return null;
|
|
305
|
+
}
|
|
306
|
+
export function normalizeOperation(operation) {
|
|
307
|
+
const match = operation.match(/^(Write|Edit|Read):\s*(\S+)/i);
|
|
308
|
+
if (match?.[2].includes('..')) {
|
|
309
|
+
const [, tool, rawPath] = match;
|
|
310
|
+
const normalizedPath = resolve(rawPath);
|
|
311
|
+
return `${tool}: ${normalizedPath}`;
|
|
312
|
+
}
|
|
313
|
+
return operation;
|
|
314
|
+
}
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
// Copyright (c) 2025-present Minionry, Inc.
|
|
2
|
+
// SPDX-License-Identifier: LicenseRef-Minionry-Software
|
|
3
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
4
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
5
|
+
import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
|
|
6
|
+
import { Agent } from 'undici';
|
|
7
|
+
import { reviewEnginePermission, sdkRunReviewContextFromEnv, setRemoteDecisionCache, } from './bouncer-integration.js';
|
|
8
|
+
import { sweepClassifierTranscripts } from './classifier/ClaudeBouncerClassifier.js';
|
|
9
|
+
const REMOTE_CACHE_TIMEOUT_MS = 400;
|
|
10
|
+
function installRemoteDecisionCache() {
|
|
11
|
+
const port = process.env.MINIONRY_PORT;
|
|
12
|
+
const secret = process.env.MINIONRY_BOUNCER_SECRET;
|
|
13
|
+
const capabilityToken = process.env.MINIONRY_CAPABILITY_TOKEN;
|
|
14
|
+
if (!port || !secret || !capabilityToken)
|
|
15
|
+
return;
|
|
16
|
+
const url = `http://127.0.0.1:${port}/internal/bouncer/decision-cache`;
|
|
17
|
+
const headers = {
|
|
18
|
+
'content-type': 'application/json',
|
|
19
|
+
'x-minionry-bouncer-secret': secret,
|
|
20
|
+
'x-minionry-capability-token': capabilityToken,
|
|
21
|
+
};
|
|
22
|
+
setRemoteDecisionCache({
|
|
23
|
+
async get(key) {
|
|
24
|
+
const res = await fetch(`${url}?key=${encodeURIComponent(key)}`, {
|
|
25
|
+
headers,
|
|
26
|
+
signal: AbortSignal.timeout(REMOTE_CACHE_TIMEOUT_MS),
|
|
27
|
+
});
|
|
28
|
+
if (!res.ok)
|
|
29
|
+
return null;
|
|
30
|
+
const json = (await res.json());
|
|
31
|
+
return json.decision ?? null;
|
|
32
|
+
},
|
|
33
|
+
async set(key, decision, ttlMs) {
|
|
34
|
+
await fetch(url, {
|
|
35
|
+
method: 'PUT',
|
|
36
|
+
headers,
|
|
37
|
+
body: JSON.stringify({ key, decision, ttlMs }),
|
|
38
|
+
signal: AbortSignal.timeout(REMOTE_CACHE_TIMEOUT_MS),
|
|
39
|
+
});
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
const askUserQuestionDispatcher = new Agent({ headersTimeout: 0, bodyTimeout: 0 });
|
|
44
|
+
const server = new Server({
|
|
45
|
+
name: 'minionry-bouncer',
|
|
46
|
+
version: '1.0.0',
|
|
47
|
+
}, {
|
|
48
|
+
capabilities: {
|
|
49
|
+
tools: {},
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
53
|
+
return {
|
|
54
|
+
tools: [
|
|
55
|
+
{
|
|
56
|
+
name: 'approval_prompt',
|
|
57
|
+
description: 'Analyze and approve/deny tool use requests from Claude Code. Integrates with Minionry security bouncer for AI-powered risk analysis.',
|
|
58
|
+
inputSchema: {
|
|
59
|
+
type: 'object',
|
|
60
|
+
properties: {
|
|
61
|
+
tool_name: {
|
|
62
|
+
type: 'string',
|
|
63
|
+
description: 'Name of the tool being requested (e.g., "Bash", "Write", "Read")',
|
|
64
|
+
},
|
|
65
|
+
input: {
|
|
66
|
+
type: 'object',
|
|
67
|
+
description: 'Tool input parameters as JSON object',
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
required: ['tool_name', 'input'],
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
],
|
|
74
|
+
};
|
|
75
|
+
});
|
|
76
|
+
async function bridgeAskUserQuestion(input) {
|
|
77
|
+
const port = process.env.MINIONRY_PORT;
|
|
78
|
+
const tabId = process.env.MINIONRY_TAB_ID;
|
|
79
|
+
const secret = process.env.MINIONRY_BOUNCER_SECRET;
|
|
80
|
+
const capabilityToken = process.env.MINIONRY_CAPABILITY_TOKEN;
|
|
81
|
+
const toolUseId = process.env.MINIONRY_CURRENT_TOOL_USE_ID || `aq-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`;
|
|
82
|
+
if (!port || !tabId || !secret || !capabilityToken) {
|
|
83
|
+
console.error('[MCP Bouncer] AskUserQuestion: missing routing context (port/tabId/secret/capability token) — passing through with no answers');
|
|
84
|
+
return { behavior: 'allow', updatedInput: input };
|
|
85
|
+
}
|
|
86
|
+
try {
|
|
87
|
+
const requestOptions = {
|
|
88
|
+
method: 'POST',
|
|
89
|
+
headers: {
|
|
90
|
+
'content-type': 'application/json',
|
|
91
|
+
'x-minionry-bouncer-secret': secret,
|
|
92
|
+
'x-minionry-capability-token': capabilityToken,
|
|
93
|
+
},
|
|
94
|
+
body: JSON.stringify({ toolUseId, tabId, questions: input.questions }),
|
|
95
|
+
};
|
|
96
|
+
requestOptions.dispatcher = askUserQuestionDispatcher;
|
|
97
|
+
const res = await fetch(`http://127.0.0.1:${port}/internal/ask-user-question`, requestOptions);
|
|
98
|
+
if (!res.ok) {
|
|
99
|
+
console.error(`[MCP Bouncer] AskUserQuestion bridge returned ${res.status} — passing through with no answers`);
|
|
100
|
+
return { behavior: 'allow', updatedInput: input };
|
|
101
|
+
}
|
|
102
|
+
const json = (await res.json());
|
|
103
|
+
const answers = json.answers && typeof json.answers === 'object' ? json.answers : {};
|
|
104
|
+
return {
|
|
105
|
+
behavior: 'allow',
|
|
106
|
+
updatedInput: { questions: input.questions, answers },
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
catch (err) {
|
|
110
|
+
console.error(`[MCP Bouncer] AskUserQuestion bridge failed: ${err instanceof Error ? err.message : String(err)} — passing through with no answers`);
|
|
111
|
+
return { behavior: 'allow', updatedInput: input };
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
function toMcpResponse(decision, input) {
|
|
115
|
+
if (decision.decision === 'deny') {
|
|
116
|
+
return {
|
|
117
|
+
behavior: 'deny',
|
|
118
|
+
message: `🚫 ${decision.reasoning}${decision.alternative ? `\n\nAlternative: ${decision.alternative}` : ''}`,
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
return {
|
|
122
|
+
behavior: 'allow',
|
|
123
|
+
updatedInput: input,
|
|
124
|
+
message: decision.decision === 'warn_allow'
|
|
125
|
+
? `⚠️ Allowed with caution: ${decision.reasoning}`
|
|
126
|
+
: undefined,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
130
|
+
if (request.params.name !== 'approval_prompt') {
|
|
131
|
+
throw new Error(`Unknown tool: ${request.params.name}`);
|
|
132
|
+
}
|
|
133
|
+
const { tool_name, input } = request.params.arguments;
|
|
134
|
+
if (tool_name === 'AskUserQuestion') {
|
|
135
|
+
console.error('[MCP Bouncer] AskUserQuestion received — bridging to web UI');
|
|
136
|
+
const response = await bridgeAskUserQuestion(input);
|
|
137
|
+
return {
|
|
138
|
+
content: [{ type: 'text', text: JSON.stringify(response) }],
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
console.error(`[MCP Bouncer] Analyzing ${tool_name} request...`);
|
|
142
|
+
const sdkRunContext = sdkRunReviewContextFromEnv(process.env);
|
|
143
|
+
try {
|
|
144
|
+
const decision = await reviewEnginePermission({
|
|
145
|
+
toolName: tool_name,
|
|
146
|
+
input,
|
|
147
|
+
context: {
|
|
148
|
+
purpose: `Tool use request from Claude`,
|
|
149
|
+
workingDirectory: process.cwd(),
|
|
150
|
+
userRequest: process.env.BOUNCER_USER_PROMPT,
|
|
151
|
+
...(sdkRunContext ?? {}),
|
|
152
|
+
},
|
|
153
|
+
});
|
|
154
|
+
console.error(`[MCP Bouncer] Decision: ${decision.decision} (${decision.confidence}% confidence)`);
|
|
155
|
+
console.error(`[MCP Bouncer] Reasoning: ${decision.reasoning}`);
|
|
156
|
+
const response = toMcpResponse(decision, input);
|
|
157
|
+
return {
|
|
158
|
+
content: [
|
|
159
|
+
{
|
|
160
|
+
type: 'text',
|
|
161
|
+
text: JSON.stringify(response),
|
|
162
|
+
},
|
|
163
|
+
],
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
catch (error) {
|
|
167
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
168
|
+
console.error(`[MCP Bouncer] Error: ${errorMessage}`);
|
|
169
|
+
return {
|
|
170
|
+
content: [
|
|
171
|
+
{
|
|
172
|
+
type: 'text',
|
|
173
|
+
text: JSON.stringify({
|
|
174
|
+
behavior: 'deny',
|
|
175
|
+
message: `Security analysis failed: ${errorMessage}. Denying for safety.`,
|
|
176
|
+
}),
|
|
177
|
+
},
|
|
178
|
+
],
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
async function main() {
|
|
183
|
+
installRemoteDecisionCache();
|
|
184
|
+
const transport = new StdioServerTransport();
|
|
185
|
+
await server.connect(transport);
|
|
186
|
+
console.error('[MCP Bouncer] Server started and ready');
|
|
187
|
+
const swept = sweepClassifierTranscripts();
|
|
188
|
+
if (swept > 0)
|
|
189
|
+
console.error(`[MCP Bouncer] Swept ${swept} stale classifier transcript(s)`);
|
|
190
|
+
}
|
|
191
|
+
main().catch((error) => {
|
|
192
|
+
console.error('[MCP Bouncer] Fatal error:', error);
|
|
193
|
+
process.exit(1);
|
|
194
|
+
});
|