@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,358 @@
1
+ /**
2
+ * APNs push notification service.
3
+ *
4
+ * Responsibilities:
5
+ * 1. Subscribe to kind 25000 events (encrypted config updates) p-tagging the backend
6
+ * 2. Decrypt NIP-44 content to extract APNs device tokens
7
+ * 3. Manage token store: Map<pubkey, Set<deviceToken>>, persisted to disk
8
+ * 4. Expose notifyIfNeeded() for the ask tool to trigger push notifications
9
+ * 5. Handle token lifecycle (register, refresh, disable, invalidation)
10
+ */
11
+
12
+ import { readJsonFile, writeJsonFile } from "@/lib/fs/filesystem";
13
+ import { getNDK } from "@/nostr/ndkClient";
14
+ import { nip44Decrypt } from "@/nostr/encryption";
15
+ import { NDKKind } from "@/nostr/kinds";
16
+ import { config } from "@/services/ConfigService";
17
+ import { logger } from "@/utils/logger";
18
+ import * as path from "node:path";
19
+ import type { NDKEvent, NDKSubscription, NDKPrivateKeySigner } from "@nostr-dev-kit/ndk";
20
+ import { APNsClient, type APNsClientConfig } from "./APNsClient";
21
+ import type { APNsPayload, APNsSendResult, ConfigUpdateContent, NotificationRequest } from "./types";
22
+
23
+ /** Minimal interface for APNs push delivery (testable). */
24
+ export interface APNsClientLike {
25
+ send(deviceToken: string, payload: APNsPayload): Promise<APNsSendResult>;
26
+ }
27
+
28
+ const LOG_PREFIX = "[APNsService]";
29
+ const TOKENS_FILENAME = "apns-tokens.json";
30
+
31
+ export class APNsService {
32
+ private static instance: APNsService | null = null;
33
+
34
+ private client: APNsClientLike | null = null;
35
+ private subscription: NDKSubscription | null = null;
36
+ private backendSigner: NDKPrivateKeySigner | null = null;
37
+
38
+ /** Factory for creating the APNs client. Overridable for testing. */
39
+ createClient: (config: APNsClientConfig) => APNsClientLike = (c) => new APNsClient(c);
40
+
41
+ /** In-memory token store: pubkey → Set<deviceToken> */
42
+ private tokenStore = new Map<string, Set<string>>();
43
+
44
+ private tokensFilePath: string;
45
+ private initialized = false;
46
+
47
+ private constructor() {
48
+ this.tokensFilePath = path.join(config.getConfigPath("data"), TOKENS_FILENAME);
49
+ }
50
+
51
+ static getInstance(): APNsService {
52
+ if (!APNsService.instance) {
53
+ APNsService.instance = new APNsService();
54
+ }
55
+ return APNsService.instance;
56
+ }
57
+
58
+ /**
59
+ * Reset the singleton (for testing).
60
+ */
61
+ static resetInstance(): void {
62
+ if (APNsService.instance) {
63
+ APNsService.instance.shutdown();
64
+ }
65
+ APNsService.instance = null;
66
+ }
67
+
68
+ /**
69
+ * Initialize the APNs service.
70
+ *
71
+ * - Reads APNs config from config.json
72
+ * - Creates the APNsClient with .p8 key
73
+ * - Subscribes to kind 25000 events for token registration
74
+ */
75
+ async initialize(): Promise<void> {
76
+ if (this.initialized) {
77
+ logger.warn(`${LOG_PREFIX} Already initialized`);
78
+ return;
79
+ }
80
+
81
+ const tenexConfig = config.getConfig();
82
+ const apnsConfig = tenexConfig.apns;
83
+
84
+ if (!apnsConfig?.enabled) {
85
+ logger.debug(`${LOG_PREFIX} Disabled (apns.enabled is false or not set)`);
86
+ return;
87
+ }
88
+
89
+ // Validate required fields
90
+ const { keyPath, keyId, teamId, bundleId } = apnsConfig;
91
+ if (!keyPath || !keyId || !teamId || !bundleId) {
92
+ logger.error(`${LOG_PREFIX} Missing required APNs config fields`, {
93
+ hasKeyPath: !!keyPath,
94
+ hasKeyId: !!keyId,
95
+ hasTeamId: !!teamId,
96
+ hasBundleId: !!bundleId,
97
+ });
98
+ return;
99
+ }
100
+
101
+ // Load persisted tokens before subscribing to new events
102
+ await this.loadTokenStore();
103
+
104
+ // Create the HTTP/2 client
105
+ const clientConfig: APNsClientConfig = {
106
+ keyPath,
107
+ keyId,
108
+ teamId,
109
+ bundleId,
110
+ production: apnsConfig.production ?? false,
111
+ };
112
+ this.client = this.createClient(clientConfig);
113
+
114
+ // Get backend signer for NIP-44 decryption
115
+ this.backendSigner = await config.getBackendSigner();
116
+ const backendPubkey = (await this.backendSigner.user()).pubkey;
117
+
118
+ // Subscribe to kind 25000 events addressed to the backend
119
+ const ndk = getNDK();
120
+ this.subscription = ndk.subscribe(
121
+ {
122
+ kinds: [NDKKind.TenexConfigUpdate as number],
123
+ "#p": [backendPubkey],
124
+ },
125
+ {
126
+ closeOnEose: false,
127
+ onEvent: (event: NDKEvent) => {
128
+ this.handleConfigUpdateEvent(event).catch((err) => {
129
+ logger.error(`${LOG_PREFIX} Error handling config update event`, {
130
+ error: err instanceof Error ? err.message : String(err),
131
+ eventId: event.id?.substring(0, 8),
132
+ });
133
+ });
134
+ },
135
+ }
136
+ );
137
+
138
+ this.initialized = true;
139
+
140
+ logger.info(`${LOG_PREFIX} Initialized`, {
141
+ production: clientConfig.production,
142
+ bundleId: clientConfig.bundleId,
143
+ backendPubkey: backendPubkey.substring(0, 8),
144
+ });
145
+ }
146
+
147
+ /**
148
+ * Handle an incoming kind 25000 config update event.
149
+ *
150
+ * Decrypts NIP-44 content and processes APNs token registration/deregistration.
151
+ */
152
+ private async handleConfigUpdateEvent(event: NDKEvent): Promise<void> {
153
+ if (!this.backendSigner) return;
154
+
155
+ const senderPubkey = event.pubkey;
156
+
157
+ try {
158
+ // Decrypt NIP-44 content via nostr layer wrapper
159
+ const decrypted = await nip44Decrypt(senderPubkey, event.content, this.backendSigner);
160
+ const content = JSON.parse(decrypted) as ConfigUpdateContent;
161
+
162
+ if (!content.notifications) {
163
+ logger.debug(`${LOG_PREFIX} Config update has no notifications section, skipping`, {
164
+ sender: senderPubkey.substring(0, 8),
165
+ });
166
+ return;
167
+ }
168
+
169
+ const { enable, apn_token } = content.notifications;
170
+
171
+ if (enable && apn_token) {
172
+ // Register or refresh token
173
+ await this.addToken(senderPubkey, apn_token);
174
+ logger.info(`${LOG_PREFIX} Registered device token`, {
175
+ sender: senderPubkey.substring(0, 8),
176
+ tokenPrefix: apn_token.substring(0, 8),
177
+ totalTokens: this.getTokenCount(senderPubkey),
178
+ });
179
+ } else if (!enable) {
180
+ // Disable: remove all tokens for this user
181
+ const removed = await this.removeAllTokens(senderPubkey);
182
+ logger.info(`${LOG_PREFIX} Disabled notifications for user`, {
183
+ sender: senderPubkey.substring(0, 8),
184
+ tokensRemoved: removed,
185
+ });
186
+ }
187
+ } catch (error) {
188
+ logger.error(`${LOG_PREFIX} Failed to process config update event`, {
189
+ error: error instanceof Error ? error.message : String(error),
190
+ sender: senderPubkey.substring(0, 8),
191
+ eventId: event.id?.substring(0, 8),
192
+ });
193
+ }
194
+ }
195
+
196
+ /**
197
+ * Send a push notification if the user has registered tokens.
198
+ *
199
+ * Called from the ask tool when the user is not connected.
200
+ * No-ops gracefully if APNs is not configured or user has no tokens.
201
+ */
202
+ async notifyIfNeeded(userPubkey: string, request: NotificationRequest): Promise<void> {
203
+ if (!this.client) return;
204
+
205
+ const tokens = this.tokenStore.get(userPubkey);
206
+ if (!tokens || tokens.size === 0) {
207
+ logger.debug(`${LOG_PREFIX} No tokens for user, skipping push`, {
208
+ user: userPubkey.substring(0, 8),
209
+ });
210
+ return;
211
+ }
212
+
213
+ const payload: APNsPayload = {
214
+ aps: {
215
+ alert: {
216
+ title: request.title,
217
+ body: request.body,
218
+ },
219
+ sound: "default",
220
+ badge: 1,
221
+ },
222
+ conversationId: request.conversationId,
223
+ eventId: request.eventId,
224
+ };
225
+
226
+ // Send to all registered tokens for this user
227
+ const invalidTokens: string[] = [];
228
+
229
+ for (const token of tokens) {
230
+ const result = await this.client.send(token, payload);
231
+
232
+ if (result.success) {
233
+ logger.info(`${LOG_PREFIX} Push notification sent`, {
234
+ user: userPubkey.substring(0, 8),
235
+ tokenPrefix: token.substring(0, 8),
236
+ });
237
+ } else if (result.statusCode === 410 || result.reason === "BadDeviceToken" || result.reason === "Unregistered") {
238
+ // Token is no longer valid
239
+ invalidTokens.push(token);
240
+ logger.warn(`${LOG_PREFIX} Removing invalid token`, {
241
+ user: userPubkey.substring(0, 8),
242
+ tokenPrefix: token.substring(0, 8),
243
+ reason: result.reason,
244
+ });
245
+ }
246
+ // Other failures are logged by APNsClient but we don't remove the token
247
+ }
248
+
249
+ // Clean up invalid tokens
250
+ for (const token of invalidTokens) {
251
+ await this.removeToken(userPubkey, token);
252
+ }
253
+ }
254
+
255
+ /**
256
+ * Check if APNs is enabled and has a client configured.
257
+ */
258
+ isEnabled(): boolean {
259
+ return this.initialized && this.client !== null;
260
+ }
261
+
262
+ /**
263
+ * Check if a user has any registered tokens.
264
+ */
265
+ hasTokens(userPubkey: string): boolean {
266
+ const tokens = this.tokenStore.get(userPubkey);
267
+ return tokens !== undefined && tokens.size > 0;
268
+ }
269
+
270
+ // =====================================================================================
271
+ // TOKEN STORE MANAGEMENT
272
+ // =====================================================================================
273
+
274
+ private async addToken(pubkey: string, token: string): Promise<void> {
275
+ let tokens = this.tokenStore.get(pubkey);
276
+ if (!tokens) {
277
+ tokens = new Set();
278
+ this.tokenStore.set(pubkey, tokens);
279
+ }
280
+ tokens.add(token);
281
+ await this.persistTokenStore();
282
+ }
283
+
284
+ private async removeToken(pubkey: string, token: string): Promise<void> {
285
+ const tokens = this.tokenStore.get(pubkey);
286
+ if (tokens) {
287
+ tokens.delete(token);
288
+ if (tokens.size === 0) {
289
+ this.tokenStore.delete(pubkey);
290
+ }
291
+ await this.persistTokenStore();
292
+ }
293
+ }
294
+
295
+ private async removeAllTokens(pubkey: string): Promise<number> {
296
+ const tokens = this.tokenStore.get(pubkey);
297
+ const count = tokens?.size ?? 0;
298
+ this.tokenStore.delete(pubkey);
299
+ if (count > 0) {
300
+ await this.persistTokenStore();
301
+ }
302
+ return count;
303
+ }
304
+
305
+ private getTokenCount(pubkey: string): number {
306
+ return this.tokenStore.get(pubkey)?.size ?? 0;
307
+ }
308
+
309
+ // =====================================================================================
310
+ // TOKEN STORE PERSISTENCE
311
+ // =====================================================================================
312
+
313
+ private async loadTokenStore(): Promise<void> {
314
+ try {
315
+ const data = await readJsonFile<Record<string, string[]>>(this.tokensFilePath);
316
+ if (!data) return;
317
+
318
+ for (const [pubkey, tokens] of Object.entries(data)) {
319
+ if (Array.isArray(tokens) && tokens.length > 0) {
320
+ this.tokenStore.set(pubkey, new Set(tokens));
321
+ }
322
+ }
323
+
324
+ logger.info(`${LOG_PREFIX} Loaded token store from disk`, {
325
+ users: this.tokenStore.size,
326
+ });
327
+ } catch (error) {
328
+ logger.warn(`${LOG_PREFIX} Failed to load token store, starting empty`, {
329
+ error: error instanceof Error ? error.message : String(error),
330
+ });
331
+ }
332
+ }
333
+
334
+ private async persistTokenStore(): Promise<void> {
335
+ const data: Record<string, string[]> = {};
336
+ for (const [pubkey, tokens] of this.tokenStore) {
337
+ data[pubkey] = [...tokens];
338
+ }
339
+ await writeJsonFile(this.tokensFilePath, data);
340
+ }
341
+
342
+ // =====================================================================================
343
+ // LIFECYCLE
344
+ // =====================================================================================
345
+
346
+ shutdown(): void {
347
+ if (this.subscription) {
348
+ this.subscription.stop();
349
+ this.subscription = null;
350
+ }
351
+ this.tokenStore.clear();
352
+ this.client = null;
353
+ this.backendSigner = null;
354
+ this.initialized = false;
355
+
356
+ logger.info(`${LOG_PREFIX} Shut down`);
357
+ }
358
+ }
@@ -0,0 +1,11 @@
1
+ export { APNsService } from "./APNsService";
2
+ export { APNsClient } from "./APNsClient";
3
+ export type { APNsClientConfig } from "./APNsClient";
4
+ export type {
5
+ APNsPayload,
6
+ APNsSendResult,
7
+ APNsAlert,
8
+ APNsAps,
9
+ ConfigUpdateContent,
10
+ NotificationRequest,
11
+ } from "./types";
@@ -0,0 +1,80 @@
1
+ /**
2
+ * APNs push notification types.
3
+ *
4
+ * Covers device token registration (via kind 25000 events),
5
+ * Apple APNs payload format, and HTTP/2 client response handling.
6
+ */
7
+
8
+ // =====================================================================================
9
+ // CONFIG UPDATE EVENT (kind 25000) — decrypted content
10
+ // =====================================================================================
11
+
12
+ /**
13
+ * Decrypted content of a kind 25000 config update event.
14
+ * The iOS client publishes this encrypted (NIP-44) to the backend's pubkey.
15
+ */
16
+ export interface ConfigUpdateContent {
17
+ notifications?: {
18
+ enable: boolean;
19
+ apn_token: string;
20
+ };
21
+ }
22
+
23
+ // =====================================================================================
24
+ // APNs PAYLOAD — sent to Apple
25
+ // =====================================================================================
26
+
27
+ /**
28
+ * APNs alert payload structure.
29
+ */
30
+ export interface APNsAlert {
31
+ title: string;
32
+ body: string;
33
+ }
34
+
35
+ /**
36
+ * The `aps` dictionary inside an APNs payload.
37
+ */
38
+ export interface APNsAps {
39
+ alert: APNsAlert;
40
+ sound: string;
41
+ badge?: number;
42
+ }
43
+
44
+ /**
45
+ * Full APNs payload sent to Apple's HTTP/2 API.
46
+ */
47
+ export interface APNsPayload {
48
+ aps: APNsAps;
49
+ conversationId?: string;
50
+ eventId?: string;
51
+ }
52
+
53
+ // =====================================================================================
54
+ // NOTIFICATION REQUEST — internal interface
55
+ // =====================================================================================
56
+
57
+ /**
58
+ * Data passed from the ask tool to APNsService.notifyIfNeeded().
59
+ */
60
+ export interface NotificationRequest {
61
+ title: string;
62
+ body: string;
63
+ conversationId: string;
64
+ eventId: string;
65
+ }
66
+
67
+ // =====================================================================================
68
+ // APNs CLIENT RESPONSE
69
+ // =====================================================================================
70
+
71
+ /**
72
+ * Result from sending a push notification via APNsClient.
73
+ */
74
+ export interface APNsSendResult {
75
+ success: boolean;
76
+ statusCode: number;
77
+ reason?: string;
78
+ /** Apple-provided timestamp when the token became invalid (for 410 Gone). */
79
+ timestampMs?: number;
80
+ }