whale-code 6.5.10 → 6.6.0
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/cli/chat/ChatApp.js +7 -11
- package/dist/cli/chat/ChatApp.js.map +1 -1
- package/dist/cli/chat/ChatInput.js +7 -3
- package/dist/cli/chat/ChatInput.js.map +1 -1
- package/dist/cli/chat/MessageList.js +5 -6
- package/dist/cli/chat/MessageList.js.map +1 -1
- package/dist/cli/chat/StatusBar.d.ts +2 -2
- package/dist/cli/chat/StatusBar.js +90 -160
- package/dist/cli/chat/StatusBar.js.map +1 -1
- package/dist/cli/chat/components/LiveArea.js +78 -115
- package/dist/cli/chat/components/LiveArea.js.map +1 -1
- package/dist/cli/chat/components/StaticMessages.js +60 -79
- package/dist/cli/chat/components/StaticMessages.js.map +1 -1
- package/dist/cli/chat/hooks/useAgentLoop.js +45 -37
- package/dist/cli/chat/hooks/useAgentLoop.js.map +1 -1
- package/dist/cli/chat/store.d.ts +12 -0
- package/dist/cli/chat/store.js +19 -0
- package/dist/cli/chat/store.js.map +1 -1
- package/dist/cli/commands/doctor.js +1 -6
- package/dist/cli/commands/doctor.js.map +1 -1
- package/dist/cli/services/agent-loop-tools.js +11 -2
- package/dist/cli/services/agent-loop-tools.js.map +1 -1
- package/dist/cli/services/agent-loop.js +1 -1
- package/dist/cli/services/agent-loop.js.map +1 -1
- package/dist/cli/services/cli-agent-loop.js +3 -2
- package/dist/cli/services/cli-agent-loop.js.map +1 -1
- package/dist/cli/services/config-store.d.ts +8 -10
- package/dist/cli/services/config-store.js +14 -13
- package/dist/cli/services/config-store.js.map +1 -1
- package/dist/cli/services/memory-manager.js +2 -2
- package/dist/cli/services/memory-manager.js.map +1 -1
- package/dist/cli/services/permission-modes.js +14 -10
- package/dist/cli/services/permission-modes.js.map +1 -1
- package/dist/cli/services/session-client.js +2 -1
- package/dist/cli/services/session-client.js.map +1 -1
- package/dist/cli/services/session-persistence.js +14 -6
- package/dist/cli/services/session-persistence.js.map +1 -1
- package/dist/cli/setup/SetupApp.d.ts +2 -2
- package/dist/cli/setup/SetupApp.js +91 -254
- package/dist/cli/setup/SetupApp.js.map +1 -1
- package/dist/cli/shared/SpinnerSlot.js +4 -1
- package/dist/cli/shared/SpinnerSlot.js.map +1 -1
- package/dist/cli/status/StatusApp.js +3 -3
- package/dist/cli/status/StatusApp.js.map +1 -1
- package/dist/index.js +13 -3
- package/dist/index.js.map +1 -1
- package/dist/server/handlers/browser-lifecycle.js +10 -0
- package/dist/server/handlers/browser-lifecycle.js.map +1 -1
- package/dist/server/handlers/browser.js +16 -1
- package/dist/server/handlers/browser.js.map +1 -1
- package/dist/server/handlers/campaigns.js +11 -0
- package/dist/server/handlers/campaigns.js.map +1 -1
- package/dist/server/handlers/catalog-products.js +19 -5
- package/dist/server/handlers/catalog-products.js.map +1 -1
- package/dist/server/handlers/catalog.js +42 -8
- package/dist/server/handlers/catalog.js.map +1 -1
- package/dist/server/handlers/clickhouse.js +4 -4
- package/dist/server/handlers/clickhouse.js.map +1 -1
- package/dist/server/handlers/comms-email.js +70 -8
- package/dist/server/handlers/comms-email.js.map +1 -1
- package/dist/server/handlers/comms.js +63 -21
- package/dist/server/handlers/comms.js.map +1 -1
- package/dist/server/handlers/coupons.js +141 -77
- package/dist/server/handlers/coupons.js.map +1 -1
- package/dist/server/handlers/google-ads.js +280 -8
- package/dist/server/handlers/google-ads.js.map +1 -1
- package/dist/server/handlers/remove-bg.d.ts +33 -0
- package/dist/server/handlers/remove-bg.js +698 -44
- package/dist/server/handlers/remove-bg.js.map +1 -1
- package/dist/server/handlers/supply-chain.js +93 -1
- package/dist/server/handlers/supply-chain.js.map +1 -1
- package/dist/server/handlers/workflow-steps-types.d.ts +1 -1
- package/dist/server/handlers/workflow-steps-types.js +7 -1
- package/dist/server/handlers/workflow-steps-types.js.map +1 -1
- package/dist/server/handlers/workflow-steps.js +1 -1
- package/dist/server/handlers/workflow-steps.js.map +1 -1
- package/dist/server/index.js +122 -29
- package/dist/server/index.js.map +1 -1
- package/dist/server/lib/agent-loop-turn.js +33 -3
- package/dist/server/lib/agent-loop-turn.js.map +1 -1
- package/dist/server/lib/agent-loop-types.d.ts +6 -2
- package/dist/server/lib/agent-loop-types.js +14 -2
- package/dist/server/lib/agent-loop-types.js.map +1 -1
- package/dist/server/lib/clickhouse-client.js +4 -2
- package/dist/server/lib/clickhouse-client.js.map +1 -1
- package/dist/server/lib/code-worker.js +4 -1
- package/dist/server/lib/code-worker.js.map +1 -1
- package/dist/server/providers/anthropic.js +103 -33
- package/dist/server/providers/anthropic.js.map +1 -1
- package/dist/server/server-chat.js +2 -2
- package/dist/server/server-chat.js.map +1 -1
- package/dist/server/server-helpers.d.ts +8 -1
- package/dist/server/server-helpers.js +17 -3
- package/dist/server/server-helpers.js.map +1 -1
- package/dist/server/server-persist.js +34 -21
- package/dist/server/server-persist.js.map +1 -1
- package/dist/server/server-rate-limit.d.ts +0 -1
- package/dist/server/server-rate-limit.js +5 -5
- package/dist/server/server-rate-limit.js.map +1 -1
- package/dist/server/server-routes-approvals.js +2 -2
- package/dist/server/server-routes-approvals.js.map +1 -1
- package/dist/server/server-routes-auth.js +2 -2
- package/dist/server/server-routes-auth.js.map +1 -1
- package/dist/server/server-routes-events.js +2 -2
- package/dist/server/server-routes-events.js.map +1 -1
- package/dist/server/server-routes-public.js +4 -4
- package/dist/server/server-routes-public.js.map +1 -1
- package/dist/server/server-routes-webchat.js +3 -3
- package/dist/server/server-routes-webchat.js.map +1 -1
- package/dist/server/server-store-circuit-breaker.js +1 -1
- package/dist/server/server-store-circuit-breaker.js.map +1 -1
- package/dist/server/tool-router.js +7 -4
- package/dist/server/tool-router.js.map +1 -1
- package/dist/server/validation.js +11 -0
- package/dist/server/validation.js.map +1 -1
- package/dist/setup.js +5 -25
- package/dist/setup.js.map +1 -1
- package/dist/shared/api-client.js +38 -11
- package/dist/shared/api-client.js.map +1 -1
- package/package.json +12 -10
- package/vendor/ink/build/ink.js +68 -24
- package/vendor/ink/node_modules/react-devtools-core/README.md +152 -0
- package/vendor/ink/node_modules/react-devtools-core/backend.js +1 -0
- package/vendor/ink/node_modules/react-devtools-core/dist/648.chunk.js +2 -0
- package/vendor/ink/node_modules/react-devtools-core/dist/648.chunk.js.map +1 -0
- package/vendor/ink/node_modules/react-devtools-core/dist/backend.js +15691 -0
- package/vendor/ink/node_modules/react-devtools-core/dist/backend.js.map +1 -0
- package/vendor/ink/node_modules/react-devtools-core/dist/importFile.worker.worker.js +2 -0
- package/vendor/ink/node_modules/react-devtools-core/dist/importFile.worker.worker.js.map +1 -0
- package/vendor/ink/node_modules/react-devtools-core/dist/parseSourceAndMetadata.worker.worker.js +14 -0
- package/vendor/ink/node_modules/react-devtools-core/dist/parseSourceAndMetadata.worker.worker.js.map +1 -0
- package/vendor/ink/node_modules/react-devtools-core/dist/standalone.js +2 -0
- package/vendor/ink/node_modules/react-devtools-core/dist/standalone.js.map +1 -0
- package/vendor/ink/node_modules/react-devtools-core/node_modules/ws/LICENSE +21 -0
- package/vendor/ink/node_modules/react-devtools-core/node_modules/ws/README.md +495 -0
- package/vendor/ink/node_modules/react-devtools-core/node_modules/ws/browser.js +8 -0
- package/vendor/ink/node_modules/react-devtools-core/node_modules/ws/index.js +10 -0
- package/vendor/ink/node_modules/react-devtools-core/node_modules/ws/lib/buffer-util.js +129 -0
- package/vendor/ink/node_modules/react-devtools-core/node_modules/ws/lib/constants.js +10 -0
- package/vendor/ink/node_modules/react-devtools-core/node_modules/ws/lib/event-target.js +184 -0
- package/vendor/ink/node_modules/react-devtools-core/node_modules/ws/lib/extension.js +223 -0
- package/vendor/ink/node_modules/react-devtools-core/node_modules/ws/lib/limiter.js +55 -0
- package/vendor/ink/node_modules/react-devtools-core/node_modules/ws/lib/permessage-deflate.js +518 -0
- package/vendor/ink/node_modules/react-devtools-core/node_modules/ws/lib/receiver.js +607 -0
- package/vendor/ink/node_modules/react-devtools-core/node_modules/ws/lib/sender.js +409 -0
- package/vendor/ink/node_modules/react-devtools-core/node_modules/ws/lib/stream.js +180 -0
- package/vendor/ink/node_modules/react-devtools-core/node_modules/ws/lib/validation.js +104 -0
- package/vendor/ink/node_modules/react-devtools-core/node_modules/ws/lib/websocket-server.js +449 -0
- package/vendor/ink/node_modules/react-devtools-core/node_modules/ws/lib/websocket.js +1197 -0
- package/vendor/ink/node_modules/react-devtools-core/node_modules/ws/package.json +56 -0
- package/vendor/ink/node_modules/react-devtools-core/package.json +38 -0
- package/vendor/ink/node_modules/react-devtools-core/standalone.js +1 -0
- package/dist/cli/__tests__/print-mode-streaming.test.js +0 -270
- package/dist/cli/__tests__/print-mode.basic-output.test.js +0 -230
- package/dist/cli/__tests__/print-mode.session-errors.test.js +0 -252
- package/dist/cli/__tests__/print-mode.test.js +0 -273
- package/dist/cli/__tests__/serve-mode-messages.test.js +0 -338
- package/dist/cli/__tests__/serve-mode.messages.part2.test.js +0 -266
- package/dist/cli/__tests__/serve-mode.messages.test.js +0 -277
- package/dist/cli/__tests__/serve-mode.startup-http.test.js +0 -279
- package/dist/cli/__tests__/serve-mode.test.js +0 -345
- package/dist/cli/chat/NodeManager.d.ts +0 -30
- package/dist/cli/chat/NodeManager.js +0 -66
- package/dist/cli/chat/NodeManager.js.map +0 -1
- package/dist/cli/chat/chat-input-menu-handler.d.ts +0 -32
- package/dist/cli/chat/hooks/slash-imsg-handlers.js +0 -148
- package/dist/cli/chat/hooks/slash-imsg-handlers.js.map +0 -1
- package/dist/cli/chat/hooks/useStreamingReducer.d.ts +0 -66
- package/dist/cli/commands/__tests__/config-cmd.test.js +0 -270
- package/dist/cli/commands/__tests__/doctor.test.js +0 -257
- package/dist/cli/commands/__tests__/imsg-node-bridge.test.js +0 -99
- package/dist/cli/commands/__tests__/imsg-utils.test.js +0 -73
- package/dist/cli/commands/__tests__/init.test.js +0 -214
- package/dist/cli/commands/__tests__/mcp.test.js +0 -287
- package/dist/cli/commands/imsg-watcher-helpers.d.ts +0 -40
- package/dist/cli/commands/imsg-watcher-helpers.js +0 -184
- package/dist/cli/commands/imsg-watcher-helpers.js.map +0 -1
- package/dist/cli/commands/imsg-watcher.d.ts +0 -11
- package/dist/cli/commands/imsg-watcher.js +0 -230
- package/dist/cli/commands/imsg-watcher.js.map +0 -1
- package/dist/cli/services/__tests__/agent-definitions.test.js +0 -153
- package/dist/cli/services/__tests__/agent-events-global.test.js +0 -39
- package/dist/cli/services/__tests__/agent-events.part2.test.js +0 -113
- package/dist/cli/services/__tests__/agent-events.test.js +0 -157
- package/dist/cli/services/__tests__/agent-loop-auth.test.js +0 -392
- package/dist/cli/services/__tests__/agent-loop-budget.test.js +0 -389
- package/dist/cli/services/__tests__/agent-loop-tools-lifecycle.test.js +0 -430
- package/dist/cli/services/__tests__/agent-loop-tools-maxturns.test.js +0 -486
- package/dist/cli/services/__tests__/agent-loop-utils-execution.test.js +0 -528
- package/dist/cli/services/__tests__/agent-loop-utils-helpers.test.js +0 -466
- package/dist/cli/services/__tests__/agent-worker-base-execute.test.js +0 -257
- package/dist/cli/services/__tests__/agent-worker-base-helpers.test.js +0 -198
- package/dist/cli/services/__tests__/agent-worker-base.test.js +0 -278
- package/dist/cli/services/__tests__/auth-service-exports.test.js +0 -41
- package/dist/cli/services/__tests__/auth-service.part2.test.js +0 -169
- package/dist/cli/services/__tests__/auth-service.test.js +0 -242
- package/dist/cli/services/__tests__/background-processes.test.js +0 -282
- package/dist/cli/services/__tests__/claude-md-loader.test.js +0 -134
- package/dist/cli/services/__tests__/config-store.test.js +0 -247
- package/dist/cli/services/__tests__/debug-log.test.js +0 -199
- package/dist/cli/services/__tests__/edge-cases-caching.test.js +0 -174
- package/dist/cli/services/__tests__/edge-cases-compaction-core.test.js +0 -226
- package/dist/cli/services/__tests__/edge-cases-compaction-openai.test.js +0 -152
- package/dist/cli/services/__tests__/edge-cases-compaction-shapes.test.js +0 -53
- package/dist/cli/services/__tests__/edge-cases-compaction-thinking.test.js +0 -226
- package/dist/cli/services/__tests__/edge-cases-compaction.test.js +0 -131
- package/dist/cli/services/__tests__/edge-cases-paths.test.js +0 -86
- package/dist/cli/services/__tests__/error-logger-messages.test.js +0 -81
- package/dist/cli/services/__tests__/error-logger-transport.test.js +0 -119
- package/dist/cli/services/__tests__/error-logger.test.js +0 -264
- package/dist/cli/services/__tests__/file-history.test.js +0 -136
- package/dist/cli/services/__tests__/git-context-cache-reset.test.js +0 -223
- package/dist/cli/services/__tests__/git-context.test.js +0 -241
- package/dist/cli/services/__tests__/interactive-tools-execute.test.js +0 -166
- package/dist/cli/services/__tests__/interactive-tools-plan.test.js +0 -197
- package/dist/cli/services/__tests__/interactive-tools.part2.test.js +0 -168
- package/dist/cli/services/__tests__/interactive-tools.test.js +0 -179
- package/dist/cli/services/__tests__/keybinding-manager.test.js +0 -205
- package/dist/cli/services/__tests__/local-tools-dispatch.test.js +0 -404
- package/dist/cli/services/__tests__/local-tools.test.js +0 -238
- package/dist/cli/services/__tests__/lsp-manager.test.js +0 -364
- package/dist/cli/services/__tests__/mcp-client-connect-disconnect.test.js +0 -310
- package/dist/cli/services/__tests__/mcp-client.test.js +0 -93
- package/dist/cli/services/__tests__/memory-manager.test.js +0 -154
- package/dist/cli/services/__tests__/model-manager-utils.test.js +0 -154
- package/dist/cli/services/__tests__/model-manager.test.js +0 -175
- package/dist/cli/services/__tests__/permission-modes.test.js +0 -222
- package/dist/cli/services/__tests__/ripgrep.test.js +0 -328
- package/dist/cli/services/__tests__/server-tools-execute.test.js +0 -317
- package/dist/cli/services/__tests__/server-tools.test.js +0 -272
- package/dist/cli/services/__tests__/session-persistence.test.js +0 -245
- package/dist/cli/services/__tests__/subagent-basic.test.js +0 -489
- package/dist/cli/services/__tests__/subagent-edge.test.js +0 -545
- package/dist/cli/services/__tests__/subagent-prompts.test.js +0 -558
- package/dist/cli/services/__tests__/subagent-worker-errors.test.js +0 -255
- package/dist/cli/services/__tests__/subagent-worker.test.js +0 -242
- package/dist/cli/services/__tests__/system-prompt.test.js +0 -210
- package/dist/cli/services/__tests__/team-lead-comms-messaging.test.js +0 -250
- package/dist/cli/services/__tests__/team-lead-comms-result.test.js +0 -232
- package/dist/cli/services/__tests__/team-lead-comms-stop.test.js +0 -344
- package/dist/cli/services/__tests__/team-lead-comms.test.js +0 -285
- package/dist/cli/services/__tests__/team-lead-create.test.js +0 -327
- package/dist/cli/services/__tests__/team-lead-run.test.js +0 -318
- package/dist/cli/services/__tests__/team-lead-stop.test.js +0 -199
- package/dist/cli/services/__tests__/team-state-comms.test.js +0 -240
- package/dist/cli/services/__tests__/team-state-core.test.js +0 -230
- package/dist/cli/services/__tests__/team-state-tasks-complete-fail-available.test.js +0 -224
- package/dist/cli/services/__tests__/team-state-tasks.test.js +0 -184
- package/dist/cli/services/__tests__/telemetry-ai-metadata.test.js +0 -116
- package/dist/cli/services/__tests__/telemetry.part2.test.js +0 -195
- package/dist/cli/services/__tests__/telemetry.test.js +0 -176
- package/dist/cli/services/agent-loop-iteration.d.ts +0 -13
- package/dist/cli/services/agent-loop-setup.d.ts +0 -32
- package/dist/cli/services/agent-worker-base-api.d.ts +0 -19
- package/dist/cli/services/agent-worker-base-helpers.d.ts +0 -27
- package/dist/cli/services/agent-worker-base-tools.d.ts +0 -16
- package/dist/cli/services/agent-worker-base-types.d.ts +0 -81
- package/dist/cli/services/background-agents.d.ts +0 -26
- package/dist/cli/services/background-processes-ops.d.ts +0 -24
- package/dist/cli/services/background-tool-defs.d.ts +0 -50
- package/dist/cli/services/config-modules-model.test.js +0 -133
- package/dist/cli/services/config-modules-permission.test.js +0 -85
- package/dist/cli/services/config-modules-permissions.test.js +0 -85
- package/dist/cli/services/config-modules-session.test.js +0 -297
- package/dist/cli/services/format-server-response-columns.test.js +0 -265
- package/dist/cli/services/format-server-response-fallback.test.js +0 -65
- package/dist/cli/services/format-server-response-primitives-basic.test.js +0 -261
- package/dist/cli/services/format-server-response-primitives-nested.test.js +0 -188
- package/dist/cli/services/format-server-response-primitives.test.js +0 -300
- package/dist/cli/services/format-server-response-realworld.test.js +0 -248
- package/dist/cli/services/format-server-response-values.test.js +0 -247
- package/dist/cli/services/hooks-runners.test.js +0 -184
- package/dist/cli/services/hooks.glob-load.test.js +0 -233
- package/dist/cli/services/hooks.run-hooks.test.js +0 -184
- package/dist/cli/services/hooks.test.js +0 -233
- package/dist/cli/services/ink-incremental.d.ts +0 -19
- package/dist/cli/services/ink-incremental.js +0 -59
- package/dist/cli/services/ink-incremental.js.map +0 -1
- package/dist/cli/services/ink-resize-fix.d.ts +0 -18
- package/dist/cli/services/ink-resize-fix.js +0 -76
- package/dist/cli/services/ink-resize-fix.js.map +0 -1
- package/dist/cli/services/ink-sync-output.d.ts +0 -12
- package/dist/cli/services/ink-sync-output.js +0 -16
- package/dist/cli/services/ink-sync-output.js.map +0 -1
- package/dist/cli/services/interactive-tool-defs.d.ts +0 -80
- package/dist/cli/services/local-tools-definitions.d.ts +0 -6
- package/dist/cli/services/local-tools-files.test.js +0 -256
- package/dist/cli/services/local-tools-read-many.d.ts +0 -6
- package/dist/cli/services/model-router.test.js +0 -245
- package/dist/cli/services/rewind-rewindTo.test.js +0 -202
- package/dist/cli/services/rewind.test.js +0 -175
- package/dist/cli/services/sandbox.test.js +0 -198
- package/dist/cli/services/subagent-execution.d.ts +0 -12
- package/dist/cli/services/team-lead-auto.d.ts +0 -11
- package/dist/cli/services/team-lead-execution.d.ts +0 -28
- package/dist/cli/services/teammate-loop.js +0 -557
- package/dist/cli/services/teammate-loop.js.map +0 -1
- package/dist/cli/services/tools/__tests__/agent-tools-tasks-teams.test.js +0 -250
- package/dist/cli/services/tools/__tests__/agent-tools-teams.test.js +0 -200
- package/dist/cli/services/tools/__tests__/agent-tools.test.js +0 -340
- package/dist/cli/services/tools/__tests__/file-ops-cache.test.js +0 -152
- package/dist/cli/services/tools/__tests__/file-ops-notebook.test.js +0 -249
- package/dist/cli/services/tools/__tests__/file-ops-read.test.js +0 -261
- package/dist/cli/services/tools/__tests__/file-ops-write.test.js +0 -292
- package/dist/cli/services/tools/__tests__/search-tools-rg.test.js +0 -92
- package/dist/cli/services/tools/__tests__/search-tools.part2.test.js +0 -174
- package/dist/cli/services/tools/__tests__/search-tools.test.js +0 -227
- package/dist/cli/services/tools/__tests__/shell-exec-allowed-core.test.js +0 -163
- package/dist/cli/services/tools/__tests__/shell-exec-allowed-extended.test.js +0 -220
- package/dist/cli/services/tools/__tests__/shell-exec-allowed.part2.test.js +0 -215
- package/dist/cli/services/tools/__tests__/shell-exec-allowed.test.js +0 -154
- package/dist/cli/services/tools/__tests__/shell-exec-blocked.test.js +0 -132
- package/dist/cli/services/tools/__tests__/shell-exec-execution.test.js +0 -245
- package/dist/cli/services/tools/__tests__/task-manager-create.test.js +0 -110
- package/dist/cli/services/tools/__tests__/task-manager-crud.test.js +0 -339
- package/dist/cli/services/tools/__tests__/task-manager-list-get.test.js +0 -343
- package/dist/cli/services/tools/__tests__/task-manager-query.test.js +0 -346
- package/dist/cli/services/tools/__tests__/task-manager-routing.test.js +0 -58
- package/dist/cli/services/tools/__tests__/task-manager-update.test.js +0 -224
- package/dist/cli/services/tools/__tests__/task-manager.test.js +0 -159
- package/dist/cli/services/tools/__tests__/web-tools-html-search.test.js +0 -227
- package/dist/cli/services/tools/__tests__/web-tools.test.js +0 -285
- package/dist/cli/services/tools/shell-exec.test.js +0 -148
- package/dist/cli/shared/SharedTick.d.ts +0 -10
- package/dist/cli/shared/__tests__/markdown.test.js +0 -188
- package/dist/local-agent/__tests__/connection-disconnect.test.js +0 -201
- package/dist/local-agent/__tests__/connection-lifecycle.test.js +0 -289
- package/dist/local-agent/__tests__/connection-msghandling.test.js +0 -311
- package/dist/local-agent/__tests__/connection-reconnect.test.js +0 -230
- package/dist/local-agent/__tests__/connection-toolexec.test.js +0 -253
- package/dist/local-agent/__tests__/discovery.test.js +0 -328
- package/dist/local-agent/__tests__/executor-background.test.js +0 -219
- package/dist/local-agent/__tests__/executor-exec.test.js +0 -221
- package/dist/local-agent/__tests__/executor-jobs-sessions.test.js +0 -220
- package/dist/local-agent/__tests__/executor-system-info.test.js +0 -133
- package/dist/local-agent/__tests__/executor-systeminfo.test.js +0 -109
- package/dist/local-agent/__tests__/executor.test.js +0 -235
- package/dist/local-agent/__tests__/index.test.js +0 -139
- package/dist/node/__tests__/cli-channels.test.js +0 -293
- package/dist/node/__tests__/cli-config-edge.test.js +0 -154
- package/dist/node/__tests__/cli-config.test.js +0 -215
- package/dist/node/__tests__/config.test.js +0 -292
- package/dist/node/__tests__/runtime-heartbeat.test.js +0 -153
- package/dist/node/__tests__/runtime-lifecycle-init.test.js +0 -263
- package/dist/node/__tests__/runtime-lifecycle-stats.test.js +0 -180
- package/dist/node/__tests__/runtime-lifecycle.test.js +0 -305
- package/dist/node/__tests__/runtime-relay.test.js +0 -341
- package/dist/node/adapters/__tests__/base.test.js +0 -286
- package/dist/node/adapters/__tests__/discord.test.js +0 -284
- package/dist/node/adapters/__tests__/email-send.test.js +0 -295
- package/dist/node/adapters/__tests__/email.inbound-send.test.js +0 -217
- package/dist/node/adapters/__tests__/email.lifecycle.test.js +0 -211
- package/dist/node/adapters/__tests__/email.test.js +0 -290
- package/dist/node/adapters/__tests__/email.webhook-send.test.js +0 -251
- package/dist/node/adapters/__tests__/imessage-filter.test.js +0 -183
- package/dist/node/adapters/__tests__/imessage-lifecycle.test.js +0 -215
- package/dist/node/adapters/__tests__/imessage-send-restart.test.js +0 -227
- package/dist/node/adapters/__tests__/slack.part2.test.js +0 -135
- package/dist/node/adapters/__tests__/slack.test.js +0 -241
- package/dist/node/adapters/__tests__/sms-extras.test.js +0 -108
- package/dist/node/adapters/__tests__/sms-lifecycle.test.js +0 -203
- package/dist/node/adapters/__tests__/sms-messaging.test.js +0 -266
- package/dist/node/adapters/__tests__/sms.part2.test.js +0 -174
- package/dist/node/adapters/__tests__/sms.test.js +0 -253
- package/dist/node/adapters/__tests__/telegram-polling.test.js +0 -256
- package/dist/node/adapters/__tests__/telegram-send.test.js +0 -166
- package/dist/node/adapters/__tests__/webchat-inbound.test.js +0 -188
- package/dist/node/adapters/__tests__/webchat-outbound.test.js +0 -178
- package/dist/node/adapters/__tests__/whatsapp-inbound.test.js +0 -200
- package/dist/node/adapters/__tests__/whatsapp-send.test.js +0 -212
- package/dist/node/adapters/__tests__/whatsapp.test.js +0 -280
- package/dist/server/__tests__/gateway-fast-fail.test.js +0 -160
- package/dist/server/__tests__/local-agent-gateway.test.js +0 -186
- package/dist/server/__tests__/proxy-handlers-delegation.test.js +0 -240
- package/dist/server/__tests__/proxy-handlers-validation.test.js +0 -211
- package/dist/server/__tests__/proxy-handlers.part2.test.js +0 -240
- package/dist/server/__tests__/proxy-handlers.test.js +0 -213
- package/dist/server/__tests__/strip-base64-e2e.test.js +0 -303
- package/dist/server/__tests__/strip-base64.test.js +0 -256
- package/dist/server/__tests__/tool-router-agent-tools.test.js +0 -324
- package/dist/server/__tests__/tool-router-execute-core.test.js +0 -357
- package/dist/server/__tests__/tool-router-execute-permissions.test.js +0 -332
- package/dist/server/__tests__/tool-router-execute.test.js +0 -348
- package/dist/server/__tests__/tool-router-load.test.js +0 -432
- package/dist/server/__tests__/tool-router-permissions.test.js +0 -359
- package/dist/server/__tests__/tool-router-registry-cache.test.js +0 -383
- package/dist/server/__tests__/tool-router-registry-handlers.test.js +0 -272
- package/dist/server/__tests__/tool-router-registry.test.js +0 -331
- package/dist/server/__tests__/validation-inventory.test.js +0 -250
- package/dist/server/__tests__/validation-misc.test.js +0 -243
- package/dist/server/__tests__/validation-supply-chain.test.js +0 -188
- package/dist/server/__tests__/worker.test.js +0 -265
- package/dist/server/handlers/__tests__/conversation-lock.test.js +0 -117
- package/dist/server/handlers/__tests__/e2e/auth-cross-platform-login.e2e.test.js +0 -268
- package/dist/server/handlers/__tests__/e2e/auth-cross-platform-tokens.e2e.test.js +0 -264
- package/dist/server/handlers/__tests__/e2e/email-pipeline-send.e2e.test.js +0 -214
- package/dist/server/handlers/__tests__/e2e/email-pipeline-threads.e2e.test.js +0 -168
- package/dist/server/handlers/__tests__/e2e/error-logging-pipeline-dedup.e2e.test.js +0 -229
- package/dist/server/handlers/__tests__/e2e/error-logging-pipeline.e2e.test.js +0 -239
- package/dist/server/handlers/__tests__/e2e/error-logging-rate-limit.e2e.test.js +0 -150
- package/dist/server/handlers/__tests__/e2e/inventory-sync-guards.e2e.test.js +0 -177
- package/dist/server/handlers/__tests__/e2e/inventory-sync.e2e.test.js +0 -228
- package/dist/server/handlers/__tests__/e2e/inventory-sync.part2.e2e.test.js +0 -188
- package/dist/server/handlers/__tests__/e2e/order-lifecycle-fulfillment.e2e.test.js +0 -295
- package/dist/server/handlers/__tests__/e2e/order-lifecycle.e2e.test.js +0 -277
- package/dist/server/handlers/__tests__/e2e/order-lifecycle.fulfillment.e2e.test.js +0 -307
- package/dist/server/handlers/__tests__/e2e/order-lifecycle.setup.e2e.test.js +0 -177
- package/dist/server/handlers/__tests__/e2e/storefront-checkout-cart.e2e.test.js +0 -255
- package/dist/server/handlers/__tests__/e2e/storefront-checkout-webhook.e2e.test.js +0 -231
- package/dist/server/handlers/__tests__/e2e/workflow-execution-failures.e2e.test.js +0 -235
- package/dist/server/handlers/__tests__/e2e/workflow-execution.e2e.test.js +0 -294
- package/dist/server/handlers/__tests__/e2e/workflow-security.e2e.test.js +0 -311
- package/dist/server/handlers/__tests__/e2e/workflow-security.part2.e2e.test.js +0 -267
- package/dist/server/handlers/__tests__/workflow-cache.test.js +0 -237
- package/dist/server/handlers/analytics-errors-edge.test.js +0 -173
- package/dist/server/handlers/analytics.test.js +0 -280
- package/dist/server/handlers/api-docs-examples-ext.d.ts +0 -9
- package/dist/server/handlers/api-docs-examples-ext.js +0 -278
- package/dist/server/handlers/api-docs-examples-ext.js.map +0 -1
- package/dist/server/handlers/api-docs-examples.d.ts +0 -8
- package/dist/server/handlers/api-docs-examples.js +0 -221
- package/dist/server/handlers/api-docs-examples.js.map +0 -1
- package/dist/server/handlers/api-docs-sections-ext.d.ts +0 -2
- package/dist/server/handlers/api-docs-sections-ext.js +0 -497
- package/dist/server/handlers/api-docs-sections-ext.js.map +0 -1
- package/dist/server/handlers/api-docs-sections.d.ts +0 -21
- package/dist/server/handlers/api-docs-sections.js +0 -293
- package/dist/server/handlers/api-docs-sections.js.map +0 -1
- package/dist/server/handlers/api-keys.part2.test.js +0 -157
- package/dist/server/handlers/api-keys.test.js +0 -161
- package/dist/server/handlers/billing-routes.test.js +0 -123
- package/dist/server/handlers/billing.test.js +0 -215
- package/dist/server/handlers/browser-actions-errors.test.js +0 -94
- package/dist/server/handlers/browser-actions.part2.test.js +0 -190
- package/dist/server/handlers/browser-actions.test.js +0 -190
- package/dist/server/handlers/browser-validation.test.js +0 -257
- package/dist/server/handlers/catalog.test.js +0 -297
- package/dist/server/handlers/comms.test.js +0 -289
- package/dist/server/handlers/creations-advanced-collections.test.js +0 -214
- package/dist/server/handlers/creations-advanced-generate.test.js +0 -142
- package/dist/server/handlers/creations-advanced.test.js +0 -171
- package/dist/server/handlers/creations-collections-preview.test.js +0 -214
- package/dist/server/handlers/creations-crud.test.js +0 -260
- package/dist/server/handlers/creations-mutations.test.js +0 -197
- package/dist/server/handlers/crm.test.js +0 -179
- package/dist/server/handlers/discovery-advertise.test.js +0 -185
- package/dist/server/handlers/discovery-scan.test.js +0 -233
- package/dist/server/handlers/embeddings-embed-search.test.js +0 -196
- package/dist/server/handlers/embeddings-index-delete-stats.test.js +0 -140
- package/dist/server/handlers/embeddings-search.test.js +0 -221
- package/dist/server/handlers/embeddings.test.js +0 -137
- package/dist/server/handlers/enrichment-breach.d.ts +0 -8
- package/dist/server/handlers/enrichment-breach.js +0 -266
- package/dist/server/handlers/enrichment-breach.js.map +0 -1
- package/dist/server/handlers/enrichment-data.d.ts +0 -13
- package/dist/server/handlers/enrichment-data.js +0 -145
- package/dist/server/handlers/enrichment-data.js.map +0 -1
- package/dist/server/handlers/enrichment-mutations.test.js +0 -240
- package/dist/server/handlers/enrichment-queries.test.js +0 -181
- package/dist/server/handlers/enrichment-validation.test.js +0 -177
- package/dist/server/handlers/enrichment-writes.d.ts +0 -16
- package/dist/server/handlers/enrichment-writes.js +0 -226
- package/dist/server/handlers/enrichment-writes.js.map +0 -1
- package/dist/server/handlers/image-gen.test.js +0 -205
- package/dist/server/handlers/inventory.test.js +0 -380
- package/dist/server/handlers/kali-background.test.js +0 -222
- package/dist/server/handlers/kali-errors.test.js +0 -92
- package/dist/server/handlers/kali-validation.test.js +0 -234
- package/dist/server/handlers/llm-providers-actions.test.js +0 -220
- package/dist/server/handlers/llm-providers-anthropic.test.js +0 -239
- package/dist/server/handlers/llm-providers-failover.test.js +0 -232
- package/dist/server/handlers/llm-providers-providers.test.js +0 -300
- package/dist/server/handlers/llm-providers-validation.test.js +0 -239
- package/dist/server/handlers/local-agent-tools.test.js +0 -224
- package/dist/server/handlers/local-agent.test.js +0 -198
- package/dist/server/handlers/local-agent.tools-status.test.js +0 -204
- package/dist/server/handlers/local-agent.validation-exec.test.js +0 -182
- package/dist/server/handlers/meta-ads-audience-rules.test.js +0 -243
- package/dist/server/handlers/meta-ads-audience-targeting.test.js +0 -205
- package/dist/server/handlers/meta-ads-audiences-targeting.test.js +0 -383
- package/dist/server/handlers/meta-ads-crud-ads.test.js +0 -136
- package/dist/server/handlers/meta-ads-crud-campaigns.test.js +0 -189
- package/dist/server/handlers/meta-ads-crud-create.test.js +0 -303
- package/dist/server/handlers/meta-ads-crud-list-update.test.js +0 -259
- package/dist/server/handlers/meta-ads-delete-publish-sync.test.js +0 -282
- package/dist/server/handlers/meta-ads-insights.test.js +0 -80
- package/dist/server/handlers/meta-ads-list-get.test.js +0 -237
- package/dist/server/handlers/meta-ads-publish-delete.test.js +0 -254
- package/dist/server/handlers/meta-ads-publish-helpers.js +0 -117
- package/dist/server/handlers/meta-ads-publish-helpers.js.map +0 -1
- package/dist/server/handlers/meta-ads-publish-sync.test.js +0 -205
- package/dist/server/handlers/meta-ads-publish.test.js +0 -254
- package/dist/server/handlers/meta-ads-sync-insights.test.js +0 -184
- package/dist/server/handlers/meta-ads-update.test.js +0 -117
- package/dist/server/handlers/nodes-channels.test.js +0 -413
- package/dist/server/handlers/nodes-events.test.js +0 -131
- package/dist/server/handlers/nodes-list-delete.test.js +0 -171
- package/dist/server/handlers/nodes-messages-delivery.test.js +0 -208
- package/dist/server/handlers/nodes-messages.test.js +0 -211
- package/dist/server/handlers/nodes-register.test.js +0 -277
- package/dist/server/handlers/nodes.test.js +0 -353
- package/dist/server/handlers/operations.test.js +0 -136
- package/dist/server/handlers/platform-telemetry.test.js +0 -200
- package/dist/server/handlers/platform-websearch.test.js +0 -160
- package/dist/server/handlers/storefront.test.js +0 -329
- package/dist/server/handlers/supply-chain.test.js +0 -347
- package/dist/server/handlers/transcription.test.js +0 -118
- package/dist/server/handlers/video-gen-veo.js +0 -114
- package/dist/server/handlers/video-gen-veo.js.map +0 -1
- package/dist/server/handlers/video-gen.test.js +0 -146
- package/dist/server/handlers/voice.test.js +0 -153
- package/dist/server/handlers/workflow-steps.test.js +0 -330
- package/dist/server/handlers/workflows-extras.test.js +0 -65
- package/dist/server/handlers/workflows.part2.test.js +0 -170
- package/dist/server/handlers/workflows.test.js +0 -281
- package/dist/server/lib/__tests__/batch-client-conversion-jsonl.test.js +0 -171
- package/dist/server/lib/__tests__/batch-client-polling.test.js +0 -292
- package/dist/server/lib/__tests__/batch-client-queue.test.js +0 -270
- package/dist/server/lib/__tests__/clickhouse-buffer.test.js +0 -236
- package/dist/server/lib/__tests__/code-worker-edge-cases.test.js +0 -118
- package/dist/server/lib/__tests__/code-worker-pool-execute.test.js +0 -193
- package/dist/server/lib/__tests__/code-worker-pool-execution.test.js +0 -165
- package/dist/server/lib/__tests__/code-worker-pool-init.test.js +0 -131
- package/dist/server/lib/__tests__/code-worker-pool.test.js +0 -194
- package/dist/server/lib/__tests__/code-worker-sandbox-ops.test.js +0 -123
- package/dist/server/lib/__tests__/code-worker-sandbox.test.js +0 -217
- package/dist/server/lib/__tests__/code-worker.test.js +0 -179
- package/dist/server/lib/__tests__/compaction-service-generate.test.js +0 -229
- package/dist/server/lib/__tests__/compaction-service.test.js +0 -319
- package/dist/server/lib/__tests__/otel.test.js +0 -146
- package/dist/server/lib/__tests__/prompt-sanitizer-validation.test.js +0 -165
- package/dist/server/lib/__tests__/prompt-sanitizer.sanitize.test.js +0 -343
- package/dist/server/lib/__tests__/prompt-sanitizer.test.js +0 -328
- package/dist/server/lib/__tests__/prompt-sanitizer.validate-tool.test.js +0 -145
- package/dist/server/lib/__tests__/provider-capabilities.test.js +0 -263
- package/dist/server/lib/__tests__/provider-failover-routing.test.js +0 -145
- package/dist/server/lib/__tests__/provider-failover-state.test.js +0 -131
- package/dist/server/lib/__tests__/rate-limiter-budgets.test.js +0 -216
- package/dist/server/lib/__tests__/rate-limiter.budgets-tools.test.js +0 -113
- package/dist/server/lib/__tests__/rate-limiter.check-request.test.js +0 -141
- package/dist/server/lib/__tests__/rate-limiter.stats-lifecycle.test.js +0 -135
- package/dist/server/lib/__tests__/rate-limiter.test.js +0 -207
- package/dist/server/lib/__tests__/server-agent-loop-abort-conditions.test.js +0 -544
- package/dist/server/lib/__tests__/server-agent-loop-abort.part2.test.js +0 -504
- package/dist/server/lib/__tests__/server-agent-loop-abort.test.js +0 -396
- package/dist/server/lib/__tests__/server-agent-loop-compaction.test.js +0 -397
- package/dist/server/lib/__tests__/server-agent-loop-failover.test.js +0 -356
- package/dist/server/lib/__tests__/server-agent-loop-features-caching.test.js +0 -519
- package/dist/server/lib/__tests__/server-agent-loop-features-edges.test.js +0 -512
- package/dist/server/lib/__tests__/server-subagent-bailout.test.js +0 -194
- package/dist/server/lib/__tests__/server-subagent-basics.test.js +0 -348
- package/dist/server/lib/__tests__/server-subagent-errors-abort.test.js +0 -319
- package/dist/server/lib/__tests__/server-subagent-errors-progress.test.js +0 -253
- package/dist/server/lib/__tests__/server-subagent-errors.part2.test.js +0 -253
- package/dist/server/lib/__tests__/server-subagent-errors.test.js +0 -319
- package/dist/server/lib/__tests__/session-checkpoint-load.test.js +0 -275
- package/dist/server/lib/__tests__/session-checkpoint-save.test.js +0 -159
- package/dist/server/lib/__tests__/ssrf-guard.test.js +0 -93
- package/dist/server/lib/__tests__/supabase-client.test.js +0 -111
- package/dist/server/lib/__tests__/template-resolver.test.js +0 -317
- package/dist/server/lib/__tests__/utils-timeout.test.js +0 -49
- package/dist/server/lib/__tests__/utils.test.js +0 -322
- package/dist/server/providers/__tests__/anthropic-adapter.test.js +0 -228
- package/dist/server/providers/__tests__/anthropic-betas-toolchoice.test.js +0 -257
- package/dist/server/providers/__tests__/anthropic-errors.test.js +0 -262
- package/dist/server/providers/__tests__/anthropic-stream-core.test.js +0 -275
- package/dist/server/providers/__tests__/anthropic-streaming-betas.test.js +0 -247
- package/dist/server/providers/__tests__/anthropic-streaming-core.test.js +0 -275
- package/dist/server/providers/__tests__/bedrock-config.test.js +0 -177
- package/dist/server/providers/__tests__/bedrock-stream-behavior-streaming.test.js +0 -272
- package/dist/server/providers/__tests__/bedrock-stream-behavior-toolchoice.test.js +0 -214
- package/dist/server/providers/__tests__/bedrock-stream-behavior.part2.test.js +0 -165
- package/dist/server/providers/__tests__/bedrock-stream-behavior.test.js +0 -309
- package/dist/server/providers/__tests__/bedrock-stream-body-credentials.test.js +0 -170
- package/dist/server/providers/__tests__/bedrock-stream-body-extras.test.js +0 -183
- package/dist/server/providers/__tests__/bedrock-stream-body-request.test.js +0 -305
- package/dist/server/providers/__tests__/bedrock-stream-body.part2.test.js +0 -305
- package/dist/server/providers/__tests__/bedrock-stream-body.test.js +0 -175
- package/dist/server/providers/__tests__/bedrock-stream-errors.test.js +0 -165
- package/dist/server/providers/__tests__/gemini-config-methods.test.js +0 -182
- package/dist/server/providers/__tests__/gemini-config-streaming.test.js +0 -257
- package/dist/server/providers/__tests__/gemini-conversion-messages.test.js +0 -247
- package/dist/server/providers/__tests__/gemini-conversion-schema.test.js +0 -365
- package/dist/server/providers/__tests__/gemini-tools-choice.test.js +0 -221
- package/dist/server/providers/__tests__/gemini-tools-fn.test.js +0 -252
- package/dist/server/providers/__tests__/openai-config.test.js +0 -194
- package/dist/server/providers/__tests__/openai-conversion.test.js +0 -276
- package/dist/server/providers/__tests__/openai-messages.test.js +0 -261
- package/dist/server/providers/__tests__/openai-streaming.test.js +0 -394
- package/dist/server/providers/__tests__/openai-tools-cache.test.js +0 -227
- package/dist/server/providers/__tests__/registry.test.js +0 -183
- package/dist/server/providers/__tests__/shared.test.js +0 -297
- package/dist/shared/agent-core-config.test.js +0 -132
- package/dist/shared/agent-core-context-thinking.test.js +0 -293
- package/dist/shared/agent-core-loop-calls.test.js +0 -174
- package/dist/shared/agent-core-loop-detector-bail.test.js +0 -201
- package/dist/shared/agent-core-loop-detector.test.js +0 -195
- package/dist/shared/agent-core-loop-errors.test.js +0 -258
- package/dist/shared/agent-core-pricing.test.js +0 -191
- package/dist/shared/agent-core-sanitize-retry.test.js +0 -129
- package/dist/shared/api-client-build-request.test.js +0 -228
- package/dist/shared/api-client-build-system-caching.test.js +0 -107
- package/dist/shared/api-client-build.test.js +0 -223
- package/dist/shared/api-client-config.d.ts +0 -21
- package/dist/shared/api-client-helpers.d.ts +0 -57
- package/dist/shared/api-client-helpers.test.js +0 -261
- package/dist/shared/api-client-proxy-happy.test.js +0 -255
- package/dist/shared/api-client-proxy-retry.test.js +0 -307
- package/dist/shared/api-client-proxy.d.ts +0 -26
- package/dist/shared/api-client-proxy.test.js +0 -255
- package/dist/shared/api-client-retry.test.js +0 -307
- package/dist/shared/api-client-system-trimming.test.js +0 -261
- package/dist/shared/api-client-trimming.d.ts +0 -36
- package/dist/shared/api-client.test.js +0 -228
- package/dist/shared/compaction-thinking.test.js +0 -315
- package/dist/shared/compaction-trimming.test.js +0 -223
- package/dist/shared/sse-parser-callbacks.test.js +0 -422
- package/dist/shared/sse-parser-collect.test.js +0 -252
- package/dist/shared/sse-parser-e2e.test.js +0 -558
- package/dist/shared/sse-parser-parse.test.js +0 -253
- package/dist/shared/tool-dispatch-advanced-batch-build.test.js +0 -405
- package/dist/shared/tool-dispatch-advanced.test.js +0 -320
- package/dist/shared/tool-dispatch-basic.test.js +0 -278
- package/dist/shared/tool-dispatch-content.d.ts +0 -14
- package/dist/shared/tool-dispatch-parallel.test.js +0 -378
- package/dist/webchat/__tests__/widget-messaging.test.js +0 -323
- package/dist/webchat/__tests__/widget.test.js +0 -273
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SpinnerSlot.js","names":["useState","useEffect","Text","colors","jsx","_jsx","FRAMES","GRADIENT","brand","indigo","purple","pink","FRAME_MS","tick","intervalId","listeners","Set","advance","snapshot","cb","subscribe","callback","add","setInterval","delete","size","clearInterval","useTick","$","_c","t","setT","t0","t1","Symbol","for","SpinnerSlot","undefined","color","frame","Math","floor","length","gradientColor","t2","t3","children","ShimmerText","text","dim","chars","tertiary","palette","map","char","i","phase"],"sources":["../../../src/cli/shared/SpinnerSlot.tsx"],"sourcesContent":["/**\n * SpinnerSlot — diamond bloom spinner with breathing gradient\n *\n * Blooms: · → ◇ → ◈ → ◆ → ◈ → ◇ (fast loop)\n * Color breathes: blue → indigo → purple → pink → back\n *\n * All mounted instances share a single interval timer.\n * Uses useState + subscribe for Ink renderer compatibility.\n */\n\nimport { useState, useEffect } from \"react\";\nimport { Text } from \"ink\";\nimport { colors } from \"./Theme.js\";\n\n// Diamond bloom — fills in and empties, like a gem pulsing\nconst FRAMES = [\"\\u00B7\", \"\\u25C7\", \"\\u25C8\", \"\\u25C6\", \"\\u25C8\", \"\\u25C7\"];\n// · ◇ ◈ ◆ ◈ ◇\n\n// Brand gradient — 24 steps for ultra-smooth breathing and shimmer sweep\nconst GRADIENT = [\n colors.brand, \"#3B6FF2\", \"#4B65F0\",\n colors.indigo, \"#7050E8\", \"#8E58EC\",\n colors.purple, \"#B84DD4\", \"#DF4AA9\",\n colors.pink, \"#DF4AA9\", \"#B84DD4\",\n colors.purple, \"#8E58EC\", \"#7050E8\",\n colors.indigo, \"#4B65F0\", \"#3B6FF2\",\n colors.brand, colors.brand, \"#3B6FF2\",\n \"#4B65F0\", colors.indigo, \"#7050E8\",\n];\n\nconst FRAME_MS = 150; // Fast tick — smooth animation at ~6.7fps\n\nlet tick = 0;\nlet intervalId: ReturnType<typeof setInterval> | null = null;\nconst listeners = new Set<() => void>();\n\nfunction advance() {\n tick += 1;\n const snapshot = [...listeners];\n for (const cb of snapshot) {\n try { cb(); } catch { /* don't break the tick loop */ }\n }\n}\n\nfunction subscribe(callback: () => void): () => void {\n listeners.add(callback);\n if (!intervalId) {\n intervalId = setInterval(advance, FRAME_MS);\n }\n return () => {\n listeners.delete(callback);\n if (listeners.size === 0 && intervalId) {\n clearInterval(intervalId);\n intervalId = null;\n tick = 0;\n }\n };\n}\n\nfunction useTick(): number {\n const [t, setT] = useState(tick);\n useEffect(() => subscribe(() => setT(tick)), []);\n return t;\n}\n\nexport function SpinnerSlot({ color }: { color?: string } = {}) {\n const t = useTick();\n // Bloom cycles slower than the tick (every 3 ticks ≈ 450ms per frame)\n const frame = FRAMES[Math.floor(t / 3) % FRAMES.length]!;\n const gradientColor = GRADIENT[t % GRADIENT.length]!;\n return <Text color={color || gradientColor}>{frame}</Text>;\n}\n\n/**\n * ShimmerText — text with a fast color wave sweeping across it\n *\n * Each character gets a phase offset in the gradient, creating a\n * rippling shimmer that feels alive. Wave speed = 1 char per tick.\n */\nexport function ShimmerText({ text, dim }: { text: string; dim?: boolean }) {\n const t = useTick();\n const chars = [...text];\n\n // Dim shimmer uses a muted palette that still moves visibly\n const palette = dim\n ? [colors.tertiary, \"#8A7FA0\", \"#7A6F8E\", colors.dim, \"#6A5F7E\", \"#7A6F8E\", \"#8A7FA0\", colors.tertiary]\n : GRADIENT;\n\n return (\n <Text>\n {chars.map((char, i) => {\n if (char === \" \") return <Text key={i}> </Text>;\n // Wave sweeps right at 1 char per tick — feels alive\n const phase = (t + i) % palette.length;\n return <Text key={i} color={palette[phase]}>{char}</Text>;\n })}\n </Text>\n );\n}\n"],"mappings":";AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,SAASA,QAAQ,EAAEC,SAAS,QAAQ,OAAO;AAC3C,SAASC,IAAI,QAAQ,KAAK;AAC1B,SAASC,MAAM,QAAQ,YAAY;;AAEnC;AAAA,SAAAC,GAAA,IAAAC,IAAA;AACA,MAAMC,MAAM,GAAG,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC;AAC3E;;AAEA;AACA,MAAMC,QAAQ,GAAG,CACfJ,MAAM,CAACK,KAAK,EAAE,SAAS,EAAE,SAAS,EAClCL,MAAM,CAACM,MAAM,EAAE,SAAS,EAAE,SAAS,EACnCN,MAAM,CAACO,MAAM,EAAE,SAAS,EAAE,SAAS,EACnCP,MAAM,CAACQ,IAAI,EAAE,SAAS,EAAE,SAAS,EACjCR,MAAM,CAACO,MAAM,EAAE,SAAS,EAAE,SAAS,EACnCP,MAAM,CAACM,MAAM,EAAE,SAAS,EAAE,SAAS,EACnCN,MAAM,CAACK,KAAK,EAAEL,MAAM,CAACK,KAAK,EAAE,SAAS,EACrC,SAAS,EAAEL,MAAM,CAACM,MAAM,EAAE,SAAS,CACpC;AAED,MAAMG,QAAQ,GAAG,GAAG,CAAC,CAAC;;AAEtB,IAAIC,IAAI,GAAG,CAAC;AACZ,IAAIC,UAAiD,GAAG,IAAI;AAC5D,MAAMC,SAAS,GAAG,IAAIC,GAAG,CAAa,CAAC;AAEvC,SAASC,OAAOA,CAAA,EAAG;EACjBJ,IAAI,IAAI,CAAC;EACT,MAAMK,QAAQ,GAAG,CAAC,GAAGH,SAAS,CAAC;EAC/B,KAAK,MAAMI,EAAE,IAAID,QAAQ,EAAE;IACzB,IAAI;MAAEC,EAAE,CAAC,CAAC;IAAE,CAAC,CAAC,MAAM,CAAE;EACxB;AACF;AAEA,SAASC,SAASA,CAACC,QAAoB,EAAc;EACnDN,SAAS,CAACO,GAAG,CAACD,QAAQ,CAAC;EACvB,IAAI,CAACP,UAAU,EAAE;IACfA,UAAU,GAAGS,WAAW,CAACN,OAAO,EAAEL,QAAQ,CAAC;EAC7C;EACA,OAAO,MAAM;IACXG,SAAS,CAACS,MAAM,CAACH,QAAQ,CAAC;IAC1B,IAAIN,SAAS,CAACU,IAAI,KAAK,CAAC,IAAIX,UAAU,EAAE;MACtCY,aAAa,CAACZ,UAAU,CAAC;MACzBA,UAAU,GAAG,IAAI;MACjBD,IAAI,GAAG,CAAC;IACV;EACF,CAAC;AACH;AAEA,SAAAc,QAAA;EAAA,MAAAC,CAAA,GAAAC,EAAA;EACE,OAAAC,CAAA,EAAAC,IAAA,IAAkB/B,QAAQ,CAACa,IAAI,CAAC;EAAC,IAAAmB,EAAA;EAAA,IAAAC,EAAA;EAAA,IAAAL,CAAA,QAAAM,MAAA,CAAAC,GAAA;IACvBH,EAAA,GAAAA,CAAA,KAAMZ,SAAS,CAAC,MAAMW,IAAI,
|
|
1
|
+
{"version":3,"file":"SpinnerSlot.js","names":["useState","useEffect","Text","colors","jsx","_jsx","FRAMES","GRADIENT","brand","indigo","purple","pink","FRAME_MS","tick","intervalId","listeners","Set","advance","snapshot","cb","subscribe","callback","add","setInterval","delete","size","clearInterval","useTick","$","_c","t","setT","t0","t1","Symbol","for","_temp","SpinnerSlot","undefined","color","frame","Math","floor","length","gradientColor","t2","t3","children","ShimmerText","text","dim","chars","tertiary","palette","map","char","i","phase"],"sources":["../../../src/cli/shared/SpinnerSlot.tsx"],"sourcesContent":["/**\n * SpinnerSlot — diamond bloom spinner with breathing gradient\n *\n * Blooms: · → ◇ → ◈ → ◆ → ◈ → ◇ (fast loop)\n * Color breathes: blue → indigo → purple → pink → back\n *\n * All mounted instances share a single interval timer.\n * Uses useState + subscribe for Ink renderer compatibility.\n */\n\nimport { useState, useEffect } from \"react\";\nimport { Text } from \"ink\";\nimport { colors } from \"./Theme.js\";\n\n// Diamond bloom — fills in and empties, like a gem pulsing\nconst FRAMES = [\"\\u00B7\", \"\\u25C7\", \"\\u25C8\", \"\\u25C6\", \"\\u25C8\", \"\\u25C7\"];\n// · ◇ ◈ ◆ ◈ ◇\n\n// Brand gradient — 24 steps for ultra-smooth breathing and shimmer sweep\nconst GRADIENT = [\n colors.brand, \"#3B6FF2\", \"#4B65F0\",\n colors.indigo, \"#7050E8\", \"#8E58EC\",\n colors.purple, \"#B84DD4\", \"#DF4AA9\",\n colors.pink, \"#DF4AA9\", \"#B84DD4\",\n colors.purple, \"#8E58EC\", \"#7050E8\",\n colors.indigo, \"#4B65F0\", \"#3B6FF2\",\n colors.brand, colors.brand, \"#3B6FF2\",\n \"#4B65F0\", colors.indigo, \"#7050E8\",\n];\n\nconst FRAME_MS = 150; // Fast tick — smooth animation at ~6.7fps\n\nlet tick = 0;\nlet intervalId: ReturnType<typeof setInterval> | null = null;\nconst listeners = new Set<() => void>();\n\nfunction advance() {\n tick += 1;\n const snapshot = [...listeners];\n for (const cb of snapshot) {\n try { cb(); } catch { /* don't break the tick loop */ }\n }\n}\n\nfunction subscribe(callback: () => void): () => void {\n listeners.add(callback);\n if (!intervalId) {\n intervalId = setInterval(advance, FRAME_MS);\n }\n return () => {\n listeners.delete(callback);\n if (listeners.size === 0 && intervalId) {\n clearInterval(intervalId);\n intervalId = null;\n tick = 0;\n }\n };\n}\n\nfunction useTick(): number {\n const [t, setT] = useState(tick);\n useEffect(() => subscribe(() => setT(() => tick)), []);\n return t;\n}\n\nexport function SpinnerSlot({ color }: { color?: string } = {}) {\n const t = useTick();\n // Bloom cycles slower than the tick (every 3 ticks ≈ 450ms per frame)\n const frame = FRAMES[Math.floor(t / 3) % FRAMES.length]!;\n const gradientColor = GRADIENT[t % GRADIENT.length]!;\n return <Text color={color || gradientColor}>{frame}</Text>;\n}\n\n/**\n * ShimmerText — text with a fast color wave sweeping across it\n *\n * Each character gets a phase offset in the gradient, creating a\n * rippling shimmer that feels alive. Wave speed = 1 char per tick.\n */\nexport function ShimmerText({ text, dim }: { text: string; dim?: boolean }) {\n const t = useTick();\n const chars = [...text];\n\n // Dim shimmer uses a muted palette that still moves visibly\n const palette = dim\n ? [colors.tertiary, \"#8A7FA0\", \"#7A6F8E\", colors.dim, \"#6A5F7E\", \"#7A6F8E\", \"#8A7FA0\", colors.tertiary]\n : GRADIENT;\n\n return (\n <Text>\n {chars.map((char, i) => {\n if (char === \" \") return <Text key={i}> </Text>;\n // Wave sweeps right at 1 char per tick — feels alive\n const phase = (t + i) % palette.length;\n return <Text key={i} color={palette[phase]}>{char}</Text>;\n })}\n </Text>\n );\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -210,9 +210,9 @@ export function StatusApp() {
|
|
|
210
210
|
label: "local tools",
|
|
211
211
|
value: `${status.localTools} (file, shell, search)`
|
|
212
212
|
}), !status.loggedIn && /*#__PURE__*/_jsx(Row, {
|
|
213
|
-
label: "
|
|
214
|
-
value:
|
|
215
|
-
color:
|
|
213
|
+
label: "auth",
|
|
214
|
+
value: "not logged in \u2014 run: whale login",
|
|
215
|
+
color: colors.warning
|
|
216
216
|
}), status.agents.length > 0 && /*#__PURE__*/_jsxs(_Fragment, {
|
|
217
217
|
children: [/*#__PURE__*/_jsx(Box, {
|
|
218
218
|
height: 1
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StatusApp.js","names":["React","useState","useEffect","Box","Text","useApp","SpinnerSlot","createClient","resolveConfig","loadConfig","isLoggedIn","getValidToken","createAuthenticatedClient","LOCAL_TOOL_NAMES","WhaleBanner","colors","symbols","boxLine","readFileSync","dirname","join","fileURLToPath","jsxs","_jsxs","jsx","_jsx","Fragment","_Fragment","getVersion","__filename","import","meta","url","__dirname","pkg","JSON","parse","version","Row","t0","$","_c","label","value","color","t1","padEnd","t2","dim","children","t3","text","t4","t5","StatusApp","exit","status","setStatus","loading","setLoading","config","file","loggedIn","supabase","token","supabaseUrl","supabaseKey","supabaseOk","storeId","store_id","storeName","store_name","serverTools","localTools","size","agents","email","error","toolsRes","agentsRes","storeRes","Promise","all","from","select","eq","single","resolve","data","name","length","err","t","setTimeout","clearTimeout","flexDirection","padding","height","brand","muted","border","check","cross","success","warning","anthropicApiKey","map","agent","marginLeft","arrowRight","bold","model","subtle","enabled_tools","id"],"sources":["../../../src/cli/status/StatusApp.tsx"],"sourcesContent":["/**\n * Status Dashboard with whale branding\n */\n\nimport React, { useState, useEffect } from \"react\";\nimport { Box, Text, useApp } from \"ink\";\nimport { SpinnerSlot } from \"../shared/SpinnerSlot.js\";\nimport { createClient } from \"@supabase/supabase-js\";\nimport { resolveConfig, loadConfig } from \"../services/config-store.js\";\nimport { isLoggedIn, getValidToken, createAuthenticatedClient } from \"../services/auth-service.js\";\nimport { LOCAL_TOOL_NAMES } from \"../services/local-tools.js\";\nimport { WhaleBanner } from \"../shared/WhaleBanner.js\";\nimport { colors, symbols, boxLine } from \"../shared/Theme.js\";\nimport { readFileSync } from \"fs\";\nimport { dirname, join } from \"path\";\nimport { fileURLToPath } from \"url\";\n\nfunction getVersion(): string {\n try {\n const __filename = fileURLToPath(import.meta.url);\n const __dirname = dirname(__filename);\n const pkg = JSON.parse(readFileSync(join(__dirname, \"..\", \"..\", \"..\", \"package.json\"), \"utf-8\"));\n return pkg.version || \"?\";\n } catch { return \"?\"; }\n}\n\ninterface StatusData {\n version: string;\n supabaseOk: boolean;\n storeId: string;\n storeName: string;\n serverTools: number;\n localTools: number;\n agents: Array<{ id: string; name: string; model: string; enabled_tools: string[] }>;\n loggedIn: boolean;\n email: string;\n error?: string;\n}\n\nfunction Row({ label, value, color }: { label: string; value: string; color?: string }) {\n return (\n <Box>\n <Text color={colors.dim}> {label.padEnd(18)}</Text>\n <Text color={color || colors.text}>{value}</Text>\n </Box>\n );\n}\n\nexport function StatusApp() {\n const { exit } = useApp();\n const [status, setStatus] = useState<StatusData | null>(null);\n const [loading, setLoading] = useState(true);\n\n useEffect(() => {\n (async () => {\n const config = resolveConfig();\n const file = loadConfig();\n const version = getVersion();\n const loggedIn = isLoggedIn();\n\n let supabase;\n if (loggedIn) {\n const token = await getValidToken();\n if (token) supabase = createAuthenticatedClient(token);\n } else if (config.supabaseUrl && config.supabaseKey) {\n supabase = createClient(config.supabaseUrl, config.supabaseKey);\n }\n\n if (!supabase) {\n setStatus({\n version, supabaseOk: false,\n storeId: config.storeId || file.store_id || \"—\",\n storeName: file.store_name || \"\",\n serverTools: 0, localTools: LOCAL_TOOL_NAMES.size,\n agents: [], loggedIn, email: file.email || \"\",\n error: loggedIn ? \"Session expired. Run: whale login\" : \"Not configured. Run: whale login\",\n });\n setLoading(false); return;\n }\n\n try {\n const [toolsRes, agentsRes, storeRes] = await Promise.all([\n supabase.from(\"ai_tool_registry\").select(\"name\").eq(\"is_active\", true),\n supabase.from(\"ai_agent_config\").select(\"id, name, model, enabled_tools\").eq(\"is_active\", true),\n (config.storeId || file.store_id)\n ? supabase.from(\"stores\").select(\"name\").eq(\"id\", config.storeId || file.store_id).single()\n : Promise.resolve({ data: null, error: null }),\n ]);\n\n setStatus({\n version, supabaseOk: true,\n storeId: config.storeId || file.store_id || \"—\",\n storeName: file.store_name || storeRes.data?.name || \"\",\n serverTools: toolsRes.data?.length || 0,\n localTools: LOCAL_TOOL_NAMES.size,\n agents: (agentsRes.data || []) as StatusData[\"agents\"],\n loggedIn, email: file.email || \"\",\n });\n } catch (err) {\n setStatus({\n version, supabaseOk: false,\n storeId: config.storeId || file.store_id || \"—\",\n storeName: file.store_name || \"\",\n serverTools: 0, localTools: LOCAL_TOOL_NAMES.size,\n agents: [], loggedIn, email: file.email || \"\",\n error: `Connection failed: ${err}`,\n });\n }\n setLoading(false);\n })();\n }, []);\n\n useEffect(() => {\n if (!loading) { const t = setTimeout(() => exit(), 100); return () => clearTimeout(t); }\n }, [loading, exit]);\n\n if (loading) {\n return (\n <Box flexDirection=\"column\" padding={1}>\n <WhaleBanner version={getVersion()} />\n <Box height={1} />\n <Box>\n <Text color={colors.brand}> <SpinnerSlot /></Text>\n <Text color={colors.muted}> connecting…</Text>\n </Box>\n </Box>\n );\n }\n\n if (!status) return null;\n\n return (\n <Box flexDirection=\"column\" padding={1}>\n <WhaleBanner version={status.version} />\n <Box height={1} />\n <Text color={colors.border}>{boxLine(44)}</Text>\n <Box height={1} />\n\n {/* Auth */}\n <Row\n label=\"auth\"\n value={status.loggedIn ? `${symbols.check} logged in` : `${symbols.cross} not logged in`}\n color={status.loggedIn ? colors.success : colors.warning}\n />\n {status.email && <Row label=\"user\" value={status.email} />}\n\n {/* Connection */}\n <Row\n label=\"supabase\"\n value={status.supabaseOk ? `${symbols.check} connected` : `${symbols.cross} disconnected`}\n color={status.supabaseOk ? colors.success : colors.error}\n />\n {status.storeName && <Row label=\"store\" value={status.storeName} />}\n {!status.storeName && <Row label=\"store id\" value={status.storeId} />}\n\n {/* Tools */}\n <Box height={1} />\n <Row label=\"server tools\" value={`${status.serverTools} (edge function)`} />\n <Row label=\"local tools\" value={`${status.localTools} (file, shell, search)`} />\n\n {/* Only show Anthropic key in legacy mode */}\n {!status.loggedIn && (\n <Row\n label=\"anthropic key\"\n value={resolveConfig().anthropicApiKey ? `${symbols.check} set` : `${symbols.cross} not set`}\n color={resolveConfig().anthropicApiKey ? colors.success : colors.warning}\n />\n )}\n\n {/* Agents */}\n {status.agents.length > 0 && (\n <>\n <Box height={1} />\n <Text color={colors.border}>{boxLine(44)}</Text>\n <Text color={colors.muted}> agents</Text>\n <Box height={1} />\n {status.agents.map((agent) => (\n <Box key={agent.id} marginLeft={2}>\n <Text color={colors.brand}>{symbols.arrowRight} </Text>\n <Text color={colors.text} bold>{agent.name}</Text>\n <Text color={colors.dim}> {agent.model}</Text>\n <Text color={colors.subtle}> ({agent.enabled_tools?.length || \"all\"} tools)</Text>\n </Box>\n ))}\n </>\n )}\n\n {status.error && (\n <>\n <Box height={1} />\n <Text color={colors.error}> {symbols.cross} {status.error}</Text>\n </>\n )}\n </Box>\n );\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"StatusApp.js","names":["React","useState","useEffect","Box","Text","useApp","SpinnerSlot","createClient","resolveConfig","loadConfig","isLoggedIn","getValidToken","createAuthenticatedClient","LOCAL_TOOL_NAMES","WhaleBanner","colors","symbols","boxLine","readFileSync","dirname","join","fileURLToPath","jsxs","_jsxs","jsx","_jsx","Fragment","_Fragment","getVersion","__filename","import","meta","url","__dirname","pkg","JSON","parse","version","Row","t0","$","_c","label","value","color","t1","padEnd","t2","dim","children","t3","text","t4","t5","StatusApp","exit","status","setStatus","loading","setLoading","config","file","loggedIn","supabase","token","supabaseUrl","supabaseKey","supabaseOk","storeId","store_id","storeName","store_name","serverTools","localTools","size","agents","email","error","toolsRes","agentsRes","storeRes","Promise","all","from","select","eq","single","resolve","data","name","length","err","t","setTimeout","clearTimeout","flexDirection","padding","height","brand","muted","border","check","cross","success","warning","map","agent","marginLeft","arrowRight","bold","model","subtle","enabled_tools","id"],"sources":["../../../src/cli/status/StatusApp.tsx"],"sourcesContent":["/**\n * Status Dashboard with whale branding\n */\n\nimport React, { useState, useEffect } from \"react\";\nimport { Box, Text, useApp } from \"ink\";\nimport { SpinnerSlot } from \"../shared/SpinnerSlot.js\";\nimport { createClient } from \"@supabase/supabase-js\";\nimport { resolveConfig, loadConfig } from \"../services/config-store.js\";\nimport { isLoggedIn, getValidToken, createAuthenticatedClient } from \"../services/auth-service.js\";\nimport { LOCAL_TOOL_NAMES } from \"../services/local-tools.js\";\nimport { WhaleBanner } from \"../shared/WhaleBanner.js\";\nimport { colors, symbols, boxLine } from \"../shared/Theme.js\";\nimport { readFileSync } from \"fs\";\nimport { dirname, join } from \"path\";\nimport { fileURLToPath } from \"url\";\n\nfunction getVersion(): string {\n try {\n const __filename = fileURLToPath(import.meta.url);\n const __dirname = dirname(__filename);\n const pkg = JSON.parse(readFileSync(join(__dirname, \"..\", \"..\", \"..\", \"package.json\"), \"utf-8\"));\n return pkg.version || \"?\";\n } catch { return \"?\"; }\n}\n\ninterface StatusData {\n version: string;\n supabaseOk: boolean;\n storeId: string;\n storeName: string;\n serverTools: number;\n localTools: number;\n agents: Array<{ id: string; name: string; model: string; enabled_tools: string[] }>;\n loggedIn: boolean;\n email: string;\n error?: string;\n}\n\nfunction Row({ label, value, color }: { label: string; value: string; color?: string }) {\n return (\n <Box>\n <Text color={colors.dim}> {label.padEnd(18)}</Text>\n <Text color={color || colors.text}>{value}</Text>\n </Box>\n );\n}\n\nexport function StatusApp() {\n const { exit } = useApp();\n const [status, setStatus] = useState<StatusData | null>(null);\n const [loading, setLoading] = useState(true);\n\n useEffect(() => {\n (async () => {\n const config = resolveConfig();\n const file = loadConfig();\n const version = getVersion();\n const loggedIn = isLoggedIn();\n\n let supabase;\n if (loggedIn) {\n const token = await getValidToken();\n if (token) supabase = createAuthenticatedClient(token);\n } else if (config.supabaseUrl && config.supabaseKey) {\n supabase = createClient(config.supabaseUrl, config.supabaseKey);\n }\n\n if (!supabase) {\n setStatus({\n version, supabaseOk: false,\n storeId: config.storeId || file.store_id || \"—\",\n storeName: file.store_name || \"\",\n serverTools: 0, localTools: LOCAL_TOOL_NAMES.size,\n agents: [], loggedIn, email: file.email || \"\",\n error: loggedIn ? \"Session expired. Run: whale login\" : \"Not configured. Run: whale login\",\n });\n setLoading(false); return;\n }\n\n try {\n const [toolsRes, agentsRes, storeRes] = await Promise.all([\n supabase.from(\"ai_tool_registry\").select(\"name\").eq(\"is_active\", true),\n supabase.from(\"ai_agent_config\").select(\"id, name, model, enabled_tools\").eq(\"is_active\", true),\n (config.storeId || file.store_id)\n ? supabase.from(\"stores\").select(\"name\").eq(\"id\", config.storeId || file.store_id).single()\n : Promise.resolve({ data: null, error: null }),\n ]);\n\n setStatus({\n version, supabaseOk: true,\n storeId: config.storeId || file.store_id || \"—\",\n storeName: file.store_name || storeRes.data?.name || \"\",\n serverTools: toolsRes.data?.length || 0,\n localTools: LOCAL_TOOL_NAMES.size,\n agents: (agentsRes.data || []) as StatusData[\"agents\"],\n loggedIn, email: file.email || \"\",\n });\n } catch (err) {\n setStatus({\n version, supabaseOk: false,\n storeId: config.storeId || file.store_id || \"—\",\n storeName: file.store_name || \"\",\n serverTools: 0, localTools: LOCAL_TOOL_NAMES.size,\n agents: [], loggedIn, email: file.email || \"\",\n error: `Connection failed: ${err}`,\n });\n }\n setLoading(false);\n })();\n }, []);\n\n useEffect(() => {\n if (!loading) { const t = setTimeout(() => exit(), 100); return () => clearTimeout(t); }\n }, [loading, exit]);\n\n if (loading) {\n return (\n <Box flexDirection=\"column\" padding={1}>\n <WhaleBanner version={getVersion()} />\n <Box height={1} />\n <Box>\n <Text color={colors.brand}> <SpinnerSlot /></Text>\n <Text color={colors.muted}> connecting…</Text>\n </Box>\n </Box>\n );\n }\n\n if (!status) return null;\n\n return (\n <Box flexDirection=\"column\" padding={1}>\n <WhaleBanner version={status.version} />\n <Box height={1} />\n <Text color={colors.border}>{boxLine(44)}</Text>\n <Box height={1} />\n\n {/* Auth */}\n <Row\n label=\"auth\"\n value={status.loggedIn ? `${symbols.check} logged in` : `${symbols.cross} not logged in`}\n color={status.loggedIn ? colors.success : colors.warning}\n />\n {status.email && <Row label=\"user\" value={status.email} />}\n\n {/* Connection */}\n <Row\n label=\"supabase\"\n value={status.supabaseOk ? `${symbols.check} connected` : `${symbols.cross} disconnected`}\n color={status.supabaseOk ? colors.success : colors.error}\n />\n {status.storeName && <Row label=\"store\" value={status.storeName} />}\n {!status.storeName && <Row label=\"store id\" value={status.storeId} />}\n\n {/* Tools */}\n <Box height={1} />\n <Row label=\"server tools\" value={`${status.serverTools} (edge function)`} />\n <Row label=\"local tools\" value={`${status.localTools} (file, shell, search)`} />\n\n {/* Prompt login if not authenticated */}\n {!status.loggedIn && (\n <Row\n label=\"auth\"\n value=\"not logged in — run: whale login\"\n color={colors.warning}\n />\n )}\n\n {/* Agents */}\n {status.agents.length > 0 && (\n <>\n <Box height={1} />\n <Text color={colors.border}>{boxLine(44)}</Text>\n <Text color={colors.muted}> agents</Text>\n <Box height={1} />\n {status.agents.map((agent) => (\n <Box key={agent.id} marginLeft={2}>\n <Text color={colors.brand}>{symbols.arrowRight} </Text>\n <Text color={colors.text} bold>{agent.name}</Text>\n <Text color={colors.dim}> {agent.model}</Text>\n <Text color={colors.subtle}> ({agent.enabled_tools?.length || \"all\"} tools)</Text>\n </Box>\n ))}\n </>\n )}\n\n {status.error && (\n <>\n <Box height={1} />\n <Text color={colors.error}> {symbols.cross} {status.error}</Text>\n </>\n )}\n </Box>\n );\n}\n"],"mappings":"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","ignoreList":[]}
|
package/dist/index.js
CHANGED
|
@@ -19,7 +19,7 @@ import { createClient } from "@supabase/supabase-js";
|
|
|
19
19
|
import { createRequire } from "module";
|
|
20
20
|
import { startUpdateLoop } from "./updater.js";
|
|
21
21
|
import { resolveConfig, loadConfig, updateConfig } from "./cli/services/config-store.js";
|
|
22
|
-
import { getValidToken, getStoresForUser, selectStore, SUPABASE_ANON_KEY } from "./cli/services/auth-service.js";
|
|
22
|
+
import { getValidToken, getStoresForUser, selectStore, createAuthenticatedClient, SUPABASE_ANON_KEY } from "./cli/services/auth-service.js";
|
|
23
23
|
import { signInWithBrowser } from "./cli/services/browser-auth.js";
|
|
24
24
|
import { LocalAgentConnection } from "./local-agent/connection.js";
|
|
25
25
|
import { initErrorLogger, setErrorLoggerUser, captureError } from "./cli/services/error-logger.js";
|
|
@@ -108,8 +108,18 @@ function reloadConfig() {
|
|
|
108
108
|
STORE_ID = config.storeId;
|
|
109
109
|
USER_ID = rawConfig.user_id || null;
|
|
110
110
|
USER_EMAIL = rawConfig.email || null;
|
|
111
|
-
if (
|
|
112
|
-
|
|
111
|
+
if (IS_SERVICE_ROLE && config.supabaseKey) {
|
|
112
|
+
// Service role — use key directly as apiKey
|
|
113
|
+
supabase = createClient(config.supabaseUrl, config.supabaseKey, {
|
|
114
|
+
auth: {
|
|
115
|
+
persistSession: false,
|
|
116
|
+
autoRefreshToken: false
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
isAuthenticated = true;
|
|
120
|
+
} else if (rawConfig.access_token) {
|
|
121
|
+
// User JWT — use built-in anon key + JWT header
|
|
122
|
+
supabase = createAuthenticatedClient(rawConfig.access_token);
|
|
113
123
|
isAuthenticated = true;
|
|
114
124
|
}
|
|
115
125
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["Server","StdioServerTransport","CallToolRequestSchema","ListToolsRequestSchema","createClient","createRequire","startUpdateLoop","resolveConfig","loadConfig","updateConfig","getValidToken","getStoresForUser","selectStore","SUPABASE_ANON_KEY","signInWithBrowser","LocalAgentConnection","initErrorLogger","setErrorLoggerUser","captureError","require","import","meta","url","PKG_VERSION","version","config","rawConfig","SUPABASE_URL","supabaseUrl","INITIAL_SUPABASE_KEY","supabaseKey","STORE_ID","storeId","IS_SERVICE_ROLE","process","env","SUPABASE_SERVICE_ROLE_KEY","USER_ID","user_id","USER_EMAIL","email","access_token","refresh_token","now","Math","floor","Date","expires_at","console","error","freshToken","store_id","e","message","isAuthenticated","supabase","auth","persistSession","autoRefreshToken","global","headers","Authorization","reloadConfig","getAuthToken","token","SERVER_URL","serverUrl","SESSION_ID","crypto","randomUUID","WHALE_LOGIN_TOOL","name","description","inputSchema","type","properties","WHALE_STATUS_TOOL","WHALE_STORES_TOOL","LOCAL_TOOLS","toolDefinitions","toolsLoadedAt","TOOL_CACHE_TTL","loadToolDefinitions","force","length","data","from","select","eq","neq","map","t","definition","input_schema","err","executeToolRemote","toolName","args","traceId","response","fetch","method","body","JSON","stringify","mode","tool_name","conversation_id","trace_id","userId","userEmail","source","result","json","success","handleWhaleLogin","platformUrl","onBrowserOpening","onWaitingForCallback","onExchangingCode","content","text","isError","tools","server","notification","cfg","msg","store_name","stores","s","id","Error","String","handleWhaleStatus","lines","push","exp","toISOString","join","handleWhaleStores","switchToId","target","find","active","slug","capabilities","setRequestHandler","remoteTools","allTools","request","params","toolArgs","arguments","effectiveStoreId","undefined","slice","localAgent","getOrCreateAgentApiKey","agent_api_key","action","scopes","key_type","key","key_value","api_key","getAgentWsUrl","base","replace","wsBase","startLocalAgent","apiKey","wsUrl","onConnected","onDisconnected","reason","onError","onLog","connect","main","serviceName","transport","catch","on","disconnect","severity","tags","setTimeout","exit"],"sources":["../src/index.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * Whale Code MCP Server\n *\n * Thin proxy that connects any MCP client (Claude Code, Cursor, etc.)\n * to the WhaleTools platform.\n *\n * - Tool DEFINITIONS loaded from ai_tool_registry (database-driven)\n * - Tool EXECUTION proxied to the Fly.io server (server-driven)\n * - Auth via browser-based OAuth (`whale_login` tool) or env vars\n *\n * When tools change on the server, this MCP server automatically picks\n * them up — no code changes, no rebuild, no redeploy.\n */\n\nimport { Server } from \"@modelcontextprotocol/sdk/server/index.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport {\n CallToolRequestSchema,\n ListToolsRequestSchema,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport { createClient, type SupabaseClient } from \"@supabase/supabase-js\";\nimport { createRequire } from \"module\";\nimport { startUpdateLoop } from \"./updater.js\";\nimport { resolveConfig, loadConfig, updateConfig } from \"./cli/services/config-store.js\";\nimport { getValidToken, getStoresForUser, selectStore, createAuthenticatedClient, SUPABASE_URL as AUTH_SUPABASE_URL, SUPABASE_ANON_KEY } from \"./cli/services/auth-service.js\";\nimport { signInWithBrowser } from \"./cli/services/browser-auth.js\";\nimport { LocalAgentConnection } from \"./local-agent/connection.js\";\nimport { initErrorLogger, setErrorLoggerUser, captureError } from \"./cli/services/error-logger.js\";\n\nconst require = createRequire(import.meta.url);\nconst PKG_VERSION: string = require(\"../package.json\").version;\n\n// ============================================================================\n// CONFIGURATION — env vars → ~/.whaletools/session.json (set by `whale login`)\n// ============================================================================\n\nlet config = resolveConfig();\nlet rawConfig = loadConfig();\nconst SUPABASE_URL = config.supabaseUrl;\nlet INITIAL_SUPABASE_KEY = config.supabaseKey;\nlet STORE_ID = config.storeId;\nconst IS_SERVICE_ROLE = !!process.env.SUPABASE_SERVICE_ROLE_KEY;\n\n// User identity — loaded from config (set by `whale login`)\nlet USER_ID = rawConfig.user_id || null;\nlet USER_EMAIL = rawConfig.email || null;\n\n// ============================================================================\n// AUTH STATE — auto-refresh expired tokens before connecting\n// ============================================================================\n\n// If using a user JWT (not service role), check if it needs refreshing\nif (!IS_SERVICE_ROLE && rawConfig.access_token && rawConfig.refresh_token) {\n const now = Math.floor(Date.now() / 1000);\n if (!rawConfig.expires_at || rawConfig.expires_at - 300 < now) {\n console.error(\"[MCP] Access token expired, refreshing...\");\n try {\n const freshToken = await getValidToken();\n if (freshToken) {\n INITIAL_SUPABASE_KEY = freshToken;\n // Reload config to get updated values\n rawConfig = loadConfig();\n USER_ID = rawConfig.user_id || USER_ID;\n USER_EMAIL = rawConfig.email || USER_EMAIL;\n STORE_ID = rawConfig.store_id || STORE_ID;\n console.error(\"[MCP] Token refreshed successfully\");\n } else {\n console.error(\"[MCP] Token refresh failed — run `whale login` to re-authenticate\");\n }\n } catch (e) {\n console.error(\"[MCP] Token refresh error:\", (e as Error).message);\n }\n }\n}\n\nlet isAuthenticated = !!(SUPABASE_URL && INITIAL_SUPABASE_KEY);\nlet supabase: SupabaseClient | null = null;\n\nif (isAuthenticated) {\n if (IS_SERVICE_ROLE) {\n // Service role key — use directly as apiKey (full access)\n supabase = createClient(SUPABASE_URL, INITIAL_SUPABASE_KEY, {\n auth: { persistSession: false, autoRefreshToken: false },\n });\n if (!USER_ID) {\n console.error(\"[MCP] WARNING: Using service role key without user login. Tools will work but store scoping is disabled.\");\n }\n } else {\n // User JWT — use anon key as apiKey, pass JWT via Authorization header\n supabase = createClient(SUPABASE_URL, SUPABASE_ANON_KEY, {\n auth: { persistSession: false, autoRefreshToken: false },\n global: { headers: { Authorization: `Bearer ${INITIAL_SUPABASE_KEY}` } },\n });\n }\n} else {\n console.error(\"[MCP] Not authenticated. Use the whale_login tool to sign in, or run `whale login` in a terminal.\");\n}\n\n/** Reload config from disk and update in-memory state */\nfunction reloadConfig(): void {\n config = resolveConfig();\n rawConfig = loadConfig();\n INITIAL_SUPABASE_KEY = config.supabaseKey;\n STORE_ID = config.storeId;\n USER_ID = rawConfig.user_id || null;\n USER_EMAIL = rawConfig.email || null;\n\n if (config.supabaseUrl && config.supabaseKey) {\n supabase = createClient(config.supabaseUrl, config.supabaseKey);\n isAuthenticated = true;\n }\n}\n\n/** Get a fresh auth token — service role keys are static, JWTs auto-refresh */\nasync function getAuthToken(): Promise<string> {\n if (IS_SERVICE_ROLE) return INITIAL_SUPABASE_KEY!;\n // JWT user — refresh if needed\n const token = await getValidToken();\n return token || INITIAL_SUPABASE_KEY!;\n}\n\n// Fly.io server URL for tool execution\nconst SERVER_URL = config.serverUrl;\n\n// Session ID for tracing — links all tool calls in one conversation\nconst SESSION_ID = crypto.randomUUID();\n\n// ============================================================================\n// LOCAL TOOL DEFINITIONS (whale_login, whale_status, whale_stores)\n// ============================================================================\n\ninterface ToolDefinition {\n name: string;\n description: string;\n inputSchema: {\n type: \"object\";\n properties: Record<string, any>;\n required?: string[];\n };\n}\n\nconst WHALE_LOGIN_TOOL: ToolDefinition = {\n name: \"whale_login\",\n description: \"Log in to your WhaleTools account. Opens a browser for secure authentication. Use this when you see 'not authenticated' errors.\",\n inputSchema: { type: \"object\", properties: {} },\n};\n\nconst WHALE_STATUS_TOOL: ToolDefinition = {\n name: \"whale_status\",\n description: \"Check current authentication status, active store, and account info.\",\n inputSchema: { type: \"object\", properties: {} },\n};\n\nconst WHALE_STORES_TOOL: ToolDefinition = {\n name: \"whale_stores\",\n description: \"List your stores or switch the active store.\",\n inputSchema: {\n type: \"object\",\n properties: {\n store_id: {\n type: \"string\",\n description: \"Store ID to switch to. Omit to list all available stores.\",\n },\n },\n },\n};\n\nconst LOCAL_TOOLS = [WHALE_LOGIN_TOOL, WHALE_STATUS_TOOL, WHALE_STORES_TOOL];\n\n// ============================================================================\n// REMOTE TOOL DEFINITIONS (loaded from database)\n// ============================================================================\n\nlet toolDefinitions: ToolDefinition[] = [];\nlet toolsLoadedAt = 0;\nconst TOOL_CACHE_TTL = 300_000; // 5 minutes — tool defs rarely change mid-session\n\nasync function loadToolDefinitions(force = false): Promise<ToolDefinition[]> {\n if (!isAuthenticated || !supabase) return [];\n\n if (!force && toolDefinitions.length > 0 && Date.now() - toolsLoadedAt < TOOL_CACHE_TTL) {\n return toolDefinitions;\n }\n\n try {\n const { data, error } = await supabase\n .from(\"ai_tool_registry\")\n .select(\"name, description, definition\")\n .eq(\"is_active\", true)\n .neq(\"tool_mode\", \"code\");\n\n if (error) {\n console.error(\"[MCP] Failed to load tools from registry:\", error.message);\n return toolDefinitions; // Return stale cache on error\n }\n\n toolDefinitions = (data || []).map(t => ({\n name: t.name,\n description: t.description || t.definition?.description || `Execute ${t.name}`,\n inputSchema: t.definition?.input_schema || { type: \"object\", properties: {} }\n }));\n toolsLoadedAt = Date.now();\n\n return toolDefinitions;\n } catch (err) {\n console.error(\"[MCP] Error loading tool definitions:\", err);\n return toolDefinitions;\n }\n}\n\n// ============================================================================\n// TOOL EXECUTION (proxied to Fly.io server)\n// ============================================================================\n\ninterface RemoteToolResult {\n success: boolean;\n data?: unknown;\n error?: string;\n}\n\nasync function executeToolRemote(\n toolName: string,\n args: Record<string, unknown>,\n storeId?: string,\n traceId?: string,\n): Promise<RemoteToolResult> {\n try {\n const token = await getAuthToken();\n const response = await fetch(SERVER_URL, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"Authorization\": `Bearer ${token}`,\n },\n body: JSON.stringify({\n mode: \"tool\",\n tool_name: toolName,\n args,\n store_id: storeId,\n conversation_id: SESSION_ID,\n trace_id: traceId,\n userId: USER_ID,\n userEmail: USER_EMAIL,\n source: \"whale-code-mcp\",\n }),\n });\n\n const result = await response.json() as RemoteToolResult;\n return result;\n } catch (err: any) {\n return {\n success: false,\n error: `Server tool call failed: ${err.message}`,\n };\n }\n}\n\n// ============================================================================\n// LOCAL TOOL HANDLERS\n// ============================================================================\n\nasync function handleWhaleLogin(): Promise<{ content: Array<{ type: \"text\"; text: string }>; isError?: boolean }> {\n try {\n const result = await signInWithBrowser(config.platformUrl, {\n onBrowserOpening: (url) => {\n console.error(`[MCP] Opening browser for login: ${url}`);\n },\n onWaitingForCallback: () => {\n console.error(\"[MCP] Waiting for browser login...\");\n },\n onExchangingCode: () => {\n console.error(\"[MCP] Exchanging auth code...\");\n },\n });\n\n if (!result.success) {\n return {\n content: [{ type: \"text\", text: `Login failed: ${result.error}\\n\\nYou can also try running \\`whale login\\` in a terminal.` }],\n isError: true,\n };\n }\n\n // Reload config after successful login\n reloadConfig();\n\n // Force-reload tool definitions\n const tools = await loadToolDefinitions(true);\n\n // Notify MCP client that tools have changed\n server.notification({ method: \"notifications/tools/list_changed\" });\n\n const cfg = result.config!;\n let msg = `Logged in as ${cfg.email || \"unknown\"}`;\n if (cfg.store_name || cfg.store_id) {\n msg += `\\nActive store: ${cfg.store_name || cfg.store_id}`;\n }\n msg += `\\n${tools.length} tools now available.`;\n\n if (result.stores && result.stores.length > 1) {\n msg += `\\n\\nYou have ${result.stores.length} stores. Use whale_stores to switch:`;\n for (const s of result.stores) {\n msg += `\\n - ${s.name} (${s.id})`;\n }\n }\n\n return { content: [{ type: \"text\", text: msg }] };\n } catch (err) {\n return {\n content: [{ type: \"text\", text: `Login error: ${err instanceof Error ? err.message : String(err)}` }],\n isError: true,\n };\n }\n}\n\nfunction handleWhaleStatus(): { content: Array<{ type: \"text\"; text: string }> } {\n const cfg = loadConfig();\n const lines: string[] = [];\n\n if (isAuthenticated) {\n lines.push(\"Authenticated: yes\");\n lines.push(`User: ${cfg.email || \"(unknown)\"}`);\n lines.push(`User ID: ${cfg.user_id || \"(unknown)\"}`);\n lines.push(`Store: ${cfg.store_name || cfg.store_id || \"(none selected)\"}`);\n lines.push(`Auth method: ${IS_SERVICE_ROLE ? \"service role key (env var)\" : \"user JWT (whale login)\"}`);\n if (cfg.expires_at) {\n const exp = new Date(cfg.expires_at * 1000);\n lines.push(`Token expires: ${exp.toISOString()}`);\n }\n } else {\n lines.push(\"Authenticated: no\");\n lines.push(\"Use whale_login to sign in.\");\n }\n\n lines.push(`MCP version: ${PKG_VERSION}`);\n lines.push(`Server: ${SERVER_URL}`);\n lines.push(`Tools loaded: ${toolDefinitions.length}`);\n\n return { content: [{ type: \"text\", text: lines.join(\"\\n\") }] };\n}\n\nasync function handleWhaleStores(args: Record<string, any>): Promise<{ content: Array<{ type: \"text\"; text: string }>; isError?: boolean }> {\n if (!isAuthenticated) {\n return {\n content: [{ type: \"text\", text: \"Not authenticated. Use whale_login first.\" }],\n isError: true,\n };\n }\n\n const switchToId = args.store_id as string | undefined;\n\n if (switchToId) {\n // Switch store\n // Verify the store exists for this user\n const token = await getAuthToken();\n const stores = await getStoresForUser(token, USER_ID || \"\");\n\n const target = stores.find(s => s.id === switchToId);\n if (!target) {\n return {\n content: [{ type: \"text\", text: `Store not found: ${switchToId}\\nAvailable stores: ${stores.map(s => `${s.name} (${s.id})`).join(\", \")}` }],\n isError: true,\n };\n }\n\n selectStore(target.id, target.name);\n reloadConfig();\n\n // Notify MCP client that tools may have changed context\n server.notification({ method: \"notifications/tools/list_changed\" });\n\n return {\n content: [{ type: \"text\", text: `Switched to store: ${target.name} (${target.id})` }],\n };\n }\n\n // List stores\n const token = await getAuthToken();\n const stores = await getStoresForUser(token, USER_ID || \"\");\n\n if (stores.length === 0) {\n return { content: [{ type: \"text\", text: \"No stores found for your account.\" }] };\n }\n\n const cfg = loadConfig();\n const lines = [\"Your stores:\"];\n for (const s of stores) {\n const active = s.id === cfg.store_id ? \" (active)\" : \"\";\n lines.push(` - ${s.name}${s.slug ? ` [${s.slug}]` : \"\"}: ${s.id}${active}`);\n }\n lines.push(\"\\nTo switch: use whale_stores with store_id parameter\");\n\n return { content: [{ type: \"text\", text: lines.join(\"\\n\") }] };\n}\n\n// ============================================================================\n// MCP SERVER\n// ============================================================================\n\nconst server = new Server(\n { name: \"whale\", version: PKG_VERSION },\n { capabilities: { tools: {} } }\n);\n\n// List available tools — local auth tools always present; remote tools when authenticated\nserver.setRequestHandler(ListToolsRequestSchema, async () => {\n if (!isAuthenticated) {\n console.error(`[MCP] Returning ${LOCAL_TOOLS.length} tools (not authenticated)`);\n return {\n tools: LOCAL_TOOLS.map(t => ({\n name: t.name,\n description: t.description,\n inputSchema: t.inputSchema,\n })),\n };\n }\n\n const remoteTools = await loadToolDefinitions();\n const allTools = [...LOCAL_TOOLS, ...remoteTools];\n console.error(`[MCP] Returning ${allTools.length} tools (${LOCAL_TOOLS.length} local + ${remoteTools.length} remote)`);\n\n return {\n tools: allTools.map(t => ({\n name: t.name,\n description: t.description,\n inputSchema: t.inputSchema,\n })),\n };\n});\n\n// Execute a tool — local auth tools handled here, everything else proxied to Fly.io\nserver.setRequestHandler(CallToolRequestSchema, async (request) => {\n const toolName = request.params.name;\n const toolArgs = (request.params.arguments || {}) as Record<string, any>;\n\n // ── Local tools (handled in-process) ──\n\n if (toolName === \"whale_login\") {\n return handleWhaleLogin();\n }\n\n if (toolName === \"whale_status\") {\n return handleWhaleStatus();\n }\n\n if (toolName === \"whale_stores\") {\n return handleWhaleStores(toolArgs);\n }\n\n // ── Auth gate for remote tools ──\n\n if (!isAuthenticated) {\n return {\n content: [{\n type: \"text\" as const,\n text: \"Not authenticated. Please use the whale_login tool first to sign in to your WhaleTools account.\",\n }],\n isError: true,\n };\n }\n\n // ── Remote tool execution ──\n\n const traceId = crypto.randomUUID();\n\n // Allow tool-level store_id override (e.g. multi-store users switching context)\n const effectiveStoreId = (toolArgs.store_id as string) || STORE_ID || undefined;\n if (toolArgs.store_id) {\n delete toolArgs.store_id; // Don't send as a tool arg — it's a routing param\n }\n\n console.error(`[MCP] Executing: ${toolName} → Fly.io [${traceId.slice(0, 8)}] store=${effectiveStoreId?.slice(0, 8) || \"none\"}`);\n\n const result = await executeToolRemote(toolName, toolArgs, effectiveStoreId, traceId);\n\n if (result.success) {\n return {\n content: [{\n type: \"text\" as const,\n text: typeof result.data === \"string\"\n ? result.data\n : JSON.stringify(result.data, null, 2),\n }],\n };\n } else {\n return {\n content: [{\n type: \"text\" as const,\n text: JSON.stringify({ error: result.error }),\n }],\n isError: true,\n };\n }\n});\n\n// ============================================================================\n// LOCAL AGENT (auto-spawned — shares this process with MCP server)\n// ============================================================================\n\nlet localAgent: LocalAgentConnection | null = null;\n\n/**\n * Get or create a store API key for the local agent WebSocket connection.\n * Persisted to ~/.whaletools/session.json so we reuse across restarts.\n */\nasync function getOrCreateAgentApiKey(): Promise<string | null> {\n const rawConfig = loadConfig();\n if (rawConfig.agent_api_key) return rawConfig.agent_api_key;\n\n // Auto-generate via the server's api_keys tool\n try {\n const result = await executeToolRemote(\"api_keys\", {\n action: \"generate\",\n name: \"local-agent-auto\",\n scopes: [\"*\"],\n key_type: \"live\",\n }, STORE_ID || undefined);\n\n if (result.success && result.data) {\n const data = result.data as any;\n const key = data.key_value || data.api_key || data.key;\n if (key) {\n updateConfig({ agent_api_key: key });\n console.error(\"[MCP] Auto-generated local agent API key\");\n return key;\n }\n }\n console.error(\"[MCP] Failed to auto-generate agent API key:\", result.error);\n return null;\n } catch (err: any) {\n console.error(\"[MCP] Error generating agent API key:\", err.message);\n return null;\n }\n}\n\n/**\n * Derive WebSocket URL from the HTTP server URL.\n * https://whale-agent.fly.dev → wss://whale-agent.fly.dev/agent/ws\n */\nfunction getAgentWsUrl(): string {\n const base = SERVER_URL.replace(/\\/$/, \"\");\n const wsBase = base.replace(/^https:/, \"wss:\").replace(/^http:/, \"ws:\");\n return `${wsBase}/agent/ws`;\n}\n\n/**\n * Start the local agent WebSocket connection in the background.\n * Non-blocking — MCP server continues even if this fails.\n */\nasync function startLocalAgent(): Promise<void> {\n const apiKey = await getOrCreateAgentApiKey();\n if (!apiKey) {\n console.error(\"[MCP] Skipping local agent — no API key available\");\n return;\n }\n\n const wsUrl = getAgentWsUrl();\n console.error(`[MCP] Starting local agent → ${wsUrl}`);\n\n localAgent = new LocalAgentConnection({\n apiKey,\n serverUrl: wsUrl,\n onConnected: () => console.error(\"[MCP] Local agent connected — WhaleChat can now use local tools\"),\n onDisconnected: (reason) => console.error(`[MCP] Local agent disconnected: ${reason}`),\n onError: (err) => console.error(`[MCP] Local agent error: ${err.message}`),\n onLog: (msg) => console.error(msg),\n });\n\n try {\n await localAgent.connect();\n } catch (err: any) {\n console.error(`[MCP] Local agent failed to connect: ${err.message} (non-fatal)`);\n }\n}\n\n// ============================================================================\n// STARTUP\n// ============================================================================\n\nasync function main() {\n // Initialize error logging for MCP mode\n initErrorLogger({ serviceName: \"whale-code-mcp\" });\n if (USER_ID || USER_EMAIL) {\n setErrorLoggerUser(USER_ID || undefined, USER_EMAIL || undefined, STORE_ID || undefined);\n }\n\n console.error(`[MCP] Whale MCP Server v${PKG_VERSION}`);\n console.error(`[MCP] Supabase: ${SUPABASE_URL}`);\n console.error(`[MCP] Server: ${SERVER_URL}`);\n console.error(`[MCP] Store: ${STORE_ID || \"(default)\"}`);\n console.error(`[MCP] User: ${USER_EMAIL || \"(unknown)\"} [${USER_ID?.slice(0, 8) || \"no-id\"}]`);\n console.error(`[MCP] Session: ${SESSION_ID}`);\n console.error(`[MCP] Authenticated: ${isAuthenticated ? \"yes\" : \"no — use whale_login tool\"}`);\n\n // Pre-load tools from database (only if authenticated)\n if (isAuthenticated) {\n const tools = await loadToolDefinitions(true);\n console.error(`[MCP] Loaded ${tools.length} tools from registry`);\n } else {\n console.error(`[MCP] Skipping tool load — not authenticated. ${LOCAL_TOOLS.length} auth tools available.`);\n }\n\n // Start OTA update checker (non-blocking, runs in background)\n startUpdateLoop(true);\n\n // Connect via stdio\n const transport = new StdioServerTransport();\n await server.connect(transport);\n console.error(\"[MCP] Ready\");\n\n // Start local agent in background — only if authenticated\n if (isAuthenticated) {\n startLocalAgent().catch((err) => {\n console.error(\"[MCP] Local agent startup error:\", err.message);\n });\n }\n}\n\n// Graceful shutdown — disconnect local agent\nprocess.on(\"SIGINT\", () => {\n localAgent?.disconnect();\n});\nprocess.on(\"SIGTERM\", () => {\n localAgent?.disconnect();\n});\n\nmain().catch((err) => {\n console.error(\"[MCP] Fatal:\", err);\n captureError({ error: err instanceof Error ? err : new Error(String(err)), severity: \"fatal\", tags: { source: \"mcp_main\" } });\n // Give error logger a moment to flush before exit\n setTimeout(() => process.exit(1), 500);\n});\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"index.js","names":["Server","StdioServerTransport","CallToolRequestSchema","ListToolsRequestSchema","createClient","createRequire","startUpdateLoop","resolveConfig","loadConfig","updateConfig","getValidToken","getStoresForUser","selectStore","createAuthenticatedClient","SUPABASE_ANON_KEY","signInWithBrowser","LocalAgentConnection","initErrorLogger","setErrorLoggerUser","captureError","require","import","meta","url","PKG_VERSION","version","config","rawConfig","SUPABASE_URL","supabaseUrl","INITIAL_SUPABASE_KEY","supabaseKey","STORE_ID","storeId","IS_SERVICE_ROLE","process","env","SUPABASE_SERVICE_ROLE_KEY","USER_ID","user_id","USER_EMAIL","email","access_token","refresh_token","now","Math","floor","Date","expires_at","console","error","freshToken","store_id","e","message","isAuthenticated","supabase","auth","persistSession","autoRefreshToken","global","headers","Authorization","reloadConfig","getAuthToken","token","SERVER_URL","serverUrl","SESSION_ID","crypto","randomUUID","WHALE_LOGIN_TOOL","name","description","inputSchema","type","properties","WHALE_STATUS_TOOL","WHALE_STORES_TOOL","LOCAL_TOOLS","toolDefinitions","toolsLoadedAt","TOOL_CACHE_TTL","loadToolDefinitions","force","length","data","from","select","eq","neq","map","t","definition","input_schema","err","executeToolRemote","toolName","args","traceId","response","fetch","method","body","JSON","stringify","mode","tool_name","conversation_id","trace_id","userId","userEmail","source","result","json","success","handleWhaleLogin","platformUrl","onBrowserOpening","onWaitingForCallback","onExchangingCode","content","text","isError","tools","server","notification","cfg","msg","store_name","stores","s","id","Error","String","handleWhaleStatus","lines","push","exp","toISOString","join","handleWhaleStores","switchToId","target","find","active","slug","capabilities","setRequestHandler","remoteTools","allTools","request","params","toolArgs","arguments","effectiveStoreId","undefined","slice","localAgent","getOrCreateAgentApiKey","agent_api_key","action","scopes","key_type","key","key_value","api_key","getAgentWsUrl","base","replace","wsBase","startLocalAgent","apiKey","wsUrl","onConnected","onDisconnected","reason","onError","onLog","connect","main","serviceName","transport","catch","on","disconnect","severity","tags","setTimeout","exit"],"sources":["../src/index.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * Whale Code MCP Server\n *\n * Thin proxy that connects any MCP client (Claude Code, Cursor, etc.)\n * to the WhaleTools platform.\n *\n * - Tool DEFINITIONS loaded from ai_tool_registry (database-driven)\n * - Tool EXECUTION proxied to the Fly.io server (server-driven)\n * - Auth via browser-based OAuth (`whale_login` tool) or env vars\n *\n * When tools change on the server, this MCP server automatically picks\n * them up — no code changes, no rebuild, no redeploy.\n */\n\nimport { Server } from \"@modelcontextprotocol/sdk/server/index.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport {\n CallToolRequestSchema,\n ListToolsRequestSchema,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport { createClient, type SupabaseClient } from \"@supabase/supabase-js\";\nimport { createRequire } from \"module\";\nimport { startUpdateLoop } from \"./updater.js\";\nimport { resolveConfig, loadConfig, updateConfig } from \"./cli/services/config-store.js\";\nimport { getValidToken, getStoresForUser, selectStore, createAuthenticatedClient, SUPABASE_URL as AUTH_SUPABASE_URL, SUPABASE_ANON_KEY } from \"./cli/services/auth-service.js\";\nimport { signInWithBrowser } from \"./cli/services/browser-auth.js\";\nimport { LocalAgentConnection } from \"./local-agent/connection.js\";\nimport { initErrorLogger, setErrorLoggerUser, captureError } from \"./cli/services/error-logger.js\";\n\nconst require = createRequire(import.meta.url);\nconst PKG_VERSION: string = require(\"../package.json\").version;\n\n// ============================================================================\n// CONFIGURATION — env vars → ~/.whaletools/session.json (set by `whale login`)\n// ============================================================================\n\nlet config = resolveConfig();\nlet rawConfig = loadConfig();\nconst SUPABASE_URL = config.supabaseUrl;\nlet INITIAL_SUPABASE_KEY = config.supabaseKey;\nlet STORE_ID = config.storeId;\nconst IS_SERVICE_ROLE = !!process.env.SUPABASE_SERVICE_ROLE_KEY;\n\n// User identity — loaded from config (set by `whale login`)\nlet USER_ID = rawConfig.user_id || null;\nlet USER_EMAIL = rawConfig.email || null;\n\n// ============================================================================\n// AUTH STATE — auto-refresh expired tokens before connecting\n// ============================================================================\n\n// If using a user JWT (not service role), check if it needs refreshing\nif (!IS_SERVICE_ROLE && rawConfig.access_token && rawConfig.refresh_token) {\n const now = Math.floor(Date.now() / 1000);\n if (!rawConfig.expires_at || rawConfig.expires_at - 300 < now) {\n console.error(\"[MCP] Access token expired, refreshing...\");\n try {\n const freshToken = await getValidToken();\n if (freshToken) {\n INITIAL_SUPABASE_KEY = freshToken;\n // Reload config to get updated values\n rawConfig = loadConfig();\n USER_ID = rawConfig.user_id || USER_ID;\n USER_EMAIL = rawConfig.email || USER_EMAIL;\n STORE_ID = rawConfig.store_id || STORE_ID;\n console.error(\"[MCP] Token refreshed successfully\");\n } else {\n console.error(\"[MCP] Token refresh failed — run `whale login` to re-authenticate\");\n }\n } catch (e) {\n console.error(\"[MCP] Token refresh error:\", (e as Error).message);\n }\n }\n}\n\nlet isAuthenticated = !!(SUPABASE_URL && INITIAL_SUPABASE_KEY);\nlet supabase: SupabaseClient | null = null;\n\nif (isAuthenticated) {\n if (IS_SERVICE_ROLE) {\n // Service role key — use directly as apiKey (full access)\n supabase = createClient(SUPABASE_URL, INITIAL_SUPABASE_KEY, {\n auth: { persistSession: false, autoRefreshToken: false },\n });\n if (!USER_ID) {\n console.error(\"[MCP] WARNING: Using service role key without user login. Tools will work but store scoping is disabled.\");\n }\n } else {\n // User JWT — use anon key as apiKey, pass JWT via Authorization header\n supabase = createClient(SUPABASE_URL, SUPABASE_ANON_KEY, {\n auth: { persistSession: false, autoRefreshToken: false },\n global: { headers: { Authorization: `Bearer ${INITIAL_SUPABASE_KEY}` } },\n });\n }\n} else {\n console.error(\"[MCP] Not authenticated. Use the whale_login tool to sign in, or run `whale login` in a terminal.\");\n}\n\n/** Reload config from disk and update in-memory state */\nfunction reloadConfig(): void {\n config = resolveConfig();\n rawConfig = loadConfig();\n INITIAL_SUPABASE_KEY = config.supabaseKey;\n STORE_ID = config.storeId;\n USER_ID = rawConfig.user_id || null;\n USER_EMAIL = rawConfig.email || null;\n\n if (IS_SERVICE_ROLE && config.supabaseKey) {\n // Service role — use key directly as apiKey\n supabase = createClient(config.supabaseUrl, config.supabaseKey, {\n auth: { persistSession: false, autoRefreshToken: false },\n });\n isAuthenticated = true;\n } else if (rawConfig.access_token) {\n // User JWT — use built-in anon key + JWT header\n supabase = createAuthenticatedClient(rawConfig.access_token);\n isAuthenticated = true;\n }\n}\n\n/** Get a fresh auth token — service role keys are static, JWTs auto-refresh */\nasync function getAuthToken(): Promise<string> {\n if (IS_SERVICE_ROLE) return INITIAL_SUPABASE_KEY!;\n // JWT user — refresh if needed\n const token = await getValidToken();\n return token || INITIAL_SUPABASE_KEY!;\n}\n\n// Fly.io server URL for tool execution\nconst SERVER_URL = config.serverUrl;\n\n// Session ID for tracing — links all tool calls in one conversation\nconst SESSION_ID = crypto.randomUUID();\n\n// ============================================================================\n// LOCAL TOOL DEFINITIONS (whale_login, whale_status, whale_stores)\n// ============================================================================\n\ninterface ToolDefinition {\n name: string;\n description: string;\n inputSchema: {\n type: \"object\";\n properties: Record<string, any>;\n required?: string[];\n };\n}\n\nconst WHALE_LOGIN_TOOL: ToolDefinition = {\n name: \"whale_login\",\n description: \"Log in to your WhaleTools account. Opens a browser for secure authentication. Use this when you see 'not authenticated' errors.\",\n inputSchema: { type: \"object\", properties: {} },\n};\n\nconst WHALE_STATUS_TOOL: ToolDefinition = {\n name: \"whale_status\",\n description: \"Check current authentication status, active store, and account info.\",\n inputSchema: { type: \"object\", properties: {} },\n};\n\nconst WHALE_STORES_TOOL: ToolDefinition = {\n name: \"whale_stores\",\n description: \"List your stores or switch the active store.\",\n inputSchema: {\n type: \"object\",\n properties: {\n store_id: {\n type: \"string\",\n description: \"Store ID to switch to. Omit to list all available stores.\",\n },\n },\n },\n};\n\nconst LOCAL_TOOLS = [WHALE_LOGIN_TOOL, WHALE_STATUS_TOOL, WHALE_STORES_TOOL];\n\n// ============================================================================\n// REMOTE TOOL DEFINITIONS (loaded from database)\n// ============================================================================\n\nlet toolDefinitions: ToolDefinition[] = [];\nlet toolsLoadedAt = 0;\nconst TOOL_CACHE_TTL = 300_000; // 5 minutes — tool defs rarely change mid-session\n\nasync function loadToolDefinitions(force = false): Promise<ToolDefinition[]> {\n if (!isAuthenticated || !supabase) return [];\n\n if (!force && toolDefinitions.length > 0 && Date.now() - toolsLoadedAt < TOOL_CACHE_TTL) {\n return toolDefinitions;\n }\n\n try {\n const { data, error } = await supabase\n .from(\"ai_tool_registry\")\n .select(\"name, description, definition\")\n .eq(\"is_active\", true)\n .neq(\"tool_mode\", \"code\");\n\n if (error) {\n console.error(\"[MCP] Failed to load tools from registry:\", error.message);\n return toolDefinitions; // Return stale cache on error\n }\n\n toolDefinitions = (data || []).map(t => ({\n name: t.name,\n description: t.description || t.definition?.description || `Execute ${t.name}`,\n inputSchema: t.definition?.input_schema || { type: \"object\", properties: {} }\n }));\n toolsLoadedAt = Date.now();\n\n return toolDefinitions;\n } catch (err) {\n console.error(\"[MCP] Error loading tool definitions:\", err);\n return toolDefinitions;\n }\n}\n\n// ============================================================================\n// TOOL EXECUTION (proxied to Fly.io server)\n// ============================================================================\n\ninterface RemoteToolResult {\n success: boolean;\n data?: unknown;\n error?: string;\n}\n\nasync function executeToolRemote(\n toolName: string,\n args: Record<string, unknown>,\n storeId?: string,\n traceId?: string,\n): Promise<RemoteToolResult> {\n try {\n const token = await getAuthToken();\n const response = await fetch(SERVER_URL, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"Authorization\": `Bearer ${token}`,\n },\n body: JSON.stringify({\n mode: \"tool\",\n tool_name: toolName,\n args,\n store_id: storeId,\n conversation_id: SESSION_ID,\n trace_id: traceId,\n userId: USER_ID,\n userEmail: USER_EMAIL,\n source: \"whale-code-mcp\",\n }),\n });\n\n const result = await response.json() as RemoteToolResult;\n return result;\n } catch (err: any) {\n return {\n success: false,\n error: `Server tool call failed: ${err.message}`,\n };\n }\n}\n\n// ============================================================================\n// LOCAL TOOL HANDLERS\n// ============================================================================\n\nasync function handleWhaleLogin(): Promise<{ content: Array<{ type: \"text\"; text: string }>; isError?: boolean }> {\n try {\n const result = await signInWithBrowser(config.platformUrl, {\n onBrowserOpening: (url) => {\n console.error(`[MCP] Opening browser for login: ${url}`);\n },\n onWaitingForCallback: () => {\n console.error(\"[MCP] Waiting for browser login...\");\n },\n onExchangingCode: () => {\n console.error(\"[MCP] Exchanging auth code...\");\n },\n });\n\n if (!result.success) {\n return {\n content: [{ type: \"text\", text: `Login failed: ${result.error}\\n\\nYou can also try running \\`whale login\\` in a terminal.` }],\n isError: true,\n };\n }\n\n // Reload config after successful login\n reloadConfig();\n\n // Force-reload tool definitions\n const tools = await loadToolDefinitions(true);\n\n // Notify MCP client that tools have changed\n server.notification({ method: \"notifications/tools/list_changed\" });\n\n const cfg = result.config!;\n let msg = `Logged in as ${cfg.email || \"unknown\"}`;\n if (cfg.store_name || cfg.store_id) {\n msg += `\\nActive store: ${cfg.store_name || cfg.store_id}`;\n }\n msg += `\\n${tools.length} tools now available.`;\n\n if (result.stores && result.stores.length > 1) {\n msg += `\\n\\nYou have ${result.stores.length} stores. Use whale_stores to switch:`;\n for (const s of result.stores) {\n msg += `\\n - ${s.name} (${s.id})`;\n }\n }\n\n return { content: [{ type: \"text\", text: msg }] };\n } catch (err) {\n return {\n content: [{ type: \"text\", text: `Login error: ${err instanceof Error ? err.message : String(err)}` }],\n isError: true,\n };\n }\n}\n\nfunction handleWhaleStatus(): { content: Array<{ type: \"text\"; text: string }> } {\n const cfg = loadConfig();\n const lines: string[] = [];\n\n if (isAuthenticated) {\n lines.push(\"Authenticated: yes\");\n lines.push(`User: ${cfg.email || \"(unknown)\"}`);\n lines.push(`User ID: ${cfg.user_id || \"(unknown)\"}`);\n lines.push(`Store: ${cfg.store_name || cfg.store_id || \"(none selected)\"}`);\n lines.push(`Auth method: ${IS_SERVICE_ROLE ? \"service role key (env var)\" : \"user JWT (whale login)\"}`);\n if (cfg.expires_at) {\n const exp = new Date(cfg.expires_at * 1000);\n lines.push(`Token expires: ${exp.toISOString()}`);\n }\n } else {\n lines.push(\"Authenticated: no\");\n lines.push(\"Use whale_login to sign in.\");\n }\n\n lines.push(`MCP version: ${PKG_VERSION}`);\n lines.push(`Server: ${SERVER_URL}`);\n lines.push(`Tools loaded: ${toolDefinitions.length}`);\n\n return { content: [{ type: \"text\", text: lines.join(\"\\n\") }] };\n}\n\nasync function handleWhaleStores(args: Record<string, any>): Promise<{ content: Array<{ type: \"text\"; text: string }>; isError?: boolean }> {\n if (!isAuthenticated) {\n return {\n content: [{ type: \"text\", text: \"Not authenticated. Use whale_login first.\" }],\n isError: true,\n };\n }\n\n const switchToId = args.store_id as string | undefined;\n\n if (switchToId) {\n // Switch store\n // Verify the store exists for this user\n const token = await getAuthToken();\n const stores = await getStoresForUser(token, USER_ID || \"\");\n\n const target = stores.find(s => s.id === switchToId);\n if (!target) {\n return {\n content: [{ type: \"text\", text: `Store not found: ${switchToId}\\nAvailable stores: ${stores.map(s => `${s.name} (${s.id})`).join(\", \")}` }],\n isError: true,\n };\n }\n\n selectStore(target.id, target.name);\n reloadConfig();\n\n // Notify MCP client that tools may have changed context\n server.notification({ method: \"notifications/tools/list_changed\" });\n\n return {\n content: [{ type: \"text\", text: `Switched to store: ${target.name} (${target.id})` }],\n };\n }\n\n // List stores\n const token = await getAuthToken();\n const stores = await getStoresForUser(token, USER_ID || \"\");\n\n if (stores.length === 0) {\n return { content: [{ type: \"text\", text: \"No stores found for your account.\" }] };\n }\n\n const cfg = loadConfig();\n const lines = [\"Your stores:\"];\n for (const s of stores) {\n const active = s.id === cfg.store_id ? \" (active)\" : \"\";\n lines.push(` - ${s.name}${s.slug ? ` [${s.slug}]` : \"\"}: ${s.id}${active}`);\n }\n lines.push(\"\\nTo switch: use whale_stores with store_id parameter\");\n\n return { content: [{ type: \"text\", text: lines.join(\"\\n\") }] };\n}\n\n// ============================================================================\n// MCP SERVER\n// ============================================================================\n\nconst server = new Server(\n { name: \"whale\", version: PKG_VERSION },\n { capabilities: { tools: {} } }\n);\n\n// List available tools — local auth tools always present; remote tools when authenticated\nserver.setRequestHandler(ListToolsRequestSchema, async () => {\n if (!isAuthenticated) {\n console.error(`[MCP] Returning ${LOCAL_TOOLS.length} tools (not authenticated)`);\n return {\n tools: LOCAL_TOOLS.map(t => ({\n name: t.name,\n description: t.description,\n inputSchema: t.inputSchema,\n })),\n };\n }\n\n const remoteTools = await loadToolDefinitions();\n const allTools = [...LOCAL_TOOLS, ...remoteTools];\n console.error(`[MCP] Returning ${allTools.length} tools (${LOCAL_TOOLS.length} local + ${remoteTools.length} remote)`);\n\n return {\n tools: allTools.map(t => ({\n name: t.name,\n description: t.description,\n inputSchema: t.inputSchema,\n })),\n };\n});\n\n// Execute a tool — local auth tools handled here, everything else proxied to Fly.io\nserver.setRequestHandler(CallToolRequestSchema, async (request) => {\n const toolName = request.params.name;\n const toolArgs = (request.params.arguments || {}) as Record<string, any>;\n\n // ── Local tools (handled in-process) ──\n\n if (toolName === \"whale_login\") {\n return handleWhaleLogin();\n }\n\n if (toolName === \"whale_status\") {\n return handleWhaleStatus();\n }\n\n if (toolName === \"whale_stores\") {\n return handleWhaleStores(toolArgs);\n }\n\n // ── Auth gate for remote tools ──\n\n if (!isAuthenticated) {\n return {\n content: [{\n type: \"text\" as const,\n text: \"Not authenticated. Please use the whale_login tool first to sign in to your WhaleTools account.\",\n }],\n isError: true,\n };\n }\n\n // ── Remote tool execution ──\n\n const traceId = crypto.randomUUID();\n\n // Allow tool-level store_id override (e.g. multi-store users switching context)\n const effectiveStoreId = (toolArgs.store_id as string) || STORE_ID || undefined;\n if (toolArgs.store_id) {\n delete toolArgs.store_id; // Don't send as a tool arg — it's a routing param\n }\n\n console.error(`[MCP] Executing: ${toolName} → Fly.io [${traceId.slice(0, 8)}] store=${effectiveStoreId?.slice(0, 8) || \"none\"}`);\n\n const result = await executeToolRemote(toolName, toolArgs, effectiveStoreId, traceId);\n\n if (result.success) {\n return {\n content: [{\n type: \"text\" as const,\n text: typeof result.data === \"string\"\n ? result.data\n : JSON.stringify(result.data, null, 2),\n }],\n };\n } else {\n return {\n content: [{\n type: \"text\" as const,\n text: JSON.stringify({ error: result.error }),\n }],\n isError: true,\n };\n }\n});\n\n// ============================================================================\n// LOCAL AGENT (auto-spawned — shares this process with MCP server)\n// ============================================================================\n\nlet localAgent: LocalAgentConnection | null = null;\n\n/**\n * Get or create a store API key for the local agent WebSocket connection.\n * Persisted to ~/.whaletools/session.json so we reuse across restarts.\n */\nasync function getOrCreateAgentApiKey(): Promise<string | null> {\n const rawConfig = loadConfig();\n if (rawConfig.agent_api_key) return rawConfig.agent_api_key;\n\n // Auto-generate via the server's api_keys tool\n try {\n const result = await executeToolRemote(\"api_keys\", {\n action: \"generate\",\n name: \"local-agent-auto\",\n scopes: [\"*\"],\n key_type: \"live\",\n }, STORE_ID || undefined);\n\n if (result.success && result.data) {\n const data = result.data as any;\n const key = data.key_value || data.api_key || data.key;\n if (key) {\n updateConfig({ agent_api_key: key });\n console.error(\"[MCP] Auto-generated local agent API key\");\n return key;\n }\n }\n console.error(\"[MCP] Failed to auto-generate agent API key:\", result.error);\n return null;\n } catch (err: any) {\n console.error(\"[MCP] Error generating agent API key:\", err.message);\n return null;\n }\n}\n\n/**\n * Derive WebSocket URL from the HTTP server URL.\n * https://whale-agent.fly.dev → wss://whale-agent.fly.dev/agent/ws\n */\nfunction getAgentWsUrl(): string {\n const base = SERVER_URL.replace(/\\/$/, \"\");\n const wsBase = base.replace(/^https:/, \"wss:\").replace(/^http:/, \"ws:\");\n return `${wsBase}/agent/ws`;\n}\n\n/**\n * Start the local agent WebSocket connection in the background.\n * Non-blocking — MCP server continues even if this fails.\n */\nasync function startLocalAgent(): Promise<void> {\n const apiKey = await getOrCreateAgentApiKey();\n if (!apiKey) {\n console.error(\"[MCP] Skipping local agent — no API key available\");\n return;\n }\n\n const wsUrl = getAgentWsUrl();\n console.error(`[MCP] Starting local agent → ${wsUrl}`);\n\n localAgent = new LocalAgentConnection({\n apiKey,\n serverUrl: wsUrl,\n onConnected: () => console.error(\"[MCP] Local agent connected — WhaleChat can now use local tools\"),\n onDisconnected: (reason) => console.error(`[MCP] Local agent disconnected: ${reason}`),\n onError: (err) => console.error(`[MCP] Local agent error: ${err.message}`),\n onLog: (msg) => console.error(msg),\n });\n\n try {\n await localAgent.connect();\n } catch (err: any) {\n console.error(`[MCP] Local agent failed to connect: ${err.message} (non-fatal)`);\n }\n}\n\n// ============================================================================\n// STARTUP\n// ============================================================================\n\nasync function main() {\n // Initialize error logging for MCP mode\n initErrorLogger({ serviceName: \"whale-code-mcp\" });\n if (USER_ID || USER_EMAIL) {\n setErrorLoggerUser(USER_ID || undefined, USER_EMAIL || undefined, STORE_ID || undefined);\n }\n\n console.error(`[MCP] Whale MCP Server v${PKG_VERSION}`);\n console.error(`[MCP] Supabase: ${SUPABASE_URL}`);\n console.error(`[MCP] Server: ${SERVER_URL}`);\n console.error(`[MCP] Store: ${STORE_ID || \"(default)\"}`);\n console.error(`[MCP] User: ${USER_EMAIL || \"(unknown)\"} [${USER_ID?.slice(0, 8) || \"no-id\"}]`);\n console.error(`[MCP] Session: ${SESSION_ID}`);\n console.error(`[MCP] Authenticated: ${isAuthenticated ? \"yes\" : \"no — use whale_login tool\"}`);\n\n // Pre-load tools from database (only if authenticated)\n if (isAuthenticated) {\n const tools = await loadToolDefinitions(true);\n console.error(`[MCP] Loaded ${tools.length} tools from registry`);\n } else {\n console.error(`[MCP] Skipping tool load — not authenticated. ${LOCAL_TOOLS.length} auth tools available.`);\n }\n\n // Start OTA update checker (non-blocking, runs in background)\n startUpdateLoop(true);\n\n // Connect via stdio\n const transport = new StdioServerTransport();\n await server.connect(transport);\n console.error(\"[MCP] Ready\");\n\n // Start local agent in background — only if authenticated\n if (isAuthenticated) {\n startLocalAgent().catch((err) => {\n console.error(\"[MCP] Local agent startup error:\", err.message);\n });\n }\n}\n\n// Graceful shutdown — disconnect local agent\nprocess.on(\"SIGINT\", () => {\n localAgent?.disconnect();\n});\nprocess.on(\"SIGTERM\", () => {\n localAgent?.disconnect();\n});\n\nmain().catch((err) => {\n console.error(\"[MCP] Fatal:\", err);\n captureError({ error: err instanceof Error ? err : new Error(String(err)), severity: \"fatal\", tags: { source: \"mcp_main\" } });\n // Give error logger a moment to flush before exit\n setTimeout(() => process.exit(1), 500);\n});\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { chromium } from "playwright-core";
|
|
4
4
|
import { detectAndSolveCaptcha } from "./browser-captcha.js";
|
|
5
|
+
import { validateUrl } from "../lib/ssrf-guard.js";
|
|
5
6
|
|
|
6
7
|
// ============================================================================
|
|
7
8
|
// BROWSER INSTANCE LIFECYCLE
|
|
@@ -48,6 +49,15 @@ async function getBrowser() {
|
|
|
48
49
|
return browserInstance;
|
|
49
50
|
}
|
|
50
51
|
export async function withPage(url, waitFor, fn) {
|
|
52
|
+
// SSRF check — fast synchronous pre-check, then DNS-based validation
|
|
53
|
+
const blocked = isBlockedUrl(url);
|
|
54
|
+
if (blocked) {
|
|
55
|
+
throw new Error(blocked);
|
|
56
|
+
}
|
|
57
|
+
const dnsBlocked = await validateUrl(url);
|
|
58
|
+
if (dnsBlocked) {
|
|
59
|
+
throw new Error(dnsBlocked);
|
|
60
|
+
}
|
|
51
61
|
const browser = await getBrowser();
|
|
52
62
|
const context = await browser.newContext({
|
|
53
63
|
userAgent: "WhaleBot/1.0 (https://whale.app)",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"browser-lifecycle.js","names":["chromium","detectAndSolveCaptcha","browserInstance","idleTimer","IDLE_TIMEOUT_MS","PAGE_TIMEOUT_MS","MAX_RESULT_BYTES","MAX_TEXT_CHARS","resetIdleTimer","clearTimeout","setTimeout","close","console","log","getBrowser","isConnected","launch","headless","executablePath","process","env","PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH","undefined","args","on","withPage","url","waitFor","fn","browser","context","newContext","userAgent","viewport","width","height","ignoreHTTPSErrors","setDefaultTimeout","page","newPage","goto","waitUntil","timeout","captchaResult","solved","type","waitForTimeout","waitForSelector","catch","isBlockedUrl","parsed","URL","protocol","host","hostname","toLowerCase","endsWith","test","startsWith","includes","stripScriptsAndStyles","html","replace","trim","truncate","text","maxChars","length","substring","truncateResult","data","json","JSON","stringify","parse"],"sources":["../../../src/server/handlers/browser-lifecycle.ts"],"sourcesContent":["// browser-lifecycle.ts — Browser instance management, page context, SSRF protection, text helpers\n\nimport { chromium, type Browser, type Page } from \"playwright-core\";\nimport { detectAndSolveCaptcha } from \"./browser-captcha.js\";\n\n// ============================================================================\n// BROWSER INSTANCE LIFECYCLE\n// ============================================================================\n\nlet browserInstance: Browser | null = null;\nlet idleTimer: ReturnType<typeof setTimeout> | null = null;\nconst IDLE_TIMEOUT_MS = 5 * 60 * 1000; // 5 minutes\nexport const PAGE_TIMEOUT_MS = 60_000; // 60 seconds per page operation (increased for CAPTCHA solving)\nexport const MAX_RESULT_BYTES = 500 * 1024; // 500KB safety cap — context_management handles limits\nexport const MAX_TEXT_CHARS = 200_000; // 200K chars for text content\n\nfunction resetIdleTimer(): void {\n if (idleTimer) clearTimeout(idleTimer);\n idleTimer = setTimeout(async () => {\n if (browserInstance) {\n try {\n await browserInstance.close();\n } catch { /* browser may already be closed */ }\n browserInstance = null;\n console.log(\"[browser] Closed after idle timeout\");\n }\n }, IDLE_TIMEOUT_MS);\n}\n\nasync function getBrowser(): Promise<Browser> {\n if (browserInstance && browserInstance.isConnected()) {\n resetIdleTimer();\n return browserInstance;\n }\n\n browserInstance = await chromium.launch({\n headless: true,\n executablePath: process.env.PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH || undefined,\n args: [\n \"--no-sandbox\",\n \"--disable-setuid-sandbox\",\n \"--disable-dev-shm-usage\",\n \"--disable-gpu\",\n ],\n });\n\n browserInstance.on(\"disconnected\", () => {\n browserInstance = null;\n if (idleTimer) {\n clearTimeout(idleTimer);\n idleTimer = null;\n }\n });\n\n resetIdleTimer();\n console.log(\"[browser] Launched new instance\");\n return browserInstance;\n}\n\nexport async function withPage<T>(url: string, waitFor: string | undefined, fn: (page: Page) => Promise<T>): Promise<T> {\n const browser = await getBrowser();\n const context = await browser.newContext({\n userAgent: \"WhaleBot/1.0 (https://whale.app)\",\n viewport: { width: 1280, height: 720 },\n ignoreHTTPSErrors: true,\n });\n context.setDefaultTimeout(PAGE_TIMEOUT_MS);\n\n const page = await context.newPage();\n try {\n await page.goto(url, { waitUntil: \"domcontentloaded\", timeout: PAGE_TIMEOUT_MS });\n\n // Auto-detect and solve CAPTCHAs after page load\n const captchaResult = await detectAndSolveCaptcha(page);\n if (captchaResult.solved) {\n console.log(`[browser] Solved ${captchaResult.type} CAPTCHA on ${url}`);\n // Wait for page to update after CAPTCHA solution\n await page.waitForTimeout(2000);\n }\n\n if (waitFor) {\n await page.waitForSelector(waitFor, { timeout: PAGE_TIMEOUT_MS });\n }\n\n return await fn(page);\n } finally {\n await page.close().catch(() => {});\n await context.close().catch(() => {});\n }\n}\n\n// ============================================================================\n// SSRF PROTECTION\n// ============================================================================\n\nexport function isBlockedUrl(url: string): string | null {\n let parsed: URL;\n try {\n parsed = new URL(url);\n } catch {\n return \"Invalid URL\";\n }\n\n if (parsed.protocol !== \"http:\" && parsed.protocol !== \"https:\") {\n return `Blocked protocol: ${parsed.protocol}`;\n }\n\n const host = parsed.hostname.toLowerCase();\n\n // Block localhost variants\n if (host === \"localhost\" || host === \"127.0.0.1\" || host === \"0.0.0.0\" ||\n host === \"::1\" || host === \"[::1]\") {\n return \"Blocked: localhost\";\n }\n\n // Block private/internal domains\n if (host.endsWith(\".internal\") || host.endsWith(\".local\") ||\n host === \"metadata.google.internal\") {\n return \"Blocked: internal/local domain\";\n }\n\n // Block private IP ranges\n if (/^10\\./.test(host) ||\n /^172\\.(1[6-9]|2\\d|3[01])\\./.test(host) ||\n /^192\\.168\\./.test(host) ||\n /^169\\.254\\./.test(host)) {\n return \"Blocked: private IP range\";\n }\n\n // Block IPv6 private\n if (host.startsWith(\"fd\") || host.startsWith(\"fc00:\") ||\n host.startsWith(\"fe80:\") || host.includes(\"::ffff:\")) {\n return \"Blocked: IPv6 private range\";\n }\n\n return null;\n}\n\n// ============================================================================\n// TEXT CLEANUP\n// ============================================================================\n\nexport function stripScriptsAndStyles(html: string): string {\n return html\n .replace(/<script[\\s\\S]*?<\\/script>/gi, \"\")\n .replace(/<style[\\s\\S]*?<\\/style>/gi, \"\")\n .replace(/<[^>]+>/g, \" \")\n .replace(/\\s+/g, \" \")\n .trim();\n}\n\nexport function truncate(text: string, maxChars: number): string {\n if (text.length <= maxChars) return text;\n return text.substring(0, maxChars) + \"\\n...[truncated]\";\n}\n\nexport function truncateResult(data: unknown): unknown {\n const json = JSON.stringify(data);\n if (json.length <= MAX_RESULT_BYTES) return data;\n // If too large, stringify and truncate\n return JSON.parse(truncate(json, MAX_RESULT_BYTES));\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"browser-lifecycle.js","names":["chromium","detectAndSolveCaptcha","validateUrl","browserInstance","idleTimer","IDLE_TIMEOUT_MS","PAGE_TIMEOUT_MS","MAX_RESULT_BYTES","MAX_TEXT_CHARS","resetIdleTimer","clearTimeout","setTimeout","close","console","log","getBrowser","isConnected","launch","headless","executablePath","process","env","PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH","undefined","args","on","withPage","url","waitFor","fn","blocked","isBlockedUrl","Error","dnsBlocked","browser","context","newContext","userAgent","viewport","width","height","ignoreHTTPSErrors","setDefaultTimeout","page","newPage","goto","waitUntil","timeout","captchaResult","solved","type","waitForTimeout","waitForSelector","catch","parsed","URL","protocol","host","hostname","toLowerCase","endsWith","test","startsWith","includes","stripScriptsAndStyles","html","replace","trim","truncate","text","maxChars","length","substring","truncateResult","data","json","JSON","stringify","parse"],"sources":["../../../src/server/handlers/browser-lifecycle.ts"],"sourcesContent":["// browser-lifecycle.ts — Browser instance management, page context, SSRF protection, text helpers\n\nimport { chromium, type Browser, type Page } from \"playwright-core\";\nimport { detectAndSolveCaptcha } from \"./browser-captcha.js\";\nimport { validateUrl } from \"../lib/ssrf-guard.js\";\n\n// ============================================================================\n// BROWSER INSTANCE LIFECYCLE\n// ============================================================================\n\nlet browserInstance: Browser | null = null;\nlet idleTimer: ReturnType<typeof setTimeout> | null = null;\nconst IDLE_TIMEOUT_MS = 5 * 60 * 1000; // 5 minutes\nexport const PAGE_TIMEOUT_MS = 60_000; // 60 seconds per page operation (increased for CAPTCHA solving)\nexport const MAX_RESULT_BYTES = 500 * 1024; // 500KB safety cap — context_management handles limits\nexport const MAX_TEXT_CHARS = 200_000; // 200K chars for text content\n\nfunction resetIdleTimer(): void {\n if (idleTimer) clearTimeout(idleTimer);\n idleTimer = setTimeout(async () => {\n if (browserInstance) {\n try {\n await browserInstance.close();\n } catch { /* browser may already be closed */ }\n browserInstance = null;\n console.log(\"[browser] Closed after idle timeout\");\n }\n }, IDLE_TIMEOUT_MS);\n}\n\nasync function getBrowser(): Promise<Browser> {\n if (browserInstance && browserInstance.isConnected()) {\n resetIdleTimer();\n return browserInstance;\n }\n\n browserInstance = await chromium.launch({\n headless: true,\n executablePath: process.env.PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH || undefined,\n args: [\n \"--no-sandbox\",\n \"--disable-setuid-sandbox\",\n \"--disable-dev-shm-usage\",\n \"--disable-gpu\",\n ],\n });\n\n browserInstance.on(\"disconnected\", () => {\n browserInstance = null;\n if (idleTimer) {\n clearTimeout(idleTimer);\n idleTimer = null;\n }\n });\n\n resetIdleTimer();\n console.log(\"[browser] Launched new instance\");\n return browserInstance;\n}\n\nexport async function withPage<T>(url: string, waitFor: string | undefined, fn: (page: Page) => Promise<T>): Promise<T> {\n // SSRF check — fast synchronous pre-check, then DNS-based validation\n const blocked = isBlockedUrl(url);\n if (blocked) {\n throw new Error(blocked);\n }\n const dnsBlocked = await validateUrl(url);\n if (dnsBlocked) {\n throw new Error(dnsBlocked);\n }\n\n const browser = await getBrowser();\n const context = await browser.newContext({\n userAgent: \"WhaleBot/1.0 (https://whale.app)\",\n viewport: { width: 1280, height: 720 },\n ignoreHTTPSErrors: true,\n });\n context.setDefaultTimeout(PAGE_TIMEOUT_MS);\n\n const page = await context.newPage();\n try {\n await page.goto(url, { waitUntil: \"domcontentloaded\", timeout: PAGE_TIMEOUT_MS });\n\n // Auto-detect and solve CAPTCHAs after page load\n const captchaResult = await detectAndSolveCaptcha(page);\n if (captchaResult.solved) {\n console.log(`[browser] Solved ${captchaResult.type} CAPTCHA on ${url}`);\n // Wait for page to update after CAPTCHA solution\n await page.waitForTimeout(2000);\n }\n\n if (waitFor) {\n await page.waitForSelector(waitFor, { timeout: PAGE_TIMEOUT_MS });\n }\n\n return await fn(page);\n } finally {\n await page.close().catch(() => {});\n await context.close().catch(() => {});\n }\n}\n\n// ============================================================================\n// SSRF PROTECTION\n// ============================================================================\n\nexport function isBlockedUrl(url: string): string | null {\n let parsed: URL;\n try {\n parsed = new URL(url);\n } catch {\n return \"Invalid URL\";\n }\n\n if (parsed.protocol !== \"http:\" && parsed.protocol !== \"https:\") {\n return `Blocked protocol: ${parsed.protocol}`;\n }\n\n const host = parsed.hostname.toLowerCase();\n\n // Block localhost variants\n if (host === \"localhost\" || host === \"127.0.0.1\" || host === \"0.0.0.0\" ||\n host === \"::1\" || host === \"[::1]\") {\n return \"Blocked: localhost\";\n }\n\n // Block private/internal domains\n if (host.endsWith(\".internal\") || host.endsWith(\".local\") ||\n host === \"metadata.google.internal\") {\n return \"Blocked: internal/local domain\";\n }\n\n // Block private IP ranges\n if (/^10\\./.test(host) ||\n /^172\\.(1[6-9]|2\\d|3[01])\\./.test(host) ||\n /^192\\.168\\./.test(host) ||\n /^169\\.254\\./.test(host)) {\n return \"Blocked: private IP range\";\n }\n\n // Block IPv6 private\n if (host.startsWith(\"fd\") || host.startsWith(\"fc00:\") ||\n host.startsWith(\"fe80:\") || host.includes(\"::ffff:\")) {\n return \"Blocked: IPv6 private range\";\n }\n\n return null;\n}\n\n// ============================================================================\n// TEXT CLEANUP\n// ============================================================================\n\nexport function stripScriptsAndStyles(html: string): string {\n return html\n .replace(/<script[\\s\\S]*?<\\/script>/gi, \"\")\n .replace(/<style[\\s\\S]*?<\\/style>/gi, \"\")\n .replace(/<[^>]+>/g, \" \")\n .replace(/\\s+/g, \" \")\n .trim();\n}\n\nexport function truncate(text: string, maxChars: number): string {\n if (text.length <= maxChars) return text;\n return text.substring(0, maxChars) + \"\\n...[truncated]\";\n}\n\nexport function truncateResult(data: unknown): unknown {\n const json = JSON.stringify(data);\n if (json.length <= MAX_RESULT_BYTES) return data;\n // If too large, stringify and truncate\n return JSON.parse(truncate(json, MAX_RESULT_BYTES));\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
// Supports: navigate, screenshot, extract, click, fill, evaluate, pdf
|
|
3
3
|
|
|
4
4
|
import { chromium } from "playwright-core";
|
|
5
|
+
import { validateUrl } from "../lib/ssrf-guard.js";
|
|
5
6
|
|
|
6
7
|
// ============================================================================
|
|
7
8
|
// BROWSER INSTANCE LIFECYCLE
|
|
@@ -501,7 +502,7 @@ export async function handleBrowser(_sb, args, _storeId) {
|
|
|
501
502
|
};
|
|
502
503
|
}
|
|
503
504
|
|
|
504
|
-
// SSRF check
|
|
505
|
+
// SSRF check — fast synchronous pre-check, then DNS-based validation
|
|
505
506
|
const blocked = isBlockedUrl(url);
|
|
506
507
|
if (blocked) {
|
|
507
508
|
return {
|
|
@@ -509,6 +510,20 @@ export async function handleBrowser(_sb, args, _storeId) {
|
|
|
509
510
|
error: blocked
|
|
510
511
|
};
|
|
511
512
|
}
|
|
513
|
+
try {
|
|
514
|
+
const dnsBlocked = await validateUrl(url);
|
|
515
|
+
if (dnsBlocked) {
|
|
516
|
+
return {
|
|
517
|
+
success: false,
|
|
518
|
+
error: dnsBlocked
|
|
519
|
+
};
|
|
520
|
+
}
|
|
521
|
+
} catch {
|
|
522
|
+
return {
|
|
523
|
+
success: false,
|
|
524
|
+
error: "URL validation failed"
|
|
525
|
+
};
|
|
526
|
+
}
|
|
512
527
|
try {
|
|
513
528
|
switch (action) {
|
|
514
529
|
case "navigate":
|