@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,374 @@
|
|
|
1
|
+
// Copyright (c) 2025-present Minionry, Inc.
|
|
2
|
+
// SPDX-License-Identifier: LicenseRef-Minionry-Software
|
|
3
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
4
|
+
import { ensureMachineDir, machineFile, machineLockPath } from '../../bin/machine-layout.js';
|
|
5
|
+
import { ENGINE_IDS, isEngineId } from '../engines/types.js';
|
|
6
|
+
import { withFileLock, writeFileAtomic } from '../utils/file-store.js';
|
|
7
|
+
import { getClientId } from './client-id.js';
|
|
8
|
+
function settingsFile() {
|
|
9
|
+
return machineFile('settings');
|
|
10
|
+
}
|
|
11
|
+
function settingsLock() {
|
|
12
|
+
return machineLockPath('settings');
|
|
13
|
+
}
|
|
14
|
+
export const BOUNCER_ELIGIBLE_MODELS = {
|
|
15
|
+
'claude-code': ['haiku', 'sonnet'],
|
|
16
|
+
codex: [],
|
|
17
|
+
hermes: [],
|
|
18
|
+
};
|
|
19
|
+
export const DEFAULT_BOUNCER_CLASSIFIER = {
|
|
20
|
+
engine: 'claude-code',
|
|
21
|
+
model: 'haiku',
|
|
22
|
+
};
|
|
23
|
+
export const DEFAULT_SHADOW_EVAL_CONFIG = {
|
|
24
|
+
enabled: false,
|
|
25
|
+
sampleRate: 0.1,
|
|
26
|
+
referenceModel: 'sonnet',
|
|
27
|
+
divergenceThreshold: 0.2,
|
|
28
|
+
maxSamplesPerRun: 50,
|
|
29
|
+
};
|
|
30
|
+
function clampUnitInterval(value, fallback) {
|
|
31
|
+
if (typeof value !== 'number' || !Number.isFinite(value))
|
|
32
|
+
return fallback;
|
|
33
|
+
if (value < 0)
|
|
34
|
+
return 0;
|
|
35
|
+
if (value > 1)
|
|
36
|
+
return 1;
|
|
37
|
+
return value;
|
|
38
|
+
}
|
|
39
|
+
export function normalizeShadowEvalConfig(config) {
|
|
40
|
+
if (config === null || typeof config !== 'object') {
|
|
41
|
+
return { ...DEFAULT_SHADOW_EVAL_CONFIG };
|
|
42
|
+
}
|
|
43
|
+
const c = config;
|
|
44
|
+
const referenceModel = typeof c.referenceModel === 'string' && c.referenceModel.trim().length > 0
|
|
45
|
+
? c.referenceModel.trim()
|
|
46
|
+
: DEFAULT_SHADOW_EVAL_CONFIG.referenceModel;
|
|
47
|
+
const maxSamplesPerRun = typeof c.maxSamplesPerRun === 'number' &&
|
|
48
|
+
Number.isFinite(c.maxSamplesPerRun) &&
|
|
49
|
+
c.maxSamplesPerRun > 0
|
|
50
|
+
? Math.floor(c.maxSamplesPerRun)
|
|
51
|
+
: DEFAULT_SHADOW_EVAL_CONFIG.maxSamplesPerRun;
|
|
52
|
+
return {
|
|
53
|
+
enabled: c.enabled === true,
|
|
54
|
+
sampleRate: clampUnitInterval(c.sampleRate, DEFAULT_SHADOW_EVAL_CONFIG.sampleRate),
|
|
55
|
+
referenceModel,
|
|
56
|
+
divergenceThreshold: clampUnitInterval(c.divergenceThreshold, DEFAULT_SHADOW_EVAL_CONFIG.divergenceThreshold),
|
|
57
|
+
maxSamplesPerRun,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
export function validateBouncerClassifier(config) {
|
|
61
|
+
if (config === null || typeof config !== 'object') {
|
|
62
|
+
throw new Error('bouncerClassifier must be an object with { engine, model }');
|
|
63
|
+
}
|
|
64
|
+
const { engine, model } = config;
|
|
65
|
+
if (!isEngineId(engine)) {
|
|
66
|
+
throw new Error(`bouncerClassifier.engine must be one of ${ENGINE_IDS.join(', ')} (got ${String(engine)})`);
|
|
67
|
+
}
|
|
68
|
+
if (typeof model !== 'string' || model.length === 0) {
|
|
69
|
+
throw new Error('bouncerClassifier.model must be a non-empty string');
|
|
70
|
+
}
|
|
71
|
+
const eligible = BOUNCER_ELIGIBLE_MODELS[engine];
|
|
72
|
+
if (!eligible.includes(model)) {
|
|
73
|
+
throw new Error(`Model '${model}' is not bouncer-eligible for engine '${engine}'. ` +
|
|
74
|
+
`Eligible models: ${eligible.join(', ')}. ` +
|
|
75
|
+
`Frontier models (Opus, GPT-4o, etc.) are deliberately excluded to keep the classifier fast.`);
|
|
76
|
+
}
|
|
77
|
+
return { engine, model };
|
|
78
|
+
}
|
|
79
|
+
export const DEFAULT_MAX_CONCURRENT_SESSIONS = 0;
|
|
80
|
+
const SETTINGS_SCHEMA_VERSION = 1;
|
|
81
|
+
const DEFAULT_SETTINGS = {
|
|
82
|
+
schemaVersion: SETTINGS_SCHEMA_VERSION,
|
|
83
|
+
model: 'opus',
|
|
84
|
+
effortLevel: 'auto',
|
|
85
|
+
fastMode: false,
|
|
86
|
+
subagentModel: 'auto',
|
|
87
|
+
subagentModelForce: false,
|
|
88
|
+
maxConcurrentSessions: DEFAULT_MAX_CONCURRENT_SESSIONS,
|
|
89
|
+
engine: 'claude-code',
|
|
90
|
+
qualityModel: 'default',
|
|
91
|
+
qualityEngine: 'claude-code',
|
|
92
|
+
qualityEffortLevel: 'auto',
|
|
93
|
+
qualityFastMode: false,
|
|
94
|
+
qualityAgentNotes: true,
|
|
95
|
+
bouncerClassifier: { ...DEFAULT_BOUNCER_CLASSIFIER },
|
|
96
|
+
bouncerClassifierOverrides: {},
|
|
97
|
+
shadowEval: { ...DEFAULT_SHADOW_EVAL_CONFIG },
|
|
98
|
+
maxUploadSizeMb: 0,
|
|
99
|
+
browser: { allowlist: [] },
|
|
100
|
+
};
|
|
101
|
+
function ensureMinionryDir() {
|
|
102
|
+
ensureMachineDir('config');
|
|
103
|
+
}
|
|
104
|
+
function migrateStoredSettings(stored) {
|
|
105
|
+
if (stored === null || typeof stored !== 'object' || Array.isArray(stored))
|
|
106
|
+
return {};
|
|
107
|
+
const doc = stored;
|
|
108
|
+
const version = typeof doc.schemaVersion === 'number' ? doc.schemaVersion : 0;
|
|
109
|
+
if (version >= SETTINGS_SCHEMA_VERSION)
|
|
110
|
+
return doc;
|
|
111
|
+
const migrated = { ...doc, schemaVersion: SETTINGS_SCHEMA_VERSION };
|
|
112
|
+
if (migrated.maxConcurrentSessions === 3) {
|
|
113
|
+
migrated.maxConcurrentSessions = DEFAULT_MAX_CONCURRENT_SESSIONS;
|
|
114
|
+
}
|
|
115
|
+
return migrated;
|
|
116
|
+
}
|
|
117
|
+
export function getSettings() {
|
|
118
|
+
const file = settingsFile();
|
|
119
|
+
if (!existsSync(file)) {
|
|
120
|
+
return { ...DEFAULT_SETTINGS };
|
|
121
|
+
}
|
|
122
|
+
try {
|
|
123
|
+
const content = readFileSync(file, 'utf-8');
|
|
124
|
+
const stored = migrateStoredSettings(JSON.parse(content));
|
|
125
|
+
const merged = {
|
|
126
|
+
...DEFAULT_SETTINGS,
|
|
127
|
+
...stored,
|
|
128
|
+
};
|
|
129
|
+
if (stored && typeof stored === 'object' && 'bouncerClassifier' in stored) {
|
|
130
|
+
try {
|
|
131
|
+
merged.bouncerClassifier = validateBouncerClassifier(stored.bouncerClassifier);
|
|
132
|
+
}
|
|
133
|
+
catch (err) {
|
|
134
|
+
console.warn('[settings] Stored bouncerClassifier is not bouncer-eligible, falling back to default:', err instanceof Error ? err.message : String(err));
|
|
135
|
+
merged.bouncerClassifier = { ...DEFAULT_BOUNCER_CLASSIFIER };
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
merged.maxConcurrentSessions = normalizeMaxConcurrentSessions(merged.maxConcurrentSessions);
|
|
139
|
+
return merged;
|
|
140
|
+
}
|
|
141
|
+
catch (err) {
|
|
142
|
+
console.warn('Failed to read settings file, using defaults:', err);
|
|
143
|
+
return { ...DEFAULT_SETTINGS };
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
function writeSettingsFile(settings) {
|
|
147
|
+
if (settings.bouncerClassifier !== undefined) {
|
|
148
|
+
validateBouncerClassifier(settings.bouncerClassifier);
|
|
149
|
+
}
|
|
150
|
+
ensureMinionryDir();
|
|
151
|
+
writeFileAtomic(settingsFile(), JSON.stringify(settings, null, 2), { mode: 0o600 });
|
|
152
|
+
}
|
|
153
|
+
function mutateSettings(apply) {
|
|
154
|
+
return withFileLock(settingsLock(), () => {
|
|
155
|
+
const settings = getSettings();
|
|
156
|
+
const result = apply(settings);
|
|
157
|
+
writeSettingsFile(settings);
|
|
158
|
+
return result;
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
export function getModel() {
|
|
162
|
+
return getSettings().model;
|
|
163
|
+
}
|
|
164
|
+
export function setModel(model) {
|
|
165
|
+
mutateSettings((settings) => {
|
|
166
|
+
settings.model = model;
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
export function resolveEnabledEngineId(value) {
|
|
170
|
+
return isEngineId(value) ? value : 'claude-code';
|
|
171
|
+
}
|
|
172
|
+
export function getEngine() {
|
|
173
|
+
return resolveEnabledEngineId(getSettings().engine);
|
|
174
|
+
}
|
|
175
|
+
export function setEngine(engine) {
|
|
176
|
+
mutateSettings((settings) => {
|
|
177
|
+
settings.engine = engine;
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
export function getEffortLevel() {
|
|
181
|
+
return getSettings().effortLevel;
|
|
182
|
+
}
|
|
183
|
+
export function setEffortLevel(effortLevel) {
|
|
184
|
+
mutateSettings((settings) => {
|
|
185
|
+
settings.effortLevel = effortLevel;
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
export function getFastMode() {
|
|
189
|
+
return getSettings().fastMode === true;
|
|
190
|
+
}
|
|
191
|
+
export function setFastMode(fastMode) {
|
|
192
|
+
mutateSettings((settings) => {
|
|
193
|
+
settings.fastMode = fastMode;
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
export function getSubagentModel() {
|
|
197
|
+
const value = getSettings().subagentModel;
|
|
198
|
+
return typeof value === 'string' && value.trim().length > 0 ? value.trim() : 'auto';
|
|
199
|
+
}
|
|
200
|
+
export function setSubagentModel(subagentModel) {
|
|
201
|
+
mutateSettings((settings) => {
|
|
202
|
+
settings.subagentModel = subagentModel.trim() || 'auto';
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
export function getSubagentModelForce() {
|
|
206
|
+
return getSettings().subagentModelForce === true;
|
|
207
|
+
}
|
|
208
|
+
export function setSubagentModelForce(force) {
|
|
209
|
+
mutateSettings((settings) => {
|
|
210
|
+
settings.subagentModelForce = force;
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
function normalizeMaxConcurrentSessions(value) {
|
|
214
|
+
return typeof value === 'number' && Number.isFinite(value) && value >= 0
|
|
215
|
+
? Math.floor(value)
|
|
216
|
+
: DEFAULT_MAX_CONCURRENT_SESSIONS;
|
|
217
|
+
}
|
|
218
|
+
export function getMaxConcurrentSessions() {
|
|
219
|
+
return normalizeMaxConcurrentSessions(getSettings().maxConcurrentSessions);
|
|
220
|
+
}
|
|
221
|
+
export function setMaxConcurrentSessions(max) {
|
|
222
|
+
mutateSettings((settings) => {
|
|
223
|
+
settings.maxConcurrentSessions = normalizeMaxConcurrentSessions(max);
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
export function getQualityModel() {
|
|
227
|
+
return getSettings().qualityModel ?? 'default';
|
|
228
|
+
}
|
|
229
|
+
export function setQualityModel(qualityModel) {
|
|
230
|
+
mutateSettings((settings) => {
|
|
231
|
+
settings.qualityModel = qualityModel;
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
export function getQualityEngine() {
|
|
235
|
+
const engine = getSettings().qualityEngine;
|
|
236
|
+
return isEngineId(engine) ? engine : 'claude-code';
|
|
237
|
+
}
|
|
238
|
+
export function setQualityEngine(qualityEngine) {
|
|
239
|
+
mutateSettings((settings) => {
|
|
240
|
+
settings.qualityEngine = qualityEngine;
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
export function getQualityEffortLevel() {
|
|
244
|
+
return getSettings().qualityEffortLevel ?? 'auto';
|
|
245
|
+
}
|
|
246
|
+
export function setQualityEffortLevel(qualityEffortLevel) {
|
|
247
|
+
mutateSettings((settings) => {
|
|
248
|
+
settings.qualityEffortLevel = qualityEffortLevel;
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
export function getQualityFastMode() {
|
|
252
|
+
return getSettings().qualityFastMode === true;
|
|
253
|
+
}
|
|
254
|
+
export function setQualityFastMode(qualityFastMode) {
|
|
255
|
+
mutateSettings((settings) => {
|
|
256
|
+
settings.qualityFastMode = qualityFastMode;
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
export function getQualityAgentNotes() {
|
|
260
|
+
return getSettings().qualityAgentNotes !== false;
|
|
261
|
+
}
|
|
262
|
+
export function setQualityAgentNotes(qualityAgentNotes) {
|
|
263
|
+
mutateSettings((settings) => {
|
|
264
|
+
settings.qualityAgentNotes = qualityAgentNotes;
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
export function updateQualitySettings(patch) {
|
|
268
|
+
const defined = Object.fromEntries(Object.entries(patch).filter(([, value]) => value !== undefined));
|
|
269
|
+
if (Object.keys(defined).length === 0)
|
|
270
|
+
return;
|
|
271
|
+
mutateSettings((settings) => {
|
|
272
|
+
Object.assign(settings, defined);
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
export function setMaxUploadSizeMb(maxUploadSizeMb) {
|
|
276
|
+
const safe = Number.isFinite(maxUploadSizeMb) && maxUploadSizeMb > 0 ? Math.floor(maxUploadSizeMb) : 0;
|
|
277
|
+
mutateSettings((settings) => {
|
|
278
|
+
settings.maxUploadSizeMb = safe;
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
export function getMaxUploadBytes() {
|
|
282
|
+
const mb = getSettings().maxUploadSizeMb;
|
|
283
|
+
return typeof mb === 'number' && Number.isFinite(mb) && mb > 0 ? Math.floor(mb) * 1024 * 1024 : 0;
|
|
284
|
+
}
|
|
285
|
+
export function uploadTooLargeMessage(bytes, limitBytes) {
|
|
286
|
+
const mb = (n) => (n / 1024 / 1024).toFixed(1).replace(/\.0$/, '');
|
|
287
|
+
return `File too large: ${mb(bytes)}MB exceeds the ${mb(limitBytes)}MB upload limit for this machine`;
|
|
288
|
+
}
|
|
289
|
+
export function getBouncerClassifier() {
|
|
290
|
+
const settings = getSettings();
|
|
291
|
+
if (settings.bouncerClassifier) {
|
|
292
|
+
try {
|
|
293
|
+
return validateBouncerClassifier(settings.bouncerClassifier);
|
|
294
|
+
}
|
|
295
|
+
catch {
|
|
296
|
+
return { ...DEFAULT_BOUNCER_CLASSIFIER };
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
return { ...DEFAULT_BOUNCER_CLASSIFIER };
|
|
300
|
+
}
|
|
301
|
+
export function setBouncerClassifier(config) {
|
|
302
|
+
const validated = validateBouncerClassifier(config);
|
|
303
|
+
return mutateSettings((settings) => {
|
|
304
|
+
settings.bouncerClassifier = validated;
|
|
305
|
+
return validated;
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
export function makeSpaceKey(clientId, workingDirectory) {
|
|
309
|
+
return `${clientId}:${workingDirectory}`;
|
|
310
|
+
}
|
|
311
|
+
export function getCurrentWorkingDirectory() {
|
|
312
|
+
return process.env.MINIONRY_WORKING_DIR || process.env.WORKING_DIR || process.cwd();
|
|
313
|
+
}
|
|
314
|
+
export function getCurrentSpaceIdentity() {
|
|
315
|
+
return { clientId: getClientId(), workingDirectory: getCurrentWorkingDirectory() };
|
|
316
|
+
}
|
|
317
|
+
export function getBouncerClassifierOverride(clientId, workingDirectory) {
|
|
318
|
+
const settings = getSettings();
|
|
319
|
+
const overrides = settings.bouncerClassifierOverrides;
|
|
320
|
+
if (!overrides || typeof overrides !== 'object')
|
|
321
|
+
return undefined;
|
|
322
|
+
return overrides[makeSpaceKey(clientId, workingDirectory)];
|
|
323
|
+
}
|
|
324
|
+
export function setBouncerClassifierOverride(clientId, workingDirectory, config) {
|
|
325
|
+
const validated = validateBouncerClassifier(config);
|
|
326
|
+
return mutateSettings((settings) => {
|
|
327
|
+
const overrides = { ...(settings.bouncerClassifierOverrides ?? {}) };
|
|
328
|
+
overrides[makeSpaceKey(clientId, workingDirectory)] = validated;
|
|
329
|
+
settings.bouncerClassifierOverrides = overrides;
|
|
330
|
+
return validated;
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
export function clearBouncerClassifierOverride(clientId, workingDirectory) {
|
|
334
|
+
mutateSettings((settings) => {
|
|
335
|
+
const overrides = { ...(settings.bouncerClassifierOverrides ?? {}) };
|
|
336
|
+
delete overrides[makeSpaceKey(clientId, workingDirectory)];
|
|
337
|
+
settings.bouncerClassifierOverrides = overrides;
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
export function getShadowEvalConfig() {
|
|
341
|
+
return normalizeShadowEvalConfig(getSettings().shadowEval);
|
|
342
|
+
}
|
|
343
|
+
export function setShadowEvalConfig(config) {
|
|
344
|
+
const normalized = normalizeShadowEvalConfig(config);
|
|
345
|
+
return mutateSettings((settings) => {
|
|
346
|
+
settings.shadowEval = normalized;
|
|
347
|
+
return normalized;
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
export function getBrowserAllowlist() {
|
|
351
|
+
const settings = getSettings();
|
|
352
|
+
const list = settings.browser?.allowlist;
|
|
353
|
+
if (!Array.isArray(list))
|
|
354
|
+
return [];
|
|
355
|
+
return list.filter((entry) => typeof entry === 'string' && entry.trim().length > 0);
|
|
356
|
+
}
|
|
357
|
+
function normalizeRemoteUrl(remoteUrl) {
|
|
358
|
+
return remoteUrl
|
|
359
|
+
.replace(/^(https?:\/\/|git@)/, '')
|
|
360
|
+
.replace(/\.git$/, '')
|
|
361
|
+
.replace(/:/, '/');
|
|
362
|
+
}
|
|
363
|
+
export function getPrBaseBranch(remoteUrl) {
|
|
364
|
+
const settings = getSettings();
|
|
365
|
+
const key = normalizeRemoteUrl(remoteUrl);
|
|
366
|
+
return settings.prBaseBranches?.[key] ?? null;
|
|
367
|
+
}
|
|
368
|
+
export function setPrBaseBranch(remoteUrl, branch) {
|
|
369
|
+
mutateSettings((settings) => {
|
|
370
|
+
if (!settings.prBaseBranches)
|
|
371
|
+
settings.prBaseBranches = {};
|
|
372
|
+
settings.prBaseBranches[normalizeRemoteUrl(remoteUrl)] = branch;
|
|
373
|
+
});
|
|
374
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
// Copyright (c) 2025-present Minionry, Inc.
|
|
2
|
+
// SPDX-License-Identifier: LicenseRef-Minionry-Software
|
|
3
|
+
import { findSnippetTokens } from './parser.js';
|
|
4
|
+
export const MAX_DEPTH = 15;
|
|
5
|
+
export const MAX_EXPANSIONS = 200;
|
|
6
|
+
export function createExpander(resolver) {
|
|
7
|
+
return {
|
|
8
|
+
expand(text) {
|
|
9
|
+
const state = {
|
|
10
|
+
resolver,
|
|
11
|
+
diagnostics: [],
|
|
12
|
+
expanded: new Set(),
|
|
13
|
+
substitutionCount: 0,
|
|
14
|
+
fanoutHit: false,
|
|
15
|
+
};
|
|
16
|
+
const result = expandRecursive(text, new Set(), 0, state);
|
|
17
|
+
return {
|
|
18
|
+
text: result,
|
|
19
|
+
expanded: Array.from(state.expanded),
|
|
20
|
+
diagnostics: state.diagnostics,
|
|
21
|
+
};
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
function expandRecursive(text, visited, depth, state) {
|
|
26
|
+
if (state.fanoutHit)
|
|
27
|
+
return text;
|
|
28
|
+
const tokens = findSnippetTokens(text);
|
|
29
|
+
if (tokens.length === 0)
|
|
30
|
+
return text;
|
|
31
|
+
if (depth >= MAX_DEPTH) {
|
|
32
|
+
state.diagnostics.push({
|
|
33
|
+
kind: 'depth-exceeded',
|
|
34
|
+
name: tokens[0].name,
|
|
35
|
+
chain: Array.from(visited),
|
|
36
|
+
});
|
|
37
|
+
return text;
|
|
38
|
+
}
|
|
39
|
+
return rebuildWithSubstitutions(text, tokens, visited, depth, state);
|
|
40
|
+
}
|
|
41
|
+
function rebuildWithSubstitutions(text, tokens, visited, depth, state) {
|
|
42
|
+
let out = '';
|
|
43
|
+
let cursor = 0;
|
|
44
|
+
for (const token of tokens) {
|
|
45
|
+
out += text.slice(cursor, token.start);
|
|
46
|
+
out += resolveOne(token, visited, depth, state);
|
|
47
|
+
cursor = token.end;
|
|
48
|
+
if (state.fanoutHit) {
|
|
49
|
+
out += text.slice(cursor);
|
|
50
|
+
return out;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
out += text.slice(cursor);
|
|
54
|
+
return out;
|
|
55
|
+
}
|
|
56
|
+
function resolveOne(token, visited, depth, state) {
|
|
57
|
+
const original = `#${token.name}`;
|
|
58
|
+
const snippet = state.resolver.resolve(token.name);
|
|
59
|
+
if (!snippet) {
|
|
60
|
+
state.diagnostics.push({ kind: 'missing', name: token.name });
|
|
61
|
+
return original;
|
|
62
|
+
}
|
|
63
|
+
if (visited.has(snippet.name)) {
|
|
64
|
+
state.diagnostics.push({
|
|
65
|
+
kind: 'cycle',
|
|
66
|
+
name: snippet.name,
|
|
67
|
+
chain: [...visited, snippet.name],
|
|
68
|
+
});
|
|
69
|
+
return original;
|
|
70
|
+
}
|
|
71
|
+
state.substitutionCount += 1;
|
|
72
|
+
if (state.substitutionCount > MAX_EXPANSIONS) {
|
|
73
|
+
if (!state.fanoutHit) {
|
|
74
|
+
state.fanoutHit = true;
|
|
75
|
+
state.diagnostics.push({
|
|
76
|
+
kind: 'depth-exceeded',
|
|
77
|
+
name: snippet.name,
|
|
78
|
+
chain: [...visited, snippet.name],
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
return original;
|
|
82
|
+
}
|
|
83
|
+
state.expanded.add(snippet.name);
|
|
84
|
+
const childVisited = new Set(visited);
|
|
85
|
+
childVisited.add(snippet.name);
|
|
86
|
+
return expandRecursive(snippet.body, childVisited, depth + 1, state);
|
|
87
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// Copyright (c) 2025-present Minionry, Inc.
|
|
2
|
+
// SPDX-License-Identifier: LicenseRef-Minionry-Software
|
|
3
|
+
export { createExpander, MAX_DEPTH } from './expander.js';
|
|
4
|
+
export { defaultSnippetSources, SnippetRegistry } from './loader.js';
|
|
5
|
+
export { findSnippetTokens } from './parser.js';
|
|
6
|
+
export { SnippetWatcher } from './watcher.js';
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
// Copyright (c) 2025-present Minionry, Inc.
|
|
2
|
+
// SPDX-License-Identifier: LicenseRef-Minionry-Software
|
|
3
|
+
import { existsSync, readdirSync, readFileSync } from 'node:fs';
|
|
4
|
+
import { basename, extname, join } from 'node:path';
|
|
5
|
+
import { machinePath } from '../../../bin/machine-layout.js';
|
|
6
|
+
import { parseFrontMatter } from '../plan/parser-core.js';
|
|
7
|
+
import { spacePath } from '../space-layout.js';
|
|
8
|
+
const VALID_NAME_RE = /^[a-z][a-z0-9-]*$/;
|
|
9
|
+
const MAX_DESCRIPTION_CHARS = 500;
|
|
10
|
+
function sanitizeName(raw) {
|
|
11
|
+
const cleaned = raw.toLowerCase().trim();
|
|
12
|
+
return VALID_NAME_RE.test(cleaned) ? cleaned : null;
|
|
13
|
+
}
|
|
14
|
+
function extractAliases(value) {
|
|
15
|
+
const collect = (entries) => entries.flatMap((entry) => {
|
|
16
|
+
if (typeof entry !== 'string')
|
|
17
|
+
return [];
|
|
18
|
+
const cleaned = sanitizeName(entry);
|
|
19
|
+
return cleaned ? [cleaned] : [];
|
|
20
|
+
});
|
|
21
|
+
if (Array.isArray(value))
|
|
22
|
+
return collect(value);
|
|
23
|
+
if (typeof value === 'string') {
|
|
24
|
+
const cleaned = sanitizeName(value);
|
|
25
|
+
return cleaned ? [cleaned] : [];
|
|
26
|
+
}
|
|
27
|
+
return [];
|
|
28
|
+
}
|
|
29
|
+
function loadSnippetsFromDir(source) {
|
|
30
|
+
if (!existsSync(source.dir))
|
|
31
|
+
return [];
|
|
32
|
+
const snippets = [];
|
|
33
|
+
let entries;
|
|
34
|
+
try {
|
|
35
|
+
entries = readdirSync(source.dir, { withFileTypes: true });
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
return [];
|
|
39
|
+
}
|
|
40
|
+
for (const entry of entries) {
|
|
41
|
+
if (!entry.isFile() || !entry.name.endsWith('.md'))
|
|
42
|
+
continue;
|
|
43
|
+
const filePath = join(source.dir, entry.name);
|
|
44
|
+
let raw;
|
|
45
|
+
try {
|
|
46
|
+
raw = readFileSync(filePath, 'utf-8');
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
const { frontMatter, body } = parseFrontMatter(raw);
|
|
52
|
+
const name = sanitizeName(basename(entry.name, extname(entry.name)));
|
|
53
|
+
if (!name)
|
|
54
|
+
continue;
|
|
55
|
+
const aliases = extractAliases(frontMatter.aliases);
|
|
56
|
+
const description = typeof frontMatter.description === 'string'
|
|
57
|
+
? frontMatter.description.slice(0, MAX_DESCRIPTION_CHARS)
|
|
58
|
+
: '';
|
|
59
|
+
snippets.push({
|
|
60
|
+
name,
|
|
61
|
+
aliases,
|
|
62
|
+
description,
|
|
63
|
+
body: body.trim(),
|
|
64
|
+
sourcePath: filePath,
|
|
65
|
+
origin: source.origin,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
return snippets;
|
|
69
|
+
}
|
|
70
|
+
export class SnippetRegistry {
|
|
71
|
+
sources;
|
|
72
|
+
byName = new Map();
|
|
73
|
+
all = [];
|
|
74
|
+
constructor(sources) {
|
|
75
|
+
this.sources = sources;
|
|
76
|
+
this.reload();
|
|
77
|
+
}
|
|
78
|
+
reload() {
|
|
79
|
+
const orderedSources = sortByPriority(this.sources);
|
|
80
|
+
const byName = new Map();
|
|
81
|
+
const canonical = new Map();
|
|
82
|
+
let anyDirReadable = false;
|
|
83
|
+
for (const source of orderedSources) {
|
|
84
|
+
const loaded = loadSnippetsFromDir(source);
|
|
85
|
+
if (loaded.length > 0)
|
|
86
|
+
anyDirReadable = true;
|
|
87
|
+
for (const snippet of loaded) {
|
|
88
|
+
canonical.set(snippet.name, snippet);
|
|
89
|
+
byName.set(snippet.name, snippet);
|
|
90
|
+
for (const alias of snippet.aliases) {
|
|
91
|
+
byName.set(alias, snippet);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
if (this.all.length > 0 && canonical.size === 0 && !anyDirReadable)
|
|
96
|
+
return;
|
|
97
|
+
this.byName = byName;
|
|
98
|
+
this.all = Array.from(canonical.values()).sort((a, b) => a.name.localeCompare(b.name));
|
|
99
|
+
}
|
|
100
|
+
resolve(name) {
|
|
101
|
+
return this.byName.get(name) ?? null;
|
|
102
|
+
}
|
|
103
|
+
list() {
|
|
104
|
+
return this.all;
|
|
105
|
+
}
|
|
106
|
+
sourceDir(origin) {
|
|
107
|
+
return this.sources.find((s) => s.origin === origin)?.dir ?? null;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
function sortByPriority(sources) {
|
|
111
|
+
const rank = { personal: 0, project: 1 };
|
|
112
|
+
return [...sources].sort((a, b) => rank[a.origin] - rank[b.origin]);
|
|
113
|
+
}
|
|
114
|
+
export function defaultSnippetSources(workingDir) {
|
|
115
|
+
return [
|
|
116
|
+
{ dir: spacePath(workingDir, 'snippets'), origin: 'project' },
|
|
117
|
+
{ dir: machinePath('snippets'), origin: 'personal' },
|
|
118
|
+
];
|
|
119
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// Copyright (c) 2025-present Minionry, Inc.
|
|
2
|
+
// SPDX-License-Identifier: LicenseRef-Minionry-Software
|
|
3
|
+
const FENCED_RE = /```[\s\S]*?```/g;
|
|
4
|
+
const INLINE_CODE_RE = /`[^`\n]*`/g;
|
|
5
|
+
function collectRanges(text, regex) {
|
|
6
|
+
const ranges = [];
|
|
7
|
+
regex.lastIndex = 0;
|
|
8
|
+
let match;
|
|
9
|
+
while ((match = regex.exec(text)) !== null) {
|
|
10
|
+
ranges.push({ start: match.index, end: match.index + match[0].length });
|
|
11
|
+
}
|
|
12
|
+
return ranges;
|
|
13
|
+
}
|
|
14
|
+
function isInside(pos, ranges) {
|
|
15
|
+
for (const r of ranges) {
|
|
16
|
+
if (pos >= r.start && pos < r.end)
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
function isWordChar(ch) {
|
|
22
|
+
return ch !== undefined && /[A-Za-z0-9_]/.test(ch);
|
|
23
|
+
}
|
|
24
|
+
function looksLikeUrlFragment(text, hashPos) {
|
|
25
|
+
let i = hashPos - 1;
|
|
26
|
+
while (i >= 0 && !/\s/.test(text[i]))
|
|
27
|
+
i--;
|
|
28
|
+
const segment = text.slice(i + 1, hashPos);
|
|
29
|
+
return segment.includes('://');
|
|
30
|
+
}
|
|
31
|
+
export function findSnippetTokens(text) {
|
|
32
|
+
if (!text.includes('#'))
|
|
33
|
+
return [];
|
|
34
|
+
const skipRegions = [
|
|
35
|
+
...collectRanges(text, FENCED_RE),
|
|
36
|
+
...collectRanges(text, INLINE_CODE_RE),
|
|
37
|
+
];
|
|
38
|
+
const snippetNameRe = /#([a-z][a-z0-9-]*)/g;
|
|
39
|
+
const tokens = [];
|
|
40
|
+
let match;
|
|
41
|
+
while ((match = snippetNameRe.exec(text)) !== null) {
|
|
42
|
+
const start = match.index;
|
|
43
|
+
if (isInside(start, skipRegions))
|
|
44
|
+
continue;
|
|
45
|
+
if (looksLikeUrlFragment(text, start))
|
|
46
|
+
continue;
|
|
47
|
+
if (start > 0 && isWordChar(text[start - 1]))
|
|
48
|
+
continue;
|
|
49
|
+
tokens.push({ name: match[1], start, end: start + match[0].length });
|
|
50
|
+
}
|
|
51
|
+
return tokens;
|
|
52
|
+
}
|