@pellux/goodvibes-sdk 0.21.30 → 0.21.33
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/_internal/contracts/zod-schemas/accounts.d.ts +9 -9
- package/dist/_internal/contracts/zod-schemas/auth.d.ts +1 -1
- package/dist/_internal/daemon/context.d.ts +1 -0
- package/dist/_internal/daemon/context.d.ts.map +1 -1
- package/dist/_internal/daemon/error-response.js +22 -22
- package/dist/_internal/daemon/integration-route-types.d.ts +2 -1
- package/dist/_internal/daemon/integration-route-types.d.ts.map +1 -1
- package/dist/_internal/daemon/knowledge-routes.js +5 -5
- package/dist/_internal/daemon/media-routes.d.ts.map +1 -1
- package/dist/_internal/daemon/media-routes.js +4 -3
- package/dist/_internal/daemon/operator.d.ts +1 -1
- package/dist/_internal/daemon/operator.d.ts.map +1 -1
- package/dist/_internal/daemon/operator.js +2 -0
- package/dist/_internal/daemon/runtime-route-types.d.ts +2 -1
- package/dist/_internal/daemon/runtime-route-types.d.ts.map +1 -1
- package/dist/_internal/daemon/runtime-routes.d.ts +1 -1
- package/dist/_internal/daemon/runtime-routes.d.ts.map +1 -1
- package/dist/_internal/daemon/runtime-routes.js +1 -0
- package/dist/_internal/daemon/telemetry-routes.d.ts.map +1 -1
- package/dist/_internal/daemon/telemetry-routes.js +13 -12
- package/dist/_internal/errors/daemon-error-contract.d.ts +17 -0
- package/dist/_internal/errors/daemon-error-contract.d.ts.map +1 -1
- package/dist/_internal/errors/daemon-error-contract.js +17 -1
- package/dist/_internal/errors/index.d.ts +2 -1
- package/dist/_internal/errors/index.d.ts.map +1 -1
- package/dist/_internal/errors/index.js +1 -0
- package/dist/_internal/platform/artifacts/store.d.ts.map +1 -1
- package/dist/_internal/platform/artifacts/store.js +2 -1
- package/dist/_internal/platform/automation/scheduler-capacity.d.ts +29 -0
- package/dist/_internal/platform/automation/scheduler-capacity.d.ts.map +1 -0
- package/dist/_internal/platform/automation/scheduler-capacity.js +31 -0
- package/dist/_internal/platform/channels/delivery/shared.d.ts.map +1 -1
- package/dist/_internal/platform/channels/delivery/shared.js +3 -2
- package/dist/_internal/platform/channels/delivery/strategies-bridge.d.ts.map +1 -1
- package/dist/_internal/platform/channels/delivery/strategies-bridge.js +3 -2
- package/dist/_internal/platform/channels/delivery/strategies-core.d.ts.map +1 -1
- package/dist/_internal/platform/channels/delivery/strategies-core.js +5 -4
- package/dist/_internal/platform/channels/delivery/strategies-enterprise.d.ts.map +1 -1
- package/dist/_internal/platform/channels/delivery/strategies-enterprise.js +4 -3
- package/dist/_internal/platform/config/manager.d.ts.map +1 -1
- package/dist/_internal/platform/config/manager.js +2 -1
- package/dist/_internal/platform/config/schema-domain-runtime.d.ts +6 -0
- package/dist/_internal/platform/config/schema-domain-runtime.d.ts.map +1 -1
- package/dist/_internal/platform/config/schema-domain-runtime.js +22 -0
- package/dist/_internal/platform/config/schema-types.d.ts +16 -2
- package/dist/_internal/platform/config/schema-types.d.ts.map +1 -1
- package/dist/_internal/platform/config/schema.d.ts.map +1 -1
- package/dist/_internal/platform/config/schema.js +1 -0
- package/dist/_internal/platform/config/service-registry.d.ts.map +1 -1
- package/dist/_internal/platform/config/service-registry.js +2 -1
- package/dist/_internal/platform/control-plane/gateway-web-ui.d.ts +0 -1
- package/dist/_internal/platform/control-plane/gateway-web-ui.d.ts.map +1 -1
- package/dist/_internal/platform/control-plane/gateway-web-ui.js +7 -6
- package/dist/_internal/platform/control-plane/session-broker.d.ts.map +1 -1
- package/dist/_internal/platform/control-plane/session-broker.js +12 -4
- package/dist/_internal/platform/core/orchestrator-tool-runtime.d.ts.map +1 -1
- package/dist/_internal/platform/core/orchestrator-tool-runtime.js +6 -6
- package/dist/_internal/platform/core/orchestrator-turn-loop.d.ts.map +1 -1
- package/dist/_internal/platform/core/orchestrator-turn-loop.js +10 -2
- package/dist/_internal/platform/daemon/facade-composition.d.ts +4 -131
- package/dist/_internal/platform/daemon/facade-composition.d.ts.map +1 -1
- package/dist/_internal/platform/daemon/facade-composition.js +9 -10
- package/dist/_internal/platform/daemon/facade-types.d.ts +141 -0
- package/dist/_internal/platform/daemon/facade-types.d.ts.map +1 -0
- package/dist/_internal/platform/daemon/facade-types.js +1 -0
- package/dist/_internal/platform/daemon/http/rate-limiter.d.ts +23 -0
- package/dist/_internal/platform/daemon/http/rate-limiter.d.ts.map +1 -0
- package/dist/_internal/platform/daemon/http/rate-limiter.js +71 -0
- package/dist/_internal/platform/daemon/http/router-route-contexts.d.ts.map +1 -1
- package/dist/_internal/platform/daemon/http/router-route-contexts.js +2 -1
- package/dist/_internal/platform/daemon/http/router.d.ts.map +1 -1
- package/dist/_internal/platform/daemon/http/router.js +70 -65
- package/dist/_internal/platform/daemon/http/runtime-route-types.d.ts.map +1 -1
- package/dist/_internal/platform/daemon/http-listener.d.ts +1 -0
- package/dist/_internal/platform/daemon/http-listener.d.ts.map +1 -1
- package/dist/_internal/platform/daemon/http-listener.js +53 -73
- package/dist/_internal/platform/daemon/surface-delivery.d.ts.map +1 -1
- package/dist/_internal/platform/daemon/surface-delivery.js +6 -5
- package/dist/_internal/platform/discovery/mcp-scanner.d.ts.map +1 -1
- package/dist/_internal/platform/discovery/mcp-scanner.js +28 -22
- package/dist/_internal/platform/discovery/scanner.d.ts.map +1 -1
- package/dist/_internal/platform/discovery/scanner.js +38 -22
- package/dist/_internal/platform/export/session-export.d.ts +0 -1
- package/dist/_internal/platform/export/session-export.d.ts.map +1 -1
- package/dist/_internal/platform/export/session-export.js +1 -33
- package/dist/_internal/platform/hooks/runners/http.d.ts.map +1 -1
- package/dist/_internal/platform/hooks/runners/http.js +2 -1
- package/dist/_internal/platform/integrations/delivery.d.ts +3 -1
- package/dist/_internal/platform/integrations/delivery.d.ts.map +1 -1
- package/dist/_internal/platform/integrations/delivery.js +3 -2
- package/dist/_internal/platform/integrations/discord.d.ts.map +1 -1
- package/dist/_internal/platform/integrations/discord.js +6 -5
- package/dist/_internal/platform/integrations/ntfy.d.ts.map +1 -1
- package/dist/_internal/platform/integrations/ntfy.js +3 -2
- package/dist/_internal/platform/integrations/webhooks.d.ts.map +1 -1
- package/dist/_internal/platform/integrations/webhooks.js +2 -1
- package/dist/_internal/platform/intelligence/lsp/binary-downloader.d.ts.map +1 -1
- package/dist/_internal/platform/intelligence/lsp/binary-downloader.js +4 -3
- package/dist/_internal/platform/knowledge/store.d.ts.map +1 -1
- package/dist/_internal/platform/knowledge/store.js +50 -25
- package/dist/_internal/platform/mcp/client.d.ts.map +1 -1
- package/dist/_internal/platform/mcp/client.js +3 -2
- package/dist/_internal/platform/media/builtin-generation-providers.d.ts.map +1 -1
- package/dist/_internal/platform/media/builtin-generation-providers.js +4 -3
- package/dist/_internal/platform/media/builtin-image-understanding.d.ts.map +1 -1
- package/dist/_internal/platform/media/builtin-image-understanding.js +5 -4
- package/dist/_internal/platform/providers/anthropic-compat.d.ts.map +1 -1
- package/dist/_internal/platform/providers/anthropic-compat.js +5 -3
- package/dist/_internal/platform/providers/anthropic.d.ts.map +1 -1
- package/dist/_internal/platform/providers/anthropic.js +10 -7
- package/dist/_internal/platform/providers/builtin-catalog.d.ts.map +1 -1
- package/dist/_internal/platform/providers/builtin-catalog.js +3 -2
- package/dist/_internal/platform/providers/catalogue.d.ts +56 -0
- package/dist/_internal/platform/providers/catalogue.d.ts.map +1 -0
- package/dist/_internal/platform/providers/catalogue.js +111 -0
- package/dist/_internal/platform/providers/context-discovery.d.ts.map +1 -1
- package/dist/_internal/platform/providers/context-discovery.js +2 -1
- package/dist/_internal/platform/providers/credentials.d.ts +12 -0
- package/dist/_internal/platform/providers/credentials.d.ts.map +1 -0
- package/dist/_internal/platform/providers/credentials.js +54 -0
- package/dist/_internal/platform/providers/gemini.d.ts.map +1 -1
- package/dist/_internal/platform/providers/gemini.js +6 -5
- package/dist/_internal/platform/providers/github-copilot.d.ts.map +1 -1
- package/dist/_internal/platform/providers/github-copilot.js +2 -1
- package/dist/_internal/platform/providers/health.d.ts +15 -0
- package/dist/_internal/platform/providers/health.d.ts.map +1 -0
- package/dist/_internal/platform/providers/health.js +32 -0
- package/dist/_internal/platform/providers/llama-cpp.d.ts.map +1 -1
- package/dist/_internal/platform/providers/llama-cpp.js +5 -3
- package/dist/_internal/platform/providers/lm-studio.d.ts.map +1 -1
- package/dist/_internal/platform/providers/lm-studio.js +5 -3
- package/dist/_internal/platform/providers/model-benchmarks.d.ts.map +1 -1
- package/dist/_internal/platform/providers/model-benchmarks.js +2 -1
- package/dist/_internal/platform/providers/model-catalog-cache.d.ts.map +1 -1
- package/dist/_internal/platform/providers/model-catalog-cache.js +2 -1
- package/dist/_internal/platform/providers/model-limits.d.ts.map +1 -1
- package/dist/_internal/platform/providers/model-limits.js +2 -1
- package/dist/_internal/platform/providers/ollama.d.ts.map +1 -1
- package/dist/_internal/platform/providers/ollama.js +5 -3
- package/dist/_internal/platform/providers/openai-codex.d.ts.map +1 -1
- package/dist/_internal/platform/providers/openai-codex.js +4 -2
- package/dist/_internal/platform/providers/openai-compat.d.ts.map +1 -1
- package/dist/_internal/platform/providers/openai-compat.js +3 -2
- package/dist/_internal/platform/providers/provider-not-found-error.d.ts +3 -1
- package/dist/_internal/platform/providers/provider-not-found-error.d.ts.map +1 -1
- package/dist/_internal/platform/providers/provider-not-found-error.js +3 -4
- package/dist/_internal/platform/providers/well-known-endpoints.d.ts +53 -0
- package/dist/_internal/platform/providers/well-known-endpoints.d.ts.map +1 -0
- package/dist/_internal/platform/providers/well-known-endpoints.js +52 -0
- package/dist/_internal/platform/runtime/auth/oauth-core.d.ts.map +1 -1
- package/dist/_internal/platform/runtime/auth/oauth-core.js +2 -1
- package/dist/_internal/platform/runtime/contracts/index.d.ts.map +1 -1
- package/dist/_internal/platform/runtime/contracts/index.js +1 -5
- package/dist/_internal/platform/runtime/contracts/migrations/schemas.d.ts +57 -0
- package/dist/_internal/platform/runtime/contracts/migrations/schemas.d.ts.map +1 -0
- package/dist/_internal/platform/runtime/contracts/migrations/schemas.js +157 -0
- package/dist/_internal/platform/runtime/correlation.d.ts +44 -0
- package/dist/_internal/platform/runtime/correlation.d.ts.map +1 -0
- package/dist/_internal/platform/runtime/correlation.js +40 -0
- package/dist/_internal/platform/runtime/emitters/security.d.ts +32 -0
- package/dist/_internal/platform/runtime/emitters/security.d.ts.map +1 -1
- package/dist/_internal/platform/runtime/emitters/security.js +26 -0
- package/dist/_internal/platform/runtime/emitters/tools.d.ts +11 -2
- package/dist/_internal/platform/runtime/emitters/tools.d.ts.map +1 -1
- package/dist/_internal/platform/runtime/emitters/tools.js +27 -0
- package/dist/_internal/platform/runtime/emitters/transport.d.ts +27 -0
- package/dist/_internal/platform/runtime/emitters/transport.d.ts.map +1 -1
- package/dist/_internal/platform/runtime/emitters/transport.js +19 -0
- package/dist/_internal/platform/runtime/emitters/turn.d.ts +22 -1
- package/dist/_internal/platform/runtime/emitters/turn.d.ts.map +1 -1
- package/dist/_internal/platform/runtime/emitters/turn.js +9 -0
- package/dist/_internal/platform/runtime/events/index.d.ts +45 -0
- package/dist/_internal/platform/runtime/events/index.d.ts.map +1 -1
- package/dist/_internal/platform/runtime/events/index.js +108 -14
- package/dist/_internal/platform/runtime/events/ops.d.ts +8 -0
- package/dist/_internal/platform/runtime/events/ops.d.ts.map +1 -1
- package/dist/_internal/platform/runtime/events/security.d.ts +47 -0
- package/dist/_internal/platform/runtime/events/security.d.ts.map +1 -1
- package/dist/_internal/platform/runtime/events/tools.d.ts +14 -2
- package/dist/_internal/platform/runtime/events/tools.d.ts.map +1 -1
- package/dist/_internal/platform/runtime/events/transport.d.ts +31 -0
- package/dist/_internal/platform/runtime/events/transport.d.ts.map +1 -1
- package/dist/_internal/platform/runtime/events/turn.d.ts +25 -1
- package/dist/_internal/platform/runtime/events/turn.d.ts.map +1 -1
- package/dist/_internal/platform/runtime/events/workspace.d.ts +16 -0
- package/dist/_internal/platform/runtime/events/workspace.d.ts.map +1 -1
- package/dist/_internal/platform/runtime/llm-observability.d.ts +43 -0
- package/dist/_internal/platform/runtime/llm-observability.d.ts.map +1 -0
- package/dist/_internal/platform/runtime/llm-observability.js +107 -0
- package/dist/_internal/platform/runtime/metrics.d.ts +49 -0
- package/dist/_internal/platform/runtime/metrics.d.ts.map +1 -0
- package/dist/_internal/platform/runtime/metrics.js +114 -0
- package/dist/_internal/platform/runtime/ops/control-plane.d.ts +5 -2
- package/dist/_internal/platform/runtime/ops/control-plane.d.ts.map +1 -1
- package/dist/_internal/platform/runtime/ops/control-plane.js +5 -4
- package/dist/_internal/platform/runtime/permissions/divergence-dashboard.d.ts +3 -1
- package/dist/_internal/platform/runtime/permissions/divergence-dashboard.d.ts.map +1 -1
- package/dist/_internal/platform/runtime/permissions/divergence-dashboard.js +3 -2
- package/dist/_internal/platform/runtime/permissions/policy-loader.d.ts +3 -1
- package/dist/_internal/platform/runtime/permissions/policy-loader.d.ts.map +1 -1
- package/dist/_internal/platform/runtime/permissions/policy-loader.js +3 -2
- package/dist/_internal/platform/runtime/permissions/policy-signer.d.ts.map +1 -1
- package/dist/_internal/platform/runtime/permissions/policy-signer.js +7 -2
- package/dist/_internal/platform/runtime/permissions/simulation.d.ts +3 -1
- package/dist/_internal/platform/runtime/permissions/simulation.d.ts.map +1 -1
- package/dist/_internal/platform/runtime/permissions/simulation.js +3 -2
- package/dist/_internal/platform/runtime/remote/transport-contract.d.ts +14 -2
- package/dist/_internal/platform/runtime/remote/transport-contract.d.ts.map +1 -1
- package/dist/_internal/platform/runtime/remote/transport-contract.js +7 -5
- package/dist/_internal/platform/runtime/store/helpers/reducers/sync.d.ts.map +1 -1
- package/dist/_internal/platform/runtime/store/helpers/reducers/sync.js +12 -1
- package/dist/_internal/platform/runtime/tasks/manager.d.ts +7 -3
- package/dist/_internal/platform/runtime/tasks/manager.d.ts.map +1 -1
- package/dist/_internal/platform/runtime/tasks/manager.js +7 -6
- package/dist/_internal/platform/runtime/telemetry/api-helpers.d.ts +14 -0
- package/dist/_internal/platform/runtime/telemetry/api-helpers.d.ts.map +1 -1
- package/dist/_internal/platform/runtime/telemetry/api-helpers.js +59 -0
- package/dist/_internal/platform/runtime/telemetry/api.d.ts.map +1 -1
- package/dist/_internal/platform/runtime/telemetry/api.js +9 -2
- package/dist/_internal/platform/runtime/telemetry/exporters/otlp.d.ts.map +1 -1
- package/dist/_internal/platform/runtime/telemetry/exporters/otlp.js +19 -6
- package/dist/_internal/platform/runtime/telemetry/exporters/queue.d.ts.map +1 -1
- package/dist/_internal/platform/runtime/telemetry/exporters/queue.js +11 -4
- package/dist/_internal/platform/runtime/telemetry/meter.d.ts.map +1 -1
- package/dist/_internal/platform/runtime/telemetry/meter.js +7 -3
- package/dist/_internal/platform/runtime/telemetry/redaction-config.d.ts +9 -0
- package/dist/_internal/platform/runtime/telemetry/redaction-config.d.ts.map +1 -0
- package/dist/_internal/platform/runtime/telemetry/redaction-config.js +52 -0
- package/dist/_internal/platform/runtime/tools/phases/budget.d.ts.map +1 -1
- package/dist/_internal/platform/runtime/tools/phases/budget.js +3 -2
- package/dist/_internal/platform/runtime/transports/daemon-http-client.d.ts.map +1 -1
- package/dist/_internal/platform/runtime/transports/daemon-http-client.js +138 -17
- package/dist/_internal/platform/scheduler/scheduler.d.ts.map +1 -1
- package/dist/_internal/platform/scheduler/scheduler.js +6 -2
- package/dist/_internal/platform/sessions/manager.d.ts.map +1 -1
- package/dist/_internal/platform/sessions/manager.js +6 -2
- package/dist/_internal/platform/state/memory-embedding-http.d.ts.map +1 -1
- package/dist/_internal/platform/state/memory-embedding-http.js +3 -2
- package/dist/_internal/platform/state/project-index.d.ts.map +1 -1
- package/dist/_internal/platform/state/project-index.js +6 -4
- package/dist/_internal/platform/tools/agent/index.d.ts.map +1 -1
- package/dist/_internal/platform/tools/agent/index.js +2 -1
- package/dist/_internal/platform/tools/analyze/git-modes.d.ts.map +1 -1
- package/dist/_internal/platform/tools/analyze/git-modes.js +2 -1
- package/dist/_internal/platform/tools/edit/core.d.ts.map +1 -1
- package/dist/_internal/platform/tools/edit/core.js +2 -1
- package/dist/_internal/platform/tools/exec/runtime.d.ts.map +1 -1
- package/dist/_internal/platform/tools/exec/runtime.js +3 -2
- package/dist/_internal/platform/tools/fetch/runtime.d.ts.map +1 -1
- package/dist/_internal/platform/tools/fetch/runtime.js +4 -2
- package/dist/_internal/platform/tools/read/index.d.ts.map +1 -1
- package/dist/_internal/platform/tools/read/index.js +2 -1
- package/dist/_internal/platform/tools/registry-tool/index.d.ts.map +1 -1
- package/dist/_internal/platform/tools/registry-tool/index.js +2 -1
- package/dist/_internal/platform/tools/state/index.d.ts.map +1 -1
- package/dist/_internal/platform/tools/state/index.js +2 -1
- package/dist/_internal/platform/tools/task/index.d.ts.map +1 -1
- package/dist/_internal/platform/tools/task/index.js +2 -1
- package/dist/_internal/platform/tools/team/index.d.ts.map +1 -1
- package/dist/_internal/platform/tools/team/index.js +2 -1
- package/dist/_internal/platform/tools/web-search/index.d.ts.map +1 -1
- package/dist/_internal/platform/tools/web-search/index.js +2 -1
- package/dist/_internal/platform/tools/worklist/index.d.ts.map +1 -1
- package/dist/_internal/platform/tools/worklist/index.js +2 -1
- package/dist/_internal/platform/types/errors.d.ts +12 -10
- package/dist/_internal/platform/types/errors.d.ts.map +1 -1
- package/dist/_internal/platform/types/errors.js +21 -20
- package/dist/_internal/platform/utils/error-display.d.ts.map +1 -1
- package/dist/_internal/platform/utils/error-display.js +6 -4
- package/dist/_internal/platform/utils/fetch-with-timeout.d.ts +17 -0
- package/dist/_internal/platform/utils/fetch-with-timeout.d.ts.map +1 -1
- package/dist/_internal/platform/utils/fetch-with-timeout.js +59 -0
- package/dist/_internal/platform/utils/record-coerce.d.ts +11 -0
- package/dist/_internal/platform/utils/record-coerce.d.ts.map +1 -0
- package/dist/_internal/platform/utils/record-coerce.js +12 -0
- package/dist/_internal/platform/utils/redaction.js +1 -1
- package/dist/_internal/platform/utils/ring-buffer.d.ts +54 -0
- package/dist/_internal/platform/utils/ring-buffer.d.ts.map +1 -0
- package/dist/_internal/platform/utils/ring-buffer.js +96 -0
- package/dist/_internal/platform/utils/shell-split.d.ts +11 -0
- package/dist/_internal/platform/utils/shell-split.d.ts.map +1 -0
- package/dist/_internal/platform/utils/shell-split.js +83 -0
- package/dist/_internal/platform/version.js +1 -1
- package/dist/_internal/platform/voice/providers/deepgram.d.ts.map +1 -1
- package/dist/_internal/platform/voice/providers/deepgram.js +2 -1
- package/dist/_internal/platform/voice/providers/elevenlabs.d.ts.map +1 -1
- package/dist/_internal/platform/voice/providers/elevenlabs.js +5 -4
- package/dist/_internal/platform/voice/providers/google.d.ts.map +1 -1
- package/dist/_internal/platform/voice/providers/google.js +5 -4
- package/dist/_internal/platform/voice/providers/microsoft.d.ts.map +1 -1
- package/dist/_internal/platform/voice/providers/microsoft.js +2 -1
- package/dist/_internal/platform/voice/providers/openai.d.ts.map +1 -1
- package/dist/_internal/platform/voice/providers/openai.js +4 -3
- package/dist/_internal/platform/voice/providers/shared.d.ts.map +1 -1
- package/dist/_internal/platform/voice/providers/shared.js +2 -1
- package/dist/_internal/platform/voice/providers/vydra.d.ts.map +1 -1
- package/dist/_internal/platform/voice/providers/vydra.js +3 -2
- package/dist/_internal/platform/watchers/registry.d.ts.map +1 -1
- package/dist/_internal/platform/watchers/registry.js +3 -2
- package/dist/_internal/platform/workflow/trigger-executor.d.ts.map +1 -1
- package/dist/_internal/platform/workflow/trigger-executor.js +5 -3
- package/dist/_internal/platform/workspace/daemon-home.d.ts.map +1 -1
- package/dist/_internal/platform/workspace/daemon-home.js +6 -2
- package/dist/_internal/platform/workspace/workspace-swap-manager.d.ts +1 -0
- package/dist/_internal/platform/workspace/workspace-swap-manager.d.ts.map +1 -1
- package/dist/_internal/platform/workspace/workspace-swap-manager.js +14 -2
- package/package.json +1 -1
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
1
2
|
import { logger } from '../utils/logger.js';
|
|
3
|
+
import { authFailureTotal, authSuccessTotal, httpRequestDurationMs, httpRequestsTotal, } from '../runtime/metrics.js';
|
|
2
4
|
import { HookDispatcher } from '../hooks/dispatcher.js';
|
|
3
5
|
import { authenticateOperatorRequest, buildOperatorSessionCookie, } from '../security/http-auth.js';
|
|
4
6
|
import { UserAuthManager } from '../security/user-auth.js';
|
|
@@ -8,77 +10,7 @@ import { summarizeError } from '../utils/error-display.js';
|
|
|
8
10
|
import { requirePortAvailable } from './port-check.js';
|
|
9
11
|
import { resolveHostBinding } from './host-resolver.js';
|
|
10
12
|
import { createHostModeRestartWatcher } from './host-mode-watcher.js';
|
|
11
|
-
|
|
12
|
-
// Rate limiter (sliding window per IP, in-memory)
|
|
13
|
-
// ---------------------------------------------------------------------------
|
|
14
|
-
const RATE_WINDOW_MS = 60_000;
|
|
15
|
-
/** Entries older than this are eligible for TTL eviction. Default: 10 minutes. */
|
|
16
|
-
const RATE_TTL_MS = 10 * 60_000;
|
|
17
|
-
/** Maximum number of IP entries kept in the limiter at any time (LRU eviction). */
|
|
18
|
-
const RATE_MAX_ENTRIES = 10_000;
|
|
19
|
-
/** How often the background sweep runs to evict expired entries (ms). */
|
|
20
|
-
const RATE_SWEEP_INTERVAL_MS = 60_000;
|
|
21
|
-
class RateLimiter {
|
|
22
|
-
limit;
|
|
23
|
-
/** hits[ip] = sorted ascending array of request timestamps within the window */
|
|
24
|
-
counts = new Map();
|
|
25
|
-
/**
|
|
26
|
-
* O(1) LRU tracking via Map insertion-order semantics.
|
|
27
|
-
* Key = ip, value = last-seen timestamp.
|
|
28
|
-
* To promote an entry to MRU: delete it and re-set it (both O(1)).
|
|
29
|
-
* The Map iterator yields entries in insertion order, so the first entry is
|
|
30
|
-
* the least-recently-used — perfect for LRU eviction without any indexOf scan.
|
|
31
|
-
* (PERF-02)
|
|
32
|
-
*/
|
|
33
|
-
lruMap = new Map();
|
|
34
|
-
sweepInterval = null;
|
|
35
|
-
constructor(limit) {
|
|
36
|
-
this.limit = limit;
|
|
37
|
-
// Periodic sweep to evict entries whose TTL has expired.
|
|
38
|
-
this.sweepInterval = setInterval(() => this._sweep(), RATE_SWEEP_INTERVAL_MS);
|
|
39
|
-
// Don't block clean process exit (PERF-07).
|
|
40
|
-
this.sweepInterval.unref?.();
|
|
41
|
-
}
|
|
42
|
-
/** Returns true if the request is allowed, false if rate-limited. */
|
|
43
|
-
check(ip) {
|
|
44
|
-
const now = Date.now();
|
|
45
|
-
const windowStart = now - RATE_WINDOW_MS;
|
|
46
|
-
const hits = (this.counts.get(ip) ?? []).filter((t) => t > windowStart);
|
|
47
|
-
hits.push(now);
|
|
48
|
-
this.counts.set(ip, hits);
|
|
49
|
-
// Promote to MRU: delete then re-set (both O(1) Map operations).
|
|
50
|
-
this.lruMap.delete(ip);
|
|
51
|
-
this.lruMap.set(ip, now);
|
|
52
|
-
// Evict least-recently-used entry when cap is exceeded.
|
|
53
|
-
if (this.lruMap.size > RATE_MAX_ENTRIES) {
|
|
54
|
-
const evict = this.lruMap.keys().next().value;
|
|
55
|
-
if (evict !== undefined) {
|
|
56
|
-
this.lruMap.delete(evict);
|
|
57
|
-
this.counts.delete(evict);
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
return hits.length <= this.limit;
|
|
61
|
-
}
|
|
62
|
-
/** Stop the background sweep interval. Call this when the listener stops. */
|
|
63
|
-
stop() {
|
|
64
|
-
if (this.sweepInterval !== null) {
|
|
65
|
-
clearInterval(this.sweepInterval);
|
|
66
|
-
this.sweepInterval = null;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
/** Evict entries whose last-seen timestamp is older than RATE_TTL_MS. */
|
|
70
|
-
_sweep() {
|
|
71
|
-
const cutoff = Date.now() - RATE_TTL_MS;
|
|
72
|
-
for (const [ip, lastSeen] of this.lruMap) {
|
|
73
|
-
// Map iteration is insertion-order; first entries are oldest.
|
|
74
|
-
// Break early once we hit a non-expired entry (all subsequent are newer).
|
|
75
|
-
if (lastSeen >= cutoff)
|
|
76
|
-
break;
|
|
77
|
-
this.lruMap.delete(ip);
|
|
78
|
-
this.counts.delete(ip);
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
}
|
|
13
|
+
import { RateLimiter } from './http/rate-limiter.js';
|
|
82
14
|
// ---------------------------------------------------------------------------
|
|
83
15
|
// HttpListener
|
|
84
16
|
// ---------------------------------------------------------------------------
|
|
@@ -323,8 +255,36 @@ export class HttpListener {
|
|
|
323
255
|
// Request handling
|
|
324
256
|
// -------------------------------------------------------------------------
|
|
325
257
|
async handleRequest(req) {
|
|
258
|
+
const requestId = randomUUID();
|
|
259
|
+
const startMs = Date.now();
|
|
326
260
|
const url = new URL(req.url);
|
|
327
261
|
const clientIp = extractForwardedClientIp(req, this.trustProxy || (this.tlsState?.trustProxy ?? false)) ?? 'unknown';
|
|
262
|
+
let response = null;
|
|
263
|
+
try {
|
|
264
|
+
response = await this._handleRequestInner(req, url, clientIp, requestId);
|
|
265
|
+
return response;
|
|
266
|
+
}
|
|
267
|
+
finally {
|
|
268
|
+
const status = response?.status ?? 500;
|
|
269
|
+
const latencyMs = Date.now() - startMs;
|
|
270
|
+
// OBS-01: structured HTTP access log — SIEM-ingestable
|
|
271
|
+
logger.info('HTTP_ACCESS_LOG', {
|
|
272
|
+
type: 'HTTP_ACCESS_LOG',
|
|
273
|
+
requestId,
|
|
274
|
+
method: req.method,
|
|
275
|
+
path: url.pathname,
|
|
276
|
+
status,
|
|
277
|
+
latencyMs,
|
|
278
|
+
clientIp,
|
|
279
|
+
});
|
|
280
|
+
// C-1: record HTTP metric instruments
|
|
281
|
+
const statusClass = status >= 500 ? '5xx' : status >= 400 ? '4xx' : '2xx';
|
|
282
|
+
const pathPattern = url.pathname.replace(/\/[0-9a-f-]{8,}(?=\/|$)/gi, '/:id');
|
|
283
|
+
httpRequestsTotal.add(1, { method: req.method, status_class: statusClass });
|
|
284
|
+
httpRequestDurationMs.record(latencyMs, { method: req.method, path_pattern: pathPattern, status_class: statusClass });
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
async _handleRequestInner(req, url, clientIp, requestId) {
|
|
328
288
|
// SEC-07: CORS origin check is OPT-IN via enforceCors. Default is permissive
|
|
329
289
|
// (home/single-user deployments) — pre-0.21.29 behavior preserved. When
|
|
330
290
|
// enforceCors is true:
|
|
@@ -351,7 +311,7 @@ export class HttpListener {
|
|
|
351
311
|
if (!this.loginRateLimiter.check(clientIp)) {
|
|
352
312
|
return Response.json({ error: 'Too many requests' }, { status: 429 });
|
|
353
313
|
}
|
|
354
|
-
return this.handleLogin(req);
|
|
314
|
+
return this.handleLogin(req, clientIp, requestId);
|
|
355
315
|
}
|
|
356
316
|
// General rate limiting for all other routes.
|
|
357
317
|
if (!this.rateLimiter.check(clientIp)) {
|
|
@@ -370,7 +330,7 @@ export class HttpListener {
|
|
|
370
330
|
}
|
|
371
331
|
return Response.json({ error: 'Not found' }, { status: 404 });
|
|
372
332
|
}
|
|
373
|
-
async handleLogin(req) {
|
|
333
|
+
async handleLogin(req, clientIp, requestId) {
|
|
374
334
|
const body = await this.parseJsonBody(req);
|
|
375
335
|
if (body instanceof Response)
|
|
376
336
|
return body;
|
|
@@ -378,9 +338,29 @@ export class HttpListener {
|
|
|
378
338
|
const password = typeof body.password === 'string' ? body.password : '';
|
|
379
339
|
const user = this.userAuth.authenticate(username, password);
|
|
380
340
|
if (!user) {
|
|
341
|
+
// OBS-02: AUTH_FAILED — never log credential values
|
|
342
|
+
logger.warn('AUTH_FAILED', {
|
|
343
|
+
type: 'AUTH_FAILED',
|
|
344
|
+
requestId,
|
|
345
|
+
usernameAttempted: username,
|
|
346
|
+
clientIp,
|
|
347
|
+
reason: 'invalid_credentials',
|
|
348
|
+
});
|
|
349
|
+
// C-1: record auth failure metric
|
|
350
|
+
authFailureTotal.add(1);
|
|
381
351
|
return Response.json({ error: 'Invalid credentials' }, { status: 401 });
|
|
382
352
|
}
|
|
383
353
|
const session = this.userAuth.createSession(user.username);
|
|
354
|
+
// OBS-02: AUTH_SUCCEEDED — never log credential values
|
|
355
|
+
// C-1: record auth success metric
|
|
356
|
+
authSuccessTotal.add(1);
|
|
357
|
+
logger.info('AUTH_SUCCEEDED', {
|
|
358
|
+
type: 'AUTH_SUCCEEDED',
|
|
359
|
+
requestId,
|
|
360
|
+
username: user.username,
|
|
361
|
+
clientIp,
|
|
362
|
+
method: 'password',
|
|
363
|
+
});
|
|
384
364
|
return Response.json({
|
|
385
365
|
authenticated: true,
|
|
386
366
|
token: session.token,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"surface-delivery.d.ts","sourceRoot":"","sources":["../../../../src/_internal/platform/daemon/surface-delivery.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AACrE,OAAO,KAAK,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAK7G,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACtE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"surface-delivery.d.ts","sourceRoot":"","sources":["../../../../src/_internal/platform/daemon/surface-delivery.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,6 +3,7 @@ import { SlackIntegration, DiscordIntegration, NtfyIntegration } from '../integr
|
|
|
3
3
|
import { logger } from '../utils/logger.js';
|
|
4
4
|
import { validatePublicWebhookUrl } from '../utils/url-safety.js';
|
|
5
5
|
import { summarizeError } from '../utils/error-display.js';
|
|
6
|
+
import { instrumentedFetch } from '../utils/fetch-with-timeout.js';
|
|
6
7
|
function isSupportedDeliverySurface(surface) {
|
|
7
8
|
return surface === 'slack'
|
|
8
9
|
|| surface === 'discord'
|
|
@@ -116,7 +117,7 @@ export class DaemonSurfaceDeliveryHelper {
|
|
|
116
117
|
?? process.env.SLACK_BOT_TOKEN;
|
|
117
118
|
const slack = new SlackIntegration(webhookUrl ?? undefined, botToken ?? undefined);
|
|
118
119
|
if (pending.responseUrl) {
|
|
119
|
-
await
|
|
120
|
+
await instrumentedFetch(pending.responseUrl, {
|
|
120
121
|
method: 'POST',
|
|
121
122
|
headers: { 'Content-Type': 'application/json' },
|
|
122
123
|
body: JSON.stringify({
|
|
@@ -153,7 +154,7 @@ export class DaemonSurfaceDeliveryHelper {
|
|
|
153
154
|
?? process.env.SLACK_BOT_TOKEN;
|
|
154
155
|
const slack = new SlackIntegration(webhookUrl ?? undefined, botToken ?? undefined);
|
|
155
156
|
if (pending.responseUrl) {
|
|
156
|
-
await
|
|
157
|
+
await instrumentedFetch(pending.responseUrl, {
|
|
157
158
|
method: 'POST',
|
|
158
159
|
headers: { 'Content-Type': 'application/json' },
|
|
159
160
|
body: JSON.stringify({
|
|
@@ -237,7 +238,7 @@ export class DaemonSurfaceDeliveryHelper {
|
|
|
237
238
|
else if (secret && pending.callbackSignature === 'shared-secret') {
|
|
238
239
|
headers.set('X-Goodvibes-Webhook-Secret', secret);
|
|
239
240
|
}
|
|
240
|
-
await
|
|
241
|
+
await instrumentedFetch(validation.url, {
|
|
241
242
|
method: 'POST',
|
|
242
243
|
headers,
|
|
243
244
|
signal: AbortSignal.timeout(timeoutMs),
|
|
@@ -379,7 +380,7 @@ export class DaemonSurfaceDeliveryHelper {
|
|
|
379
380
|
]
|
|
380
381
|
: undefined;
|
|
381
382
|
if (typeof binding.metadata.responseUrl === 'string' && binding.metadata.responseUrl.startsWith('https://')) {
|
|
382
|
-
await
|
|
383
|
+
await instrumentedFetch(binding.metadata.responseUrl, {
|
|
383
384
|
method: 'POST',
|
|
384
385
|
headers: { 'Content-Type': 'application/json' },
|
|
385
386
|
body: JSON.stringify({
|
|
@@ -450,7 +451,7 @@ export class DaemonSurfaceDeliveryHelper {
|
|
|
450
451
|
if (secret) {
|
|
451
452
|
headers.set('X-Goodvibes-Signature', this.signWebhookPayload(payload, secret));
|
|
452
453
|
}
|
|
453
|
-
await
|
|
454
|
+
await instrumentedFetch(validation.url, {
|
|
454
455
|
method: 'POST',
|
|
455
456
|
headers,
|
|
456
457
|
body: payload,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-scanner.d.ts","sourceRoot":"","sources":["../../../../src/_internal/platform/discovery/mcp-scanner.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAIlE,MAAM,WAAW,kBAAkB;IACjC,wDAAwD;IACxD,WAAW,EAAE,eAAe,EAAE,CAAC;IAC/B,kCAAkC;IAClC,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,MAAM,iBAAiB,GAAG,IAAI,CAAC,gBAAgB,EAAE,kBAAkB,GAAG,eAAe,CAAC,GAAG;IAC7F,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B,CAAC;AA4KF;;;;;;GAMG;AACH,wBAAsB,cAAc,CAClC,KAAK,EAAE,iBAAiB,EACxB,eAAe,GAAE,GAAG,CAAC,MAAM,CAAa,GACvC,OAAO,CAAC,kBAAkB,CAAC,
|
|
1
|
+
{"version":3,"file":"mcp-scanner.d.ts","sourceRoot":"","sources":["../../../../src/_internal/platform/discovery/mcp-scanner.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAIlE,MAAM,WAAW,kBAAkB;IACjC,wDAAwD;IACxD,WAAW,EAAE,eAAe,EAAE,CAAC;IAC/B,kCAAkC;IAClC,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,MAAM,iBAAiB,GAAG,IAAI,CAAC,gBAAgB,EAAE,kBAAkB,GAAG,eAAe,CAAC,GAAG;IAC7F,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B,CAAC;AA4KF;;;;;;GAMG;AACH,wBAAsB,cAAc,CAClC,KAAK,EAAE,iBAAiB,EACxB,eAAe,GAAE,GAAG,CAAC,MAAM,CAAa,GACvC,OAAO,CAAC,kBAAkB,CAAC,CAwC7B"}
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
*
|
|
12
12
|
* Returns suggested McpServerConfig[] for servers not already in the registry.
|
|
13
13
|
*/
|
|
14
|
-
import {
|
|
14
|
+
import { readdir, stat } from 'node:fs/promises';
|
|
15
15
|
import { join } from 'path';
|
|
16
16
|
import { logger } from '../utils/logger.js';
|
|
17
17
|
import { requireSurfaceRoot } from '../runtime/surface-root.js';
|
|
@@ -50,15 +50,15 @@ function deriveServerName(nameOrPath) {
|
|
|
50
50
|
* Check if a given package is installed locally (in node_modules).
|
|
51
51
|
* Returns the bin path if found, null otherwise.
|
|
52
52
|
*/
|
|
53
|
-
function findLocalNpxBin(cwd, packageName) {
|
|
53
|
+
async function findLocalNpxBin(cwd, packageName) {
|
|
54
54
|
// Check project-local node_modules/.bin
|
|
55
55
|
const binName = packageName.replace(/^@[^/]+\//, '');
|
|
56
56
|
const localBin = join(cwd, 'node_modules', '.bin', binName);
|
|
57
|
-
if (
|
|
57
|
+
if (await stat(localBin).then(() => true).catch(() => false))
|
|
58
58
|
return localBin;
|
|
59
59
|
// Also check if the package itself exists in node_modules
|
|
60
60
|
const localPkg = join(cwd, 'node_modules', packageName, 'package.json');
|
|
61
|
-
if (
|
|
61
|
+
if (await stat(localPkg).then(() => true).catch(() => false))
|
|
62
62
|
return packageName;
|
|
63
63
|
return null;
|
|
64
64
|
}
|
|
@@ -68,27 +68,27 @@ function findLocalNpxBin(cwd, packageName) {
|
|
|
68
68
|
* - .mcp/mcp.json (already handled by loadMcpConfig, skip)
|
|
69
69
|
* - .mcp/<name>/index.js or .mcp/<name>/index.ts or .mcp/<name>/server.js
|
|
70
70
|
*/
|
|
71
|
-
function scanProjectMcpDir(roots, knownNames) {
|
|
71
|
+
async function scanProjectMcpDir(roots, knownNames) {
|
|
72
72
|
const mcpDir = join(roots.workingDirectory, '.mcp');
|
|
73
|
-
if (!
|
|
73
|
+
if (!await stat(mcpDir).then(() => true).catch(() => false))
|
|
74
74
|
return [];
|
|
75
75
|
const suggestions = [];
|
|
76
76
|
try {
|
|
77
|
-
const entries =
|
|
77
|
+
const entries = await readdir(mcpDir);
|
|
78
78
|
for (const entry of entries) {
|
|
79
79
|
// Skip mcp.json — already read by loadMcpConfig
|
|
80
80
|
if (entry === 'mcp.json')
|
|
81
81
|
continue;
|
|
82
82
|
const entryPath = join(mcpDir, entry);
|
|
83
83
|
try {
|
|
84
|
-
const
|
|
85
|
-
if (!
|
|
84
|
+
const entryStat = await stat(entryPath);
|
|
85
|
+
if (!entryStat.isDirectory())
|
|
86
86
|
continue;
|
|
87
87
|
// Look for a server entry point inside the subdirectory
|
|
88
88
|
const candidates = ['index.js', 'index.ts', 'server.js', 'server.ts', 'main.js', 'main.ts'];
|
|
89
89
|
for (const candidate of candidates) {
|
|
90
90
|
const candidatePath = join(entryPath, candidate);
|
|
91
|
-
if (
|
|
91
|
+
if (await stat(candidatePath).then(() => true).catch(() => false)) {
|
|
92
92
|
if (knownNames.has(entry))
|
|
93
93
|
break; // already registered
|
|
94
94
|
const runtime = candidate.endsWith('.ts') ? 'bun' : 'node';
|
|
@@ -117,22 +117,22 @@ function scanProjectMcpDir(roots, knownNames) {
|
|
|
117
117
|
* - <name>/index.js, <name>/server.js, etc.
|
|
118
118
|
* - <name>.js, <name>.ts standalone scripts
|
|
119
119
|
*/
|
|
120
|
-
function scanGoodvibesMcpDir(roots, knownNames) {
|
|
120
|
+
async function scanGoodvibesMcpDir(roots, knownNames) {
|
|
121
121
|
const mcpDir = join(roots.homeDirectory, '.goodvibes', requireSurfaceRoot(roots.surfaceRoot, 'MCP discovery surfaceRoot'), 'mcp');
|
|
122
|
-
if (!
|
|
122
|
+
if (!await stat(mcpDir).then(() => true).catch(() => false))
|
|
123
123
|
return [];
|
|
124
124
|
const suggestions = [];
|
|
125
125
|
try {
|
|
126
|
-
const entries =
|
|
126
|
+
const entries = await readdir(mcpDir);
|
|
127
127
|
for (const entry of entries) {
|
|
128
128
|
const entryPath = join(mcpDir, entry);
|
|
129
129
|
try {
|
|
130
|
-
const
|
|
131
|
-
if (
|
|
130
|
+
const entryStat = await stat(entryPath);
|
|
131
|
+
if (entryStat.isDirectory()) {
|
|
132
132
|
const candidates = ['index.js', 'index.ts', 'server.js', 'server.ts'];
|
|
133
133
|
for (const candidate of candidates) {
|
|
134
134
|
const candidatePath = join(entryPath, candidate);
|
|
135
|
-
if (
|
|
135
|
+
if (await stat(candidatePath).then(() => true).catch(() => false)) {
|
|
136
136
|
if (knownNames.has(entry))
|
|
137
137
|
break;
|
|
138
138
|
const runtime = candidate.endsWith('.ts') ? 'bun' : 'node';
|
|
@@ -141,7 +141,7 @@ function scanGoodvibesMcpDir(roots, knownNames) {
|
|
|
141
141
|
}
|
|
142
142
|
}
|
|
143
143
|
}
|
|
144
|
-
else if (
|
|
144
|
+
else if (entryStat.isFile()) {
|
|
145
145
|
// Standalone script: name.js or name.ts
|
|
146
146
|
if (!entry.endsWith('.js') && !entry.endsWith('.ts'))
|
|
147
147
|
continue;
|
|
@@ -165,10 +165,10 @@ function scanGoodvibesMcpDir(roots, knownNames) {
|
|
|
165
165
|
/**
|
|
166
166
|
* Check for locally-installed npx MCP packages not already registered.
|
|
167
167
|
*/
|
|
168
|
-
function scanNpxMcpPackages(roots, knownNames) {
|
|
168
|
+
async function scanNpxMcpPackages(roots, knownNames) {
|
|
169
169
|
const suggestions = [];
|
|
170
170
|
for (const pkg of KNOWN_NPX_MCP_PACKAGES) {
|
|
171
|
-
const binPath = findLocalNpxBin(roots.workingDirectory, pkg);
|
|
171
|
+
const binPath = await findLocalNpxBin(roots.workingDirectory, pkg);
|
|
172
172
|
if (!binPath)
|
|
173
173
|
continue;
|
|
174
174
|
const serverName = deriveServerName(pkg);
|
|
@@ -202,15 +202,21 @@ export async function scanMcpServers(roots, registeredNames = new Set()) {
|
|
|
202
202
|
}
|
|
203
203
|
}
|
|
204
204
|
};
|
|
205
|
+
// Run all three scanners in parallel — they are independent
|
|
206
|
+
const [projectResults, goodvibesResults, npxResults] = await Promise.all([
|
|
207
|
+
scanProjectMcpDir(roots, registeredNames),
|
|
208
|
+
scanGoodvibesMcpDir(roots, registeredNames),
|
|
209
|
+
scanNpxMcpPackages(roots, registeredNames),
|
|
210
|
+
]);
|
|
205
211
|
// 1. Project .mcp/ directory
|
|
206
212
|
locationsScanned++;
|
|
207
|
-
addSuggestions(
|
|
213
|
+
addSuggestions(projectResults);
|
|
208
214
|
// 2. ~/.goodvibes/<surface>/mcp/ user-global directory
|
|
209
215
|
locationsScanned++;
|
|
210
|
-
addSuggestions(
|
|
216
|
+
addSuggestions(goodvibesResults);
|
|
211
217
|
// 3. Locally installed npx MCP packages
|
|
212
218
|
locationsScanned++;
|
|
213
|
-
addSuggestions(
|
|
219
|
+
addSuggestions(npxResults);
|
|
214
220
|
logger.debug('[mcp-scanner] Scan complete', {
|
|
215
221
|
locationsScanned,
|
|
216
222
|
suggestions: suggestions.length,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scanner.d.ts","sourceRoot":"","sources":["../../../../src/_internal/platform/discovery/scanner.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"scanner.d.ts","sourceRoot":"","sources":["../../../../src/_internal/platform/discovery/scanner.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAQlE,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,WAAW,GAAG,MAAM,GAAG,UAAU,GAAG,SAAS,GAAG,KAAK,GAAG,KAAK,GAAG,SAAS,GAAG,WAAW,GAAG,WAAW,GAAG,SAAS,CAAC;AAEtJ,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,UAAU,EAAE,UAAU,CAAC;IACvB,mBAAmB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7C,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC5C;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;CACpB;AAMD,KAAK,cAAc,GAAG,IAAI,CAAC,gBAAgB,EAAE,eAAe,CAAC,GAAG;IAC9D,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B,CAAC;AAUF,iGAAiG;AACjG,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,cAAc,GAAG,gBAAgB,EAAE,CAiBhF;AAED,0FAA0F;AAC1F,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,cAAc,EAAE,OAAO,EAAE,gBAAgB,EAAE,GAAG,IAAI,CAgCzF;AAED,sEAAsE;AACtE,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG,IAAI,CAerH;AAgND;;;;GAIG;AACH,wBAAsB,wBAAwB,CAC5C,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,UAAU,EACtB,MAAM,EAAE,MAAM,EAAE,GACf,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CA0KjC;AA4MD;;GAEG;AACH,wBAAsB,SAAS,CAC7B,KAAK,EAAE,MAAM,EAAE,EACf,UAAU,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,GACtD,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAkC7B;AAMD;;GAEG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,UAAU,CAAC,CASzD;AAED;;;GAGG;AACH,wBAAsB,IAAI,CACxB,UAAU,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,GACtD,OAAO,CAAC,UAAU,CAAC,CA8BrB"}
|
|
@@ -3,7 +3,9 @@ import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
|
|
|
3
3
|
import { dirname } from 'node:path';
|
|
4
4
|
import { logger } from '../utils/logger.js';
|
|
5
5
|
import { discoverContextWindows } from '../providers/context-discovery.js';
|
|
6
|
+
import { WELL_KNOWN_LOCAL_PORTS } from '../providers/well-known-endpoints.js';
|
|
6
7
|
import { resolveSurfaceDirectory } from '../runtime/surface-root.js';
|
|
8
|
+
import { instrumentedFetch } from '../utils/fetch-with-timeout.js';
|
|
7
9
|
function getPersistedPath(roots) {
|
|
8
10
|
return resolveSurfaceDirectory(roots.homeDirectory, roots.surfaceRoot, 'discovered-providers.json');
|
|
9
11
|
}
|
|
@@ -57,8 +59,9 @@ export function persistProviders(roots, servers) {
|
|
|
57
59
|
mkdirSync(dirname(persistedPath), { recursive: true });
|
|
58
60
|
writeFileSync(persistedPath, JSON.stringify([...byKey.values()], null, 2) + '\n', 'utf-8');
|
|
59
61
|
}
|
|
60
|
-
catch {
|
|
61
|
-
// Non-fatal — persistence is best-effort
|
|
62
|
+
catch (err) {
|
|
63
|
+
// OBS-11: Non-fatal — persistence is best-effort
|
|
64
|
+
logger.debug('[Scanner] persistProviders failed (non-fatal)', { error: String(err) });
|
|
62
65
|
}
|
|
63
66
|
}
|
|
64
67
|
/** Remove specific servers from the persisted file (by host:port). */
|
|
@@ -77,14 +80,27 @@ export function removePersistedProviders(roots, toRemove) {
|
|
|
77
80
|
const filtered = current.filter(s => !removeKeys.has(`${s.host}:${s.port}`));
|
|
78
81
|
writeFileSync(persistedPath, JSON.stringify(filtered, null, 2) + '\n', 'utf-8');
|
|
79
82
|
}
|
|
80
|
-
catch {
|
|
81
|
-
// Non-fatal
|
|
83
|
+
catch (err) {
|
|
84
|
+
// OBS-11: Non-fatal — removal from persisted file failed
|
|
85
|
+
logger.debug('[Scanner] removePersistedProviders failed (non-fatal)', { error: String(err) });
|
|
82
86
|
}
|
|
83
87
|
}
|
|
84
88
|
// ---------------------------------------------------------------------------
|
|
85
89
|
// Constants
|
|
86
90
|
// ---------------------------------------------------------------------------
|
|
87
|
-
const KNOWN_PORTS = [
|
|
91
|
+
const KNOWN_PORTS = [
|
|
92
|
+
WELL_KNOWN_LOCAL_PORTS.lmStudio,
|
|
93
|
+
WELL_KNOWN_LOCAL_PORTS.jan,
|
|
94
|
+
WELL_KNOWN_LOCAL_PORTS.aphrodite,
|
|
95
|
+
WELL_KNOWN_LOCAL_PORTS.gpt4all,
|
|
96
|
+
5000,
|
|
97
|
+
WELL_KNOWN_LOCAL_PORTS.koboldCpp,
|
|
98
|
+
7860,
|
|
99
|
+
8000,
|
|
100
|
+
8001,
|
|
101
|
+
WELL_KNOWN_LOCAL_PORTS.llamaCpp,
|
|
102
|
+
WELL_KNOWN_LOCAL_PORTS.ollama,
|
|
103
|
+
];
|
|
88
104
|
const PROBE_TIMEOUT_MS = 200;
|
|
89
105
|
const MAX_CONCURRENT_PROBES = 50;
|
|
90
106
|
const METADATA_TIMEOUT_MS = 2000;
|
|
@@ -152,7 +168,7 @@ async function probeHost(host, port) {
|
|
|
152
168
|
}
|
|
153
169
|
async function tryFetch(url) {
|
|
154
170
|
try {
|
|
155
|
-
const res = await
|
|
171
|
+
const res = await instrumentedFetch(url, {
|
|
156
172
|
signal: AbortSignal.timeout(PROBE_TIMEOUT_MS),
|
|
157
173
|
});
|
|
158
174
|
if (!res.ok)
|
|
@@ -200,17 +216,17 @@ function identifyServer(port, headers, responseBody) {
|
|
|
200
216
|
.map((item) => String(item.id))
|
|
201
217
|
.join(' ');
|
|
202
218
|
}
|
|
203
|
-
if (port ===
|
|
219
|
+
if (port === WELL_KNOWN_LOCAL_PORTS.ollama)
|
|
204
220
|
return 'ollama';
|
|
205
|
-
if (port ===
|
|
221
|
+
if (port === WELL_KNOWN_LOCAL_PORTS.jan)
|
|
206
222
|
return 'jan';
|
|
207
|
-
if (port ===
|
|
223
|
+
if (port === WELL_KNOWN_LOCAL_PORTS.gpt4all)
|
|
208
224
|
return 'gpt4all';
|
|
209
|
-
if (port ===
|
|
225
|
+
if (port === WELL_KNOWN_LOCAL_PORTS.koboldCpp)
|
|
210
226
|
return 'koboldcpp';
|
|
211
|
-
if (port ===
|
|
227
|
+
if (port === WELL_KNOWN_LOCAL_PORTS.aphrodite)
|
|
212
228
|
return 'aphrodite';
|
|
213
|
-
if (port ===
|
|
229
|
+
if (port === WELL_KNOWN_LOCAL_PORTS.lmStudio || headerValues.includes('lmstudio') || modelIds.includes('lmstudio')) {
|
|
214
230
|
return 'lm-studio';
|
|
215
231
|
}
|
|
216
232
|
if (Object.keys(headers).some((k) => k.startsWith('x-vllm')))
|
|
@@ -240,7 +256,7 @@ export async function fetchModelContextWindows(host, port, serverType, models) {
|
|
|
240
256
|
// Ollama: POST /api/show for each model — parallel to avoid blocking pool slot
|
|
241
257
|
await Promise.allSettled(models.map(async (model) => {
|
|
242
258
|
try {
|
|
243
|
-
const res = await
|
|
259
|
+
const res = await instrumentedFetch(`http://${host}:${port}/api/show`, {
|
|
244
260
|
method: 'POST',
|
|
245
261
|
headers: { 'Content-Type': 'application/json' },
|
|
246
262
|
body: JSON.stringify({ name: model }),
|
|
@@ -281,7 +297,7 @@ export async function fetchModelContextWindows(host, port, serverType, models) {
|
|
|
281
297
|
// vLLM: GET /v1/models/{id} returns max_model_len — parallel to avoid blocking pool slot
|
|
282
298
|
await Promise.allSettled(models.map(async (model) => {
|
|
283
299
|
try {
|
|
284
|
-
const res = await
|
|
300
|
+
const res = await instrumentedFetch(`http://${host}:${port}/v1/models/${encodeURIComponent(model)}`, {
|
|
285
301
|
signal: AbortSignal.timeout(METADATA_TIMEOUT_MS),
|
|
286
302
|
});
|
|
287
303
|
if (!res.ok)
|
|
@@ -301,7 +317,7 @@ export async function fetchModelContextWindows(host, port, serverType, models) {
|
|
|
301
317
|
case 'llamacpp': {
|
|
302
318
|
// llama.cpp: GET /props returns default_generation_settings.n_ctx (server-wide)
|
|
303
319
|
try {
|
|
304
|
-
const res = await
|
|
320
|
+
const res = await instrumentedFetch(`http://${host}:${port}/props`, {
|
|
305
321
|
signal: AbortSignal.timeout(METADATA_TIMEOUT_MS),
|
|
306
322
|
});
|
|
307
323
|
if (res.ok) {
|
|
@@ -349,7 +365,7 @@ export async function fetchModelContextWindows(host, port, serverType, models) {
|
|
|
349
365
|
// Generic: try /v1/models/{id} for each model, look for common context length fields — parallel
|
|
350
366
|
await Promise.allSettled(models.map(async (model) => {
|
|
351
367
|
try {
|
|
352
|
-
const res = await
|
|
368
|
+
const res = await instrumentedFetch(`http://${host}:${port}/v1/models/${encodeURIComponent(model)}`, {
|
|
353
369
|
signal: AbortSignal.timeout(METADATA_TIMEOUT_MS),
|
|
354
370
|
});
|
|
355
371
|
if (!res.ok)
|
|
@@ -371,7 +387,7 @@ export async function fetchModelContextWindows(host, port, serverType, models) {
|
|
|
371
387
|
// Fallback: try /props (llama.cpp-style) if no context windows found
|
|
372
388
|
if (Object.keys(result).length === 0 && models.length > 0) {
|
|
373
389
|
try {
|
|
374
|
-
const res = await
|
|
390
|
+
const res = await instrumentedFetch(`http://${host}:${port}/props`, {
|
|
375
391
|
signal: AbortSignal.timeout(METADATA_TIMEOUT_MS),
|
|
376
392
|
});
|
|
377
393
|
if (res.ok) {
|
|
@@ -410,7 +426,7 @@ async function fetchModelOutputLimits(host, port, serverType, models) {
|
|
|
410
426
|
// Ollama: POST /api/show for each model — look for num_predict in model_info or parameters
|
|
411
427
|
await Promise.allSettled(models.map(async (model) => {
|
|
412
428
|
try {
|
|
413
|
-
const res = await
|
|
429
|
+
const res = await instrumentedFetch(`http://${host}:${port}/api/show`, {
|
|
414
430
|
method: 'POST',
|
|
415
431
|
headers: { 'Content-Type': 'application/json' },
|
|
416
432
|
body: JSON.stringify({ name: model }),
|
|
@@ -450,7 +466,7 @@ async function fetchModelOutputLimits(host, port, serverType, models) {
|
|
|
450
466
|
// vLLM: GET /v1/models/{id} — look for max_completion_tokens
|
|
451
467
|
await Promise.allSettled(models.map(async (model) => {
|
|
452
468
|
try {
|
|
453
|
-
const res = await
|
|
469
|
+
const res = await instrumentedFetch(`http://${host}:${port}/v1/models/${encodeURIComponent(model)}`, {
|
|
454
470
|
signal: AbortSignal.timeout(METADATA_TIMEOUT_MS),
|
|
455
471
|
});
|
|
456
472
|
if (!res.ok)
|
|
@@ -470,7 +486,7 @@ async function fetchModelOutputLimits(host, port, serverType, models) {
|
|
|
470
486
|
case 'llamacpp': {
|
|
471
487
|
// llama.cpp: GET /props — look for default_generation_settings.n_predict
|
|
472
488
|
try {
|
|
473
|
-
const res = await
|
|
489
|
+
const res = await instrumentedFetch(`http://${host}:${port}/props`, {
|
|
474
490
|
signal: AbortSignal.timeout(METADATA_TIMEOUT_MS),
|
|
475
491
|
});
|
|
476
492
|
if (res.ok) {
|
|
@@ -502,7 +518,7 @@ async function fetchModelOutputLimits(host, port, serverType, models) {
|
|
|
502
518
|
// Generic: try /v1/models/{id} for each model, look for common output limit fields
|
|
503
519
|
await Promise.allSettled(models.map(async (model) => {
|
|
504
520
|
try {
|
|
505
|
-
const res = await
|
|
521
|
+
const res = await instrumentedFetch(`http://${host}:${port}/v1/models/${encodeURIComponent(model)}`, {
|
|
506
522
|
signal: AbortSignal.timeout(METADATA_TIMEOUT_MS),
|
|
507
523
|
});
|
|
508
524
|
if (!res.ok)
|
|
@@ -522,7 +538,7 @@ async function fetchModelOutputLimits(host, port, serverType, models) {
|
|
|
522
538
|
// Fallback: try /props (llama.cpp-style) for n_predict if no output limits found
|
|
523
539
|
if (Object.keys(result).length === 0 && models.length > 0) {
|
|
524
540
|
try {
|
|
525
|
-
const res = await
|
|
541
|
+
const res = await instrumentedFetch(`http://${host}:${port}/props`, {
|
|
526
542
|
signal: AbortSignal.timeout(METADATA_TIMEOUT_MS),
|
|
527
543
|
});
|
|
528
544
|
if (res.ok) {
|
|
@@ -12,7 +12,6 @@ export interface SessionExportData {
|
|
|
12
12
|
/** ISO timestamp of export. */
|
|
13
13
|
exportedAt?: string;
|
|
14
14
|
}
|
|
15
|
-
export declare function redactSensitiveData(text: string): string;
|
|
16
15
|
/**
|
|
17
16
|
* redactMessage - Deep-clone a message and redact all string fields that may
|
|
18
17
|
* contain sensitive data (content, reasoning, tool arguments).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-export.d.ts","sourceRoot":"","sources":["../../../../src/_internal/platform/export/session-export.ts"],"names":[],"mappings":"AAEA,OAAO,EAAiC,KAAK,aAAa,EAAE,KAAK,cAAc,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"session-export.d.ts","sourceRoot":"","sources":["../../../../src/_internal/platform/export/session-export.ts"],"names":[],"mappings":"AAEA,OAAO,EAAiC,KAAK,aAAa,EAAE,KAAK,cAAc,EAAE,MAAM,eAAe,CAAC;AAKvG,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,CAAC;AAE9C,MAAM,WAAW,aAAa;IAC5B,sEAAsE;IACtE,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,+BAA+B;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,+BAA+B;IAC/B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAID;;;GAGG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,aAAa,GAAG,aAAa,CAqB/D;AAID;;;;;GAKG;AACH,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,aAAa,EAAE,EACzB,QAAQ,CAAC,EAAE,cAAc,EACzB,OAAO,GAAE,aAAa,GAAG;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,GAC9C,MAAM,CAwCR;AAqBD;;;GAGG;AACH,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,aAAa,EAAE,EACzB,QAAQ,CAAC,EAAE,cAAc,EACzB,OAAO,GAAE,aAAa,GAAG;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,GAC9C,MAAM,CAsBR;AAOD;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,aAAa,EAAE,EACzB,QAAQ,CAAC,EAAE,cAAc,EACzB,OAAO,GAAE,aAAa,GAAG;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,GAC9C,MAAM,CA0JR;AAmQD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM,CAG/F"}
|
|
@@ -1,38 +1,6 @@
|
|
|
1
1
|
import { join } from 'node:path';
|
|
2
2
|
import { exportToMarkdown, extractText } from './markdown.js';
|
|
3
|
-
|
|
4
|
-
/** Patterns that identify sensitive content — API keys and absolute paths. */
|
|
5
|
-
const REDACT_PATTERNS = [
|
|
6
|
-
// Generic API key patterns (sk-*, key-*, bearer tokens)
|
|
7
|
-
{ pattern: /\b(sk-[A-Za-z0-9_-]{20,})/g, replacement: '[REDACTED_API_KEY]' },
|
|
8
|
-
{ pattern: /\b(key-[A-Za-z0-9_-]{16,})/g, replacement: '[REDACTED_API_KEY]' },
|
|
9
|
-
// Bearer / Authorization header values
|
|
10
|
-
{ pattern: /(Bearer\s+)[A-Za-z0-9._~+\/-]+=*/gi, replacement: '$1[REDACTED_TOKEN]' },
|
|
11
|
-
// GitHub tokens
|
|
12
|
-
{ pattern: /\b(ghp_[A-Za-z0-9]{36,})/g, replacement: '[REDACTED_GITHUB_TOKEN]' },
|
|
13
|
-
{ pattern: /\b(gho_[A-Za-z0-9]{36,})/g, replacement: '[REDACTED_GITHUB_TOKEN]' },
|
|
14
|
-
{ pattern: /\b(github_pat_[A-Za-z0-9_]{36,})/g, replacement: '[REDACTED_GITHUB_TOKEN]' },
|
|
15
|
-
// GitLab tokens
|
|
16
|
-
{ pattern: /\b(glpat-[A-Za-z0-9_-]{20,})/g, replacement: '[REDACTED_GITLAB_TOKEN]' },
|
|
17
|
-
// Slack tokens
|
|
18
|
-
{ pattern: /\b(xoxb-[A-Za-z0-9-]{24,})/g, replacement: '[REDACTED_SLACK_TOKEN]' },
|
|
19
|
-
{ pattern: /\b(xoxp-[A-Za-z0-9-]{24,})/g, replacement: '[REDACTED_SLACK_TOKEN]' },
|
|
20
|
-
// AWS access keys
|
|
21
|
-
{ pattern: /\b(AKIA[A-Z0-9]{16})\b/g, replacement: '[REDACTED_AWS_KEY]' },
|
|
22
|
-
// Absolute Unix paths starting from home (e.g. /home/alice/projects/...)
|
|
23
|
-
{ pattern: /\/home\/[A-Za-z0-9_.-]+/g, replacement: '/home/[REDACTED]' },
|
|
24
|
-
// Absolute Unix paths in /Users (macOS)
|
|
25
|
-
{ pattern: /\/Users\/[A-Za-z0-9_.-]+/g, replacement: '/Users/[REDACTED]' },
|
|
26
|
-
// Windows user paths (C:\Users\username\...)
|
|
27
|
-
{ pattern: /[A-Za-z]:\\Users\\[A-Za-z0-9_.-]+/g, replacement: 'C:\\Users\\[REDACTED]' },
|
|
28
|
-
];
|
|
29
|
-
export function redactSensitiveData(text) {
|
|
30
|
-
let result = text;
|
|
31
|
-
for (const { pattern, replacement } of REDACT_PATTERNS) {
|
|
32
|
-
result = result.replace(pattern, replacement);
|
|
33
|
-
}
|
|
34
|
-
return result;
|
|
35
|
-
}
|
|
3
|
+
import { redactSensitiveData } from '../utils/redaction.js';
|
|
36
4
|
// ── Message redaction helper ─────────────────────────────────────────────────
|
|
37
5
|
/**
|
|
38
6
|
* redactMessage - Deep-clone a message and redact all string fields that may
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../../../../src/_internal/platform/hooks/runners/http.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../../../../src/_internal/platform/hooks/runners/http.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAMzE;;;GAGG;AACH,wBAAsB,GAAG,CAAC,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CA+DrF"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { logger } from '../../utils/logger.js';
|
|
2
2
|
import { summarizeError } from '../../utils/error-display.js';
|
|
3
3
|
import { classifyHostTrustTier, extractHostname, emitSsrfDeny } from '../../tools/fetch/trust-tiers.js';
|
|
4
|
+
import { instrumentedFetch } from '../../utils/fetch-with-timeout.js';
|
|
4
5
|
/**
|
|
5
6
|
* HTTP hook runner.
|
|
6
7
|
* POSTs the event JSON to the configured URL and parses the response as HookResult.
|
|
@@ -28,7 +29,7 @@ export async function run(hook, event) {
|
|
|
28
29
|
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
29
30
|
let response;
|
|
30
31
|
try {
|
|
31
|
-
response = await
|
|
32
|
+
response = await instrumentedFetch(url, {
|
|
32
33
|
method: 'POST',
|
|
33
34
|
headers: {
|
|
34
35
|
'Content-Type': 'application/json',
|