@pellux/goodvibes-tui 0.18.8 → 0.18.10
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/CHANGELOG.md +65 -0
- package/README.md +1 -1
- package/docs/foundation-artifacts/operator-contract.json +1 -1
- package/package.json +2 -2
- package/src/acp/connection.ts +5 -5
- package/src/acp/index.ts +1 -1
- package/src/acp/manager.ts +1 -133
- package/src/adapters/bluebubbles/index.ts +1 -1
- package/src/adapters/discord/index.ts +2 -2
- package/src/adapters/github/index.ts +1 -1
- package/src/adapters/google-chat/index.ts +1 -1
- package/src/adapters/imessage/index.ts +1 -1
- package/src/adapters/index.ts +15 -15
- package/src/adapters/matrix/index.ts +1 -1
- package/src/adapters/mattermost/index.ts +1 -1
- package/src/adapters/msteams/index.ts +2 -2
- package/src/adapters/ntfy/index.ts +1 -1
- package/src/adapters/signal/index.ts +1 -1
- package/src/adapters/slack/index.ts +2 -2
- package/src/adapters/telegram/index.ts +1 -1
- package/src/adapters/types.ts +4 -4
- package/src/adapters/webhook/index.ts +1 -1
- package/src/adapters/whatsapp/index.ts +1 -1
- package/src/agents/message-bus-core.ts +2 -2
- package/src/agents/message-bus.ts +2 -2
- package/src/agents/orchestrator-prompts.ts +4 -4
- package/src/agents/orchestrator-runner.ts +11 -11
- package/src/agents/orchestrator.ts +14 -13
- package/src/agents/session.ts +1 -1
- package/src/agents/worktree.ts +1 -1
- package/src/agents/wrfc-config.ts +2 -2
- package/src/agents/wrfc-controller.ts +12 -12
- package/src/agents/wrfc-gate-runtime.ts +5 -5
- package/src/agents/wrfc-reporting.ts +1 -1
- package/src/agents/wrfc-runtime-events.ts +3 -3
- package/src/agents/wrfc-types.ts +1 -1
- package/src/automation/delivery-manager.ts +4 -4
- package/src/automation/index.ts +4 -4
- package/src/automation/manager-runtime-delivery.ts +1 -1
- package/src/automation/manager-runtime-events.ts +3 -3
- package/src/automation/manager-runtime-execution.ts +5 -5
- package/src/automation/manager-runtime-helpers.ts +2 -2
- package/src/automation/manager-runtime-job-mutations.ts +3 -3
- package/src/automation/manager-runtime-reconcile.ts +4 -4
- package/src/automation/manager-runtime-scheduling.ts +2 -2
- package/src/automation/manager-runtime.ts +18 -18
- package/src/automation/manager.ts +2 -2
- package/src/automation/service.ts +2 -2
- package/src/channels/builtin/account-actions.ts +5 -5
- package/src/channels/builtin/accounts.ts +2 -2
- package/src/channels/builtin/contracts.ts +3 -3
- package/src/channels/builtin/plugins.ts +5 -5
- package/src/channels/builtin/rendering.ts +4 -4
- package/src/channels/builtin/setup-schema.ts +1 -1
- package/src/channels/builtin/shared.ts +7 -7
- package/src/channels/builtin/surfaces.ts +2 -2
- package/src/channels/builtin/targets.ts +3 -3
- package/src/channels/builtin-runtime.ts +11 -11
- package/src/channels/delivery/shared.ts +2 -2
- package/src/channels/delivery/strategies-bridge.ts +3 -3
- package/src/channels/delivery/strategies-core.ts +5 -5
- package/src/channels/delivery/strategies-enterprise.ts +3 -3
- package/src/channels/delivery/types.ts +2 -2
- package/src/channels/delivery-router.ts +9 -9
- package/src/channels/index.ts +12 -12
- package/src/channels/plugin-registry.ts +1 -1
- package/src/channels/provider-runtime.ts +3 -3
- package/src/channels/reply-pipeline.ts +3 -3
- package/src/channels/route-manager.ts +2 -2
- package/src/channels/surface-registry.ts +2 -2
- package/src/config/helper-model.ts +1 -233
- package/src/config/index.ts +3 -3
- package/src/config/manager.ts +8 -404
- package/src/config/secrets.ts +21 -542
- package/src/config/service-registry.ts +1 -329
- package/src/config/tool-llm.ts +3 -3
- package/src/control-plane/approval-broker.ts +1 -1
- package/src/control-plane/gateway.ts +1 -713
- package/src/control-plane/index.ts +7 -7
- package/src/control-plane/media-contract-schemas.ts +1 -208
- package/src/control-plane/method-catalog-admin.ts +1 -136
- package/src/control-plane/method-catalog-channels.ts +1 -591
- package/src/control-plane/method-catalog-control-automation.ts +1 -475
- package/src/control-plane/method-catalog-control-core.ts +1 -594
- package/src/control-plane/method-catalog-control.ts +1 -8
- package/src/control-plane/method-catalog-events.ts +1 -74
- package/src/control-plane/method-catalog-knowledge.ts +1 -531
- package/src/control-plane/method-catalog-media.ts +1 -279
- package/src/control-plane/method-catalog-runtime.ts +1 -304
- package/src/control-plane/method-catalog-shared.ts +1 -223
- package/src/control-plane/method-catalog.ts +1 -242
- package/src/control-plane/operator-contract-schemas-admin.ts +1 -639
- package/src/control-plane/operator-contract-schemas-channels.ts +1 -375
- package/src/control-plane/operator-contract-schemas-control.ts +1 -226
- package/src/control-plane/operator-contract-schemas-domains.ts +1 -4
- package/src/control-plane/operator-contract-schemas-knowledge.ts +1 -582
- package/src/control-plane/operator-contract-schemas-media.ts +1 -297
- package/src/control-plane/operator-contract-schemas-permissions.ts +1 -100
- package/src/control-plane/operator-contract-schemas-remote.ts +1 -38
- package/src/control-plane/operator-contract-schemas-runtime.ts +1 -563
- package/src/control-plane/operator-contract-schemas-shared.ts +1 -85
- package/src/control-plane/operator-contract-schemas-telemetry.ts +1 -349
- package/src/control-plane/operator-contract-schemas.ts +1 -6
- package/src/control-plane/operator-contract.ts +5 -3
- package/src/control-plane/session-broker.ts +1 -1
- package/src/core/compaction-sections.ts +5 -5
- package/src/core/compaction-types.ts +3 -3
- package/src/core/composer-state.ts +1 -1
- package/src/core/context-compaction.ts +7 -7
- package/src/core/conversation-compaction.ts +4 -4
- package/src/core/conversation-diff.ts +1 -1
- package/src/core/conversation-rendering.ts +5 -5
- package/src/core/conversation-utils.ts +2 -2
- package/src/core/conversation.ts +10 -10
- package/src/core/event-replay.ts +1 -1
- package/src/core/orchestrator-context-runtime.ts +8 -8
- package/src/core/orchestrator-follow-up-runtime.ts +2 -2
- package/src/core/orchestrator-runtime.ts +4 -4
- package/src/core/orchestrator-tool-runtime.ts +7 -7
- package/src/core/orchestrator-turn-helpers.ts +7 -7
- package/src/core/orchestrator-turn-loop.ts +10 -10
- package/src/core/orchestrator.ts +17 -17
- package/src/core/plan-command-handler.ts +2 -2
- package/src/core/system-message-router.ts +2 -2
- package/src/core/transcript-events/classify.ts +1 -1
- package/src/core/transcript-events/index.ts +3 -3
- package/src/daemon/cli.ts +6 -6
- package/src/daemon/control-plane.ts +7 -7
- package/src/daemon/facade-composition.ts +16 -15
- package/src/daemon/facade.ts +17 -17
- package/src/daemon/helpers.ts +2 -2
- package/src/daemon/http/router-route-contexts.ts +11 -11
- package/src/daemon/http/router.ts +25 -25
- package/src/daemon/http-listener.ts +3 -3
- package/src/daemon/index.ts +1 -3
- package/src/daemon/service-manager.ts +1 -1
- package/src/daemon/surface-actions.ts +8 -8
- package/src/daemon/surface-delivery.ts +7 -7
- package/src/daemon/surface-policy.ts +1 -1
- package/src/daemon/transport-events.ts +4 -4
- package/src/daemon/types.ts +24 -24
- package/src/export/markdown.ts +1 -1
- package/src/export/session-export.ts +1 -633
- package/src/git/index.ts +1 -1
- package/src/git/service.ts +1 -1
- package/src/hooks/chain-engine.ts +1 -1
- package/src/hooks/dispatcher.ts +4 -4
- package/src/hooks/hook-api.ts +1 -1
- package/src/hooks/index.ts +8 -8
- package/src/hooks/runners/agent.ts +1 -1
- package/src/hooks/runners/prompt.ts +1 -1
- package/src/hooks/workbench.ts +2 -2
- package/src/input/command-registry.ts +24 -17
- package/src/input/commands/config.ts +1 -1
- package/src/input/commands/control-room-runtime.ts +2 -2
- package/src/input/commands/conversation-runtime.ts +1 -1
- package/src/input/commands/eval.ts +2 -2
- package/src/input/commands/git-runtime.ts +1 -1
- package/src/input/commands/guidance-runtime.ts +3 -3
- package/src/input/commands/health-runtime.ts +7 -7
- package/src/input/commands/incident-runtime.ts +1 -1
- package/src/input/commands/integration-runtime.ts +3 -3
- package/src/input/commands/local-provider-runtime.ts +1 -1
- package/src/input/commands/local-runtime.ts +1 -1
- package/src/input/commands/local-setup-review.ts +1 -1
- package/src/input/commands/local-setup.ts +1 -1
- package/src/input/commands/managed-runtime.ts +2 -2
- package/src/input/commands/marketplace-runtime.ts +1 -1
- package/src/input/commands/platform-access-runtime.ts +1 -1
- package/src/input/commands/policy-dispatch.ts +2 -2
- package/src/input/commands/product-runtime.ts +2 -2
- package/src/input/commands/profile-sync-runtime.ts +1 -1
- package/src/input/commands/provider-accounts-runtime.ts +1 -1
- package/src/input/commands/provider.ts +3 -3
- package/src/input/commands/quit-shared.ts +1 -1
- package/src/input/commands/recall-bundle.ts +1 -1
- package/src/input/commands/recall-capture.ts +2 -2
- package/src/input/commands/recall-query.ts +2 -2
- package/src/input/commands/recall-shared.ts +1 -1
- package/src/input/commands/remote-runtime-setup.ts +1 -1
- package/src/input/commands/remote-runtime.ts +1 -1
- package/src/input/commands/runtime-services.ts +13 -11
- package/src/input/commands/schedule-runtime.ts +2 -2
- package/src/input/commands/session-content.ts +1 -1
- package/src/input/commands/session-workflow.ts +4 -4
- package/src/input/commands/settings-sync-runtime.ts +1 -1
- package/src/input/commands/share-runtime.ts +9 -4
- package/src/input/commands/shell-core.ts +1 -1
- package/src/input/commands/skills-runtime.ts +1 -1
- package/src/input/commands/subscription-runtime.ts +1 -1
- package/src/input/commands/tasks-runtime.ts +1 -1
- package/src/input/commands/teamwork-runtime.ts +1 -1
- package/src/input/commands/worktree-runtime.ts +1 -1
- package/src/input/handler-command-route.ts +1 -1
- package/src/input/handler-content-actions.ts +3 -3
- package/src/input/handler-feed-routes.ts +2 -2
- package/src/input/handler-feed.ts +1 -1
- package/src/input/handler-shortcuts.ts +1 -1
- package/src/input/handler.ts +1 -1
- package/src/input/keybindings.ts +5 -0
- package/src/input/model-picker.ts +2 -2
- package/src/input/profile-picker-modal.ts +1 -1
- package/src/input/session-picker-modal.ts +1 -1
- package/src/input/settings-modal.ts +4 -4
- package/src/integrations/index.ts +1 -1
- package/src/integrations/notifier.ts +1 -1
- package/src/integrations/webhooks.ts +1 -177
- package/src/knowledge/consolidation.ts +2 -2
- package/src/knowledge/graphql.ts +1 -1
- package/src/knowledge/index.ts +5 -5
- package/src/knowledge/ingest-compile.ts +3 -3
- package/src/knowledge/ingest-context.ts +1 -1
- package/src/knowledge/ingest-inputs.ts +4 -4
- package/src/knowledge/ingest.ts +1 -20
- package/src/knowledge/internal.ts +1 -1
- package/src/knowledge/knowledge-api.ts +7 -7
- package/src/knowledge/lint.ts +3 -3
- package/src/knowledge/memory-sync.ts +2 -2
- package/src/knowledge/packet.ts +3 -3
- package/src/knowledge/scheduling.ts +2 -2
- package/src/knowledge/service.ts +10 -10
- package/src/main.ts +11 -10
- package/src/mcp/index.ts +4 -4
- package/src/mcp/mcp-api.ts +1 -1
- package/src/mcp/registry.ts +1 -506
- package/src/media/builtin-image-understanding.ts +2 -2
- package/src/media/builtin-providers.ts +2 -2
- package/src/media/index.ts +1 -1
- package/src/multimodal/index.ts +1 -1
- package/src/multimodal/service.ts +2 -2
- package/src/panels/agent-inspector-panel.ts +2 -2
- package/src/panels/agent-logs-panel.ts +3 -3
- package/src/panels/approval-panel.ts +2 -2
- package/src/panels/builtin/operations.ts +3 -1
- package/src/panels/builtin/shared.ts +13 -13
- package/src/panels/context-visualizer-panel.ts +2 -2
- package/src/panels/cost-tracker-panel.ts +2 -2
- package/src/panels/debug-panel.ts +3 -3
- package/src/panels/git-panel.ts +1 -1
- package/src/panels/hooks-panel.ts +4 -4
- package/src/panels/knowledge-panel.ts +1 -1
- package/src/panels/marketplace-panel.ts +1 -1
- package/src/panels/mcp-panel.ts +1 -1
- package/src/panels/memory-panel.ts +2 -2
- package/src/panels/ops-control-panel.ts +2 -2
- package/src/panels/ops-strategy-panel.ts +2 -2
- package/src/panels/plugins-panel.ts +1 -1
- package/src/panels/policy-panel.ts +1 -1
- package/src/panels/provider-health-panel.ts +3 -3
- package/src/panels/provider-stats-panel.ts +2 -2
- package/src/panels/sandbox-panel.ts +1 -1
- package/src/panels/schedule-panel.ts +1 -1
- package/src/panels/settings-sync-panel.ts +1 -1
- package/src/panels/system-messages-panel.ts +1 -1
- package/src/panels/tasks-panel.ts +1 -1
- package/src/panels/thinking-panel.ts +2 -2
- package/src/panels/token-budget-panel.ts +1 -1
- package/src/panels/tool-inspector-panel.ts +2 -2
- package/src/panels/worktree-panel.ts +1 -1
- package/src/panels/wrfc-panel.ts +4 -4
- package/src/permissions/briefs/build.ts +1 -1
- package/src/permissions/manager.ts +1 -356
- package/src/permissions/prompt.ts +1 -1
- package/src/plugins/api.ts +9 -9
- package/src/plugins/loader.ts +8 -8
- package/src/plugins/manager.ts +5 -5
- package/src/providers/amazon-bedrock-mantle.ts +1 -1
- package/src/providers/amazon-bedrock.ts +1 -1
- package/src/providers/anthropic-compat.ts +4 -4
- package/src/providers/anthropic-sdk-provider.ts +5 -5
- package/src/providers/anthropic-vertex.ts +1 -1
- package/src/providers/anthropic.ts +4 -4
- package/src/providers/auto-register.ts +6 -6
- package/src/providers/builtin-catalog.ts +2 -2
- package/src/providers/builtin-registry.ts +15 -15
- package/src/providers/cache-planner.ts +2 -2
- package/src/providers/capabilities.ts +1 -601
- package/src/providers/custom-loader.ts +6 -6
- package/src/providers/discovered-compat.ts +7 -18
- package/src/providers/discovered-factory.ts +7 -7
- package/src/providers/discovered-traits.ts +1 -1
- package/src/providers/gemini.ts +4 -4
- package/src/providers/github-copilot.ts +4 -4
- package/src/providers/index.ts +1 -47
- package/src/providers/interface.ts +1 -1
- package/src/providers/llama-cpp.ts +4 -4
- package/src/providers/lm-studio-helpers.ts +1 -1
- package/src/providers/lm-studio.ts +4 -4
- package/src/providers/model-catalog-cache.ts +1 -1
- package/src/providers/model-catalog-notifications.ts +1 -1
- package/src/providers/model-catalog-synthetic.ts +2 -2
- package/src/providers/model-catalog.ts +7 -7
- package/src/providers/model-limits.ts +1 -280
- package/src/providers/ollama.ts +4 -4
- package/src/providers/openai-codex.ts +2 -2
- package/src/providers/openai-compat.ts +4 -4
- package/src/providers/openai.ts +3 -3
- package/src/providers/optimizer.ts +1 -381
- package/src/providers/provider-api.ts +1 -553
- package/src/providers/registry-helpers.ts +1 -1
- package/src/providers/registry-models.ts +2 -2
- package/src/providers/registry-types.ts +5 -5
- package/src/providers/registry.ts +1 -729
- package/src/providers/runtime-metadata.ts +1 -1
- package/src/providers/runtime-snapshot.ts +3 -3
- package/src/providers/synthetic.ts +3 -3
- package/src/providers/tier-prompts.ts +1 -1
- package/src/providers/tool-formats.ts +1 -1
- package/src/renderer/agent-detail-modal.ts +2 -2
- package/src/renderer/block-actions.ts +1 -1
- package/src/renderer/context-inspector.ts +1 -1
- package/src/renderer/conversation-layout.ts +1 -1
- package/src/renderer/conversation-overlays.ts +1 -1
- package/src/renderer/git-status.ts +1 -1
- package/src/renderer/live-tail-modal.ts +1 -1
- package/src/renderer/process-modal.ts +2 -2
- package/src/runtime/bootstrap-background.ts +4 -4
- package/src/runtime/bootstrap-command-context.ts +23 -23
- package/src/runtime/bootstrap-command-parts.ts +23 -23
- package/src/runtime/bootstrap-core.ts +12 -10
- package/src/runtime/bootstrap-helpers.ts +2 -2
- package/src/runtime/bootstrap-hook-bridge.ts +9 -9
- package/src/runtime/bootstrap-runtime-events.ts +4 -4
- package/src/runtime/bootstrap-services.ts +4 -4
- package/src/runtime/bootstrap-shell.ts +11 -11
- package/src/runtime/bootstrap.ts +28 -10
- package/src/runtime/compaction/index.ts +1 -90
- package/src/runtime/compaction/lifecycle.ts +1 -167
- package/src/runtime/compaction/manager.ts +11 -11
- package/src/runtime/compaction/quality-score.ts +1 -279
- package/src/runtime/compaction/resume-repair.ts +1 -183
- package/src/runtime/compaction/strategies/autocompact.ts +1 -65
- package/src/runtime/compaction/strategies/boundary-commit.ts +1 -106
- package/src/runtime/compaction/strategies/collapse.ts +1 -90
- package/src/runtime/compaction/strategies/index.ts +1 -23
- package/src/runtime/compaction/strategies/microcompact.ts +1 -74
- package/src/runtime/compaction/strategies/reactive.ts +1 -89
- package/src/runtime/compaction/types.ts +1 -221
- package/src/runtime/context.ts +9 -9
- package/src/runtime/diagnostics/actions.ts +1 -1
- package/src/runtime/diagnostics/index.ts +5 -5
- package/src/runtime/diagnostics/panels/agents.ts +2 -2
- package/src/runtime/diagnostics/panels/events.ts +2 -2
- package/src/runtime/diagnostics/panels/health.ts +2 -2
- package/src/runtime/diagnostics/panels/ops.ts +2 -2
- package/src/runtime/diagnostics/panels/policy.ts +2 -2
- package/src/runtime/diagnostics/panels/tasks.ts +2 -2
- package/src/runtime/diagnostics/panels/tool-calls.ts +2 -2
- package/src/runtime/diagnostics/provider.ts +1 -1
- package/src/runtime/ecosystem/recommendations.ts +1 -1
- package/src/runtime/emitters/agents.ts +2 -2
- package/src/runtime/emitters/automation.ts +2 -2
- package/src/runtime/emitters/communication.ts +2 -2
- package/src/runtime/emitters/compaction.ts +2 -2
- package/src/runtime/emitters/control-plane.ts +2 -2
- package/src/runtime/emitters/deliveries.ts +2 -2
- package/src/runtime/emitters/forensics.ts +2 -2
- package/src/runtime/emitters/index.ts +27 -27
- package/src/runtime/emitters/knowledge.ts +2 -2
- package/src/runtime/emitters/mcp.ts +2 -2
- package/src/runtime/emitters/ops.ts +2 -2
- package/src/runtime/emitters/orchestration.ts +2 -2
- package/src/runtime/emitters/permissions.ts +2 -2
- package/src/runtime/emitters/planner.ts +2 -2
- package/src/runtime/emitters/plugins.ts +2 -2
- package/src/runtime/emitters/providers.ts +2 -2
- package/src/runtime/emitters/routes.ts +2 -2
- package/src/runtime/emitters/security.ts +2 -2
- package/src/runtime/emitters/session.ts +2 -2
- package/src/runtime/emitters/surfaces.ts +2 -2
- package/src/runtime/emitters/tasks.ts +2 -2
- package/src/runtime/emitters/tools.ts +2 -2
- package/src/runtime/emitters/transport.ts +2 -2
- package/src/runtime/emitters/turn.ts +3 -3
- package/src/runtime/emitters/ui.ts +2 -2
- package/src/runtime/emitters/watchers.ts +2 -2
- package/src/runtime/emitters/workflows.ts +3 -3
- package/src/runtime/eval/index.ts +3 -3
- package/src/runtime/eval/runner.ts +1 -1
- package/src/runtime/eval/suites.ts +1 -1
- package/src/runtime/events/domain-map.ts +2 -2
- package/src/runtime/events/index.ts +1 -194
- package/src/runtime/events/turn.ts +1 -60
- package/src/runtime/events/workflows.ts +1 -17
- package/src/runtime/forensics/collector.ts +4 -4
- package/src/runtime/forensics/index.ts +1 -1
- package/src/runtime/foundation-clients.ts +14 -14
- package/src/runtime/foundation-services.ts +8 -8
- package/src/runtime/guidance.ts +3 -3
- package/src/runtime/health/effect-handlers.ts +3 -3
- package/src/runtime/health/index.ts +4 -4
- package/src/runtime/health/wiring.ts +2 -2
- package/src/runtime/index.ts +29 -29
- package/src/runtime/integration/helpers.ts +12 -12
- package/src/runtime/lifecycle.ts +4 -4
- package/src/runtime/mcp/index.ts +3 -3
- package/src/runtime/mcp/manager.ts +1 -1
- package/src/runtime/network/inbound.ts +2 -2
- package/src/runtime/network/index.ts +5 -5
- package/src/runtime/network/outbound.ts +2 -2
- package/src/runtime/network/shared.ts +1 -1
- package/src/runtime/operator-client.ts +9 -9
- package/src/runtime/ops/control-plane.ts +2 -2
- package/src/runtime/ops/index.ts +3 -3
- package/src/runtime/ops/playbooks/index.ts +2 -2
- package/src/runtime/ops/playbooks/session-unrecoverable.ts +2 -2
- package/src/runtime/ops/playbooks/stuck-turn.ts +1 -1
- package/src/runtime/ops/runtime-context.ts +1 -1
- package/src/runtime/orchestration/spawn-policy.ts +1 -1
- package/src/runtime/peer-client.ts +3 -3
- package/src/runtime/perf/index.ts +1 -1
- package/src/runtime/perf/slo-collector.ts +1 -1
- package/src/runtime/permissions/index.ts +5 -5
- package/src/runtime/permissions/policy-runtime.ts +1 -175
- package/src/runtime/permissions/rule-suggestions.ts +1 -1
- package/src/runtime/plugins/hot-reload.ts +4 -4
- package/src/runtime/plugins/index.ts +13 -13
- package/src/runtime/plugins/lifecycle.ts +1 -1
- package/src/runtime/plugins/manager.ts +10 -10
- package/src/runtime/plugins/manifest.ts +2 -2
- package/src/runtime/plugins/quarantine.ts +2 -2
- package/src/runtime/plugins/trust.ts +2 -2
- package/src/runtime/plugins/types.ts +1 -1
- package/src/runtime/provider-accounts/registry.ts +2 -2
- package/src/runtime/remote/distributed-runtime-contract-schemas.ts +3 -3
- package/src/runtime/remote/index.ts +3 -3
- package/src/runtime/remote/runner-registry.ts +2 -2
- package/src/runtime/remote/supervisor.ts +1 -1
- package/src/runtime/runtime-hook-api.ts +1 -1
- package/src/runtime/runtime-knowledge-api.ts +1 -1
- package/src/runtime/runtime-mcp-api.ts +1 -1
- package/src/runtime/runtime-ops-api.ts +2 -2
- package/src/runtime/runtime-provider-api.ts +1 -1
- package/src/runtime/services.ts +35 -32
- package/src/runtime/session-maintenance.ts +1 -1
- package/src/runtime/session-persistence.ts +2 -2
- package/src/runtime/session-return-context.ts +3 -3
- package/src/runtime/settings/control-plane-store.ts +1 -1
- package/src/runtime/settings/control-plane.ts +2 -2
- package/src/runtime/shell-command-extensions.ts +7 -7
- package/src/runtime/shell-command-ops.ts +6 -6
- package/src/runtime/shell-command-platform.ts +1 -1
- package/src/runtime/shell-command-services.ts +17 -17
- package/src/runtime/shell-command-workspace.ts +1 -1
- package/src/runtime/store/domains/conversation.ts +1 -1
- package/src/runtime/store/domains/index.ts +4 -4
- package/src/runtime/store/domains/permissions.ts +1 -1
- package/src/runtime/store/helpers/reducers/conversation.ts +3 -3
- package/src/runtime/store/helpers/reducers/lifecycle.ts +3 -3
- package/src/runtime/store/helpers/reducers/shared.ts +2 -2
- package/src/runtime/store/helpers/reducers/sync.ts +1 -1
- package/src/runtime/store/helpers/reducers.ts +4 -4
- package/src/runtime/store/index.ts +4 -4
- package/src/runtime/store/selectors/index.ts +2 -2
- package/src/runtime/store/state.ts +4 -4
- package/src/runtime/tasks/adapters/acp-adapter.ts +1 -1
- package/src/runtime/tasks/adapters/index.ts +6 -6
- package/src/runtime/tasks/index.ts +3 -3
- package/src/runtime/tasks/manager.ts +3 -3
- package/src/runtime/telemetry/api-helpers.ts +2 -2
- package/src/runtime/telemetry/api.ts +2 -2
- package/src/runtime/telemetry/index.ts +5 -5
- package/src/runtime/telemetry/instrumentation/domain-bridge-agent-session.ts +1 -1
- package/src/runtime/telemetry/instrumentation/domain-bridge-plugin-mcp.ts +1 -1
- package/src/runtime/telemetry/instrumentation/domain-bridge-shared.ts +1 -1
- package/src/runtime/telemetry/instrumentation/domain-bridge-transport-task.ts +1 -1
- package/src/runtime/telemetry/instrumentation/domain-bridge.ts +5 -5
- package/src/runtime/telemetry/instrumentation/index.ts +3 -3
- package/src/runtime/tools/context.ts +3 -3
- package/src/runtime/tools/index.ts +4 -4
- package/src/runtime/tools/phased-executor.ts +3 -3
- package/src/runtime/tools/phases/budget.ts +1 -1
- package/src/runtime/tools/phases/execute.ts +1 -1
- package/src/runtime/tools/phases/index.ts +7 -7
- package/src/runtime/tools/phases/map-output.ts +1 -1
- package/src/runtime/tools/phases/permission.ts +2 -2
- package/src/runtime/tools/phases/posthook.ts +1 -1
- package/src/runtime/tools/phases/prehook.ts +1 -1
- package/src/runtime/tools/phases/validate.ts +1 -1
- package/src/runtime/transports/direct.ts +4 -4
- package/src/runtime/transports/http-helpers.ts +3 -3
- package/src/runtime/transports/http-types.ts +6 -6
- package/src/runtime/transports/http.ts +8 -8
- package/src/runtime/transports/realtime.ts +4 -4
- package/src/runtime/transports/remote-events.ts +1 -1
- package/src/runtime/transports/shared.ts +2 -2
- package/src/runtime/transports/ui-runtime-events.ts +2 -2
- package/src/runtime/ui/index.ts +7 -7
- package/src/runtime/ui/model-picker/data-provider.ts +4 -4
- package/src/runtime/ui/model-picker/health-enrichment.ts +3 -3
- package/src/runtime/ui/model-picker/index.ts +8 -8
- package/src/runtime/ui/provider-health/data-provider.ts +2 -2
- package/src/runtime/ui/provider-health/fallback-visualizer.ts +1 -1
- package/src/runtime/ui/provider-health/index.ts +5 -5
- package/src/runtime/ui-events.ts +1 -1
- package/src/runtime/ui-read-models-core.ts +2 -2
- package/src/runtime/ui-read-models-observability-maintenance.ts +4 -4
- package/src/runtime/ui-read-models-observability-options.ts +1 -1
- package/src/runtime/ui-read-models-observability-remote.ts +2 -2
- package/src/runtime/ui-read-models-observability-security.ts +3 -3
- package/src/runtime/ui-read-models-observability-system.ts +6 -6
- package/src/runtime/ui-read-models-observability.ts +10 -10
- package/src/runtime/ui-read-models-operations.ts +2 -2
- package/src/runtime/ui-read-models.ts +7 -7
- package/src/runtime/ui-service-queries.ts +2 -2
- package/src/runtime/ui-services.ts +7 -7
- package/src/runtime/worktree/registry.ts +1 -1
- package/src/scripts/process-messages.ts +1 -1
- package/src/sessions/manager.ts +9 -383
- package/src/shell/blocking-input.ts +3 -3
- package/src/shell/ui-openers.ts +3 -3
- package/src/state/file-watcher.ts +1 -1
- package/src/state/index.ts +10 -10
- package/src/state/knowledge-injection.ts +2 -2
- package/src/state/memory-embedding-http.ts +2 -2
- package/src/state/memory-embeddings.ts +1 -1
- package/src/state/memory-ingest.ts +3 -3
- package/src/state/memory-registry.ts +3 -3
- package/src/state/memory-store-helpers.ts +1 -1
- package/src/state/memory-store.ts +4 -4
- package/src/state/memory-vector-store.ts +3 -3
- package/src/tools/agent/index.ts +7 -7
- package/src/tools/agent/manager.ts +8 -8
- package/src/tools/analyze/git-modes.ts +2 -2
- package/src/tools/analyze/index.ts +2 -2
- package/src/tools/channel/agent-tools.ts +1 -1
- package/src/tools/channel/index.ts +2 -2
- package/src/tools/edit/core.ts +4 -4
- package/src/tools/edit/index.ts +2 -2
- package/src/tools/edit/phased.ts +2 -2
- package/src/tools/fetch/index.ts +2 -2
- package/src/tools/fetch/phased.ts +1 -1
- package/src/tools/index.ts +21 -21
- package/src/tools/mcp/index.ts +1 -1
- package/src/tools/remote-trigger/index.ts +1 -1
- package/src/tools/shared/auto-heal.ts +2 -2
- package/src/tools/state/index.ts +1 -1
- package/src/tools/web-search/index.ts +1 -1
- package/src/tools/write/index.ts +3 -3
- package/src/tools/write/phased.ts +1 -1
- package/src/version.ts +1 -1
- package/src/watchers/index.ts +2 -2
- package/src/watchers/registry.ts +2 -2
- package/src/web-search/index.ts +10 -10
- package/src/web-search/provider-registry.ts +8 -8
- package/src/web-search/providers/brave.ts +1 -1
- package/src/web-search/providers/duckduckgo.ts +1 -1
- package/src/web-search/providers/exa.ts +1 -1
- package/src/web-search/providers/firecrawl.ts +1 -1
- package/src/web-search/providers/perplexity.ts +1 -1
- package/src/web-search/providers/searxng.ts +1 -1
- package/src/web-search/providers/shared.ts +1 -1
- package/src/web-search/providers/tavily.ts +1 -1
- package/src/web-search/service.ts +2 -2
- package/src/runtime/ecosystem/catalog.ts +0 -606
package/src/config/manager.ts
CHANGED
|
@@ -1,404 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
import { getManagedSettingLock } from '../runtime/settings/control-plane.ts';
|
|
10
|
-
import { summarizeError } from '@pellux/goodvibes-sdk/platform/utils/error-display';
|
|
11
|
-
|
|
12
|
-
/** Deep immutable type — prevents mutation of nested objects returned from getAll(). */
|
|
13
|
-
export type DeepReadonly<T> = {
|
|
14
|
-
readonly [K in keyof T]: T[K] extends object ? DeepReadonly<T[K]> : T[K];
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
/** Constructor overrides for CLI args and programmatic instantiation. */
|
|
18
|
-
interface ConfigCliOverrides {
|
|
19
|
-
model?: string;
|
|
20
|
-
provider?: string;
|
|
21
|
-
autoApprove?: boolean;
|
|
22
|
-
systemPromptFile?: string;
|
|
23
|
-
workingDir?: string;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export type ConfigOverrides = ConfigCliOverrides & (
|
|
27
|
-
| {
|
|
28
|
-
configDir: string;
|
|
29
|
-
homeDir?: string;
|
|
30
|
-
sharedConfigPath?: string;
|
|
31
|
-
}
|
|
32
|
-
| {
|
|
33
|
-
homeDir: string;
|
|
34
|
-
configDir?: string;
|
|
35
|
-
sharedConfigPath?: string;
|
|
36
|
-
}
|
|
37
|
-
);
|
|
38
|
-
|
|
39
|
-
interface ConfigRoots {
|
|
40
|
-
configDir?: string;
|
|
41
|
-
homeDir?: string;
|
|
42
|
-
sharedConfigPath?: string;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export interface ConfigSetOptions {
|
|
46
|
-
bypassManagedLock?: boolean;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const DEFAULT_CONFIG_SNAPSHOT = structuredClone(DEFAULT_CONFIG) as GoodVibesConfig;
|
|
50
|
-
const PERMISSION_TOOL_KEYS = new Set(Object.keys(DEFAULT_CONFIG.permissions.tools));
|
|
51
|
-
|
|
52
|
-
function cloneDefaultConfig(): GoodVibesConfig {
|
|
53
|
-
return structuredClone(DEFAULT_CONFIG_SNAPSHOT) as GoodVibesConfig;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
function sanitizeConfigShape(config: GoodVibesConfig): GoodVibesConfig {
|
|
57
|
-
const sanitized = structuredClone(config) as GoodVibesConfig;
|
|
58
|
-
const lineNumbers = (sanitized.display as Record<string, unknown>).lineNumbers;
|
|
59
|
-
if (typeof lineNumbers === 'boolean') {
|
|
60
|
-
sanitized.display.lineNumbers = lineNumbers ? 'all' : 'off';
|
|
61
|
-
}
|
|
62
|
-
for (const key of Object.keys(sanitized.permissions.tools)) {
|
|
63
|
-
if (!PERMISSION_TOOL_KEYS.has(key)) {
|
|
64
|
-
delete (sanitized.permissions.tools as Record<string, unknown>)[key];
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
return sanitized;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
function requireAbsoluteOwnedPath(path: string | undefined, name: string): string | undefined {
|
|
71
|
-
if (path === undefined) return undefined;
|
|
72
|
-
const trimmed = path.trim();
|
|
73
|
-
if (!trimmed) {
|
|
74
|
-
throw new Error(`ConfigManager ${name} must be a non-empty absolute path.`);
|
|
75
|
-
}
|
|
76
|
-
if (!isAbsolute(trimmed)) {
|
|
77
|
-
throw new Error(`ConfigManager ${name} must be an absolute path.`);
|
|
78
|
-
}
|
|
79
|
-
return resolve(trimmed);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* Ensure the shared ~/.goodvibes/goodvibes.json exists (empty object if not).
|
|
84
|
-
* This is reserved for future cross-app use — no TUI settings go here.
|
|
85
|
-
*/
|
|
86
|
-
function ensureSharedConfig(sharedPath: string): void {
|
|
87
|
-
if (!existsSync(sharedPath)) {
|
|
88
|
-
mkdirSync(dirname(sharedPath), { recursive: true });
|
|
89
|
-
try {
|
|
90
|
-
writeFileSync(sharedPath, '{}\n', 'utf-8');
|
|
91
|
-
} catch (err) {
|
|
92
|
-
logger.debug('Could not create shared goodvibes.json (non-fatal)', { error: summarizeError(err) });
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* ConfigManager — Layered, mutable, persistent config system.
|
|
99
|
-
*
|
|
100
|
-
* Load order: defaults < global TUI settings < project TUI settings < CLI overrides
|
|
101
|
-
* API keys are never persisted — loaded from env vars only.
|
|
102
|
-
*/
|
|
103
|
-
export class ConfigManager {
|
|
104
|
-
private config: GoodVibesConfig;
|
|
105
|
-
private readonly configDir: string;
|
|
106
|
-
private readonly configPath: string;
|
|
107
|
-
private readonly projectConfigPath: string | null;
|
|
108
|
-
private readonly workingDirectory: string | null;
|
|
109
|
-
private readonly homeDirectory: string | null;
|
|
110
|
-
private hookDispatcher: Pick<HookDispatcher, 'fire'> | null = null;
|
|
111
|
-
|
|
112
|
-
constructor(overrides: ConfigOverrides) {
|
|
113
|
-
const roots = overrides as ConfigRoots;
|
|
114
|
-
const configDir = requireAbsoluteOwnedPath(roots.configDir, 'configDir');
|
|
115
|
-
const homeDirectory = requireAbsoluteOwnedPath(roots.homeDir, 'homeDir') ?? null;
|
|
116
|
-
const workingDirectory = requireAbsoluteOwnedPath(overrides.workingDir, 'workingDir') ?? null;
|
|
117
|
-
const sharedConfigPath = requireAbsoluteOwnedPath(roots.sharedConfigPath, 'sharedConfigPath');
|
|
118
|
-
const base = configDir ?? join(homeDirectory!, '.goodvibes', 'tui');
|
|
119
|
-
this.configDir = base;
|
|
120
|
-
this.configPath = join(base, 'settings.json');
|
|
121
|
-
this.workingDirectory = workingDirectory;
|
|
122
|
-
this.homeDirectory = homeDirectory;
|
|
123
|
-
this.projectConfigPath = this.workingDirectory
|
|
124
|
-
? join(this.workingDirectory, '.goodvibes', 'tui', 'settings.json')
|
|
125
|
-
: null;
|
|
126
|
-
this.config = cloneDefaultConfig();
|
|
127
|
-
|
|
128
|
-
const ownedSharedConfigPath = sharedConfigPath ?? (
|
|
129
|
-
this.homeDirectory ? join(this.homeDirectory, '.goodvibes', 'goodvibes.json') : null
|
|
130
|
-
);
|
|
131
|
-
if (ownedSharedConfigPath) {
|
|
132
|
-
ensureSharedConfig(ownedSharedConfigPath);
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
this.load();
|
|
136
|
-
|
|
137
|
-
// Apply constructor overrides (CLI args, etc.) after load
|
|
138
|
-
if (overrides.model !== undefined) {
|
|
139
|
-
this.config.provider.model = overrides.model;
|
|
140
|
-
}
|
|
141
|
-
if (overrides.provider !== undefined) {
|
|
142
|
-
this.config.provider.provider = overrides.provider;
|
|
143
|
-
}
|
|
144
|
-
if (overrides.autoApprove !== undefined) {
|
|
145
|
-
this.config.behavior.autoApprove = overrides.autoApprove;
|
|
146
|
-
}
|
|
147
|
-
if (overrides.systemPromptFile !== undefined) {
|
|
148
|
-
this.config.provider.systemPromptFile = overrides.systemPromptFile;
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
getControlPlaneConfigDir(): string {
|
|
153
|
-
return this.configDir;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
getWorkingDirectory(): string | null {
|
|
157
|
-
return this.workingDirectory;
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
getHomeDirectory(): string | null {
|
|
161
|
-
return this.homeDirectory;
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
attachHookDispatcher(hookDispatcher: Pick<HookDispatcher, 'fire'> | null): void {
|
|
165
|
-
this.hookDispatcher = hookDispatcher;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
private resolvePath(
|
|
169
|
-
key: ConfigKey,
|
|
170
|
-
): { parent: Record<string, unknown>; field: string } {
|
|
171
|
-
const parts = key.split('.');
|
|
172
|
-
let cursor: unknown = this.config;
|
|
173
|
-
|
|
174
|
-
for (let i = 0; i < parts.length - 1; i++) {
|
|
175
|
-
const part = parts[i]!;
|
|
176
|
-
if (cursor == null || typeof cursor !== 'object' || !(part in (cursor as Record<string, unknown>))) {
|
|
177
|
-
throw new Error(`Invalid config path: section '${parts.slice(0, i + 1).join('.')}' does not exist`);
|
|
178
|
-
}
|
|
179
|
-
cursor = (cursor as Record<string, unknown>)[part];
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
if (cursor == null || typeof cursor !== 'object') {
|
|
183
|
-
throw new Error(`Invalid config path: section '${parts.slice(0, -1).join('.')}' does not exist`);
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
return {
|
|
187
|
-
parent: cursor as Record<string, unknown>,
|
|
188
|
-
field: parts[parts.length - 1]!,
|
|
189
|
-
};
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
/** Get a config value by dot-path key. */
|
|
193
|
-
get<K extends ConfigKey>(key: K): ConfigValue<K> {
|
|
194
|
-
const { parent, field } = this.resolvePath(key);
|
|
195
|
-
return parent[field] as ConfigValue<K>;
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
/** Set a config value by dot-path key and auto-save to disk. */
|
|
199
|
-
set<K extends ConfigKey>(key: K, value: ConfigValue<K>, options: ConfigSetOptions = {}): void {
|
|
200
|
-
const schema = CONFIG_SCHEMA.find(s => s.key === key);
|
|
201
|
-
if (schema?.validate && !schema.validate(value)) {
|
|
202
|
-
throw new ConfigError(`Invalid value for ${key}: ${String(value)}`);
|
|
203
|
-
}
|
|
204
|
-
if (schema?.type === 'enum' && schema.enumValues && !schema.enumValues.includes(value as string)) {
|
|
205
|
-
throw new ConfigError(`Invalid value for ${key}: "${String(value)}". Allowed: ${schema.enumValues.join(', ')}`);
|
|
206
|
-
}
|
|
207
|
-
if (!options.bypassManagedLock) {
|
|
208
|
-
const lock = getManagedSettingLock(key, this.configDir);
|
|
209
|
-
if (lock) {
|
|
210
|
-
throw new ConfigError(`Setting ${key} is locked by ${lock.source}: ${lock.reason}`);
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
const { parent, field } = this.resolvePath(key);
|
|
215
|
-
const previousValue = parent[field];
|
|
216
|
-
parent[field] = value;
|
|
217
|
-
this.save();
|
|
218
|
-
this.emitConfigHook(key, previousValue, value);
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
/**
|
|
222
|
-
* Fire the Change:config hook for a config key change.
|
|
223
|
-
* Best-effort: the hook dispatcher may not be initialised during startup.
|
|
224
|
-
*/
|
|
225
|
-
private emitConfigHook(key: ConfigKey, previousValue: unknown, newValue: unknown): void {
|
|
226
|
-
if (!this.hookDispatcher) return;
|
|
227
|
-
try {
|
|
228
|
-
const event: HookEvent = {
|
|
229
|
-
path: `Change:config:${key}`,
|
|
230
|
-
phase: 'Change',
|
|
231
|
-
category: 'config',
|
|
232
|
-
specific: key,
|
|
233
|
-
sessionId: '',
|
|
234
|
-
timestamp: Date.now(),
|
|
235
|
-
payload: { key, value: newValue, previousValue },
|
|
236
|
-
};
|
|
237
|
-
this.hookDispatcher
|
|
238
|
-
.fire(event)
|
|
239
|
-
.catch(() => { /* ignore async errors */ });
|
|
240
|
-
} catch {
|
|
241
|
-
// Dispatcher not ready during startup — safe to ignore
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
/**
|
|
246
|
-
* Set a config value from a validated ConfigKey with unknown value type.
|
|
247
|
-
* Used when iterating schema entries where the value type cannot be statically
|
|
248
|
-
* inferred. Runtime validation is still applied by the underlying set() method.
|
|
249
|
-
*/
|
|
250
|
-
setDynamic(key: ConfigKey, value: unknown, options: ConfigSetOptions = {}): void {
|
|
251
|
-
this.set(key, value as never, options);
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
/** Return a deep-readonly snapshot of the full config. Nested objects are immutable. */
|
|
255
|
-
getAll(): DeepReadonly<GoodVibesConfig> {
|
|
256
|
-
return structuredClone(this.config) as DeepReadonly<GoodVibesConfig>;
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
/** Return a deep-cloned snapshot of a config category. */
|
|
260
|
-
getCategory<C extends keyof GoodVibesConfig>(category: C): Readonly<GoodVibesConfig[C]> {
|
|
261
|
-
return structuredClone(this.config[category]);
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
/** Return a deep-cloned snapshot of the live config. Safe for read-only external consumers. */
|
|
265
|
-
getRaw(): Readonly<GoodVibesConfig> {
|
|
266
|
-
return structuredClone(this.config) as Readonly<GoodVibesConfig>;
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
/** Return the full schema. */
|
|
270
|
-
getSchema(): ConfigSetting[] {
|
|
271
|
-
return CONFIG_SCHEMA;
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
/** Persist current config to global TUI settings file. */
|
|
275
|
-
save(): void {
|
|
276
|
-
try {
|
|
277
|
-
mkdirSync(dirname(this.configPath), { recursive: true });
|
|
278
|
-
writeFileSync(this.configPath, JSON.stringify(this.config, null, 2) + '\n', 'utf-8');
|
|
279
|
-
} catch (err) {
|
|
280
|
-
logger.debug('Config save failed (non-fatal)', { error: summarizeError(err) });
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
/** Persist current config to project-level TUI settings file (.goodvibes/tui/settings.json). */
|
|
285
|
-
saveProject(): void {
|
|
286
|
-
if (!this.projectConfigPath) {
|
|
287
|
-
throw new Error('ConfigManager.saveProject requires an explicit workingDir.');
|
|
288
|
-
}
|
|
289
|
-
try {
|
|
290
|
-
mkdirSync(dirname(this.projectConfigPath), { recursive: true });
|
|
291
|
-
writeFileSync(this.projectConfigPath, JSON.stringify(this.config, null, 2) + '\n', 'utf-8');
|
|
292
|
-
} catch (err) {
|
|
293
|
-
logger.debug('Project config save failed (non-fatal)', { error: summarizeError(err) });
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
/** Load config from disk: global then project (project wins). Deep-merges with defaults. */
|
|
298
|
-
load(): void {
|
|
299
|
-
// Load global settings
|
|
300
|
-
if (existsSync(this.configPath)) {
|
|
301
|
-
try {
|
|
302
|
-
const raw = readFileSync(this.configPath, 'utf-8');
|
|
303
|
-
const parsed = JSON.parse(raw) as Record<string, unknown>;
|
|
304
|
-
|
|
305
|
-
this.config = sanitizeConfigShape(deepMerge(cloneDefaultConfig(), parsed) as GoodVibesConfig);
|
|
306
|
-
} catch (err) {
|
|
307
|
-
logger.debug('Global config load failed (non-fatal, using defaults)', { error: summarizeError(err) });
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
// Load project settings and deep-merge on top (project wins)
|
|
312
|
-
if (this.projectConfigPath && existsSync(this.projectConfigPath)) {
|
|
313
|
-
try {
|
|
314
|
-
const raw = readFileSync(this.projectConfigPath, 'utf-8');
|
|
315
|
-
const parsed = JSON.parse(raw) as Record<string, unknown>;
|
|
316
|
-
this.config = sanitizeConfigShape(deepMerge(this.config, parsed) as GoodVibesConfig);
|
|
317
|
-
} catch (err) {
|
|
318
|
-
logger.debug('Project config load failed (non-fatal)', { error: summarizeError(err) });
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
/**
|
|
324
|
-
* Merge a partial patch into a config category and auto-save.
|
|
325
|
-
*
|
|
326
|
-
* This is the correct way to update array or object fields within a category
|
|
327
|
-
* that cannot be expressed as a scalar dot-path key (e.g. notifications.webhookUrls).
|
|
328
|
-
* The patch is shallow-merged into the existing category value.
|
|
329
|
-
*/
|
|
330
|
-
mergeCategory<C extends keyof GoodVibesConfig>(category: C, patch: Partial<GoodVibesConfig[C]>): void {
|
|
331
|
-
const current = this.config[category] as Record<string, unknown>;
|
|
332
|
-
const patchObj = patch as Record<string, unknown>;
|
|
333
|
-
for (const key of Object.keys(patchObj)) {
|
|
334
|
-
if (patchObj[key] !== undefined) {
|
|
335
|
-
current[key] = patchObj[key];
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
this.save();
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
/**
|
|
342
|
-
* Reset a specific key to its default, or reset all config.
|
|
343
|
-
* Saves to disk after reset.
|
|
344
|
-
*/
|
|
345
|
-
reset(key?: ConfigKey): void {
|
|
346
|
-
if (key === undefined) {
|
|
347
|
-
this.config = cloneDefaultConfig();
|
|
348
|
-
} else {
|
|
349
|
-
const schema = CONFIG_SCHEMA.find(s => s.key === key);
|
|
350
|
-
if (!schema) throw new ConfigError(`Unknown config key: ${key}`);
|
|
351
|
-
const livePath = this.resolvePath(key);
|
|
352
|
-
const defaultPath = resolveArbitraryPath(DEFAULT_CONFIG_SNAPSHOT as unknown as Record<string, unknown>, key);
|
|
353
|
-
livePath.parent[livePath.field] = structuredClone(defaultPath.parent[defaultPath.field]);
|
|
354
|
-
}
|
|
355
|
-
this.save();
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
/** Deep-merge source into target. Returns a new object. Source non-objects are ignored — target clone is returned.
|
|
360
|
-
* Non-object source values will not overwrite object target values (type-safe merge). */
|
|
361
|
-
function deepMerge(target: unknown, source: unknown): unknown {
|
|
362
|
-
const result: Record<string, unknown> = isObject(target)
|
|
363
|
-
? structuredClone(target) as Record<string, unknown>
|
|
364
|
-
: {};
|
|
365
|
-
if (!isObject(source)) return result;
|
|
366
|
-
for (const key of Object.keys(source)) {
|
|
367
|
-
const sv = source[key];
|
|
368
|
-
const tv = result[key];
|
|
369
|
-
if (isObject(sv) && isObject(tv)) {
|
|
370
|
-
result[key] = deepMerge(tv, sv);
|
|
371
|
-
} else if (sv !== undefined && !isObject(tv)) {
|
|
372
|
-
// Only overwrite non-object target values — never replace an object with a scalar.
|
|
373
|
-
// Clone assigned values so config instances never share mutable references.
|
|
374
|
-
result[key] = structuredClone(sv);
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
return result;
|
|
378
|
-
}
|
|
379
|
-
|
|
380
|
-
function isObject(val: unknown): val is Record<string, unknown> {
|
|
381
|
-
return val !== null && typeof val === 'object' && !Array.isArray(val);
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
function resolveArbitraryPath(
|
|
385
|
-
root: Record<string, unknown>,
|
|
386
|
-
key: string,
|
|
387
|
-
): { parent: Record<string, unknown>; field: string } {
|
|
388
|
-
const parts = key.split('.');
|
|
389
|
-
let cursor: unknown = root;
|
|
390
|
-
for (let i = 0; i < parts.length - 1; i++) {
|
|
391
|
-
const part = parts[i]!;
|
|
392
|
-
if (cursor == null || typeof cursor !== 'object' || !(part in (cursor as Record<string, unknown>))) {
|
|
393
|
-
throw new Error(`Invalid config path: section '${parts.slice(0, i + 1).join('.')}' does not exist`);
|
|
394
|
-
}
|
|
395
|
-
cursor = (cursor as Record<string, unknown>)[part];
|
|
396
|
-
}
|
|
397
|
-
if (cursor == null || typeof cursor !== 'object') {
|
|
398
|
-
throw new Error(`Invalid config path: section '${parts.slice(0, -1).join('.')}' does not exist`);
|
|
399
|
-
}
|
|
400
|
-
return {
|
|
401
|
-
parent: cursor as Record<string, unknown>,
|
|
402
|
-
field: parts[parts.length - 1]!,
|
|
403
|
-
};
|
|
404
|
-
}
|
|
1
|
+
export {
|
|
2
|
+
ConfigManager,
|
|
3
|
+
} from '@pellux/goodvibes-sdk/platform/config/manager';
|
|
4
|
+
export type {
|
|
5
|
+
ConfigOverrides,
|
|
6
|
+
ConfigSetOptions,
|
|
7
|
+
DeepReadonly,
|
|
8
|
+
} from '@pellux/goodvibes-sdk/platform/config/manager';
|