@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
package/bin/minion.js
ADDED
|
@@ -0,0 +1,839 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Copyright (c) 2025-present Minionry, Inc.
|
|
3
|
+
// SPDX-License-Identifier: LicenseRef-Minionry-Software
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
import { spawn } from 'node:child_process';
|
|
7
|
+
import { closeSync, existsSync, mkdirSync, openSync, readFileSync, writeFileSync } from 'node:fs';
|
|
8
|
+
import { homedir } from 'node:os';
|
|
9
|
+
import { dirname, join, resolve } from 'node:path';
|
|
10
|
+
import { createInterface } from 'node:readline';
|
|
11
|
+
import { fileURLToPath } from 'node:url';
|
|
12
|
+
import { APP_NAME } from './branding.js';
|
|
13
|
+
import { launchFlagSuffix, resolveLaunchTargets } from './launch-env.js';
|
|
14
|
+
import { ensureMachineDir, machineFile, machinePath } from './machine-layout.js';
|
|
15
|
+
import { describeSource, loadNodePty, nativeRoot, prebuiltPlatformDir } from './pty-locator.js';
|
|
16
|
+
import { normalizeNodePtyTree, provisionNodePty } from './pty-provision.js';
|
|
17
|
+
|
|
18
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
19
|
+
const __dirname = dirname(__filename);
|
|
20
|
+
const CLIENT_ROOT = resolve(__dirname, '..');
|
|
21
|
+
|
|
22
|
+
const pkg = JSON.parse(readFileSync(join(CLIENT_ROOT, 'package.json'), 'utf-8'));
|
|
23
|
+
|
|
24
|
+
const UPDATE_CHECK_INTERVAL = 1000 * 60 * 60;
|
|
25
|
+
const REGISTRY_URL = (pkg.publishConfig?.registry ?? 'https://registry.npmjs.org').replace(/\/+$/, '');
|
|
26
|
+
const REGISTRY_FLAG = `--${pkg.name.split('/')[0]}:registry=${REGISTRY_URL}/`;
|
|
27
|
+
const manualUpdateCommand = () => `npm i -g ${pkg.name}@latest ${REGISTRY_FLAG}`;
|
|
28
|
+
|
|
29
|
+
const USER_CWD = process.cwd();
|
|
30
|
+
|
|
31
|
+
function setTerminalTitle(directory) {
|
|
32
|
+
if (!process.stdout.isTTY) return;
|
|
33
|
+
const dirName = directory.split('/').pop() || directory;
|
|
34
|
+
const title = `minion: ${dirName}`;
|
|
35
|
+
process.stdout.write(`\x1b]0;${title}\x07`);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
setTerminalTitle(process.cwd());
|
|
39
|
+
|
|
40
|
+
const colors = {
|
|
41
|
+
reset: '\x1b[0m',
|
|
42
|
+
bold: '\x1b[1m',
|
|
43
|
+
green: '\x1b[32m',
|
|
44
|
+
yellow: '\x1b[33m',
|
|
45
|
+
blue: '\x1b[34m',
|
|
46
|
+
red: '\x1b[31m',
|
|
47
|
+
dim: '\x1b[2m',
|
|
48
|
+
cyan: '\x1b[36m',
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
function log(msg, color = '') {
|
|
52
|
+
console.log(`${color}${msg}${colors.reset}`);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
async function isNodePtyAvailable() {
|
|
56
|
+
return loadNodePty().ok;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function hasUserDismissedPtySetup() {
|
|
60
|
+
return existsSync(machineFile('ptySetupDismissed'));
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function showPtyWarning() {
|
|
64
|
+
log(' Terminal support not available. Run: minion install terminal', colors.dim);
|
|
65
|
+
log(' (already tried? "minion doctor terminal" reports the actual reason)', colors.dim);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function reportPtyFailure(diagnosis, attempts, logPath) {
|
|
69
|
+
const tail = (attempts.at(-1)?.output ?? '')
|
|
70
|
+
.split('\n')
|
|
71
|
+
.filter((line) => line.trim())
|
|
72
|
+
.slice(-12);
|
|
73
|
+
if (tail.length > 0) {
|
|
74
|
+
log('\n Build output:', colors.bold);
|
|
75
|
+
for (const line of tail) log(` ${line}`, colors.dim);
|
|
76
|
+
log('');
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
log(` ${diagnosis.title}`, colors.red);
|
|
80
|
+
log(` ${colors.dim}(${diagnosis.code})${colors.reset}\n`);
|
|
81
|
+
for (const line of diagnosis.remedies) log(` ${line}`, colors.dim);
|
|
82
|
+
log('');
|
|
83
|
+
if (logPath) log(` Full build log: ${logPath}`, colors.dim);
|
|
84
|
+
log(' Diagnose again any time: minion doctor terminal\n', colors.dim);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
async function runPtySetup() {
|
|
88
|
+
const { probeToolchain, toolchainReady, classifyPtyFailure, writeInstallLog } = await import('./pty-doctor.js');
|
|
89
|
+
const probe = probeToolchain();
|
|
90
|
+
const loadErrors = loadNodePty().errors ?? [];
|
|
91
|
+
|
|
92
|
+
if (!toolchainReady(probe).ready) {
|
|
93
|
+
reportPtyFailure(classifyPtyFailure({ attempts: [], loadErrors, probe }), [], null);
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
log('\n The prebuilt terminal binary did not load on this machine — compiling node-pty instead.', colors.dim);
|
|
98
|
+
log(` Target: ${probe.node.version} (${process.platform}-${process.arch}) → ${nativeRoot()}\n`, colors.dim);
|
|
99
|
+
|
|
100
|
+
const result = await provisionNodePty({
|
|
101
|
+
probe,
|
|
102
|
+
onProgress: (label) => log(` → ${label}`, colors.dim),
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
if (result.ok) {
|
|
106
|
+
log('\n Terminal support enabled successfully!\n', colors.bold + colors.green);
|
|
107
|
+
return true;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const afterErrors = loadNodePty().errors ?? [];
|
|
111
|
+
const diagnosis = classifyPtyFailure({ attempts: result.attempts, loadErrors: afterErrors, probe });
|
|
112
|
+
reportPtyFailure(diagnosis, result.attempts, writeInstallLog(result.attempts, afterErrors));
|
|
113
|
+
return false;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
async function doctorTerminal() {
|
|
117
|
+
const { probeToolchain, renderProbe } = await import('./pty-doctor.js');
|
|
118
|
+
log(`\n ${APP_NAME} Terminal Doctor\n`, colors.bold + colors.cyan);
|
|
119
|
+
|
|
120
|
+
const loaded = loadNodePty();
|
|
121
|
+
if (loaded.ok) {
|
|
122
|
+
log(` Terminal: ready ${colors.dim}(${describeSource(loaded.source)})${colors.reset}`, colors.green);
|
|
123
|
+
log(` ${colors.dim}${loaded.path}${colors.reset}\n`);
|
|
124
|
+
} else {
|
|
125
|
+
log(' Terminal: not available\n', colors.yellow);
|
|
126
|
+
for (const error of loaded.errors) {
|
|
127
|
+
log(` ${error.source} — ${describeSource(error.source)}`, colors.dim);
|
|
128
|
+
log(` ${error.code}: ${error.message.split('\n')[0]}`, colors.dim);
|
|
129
|
+
}
|
|
130
|
+
log('');
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
for (const line of renderProbe(probeToolchain())) log(` ${line}`, colors.dim);
|
|
134
|
+
log('');
|
|
135
|
+
if (!loaded.ok) log(' Run: minion install terminal\n', colors.cyan);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
async function doctorBrowser() {
|
|
139
|
+
log(`\n ${APP_NAME} Browser Doctor\n`, colors.bold + colors.cyan);
|
|
140
|
+
|
|
141
|
+
const { loadPreflight, renderChecks } = await import('./commands/browser-install.js');
|
|
142
|
+
let preflightMod;
|
|
143
|
+
try {
|
|
144
|
+
preflightMod = await loadPreflight();
|
|
145
|
+
} catch (err) {
|
|
146
|
+
log(` Could not load preflight: ${err.message}`, colors.red);
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
const result = await preflightMod.preflight();
|
|
151
|
+
renderChecks(result.checks);
|
|
152
|
+
log('');
|
|
153
|
+
if (!result.ok) log(' Run: minion install browser\n', colors.cyan);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function getAliveInstances() {
|
|
157
|
+
const instancesPath = machineFile('instances');
|
|
158
|
+
const tokenPath = machineFile('sessionToken');
|
|
159
|
+
|
|
160
|
+
if (!existsSync(instancesPath) || !existsSync(tokenPath)) return null;
|
|
161
|
+
|
|
162
|
+
try {
|
|
163
|
+
const instances = JSON.parse(readFileSync(instancesPath, 'utf-8'));
|
|
164
|
+
const token = readFileSync(tokenPath, 'utf-8').trim();
|
|
165
|
+
if (!Array.isArray(instances) || !token) return null;
|
|
166
|
+
|
|
167
|
+
const now = Date.now();
|
|
168
|
+
const alive = instances.filter(i => now - i.lastHeartbeat < 2 * 60 * 1000);
|
|
169
|
+
return alive.length > 0 ? { alive, token } : null;
|
|
170
|
+
} catch {
|
|
171
|
+
return null;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
async function notifyRunningServers() {
|
|
176
|
+
const result = getAliveInstances();
|
|
177
|
+
if (!result) {
|
|
178
|
+
log(' Restart minion to enable terminal support.\n', colors.dim);
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
let reloaded = 0;
|
|
183
|
+
for (const instance of result.alive) {
|
|
184
|
+
try {
|
|
185
|
+
const res = await fetch(`http://localhost:${instance.port}/api/reload-pty`, {
|
|
186
|
+
method: 'POST',
|
|
187
|
+
headers: { 'x-session-token': result.token },
|
|
188
|
+
});
|
|
189
|
+
if (res.ok) {
|
|
190
|
+
const data = await res.json();
|
|
191
|
+
if (data.success) reloaded++;
|
|
192
|
+
}
|
|
193
|
+
} catch {
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
if (reloaded > 0) {
|
|
198
|
+
log(` Notified ${reloaded} running minion server${reloaded > 1 ? 's' : ''} — terminal is ready!\n`, colors.green);
|
|
199
|
+
} else {
|
|
200
|
+
log(' Restart minion to enable terminal support.\n', colors.dim);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
function confirm(question) {
|
|
205
|
+
return new Promise((resolveAnswer) => {
|
|
206
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
207
|
+
let answered = false;
|
|
208
|
+
rl.on('SIGINT', () => {
|
|
209
|
+
rl.close();
|
|
210
|
+
process.stdout.write('\n');
|
|
211
|
+
process.exit(130);
|
|
212
|
+
});
|
|
213
|
+
rl.on('close', () => {
|
|
214
|
+
if (!answered) resolveAnswer(false);
|
|
215
|
+
});
|
|
216
|
+
rl.question(`${question} ${colors.dim}[Y/n]${colors.reset} `, (answer) => {
|
|
217
|
+
answered = true;
|
|
218
|
+
rl.close();
|
|
219
|
+
resolveAnswer(!/^n/i.test(answer.trim()));
|
|
220
|
+
});
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
async function offerTerminalSetup(interactive) {
|
|
225
|
+
const loaded = loadNodePty();
|
|
226
|
+
if (loaded.ok) {
|
|
227
|
+
log(` Terminal: ready (${describeSource(loaded.source)})`, colors.dim);
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
if (!interactive) {
|
|
231
|
+
log(' Terminal: not set up. Run "minion install terminal" to enable the web terminal.', colors.dim);
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
log(' Terminal: not set up (the web terminal needs a one-time native module build).', colors.yellow);
|
|
235
|
+
if (await confirm(' Set up the terminal now?')) {
|
|
236
|
+
const success = await runPtySetup();
|
|
237
|
+
if (success) await notifyRunningServers();
|
|
238
|
+
} else {
|
|
239
|
+
log(' Skipped. Run "minion install terminal" any time.\n', colors.dim);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
async function offerBrowserSetup(interactive) {
|
|
244
|
+
let browserPreflight = null;
|
|
245
|
+
try {
|
|
246
|
+
const { loadPreflight } = await import('./commands/browser-install.js');
|
|
247
|
+
const preflightMod = await loadPreflight();
|
|
248
|
+
browserPreflight = await preflightMod.preflight();
|
|
249
|
+
} catch {
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
if (browserPreflight.ok) {
|
|
254
|
+
log(' Browser: ready', colors.dim);
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
const missing = browserPreflight.checks
|
|
259
|
+
.filter((c) => !c.ok && !c.advisory)
|
|
260
|
+
.map((c) => c.label);
|
|
261
|
+
if (!interactive) {
|
|
262
|
+
log(` Browser: missing ${missing.join(', ')}. Run "minion install browser".`, colors.dim);
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
log(` Browser: missing ${missing.join(', ')}.`, colors.yellow);
|
|
267
|
+
if (await confirm(' Install browser dependencies now?')) {
|
|
268
|
+
const { browserInstall } = await import('./commands/browser-install.js');
|
|
269
|
+
await browserInstall([], { exit: false });
|
|
270
|
+
} else {
|
|
271
|
+
log(' Skipped. Run "minion install browser" any time.\n', colors.dim);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
async function runPostLoginSetup() {
|
|
276
|
+
const interactive = process.stdin.isTTY && process.stdout.isTTY;
|
|
277
|
+
await offerTerminalSetup(interactive);
|
|
278
|
+
await offerBrowserSetup(interactive);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
async function installTerminal() {
|
|
282
|
+
log(`\n ${APP_NAME} Terminal Setup\n`, colors.bold + colors.cyan);
|
|
283
|
+
const loaded = loadNodePty();
|
|
284
|
+
if (loaded.ok) {
|
|
285
|
+
log(` Terminal support is already enabled — ${describeSource(loaded.source)}.`, colors.green);
|
|
286
|
+
log(` ${colors.dim}${loaded.path}${colors.reset}\n`);
|
|
287
|
+
await notifyRunningServers();
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
const success = await runPtySetup();
|
|
291
|
+
if (success) {
|
|
292
|
+
await notifyRunningServers();
|
|
293
|
+
}
|
|
294
|
+
process.exit(success ? 0 : 1);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
function showHelp() {
|
|
298
|
+
log(`\n ${APP_NAME} CLI\n`, colors.bold + colors.cyan);
|
|
299
|
+
log(' Connects this machine to app.minionry.com.\n', colors.dim);
|
|
300
|
+
log(' Usage:', colors.bold);
|
|
301
|
+
log(` minion Start ${APP_NAME} in the background (logs in automatically if needed)`, colors.dim);
|
|
302
|
+
log(' minion login Re-authenticate this device with minionry.com', colors.dim);
|
|
303
|
+
log(' minion logout Sign out of minionry.com', colors.dim);
|
|
304
|
+
log(' minion whoami Show current user and device info', colors.dim);
|
|
305
|
+
log(' minion status Show connection and auth status', colors.dim);
|
|
306
|
+
log(' minion list minions List the minion servers running on this machine', colors.dim);
|
|
307
|
+
log(' minion shutdown <pid> Stop one minion server on this machine', colors.dim);
|
|
308
|
+
log(' minion shutdown all Stop every minion server on this machine', colors.dim);
|
|
309
|
+
log(' minion fingerprint [key] Show the safety number to verify encryption', colors.dim);
|
|
310
|
+
log(' minion create sandbox Create an isolated sandbox to make Spaces in', colors.dim);
|
|
311
|
+
log(' minion list sandboxes List this machine\'s sandboxes and what they cap', colors.dim);
|
|
312
|
+
log(' minion rename sandbox <old> <new>', colors.dim);
|
|
313
|
+
log(' Rename a sandbox, keeping its disk', colors.dim);
|
|
314
|
+
log(' minion restart sandbox <name>', colors.dim);
|
|
315
|
+
log(' Restart a sandbox (also starts a stopped one);', colors.dim);
|
|
316
|
+
log(' --uncap lifts its memory cap, replacing the container', colors.dim);
|
|
317
|
+
log(' minion install browser Install in-app browser dependencies for your platform', colors.dim);
|
|
318
|
+
log(' minion doctor Report why the terminal or in-app browser is unavailable', colors.dim);
|
|
319
|
+
log(` minion update Update ${APP_NAME} to the latest version`, colors.dim);
|
|
320
|
+
log('');
|
|
321
|
+
log(' Options:', colors.bold);
|
|
322
|
+
log(' --port, -p <port> Override automatic port selection', colors.dim);
|
|
323
|
+
log(' --foreground Run attached to the terminal instead of in the background', colors.dim);
|
|
324
|
+
log(' --version, -V Show version number', colors.dim);
|
|
325
|
+
log(' --help, -h Show this help message', colors.dim);
|
|
326
|
+
log('');
|
|
327
|
+
log(' Authentication:', colors.bold);
|
|
328
|
+
log(' Running "minion" will prompt you to log in automatically if needed.', colors.dim);
|
|
329
|
+
log(' Once logged in, this machine and its Spaces appear at app.minionry.com.', colors.dim);
|
|
330
|
+
log('');
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
function resolveStartScript() {
|
|
334
|
+
if (existsSync(join(CLIENT_ROOT, 'dist', 'server', 'index.js'))) return 'start';
|
|
335
|
+
log(' No build found — starting from TypeScript sources. Run "npm run build" for the production entry.', colors.dim);
|
|
336
|
+
return 'dev';
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
function runNpmScriptDetached(script, args = [], envOverrides = {}) {
|
|
340
|
+
const logDir = machinePath('logs');
|
|
341
|
+
if (!existsSync(logDir)) mkdirSync(logDir, { recursive: true });
|
|
342
|
+
const logPath = join(logDir, `minionry-${new Date().toISOString().replace(/[:.]/g, '-')}.log`);
|
|
343
|
+
const logFd = openSync(logPath, 'a');
|
|
344
|
+
|
|
345
|
+
const npmCmd = process.platform === 'win32' ? 'npm.cmd' : 'npm';
|
|
346
|
+
const child = spawn(npmCmd, ['run', '--silent', script, ...args], {
|
|
347
|
+
cwd: CLIENT_ROOT,
|
|
348
|
+
stdio: ['ignore', logFd, logFd],
|
|
349
|
+
env: { ...process.env, MINIONRY_WORKING_DIR: USER_CWD, ...envOverrides },
|
|
350
|
+
detached: true,
|
|
351
|
+
...(process.platform === 'win32' ? { windowsHide: true } : {}),
|
|
352
|
+
});
|
|
353
|
+
|
|
354
|
+
child.on('error', (err) => {
|
|
355
|
+
log(`Error: ${err.message}`, colors.red);
|
|
356
|
+
closeSync(logFd);
|
|
357
|
+
process.exit(1);
|
|
358
|
+
});
|
|
359
|
+
|
|
360
|
+
child.unref();
|
|
361
|
+
closeSync(logFd);
|
|
362
|
+
|
|
363
|
+
log(`\n ${APP_NAME} started in background`, colors.bold + colors.green);
|
|
364
|
+
log(` Stop: kill ${child.pid}`, colors.dim);
|
|
365
|
+
log(' Status: minion status', colors.dim);
|
|
366
|
+
log(` Remote control: ${envOverrides.APP_ORIGIN || 'https://app.minionry.com'}\n`, colors.dim);
|
|
367
|
+
process.exit(0);
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
function runNpmScript(script, args = [], envOverrides = {}) {
|
|
371
|
+
const npmCmd = process.platform === 'win32' ? 'npm.cmd' : 'npm';
|
|
372
|
+
const child = spawn(npmCmd, ['run', '--silent', script, ...args], {
|
|
373
|
+
cwd: CLIENT_ROOT,
|
|
374
|
+
stdio: 'inherit',
|
|
375
|
+
env: { ...process.env, MINIONRY_WORKING_DIR: USER_CWD, ...envOverrides },
|
|
376
|
+
});
|
|
377
|
+
|
|
378
|
+
let isShuttingDown = false;
|
|
379
|
+
|
|
380
|
+
process.on('SIGINT', () => {
|
|
381
|
+
if (isShuttingDown) return;
|
|
382
|
+
isShuttingDown = true;
|
|
383
|
+
child.kill('SIGTERM');
|
|
384
|
+
});
|
|
385
|
+
|
|
386
|
+
try {
|
|
387
|
+
process.chdir(USER_CWD);
|
|
388
|
+
} catch (_e) {
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
child.on('error', (err) => {
|
|
392
|
+
log(`Error: ${err.message}`, colors.red);
|
|
393
|
+
process.exit(1);
|
|
394
|
+
});
|
|
395
|
+
|
|
396
|
+
child.on('exit', (code) => {
|
|
397
|
+
if (isShuttingDown) {
|
|
398
|
+
process.stdout.write('\n');
|
|
399
|
+
}
|
|
400
|
+
process.exit(code || 0);
|
|
401
|
+
});
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
const args = process.argv.slice(2);
|
|
405
|
+
|
|
406
|
+
function parsePort(args) {
|
|
407
|
+
const portIndex = args.findIndex(a => a === '--port' || a === '-p');
|
|
408
|
+
if (portIndex !== -1 && args[portIndex + 1]) {
|
|
409
|
+
const port = parseInt(args[portIndex + 1], 10);
|
|
410
|
+
if (!Number.isNaN(port) && port > 0 && port < 65536) {
|
|
411
|
+
return port;
|
|
412
|
+
}
|
|
413
|
+
log(`Invalid port: ${args[portIndex + 1]}`, colors.red);
|
|
414
|
+
process.exit(1);
|
|
415
|
+
}
|
|
416
|
+
return null;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
function resolveLaunchEnv(args) {
|
|
420
|
+
const requestedPort = parsePort(args);
|
|
421
|
+
const { minionryEnv, appOrigin, serverUrl } = resolveLaunchTargets(args);
|
|
422
|
+
|
|
423
|
+
process.env.MINIONRY_ENV = minionryEnv;
|
|
424
|
+
delete process.env.PLATFORM_URL;
|
|
425
|
+
delete process.env.APP_ORIGIN;
|
|
426
|
+
if (serverUrl) process.env.PLATFORM_URL = serverUrl;
|
|
427
|
+
if (appOrigin) process.env.APP_ORIGIN = appOrigin;
|
|
428
|
+
|
|
429
|
+
return {
|
|
430
|
+
...(requestedPort ? { PORT: String(requestedPort) } : {}),
|
|
431
|
+
...(serverUrl ? { PLATFORM_URL: serverUrl } : {}),
|
|
432
|
+
...(appOrigin ? { APP_ORIGIN: appOrigin } : {}),
|
|
433
|
+
MINIONRY_ENV: minionryEnv,
|
|
434
|
+
};
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
function compareVersions(a, b) {
|
|
438
|
+
const pa = a.split('.').map(Number);
|
|
439
|
+
const pb = b.split('.').map(Number);
|
|
440
|
+
for (let i = 0; i < 3; i++) {
|
|
441
|
+
if ((pa[i] || 0) > (pb[i] || 0)) return 1;
|
|
442
|
+
if ((pa[i] || 0) < (pb[i] || 0)) return -1;
|
|
443
|
+
}
|
|
444
|
+
return 0;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
function readUpdateCache() {
|
|
448
|
+
try {
|
|
449
|
+
const file = machineFile('updateCheck');
|
|
450
|
+
if (!existsSync(file)) return null;
|
|
451
|
+
const cache = JSON.parse(readFileSync(file, 'utf-8'));
|
|
452
|
+
return cache?.registry === REGISTRY_URL ? cache : null;
|
|
453
|
+
} catch {
|
|
454
|
+
return null;
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
function writeUpdateCache(latest) {
|
|
459
|
+
try {
|
|
460
|
+
ensureMachineDir('cache');
|
|
461
|
+
writeFileSync(machineFile('updateCheck'), JSON.stringify({ latest, checkedAt: Date.now(), registry: REGISTRY_URL }));
|
|
462
|
+
} catch {
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
function readNpmrcValue(key) {
|
|
467
|
+
try {
|
|
468
|
+
const npmrc = readFileSync(join(homedir(), '.npmrc'), 'utf-8');
|
|
469
|
+
for (const line of npmrc.split('\n')) {
|
|
470
|
+
const trimmed = line.trim();
|
|
471
|
+
if (!trimmed || trimmed.startsWith('#') || trimmed.startsWith(';')) continue;
|
|
472
|
+
const eq = trimmed.indexOf('=');
|
|
473
|
+
if (eq !== -1 && trimmed.slice(0, eq).trim() === key) return trimmed.slice(eq + 1);
|
|
474
|
+
}
|
|
475
|
+
} catch {
|
|
476
|
+
}
|
|
477
|
+
return null;
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
function readNpmAuthToken() {
|
|
481
|
+
const key = `${REGISTRY_URL.replace(/^https?:/, '').replace(/\/+$/, '')}/:_authToken`;
|
|
482
|
+
const raw =
|
|
483
|
+
process.env[`npm_config_${key}`] ?? process.env[`npm_config_${key.toLowerCase()}`] ?? readNpmrcValue(key);
|
|
484
|
+
if (!raw) return null;
|
|
485
|
+
|
|
486
|
+
const value = raw.trim().replace(/^["']|["']$/g, '').replace(/\$\{([^}]+)\}/g, (_, name) => process.env[name] ?? '');
|
|
487
|
+
return value && !value.includes('${') ? value : null;
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
async function fetchLatestVersion(timeoutMs = 3000) {
|
|
491
|
+
try {
|
|
492
|
+
const token = readNpmAuthToken();
|
|
493
|
+
const res = await fetch(`${REGISTRY_URL}/${encodeURIComponent(pkg.name)}/latest`, {
|
|
494
|
+
signal: AbortSignal.timeout(timeoutMs),
|
|
495
|
+
...(token ? { headers: { authorization: `Bearer ${token}` } } : {}),
|
|
496
|
+
});
|
|
497
|
+
if (!res.ok) return null;
|
|
498
|
+
const { version } = await res.json();
|
|
499
|
+
if (version) writeUpdateCache(version);
|
|
500
|
+
return version || null;
|
|
501
|
+
} catch {
|
|
502
|
+
return null;
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
function updateType(current, latest) {
|
|
507
|
+
const c = current.split('.').map(Number);
|
|
508
|
+
const l = latest.split('.').map(Number);
|
|
509
|
+
if (l[0] > c[0]) return 'major';
|
|
510
|
+
if (l[1] > c[1]) return 'minor';
|
|
511
|
+
return 'patch';
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
async function resolveLatestVersion() {
|
|
515
|
+
const cache = readUpdateCache();
|
|
516
|
+
|
|
517
|
+
if (cache?.latest && (Date.now() - cache.checkedAt) < UPDATE_CHECK_INTERVAL) {
|
|
518
|
+
return cache.latest;
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
const fetched = await fetchLatestVersion(3000);
|
|
522
|
+
if (fetched) return fetched;
|
|
523
|
+
|
|
524
|
+
return cache?.latest || null;
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
function installGlobalVersion(version) {
|
|
528
|
+
const npmCmd = process.platform === 'win32' ? 'npm.cmd' : 'npm';
|
|
529
|
+
return new Promise((resolve) => {
|
|
530
|
+
const child = spawn(npmCmd, ['install', '-g', `${pkg.name}@${version}`, REGISTRY_FLAG], {
|
|
531
|
+
stdio: ['ignore', 'ignore', 'pipe'],
|
|
532
|
+
});
|
|
533
|
+
let stderr = '';
|
|
534
|
+
child.stderr.on('data', (d) => { stderr += d; });
|
|
535
|
+
child.on('error', () => resolve({ ok: false, stderr: '' }));
|
|
536
|
+
child.on('exit', (code) => resolve({ ok: code === 0, stderr }));
|
|
537
|
+
});
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
function updateCli() {
|
|
541
|
+
const npmCmd = process.platform === 'win32' ? 'npm.cmd' : 'npm';
|
|
542
|
+
const target = `${pkg.name}@latest`;
|
|
543
|
+
const manualCmd = manualUpdateCommand();
|
|
544
|
+
log(`\n Updating minion — installing ${colors.cyan}${target}${colors.reset} ${colors.dim}(${manualCmd})${colors.reset}\n`);
|
|
545
|
+
|
|
546
|
+
const child = spawn(npmCmd, ['install', '-g', target, REGISTRY_FLAG], { stdio: 'inherit' });
|
|
547
|
+
|
|
548
|
+
child.on('error', (err) => {
|
|
549
|
+
log(`\n Update failed: ${err.message}`, colors.red);
|
|
550
|
+
log(` Run manually: ${colors.cyan}${manualCmd}${colors.reset}\n`, colors.dim);
|
|
551
|
+
process.exit(1);
|
|
552
|
+
});
|
|
553
|
+
|
|
554
|
+
child.on('exit', (code) => {
|
|
555
|
+
if (code === 0) {
|
|
556
|
+
log(`\n ${APP_NAME} updated to the latest version.`, colors.bold + colors.green);
|
|
557
|
+
log(' Run "minion" to start.\n', colors.dim);
|
|
558
|
+
} else {
|
|
559
|
+
log(`\n Update failed (npm exited with code ${code}).`, colors.red);
|
|
560
|
+
log(` Run manually: ${colors.cyan}${manualCmd}${colors.reset}\n`, colors.dim);
|
|
561
|
+
}
|
|
562
|
+
process.exit(code || 0);
|
|
563
|
+
});
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
async function autoUpdate() {
|
|
567
|
+
try {
|
|
568
|
+
const latest = await resolveLatestVersion();
|
|
569
|
+
|
|
570
|
+
if (!latest || compareVersions(latest, pkg.version) <= 0) {
|
|
571
|
+
return false;
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
const current = pkg.version;
|
|
575
|
+
const type = updateType(current, latest);
|
|
576
|
+
log(`\n Updating minion: ${colors.dim}${current}${colors.reset} → ${colors.green}${latest}${colors.reset} ${colors.dim}(${type})${colors.reset}`);
|
|
577
|
+
|
|
578
|
+
const installResult = await installGlobalVersion(latest);
|
|
579
|
+
|
|
580
|
+
if (!installResult.ok) {
|
|
581
|
+
log(` Update failed — continuing with v${current}`, colors.yellow);
|
|
582
|
+
if (installResult.stderr) {
|
|
583
|
+
const reason = installResult.stderr.split('\n').find(l => l.trim()) || '';
|
|
584
|
+
if (reason) log(` ${colors.dim}${reason.trim()}${colors.reset}`);
|
|
585
|
+
}
|
|
586
|
+
log(` Run manually: ${colors.cyan}${manualUpdateCommand()}${colors.reset}\n`);
|
|
587
|
+
return false;
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
log(` Updated to v${latest}. Restarting...\n`, colors.green);
|
|
591
|
+
|
|
592
|
+
const child = spawn(process.argv[0], process.argv.slice(1), {
|
|
593
|
+
stdio: 'inherit',
|
|
594
|
+
env: { ...process.env, MINIONRY_SKIP_UPDATE_CHECK: '1' },
|
|
595
|
+
});
|
|
596
|
+
|
|
597
|
+
process.on('SIGINT', () => {});
|
|
598
|
+
process.on('SIGTERM', () => child.kill('SIGTERM'));
|
|
599
|
+
|
|
600
|
+
child.on('exit', (code, signal) => {
|
|
601
|
+
process.exit(signal ? 1 : (code || 0));
|
|
602
|
+
});
|
|
603
|
+
child.on('error', () => process.exit(1));
|
|
604
|
+
|
|
605
|
+
return true;
|
|
606
|
+
} catch {
|
|
607
|
+
return false;
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
function isLoggedIn() {
|
|
612
|
+
const env = process.env.MINIONRY_ENV || 'production';
|
|
613
|
+
const credentialsFile = machineFile(env === 'dev' ? 'platformCredentialsDev' : 'platformCredentials');
|
|
614
|
+
if (!existsSync(credentialsFile)) {
|
|
615
|
+
return false;
|
|
616
|
+
}
|
|
617
|
+
try {
|
|
618
|
+
const creds = JSON.parse(readFileSync(credentialsFile, 'utf-8'));
|
|
619
|
+
return !!(creds.token && creds.userId && creds.email);
|
|
620
|
+
} catch {
|
|
621
|
+
return false;
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
async function ensureLoggedIn() {
|
|
626
|
+
if (isLoggedIn()) return;
|
|
627
|
+
log('\n Not logged in — starting authentication...\n', colors.bold + colors.cyan);
|
|
628
|
+
try {
|
|
629
|
+
const { login } = await import('./commands/login.js');
|
|
630
|
+
await login(args, { inline: true });
|
|
631
|
+
} catch (err) {
|
|
632
|
+
log(`\n Login failed: ${err.message}`, colors.red);
|
|
633
|
+
log(' Run "minion login" to try again.\n', colors.dim);
|
|
634
|
+
process.exit(1);
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
async function ensurePtySetup() {
|
|
639
|
+
const ptyAvailable = await isNodePtyAvailable();
|
|
640
|
+
if (ptyAvailable) return;
|
|
641
|
+
if (hasUserDismissedPtySetup()) return;
|
|
642
|
+
showPtyWarning();
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
async function startServer(envOverrides, { foreground = false } = {}) {
|
|
646
|
+
if (!foreground && !isLoggedIn() && !(process.stdin.isTTY && process.stdout.isTTY)) {
|
|
647
|
+
log('\n Not logged in.', colors.red);
|
|
648
|
+
log(' Run "minion login" first, then retry "minion".\n', colors.dim);
|
|
649
|
+
process.exit(1);
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
await ensureLoggedIn();
|
|
653
|
+
|
|
654
|
+
await ensurePtySetup();
|
|
655
|
+
|
|
656
|
+
const script = resolveStartScript();
|
|
657
|
+
if (foreground) {
|
|
658
|
+
runNpmScript(script, [], envOverrides);
|
|
659
|
+
} else {
|
|
660
|
+
runNpmScriptDetached(script, [], envOverrides);
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
async function main() {
|
|
665
|
+
if (process.env.MINIONRY_SKIP_UPDATE_CHECK) {
|
|
666
|
+
delete process.env.MINIONRY_SKIP_UPDATE_CHECK;
|
|
667
|
+
} else {
|
|
668
|
+
const updated = await autoUpdate();
|
|
669
|
+
if (updated) return;
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
normalizeNodePtyTree(prebuiltPlatformDir());
|
|
673
|
+
|
|
674
|
+
const envOverrides = resolveLaunchEnv(args);
|
|
675
|
+
|
|
676
|
+
const subcommand = args.find(arg => !arg.startsWith('-') && !arg.startsWith('--'));
|
|
677
|
+
|
|
678
|
+
const commands = new Map([
|
|
679
|
+
['login', async () => {
|
|
680
|
+
const { login } = await import('./commands/login.js');
|
|
681
|
+
const freshLogin = await login(args.slice(args.indexOf('login') + 1));
|
|
682
|
+
if (freshLogin) {
|
|
683
|
+
await runPostLoginSetup();
|
|
684
|
+
const envSuffix = launchFlagSuffix(process.env.MINIONRY_ENV);
|
|
685
|
+
log('');
|
|
686
|
+
log(` Run "minion${envSuffix}" to start a machine.`, colors.cyan);
|
|
687
|
+
log('');
|
|
688
|
+
}
|
|
689
|
+
}],
|
|
690
|
+
['logout', async () => {
|
|
691
|
+
const { logout } = await import('./commands/logout.js');
|
|
692
|
+
await logout(args.slice(args.indexOf('logout') + 1));
|
|
693
|
+
}],
|
|
694
|
+
['whoami', async () => {
|
|
695
|
+
const { whoami } = await import('./commands/whoami.js');
|
|
696
|
+
await whoami(args.slice(args.indexOf('whoami') + 1));
|
|
697
|
+
}],
|
|
698
|
+
['status', async () => {
|
|
699
|
+
const { status } = await import('./commands/status.js');
|
|
700
|
+
await status();
|
|
701
|
+
}],
|
|
702
|
+
['fingerprint', async () => {
|
|
703
|
+
const { fingerprint } = await import('./commands/fingerprint.js');
|
|
704
|
+
await fingerprint(args.slice(args.indexOf('fingerprint') + 1));
|
|
705
|
+
}],
|
|
706
|
+
['update', updateCli],
|
|
707
|
+
['install', async () => {
|
|
708
|
+
const installArgs = args.slice(args.indexOf('install') + 1);
|
|
709
|
+
const target = installArgs.find((a) => !a.startsWith('-'));
|
|
710
|
+
if (target === 'terminal') {
|
|
711
|
+
await installTerminal();
|
|
712
|
+
return;
|
|
713
|
+
}
|
|
714
|
+
if (target === 'browser') {
|
|
715
|
+
const { browserInstall } = await import('./commands/browser-install.js');
|
|
716
|
+
await browserInstall(installArgs.slice(installArgs.indexOf('browser') + 1));
|
|
717
|
+
return;
|
|
718
|
+
}
|
|
719
|
+
log('\n Usage: minion install <terminal|browser>', colors.dim);
|
|
720
|
+
log(' minion install browser [--uninstall] [--json] [--no-deps] [--check]\n', colors.dim);
|
|
721
|
+
process.exit(target ? 1 : 0);
|
|
722
|
+
}],
|
|
723
|
+
['doctor', async () => {
|
|
724
|
+
const doctorArgs = args.slice(args.indexOf('doctor') + 1);
|
|
725
|
+
const target = doctorArgs.find((a) => !a.startsWith('-'));
|
|
726
|
+
if (target === undefined) {
|
|
727
|
+
await doctorTerminal();
|
|
728
|
+
await doctorBrowser();
|
|
729
|
+
return;
|
|
730
|
+
}
|
|
731
|
+
if (target === 'terminal') {
|
|
732
|
+
await doctorTerminal();
|
|
733
|
+
return;
|
|
734
|
+
}
|
|
735
|
+
if (target === 'browser') {
|
|
736
|
+
await doctorBrowser();
|
|
737
|
+
return;
|
|
738
|
+
}
|
|
739
|
+
log('\n Usage: minion doctor [terminal|browser]\n', colors.dim);
|
|
740
|
+
process.exit(1);
|
|
741
|
+
}],
|
|
742
|
+
['create', async () => {
|
|
743
|
+
const createArgs = args.slice(args.indexOf('create') + 1);
|
|
744
|
+
const target = createArgs.find((a) => !a.startsWith('-'));
|
|
745
|
+
if (target === 'sandbox') {
|
|
746
|
+
const { createSandbox } = await import('./commands/create-sandbox.js');
|
|
747
|
+
await createSandbox(createArgs.slice(createArgs.indexOf('sandbox') + 1));
|
|
748
|
+
return;
|
|
749
|
+
}
|
|
750
|
+
log('\n Usage: minion create sandbox [name] [--rebuild] [--memory <GB>] [--disk <GB>]', colors.dim);
|
|
751
|
+
log(' Creates an isolated sandbox to make Spaces in. Asks for a name when', colors.dim);
|
|
752
|
+
log(' none is given (Enter takes the suggestion), and is uncapped unless', colors.dim);
|
|
753
|
+
log(' --memory / --disk ask for a limit.\n', colors.dim);
|
|
754
|
+
process.exit(target ? 1 : 0);
|
|
755
|
+
}],
|
|
756
|
+
['rename', async () => {
|
|
757
|
+
const renameArgs = args.slice(args.indexOf('rename') + 1);
|
|
758
|
+
const target = renameArgs.find((a) => !a.startsWith('-'));
|
|
759
|
+
if (target === 'sandbox' || target === 'sandboxes') {
|
|
760
|
+
const { renameSandbox } = await import('./commands/sandboxes.js');
|
|
761
|
+
await renameSandbox(renameArgs.slice(renameArgs.indexOf(target) + 1));
|
|
762
|
+
return;
|
|
763
|
+
}
|
|
764
|
+
log('\n Usage: minion rename sandbox <current-name> <new-name>\n', colors.dim);
|
|
765
|
+
process.exit(target ? 1 : 0);
|
|
766
|
+
}],
|
|
767
|
+
['list', async () => {
|
|
768
|
+
const listArgs = args.slice(args.indexOf('list') + 1);
|
|
769
|
+
const target = listArgs.find((a) => !a.startsWith('-'));
|
|
770
|
+
if (target === 'sandboxes' || target === 'sandbox') {
|
|
771
|
+
const { listSandboxes } = await import('./commands/sandboxes.js');
|
|
772
|
+
await listSandboxes();
|
|
773
|
+
return;
|
|
774
|
+
}
|
|
775
|
+
if (target === 'minions' || target === 'minion') {
|
|
776
|
+
const { listMinions } = await import('./commands/minions.js');
|
|
777
|
+
listMinions();
|
|
778
|
+
return;
|
|
779
|
+
}
|
|
780
|
+
log('\n Usage: minion list sandboxes', colors.dim);
|
|
781
|
+
log(' minion list minions\n', colors.dim);
|
|
782
|
+
process.exit(target ? 1 : 0);
|
|
783
|
+
}],
|
|
784
|
+
['restart', async () => {
|
|
785
|
+
const restartArgs = args.slice(args.indexOf('restart') + 1);
|
|
786
|
+
const target = restartArgs.find((a) => !a.startsWith('-'));
|
|
787
|
+
if (target === 'sandbox' || target === 'sandboxes') {
|
|
788
|
+
const { restartSandbox } = await import('./commands/sandboxes.js');
|
|
789
|
+
await restartSandbox(restartArgs.slice(restartArgs.indexOf(target) + 1));
|
|
790
|
+
return;
|
|
791
|
+
}
|
|
792
|
+
log('\n Usage: minion restart sandbox <name> [--uncap]\n', colors.dim);
|
|
793
|
+
process.exit(target ? 1 : 0);
|
|
794
|
+
}],
|
|
795
|
+
['shutdown', async () => {
|
|
796
|
+
const { shutdownMinion } = await import('./commands/minions.js');
|
|
797
|
+
shutdownMinion(args.slice(args.indexOf('shutdown') + 1));
|
|
798
|
+
}],
|
|
799
|
+
['setup-terminal', async () => {
|
|
800
|
+
log('\n Note: "minion setup-terminal" is now "minion install terminal".', colors.dim);
|
|
801
|
+
await installTerminal();
|
|
802
|
+
}],
|
|
803
|
+
['browser', async () => {
|
|
804
|
+
const browserArgs = args.slice(args.indexOf('browser') + 1);
|
|
805
|
+
const sub = browserArgs.find((a) => !a.startsWith('-'));
|
|
806
|
+
if (sub === 'install') {
|
|
807
|
+
if (!browserArgs.includes('--json')) {
|
|
808
|
+
log('\n Note: "minion browser install" is now "minion install browser".', colors.dim);
|
|
809
|
+
}
|
|
810
|
+
const { browserInstall } = await import('./commands/browser-install.js');
|
|
811
|
+
await browserInstall(browserArgs.slice(browserArgs.indexOf('install') + 1));
|
|
812
|
+
return;
|
|
813
|
+
}
|
|
814
|
+
log('\n Usage: minion install browser [--uninstall] [--json] [--no-deps] [--check]\n', colors.dim);
|
|
815
|
+
process.exit(sub ? 1 : 0);
|
|
816
|
+
}],
|
|
817
|
+
]);
|
|
818
|
+
|
|
819
|
+
if (args.includes('--version') || args.includes('-V')) {
|
|
820
|
+
log(`minion v${pkg.version}`);
|
|
821
|
+
return;
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
if (args.includes('--help') || args.includes('-h')) {
|
|
825
|
+
showHelp();
|
|
826
|
+
return;
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
const handler = subcommand ? commands.get(subcommand) : undefined;
|
|
830
|
+
if (handler) {
|
|
831
|
+
await handler();
|
|
832
|
+
return;
|
|
833
|
+
}
|
|
834
|
+
|
|
835
|
+
const foreground = args.includes('--foreground');
|
|
836
|
+
await startServer(envOverrides, { foreground });
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
main();
|