@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,353 @@
1
+ /**
2
+ * Nostr Publish As User Tool
3
+ *
4
+ * Enables agents to request the project owner to sign and publish
5
+ * arbitrary Nostr events via NIP-46 remote signing.
6
+ *
7
+ * The agent provides an unsigned event along with a human-readable
8
+ * explanation of WHY the signing is being requested. The explanation
9
+ * is transported as a root-level `tenex_explanation` property on the
10
+ * event object (NOT as a tag). Since NIP-01 event hashing only commits
11
+ * to [0, pubkey, created_at, kind, tags, content], root-level extras
12
+ * are never part of the hash or signature, making them safe transport
13
+ * metadata that the frontend/TUI can read and display to the user.
14
+ */
15
+
16
+ import type { AISdkTool, ToolExecutionContext } from "@/tools/types";
17
+ import { getNDK } from "@/nostr/ndkClient";
18
+ import { Nip46SigningService } from "@/services/nip46";
19
+ import { getProjectContext } from "@/services/projects";
20
+ import { logger } from "@/utils/logger";
21
+ import { NDKEvent, NDKNip46Signer, NDKPrivateKeySigner } from "@nostr-dev-kit/ndk";
22
+ import { tool } from "ai";
23
+ import { verifyEvent } from "nostr-tools";
24
+ import { z } from "zod";
25
+
26
+ const NIP46_CONNECT_TIMEOUT_MS = 30_000;
27
+ const NIP46_SIGNING_TIMEOUT_MS = 120_000;
28
+
29
+ const nostrPublishAsUserSchema = z.object({
30
+ description: z
31
+ .string()
32
+ .describe("A short one-liner describing what this event is"),
33
+ explanation: z
34
+ .string()
35
+ .describe(
36
+ "An explanation for the human user telling them WHY we want them to sign this event. " +
37
+ "This context is shown to the user in the frontend before they approve signing."
38
+ ),
39
+ event: z
40
+ .union([
41
+ z.string(),
42
+ z.object({
43
+ kind: z.number(),
44
+ content: z.string(),
45
+ tags: z.array(z.array(z.string())).optional(),
46
+ }).passthrough(),
47
+ ])
48
+ .describe(
49
+ "An unsigned Nostr event as a JSON object or JSON string. " +
50
+ "Must include 'kind' (number) and 'content' (string). " +
51
+ "Tags must be an array of string arrays. " +
52
+ "The event will be re-signed by the project owner via NIP-46."
53
+ ),
54
+ });
55
+
56
+ type NostrPublishAsUserInput = z.infer<typeof nostrPublishAsUserSchema>;
57
+
58
+ /** Schema for validating a parsed event object */
59
+ const parsedEventSchema = z.object({
60
+ kind: z.number({ error: "Event must include a numeric 'kind' field" }),
61
+ content: z.string({ error: "Event must include a string 'content' field" }),
62
+ tags: z.array(z.array(z.string())).optional(),
63
+ });
64
+
65
+ /**
66
+ * Parse the event input into a raw event object.
67
+ * Accepts either a JSON string or an already-validated object.
68
+ */
69
+ function parseEventInput(
70
+ input: string | { kind: number; content: string; tags?: string[][] }
71
+ ): { kind: number; content: string; tags?: string[][] } {
72
+ let raw: unknown;
73
+
74
+ if (typeof input === "string") {
75
+ try {
76
+ raw = JSON.parse(input);
77
+ } catch (e) {
78
+ throw new Error(
79
+ `Invalid JSON in event field: ${e instanceof Error ? e.message : String(e)}`
80
+ );
81
+ }
82
+ } else {
83
+ // Already validated by Zod schema at the input boundary
84
+ raw = input;
85
+ }
86
+
87
+ const result = parsedEventSchema.safeParse(raw);
88
+ if (!result.success) {
89
+ const issues = result.error.issues.map((i) => i.message).join("; ");
90
+ throw new Error(`Invalid event: ${issues}`);
91
+ }
92
+
93
+ return result.data;
94
+ }
95
+
96
+ /**
97
+ * Create an NDKNip46Signer using the agent's private key as local signer
98
+ * and the owner's pubkey as the remote signer target.
99
+ */
100
+ async function connectNip46Signer(
101
+ agentSigner: NDKPrivateKeySigner,
102
+ ownerPubkey: string,
103
+ ): Promise<NDKNip46Signer> {
104
+ const ndk = getNDK();
105
+ const nip46Service = Nip46SigningService.getInstance();
106
+ const bunkerUri = nip46Service.getBunkerUri(ownerPubkey);
107
+
108
+ if (!bunkerUri?.startsWith("bunker://")) {
109
+ throw new Error(
110
+ `Invalid bunker URI for owner ${ownerPubkey.substring(0, 12)}: ` +
111
+ `expected "bunker://" URI but got "${bunkerUri || "(empty)"}"`
112
+ );
113
+ }
114
+
115
+ logger.info("[nostr_publish_as_user] Creating NIP-46 signer", {
116
+ ownerPubkey: ownerPubkey.substring(0, 12),
117
+ bunkerUri: bunkerUri.substring(0, 60),
118
+ });
119
+
120
+ const signer = NDKNip46Signer.bunker(ndk, bunkerUri, agentSigner);
121
+
122
+ signer.on("authUrl", (url: string) => {
123
+ logger.info("[nostr_publish_as_user] NIP-46 auth URL required", {
124
+ ownerPubkey: ownerPubkey.substring(0, 12),
125
+ url,
126
+ });
127
+ });
128
+
129
+ let connectTimer: ReturnType<typeof setTimeout> | undefined;
130
+ try {
131
+ await Promise.race([
132
+ signer.blockUntilReady(),
133
+ new Promise<never>((_, reject) => {
134
+ connectTimer = setTimeout(
135
+ () => reject(new Error(
136
+ `NIP-46 connect timed out after ${NIP46_CONNECT_TIMEOUT_MS / 1000}s`
137
+ )),
138
+ NIP46_CONNECT_TIMEOUT_MS,
139
+ );
140
+ }),
141
+ ]);
142
+ } catch (error) {
143
+ try { signer.stop(); } catch { /* best-effort cleanup */ }
144
+ throw error;
145
+ } finally {
146
+ clearTimeout(connectTimer);
147
+ }
148
+
149
+ return signer;
150
+ }
151
+
152
+ /**
153
+ * Execute the nostr_publish_as_user tool.
154
+ *
155
+ * Flow:
156
+ * 1. Parse and validate the provided event
157
+ * 2. Set `tenex_explanation` as root-level property (transport for frontend context)
158
+ * 3. Send NIP-46 signing request to the project owner
159
+ * 4. Strip `tenex_explanation` property after signing (harmless — never part of hash)
160
+ * 5. Verify the signature is valid
161
+ * 6. Publish the signed event to relays
162
+ */
163
+ async function executeNostrPublishAsUser(
164
+ input: NostrPublishAsUserInput,
165
+ context: ToolExecutionContext,
166
+ ): Promise<string> {
167
+ const { description, explanation, event: eventInput } = input;
168
+
169
+ // Resolve owner pubkey
170
+ const projectCtx = getProjectContext();
171
+ const ownerPubkey = projectCtx?.project?.pubkey;
172
+
173
+ if (!ownerPubkey) {
174
+ throw new Error(
175
+ "Cannot publish as user: no project owner pubkey found. " +
176
+ "Ensure the project has an owner configured."
177
+ );
178
+ }
179
+
180
+ // Verify NIP-46 is enabled
181
+ const nip46Service = Nip46SigningService.getInstance();
182
+ if (!nip46Service.isEnabled()) {
183
+ throw new Error(
184
+ "Cannot publish as user: NIP-46 remote signing is not enabled. " +
185
+ "Enable it by setting nip46.enabled=true in your TENEX config."
186
+ );
187
+ }
188
+
189
+ // Verify agent signer type
190
+ const agentSigner: unknown = context.agent.signer;
191
+ if (!(agentSigner instanceof NDKPrivateKeySigner)) {
192
+ throw new Error(
193
+ `Expected agent signer to be NDKPrivateKeySigner for NIP-46 signing, ` +
194
+ `got ${(agentSigner as { constructor?: { name?: string } })?.constructor?.name ?? "undefined"}.`
195
+ );
196
+ }
197
+
198
+ // Parse the event input
199
+ const parsedEvent = parseEventInput(eventInput);
200
+
201
+ // Build the NDKEvent
202
+ const ndk = getNDK();
203
+ const ndkEvent = new NDKEvent(ndk);
204
+ ndkEvent.kind = parsedEvent.kind;
205
+ ndkEvent.content = parsedEvent.content;
206
+ ndkEvent.tags = parsedEvent.tags ? [...parsedEvent.tags] : [];
207
+
208
+ // Add tenex_explanation as a root-level property for frontend context.
209
+ // Root-level extras are NOT part of the NIP-01 event hash
210
+ // ([0, pubkey, created_at, kind, tags, content]), so the signature
211
+ // is computed over the clean event regardless.
212
+ (ndkEvent as any).tenex_explanation = explanation;
213
+
214
+ // Set pubkey to the owner's
215
+ ndkEvent.pubkey = ownerPubkey;
216
+
217
+ logger.info("[nostr_publish_as_user] Requesting user signature", {
218
+ description,
219
+ kind: ndkEvent.kind,
220
+ ownerPubkey: ownerPubkey.substring(0, 12),
221
+ agentPubkey: context.agent.pubkey.substring(0, 12),
222
+ tagCount: ndkEvent.tags.length,
223
+ });
224
+
225
+ // Connect NIP-46 signer
226
+ const nip46Signer = await connectNip46Signer(
227
+ context.agent.signer,
228
+ ownerPubkey,
229
+ );
230
+
231
+ // Sign with NIP-46 (the signer sends the event to the user's bunker for approval).
232
+ //
233
+ // The `tenex_explanation` root-level property is present on the event object
234
+ // during signing so the TUI/bunker can read and display it to the user.
235
+ // Since it's not in `tags`, it's never part of the event hash — the signature
236
+ // is always computed over the clean event.
237
+ let signingTimer: ReturnType<typeof setTimeout> | undefined;
238
+ try {
239
+ await Promise.race([
240
+ ndkEvent.sign(nip46Signer),
241
+ new Promise<never>((_, reject) => {
242
+ signingTimer = setTimeout(
243
+ () => reject(new Error(
244
+ `NIP-46 signing timed out after ${NIP46_SIGNING_TIMEOUT_MS / 1000}s`
245
+ )),
246
+ NIP46_SIGNING_TIMEOUT_MS,
247
+ );
248
+ }),
249
+ ]);
250
+ } catch (error) {
251
+ try { nip46Signer.stop(); } catch { /* best-effort cleanup */ }
252
+ throw error;
253
+ } finally {
254
+ clearTimeout(signingTimer);
255
+ }
256
+
257
+ // Strip the root-level tenex_explanation property now that signing is done.
258
+ // This is purely cosmetic cleanup — the property was never part of the
259
+ // event hash or signature.
260
+ delete (ndkEvent as any).tenex_explanation;
261
+
262
+ // Validate timestamp is in seconds, not milliseconds
263
+ if (ndkEvent.created_at && ndkEvent.created_at > 1_000_000_000_000) {
264
+ throw new Error(
265
+ "Event created_at appears to be in milliseconds instead of seconds. " +
266
+ "Nostr timestamps must be Unix timestamps in seconds."
267
+ );
268
+ }
269
+
270
+ // Verify the signature is valid
271
+ const rawEvent = ndkEvent.rawEvent();
272
+ if (!verifyEvent(rawEvent)) {
273
+ try { nip46Signer.stop(); } catch { /* best-effort cleanup */ }
274
+ throw new Error(
275
+ "Signature verification failed after NIP-46 signing. " +
276
+ "The event signature does not match the clean event content."
277
+ );
278
+ }
279
+
280
+ // Validate event structure per NDK guardrails
281
+ if (!ndkEvent.validate()) {
282
+ try { nip46Signer.stop(); } catch { /* best-effort cleanup */ }
283
+ throw new Error(
284
+ "NDK validation failed: event structure is invalid. " +
285
+ "Ensure kind, content, pubkey, created_at, and tags are well-formed."
286
+ );
287
+ }
288
+
289
+ // Publish the signed event
290
+ try {
291
+ await ndkEvent.publish();
292
+ } finally {
293
+ try { nip46Signer.stop(); } catch { /* best-effort cleanup */ }
294
+ }
295
+
296
+ logger.info("[nostr_publish_as_user] Event published successfully", {
297
+ eventId: ndkEvent.id,
298
+ kind: ndkEvent.kind,
299
+ ownerPubkey: ownerPubkey.substring(0, 12),
300
+ description,
301
+ });
302
+
303
+ return JSON.stringify({
304
+ success: true,
305
+ eventId: ndkEvent.id,
306
+ kind: ndkEvent.kind,
307
+ description,
308
+ });
309
+ }
310
+
311
+ /**
312
+ * Create the nostr_publish_as_user AI SDK tool
313
+ */
314
+ export function createNostrPublishAsUserTool(context: ToolExecutionContext): AISdkTool {
315
+ const aiTool = tool({
316
+ description:
317
+ "Request the project owner/user to sign and publish a Nostr event via NIP-46 remote signing. " +
318
+ "Provide the unsigned event, a short description, and an explanation of WHY the user should sign it. " +
319
+ "The explanation is shown to the user in the frontend before they approve. " +
320
+ "Once approved, the event is signed by the user and published to relays.",
321
+
322
+ inputSchema: nostrPublishAsUserSchema,
323
+
324
+ execute: async (input: NostrPublishAsUserInput) => {
325
+ try {
326
+ return await executeNostrPublishAsUser(input, context);
327
+ } catch (error) {
328
+ logger.error("[nostr_publish_as_user] Failed", {
329
+ error: error instanceof Error ? error.message : String(error),
330
+ });
331
+ throw new Error(
332
+ `Failed to publish as user: ${error instanceof Error ? error.message : String(error)}`,
333
+ { cause: error }
334
+ );
335
+ }
336
+ },
337
+ });
338
+
339
+ Object.defineProperty(aiTool, "getHumanReadableContent", {
340
+ value: ({ description, event }: NostrPublishAsUserInput) => {
341
+ try {
342
+ const parsed = typeof event === "string" ? JSON.parse(event) : event;
343
+ return `Requesting user to sign kind:${parsed.kind} event — ${description}`;
344
+ } catch {
345
+ return `Requesting user to sign event — ${description}`;
346
+ }
347
+ },
348
+ enumerable: false,
349
+ configurable: true,
350
+ });
351
+
352
+ return aiTool as AISdkTool;
353
+ }
@@ -0,0 +1,146 @@
1
+ import type { AISdkTool, ToolExecutionContext } from "@/tools/types";
2
+ import { getDaemon } from "@/daemon";
3
+ import { agentStorage } from "@/agents/AgentStorage";
4
+ import { logger } from "@/utils/logger";
5
+ import { NDKPrivateKeySigner } from "@nostr-dev-kit/ndk";
6
+ import { PREFIX_LENGTH } from "@/utils/nostr-entity-parser";
7
+ import { tool } from "ai";
8
+ import { z } from "zod";
9
+
10
+ const projectListSchema = z.object({});
11
+
12
+ type ProjectAgent = {
13
+ slug: string;
14
+ pubkey: string;
15
+ role: string;
16
+ isPM?: true;
17
+ };
18
+
19
+ type ProjectInfo = {
20
+ id: string; // The project's dTag (unique identifier)
21
+ title?: string;
22
+ description?: string;
23
+ repository?: string;
24
+ isRunning: boolean;
25
+ agents: ProjectAgent[];
26
+ };
27
+
28
+ type ProjectListOutput = {
29
+ projects: ProjectInfo[];
30
+ summary: {
31
+ totalProjects: number;
32
+ runningProjects: number;
33
+ totalAgents: number;
34
+ };
35
+ };
36
+
37
+ async function executeProjectList(context: ToolExecutionContext): Promise<ProjectListOutput> {
38
+ const daemon = getDaemon();
39
+ const knownProjects = daemon.getKnownProjects();
40
+ const activeRuntimes = daemon.getActiveRuntimes();
41
+
42
+ logger.info("📦 Listing all known projects", {
43
+ knownCount: knownProjects.size,
44
+ runningCount: activeRuntimes.size,
45
+ agent: context.agent.name,
46
+ });
47
+
48
+ const projects: ProjectInfo[] = [];
49
+ let totalAgents = 0;
50
+
51
+ for (const [projectId, project] of knownProjects) {
52
+ // projectId format is "31933:pubkey:id"
53
+ const id = projectId.split(":")[2];
54
+ if (!id) {
55
+ logger.warn("⚠️ Project missing id, skipping", { projectId });
56
+ continue;
57
+ }
58
+
59
+ const title = project.tagValue("title") || project.tagValue("name");
60
+ const description = project.tagValue("description");
61
+ const repository = project.tagValue("repository");
62
+ // Check if this project is running
63
+ const runtime = activeRuntimes.get(projectId);
64
+ const isRunning = !!runtime;
65
+
66
+ // Get agents - from running context if available, otherwise from storage
67
+ const agents: ProjectAgent[] = [];
68
+
69
+ if (runtime) {
70
+ // Running project - get agents from runtime context
71
+ const runtimeContext = runtime.getContext();
72
+ const pmPubkey = runtimeContext?.projectManager?.pubkey;
73
+ const agentMap = runtimeContext?.agentRegistry.getAllAgentsMap() || new Map();
74
+ for (const agent of agentMap.values()) {
75
+ const isPM = agent.pubkey === pmPubkey;
76
+ agents.push({
77
+ slug: agent.slug,
78
+ pubkey: agent.pubkey.substring(0, PREFIX_LENGTH),
79
+ role: agent.role,
80
+ ...(isPM && { isPM: true }),
81
+ });
82
+ }
83
+ } else {
84
+ // Not running - get agents from storage
85
+ const storedAgents = await agentStorage.getProjectAgents(id);
86
+ for (const storedAgent of storedAgents) {
87
+ const signer = new NDKPrivateKeySigner(storedAgent.nsec);
88
+ const pubkey = (await signer.user()).pubkey;
89
+ agents.push({
90
+ slug: storedAgent.slug,
91
+ pubkey: pubkey.substring(0, PREFIX_LENGTH),
92
+ role: storedAgent.role,
93
+ });
94
+ }
95
+ }
96
+
97
+ totalAgents += agents.length;
98
+
99
+ projects.push({
100
+ id,
101
+ title,
102
+ description,
103
+ repository,
104
+ isRunning,
105
+ agents,
106
+ });
107
+ }
108
+
109
+ const runningCount = projects.filter((p) => p.isRunning).length;
110
+
111
+ logger.info("✅ Project list complete", {
112
+ totalProjects: projects.length,
113
+ runningProjects: runningCount,
114
+ totalAgents,
115
+ agent: context.agent.name,
116
+ });
117
+
118
+ return {
119
+ projects,
120
+ summary: {
121
+ totalProjects: projects.length,
122
+ runningProjects: runningCount,
123
+ totalAgents,
124
+ },
125
+ };
126
+ }
127
+
128
+ export function createProjectListTool(context: ToolExecutionContext): AISdkTool {
129
+ const coreTool = tool({
130
+ description:
131
+ "List ALL known projects with their agents and running status. " +
132
+ "For each project shows: id, title, description, repository, isRunning flag, and all agents. " +
133
+ "For each agent shows: slug, pubkey (shortened), role, and isPM (only if true). " +
134
+ "Includes both running and non-running projects discovered by the daemon.",
135
+ inputSchema: projectListSchema,
136
+ execute: async () => {
137
+ return await executeProjectList(context);
138
+ },
139
+ }) as AISdkTool;
140
+
141
+ coreTool.getHumanReadableContent = () => {
142
+ return "Listing all known projects and their agents";
143
+ };
144
+
145
+ return coreTool;
146
+ }