@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,522 @@
|
|
|
1
|
+
// Status publishing interval
|
|
2
|
+
const STATUS_INTERVAL_MS = 30_000; // 30 seconds
|
|
3
|
+
|
|
4
|
+
import { DELEGATE_TOOLS, CORE_AGENT_TOOLS, CONTEXT_INJECTED_TOOLS } from "@/agents/constants";
|
|
5
|
+
import type { ScheduledTaskInfo, StatusIntent } from "@/nostr/types";
|
|
6
|
+
import { NDKKind } from "@/nostr/kinds";
|
|
7
|
+
import { getNDK } from "@/nostr/ndkClient";
|
|
8
|
+
import { config } from "@/services/ConfigService";
|
|
9
|
+
import { type ProjectContext, projectContextStore } from "@/services/projects";
|
|
10
|
+
import { getAllToolNames } from "@/tools/registry";
|
|
11
|
+
import type { ToolName } from "@/tools/types";
|
|
12
|
+
import { SchedulerService } from "@/services/scheduling/SchedulerService";
|
|
13
|
+
import { formatAnyError } from "@/lib/error-formatter";
|
|
14
|
+
import { getDefaultBranchName } from "@/utils/git/initializeGitRepo";
|
|
15
|
+
import { listWorktrees } from "@/utils/git/worktree";
|
|
16
|
+
import { logger } from "@/utils/logger";
|
|
17
|
+
import { NDKEvent, NDKPrivateKeySigner } from "@nostr-dev-kit/ndk";
|
|
18
|
+
import { join } from "path";
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* StatusPublisher handles periodic publishing of status events to Nostr.
|
|
22
|
+
*
|
|
23
|
+
* This class manages the lifecycle of status event publishing, including:
|
|
24
|
+
* - Starting and stopping the periodic publishing interval
|
|
25
|
+
* - Creating and publishing status events with agent and model information
|
|
26
|
+
* - Handling errors gracefully to ensure the main process continues
|
|
27
|
+
*
|
|
28
|
+
* Status events are published at regular intervals (STATUS_INTERVAL_MS) and include:
|
|
29
|
+
* - Project reference tags
|
|
30
|
+
* - Agent pubkeys and slugs
|
|
31
|
+
* - Model configurations
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```typescript
|
|
35
|
+
* const service = new ProjectStatusService();
|
|
36
|
+
* await service.startPublishing('/path/to/project', projectContext);
|
|
37
|
+
* // ... later
|
|
38
|
+
* service.stopPublishing();
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
export class ProjectStatusService {
|
|
42
|
+
private statusInterval?: NodeJS.Timeout;
|
|
43
|
+
private projectContext!: ProjectContext;
|
|
44
|
+
|
|
45
|
+
async startPublishing(projectPath: string, projectContext: ProjectContext): Promise<void> {
|
|
46
|
+
// Store the project context (required for daemon mode)
|
|
47
|
+
this.projectContext = projectContext;
|
|
48
|
+
|
|
49
|
+
await this.publishStatusEvent(projectPath);
|
|
50
|
+
|
|
51
|
+
this.statusInterval = setInterval(async () => {
|
|
52
|
+
// Wrap the publish in AsyncLocalStorage to ensure context is available
|
|
53
|
+
await projectContextStore.run(this.projectContext, async () => {
|
|
54
|
+
await this.publishStatusEvent(projectPath);
|
|
55
|
+
});
|
|
56
|
+
}, STATUS_INTERVAL_MS);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
stopPublishing(): void {
|
|
60
|
+
if (this.statusInterval) {
|
|
61
|
+
clearInterval(this.statusInterval);
|
|
62
|
+
this.statusInterval = undefined;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Publish a status event immediately.
|
|
68
|
+
* Use this after agent configuration changes to immediately reflect the new state.
|
|
69
|
+
*/
|
|
70
|
+
async publishImmediately(): Promise<void> {
|
|
71
|
+
if (!this.projectContext) {
|
|
72
|
+
logger.warn("Cannot publish immediately - no project context available");
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Get project path from context
|
|
77
|
+
const projectPath = this.projectContext.project.tagValue("d");
|
|
78
|
+
if (!projectPath) {
|
|
79
|
+
logger.warn("Cannot publish immediately - no project path available");
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Get the actual project base path from config
|
|
84
|
+
const projectBasePath = join(config.getProjectsBase(), projectPath);
|
|
85
|
+
|
|
86
|
+
await projectContextStore.run(this.projectContext, async () => {
|
|
87
|
+
await this.publishStatusEvent(projectBasePath);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
logger.debug("Published status event immediately after config change");
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Create a status event from the intent.
|
|
95
|
+
* Directly creates the event without depending on AgentPublisher.
|
|
96
|
+
*/
|
|
97
|
+
private createStatusEvent(intent: StatusIntent): NDKEvent {
|
|
98
|
+
const event = new NDKEvent(getNDK());
|
|
99
|
+
event.kind = NDKKind.TenexProjectStatus;
|
|
100
|
+
event.content = "";
|
|
101
|
+
|
|
102
|
+
// Use stored context (this.projectContext is always set when publishing)
|
|
103
|
+
const projectCtx = this.projectContext;
|
|
104
|
+
|
|
105
|
+
// Add project tag
|
|
106
|
+
event.tag(projectCtx.project.tagReference());
|
|
107
|
+
|
|
108
|
+
// Add p-tag for the project owner's pubkey
|
|
109
|
+
event.tag(["p", projectCtx.project.pubkey]);
|
|
110
|
+
|
|
111
|
+
// Track unique agent slugs for single-letter tags
|
|
112
|
+
const uniqueAgentSlugs = new Set<string>();
|
|
113
|
+
|
|
114
|
+
// Add agent pubkeys with PM flag for project manager
|
|
115
|
+
const pmPubkey = projectCtx.projectManager?.pubkey;
|
|
116
|
+
for (const agent of intent.agents) {
|
|
117
|
+
const tags = ["agent", agent.pubkey, agent.slug];
|
|
118
|
+
// Add "pm" flag if this is the project manager
|
|
119
|
+
if (pmPubkey && agent.pubkey === pmPubkey) {
|
|
120
|
+
tags.push("pm");
|
|
121
|
+
}
|
|
122
|
+
event.tag(tags);
|
|
123
|
+
|
|
124
|
+
// Collect unique agent slugs
|
|
125
|
+
uniqueAgentSlugs.add(agent.slug);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Add model access tags
|
|
129
|
+
for (const model of intent.models) {
|
|
130
|
+
event.tag(["model", model.slug, ...model.agents]);
|
|
131
|
+
|
|
132
|
+
// Collect agent slugs from models
|
|
133
|
+
for (const agentSlug of model.agents) {
|
|
134
|
+
uniqueAgentSlugs.add(agentSlug);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Add tool access tags
|
|
139
|
+
for (const tool of intent.tools) {
|
|
140
|
+
event.tag(["tool", tool.name, ...tool.agents]);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Add worktree tags (default branch first)
|
|
144
|
+
if (intent.worktrees && intent.worktrees.length > 0) {
|
|
145
|
+
for (const branchName of intent.worktrees) {
|
|
146
|
+
event.tag(["branch", branchName]);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Add scheduled task tags
|
|
151
|
+
// Format: ["scheduled-task", id, title, schedule, targetAgent, type, lastRunTimestamp]
|
|
152
|
+
if (intent.scheduledTasks && intent.scheduledTasks.length > 0) {
|
|
153
|
+
for (const task of intent.scheduledTasks) {
|
|
154
|
+
event.tag([
|
|
155
|
+
"scheduled-task",
|
|
156
|
+
task.id,
|
|
157
|
+
task.title,
|
|
158
|
+
task.schedule,
|
|
159
|
+
task.targetAgent,
|
|
160
|
+
task.type,
|
|
161
|
+
task.lastRun !== undefined ? String(task.lastRun) : "",
|
|
162
|
+
]);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
return event;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
private async publishStatusEvent(projectPath: string): Promise<void> {
|
|
170
|
+
try {
|
|
171
|
+
// Use stored context (this.projectContext is always set when publishing)
|
|
172
|
+
const projectCtx = this.projectContext;
|
|
173
|
+
|
|
174
|
+
// Build status intent
|
|
175
|
+
const intent: StatusIntent = {
|
|
176
|
+
type: "status",
|
|
177
|
+
agents: [],
|
|
178
|
+
models: [],
|
|
179
|
+
tools: [],
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
// Gather agent info - preserve order from NDKProject
|
|
183
|
+
{
|
|
184
|
+
// Get agent tags from project in their original order
|
|
185
|
+
const projectAgentTags = projectCtx.project.tags.filter(
|
|
186
|
+
(tag) => tag[0] === "agent" && tag[1]
|
|
187
|
+
);
|
|
188
|
+
|
|
189
|
+
// Track which agents we've already added (by slug)
|
|
190
|
+
const addedAgentSlugs = new Set<string>();
|
|
191
|
+
|
|
192
|
+
// First, add agents that have eventIds in the order they appear in the project
|
|
193
|
+
for (const agentTag of projectAgentTags) {
|
|
194
|
+
const eventId = agentTag[1];
|
|
195
|
+
|
|
196
|
+
// Find agent with matching eventId
|
|
197
|
+
for (const [agentSlug, agent] of projectCtx.agentRegistry.getAllAgentsMap()) {
|
|
198
|
+
if (agent.eventId === eventId) {
|
|
199
|
+
intent.agents.push({
|
|
200
|
+
pubkey: agent.pubkey,
|
|
201
|
+
slug: agentSlug,
|
|
202
|
+
});
|
|
203
|
+
addedAgentSlugs.add(agentSlug);
|
|
204
|
+
break;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// Then add any remaining agents (global or inline agents without eventIds)
|
|
210
|
+
for (const [agentSlug, agent] of projectCtx.agentRegistry.getAllAgentsMap()) {
|
|
211
|
+
if (!addedAgentSlugs.has(agentSlug)) {
|
|
212
|
+
intent.agents.push({
|
|
213
|
+
pubkey: agent.pubkey,
|
|
214
|
+
slug: agentSlug,
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// Gather model info
|
|
221
|
+
await this.gatherModelInfo(intent);
|
|
222
|
+
|
|
223
|
+
// Gather tool info
|
|
224
|
+
await this.gatherToolInfo(intent);
|
|
225
|
+
|
|
226
|
+
// Gather worktree info
|
|
227
|
+
await this.gatherWorktreeInfo(intent, projectPath);
|
|
228
|
+
|
|
229
|
+
// Gather scheduled task info
|
|
230
|
+
await this.gatherScheduledTaskInfo(intent);
|
|
231
|
+
|
|
232
|
+
// Create and publish the status event directly
|
|
233
|
+
const event = this.createStatusEvent(intent);
|
|
234
|
+
|
|
235
|
+
// Sign and publish with TENEX backend private key
|
|
236
|
+
try {
|
|
237
|
+
const backendPrivateKey = await config.ensureBackendPrivateKey();
|
|
238
|
+
const backendSigner = new NDKPrivateKeySigner(backendPrivateKey);
|
|
239
|
+
|
|
240
|
+
await event.sign(backendSigner, { pTags: false });
|
|
241
|
+
await event.publish();
|
|
242
|
+
} catch (error) {
|
|
243
|
+
logger.error("Failed to sign and publish status event", {
|
|
244
|
+
error: formatAnyError(error),
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
} catch (err) {
|
|
248
|
+
const errorMessage = formatAnyError(err);
|
|
249
|
+
logger.warn(`Failed to publish status event: ${errorMessage}`);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
private async gatherModelInfo(intent: StatusIntent): Promise<void> {
|
|
254
|
+
try {
|
|
255
|
+
const { llms } = await config.loadConfig();
|
|
256
|
+
|
|
257
|
+
if (!llms || !llms.configurations) {
|
|
258
|
+
logger.debug("No LLM configurations found");
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// Build a map of configuration slugs to agents that use them
|
|
263
|
+
const configToAgents = new Map<string, Set<string>>();
|
|
264
|
+
|
|
265
|
+
// First, add ALL configured models (even if not used by any agent)
|
|
266
|
+
for (const configSlug of Object.keys(llms.configurations)) {
|
|
267
|
+
configToAgents.set(configSlug, new Set());
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
logger.debug(`Found ${Object.keys(llms.configurations).length} LLM configurations`);
|
|
271
|
+
logger.debug(`Global default configuration: ${llms.default || "none"}`);
|
|
272
|
+
|
|
273
|
+
// Process agent-specific configurations
|
|
274
|
+
if (this.projectContext) {
|
|
275
|
+
const projectCtx = this.projectContext;
|
|
276
|
+
|
|
277
|
+
// Get the global default configuration name
|
|
278
|
+
const globalDefault = llms.default;
|
|
279
|
+
|
|
280
|
+
// Map each agent to its configuration
|
|
281
|
+
const agentsList = Array.from(projectCtx.agentRegistry.getAllAgentsMap().keys());
|
|
282
|
+
logger.debug(
|
|
283
|
+
`Mapping ${agentsList.length} agents to configurations: ${agentsList.join(", ")}`
|
|
284
|
+
);
|
|
285
|
+
|
|
286
|
+
for (const [agentSlug, agent] of projectCtx.agentRegistry.getAllAgentsMap()) {
|
|
287
|
+
// Check if agent has a specific llmConfig
|
|
288
|
+
const agentConfig = agent.llmConfig;
|
|
289
|
+
|
|
290
|
+
if (agentConfig && llms.configurations[agentConfig]) {
|
|
291
|
+
// Agent has a specific configuration that exists
|
|
292
|
+
configToAgents.get(agentConfig)?.add(agentSlug);
|
|
293
|
+
logger.debug(
|
|
294
|
+
`Agent '${agentSlug}' mapped to specific configuration '${agentConfig}'`
|
|
295
|
+
);
|
|
296
|
+
} else if (globalDefault && llms.configurations[globalDefault]) {
|
|
297
|
+
// Fall back to global default configuration
|
|
298
|
+
configToAgents.get(globalDefault)?.add(agentSlug);
|
|
299
|
+
logger.debug(
|
|
300
|
+
`Agent '${agentSlug}' mapped to default configuration '${globalDefault}'`
|
|
301
|
+
);
|
|
302
|
+
} else {
|
|
303
|
+
logger.debug(
|
|
304
|
+
`Agent '${agentSlug}' not mapped - no valid configuration found (agent config: ${agentConfig}, default: ${globalDefault})`
|
|
305
|
+
);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
// Add models to intent
|
|
311
|
+
for (const [configSlug, agentSet] of configToAgents) {
|
|
312
|
+
const agentSlugs = Array.from(agentSet).sort(); // Sort for consistency
|
|
313
|
+
logger.debug(
|
|
314
|
+
`Configuration '${configSlug}' has ${agentSlugs.length} agents: ${agentSlugs.join(", ")}`
|
|
315
|
+
);
|
|
316
|
+
intent.models.push({
|
|
317
|
+
slug: configSlug,
|
|
318
|
+
agents: agentSlugs,
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
} catch (err) {
|
|
322
|
+
logger.warn(
|
|
323
|
+
`Could not load LLM information for status event model tags: ${formatAnyError(err)}`
|
|
324
|
+
);
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
private async gatherToolInfo(intent: StatusIntent): Promise<void> {
|
|
329
|
+
try {
|
|
330
|
+
if (!this.projectContext) {
|
|
331
|
+
logger.warn("ProjectContext not initialized for tool tags");
|
|
332
|
+
return;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
const projectCtx = this.projectContext;
|
|
336
|
+
const toolAgentMap = new Map<string, Set<string>>();
|
|
337
|
+
|
|
338
|
+
// First, add ALL tool names from the registry (except excluded tools)
|
|
339
|
+
const allToolNames = getAllToolNames();
|
|
340
|
+
for (const toolName of allToolNames) {
|
|
341
|
+
// Skip delegate tools, core tools, and context-injected tools from TenexProjectStatus events
|
|
342
|
+
// These are handled automatically by the system and not configurable per-agent
|
|
343
|
+
if (
|
|
344
|
+
!DELEGATE_TOOLS.includes(toolName) &&
|
|
345
|
+
!CORE_AGENT_TOOLS.includes(toolName) &&
|
|
346
|
+
!CONTEXT_INJECTED_TOOLS.includes(toolName)
|
|
347
|
+
) {
|
|
348
|
+
toolAgentMap.set(toolName, new Set());
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
// Add all MCP tools from running servers (with empty agent sets initially)
|
|
353
|
+
// Agents will be added to their MCP tools in the loop below
|
|
354
|
+
// Note: mcp__tenex__* tools are filtered out - these are internal TENEX tools
|
|
355
|
+
// wrapped through MCP and should not be announced in status events
|
|
356
|
+
// We also track valid MCP tools to filter agent definitions later
|
|
357
|
+
const validMcpToolNames = new Set<string>();
|
|
358
|
+
if (projectCtx.mcpManager) {
|
|
359
|
+
try {
|
|
360
|
+
const mcpTools = projectCtx.mcpManager.getCachedTools();
|
|
361
|
+
for (const toolName of Object.keys(mcpTools)) {
|
|
362
|
+
// Filter out mcp__tenex__* tools - internal TENEX MCP wrapper tools
|
|
363
|
+
if (toolName && !toolName.startsWith("mcp__tenex__")) {
|
|
364
|
+
validMcpToolNames.add(toolName);
|
|
365
|
+
if (!toolAgentMap.has(toolName)) {
|
|
366
|
+
toolAgentMap.set(toolName, new Set());
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
} catch {
|
|
371
|
+
// MCP tools might not be available yet, that's okay
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
// Then build a map of tool name -> set of agent slugs that have access
|
|
376
|
+
for (const [agentSlug, agent] of projectCtx.agentRegistry.getAllAgentsMap()) {
|
|
377
|
+
// Get the agent's configured tools
|
|
378
|
+
const agentTools = agent.tools || [];
|
|
379
|
+
|
|
380
|
+
for (const toolName of agentTools) {
|
|
381
|
+
// Skip invalid tool names
|
|
382
|
+
if (!toolName) {
|
|
383
|
+
logger.warn(`Agent ${agentSlug} has invalid tool name: ${toolName}`);
|
|
384
|
+
continue;
|
|
385
|
+
}
|
|
386
|
+
// Skip delegate tools, core tools, and context-injected tools - they're not included in TenexProjectStatus events
|
|
387
|
+
// These are handled automatically by the system
|
|
388
|
+
if (
|
|
389
|
+
DELEGATE_TOOLS.includes(toolName as ToolName) ||
|
|
390
|
+
CORE_AGENT_TOOLS.includes(toolName as ToolName) ||
|
|
391
|
+
CONTEXT_INJECTED_TOOLS.includes(toolName as ToolName)
|
|
392
|
+
) {
|
|
393
|
+
continue;
|
|
394
|
+
}
|
|
395
|
+
// For MCP tools, only include if they exist in running MCP servers
|
|
396
|
+
// This prevents announcing MCP tools in agent definitions that aren't actually available
|
|
397
|
+
// Note: mcp__tenex__* tools are already excluded from validMcpToolNames
|
|
398
|
+
if (toolName.startsWith("mcp__") && !validMcpToolNames.has(toolName)) {
|
|
399
|
+
continue;
|
|
400
|
+
}
|
|
401
|
+
const toolAgents = toolAgentMap.get(toolName);
|
|
402
|
+
if (toolAgents) {
|
|
403
|
+
toolAgents.add(agentSlug);
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
// Convert the map to tool entries
|
|
409
|
+
// Include ALL tools with valid names, even if no agents are assigned
|
|
410
|
+
for (const [toolName, agentSlugs] of toolAgentMap) {
|
|
411
|
+
if (toolName) {
|
|
412
|
+
const agentArray = Array.from(agentSlugs).sort(); // Sort for consistency
|
|
413
|
+
intent.tools.push({
|
|
414
|
+
name: toolName,
|
|
415
|
+
agents: agentArray, // Can be empty array for unassigned tools
|
|
416
|
+
});
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
} catch (err) {
|
|
420
|
+
logger.warn(`Could not add tool tags to status event: ${formatAnyError(err)}`);
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
private async gatherWorktreeInfo(intent: StatusIntent, projectPath: string): Promise<void> {
|
|
425
|
+
try {
|
|
426
|
+
// Get all worktrees
|
|
427
|
+
const worktrees = await listWorktrees(projectPath);
|
|
428
|
+
|
|
429
|
+
if (worktrees.length === 0) {
|
|
430
|
+
logger.debug("No worktrees found for project", { projectPath });
|
|
431
|
+
return;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
// Get the default branch name (current branch of main worktree)
|
|
435
|
+
const defaultBranch = await getDefaultBranchName(projectPath);
|
|
436
|
+
|
|
437
|
+
// Build worktree list with default branch first
|
|
438
|
+
const worktreeList: string[] = [];
|
|
439
|
+
|
|
440
|
+
// Find and add default branch first
|
|
441
|
+
const defaultWorktree = worktrees.find((wt) => wt.branch === defaultBranch);
|
|
442
|
+
if (defaultWorktree) {
|
|
443
|
+
worktreeList.push(defaultWorktree.branch);
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
// Add remaining worktrees sorted alphabetically
|
|
447
|
+
const remainingWorktrees = worktrees
|
|
448
|
+
.filter((wt) => wt.branch !== defaultBranch)
|
|
449
|
+
.map((wt) => wt.branch)
|
|
450
|
+
.sort();
|
|
451
|
+
|
|
452
|
+
worktreeList.push(...remainingWorktrees);
|
|
453
|
+
|
|
454
|
+
logger.debug("Gathered worktrees for status", {
|
|
455
|
+
total: worktreeList.length,
|
|
456
|
+
default: defaultBranch,
|
|
457
|
+
worktrees: worktreeList,
|
|
458
|
+
});
|
|
459
|
+
|
|
460
|
+
intent.worktrees = worktreeList;
|
|
461
|
+
} catch (err) {
|
|
462
|
+
logger.warn(`Could not gather worktree information: ${formatAnyError(err)}`);
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
/**
|
|
467
|
+
* Gather scheduled task information into the status intent.
|
|
468
|
+
* Exposed for testability — not intended for external use.
|
|
469
|
+
*/
|
|
470
|
+
async gatherScheduledTaskInfo(intent: StatusIntent): Promise<void> {
|
|
471
|
+
try {
|
|
472
|
+
const projectCtx = this.projectContext;
|
|
473
|
+
const projectTagId = projectCtx.project.tagId();
|
|
474
|
+
|
|
475
|
+
if (!projectTagId) {
|
|
476
|
+
logger.debug("No project tagId available for scheduled task gathering");
|
|
477
|
+
return;
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
const scheduler = SchedulerService.getInstance();
|
|
481
|
+
const tasks = await scheduler.getTasks(projectTagId);
|
|
482
|
+
|
|
483
|
+
if (tasks.length === 0) {
|
|
484
|
+
logger.debug("No scheduled tasks for project", { projectTagId });
|
|
485
|
+
return;
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
// Build a pubkey-to-slug map from agents for resolving toPubkey
|
|
489
|
+
const pubkeyToSlug = new Map<string, string>();
|
|
490
|
+
for (const [slug, agent] of projectCtx.agentRegistry.getAllAgentsMap()) {
|
|
491
|
+
pubkeyToSlug.set(agent.pubkey, slug);
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
const scheduledTasks: ScheduledTaskInfo[] = [];
|
|
495
|
+
|
|
496
|
+
for (const task of tasks) {
|
|
497
|
+
const targetAgent = pubkeyToSlug.get(task.toPubkey) || task.toPubkey.substring(0, 8);
|
|
498
|
+
const lastRunTimestamp = task.lastRun
|
|
499
|
+
? Math.floor(new Date(task.lastRun).getTime() / 1000)
|
|
500
|
+
: undefined;
|
|
501
|
+
|
|
502
|
+
scheduledTasks.push({
|
|
503
|
+
id: task.id,
|
|
504
|
+
title: task.title || task.prompt.substring(0, 50),
|
|
505
|
+
schedule: task.schedule,
|
|
506
|
+
targetAgent,
|
|
507
|
+
type: task.type || "cron",
|
|
508
|
+
lastRun: lastRunTimestamp,
|
|
509
|
+
});
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
intent.scheduledTasks = scheduledTasks;
|
|
513
|
+
|
|
514
|
+
logger.debug("Gathered scheduled tasks for status", {
|
|
515
|
+
total: scheduledTasks.length,
|
|
516
|
+
projectTagId,
|
|
517
|
+
});
|
|
518
|
+
} catch (err) {
|
|
519
|
+
logger.warn(`Could not gather scheduled task information: ${formatAnyError(err)}`);
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Status Publishing Services
|
|
3
|
+
*
|
|
4
|
+
* Handles broadcasting of status events for daemon, projects, and operations
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
// Project status (single project context)
|
|
8
|
+
export { ProjectStatusService } from "./ProjectStatusService";
|
|
9
|
+
|
|
10
|
+
// Operations status (LLM operations)
|
|
11
|
+
export { OperationsStatusService } from "./OperationsStatusService";
|