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,184 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* iMessage Watch Daemon — helpers: agent API client, message logging, CLI queries
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { existsSync, readFileSync, unlinkSync } from "node:fs";
|
|
6
|
-
import { execFileSync } from "node:child_process";
|
|
7
|
-
import { SUPABASE_URL, SUPABASE_ANON_KEY } from "../services/auth-service.js";
|
|
8
|
-
import { WHALE_SERVER_URL } from "../services/config-store.js";
|
|
9
|
-
import { IMSG_BIN, PID_FILE } from "../../shared/imsg-constants.js";
|
|
10
|
-
export { IMSG_BIN, PID_FILE };
|
|
11
|
-
export const AGENT_URL = `${WHALE_SERVER_URL}/api/chat`;
|
|
12
|
-
|
|
13
|
-
// Stats for `whale imsg status`
|
|
14
|
-
|
|
15
|
-
export function log(msg) {
|
|
16
|
-
const ts = new Date().toLocaleTimeString("en-US", {
|
|
17
|
-
hour12: false
|
|
18
|
-
});
|
|
19
|
-
console.log(`[${ts}] ${msg}`);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Call the agent API with SSE streaming and accumulate the text response.
|
|
24
|
-
*/
|
|
25
|
-
export async function getAgentResponse(message, conversationId, agentId, storeId, token, systemPrompt) {
|
|
26
|
-
const payload = {
|
|
27
|
-
agentId,
|
|
28
|
-
message,
|
|
29
|
-
storeId,
|
|
30
|
-
source: "imessage",
|
|
31
|
-
conversationId
|
|
32
|
-
};
|
|
33
|
-
if (systemPrompt) payload.systemPrompt = systemPrompt;
|
|
34
|
-
let response;
|
|
35
|
-
try {
|
|
36
|
-
response = await fetch(AGENT_URL, {
|
|
37
|
-
method: "POST",
|
|
38
|
-
headers: {
|
|
39
|
-
"Content-Type": "application/json",
|
|
40
|
-
Authorization: `Bearer ${token}`
|
|
41
|
-
},
|
|
42
|
-
body: JSON.stringify(payload),
|
|
43
|
-
signal: AbortSignal.timeout(60_000)
|
|
44
|
-
});
|
|
45
|
-
} catch {
|
|
46
|
-
return "";
|
|
47
|
-
}
|
|
48
|
-
if (!response.ok || !response.body) return "";
|
|
49
|
-
|
|
50
|
-
// Read SSE stream and accumulate text chunks
|
|
51
|
-
const reader = response.body.getReader();
|
|
52
|
-
const decoder = new TextDecoder();
|
|
53
|
-
let fullText = "";
|
|
54
|
-
let buffer = "";
|
|
55
|
-
try {
|
|
56
|
-
while (true) {
|
|
57
|
-
const {
|
|
58
|
-
done,
|
|
59
|
-
value
|
|
60
|
-
} = await reader.read();
|
|
61
|
-
if (done) break;
|
|
62
|
-
buffer += decoder.decode(value, {
|
|
63
|
-
stream: true
|
|
64
|
-
});
|
|
65
|
-
const lines = buffer.split("\n");
|
|
66
|
-
buffer = lines.pop() || "";
|
|
67
|
-
for (const line of lines) {
|
|
68
|
-
if (!line.startsWith("data: ")) continue;
|
|
69
|
-
const data = line.slice(6);
|
|
70
|
-
try {
|
|
71
|
-
const parsed = JSON.parse(data);
|
|
72
|
-
if (parsed.type === "text" && parsed.text) {
|
|
73
|
-
fullText += parsed.text;
|
|
74
|
-
}
|
|
75
|
-
} catch {
|
|
76
|
-
// Not valid JSON SSE chunk — skip
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
} catch {
|
|
81
|
-
// Stream error — return what we have
|
|
82
|
-
}
|
|
83
|
-
return fullText;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* Log a message to Supabase channel_messages table.
|
|
88
|
-
*/
|
|
89
|
-
export async function logMessage(direction, content, senderId, conversationId, token, storeId, senderName, metadata) {
|
|
90
|
-
const body = [{
|
|
91
|
-
store_id: storeId,
|
|
92
|
-
direction,
|
|
93
|
-
content,
|
|
94
|
-
sender_id: senderId,
|
|
95
|
-
sender_name: senderName || "",
|
|
96
|
-
conversation_id: conversationId,
|
|
97
|
-
metadata: metadata || {}
|
|
98
|
-
}];
|
|
99
|
-
try {
|
|
100
|
-
await fetch(`${SUPABASE_URL}/rest/v1/channel_messages`, {
|
|
101
|
-
method: "POST",
|
|
102
|
-
headers: {
|
|
103
|
-
apikey: SUPABASE_ANON_KEY,
|
|
104
|
-
Authorization: `Bearer ${token}`,
|
|
105
|
-
"Content-Type": "application/json",
|
|
106
|
-
Prefer: "return=minimal"
|
|
107
|
-
},
|
|
108
|
-
body: JSON.stringify(body)
|
|
109
|
-
});
|
|
110
|
-
} catch {
|
|
111
|
-
// Logging is best-effort
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
/**
|
|
116
|
-
* List recent chats via imsg chats --json.
|
|
117
|
-
*/
|
|
118
|
-
export function listChats(limit = 20) {
|
|
119
|
-
try {
|
|
120
|
-
const result = execFileSync(IMSG_BIN, ["chats", "--limit", String(limit), "--json"], {
|
|
121
|
-
encoding: "utf-8",
|
|
122
|
-
timeout: 10000
|
|
123
|
-
});
|
|
124
|
-
return JSON.parse(result);
|
|
125
|
-
} catch {
|
|
126
|
-
return [];
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
/**
|
|
131
|
-
* List recent messages via imsg list --json.
|
|
132
|
-
*/
|
|
133
|
-
export function listMessages(chatId, limit = 20) {
|
|
134
|
-
const args = ["list", "--limit", String(limit), "--json"];
|
|
135
|
-
if (chatId != null) args.push("--chat-id", String(chatId));
|
|
136
|
-
try {
|
|
137
|
-
const result = execFileSync(IMSG_BIN, args, {
|
|
138
|
-
encoding: "utf-8",
|
|
139
|
-
timeout: 10000
|
|
140
|
-
});
|
|
141
|
-
return JSON.parse(result);
|
|
142
|
-
} catch {
|
|
143
|
-
return [];
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
/**
|
|
148
|
-
* Read the PID file and return daemon info (or null if not running).
|
|
149
|
-
*/
|
|
150
|
-
export function getDaemonStatus() {
|
|
151
|
-
if (!existsSync(PID_FILE)) return null;
|
|
152
|
-
try {
|
|
153
|
-
const pid = parseInt(readFileSync(PID_FILE, "utf-8").trim(), 10);
|
|
154
|
-
// Check if process is alive
|
|
155
|
-
process.kill(pid, 0); // Signal 0 = check existence
|
|
156
|
-
return {
|
|
157
|
-
pid
|
|
158
|
-
};
|
|
159
|
-
} catch {
|
|
160
|
-
// PID file exists but process is dead — clean up
|
|
161
|
-
try {
|
|
162
|
-
unlinkSync(PID_FILE);
|
|
163
|
-
} catch {/* ignore */}
|
|
164
|
-
return null;
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
/**
|
|
169
|
-
* Stop a running daemon.
|
|
170
|
-
*/
|
|
171
|
-
export function stopDaemon() {
|
|
172
|
-
const status = getDaemonStatus();
|
|
173
|
-
if (!status) return false;
|
|
174
|
-
try {
|
|
175
|
-
process.kill(status.pid, "SIGTERM");
|
|
176
|
-
try {
|
|
177
|
-
unlinkSync(PID_FILE);
|
|
178
|
-
} catch {/* ignore */}
|
|
179
|
-
return true;
|
|
180
|
-
} catch {
|
|
181
|
-
return false;
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
//# sourceMappingURL=imsg-watcher-helpers.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"imsg-watcher-helpers.js","names":["existsSync","readFileSync","unlinkSync","execFileSync","SUPABASE_URL","SUPABASE_ANON_KEY","WHALE_SERVER_URL","IMSG_BIN","PID_FILE","AGENT_URL","log","msg","ts","Date","toLocaleTimeString","hour12","console","getAgentResponse","message","conversationId","agentId","storeId","token","systemPrompt","payload","source","response","fetch","method","headers","Authorization","body","JSON","stringify","signal","AbortSignal","timeout","ok","reader","getReader","decoder","TextDecoder","fullText","buffer","done","value","read","decode","stream","lines","split","pop","line","startsWith","data","slice","parsed","parse","type","text","logMessage","direction","content","senderId","senderName","metadata","store_id","sender_id","sender_name","conversation_id","apikey","Prefer","listChats","limit","result","String","encoding","listMessages","chatId","args","push","getDaemonStatus","pid","parseInt","trim","process","kill","stopDaemon","status"],"sources":["../../../src/cli/commands/imsg-watcher-helpers.ts"],"sourcesContent":["/**\n * iMessage Watch Daemon — helpers: agent API client, message logging, CLI queries\n */\n\nimport { existsSync, readFileSync, unlinkSync } from \"node:fs\";\nimport { execFileSync } from \"node:child_process\";\nimport { SUPABASE_URL, SUPABASE_ANON_KEY } from \"../services/auth-service.js\";\nimport { WHALE_SERVER_URL } from \"../services/config-store.js\";\nimport { IMSG_BIN, PID_FILE } from \"../../shared/imsg-constants.js\";\n\nexport { IMSG_BIN, PID_FILE };\nexport const AGENT_URL = `${WHALE_SERVER_URL}/api/chat`;\n\n// Stats for `whale imsg status`\nexport interface DaemonStats {\n started_at: string;\n messages_in: number;\n messages_out: number;\n errors: number;\n}\n\nexport function log(msg: string): void {\n const ts = new Date().toLocaleTimeString(\"en-US\", { hour12: false });\n console.log(`[${ts}] ${msg}`);\n}\n\n/**\n * Call the agent API with SSE streaming and accumulate the text response.\n */\nexport async function getAgentResponse(\n message: string,\n conversationId: string,\n agentId: string,\n storeId: string,\n token: string,\n systemPrompt?: string | null,\n): Promise<string> {\n const payload: Record<string, string> = {\n agentId,\n message,\n storeId,\n source: \"imessage\",\n conversationId,\n };\n if (systemPrompt) payload.systemPrompt = systemPrompt;\n\n let response: Response;\n try {\n response = await fetch(AGENT_URL, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${token}`,\n },\n body: JSON.stringify(payload),\n signal: AbortSignal.timeout(60_000),\n });\n } catch {\n return \"\";\n }\n\n if (!response.ok || !response.body) return \"\";\n\n // Read SSE stream and accumulate text chunks\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let fullText = \"\";\n let buffer = \"\";\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n buffer += decoder.decode(value, { stream: true });\n\n const lines = buffer.split(\"\\n\");\n buffer = lines.pop() || \"\";\n\n for (const line of lines) {\n if (!line.startsWith(\"data: \")) continue;\n const data = line.slice(6);\n try {\n const parsed = JSON.parse(data);\n if (parsed.type === \"text\" && parsed.text) {\n fullText += parsed.text;\n }\n } catch {\n // Not valid JSON SSE chunk — skip\n }\n }\n }\n } catch {\n // Stream error — return what we have\n }\n\n return fullText;\n}\n\n/**\n * Log a message to Supabase channel_messages table.\n */\nexport async function logMessage(\n direction: \"inbound\" | \"outbound\",\n content: string,\n senderId: string,\n conversationId: string,\n token: string,\n storeId: string,\n senderName?: string,\n metadata?: Record<string, unknown>,\n): Promise<void> {\n const body = [\n {\n store_id: storeId,\n direction,\n content,\n sender_id: senderId,\n sender_name: senderName || \"\",\n conversation_id: conversationId,\n metadata: metadata || {},\n },\n ];\n\n try {\n await fetch(`${SUPABASE_URL}/rest/v1/channel_messages`, {\n method: \"POST\",\n headers: {\n apikey: SUPABASE_ANON_KEY,\n Authorization: `Bearer ${token}`,\n \"Content-Type\": \"application/json\",\n Prefer: \"return=minimal\",\n },\n body: JSON.stringify(body),\n });\n } catch {\n // Logging is best-effort\n }\n}\n\n/**\n * List recent chats via imsg chats --json.\n */\nexport function listChats(limit = 20): any[] {\n try {\n const result = execFileSync(\n IMSG_BIN, [\"chats\", \"--limit\", String(limit), \"--json\"],\n { encoding: \"utf-8\", timeout: 10000 },\n );\n return JSON.parse(result);\n } catch {\n return [];\n }\n}\n\n/**\n * List recent messages via imsg list --json.\n */\nexport function listMessages(chatId?: number, limit = 20): any[] {\n const args = [\"list\", \"--limit\", String(limit), \"--json\"];\n if (chatId != null) args.push(\"--chat-id\", String(chatId));\n\n try {\n const result = execFileSync(\n IMSG_BIN, args,\n { encoding: \"utf-8\", timeout: 10000 },\n );\n return JSON.parse(result);\n } catch {\n return [];\n }\n}\n\n/**\n * Read the PID file and return daemon info (or null if not running).\n */\nexport function getDaemonStatus(): { pid: number; uptime?: string } | null {\n if (!existsSync(PID_FILE)) return null;\n\n try {\n const pid = parseInt(readFileSync(PID_FILE, \"utf-8\").trim(), 10);\n // Check if process is alive\n process.kill(pid, 0); // Signal 0 = check existence\n return { pid };\n } catch {\n // PID file exists but process is dead — clean up\n try {\n unlinkSync(PID_FILE);\n } catch { /* ignore */ }\n return null;\n }\n}\n\n/**\n * Stop a running daemon.\n */\nexport function stopDaemon(): boolean {\n const status = getDaemonStatus();\n if (!status) return false;\n\n try {\n process.kill(status.pid, \"SIGTERM\");\n try {\n unlinkSync(PID_FILE);\n } catch { /* ignore */ }\n return true;\n } catch {\n return false;\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* iMessage Watch Daemon — replaces Developer Tools/imsg/auto-respond.sh
|
|
3
|
-
*
|
|
4
|
-
* Pipes `imsg watch --json` -> agent API (SSE) -> `imsg send`
|
|
5
|
-
* Uses CLI auth (getValidToken) instead of separate SERVICE_KEY_FILE.
|
|
6
|
-
*/
|
|
7
|
-
export { listChats, listMessages, getDaemonStatus, stopDaemon } from "./imsg-watcher-helpers.js";
|
|
8
|
-
/**
|
|
9
|
-
* Start the watch daemon.
|
|
10
|
-
*/
|
|
11
|
-
export declare function startWatcher(): Promise<void>;
|
|
@@ -1,230 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* iMessage Watch Daemon — replaces Developer Tools/imsg/auto-respond.sh
|
|
3
|
-
*
|
|
4
|
-
* Pipes `imsg watch --json` -> agent API (SSE) -> `imsg send`
|
|
5
|
-
* Uses CLI auth (getValidToken) instead of separate SERVICE_KEY_FILE.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import { spawn } from "node:child_process";
|
|
9
|
-
import { writeFileSync, unlinkSync } from "node:fs";
|
|
10
|
-
import { loadImsgConfig } from "./imsg-config.js";
|
|
11
|
-
import { getValidToken } from "../services/auth-service.js";
|
|
12
|
-
import { loadConfig } from "../services/config-store.js";
|
|
13
|
-
import { IMSG_BIN, PID_FILE, log, getAgentResponse, logMessage } from "./imsg-watcher-helpers.js";
|
|
14
|
-
|
|
15
|
-
// Re-export public API consumed by imsg.ts
|
|
16
|
-
export { listChats, listMessages, getDaemonStatus, stopDaemon } from "./imsg-watcher-helpers.js";
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Start the watch daemon.
|
|
20
|
-
*/
|
|
21
|
-
export async function startWatcher() {
|
|
22
|
-
// Auth
|
|
23
|
-
const tokenOrNull = await getValidToken();
|
|
24
|
-
if (!tokenOrNull) {
|
|
25
|
-
console.error("Not logged in. Run: whale login");
|
|
26
|
-
process.exit(1);
|
|
27
|
-
return;
|
|
28
|
-
}
|
|
29
|
-
const token = tokenOrNull;
|
|
30
|
-
const whaleConfig = loadConfig();
|
|
31
|
-
if (!whaleConfig.store_id) {
|
|
32
|
-
console.error("No store selected. Run: whale stores");
|
|
33
|
-
process.exit(1);
|
|
34
|
-
return;
|
|
35
|
-
}
|
|
36
|
-
const storeId = whaleConfig.store_id;
|
|
37
|
-
|
|
38
|
-
// Load iMessage config
|
|
39
|
-
let imsgConfig = loadImsgConfig();
|
|
40
|
-
const resolvedAgent = imsgConfig.default_agent || whaleConfig.default_agent_id;
|
|
41
|
-
if (!resolvedAgent) {
|
|
42
|
-
console.error("No default agent configured.");
|
|
43
|
-
console.error("Set one in ~/.whaletools/imsg-conversations.json or run: whale config --agent <id>");
|
|
44
|
-
process.exit(1);
|
|
45
|
-
return;
|
|
46
|
-
}
|
|
47
|
-
const defaultAgent = resolvedAgent;
|
|
48
|
-
|
|
49
|
-
// Write PID file
|
|
50
|
-
writeFileSync(PID_FILE, String(process.pid));
|
|
51
|
-
const stats = {
|
|
52
|
-
started_at: new Date().toISOString(),
|
|
53
|
-
messages_in: 0,
|
|
54
|
-
messages_out: 0,
|
|
55
|
-
errors: 0
|
|
56
|
-
};
|
|
57
|
-
log("=== iMessage Auto-Responder (whale imsg watch) ===");
|
|
58
|
-
log(`PID: ${process.pid}`);
|
|
59
|
-
log(`Agent: ${defaultAgent.slice(0, 8)}...`);
|
|
60
|
-
log(`Store: ${storeId.slice(0, 8)}...`);
|
|
61
|
-
log(`Binary: ${IMSG_BIN}`);
|
|
62
|
-
log("");
|
|
63
|
-
|
|
64
|
-
// Spawn imsg watch
|
|
65
|
-
const child = spawn(IMSG_BIN, ["watch", "--json", "--interval", "2"], {
|
|
66
|
-
stdio: ["ignore", "pipe", "pipe"]
|
|
67
|
-
});
|
|
68
|
-
let messageCounter = 0;
|
|
69
|
-
let currentToken = token;
|
|
70
|
-
let lastTokenRefresh = Date.now();
|
|
71
|
-
let restartAttempts = 0;
|
|
72
|
-
const MAX_RESTARTS = 5;
|
|
73
|
-
const TOKEN_REFRESH_INTERVAL_MS = 45 * 60 * 1000; // 45 minutes
|
|
74
|
-
|
|
75
|
-
// Reload config periodically
|
|
76
|
-
const reloadConfig = () => {
|
|
77
|
-
imsgConfig = loadImsgConfig();
|
|
78
|
-
log("Reloaded config");
|
|
79
|
-
};
|
|
80
|
-
|
|
81
|
-
// SIGHUP -> reload config
|
|
82
|
-
process.on("SIGHUP", reloadConfig);
|
|
83
|
-
|
|
84
|
-
// Clean shutdown
|
|
85
|
-
const shutdown = () => {
|
|
86
|
-
log("Shutting down...");
|
|
87
|
-
child.kill("SIGTERM");
|
|
88
|
-
try {
|
|
89
|
-
unlinkSync(PID_FILE);
|
|
90
|
-
} catch {/* ignore */}
|
|
91
|
-
log(`Stats: ${stats.messages_in} in, ${stats.messages_out} out, ${stats.errors} errors`);
|
|
92
|
-
process.exit(0);
|
|
93
|
-
};
|
|
94
|
-
process.on("SIGINT", shutdown);
|
|
95
|
-
process.on("SIGTERM", shutdown);
|
|
96
|
-
|
|
97
|
-
// Process stdout line-by-line
|
|
98
|
-
let buffer = "";
|
|
99
|
-
child.stdout?.on("data", chunk => {
|
|
100
|
-
buffer += chunk.toString();
|
|
101
|
-
const lines = buffer.split("\n");
|
|
102
|
-
buffer = lines.pop() || "";
|
|
103
|
-
restartAttempts = 0;
|
|
104
|
-
for (const line of lines) {
|
|
105
|
-
if (!line.trim()) continue;
|
|
106
|
-
handleLine(line).catch(err => {
|
|
107
|
-
log(`Error handling message: ${err instanceof Error ? err.message : err}`);
|
|
108
|
-
stats.errors++;
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
});
|
|
112
|
-
child.stderr?.on("data", chunk => {
|
|
113
|
-
const msg = chunk.toString().trim();
|
|
114
|
-
if (msg) log(`[imsg] ${msg}`);
|
|
115
|
-
});
|
|
116
|
-
child.on("exit", (code, signal) => {
|
|
117
|
-
if (signal === "SIGTERM" || signal === "SIGINT") {
|
|
118
|
-
try {
|
|
119
|
-
unlinkSync(PID_FILE);
|
|
120
|
-
} catch {/* ignore */}
|
|
121
|
-
process.exit(0);
|
|
122
|
-
return;
|
|
123
|
-
}
|
|
124
|
-
log(`imsg watch exited (code=${code}, signal=${signal})`);
|
|
125
|
-
restartAttempts++;
|
|
126
|
-
if (restartAttempts > MAX_RESTARTS) {
|
|
127
|
-
log(`Max restart attempts (${MAX_RESTARTS}) reached. Giving up.`);
|
|
128
|
-
log("Possible causes: Full Disk Access not granted, imsg binary not properly signed.");
|
|
129
|
-
log("Fix: System Settings > Privacy & Security > Full Disk Access > add your terminal");
|
|
130
|
-
log("Fix: codesign --force --sign - /opt/homebrew/bin/imsg");
|
|
131
|
-
try {
|
|
132
|
-
unlinkSync(PID_FILE);
|
|
133
|
-
} catch {/* ignore */}
|
|
134
|
-
process.exit(1);
|
|
135
|
-
return;
|
|
136
|
-
}
|
|
137
|
-
const delay = Math.min(5000 * Math.pow(2, restartAttempts - 1), 80000);
|
|
138
|
-
log(`Restarting in ${delay / 1000}s (attempt ${restartAttempts}/${MAX_RESTARTS})...`);
|
|
139
|
-
setTimeout(() => {
|
|
140
|
-
startWatcher().catch(err => {
|
|
141
|
-
log(`Restart failed: ${err instanceof Error ? err.message : err}`);
|
|
142
|
-
try {
|
|
143
|
-
unlinkSync(PID_FILE);
|
|
144
|
-
} catch {/* ignore */}
|
|
145
|
-
process.exit(1);
|
|
146
|
-
});
|
|
147
|
-
}, delay);
|
|
148
|
-
});
|
|
149
|
-
async function handleLine(line) {
|
|
150
|
-
let data;
|
|
151
|
-
try {
|
|
152
|
-
data = JSON.parse(line);
|
|
153
|
-
} catch {
|
|
154
|
-
return;
|
|
155
|
-
}
|
|
156
|
-
const sender = data.sender || "";
|
|
157
|
-
const senderName = data.sender_name || "";
|
|
158
|
-
const text = data.text || "";
|
|
159
|
-
const chatId = data.chat_id || 0;
|
|
160
|
-
const isGroup = data.is_group || false;
|
|
161
|
-
const groupName = data.group_name || data.display_name || "";
|
|
162
|
-
const members = data.members || [];
|
|
163
|
-
const chatIdentifier = data.chat_identifier || data.identifier || "";
|
|
164
|
-
const attachments = data.attachments || [];
|
|
165
|
-
if (!text) return;
|
|
166
|
-
messageCounter++;
|
|
167
|
-
if (messageCounter % 30 === 0) reloadConfig();
|
|
168
|
-
|
|
169
|
-
// Time-based token refresh (every 45 min, well before 1h JWT expiry)
|
|
170
|
-
if (Date.now() - lastTokenRefresh > TOKEN_REFRESH_INTERVAL_MS) {
|
|
171
|
-
const refreshed = await getValidToken();
|
|
172
|
-
if (refreshed) {
|
|
173
|
-
currentToken = refreshed;
|
|
174
|
-
lastTokenRefresh = Date.now();
|
|
175
|
-
log("Token refreshed");
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
const convId = sender;
|
|
179
|
-
const contactConfig = imsgConfig.conversations[sender];
|
|
180
|
-
if (contactConfig && contactConfig.allowed === false) {
|
|
181
|
-
log(` SKIP (blocked): ${sender}`);
|
|
182
|
-
return;
|
|
183
|
-
}
|
|
184
|
-
if (!contactConfig && Object.keys(imsgConfig.conversations).length > 0) {
|
|
185
|
-
log(` SKIP (unknown): ${sender}`);
|
|
186
|
-
return;
|
|
187
|
-
}
|
|
188
|
-
const activeAgent = contactConfig?.agent_id || defaultAgent;
|
|
189
|
-
const systemPrompt = contactConfig?.system_prompt || null;
|
|
190
|
-
const metadata = {};
|
|
191
|
-
if (isGroup) {
|
|
192
|
-
metadata.is_group = true;
|
|
193
|
-
metadata.group_name = groupName;
|
|
194
|
-
metadata.members = members;
|
|
195
|
-
metadata.chat_identifier = chatIdentifier;
|
|
196
|
-
log(`>> ${sender} in group ${groupName || chatIdentifier}: ${text}`);
|
|
197
|
-
} else {
|
|
198
|
-
log(`>> ${sender} (${senderName}): ${text}`);
|
|
199
|
-
}
|
|
200
|
-
if (attachments.length > 0) {
|
|
201
|
-
metadata.attachments = attachments;
|
|
202
|
-
log(` ${attachments.length} attachment(s)`);
|
|
203
|
-
}
|
|
204
|
-
stats.messages_in++;
|
|
205
|
-
logMessage("inbound", text, sender, convId, currentToken, storeId, senderName, metadata);
|
|
206
|
-
log(` Thinking... (agent=${activeAgent.slice(0, 8)}...${systemPrompt ? ` prompt=${systemPrompt.slice(0, 40)}` : ""})`);
|
|
207
|
-
const aiReply = await getAgentResponse(text, convId, activeAgent, storeId, currentToken, systemPrompt);
|
|
208
|
-
if (!aiReply) {
|
|
209
|
-
log(" ERROR: Empty AI response");
|
|
210
|
-
stats.errors++;
|
|
211
|
-
return;
|
|
212
|
-
}
|
|
213
|
-
log(`<< Reply (${aiReply.length} chars): ${aiReply.slice(0, 120)}...`);
|
|
214
|
-
const sendArgs = isGroup ? ["send", "--chat-id", String(chatId), "--text", aiReply] : ["send", "--to", sender, "--text", aiReply];
|
|
215
|
-
const sendProc = spawn(IMSG_BIN, sendArgs);
|
|
216
|
-
const sendOk = await new Promise(resolve => {
|
|
217
|
-
sendProc.on("exit", code => resolve(code === 0));
|
|
218
|
-
sendProc.on("error", () => resolve(false));
|
|
219
|
-
});
|
|
220
|
-
if (sendOk) {
|
|
221
|
-
log(" Sent OK");
|
|
222
|
-
stats.messages_out++;
|
|
223
|
-
} else {
|
|
224
|
-
log(" WARN: Send failed");
|
|
225
|
-
stats.errors++;
|
|
226
|
-
}
|
|
227
|
-
logMessage("outbound", aiReply, "whale-agent", convId, currentToken, storeId, "AI Agent", metadata);
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
//# sourceMappingURL=imsg-watcher.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"imsg-watcher.js","names":["spawn","writeFileSync","unlinkSync","loadImsgConfig","getValidToken","loadConfig","IMSG_BIN","PID_FILE","log","getAgentResponse","logMessage","listChats","listMessages","getDaemonStatus","stopDaemon","startWatcher","tokenOrNull","console","error","process","exit","token","whaleConfig","store_id","storeId","imsgConfig","resolvedAgent","default_agent","default_agent_id","defaultAgent","String","pid","stats","started_at","Date","toISOString","messages_in","messages_out","errors","slice","child","stdio","messageCounter","currentToken","lastTokenRefresh","now","restartAttempts","MAX_RESTARTS","TOKEN_REFRESH_INTERVAL_MS","reloadConfig","on","shutdown","kill","buffer","stdout","chunk","toString","lines","split","pop","line","trim","handleLine","catch","err","Error","message","stderr","msg","code","signal","delay","Math","min","pow","setTimeout","data","JSON","parse","sender","senderName","sender_name","text","chatId","chat_id","isGroup","is_group","groupName","group_name","display_name","members","chatIdentifier","chat_identifier","identifier","attachments","refreshed","convId","contactConfig","conversations","allowed","Object","keys","length","activeAgent","agent_id","systemPrompt","system_prompt","metadata","aiReply","sendArgs","sendProc","sendOk","Promise","resolve"],"sources":["../../../src/cli/commands/imsg-watcher.ts"],"sourcesContent":["/**\n * iMessage Watch Daemon — replaces Developer Tools/imsg/auto-respond.sh\n *\n * Pipes `imsg watch --json` -> agent API (SSE) -> `imsg send`\n * Uses CLI auth (getValidToken) instead of separate SERVICE_KEY_FILE.\n */\n\nimport { spawn, type ChildProcess } from \"node:child_process\";\nimport { writeFileSync, unlinkSync } from \"node:fs\";\nimport { loadImsgConfig, type ImsgConfig } from \"./imsg-config.js\";\nimport { getValidToken } from \"../services/auth-service.js\";\nimport { loadConfig } from \"../services/config-store.js\";\n\nimport {\n IMSG_BIN,\n PID_FILE,\n log,\n getAgentResponse,\n logMessage,\n type DaemonStats,\n} from \"./imsg-watcher-helpers.js\";\n\n// Re-export public API consumed by imsg.ts\nexport { listChats, listMessages, getDaemonStatus, stopDaemon } from \"./imsg-watcher-helpers.js\";\n\n/**\n * Start the watch daemon.\n */\nexport async function startWatcher(): Promise<void> {\n // Auth\n const tokenOrNull = await getValidToken();\n if (!tokenOrNull) {\n console.error(\"Not logged in. Run: whale login\");\n process.exit(1);\n return;\n }\n const token: string = tokenOrNull;\n\n const whaleConfig = loadConfig();\n if (!whaleConfig.store_id) {\n console.error(\"No store selected. Run: whale stores\");\n process.exit(1);\n return;\n }\n const storeId: string = whaleConfig.store_id;\n\n // Load iMessage config\n let imsgConfig = loadImsgConfig();\n const resolvedAgent = imsgConfig.default_agent || whaleConfig.default_agent_id;\n if (!resolvedAgent) {\n console.error(\"No default agent configured.\");\n console.error(\"Set one in ~/.whaletools/imsg-conversations.json or run: whale config --agent <id>\");\n process.exit(1);\n return;\n }\n const defaultAgent: string = resolvedAgent;\n\n // Write PID file\n writeFileSync(PID_FILE, String(process.pid));\n\n const stats: DaemonStats = {\n started_at: new Date().toISOString(),\n messages_in: 0,\n messages_out: 0,\n errors: 0,\n };\n\n log(\"=== iMessage Auto-Responder (whale imsg watch) ===\");\n log(`PID: ${process.pid}`);\n log(`Agent: ${defaultAgent.slice(0, 8)}...`);\n log(`Store: ${storeId.slice(0, 8)}...`);\n log(`Binary: ${IMSG_BIN}`);\n log(\"\");\n\n // Spawn imsg watch\n const child: ChildProcess = spawn(IMSG_BIN, [\"watch\", \"--json\", \"--interval\", \"2\"], {\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n });\n\n let messageCounter = 0;\n let currentToken = token;\n let lastTokenRefresh = Date.now();\n let restartAttempts = 0;\n const MAX_RESTARTS = 5;\n const TOKEN_REFRESH_INTERVAL_MS = 45 * 60 * 1000; // 45 minutes\n\n // Reload config periodically\n const reloadConfig = (): void => {\n imsgConfig = loadImsgConfig();\n log(\"Reloaded config\");\n };\n\n // SIGHUP -> reload config\n process.on(\"SIGHUP\", reloadConfig);\n\n // Clean shutdown\n const shutdown = (): void => {\n log(\"Shutting down...\");\n child.kill(\"SIGTERM\");\n try { unlinkSync(PID_FILE); } catch { /* ignore */ }\n log(`Stats: ${stats.messages_in} in, ${stats.messages_out} out, ${stats.errors} errors`);\n process.exit(0);\n };\n process.on(\"SIGINT\", shutdown);\n process.on(\"SIGTERM\", shutdown);\n\n // Process stdout line-by-line\n let buffer = \"\";\n child.stdout?.on(\"data\", (chunk: Buffer) => {\n buffer += chunk.toString();\n const lines = buffer.split(\"\\n\");\n buffer = lines.pop() || \"\";\n\n restartAttempts = 0;\n\n for (const line of lines) {\n if (!line.trim()) continue;\n handleLine(line).catch((err) => {\n log(`Error handling message: ${err instanceof Error ? err.message : err}`);\n stats.errors++;\n });\n }\n });\n\n child.stderr?.on(\"data\", (chunk: Buffer) => {\n const msg = chunk.toString().trim();\n if (msg) log(`[imsg] ${msg}`);\n });\n\n child.on(\"exit\", (code, signal) => {\n if (signal === \"SIGTERM\" || signal === \"SIGINT\") {\n try { unlinkSync(PID_FILE); } catch { /* ignore */ }\n process.exit(0);\n return;\n }\n\n log(`imsg watch exited (code=${code}, signal=${signal})`);\n\n restartAttempts++;\n if (restartAttempts > MAX_RESTARTS) {\n log(`Max restart attempts (${MAX_RESTARTS}) reached. Giving up.`);\n log(\"Possible causes: Full Disk Access not granted, imsg binary not properly signed.\");\n log(\"Fix: System Settings > Privacy & Security > Full Disk Access > add your terminal\");\n log(\"Fix: codesign --force --sign - /opt/homebrew/bin/imsg\");\n try { unlinkSync(PID_FILE); } catch { /* ignore */ }\n process.exit(1);\n return;\n }\n\n const delay = Math.min(5000 * Math.pow(2, restartAttempts - 1), 80000);\n log(`Restarting in ${delay / 1000}s (attempt ${restartAttempts}/${MAX_RESTARTS})...`);\n setTimeout(() => {\n startWatcher().catch((err) => {\n log(`Restart failed: ${err instanceof Error ? err.message : err}`);\n try { unlinkSync(PID_FILE); } catch { /* ignore */ }\n process.exit(1);\n });\n }, delay);\n });\n\n async function handleLine(line: string): Promise<void> {\n let data: any;\n try { data = JSON.parse(line); } catch { return; }\n\n const sender: string = data.sender || \"\";\n const senderName: string = data.sender_name || \"\";\n const text: string = data.text || \"\";\n const chatId: number = data.chat_id || 0;\n const isGroup: boolean = data.is_group || false;\n const groupName: string = data.group_name || data.display_name || \"\";\n const members: string[] = data.members || [];\n const chatIdentifier: string = data.chat_identifier || data.identifier || \"\";\n const attachments: string[] = data.attachments || [];\n\n if (!text) return;\n\n messageCounter++;\n if (messageCounter % 30 === 0) reloadConfig();\n\n // Time-based token refresh (every 45 min, well before 1h JWT expiry)\n if (Date.now() - lastTokenRefresh > TOKEN_REFRESH_INTERVAL_MS) {\n const refreshed = await getValidToken();\n if (refreshed) {\n currentToken = refreshed;\n lastTokenRefresh = Date.now();\n log(\"Token refreshed\");\n }\n }\n\n const convId = sender;\n\n const contactConfig = imsgConfig.conversations[sender];\n if (contactConfig && contactConfig.allowed === false) {\n log(` SKIP (blocked): ${sender}`);\n return;\n }\n\n if (!contactConfig && Object.keys(imsgConfig.conversations).length > 0) {\n log(` SKIP (unknown): ${sender}`);\n return;\n }\n\n const activeAgent: string = contactConfig?.agent_id || defaultAgent;\n const systemPrompt = contactConfig?.system_prompt || null;\n\n const metadata: Record<string, unknown> = {};\n if (isGroup) {\n metadata.is_group = true;\n metadata.group_name = groupName;\n metadata.members = members;\n metadata.chat_identifier = chatIdentifier;\n log(`>> ${sender} in group ${groupName || chatIdentifier}: ${text}`);\n } else {\n log(`>> ${sender} (${senderName}): ${text}`);\n }\n if (attachments.length > 0) {\n metadata.attachments = attachments;\n log(` ${attachments.length} attachment(s)`);\n }\n\n stats.messages_in++;\n\n logMessage(\"inbound\", text, sender, convId, currentToken, storeId, senderName, metadata);\n\n log(` Thinking... (agent=${activeAgent.slice(0, 8)}...${systemPrompt ? ` prompt=${systemPrompt.slice(0, 40)}` : \"\"})`);\n const aiReply = await getAgentResponse(text, convId, activeAgent, storeId, currentToken, systemPrompt);\n\n if (!aiReply) {\n log(\" ERROR: Empty AI response\");\n stats.errors++;\n return;\n }\n\n log(`<< Reply (${aiReply.length} chars): ${aiReply.slice(0, 120)}...`);\n\n const sendArgs = isGroup\n ? [\"send\", \"--chat-id\", String(chatId), \"--text\", aiReply]\n : [\"send\", \"--to\", sender, \"--text\", aiReply];\n\n const sendProc = spawn(IMSG_BIN, sendArgs);\n const sendOk = await new Promise<boolean>((resolve) => {\n sendProc.on(\"exit\", (code) => resolve(code === 0));\n sendProc.on(\"error\", () => resolve(false));\n });\n\n if (sendOk) {\n log(\" Sent OK\");\n stats.messages_out++;\n } else {\n log(\" WARN: Send failed\");\n stats.errors++;\n }\n\n logMessage(\"outbound\", aiReply, \"whale-agent\", convId, currentToken, storeId, \"AI Agent\", metadata);\n }\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,153 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
2
|
-
import { vol } from "memfs";
|
|
3
|
-
|
|
4
|
-
// ============================================================================
|
|
5
|
-
// Mocks
|
|
6
|
-
// ============================================================================
|
|
7
|
-
|
|
8
|
-
vi.mock("fs", async () => {
|
|
9
|
-
const memfs = await import("memfs");
|
|
10
|
-
return {
|
|
11
|
-
...memfs.fs,
|
|
12
|
-
default: memfs.fs
|
|
13
|
-
};
|
|
14
|
-
});
|
|
15
|
-
vi.mock("os", () => ({
|
|
16
|
-
homedir: () => "/home/testuser"
|
|
17
|
-
}));
|
|
18
|
-
import { loadAgentDefinitions, getAgentDefinition } from "../agent-definitions.js";
|
|
19
|
-
|
|
20
|
-
// ============================================================================
|
|
21
|
-
// Setup
|
|
22
|
-
// ============================================================================
|
|
23
|
-
|
|
24
|
-
const GLOBAL_DIR = "/home/testuser/.whale/agents";
|
|
25
|
-
beforeEach(() => {
|
|
26
|
-
vol.reset();
|
|
27
|
-
// Default cwd
|
|
28
|
-
vi.spyOn(process, "cwd").mockReturnValue("/tmp/project");
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
// ============================================================================
|
|
32
|
-
// loadAgentDefinitions
|
|
33
|
-
// ============================================================================
|
|
34
|
-
|
|
35
|
-
describe("loadAgentDefinitions", () => {
|
|
36
|
-
it("returns empty array when no agent dirs exist", () => {
|
|
37
|
-
expect(loadAgentDefinitions()).toEqual([]);
|
|
38
|
-
});
|
|
39
|
-
it("loads global agents from ~/.whale/agents/", () => {
|
|
40
|
-
vol.fromJSON({
|
|
41
|
-
[`${GLOBAL_DIR}/reviewer.md`]: "You are a code reviewer."
|
|
42
|
-
});
|
|
43
|
-
const agents = loadAgentDefinitions();
|
|
44
|
-
expect(agents.length).toBe(1);
|
|
45
|
-
expect(agents[0].name).toBe("reviewer");
|
|
46
|
-
expect(agents[0].prompt).toBe("You are a code reviewer.");
|
|
47
|
-
expect(agents[0].source).toBe("global");
|
|
48
|
-
});
|
|
49
|
-
it("loads local agents from .whale/agents/", () => {
|
|
50
|
-
vol.fromJSON({
|
|
51
|
-
"/tmp/project/.whale/agents/tester.md": "You are a test writer."
|
|
52
|
-
});
|
|
53
|
-
const agents = loadAgentDefinitions();
|
|
54
|
-
expect(agents.length).toBe(1);
|
|
55
|
-
expect(agents[0].name).toBe("tester");
|
|
56
|
-
expect(agents[0].source).toBe("local");
|
|
57
|
-
});
|
|
58
|
-
it("parses frontmatter description and tools", () => {
|
|
59
|
-
vol.fromJSON({
|
|
60
|
-
[`${GLOBAL_DIR}/security.md`]: `---
|
|
61
|
-
description: Reviews code for security issues
|
|
62
|
-
tools: read_file, glob, grep
|
|
63
|
-
---
|
|
64
|
-
You are a security agent.`
|
|
65
|
-
});
|
|
66
|
-
const agents = loadAgentDefinitions();
|
|
67
|
-
expect(agents[0].description).toBe("Reviews code for security issues");
|
|
68
|
-
expect(agents[0].tools).toEqual(["read_file", "glob", "grep"]);
|
|
69
|
-
expect(agents[0].prompt).toBe("You are a security agent.");
|
|
70
|
-
});
|
|
71
|
-
it("handles frontmatter without description or tools", () => {
|
|
72
|
-
vol.fromJSON({
|
|
73
|
-
[`${GLOBAL_DIR}/simple.md`]: `---
|
|
74
|
-
description: Simple agent
|
|
75
|
-
---
|
|
76
|
-
Do things.`
|
|
77
|
-
});
|
|
78
|
-
const agents = loadAgentDefinitions();
|
|
79
|
-
expect(agents[0].description).toBe("Simple agent");
|
|
80
|
-
expect(agents[0].tools).toBeUndefined();
|
|
81
|
-
});
|
|
82
|
-
it("handles files without frontmatter", () => {
|
|
83
|
-
vol.fromJSON({
|
|
84
|
-
[`${GLOBAL_DIR}/bare.md`]: "Just plain content."
|
|
85
|
-
});
|
|
86
|
-
const agents = loadAgentDefinitions();
|
|
87
|
-
expect(agents[0].prompt).toBe("Just plain content.");
|
|
88
|
-
expect(agents[0].description).toBeUndefined();
|
|
89
|
-
});
|
|
90
|
-
it("local agents override global agents with same name", () => {
|
|
91
|
-
vol.fromJSON({
|
|
92
|
-
[`${GLOBAL_DIR}/reviewer.md`]: "Global reviewer",
|
|
93
|
-
"/tmp/project/.whale/agents/reviewer.md": "Local reviewer"
|
|
94
|
-
});
|
|
95
|
-
const agents = loadAgentDefinitions();
|
|
96
|
-
expect(agents.length).toBe(1);
|
|
97
|
-
expect(agents[0].prompt).toBe("Local reviewer");
|
|
98
|
-
expect(agents[0].source).toBe("local");
|
|
99
|
-
});
|
|
100
|
-
it("merges global and local agents and sorts by name", () => {
|
|
101
|
-
vol.fromJSON({
|
|
102
|
-
[`${GLOBAL_DIR}/zebra.md`]: "Z agent",
|
|
103
|
-
[`${GLOBAL_DIR}/alpha.md`]: "A agent",
|
|
104
|
-
"/tmp/project/.whale/agents/middle.md": "M agent"
|
|
105
|
-
});
|
|
106
|
-
const agents = loadAgentDefinitions();
|
|
107
|
-
expect(agents.map(a => a.name)).toEqual(["alpha", "middle", "zebra"]);
|
|
108
|
-
});
|
|
109
|
-
it("only loads .md files", () => {
|
|
110
|
-
vol.fromJSON({
|
|
111
|
-
[`${GLOBAL_DIR}/valid.md`]: "Agent",
|
|
112
|
-
[`${GLOBAL_DIR}/invalid.txt`]: "Not an agent",
|
|
113
|
-
[`${GLOBAL_DIR}/also-invalid.json`]: "{}"
|
|
114
|
-
});
|
|
115
|
-
const agents = loadAgentDefinitions();
|
|
116
|
-
expect(agents.length).toBe(1);
|
|
117
|
-
expect(agents[0].name).toBe("valid");
|
|
118
|
-
});
|
|
119
|
-
it("handles broken frontmatter (no closing ---)", () => {
|
|
120
|
-
vol.fromJSON({
|
|
121
|
-
[`${GLOBAL_DIR}/broken.md`]: "---\ndescription: Broken\nSome content"
|
|
122
|
-
});
|
|
123
|
-
const agents = loadAgentDefinitions();
|
|
124
|
-
expect(agents[0].prompt).toBe("---\ndescription: Broken\nSome content");
|
|
125
|
-
});
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
// ============================================================================
|
|
129
|
-
// getAgentDefinition
|
|
130
|
-
// ============================================================================
|
|
131
|
-
|
|
132
|
-
describe("getAgentDefinition", () => {
|
|
133
|
-
it("returns agent by name", () => {
|
|
134
|
-
vol.fromJSON({
|
|
135
|
-
[`${GLOBAL_DIR}/reviewer.md`]: "Review code"
|
|
136
|
-
});
|
|
137
|
-
const agent = getAgentDefinition("reviewer");
|
|
138
|
-
expect(agent).toBeDefined();
|
|
139
|
-
expect(agent.name).toBe("reviewer");
|
|
140
|
-
});
|
|
141
|
-
it("returns undefined for non-existent agent", () => {
|
|
142
|
-
expect(getAgentDefinition("nonexistent")).toBeUndefined();
|
|
143
|
-
});
|
|
144
|
-
it("prefers local over global when both exist", () => {
|
|
145
|
-
vol.fromJSON({
|
|
146
|
-
[`${GLOBAL_DIR}/reviewer.md`]: "Global",
|
|
147
|
-
"/tmp/project/.whale/agents/reviewer.md": "Local"
|
|
148
|
-
});
|
|
149
|
-
const agent = getAgentDefinition("reviewer");
|
|
150
|
-
expect(agent.prompt).toBe("Local");
|
|
151
|
-
expect(agent.source).toBe("local");
|
|
152
|
-
});
|
|
153
|
-
});
|