@paperclipai/server 2026.817.0 → 2026.818.0-beta.1
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/dist/adapters/hermes-gateway-doc.d.ts +1 -1
- package/dist/adapters/hermes-gateway-doc.d.ts.map +1 -1
- package/dist/adapters/hermes-gateway-doc.js +1 -1
- package/dist/adapters/plugin-loader.d.ts.map +1 -1
- package/dist/adapters/plugin-loader.js +3 -2
- package/dist/adapters/plugin-loader.js.map +1 -1
- package/dist/agent-auth-jwt.d.ts.map +1 -1
- package/dist/agent-auth-jwt.js +8 -2
- package/dist/agent-auth-jwt.js.map +1 -1
- package/dist/app.d.ts +5 -1
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +202 -15
- package/dist/app.js.map +1 -1
- package/dist/built-ins/agents/summarizer/AGENTS.md +2 -2
- package/dist/built-ins/agents/summarizer/routines/refresh-stale-summaries.md +1 -0
- package/dist/db-errors.d.ts +9 -0
- package/dist/db-errors.d.ts.map +1 -1
- package/dist/db-errors.js +19 -0
- package/dist/db-errors.js.map +1 -1
- package/dist/errors.d.ts +1 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +2 -2
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +162 -38
- package/dist/index.js.map +1 -1
- package/dist/lib/request-promise-memo.d.ts +6 -0
- package/dist/lib/request-promise-memo.d.ts.map +1 -0
- package/dist/lib/request-promise-memo.js +25 -0
- package/dist/lib/request-promise-memo.js.map +1 -0
- package/dist/lib/request-promise-memo.test.d.ts +2 -0
- package/dist/lib/request-promise-memo.test.d.ts.map +1 -0
- package/dist/lib/request-promise-memo.test.js +74 -0
- package/dist/lib/request-promise-memo.test.js.map +1 -0
- package/dist/middleware/auth.d.ts +13 -1
- package/dist/middleware/auth.d.ts.map +1 -1
- package/dist/middleware/auth.js +92 -41
- package/dist/middleware/auth.js.map +1 -1
- package/dist/middleware/cloud-tenant-actor.test.js +26 -1
- package/dist/middleware/cloud-tenant-actor.test.js.map +1 -1
- package/dist/middleware/error-handler.d.ts.map +1 -1
- package/dist/middleware/error-handler.js +11 -2
- package/dist/middleware/error-handler.js.map +1 -1
- package/dist/middleware/logger.d.ts.map +1 -1
- package/dist/middleware/logger.js +7 -33
- package/dist/middleware/logger.js.map +1 -1
- package/dist/middleware/private-hostname-guard.d.ts.map +1 -1
- package/dist/middleware/private-hostname-guard.js +11 -6
- package/dist/middleware/private-hostname-guard.js.map +1 -1
- package/dist/middleware/private-json-etag.d.ts +3 -0
- package/dist/middleware/private-json-etag.d.ts.map +1 -0
- package/dist/middleware/private-json-etag.js +37 -0
- package/dist/middleware/private-json-etag.js.map +1 -0
- package/dist/middleware/redact-sensitive.d.ts.map +1 -1
- package/dist/middleware/redact-sensitive.js +11 -0
- package/dist/middleware/redact-sensitive.js.map +1 -1
- package/dist/realtime/live-events-ws.d.ts +12 -0
- package/dist/realtime/live-events-ws.d.ts.map +1 -1
- package/dist/realtime/live-events-ws.js +20 -0
- package/dist/realtime/live-events-ws.js.map +1 -1
- package/dist/redaction.js +1 -1
- package/dist/redaction.js.map +1 -1
- package/dist/routes/access.d.ts +2 -0
- package/dist/routes/access.d.ts.map +1 -1
- package/dist/routes/access.js +21 -10
- package/dist/routes/access.js.map +1 -1
- package/dist/routes/agents.d.ts +42 -0
- package/dist/routes/agents.d.ts.map +1 -1
- package/dist/routes/agents.js +875 -8
- package/dist/routes/agents.js.map +1 -1
- package/dist/routes/companies.d.ts +5 -1
- package/dist/routes/companies.d.ts.map +1 -1
- package/dist/routes/companies.js +467 -30
- package/dist/routes/companies.js.map +1 -1
- package/dist/routes/environments.d.ts +12 -3
- package/dist/routes/environments.d.ts.map +1 -1
- package/dist/routes/environments.js +139 -23
- package/dist/routes/environments.js.map +1 -1
- package/dist/routes/execution-workspaces.d.ts.map +1 -1
- package/dist/routes/execution-workspaces.js +240 -70
- package/dist/routes/execution-workspaces.js.map +1 -1
- package/dist/routes/file-resources.d.ts +14 -1
- package/dist/routes/file-resources.d.ts.map +1 -1
- package/dist/routes/file-resources.js +182 -3
- package/dist/routes/file-resources.js.map +1 -1
- package/dist/routes/index.d.ts +2 -1
- package/dist/routes/index.d.ts.map +1 -1
- package/dist/routes/index.js +2 -1
- package/dist/routes/index.js.map +1 -1
- package/dist/routes/instance-settings.d.ts.map +1 -1
- package/dist/routes/instance-settings.js +20 -1
- package/dist/routes/instance-settings.js.map +1 -1
- package/dist/routes/issues.d.ts.map +1 -1
- package/dist/routes/issues.js +750 -235
- package/dist/routes/issues.js.map +1 -1
- package/dist/routes/onboarding-seed.d.ts +27 -0
- package/dist/routes/onboarding-seed.d.ts.map +1 -0
- package/dist/routes/onboarding-seed.js +56 -0
- package/dist/routes/onboarding-seed.js.map +1 -0
- package/dist/routes/openapi.d.ts.map +1 -1
- package/dist/routes/openapi.js +316 -2
- package/dist/routes/openapi.js.map +1 -1
- package/dist/routes/secrets.d.ts.map +1 -1
- package/dist/routes/secrets.js +11 -1
- package/dist/routes/secrets.js.map +1 -1
- package/dist/routes/setup-token-route.test.d.ts +2 -0
- package/dist/routes/setup-token-route.test.d.ts.map +1 -0
- package/dist/routes/setup-token-route.test.js +896 -0
- package/dist/routes/setup-token-route.test.js.map +1 -0
- package/dist/routes/tool-access.d.ts.map +1 -1
- package/dist/routes/tool-access.js +87 -52
- package/dist/routes/tool-access.js.map +1 -1
- package/dist/routes/workspace-runtime-service-authz.d.ts +11 -1
- package/dist/routes/workspace-runtime-service-authz.d.ts.map +1 -1
- package/dist/routes/workspace-runtime-service-authz.js +18 -16
- package/dist/routes/workspace-runtime-service-authz.js.map +1 -1
- package/dist/services/access.d.ts.map +1 -1
- package/dist/services/activity.d.ts +1 -1
- package/dist/services/agents.d.ts +21 -0
- package/dist/services/agents.d.ts.map +1 -1
- package/dist/services/agents.js +121 -1
- package/dist/services/agents.js.map +1 -1
- package/dist/services/attention-resolver-audience.test.d.ts +2 -0
- package/dist/services/attention-resolver-audience.test.d.ts.map +1 -0
- package/dist/services/attention-resolver-audience.test.js +81 -0
- package/dist/services/attention-resolver-audience.test.js.map +1 -0
- package/dist/services/attention.d.ts +20 -1
- package/dist/services/attention.d.ts.map +1 -1
- package/dist/services/attention.js +45 -1
- package/dist/services/attention.js.map +1 -1
- package/dist/services/authorization.d.ts +2 -2
- package/dist/services/authorization.d.ts.map +1 -1
- package/dist/services/authorization.js +89 -46
- package/dist/services/authorization.js.map +1 -1
- package/dist/services/board-auth.d.ts.map +1 -1
- package/dist/services/board-auth.js +40 -1
- package/dist/services/board-auth.js.map +1 -1
- package/dist/services/board-auth.test.d.ts +2 -0
- package/dist/services/board-auth.test.d.ts.map +1 -0
- package/dist/services/board-auth.test.js +34 -0
- package/dist/services/board-auth.test.js.map +1 -0
- package/dist/services/built-in-agents.d.ts.map +1 -1
- package/dist/services/built-in-agents.js +20 -4
- package/dist/services/built-in-agents.js.map +1 -1
- package/dist/services/bundled-plugins.d.ts +11 -1
- package/dist/services/bundled-plugins.d.ts.map +1 -1
- package/dist/services/bundled-plugins.js +46 -1
- package/dist/services/bundled-plugins.js.map +1 -1
- package/dist/services/codex-device-login-reaper.d.ts +61 -0
- package/dist/services/codex-device-login-reaper.d.ts.map +1 -0
- package/dist/services/codex-device-login-reaper.js +219 -0
- package/dist/services/codex-device-login-reaper.js.map +1 -0
- package/dist/services/codex-device-login-service.d.ts +355 -0
- package/dist/services/codex-device-login-service.d.ts.map +1 -0
- package/dist/services/codex-device-login-service.js +775 -0
- package/dist/services/codex-device-login-service.js.map +1 -0
- package/dist/services/companies.d.ts.map +1 -1
- package/dist/services/companies.js +7 -0
- package/dist/services/companies.js.map +1 -1
- package/dist/services/company-export-readme.js +1 -1
- package/dist/services/company-export-readme.js.map +1 -1
- package/dist/services/company-import-transfers.d.ts +55 -0
- package/dist/services/company-import-transfers.d.ts.map +1 -0
- package/dist/services/company-import-transfers.js +151 -0
- package/dist/services/company-import-transfers.js.map +1 -0
- package/dist/services/company-portability.d.ts.map +1 -1
- package/dist/services/company-portability.js +128 -3
- package/dist/services/company-portability.js.map +1 -1
- package/dist/services/company-transfer-runs.d.ts +136 -0
- package/dist/services/company-transfer-runs.d.ts.map +1 -0
- package/dist/services/company-transfer-runs.js +243 -0
- package/dist/services/company-transfer-runs.js.map +1 -0
- package/dist/services/cross-issue-influence-limit.d.ts +7 -1
- package/dist/services/cross-issue-influence-limit.d.ts.map +1 -1
- package/dist/services/cross-issue-influence-limit.js.map +1 -1
- package/dist/services/environment-config.d.ts +15 -0
- package/dist/services/environment-config.d.ts.map +1 -1
- package/dist/services/environment-config.js +56 -10
- package/dist/services/environment-config.js.map +1 -1
- package/dist/services/environment-execution-target.d.ts.map +1 -1
- package/dist/services/environment-execution-target.js +61 -11
- package/dist/services/environment-execution-target.js.map +1 -1
- package/dist/services/environment-run-orchestrator.d.ts +16 -1
- package/dist/services/environment-run-orchestrator.d.ts.map +1 -1
- package/dist/services/environment-run-orchestrator.js +1 -1
- package/dist/services/environment-run-orchestrator.js.map +1 -1
- package/dist/services/environment-runtime.d.ts +178 -2
- package/dist/services/environment-runtime.d.ts.map +1 -1
- package/dist/services/environment-runtime.js +1035 -96
- package/dist/services/environment-runtime.js.map +1 -1
- package/dist/services/environments.d.ts +75 -0
- package/dist/services/environments.d.ts.map +1 -1
- package/dist/services/environments.js +199 -8
- package/dist/services/environments.js.map +1 -1
- package/dist/services/execution-allowlist.d.ts +16 -4
- package/dist/services/execution-allowlist.d.ts.map +1 -1
- package/dist/services/execution-allowlist.js +35 -16
- package/dist/services/execution-allowlist.js.map +1 -1
- package/dist/services/execution-allowlist.test.js +33 -0
- package/dist/services/execution-allowlist.test.js.map +1 -1
- package/dist/services/execution-workspace-policy.d.ts +14 -1
- package/dist/services/execution-workspace-policy.d.ts.map +1 -1
- package/dist/services/execution-workspace-policy.js +29 -12
- package/dist/services/execution-workspace-policy.js.map +1 -1
- package/dist/services/execution-workspaces.d.ts +89 -0
- package/dist/services/execution-workspaces.d.ts.map +1 -1
- package/dist/services/execution-workspaces.js +997 -125
- package/dist/services/execution-workspaces.js.map +1 -1
- package/dist/services/heartbeat-run-summary.d.ts +1 -0
- package/dist/services/heartbeat-run-summary.d.ts.map +1 -1
- package/dist/services/heartbeat-run-summary.js +19 -3
- package/dist/services/heartbeat-run-summary.js.map +1 -1
- package/dist/services/heartbeat.d.ts +18 -2
- package/dist/services/heartbeat.d.ts.map +1 -1
- package/dist/services/heartbeat.js +369 -16
- package/dist/services/heartbeat.js.map +1 -1
- package/dist/services/import-write-types.d.ts +12 -0
- package/dist/services/import-write-types.d.ts.map +1 -1
- package/dist/services/index.d.ts +2 -0
- package/dist/services/index.d.ts.map +1 -1
- package/dist/services/index.js +2 -0
- package/dist/services/index.js.map +1 -1
- package/dist/services/instance-settings.d.ts +10 -1
- package/dist/services/instance-settings.d.ts.map +1 -1
- package/dist/services/instance-settings.js +16 -9
- package/dist/services/instance-settings.js.map +1 -1
- package/dist/services/issue-review-policy.d.ts +4 -0
- package/dist/services/issue-review-policy.d.ts.map +1 -1
- package/dist/services/issue-review-policy.js +18 -7
- package/dist/services/issue-review-policy.js.map +1 -1
- package/dist/services/issue-thread-interaction-resolution.d.ts +92 -0
- package/dist/services/issue-thread-interaction-resolution.d.ts.map +1 -0
- package/dist/services/issue-thread-interaction-resolution.js +198 -0
- package/dist/services/issue-thread-interaction-resolution.js.map +1 -0
- package/dist/services/issue-thread-interaction-resolution.test.d.ts +2 -0
- package/dist/services/issue-thread-interaction-resolution.test.d.ts.map +1 -0
- package/dist/services/issue-thread-interaction-resolution.test.js +152 -0
- package/dist/services/issue-thread-interaction-resolution.test.js.map +1 -0
- package/dist/services/issue-thread-interactions.d.ts +24 -4
- package/dist/services/issue-thread-interactions.d.ts.map +1 -1
- package/dist/services/issue-thread-interactions.js +360 -145
- package/dist/services/issue-thread-interactions.js.map +1 -1
- package/dist/services/issue-thread-interactions.test.js +18 -11
- package/dist/services/issue-thread-interactions.test.js.map +1 -1
- package/dist/services/issues.d.ts +3 -0
- package/dist/services/issues.d.ts.map +1 -1
- package/dist/services/issues.js +157 -33
- package/dist/services/issues.js.map +1 -1
- package/dist/services/local-service-supervisor.d.ts +2 -0
- package/dist/services/local-service-supervisor.d.ts.map +1 -1
- package/dist/services/local-service-supervisor.js +53 -3
- package/dist/services/local-service-supervisor.js.map +1 -1
- package/dist/services/managed-environments.d.ts +4 -1
- package/dist/services/managed-environments.d.ts.map +1 -1
- package/dist/services/managed-environments.js +86 -2
- package/dist/services/managed-environments.js.map +1 -1
- package/dist/services/managed-environments.test.js +164 -0
- package/dist/services/managed-environments.test.js.map +1 -1
- package/dist/services/onboarding-greeting.d.ts +7 -0
- package/dist/services/onboarding-greeting.d.ts.map +1 -0
- package/dist/services/onboarding-greeting.js +27 -0
- package/dist/services/onboarding-greeting.js.map +1 -0
- package/dist/services/onboarding-greeting.test.d.ts +2 -0
- package/dist/services/onboarding-greeting.test.d.ts.map +1 -0
- package/dist/services/onboarding-greeting.test.js +32 -0
- package/dist/services/onboarding-greeting.test.js.map +1 -0
- package/dist/services/onboarding-seed.d.ts +57 -0
- package/dist/services/onboarding-seed.d.ts.map +1 -0
- package/dist/services/onboarding-seed.js +344 -0
- package/dist/services/onboarding-seed.js.map +1 -0
- package/dist/services/plan-review-context.d.ts +9 -1
- package/dist/services/plan-review-context.d.ts.map +1 -1
- package/dist/services/plan-review-context.js +192 -0
- package/dist/services/plan-review-context.js.map +1 -1
- package/dist/services/plugin-environment-driver.d.ts +46 -0
- package/dist/services/plugin-environment-driver.d.ts.map +1 -1
- package/dist/services/plugin-environment-driver.js +50 -0
- package/dist/services/plugin-environment-driver.js.map +1 -1
- package/dist/services/plugin-host-services.d.ts +1 -0
- package/dist/services/plugin-host-services.d.ts.map +1 -1
- package/dist/services/plugin-host-services.js +51 -28
- package/dist/services/plugin-host-services.js.map +1 -1
- package/dist/services/plugin-loader.d.ts +10 -1
- package/dist/services/plugin-loader.d.ts.map +1 -1
- package/dist/services/plugin-loader.js +43 -2
- package/dist/services/plugin-loader.js.map +1 -1
- package/dist/services/plugin-worker-manager.d.ts +61 -0
- package/dist/services/plugin-worker-manager.d.ts.map +1 -1
- package/dist/services/plugin-worker-manager.js +248 -1
- package/dist/services/plugin-worker-manager.js.map +1 -1
- package/dist/services/productivity-review.d.ts.map +1 -1
- package/dist/services/productivity-review.js +5 -0
- package/dist/services/productivity-review.js.map +1 -1
- package/dist/services/recovery/service.d.ts.map +1 -1
- package/dist/services/recovery/service.js +5 -1
- package/dist/services/recovery/service.js.map +1 -1
- package/dist/services/recovery/successful-run-handoff.d.ts +16 -1
- package/dist/services/recovery/successful-run-handoff.d.ts.map +1 -1
- package/dist/services/recovery/successful-run-handoff.js +32 -0
- package/dist/services/recovery/successful-run-handoff.js.map +1 -1
- package/dist/services/recovery/successful-run-handoff.test.js +51 -1
- package/dist/services/recovery/successful-run-handoff.test.js.map +1 -1
- package/dist/services/routines.d.ts.map +1 -1
- package/dist/services/routines.js +48 -4
- package/dist/services/routines.js.map +1 -1
- package/dist/services/runtime-exposure/broker-client.d.ts +88 -0
- package/dist/services/runtime-exposure/broker-client.d.ts.map +1 -0
- package/dist/services/runtime-exposure/broker-client.js +217 -0
- package/dist/services/runtime-exposure/broker-client.js.map +1 -0
- package/dist/services/runtime-exposure/broker-client.test.d.ts +2 -0
- package/dist/services/runtime-exposure/broker-client.test.d.ts.map +1 -0
- package/dist/services/runtime-exposure/broker-client.test.js +185 -0
- package/dist/services/runtime-exposure/broker-client.test.js.map +1 -0
- package/dist/services/runtime-exposure/exposure-manager.d.ts +135 -0
- package/dist/services/runtime-exposure/exposure-manager.d.ts.map +1 -0
- package/dist/services/runtime-exposure/exposure-manager.js +247 -0
- package/dist/services/runtime-exposure/exposure-manager.js.map +1 -0
- package/dist/services/runtime-exposure/exposure-manager.test.d.ts +2 -0
- package/dist/services/runtime-exposure/exposure-manager.test.d.ts.map +1 -0
- package/dist/services/runtime-exposure/exposure-manager.test.js +384 -0
- package/dist/services/runtime-exposure/exposure-manager.test.js.map +1 -0
- package/dist/services/runtime-exposure/loopback-listener.d.ts +33 -0
- package/dist/services/runtime-exposure/loopback-listener.d.ts.map +1 -0
- package/dist/services/runtime-exposure/loopback-listener.js +146 -0
- package/dist/services/runtime-exposure/loopback-listener.js.map +1 -0
- package/dist/services/runtime-exposure/loopback-listener.test.d.ts +2 -0
- package/dist/services/runtime-exposure/loopback-listener.test.d.ts.map +1 -0
- package/dist/services/runtime-exposure/loopback-listener.test.js +116 -0
- package/dist/services/runtime-exposure/loopback-listener.test.js.map +1 -0
- package/dist/services/runtime-exposure/port-pair.d.ts +47 -0
- package/dist/services/runtime-exposure/port-pair.d.ts.map +1 -0
- package/dist/services/runtime-exposure/port-pair.js +57 -0
- package/dist/services/runtime-exposure/port-pair.js.map +1 -0
- package/dist/services/runtime-exposure/port-pair.test.d.ts +2 -0
- package/dist/services/runtime-exposure/port-pair.test.d.ts.map +1 -0
- package/dist/services/runtime-exposure/port-pair.test.js +92 -0
- package/dist/services/runtime-exposure/port-pair.test.js.map +1 -0
- package/dist/services/runtime-exposure/port-reservation.d.ts +211 -0
- package/dist/services/runtime-exposure/port-reservation.d.ts.map +1 -0
- package/dist/services/runtime-exposure/port-reservation.js +380 -0
- package/dist/services/runtime-exposure/port-reservation.js.map +1 -0
- package/dist/services/runtime-exposure/port-reservation.test.d.ts +2 -0
- package/dist/services/runtime-exposure/port-reservation.test.d.ts.map +1 -0
- package/dist/services/runtime-exposure/port-reservation.test.js +456 -0
- package/dist/services/runtime-exposure/port-reservation.test.js.map +1 -0
- package/dist/services/runtime-exposure/tailscale-hostname.d.ts +11 -0
- package/dist/services/runtime-exposure/tailscale-hostname.d.ts.map +1 -0
- package/dist/services/runtime-exposure/tailscale-hostname.js +36 -0
- package/dist/services/runtime-exposure/tailscale-hostname.js.map +1 -0
- package/dist/services/runtime-exposure/tailscale-hostname.test.d.ts +2 -0
- package/dist/services/runtime-exposure/tailscale-hostname.test.d.ts.map +1 -0
- package/dist/services/runtime-exposure/tailscale-hostname.test.js +14 -0
- package/dist/services/runtime-exposure/tailscale-hostname.test.js.map +1 -0
- package/dist/services/sandbox-orphan-cleanup-spool.d.ts +64 -0
- package/dist/services/sandbox-orphan-cleanup-spool.d.ts.map +1 -0
- package/dist/services/sandbox-orphan-cleanup-spool.js +134 -0
- package/dist/services/sandbox-orphan-cleanup-spool.js.map +1 -0
- package/dist/services/sandbox-provider-runtime.d.ts +15 -0
- package/dist/services/sandbox-provider-runtime.d.ts.map +1 -1
- package/dist/services/sandbox-provider-runtime.js +1 -0
- package/dist/services/sandbox-provider-runtime.js.map +1 -1
- package/dist/services/secrets.d.ts +103 -0
- package/dist/services/secrets.d.ts.map +1 -1
- package/dist/services/secrets.js +432 -10
- package/dist/services/secrets.js.map +1 -1
- package/dist/services/setup-token-session.d.ts +630 -0
- package/dist/services/setup-token-session.d.ts.map +1 -0
- package/dist/services/setup-token-session.js +1005 -0
- package/dist/services/setup-token-session.js.map +1 -0
- package/dist/services/setup-token-session.test.d.ts +2 -0
- package/dist/services/setup-token-session.test.d.ts.map +1 -0
- package/dist/services/setup-token-session.test.js +1143 -0
- package/dist/services/setup-token-session.test.js.map +1 -0
- package/dist/services/setup-token-transport-binding.d.ts +202 -0
- package/dist/services/setup-token-transport-binding.d.ts.map +1 -0
- package/dist/services/setup-token-transport-binding.js +386 -0
- package/dist/services/setup-token-transport-binding.js.map +1 -0
- package/dist/services/setup-token-transport-binding.test.d.ts +2 -0
- package/dist/services/setup-token-transport-binding.test.d.ts.map +1 -0
- package/dist/services/setup-token-transport-binding.test.js +761 -0
- package/dist/services/setup-token-transport-binding.test.js.map +1 -0
- package/dist/services/summary-slots.d.ts.map +1 -1
- package/dist/services/summary-slots.js +40 -6
- package/dist/services/summary-slots.js.map +1 -1
- package/dist/services/task-watchdogs.js +2 -2
- package/dist/services/task-watchdogs.js.map +1 -1
- package/dist/services/tool-access-policy.d.ts +1 -1
- package/dist/services/tool-access.d.ts.map +1 -1
- package/dist/services/tool-access.js +29 -11
- package/dist/services/tool-access.js.map +1 -1
- package/dist/services/tool-gateway.d.ts +1 -1
- package/dist/services/tool-gateway.d.ts.map +1 -1
- package/dist/services/tool-gateway.js +56 -5
- package/dist/services/tool-gateway.js.map +1 -1
- package/dist/services/workspace-file-resources.d.ts +10 -1
- package/dist/services/workspace-file-resources.d.ts.map +1 -1
- package/dist/services/workspace-file-resources.js +258 -6
- package/dist/services/workspace-file-resources.js.map +1 -1
- package/dist/services/workspace-git-operation-scheduler.d.ts +135 -0
- package/dist/services/workspace-git-operation-scheduler.d.ts.map +1 -0
- package/dist/services/workspace-git-operation-scheduler.js +655 -0
- package/dist/services/workspace-git-operation-scheduler.js.map +1 -0
- package/dist/services/workspace-git-operation-scheduler.test.d.ts +2 -0
- package/dist/services/workspace-git-operation-scheduler.test.d.ts.map +1 -0
- package/dist/services/workspace-git-operation-scheduler.test.js +367 -0
- package/dist/services/workspace-git-operation-scheduler.test.js.map +1 -0
- package/dist/services/workspace-operations.d.ts +60 -0
- package/dist/services/workspace-operations.d.ts.map +1 -1
- package/dist/services/workspace-operations.js +384 -19
- package/dist/services/workspace-operations.js.map +1 -1
- package/dist/services/workspace-runtime-exposure-backfill.test.d.ts +2 -0
- package/dist/services/workspace-runtime-exposure-backfill.test.d.ts.map +1 -0
- package/dist/services/workspace-runtime-exposure-backfill.test.js +149 -0
- package/dist/services/workspace-runtime-exposure-backfill.test.js.map +1 -0
- package/dist/services/workspace-runtime-exposure.test.d.ts +2 -0
- package/dist/services/workspace-runtime-exposure.test.d.ts.map +1 -0
- package/dist/services/workspace-runtime-exposure.test.js +517 -0
- package/dist/services/workspace-runtime-exposure.test.js.map +1 -0
- package/dist/services/workspace-runtime-leases.d.ts +90 -0
- package/dist/services/workspace-runtime-leases.d.ts.map +1 -0
- package/dist/services/workspace-runtime-leases.js +252 -0
- package/dist/services/workspace-runtime-leases.js.map +1 -0
- package/dist/services/workspace-runtime-read-model.d.ts +12 -0
- package/dist/services/workspace-runtime-read-model.d.ts.map +1 -1
- package/dist/services/workspace-runtime-read-model.test.js +3 -0
- package/dist/services/workspace-runtime-read-model.test.js.map +1 -1
- package/dist/services/workspace-runtime-ready-comment.test.js +1 -0
- package/dist/services/workspace-runtime-ready-comment.test.js.map +1 -1
- package/dist/services/workspace-runtime.d.ts +160 -2
- package/dist/services/workspace-runtime.d.ts.map +1 -1
- package/dist/services/workspace-runtime.js +1693 -141
- package/dist/services/workspace-runtime.js.map +1 -1
- package/dist/shutdown.d.ts +24 -0
- package/dist/shutdown.d.ts.map +1 -1
- package/dist/shutdown.js +37 -0
- package/dist/shutdown.js.map +1 -1
- package/dist/shutdown.test.js +113 -1
- package/dist/shutdown.test.js.map +1 -1
- package/dist/startup-banner.js +1 -1
- package/dist/startup-banner.js.map +1 -1
- package/dist/url-utils.d.ts +26 -0
- package/dist/url-utils.d.ts.map +1 -0
- package/dist/url-utils.js +59 -0
- package/dist/url-utils.js.map +1 -0
- package/dist/url-utils.test.d.ts +2 -0
- package/dist/url-utils.test.d.ts.map +1 -0
- package/dist/url-utils.test.js +55 -0
- package/dist/url-utils.test.js.map +1 -0
- package/dist/worktree-config.d.ts.map +1 -1
- package/dist/worktree-config.js +3 -17
- package/dist/worktree-config.js.map +1 -1
- package/package.json +20 -20
- package/skills/paperclip/SKILL.md +16 -11
- package/skills/paperclip/references/api-reference.md +8 -5
- package/skills/paperclip-board/SKILL.md +1 -1
- package/ui-dist/assets/{abnfDiagram-VRR7QNED-wvSnvD6-.js → abnfDiagram-N423BO3Z-BvgoV-u5.js} +1 -1
- package/ui-dist/assets/{arc-Bx0V1JsN.js → arc-BInnUBUU.js} +1 -1
- package/ui-dist/assets/architectureDiagram-T3A2C74G-Dg4MziOm.js +36 -0
- package/ui-dist/assets/{blockDiagram-677ZJIJ3-BROcLaUk.js → blockDiagram-VBNYF7ZC-D9kzAkLN.js} +1 -1
- package/ui-dist/assets/{c4Diagram-LMCZKHZV-D-V3kgju.js → c4Diagram-5PPSVZJV-BwzsgV_0.js} +1 -1
- package/ui-dist/assets/channel-qoSYbCn0.js +1 -0
- package/ui-dist/assets/{chunk-32BRIVSS-qillH3H6.js → chunk-2GRJ4B5K-D2EQ9vrl.js} +1 -1
- package/ui-dist/assets/{chunk-2Q5K7J3B-D19cVnii.js → chunk-2Q5K7J3B-DOA_8fSd.js} +1 -1
- package/ui-dist/assets/{chunk-EX3LRPZG-CLUswrZg.js → chunk-5RXB4S5H-CT5ukRiT.js} +1 -1
- package/ui-dist/assets/{chunk-5VM5RSS4-Cwlp02Lx.js → chunk-5VM5RSS4-D2gOlkyB.js} +1 -1
- package/ui-dist/assets/{chunk-MOJQB5TN-yKciyq6E.js → chunk-6Q2QTUOP-DUb6aG8c.js} +1 -1
- package/ui-dist/assets/{chunk-V7JOEXUC-DjJ75g0_.js → chunk-GF5L2VYU-BPabG3Cx.js} +1 -1
- package/ui-dist/assets/{chunk-JWPE2WC7-BjepyzEb.js → chunk-JWPE2WC7-scNfhlZz.js} +1 -1
- package/ui-dist/assets/{chunk-VR4S4FIN-CiEmy8-R.js → chunk-KBJHAD2P-BcRAzRpq.js} +1 -1
- package/ui-dist/assets/{chunk-RYQCIY6F-ed7mQM9j.js → chunk-RYQCIY6F-BiZ0-EGh.js} +1 -1
- package/ui-dist/assets/{chunk-XXDRQBXY-BiI83zoO.js → chunk-XXDRQBXY-lJULxFIE.js} +1 -1
- package/ui-dist/assets/classDiagram-JCYQIIEL-B24u1REs.js +1 -0
- package/ui-dist/assets/classDiagram-v2-OCEON4UE-B24u1REs.js +1 -0
- package/ui-dist/assets/{cose-bilkent-JH36ORCC-DIdQf5ta.js → cose-bilkent-JH36ORCC-Do8pe8JB.js} +1 -1
- package/ui-dist/assets/{cynefin-VYW2F7L2-B2m9xxh8.js → cynefin-VYW2F7L2-B34jJY1x.js} +1 -1
- package/ui-dist/assets/{cynefinDiagram-TSTJHNR4-CGVdB0kX.js → cynefinDiagram-MW4NZA55-DQ8QK8JK.js} +1 -1
- package/ui-dist/assets/cytoscape.esm-DShqj__B.js +321 -0
- package/ui-dist/assets/{dagre-VKFMJZFB-CskKiZwJ.js → dagre-VZM6K2ZE-B7lSKgxH.js} +1 -1
- package/ui-dist/assets/{diagram-OA4YK3LP-D2cn5eIN.js → diagram-7IWD3JNH-B3hLAFGE.js} +1 -1
- package/ui-dist/assets/{diagram-FQU43EPY-oa5Zu0XG.js → diagram-B4RE2ZJO-CH9Ro9e0.js} +1 -1
- package/ui-dist/assets/{diagram-NH7WQ7WH-fymti5Js.js → diagram-LBJQPF4R-DdPVMii7.js} +1 -1
- package/ui-dist/assets/{diagram-G47NLZAW-BWF2ZCsw.js → diagram-Q27KOJAE-f5VXswjc.js} +1 -1
- package/ui-dist/assets/diagram-UB23O5K3-DGqxixsR.js +41 -0
- package/ui-dist/assets/{ebnfDiagram-CCIWWBDH-CJ1d3D5q.js → ebnfDiagram-BXEA7PRR-C-1klg_w.js} +1 -1
- package/ui-dist/assets/{erDiagram-Q63AITRT-BJCPa7kK.js → erDiagram-JOGREHBK-Dt4qK4gv.js} +1 -1
- package/ui-dist/assets/{flowDiagram-23GEKE2U-BWjWuz6r.js → flowDiagram-UKHOOZJN-9ZlrTuET.js} +5 -5
- package/ui-dist/assets/{ganttDiagram-NO4QXBWP-Dv1KKjoM.js → ganttDiagram-PKOTCBZU-CE3lyvFq.js} +1 -1
- package/ui-dist/assets/{gitGraphDiagram-IHSO6WYX-9X7vgL0A.js → gitGraphDiagram-DS77QQ5N-HH2fSgad.js} +1 -1
- package/ui-dist/assets/{index-CpaK48ok.js → index-B61ORkIb.js} +1 -1
- package/ui-dist/assets/index-BHiUiToL.css +1 -0
- package/ui-dist/assets/{index-D2YCrA-D.js → index-BY5ITKmG.js} +1 -1
- package/ui-dist/assets/{index-9JMDmXc5.js → index-BbAhzCq8.js} +1 -1
- package/ui-dist/assets/{index-C5qHatpp.js → index-Bc9g6q63.js} +1 -1
- package/ui-dist/assets/{index-DuI6e5mP.js → index-Bf7tyGxE.js} +1 -1
- package/ui-dist/assets/{index-BahRsj0s.js → index-BvFx-4KW.js} +1 -1
- package/ui-dist/assets/{index-DKlsEDV7.js → index-C1mpWCcn.js} +1 -1
- package/ui-dist/assets/{index-DIXaXZrW.js → index-CHXG4GPL.js} +1 -1
- package/ui-dist/assets/{index-DcfO6NoY.js → index-CLu3Tfpv.js} +1 -1
- package/ui-dist/assets/{index-Cfz6P0Qq.js → index-CQhaM6qd.js} +1 -1
- package/ui-dist/assets/{index-D9d3sl6K.js → index-CVTL3aAL.js} +1 -1
- package/ui-dist/assets/{index-BexA3NAl.js → index-CcRTJ93J.js} +1 -1
- package/ui-dist/assets/{index-CnBrDwGT.js → index-Cm6iEYPt.js} +247 -223
- package/ui-dist/assets/{index-ByGcu-MB.js → index-DQIrrn2L.js} +1 -1
- package/ui-dist/assets/{index-DKEzHO7c.js → index-DU4U1fuv.js} +1 -1
- package/ui-dist/assets/{index-pqJO8FsV.js → index-DV2FOgyD.js} +1 -1
- package/ui-dist/assets/{index-tDuieU3u.js → index-DceuCrr8.js} +1 -1
- package/ui-dist/assets/{index-CjN2lm_w.js → index-DlVBBF8o.js} +1 -1
- package/ui-dist/assets/{index-0yJtUsFh.js → index-DsdVneqe.js} +1 -1
- package/ui-dist/assets/{index-C2a4_IKU.js → index-DvFUXI-Q.js} +1 -1
- package/ui-dist/assets/{index-BTMiDMYv.js → index-FHzrJ7iQ.js} +1 -1
- package/ui-dist/assets/{index-cUQXJtLK.js → index-diFs0CNC.js} +1 -1
- package/ui-dist/assets/{index-C96LHV1A.js → index-hkanj4t6.js} +1 -1
- package/ui-dist/assets/{index-rDI1Q4r9.js → index-yRJnh4vx.js} +1 -1
- package/ui-dist/assets/{infoDiagram-FWYZ7A6U-CHIhutSb.js → infoDiagram-6WML65LV-2jai2fw-.js} +1 -1
- package/ui-dist/assets/{ishikawaDiagram-FXEZZL3T-ChaD7-5_.js → ishikawaDiagram-WSZJBQD7-CUmGhmEb.js} +1 -1
- package/ui-dist/assets/{journeyDiagram-5HDEW3XC-M5T2sMgn.js → journeyDiagram-NVQOT4AX-CGQuPDO1.js} +1 -1
- package/ui-dist/assets/{kanban-definition-HUTT4EX6-B8H6R_Wc.js → kanban-definition-27J2QSJJ-zgEPcbHl.js} +1 -1
- package/ui-dist/assets/{linear-cpPKlVCq.js → linear-BVf5VtLS.js} +1 -1
- package/ui-dist/assets/mermaid.core-D2TFkGfI.js +308 -0
- package/ui-dist/assets/{mindmap-definition-LN4V7U3C-Bf6POzvm.js → mindmap-definition-FAOFIHXS-xoAQ0Lb_.js} +1 -1
- package/ui-dist/assets/{pegDiagram-2B236MQR-BJbGktAV.js → pegDiagram-VL7TDLO6-CBR1PWLr.js} +1 -1
- package/ui-dist/assets/{pieDiagram-ENE6RG2P-BmSN9Bio.js → pieDiagram-7S7Q4E2Y-BMPnzK_e.js} +1 -1
- package/ui-dist/assets/{quadrantDiagram-ABIIQ3AL-JUpqQCx_.js → quadrantDiagram-CIZ2JOQS-CPtVUPkR.js} +1 -1
- package/ui-dist/assets/{railroadDiagram-RFXS5EU6-B8k8T4-2.js → railroadDiagram-AXF67PYL-DC0lsZV1.js} +1 -1
- package/ui-dist/assets/{requirementDiagram-TGXJPOKE-b32heq7Q.js → requirementDiagram-LRYGKXZP-BF6k05SB.js} +1 -1
- package/ui-dist/assets/{sankeyDiagram-HTMAVEWB-DC3s-xgf.js → sankeyDiagram-W5VNT64P-CRN0ibiP.js} +1 -1
- package/ui-dist/assets/{sequenceDiagram-DBY2YBRQ-BsCFyv_E.js → sequenceDiagram-SI44F4Z6-CQtTiPWm.js} +1 -1
- package/ui-dist/assets/{sizeCapture-X5ZJPWSS-S7xeCud3.js → sizeCapture-X5ZJPWSS-BdjuGZd1.js} +1 -1
- package/ui-dist/assets/{stateDiagram-2N3HPSRC-58O3ofoS.js → stateDiagram-OKZ733FA-B99onxyh.js} +1 -1
- package/ui-dist/assets/stateDiagram-v2-UEYNNEHI-bzFlYBZ1.js +1 -0
- package/ui-dist/assets/{swimlanes-5IMT3BWC-DFCVG0iF.js → swimlanes-SLNWSIFB-BIByPbrL.js} +2 -2
- package/ui-dist/assets/swimlanesDiagram-ULZ7WXOC-DgdkBnuK.js +8 -0
- package/ui-dist/assets/{timeline-definition-FHXFAJF6-C0c0SkQu.js → timeline-definition-Z64GVDOM-I1NgOcn9.js} +1 -1
- package/ui-dist/assets/{vennDiagram-L72KCM5P-B1cEx8GQ.js → vennDiagram-T6HMQDX7-D6t2Njcl.js} +1 -1
- package/ui-dist/assets/{wardleyDiagram-EHGQE667-BQhDkOx9.js → wardleyDiagram-T6FBY63Y-BiYKm9gh.js} +1 -1
- package/ui-dist/assets/{xychartDiagram-FW5EYKEG-YSQp1N0i.js → xychartDiagram-ELKLHX3M-BhwXKWIa.js} +4 -4
- package/ui-dist/index.html +3 -3
- package/ui-dist/sw.js +8 -3
- package/ui-dist/assets/architectureDiagram-ZJ3FMSHR-BcJt8Ia1.js +0 -36
- package/ui-dist/assets/channel-ZRpjyNiZ.js +0 -1
- package/ui-dist/assets/classDiagram-OUVF2IWQ-CCzzzCgk.js +0 -1
- package/ui-dist/assets/classDiagram-v2-EOCWNBFH-CCzzzCgk.js +0 -1
- package/ui-dist/assets/cytoscape.esm-D8joxN9f.js +0 -321
- package/ui-dist/assets/diagram-WEI45ONY-M3WOC2tK.js +0 -41
- package/ui-dist/assets/index-BqfqfoQX.css +0 -1
- package/ui-dist/assets/mermaid.core-MCazc_od.js +0 -308
- package/ui-dist/assets/stateDiagram-v2-6OUMAXLB-_VY5dpDG.js +0 -1
- package/ui-dist/assets/swimlanesDiagram-G3AALYLV-BJhUjfns.js +0 -8
|
@@ -0,0 +1,517 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import net from "node:net";
|
|
3
|
+
import os from "node:os";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
|
|
6
|
+
import { diagnoseRuntimeListenerBinds } from "./runtime-exposure/loopback-listener.js";
|
|
7
|
+
import { resetRuntimeServicesForTests, setWorkspaceRuntimeExposureDepsForTests, startRuntimeServicesForWorkspaceControl, stopRuntimeServicesForExecutionWorkspace, } from "./workspace-runtime.js";
|
|
8
|
+
const EXECUTION_WORKSPACE_ID = "11111111-2222-4333-8444-555566667777";
|
|
9
|
+
const HANDLE = "handle-abcdef1234567890";
|
|
10
|
+
// The shared test setup pins the automatic default off so unrelated suites do
|
|
11
|
+
// not probe for a real host broker. This suite is about the default, so it opts
|
|
12
|
+
// back in and restores the harness value afterwards.
|
|
13
|
+
let previousHttpsMode;
|
|
14
|
+
beforeEach(() => {
|
|
15
|
+
previousHttpsMode = process.env.PAPERCLIP_MANAGED_RUNTIME_HTTPS;
|
|
16
|
+
process.env.PAPERCLIP_MANAGED_RUNTIME_HTTPS = "auto";
|
|
17
|
+
});
|
|
18
|
+
afterEach(async () => {
|
|
19
|
+
if (previousHttpsMode === undefined)
|
|
20
|
+
delete process.env.PAPERCLIP_MANAGED_RUNTIME_HTTPS;
|
|
21
|
+
else
|
|
22
|
+
process.env.PAPERCLIP_MANAGED_RUNTIME_HTTPS = previousHttpsMode;
|
|
23
|
+
// These tests spawn real loopback backends on dedicated-range ports; reap them
|
|
24
|
+
// rather than leaving one squatting 42xxx/52xxx for every test in the file.
|
|
25
|
+
await resetRuntimeServicesForTests({ terminateProcesses: true });
|
|
26
|
+
});
|
|
27
|
+
function serviceCommand() {
|
|
28
|
+
return `node -e 'const http=require("http");const p=Number(process.env.PORT);for(const q of [p,p+10000])http.createServer((_,r)=>{r.statusCode=200;r.end("ok")}).listen(q,"127.0.0.1");setInterval(()=>{},1000)'`;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Fake guest dev runners written to disk (PAP-17256).
|
|
32
|
+
*
|
|
33
|
+
* They must be real files named `dev-runner*.mjs` for two reasons: the command
|
|
34
|
+
* has to look like a dev-runner invocation for the rewrite to apply at all, and
|
|
35
|
+
* `node <file> --bind lan` hands the flags to the script, which is exactly how a
|
|
36
|
+
* real `pnpm dev --bind lan` reaches `scripts/dev-runner.ts`.
|
|
37
|
+
*/
|
|
38
|
+
let guestDir;
|
|
39
|
+
/**
|
|
40
|
+
* A guest checkout from *before* managed HTTPS exposure existed.
|
|
41
|
+
*
|
|
42
|
+
* Reproduces the behaviour that actually broke the lanes: `scripts/dev-runner.ts`
|
|
43
|
+
* on plain master derives its bind mode from its own `--bind` / `--bind-host`
|
|
44
|
+
* argv and **ignores `PAPERCLIP_BIND` / `PAPERCLIP_MANAGED_RUNTIME_EXPOSURE`
|
|
45
|
+
* entirely** — so env-only hardening cannot reach it. `--bind lan` therefore
|
|
46
|
+
* means `0.0.0.0`, which the broker must refuse.
|
|
47
|
+
*/
|
|
48
|
+
const PRE_MANAGED_EXPOSURE_GUEST = `
|
|
49
|
+
import http from "node:http";
|
|
50
|
+
const argv = process.argv.slice(2);
|
|
51
|
+
const valueOf = (flag) => {
|
|
52
|
+
const at = argv.indexOf(flag);
|
|
53
|
+
const value = at >= 0 ? argv[at + 1] : undefined;
|
|
54
|
+
return value && !value.startsWith("--") ? value : undefined;
|
|
55
|
+
};
|
|
56
|
+
const mode = valueOf("--bind") ?? "loopback";
|
|
57
|
+
const host = mode === "custom" ? (valueOf("--bind-host") ?? "127.0.0.1")
|
|
58
|
+
: mode === "lan" ? "0.0.0.0"
|
|
59
|
+
: "127.0.0.1";
|
|
60
|
+
const p = Number(process.env.PORT);
|
|
61
|
+
for (const q of [p, p + 10000]) {
|
|
62
|
+
http.createServer((_, r) => { r.statusCode = 200; r.end("ok"); }).listen(q, host);
|
|
63
|
+
}
|
|
64
|
+
setInterval(() => {}, 1000);
|
|
65
|
+
`;
|
|
66
|
+
/**
|
|
67
|
+
* The true shape of the deployed failure: a guest that honours the bind argv for
|
|
68
|
+
* its own HTTP listener but whose Vite gets `hmr.port` with no `hmr.server` and
|
|
69
|
+
* no `server.host`, so Vite opens its *own* HMR websocket on the IPv6 wildcard
|
|
70
|
+
* regardless of the bind mode. Plain master's `server/src/app.ts` does exactly
|
|
71
|
+
* this, which is why forcing the bind is necessary but not sufficient there.
|
|
72
|
+
*/
|
|
73
|
+
const WILDCARD_HMR_GUEST = `
|
|
74
|
+
import http from "node:http";
|
|
75
|
+
const argv = process.argv.slice(2);
|
|
76
|
+
const at = argv.indexOf("--bind-host");
|
|
77
|
+
const host = at >= 0 ? argv[at + 1] : "127.0.0.1";
|
|
78
|
+
const p = Number(process.env.PORT);
|
|
79
|
+
http.createServer((_, r) => { r.statusCode = 200; r.end("ok"); }).listen(p, host);
|
|
80
|
+
// No host argument: Vite's own HMR listener lands on the wildcard.
|
|
81
|
+
http.createServer((_, r) => { r.statusCode = 426; r.end(); }).listen(p + 10000);
|
|
82
|
+
setInterval(() => {}, 1000);
|
|
83
|
+
`;
|
|
84
|
+
/** A guest so old it has no bind flags at all and always binds the wildcard. */
|
|
85
|
+
const ALWAYS_WILDCARD_GUEST = `
|
|
86
|
+
import http from "node:http";
|
|
87
|
+
const p = Number(process.env.PORT);
|
|
88
|
+
for (const q of [p, p + 10000]) {
|
|
89
|
+
http.createServer((_, r) => { r.statusCode = 200; r.end("ok"); }).listen(q, "0.0.0.0");
|
|
90
|
+
}
|
|
91
|
+
setInterval(() => {}, 1000);
|
|
92
|
+
`;
|
|
93
|
+
beforeAll(async () => {
|
|
94
|
+
guestDir = await fs.mkdtemp(path.join(os.tmpdir(), "pap-17256-guest-"));
|
|
95
|
+
await fs.writeFile(path.join(guestDir, "dev-runner.mjs"), PRE_MANAGED_EXPOSURE_GUEST);
|
|
96
|
+
await fs.writeFile(path.join(guestDir, "dev-runner-legacy.mjs"), ALWAYS_WILDCARD_GUEST);
|
|
97
|
+
await fs.writeFile(path.join(guestDir, "dev-runner-wildcard-hmr.mjs"), WILDCARD_HMR_GUEST);
|
|
98
|
+
});
|
|
99
|
+
afterAll(async () => {
|
|
100
|
+
await fs.rm(guestDir, { recursive: true, force: true });
|
|
101
|
+
});
|
|
102
|
+
const guestCommand = (file) => `node ${path.join(guestDir, file)}`;
|
|
103
|
+
function createBroker() {
|
|
104
|
+
const calls = [];
|
|
105
|
+
let listeners = [];
|
|
106
|
+
const broker = {
|
|
107
|
+
async reserve(_runtimeId, requested) {
|
|
108
|
+
calls.push("reserve");
|
|
109
|
+
listeners = requested;
|
|
110
|
+
return { handle: HANDLE, reservedPorts: requested.map((listener) => listener.port) };
|
|
111
|
+
},
|
|
112
|
+
async expose() {
|
|
113
|
+
calls.push("expose");
|
|
114
|
+
return { handle: HANDLE, publicPorts: listeners.map((listener) => listener.port) };
|
|
115
|
+
},
|
|
116
|
+
async remove() {
|
|
117
|
+
calls.push("remove");
|
|
118
|
+
return { removedPorts: listeners.map((listener) => listener.port) };
|
|
119
|
+
},
|
|
120
|
+
async list() {
|
|
121
|
+
return [];
|
|
122
|
+
},
|
|
123
|
+
};
|
|
124
|
+
return { broker, calls };
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* A real loopback bind probe, matching production's `isLoopbackPortAvailable`.
|
|
128
|
+
*
|
|
129
|
+
* The default used to be `async () => true`, which claimed every port in the
|
|
130
|
+
* dedicated range was free. On a developer or canary host that already runs a
|
|
131
|
+
* managed lane on `42000`, that lie made the suite allocate a port something
|
|
132
|
+
* else was listening on — so the spawned guest could not bind, and every
|
|
133
|
+
* assertion downstream failed for a reason that had nothing to do with the
|
|
134
|
+
* behaviour under test. It also meant the suite exercised allocation against a
|
|
135
|
+
* range it never actually checked (PAP-17419; PAP-17255 started this with
|
|
136
|
+
* "make exposure fixture honor occupied ports").
|
|
137
|
+
*/
|
|
138
|
+
async function isLoopbackPortFree(port) {
|
|
139
|
+
return await new Promise((resolve) => {
|
|
140
|
+
const probe = net.createServer();
|
|
141
|
+
probe.unref();
|
|
142
|
+
probe.once("error", () => resolve(false));
|
|
143
|
+
probe.listen(port, "127.0.0.1", () => {
|
|
144
|
+
probe.close(() => resolve(true));
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
function installDeps(overrides) {
|
|
149
|
+
setWorkspaceRuntimeExposureDepsForTests({
|
|
150
|
+
broker: overrides.broker,
|
|
151
|
+
isPortAvailable: overrides.isPortAvailable ?? isLoopbackPortFree,
|
|
152
|
+
isBrokerAvailable: overrides.isBrokerAvailable ?? (async () => true),
|
|
153
|
+
resolveHostname: overrides.resolveHostname ?? (async () => "runner.tail123.ts.net"),
|
|
154
|
+
probeHealth: overrides.probeHealth ?? (async () => true),
|
|
155
|
+
now: () => "2026-08-11T00:00:00.000Z",
|
|
156
|
+
// The real /proc-backed diagnosis, not a fake: the fake broker below always
|
|
157
|
+
// says yes, so this is what has to catch an off-loopback bind here.
|
|
158
|
+
diagnoseListenerBinds: overrides.diagnoseListenerBinds ?? diagnoseRuntimeListenerBinds,
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
const DECLARED_EXPOSE = {
|
|
162
|
+
type: "tailscale_https",
|
|
163
|
+
hostname: "auto",
|
|
164
|
+
publicPort: "same",
|
|
165
|
+
includePaperclipViteHmr: true,
|
|
166
|
+
failurePolicy: "fail_closed",
|
|
167
|
+
};
|
|
168
|
+
/**
|
|
169
|
+
* The pre-feature Paperclip App project template, verbatim: a hard-coded HTTP
|
|
170
|
+
* `urlTemplate`, a pinned port outside the broker's dedicated range, and no
|
|
171
|
+
* exposure declaration at all.
|
|
172
|
+
*/
|
|
173
|
+
const LEGACY_HTTP_EXPOSE = {
|
|
174
|
+
type: "url",
|
|
175
|
+
urlTemplate: "http://paperclip-dev:{{port}}",
|
|
176
|
+
};
|
|
177
|
+
function startInput(options) {
|
|
178
|
+
const expose = options?.expose === undefined ? DECLARED_EXPOSE : options.expose;
|
|
179
|
+
return {
|
|
180
|
+
invocationId: "runtime-exposure-test",
|
|
181
|
+
actor: { id: null, name: "Paperclip", companyId: "aaaaaaaa-bbbb-4ccc-8ddd-eeeeeeeeeeee" },
|
|
182
|
+
issue: null,
|
|
183
|
+
workspace: {
|
|
184
|
+
baseCwd: process.cwd(),
|
|
185
|
+
source: "project_primary",
|
|
186
|
+
projectId: null,
|
|
187
|
+
workspaceId: null,
|
|
188
|
+
repoUrl: null,
|
|
189
|
+
repoRef: null,
|
|
190
|
+
strategy: "project_primary",
|
|
191
|
+
cwd: process.cwd(),
|
|
192
|
+
branchName: "test",
|
|
193
|
+
worktreePath: null,
|
|
194
|
+
warnings: [],
|
|
195
|
+
created: false,
|
|
196
|
+
},
|
|
197
|
+
executionWorkspaceId: EXECUTION_WORKSPACE_ID,
|
|
198
|
+
config: {
|
|
199
|
+
workspaceRuntime: {
|
|
200
|
+
services: [{
|
|
201
|
+
name: options?.serviceName ?? "preview",
|
|
202
|
+
command: options?.command ?? serviceCommand(),
|
|
203
|
+
port: options?.port ?? { type: "auto", envKey: "PORT" },
|
|
204
|
+
readiness: { type: "http", urlTemplate: "http://127.0.0.1:{{port}}", timeoutSec: 5 },
|
|
205
|
+
...(expose ? { expose } : {}),
|
|
206
|
+
}],
|
|
207
|
+
},
|
|
208
|
+
},
|
|
209
|
+
adapterEnv: {},
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
describe("workspace runtime tailscale_https lifecycle", () => {
|
|
213
|
+
it("reserves before spawn, exposes after backend readiness, and removes on stop", async () => {
|
|
214
|
+
const { broker, calls } = createBroker();
|
|
215
|
+
installDeps({ broker });
|
|
216
|
+
const [runtime] = await startRuntimeServicesForWorkspaceControl(startInput());
|
|
217
|
+
expect(calls.slice(0, 2)).toEqual(["reserve", "expose"]);
|
|
218
|
+
expect(runtime.port).toBeGreaterThanOrEqual(42000);
|
|
219
|
+
expect(runtime.url).toBe(`https://runner.tail123.ts.net:${runtime.port}`);
|
|
220
|
+
expect(runtime.exposure?.state).toBe("ready");
|
|
221
|
+
await stopRuntimeServicesForExecutionWorkspace({
|
|
222
|
+
executionWorkspaceId: EXECUTION_WORKSPACE_ID,
|
|
223
|
+
runtimeServiceId: runtime.id,
|
|
224
|
+
});
|
|
225
|
+
expect(calls).toEqual(["reserve", "expose", "remove"]);
|
|
226
|
+
}, 15_000);
|
|
227
|
+
it("fails closed and removes the mapping when external HTTPS validation fails", async () => {
|
|
228
|
+
const { broker, calls } = createBroker();
|
|
229
|
+
installDeps({ broker, probeHealth: async () => false });
|
|
230
|
+
await expect(startRuntimeServicesForWorkspaceControl(startInput())).rejects.toThrow(/HTTPS exposure failed/);
|
|
231
|
+
expect(calls).toEqual(["reserve", "expose", "remove"]);
|
|
232
|
+
}, 15_000);
|
|
233
|
+
});
|
|
234
|
+
describe("automatic tailscale_https default for managed worktree runtimes", () => {
|
|
235
|
+
it("defaults a legacy paperclip-dev service with no exposure block, relocating its pinned port", async () => {
|
|
236
|
+
const { broker, calls } = createBroker();
|
|
237
|
+
installDeps({ broker });
|
|
238
|
+
// Exactly the persisted pre-feature shape: pinned 45439 + HTTP urlTemplate.
|
|
239
|
+
const [runtime] = await startRuntimeServicesForWorkspaceControl(startInput({
|
|
240
|
+
serviceName: "paperclip-dev",
|
|
241
|
+
expose: LEGACY_HTTP_EXPOSE,
|
|
242
|
+
port: 45_439,
|
|
243
|
+
}));
|
|
244
|
+
expect(calls.slice(0, 2)).toEqual(["reserve", "expose"]);
|
|
245
|
+
// 45439 is outside the broker allowlist, so the pinned port cannot be kept.
|
|
246
|
+
expect(runtime.port).not.toBe(45_439);
|
|
247
|
+
expect(runtime.port).toBeGreaterThanOrEqual(42_000);
|
|
248
|
+
expect(runtime.port).toBeLessThanOrEqual(42_999);
|
|
249
|
+
// The canonical URL is the verified HTTPS origin; HTTP is never retained.
|
|
250
|
+
expect(runtime.url).toBe(`https://runner.tail123.ts.net:${runtime.port}`);
|
|
251
|
+
expect(runtime.url).not.toContain("http://");
|
|
252
|
+
expect(runtime.exposure?.state).toBe("ready");
|
|
253
|
+
}, 15_000);
|
|
254
|
+
it("keeps an existing runtime port that is already inside the dedicated range", async () => {
|
|
255
|
+
const { broker } = createBroker();
|
|
256
|
+
installDeps({ broker });
|
|
257
|
+
const [runtime] = await startRuntimeServicesForWorkspaceControl(startInput({
|
|
258
|
+
serviceName: "paperclip-dev",
|
|
259
|
+
expose: LEGACY_HTTP_EXPOSE,
|
|
260
|
+
port: 42_500,
|
|
261
|
+
}));
|
|
262
|
+
expect(runtime.port).toBe(42_500);
|
|
263
|
+
expect(runtime.url).toBe("https://runner.tail123.ts.net:42500");
|
|
264
|
+
}, 15_000);
|
|
265
|
+
it("preserves a deliberate opt-out and leaves the service on plain HTTP", async () => {
|
|
266
|
+
const { broker, calls } = createBroker();
|
|
267
|
+
installDeps({ broker });
|
|
268
|
+
const [runtime] = await startRuntimeServicesForWorkspaceControl(startInput({
|
|
269
|
+
serviceName: "paperclip-dev",
|
|
270
|
+
expose: { ...LEGACY_HTTP_EXPOSE, tailscaleHttps: false },
|
|
271
|
+
port: { type: "auto", envKey: "PORT" },
|
|
272
|
+
}));
|
|
273
|
+
expect(calls).toEqual([]);
|
|
274
|
+
expect(runtime.exposure ?? null).toBeNull();
|
|
275
|
+
expect(runtime.url).toBe(`http://paperclip-dev:${runtime.port}`);
|
|
276
|
+
}, 15_000);
|
|
277
|
+
it("leaves an unmanaged/custom service untouched", async () => {
|
|
278
|
+
const { broker, calls } = createBroker();
|
|
279
|
+
installDeps({ broker });
|
|
280
|
+
const [runtime] = await startRuntimeServicesForWorkspaceControl(startInput({
|
|
281
|
+
serviceName: "preview",
|
|
282
|
+
expose: LEGACY_HTTP_EXPOSE,
|
|
283
|
+
port: { type: "auto", envKey: "PORT" },
|
|
284
|
+
}));
|
|
285
|
+
expect(calls).toEqual([]);
|
|
286
|
+
expect(runtime.exposure ?? null).toBeNull();
|
|
287
|
+
expect(runtime.url).toBe(`http://paperclip-dev:${runtime.port}`);
|
|
288
|
+
}, 15_000);
|
|
289
|
+
it("does not default when the host broker is unavailable", async () => {
|
|
290
|
+
const { broker, calls } = createBroker();
|
|
291
|
+
installDeps({ broker, isBrokerAvailable: async () => false });
|
|
292
|
+
const [runtime] = await startRuntimeServicesForWorkspaceControl(startInput({
|
|
293
|
+
serviceName: "paperclip-dev",
|
|
294
|
+
expose: LEGACY_HTTP_EXPOSE,
|
|
295
|
+
port: { type: "auto", envKey: "PORT" },
|
|
296
|
+
}));
|
|
297
|
+
expect(calls).toEqual([]);
|
|
298
|
+
expect(runtime.exposure ?? null).toBeNull();
|
|
299
|
+
}, 15_000);
|
|
300
|
+
it("still honors an explicit opt-in when the broker socket is missing, failing loudly", async () => {
|
|
301
|
+
// A missing broker must never silently downgrade a requested HTTPS preview.
|
|
302
|
+
const { broker, calls } = createBroker();
|
|
303
|
+
const failing = {
|
|
304
|
+
...broker,
|
|
305
|
+
async reserve() {
|
|
306
|
+
calls.push("reserve");
|
|
307
|
+
throw new Error("ENOENT: broker socket missing");
|
|
308
|
+
},
|
|
309
|
+
};
|
|
310
|
+
installDeps({ broker: failing, isBrokerAvailable: async () => false });
|
|
311
|
+
await expect(startRuntimeServicesForWorkspaceControl(startInput({ serviceName: "paperclip-dev" }))).rejects.toThrow();
|
|
312
|
+
expect(calls).toEqual(["reserve"]);
|
|
313
|
+
}, 15_000);
|
|
314
|
+
it("is idempotent across repeated starts: the same port pair is reserved again", async () => {
|
|
315
|
+
const { broker, calls } = createBroker();
|
|
316
|
+
installDeps({ broker });
|
|
317
|
+
const [first] = await startRuntimeServicesForWorkspaceControl(startInput({
|
|
318
|
+
serviceName: "paperclip-dev",
|
|
319
|
+
expose: LEGACY_HTTP_EXPOSE,
|
|
320
|
+
port: 45_439,
|
|
321
|
+
}));
|
|
322
|
+
const firstPort = first.port;
|
|
323
|
+
await stopRuntimeServicesForExecutionWorkspace({
|
|
324
|
+
executionWorkspaceId: EXECUTION_WORKSPACE_ID,
|
|
325
|
+
runtimeServiceId: first.id,
|
|
326
|
+
});
|
|
327
|
+
calls.length = 0;
|
|
328
|
+
const [second] = await startRuntimeServicesForWorkspaceControl(startInput({
|
|
329
|
+
serviceName: "paperclip-dev",
|
|
330
|
+
expose: LEGACY_HTTP_EXPOSE,
|
|
331
|
+
port: 45_439,
|
|
332
|
+
}));
|
|
333
|
+
expect(calls.slice(0, 2)).toEqual(["reserve", "expose"]);
|
|
334
|
+
expect(second.port).toBe(firstPort);
|
|
335
|
+
expect(second.url).toBe(`https://runner.tail123.ts.net:${firstPort}`);
|
|
336
|
+
}, 25_000);
|
|
337
|
+
it("releases the in-flight pair claim when hostname resolution fails, so a retry storm cannot exhaust the range", async () => {
|
|
338
|
+
// The reservation keeps the winning pair's in-process claim on purpose, for
|
|
339
|
+
// the caller to release on stop/teardown. A hostname failure throws before any
|
|
340
|
+
// runtime record exists, so that teardown can never run for this pair — and
|
|
341
|
+
// removing only the broker reservation would leave the claim held. Each retry
|
|
342
|
+
// would then burn another pair and the lane would report the range exhausted
|
|
343
|
+
// rather than the real cause, a Tailscale outage.
|
|
344
|
+
const reservedAppPorts = [];
|
|
345
|
+
const broker = {
|
|
346
|
+
async reserve(_runtimeId, requested) {
|
|
347
|
+
reservedAppPorts.push(requested[0].port);
|
|
348
|
+
return { handle: HANDLE, reservedPorts: requested.map((listener) => listener.port) };
|
|
349
|
+
},
|
|
350
|
+
async expose() {
|
|
351
|
+
return { handle: HANDLE, publicPorts: [] };
|
|
352
|
+
},
|
|
353
|
+
async remove() {
|
|
354
|
+
return { removedPorts: [] };
|
|
355
|
+
},
|
|
356
|
+
async list() {
|
|
357
|
+
return [];
|
|
358
|
+
},
|
|
359
|
+
};
|
|
360
|
+
installDeps({
|
|
361
|
+
broker,
|
|
362
|
+
resolveHostname: async () => {
|
|
363
|
+
throw new Error("MagicDNS unavailable");
|
|
364
|
+
},
|
|
365
|
+
});
|
|
366
|
+
for (let attempt = 0; attempt < 3; attempt += 1) {
|
|
367
|
+
await expect(startRuntimeServicesForWorkspaceControl(startInput({ serviceName: "paperclip-dev" }))).rejects.toThrow(/MagicDNS hostname unavailable/);
|
|
368
|
+
}
|
|
369
|
+
// Every attempt reserved the same pair. A leaked claim would push each retry
|
|
370
|
+
// onto a fresh pair instead.
|
|
371
|
+
expect(reservedAppPorts).toHaveLength(3);
|
|
372
|
+
expect(new Set(reservedAppPorts).size).toBe(1);
|
|
373
|
+
}, 25_000);
|
|
374
|
+
});
|
|
375
|
+
/**
|
|
376
|
+
* PAP-17256: the deployed regression. A fresh managed lane on service index 0
|
|
377
|
+
* failed every start with `listener_ownership_mismatch` because the branch
|
|
378
|
+
* checkout it launched bound `0.0.0.0`, and the server only asked for loopback
|
|
379
|
+
* via env vars that checkout never read.
|
|
380
|
+
*/
|
|
381
|
+
describe("loopback bind is forced on the guest, not merely requested (PAP-17256)", () => {
|
|
382
|
+
it("starts a fresh service-index-0 lane whose guest only honours argv", async () => {
|
|
383
|
+
const { broker, calls } = createBroker();
|
|
384
|
+
installDeps({ broker });
|
|
385
|
+
const [runtime] = await startRuntimeServicesForWorkspaceControl(startInput({
|
|
386
|
+
serviceName: "paperclip-dev",
|
|
387
|
+
// Verbatim the command every failing lane recorded, modulo the fake guest.
|
|
388
|
+
command: `${guestCommand("dev-runner.mjs")} --bind lan`,
|
|
389
|
+
expose: LEGACY_HTTP_EXPOSE,
|
|
390
|
+
port: { type: "auto", envKey: "PORT" },
|
|
391
|
+
}));
|
|
392
|
+
// The launched command carries the loopback bind, replacing `--bind lan`.
|
|
393
|
+
expect(runtime.command).toContain("--bind custom --bind-host 127.0.0.1");
|
|
394
|
+
expect(runtime.command).not.toContain("--bind lan");
|
|
395
|
+
// And because the guest honoured it, both listeners are loopback-only, so
|
|
396
|
+
// the exposure completes instead of being denied.
|
|
397
|
+
expect(calls.slice(0, 2)).toEqual(["reserve", "expose"]);
|
|
398
|
+
expect(runtime.exposure?.state).toBe("ready");
|
|
399
|
+
expect(runtime.exposure?.lastError ?? null).toBeNull();
|
|
400
|
+
expect(runtime.port).toBeGreaterThanOrEqual(42_000);
|
|
401
|
+
expect(runtime.url).toBe(`https://runner.tail123.ts.net:${runtime.port}`);
|
|
402
|
+
// Independent confirmation on the live listeners, using the same /proc read
|
|
403
|
+
// the broker's gate performs.
|
|
404
|
+
const hmrPort = runtime.port + 10_000;
|
|
405
|
+
expect(await diagnoseRuntimeListenerBinds([runtime.port, hmrPort])).toBeNull();
|
|
406
|
+
await stopRuntimeServicesForExecutionWorkspace({
|
|
407
|
+
executionWorkspaceId: EXECUTION_WORKSPACE_ID,
|
|
408
|
+
runtimeServiceId: runtime.id,
|
|
409
|
+
});
|
|
410
|
+
expect(calls).toEqual(["reserve", "expose", "remove"]);
|
|
411
|
+
}, 20_000);
|
|
412
|
+
it("reaches a terminal failure naming the port and address when a guest still binds the wildcard", async () => {
|
|
413
|
+
const { broker, calls } = createBroker();
|
|
414
|
+
installDeps({ broker });
|
|
415
|
+
// A guest with no bind flags at all: the argv rewrite cannot reach it, so
|
|
416
|
+
// this is the residual case that must fail loudly rather than expose.
|
|
417
|
+
await expect(startRuntimeServicesForWorkspaceControl(startInput({
|
|
418
|
+
serviceName: "paperclip-dev",
|
|
419
|
+
command: guestCommand("dev-runner-legacy.mjs"),
|
|
420
|
+
expose: LEGACY_HTTP_EXPOSE,
|
|
421
|
+
port: { type: "auto", envKey: "PORT" },
|
|
422
|
+
}))).rejects.toThrow(/listener_ownership_mismatch.*(?:0\.0\.0\.0|::)/s);
|
|
423
|
+
// Terminal recovery: the reservation is released and nothing was exposed.
|
|
424
|
+
// The diagnosis runs before the broker, so `expose` is never attempted.
|
|
425
|
+
expect(calls).toEqual(["reserve", "remove"]);
|
|
426
|
+
}, 20_000);
|
|
427
|
+
it("explains rather than only coding the failure, so the next operator can act", async () => {
|
|
428
|
+
const { broker } = createBroker();
|
|
429
|
+
installDeps({ broker });
|
|
430
|
+
const error = await startRuntimeServicesForWorkspaceControl(startInput({
|
|
431
|
+
serviceName: "paperclip-dev",
|
|
432
|
+
command: guestCommand("dev-runner-legacy.mjs"),
|
|
433
|
+
expose: LEGACY_HTTP_EXPOSE,
|
|
434
|
+
port: { type: "auto", envKey: "PORT" },
|
|
435
|
+
})).then(() => null, (err) => err);
|
|
436
|
+
expect(error).not.toBeNull();
|
|
437
|
+
// The bare code alone is what cost PAP-17254 three diagnostic cycles.
|
|
438
|
+
expect(error.message).toContain("listener_ownership_mismatch");
|
|
439
|
+
expect(error.message).toContain("loopback");
|
|
440
|
+
expect(error.message).toContain("--bind custom --bind-host 127.0.0.1");
|
|
441
|
+
}, 20_000);
|
|
442
|
+
it("leaves a non-Paperclip service's --bind argument alone", async () => {
|
|
443
|
+
// `--bind` means something entirely different to the HTTPS probe canaries
|
|
444
|
+
// (`python3 -m http.server --bind 127.0.0.1`); rewriting it would break them.
|
|
445
|
+
const { broker, calls } = createBroker();
|
|
446
|
+
installDeps({ broker });
|
|
447
|
+
const declared = `${serviceCommand()} -- --bind 127.0.0.1`;
|
|
448
|
+
const [runtime] = await startRuntimeServicesForWorkspaceControl(startInput({
|
|
449
|
+
serviceName: "https-probe-canary",
|
|
450
|
+
command: declared,
|
|
451
|
+
port: { type: "auto", envKey: "PORT" },
|
|
452
|
+
}));
|
|
453
|
+
expect(runtime.command).toBe(declared);
|
|
454
|
+
expect(runtime.command).not.toContain("--bind custom");
|
|
455
|
+
expect(calls.slice(0, 2)).toEqual(["reserve", "expose"]);
|
|
456
|
+
expect(runtime.exposure?.state).toBe("ready");
|
|
457
|
+
}, 20_000);
|
|
458
|
+
it("does not rewrite a Paperclip dev command when the service is not exposed", async () => {
|
|
459
|
+
const { broker, calls } = createBroker();
|
|
460
|
+
installDeps({ broker });
|
|
461
|
+
const declared = `${guestCommand("dev-runner.mjs")} --bind lan`;
|
|
462
|
+
const [runtime] = await startRuntimeServicesForWorkspaceControl(startInput({
|
|
463
|
+
serviceName: "paperclip-dev",
|
|
464
|
+
command: declared,
|
|
465
|
+
expose: { ...LEGACY_HTTP_EXPOSE, tailscaleHttps: false },
|
|
466
|
+
port: { type: "auto", envKey: "PORT" },
|
|
467
|
+
}));
|
|
468
|
+
expect(calls).toEqual([]);
|
|
469
|
+
expect(runtime.command).toBe(declared);
|
|
470
|
+
}, 20_000);
|
|
471
|
+
});
|
|
472
|
+
describe("readiness probes loopback for an exposed runtime (PAP-17256)", () => {
|
|
473
|
+
it("starts even when the only readiness target is the MagicDNS display URL", async () => {
|
|
474
|
+
// The live project config declares a loopback readiness URL, but when it does
|
|
475
|
+
// not, readiness falls back to `expose.urlTemplate` — a MagicDNS name that
|
|
476
|
+
// resolves off-loopback. That only ever answered because the guest was bound
|
|
477
|
+
// to the wildcard, so it must be normalised alongside the bind fix.
|
|
478
|
+
const { broker, calls } = createBroker();
|
|
479
|
+
installDeps({ broker });
|
|
480
|
+
const input = startInput({
|
|
481
|
+
serviceName: "paperclip-dev",
|
|
482
|
+
command: `${guestCommand("dev-runner.mjs")} --bind lan`,
|
|
483
|
+
expose: LEGACY_HTTP_EXPOSE,
|
|
484
|
+
port: { type: "auto", envKey: "PORT" },
|
|
485
|
+
});
|
|
486
|
+
// Drop the explicit loopback readiness URL so the fallback path is exercised.
|
|
487
|
+
const service = input.config.workspaceRuntime.services[0];
|
|
488
|
+
service.readiness = { type: "http", timeoutSec: 10, intervalMs: 100 };
|
|
489
|
+
const [runtime] = await startRuntimeServicesForWorkspaceControl(input);
|
|
490
|
+
expect(calls.slice(0, 2)).toEqual(["reserve", "expose"]);
|
|
491
|
+
expect(runtime.exposure?.state).toBe("ready");
|
|
492
|
+
expect(runtime.url).toBe(`https://runner.tail123.ts.net:${runtime.port}`);
|
|
493
|
+
}, 20_000);
|
|
494
|
+
});
|
|
495
|
+
describe("the deployed failure shape: loopback app port, wildcard HMR (PAP-17256)", () => {
|
|
496
|
+
it("fails terminally naming the HMR port, because forcing the bind cannot reach Vite's own listener", async () => {
|
|
497
|
+
// Plain master's app.ts passes Vite `hmr.port` without `hmr.server` or
|
|
498
|
+
// `server.host`, so the HMR websocket binds `::` no matter what the bind mode
|
|
499
|
+
// is. The argv rewrite fixes the app port; only the preflight catches this.
|
|
500
|
+
const { broker, calls } = createBroker();
|
|
501
|
+
installDeps({ broker });
|
|
502
|
+
const error = await startRuntimeServicesForWorkspaceControl(startInput({
|
|
503
|
+
serviceName: "paperclip-dev",
|
|
504
|
+
command: `${guestCommand("dev-runner-wildcard-hmr.mjs")} --bind lan`,
|
|
505
|
+
expose: LEGACY_HTTP_EXPOSE,
|
|
506
|
+
port: { type: "auto", envKey: "PORT" },
|
|
507
|
+
})).then(() => null, (err) => err);
|
|
508
|
+
expect(error).not.toBeNull();
|
|
509
|
+
expect(error.message).toContain("listener_ownership_mismatch");
|
|
510
|
+
// The app port obeyed the forced bind; the HMR companion is the offender, and
|
|
511
|
+
// the diagnosis has to say so rather than blaming the lane as a whole.
|
|
512
|
+
expect(error.message).toMatch(/port 5\d{4} is bound to/);
|
|
513
|
+
expect(error.message).not.toMatch(/port 4\d{4} is bound to/);
|
|
514
|
+
expect(calls).toEqual(["reserve", "remove"]);
|
|
515
|
+
}, 20_000);
|
|
516
|
+
});
|
|
517
|
+
//# sourceMappingURL=workspace-runtime-exposure.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace-runtime-exposure.test.js","sourceRoot":"","sources":["../../src/services/workspace-runtime-exposure.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import type { Db } from "@paperclipai/db";
|
|
2
|
+
import { executionWorkspaceRuntimeLeases } from "@paperclipai/db";
|
|
3
|
+
type ExecutionWorkspaceRuntimeLeaseRow = typeof executionWorkspaceRuntimeLeases.$inferSelect;
|
|
4
|
+
/**
|
|
5
|
+
* Issue statuses that keep an issue eligible to drive workspace runtime controls.
|
|
6
|
+
* Shared with the runtime authorization path so "still authorized" and "still owns
|
|
7
|
+
* the lease" cannot drift apart.
|
|
8
|
+
*/
|
|
9
|
+
export declare const WORKSPACE_RUNTIME_ELIGIBLE_ISSUE_STATUSES: readonly string[];
|
|
10
|
+
/** Runtime control actions that mutate the workspace and therefore need the lease. */
|
|
11
|
+
export declare const LEASED_WORKSPACE_RUNTIME_ACTIONS: readonly string[];
|
|
12
|
+
/**
|
|
13
|
+
* Upper bound on how long a lease survives without the owner touching it. Recovery
|
|
14
|
+
* from a stale owner is otherwise driven by owner eligibility, which is cheaper and
|
|
15
|
+
* more precise; the TTL only bounds the cases eligibility cannot see (for example an
|
|
16
|
+
* agent-scoped owner with no run or issue identity).
|
|
17
|
+
*/
|
|
18
|
+
export declare const WORKSPACE_RUNTIME_LEASE_TTL_MS: number;
|
|
19
|
+
export type WorkspaceRuntimeLeaseOwner = {
|
|
20
|
+
actorType: string;
|
|
21
|
+
agentId?: string | null;
|
|
22
|
+
runId?: string | null;
|
|
23
|
+
issueId?: string | null;
|
|
24
|
+
};
|
|
25
|
+
export type WorkspaceRuntimeLeaseStaleReason = "lease_expired" | "owner_issue_missing" | "owner_issue_hidden" | "owner_issue_terminal" | "owner_run_missing" | "owner_run_terminal";
|
|
26
|
+
export type WorkspaceRuntimeLeaseClaim = {
|
|
27
|
+
outcome: "created" | "renewed" | "reclaimed" | "bypassed";
|
|
28
|
+
ownerKey: string | null;
|
|
29
|
+
lease: ExecutionWorkspaceRuntimeLeaseRow | null;
|
|
30
|
+
reclaimedFrom: {
|
|
31
|
+
ownerKey: string;
|
|
32
|
+
reason: WorkspaceRuntimeLeaseStaleReason;
|
|
33
|
+
} | null;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Durable owner identity for a lease. The controlling issue is preferred because a
|
|
37
|
+
* canary lane outlives any single heartbeat run; runs and bare agent keys are only
|
|
38
|
+
* used when no issue is in scope.
|
|
39
|
+
*/
|
|
40
|
+
export declare function buildWorkspaceRuntimeLeaseOwnerKey(owner: WorkspaceRuntimeLeaseOwner): string | null;
|
|
41
|
+
export declare function workspaceRuntimeLeaseService(db: Db): {
|
|
42
|
+
get(executionWorkspaceId: string): Promise<{
|
|
43
|
+
id: string;
|
|
44
|
+
companyId: string;
|
|
45
|
+
executionWorkspaceId: string;
|
|
46
|
+
ownerKey: string;
|
|
47
|
+
ownerIssueId: string | null;
|
|
48
|
+
ownerRunId: string | null;
|
|
49
|
+
ownerAgentId: string | null;
|
|
50
|
+
lastAction: string;
|
|
51
|
+
claimedAt: Date;
|
|
52
|
+
renewedAt: Date;
|
|
53
|
+
expiresAt: Date;
|
|
54
|
+
metadata: Record<string, unknown> | null;
|
|
55
|
+
createdAt: Date;
|
|
56
|
+
updatedAt: Date;
|
|
57
|
+
}>;
|
|
58
|
+
/**
|
|
59
|
+
* Atomically claim (or renew, or reclaim from a stale owner) the exclusive runtime
|
|
60
|
+
* lease for an execution workspace. Cross-process exclusivity comes from the unique
|
|
61
|
+
* constraint on execution_workspace_id plus a `SELECT ... FOR UPDATE` on the existing
|
|
62
|
+
* row, so competing claims serialize in the database rather than in one process.
|
|
63
|
+
*
|
|
64
|
+
* Board/operator actors bypass the lease entirely: they keep unconditional control
|
|
65
|
+
* and never take the lane away from an agent run.
|
|
66
|
+
*/
|
|
67
|
+
claim(input: {
|
|
68
|
+
companyId: string;
|
|
69
|
+
executionWorkspaceId: string;
|
|
70
|
+
action: string;
|
|
71
|
+
owner: WorkspaceRuntimeLeaseOwner;
|
|
72
|
+
now?: Date;
|
|
73
|
+
ttlMs?: number;
|
|
74
|
+
}): Promise<WorkspaceRuntimeLeaseClaim>;
|
|
75
|
+
/**
|
|
76
|
+
* Give up the lane. `force` is for operator/lifecycle paths (workspace archive);
|
|
77
|
+
* owner-scoped releases only remove a lease the caller actually holds.
|
|
78
|
+
*/
|
|
79
|
+
release(input: {
|
|
80
|
+
executionWorkspaceId: string;
|
|
81
|
+
owner?: WorkspaceRuntimeLeaseOwner;
|
|
82
|
+
force?: boolean;
|
|
83
|
+
}): Promise<{
|
|
84
|
+
released: boolean;
|
|
85
|
+
ownerKey: string | null;
|
|
86
|
+
}>;
|
|
87
|
+
};
|
|
88
|
+
export type WorkspaceRuntimeLeaseService = ReturnType<typeof workspaceRuntimeLeaseService>;
|
|
89
|
+
export {};
|
|
90
|
+
//# sourceMappingURL=workspace-runtime-leases.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace-runtime-leases.d.ts","sourceRoot":"","sources":["../../src/services/workspace-runtime-leases.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,iBAAiB,CAAC;AAC1C,OAAO,EAAE,+BAA+B,EAAyB,MAAM,iBAAiB,CAAC;AAGzF,KAAK,iCAAiC,GAAG,OAAO,+BAA+B,CAAC,YAAY,CAAC;AAG7F;;;;GAIG;AACH,eAAO,MAAM,yCAAyC,EAAE,SAAS,MAAM,EAMtE,CAAC;AAUF,sFAAsF;AACtF,eAAO,MAAM,gCAAgC,EAAE,SAAS,MAAM,EAAiC,CAAC;AAEhG;;;;;GAKG;AACH,eAAO,MAAM,8BAA8B,QAAiB,CAAC;AAE7D,MAAM,MAAM,0BAA0B,GAAG;IACvC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,gCAAgC,GACxC,eAAe,GACf,qBAAqB,GACrB,oBAAoB,GACpB,sBAAsB,GACtB,mBAAmB,GACnB,oBAAoB,CAAC;AAEzB,MAAM,MAAM,0BAA0B,GAAG;IACvC,OAAO,EAAE,SAAS,GAAG,SAAS,GAAG,WAAW,GAAG,UAAU,CAAC;IAC1D,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,KAAK,EAAE,iCAAiC,GAAG,IAAI,CAAC;IAChD,aAAa,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,gCAAgC,CAAA;KAAE,GAAG,IAAI,CAAC;CACtF,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,kCAAkC,CAAC,KAAK,EAAE,0BAA0B,GAAG,MAAM,GAAG,IAAI,CAKnG;AA2ED,wBAAgB,4BAA4B,CAAC,EAAE,EAAE,EAAE;8BAEf,MAAM;;;;;;;;;;;;;;;;IAQtC;;;;;;;;OAQG;iBACgB;QACjB,SAAS,EAAE,MAAM,CAAC;QAClB,oBAAoB,EAAE,MAAM,CAAC;QAC7B,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,EAAE,0BAA0B,CAAC;QAClC,GAAG,CAAC,EAAE,IAAI,CAAC;QACX,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,GAAG,OAAO,CAAC,0BAA0B,CAAC;IAiHvC;;;OAGG;mBACkB;QACnB,oBAAoB,EAAE,MAAM,CAAC;QAC7B,KAAK,CAAC,EAAE,0BAA0B,CAAC;QACnC,KAAK,CAAC,EAAE,OAAO,CAAC;KACjB,GAAG,OAAO,CAAC;QAAE,QAAQ,EAAE,OAAO,CAAC;QAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;EAoB9D;AAED,MAAM,MAAM,4BAA4B,GAAG,UAAU,CAAC,OAAO,4BAA4B,CAAC,CAAC"}
|