opencode-orchestrator 1.2.71 → 1.3.4
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/LICENSE +21 -21
- package/README.md +444 -355
- package/bin/orchestrator-linux-arm64 +0 -0
- package/bin/orchestrator-linux-x64 +0 -0
- package/dist/agents/commander.d.ts +0 -0
- package/dist/agents/definitions.d.ts +0 -0
- package/dist/agents/prompts/01_philosophy/anti_hallucination.d.ts +0 -0
- package/dist/agents/prompts/01_philosophy/core.d.ts +0 -0
- package/dist/agents/prompts/01_philosophy/execution_assurance.d.ts +0 -0
- package/dist/agents/prompts/01_philosophy/index.d.ts +0 -0
- package/dist/agents/prompts/01_philosophy/metadata.d.ts +0 -0
- package/dist/agents/prompts/01_philosophy/modularity.d.ts +0 -0
- package/dist/agents/prompts/02_discovery/agents/discovery_commander.d.ts +0 -0
- package/dist/agents/prompts/02_discovery/agents/discovery_planner.d.ts +0 -0
- package/dist/agents/prompts/02_discovery/agents/index.d.ts +0 -0
- package/dist/agents/prompts/02_discovery/discovery_core.d.ts +0 -0
- package/dist/agents/prompts/02_discovery/discovery_environment.d.ts +0 -0
- package/dist/agents/prompts/02_discovery/discovery_skills.d.ts +0 -0
- package/dist/agents/prompts/02_discovery/discovery_workspace.d.ts +0 -0
- package/dist/agents/prompts/02_discovery/index.d.ts +0 -0
- package/dist/agents/prompts/03_planning/agents/index.d.ts +0 -0
- package/dist/agents/prompts/03_planning/agents/planning_commander.d.ts +0 -0
- package/dist/agents/prompts/03_planning/agents/planning_planner.d.ts +0 -0
- package/dist/agents/prompts/03_planning/agents/planning_reviewer.d.ts +0 -0
- package/dist/agents/prompts/03_planning/index.d.ts +0 -0
- package/dist/agents/prompts/03_planning/planning_core.d.ts +0 -0
- package/dist/agents/prompts/03_planning/planning_decomposition.d.ts +0 -0
- package/dist/agents/prompts/03_planning/planning_file_planning.d.ts +0 -0
- package/dist/agents/prompts/03_planning/planning_parallel.d.ts +0 -0
- package/dist/agents/prompts/03_planning/planning_research.d.ts +0 -0
- package/dist/agents/prompts/03_planning/planning_todo_format.d.ts +0 -0
- package/dist/agents/prompts/03_planning/planning_todo_rules.d.ts +0 -0
- package/dist/agents/prompts/03_planning/planning_todo_sync.d.ts +0 -0
- package/dist/agents/prompts/04_execution/agents/execution_commander.d.ts +0 -0
- package/dist/agents/prompts/04_execution/agents/execution_worker.d.ts +0 -0
- package/dist/agents/prompts/04_execution/agents/index.d.ts +0 -0
- package/dist/agents/prompts/04_execution/execution_core.d.ts +0 -0
- package/dist/agents/prompts/04_execution/execution_delegation.d.ts +0 -0
- package/dist/agents/prompts/04_execution/execution_error_handling.d.ts +0 -0
- package/dist/agents/prompts/04_execution/execution_file_assignment.d.ts +0 -0
- package/dist/agents/prompts/04_execution/execution_hyper_parallel.d.ts +0 -0
- package/dist/agents/prompts/04_execution/execution_isolation.d.ts +0 -0
- package/dist/agents/prompts/04_execution/execution_quality.d.ts +0 -0
- package/dist/agents/prompts/04_execution/execution_strategy.d.ts +0 -0
- package/dist/agents/prompts/04_execution/execution_tdd.d.ts +0 -0
- package/dist/agents/prompts/04_execution/execution_workflow.d.ts +0 -0
- package/dist/agents/prompts/04_execution/index.d.ts +0 -0
- package/dist/agents/prompts/05_verification/agents/index.d.ts +0 -0
- package/dist/agents/prompts/05_verification/agents/verification_commander.d.ts +0 -0
- package/dist/agents/prompts/05_verification/agents/verification_reviewer.d.ts +0 -0
- package/dist/agents/prompts/05_verification/index.d.ts +0 -0
- package/dist/agents/prompts/05_verification/verification_async_monitoring.d.ts +0 -0
- package/dist/agents/prompts/05_verification/verification_build.d.ts +0 -0
- package/dist/agents/prompts/05_verification/verification_core.d.ts +0 -0
- package/dist/agents/prompts/05_verification/verification_evidence.d.ts +0 -0
- package/dist/agents/prompts/05_verification/verification_integration.d.ts +0 -0
- package/dist/agents/prompts/05_verification/verification_strategy.d.ts +0 -0
- package/dist/agents/prompts/05_verification/verification_sync_check.d.ts +0 -0
- package/dist/agents/prompts/05_verification/verification_sync_handling.d.ts +0 -0
- package/dist/agents/prompts/05_verification/verification_test.d.ts +0 -0
- package/dist/agents/prompts/06_mission/agents/index.d.ts +0 -0
- package/dist/agents/prompts/06_mission/agents/mission_commander.d.ts +0 -0
- package/dist/agents/prompts/06_mission/index.d.ts +0 -0
- package/dist/agents/prompts/06_mission/mission_completion_conditions.d.ts +0 -0
- package/dist/agents/prompts/06_mission/mission_core.d.ts +0 -0
- package/dist/agents/prompts/06_mission/mission_lifecycle.d.ts +0 -0
- package/dist/agents/prompts/06_mission/mission_loop_continuation.d.ts +0 -0
- package/dist/agents/prompts/06_mission/mission_recovery.d.ts +0 -0
- package/dist/agents/prompts/06_mission/mission_status_tracking.d.ts +0 -0
- package/dist/agents/prompts/07_agents/commander/commander_forbidden.d.ts +0 -0
- package/dist/agents/prompts/07_agents/commander/commander_identity.d.ts +0 -0
- package/dist/agents/prompts/07_agents/commander/commander_mandate.d.ts +0 -0
- package/dist/agents/prompts/07_agents/commander/commander_required.d.ts +0 -0
- package/dist/agents/prompts/07_agents/commander/commander_role.d.ts +0 -0
- package/dist/agents/prompts/07_agents/commander/index.d.ts +0 -0
- package/dist/agents/prompts/07_agents/planner/index.d.ts +0 -0
- package/dist/agents/prompts/07_agents/planner/planner_forbidden.d.ts +0 -0
- package/dist/agents/prompts/07_agents/planner/planner_identity.d.ts +0 -0
- package/dist/agents/prompts/07_agents/planner/planner_mandate.d.ts +0 -0
- package/dist/agents/prompts/07_agents/planner/planner_required.d.ts +0 -0
- package/dist/agents/prompts/07_agents/reviewer/index.d.ts +0 -0
- package/dist/agents/prompts/07_agents/reviewer/reviewer_forbidden.d.ts +0 -0
- package/dist/agents/prompts/07_agents/reviewer/reviewer_identity.d.ts +0 -0
- package/dist/agents/prompts/07_agents/reviewer/reviewer_mandate.d.ts +0 -0
- package/dist/agents/prompts/07_agents/reviewer/reviewer_required.d.ts +0 -0
- package/dist/agents/prompts/07_agents/worker/index.d.ts +0 -0
- package/dist/agents/prompts/07_agents/worker/worker_forbidden.d.ts +0 -0
- package/dist/agents/prompts/07_agents/worker/worker_identity.d.ts +0 -0
- package/dist/agents/prompts/07_agents/worker/worker_mandate.d.ts +0 -0
- package/dist/agents/prompts/07_agents/worker/worker_required.d.ts +0 -0
- package/dist/agents/prompts/08_tools/agents/index.d.ts +0 -0
- package/dist/agents/prompts/08_tools/agents/tools_reviewer.d.ts +0 -0
- package/dist/agents/prompts/08_tools/agents/tools_worker.d.ts +0 -0
- package/dist/agents/prompts/08_tools/index.d.ts +0 -0
- package/dist/agents/prompts/08_tools/tools_ast.d.ts +0 -0
- package/dist/agents/prompts/08_tools/tools_code_editing.d.ts +0 -0
- package/dist/agents/prompts/08_tools/tools_core.d.ts +0 -0
- package/dist/agents/prompts/08_tools/tools_lsp.d.ts +0 -0
- package/dist/agents/prompts/08_tools/tools_search.d.ts +0 -0
- package/dist/agents/prompts/08_tools/tools_testing.d.ts +0 -0
- package/dist/agents/prompts/index.d.ts +0 -0
- package/dist/agents/subagents/planner.d.ts +0 -0
- package/dist/agents/subagents/reviewer.d.ts +0 -0
- package/dist/agents/subagents/worker.d.ts +0 -0
- package/dist/core/agents/agent-registry.d.ts +0 -0
- package/dist/core/agents/concurrency-config.d.ts +4 -0
- package/dist/core/agents/concurrency-token.d.ts +0 -0
- package/dist/core/agents/concurrency.d.ts +2 -0
- package/dist/core/agents/config.d.ts +0 -0
- package/dist/core/agents/consts/index.d.ts +0 -0
- package/dist/core/agents/consts/task-status.const.d.ts +0 -0
- package/dist/core/agents/format.d.ts +0 -0
- package/dist/core/agents/index.d.ts +0 -0
- package/dist/core/agents/interfaces/index.d.ts +0 -0
- package/dist/core/agents/interfaces/launch-input.interface.d.ts +0 -0
- package/dist/core/agents/interfaces/resume-input.interface.d.ts +0 -0
- package/dist/core/agents/interfaces/session-pool.interface.d.ts +0 -0
- package/dist/core/agents/logger.d.ts +0 -0
- package/dist/core/agents/manager/event-handler.d.ts +0 -0
- package/dist/core/agents/manager/index.d.ts +0 -0
- package/dist/core/agents/manager/task-cleaner.d.ts +0 -0
- package/dist/core/agents/manager/task-launcher.d.ts +0 -0
- package/dist/core/agents/manager/task-poller.d.ts +0 -0
- package/dist/core/agents/manager/task-resumer.d.ts +0 -0
- package/dist/core/agents/manager.d.ts +3 -1
- package/dist/core/agents/persistence/task-wal.d.ts +0 -0
- package/dist/core/agents/session-pool.d.ts +0 -0
- package/dist/core/agents/task-store.d.ts +0 -0
- package/dist/core/agents/types/index.d.ts +0 -0
- package/dist/core/agents/types/parallel-task-status.type.d.ts +0 -0
- package/dist/core/cache/constants.d.ts +0 -0
- package/dist/core/cache/document-cache.d.ts +0 -0
- package/dist/core/cache/index.d.ts +0 -0
- package/dist/core/cache/interfaces/cache-document-entry.d.ts +0 -0
- package/dist/core/cache/interfaces/cache-list-entry.d.ts +0 -0
- package/dist/core/cache/interfaces/cache-metadata.d.ts +0 -0
- package/dist/core/cache/interfaces/cache-stats.d.ts +0 -0
- package/dist/core/cache/interfaces/cached-document.d.ts +0 -0
- package/dist/core/cache/interfaces/index.d.ts +0 -0
- package/dist/core/cache/interfaces.d.ts +0 -0
- package/dist/core/cache/operations.d.ts +0 -0
- package/dist/core/cache/utils.d.ts +0 -0
- package/dist/core/cleanup/cleanup-scheduler.d.ts +0 -0
- package/dist/core/commands/index.d.ts +0 -0
- package/dist/core/commands/interfaces/background-task.d.ts +0 -0
- package/dist/core/commands/interfaces/index.d.ts +0 -0
- package/dist/core/commands/interfaces/run-background-options.d.ts +0 -0
- package/dist/core/commands/manager.d.ts +0 -0
- package/dist/core/commands/types/background-task-status.d.ts +0 -0
- package/dist/core/commands/types/index.d.ts +0 -0
- package/dist/core/config/plugin-options.d.ts +9 -0
- package/dist/core/context/context-window-monitor.d.ts +0 -0
- package/dist/core/context/index.d.ts +0 -0
- package/dist/core/knowledge/context-provider.d.ts +8 -0
- package/dist/core/knowledge/graph-parser.d.ts +39 -0
- package/dist/core/knowledge/hybrid-search.d.ts +65 -0
- package/dist/core/knowledge/index.d.ts +16 -0
- package/dist/core/knowledge/memory-consolidation.d.ts +38 -0
- package/dist/core/knowledge/mission-memory.d.ts +4 -0
- package/dist/core/knowledge/safety-guards.d.ts +39 -0
- package/dist/core/knowledge/scratchpad.d.ts +38 -0
- package/dist/core/knowledge/tag-indexer.d.ts +73 -0
- package/dist/core/loop/circuit-breaker.d.ts +0 -0
- package/dist/core/loop/compaction-guard.d.ts +0 -0
- package/dist/core/loop/formatters.d.ts +0 -0
- package/dist/core/loop/interfaces/index.d.ts +0 -0
- package/dist/core/loop/interfaces/todo-stats.d.ts +0 -0
- package/dist/core/loop/interfaces/todo.d.ts +0 -0
- package/dist/core/loop/interfaces.d.ts +0 -0
- package/dist/core/loop/mission-ledger.d.ts +17 -0
- package/dist/core/loop/mission-loop-handler.d.ts +0 -0
- package/dist/core/loop/mission-loop.d.ts +7 -1
- package/dist/core/loop/mission-runtime-options.d.ts +8 -0
- package/dist/core/loop/parser.d.ts +0 -0
- package/dist/core/loop/progress-tracker.d.ts +0 -0
- package/dist/core/loop/session-state-store.d.ts +0 -0
- package/dist/core/loop/stats.d.ts +0 -0
- package/dist/core/loop/todo-continuation.d.ts +0 -0
- package/dist/core/loop/todo-enforcer.d.ts +0 -0
- package/dist/core/loop/todo-manager.d.ts +0 -0
- package/dist/core/loop/types/index.d.ts +0 -0
- package/dist/core/loop/types/todo-priority.d.ts +0 -0
- package/dist/core/loop/types/todo-status.d.ts +0 -0
- package/dist/core/loop/verification.d.ts +0 -0
- package/dist/core/memory/interfaces.d.ts +0 -0
- package/dist/core/memory/memory-manager.d.ts +0 -0
- package/dist/core/metrics/collector.d.ts +0 -0
- package/dist/core/notification/os-notify/index.d.ts +0 -0
- package/dist/core/notification/os-notify/notifier.d.ts +0 -0
- package/dist/core/notification/os-notify/platform-resolver.d.ts +0 -0
- package/dist/core/notification/os-notify/platform.d.ts +0 -0
- package/dist/core/notification/os-notify/sound-player.d.ts +0 -0
- package/dist/core/notification/os-notify/todo-checker.d.ts +0 -0
- package/dist/core/notification/task-toast-manager.d.ts +0 -0
- package/dist/core/notification/toast-core.d.ts +0 -0
- package/dist/core/notification/toast-sanitizer.d.ts +0 -0
- package/dist/core/notification/toast.d.ts +0 -0
- package/dist/core/orchestrator/index.d.ts +0 -0
- package/dist/core/orchestrator/interfaces/index.d.ts +0 -0
- package/dist/core/orchestrator/interfaces/session-state.d.ts +0 -0
- package/dist/core/orchestrator/session-manager.d.ts +0 -0
- package/dist/core/orchestrator/state.d.ts +0 -0
- package/dist/core/orchestrator/types/index.d.ts +0 -0
- package/dist/core/orchestrator/types/task-status.d.ts +0 -0
- package/dist/core/plugins/interfaces.d.ts +0 -0
- package/dist/core/plugins/plugin-manager.d.ts +0 -0
- package/dist/core/pool/buffer-pool.d.ts +0 -0
- package/dist/core/pool/object-pool.d.ts +0 -0
- package/dist/core/pool/string-pool.d.ts +0 -0
- package/dist/core/pool/task-pool.d.ts +0 -0
- package/dist/core/progress/calculator.d.ts +0 -0
- package/dist/core/progress/formatters.d.ts +0 -0
- package/dist/core/progress/interfaces/index.d.ts +0 -0
- package/dist/core/progress/interfaces/progress-snapshot.d.ts +0 -0
- package/dist/core/progress/interfaces/snapshot-input.d.ts +0 -0
- package/dist/core/progress/interfaces/step-progress.d.ts +0 -0
- package/dist/core/progress/interfaces/task-progress.d.ts +0 -0
- package/dist/core/progress/interfaces/todo-progress.d.ts +0 -0
- package/dist/core/progress/interfaces.d.ts +0 -0
- package/dist/core/progress/progress-notifier.d.ts +0 -0
- package/dist/core/progress/state-broadcaster.d.ts +0 -0
- package/dist/core/progress/store.d.ts +0 -0
- package/dist/core/progress/tracker.d.ts +0 -0
- package/dist/core/queue/async-queue.d.ts +0 -0
- package/dist/core/queue/async-utils.d.ts +0 -0
- package/dist/core/queue/index.d.ts +0 -0
- package/dist/core/queue/work-pool.d.ts +0 -0
- package/dist/core/queue/work-stealing-deque.d.ts +0 -0
- package/dist/core/queue/worker-pool.d.ts +0 -0
- package/dist/core/recovery/auto-recovery.d.ts +0 -0
- package/dist/core/recovery/constants.d.ts +0 -0
- package/dist/core/recovery/handler.d.ts +0 -0
- package/dist/core/recovery/interfaces/error-context.d.ts +0 -0
- package/dist/core/recovery/interfaces/error-pattern.d.ts +0 -0
- package/dist/core/recovery/interfaces/index.d.ts +0 -0
- package/dist/core/recovery/interfaces/recovery-action.d.ts +0 -0
- package/dist/core/recovery/interfaces/recovery-record.d.ts +0 -0
- package/dist/core/recovery/interfaces/recovery-stats.d.ts +0 -0
- package/dist/core/recovery/interfaces.d.ts +0 -0
- package/dist/core/recovery/patterns.d.ts +0 -0
- package/dist/core/recovery/retry.d.ts +0 -0
- package/dist/core/recovery/session-recovery.d.ts +0 -0
- package/dist/core/session/interfaces/context-stats.d.ts +0 -0
- package/dist/core/session/interfaces/index.d.ts +0 -0
- package/dist/core/session/interfaces/shared-context.d.ts +0 -0
- package/dist/core/session/interfaces/shared-decision.d.ts +0 -0
- package/dist/core/session/interfaces/shared-document.d.ts +0 -0
- package/dist/core/session/interfaces/shared-finding.d.ts +0 -0
- package/dist/core/session/interfaces.d.ts +0 -0
- package/dist/core/session/shared-context.d.ts +0 -0
- package/dist/core/session/store.d.ts +0 -0
- package/dist/core/session/summary.d.ts +0 -0
- package/dist/core/sync/todo-parser.d.ts +0 -0
- package/dist/core/sync/todo-sync-service.d.ts +0 -0
- package/dist/core/task/interfaces/index.d.ts +0 -0
- package/dist/core/task/interfaces/task-hierarchy.d.ts +0 -0
- package/dist/core/task/interfaces/task-input.d.ts +0 -0
- package/dist/core/task/interfaces/task-node.d.ts +0 -0
- package/dist/core/task/interfaces/task-progress.d.ts +0 -0
- package/dist/core/task/interfaces.d.ts +0 -0
- package/dist/core/task/parser.d.ts +0 -0
- package/dist/core/task/scheduler.d.ts +0 -0
- package/dist/core/task/store.d.ts +0 -0
- package/dist/core/task/summary.d.ts +0 -0
- package/dist/core/task/task-decomposer.d.ts +0 -0
- package/dist/core/todo/todo-manager.d.ts +0 -0
- package/dist/hooks/compatibility/external-plugin.d.ts +0 -0
- package/dist/hooks/constants.d.ts +0 -0
- package/dist/hooks/custom/agent-ui.d.ts +0 -0
- package/dist/hooks/custom/memory-gate.d.ts +0 -0
- package/dist/hooks/custom/metrics.d.ts +0 -0
- package/dist/hooks/custom/resource-control.d.ts +0 -0
- package/dist/hooks/custom/secret-scanner.d.ts +0 -0
- package/dist/hooks/custom/strict-role-guard.d.ts +0 -0
- package/dist/hooks/custom/user-activity.d.ts +0 -0
- package/dist/hooks/features/mission-loop.d.ts +0 -0
- package/dist/hooks/features/sanity-check.d.ts +0 -0
- package/dist/hooks/index.d.ts +0 -0
- package/dist/hooks/registry.d.ts +0 -0
- package/dist/hooks/types.d.ts +0 -0
- package/dist/index.d.ts +0 -0
- package/dist/index.js +1388 -278
- package/dist/plugin-handlers/assistant-done-handler.d.ts +3 -4
- package/dist/plugin-handlers/chat-message-handler.d.ts +0 -0
- package/dist/plugin-handlers/config-handler.d.ts +8 -1
- package/dist/plugin-handlers/event-handler.d.ts +0 -0
- package/dist/plugin-handlers/index.d.ts +0 -1
- package/dist/plugin-handlers/interfaces/assistant-done-context.d.ts +0 -0
- package/dist/plugin-handlers/interfaces/chat-message-context.d.ts +0 -0
- package/dist/plugin-handlers/interfaces/event-handler-context.d.ts +0 -0
- package/dist/plugin-handlers/interfaces/index.d.ts +0 -0
- package/dist/plugin-handlers/interfaces/orchestrator-state.d.ts +0 -0
- package/dist/plugin-handlers/interfaces/session-compacting.d.ts +0 -0
- package/dist/plugin-handlers/interfaces/session-state.d.ts +1 -0
- package/dist/plugin-handlers/interfaces/system-transform.d.ts +3 -0
- package/dist/plugin-handlers/interfaces/tool-execute-context.d.ts +0 -0
- package/dist/plugin-handlers/interfaces/tool-hook.d.ts +0 -0
- package/dist/plugin-handlers/session-compacting-handler.d.ts +0 -0
- package/dist/plugin-handlers/system-transform-handler.d.ts +0 -0
- package/dist/plugin-handlers/tool-execute-handler.d.ts +0 -0
- package/dist/plugin-handlers/tool-execute-pre-handler.d.ts +0 -0
- package/dist/shared/agent/constants/index.d.ts +0 -1
- package/dist/shared/agent/constants/names.d.ts +0 -0
- package/dist/shared/agent/index.d.ts +0 -0
- package/dist/shared/agent/interfaces/agent-definition.d.ts +0 -0
- package/dist/shared/agent/interfaces/concurrency-config.d.ts +0 -0
- package/dist/shared/agent/interfaces/index.d.ts +0 -0
- package/dist/shared/agent/types/agent-name.d.ts +0 -0
- package/dist/shared/agent/types/index.d.ts +0 -0
- package/dist/shared/agent/utils/index.d.ts +0 -0
- package/dist/shared/cache/constants/cache-actions.d.ts +0 -0
- package/dist/shared/cache/constants/cache.d.ts +0 -0
- package/dist/shared/cache/constants/filter-status.d.ts +0 -0
- package/dist/shared/cache/constants/index.d.ts +0 -0
- package/dist/shared/cache/index.d.ts +0 -0
- package/dist/shared/command/index.d.ts +0 -0
- package/dist/shared/command/interfaces/background-task.d.ts +0 -0
- package/dist/shared/command/interfaces/index.d.ts +0 -0
- package/dist/shared/command/interfaces/run-background-options.d.ts +0 -0
- package/dist/shared/command/types/background-task-status.d.ts +0 -0
- package/dist/shared/command/types/index.d.ts +0 -0
- package/dist/shared/constants/security-patterns.d.ts +0 -0
- package/dist/shared/constants/system-messages.d.ts +0 -0
- package/dist/shared/core/constants/cli.d.ts +0 -0
- package/dist/shared/core/constants/id-prefix.d.ts +0 -0
- package/dist/shared/core/constants/index.d.ts +0 -0
- package/dist/shared/core/constants/lifecycle.d.ts +0 -0
- package/dist/shared/core/constants/limits.d.ts +0 -0
- package/dist/shared/core/constants/logging.d.ts +0 -0
- package/dist/shared/core/constants/memory-hooks.d.ts +0 -0
- package/dist/shared/core/constants/memory-limits.d.ts +0 -0
- package/dist/shared/core/constants/paths.d.ts +0 -0
- package/dist/shared/core/constants/phases.d.ts +0 -0
- package/dist/shared/core/constants/status-labels.d.ts +0 -0
- package/dist/shared/core/constants/time.d.ts +0 -0
- package/dist/shared/core/constants/wal-actions.d.ts +0 -0
- package/dist/shared/core/index.d.ts +0 -0
- package/dist/shared/core/poolable.d.ts +0 -0
- package/dist/shared/errors/constants/error-patterns.d.ts +0 -0
- package/dist/shared/errors/constants/error-type.d.ts +0 -0
- package/dist/shared/errors/constants/index.d.ts +0 -0
- package/dist/shared/errors/detection.d.ts +0 -0
- package/dist/shared/errors/index.d.ts +0 -0
- package/dist/shared/errors/retry.d.ts +0 -0
- package/dist/shared/errors/types/error-pattern-type.d.ts +0 -0
- package/dist/shared/errors/types/index.d.ts +0 -0
- package/dist/shared/index.d.ts +0 -0
- package/dist/shared/lifecycle/index.d.ts +0 -0
- package/dist/shared/lifecycle/registration.d.ts +0 -0
- package/dist/shared/lifecycle/shutdown-manager.d.ts +0 -0
- package/dist/shared/loop/constants/index.d.ts +0 -0
- package/dist/shared/loop/constants/labels.d.ts +0 -0
- package/dist/shared/loop/constants/loop.d.ts +0 -0
- package/dist/shared/loop/constants/mission-control.d.ts +0 -0
- package/dist/shared/loop/constants/task-status.d.ts +0 -0
- package/dist/shared/loop/constants/todo-status.d.ts +0 -0
- package/dist/shared/loop/index.d.ts +0 -0
- package/dist/shared/loop/interfaces/index.d.ts +0 -0
- package/dist/shared/loop/interfaces/mission-loop.d.ts +8 -0
- package/dist/shared/loop/interfaces/todo-stats.d.ts +0 -0
- package/dist/shared/loop/interfaces/todo.d.ts +0 -0
- package/dist/shared/loop/types/index.d.ts +0 -0
- package/dist/shared/loop/types/todo-priority.d.ts +0 -0
- package/dist/shared/loop/types/todo-status.d.ts +0 -0
- package/dist/shared/message/constants/index.d.ts +0 -0
- package/dist/shared/message/constants/message-roles.d.ts +0 -0
- package/dist/shared/message/constants/part-types.d.ts +0 -0
- package/dist/shared/message/constants/plugin-hooks.d.ts +6 -2
- package/dist/shared/message/constants/prompts.d.ts +0 -0
- package/dist/shared/message/constants/slash-commands.d.ts +0 -0
- package/dist/shared/message/index.d.ts +0 -0
- package/dist/shared/notification/constants/index.d.ts +0 -0
- package/dist/shared/notification/constants/toast-duration.d.ts +0 -0
- package/dist/shared/notification/constants/toast-variants.d.ts +0 -0
- package/dist/shared/notification/constants/tui.const.d.ts +0 -0
- package/dist/shared/notification/index.d.ts +0 -0
- package/dist/shared/notification/interfaces/index.d.ts +0 -0
- package/dist/shared/notification/interfaces/task-toast.interface.d.ts +0 -0
- package/dist/shared/notification/interfaces/toast-message.d.ts +0 -0
- package/dist/shared/notification/interfaces/toast-options.d.ts +0 -0
- package/dist/shared/notification/os-notify/constants/index.d.ts +0 -0
- package/dist/shared/notification/os-notify/constants/notification-command-keys.d.ts +0 -0
- package/dist/shared/notification/os-notify/constants/notification-commands.d.ts +0 -0
- package/dist/shared/notification/os-notify/constants/notification-defaults.d.ts +0 -0
- package/dist/shared/notification/os-notify/index.d.ts +0 -0
- package/dist/shared/notification/os-notify/interfaces/index.d.ts +0 -0
- package/dist/shared/notification/os-notify/interfaces/notification-config.d.ts +0 -0
- package/dist/shared/notification/os-notify/interfaces/notification-state.d.ts +0 -0
- package/dist/shared/notification/os-notify/types/index.d.ts +0 -0
- package/dist/shared/notification/os-notify/types/notification-commands.d.ts +0 -0
- package/dist/shared/notification/presets/index.d.ts +0 -0
- package/dist/shared/notification/presets/mission.d.ts +0 -0
- package/dist/shared/notification/presets/parallel.d.ts +0 -0
- package/dist/shared/notification/presets/session.d.ts +0 -0
- package/dist/shared/notification/presets/task-lifecycle.d.ts +0 -0
- package/dist/shared/notification/presets/tools.d.ts +0 -0
- package/dist/shared/notification/presets/warnings.d.ts +0 -0
- package/dist/shared/notification/types/index.d.ts +0 -0
- package/dist/shared/notification/types/toast-variant.d.ts +0 -0
- package/dist/shared/os/constants/index.d.ts +0 -0
- package/dist/shared/os/constants/platform.d.ts +0 -0
- package/dist/shared/os/index.d.ts +0 -0
- package/dist/shared/os/types/index.d.ts +0 -0
- package/dist/shared/os/types/platform.d.ts +0 -0
- package/dist/shared/prompt/constants/architecture.d.ts +0 -0
- package/dist/shared/prompt/constants/index.d.ts +0 -0
- package/dist/shared/prompt/constants/mandates.d.ts +0 -0
- package/dist/shared/prompt/constants/philosophy.d.ts +0 -0
- package/dist/shared/prompt/constants/scouts.d.ts +0 -0
- package/dist/shared/prompt/constants/status.d.ts +0 -0
- package/dist/shared/prompt/constants/tags.d.ts +0 -0
- package/dist/shared/prompt/index.d.ts +0 -0
- package/dist/shared/recovery/constants/history.d.ts +0 -0
- package/dist/shared/recovery/constants/index.d.ts +0 -0
- package/dist/shared/recovery/constants/recovery-level.d.ts +0 -0
- package/dist/shared/recovery/constants/recovery.d.ts +0 -0
- package/dist/shared/recovery/index.d.ts +0 -0
- package/dist/shared/recovery/interfaces/error-context.d.ts +0 -0
- package/dist/shared/recovery/interfaces/index.d.ts +0 -0
- package/dist/shared/recovery/interfaces/recovery-record.d.ts +0 -0
- package/dist/shared/recovery/types/index.d.ts +0 -0
- package/dist/shared/recovery/types/recovery-action.d.ts +0 -0
- package/dist/shared/session/constants/events/document-events.d.ts +0 -0
- package/dist/shared/session/constants/events/index.d.ts +0 -0
- package/dist/shared/session/constants/events/message-events.d.ts +0 -0
- package/dist/shared/session/constants/events/mission-events.d.ts +0 -0
- package/dist/shared/session/constants/events/session-events.d.ts +0 -0
- package/dist/shared/session/constants/events/special-events.d.ts +0 -0
- package/dist/shared/session/constants/events/task-events.d.ts +0 -0
- package/dist/shared/session/constants/events/todo-events.d.ts +0 -0
- package/dist/shared/session/constants/index.d.ts +0 -0
- package/dist/shared/session/index.d.ts +0 -0
- package/dist/shared/task/base-task.d.ts +0 -0
- package/dist/shared/task/constants/background-status.d.ts +0 -0
- package/dist/shared/task/constants/background-task.d.ts +0 -0
- package/dist/shared/task/constants/index.d.ts +0 -0
- package/dist/shared/task/constants/metadata-keys.d.ts +0 -0
- package/dist/shared/task/constants/parallel-task.d.ts +0 -0
- package/dist/shared/task/index.d.ts +0 -0
- package/dist/shared/task/interfaces/index.d.ts +0 -0
- package/dist/shared/task/interfaces/launch-input.d.ts +0 -0
- package/dist/shared/task/interfaces/parallel-task.d.ts +0 -0
- package/dist/shared/task/interfaces/resume-input.d.ts +0 -0
- package/dist/shared/task/interfaces/task-progress.d.ts +0 -0
- package/dist/shared/task/types/index.d.ts +0 -0
- package/dist/shared/task/types/parallel-task-status.d.ts +0 -0
- package/dist/shared/tool/constants/common/index.d.ts +0 -0
- package/dist/shared/tool/constants/common/labels.d.ts +0 -0
- package/dist/shared/tool/constants/common/languages.d.ts +0 -0
- package/dist/shared/tool/constants/common/output-labels.d.ts +0 -0
- package/dist/shared/tool/constants/common/sources.d.ts +0 -0
- package/dist/shared/tool/constants/index.d.ts +0 -0
- package/dist/shared/tool/constants/lsp/index.d.ts +0 -0
- package/dist/shared/tool/constants/lsp/lsp-severity-labels.d.ts +0 -0
- package/dist/shared/tool/constants/lsp/lsp-severity.d.ts +0 -0
- package/dist/shared/tool/constants/parallel/index.d.ts +0 -0
- package/dist/shared/tool/constants/parallel/logging.d.ts +0 -0
- package/dist/shared/tool/constants/parallel/parameters.d.ts +0 -0
- package/dist/shared/tool/constants/tool-names.d.ts +0 -0
- package/dist/shared/tool/constants/tool-output.d.ts +0 -0
- package/dist/shared/tool/index.d.ts +0 -0
- package/dist/shared/tool/interfaces/ast/ast-replace-result.d.ts +0 -0
- package/dist/shared/tool/interfaces/ast/ast-search-result.d.ts +0 -0
- package/dist/shared/tool/interfaces/ast/index.d.ts +0 -0
- package/dist/shared/tool/interfaces/index.d.ts +0 -0
- package/dist/shared/tool/interfaces/lsp/index.d.ts +0 -0
- package/dist/shared/tool/interfaces/lsp/lsp-command-result.d.ts +0 -0
- package/dist/shared/tool/interfaces/lsp/lsp-diagnostic.d.ts +0 -0
- package/dist/shared/tool/interfaces/lsp/lsp-rename-location.d.ts +0 -0
- package/dist/shared/tool/interfaces/lsp/lsp-rename-result.d.ts +0 -0
- package/dist/shared/tool/interfaces/parallel/index.d.ts +0 -0
- package/dist/shared/tool/interfaces/parallel/poll-result.d.ts +0 -0
- package/dist/shared/tool/interfaces/parallel/session-client.d.ts +0 -0
- package/dist/shared/verification/constants/categories.d.ts +0 -0
- package/dist/shared/verification/constants/checklist.d.ts +0 -0
- package/dist/shared/verification/constants/index.d.ts +0 -0
- package/dist/shared/verification/constants/patterns.d.ts +0 -0
- package/dist/shared/verification/constants/signals.d.ts +0 -0
- package/dist/shared/verification/index.d.ts +0 -0
- package/dist/shared/verification/interfaces/checklist-item.d.ts +0 -0
- package/dist/shared/verification/interfaces/checklist-verification-result.d.ts +0 -0
- package/dist/shared/verification/interfaces/index.d.ts +0 -0
- package/dist/shared/verification/interfaces/verification-checklist.d.ts +0 -0
- package/dist/shared/verification/interfaces/verification-result.d.ts +0 -0
- package/dist/shared/verification/types/checklist-category.d.ts +0 -0
- package/dist/shared/verification/types/index.d.ts +0 -0
- package/dist/tools/ast/index.d.ts +0 -0
- package/dist/tools/background-cmd/check.d.ts +0 -0
- package/dist/tools/background-cmd/index.d.ts +0 -0
- package/dist/tools/background-cmd/kill.d.ts +0 -0
- package/dist/tools/background-cmd/list.d.ts +0 -0
- package/dist/tools/background-cmd/run.d.ts +0 -0
- package/dist/tools/callAgent.d.ts +0 -0
- package/dist/tools/lsp/diagnostics-cache.d.ts +0 -0
- package/dist/tools/lsp/index.d.ts +0 -0
- package/dist/tools/parallel/cancel-task.d.ts +0 -0
- package/dist/tools/parallel/delegate-task.d.ts +0 -0
- package/dist/tools/parallel/get-task-result.d.ts +0 -0
- package/dist/tools/parallel/index.d.ts +0 -0
- package/dist/tools/parallel/list-agents.d.ts +0 -0
- package/dist/tools/parallel/list-tasks.d.ts +0 -0
- package/dist/tools/parallel/show-metrics.d.ts +0 -0
- package/dist/tools/parallel/update-todo.d.ts +0 -0
- package/dist/tools/registry.d.ts +0 -0
- package/dist/tools/rust-pool.d.ts +32 -2
- package/dist/tools/rust.d.ts +0 -0
- package/dist/tools/search.d.ts +0 -0
- package/dist/tools/slashCommand.d.ts +0 -0
- package/dist/tools/web/cache-docs.d.ts +0 -0
- package/dist/tools/web/codesearch.d.ts +0 -0
- package/dist/tools/web/index.d.ts +0 -0
- package/dist/tools/web/webfetch.d.ts +0 -0
- package/dist/tools/web/websearch.d.ts +0 -0
- package/dist/utils/binary.d.ts +0 -0
- package/dist/utils/common.d.ts +0 -0
- package/dist/utils/compatibility/claude.d.ts +0 -0
- package/dist/utils/formatting/elapsed-time.d.ts +0 -0
- package/dist/utils/formatting/index.d.ts +0 -0
- package/dist/utils/formatting/timestamp.d.ts +0 -0
- package/dist/utils/parsing/index.d.ts +0 -0
- package/dist/utils/parsing/slash-command.d.ts +0 -0
- package/dist/utils/sanity/checker.d.ts +0 -0
- package/dist/utils/sanity/constants/escalation-prompt.d.ts +0 -0
- package/dist/utils/sanity/constants/index.d.ts +0 -0
- package/dist/utils/sanity/constants/recovery-prompt.d.ts +0 -0
- package/dist/utils/sanity/constants/severity.d.ts +0 -0
- package/dist/utils/sanity/index.d.ts +0 -0
- package/dist/utils/sanity/interfaces/index.d.ts +0 -0
- package/dist/utils/sanity/interfaces/sanity-result.d.ts +0 -0
- package/dist/utils/sanity/types/index.d.ts +0 -0
- package/dist/utils/sanity/types/severity.d.ts +0 -0
- package/package.json +89 -88
- package/scripts/run-install-hook.mjs +66 -66
- package/dist/shared/agent/constants/agent-tokens.d.ts +0 -11
package/dist/index.js
CHANGED
|
@@ -37,28 +37,11 @@ var init_names = __esm({
|
|
|
37
37
|
}
|
|
38
38
|
});
|
|
39
39
|
|
|
40
|
-
// src/shared/agent/constants/agent-tokens.ts
|
|
41
|
-
var AGENT_TOKENS;
|
|
42
|
-
var init_agent_tokens = __esm({
|
|
43
|
-
"src/shared/agent/constants/agent-tokens.ts"() {
|
|
44
|
-
"use strict";
|
|
45
|
-
AGENT_TOKENS = {
|
|
46
|
-
/** Primary agent (Commander) max tokens */
|
|
47
|
-
PRIMARY_MAX_TOKENS: 64e3,
|
|
48
|
-
/** Primary agent thinking budget */
|
|
49
|
-
PRIMARY_THINKING_BUDGET: 32e3,
|
|
50
|
-
/** Subagent max tokens */
|
|
51
|
-
SUBAGENT_MAX_TOKENS: 32e3
|
|
52
|
-
};
|
|
53
|
-
}
|
|
54
|
-
});
|
|
55
|
-
|
|
56
40
|
// src/shared/agent/constants/index.ts
|
|
57
41
|
var init_constants = __esm({
|
|
58
42
|
"src/shared/agent/constants/index.ts"() {
|
|
59
43
|
"use strict";
|
|
60
44
|
init_names();
|
|
61
|
-
init_agent_tokens();
|
|
62
45
|
}
|
|
63
46
|
});
|
|
64
47
|
|
|
@@ -1903,10 +1886,14 @@ var init_plugin_hooks = __esm({
|
|
|
1903
1886
|
PLUGIN_HOOKS = {
|
|
1904
1887
|
/** Intercepts user messages before sending to LLM */
|
|
1905
1888
|
CHAT_MESSAGE: "chat.message",
|
|
1906
|
-
/** Runs
|
|
1907
|
-
|
|
1889
|
+
/** Runs before any tool call */
|
|
1890
|
+
TOOL_EXECUTE_BEFORE: "tool.execute.before",
|
|
1908
1891
|
/** Runs after any tool call completes */
|
|
1909
|
-
TOOL_EXECUTE_AFTER: "tool.execute.after"
|
|
1892
|
+
TOOL_EXECUTE_AFTER: "tool.execute.after",
|
|
1893
|
+
/** Preserves custom compaction context */
|
|
1894
|
+
EXPERIMENTAL_SESSION_COMPACTING: "experimental.session.compacting",
|
|
1895
|
+
/** Injects dynamic system prompt additions */
|
|
1896
|
+
EXPERIMENTAL_CHAT_SYSTEM_TRANSFORM: "experimental.chat.system.transform"
|
|
1910
1897
|
};
|
|
1911
1898
|
}
|
|
1912
1899
|
});
|
|
@@ -4733,9 +4720,10 @@ You are ${AGENT_NAMES.COMMANDER}. Autonomous mission controller.
|
|
|
4733
4720
|
- You ADAPT your approach to what the project requires
|
|
4734
4721
|
|
|
4735
4722
|
## \u{1F680} AUTONOMOUS EXECUTION MODE
|
|
4736
|
-
- Complete the ENTIRE mission without
|
|
4723
|
+
- Complete the ENTIRE mission without routine user hand-holding
|
|
4737
4724
|
- Make decisions yourself - don't present options to user
|
|
4738
4725
|
- If uncertain, make the BEST choice and proceed
|
|
4726
|
+
- Ask a concise clarification only when truly blocked and the OpenCode question permission allows it
|
|
4739
4727
|
- Conclude ONLY after ${AGENT_NAMES.REVIEWER} verifies the full system
|
|
4740
4728
|
- Only stop when everything is verified or truly blocked
|
|
4741
4729
|
${PROMPT_TAGS.ROLE.close}`;
|
|
@@ -5510,6 +5498,9 @@ var ConcurrencyToken = class {
|
|
|
5510
5498
|
}, autoReleaseMs);
|
|
5511
5499
|
this.autoReleaseTimer.unref();
|
|
5512
5500
|
}
|
|
5501
|
+
controller;
|
|
5502
|
+
key;
|
|
5503
|
+
autoReleaseMs;
|
|
5513
5504
|
released = false;
|
|
5514
5505
|
autoReleaseTimer = null;
|
|
5515
5506
|
/**
|
|
@@ -5853,6 +5844,12 @@ var ConcurrencyController = class {
|
|
|
5853
5844
|
constructor(config3) {
|
|
5854
5845
|
this.config = config3 ?? {};
|
|
5855
5846
|
}
|
|
5847
|
+
configure(config3) {
|
|
5848
|
+
this.config = config3;
|
|
5849
|
+
}
|
|
5850
|
+
getConfig() {
|
|
5851
|
+
return this.config;
|
|
5852
|
+
}
|
|
5856
5853
|
setLimit(key, limit) {
|
|
5857
5854
|
this.limits.set(key, limit);
|
|
5858
5855
|
}
|
|
@@ -7779,7 +7776,7 @@ function $constructor(name, initializer5, params) {
|
|
|
7779
7776
|
Object.defineProperty(_, "name", { value: name });
|
|
7780
7777
|
return _;
|
|
7781
7778
|
}
|
|
7782
|
-
var $brand = Symbol("zod_brand");
|
|
7779
|
+
var $brand = /* @__PURE__ */ Symbol("zod_brand");
|
|
7783
7780
|
var $ZodAsyncError = class extends Error {
|
|
7784
7781
|
constructor() {
|
|
7785
7782
|
super(`Encountered Promise during synchronous parse. Use .parseAsync() instead.`);
|
|
@@ -7966,10 +7963,10 @@ function mergeDefs(...defs) {
|
|
|
7966
7963
|
function cloneDef(schema) {
|
|
7967
7964
|
return mergeDefs(schema._zod.def);
|
|
7968
7965
|
}
|
|
7969
|
-
function getElementAtPath(obj,
|
|
7970
|
-
if (!
|
|
7966
|
+
function getElementAtPath(obj, path11) {
|
|
7967
|
+
if (!path11)
|
|
7971
7968
|
return obj;
|
|
7972
|
-
return
|
|
7969
|
+
return path11.reduce((acc, key) => acc?.[key], obj);
|
|
7973
7970
|
}
|
|
7974
7971
|
function promiseAllObject(promisesObj) {
|
|
7975
7972
|
const keys = Object.keys(promisesObj);
|
|
@@ -8378,11 +8375,11 @@ function explicitlyAborted(x, startIndex = 0) {
|
|
|
8378
8375
|
}
|
|
8379
8376
|
return false;
|
|
8380
8377
|
}
|
|
8381
|
-
function prefixIssues(
|
|
8378
|
+
function prefixIssues(path11, issues) {
|
|
8382
8379
|
return issues.map((iss) => {
|
|
8383
8380
|
var _a3;
|
|
8384
8381
|
(_a3 = iss).path ?? (_a3.path = []);
|
|
8385
|
-
iss.path.unshift(
|
|
8382
|
+
iss.path.unshift(path11);
|
|
8386
8383
|
return iss;
|
|
8387
8384
|
});
|
|
8388
8385
|
}
|
|
@@ -8529,16 +8526,16 @@ function flattenError(error95, mapper = (issue3) => issue3.message) {
|
|
|
8529
8526
|
}
|
|
8530
8527
|
function formatError(error95, mapper = (issue3) => issue3.message) {
|
|
8531
8528
|
const fieldErrors = { _errors: [] };
|
|
8532
|
-
const processError = (error96,
|
|
8529
|
+
const processError = (error96, path11 = []) => {
|
|
8533
8530
|
for (const issue3 of error96.issues) {
|
|
8534
8531
|
if (issue3.code === "invalid_union" && issue3.errors.length) {
|
|
8535
|
-
issue3.errors.map((issues) => processError({ issues }, [...
|
|
8532
|
+
issue3.errors.map((issues) => processError({ issues }, [...path11, ...issue3.path]));
|
|
8536
8533
|
} else if (issue3.code === "invalid_key") {
|
|
8537
|
-
processError({ issues: issue3.issues }, [...
|
|
8534
|
+
processError({ issues: issue3.issues }, [...path11, ...issue3.path]);
|
|
8538
8535
|
} else if (issue3.code === "invalid_element") {
|
|
8539
|
-
processError({ issues: issue3.issues }, [...
|
|
8536
|
+
processError({ issues: issue3.issues }, [...path11, ...issue3.path]);
|
|
8540
8537
|
} else {
|
|
8541
|
-
const fullpath = [...
|
|
8538
|
+
const fullpath = [...path11, ...issue3.path];
|
|
8542
8539
|
if (fullpath.length === 0) {
|
|
8543
8540
|
fieldErrors._errors.push(mapper(issue3));
|
|
8544
8541
|
} else {
|
|
@@ -8565,17 +8562,17 @@ function formatError(error95, mapper = (issue3) => issue3.message) {
|
|
|
8565
8562
|
}
|
|
8566
8563
|
function treeifyError(error95, mapper = (issue3) => issue3.message) {
|
|
8567
8564
|
const result = { errors: [] };
|
|
8568
|
-
const processError = (error96,
|
|
8565
|
+
const processError = (error96, path11 = []) => {
|
|
8569
8566
|
var _a3, _b;
|
|
8570
8567
|
for (const issue3 of error96.issues) {
|
|
8571
8568
|
if (issue3.code === "invalid_union" && issue3.errors.length) {
|
|
8572
|
-
issue3.errors.map((issues) => processError({ issues }, [...
|
|
8569
|
+
issue3.errors.map((issues) => processError({ issues }, [...path11, ...issue3.path]));
|
|
8573
8570
|
} else if (issue3.code === "invalid_key") {
|
|
8574
|
-
processError({ issues: issue3.issues }, [...
|
|
8571
|
+
processError({ issues: issue3.issues }, [...path11, ...issue3.path]);
|
|
8575
8572
|
} else if (issue3.code === "invalid_element") {
|
|
8576
|
-
processError({ issues: issue3.issues }, [...
|
|
8573
|
+
processError({ issues: issue3.issues }, [...path11, ...issue3.path]);
|
|
8577
8574
|
} else {
|
|
8578
|
-
const fullpath = [...
|
|
8575
|
+
const fullpath = [...path11, ...issue3.path];
|
|
8579
8576
|
if (fullpath.length === 0) {
|
|
8580
8577
|
result.errors.push(mapper(issue3));
|
|
8581
8578
|
continue;
|
|
@@ -8607,8 +8604,8 @@ function treeifyError(error95, mapper = (issue3) => issue3.message) {
|
|
|
8607
8604
|
}
|
|
8608
8605
|
function toDotPath(_path) {
|
|
8609
8606
|
const segs = [];
|
|
8610
|
-
const
|
|
8611
|
-
for (const seg of
|
|
8607
|
+
const path11 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
8608
|
+
for (const seg of path11) {
|
|
8612
8609
|
if (typeof seg === "number")
|
|
8613
8610
|
segs.push(`[${seg}]`);
|
|
8614
8611
|
else if (typeof seg === "symbol")
|
|
@@ -17522,8 +17519,8 @@ function yo_default() {
|
|
|
17522
17519
|
|
|
17523
17520
|
// node_modules/zod/v4/core/registries.js
|
|
17524
17521
|
var _a2;
|
|
17525
|
-
var $output = Symbol("ZodOutput");
|
|
17526
|
-
var $input = Symbol("ZodInput");
|
|
17522
|
+
var $output = /* @__PURE__ */ Symbol("ZodOutput");
|
|
17523
|
+
var $input = /* @__PURE__ */ Symbol("ZodInput");
|
|
17527
17524
|
var $ZodRegistry = class {
|
|
17528
17525
|
constructor() {
|
|
17529
17526
|
this._map = /* @__PURE__ */ new WeakMap();
|
|
@@ -18560,7 +18557,7 @@ function _stringbool(Classes, _params) {
|
|
|
18560
18557
|
type: "pipe",
|
|
18561
18558
|
in: stringSchema,
|
|
18562
18559
|
out: booleanSchema,
|
|
18563
|
-
transform: (input, payload) => {
|
|
18560
|
+
transform: ((input, payload) => {
|
|
18564
18561
|
let data = input;
|
|
18565
18562
|
if (params.case !== "sensitive")
|
|
18566
18563
|
data = data.toLowerCase();
|
|
@@ -18579,14 +18576,14 @@ function _stringbool(Classes, _params) {
|
|
|
18579
18576
|
});
|
|
18580
18577
|
return {};
|
|
18581
18578
|
}
|
|
18582
|
-
},
|
|
18583
|
-
reverseTransform: (input, _payload) => {
|
|
18579
|
+
}),
|
|
18580
|
+
reverseTransform: ((input, _payload) => {
|
|
18584
18581
|
if (input === true) {
|
|
18585
18582
|
return truthyArray[0] || "true";
|
|
18586
18583
|
} else {
|
|
18587
18584
|
return falsyArray[0] || "false";
|
|
18588
18585
|
}
|
|
18589
|
-
},
|
|
18586
|
+
}),
|
|
18590
18587
|
error: params.error
|
|
18591
18588
|
});
|
|
18592
18589
|
return codec3;
|
|
@@ -21300,13 +21297,13 @@ function resolveRef(ref, ctx) {
|
|
|
21300
21297
|
if (!ref.startsWith("#")) {
|
|
21301
21298
|
throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
|
|
21302
21299
|
}
|
|
21303
|
-
const
|
|
21304
|
-
if (
|
|
21300
|
+
const path11 = ref.slice(1).split("/").filter(Boolean);
|
|
21301
|
+
if (path11.length === 0) {
|
|
21305
21302
|
return ctx.rootSchema;
|
|
21306
21303
|
}
|
|
21307
21304
|
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
|
21308
|
-
if (
|
|
21309
|
-
const key =
|
|
21305
|
+
if (path11[0] === defsKey) {
|
|
21306
|
+
const key = path11[1];
|
|
21310
21307
|
if (!key || !ctx.defs[key]) {
|
|
21311
21308
|
throw new Error(`Reference not found: ${ref}`);
|
|
21312
21309
|
}
|
|
@@ -21723,9 +21720,6 @@ var AgentDefinitionSchema = external_exports.object({
|
|
|
21723
21720
|
mode: external_exports.enum(["primary", "subagent"]).optional(),
|
|
21724
21721
|
color: external_exports.string().optional(),
|
|
21725
21722
|
hidden: external_exports.boolean().optional(),
|
|
21726
|
-
thinking: external_exports.boolean().optional(),
|
|
21727
|
-
maxTokens: external_exports.number().optional(),
|
|
21728
|
-
budgetTokens: external_exports.number().optional(),
|
|
21729
21723
|
canWrite: external_exports.boolean(),
|
|
21730
21724
|
// Required per interface
|
|
21731
21725
|
canBash: external_exports.boolean()
|
|
@@ -21782,7 +21776,7 @@ var AgentRegistry = class _AgentRegistry {
|
|
|
21782
21776
|
for (const [name, def] of Object.entries(customAgents)) {
|
|
21783
21777
|
const result = AgentDefinitionSchema.safeParse(def);
|
|
21784
21778
|
if (result.success) {
|
|
21785
|
-
this.registerAgent(name,
|
|
21779
|
+
this.registerAgent(name, result.data);
|
|
21786
21780
|
} else {
|
|
21787
21781
|
log(`[AgentRegistry] Invalid custom agent definition for: ${name}. Errors: ${result.error.message}`);
|
|
21788
21782
|
}
|
|
@@ -21808,6 +21802,13 @@ var TaskLauncher = class {
|
|
|
21808
21802
|
this.onTaskError = onTaskError;
|
|
21809
21803
|
this.startPolling = startPolling;
|
|
21810
21804
|
}
|
|
21805
|
+
client;
|
|
21806
|
+
directory;
|
|
21807
|
+
store;
|
|
21808
|
+
concurrency;
|
|
21809
|
+
sessionPool;
|
|
21810
|
+
onTaskError;
|
|
21811
|
+
startPolling;
|
|
21811
21812
|
/**
|
|
21812
21813
|
* Unified launch method - handles both single and multiple tasks efficiently.
|
|
21813
21814
|
* All session creations happen in parallel immediately.
|
|
@@ -21977,6 +21978,11 @@ var TaskResumer = class {
|
|
|
21977
21978
|
this.startPolling = startPolling;
|
|
21978
21979
|
this.notifyParentIfAllComplete = notifyParentIfAllComplete;
|
|
21979
21980
|
}
|
|
21981
|
+
client;
|
|
21982
|
+
store;
|
|
21983
|
+
findBySession;
|
|
21984
|
+
startPolling;
|
|
21985
|
+
notifyParentIfAllComplete;
|
|
21980
21986
|
async resume(input) {
|
|
21981
21987
|
const existingTask = this.findBySession(input.sessionId);
|
|
21982
21988
|
if (!existingTask) {
|
|
@@ -22131,6 +22137,13 @@ var TaskPoller = class {
|
|
|
22131
22137
|
this.pruneExpiredTasks = pruneExpiredTasks;
|
|
22132
22138
|
this.onTaskComplete = onTaskComplete;
|
|
22133
22139
|
}
|
|
22140
|
+
client;
|
|
22141
|
+
store;
|
|
22142
|
+
concurrency;
|
|
22143
|
+
notifyParentIfAllComplete;
|
|
22144
|
+
scheduleCleanup;
|
|
22145
|
+
pruneExpiredTasks;
|
|
22146
|
+
onTaskComplete;
|
|
22134
22147
|
pollingInterval;
|
|
22135
22148
|
messageCache = /* @__PURE__ */ new Map();
|
|
22136
22149
|
// Adaptive polling
|
|
@@ -22335,6 +22348,10 @@ var TaskCleaner = class {
|
|
|
22335
22348
|
this.concurrency = concurrency;
|
|
22336
22349
|
this.sessionPool = sessionPool2;
|
|
22337
22350
|
}
|
|
22351
|
+
client;
|
|
22352
|
+
store;
|
|
22353
|
+
concurrency;
|
|
22354
|
+
sessionPool;
|
|
22338
22355
|
pruneExpiredTasks() {
|
|
22339
22356
|
const now = Date.now();
|
|
22340
22357
|
for (const [taskId, task] of this.store.getAll().map((t) => [t.id, t])) {
|
|
@@ -22450,6 +22467,14 @@ var EventHandler = class {
|
|
|
22450
22467
|
this.validateSessionHasOutput = validateSessionHasOutput2;
|
|
22451
22468
|
this.onTaskComplete = onTaskComplete;
|
|
22452
22469
|
}
|
|
22470
|
+
client;
|
|
22471
|
+
store;
|
|
22472
|
+
concurrency;
|
|
22473
|
+
findBySession;
|
|
22474
|
+
notifyParentIfAllComplete;
|
|
22475
|
+
scheduleCleanup;
|
|
22476
|
+
validateSessionHasOutput;
|
|
22477
|
+
onTaskComplete;
|
|
22453
22478
|
/**
|
|
22454
22479
|
* Handle OpenCode session events for proper resource cleanup.
|
|
22455
22480
|
* Call this from your plugin's event hook.
|
|
@@ -22955,7 +22980,7 @@ var ParallelAgentManager = class _ParallelAgentManager {
|
|
|
22955
22980
|
store = new TaskStore();
|
|
22956
22981
|
client;
|
|
22957
22982
|
directory;
|
|
22958
|
-
concurrency
|
|
22983
|
+
concurrency;
|
|
22959
22984
|
sessionPool;
|
|
22960
22985
|
// Composed components
|
|
22961
22986
|
launcher;
|
|
@@ -22963,9 +22988,10 @@ var ParallelAgentManager = class _ParallelAgentManager {
|
|
|
22963
22988
|
poller;
|
|
22964
22989
|
cleaner;
|
|
22965
22990
|
eventHandler;
|
|
22966
|
-
constructor(client, directory) {
|
|
22991
|
+
constructor(client, directory, concurrencyConfig) {
|
|
22967
22992
|
this.client = client;
|
|
22968
22993
|
this.directory = directory;
|
|
22994
|
+
this.concurrency = new ConcurrencyController(concurrencyConfig);
|
|
22969
22995
|
const memory = MemoryManager.getInstance();
|
|
22970
22996
|
memory.add("system" /* SYSTEM */, CORE_PHILOSOPHY, 1);
|
|
22971
22997
|
memory.add("project" /* PROJECT */, `Working directory: ${directory}`, 0.9);
|
|
@@ -23017,12 +23043,12 @@ var ParallelAgentManager = class _ParallelAgentManager {
|
|
|
23017
23043
|
log("Recovery error:", err);
|
|
23018
23044
|
});
|
|
23019
23045
|
}
|
|
23020
|
-
static getInstance(client, directory) {
|
|
23046
|
+
static getInstance(client, directory, concurrencyConfig) {
|
|
23021
23047
|
if (!_ParallelAgentManager._instance) {
|
|
23022
23048
|
if (!client || !directory) {
|
|
23023
23049
|
throw new Error("ParallelAgentManager requires client and directory on first call");
|
|
23024
23050
|
}
|
|
23025
|
-
_ParallelAgentManager._instance = new _ParallelAgentManager(client, directory);
|
|
23051
|
+
_ParallelAgentManager._instance = new _ParallelAgentManager(client, directory, concurrencyConfig);
|
|
23026
23052
|
}
|
|
23027
23053
|
return _ParallelAgentManager._instance;
|
|
23028
23054
|
}
|
|
@@ -23091,6 +23117,9 @@ var ParallelAgentManager = class _ParallelAgentManager {
|
|
|
23091
23117
|
setConcurrencyLimit(agentType, limit) {
|
|
23092
23118
|
this.concurrency.setLimit(agentType, limit);
|
|
23093
23119
|
}
|
|
23120
|
+
configureConcurrency(config3) {
|
|
23121
|
+
this.concurrency.configure(config3);
|
|
23122
|
+
}
|
|
23094
23123
|
getPendingCount(parentSessionID) {
|
|
23095
23124
|
return this.store.getPendingCount(parentSessionID);
|
|
23096
23125
|
}
|
|
@@ -23719,7 +23748,7 @@ function $constructor2(name, initializer5, params) {
|
|
|
23719
23748
|
Object.defineProperty(_, "name", { value: name });
|
|
23720
23749
|
return _;
|
|
23721
23750
|
}
|
|
23722
|
-
var $brand2 = Symbol("zod_brand");
|
|
23751
|
+
var $brand2 = /* @__PURE__ */ Symbol("zod_brand");
|
|
23723
23752
|
var $ZodAsyncError2 = class extends Error {
|
|
23724
23753
|
constructor() {
|
|
23725
23754
|
super(`Encountered Promise during synchronous parse. Use .parseAsync() instead.`);
|
|
@@ -23864,7 +23893,7 @@ function floatSafeRemainder2(val, step) {
|
|
|
23864
23893
|
const stepInt = Number.parseInt(step.toFixed(decCount).replace(".", ""));
|
|
23865
23894
|
return valInt % stepInt / 10 ** decCount;
|
|
23866
23895
|
}
|
|
23867
|
-
var EVALUATING2 = Symbol("evaluating");
|
|
23896
|
+
var EVALUATING2 = /* @__PURE__ */ Symbol("evaluating");
|
|
23868
23897
|
function defineLazy2(object3, key, getter) {
|
|
23869
23898
|
let value = void 0;
|
|
23870
23899
|
Object.defineProperty(object3, key, {
|
|
@@ -23909,10 +23938,10 @@ function mergeDefs2(...defs) {
|
|
|
23909
23938
|
function cloneDef2(schema) {
|
|
23910
23939
|
return mergeDefs2(schema._zod.def);
|
|
23911
23940
|
}
|
|
23912
|
-
function getElementAtPath2(obj,
|
|
23913
|
-
if (!
|
|
23941
|
+
function getElementAtPath2(obj, path11) {
|
|
23942
|
+
if (!path11)
|
|
23914
23943
|
return obj;
|
|
23915
|
-
return
|
|
23944
|
+
return path11.reduce((acc, key) => acc?.[key], obj);
|
|
23916
23945
|
}
|
|
23917
23946
|
function promiseAllObject2(promisesObj) {
|
|
23918
23947
|
const keys = Object.keys(promisesObj);
|
|
@@ -24273,11 +24302,11 @@ function aborted2(x, startIndex = 0) {
|
|
|
24273
24302
|
}
|
|
24274
24303
|
return false;
|
|
24275
24304
|
}
|
|
24276
|
-
function prefixIssues2(
|
|
24305
|
+
function prefixIssues2(path11, issues) {
|
|
24277
24306
|
return issues.map((iss) => {
|
|
24278
24307
|
var _a3;
|
|
24279
24308
|
(_a3 = iss).path ?? (_a3.path = []);
|
|
24280
|
-
iss.path.unshift(
|
|
24309
|
+
iss.path.unshift(path11);
|
|
24281
24310
|
return iss;
|
|
24282
24311
|
});
|
|
24283
24312
|
}
|
|
@@ -24445,7 +24474,7 @@ function treeifyError2(error95, _mapper) {
|
|
|
24445
24474
|
return issue3.message;
|
|
24446
24475
|
};
|
|
24447
24476
|
const result = { errors: [] };
|
|
24448
|
-
const processError = (error96,
|
|
24477
|
+
const processError = (error96, path11 = []) => {
|
|
24449
24478
|
var _a3, _b;
|
|
24450
24479
|
for (const issue3 of error96.issues) {
|
|
24451
24480
|
if (issue3.code === "invalid_union" && issue3.errors.length) {
|
|
@@ -24455,7 +24484,7 @@ function treeifyError2(error95, _mapper) {
|
|
|
24455
24484
|
} else if (issue3.code === "invalid_element") {
|
|
24456
24485
|
processError({ issues: issue3.issues }, issue3.path);
|
|
24457
24486
|
} else {
|
|
24458
|
-
const fullpath = [...
|
|
24487
|
+
const fullpath = [...path11, ...issue3.path];
|
|
24459
24488
|
if (fullpath.length === 0) {
|
|
24460
24489
|
result.errors.push(mapper(issue3));
|
|
24461
24490
|
continue;
|
|
@@ -24487,8 +24516,8 @@ function treeifyError2(error95, _mapper) {
|
|
|
24487
24516
|
}
|
|
24488
24517
|
function toDotPath2(_path) {
|
|
24489
24518
|
const segs = [];
|
|
24490
|
-
const
|
|
24491
|
-
for (const seg of
|
|
24519
|
+
const path11 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
24520
|
+
for (const seg of path11) {
|
|
24492
24521
|
if (typeof seg === "number")
|
|
24493
24522
|
segs.push(`[${seg}]`);
|
|
24494
24523
|
else if (typeof seg === "symbol")
|
|
@@ -32709,8 +32738,8 @@ function yo_default2() {
|
|
|
32709
32738
|
}
|
|
32710
32739
|
|
|
32711
32740
|
// node_modules/@opencode-ai/plugin/node_modules/zod/v4/core/registries.js
|
|
32712
|
-
var $output2 = Symbol("ZodOutput");
|
|
32713
|
-
var $input2 = Symbol("ZodInput");
|
|
32741
|
+
var $output2 = /* @__PURE__ */ Symbol("ZodOutput");
|
|
32742
|
+
var $input2 = /* @__PURE__ */ Symbol("ZodInput");
|
|
32714
32743
|
var $ZodRegistry2 = class {
|
|
32715
32744
|
constructor() {
|
|
32716
32745
|
this._map = /* @__PURE__ */ new WeakMap();
|
|
@@ -33593,7 +33622,7 @@ function _stringbool2(Classes, _params) {
|
|
|
33593
33622
|
type: "pipe",
|
|
33594
33623
|
in: stringSchema,
|
|
33595
33624
|
out: booleanSchema,
|
|
33596
|
-
transform: (input, payload) => {
|
|
33625
|
+
transform: ((input, payload) => {
|
|
33597
33626
|
let data = input;
|
|
33598
33627
|
if (params.case !== "sensitive")
|
|
33599
33628
|
data = data.toLowerCase();
|
|
@@ -33612,14 +33641,14 @@ function _stringbool2(Classes, _params) {
|
|
|
33612
33641
|
});
|
|
33613
33642
|
return {};
|
|
33614
33643
|
}
|
|
33615
|
-
},
|
|
33616
|
-
reverseTransform: (input, _payload) => {
|
|
33644
|
+
}),
|
|
33645
|
+
reverseTransform: ((input, _payload) => {
|
|
33617
33646
|
if (input === true) {
|
|
33618
33647
|
return truthyArray[0] || "true";
|
|
33619
33648
|
} else {
|
|
33620
33649
|
return falsyArray[0] || "false";
|
|
33621
33650
|
}
|
|
33622
|
-
},
|
|
33651
|
+
}),
|
|
33623
33652
|
error: params.error
|
|
33624
33653
|
});
|
|
33625
33654
|
return codec3;
|
|
@@ -34579,10 +34608,10 @@ var ZodType2 = /* @__PURE__ */ $constructor2("ZodType", (inst, def) => {
|
|
|
34579
34608
|
};
|
|
34580
34609
|
inst.clone = (def2, params) => clone2(inst, def2, params);
|
|
34581
34610
|
inst.brand = () => inst;
|
|
34582
|
-
inst.register = (reg, meta3) => {
|
|
34611
|
+
inst.register = ((reg, meta3) => {
|
|
34583
34612
|
reg.add(inst, meta3);
|
|
34584
34613
|
return inst;
|
|
34585
|
-
};
|
|
34614
|
+
});
|
|
34586
34615
|
inst.parse = (data, params) => parse4(inst, data, params, { callee: inst.parse });
|
|
34587
34616
|
inst.safeParse = (data, params) => safeParse4(inst, data, params);
|
|
34588
34617
|
inst.parseAsync = async (data, params) => parseAsync4(inst, data, params, { callee: inst.parseAsync });
|
|
@@ -36409,8 +36438,8 @@ init_logger();
|
|
|
36409
36438
|
// src/core/loop/mission-loop.ts
|
|
36410
36439
|
init_logger();
|
|
36411
36440
|
init_shared();
|
|
36412
|
-
import { existsSync as
|
|
36413
|
-
import { join as
|
|
36441
|
+
import { existsSync as existsSync3, readFileSync as readFileSync2, writeFileSync as writeFileSync2, unlinkSync, mkdirSync as mkdirSync4 } from "node:fs";
|
|
36442
|
+
import { join as join6 } from "node:path";
|
|
36414
36443
|
|
|
36415
36444
|
// src/shared/constants/system-messages.ts
|
|
36416
36445
|
init_mission_control();
|
|
@@ -36518,19 +36547,199 @@ You must maintain a pristine workspace. **As part of your move**, perform these
|
|
|
36518
36547
|
</system_maintenance>
|
|
36519
36548
|
`;
|
|
36520
36549
|
|
|
36550
|
+
// src/core/knowledge/mission-memory.ts
|
|
36551
|
+
init_shared();
|
|
36552
|
+
import { mkdirSync as mkdirSync3, renameSync, writeFileSync } from "node:fs";
|
|
36553
|
+
import { dirname as dirname2, join as join5 } from "node:path";
|
|
36554
|
+
|
|
36555
|
+
// src/core/loop/mission-ledger.ts
|
|
36556
|
+
init_shared();
|
|
36557
|
+
import { appendFileSync, existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync } from "node:fs";
|
|
36558
|
+
import { join as join4 } from "node:path";
|
|
36559
|
+
import { randomUUID } from "node:crypto";
|
|
36560
|
+
|
|
36561
|
+
// src/core/loop/mission-runtime-options.ts
|
|
36562
|
+
var DEFAULT_MISSION_RUNTIME_OPTIONS = {
|
|
36563
|
+
ledger: true,
|
|
36564
|
+
markdownMemory: true,
|
|
36565
|
+
maxEvidenceEvents: 20
|
|
36566
|
+
};
|
|
36567
|
+
var runtimeOptions = { ...DEFAULT_MISSION_RUNTIME_OPTIONS };
|
|
36568
|
+
function configureMissionRuntimeOptions(options) {
|
|
36569
|
+
runtimeOptions = { ...DEFAULT_MISSION_RUNTIME_OPTIONS, ...options };
|
|
36570
|
+
}
|
|
36571
|
+
function getMissionRuntimeOptions() {
|
|
36572
|
+
return runtimeOptions;
|
|
36573
|
+
}
|
|
36574
|
+
|
|
36575
|
+
// src/core/loop/mission-ledger.ts
|
|
36576
|
+
var LEDGER_FILE = "mission-ledger.jsonl";
|
|
36577
|
+
function getMissionLedgerPath(directory) {
|
|
36578
|
+
return join4(directory, PATHS.OPENCODE, LEDGER_FILE);
|
|
36579
|
+
}
|
|
36580
|
+
function appendMissionLedgerEvent(directory, input) {
|
|
36581
|
+
if (!getMissionRuntimeOptions().ledger) return null;
|
|
36582
|
+
const event = {
|
|
36583
|
+
id: randomUUID(),
|
|
36584
|
+
timestamp: input.timestamp ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
36585
|
+
type: input.type,
|
|
36586
|
+
sessionID: input.sessionID,
|
|
36587
|
+
iteration: input.iteration,
|
|
36588
|
+
objective: input.objective,
|
|
36589
|
+
summary: input.summary,
|
|
36590
|
+
reason: input.reason
|
|
36591
|
+
};
|
|
36592
|
+
try {
|
|
36593
|
+
const ledgerPath = getMissionLedgerPath(directory);
|
|
36594
|
+
mkdirSync2(join4(directory, PATHS.OPENCODE), { recursive: true });
|
|
36595
|
+
appendFileSync(ledgerPath, `${JSON.stringify(event)}
|
|
36596
|
+
`, "utf8");
|
|
36597
|
+
return event;
|
|
36598
|
+
} catch {
|
|
36599
|
+
return null;
|
|
36600
|
+
}
|
|
36601
|
+
}
|
|
36602
|
+
function readMissionLedger(directory, limit = 20) {
|
|
36603
|
+
const options = getMissionRuntimeOptions();
|
|
36604
|
+
if (!options.ledger) return [];
|
|
36605
|
+
const ledgerPath = getMissionLedgerPath(directory);
|
|
36606
|
+
if (!existsSync2(ledgerPath)) return [];
|
|
36607
|
+
try {
|
|
36608
|
+
const lines = readFileSync(ledgerPath, "utf8").split(/\r?\n/).filter(Boolean);
|
|
36609
|
+
const maxEvents = Math.max(1, Math.min(limit, options.maxEvidenceEvents));
|
|
36610
|
+
return lines.slice(Math.max(0, lines.length - maxEvents)).map(parseLedgerLine).filter((event) => event !== null);
|
|
36611
|
+
} catch {
|
|
36612
|
+
return [];
|
|
36613
|
+
}
|
|
36614
|
+
}
|
|
36615
|
+
function parseLedgerLine(line) {
|
|
36616
|
+
try {
|
|
36617
|
+
const value = JSON.parse(line);
|
|
36618
|
+
if (!value.id || !value.type || !value.timestamp || !value.sessionID) return null;
|
|
36619
|
+
return value;
|
|
36620
|
+
} catch {
|
|
36621
|
+
return null;
|
|
36622
|
+
}
|
|
36623
|
+
}
|
|
36624
|
+
|
|
36625
|
+
// src/core/knowledge/mission-memory.ts
|
|
36626
|
+
var BRAIN_DIR = join5(PATHS.DOCS, "brain");
|
|
36627
|
+
var SCRATCHPAD_FILE = "scratchpad.md";
|
|
36628
|
+
var CANVAS_FILE = "knowledge-map.canvas";
|
|
36629
|
+
var MAX_CANVAS_EVENTS = 3;
|
|
36630
|
+
var MAX_SCRATCHPAD_EVENTS = 6;
|
|
36631
|
+
function syncMissionMemory(directory, state2) {
|
|
36632
|
+
const options = getMissionRuntimeOptions();
|
|
36633
|
+
if (!options.markdownMemory) return false;
|
|
36634
|
+
const events = readMissionLedger(
|
|
36635
|
+
directory,
|
|
36636
|
+
Math.min(MAX_SCRATCHPAD_EVENTS, options.maxEvidenceEvents)
|
|
36637
|
+
);
|
|
36638
|
+
try {
|
|
36639
|
+
writeScratchpad(directory, state2, events);
|
|
36640
|
+
writeCanvas(directory, state2, events);
|
|
36641
|
+
return true;
|
|
36642
|
+
} catch {
|
|
36643
|
+
return false;
|
|
36644
|
+
}
|
|
36645
|
+
}
|
|
36646
|
+
function getMissionScratchpadPath(directory) {
|
|
36647
|
+
return join5(directory, BRAIN_DIR, SCRATCHPAD_FILE);
|
|
36648
|
+
}
|
|
36649
|
+
function getMissionCanvasPath(directory) {
|
|
36650
|
+
return join5(directory, BRAIN_DIR, CANVAS_FILE);
|
|
36651
|
+
}
|
|
36652
|
+
function writeScratchpad(directory, state2, events) {
|
|
36653
|
+
const content = [
|
|
36654
|
+
"---",
|
|
36655
|
+
"tags: [scratchpad, mission, orchestrator]",
|
|
36656
|
+
"keep: true",
|
|
36657
|
+
`title: "${escapeYaml(state2.objective ?? "Active Mission")}"`,
|
|
36658
|
+
"---",
|
|
36659
|
+
"# Orchestrator Mission Scratchpad",
|
|
36660
|
+
"",
|
|
36661
|
+
"## Focus",
|
|
36662
|
+
`- Objective: ${state2.objective ?? state2.prompt}`,
|
|
36663
|
+
`- Session: ${state2.sessionID}`,
|
|
36664
|
+
`- Status: ${state2.active ? "active" : "inactive"}`,
|
|
36665
|
+
`- Iteration: ${state2.iteration}/${state2.maxIterations}`,
|
|
36666
|
+
"",
|
|
36667
|
+
"## Runtime State",
|
|
36668
|
+
`- Last progress: ${state2.lastProgress ?? "unknown"}`,
|
|
36669
|
+
`- Last verification: ${state2.lastVerificationSummary ?? "unknown"}`,
|
|
36670
|
+
`- Last continuation reason: ${state2.lastContinuationReason ?? "unknown"}`,
|
|
36671
|
+
"",
|
|
36672
|
+
"## Recent Evidence",
|
|
36673
|
+
...formatEventLines(events),
|
|
36674
|
+
"",
|
|
36675
|
+
"## Open Questions",
|
|
36676
|
+
"- Keep this section short; unresolved blockers should be reflected in TODO or sync issues.",
|
|
36677
|
+
""
|
|
36678
|
+
].join("\n");
|
|
36679
|
+
atomicWrite(getMissionScratchpadPath(directory), content);
|
|
36680
|
+
}
|
|
36681
|
+
function writeCanvas(directory, state2, events) {
|
|
36682
|
+
const nodes = buildCanvasNodes(state2, events);
|
|
36683
|
+
const edges = buildCanvasEdges(nodes);
|
|
36684
|
+
atomicWrite(getMissionCanvasPath(directory), JSON.stringify({ nodes, edges }, null, 2));
|
|
36685
|
+
}
|
|
36686
|
+
function buildCanvasNodes(state2, events) {
|
|
36687
|
+
const nodes = [
|
|
36688
|
+
textNode("objective", `Objective
|
|
36689
|
+
${state2.objective ?? state2.prompt}`, 0, 0),
|
|
36690
|
+
textNode("runtime", `Runtime
|
|
36691
|
+
Iteration ${state2.iteration}/${state2.maxIterations}
|
|
36692
|
+
Progress ${state2.lastProgress ?? "unknown"}`, 420, 0),
|
|
36693
|
+
textNode("verification", `Verification
|
|
36694
|
+
${state2.lastVerificationSummary ?? "unknown"}`, 840, 0)
|
|
36695
|
+
];
|
|
36696
|
+
events.slice(-MAX_CANVAS_EVENTS).forEach((event, index) => {
|
|
36697
|
+
nodes.push(textNode(`event-${index}`, `${event.type}
|
|
36698
|
+
${event.summary ?? event.reason ?? event.timestamp}`, 420 * index, 260));
|
|
36699
|
+
});
|
|
36700
|
+
return nodes;
|
|
36701
|
+
}
|
|
36702
|
+
function buildCanvasEdges(nodes) {
|
|
36703
|
+
const edges = [
|
|
36704
|
+
{ id: "objective-runtime", fromNode: "objective", toNode: "runtime", label: "drives" },
|
|
36705
|
+
{ id: "runtime-verification", fromNode: "runtime", toNode: "verification", label: "checks" }
|
|
36706
|
+
];
|
|
36707
|
+
for (const node of nodes.filter((item) => item.id.startsWith("event-"))) {
|
|
36708
|
+
edges.push({ id: `verification-${node.id}`, fromNode: "verification", toNode: node.id, label: "evidence" });
|
|
36709
|
+
}
|
|
36710
|
+
return edges;
|
|
36711
|
+
}
|
|
36712
|
+
function textNode(id, text, x, y) {
|
|
36713
|
+
return { id, type: "text", text, x, y, width: 360, height: 180 };
|
|
36714
|
+
}
|
|
36715
|
+
function formatEventLines(events) {
|
|
36716
|
+
if (events.length === 0) return ["- No runtime evidence recorded yet."];
|
|
36717
|
+
return events.map((event) => `- ${event.timestamp} ${event.type}: ${event.summary ?? event.reason ?? "recorded"}`);
|
|
36718
|
+
}
|
|
36719
|
+
function atomicWrite(path11, content) {
|
|
36720
|
+
mkdirSync3(dirname2(path11), { recursive: true });
|
|
36721
|
+
const tempPath = `${path11}.tmp`;
|
|
36722
|
+
writeFileSync(tempPath, content, "utf8");
|
|
36723
|
+
renameSync(tempPath, path11);
|
|
36724
|
+
}
|
|
36725
|
+
function escapeYaml(value) {
|
|
36726
|
+
return value.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
|
|
36727
|
+
}
|
|
36728
|
+
|
|
36521
36729
|
// src/core/loop/mission-loop.ts
|
|
36522
36730
|
var STATE_FILE = MISSION_CONTROL.STATE_FILE;
|
|
36523
36731
|
var DEFAULT_MAX_ITERATIONS = MISSION_CONTROL.DEFAULT_MAX_ITERATIONS;
|
|
36732
|
+
var UNKNOWN_STATUS = "unknown";
|
|
36524
36733
|
function getStateFilePath(directory) {
|
|
36525
|
-
return
|
|
36734
|
+
return join6(directory, PATHS.OPENCODE, STATE_FILE);
|
|
36526
36735
|
}
|
|
36527
36736
|
function readLoopState(directory) {
|
|
36528
36737
|
const filePath = getStateFilePath(directory);
|
|
36529
|
-
if (!
|
|
36738
|
+
if (!existsSync3(filePath)) {
|
|
36530
36739
|
return null;
|
|
36531
36740
|
}
|
|
36532
36741
|
try {
|
|
36533
|
-
const content =
|
|
36742
|
+
const content = readFileSync2(filePath, "utf-8");
|
|
36534
36743
|
return JSON.parse(content);
|
|
36535
36744
|
} catch (error95) {
|
|
36536
36745
|
log(`[${MISSION_CONTROL.LOG_SOURCE}] Failed to read state: ${error95}`);
|
|
@@ -36539,12 +36748,12 @@ function readLoopState(directory) {
|
|
|
36539
36748
|
}
|
|
36540
36749
|
function writeLoopState(directory, state2) {
|
|
36541
36750
|
const filePath = getStateFilePath(directory);
|
|
36542
|
-
const dirPath =
|
|
36751
|
+
const dirPath = join6(directory, PATHS.OPENCODE);
|
|
36543
36752
|
try {
|
|
36544
|
-
if (!
|
|
36545
|
-
|
|
36753
|
+
if (!existsSync3(dirPath)) {
|
|
36754
|
+
mkdirSync4(dirPath, { recursive: true });
|
|
36546
36755
|
}
|
|
36547
|
-
|
|
36756
|
+
writeFileSync2(filePath, JSON.stringify(state2, null, 2), "utf-8");
|
|
36548
36757
|
return true;
|
|
36549
36758
|
} catch (error95) {
|
|
36550
36759
|
log(`[${MISSION_CONTROL.LOG_SOURCE}] Failed to write state: ${error95}`);
|
|
@@ -36553,7 +36762,7 @@ function writeLoopState(directory, state2) {
|
|
|
36553
36762
|
}
|
|
36554
36763
|
function clearLoopState(directory) {
|
|
36555
36764
|
const filePath = getStateFilePath(directory);
|
|
36556
|
-
if (!
|
|
36765
|
+
if (!existsSync3(filePath)) {
|
|
36557
36766
|
return false;
|
|
36558
36767
|
}
|
|
36559
36768
|
try {
|
|
@@ -36574,17 +36783,30 @@ function incrementIteration(directory) {
|
|
|
36574
36783
|
}
|
|
36575
36784
|
return null;
|
|
36576
36785
|
}
|
|
36786
|
+
function deriveObjective(prompt) {
|
|
36787
|
+
const firstLine = prompt.split(/\r?\n/).find((line) => line.trim().length > 0);
|
|
36788
|
+
return firstLine?.trim() || prompt.trim() || "Continue the active mission";
|
|
36789
|
+
}
|
|
36577
36790
|
function startMissionLoop(directory, sessionID, prompt, options = {}) {
|
|
36578
36791
|
const state2 = {
|
|
36579
36792
|
active: true,
|
|
36580
36793
|
iteration: 1,
|
|
36581
36794
|
maxIterations: options.maxIterations ?? DEFAULT_MAX_ITERATIONS,
|
|
36582
36795
|
prompt,
|
|
36796
|
+
objective: deriveObjective(prompt),
|
|
36583
36797
|
sessionID,
|
|
36584
36798
|
startedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
36585
36799
|
};
|
|
36586
36800
|
const success3 = writeLoopState(directory, state2);
|
|
36587
36801
|
if (success3) {
|
|
36802
|
+
appendMissionLedgerEvent(directory, {
|
|
36803
|
+
type: "mission_started",
|
|
36804
|
+
sessionID,
|
|
36805
|
+
iteration: state2.iteration,
|
|
36806
|
+
objective: state2.objective,
|
|
36807
|
+
summary: "Mission loop started"
|
|
36808
|
+
});
|
|
36809
|
+
syncMissionMemory(directory, state2);
|
|
36588
36810
|
log(`[${MISSION_CONTROL.LOG_SOURCE}] Loop started`, {
|
|
36589
36811
|
sessionID,
|
|
36590
36812
|
maxIterations: state2.maxIterations
|
|
@@ -36599,6 +36821,19 @@ function cancelMissionLoop(directory, sessionID) {
|
|
|
36599
36821
|
}
|
|
36600
36822
|
const success3 = clearLoopState(directory);
|
|
36601
36823
|
if (success3) {
|
|
36824
|
+
const cancelledState = {
|
|
36825
|
+
...state2,
|
|
36826
|
+
active: false,
|
|
36827
|
+
lastContinuationReason: "cancelled"
|
|
36828
|
+
};
|
|
36829
|
+
appendMissionLedgerEvent(directory, {
|
|
36830
|
+
type: "mission_cancelled",
|
|
36831
|
+
sessionID,
|
|
36832
|
+
iteration: state2.iteration,
|
|
36833
|
+
objective: state2.objective,
|
|
36834
|
+
reason: "cancelled"
|
|
36835
|
+
});
|
|
36836
|
+
syncMissionMemory(directory, cancelledState);
|
|
36602
36837
|
log(`[${MISSION_CONTROL.LOG_SOURCE}] Loop cancelled`, { sessionID, iteration: state2.iteration });
|
|
36603
36838
|
}
|
|
36604
36839
|
return success3;
|
|
@@ -36607,26 +36842,48 @@ function isLoopActive(directory, sessionID) {
|
|
|
36607
36842
|
const state2 = readLoopState(directory);
|
|
36608
36843
|
return state2?.active === true && state2?.sessionID === sessionID;
|
|
36609
36844
|
}
|
|
36610
|
-
function generateMissionContinuationPrompt(state2,
|
|
36611
|
-
const
|
|
36612
|
-
[Verification Status]: ${verificationSummary}
|
|
36613
|
-
` : "";
|
|
36845
|
+
function generateMissionContinuationPrompt(state2, input) {
|
|
36846
|
+
const context = normalizeContinuationContext(state2, input);
|
|
36614
36847
|
let prompt = `${CONTINUE_INSTRUCTION}
|
|
36615
36848
|
|
|
36616
36849
|
<mission_loop iteration="${state2.iteration}" max="${state2.maxIterations}">
|
|
36617
|
-
|
|
36618
|
-
|
|
36850
|
+
MISSION NOT COMPLETE
|
|
36851
|
+
|
|
36852
|
+
Objective:
|
|
36853
|
+
${context.objective}
|
|
36619
36854
|
|
|
36620
|
-
|
|
36621
|
-
${
|
|
36855
|
+
Runtime status:
|
|
36856
|
+
- todo progress: ${context.progress}
|
|
36857
|
+
- verification: ${context.verification}
|
|
36858
|
+
- stagnation: ${context.stagnation}
|
|
36859
|
+
- continuation reason: ${context.reason}
|
|
36622
36860
|
|
|
36623
|
-
|
|
36861
|
+
Next action:
|
|
36862
|
+
1. Read the current TODO, checklist, and sync issue state.
|
|
36863
|
+
2. Execute or delegate only the next unblocked work.
|
|
36864
|
+
3. Verify the result with real file reads, build commands, tests, or tool output.
|
|
36865
|
+
4. Finish only when mission verification passes.
|
|
36866
|
+
|
|
36867
|
+
Completion rule:
|
|
36868
|
+
Do not declare success while TODO/checklist/sync verification is still failing.
|
|
36624
36869
|
</mission_loop>`;
|
|
36625
36870
|
if (state2.iteration > 1) {
|
|
36626
36871
|
prompt += "\n" + CLEANUP_INSTRUCTION.replace("%ITER%", state2.iteration.toString());
|
|
36627
36872
|
}
|
|
36628
36873
|
return prompt;
|
|
36629
36874
|
}
|
|
36875
|
+
function normalizeContinuationContext(state2, input) {
|
|
36876
|
+
const verificationSummary = typeof input === "string" ? input : input?.verificationSummary;
|
|
36877
|
+
const continuationReason = typeof input === "string" ? void 0 : input?.continuationReason;
|
|
36878
|
+
const stagnationCount = state2.stagnationCount ?? 0;
|
|
36879
|
+
return {
|
|
36880
|
+
objective: state2.objective || deriveObjective(state2.prompt),
|
|
36881
|
+
progress: state2.lastProgress ?? UNKNOWN_STATUS,
|
|
36882
|
+
verification: verificationSummary ?? state2.lastVerificationSummary ?? UNKNOWN_STATUS,
|
|
36883
|
+
reason: continuationReason ?? state2.lastContinuationReason ?? "verification_failed",
|
|
36884
|
+
stagnation: stagnationCount > 0 ? `${stagnationCount} unchanged check(s)` : "not detected"
|
|
36885
|
+
};
|
|
36886
|
+
}
|
|
36630
36887
|
|
|
36631
36888
|
// src/core/orchestrator/session-manager.ts
|
|
36632
36889
|
function ensureSessionInitialized(sessions, sessionID, directory) {
|
|
@@ -36638,6 +36895,7 @@ function ensureSessionInitialized(sessions, sessionID, directory) {
|
|
|
36638
36895
|
timestamp: now,
|
|
36639
36896
|
startTime: now,
|
|
36640
36897
|
lastStepTime: now,
|
|
36898
|
+
lastCompletedMessageID: void 0,
|
|
36641
36899
|
tokens: { totalInput: 0, totalOutput: 0, estimatedCost: 0 }
|
|
36642
36900
|
};
|
|
36643
36901
|
if (directory) {
|
|
@@ -36949,8 +37207,8 @@ ${commandList}`;
|
|
|
36949
37207
|
// src/core/loop/verification.ts
|
|
36950
37208
|
init_shared();
|
|
36951
37209
|
init_logger();
|
|
36952
|
-
import { existsSync as
|
|
36953
|
-
import { join as
|
|
37210
|
+
import { existsSync as existsSync4, readFileSync as readFileSync3 } from "node:fs";
|
|
37211
|
+
import { join as join7 } from "node:path";
|
|
36954
37212
|
var CHECKLIST_FILE = CHECKLIST.FILE;
|
|
36955
37213
|
function parseChecklistLine(line, currentCategory) {
|
|
36956
37214
|
const trimmedLine = line.trim();
|
|
@@ -37015,12 +37273,12 @@ function parseChecklist(content) {
|
|
|
37015
37273
|
return items;
|
|
37016
37274
|
}
|
|
37017
37275
|
function readChecklist(directory) {
|
|
37018
|
-
const filePath =
|
|
37019
|
-
if (!
|
|
37276
|
+
const filePath = join7(directory, CHECKLIST_FILE);
|
|
37277
|
+
if (!existsSync4(filePath)) {
|
|
37020
37278
|
return [];
|
|
37021
37279
|
}
|
|
37022
37280
|
try {
|
|
37023
|
-
const content =
|
|
37281
|
+
const content = readFileSync3(filePath, "utf-8");
|
|
37024
37282
|
return parseChecklist(content);
|
|
37025
37283
|
} catch (error95) {
|
|
37026
37284
|
log(`[checklist] Failed to read checklist: ${error95}`);
|
|
@@ -37037,8 +37295,8 @@ function verifyChecklist(directory) {
|
|
|
37037
37295
|
incompleteList: [],
|
|
37038
37296
|
errors: []
|
|
37039
37297
|
};
|
|
37040
|
-
const filePath =
|
|
37041
|
-
if (!
|
|
37298
|
+
const filePath = join7(directory, CHECKLIST_FILE);
|
|
37299
|
+
if (!existsSync4(filePath)) {
|
|
37042
37300
|
result.errors.push(`Verification checklist not found at ${CHECKLIST_FILE}`);
|
|
37043
37301
|
result.errors.push("Create checklist with at least: build, tests, and any environment-specific checks");
|
|
37044
37302
|
return result;
|
|
@@ -37114,10 +37372,10 @@ function verifyMissionCompletion(directory) {
|
|
|
37114
37372
|
result.errors.push(` ... and ${checklistResult.incompleteList.length - 5} more`);
|
|
37115
37373
|
}
|
|
37116
37374
|
}
|
|
37117
|
-
const todoPath =
|
|
37118
|
-
if (
|
|
37375
|
+
const todoPath = join7(directory, PATHS.TODO);
|
|
37376
|
+
if (existsSync4(todoPath)) {
|
|
37119
37377
|
try {
|
|
37120
|
-
const content =
|
|
37378
|
+
const content = readFileSync3(todoPath, "utf-8");
|
|
37121
37379
|
const incompleteCount = countMatches(content, TODO_INCOMPLETE_PATTERN);
|
|
37122
37380
|
const completeCount = countMatches(content, TODO_COMPLETE_PATTERN);
|
|
37123
37381
|
const total = incompleteCount + completeCount;
|
|
@@ -37139,10 +37397,10 @@ function verifyMissionCompletion(directory) {
|
|
|
37139
37397
|
} else if (!hasChecklist) {
|
|
37140
37398
|
result.errors.push(`TODO file not found at ${PATHS.TODO}`);
|
|
37141
37399
|
}
|
|
37142
|
-
const syncPath =
|
|
37143
|
-
if (
|
|
37400
|
+
const syncPath = join7(directory, PATHS.SYNC_ISSUES);
|
|
37401
|
+
if (existsSync4(syncPath)) {
|
|
37144
37402
|
try {
|
|
37145
|
-
const content =
|
|
37403
|
+
const content = readFileSync3(syncPath, "utf-8");
|
|
37146
37404
|
result.syncIssuesEmpty = !hasRealSyncIssues(content);
|
|
37147
37405
|
if (!result.syncIssuesEmpty) {
|
|
37148
37406
|
const issueLines = content.split("\n").filter(
|
|
@@ -37230,7 +37488,7 @@ function buildVerificationSummary(result) {
|
|
|
37230
37488
|
init_logger();
|
|
37231
37489
|
import { exec as exec2 } from "node:child_process";
|
|
37232
37490
|
import { promisify as promisify2 } from "node:util";
|
|
37233
|
-
import { readFileSync as
|
|
37491
|
+
import { readFileSync as readFileSync4 } from "node:fs";
|
|
37234
37492
|
|
|
37235
37493
|
// src/shared/notification/os-notify/constants/notification-commands.ts
|
|
37236
37494
|
var NOTIFICATION_COMMANDS = {
|
|
@@ -37284,10 +37542,10 @@ async function resolveCommandPath(key, commandName) {
|
|
|
37284
37542
|
const currentPending = pending.get(key);
|
|
37285
37543
|
if (currentPending) return currentPending;
|
|
37286
37544
|
const promise3 = (async () => {
|
|
37287
|
-
const
|
|
37288
|
-
cache[key] =
|
|
37545
|
+
const path11 = await findCommand(commandName);
|
|
37546
|
+
cache[key] = path11;
|
|
37289
37547
|
pending.delete(key);
|
|
37290
|
-
return
|
|
37548
|
+
return path11;
|
|
37291
37549
|
})();
|
|
37292
37550
|
pending.set(key, promise3);
|
|
37293
37551
|
return promise3;
|
|
@@ -37296,19 +37554,19 @@ async function resolveCommandPath(key, commandName) {
|
|
|
37296
37554
|
// src/core/notification/os-notify/notifier.ts
|
|
37297
37555
|
var execAsync2 = promisify2(exec2);
|
|
37298
37556
|
async function notifyDarwin(title, message) {
|
|
37299
|
-
const
|
|
37557
|
+
const path11 = await resolveCommandPath(
|
|
37300
37558
|
NOTIFICATION_COMMAND_KEYS.OSASCRIPT,
|
|
37301
37559
|
NOTIFICATION_COMMANDS.OSASCRIPT
|
|
37302
37560
|
);
|
|
37303
|
-
if (!
|
|
37561
|
+
if (!path11) return;
|
|
37304
37562
|
const escT = title.replace(/"/g, '\\"');
|
|
37305
37563
|
const escM = message.replace(/"/g, '\\"');
|
|
37306
|
-
await execAsync2(`${
|
|
37564
|
+
await execAsync2(`${path11} -e 'display notification "${escM}" with title "${escT}" sound name "Glass"' >/dev/null 2>/dev/null`);
|
|
37307
37565
|
}
|
|
37308
37566
|
function isWSL() {
|
|
37309
37567
|
try {
|
|
37310
37568
|
if (process.env.WSL_DISTRO_NAME || process.env.WSLENV) return true;
|
|
37311
|
-
const procVersion =
|
|
37569
|
+
const procVersion = readFileSync4("/proc/version", "utf-8");
|
|
37312
37570
|
return /microsoft|WSL/i.test(procVersion);
|
|
37313
37571
|
} catch {
|
|
37314
37572
|
return false;
|
|
@@ -37316,11 +37574,11 @@ function isWSL() {
|
|
|
37316
37574
|
}
|
|
37317
37575
|
async function notifyLinux(title, message) {
|
|
37318
37576
|
if (isWSL()) return;
|
|
37319
|
-
const
|
|
37577
|
+
const path11 = await resolveCommandPath(
|
|
37320
37578
|
NOTIFICATION_COMMAND_KEYS.NOTIFY_SEND,
|
|
37321
37579
|
NOTIFICATION_COMMANDS.NOTIFY_SEND
|
|
37322
37580
|
);
|
|
37323
|
-
if (
|
|
37581
|
+
if (path11) await execAsync2(`${path11} "${title}" "${message}" >/dev/null 2>/dev/null`);
|
|
37324
37582
|
}
|
|
37325
37583
|
async function notifyWindows(title, message) {
|
|
37326
37584
|
const ps = await resolveCommandPath(
|
|
@@ -37368,11 +37626,11 @@ init_os();
|
|
|
37368
37626
|
async function playDarwin(soundPath) {
|
|
37369
37627
|
if (!soundPath) return;
|
|
37370
37628
|
try {
|
|
37371
|
-
const
|
|
37629
|
+
const path11 = await resolveCommandPath(
|
|
37372
37630
|
NOTIFICATION_COMMAND_KEYS.AFPLAY,
|
|
37373
37631
|
NOTIFICATION_COMMANDS.AFPLAY
|
|
37374
37632
|
);
|
|
37375
|
-
if (
|
|
37633
|
+
if (path11) exec3(`"${path11}" "${soundPath}" >/dev/null 2>/dev/null`);
|
|
37376
37634
|
} catch (err) {
|
|
37377
37635
|
log(`[session-notify] Error playing sound (Darwin): ${err}`);
|
|
37378
37636
|
}
|
|
@@ -38784,9 +39042,9 @@ import * as path6 from "node:path";
|
|
|
38784
39042
|
|
|
38785
39043
|
// src/core/cache/utils.ts
|
|
38786
39044
|
import * as fs6 from "node:fs/promises";
|
|
38787
|
-
import { existsSync as
|
|
39045
|
+
import { existsSync as existsSync6 } from "node:fs";
|
|
38788
39046
|
async function ensureCacheDir() {
|
|
38789
|
-
if (!
|
|
39047
|
+
if (!existsSync6(CACHE_DIR)) {
|
|
38790
39048
|
await fs6.mkdir(CACHE_DIR, { recursive: true });
|
|
38791
39049
|
}
|
|
38792
39050
|
}
|
|
@@ -39288,15 +39546,15 @@ var backgroundTaskManager = BackgroundTaskManager.instance;
|
|
|
39288
39546
|
|
|
39289
39547
|
// src/tools/rust-pool.ts
|
|
39290
39548
|
import { spawn as spawn2 } from "child_process";
|
|
39291
|
-
import { existsSync as
|
|
39549
|
+
import { existsSync as existsSync9 } from "fs";
|
|
39292
39550
|
|
|
39293
39551
|
// src/utils/binary.ts
|
|
39294
39552
|
init_shared();
|
|
39295
|
-
import { join as
|
|
39553
|
+
import { join as join12, dirname as dirname5 } from "path";
|
|
39296
39554
|
import { fileURLToPath } from "url";
|
|
39297
39555
|
import { platform, arch } from "os";
|
|
39298
|
-
import { existsSync as
|
|
39299
|
-
var __dirname =
|
|
39556
|
+
import { existsSync as existsSync8 } from "fs";
|
|
39557
|
+
var __dirname = dirname5(fileURLToPath(import.meta.url));
|
|
39300
39558
|
function getPlatformBinaryName(os = platform(), cpu = arch()) {
|
|
39301
39559
|
if (os === PLATFORM.WIN32) {
|
|
39302
39560
|
return "orchestrator-windows-x64.exe";
|
|
@@ -39308,30 +39566,30 @@ function getPlatformBinaryName(os = platform(), cpu = arch()) {
|
|
|
39308
39566
|
}
|
|
39309
39567
|
function getCandidateBinDirs(moduleDir = __dirname) {
|
|
39310
39568
|
return [
|
|
39311
|
-
|
|
39312
|
-
|
|
39569
|
+
join12(moduleDir, "..", "bin"),
|
|
39570
|
+
join12(moduleDir, "..", "..", "bin")
|
|
39313
39571
|
];
|
|
39314
39572
|
}
|
|
39315
39573
|
function resolveBinaryPath(options = {}) {
|
|
39316
39574
|
const moduleDir = options.moduleDir ?? __dirname;
|
|
39317
39575
|
const os = options.os ?? platform();
|
|
39318
39576
|
const cpu = options.cpu ?? arch();
|
|
39319
|
-
const exists = options.exists ??
|
|
39577
|
+
const exists = options.exists ?? existsSync8;
|
|
39320
39578
|
const binaryName = getPlatformBinaryName(os, cpu);
|
|
39321
39579
|
for (const binDir of getCandidateBinDirs(moduleDir)) {
|
|
39322
|
-
const binaryPath =
|
|
39580
|
+
const binaryPath = join12(binDir, binaryName);
|
|
39323
39581
|
if (exists(binaryPath)) {
|
|
39324
39582
|
return binaryPath;
|
|
39325
39583
|
}
|
|
39326
39584
|
}
|
|
39327
39585
|
const fallbackName = os === PLATFORM.WIN32 ? "orchestrator.exe" : "orchestrator";
|
|
39328
39586
|
for (const binDir of getCandidateBinDirs(moduleDir)) {
|
|
39329
|
-
const fallbackPath =
|
|
39587
|
+
const fallbackPath = join12(binDir, fallbackName);
|
|
39330
39588
|
if (exists(fallbackPath)) {
|
|
39331
39589
|
return fallbackPath;
|
|
39332
39590
|
}
|
|
39333
39591
|
}
|
|
39334
|
-
return
|
|
39592
|
+
return join12(getCandidateBinDirs(moduleDir)[0], binaryName);
|
|
39335
39593
|
}
|
|
39336
39594
|
function getBinaryPath() {
|
|
39337
39595
|
return resolveBinaryPath();
|
|
@@ -39345,10 +39603,21 @@ var RustToolPool = class {
|
|
|
39345
39603
|
maxSize = 4;
|
|
39346
39604
|
idleTimeout = 3e4;
|
|
39347
39605
|
// 30 seconds
|
|
39606
|
+
processReadyDelay = 100;
|
|
39607
|
+
requestTimeout = 6e4;
|
|
39348
39608
|
cleanupInterval = null;
|
|
39609
|
+
binaryPath;
|
|
39610
|
+
exists;
|
|
39611
|
+
spawnProcess;
|
|
39349
39612
|
shuttingDown = false;
|
|
39350
|
-
constructor(maxSize = 4) {
|
|
39613
|
+
constructor(maxSize = 4, options = {}) {
|
|
39351
39614
|
this.maxSize = maxSize;
|
|
39615
|
+
this.binaryPath = options.binaryPath ?? getBinaryPath;
|
|
39616
|
+
this.exists = options.exists ?? existsSync9;
|
|
39617
|
+
this.idleTimeout = options.idleTimeoutMs ?? this.idleTimeout;
|
|
39618
|
+
this.processReadyDelay = options.processReadyDelayMs ?? this.processReadyDelay;
|
|
39619
|
+
this.requestTimeout = options.requestTimeoutMs ?? this.requestTimeout;
|
|
39620
|
+
this.spawnProcess = options.spawnProcess ?? spawn2;
|
|
39352
39621
|
this.startCleanupTimer();
|
|
39353
39622
|
}
|
|
39354
39623
|
/**
|
|
@@ -39358,16 +39627,13 @@ var RustToolPool = class {
|
|
|
39358
39627
|
if (this.shuttingDown) {
|
|
39359
39628
|
throw new Error("Pool is shutting down");
|
|
39360
39629
|
}
|
|
39361
|
-
const binary =
|
|
39362
|
-
if (!
|
|
39630
|
+
const binary = this.binaryPath();
|
|
39631
|
+
if (!this.exists(binary)) {
|
|
39363
39632
|
return JSON.stringify({ error: `Binary not found: ${binary}` });
|
|
39364
39633
|
}
|
|
39365
39634
|
let pooled = this.getAvailable();
|
|
39366
|
-
if (!pooled && this.processes.length < this.maxSize) {
|
|
39367
|
-
pooled = await this.createProcess(binary);
|
|
39368
|
-
}
|
|
39369
39635
|
if (!pooled) {
|
|
39370
|
-
pooled = await this.
|
|
39636
|
+
pooled = await this.createOrWaitForProcess(binary);
|
|
39371
39637
|
}
|
|
39372
39638
|
try {
|
|
39373
39639
|
return await this.sendRequest(pooled, name, args);
|
|
@@ -39382,15 +39648,29 @@ var RustToolPool = class {
|
|
|
39382
39648
|
return this.processes.find((p) => !p.busy) || null;
|
|
39383
39649
|
}
|
|
39384
39650
|
/**
|
|
39385
|
-
*
|
|
39651
|
+
* Create a process immediately, or wait until one is available/capacity opens.
|
|
39386
39652
|
*/
|
|
39387
|
-
async
|
|
39388
|
-
|
|
39653
|
+
async createOrWaitForProcess(binary) {
|
|
39654
|
+
if (this.processes.length < this.maxSize) {
|
|
39655
|
+
return this.createProcess(binary);
|
|
39656
|
+
}
|
|
39657
|
+
return this.waitForAvailable(binary);
|
|
39658
|
+
}
|
|
39659
|
+
/**
|
|
39660
|
+
* Wait for a process to become available, or create one if capacity opens.
|
|
39661
|
+
*/
|
|
39662
|
+
async waitForAvailable(binary) {
|
|
39663
|
+
return new Promise((resolve, reject) => {
|
|
39389
39664
|
const interval = setInterval(() => {
|
|
39390
39665
|
const available = this.getAvailable();
|
|
39391
39666
|
if (available) {
|
|
39392
39667
|
clearInterval(interval);
|
|
39393
39668
|
resolve(available);
|
|
39669
|
+
return;
|
|
39670
|
+
}
|
|
39671
|
+
if (this.processes.length < this.maxSize) {
|
|
39672
|
+
clearInterval(interval);
|
|
39673
|
+
this.createProcess(binary).then(resolve, reject);
|
|
39394
39674
|
}
|
|
39395
39675
|
}, 10);
|
|
39396
39676
|
});
|
|
@@ -39400,41 +39680,47 @@ var RustToolPool = class {
|
|
|
39400
39680
|
*/
|
|
39401
39681
|
async createProcess(binary) {
|
|
39402
39682
|
return new Promise((resolve, reject) => {
|
|
39403
|
-
const proc =
|
|
39683
|
+
const proc = this.spawnProcess(binary, ["serve"], {
|
|
39404
39684
|
stdio: ["pipe", "pipe", "pipe"],
|
|
39405
39685
|
detached: false
|
|
39406
39686
|
});
|
|
39407
|
-
let
|
|
39687
|
+
let startupSettled = false;
|
|
39688
|
+
let readyTimer = null;
|
|
39408
39689
|
const pooled = {
|
|
39409
39690
|
proc,
|
|
39410
|
-
busy:
|
|
39691
|
+
busy: true,
|
|
39692
|
+
destroyed: false,
|
|
39411
39693
|
lastUsed: Date.now(),
|
|
39412
39694
|
requestId: 0,
|
|
39413
39695
|
stdout: ""
|
|
39414
39696
|
};
|
|
39415
|
-
|
|
39416
|
-
|
|
39417
|
-
|
|
39418
|
-
started = true;
|
|
39697
|
+
const settleStartup = (callback) => {
|
|
39698
|
+
if (startupSettled) {
|
|
39699
|
+
return;
|
|
39419
39700
|
}
|
|
39420
|
-
|
|
39421
|
-
|
|
39422
|
-
|
|
39423
|
-
|
|
39424
|
-
this.processes.splice(index, 1);
|
|
39701
|
+
startupSettled = true;
|
|
39702
|
+
if (readyTimer) {
|
|
39703
|
+
clearTimeout(readyTimer);
|
|
39704
|
+
readyTimer = null;
|
|
39425
39705
|
}
|
|
39706
|
+
callback();
|
|
39707
|
+
};
|
|
39708
|
+
proc.on("close", () => {
|
|
39709
|
+
const error95 = new Error("Rust tool process closed before completing request");
|
|
39710
|
+
settleStartup(() => reject(error95));
|
|
39711
|
+
pooled.pendingReject?.(error95);
|
|
39712
|
+
this.removeProcess(pooled, false);
|
|
39426
39713
|
});
|
|
39427
39714
|
proc.on("error", (err) => {
|
|
39428
|
-
const
|
|
39429
|
-
|
|
39430
|
-
|
|
39431
|
-
|
|
39432
|
-
if (!started) {
|
|
39433
|
-
reject(err);
|
|
39434
|
-
}
|
|
39715
|
+
const error95 = err instanceof Error ? err : new Error(String(err));
|
|
39716
|
+
settleStartup(() => reject(error95));
|
|
39717
|
+
pooled.pendingReject?.(error95);
|
|
39718
|
+
this.removeProcess(pooled, false);
|
|
39435
39719
|
});
|
|
39436
39720
|
this.processes.push(pooled);
|
|
39437
|
-
setTimeout(() =>
|
|
39721
|
+
readyTimer = setTimeout(() => {
|
|
39722
|
+
settleStartup(() => resolve(pooled));
|
|
39723
|
+
}, this.processReadyDelay);
|
|
39438
39724
|
});
|
|
39439
39725
|
}
|
|
39440
39726
|
/**
|
|
@@ -39444,13 +39730,39 @@ var RustToolPool = class {
|
|
|
39444
39730
|
pooled.busy = true;
|
|
39445
39731
|
pooled.lastUsed = Date.now();
|
|
39446
39732
|
pooled.stdout = "";
|
|
39733
|
+
if (pooled.destroyed || !this.processes.includes(pooled)) {
|
|
39734
|
+
throw new Error("Rust tool process is unavailable");
|
|
39735
|
+
}
|
|
39447
39736
|
return new Promise((resolve, reject) => {
|
|
39448
39737
|
const requestId = ++pooled.requestId;
|
|
39738
|
+
let settled = false;
|
|
39739
|
+
const fail = (error95, kill) => {
|
|
39740
|
+
if (settled) {
|
|
39741
|
+
return;
|
|
39742
|
+
}
|
|
39743
|
+
settled = true;
|
|
39744
|
+
cleanup();
|
|
39745
|
+
this.removeProcess(pooled, kill);
|
|
39746
|
+
reject(error95);
|
|
39747
|
+
};
|
|
39748
|
+
const succeed = (text) => {
|
|
39749
|
+
if (settled) {
|
|
39750
|
+
return;
|
|
39751
|
+
}
|
|
39752
|
+
settled = true;
|
|
39753
|
+
cleanup();
|
|
39754
|
+
resolve(text);
|
|
39755
|
+
};
|
|
39449
39756
|
const timeout = setTimeout(() => {
|
|
39757
|
+
fail(new Error("Request timeout"), true);
|
|
39758
|
+
}, this.requestTimeout);
|
|
39759
|
+
const cleanup = () => {
|
|
39760
|
+
clearTimeout(timeout);
|
|
39450
39761
|
pooled.pendingResolve = void 0;
|
|
39451
39762
|
pooled.pendingReject = void 0;
|
|
39452
|
-
|
|
39453
|
-
|
|
39763
|
+
pooled.pendingCleanup = void 0;
|
|
39764
|
+
pooled.proc.stdout?.removeListener("data", onData);
|
|
39765
|
+
};
|
|
39454
39766
|
const onData = (data) => {
|
|
39455
39767
|
pooled.stdout += data.toString();
|
|
39456
39768
|
const lines = pooled.stdout.trim().split("\n");
|
|
@@ -39458,10 +39770,8 @@ var RustToolPool = class {
|
|
|
39458
39770
|
try {
|
|
39459
39771
|
const response = JSON.parse(lines[i]);
|
|
39460
39772
|
if (response.id === requestId && (response.result || response.error)) {
|
|
39461
|
-
clearTimeout(timeout);
|
|
39462
|
-
pooled.proc.stdout?.removeListener("data", onData);
|
|
39463
39773
|
const text = response?.result?.content?.[0]?.text;
|
|
39464
|
-
|
|
39774
|
+
succeed(text || JSON.stringify(response.result));
|
|
39465
39775
|
return;
|
|
39466
39776
|
}
|
|
39467
39777
|
} catch {
|
|
@@ -39469,6 +39779,8 @@ var RustToolPool = class {
|
|
|
39469
39779
|
}
|
|
39470
39780
|
}
|
|
39471
39781
|
};
|
|
39782
|
+
pooled.pendingReject = (error95) => fail(error95, false);
|
|
39783
|
+
pooled.pendingCleanup = cleanup;
|
|
39472
39784
|
pooled.proc.stdout?.on("data", onData);
|
|
39473
39785
|
const request = JSON.stringify({
|
|
39474
39786
|
jsonrpc: "2.0",
|
|
@@ -39477,11 +39789,13 @@ var RustToolPool = class {
|
|
|
39477
39789
|
params: { name, arguments: args }
|
|
39478
39790
|
});
|
|
39479
39791
|
try {
|
|
39480
|
-
pooled.proc.stdin?.write(request + "\n");
|
|
39792
|
+
const written = pooled.proc.stdin?.write(request + "\n");
|
|
39793
|
+
if (written === false || written === void 0) {
|
|
39794
|
+
fail(new Error("Failed to write request to Rust tool process"), true);
|
|
39795
|
+
}
|
|
39481
39796
|
} catch (err) {
|
|
39482
|
-
|
|
39483
|
-
|
|
39484
|
-
reject(err);
|
|
39797
|
+
const error95 = err instanceof Error ? err : new Error(String(err));
|
|
39798
|
+
fail(error95, true);
|
|
39485
39799
|
}
|
|
39486
39800
|
});
|
|
39487
39801
|
}
|
|
@@ -39489,9 +39803,29 @@ var RustToolPool = class {
|
|
|
39489
39803
|
* Release a process back to the pool
|
|
39490
39804
|
*/
|
|
39491
39805
|
release(pooled) {
|
|
39806
|
+
if (pooled.destroyed || !this.processes.includes(pooled)) {
|
|
39807
|
+
return;
|
|
39808
|
+
}
|
|
39492
39809
|
pooled.busy = false;
|
|
39493
39810
|
pooled.lastUsed = Date.now();
|
|
39494
39811
|
}
|
|
39812
|
+
/**
|
|
39813
|
+
* Remove a process from the pool, optionally terminating it first.
|
|
39814
|
+
*/
|
|
39815
|
+
removeProcess(pooled, kill) {
|
|
39816
|
+
pooled.destroyed = true;
|
|
39817
|
+
pooled.pendingCleanup?.();
|
|
39818
|
+
if (kill) {
|
|
39819
|
+
try {
|
|
39820
|
+
pooled.proc.kill();
|
|
39821
|
+
} catch {
|
|
39822
|
+
}
|
|
39823
|
+
}
|
|
39824
|
+
const index = this.processes.indexOf(pooled);
|
|
39825
|
+
if (index !== -1) {
|
|
39826
|
+
this.processes.splice(index, 1);
|
|
39827
|
+
}
|
|
39828
|
+
}
|
|
39495
39829
|
/**
|
|
39496
39830
|
* Start cleanup timer for idle processes
|
|
39497
39831
|
*/
|
|
@@ -39505,14 +39839,7 @@ var RustToolPool = class {
|
|
|
39505
39839
|
}
|
|
39506
39840
|
}
|
|
39507
39841
|
for (const pooled of toRemove) {
|
|
39508
|
-
|
|
39509
|
-
pooled.proc.kill();
|
|
39510
|
-
} catch {
|
|
39511
|
-
}
|
|
39512
|
-
const index = this.processes.indexOf(pooled);
|
|
39513
|
-
if (index !== -1) {
|
|
39514
|
-
this.processes.splice(index, 1);
|
|
39515
|
-
}
|
|
39842
|
+
this.removeProcess(pooled, true);
|
|
39516
39843
|
}
|
|
39517
39844
|
if (toRemove.length > 0) {
|
|
39518
39845
|
log(`[${LOG_PREFIX.RUST_POOL}] Cleaned up ${toRemove.length} idle processes`);
|
|
@@ -39529,11 +39856,8 @@ var RustToolPool = class {
|
|
|
39529
39856
|
clearInterval(this.cleanupInterval);
|
|
39530
39857
|
this.cleanupInterval = null;
|
|
39531
39858
|
}
|
|
39532
|
-
for (const pooled of this.processes) {
|
|
39533
|
-
|
|
39534
|
-
pooled.proc.kill();
|
|
39535
|
-
} catch {
|
|
39536
|
-
}
|
|
39859
|
+
for (const pooled of [...this.processes]) {
|
|
39860
|
+
this.removeProcess(pooled, true);
|
|
39537
39861
|
}
|
|
39538
39862
|
this.processes = [];
|
|
39539
39863
|
log(`[${LOG_PREFIX.RUST_POOL}] Shutdown complete`);
|
|
@@ -39551,18 +39875,39 @@ var RustToolPool = class {
|
|
|
39551
39875
|
}
|
|
39552
39876
|
};
|
|
39553
39877
|
var globalPool = null;
|
|
39878
|
+
var resetInFlight = null;
|
|
39554
39879
|
function getRustToolPool() {
|
|
39555
39880
|
if (!globalPool) {
|
|
39556
39881
|
globalPool = new RustToolPool();
|
|
39557
39882
|
}
|
|
39558
39883
|
return globalPool;
|
|
39559
39884
|
}
|
|
39560
|
-
async function
|
|
39561
|
-
|
|
39562
|
-
await
|
|
39885
|
+
async function resetRustToolPool(reason = "manual reset", expectedPool) {
|
|
39886
|
+
while (resetInFlight) {
|
|
39887
|
+
await resetInFlight;
|
|
39888
|
+
}
|
|
39889
|
+
const poolToReset = globalPool;
|
|
39890
|
+
if (!poolToReset) {
|
|
39891
|
+
return;
|
|
39892
|
+
}
|
|
39893
|
+
if (expectedPool && poolToReset !== expectedPool) {
|
|
39894
|
+
log(`[${LOG_PREFIX.RUST_POOL}] Skipped reset for stale pool: ${reason}`);
|
|
39895
|
+
return;
|
|
39896
|
+
}
|
|
39897
|
+
resetInFlight = (async () => {
|
|
39563
39898
|
globalPool = null;
|
|
39899
|
+
log(`[${LOG_PREFIX.RUST_POOL}] Resetting global pool: ${reason}`);
|
|
39900
|
+
await poolToReset.shutdown();
|
|
39901
|
+
})();
|
|
39902
|
+
try {
|
|
39903
|
+
await resetInFlight;
|
|
39904
|
+
} finally {
|
|
39905
|
+
resetInFlight = null;
|
|
39564
39906
|
}
|
|
39565
39907
|
}
|
|
39908
|
+
async function shutdownRustToolPool() {
|
|
39909
|
+
await resetRustToolPool("shutdown");
|
|
39910
|
+
}
|
|
39566
39911
|
|
|
39567
39912
|
// src/tools/callAgent.ts
|
|
39568
39913
|
init_shared();
|
|
@@ -39631,13 +39976,15 @@ ${PROMPT_TAGS.EXECUTION.close}
|
|
|
39631
39976
|
init_logger();
|
|
39632
39977
|
init_shared();
|
|
39633
39978
|
async function callRustTool(name, args) {
|
|
39979
|
+
const pool = getRustToolPool();
|
|
39634
39980
|
try {
|
|
39635
|
-
const pool = getRustToolPool();
|
|
39636
39981
|
return await pool.call(name, args);
|
|
39637
39982
|
} catch (err) {
|
|
39638
|
-
log(`[${LOG_PREFIX.RUST_TOOL}] Pool error: ${err}`);
|
|
39639
|
-
|
|
39983
|
+
log(`[${LOG_PREFIX.RUST_TOOL}] Pool error, resetting and retrying once: ${err}`);
|
|
39984
|
+
await resetRustToolPool(`transport error while calling ${name}`, pool);
|
|
39640
39985
|
}
|
|
39986
|
+
const retryPool = getRustToolPool();
|
|
39987
|
+
return retryPool.call(name, args);
|
|
39641
39988
|
}
|
|
39642
39989
|
|
|
39643
39990
|
// src/tools/search.ts
|
|
@@ -40783,6 +41130,92 @@ function registerAllTools(directory, asyncAgentTools, dynamicTools) {
|
|
|
40783
41130
|
// src/index.ts
|
|
40784
41131
|
init_shared();
|
|
40785
41132
|
|
|
41133
|
+
// src/core/agents/concurrency-config.ts
|
|
41134
|
+
var CONCURRENCY_KEYS = [
|
|
41135
|
+
"defaultConcurrency",
|
|
41136
|
+
"agentConcurrency",
|
|
41137
|
+
"providerConcurrency",
|
|
41138
|
+
"modelConcurrency"
|
|
41139
|
+
];
|
|
41140
|
+
function isRecord(value) {
|
|
41141
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
41142
|
+
}
|
|
41143
|
+
function readLimitMap(value) {
|
|
41144
|
+
if (!isRecord(value)) return void 0;
|
|
41145
|
+
const result = {};
|
|
41146
|
+
for (const [key, limit] of Object.entries(value)) {
|
|
41147
|
+
if (typeof limit === "number" && Number.isFinite(limit) && limit >= 0) {
|
|
41148
|
+
result[key] = limit;
|
|
41149
|
+
}
|
|
41150
|
+
}
|
|
41151
|
+
return Object.keys(result).length > 0 ? result : void 0;
|
|
41152
|
+
}
|
|
41153
|
+
function extractConcurrencyConfig(source) {
|
|
41154
|
+
if (!isRecord(source)) return {};
|
|
41155
|
+
const config3 = {};
|
|
41156
|
+
if (typeof source.defaultConcurrency === "number" && source.defaultConcurrency >= 0) {
|
|
41157
|
+
config3.defaultConcurrency = source.defaultConcurrency;
|
|
41158
|
+
}
|
|
41159
|
+
const agentConcurrency = readLimitMap(source.agentConcurrency);
|
|
41160
|
+
if (agentConcurrency) config3.agentConcurrency = agentConcurrency;
|
|
41161
|
+
const providerConcurrency = readLimitMap(source.providerConcurrency);
|
|
41162
|
+
if (providerConcurrency) config3.providerConcurrency = providerConcurrency;
|
|
41163
|
+
const modelConcurrency = readLimitMap(source.modelConcurrency);
|
|
41164
|
+
if (modelConcurrency) config3.modelConcurrency = modelConcurrency;
|
|
41165
|
+
return config3;
|
|
41166
|
+
}
|
|
41167
|
+
function hasConcurrencyConfig(source) {
|
|
41168
|
+
if (!isRecord(source)) return false;
|
|
41169
|
+
return CONCURRENCY_KEYS.some((key) => source[key] !== void 0);
|
|
41170
|
+
}
|
|
41171
|
+
function mergeConcurrencyConfig(base, override) {
|
|
41172
|
+
return {
|
|
41173
|
+
...base,
|
|
41174
|
+
...override,
|
|
41175
|
+
agentConcurrency: {
|
|
41176
|
+
...base.agentConcurrency,
|
|
41177
|
+
...override.agentConcurrency
|
|
41178
|
+
},
|
|
41179
|
+
providerConcurrency: {
|
|
41180
|
+
...base.providerConcurrency,
|
|
41181
|
+
...override.providerConcurrency
|
|
41182
|
+
},
|
|
41183
|
+
modelConcurrency: {
|
|
41184
|
+
...base.modelConcurrency,
|
|
41185
|
+
...override.modelConcurrency
|
|
41186
|
+
}
|
|
41187
|
+
};
|
|
41188
|
+
}
|
|
41189
|
+
|
|
41190
|
+
// src/core/config/plugin-options.ts
|
|
41191
|
+
function parseOrchestratorPluginOptions(options) {
|
|
41192
|
+
const source = isRecord2(options) ? options : {};
|
|
41193
|
+
return {
|
|
41194
|
+
concurrency: extractConcurrencyConfig(source),
|
|
41195
|
+
missionLoop: readMissionLoopOptions(source.missionLoop)
|
|
41196
|
+
};
|
|
41197
|
+
}
|
|
41198
|
+
function readMissionLoopOptions(value) {
|
|
41199
|
+
if (!isRecord2(value)) return DEFAULT_MISSION_RUNTIME_OPTIONS;
|
|
41200
|
+
return {
|
|
41201
|
+
ledger: readBoolean(value.ledger, DEFAULT_MISSION_RUNTIME_OPTIONS.ledger),
|
|
41202
|
+
markdownMemory: readBoolean(value.markdownMemory, DEFAULT_MISSION_RUNTIME_OPTIONS.markdownMemory),
|
|
41203
|
+
maxEvidenceEvents: readPositiveInteger(
|
|
41204
|
+
value.maxEvidenceEvents,
|
|
41205
|
+
DEFAULT_MISSION_RUNTIME_OPTIONS.maxEvidenceEvents
|
|
41206
|
+
)
|
|
41207
|
+
};
|
|
41208
|
+
}
|
|
41209
|
+
function readBoolean(value, fallback) {
|
|
41210
|
+
return typeof value === "boolean" ? value : fallback;
|
|
41211
|
+
}
|
|
41212
|
+
function readPositiveInteger(value, fallback) {
|
|
41213
|
+
return typeof value === "number" && Number.isInteger(value) && value > 0 ? value : fallback;
|
|
41214
|
+
}
|
|
41215
|
+
function isRecord2(value) {
|
|
41216
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
41217
|
+
}
|
|
41218
|
+
|
|
40786
41219
|
// src/plugin-handlers/tool-execute-pre-handler.ts
|
|
40787
41220
|
init_logger();
|
|
40788
41221
|
function createToolExecuteBeforeHandler(ctx) {
|
|
@@ -40894,8 +41327,41 @@ This plugin runs in "Claude Code Compatibility Mode".
|
|
|
40894
41327
|
}
|
|
40895
41328
|
|
|
40896
41329
|
// src/plugin-handlers/config-handler.ts
|
|
40897
|
-
function
|
|
41330
|
+
function isRecord3(value) {
|
|
41331
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
41332
|
+
}
|
|
41333
|
+
function isPermissionAction(value) {
|
|
41334
|
+
return value === "ask" || value === "allow" || value === "deny";
|
|
41335
|
+
}
|
|
41336
|
+
function mergePermission(globalPermission, agentPermission) {
|
|
41337
|
+
if (agentPermission === void 0) {
|
|
41338
|
+
return globalPermission;
|
|
41339
|
+
}
|
|
41340
|
+
if (isRecord3(globalPermission) && isRecord3(agentPermission)) {
|
|
41341
|
+
return { ...globalPermission, ...agentPermission };
|
|
41342
|
+
}
|
|
41343
|
+
if (isPermissionAction(globalPermission) && isRecord3(agentPermission)) {
|
|
41344
|
+
return { "*": globalPermission, ...agentPermission };
|
|
41345
|
+
}
|
|
41346
|
+
return agentPermission;
|
|
41347
|
+
}
|
|
41348
|
+
function defineAgent(existing, defaults, globalPermission) {
|
|
41349
|
+
const permission = mergePermission(globalPermission, existing?.permission);
|
|
41350
|
+
const agent = {
|
|
41351
|
+
...existing,
|
|
41352
|
+
...defaults
|
|
41353
|
+
};
|
|
41354
|
+
if (permission !== void 0) {
|
|
41355
|
+
agent.permission = permission;
|
|
41356
|
+
}
|
|
41357
|
+
return agent;
|
|
41358
|
+
}
|
|
41359
|
+
function createConfigHandler(options = {}) {
|
|
40898
41360
|
return async (config3) => {
|
|
41361
|
+
const mutableConfig = config3;
|
|
41362
|
+
if (hasConcurrencyConfig(config3)) {
|
|
41363
|
+
options.onConcurrencyConfig?.(extractConcurrencyConfig(config3));
|
|
41364
|
+
}
|
|
40899
41365
|
const claudeRules = findClaudeRules();
|
|
40900
41366
|
const injectRules = (prompt) => {
|
|
40901
41367
|
if (!claudeRules) return prompt;
|
|
@@ -40907,8 +41373,9 @@ ${claudeRules}`;
|
|
|
40907
41373
|
const plannerPrompt = injectRules(AGENTS[AGENT_NAMES.PLANNER]?.systemPrompt || "");
|
|
40908
41374
|
const workerPrompt = injectRules(AGENTS[AGENT_NAMES.WORKER]?.systemPrompt || "");
|
|
40909
41375
|
const reviewerPrompt = injectRules(AGENTS[AGENT_NAMES.REVIEWER]?.systemPrompt || "");
|
|
40910
|
-
const existingCommands =
|
|
40911
|
-
const existingAgents =
|
|
41376
|
+
const existingCommands = mutableConfig.command ?? {};
|
|
41377
|
+
const existingAgents = mutableConfig.agent ?? {};
|
|
41378
|
+
const globalPermission = mutableConfig.permission;
|
|
40912
41379
|
const orchestratorCommands = {};
|
|
40913
41380
|
for (const [name, cmd] of Object.entries(COMMANDS)) {
|
|
40914
41381
|
orchestratorCommands[name] = {
|
|
@@ -40919,39 +41386,34 @@ ${claudeRules}`;
|
|
|
40919
41386
|
}
|
|
40920
41387
|
const orchestratorAgents = {
|
|
40921
41388
|
// Primary agent - the main orchestrator
|
|
40922
|
-
[AGENT_NAMES.COMMANDER]: {
|
|
41389
|
+
[AGENT_NAMES.COMMANDER]: defineAgent(existingAgents[AGENT_NAMES.COMMANDER], {
|
|
40923
41390
|
description: "Autonomous orchestrator - executes until mission complete",
|
|
40924
41391
|
mode: "primary",
|
|
40925
41392
|
prompt: commanderPrompt,
|
|
40926
|
-
maxTokens: AGENT_TOKENS.PRIMARY_MAX_TOKENS,
|
|
40927
|
-
thinking: { type: "enabled", budgetTokens: AGENT_TOKENS.PRIMARY_THINKING_BUDGET },
|
|
40928
41393
|
color: "#ffea98"
|
|
40929
|
-
},
|
|
40930
|
-
// Subagents
|
|
40931
|
-
[AGENT_NAMES.PLANNER]: {
|
|
41394
|
+
}, globalPermission),
|
|
41395
|
+
// Subagents
|
|
41396
|
+
[AGENT_NAMES.PLANNER]: defineAgent(existingAgents[AGENT_NAMES.PLANNER], {
|
|
40932
41397
|
description: "Strategic planning and research specialist",
|
|
40933
41398
|
mode: "subagent",
|
|
40934
41399
|
hidden: true,
|
|
40935
41400
|
prompt: plannerPrompt,
|
|
40936
|
-
maxTokens: AGENT_TOKENS.SUBAGENT_MAX_TOKENS,
|
|
40937
41401
|
color: "#9B59B6"
|
|
40938
|
-
},
|
|
40939
|
-
[AGENT_NAMES.WORKER]: {
|
|
41402
|
+
}, globalPermission),
|
|
41403
|
+
[AGENT_NAMES.WORKER]: defineAgent(existingAgents[AGENT_NAMES.WORKER], {
|
|
40940
41404
|
description: "Implementation and documentation specialist",
|
|
40941
41405
|
mode: "subagent",
|
|
40942
41406
|
hidden: true,
|
|
40943
41407
|
prompt: workerPrompt,
|
|
40944
|
-
maxTokens: AGENT_TOKENS.SUBAGENT_MAX_TOKENS,
|
|
40945
41408
|
color: "#E67E22"
|
|
40946
|
-
},
|
|
40947
|
-
[AGENT_NAMES.REVIEWER]: {
|
|
41409
|
+
}, globalPermission),
|
|
41410
|
+
[AGENT_NAMES.REVIEWER]: defineAgent(existingAgents[AGENT_NAMES.REVIEWER], {
|
|
40948
41411
|
description: "Module-level verification specialist",
|
|
40949
41412
|
mode: "subagent",
|
|
40950
41413
|
hidden: true,
|
|
40951
41414
|
prompt: reviewerPrompt,
|
|
40952
|
-
maxTokens: AGENT_TOKENS.SUBAGENT_MAX_TOKENS,
|
|
40953
41415
|
color: "#27AE60"
|
|
40954
|
-
}
|
|
41416
|
+
}, globalPermission)
|
|
40955
41417
|
};
|
|
40956
41418
|
const processedExistingAgents = { ...existingAgents };
|
|
40957
41419
|
if (processedExistingAgents.build) {
|
|
@@ -40967,9 +41429,9 @@ ${claudeRules}`;
|
|
|
40967
41429
|
mode: "subagent"
|
|
40968
41430
|
};
|
|
40969
41431
|
}
|
|
40970
|
-
|
|
40971
|
-
|
|
40972
|
-
|
|
41432
|
+
mutableConfig.command = { ...existingCommands, ...orchestratorCommands };
|
|
41433
|
+
mutableConfig.agent = { ...processedExistingAgents, ...orchestratorAgents };
|
|
41434
|
+
mutableConfig.default_agent = AGENT_NAMES.COMMANDER;
|
|
40973
41435
|
};
|
|
40974
41436
|
}
|
|
40975
41437
|
|
|
@@ -41427,7 +41889,11 @@ async function injectContinuation2(client, directory, sessionID, loopState, cust
|
|
|
41427
41889
|
return;
|
|
41428
41890
|
}
|
|
41429
41891
|
const summary = buildVerificationSummary(verification);
|
|
41430
|
-
|
|
41892
|
+
const continuationReason = customPrompt ? "stagnation_intervention" : loopState.lastContinuationReason;
|
|
41893
|
+
let prompt = generateMissionContinuationPrompt(loopState, {
|
|
41894
|
+
verificationSummary: summary,
|
|
41895
|
+
continuationReason
|
|
41896
|
+
});
|
|
41431
41897
|
if (customPrompt) {
|
|
41432
41898
|
prompt = `${customPrompt}
|
|
41433
41899
|
|
|
@@ -41440,12 +41906,35 @@ ${prompt}`;
|
|
|
41440
41906
|
parts: [{ type: PART_TYPES.TEXT, text: prompt }]
|
|
41441
41907
|
}
|
|
41442
41908
|
});
|
|
41909
|
+
appendMissionLedgerEvent(directory, {
|
|
41910
|
+
type: "prompt_injected",
|
|
41911
|
+
sessionID,
|
|
41912
|
+
iteration: loopState.iteration,
|
|
41913
|
+
objective: loopState.objective,
|
|
41914
|
+
summary,
|
|
41915
|
+
reason: continuationReason
|
|
41916
|
+
});
|
|
41917
|
+
syncMissionMemory(directory, loopState);
|
|
41443
41918
|
markInjectionPerformed(sessionID);
|
|
41444
41919
|
} catch (err) {
|
|
41445
41920
|
log("[mission-loop-handler] Failed to inject continuation prompt", { sessionID, error: err });
|
|
41446
41921
|
}
|
|
41447
41922
|
}
|
|
41448
41923
|
async function handleMissionComplete(client, directory, loopState) {
|
|
41924
|
+
const completedState = {
|
|
41925
|
+
...loopState,
|
|
41926
|
+
active: false,
|
|
41927
|
+
lastVerificationSummary: "Mission verification passed",
|
|
41928
|
+
lastContinuationReason: "mission_completed"
|
|
41929
|
+
};
|
|
41930
|
+
appendMissionLedgerEvent(directory, {
|
|
41931
|
+
type: "mission_completed",
|
|
41932
|
+
sessionID: loopState.sessionID,
|
|
41933
|
+
iteration: loopState.iteration,
|
|
41934
|
+
objective: loopState.objective,
|
|
41935
|
+
summary: "Mission verification passed"
|
|
41936
|
+
});
|
|
41937
|
+
syncMissionMemory(directory, completedState);
|
|
41449
41938
|
const cleared = clearLoopState(directory);
|
|
41450
41939
|
if (cleared) {
|
|
41451
41940
|
await showCompletedToast(client, loopState);
|
|
@@ -41498,6 +41987,20 @@ async function handleMissionIdle(client, directory, sessionID, mainSessionID) {
|
|
|
41498
41987
|
return;
|
|
41499
41988
|
}
|
|
41500
41989
|
if (shouldTripCircuit(sessionID)) {
|
|
41990
|
+
const verificationSummary2 = buildVerificationSummary(verification);
|
|
41991
|
+
appendMissionLedgerEvent(directory, {
|
|
41992
|
+
type: "circuit_open",
|
|
41993
|
+
sessionID,
|
|
41994
|
+
iteration: loopState.iteration,
|
|
41995
|
+
objective: loopState.objective,
|
|
41996
|
+
summary: verificationSummary2,
|
|
41997
|
+
reason: "stagnation_threshold"
|
|
41998
|
+
});
|
|
41999
|
+
syncMissionMemory(directory, {
|
|
42000
|
+
...loopState,
|
|
42001
|
+
lastVerificationSummary: verificationSummary2,
|
|
42002
|
+
lastContinuationReason: "circuit_open"
|
|
42003
|
+
});
|
|
41501
42004
|
log(`[${MISSION_CONTROL.LOG_SOURCE}-handler] Circuit breaker tripped for ${sessionID}`);
|
|
41502
42005
|
return;
|
|
41503
42006
|
}
|
|
@@ -41512,8 +42015,29 @@ async function handleMissionIdle(client, directory, sessionID, mainSessionID) {
|
|
|
41512
42015
|
const stagnant = isStagnant(sessionID, DEFAULT_STAGNATION_THRESHOLD);
|
|
41513
42016
|
const newState = incrementIteration(directory);
|
|
41514
42017
|
if (!newState) return;
|
|
42018
|
+
const verificationSummary = buildVerificationSummary(verification);
|
|
41515
42019
|
newState.lastProgress = currentProgress;
|
|
42020
|
+
newState.stagnationCount = stagnant ? (newState.stagnationCount ?? 0) + 1 : 0;
|
|
42021
|
+
newState.lastVerificationSummary = verificationSummary;
|
|
42022
|
+
newState.lastContinuationReason = stagnant ? "stagnation_intervention" : "verification_failed";
|
|
42023
|
+
newState.lastContinuationAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
41516
42024
|
writeLoopState(directory, newState);
|
|
42025
|
+
appendMissionLedgerEvent(directory, {
|
|
42026
|
+
type: "verification_failed",
|
|
42027
|
+
sessionID,
|
|
42028
|
+
iteration: newState.iteration,
|
|
42029
|
+
objective: newState.objective,
|
|
42030
|
+
summary: verificationSummary
|
|
42031
|
+
});
|
|
42032
|
+
appendMissionLedgerEvent(directory, {
|
|
42033
|
+
type: "continuation_scheduled",
|
|
42034
|
+
sessionID,
|
|
42035
|
+
iteration: newState.iteration,
|
|
42036
|
+
objective: newState.objective,
|
|
42037
|
+
summary: verificationSummary,
|
|
42038
|
+
reason: newState.lastContinuationReason
|
|
42039
|
+
});
|
|
42040
|
+
syncMissionMemory(directory, newState);
|
|
41517
42041
|
await showCountdownToast2(client, MISSION_CONTROL.DEFAULT_COUNTDOWN_SECONDS, newState.iteration, newState.maxIterations);
|
|
41518
42042
|
state2.countdownTimer = setTimeout(async () => {
|
|
41519
42043
|
sessionStateStore.cancelCountdown(sessionID);
|
|
@@ -41541,6 +42065,55 @@ function handleSessionCompacted(sessionID) {
|
|
|
41541
42065
|
|
|
41542
42066
|
// src/plugin-handlers/event-handler.ts
|
|
41543
42067
|
init_shared();
|
|
42068
|
+
|
|
42069
|
+
// src/plugin-handlers/assistant-done-handler.ts
|
|
42070
|
+
init_logger();
|
|
42071
|
+
init_shared();
|
|
42072
|
+
async function handleCompletedAssistantMessage(ctx, sessionID, messageID) {
|
|
42073
|
+
const { client, directory, sessions } = ctx;
|
|
42074
|
+
const hooks = HookRegistry.getInstance();
|
|
42075
|
+
const session = sessions.get(sessionID);
|
|
42076
|
+
if (!session?.active || session.lastCompletedMessageID === messageID) {
|
|
42077
|
+
return;
|
|
42078
|
+
}
|
|
42079
|
+
const textContent = await readAssistantText(client, sessionID, messageID);
|
|
42080
|
+
session.lastCompletedMessageID = messageID;
|
|
42081
|
+
const result = await hooks.executeDone(
|
|
42082
|
+
{ sessionID, directory, sessions },
|
|
42083
|
+
textContent
|
|
42084
|
+
);
|
|
42085
|
+
if (result.action !== "inject" || result.prompts.length === 0) {
|
|
42086
|
+
return;
|
|
42087
|
+
}
|
|
42088
|
+
const now = Date.now();
|
|
42089
|
+
session.step++;
|
|
42090
|
+
session.timestamp = now;
|
|
42091
|
+
session.lastStepTime = now;
|
|
42092
|
+
try {
|
|
42093
|
+
const parts = result.prompts.map((text) => ({ type: PART_TYPES.TEXT, text }));
|
|
42094
|
+
client.session.prompt({
|
|
42095
|
+
path: { id: sessionID },
|
|
42096
|
+
body: { parts }
|
|
42097
|
+
}).catch((error95) => {
|
|
42098
|
+
log("[assistant-done-handler] Failed to inject continuation prompts", { sessionID, error: error95 });
|
|
42099
|
+
});
|
|
42100
|
+
} catch (error95) {
|
|
42101
|
+
log("[assistant-done-handler] Failed to inject continuation prompts", { sessionID, error: error95 });
|
|
42102
|
+
}
|
|
42103
|
+
}
|
|
42104
|
+
async function readAssistantText(client, sessionID, messageID) {
|
|
42105
|
+
try {
|
|
42106
|
+
const response = await client.session.message({
|
|
42107
|
+
path: { id: sessionID, messageID }
|
|
42108
|
+
});
|
|
42109
|
+
return (response.parts ?? []).filter((part) => part.type === PART_TYPES.TEXT || part.type === PART_TYPES.REASONING).map((part) => part.text ?? "").join("\n");
|
|
42110
|
+
} catch (error95) {
|
|
42111
|
+
log("[assistant-done-handler] Failed to read assistant message", { sessionID, messageID, error: error95 });
|
|
42112
|
+
return "";
|
|
42113
|
+
}
|
|
42114
|
+
}
|
|
42115
|
+
|
|
42116
|
+
// src/plugin-handlers/event-handler.ts
|
|
41544
42117
|
function createEventHandler(ctx) {
|
|
41545
42118
|
const { client, directory, sessions, state: state2 } = ctx;
|
|
41546
42119
|
return async (input) => {
|
|
@@ -41591,7 +42164,7 @@ function createEventHandler(ctx) {
|
|
|
41591
42164
|
if (event.type === MESSAGE_EVENTS.UPDATED) {
|
|
41592
42165
|
const messageProperties = event.properties;
|
|
41593
42166
|
const messageInfo = messageProperties?.info;
|
|
41594
|
-
const sessionID = messageInfo?.sessionID;
|
|
42167
|
+
const sessionID = messageProperties.sessionID || messageInfo?.sessionID;
|
|
41595
42168
|
const role = messageInfo?.role;
|
|
41596
42169
|
if (sessionID && messageProperties?.usage) {
|
|
41597
42170
|
const totalTokens = messageProperties.usage.totalTokens ?? (messageProperties.usage.inputTokens ?? 0) + (messageProperties.usage.outputTokens ?? 0);
|
|
@@ -41601,6 +42174,9 @@ function createEventHandler(ctx) {
|
|
|
41601
42174
|
}
|
|
41602
42175
|
if (sessionID && role === MESSAGE_ROLES.ASSISTANT) {
|
|
41603
42176
|
markRecoveryComplete(sessionID);
|
|
42177
|
+
if (messageInfo?.id && messageInfo.time?.completed) {
|
|
42178
|
+
await handleCompletedAssistantMessage(ctx, sessionID, messageInfo.id);
|
|
42179
|
+
}
|
|
41604
42180
|
}
|
|
41605
42181
|
if (sessionID && role === MESSAGE_ROLES.USER) {
|
|
41606
42182
|
handleUserMessage(sessionID);
|
|
@@ -41682,53 +42258,6 @@ function createToolExecuteAfterHandler(ctx) {
|
|
|
41682
42258
|
};
|
|
41683
42259
|
}
|
|
41684
42260
|
|
|
41685
|
-
// src/plugin-handlers/assistant-done-handler.ts
|
|
41686
|
-
init_logger();
|
|
41687
|
-
init_shared();
|
|
41688
|
-
function createAssistantDoneHandler(ctx) {
|
|
41689
|
-
const { client, directory, sessions } = ctx;
|
|
41690
|
-
const hooks = HookRegistry.getInstance();
|
|
41691
|
-
return async (assistantInput, assistantOutput) => {
|
|
41692
|
-
const sessionID = assistantInput.sessionID;
|
|
41693
|
-
const session = sessions.get(sessionID);
|
|
41694
|
-
if (!session?.active) return;
|
|
41695
|
-
const parts = assistantOutput.parts;
|
|
41696
|
-
const textContent = parts?.filter((p) => p.type === PART_TYPES.TEXT || p.type === PART_TYPES.REASONING).map((p) => p.text || "").join("\n") || "";
|
|
41697
|
-
const hookContext = {
|
|
41698
|
-
sessionID,
|
|
41699
|
-
directory,
|
|
41700
|
-
sessions
|
|
41701
|
-
// Cast because types might slightly differ in strict mode, but it's the same object
|
|
41702
|
-
};
|
|
41703
|
-
const result = await hooks.executeDone(hookContext, textContent);
|
|
41704
|
-
if (result.action === "stop") {
|
|
41705
|
-
return;
|
|
41706
|
-
}
|
|
41707
|
-
if (result.action === "inject" && result.prompts) {
|
|
41708
|
-
const now = Date.now();
|
|
41709
|
-
session.step++;
|
|
41710
|
-
session.timestamp = now;
|
|
41711
|
-
session.lastStepTime = now;
|
|
41712
|
-
try {
|
|
41713
|
-
if (client?.session?.prompt) {
|
|
41714
|
-
const parts2 = result.prompts.map((p) => ({
|
|
41715
|
-
type: PART_TYPES.TEXT,
|
|
41716
|
-
text: p
|
|
41717
|
-
}));
|
|
41718
|
-
client.session.prompt({
|
|
41719
|
-
path: { id: sessionID },
|
|
41720
|
-
body: { parts: parts2 }
|
|
41721
|
-
}).catch((error95) => {
|
|
41722
|
-
log("[assistant-done-handler] Failed to inject continuation prompts", { sessionID, error: error95 });
|
|
41723
|
-
});
|
|
41724
|
-
}
|
|
41725
|
-
} catch (error95) {
|
|
41726
|
-
log("[assistant-done-handler] Failed to inject continuation prompts", { sessionID, error: error95 });
|
|
41727
|
-
}
|
|
41728
|
-
}
|
|
41729
|
-
};
|
|
41730
|
-
}
|
|
41731
|
-
|
|
41732
42261
|
// src/plugin-handlers/session-compacting-handler.ts
|
|
41733
42262
|
init_shared();
|
|
41734
42263
|
function createSessionCompactingHandler(ctx) {
|
|
@@ -41767,6 +42296,9 @@ function buildMissionContext(loopState) {
|
|
|
41767
42296
|
return `<mission_context>
|
|
41768
42297
|
ACTIVE MISSION LOOP:
|
|
41769
42298
|
- Status: Active (Iteration ${loopState.iteration}/${loopState.maxIterations})
|
|
42299
|
+
- Objective: ${loopState.objective ?? "Continue the active mission"}
|
|
42300
|
+
- Last Progress: ${loopState.lastProgress ?? "unknown"}
|
|
42301
|
+
- Last Verification: ${loopState.lastVerificationSummary ?? "unknown"}
|
|
41770
42302
|
- Started: ${loopState.startedAt}
|
|
41771
42303
|
- Original Task: ${loopState.prompt.slice(0, 500)}${loopState.prompt.length > 500 ? "..." : ""}
|
|
41772
42304
|
|
|
@@ -41805,6 +42337,564 @@ Wait for these tasks to complete before concluding the mission.
|
|
|
41805
42337
|
|
|
41806
42338
|
// src/plugin-handlers/system-transform-handler.ts
|
|
41807
42339
|
init_shared();
|
|
42340
|
+
|
|
42341
|
+
// src/core/knowledge/context-provider.ts
|
|
42342
|
+
import { existsSync as existsSync10, readFileSync as readFileSync6, readdirSync } from "node:fs";
|
|
42343
|
+
import path10 from "node:path";
|
|
42344
|
+
|
|
42345
|
+
// src/core/knowledge/graph-parser.ts
|
|
42346
|
+
var GraphParser = class _GraphParser {
|
|
42347
|
+
/** Heading marker used for the auto-generated backlinks section */
|
|
42348
|
+
static BACKLINKS_HEADING = "## \u{1F517} Backlinks";
|
|
42349
|
+
// Maps note name -> set of target note names it links to
|
|
42350
|
+
forwardLinks = /* @__PURE__ */ new Map();
|
|
42351
|
+
// Maps note name -> set of source note names that link to it
|
|
42352
|
+
backlinks = /* @__PURE__ */ new Map();
|
|
42353
|
+
// Maps note name -> file path
|
|
42354
|
+
noteToPath = /* @__PURE__ */ new Map();
|
|
42355
|
+
// Maps file path -> note name
|
|
42356
|
+
pathToNote = /* @__PURE__ */ new Map();
|
|
42357
|
+
/**
|
|
42358
|
+
* Resolve file path or relative link to a note name (basename without extension).
|
|
42359
|
+
*/
|
|
42360
|
+
getNoteName(filePath) {
|
|
42361
|
+
const basename = filePath.split(/[/\\]/).pop() || "";
|
|
42362
|
+
const dotIdx = basename.lastIndexOf(".");
|
|
42363
|
+
return dotIdx !== -1 ? basename.slice(0, dotIdx) : basename;
|
|
42364
|
+
}
|
|
42365
|
+
/**
|
|
42366
|
+
* Parse content and extract all unique referenced target note names.
|
|
42367
|
+
*/
|
|
42368
|
+
parseLinks(content) {
|
|
42369
|
+
const targets = [];
|
|
42370
|
+
const wikiRegex = /\[\[([^[\]|#]+)(?:\|[^[\]]+)?(?:#[^[\]]+)?\]\]/g;
|
|
42371
|
+
let match;
|
|
42372
|
+
while ((match = wikiRegex.exec(content)) !== null) {
|
|
42373
|
+
const target = match[1].trim();
|
|
42374
|
+
if (target && !targets.includes(target)) {
|
|
42375
|
+
targets.push(target);
|
|
42376
|
+
}
|
|
42377
|
+
}
|
|
42378
|
+
const mdLinkRegex = /\[([^\]]+)\]\(([^)]+)\)/g;
|
|
42379
|
+
while ((match = mdLinkRegex.exec(content)) !== null) {
|
|
42380
|
+
const url3 = match[2].trim();
|
|
42381
|
+
if (!url3.includes("://") && (url3.endsWith(".md") || url3.startsWith(".") || url3.startsWith("/"))) {
|
|
42382
|
+
const targetName = this.getNoteName(url3);
|
|
42383
|
+
if (targetName && !targets.includes(targetName)) {
|
|
42384
|
+
targets.push(targetName);
|
|
42385
|
+
}
|
|
42386
|
+
}
|
|
42387
|
+
}
|
|
42388
|
+
return targets;
|
|
42389
|
+
}
|
|
42390
|
+
/**
|
|
42391
|
+
* Index file and register its bi-directional links.
|
|
42392
|
+
*/
|
|
42393
|
+
indexFile(filePath, content) {
|
|
42394
|
+
const sourceNote = this.getNoteName(filePath);
|
|
42395
|
+
this.noteToPath.set(sourceNote, filePath);
|
|
42396
|
+
this.pathToNote.set(filePath, sourceNote);
|
|
42397
|
+
this.clearIndexForNote(sourceNote);
|
|
42398
|
+
const targets = this.parseLinks(content);
|
|
42399
|
+
if (targets.length > 0) {
|
|
42400
|
+
const forwardSet = new Set(targets);
|
|
42401
|
+
this.forwardLinks.set(sourceNote, forwardSet);
|
|
42402
|
+
for (const target of targets) {
|
|
42403
|
+
let backSet = this.backlinks.get(target);
|
|
42404
|
+
if (!backSet) {
|
|
42405
|
+
backSet = /* @__PURE__ */ new Set();
|
|
42406
|
+
this.backlinks.set(target, backSet);
|
|
42407
|
+
}
|
|
42408
|
+
backSet.add(sourceNote);
|
|
42409
|
+
}
|
|
42410
|
+
}
|
|
42411
|
+
}
|
|
42412
|
+
/**
|
|
42413
|
+
* Retrieve backlinks for a note name or file path.
|
|
42414
|
+
*/
|
|
42415
|
+
getBacklinks(noteOrPath) {
|
|
42416
|
+
const note = noteOrPath.includes("/") || noteOrPath.endsWith(".md") ? this.getNoteName(noteOrPath) : noteOrPath;
|
|
42417
|
+
const sources = this.backlinks.get(note);
|
|
42418
|
+
return sources ? Array.from(sources).sort() : [];
|
|
42419
|
+
}
|
|
42420
|
+
/**
|
|
42421
|
+
* Retrieve forward links for a note name or file path.
|
|
42422
|
+
*/
|
|
42423
|
+
getForwardLinks(noteOrPath) {
|
|
42424
|
+
const note = noteOrPath.includes("/") || noteOrPath.endsWith(".md") ? this.getNoteName(noteOrPath) : noteOrPath;
|
|
42425
|
+
const targets = this.forwardLinks.get(note);
|
|
42426
|
+
return targets ? Array.from(targets).sort() : [];
|
|
42427
|
+
}
|
|
42428
|
+
/**
|
|
42429
|
+
* Synchronize the ## 🔗 Backlinks section in a file's content.
|
|
42430
|
+
*/
|
|
42431
|
+
syncBacklinksSection(content, backlinksList) {
|
|
42432
|
+
const backlinksHeading = _GraphParser.BACKLINKS_HEADING;
|
|
42433
|
+
const headingRegex = new RegExp(`(?:\\r?\\n|^)${backlinksHeading}\\b[\\s\\S]*$`);
|
|
42434
|
+
let backlinksSectionContent = `
|
|
42435
|
+
|
|
42436
|
+
${backlinksHeading}
|
|
42437
|
+
|
|
42438
|
+
`;
|
|
42439
|
+
if (backlinksList.length > 0) {
|
|
42440
|
+
backlinksSectionContent += backlinksList.map((b) => `- [[${b}]]`).join("\n");
|
|
42441
|
+
} else {
|
|
42442
|
+
backlinksSectionContent += "*(No backlinks found)*";
|
|
42443
|
+
}
|
|
42444
|
+
if (content.includes(backlinksHeading)) {
|
|
42445
|
+
return content.replace(headingRegex, backlinksSectionContent);
|
|
42446
|
+
} else {
|
|
42447
|
+
return content.trimEnd() + backlinksSectionContent;
|
|
42448
|
+
}
|
|
42449
|
+
}
|
|
42450
|
+
/**
|
|
42451
|
+
* Clear all indexes for a note.
|
|
42452
|
+
*/
|
|
42453
|
+
clearIndexForNote(sourceNote) {
|
|
42454
|
+
const targets = this.forwardLinks.get(sourceNote);
|
|
42455
|
+
if (targets) {
|
|
42456
|
+
for (const target of targets) {
|
|
42457
|
+
const backSet = this.backlinks.get(target);
|
|
42458
|
+
if (backSet) {
|
|
42459
|
+
backSet.delete(sourceNote);
|
|
42460
|
+
if (backSet.size === 0) {
|
|
42461
|
+
this.backlinks.delete(target);
|
|
42462
|
+
}
|
|
42463
|
+
}
|
|
42464
|
+
}
|
|
42465
|
+
this.forwardLinks.delete(sourceNote);
|
|
42466
|
+
}
|
|
42467
|
+
}
|
|
42468
|
+
};
|
|
42469
|
+
|
|
42470
|
+
// src/core/knowledge/hybrid-search.ts
|
|
42471
|
+
var RRF_K = 60;
|
|
42472
|
+
var DEFAULT_MAX_RESULTS = 20;
|
|
42473
|
+
var BM25_K1 = 1.2;
|
|
42474
|
+
var BM25_B = 0.75;
|
|
42475
|
+
var GRAPH_HOP_DEPTH = 2;
|
|
42476
|
+
var HybridSearch = class {
|
|
42477
|
+
tagIndexer;
|
|
42478
|
+
graphParser;
|
|
42479
|
+
/** Stores indexed note content keyed by note name. */
|
|
42480
|
+
contentMap = /* @__PURE__ */ new Map();
|
|
42481
|
+
constructor(tagIndexer, graphParser) {
|
|
42482
|
+
this.tagIndexer = tagIndexer;
|
|
42483
|
+
this.graphParser = graphParser;
|
|
42484
|
+
}
|
|
42485
|
+
/**
|
|
42486
|
+
* Register note content for lexical search.
|
|
42487
|
+
* Must be called after TagIndexer.indexFile / GraphParser.indexFile.
|
|
42488
|
+
*/
|
|
42489
|
+
indexContent(noteName, content) {
|
|
42490
|
+
this.contentMap.set(noteName, content.toLowerCase());
|
|
42491
|
+
}
|
|
42492
|
+
/**
|
|
42493
|
+
* Fuse lexical, tag, and graph rankings via RRF to produce a single list.
|
|
42494
|
+
*/
|
|
42495
|
+
search(query, maxResults) {
|
|
42496
|
+
const limit = maxResults ?? DEFAULT_MAX_RESULTS;
|
|
42497
|
+
const terms = this.tokenize(query);
|
|
42498
|
+
if (terms.length === 0) return [];
|
|
42499
|
+
const lexicalRanked = this.lexicalSearch(terms);
|
|
42500
|
+
const tagRanked = this.tagSearch(terms);
|
|
42501
|
+
const graphRanked = this.graphSearch(terms);
|
|
42502
|
+
return this.fuseResults(lexicalRanked, tagRanked, graphRanked, limit);
|
|
42503
|
+
}
|
|
42504
|
+
/**
|
|
42505
|
+
* BM25-inspired term-frequency scoring across all indexed documents.
|
|
42506
|
+
* Approximates IDF via corpus size and document frequency.
|
|
42507
|
+
*/
|
|
42508
|
+
lexicalSearch(terms) {
|
|
42509
|
+
const scores = /* @__PURE__ */ new Map();
|
|
42510
|
+
const corpusSize = this.contentMap.size;
|
|
42511
|
+
if (corpusSize === 0) return [];
|
|
42512
|
+
const avgLen = this.computeAverageLength();
|
|
42513
|
+
for (const term of terms) {
|
|
42514
|
+
const df = this.documentFrequency(term);
|
|
42515
|
+
const idf = Math.log((corpusSize - df + 0.5) / (df + 0.5) + 1);
|
|
42516
|
+
for (const [name, content] of this.contentMap) {
|
|
42517
|
+
const tf = this.countOccurrences(content, term);
|
|
42518
|
+
if (tf === 0) continue;
|
|
42519
|
+
const docLen = content.length;
|
|
42520
|
+
const tfNorm = tf * (BM25_K1 + 1) / (tf + BM25_K1 * (1 - BM25_B + BM25_B * (docLen / avgLen)));
|
|
42521
|
+
const prev = scores.get(name) ?? 0;
|
|
42522
|
+
scores.set(name, prev + idf * tfNorm);
|
|
42523
|
+
}
|
|
42524
|
+
}
|
|
42525
|
+
return this.sortByScore(scores);
|
|
42526
|
+
}
|
|
42527
|
+
/**
|
|
42528
|
+
* Match query terms against the tag index to find tagged notes.
|
|
42529
|
+
*/
|
|
42530
|
+
tagSearch(terms) {
|
|
42531
|
+
const scores = /* @__PURE__ */ new Map();
|
|
42532
|
+
for (const term of terms) {
|
|
42533
|
+
const files = this.tagIndexer.getFilesWithTag(term);
|
|
42534
|
+
for (const file3 of files) {
|
|
42535
|
+
const noteName = this.graphParser.getNoteName(file3);
|
|
42536
|
+
const prev = scores.get(noteName) ?? 0;
|
|
42537
|
+
scores.set(noteName, prev + 1);
|
|
42538
|
+
}
|
|
42539
|
+
}
|
|
42540
|
+
return this.sortByScore(scores);
|
|
42541
|
+
}
|
|
42542
|
+
/**
|
|
42543
|
+
* 2-hop graph traversal from tag-matched seed notes to discover related notes.
|
|
42544
|
+
*/
|
|
42545
|
+
graphSearch(terms) {
|
|
42546
|
+
const seeds = new Set(this.tagSearch(terms));
|
|
42547
|
+
const visited = /* @__PURE__ */ new Set();
|
|
42548
|
+
const scores = /* @__PURE__ */ new Map();
|
|
42549
|
+
for (const seed of seeds) {
|
|
42550
|
+
this.traverseGraph(seed, GRAPH_HOP_DEPTH, visited, scores);
|
|
42551
|
+
}
|
|
42552
|
+
return this.sortByScore(scores);
|
|
42553
|
+
}
|
|
42554
|
+
/**
|
|
42555
|
+
* Depth-limited BFS from a seed note, scoring neighbors by proximity.
|
|
42556
|
+
*/
|
|
42557
|
+
traverseGraph(note, depth, visited, scores) {
|
|
42558
|
+
if (depth <= 0 || visited.has(note)) return;
|
|
42559
|
+
visited.add(note);
|
|
42560
|
+
const neighbors = [
|
|
42561
|
+
...this.graphParser.getForwardLinks(note),
|
|
42562
|
+
...this.graphParser.getBacklinks(note)
|
|
42563
|
+
];
|
|
42564
|
+
for (const neighbor of neighbors) {
|
|
42565
|
+
const prev = scores.get(neighbor) ?? 0;
|
|
42566
|
+
scores.set(neighbor, prev + depth);
|
|
42567
|
+
this.traverseGraph(neighbor, depth - 1, visited, scores);
|
|
42568
|
+
}
|
|
42569
|
+
}
|
|
42570
|
+
/**
|
|
42571
|
+
* Reciprocal Rank Fusion: combine three ranked lists into a single ranking.
|
|
42572
|
+
* Formula: score(d) = Σ 1/(k + rank_i) for each list where d appears.
|
|
42573
|
+
*/
|
|
42574
|
+
fuseResults(lexical, tags, graph, limit) {
|
|
42575
|
+
const fused = /* @__PURE__ */ new Map();
|
|
42576
|
+
this.addRrfScores(fused, lexical, "lexical");
|
|
42577
|
+
this.addRrfScores(fused, tags, "tag");
|
|
42578
|
+
this.addRrfScores(fused, graph, "graph");
|
|
42579
|
+
return Array.from(fused.entries()).map(([noteName, { score, matchType }]) => ({ noteName, score, matchType })).sort((a, b) => b.score - a.score).slice(0, limit);
|
|
42580
|
+
}
|
|
42581
|
+
/**
|
|
42582
|
+
* Accumulate RRF scores from a single ranked list into the fused map.
|
|
42583
|
+
* The matchType is set to the source with the highest individual contribution.
|
|
42584
|
+
*/
|
|
42585
|
+
addRrfScores(fused, ranked, matchType) {
|
|
42586
|
+
for (let i = 0; i < ranked.length; i++) {
|
|
42587
|
+
const rrfScore = 1 / (RRF_K + i + 1);
|
|
42588
|
+
const existing = fused.get(ranked[i]);
|
|
42589
|
+
if (existing) {
|
|
42590
|
+
existing.score += rrfScore;
|
|
42591
|
+
if (rrfScore > 1 / (RRF_K + 1)) {
|
|
42592
|
+
existing.matchType = matchType;
|
|
42593
|
+
}
|
|
42594
|
+
} else {
|
|
42595
|
+
fused.set(ranked[i], { score: rrfScore, matchType });
|
|
42596
|
+
}
|
|
42597
|
+
}
|
|
42598
|
+
}
|
|
42599
|
+
/** Split query into lowercase tokens for matching. */
|
|
42600
|
+
tokenize(query) {
|
|
42601
|
+
return query.toLowerCase().split(/\s+/).filter(Boolean);
|
|
42602
|
+
}
|
|
42603
|
+
/** Count non-overlapping occurrences of a term in text. */
|
|
42604
|
+
countOccurrences(text, term) {
|
|
42605
|
+
let count = 0;
|
|
42606
|
+
let pos = 0;
|
|
42607
|
+
while ((pos = text.indexOf(term, pos)) !== -1) {
|
|
42608
|
+
count++;
|
|
42609
|
+
pos += term.length;
|
|
42610
|
+
}
|
|
42611
|
+
return count;
|
|
42612
|
+
}
|
|
42613
|
+
/** Average document length across the corpus (character-based). */
|
|
42614
|
+
computeAverageLength() {
|
|
42615
|
+
let total = 0;
|
|
42616
|
+
for (const content of this.contentMap.values()) {
|
|
42617
|
+
total += content.length;
|
|
42618
|
+
}
|
|
42619
|
+
return total / Math.max(this.contentMap.size, 1);
|
|
42620
|
+
}
|
|
42621
|
+
/** Number of documents containing the given term. */
|
|
42622
|
+
documentFrequency(term) {
|
|
42623
|
+
let count = 0;
|
|
42624
|
+
for (const content of this.contentMap.values()) {
|
|
42625
|
+
if (content.includes(term)) count++;
|
|
42626
|
+
}
|
|
42627
|
+
return count;
|
|
42628
|
+
}
|
|
42629
|
+
/** Sort entries by descending score and return the keys in order. */
|
|
42630
|
+
sortByScore(scores) {
|
|
42631
|
+
return Array.from(scores.entries()).sort((a, b) => b[1] - a[1]).map(([name]) => name);
|
|
42632
|
+
}
|
|
42633
|
+
};
|
|
42634
|
+
|
|
42635
|
+
// src/core/knowledge/tag-indexer.ts
|
|
42636
|
+
import { readFileSync as readFileSync5 } from "node:fs";
|
|
42637
|
+
var TagIndexer = class {
|
|
42638
|
+
tagMap = /* @__PURE__ */ new Map();
|
|
42639
|
+
fileCache = /* @__PURE__ */ new Map();
|
|
42640
|
+
/**
|
|
42641
|
+
* Parse frontmatter using regular expressions as a primary safe parser.
|
|
42642
|
+
* This avoids library dependencies and provides deterministic error recovery.
|
|
42643
|
+
*/
|
|
42644
|
+
parseFrontmatter(content) {
|
|
42645
|
+
const data = {};
|
|
42646
|
+
const frontmatterRegex = /^---\r?\n([\s\S]*?)\r?\n---/;
|
|
42647
|
+
const match = content.match(frontmatterRegex);
|
|
42648
|
+
if (!match) {
|
|
42649
|
+
return { data, body: content };
|
|
42650
|
+
}
|
|
42651
|
+
const rawYaml = match[1];
|
|
42652
|
+
const body = content.replace(frontmatterRegex, "").trim();
|
|
42653
|
+
const lines = rawYaml.split(/\r?\n/);
|
|
42654
|
+
let activeKey = null;
|
|
42655
|
+
for (const line of lines) {
|
|
42656
|
+
activeKey = this.parseYamlLine(line, data, activeKey);
|
|
42657
|
+
}
|
|
42658
|
+
return { data, body };
|
|
42659
|
+
}
|
|
42660
|
+
/**
|
|
42661
|
+
* Parse a single YAML line and update data object in-place.
|
|
42662
|
+
* Returns the currently active key for block list continuation.
|
|
42663
|
+
*/
|
|
42664
|
+
parseYamlLine(line, data, activeKey) {
|
|
42665
|
+
const trimmed = line.trim();
|
|
42666
|
+
if (!trimmed || trimmed.startsWith("#")) return activeKey;
|
|
42667
|
+
const colonIdx = trimmed.indexOf(":");
|
|
42668
|
+
if (colonIdx !== -1) {
|
|
42669
|
+
const key = trimmed.slice(0, colonIdx).trim();
|
|
42670
|
+
const val = trimmed.slice(colonIdx + 1).trim();
|
|
42671
|
+
if (val.startsWith("[") && val.endsWith("]")) {
|
|
42672
|
+
data[key] = val.slice(1, -1).split(",").map((s) => s.trim()).filter(Boolean);
|
|
42673
|
+
} else if (val) {
|
|
42674
|
+
data[key] = this.parseScalar(val);
|
|
42675
|
+
} else {
|
|
42676
|
+
data[key] = [];
|
|
42677
|
+
}
|
|
42678
|
+
return key;
|
|
42679
|
+
}
|
|
42680
|
+
if (trimmed.startsWith("-") && activeKey) {
|
|
42681
|
+
const listVal = trimmed.slice(1).trim();
|
|
42682
|
+
if (listVal) {
|
|
42683
|
+
const currentList = Array.isArray(data[activeKey]) ? data[activeKey] : [];
|
|
42684
|
+
currentList.push(listVal);
|
|
42685
|
+
data[activeKey] = currentList;
|
|
42686
|
+
}
|
|
42687
|
+
}
|
|
42688
|
+
return activeKey;
|
|
42689
|
+
}
|
|
42690
|
+
/**
|
|
42691
|
+
* Index a single markdown file content dynamically.
|
|
42692
|
+
*/
|
|
42693
|
+
indexFile(filePath, fileContent) {
|
|
42694
|
+
this.clearIndexForFile(filePath);
|
|
42695
|
+
const { data } = this.parseFrontmatter(fileContent);
|
|
42696
|
+
this.fileCache.set(filePath, data);
|
|
42697
|
+
if (data.tags && Array.isArray(data.tags)) {
|
|
42698
|
+
for (const tag of data.tags) {
|
|
42699
|
+
if (typeof tag === "string") {
|
|
42700
|
+
this.addTagEntry(tag.toLowerCase(), filePath);
|
|
42701
|
+
}
|
|
42702
|
+
}
|
|
42703
|
+
}
|
|
42704
|
+
}
|
|
42705
|
+
/**
|
|
42706
|
+
* Index a file directly from the filesystem.
|
|
42707
|
+
*/
|
|
42708
|
+
indexFileFromDisk(filePath) {
|
|
42709
|
+
try {
|
|
42710
|
+
const content = readFileSync5(filePath, "utf8");
|
|
42711
|
+
this.indexFile(filePath, content);
|
|
42712
|
+
} catch {
|
|
42713
|
+
this.clearIndexForFile(filePath);
|
|
42714
|
+
}
|
|
42715
|
+
}
|
|
42716
|
+
/**
|
|
42717
|
+
* Get all files associated with a specific tag O(1).
|
|
42718
|
+
*/
|
|
42719
|
+
getFilesWithTag(tag) {
|
|
42720
|
+
return this.tagMap.get(tag.toLowerCase()) || /* @__PURE__ */ new Set();
|
|
42721
|
+
}
|
|
42722
|
+
/**
|
|
42723
|
+
* Get intersection of files containing all specified tags.
|
|
42724
|
+
*/
|
|
42725
|
+
getFilesWithAllTags(tags) {
|
|
42726
|
+
if (tags.length === 0) return /* @__PURE__ */ new Set();
|
|
42727
|
+
let result = new Set(this.getFilesWithTag(tags[0]));
|
|
42728
|
+
for (let i = 1; i < tags.length; i++) {
|
|
42729
|
+
const currentSet = this.getFilesWithTag(tags[i]);
|
|
42730
|
+
result = new Set([...result].filter((x) => currentSet.has(x)));
|
|
42731
|
+
}
|
|
42732
|
+
return result;
|
|
42733
|
+
}
|
|
42734
|
+
/**
|
|
42735
|
+
* Get union of files containing any of the specified tags.
|
|
42736
|
+
*/
|
|
42737
|
+
getFilesWithAnyTags(tags) {
|
|
42738
|
+
const result = /* @__PURE__ */ new Set();
|
|
42739
|
+
for (const tag of tags) {
|
|
42740
|
+
const files = this.getFilesWithTag(tag);
|
|
42741
|
+
for (const file3 of files) {
|
|
42742
|
+
result.add(file3);
|
|
42743
|
+
}
|
|
42744
|
+
}
|
|
42745
|
+
return result;
|
|
42746
|
+
}
|
|
42747
|
+
/**
|
|
42748
|
+
* Get the cached frontmatter metadata of a file.
|
|
42749
|
+
*/
|
|
42750
|
+
getMetadata(filePath) {
|
|
42751
|
+
return this.fileCache.get(filePath);
|
|
42752
|
+
}
|
|
42753
|
+
/**
|
|
42754
|
+
* Return all file paths that have been indexed.
|
|
42755
|
+
*/
|
|
42756
|
+
getIndexedFiles() {
|
|
42757
|
+
return Array.from(this.fileCache.keys());
|
|
42758
|
+
}
|
|
42759
|
+
/**
|
|
42760
|
+
* Return all distinct tags currently present across all indexed files.
|
|
42761
|
+
*/
|
|
42762
|
+
getAllTags() {
|
|
42763
|
+
return Array.from(this.tagMap.keys());
|
|
42764
|
+
}
|
|
42765
|
+
/**
|
|
42766
|
+
* Remove file references cleanly from tag mappings and metadata cache.
|
|
42767
|
+
*/
|
|
42768
|
+
clearIndexForFile(filePath) {
|
|
42769
|
+
this.fileCache.delete(filePath);
|
|
42770
|
+
for (const [tag, files] of this.tagMap.entries()) {
|
|
42771
|
+
if (files.has(filePath)) {
|
|
42772
|
+
files.delete(filePath);
|
|
42773
|
+
if (files.size === 0) {
|
|
42774
|
+
this.tagMap.delete(tag);
|
|
42775
|
+
}
|
|
42776
|
+
}
|
|
42777
|
+
}
|
|
42778
|
+
}
|
|
42779
|
+
/**
|
|
42780
|
+
* Helper to insert tags atomically.
|
|
42781
|
+
*/
|
|
42782
|
+
addTagEntry(tag, filePath) {
|
|
42783
|
+
let files = this.tagMap.get(tag);
|
|
42784
|
+
if (!files) {
|
|
42785
|
+
files = /* @__PURE__ */ new Set();
|
|
42786
|
+
this.tagMap.set(tag, files);
|
|
42787
|
+
}
|
|
42788
|
+
files.add(filePath);
|
|
42789
|
+
}
|
|
42790
|
+
/**
|
|
42791
|
+
* Basic scalar value parser for YAML frontmatter fields.
|
|
42792
|
+
*/
|
|
42793
|
+
parseScalar(val) {
|
|
42794
|
+
if (val === "true") return true;
|
|
42795
|
+
if (val === "false") return false;
|
|
42796
|
+
const num = Number(val);
|
|
42797
|
+
if (!isNaN(num)) return num;
|
|
42798
|
+
if (val.startsWith('"') && val.endsWith('"') || val.startsWith("'") && val.endsWith("'")) {
|
|
42799
|
+
return val.slice(1, -1);
|
|
42800
|
+
}
|
|
42801
|
+
return val;
|
|
42802
|
+
}
|
|
42803
|
+
};
|
|
42804
|
+
|
|
42805
|
+
// src/core/knowledge/context-provider.ts
|
|
42806
|
+
var MAX_RESULTS = 3;
|
|
42807
|
+
var MAX_SNIPPET_CHARS = 220;
|
|
42808
|
+
var KNOWLEDGE_ROOTS = ["docs", path10.join(".opencode", "docs")];
|
|
42809
|
+
var SKIP_SEGMENTS = /* @__PURE__ */ new Set(["node_modules", "dist", "bin", ".git", "archive"]);
|
|
42810
|
+
var KnowledgeContextProvider = class {
|
|
42811
|
+
buildPrompt(directory, query) {
|
|
42812
|
+
const normalizedQuery = query.trim();
|
|
42813
|
+
if (!normalizedQuery) return null;
|
|
42814
|
+
const markdownFiles = this.collectMarkdownFiles(directory);
|
|
42815
|
+
if (markdownFiles.length === 0) return null;
|
|
42816
|
+
const indexed = this.indexKnowledge(directory, markdownFiles);
|
|
42817
|
+
const results = indexed.search.search(normalizedQuery, MAX_RESULTS);
|
|
42818
|
+
if (results.length === 0) return null;
|
|
42819
|
+
return this.formatPrompt(normalizedQuery, results, indexed);
|
|
42820
|
+
}
|
|
42821
|
+
collectMarkdownFiles(directory) {
|
|
42822
|
+
const files = [];
|
|
42823
|
+
for (const root of KNOWLEDGE_ROOTS) {
|
|
42824
|
+
const fullRoot = path10.join(directory, root);
|
|
42825
|
+
if (!existsSync10(fullRoot)) continue;
|
|
42826
|
+
files.push(...this.walkDirectory(fullRoot));
|
|
42827
|
+
}
|
|
42828
|
+
return files.sort();
|
|
42829
|
+
}
|
|
42830
|
+
walkDirectory(directory) {
|
|
42831
|
+
const files = [];
|
|
42832
|
+
for (const entry of readdirSync(directory, { withFileTypes: true })) {
|
|
42833
|
+
const fullPath = path10.join(directory, entry.name);
|
|
42834
|
+
if (entry.isDirectory()) {
|
|
42835
|
+
if (SKIP_SEGMENTS.has(entry.name)) continue;
|
|
42836
|
+
files.push(...this.walkDirectory(fullPath));
|
|
42837
|
+
continue;
|
|
42838
|
+
}
|
|
42839
|
+
if (entry.isFile() && entry.name.endsWith(".md")) {
|
|
42840
|
+
files.push(fullPath);
|
|
42841
|
+
}
|
|
42842
|
+
}
|
|
42843
|
+
return files;
|
|
42844
|
+
}
|
|
42845
|
+
indexKnowledge(directory, files) {
|
|
42846
|
+
const tagIndexer = new TagIndexer();
|
|
42847
|
+
const graphParser = new GraphParser();
|
|
42848
|
+
const search = new HybridSearch(tagIndexer, graphParser);
|
|
42849
|
+
const noteToPath = /* @__PURE__ */ new Map();
|
|
42850
|
+
const noteToSnippet = /* @__PURE__ */ new Map();
|
|
42851
|
+
for (const filePath of files) {
|
|
42852
|
+
try {
|
|
42853
|
+
const content = readFileSync6(filePath, "utf8");
|
|
42854
|
+
const noteName = graphParser.getNoteName(filePath);
|
|
42855
|
+
const { body } = tagIndexer.parseFrontmatter(content);
|
|
42856
|
+
const normalizedBody = body.trim();
|
|
42857
|
+
tagIndexer.indexFile(filePath, content);
|
|
42858
|
+
graphParser.indexFile(filePath, content);
|
|
42859
|
+
search.indexContent(noteName, normalizedBody);
|
|
42860
|
+
noteToPath.set(noteName, path10.relative(directory, filePath) || filePath);
|
|
42861
|
+
noteToSnippet.set(noteName, this.buildSnippet(normalizedBody));
|
|
42862
|
+
} catch {
|
|
42863
|
+
continue;
|
|
42864
|
+
}
|
|
42865
|
+
}
|
|
42866
|
+
return { search, noteToPath, noteToSnippet };
|
|
42867
|
+
}
|
|
42868
|
+
buildSnippet(content) {
|
|
42869
|
+
const normalized = content.replace(/\s+/g, " ").trim();
|
|
42870
|
+
if (normalized.length <= MAX_SNIPPET_CHARS) return normalized;
|
|
42871
|
+
return `${normalized.slice(0, MAX_SNIPPET_CHARS)}...`;
|
|
42872
|
+
}
|
|
42873
|
+
formatPrompt(query, results, indexed) {
|
|
42874
|
+
const lines = [
|
|
42875
|
+
"<knowledge_rag_context>",
|
|
42876
|
+
`Query: ${query}`,
|
|
42877
|
+
"Repository knowledge matches:",
|
|
42878
|
+
""
|
|
42879
|
+
];
|
|
42880
|
+
for (const [index, result] of results.entries()) {
|
|
42881
|
+
const filePath = indexed.noteToPath.get(result.noteName) ?? result.noteName;
|
|
42882
|
+
const snippet = indexed.noteToSnippet.get(result.noteName) ?? "";
|
|
42883
|
+
lines.push(`${index + 1}. ${result.noteName} [${result.matchType}]`);
|
|
42884
|
+
lines.push(` Source: ${filePath}`);
|
|
42885
|
+
if (snippet) {
|
|
42886
|
+
lines.push(` Snippet: ${snippet}`);
|
|
42887
|
+
}
|
|
42888
|
+
}
|
|
42889
|
+
lines.push("");
|
|
42890
|
+
lines.push("Use this as supplemental repository memory. Verify against source files before making claims.");
|
|
42891
|
+
lines.push("</knowledge_rag_context>");
|
|
42892
|
+
return lines.join("\n");
|
|
42893
|
+
}
|
|
42894
|
+
};
|
|
42895
|
+
|
|
42896
|
+
// src/plugin-handlers/system-transform-handler.ts
|
|
42897
|
+
var knowledgeContextProvider = new KnowledgeContextProvider();
|
|
41808
42898
|
function createSystemTransformHandler(ctx) {
|
|
41809
42899
|
const { directory, sessions, state: state2 } = ctx;
|
|
41810
42900
|
return async (input, output) => {
|
|
@@ -41820,11 +42910,19 @@ function createSystemTransformHandler(ctx) {
|
|
|
41820
42910
|
if (isActiveLoop && loopState) {
|
|
41821
42911
|
const { commander: commander2 } = await Promise.resolve().then(() => (init_commander(), commander_exports));
|
|
41822
42912
|
systemAdditions.push(commander2.systemPrompt);
|
|
41823
|
-
systemAdditions.push(buildMissionLoopSystemPrompt(loopState
|
|
42913
|
+
systemAdditions.push(buildMissionLoopSystemPrompt(loopState));
|
|
41824
42914
|
}
|
|
41825
42915
|
if (session?.active) {
|
|
41826
42916
|
systemAdditions.push(buildActiveSessionPrompt(session.step));
|
|
41827
42917
|
}
|
|
42918
|
+
const knowledgePrompt = buildKnowledgeContextPrompt(
|
|
42919
|
+
directory,
|
|
42920
|
+
loopState?.prompt,
|
|
42921
|
+
state2.sessions.get(sessionID)?.currentTask
|
|
42922
|
+
);
|
|
42923
|
+
if (knowledgePrompt) {
|
|
42924
|
+
systemAdditions.push(knowledgePrompt);
|
|
42925
|
+
}
|
|
41828
42926
|
try {
|
|
41829
42927
|
const manager = ParallelAgentManager.getInstance();
|
|
41830
42928
|
const tasks = manager.getTasksByParent(sessionID);
|
|
@@ -41840,18 +42938,29 @@ function createSystemTransformHandler(ctx) {
|
|
|
41840
42938
|
}
|
|
41841
42939
|
};
|
|
41842
42940
|
}
|
|
41843
|
-
function
|
|
42941
|
+
function buildKnowledgeContextPrompt(directory, missionPrompt, currentTask) {
|
|
42942
|
+
const queryParts = [missionPrompt ?? "", currentTask ?? ""].filter(Boolean);
|
|
42943
|
+
return knowledgeContextProvider.buildPrompt(directory, queryParts.join(" ").trim());
|
|
42944
|
+
}
|
|
42945
|
+
function buildMissionLoopSystemPrompt(loopState) {
|
|
41844
42946
|
return `<orchestrator_mission_loop>
|
|
41845
|
-
\u{1F3AF} MISSION LOOP ACTIVE: Iteration ${iteration}/${maxIterations}
|
|
42947
|
+
\u{1F3AF} MISSION LOOP ACTIVE: Iteration ${loopState.iteration}/${loopState.maxIterations}
|
|
41846
42948
|
|
|
41847
42949
|
You are in an autonomous mission loop. Continue working until ALL tasks are verified and 100% complete.
|
|
41848
42950
|
|
|
42951
|
+
ACTIVE OBJECTIVE:
|
|
42952
|
+
${loopState.objective ?? "Continue the active mission"}
|
|
42953
|
+
|
|
42954
|
+
RUNTIME MEMORY:
|
|
42955
|
+
- Last progress: ${loopState.lastProgress ?? "unknown"}
|
|
42956
|
+
- Last verification: ${loopState.lastVerificationSummary ?? "unknown"}
|
|
42957
|
+
|
|
41849
42958
|
COMPLETION CRITERIA:
|
|
41850
42959
|
- All hierarchical items in .opencode/todo.md are marked [x]
|
|
41851
42960
|
- .opencode/verification-checklist.md is fully checked off [x]
|
|
41852
42961
|
- All tests pass and builds succeed
|
|
41853
42962
|
|
|
41854
|
-
|
|
42963
|
+
Do not stop for routine permission or preference checks. Execute autonomously, and ask a concise clarification only when truly blocked and the OpenCode question permission allows it.
|
|
41855
42964
|
</orchestrator_mission_loop>`;
|
|
41856
42965
|
}
|
|
41857
42966
|
function buildActiveSessionPrompt(stepCount) {
|
|
@@ -41876,13 +42985,16 @@ Use \`delegate_task\` with background=true for parallel work.
|
|
|
41876
42985
|
// src/index.ts
|
|
41877
42986
|
var require2 = createRequire(import.meta.url);
|
|
41878
42987
|
var { version: PLUGIN_VERSION } = require2("../package.json");
|
|
41879
|
-
var OrchestratorPlugin = async (input) => {
|
|
42988
|
+
var OrchestratorPlugin = async (input, options) => {
|
|
41880
42989
|
const { directory, client } = input;
|
|
42990
|
+
const orchestratorOptions = parseOrchestratorPluginOptions(options);
|
|
42991
|
+
let concurrencyConfig = orchestratorOptions.concurrency;
|
|
42992
|
+
configureMissionRuntimeOptions(orchestratorOptions.missionLoop);
|
|
41881
42993
|
initializeHooks();
|
|
41882
42994
|
initToastClient(client);
|
|
41883
42995
|
const taskToastManager = initTaskToastManager(client);
|
|
41884
42996
|
const sessions = /* @__PURE__ */ new Map();
|
|
41885
|
-
const parallelAgentManager2 = ParallelAgentManager.getInstance(client, directory);
|
|
42997
|
+
const parallelAgentManager2 = ParallelAgentManager.getInstance(client, directory, concurrencyConfig);
|
|
41886
42998
|
const asyncAgentTools = createAsyncAgentTools(parallelAgentManager2, client);
|
|
41887
42999
|
const pluginManager = PluginManager.getInstance();
|
|
41888
43000
|
await pluginManager.initialize(directory);
|
|
@@ -41920,10 +43032,12 @@ var OrchestratorPlugin = async (input) => {
|
|
|
41920
43032
|
// -----------------------------------------------------------------
|
|
41921
43033
|
// Config hook - registers our commands and agents with OpenCode
|
|
41922
43034
|
// -----------------------------------------------------------------
|
|
41923
|
-
config: createConfigHandler(
|
|
41924
|
-
|
|
41925
|
-
|
|
41926
|
-
|
|
43035
|
+
config: createConfigHandler({
|
|
43036
|
+
onConcurrencyConfig: (config3) => {
|
|
43037
|
+
concurrencyConfig = mergeConcurrencyConfig(concurrencyConfig, config3);
|
|
43038
|
+
parallelAgentManager2.configureConcurrency(concurrencyConfig);
|
|
43039
|
+
}
|
|
43040
|
+
}),
|
|
41927
43041
|
// -----------------------------------------------------------------
|
|
41928
43042
|
// Event hook - handles OpenCode events
|
|
41929
43043
|
// -----------------------------------------------------------------
|
|
@@ -41945,27 +43059,23 @@ var OrchestratorPlugin = async (input) => {
|
|
|
41945
43059
|
// -----------------------------------------------------------------
|
|
41946
43060
|
// tool.execute.before hook - runs before any tool call
|
|
41947
43061
|
// -----------------------------------------------------------------
|
|
41948
|
-
|
|
43062
|
+
[PLUGIN_HOOKS.TOOL_EXECUTE_BEFORE]: createToolExecuteBeforeHandler(handlerContext),
|
|
41949
43063
|
// -----------------------------------------------------------------
|
|
41950
43064
|
// tool.execute.after hook - runs after any tool call completes
|
|
41951
43065
|
// -----------------------------------------------------------------
|
|
41952
43066
|
[PLUGIN_HOOKS.TOOL_EXECUTE_AFTER]: createToolExecuteAfterHandler(handlerContext),
|
|
41953
43067
|
// -----------------------------------------------------------------
|
|
41954
|
-
// assistant.done hook - runs when the LLM finishes responding
|
|
41955
|
-
// -----------------------------------------------------------------
|
|
41956
|
-
[PLUGIN_HOOKS.ASSISTANT_DONE]: createAssistantDoneHandler(handlerContext),
|
|
41957
|
-
// -----------------------------------------------------------------
|
|
41958
43068
|
// experimental.session.compacting hook - preserves mission context during compaction
|
|
41959
43069
|
// -----------------------------------------------------------------
|
|
41960
|
-
|
|
43070
|
+
[PLUGIN_HOOKS.EXPERIMENTAL_SESSION_COMPACTING]: createSessionCompactingHandler(handlerContext),
|
|
41961
43071
|
// -----------------------------------------------------------------
|
|
41962
43072
|
// experimental.chat.system.transform hook - dynamic system prompt injection
|
|
41963
43073
|
// -----------------------------------------------------------------
|
|
41964
|
-
|
|
43074
|
+
[PLUGIN_HOOKS.EXPERIMENTAL_CHAT_SYSTEM_TRANSFORM]: createSystemTransformHandler(handlerContext),
|
|
41965
43075
|
// -----------------------------------------------------------------
|
|
41966
|
-
//
|
|
43076
|
+
// dispose hook - cleanup resources on plugin unload
|
|
41967
43077
|
// -----------------------------------------------------------------
|
|
41968
|
-
|
|
43078
|
+
dispose: async () => {
|
|
41969
43079
|
await shutdownManager.shutdown();
|
|
41970
43080
|
}
|
|
41971
43081
|
};
|