@tenex-chat/backend 0.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (427) hide show
  1. package/README.md +194 -0
  2. package/dist/backend-wrapper.cjs +3 -0
  3. package/dist/src/index.js +331928 -0
  4. package/package.json +103 -0
  5. package/src/agents/AgentRegistry.ts +418 -0
  6. package/src/agents/AgentStorage.ts +1133 -0
  7. package/src/agents/ConfigResolver.ts +229 -0
  8. package/src/agents/agent-installer.ts +236 -0
  9. package/src/agents/agent-loader.ts +241 -0
  10. package/src/agents/constants.ts +82 -0
  11. package/src/agents/errors.ts +48 -0
  12. package/src/agents/execution/AgentExecutor.ts +561 -0
  13. package/src/agents/execution/ExecutionContextFactory.ts +112 -0
  14. package/src/agents/execution/MessageCompiler.ts +597 -0
  15. package/src/agents/execution/MessageSyncer.ts +100 -0
  16. package/src/agents/execution/PostCompletionChecker.ts +278 -0
  17. package/src/agents/execution/ProgressMonitor.ts +50 -0
  18. package/src/agents/execution/RALResolver.ts +177 -0
  19. package/src/agents/execution/SessionManager.ts +181 -0
  20. package/src/agents/execution/StreamCallbacks.ts +312 -0
  21. package/src/agents/execution/StreamExecutionHandler.ts +579 -0
  22. package/src/agents/execution/StreamSetup.ts +313 -0
  23. package/src/agents/execution/ToolEventHandlers.ts +239 -0
  24. package/src/agents/execution/ToolExecutionTracker.ts +498 -0
  25. package/src/agents/execution/ToolResultUtils.ts +97 -0
  26. package/src/agents/execution/ToolSupervisionWrapper.ts +174 -0
  27. package/src/agents/execution/constants.ts +16 -0
  28. package/src/agents/execution/index.ts +3 -0
  29. package/src/agents/execution/types.ts +96 -0
  30. package/src/agents/execution/utils.ts +26 -0
  31. package/src/agents/index.ts +4 -0
  32. package/src/agents/script-installer.ts +266 -0
  33. package/src/agents/supervision/SupervisorLLMService.ts +253 -0
  34. package/src/agents/supervision/SupervisorOrchestrator.ts +471 -0
  35. package/src/agents/supervision/heuristics/ConsecutiveToolsWithoutTodoHeuristic.ts +73 -0
  36. package/src/agents/supervision/heuristics/DelegationClaimHeuristic.ts +80 -0
  37. package/src/agents/supervision/heuristics/HeuristicRegistry.ts +114 -0
  38. package/src/agents/supervision/heuristics/PendingTodosHeuristic.ts +93 -0
  39. package/src/agents/supervision/heuristics/SilentAgentHeuristic.ts +54 -0
  40. package/src/agents/supervision/heuristics/index.ts +5 -0
  41. package/src/agents/supervision/index.ts +28 -0
  42. package/src/agents/supervision/registerHeuristics.ts +110 -0
  43. package/src/agents/supervision/supervisionHealthCheck.ts +123 -0
  44. package/src/agents/supervision/types.ts +171 -0
  45. package/src/agents/tool-names.ts +46 -0
  46. package/src/agents/tool-normalization.ts +184 -0
  47. package/src/agents/types/index.ts +2 -0
  48. package/src/agents/types/runtime.ts +74 -0
  49. package/src/agents/types/storage.ts +145 -0
  50. package/src/commands/agent/import/index.ts +6 -0
  51. package/src/commands/agent/import/openclaw-distiller.ts +57 -0
  52. package/src/commands/agent/import/openclaw-reader.ts +141 -0
  53. package/src/commands/agent/import/openclaw.ts +154 -0
  54. package/src/commands/agent/index.ts +6 -0
  55. package/src/commands/agent.ts +215 -0
  56. package/src/commands/daemon.ts +198 -0
  57. package/src/commands/doctor.ts +134 -0
  58. package/src/commands/setup/embed.ts +228 -0
  59. package/src/commands/setup/global-system-prompt.ts +223 -0
  60. package/src/commands/setup/image.ts +179 -0
  61. package/src/commands/setup/index.ts +16 -0
  62. package/src/commands/setup/interactive.ts +95 -0
  63. package/src/commands/setup/llm.ts +38 -0
  64. package/src/commands/setup/onboarding.ts +294 -0
  65. package/src/commands/setup/providers.ts +27 -0
  66. package/src/constants.ts +34 -0
  67. package/src/conversations/ConversationDiskReader.ts +148 -0
  68. package/src/conversations/ConversationRegistry.ts +728 -0
  69. package/src/conversations/ConversationStore.ts +868 -0
  70. package/src/conversations/MessageBuilder.ts +866 -0
  71. package/src/conversations/executionTime.ts +62 -0
  72. package/src/conversations/formatters/DelegationXmlFormatter.ts +64 -0
  73. package/src/conversations/formatters/ThreadedConversationFormatter.ts +303 -0
  74. package/src/conversations/formatters/index.ts +9 -0
  75. package/src/conversations/formatters/utils/MessageFormatter.ts +46 -0
  76. package/src/conversations/formatters/utils/TimestampFormatter.ts +56 -0
  77. package/src/conversations/formatters/utils/TreeBuilder.ts +131 -0
  78. package/src/conversations/formatters/utils/TreeRenderer.ts +49 -0
  79. package/src/conversations/index.ts +2 -0
  80. package/src/conversations/persistence/ToolMessageStorage.ts +143 -0
  81. package/src/conversations/search/ConversationIndexManager.ts +393 -0
  82. package/src/conversations/search/QueryParser.ts +114 -0
  83. package/src/conversations/search/SearchEngine.ts +175 -0
  84. package/src/conversations/search/SnippetExtractor.ts +345 -0
  85. package/src/conversations/search/embeddings/ConversationEmbeddingService.ts +484 -0
  86. package/src/conversations/search/embeddings/ConversationIndexingJob.ts +320 -0
  87. package/src/conversations/search/embeddings/IndexingStateManager.ts +338 -0
  88. package/src/conversations/search/embeddings/index.ts +18 -0
  89. package/src/conversations/search/index.ts +49 -0
  90. package/src/conversations/search/types.ts +124 -0
  91. package/src/conversations/services/CategoryManager.ts +160 -0
  92. package/src/conversations/services/ConversationResolver.ts +296 -0
  93. package/src/conversations/services/ConversationSummarizer.ts +234 -0
  94. package/src/conversations/services/MetadataDebounceManager.ts +188 -0
  95. package/src/conversations/services/index.ts +2 -0
  96. package/src/conversations/types.ts +148 -0
  97. package/src/conversations/utils/content-utils.ts +69 -0
  98. package/src/conversations/utils/image-placeholder.ts +281 -0
  99. package/src/conversations/utils/image-url-utils.ts +171 -0
  100. package/src/conversations/utils/multimodal-content.ts +90 -0
  101. package/src/conversations/utils/tool-result-truncator.ts +159 -0
  102. package/src/daemon/Daemon.ts +1883 -0
  103. package/src/daemon/ProjectRuntime.ts +657 -0
  104. package/src/daemon/RestartState.ts +152 -0
  105. package/src/daemon/RuntimeLifecycle.ts +268 -0
  106. package/src/daemon/SubscriptionManager.ts +305 -0
  107. package/src/daemon/UnixSocketTransport.ts +318 -0
  108. package/src/daemon/filters/SubscriptionFilterBuilder.ts +119 -0
  109. package/src/daemon/index.ts +9 -0
  110. package/src/daemon/routing/DaemonRouter.ts +491 -0
  111. package/src/daemon/types.ts +150 -0
  112. package/src/daemon/utils/routing-log.ts +76 -0
  113. package/src/daemon/utils/telemetry.ts +173 -0
  114. package/src/event-handler/agentDeletion.ts +383 -0
  115. package/src/event-handler/index.ts +749 -0
  116. package/src/event-handler/newConversation.ts +165 -0
  117. package/src/event-handler/project.ts +166 -0
  118. package/src/event-handler/reply.ts +18 -0
  119. package/src/events/NDKAgentDefinition.ts +292 -0
  120. package/src/events/NDKAgentLesson.ts +106 -0
  121. package/src/events/NDKEventMetadata.ts +34 -0
  122. package/src/events/NDKMCPTool.ts +60 -0
  123. package/src/events/NDKProjectStatus.ts +384 -0
  124. package/src/events/index.ts +4 -0
  125. package/src/index.ts +126 -0
  126. package/src/lib/agent-home.ts +334 -0
  127. package/src/lib/error-formatter.ts +200 -0
  128. package/src/lib/fs/filesystem.ts +128 -0
  129. package/src/lib/fs/index.ts +1 -0
  130. package/src/lib/json-parser.ts +30 -0
  131. package/src/lib/string.ts +15 -0
  132. package/src/lib/time.ts +74 -0
  133. package/src/llm/ChunkHandler.ts +277 -0
  134. package/src/llm/FinishHandler.ts +250 -0
  135. package/src/llm/LLMConfigEditor.ts +154 -0
  136. package/src/llm/LLMServiceFactory.ts +230 -0
  137. package/src/llm/MessageProcessor.ts +90 -0
  138. package/src/llm/RecordingState.ts +37 -0
  139. package/src/llm/StreamPublisher.ts +40 -0
  140. package/src/llm/TracingUtils.ts +77 -0
  141. package/src/llm/chunk-validators.ts +57 -0
  142. package/src/llm/constants.ts +6 -0
  143. package/src/llm/index.ts +12 -0
  144. package/src/llm/meta/MetaModelResolver.ts +352 -0
  145. package/src/llm/meta/index.ts +11 -0
  146. package/src/llm/middleware/flight-recorder.ts +188 -0
  147. package/src/llm/providers/MockProvider.ts +332 -0
  148. package/src/llm/providers/agent/ClaudeCodeProvider.ts +343 -0
  149. package/src/llm/providers/agent/ClaudeCodeToolsAdapter.ts +203 -0
  150. package/src/llm/providers/agent/CodexAppServerProvider.ts +214 -0
  151. package/src/llm/providers/agent/CodexAppServerToolsAdapter.ts +91 -0
  152. package/src/llm/providers/agent/index.ts +10 -0
  153. package/src/llm/providers/base/AgentProvider.ts +107 -0
  154. package/src/llm/providers/base/BaseProvider.ts +114 -0
  155. package/src/llm/providers/base/StandardProvider.ts +38 -0
  156. package/src/llm/providers/base/index.ts +9 -0
  157. package/src/llm/providers/index.ts +106 -0
  158. package/src/llm/providers/key-manager.ts +238 -0
  159. package/src/llm/providers/ollama-models.ts +105 -0
  160. package/src/llm/providers/openrouter-models.ts +102 -0
  161. package/src/llm/providers/provider-ids.ts +18 -0
  162. package/src/llm/providers/registry/ProviderRegistry.ts +414 -0
  163. package/src/llm/providers/registry/index.ts +7 -0
  164. package/src/llm/providers/standard/AnthropicProvider.ts +71 -0
  165. package/src/llm/providers/standard/OllamaProvider.ts +59 -0
  166. package/src/llm/providers/standard/OpenAIProvider.ts +44 -0
  167. package/src/llm/providers/standard/OpenRouterProvider.ts +103 -0
  168. package/src/llm/providers/standard/index.ts +10 -0
  169. package/src/llm/providers/types.ts +194 -0
  170. package/src/llm/providers/usage-metadata.ts +78 -0
  171. package/src/llm/service.ts +713 -0
  172. package/src/llm/types.ts +167 -0
  173. package/src/llm/utils/ConfigurationManager.ts +650 -0
  174. package/src/llm/utils/ConfigurationTester.ts +229 -0
  175. package/src/llm/utils/ModelSelector.ts +212 -0
  176. package/src/llm/utils/ProviderConfigUI.ts +177 -0
  177. package/src/llm/utils/claudeCodePromptCompiler.ts +141 -0
  178. package/src/llm/utils/codex-models.ts +53 -0
  179. package/src/llm/utils/context-window-cache.ts +30 -0
  180. package/src/llm/utils/models-dev-cache.ts +267 -0
  181. package/src/llm/utils/provider-setup.ts +50 -0
  182. package/src/llm/utils/tool-errors.ts +78 -0
  183. package/src/llm/utils/usage.ts +74 -0
  184. package/src/logging/EventRoutingLogger.ts +205 -0
  185. package/src/nostr/AgentEventDecoder.ts +357 -0
  186. package/src/nostr/AgentEventEncoder.ts +677 -0
  187. package/src/nostr/AgentProfilePublisher.ts +657 -0
  188. package/src/nostr/AgentPublisher.ts +437 -0
  189. package/src/nostr/BlossomService.ts +226 -0
  190. package/src/nostr/InterventionPublisher.ts +132 -0
  191. package/src/nostr/TagExtractor.ts +228 -0
  192. package/src/nostr/collectEvents.ts +83 -0
  193. package/src/nostr/constants.ts +38 -0
  194. package/src/nostr/encryption.ts +26 -0
  195. package/src/nostr/index.ts +31 -0
  196. package/src/nostr/keys.ts +17 -0
  197. package/src/nostr/kinds.ts +37 -0
  198. package/src/nostr/ndkClient.ts +72 -0
  199. package/src/nostr/relays.ts +43 -0
  200. package/src/nostr/trace-context.ts +39 -0
  201. package/src/nostr/types.ts +227 -0
  202. package/src/nostr/utils.ts +84 -0
  203. package/src/prompts/core/FragmentRegistry.ts +30 -0
  204. package/src/prompts/core/PromptBuilder.ts +98 -0
  205. package/src/prompts/core/index.ts +3 -0
  206. package/src/prompts/core/types.ts +13 -0
  207. package/src/prompts/fragments/00-global-system-prompt.ts +44 -0
  208. package/src/prompts/fragments/01-agent-identity.ts +69 -0
  209. package/src/prompts/fragments/02-agent-home-directory.ts +114 -0
  210. package/src/prompts/fragments/03-system-reminders-explanation.ts +14 -0
  211. package/src/prompts/fragments/04-relay-configuration.ts +38 -0
  212. package/src/prompts/fragments/05-delegation-chain.ts +45 -0
  213. package/src/prompts/fragments/06-agent-todos.ts +74 -0
  214. package/src/prompts/fragments/06-todo-usage-guidance.ts +34 -0
  215. package/src/prompts/fragments/07-meta-project-context.ts +234 -0
  216. package/src/prompts/fragments/08-active-conversations.ts +382 -0
  217. package/src/prompts/fragments/09-recent-conversations.ts +153 -0
  218. package/src/prompts/fragments/10-referenced-article.ts +21 -0
  219. package/src/prompts/fragments/11-nudges.ts +134 -0
  220. package/src/prompts/fragments/12-skills.ts +127 -0
  221. package/src/prompts/fragments/13-available-nudges.ts +122 -0
  222. package/src/prompts/fragments/15-available-agents.ts +53 -0
  223. package/src/prompts/fragments/16-stay-in-your-lane.ts +41 -0
  224. package/src/prompts/fragments/17-todo-before-delegation.ts +39 -0
  225. package/src/prompts/fragments/20-voice-mode.ts +62 -0
  226. package/src/prompts/fragments/22-scheduled-tasks.ts +175 -0
  227. package/src/prompts/fragments/24-retrieved-lessons.ts +26 -0
  228. package/src/prompts/fragments/25-rag-instructions.ts +333 -0
  229. package/src/prompts/fragments/26-mcp-resources.ts +237 -0
  230. package/src/prompts/fragments/27-memorized-reports.ts +77 -0
  231. package/src/prompts/fragments/28-agent-directed-monitoring.ts +32 -0
  232. package/src/prompts/fragments/29-rag-collections.ts +50 -0
  233. package/src/prompts/fragments/30-worktree-context.ts +98 -0
  234. package/src/prompts/fragments/31-agents-md-guidance.ts +96 -0
  235. package/src/prompts/fragments/32-process-metrics.ts +72 -0
  236. package/src/prompts/fragments/debug-mode.ts +48 -0
  237. package/src/prompts/fragments/delegation-completion.ts +44 -0
  238. package/src/prompts/fragments/index.ts +91 -0
  239. package/src/prompts/index.ts +21 -0
  240. package/src/prompts/utils/systemPromptBuilder.ts +777 -0
  241. package/src/scripts/migrate-prefix-index.ts +157 -0
  242. package/src/services/AgentDefinitionMonitor.ts +701 -0
  243. package/src/services/ConfigService.ts +723 -0
  244. package/src/services/CooldownRegistry.ts +199 -0
  245. package/src/services/LLMOperationsRegistry.ts +424 -0
  246. package/src/services/OwnerAgentListService.ts +354 -0
  247. package/src/services/PubkeyService.ts +308 -0
  248. package/src/services/agents/AgentMetadataStore.ts +72 -0
  249. package/src/services/agents/AgentResolution.ts +59 -0
  250. package/src/services/agents/EscalationService.ts +281 -0
  251. package/src/services/agents/NDKAgentDiscovery.ts +95 -0
  252. package/src/services/agents/index.ts +7 -0
  253. package/src/services/agents-md/AgentsMdService.ts +184 -0
  254. package/src/services/agents-md/SystemReminderInjector.ts +238 -0
  255. package/src/services/agents-md/index.ts +11 -0
  256. package/src/services/apns/APNsClient.ts +203 -0
  257. package/src/services/apns/APNsService.ts +358 -0
  258. package/src/services/apns/index.ts +11 -0
  259. package/src/services/apns/types.ts +80 -0
  260. package/src/services/compression/CompressionService.ts +445 -0
  261. package/src/services/compression/compression-schema.ts +28 -0
  262. package/src/services/compression/compression-types.ts +74 -0
  263. package/src/services/compression/compression-utils.ts +587 -0
  264. package/src/services/config/types.ts +394 -0
  265. package/src/services/dispatch/AgentDispatchService.ts +937 -0
  266. package/src/services/dispatch/AgentRouter.ts +181 -0
  267. package/src/services/dispatch/DelegationCompletionHandler.ts +232 -0
  268. package/src/services/embedding/EmbeddingProvider.ts +188 -0
  269. package/src/services/embedding/index.ts +5 -0
  270. package/src/services/event-context/EventContextService.ts +108 -0
  271. package/src/services/event-context/index.ts +2 -0
  272. package/src/services/heuristics/ContextBuilder.ts +106 -0
  273. package/src/services/heuristics/HeuristicEngine.ts +200 -0
  274. package/src/services/heuristics/formatters.ts +58 -0
  275. package/src/services/heuristics/index.ts +12 -0
  276. package/src/services/heuristics/rules/index.ts +25 -0
  277. package/src/services/heuristics/rules/todoBeforeDelegation.ts +69 -0
  278. package/src/services/heuristics/rules/todoReminderOnToolUse.ts +63 -0
  279. package/src/services/heuristics/types.ts +144 -0
  280. package/src/services/image/ImageGenerationService.ts +389 -0
  281. package/src/services/image/index.ts +12 -0
  282. package/src/services/intervention/InterventionService.ts +1352 -0
  283. package/src/services/intervention/index.ts +7 -0
  284. package/src/services/mcp/MCPManager.ts +683 -0
  285. package/src/services/mcp/McpNotificationDelivery.ts +139 -0
  286. package/src/services/mcp/McpSubscriptionService.ts +653 -0
  287. package/src/services/mcp/mcpInstaller.ts +130 -0
  288. package/src/services/nip46/Nip46SigningLog.ts +81 -0
  289. package/src/services/nip46/Nip46SigningService.ts +467 -0
  290. package/src/services/nip46/index.ts +4 -0
  291. package/src/services/nudge/NudgeService.ts +224 -0
  292. package/src/services/nudge/NudgeWhitelistService.ts +382 -0
  293. package/src/services/nudge/index.ts +5 -0
  294. package/src/services/nudge/types.ts +83 -0
  295. package/src/services/projects/ProjectContext.ts +672 -0
  296. package/src/services/projects/ProjectContextStore.ts +102 -0
  297. package/src/services/projects/index.ts +6 -0
  298. package/src/services/prompt-compiler/index.ts +15 -0
  299. package/src/services/prompt-compiler/prompt-compiler-service.ts +1143 -0
  300. package/src/services/pubkey-gate/PubkeyGateService.ts +93 -0
  301. package/src/services/pubkey-gate/index.ts +1 -0
  302. package/src/services/rag/EmbeddingProviderFactory.ts +292 -0
  303. package/src/services/rag/LanceDBMaintenanceService.ts +211 -0
  304. package/src/services/rag/RAGDatabaseService.ts +173 -0
  305. package/src/services/rag/RAGOperations.ts +682 -0
  306. package/src/services/rag/RAGService.ts +240 -0
  307. package/src/services/rag/RagSubscriptionService.ts +618 -0
  308. package/src/services/rag/rag-utils.ts +174 -0
  309. package/src/services/ral/PendingDelegationsRegistry.ts +168 -0
  310. package/src/services/ral/RALRegistry.ts +2782 -0
  311. package/src/services/ral/index.ts +4 -0
  312. package/src/services/ral/types.ts +292 -0
  313. package/src/services/reports/LocalReportStore.ts +380 -0
  314. package/src/services/reports/ReportEmbeddingService.ts +430 -0
  315. package/src/services/reports/ReportService.ts +440 -0
  316. package/src/services/reports/articleUtils.ts +52 -0
  317. package/src/services/reports/index.ts +7 -0
  318. package/src/services/scheduling/SchedulerService.ts +1057 -0
  319. package/src/services/scheduling/errors.ts +14 -0
  320. package/src/services/scheduling/index.ts +7 -0
  321. package/src/services/scheduling/utils.ts +77 -0
  322. package/src/services/search/SearchProviderRegistry.ts +78 -0
  323. package/src/services/search/UnifiedSearchService.ts +218 -0
  324. package/src/services/search/index.ts +47 -0
  325. package/src/services/search/projectFilter.ts +22 -0
  326. package/src/services/search/providers/ConversationSearchProvider.ts +48 -0
  327. package/src/services/search/providers/LessonSearchProvider.ts +75 -0
  328. package/src/services/search/providers/ReportSearchProvider.ts +49 -0
  329. package/src/services/search/types.ts +144 -0
  330. package/src/services/skill/SkillService.ts +482 -0
  331. package/src/services/skill/index.ts +2 -0
  332. package/src/services/skill/types.ts +70 -0
  333. package/src/services/status/OperationsStatusService.ts +276 -0
  334. package/src/services/status/ProjectStatusService.ts +522 -0
  335. package/src/services/status/index.ts +11 -0
  336. package/src/services/storage/PrefixKVStore.ts +242 -0
  337. package/src/services/storage/index.ts +1 -0
  338. package/src/services/system-reminder/SystemReminderUtils.ts +96 -0
  339. package/src/services/system-reminder/index.ts +7 -0
  340. package/src/services/trust-pubkeys/TrustPubkeyService.ts +325 -0
  341. package/src/services/trust-pubkeys/index.ts +2 -0
  342. package/src/telemetry/ConversationSpanManager.ts +111 -0
  343. package/src/telemetry/EventLoopMonitor.ts +206 -0
  344. package/src/telemetry/LLMSpanRegistry.ts +20 -0
  345. package/src/telemetry/NostrSpanProcessor.ts +89 -0
  346. package/src/telemetry/ToolCallSpanProcessor.ts +66 -0
  347. package/src/telemetry/diagnostics.ts +27 -0
  348. package/src/telemetry/setup.ts +120 -0
  349. package/src/tools/implementations/agents_discover.ts +121 -0
  350. package/src/tools/implementations/agents_hire.ts +127 -0
  351. package/src/tools/implementations/agents_list.ts +96 -0
  352. package/src/tools/implementations/agents_publish.ts +611 -0
  353. package/src/tools/implementations/agents_read.ts +173 -0
  354. package/src/tools/implementations/agents_write.ts +200 -0
  355. package/src/tools/implementations/ask.ts +411 -0
  356. package/src/tools/implementations/change_model.ts +141 -0
  357. package/src/tools/implementations/conversation_get.ts +661 -0
  358. package/src/tools/implementations/conversation_list.ts +377 -0
  359. package/src/tools/implementations/conversation_search.ts +370 -0
  360. package/src/tools/implementations/delegate.ts +327 -0
  361. package/src/tools/implementations/delegate_crossproject.ts +209 -0
  362. package/src/tools/implementations/delegate_followup.ts +300 -0
  363. package/src/tools/implementations/fs_edit.ts +162 -0
  364. package/src/tools/implementations/fs_glob.ts +182 -0
  365. package/src/tools/implementations/fs_grep.ts +513 -0
  366. package/src/tools/implementations/fs_read.ts +332 -0
  367. package/src/tools/implementations/fs_write.ts +113 -0
  368. package/src/tools/implementations/generate_image.ts +259 -0
  369. package/src/tools/implementations/home_fs.ts +515 -0
  370. package/src/tools/implementations/kill.ts +651 -0
  371. package/src/tools/implementations/learn.ts +166 -0
  372. package/src/tools/implementations/lesson-formatter.ts +38 -0
  373. package/src/tools/implementations/lesson_delete.ts +164 -0
  374. package/src/tools/implementations/lesson_get.ts +105 -0
  375. package/src/tools/implementations/lessons_list.ts +153 -0
  376. package/src/tools/implementations/mcp_resource_read.ts +161 -0
  377. package/src/tools/implementations/mcp_subscribe.ts +158 -0
  378. package/src/tools/implementations/mcp_subscription_stop.ts +85 -0
  379. package/src/tools/implementations/nostr_fetch.ts +149 -0
  380. package/src/tools/implementations/nostr_publish_as_user.ts +353 -0
  381. package/src/tools/implementations/project_list.ts +146 -0
  382. package/src/tools/implementations/rag_add_documents.ts +573 -0
  383. package/src/tools/implementations/rag_create_collection.ts +65 -0
  384. package/src/tools/implementations/rag_delete_collection.ts +68 -0
  385. package/src/tools/implementations/rag_list_collections.ts +77 -0
  386. package/src/tools/implementations/rag_query.ts +107 -0
  387. package/src/tools/implementations/rag_subscription_create.ts +105 -0
  388. package/src/tools/implementations/rag_subscription_delete.ts +80 -0
  389. package/src/tools/implementations/rag_subscription_get.ts +123 -0
  390. package/src/tools/implementations/rag_subscription_list.ts +128 -0
  391. package/src/tools/implementations/report_delete.ts +79 -0
  392. package/src/tools/implementations/report_read.ts +160 -0
  393. package/src/tools/implementations/report_write.ts +278 -0
  394. package/src/tools/implementations/reports_list.ts +77 -0
  395. package/src/tools/implementations/schedule_task.ts +104 -0
  396. package/src/tools/implementations/schedule_task_cancel.ts +62 -0
  397. package/src/tools/implementations/schedule_task_once.ts +128 -0
  398. package/src/tools/implementations/schedule_tasks_list.ts +79 -0
  399. package/src/tools/implementations/search.ts +160 -0
  400. package/src/tools/implementations/shell.ts +553 -0
  401. package/src/tools/implementations/todo.ts +260 -0
  402. package/src/tools/implementations/upload_blob.ts +381 -0
  403. package/src/tools/implementations/web_fetch.ts +153 -0
  404. package/src/tools/implementations/web_search.ts +250 -0
  405. package/src/tools/registry.ts +670 -0
  406. package/src/tools/types.ts +177 -0
  407. package/src/tools/utils.ts +256 -0
  408. package/src/types/event-ids.ts +320 -0
  409. package/src/types/index.ts +46 -0
  410. package/src/utils/agentFetcher.ts +107 -0
  411. package/src/utils/cli-error.ts +29 -0
  412. package/src/utils/conversation-id.ts +27 -0
  413. package/src/utils/conversation-utils.ts +1 -0
  414. package/src/utils/delegation-chain.ts +357 -0
  415. package/src/utils/error-handler.ts +42 -0
  416. package/src/utils/git/gitignore.ts +69 -0
  417. package/src/utils/git/index.ts +2 -0
  418. package/src/utils/git/initializeGitRepo.ts +204 -0
  419. package/src/utils/git/worktree.ts +260 -0
  420. package/src/utils/lessonFormatter.ts +70 -0
  421. package/src/utils/lessonTrust.ts +24 -0
  422. package/src/utils/lockfile.ts +123 -0
  423. package/src/utils/logger.ts +149 -0
  424. package/src/utils/nostr-entity-parser.ts +365 -0
  425. package/src/utils/process.ts +49 -0
  426. package/src/wrapper.ts +262 -0
  427. package/tsconfig.json +41 -0
@@ -0,0 +1,343 @@
1
+ /**
2
+ * Claude Code Provider
3
+ *
4
+ * Claude Code is a specialized agent-based provider that runs Claude
5
+ * with built-in coding tools and MCP server support.
6
+ */
7
+
8
+ import { type ClaudeCodeSettings, type McpServerConfig, createClaudeCode } from "ai-sdk-provider-claude-code";
9
+ import type { LanguageModelUsage } from "ai";
10
+ import { logger } from "@/utils/logger";
11
+ import { trace } from "@opentelemetry/api";
12
+ import type { LanguageModelUsageWithCostUsd } from "../../types";
13
+ import type {
14
+ ProviderInitConfig,
15
+ ProviderMetadata,
16
+ ProviderRuntimeContext,
17
+ } from "../types";
18
+ import { AgentProvider, type AgentProviderFunction } from "../base/AgentProvider";
19
+ import { ClaudeCodeToolsAdapter } from "./ClaudeCodeToolsAdapter";
20
+ import { PROVIDER_IDS } from "../provider-ids";
21
+
22
+ /**
23
+ * Claude Code-specific metadata structure
24
+ */
25
+ interface ClaudeCodeProviderMetadata {
26
+ costUsd?: number;
27
+ sessionId?: string;
28
+ durationMs?: number;
29
+ }
30
+
31
+ /**
32
+ * Mapping between Claude Code built-in tools and their TENEX/MCP equivalents.
33
+ * Used to determine which built-in tools to disable when TENEX provides alternatives.
34
+ */
35
+ interface ToolMapping {
36
+ tenex?: string;
37
+ mcpPatterns?: RegExp[];
38
+ }
39
+
40
+ /** Claude Code built-in tools and their TENEX/MCP equivalents.
41
+ * Note: Read is deliberately absent. Claude Code saves large MCP tool results
42
+ * to files and expects the model to use its built-in Read to access them.
43
+ * Disabling Read leaves agents unable to retrieve any large tool result. */
44
+ const TOOL_MAPPINGS: Readonly<Record<string, ToolMapping>> = {
45
+ // File system tools (Read excluded — see comment above)
46
+ Write: { tenex: "fs_write", mcpPatterns: [/^mcp__.*__fs_write$/, /^mcp__.*__write_file$/] },
47
+ Edit: { tenex: "fs_edit", mcpPatterns: [/^mcp__.*__fs_edit$/, /^mcp__.*__edit_file$/] },
48
+ Glob: { tenex: "fs_glob", mcpPatterns: [/^mcp__.*__fs_glob$/, /^mcp__.*__glob$/] },
49
+ Grep: { tenex: "fs_grep", mcpPatterns: [/^mcp__.*__fs_grep$/, /^mcp__.*__grep$/] },
50
+ LS: { tenex: "fs_glob", mcpPatterns: [/^mcp__.*__fs_glob$/, /^mcp__.*__list_directory$/] },
51
+ // Web tools
52
+ WebFetch: { tenex: "web_fetch", mcpPatterns: [/^mcp__.*__web_fetch$/, /^mcp__.*__fetch$/] },
53
+ WebSearch: { tenex: "web_search", mcpPatterns: [/^mcp__.*__web_search$/, /^mcp__.*__search$/] },
54
+ // Shell tools (Bash is controlled via TENEX's shell tool)
55
+ Bash: { tenex: "shell", mcpPatterns: [/^mcp__.*__shell$/, /^mcp__.*__bash$/, /^mcp__.*__execute$/] },
56
+ // Notebook tools
57
+ NotebookEdit: { tenex: undefined, mcpPatterns: [/^mcp__.*__notebook_edit$/] },
58
+ // Task/agent tools (TENEX uses delegate)
59
+ Task: { tenex: "delegate", mcpPatterns: [/^mcp__.*__delegate$/] },
60
+ // Todo tools (TENEX uses its own conversation-scoped todo_write)
61
+ TodoWrite: { tenex: "todo_write", mcpPatterns: [/^mcp__.*__todo_write$/, /^mcp__.*__write_todos$/] },
62
+ } as const;
63
+
64
+ /** File system tool names that indicate FS capability */
65
+ const FS_TOOL_NAMES = ["fs_read", "fs_write", "fs_edit", "fs_glob", "fs_grep"] as const;
66
+
67
+ /** Built-in tools that TENEX always controls — agents get these only via TENEX's equivalents.
68
+ * Read is excluded: Claude Code saves large MCP tool results to files and needs
69
+ * its built-in Read to let the model access them. */
70
+ const ALWAYS_DISABLED_BUILTINS = ["Write", "Edit", "Glob", "Grep", "LS", "NotebookEdit", "Bash", "TaskOutput"] as const;
71
+
72
+ /** Pattern to detect MCP tools that provide FS capability */
73
+ const MCP_FS_CAPABILITY_PATTERN = /mcp__.*__(fs_read|fs_write|fs_edit|fs_glob|fs_grep|read_file|write_file|edit_file|list_directory)/;
74
+
75
+ /**
76
+ * AI SDK usage with optional extended fields
77
+ */
78
+ interface ExtendedUsage extends LanguageModelUsage {
79
+ cachedInputTokens?: number;
80
+ reasoningTokens?: number;
81
+ }
82
+
83
+ type ClaudeCodeSettingsWithStreamStart = ClaudeCodeSettings & {
84
+ onStreamStart?: ProviderRuntimeContext["onStreamStart"];
85
+ };
86
+
87
+ /**
88
+ * Claude Code provider implementation
89
+ */
90
+ export class ClaudeCodeProvider extends AgentProvider {
91
+ static readonly METADATA: ProviderMetadata = AgentProvider.createMetadata(
92
+ PROVIDER_IDS.CLAUDE_CODE,
93
+ "Claude Code",
94
+ "Claude with built-in coding tools and MCP support",
95
+ "agent",
96
+ "claude-sonnet-4-20250514",
97
+ {
98
+ streaming: true,
99
+ toolCalling: true,
100
+ builtInTools: true,
101
+ sessionResumption: false,
102
+ requiresApiKey: false,
103
+ mcpSupport: true,
104
+ },
105
+ "https://docs.anthropic.com/en/docs/claude-code"
106
+ );
107
+
108
+ get metadata(): ProviderMetadata {
109
+ return ClaudeCodeProvider.METADATA;
110
+ }
111
+
112
+ /**
113
+ * Create the Claude Code provider function
114
+ */
115
+ protected createProviderFunction(_config: ProviderInitConfig): AgentProviderFunction {
116
+ // Return a function that creates providers with the right settings
117
+ // The actual settings are applied in createAgentSettings
118
+ return createClaudeCode({
119
+ defaultSettings: {},
120
+ }) as AgentProviderFunction;
121
+ }
122
+
123
+ /**
124
+ * Create the agent settings for Claude Code
125
+ */
126
+ protected createAgentSettings(
127
+ context: ProviderRuntimeContext,
128
+ _modelId: string
129
+ ): ClaudeCodeSettingsWithStreamStart {
130
+ // Extract tool names from the provided tools
131
+ const toolNames = context.tools ? Object.keys(context.tools) : [];
132
+ const regularTools = toolNames.filter((name) => !name.startsWith("mcp__"));
133
+ const mcpTools = toolNames.filter((name) => name.startsWith("mcp__"));
134
+
135
+ // Determine which built-in tools to disable based on TENEX configuration
136
+ const disallowedTools = this.computeDisallowedBuiltinTools(regularTools, mcpTools);
137
+
138
+ trace.getActiveSpan()?.addEvent("llm_factory.creating_claude_code", {
139
+ "agent.name": context.agentName ?? "",
140
+ "session.id": context.sessionId ?? "",
141
+ "tools.count": regularTools.length,
142
+ "mcp_tools.count": mcpTools.length,
143
+ "tenex_tools.enabled": true,
144
+ "cwd.from_context": context.workingDirectory ?? "(undefined)",
145
+ "disallowed_builtins": disallowedTools.join(", "),
146
+ });
147
+
148
+ // Create SDK MCP server for local TENEX tools
149
+ const tenexSdkServer =
150
+ regularTools.length > 0 && context.tools
151
+ ? ClaudeCodeToolsAdapter.createSdkMcpServer(context.tools)
152
+ : undefined;
153
+
154
+ // Build mcpServers configuration
155
+ const mcpServersConfig: Record<string, McpServerConfig> = {};
156
+
157
+ // Add TENEX tools wrapper if enabled
158
+ if (tenexSdkServer) {
159
+ mcpServersConfig.tenex = tenexSdkServer;
160
+ }
161
+
162
+ // Add MCP servers from context (passed from services layer)
163
+ const mcpConfig = context.mcpConfig;
164
+ if (mcpConfig?.enabled && mcpConfig.servers) {
165
+ for (const [serverName, serverConfig] of Object.entries(mcpConfig.servers)) {
166
+ mcpServersConfig[serverName] = {
167
+ type: "stdio" as const,
168
+ command: serverConfig.command,
169
+ args: serverConfig.args,
170
+ env: serverConfig.env,
171
+ };
172
+ }
173
+
174
+ trace.getActiveSpan()?.addEvent("llm_factory.mcp_servers_added", {
175
+ "mcp.server_count": Object.keys(mcpConfig.servers).length,
176
+ "mcp.servers": Object.keys(mcpConfig.servers).join(", "),
177
+ });
178
+ }
179
+
180
+ // Build the settings
181
+ const settings: ClaudeCodeSettingsWithStreamStart = {
182
+ permissionMode: "bypassPermissions",
183
+ verbose: true,
184
+ cwd: context.workingDirectory,
185
+ // Ensure Bash tool uses the project working directory, not the session's stored cwd
186
+ env: {
187
+ CLAUDE_BASH_MAINTAIN_PROJECT_WORKING_DIR: "1",
188
+ },
189
+ mcpServers: mcpServersConfig,
190
+ disallowedTools,
191
+ persistSession: false,
192
+ // Enable streaming input for mid-execution message injection
193
+ streamingInput: "always",
194
+ logger: {
195
+ warn: (message: string) => logger.warn("[ClaudeCode]", message),
196
+ error: (message: string) => logger.error("[ClaudeCode]", message),
197
+ info: (message: string) => logger.info("[ClaudeCode]", message),
198
+ debug: (message: string) => logger.debug("[ClaudeCode]", message),
199
+ },
200
+ };
201
+
202
+ // Pass through onStreamStart callback if provided
203
+ // The callback receives a MessageInjector when the stream starts, allowing mid-execution message injection
204
+ if (context.onStreamStart) {
205
+ settings.onStreamStart = context.onStreamStart;
206
+ }
207
+
208
+ return settings;
209
+ }
210
+
211
+ /**
212
+ * Compute which Claude Code built-in tools should be disabled.
213
+ *
214
+ * FS and shell built-in tools (Read, Write, Edit, Glob, Grep, LS,
215
+ * NotebookEdit, Bash) are ALWAYS disabled. TENEX controls filesystem
216
+ * and shell access exclusively through its fs_* and shell tools,
217
+ * provided conditionally based on agent configuration.
218
+ *
219
+ * Other built-in tools (WebFetch, etc.) are disabled when TENEX
220
+ * provides an equivalent.
221
+ */
222
+ private computeDisallowedBuiltinTools(regularTools: string[], mcpTools: string[]): string[] {
223
+ const { disallowed, hasAnyFsCapability } = this.computeDisallowedToolsCore(regularTools, mcpTools);
224
+
225
+ // Log the decision for debugging (separate from pure computation)
226
+ this.logDisallowedToolsDecision(disallowed, regularTools, hasAnyFsCapability);
227
+
228
+ return disallowed;
229
+ }
230
+
231
+ /**
232
+ * Pure computation of disallowed tools without side effects.
233
+ */
234
+ private computeDisallowedToolsCore(
235
+ regularTools: string[],
236
+ mcpTools: string[]
237
+ ): { disallowed: string[]; hasAnyFsCapability: boolean } {
238
+ // Always disallow AskUserQuestion - TENEX has its own ask tool
239
+ // Always disallow FS built-in tools — TENEX controls filesystem access
240
+ // exclusively through its fs_* tools. Agents get fs_* only when their
241
+ // tool configuration includes them.
242
+ const disallowed: string[] = ["AskUserQuestion", ...ALWAYS_DISABLED_BUILTINS];
243
+
244
+ const hasTenexFsTools = FS_TOOL_NAMES.some(tool => regularTools.includes(tool));
245
+ const hasMcpFsTools = mcpTools.some(tool => MCP_FS_CAPABILITY_PATTERN.test(tool));
246
+ const hasAnyFsCapability = hasTenexFsTools || hasMcpFsTools;
247
+
248
+ // Check each non-FS built-in tool and disable if TENEX/MCP provides equivalent
249
+ for (const [builtinTool, mapping] of Object.entries(TOOL_MAPPINGS)) {
250
+ if (disallowed.includes(builtinTool)) {
251
+ continue;
252
+ }
253
+
254
+ const hasEquivalent = this.hasToolEquivalent(mapping, regularTools, mcpTools);
255
+
256
+ if (hasEquivalent) {
257
+ disallowed.push(builtinTool);
258
+ }
259
+ }
260
+
261
+ return { disallowed, hasAnyFsCapability };
262
+ }
263
+
264
+ /**
265
+ * Check if TENEX or MCP provides an equivalent for a built-in tool.
266
+ */
267
+ private hasToolEquivalent(
268
+ mapping: ToolMapping,
269
+ regularTools: string[],
270
+ mcpTools: string[]
271
+ ): boolean {
272
+ // Check for TENEX tool equivalent
273
+ if (mapping.tenex && regularTools.includes(mapping.tenex)) {
274
+ return true;
275
+ }
276
+
277
+ // Check for MCP tool equivalent
278
+ if (mapping.mcpPatterns) {
279
+ for (const pattern of mapping.mcpPatterns) {
280
+ if (mcpTools.some(tool => pattern.test(tool))) {
281
+ return true;
282
+ }
283
+ }
284
+ }
285
+
286
+ return false;
287
+ }
288
+
289
+ /**
290
+ * Log the disallowed tools decision for debugging.
291
+ */
292
+ private logDisallowedToolsDecision(
293
+ disallowed: string[],
294
+ regularTools: string[],
295
+ hasAnyFsCapability: boolean
296
+ ): void {
297
+ const relevantTools = [...FS_TOOL_NAMES, "shell", "web_fetch", "web_search", "delegate", "todo_write"] as const;
298
+ logger.info("[ClaudeCodeProvider] Disabling built-in tools", {
299
+ disallowed,
300
+ tenexTools: regularTools.filter(t =>
301
+ (relevantTools as readonly string[]).includes(t)
302
+ ),
303
+ hasFsCapability: hasAnyFsCapability,
304
+ hasShell: regularTools.includes("shell"),
305
+ });
306
+ }
307
+
308
+ /**
309
+ * Claude Code is always available (no API key required)
310
+ */
311
+ isAvailable(): boolean {
312
+ return this._initialized;
313
+ }
314
+
315
+ /**
316
+ * Extract usage metadata from Claude Code provider response
317
+ */
318
+ static extractUsageMetadata(
319
+ model: string,
320
+ totalUsage: LanguageModelUsage | undefined,
321
+ providerMetadata: Record<string, unknown> | undefined
322
+ ): LanguageModelUsageWithCostUsd {
323
+ const metadata = providerMetadata?.[PROVIDER_IDS.CLAUDE_CODE] as ClaudeCodeProviderMetadata | undefined;
324
+ const extendedUsage = totalUsage as ExtendedUsage | undefined;
325
+
326
+ const inputTokens = totalUsage?.inputTokens;
327
+ const outputTokens = totalUsage?.outputTokens;
328
+ const totalTokens = totalUsage?.totalTokens ??
329
+ (inputTokens !== undefined && outputTokens !== undefined
330
+ ? inputTokens + outputTokens
331
+ : undefined);
332
+
333
+ return {
334
+ model,
335
+ inputTokens,
336
+ outputTokens,
337
+ totalTokens,
338
+ costUsd: metadata?.costUsd,
339
+ cachedInputTokens: extendedUsage?.cachedInputTokens,
340
+ reasoningTokens: extendedUsage?.reasoningTokens,
341
+ } as LanguageModelUsageWithCostUsd;
342
+ }
343
+ }
@@ -0,0 +1,203 @@
1
+ import type { AISdkTool } from "@/tools/types";
2
+ import { logger } from "@/utils/logger";
3
+ import { createSdkMcpServer, tool } from "ai-sdk-provider-claude-code";
4
+ import type { ToolExecutionOptions } from "@ai-sdk/provider-utils";
5
+ import { z, type ZodRawShape } from "zod";
6
+
7
+ // Infer the return type since SdkMcpServer is not exported
8
+ type SdkMcpServer = ReturnType<typeof createSdkMcpServer>;
9
+
10
+ /**
11
+ * Converts TENEX tools to Claude Code SDK MCP server format.
12
+ *
13
+ * This adapter is EXCLUSIVE to Claude Code - it uses createSdkMcpServer from
14
+ * the Claude Agent SDK which creates in-process MCP servers that only Claude Code
15
+ * can consume. Other providers (like Codex CLI) require different MCP formats.
16
+ */
17
+ export class ClaudeCodeToolsAdapter {
18
+ /**
19
+ * Check if a tool is an external MCP tool (from external MCP servers).
20
+ * External MCP tools have JSON Schema format (not Zod), so they cannot be
21
+ * wrapped with the Claude SDK's tool() function which expects Zod schemas.
22
+ * These tools are passed directly to Claude Code as MCP servers instead.
23
+ *
24
+ * Detection is metadata-based (checking for Zod schema characteristics)
25
+ * rather than name-based, to avoid collisions if a user names their
26
+ * external MCP server "tenex".
27
+ */
28
+ private static isExternalMcpTool(toolName: string, tool: AISdkTool): boolean {
29
+ // External MCP tools follow the pattern: mcp__<servername>__<toolname>
30
+ if (!toolName.startsWith("mcp__")) {
31
+ return false;
32
+ }
33
+
34
+ // Use metadata-based detection: check if the schema is a Zod object (has safeParseAsync)
35
+ // External MCP tools have JSON Schema format, TENEX tools have Zod schemas
36
+ const schema = tool.inputSchema;
37
+ if (schema && typeof schema === "object" && "safeParseAsync" in schema) {
38
+ // Has Zod schema - this is a TENEX tool (not external)
39
+ return false;
40
+ }
41
+
42
+ // No Zod schema detected - treat as external MCP tool
43
+ return true;
44
+ }
45
+
46
+ /**
47
+ * Convert TENEX tools to SDK MCP tools for Claude Code
48
+ * Only converts non-MCP tools (MCP tools are handled separately)
49
+ */
50
+ static createSdkMcpServer(
51
+ tools: Record<string, AISdkTool>
52
+ ): SdkMcpServer | undefined {
53
+ // Filter out tools that Claude Code has its own version of:
54
+ // - web_fetch (Claude Code has WebFetch)
55
+ // - web_search (Claude Code has WebSearch)
56
+ // fs_* and shell tools are NOT filtered — they pass through so TENEX controls access.
57
+ // Claude Code's built-in equivalents are always disabled via disallowedTools.
58
+ const claudeCodeBuiltinTools = new Set([
59
+ "web_fetch",
60
+ "web_search",
61
+ ]);
62
+ // CRITICAL: Filter out external MCP tools - they have JSON Schema format (no .safeParseAsync())
63
+ // and will crash if we try to wrap them with tool() from Claude SDK.
64
+ // External MCP servers are passed directly to Claude Code via mcpConfig.servers instead.
65
+ const localTools = Object.entries(tools).filter(([name, tool]) =>
66
+ !claudeCodeBuiltinTools.has(name) &&
67
+ !this.isExternalMcpTool(name, tool)
68
+ );
69
+
70
+ // Log external MCP tools that were filtered out (for debugging)
71
+ const externalMcpTools = Object.entries(tools)
72
+ .filter(([name, tool]) => this.isExternalMcpTool(name, tool))
73
+ .map(([name]) => name);
74
+
75
+ if (externalMcpTools.length > 0) {
76
+ logger.debug("[ClaudeCodeToolsAdapter] Filtered out external MCP tools (passed directly to Claude Code):", {
77
+ count: externalMcpTools.length,
78
+ tools: externalMcpTools,
79
+ });
80
+ }
81
+
82
+ if (localTools.length === 0) {
83
+ logger.debug("[ClaudeCodeToolsAdapter] No local tools to wrap after filtering", {
84
+ totalTools: Object.keys(tools).length,
85
+ externalMcpCount: externalMcpTools.length,
86
+ builtinFilteredCount: Object.keys(tools).filter(name =>
87
+ claudeCodeBuiltinTools.has(name)
88
+ ).length,
89
+ });
90
+ return undefined;
91
+ }
92
+
93
+ // Convert each TENEX tool to an SDK MCP tool
94
+ const sdkTools = localTools.map(([name, tenexTool]) => {
95
+ // The Claude SDK's tool() function expects a ZodRawShape (plain object like { a: z.number() })
96
+ // NOT a ZodObject (result of z.object({...})). We need to extract the .shape property.
97
+ // tenexTool.inputSchema from AI SDK is a ZodObject, so we extract its shape.
98
+ let rawShape: ZodRawShape = {};
99
+
100
+ if (tenexTool.inputSchema) {
101
+ // Check if it's a ZodObject with a shape property
102
+ const schema = tenexTool.inputSchema;
103
+ if (schema && typeof schema === "object" && "shape" in schema) {
104
+ // It's a ZodObject - extract the raw shape
105
+ rawShape = (schema as z.ZodObject<ZodRawShape>).shape;
106
+ } else if (schema && typeof schema === "object" && !("_def" in schema)) {
107
+ // It might already be a raw shape object (plain object with Zod types)
108
+ rawShape = schema as unknown as ZodRawShape;
109
+ } else if (schema !== null && typeof schema === "object") {
110
+ // DEFENSIVE GUARD: Log warning if we encounter an unexpected schema type
111
+ // This helps catch future regressions where non-Zod schemas slip through
112
+ logger.warn(`[ClaudeCodeToolsAdapter] Tool '${name}' has unexpected schema type - using empty schema`, {
113
+ hasShape: "shape" in schema,
114
+ hasDef: "_def" in schema,
115
+ hasSafeParseAsync: typeof (schema as { safeParseAsync?: unknown }).safeParseAsync === "function",
116
+ });
117
+ } else {
118
+ // Primitive schema (e.g., z.string()) - log warning but don't crash
119
+ logger.warn(`[ClaudeCodeToolsAdapter] Tool '${name}' has primitive or non-object schema type - using empty schema`, {
120
+ schemaType: typeof schema,
121
+ });
122
+ }
123
+ // If it's some other Zod type, leave rawShape as empty object
124
+ }
125
+
126
+ return tool(name, tenexTool.description || `Execute ${name}`, rawShape, async (args: Record<string, unknown>, extra: unknown) => {
127
+ try {
128
+ // Check if the tool has an execute method
129
+ if (!tenexTool.execute) {
130
+ throw new Error(`Tool ${name} does not have an execute function`);
131
+ }
132
+
133
+ // Execute the TENEX tool
134
+ // If extra contains execution context, pass it; otherwise use minimal fallback
135
+ const isToolExecutionOptions = (value: unknown): value is ToolExecutionOptions =>
136
+ typeof value === "object" &&
137
+ value !== null &&
138
+ "toolCallId" in value &&
139
+ "messages" in value &&
140
+ Array.isArray((value as { messages?: unknown }).messages);
141
+
142
+ let result;
143
+ if (isToolExecutionOptions(extra)) {
144
+ // Try to use the extra context from Claude Code
145
+ result = await tenexTool.execute(args, extra);
146
+ } else {
147
+ // Fallback to minimal context (should rarely happen)
148
+ result = await tenexTool.execute(args, {
149
+ abortSignal: new AbortController().signal,
150
+ toolCallId: "tool-call-" + Date.now(),
151
+ messages: [],
152
+ });
153
+ }
154
+
155
+ // Convert result to MCP format
156
+ // CallToolResult expects: { content: [{ type: "text", text: string }], isError?: boolean }
157
+ if (typeof result === "string") {
158
+ return {
159
+ content: [{ type: "text", text: result }],
160
+ };
161
+ }
162
+ if (result && typeof result === "object") {
163
+ return {
164
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
165
+ };
166
+ }
167
+ return {
168
+ content: [{ type: "text", text: String(result) }],
169
+ };
170
+ } catch (error) {
171
+ logger.error(`[ClaudeCodeToolsAdapter] Error executing tool ${name}:`, error);
172
+ return {
173
+ content: [
174
+ {
175
+ type: "text",
176
+ text: `Error: ${error instanceof Error ? error.message : String(error)}`,
177
+ },
178
+ ],
179
+ isError: true,
180
+ };
181
+ }
182
+ });
183
+ });
184
+
185
+ // Create and return the SDK MCP server
186
+ try {
187
+ const server = createSdkMcpServer({
188
+ name: "tenex",
189
+ tools: sdkTools,
190
+ });
191
+
192
+ logger.info("[ClaudeCodeToolsAdapter] SDK MCP server created successfully", {
193
+ serverName: "tenex",
194
+ toolCount: sdkTools.length,
195
+ });
196
+
197
+ return server;
198
+ } catch (error) {
199
+ logger.warn("[ClaudeCodeToolsAdapter] Could not create SDK MCP server:", error);
200
+ return undefined;
201
+ }
202
+ }
203
+ }