@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,132 @@
1
+ import { config } from "@/services/ConfigService";
2
+ import { shortenConversationId } from "@/utils/conversation-id";
3
+ import { logger } from "@/utils/logger";
4
+ import { NDKPrivateKeySigner } from "@nostr-dev-kit/ndk";
5
+ import { trace } from "@opentelemetry/api";
6
+ import { AgentEventEncoder } from "./AgentEventEncoder";
7
+ import { injectTraceContext } from "./trace-context";
8
+ import type { InterventionReviewIntent } from "./types";
9
+
10
+ /**
11
+ * Publisher for intervention review request events.
12
+ * Uses the backend private key (same as scheduled jobs) for signing.
13
+ *
14
+ * This publisher follows the established Nostr event encoding patterns:
15
+ * - Uses AgentEventEncoder for event creation and tagging
16
+ * - Injects trace context for observability
17
+ * - Includes project `a` tag for proper event association
18
+ */
19
+ export class InterventionPublisher {
20
+ private signer: NDKPrivateKeySigner | null = null;
21
+ private encoder: AgentEventEncoder;
22
+
23
+ constructor() {
24
+ this.encoder = new AgentEventEncoder();
25
+ }
26
+
27
+ /**
28
+ * Initialize the publisher by loading the backend signer.
29
+ * Must be called before publishing events.
30
+ */
31
+ async initialize(): Promise<void> {
32
+ this.signer = await config.getBackendSigner();
33
+ logger.debug("InterventionPublisher initialized", {
34
+ pubkey: this.signer.pubkey.substring(0, 8),
35
+ });
36
+ }
37
+
38
+ /**
39
+ * Get the publisher's pubkey (backend key).
40
+ * Throws if not initialized.
41
+ */
42
+ getPubkey(): string {
43
+ if (!this.signer) {
44
+ throw new Error("InterventionPublisher not initialized");
45
+ }
46
+ return this.signer.pubkey;
47
+ }
48
+
49
+ /**
50
+ * Publish an intervention review request event.
51
+ *
52
+ * Uses AgentEventEncoder to ensure consistent event structure including:
53
+ * - Project `a` tag for proper event association
54
+ * - Trace context injection for observability
55
+ * - Standard intervention-specific tags
56
+ *
57
+ * Names are pre-resolved by the caller (InterventionService) before being
58
+ * passed to this method. This avoids circular dependencies since
59
+ * InterventionPublisher (nostr layer) cannot import PubkeyService (services layer).
60
+ *
61
+ * @param humanReplicaPubkey - Pubkey of the intervention agent to notify
62
+ * @param conversationId - ID of the original conversation
63
+ * @param userName - Human-readable name of the user who hasn't responded (pre-resolved)
64
+ * @param agentName - Human-readable name of the agent that completed work (pre-resolved)
65
+ * @returns The published event ID
66
+ */
67
+ async publishReviewRequest(
68
+ humanReplicaPubkey: string,
69
+ conversationId: string,
70
+ userName: string,
71
+ agentName: string
72
+ ): Promise<string> {
73
+ if (!this.signer) {
74
+ throw new Error("InterventionPublisher not initialized");
75
+ }
76
+
77
+ const intent: InterventionReviewIntent = {
78
+ targetPubkey: humanReplicaPubkey,
79
+ conversationId,
80
+ userName,
81
+ agentName,
82
+ };
83
+
84
+ // Use encoder to create properly tagged event
85
+ const event = this.encoder.encodeInterventionReview(intent);
86
+
87
+ // Inject trace context for observability
88
+ injectTraceContext(event);
89
+
90
+ // Sign with backend signer
91
+ await event.sign(this.signer);
92
+
93
+ const shortConversationId = shortenConversationId(conversationId);
94
+
95
+ try {
96
+ const relaySet = await event.publish();
97
+ const successRelays: string[] = [];
98
+ for (const relay of relaySet) {
99
+ successRelays.push(relay.url);
100
+ }
101
+
102
+ if (successRelays.length === 0) {
103
+ logger.warn("Intervention review request published to 0 relays", {
104
+ eventId: event.id?.substring(0, 8),
105
+ conversationId: shortConversationId,
106
+ });
107
+ } else {
108
+ logger.info("Published intervention review request", {
109
+ eventId: event.id?.substring(0, 8),
110
+ conversationId: shortConversationId,
111
+ targetAgent: humanReplicaPubkey.substring(0, 8),
112
+ relayCount: successRelays.length,
113
+ });
114
+ }
115
+
116
+ trace.getActiveSpan()?.addEvent("intervention.review_request_published", {
117
+ "event.id": event.id || "unknown",
118
+ "conversation.id": conversationId,
119
+ "target.pubkey": humanReplicaPubkey.substring(0, 8),
120
+ "relay.count": successRelays.length,
121
+ });
122
+
123
+ return event.id || "";
124
+ } catch (error) {
125
+ logger.error("Failed to publish intervention review request", {
126
+ error,
127
+ conversationId: shortConversationId,
128
+ });
129
+ throw error;
130
+ }
131
+ }
132
+ }
@@ -0,0 +1,228 @@
1
+ import type { NDKEvent } from "@nostr-dev-kit/ndk";
2
+
3
+ /**
4
+ * Utility class for extracting and processing Nostr event tags.
5
+ * Consolidates tag extraction logic scattered across the codebase.
6
+ *
7
+ * This class provides a single source of truth for tag extraction,
8
+ * replacing 20+ instances of manual tag filtering across files.
9
+ */
10
+ export class TagExtractor {
11
+ /**
12
+ * Extract all a-tags from an event
13
+ * @param event - The event to extract a-tags from
14
+ * @returns Array of a-tag values
15
+ */
16
+ static getATags(event: NDKEvent): string[] {
17
+ return event.tags
18
+ .filter((tag) => tag[0] === "a")
19
+ .map((tag) => tag[1])
20
+ .filter((value): value is string => !!value);
21
+ }
22
+
23
+ /**
24
+ * Extract project-specific A-tags (those starting with "31933:")
25
+ * @param event - The event to extract project A-tags from
26
+ * @returns Array of project A-tag values
27
+ */
28
+ static getProjectATags(event: NDKEvent): string[] {
29
+ return this.getATags(event).filter((tag) => tag.startsWith("31933:"));
30
+ }
31
+
32
+ /**
33
+ * Extract all E-tags from an event
34
+ * @param event - The event to extract E-tags from
35
+ * @returns Array of E-tag values (event IDs)
36
+ */
37
+ static getETags(event: NDKEvent): string[] {
38
+ return event.tags
39
+ .filter((tag) => tag[0] === "e")
40
+ .map((tag) => tag[1])
41
+ .filter((value): value is string => !!value);
42
+ }
43
+
44
+ /**
45
+ * Extract the first E-tag value (commonly used for parent event reference)
46
+ * @param event - The event to extract E-tag from
47
+ * @returns The first E-tag value or null
48
+ */
49
+ static getFirstETag(event: NDKEvent): string | null {
50
+ const eTags = this.getETags(event);
51
+ return eTags.length > 0 ? eTags[0] : null;
52
+ }
53
+
54
+ /**
55
+ * Extract all P-tags from an event
56
+ * @param event - The event to extract P-tags from
57
+ * @returns Array of P-tag values (pubkeys)
58
+ */
59
+ static getPTags(event: NDKEvent): string[] {
60
+ return event.tags
61
+ .filter((tag) => tag[0] === "p")
62
+ .map((tag) => tag[1])
63
+ .filter((value): value is string => !!value);
64
+ }
65
+
66
+ /**
67
+ * Extract mentioned pubkeys from P-tags (alias for getPTags)
68
+ * @param event - The event to extract mentioned pubkeys from
69
+ * @returns Array of mentioned pubkeys
70
+ */
71
+ static getMentionedPubkeys(event: NDKEvent): string[] {
72
+ return this.getPTags(event);
73
+ }
74
+
75
+ /**
76
+ * Extract tool tags from an event
77
+ * @param event - The event to extract tool tags from
78
+ * @returns Array of tool tag objects with name and args
79
+ */
80
+ static getToolTags(event: NDKEvent): Array<{ name: string; args?: unknown }> {
81
+ return event.tags
82
+ .filter((tag) => tag[0] === "tool")
83
+ .map((tag) => {
84
+ const toolInfo: { name: string; args?: unknown } = { name: tag[1] };
85
+ if (tag[2]) {
86
+ try {
87
+ toolInfo.args = JSON.parse(tag[2]);
88
+ } catch {
89
+ // Keep args as undefined if parsing fails
90
+ }
91
+ }
92
+ return toolInfo;
93
+ })
94
+ .filter((tool): tool is { name: string; args?: unknown } => !!tool.name);
95
+ }
96
+
97
+ /**
98
+ * Extract D-tag value (used for replaceable events)
99
+ * @param event - The event to extract D-tag from
100
+ * @returns The D-tag value or null
101
+ */
102
+ static getDTag(event: NDKEvent): string | null {
103
+ const dTag = event.tags.find((tag) => tag[0] === "d");
104
+ return dTag?.[1] || null;
105
+ }
106
+
107
+ /**
108
+ * Extract K-tags (kind tags) from an event
109
+ * @param event - The event to extract K-tags from
110
+ * @returns Array of K-tag values (kind numbers as strings)
111
+ */
112
+ static getKTags(event: NDKEvent): string[] {
113
+ return event.tags
114
+ .filter((tag) => tag[0] === "k")
115
+ .map((tag) => tag[1])
116
+ .filter((value): value is string => !!value);
117
+ }
118
+
119
+ /**
120
+ * Extract mode tags from an event
121
+ * @param event - The event to extract mode tags from
122
+ * @returns Array of mode tag values
123
+ */
124
+ static getModeTags(event: NDKEvent): string[] {
125
+ return event.tags
126
+ .filter((tag) => tag[0] === "mode")
127
+ .map((tag) => tag[1])
128
+ .filter((value): value is string => !!value);
129
+ }
130
+
131
+ /**
132
+ * Check if event has a specific mode tag
133
+ * @param event - The event to check
134
+ * @param mode - The mode to check for
135
+ * @returns True if the event has the specified mode tag
136
+ */
137
+ static hasMode(event: NDKEvent, mode: string): boolean {
138
+ return this.getModeTags(event).includes(mode);
139
+ }
140
+
141
+ /**
142
+ * Extract nudge tags from an event
143
+ * @param event - The event to extract nudge tags from
144
+ * @returns Array of nudge event IDs
145
+ */
146
+ static getNudgeTags(event: NDKEvent): string[] {
147
+ return event.tags
148
+ .filter((tag) => tag[0] === "nudge")
149
+ .map((tag) => tag[1])
150
+ .filter((value): value is string => !!value);
151
+ }
152
+
153
+ /**
154
+ * Extract error type from error tags
155
+ * @param event - The event to extract error type from
156
+ * @returns The error type or null
157
+ */
158
+ static getErrorType(event: NDKEvent): string | null {
159
+ const errorTag = event.tags.find((tag) => tag[0] === "error");
160
+ return errorTag?.[1] || null;
161
+ }
162
+
163
+ /**
164
+ * Extract moderator from moderator tags
165
+ * @param event - The event to extract moderator from
166
+ * @returns The moderator pubkey or null
167
+ */
168
+ static getModerator(event: NDKEvent): string | null {
169
+ const modTag = event.tags.find((tag) => tag[0] === "moderator");
170
+ return modTag?.[1] || null;
171
+ }
172
+
173
+ /**
174
+ * Extract participant pubkeys from participant tags
175
+ * @param event - The event to extract participants from
176
+ * @returns Array of participant pubkeys
177
+ */
178
+ static getParticipants(event: NDKEvent): string[] {
179
+ return event.tags
180
+ .filter((tag) => tag[0] === "participant")
181
+ .map((tag) => tag[1])
182
+ .filter((value): value is string => !!value);
183
+ }
184
+
185
+ /**
186
+ * Extract trace context from an event (for telemetry)
187
+ * @param event - The event to extract trace context from
188
+ * @returns The trace context value or null
189
+ */
190
+ static getTraceContext(event: NDKEvent): string | null {
191
+ const traceTag = event.tags.find((tag) => tag[0] === "trace_context");
192
+ return traceTag?.[1] || null;
193
+ }
194
+
195
+ /**
196
+ * Check if an event has any tags of a specific type
197
+ * @param event - The event to check
198
+ * @param tagType - The tag type to check for
199
+ * @returns True if the event has at least one tag of the specified type
200
+ */
201
+ static hasTag(event: NDKEvent, tagType: string): boolean {
202
+ return event.tags.some((tag) => tag[0] === tagType);
203
+ }
204
+
205
+ /**
206
+ * Get all values for a specific tag type
207
+ * @param event - The event to extract tag values from
208
+ * @param tagType - The tag type to extract
209
+ * @returns Array of tag values
210
+ */
211
+ static getTagValues(event: NDKEvent, tagType: string): string[] {
212
+ return event.tags
213
+ .filter((tag) => tag[0] === tagType)
214
+ .map((tag) => tag[1])
215
+ .filter((value): value is string => !!value);
216
+ }
217
+
218
+ /**
219
+ * Get the first value for a specific tag type
220
+ * @param event - The event to extract tag value from
221
+ * @param tagType - The tag type to extract
222
+ * @returns The first tag value or null
223
+ */
224
+ static getTagValue(event: NDKEvent, tagType: string): string | null {
225
+ const values = this.getTagValues(event, tagType);
226
+ return values.length > 0 ? values[0] : null;
227
+ }
228
+ }
@@ -0,0 +1,83 @@
1
+ import { logger } from "@/utils/logger";
2
+ import type NDK from "@nostr-dev-kit/ndk";
3
+ import type { NDKEvent, NDKFilter, NDKSubscriptionOptions } from "@nostr-dev-kit/ndk";
4
+
5
+ const DEFAULT_TIMEOUT_MS = 15_000;
6
+
7
+ export interface CollectEventsOptions {
8
+ /** Additional subscription options (closeOnEose is always forced true). */
9
+ subOpts?: Omit<NDKSubscriptionOptions, "closeOnEose">;
10
+ /** Timeout in milliseconds. Defaults to 15 000. Set to 0 to disable. */
11
+ timeoutMs?: number;
12
+ }
13
+
14
+ /**
15
+ * Subscribe to a filter and collect all events until EOSE, with timeout
16
+ * protection and deduplication by event id.
17
+ *
18
+ * Resolves with the collected (deduplicated) events once EOSE is received
19
+ * or the timeout fires — whichever comes first. If the relay closes the
20
+ * connection before EOSE, the partial set is returned and a warning is logged.
21
+ */
22
+ export function collectEvents(
23
+ ndk: NDK,
24
+ filter: NDKFilter,
25
+ options: CollectEventsOptions = {},
26
+ ): Promise<NDKEvent[]> {
27
+ const { subOpts = {}, timeoutMs = DEFAULT_TIMEOUT_MS } = options;
28
+ const seen = new Map<string, NDKEvent>();
29
+
30
+ return new Promise<NDKEvent[]>((resolve) => {
31
+ let settled = false;
32
+ let eoseReceived = false;
33
+ let timer: ReturnType<typeof setTimeout> | undefined;
34
+
35
+ const finish = () => {
36
+ if (settled) return;
37
+ settled = true;
38
+ if (timer) clearTimeout(timer);
39
+ resolve(Array.from(seen.values()));
40
+ };
41
+
42
+ const sub = ndk.subscribe(
43
+ filter,
44
+ { ...subOpts, closeOnEose: true },
45
+ {
46
+ onEvent: (event) => {
47
+ try {
48
+ seen.set(event.id, event);
49
+ } catch (err) {
50
+ logger.warn("collectEvents: error in onEvent", { err });
51
+ }
52
+ },
53
+ onEose: () => {
54
+ eoseReceived = true;
55
+ finish();
56
+ },
57
+ onClose: () => {
58
+ if (!eoseReceived) {
59
+ logger.warn("collectEvents: relay closed before EOSE", {
60
+ filter,
61
+ collected: seen.size,
62
+ });
63
+ }
64
+ finish();
65
+ },
66
+ },
67
+ );
68
+
69
+ if (timeoutMs > 0) {
70
+ timer = setTimeout(() => {
71
+ if (!settled) {
72
+ logger.warn("collectEvents: timed out waiting for EOSE", {
73
+ timeoutMs,
74
+ filter,
75
+ collected: seen.size,
76
+ });
77
+ sub.stop();
78
+ finish();
79
+ }
80
+ }, timeoutMs);
81
+ }
82
+ });
83
+ }
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Nostr event kinds used in the application
3
+ */
4
+ export enum NostrKind {
5
+ // Standard kinds
6
+ TEXT_NOTE = 1,
7
+ REACTION = 7,
8
+ ARTICLE = 30023,
9
+ }
10
+
11
+ /**
12
+ * Standard Nostr tag names
13
+ */
14
+ export enum NostrTag {
15
+ // Standard tags
16
+ EVENT = "e",
17
+ PUBKEY = "p",
18
+ REPLACEABLE = "a",
19
+
20
+ // Application-specific tags
21
+ MODE = "mode",
22
+ PARTICIPANT = "participant",
23
+ REASON = "reason",
24
+ TOOL = "tool",
25
+ }
26
+
27
+ /**
28
+ * Tag values for specific application modes
29
+ */
30
+ export enum TagValue {
31
+ REACTION_POSITIVE = "+",
32
+ DELEGATE = "delegate",
33
+ }
34
+
35
+ /**
36
+ * Maximum lengths for various fields
37
+ */
38
+ export const MAX_REASON_LENGTH = 200;
@@ -0,0 +1,26 @@
1
+ /**
2
+ * NIP-44 encryption/decryption helpers.
3
+ *
4
+ * Wraps NDK runtime objects (NDKUser) so that service-layer code
5
+ * never needs to construct NDK instances directly.
6
+ */
7
+
8
+ import { NDKUser } from "@nostr-dev-kit/ndk";
9
+ import type { NDKPrivateKeySigner } from "@nostr-dev-kit/ndk";
10
+
11
+ /**
12
+ * Decrypt NIP-44 encrypted content from a sender.
13
+ *
14
+ * @param senderPubkey - Hex pubkey of the sender
15
+ * @param content - Encrypted content string
16
+ * @param signer - The private key signer to decrypt with
17
+ * @returns Decrypted plaintext string
18
+ */
19
+ export async function nip44Decrypt(
20
+ senderPubkey: string,
21
+ content: string,
22
+ signer: NDKPrivateKeySigner,
23
+ ): Promise<string> {
24
+ const sender = new NDKUser({ pubkey: senderPubkey });
25
+ return signer.decrypt(sender, content, "nip44");
26
+ }
@@ -0,0 +1,31 @@
1
+ // Agent event system
2
+
3
+ export { AgentEventDecoder } from "./AgentEventDecoder";
4
+
5
+ // Blossom upload service
6
+ export { BlossomService, calculateSHA256, getExtensionFromMimeType } from "./BlossomService";
7
+ export type {
8
+ BlossomUploadResult,
9
+ BlossomUploadOptions,
10
+ BlossomSigner,
11
+ } from "./BlossomService";
12
+ export type {
13
+ CompletionIntent,
14
+ DelegationIntent,
15
+ EventContext,
16
+ } from "./types";
17
+ export { AgentEventEncoder } from "./AgentEventEncoder";
18
+ export { AgentProfilePublisher } from "./AgentProfilePublisher";
19
+ export { AgentPublisher } from "./AgentPublisher";
20
+ export { InterventionPublisher } from "./InterventionPublisher";
21
+ export { injectTraceContext, type EventWithTags } from "./trace-context";
22
+ export { collectEvents } from "./collectEvents";
23
+ export type { CollectEventsOptions } from "./collectEvents";
24
+ export { getNDK } from "./ndkClient";
25
+ export {
26
+ getAgentSlugFromEvent,
27
+ isEventFromAgent,
28
+ isEventFromUser,
29
+ } from "./utils";
30
+ export { pubkeyFromNsec } from "./keys";
31
+ export { nip44Decrypt } from "./encryption";
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Nostr key derivation utilities
3
+ *
4
+ * This module provides helpers for working with Nostr keys.
5
+ * All NDK key operations should be centralized here to maintain architectural boundaries.
6
+ */
7
+ import { NDKPrivateKeySigner } from "@nostr-dev-kit/ndk";
8
+
9
+ /**
10
+ * Derive a public key from an nsec (private key)
11
+ * @param nsec - The private key in nsec format
12
+ * @returns The derived public key
13
+ */
14
+ export function pubkeyFromNsec(nsec: string): string {
15
+ const signer = new NDKPrivateKeySigner(nsec);
16
+ return signer.pubkey;
17
+ }
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Centralized event kind definitions for TENEX.
3
+ *
4
+ * This module extends NDK's NDKKind enum with custom Tenex event kinds.
5
+ * All kind references throughout the codebase should use this module instead
6
+ * of importing NDKKind directly or using magic numbers.
7
+ */
8
+
9
+ import { NDKKind as BaseNDKKind } from "@nostr-dev-kit/ndk";
10
+
11
+ // Re-export all base NDK kinds
12
+ export const NDKKind = {
13
+ ...BaseNDKKind,
14
+
15
+ // Standard NIP kinds
16
+ Text: 1 as BaseNDKKind, // Regular text note (kind:1) - unified conversation format
17
+ EventMetadata: 513 as BaseNDKKind, // Event metadata (titles, summaries)
18
+ Comment: 1111 as BaseNDKKind, // NIP-22 Comment - used for lesson refinements
19
+ AgentLesson: 4129 as BaseNDKKind, // Agent Lesson - learned knowledge
20
+ AgentDefinition: 4199 as BaseNDKKind, // Agent Definition
21
+ AgentNudge: 4201 as BaseNDKKind, // Agent Nudge - system prompt injection
22
+ AgentSkill: 4202 as BaseNDKKind, // Agent Skill - transient capability injection
23
+ DelegationMarker: 4203 as BaseNDKKind, // Delegation Marker - lifecycle tracking
24
+ NudgeSkillWhitelist: 14202 as BaseNDKKind, // Nudge/Skill Whitelist - NIP-51-like list of e-tagged nudges/skills
25
+ ProjectAgentSnapshot: 14199 as BaseNDKKind, // Owner-agent declaration (replaceable, p-tags agents)
26
+
27
+ // Tenex custom kinds (2xxxx range)
28
+ TenexBootProject: 24000 as BaseNDKKind, // Boot project via a-tag
29
+ TenexProjectStatus: 24010 as BaseNDKKind,
30
+ TenexAgentConfigUpdate: 24020 as BaseNDKKind,
31
+ TenexAgentDelete: 24030 as BaseNDKKind, // Agent deletion from projects or globally
32
+ TenexConfigUpdate: 25000 as BaseNDKKind, // Encrypted config updates (e.g., APNs device tokens)
33
+ TenexOperationsStatus: 24133 as BaseNDKKind,
34
+ TenexStopCommand: 24134 as BaseNDKKind,
35
+ } as const;
36
+
37
+ export type NDKKind = (typeof NDKKind)[keyof typeof NDKKind];
@@ -0,0 +1,72 @@
1
+ import { getRelayUrls } from "./relays";
2
+ import { logger } from "@/utils/logger";
3
+ /**
4
+ * TENEX CLI: NDK Singleton
5
+ * Manages a single NDK instance for the CLI
6
+ */
7
+ import NDK from "@nostr-dev-kit/ndk";
8
+
9
+ let ndk: NDK | undefined;
10
+
11
+ /**
12
+ * Initialize NDK with timeout for relay connections
13
+ * Proceeds even if relay connection fails (daemon can still function locally)
14
+ */
15
+ export async function initNDK(): Promise<void> {
16
+ if (ndk) {
17
+ // Disconnect existing instance
18
+ if (ndk.pool?.relays) {
19
+ for (const relay of ndk.pool.relays.values()) {
20
+ relay.disconnect();
21
+ }
22
+ }
23
+ }
24
+
25
+ const relays = getRelayUrls();
26
+ logger.debug(`Initializing NDK with relays: ${relays.join(", ")}`);
27
+
28
+ ndk = new NDK({
29
+ explicitRelayUrls: [...relays],
30
+ enableOutboxModel: false,
31
+ autoConnectUserRelays: true,
32
+ });
33
+
34
+ // Connect with timeout - don't block daemon startup if relays are unreachable
35
+ const connectionTimeout = 5000; // 5 seconds
36
+ try {
37
+ await Promise.race([
38
+ ndk.connect(),
39
+ new Promise((_, reject) =>
40
+ setTimeout(() => reject(new Error("Connection timeout")), connectionTimeout)
41
+ ),
42
+ ]);
43
+ logger.debug("NDK connected to relays");
44
+ } catch (error) {
45
+ logger.warn(`NDK relay connection failed or timed out after ${connectionTimeout}ms - continuing without Nostr connectivity`, {
46
+ error: error instanceof Error ? error.message : String(error),
47
+ relays,
48
+ });
49
+ // Don't throw - daemon can still function locally without Nostr
50
+ }
51
+ }
52
+
53
+ export function getNDK(): NDK {
54
+ if (!ndk) {
55
+ throw new Error(
56
+ "NDK not initialized. Please call initNDK() first or check your network configuration."
57
+ );
58
+ }
59
+ return ndk;
60
+ }
61
+
62
+ export async function shutdownNDK(): Promise<void> {
63
+ if (ndk) {
64
+ // Disconnect all relays
65
+ if (ndk.pool?.relays) {
66
+ for (const relay of ndk.pool.relays.values()) {
67
+ relay.disconnect();
68
+ }
69
+ }
70
+ ndk = undefined;
71
+ }
72
+ }