@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.
- package/README.md +194 -0
- package/dist/backend-wrapper.cjs +3 -0
- package/dist/src/index.js +331928 -0
- package/package.json +103 -0
- package/src/agents/AgentRegistry.ts +418 -0
- package/src/agents/AgentStorage.ts +1133 -0
- package/src/agents/ConfigResolver.ts +229 -0
- package/src/agents/agent-installer.ts +236 -0
- package/src/agents/agent-loader.ts +241 -0
- package/src/agents/constants.ts +82 -0
- package/src/agents/errors.ts +48 -0
- package/src/agents/execution/AgentExecutor.ts +561 -0
- package/src/agents/execution/ExecutionContextFactory.ts +112 -0
- package/src/agents/execution/MessageCompiler.ts +597 -0
- package/src/agents/execution/MessageSyncer.ts +100 -0
- package/src/agents/execution/PostCompletionChecker.ts +278 -0
- package/src/agents/execution/ProgressMonitor.ts +50 -0
- package/src/agents/execution/RALResolver.ts +177 -0
- package/src/agents/execution/SessionManager.ts +181 -0
- package/src/agents/execution/StreamCallbacks.ts +312 -0
- package/src/agents/execution/StreamExecutionHandler.ts +579 -0
- package/src/agents/execution/StreamSetup.ts +313 -0
- package/src/agents/execution/ToolEventHandlers.ts +239 -0
- package/src/agents/execution/ToolExecutionTracker.ts +498 -0
- package/src/agents/execution/ToolResultUtils.ts +97 -0
- package/src/agents/execution/ToolSupervisionWrapper.ts +174 -0
- package/src/agents/execution/constants.ts +16 -0
- package/src/agents/execution/index.ts +3 -0
- package/src/agents/execution/types.ts +96 -0
- package/src/agents/execution/utils.ts +26 -0
- package/src/agents/index.ts +4 -0
- package/src/agents/script-installer.ts +266 -0
- package/src/agents/supervision/SupervisorLLMService.ts +253 -0
- package/src/agents/supervision/SupervisorOrchestrator.ts +471 -0
- package/src/agents/supervision/heuristics/ConsecutiveToolsWithoutTodoHeuristic.ts +73 -0
- package/src/agents/supervision/heuristics/DelegationClaimHeuristic.ts +80 -0
- package/src/agents/supervision/heuristics/HeuristicRegistry.ts +114 -0
- package/src/agents/supervision/heuristics/PendingTodosHeuristic.ts +93 -0
- package/src/agents/supervision/heuristics/SilentAgentHeuristic.ts +54 -0
- package/src/agents/supervision/heuristics/index.ts +5 -0
- package/src/agents/supervision/index.ts +28 -0
- package/src/agents/supervision/registerHeuristics.ts +110 -0
- package/src/agents/supervision/supervisionHealthCheck.ts +123 -0
- package/src/agents/supervision/types.ts +171 -0
- package/src/agents/tool-names.ts +46 -0
- package/src/agents/tool-normalization.ts +184 -0
- package/src/agents/types/index.ts +2 -0
- package/src/agents/types/runtime.ts +74 -0
- package/src/agents/types/storage.ts +145 -0
- package/src/commands/agent/import/index.ts +6 -0
- package/src/commands/agent/import/openclaw-distiller.ts +57 -0
- package/src/commands/agent/import/openclaw-reader.ts +141 -0
- package/src/commands/agent/import/openclaw.ts +154 -0
- package/src/commands/agent/index.ts +6 -0
- package/src/commands/agent.ts +215 -0
- package/src/commands/daemon.ts +198 -0
- package/src/commands/doctor.ts +134 -0
- package/src/commands/setup/embed.ts +228 -0
- package/src/commands/setup/global-system-prompt.ts +223 -0
- package/src/commands/setup/image.ts +179 -0
- package/src/commands/setup/index.ts +16 -0
- package/src/commands/setup/interactive.ts +95 -0
- package/src/commands/setup/llm.ts +38 -0
- package/src/commands/setup/onboarding.ts +294 -0
- package/src/commands/setup/providers.ts +27 -0
- package/src/constants.ts +34 -0
- package/src/conversations/ConversationDiskReader.ts +148 -0
- package/src/conversations/ConversationRegistry.ts +728 -0
- package/src/conversations/ConversationStore.ts +868 -0
- package/src/conversations/MessageBuilder.ts +866 -0
- package/src/conversations/executionTime.ts +62 -0
- package/src/conversations/formatters/DelegationXmlFormatter.ts +64 -0
- package/src/conversations/formatters/ThreadedConversationFormatter.ts +303 -0
- package/src/conversations/formatters/index.ts +9 -0
- package/src/conversations/formatters/utils/MessageFormatter.ts +46 -0
- package/src/conversations/formatters/utils/TimestampFormatter.ts +56 -0
- package/src/conversations/formatters/utils/TreeBuilder.ts +131 -0
- package/src/conversations/formatters/utils/TreeRenderer.ts +49 -0
- package/src/conversations/index.ts +2 -0
- package/src/conversations/persistence/ToolMessageStorage.ts +143 -0
- package/src/conversations/search/ConversationIndexManager.ts +393 -0
- package/src/conversations/search/QueryParser.ts +114 -0
- package/src/conversations/search/SearchEngine.ts +175 -0
- package/src/conversations/search/SnippetExtractor.ts +345 -0
- package/src/conversations/search/embeddings/ConversationEmbeddingService.ts +484 -0
- package/src/conversations/search/embeddings/ConversationIndexingJob.ts +320 -0
- package/src/conversations/search/embeddings/IndexingStateManager.ts +338 -0
- package/src/conversations/search/embeddings/index.ts +18 -0
- package/src/conversations/search/index.ts +49 -0
- package/src/conversations/search/types.ts +124 -0
- package/src/conversations/services/CategoryManager.ts +160 -0
- package/src/conversations/services/ConversationResolver.ts +296 -0
- package/src/conversations/services/ConversationSummarizer.ts +234 -0
- package/src/conversations/services/MetadataDebounceManager.ts +188 -0
- package/src/conversations/services/index.ts +2 -0
- package/src/conversations/types.ts +148 -0
- package/src/conversations/utils/content-utils.ts +69 -0
- package/src/conversations/utils/image-placeholder.ts +281 -0
- package/src/conversations/utils/image-url-utils.ts +171 -0
- package/src/conversations/utils/multimodal-content.ts +90 -0
- package/src/conversations/utils/tool-result-truncator.ts +159 -0
- package/src/daemon/Daemon.ts +1883 -0
- package/src/daemon/ProjectRuntime.ts +657 -0
- package/src/daemon/RestartState.ts +152 -0
- package/src/daemon/RuntimeLifecycle.ts +268 -0
- package/src/daemon/SubscriptionManager.ts +305 -0
- package/src/daemon/UnixSocketTransport.ts +318 -0
- package/src/daemon/filters/SubscriptionFilterBuilder.ts +119 -0
- package/src/daemon/index.ts +9 -0
- package/src/daemon/routing/DaemonRouter.ts +491 -0
- package/src/daemon/types.ts +150 -0
- package/src/daemon/utils/routing-log.ts +76 -0
- package/src/daemon/utils/telemetry.ts +173 -0
- package/src/event-handler/agentDeletion.ts +383 -0
- package/src/event-handler/index.ts +749 -0
- package/src/event-handler/newConversation.ts +165 -0
- package/src/event-handler/project.ts +166 -0
- package/src/event-handler/reply.ts +18 -0
- package/src/events/NDKAgentDefinition.ts +292 -0
- package/src/events/NDKAgentLesson.ts +106 -0
- package/src/events/NDKEventMetadata.ts +34 -0
- package/src/events/NDKMCPTool.ts +60 -0
- package/src/events/NDKProjectStatus.ts +384 -0
- package/src/events/index.ts +4 -0
- package/src/index.ts +126 -0
- package/src/lib/agent-home.ts +334 -0
- package/src/lib/error-formatter.ts +200 -0
- package/src/lib/fs/filesystem.ts +128 -0
- package/src/lib/fs/index.ts +1 -0
- package/src/lib/json-parser.ts +30 -0
- package/src/lib/string.ts +15 -0
- package/src/lib/time.ts +74 -0
- package/src/llm/ChunkHandler.ts +277 -0
- package/src/llm/FinishHandler.ts +250 -0
- package/src/llm/LLMConfigEditor.ts +154 -0
- package/src/llm/LLMServiceFactory.ts +230 -0
- package/src/llm/MessageProcessor.ts +90 -0
- package/src/llm/RecordingState.ts +37 -0
- package/src/llm/StreamPublisher.ts +40 -0
- package/src/llm/TracingUtils.ts +77 -0
- package/src/llm/chunk-validators.ts +57 -0
- package/src/llm/constants.ts +6 -0
- package/src/llm/index.ts +12 -0
- package/src/llm/meta/MetaModelResolver.ts +352 -0
- package/src/llm/meta/index.ts +11 -0
- package/src/llm/middleware/flight-recorder.ts +188 -0
- package/src/llm/providers/MockProvider.ts +332 -0
- package/src/llm/providers/agent/ClaudeCodeProvider.ts +343 -0
- package/src/llm/providers/agent/ClaudeCodeToolsAdapter.ts +203 -0
- package/src/llm/providers/agent/CodexAppServerProvider.ts +214 -0
- package/src/llm/providers/agent/CodexAppServerToolsAdapter.ts +91 -0
- package/src/llm/providers/agent/index.ts +10 -0
- package/src/llm/providers/base/AgentProvider.ts +107 -0
- package/src/llm/providers/base/BaseProvider.ts +114 -0
- package/src/llm/providers/base/StandardProvider.ts +38 -0
- package/src/llm/providers/base/index.ts +9 -0
- package/src/llm/providers/index.ts +106 -0
- package/src/llm/providers/key-manager.ts +238 -0
- package/src/llm/providers/ollama-models.ts +105 -0
- package/src/llm/providers/openrouter-models.ts +102 -0
- package/src/llm/providers/provider-ids.ts +18 -0
- package/src/llm/providers/registry/ProviderRegistry.ts +414 -0
- package/src/llm/providers/registry/index.ts +7 -0
- package/src/llm/providers/standard/AnthropicProvider.ts +71 -0
- package/src/llm/providers/standard/OllamaProvider.ts +59 -0
- package/src/llm/providers/standard/OpenAIProvider.ts +44 -0
- package/src/llm/providers/standard/OpenRouterProvider.ts +103 -0
- package/src/llm/providers/standard/index.ts +10 -0
- package/src/llm/providers/types.ts +194 -0
- package/src/llm/providers/usage-metadata.ts +78 -0
- package/src/llm/service.ts +713 -0
- package/src/llm/types.ts +167 -0
- package/src/llm/utils/ConfigurationManager.ts +650 -0
- package/src/llm/utils/ConfigurationTester.ts +229 -0
- package/src/llm/utils/ModelSelector.ts +212 -0
- package/src/llm/utils/ProviderConfigUI.ts +177 -0
- package/src/llm/utils/claudeCodePromptCompiler.ts +141 -0
- package/src/llm/utils/codex-models.ts +53 -0
- package/src/llm/utils/context-window-cache.ts +30 -0
- package/src/llm/utils/models-dev-cache.ts +267 -0
- package/src/llm/utils/provider-setup.ts +50 -0
- package/src/llm/utils/tool-errors.ts +78 -0
- package/src/llm/utils/usage.ts +74 -0
- package/src/logging/EventRoutingLogger.ts +205 -0
- package/src/nostr/AgentEventDecoder.ts +357 -0
- package/src/nostr/AgentEventEncoder.ts +677 -0
- package/src/nostr/AgentProfilePublisher.ts +657 -0
- package/src/nostr/AgentPublisher.ts +437 -0
- package/src/nostr/BlossomService.ts +226 -0
- package/src/nostr/InterventionPublisher.ts +132 -0
- package/src/nostr/TagExtractor.ts +228 -0
- package/src/nostr/collectEvents.ts +83 -0
- package/src/nostr/constants.ts +38 -0
- package/src/nostr/encryption.ts +26 -0
- package/src/nostr/index.ts +31 -0
- package/src/nostr/keys.ts +17 -0
- package/src/nostr/kinds.ts +37 -0
- package/src/nostr/ndkClient.ts +72 -0
- package/src/nostr/relays.ts +43 -0
- package/src/nostr/trace-context.ts +39 -0
- package/src/nostr/types.ts +227 -0
- package/src/nostr/utils.ts +84 -0
- package/src/prompts/core/FragmentRegistry.ts +30 -0
- package/src/prompts/core/PromptBuilder.ts +98 -0
- package/src/prompts/core/index.ts +3 -0
- package/src/prompts/core/types.ts +13 -0
- package/src/prompts/fragments/00-global-system-prompt.ts +44 -0
- package/src/prompts/fragments/01-agent-identity.ts +69 -0
- package/src/prompts/fragments/02-agent-home-directory.ts +114 -0
- package/src/prompts/fragments/03-system-reminders-explanation.ts +14 -0
- package/src/prompts/fragments/04-relay-configuration.ts +38 -0
- package/src/prompts/fragments/05-delegation-chain.ts +45 -0
- package/src/prompts/fragments/06-agent-todos.ts +74 -0
- package/src/prompts/fragments/06-todo-usage-guidance.ts +34 -0
- package/src/prompts/fragments/07-meta-project-context.ts +234 -0
- package/src/prompts/fragments/08-active-conversations.ts +382 -0
- package/src/prompts/fragments/09-recent-conversations.ts +153 -0
- package/src/prompts/fragments/10-referenced-article.ts +21 -0
- package/src/prompts/fragments/11-nudges.ts +134 -0
- package/src/prompts/fragments/12-skills.ts +127 -0
- package/src/prompts/fragments/13-available-nudges.ts +122 -0
- package/src/prompts/fragments/15-available-agents.ts +53 -0
- package/src/prompts/fragments/16-stay-in-your-lane.ts +41 -0
- package/src/prompts/fragments/17-todo-before-delegation.ts +39 -0
- package/src/prompts/fragments/20-voice-mode.ts +62 -0
- package/src/prompts/fragments/22-scheduled-tasks.ts +175 -0
- package/src/prompts/fragments/24-retrieved-lessons.ts +26 -0
- package/src/prompts/fragments/25-rag-instructions.ts +333 -0
- package/src/prompts/fragments/26-mcp-resources.ts +237 -0
- package/src/prompts/fragments/27-memorized-reports.ts +77 -0
- package/src/prompts/fragments/28-agent-directed-monitoring.ts +32 -0
- package/src/prompts/fragments/29-rag-collections.ts +50 -0
- package/src/prompts/fragments/30-worktree-context.ts +98 -0
- package/src/prompts/fragments/31-agents-md-guidance.ts +96 -0
- package/src/prompts/fragments/32-process-metrics.ts +72 -0
- package/src/prompts/fragments/debug-mode.ts +48 -0
- package/src/prompts/fragments/delegation-completion.ts +44 -0
- package/src/prompts/fragments/index.ts +91 -0
- package/src/prompts/index.ts +21 -0
- package/src/prompts/utils/systemPromptBuilder.ts +777 -0
- package/src/scripts/migrate-prefix-index.ts +157 -0
- package/src/services/AgentDefinitionMonitor.ts +701 -0
- package/src/services/ConfigService.ts +723 -0
- package/src/services/CooldownRegistry.ts +199 -0
- package/src/services/LLMOperationsRegistry.ts +424 -0
- package/src/services/OwnerAgentListService.ts +354 -0
- package/src/services/PubkeyService.ts +308 -0
- package/src/services/agents/AgentMetadataStore.ts +72 -0
- package/src/services/agents/AgentResolution.ts +59 -0
- package/src/services/agents/EscalationService.ts +281 -0
- package/src/services/agents/NDKAgentDiscovery.ts +95 -0
- package/src/services/agents/index.ts +7 -0
- package/src/services/agents-md/AgentsMdService.ts +184 -0
- package/src/services/agents-md/SystemReminderInjector.ts +238 -0
- package/src/services/agents-md/index.ts +11 -0
- package/src/services/apns/APNsClient.ts +203 -0
- package/src/services/apns/APNsService.ts +358 -0
- package/src/services/apns/index.ts +11 -0
- package/src/services/apns/types.ts +80 -0
- package/src/services/compression/CompressionService.ts +445 -0
- package/src/services/compression/compression-schema.ts +28 -0
- package/src/services/compression/compression-types.ts +74 -0
- package/src/services/compression/compression-utils.ts +587 -0
- package/src/services/config/types.ts +394 -0
- package/src/services/dispatch/AgentDispatchService.ts +937 -0
- package/src/services/dispatch/AgentRouter.ts +181 -0
- package/src/services/dispatch/DelegationCompletionHandler.ts +232 -0
- package/src/services/embedding/EmbeddingProvider.ts +188 -0
- package/src/services/embedding/index.ts +5 -0
- package/src/services/event-context/EventContextService.ts +108 -0
- package/src/services/event-context/index.ts +2 -0
- package/src/services/heuristics/ContextBuilder.ts +106 -0
- package/src/services/heuristics/HeuristicEngine.ts +200 -0
- package/src/services/heuristics/formatters.ts +58 -0
- package/src/services/heuristics/index.ts +12 -0
- package/src/services/heuristics/rules/index.ts +25 -0
- package/src/services/heuristics/rules/todoBeforeDelegation.ts +69 -0
- package/src/services/heuristics/rules/todoReminderOnToolUse.ts +63 -0
- package/src/services/heuristics/types.ts +144 -0
- package/src/services/image/ImageGenerationService.ts +389 -0
- package/src/services/image/index.ts +12 -0
- package/src/services/intervention/InterventionService.ts +1352 -0
- package/src/services/intervention/index.ts +7 -0
- package/src/services/mcp/MCPManager.ts +683 -0
- package/src/services/mcp/McpNotificationDelivery.ts +139 -0
- package/src/services/mcp/McpSubscriptionService.ts +653 -0
- package/src/services/mcp/mcpInstaller.ts +130 -0
- package/src/services/nip46/Nip46SigningLog.ts +81 -0
- package/src/services/nip46/Nip46SigningService.ts +467 -0
- package/src/services/nip46/index.ts +4 -0
- package/src/services/nudge/NudgeService.ts +224 -0
- package/src/services/nudge/NudgeWhitelistService.ts +382 -0
- package/src/services/nudge/index.ts +5 -0
- package/src/services/nudge/types.ts +83 -0
- package/src/services/projects/ProjectContext.ts +672 -0
- package/src/services/projects/ProjectContextStore.ts +102 -0
- package/src/services/projects/index.ts +6 -0
- package/src/services/prompt-compiler/index.ts +15 -0
- package/src/services/prompt-compiler/prompt-compiler-service.ts +1143 -0
- package/src/services/pubkey-gate/PubkeyGateService.ts +93 -0
- package/src/services/pubkey-gate/index.ts +1 -0
- package/src/services/rag/EmbeddingProviderFactory.ts +292 -0
- package/src/services/rag/LanceDBMaintenanceService.ts +211 -0
- package/src/services/rag/RAGDatabaseService.ts +173 -0
- package/src/services/rag/RAGOperations.ts +682 -0
- package/src/services/rag/RAGService.ts +240 -0
- package/src/services/rag/RagSubscriptionService.ts +618 -0
- package/src/services/rag/rag-utils.ts +174 -0
- package/src/services/ral/PendingDelegationsRegistry.ts +168 -0
- package/src/services/ral/RALRegistry.ts +2782 -0
- package/src/services/ral/index.ts +4 -0
- package/src/services/ral/types.ts +292 -0
- package/src/services/reports/LocalReportStore.ts +380 -0
- package/src/services/reports/ReportEmbeddingService.ts +430 -0
- package/src/services/reports/ReportService.ts +440 -0
- package/src/services/reports/articleUtils.ts +52 -0
- package/src/services/reports/index.ts +7 -0
- package/src/services/scheduling/SchedulerService.ts +1057 -0
- package/src/services/scheduling/errors.ts +14 -0
- package/src/services/scheduling/index.ts +7 -0
- package/src/services/scheduling/utils.ts +77 -0
- package/src/services/search/SearchProviderRegistry.ts +78 -0
- package/src/services/search/UnifiedSearchService.ts +218 -0
- package/src/services/search/index.ts +47 -0
- package/src/services/search/projectFilter.ts +22 -0
- package/src/services/search/providers/ConversationSearchProvider.ts +48 -0
- package/src/services/search/providers/LessonSearchProvider.ts +75 -0
- package/src/services/search/providers/ReportSearchProvider.ts +49 -0
- package/src/services/search/types.ts +144 -0
- package/src/services/skill/SkillService.ts +482 -0
- package/src/services/skill/index.ts +2 -0
- package/src/services/skill/types.ts +70 -0
- package/src/services/status/OperationsStatusService.ts +276 -0
- package/src/services/status/ProjectStatusService.ts +522 -0
- package/src/services/status/index.ts +11 -0
- package/src/services/storage/PrefixKVStore.ts +242 -0
- package/src/services/storage/index.ts +1 -0
- package/src/services/system-reminder/SystemReminderUtils.ts +96 -0
- package/src/services/system-reminder/index.ts +7 -0
- package/src/services/trust-pubkeys/TrustPubkeyService.ts +325 -0
- package/src/services/trust-pubkeys/index.ts +2 -0
- package/src/telemetry/ConversationSpanManager.ts +111 -0
- package/src/telemetry/EventLoopMonitor.ts +206 -0
- package/src/telemetry/LLMSpanRegistry.ts +20 -0
- package/src/telemetry/NostrSpanProcessor.ts +89 -0
- package/src/telemetry/ToolCallSpanProcessor.ts +66 -0
- package/src/telemetry/diagnostics.ts +27 -0
- package/src/telemetry/setup.ts +120 -0
- package/src/tools/implementations/agents_discover.ts +121 -0
- package/src/tools/implementations/agents_hire.ts +127 -0
- package/src/tools/implementations/agents_list.ts +96 -0
- package/src/tools/implementations/agents_publish.ts +611 -0
- package/src/tools/implementations/agents_read.ts +173 -0
- package/src/tools/implementations/agents_write.ts +200 -0
- package/src/tools/implementations/ask.ts +411 -0
- package/src/tools/implementations/change_model.ts +141 -0
- package/src/tools/implementations/conversation_get.ts +661 -0
- package/src/tools/implementations/conversation_list.ts +377 -0
- package/src/tools/implementations/conversation_search.ts +370 -0
- package/src/tools/implementations/delegate.ts +327 -0
- package/src/tools/implementations/delegate_crossproject.ts +209 -0
- package/src/tools/implementations/delegate_followup.ts +300 -0
- package/src/tools/implementations/fs_edit.ts +162 -0
- package/src/tools/implementations/fs_glob.ts +182 -0
- package/src/tools/implementations/fs_grep.ts +513 -0
- package/src/tools/implementations/fs_read.ts +332 -0
- package/src/tools/implementations/fs_write.ts +113 -0
- package/src/tools/implementations/generate_image.ts +259 -0
- package/src/tools/implementations/home_fs.ts +515 -0
- package/src/tools/implementations/kill.ts +651 -0
- package/src/tools/implementations/learn.ts +166 -0
- package/src/tools/implementations/lesson-formatter.ts +38 -0
- package/src/tools/implementations/lesson_delete.ts +164 -0
- package/src/tools/implementations/lesson_get.ts +105 -0
- package/src/tools/implementations/lessons_list.ts +153 -0
- package/src/tools/implementations/mcp_resource_read.ts +161 -0
- package/src/tools/implementations/mcp_subscribe.ts +158 -0
- package/src/tools/implementations/mcp_subscription_stop.ts +85 -0
- package/src/tools/implementations/nostr_fetch.ts +149 -0
- package/src/tools/implementations/nostr_publish_as_user.ts +353 -0
- package/src/tools/implementations/project_list.ts +146 -0
- package/src/tools/implementations/rag_add_documents.ts +573 -0
- package/src/tools/implementations/rag_create_collection.ts +65 -0
- package/src/tools/implementations/rag_delete_collection.ts +68 -0
- package/src/tools/implementations/rag_list_collections.ts +77 -0
- package/src/tools/implementations/rag_query.ts +107 -0
- package/src/tools/implementations/rag_subscription_create.ts +105 -0
- package/src/tools/implementations/rag_subscription_delete.ts +80 -0
- package/src/tools/implementations/rag_subscription_get.ts +123 -0
- package/src/tools/implementations/rag_subscription_list.ts +128 -0
- package/src/tools/implementations/report_delete.ts +79 -0
- package/src/tools/implementations/report_read.ts +160 -0
- package/src/tools/implementations/report_write.ts +278 -0
- package/src/tools/implementations/reports_list.ts +77 -0
- package/src/tools/implementations/schedule_task.ts +104 -0
- package/src/tools/implementations/schedule_task_cancel.ts +62 -0
- package/src/tools/implementations/schedule_task_once.ts +128 -0
- package/src/tools/implementations/schedule_tasks_list.ts +79 -0
- package/src/tools/implementations/search.ts +160 -0
- package/src/tools/implementations/shell.ts +553 -0
- package/src/tools/implementations/todo.ts +260 -0
- package/src/tools/implementations/upload_blob.ts +381 -0
- package/src/tools/implementations/web_fetch.ts +153 -0
- package/src/tools/implementations/web_search.ts +250 -0
- package/src/tools/registry.ts +670 -0
- package/src/tools/types.ts +177 -0
- package/src/tools/utils.ts +256 -0
- package/src/types/event-ids.ts +320 -0
- package/src/types/index.ts +46 -0
- package/src/utils/agentFetcher.ts +107 -0
- package/src/utils/cli-error.ts +29 -0
- package/src/utils/conversation-id.ts +27 -0
- package/src/utils/conversation-utils.ts +1 -0
- package/src/utils/delegation-chain.ts +357 -0
- package/src/utils/error-handler.ts +42 -0
- package/src/utils/git/gitignore.ts +69 -0
- package/src/utils/git/index.ts +2 -0
- package/src/utils/git/initializeGitRepo.ts +204 -0
- package/src/utils/git/worktree.ts +260 -0
- package/src/utils/lessonFormatter.ts +70 -0
- package/src/utils/lessonTrust.ts +24 -0
- package/src/utils/lockfile.ts +123 -0
- package/src/utils/logger.ts +149 -0
- package/src/utils/nostr-entity-parser.ts +365 -0
- package/src/utils/process.ts +49 -0
- package/src/wrapper.ts +262 -0
- 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
|
+
}
|