@pellux/goodvibes-tui 0.18.11 → 0.18.13
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 +72 -0
- package/README.md +1 -1
- package/docs/foundation-artifacts/operator-contract.json +1 -1
- package/package.json +2 -2
- package/src/config/index.ts +1 -138
- package/src/config/subscription-providers.ts +1 -127
- package/src/core/conversation-rendering.ts +5 -5
- package/src/core/conversation.ts +177 -424
- package/src/core/history.ts +45 -0
- package/src/core/orchestrator.ts +3 -733
- package/src/core/system-message-router.ts +19 -58
- package/src/input/command-registry.ts +3 -3
- package/src/input/commands/session-content.ts +2 -2
- package/src/input/commands/session-workflow.ts +1 -1
- package/src/input/handler-content-actions.ts +2 -2
- package/src/input/handler-feed.ts +2 -2
- package/src/input/handler-modal-token-routes.ts +1 -1
- package/src/input/handler-ui-state.ts +1 -1
- package/src/input/handler.ts +1 -1
- package/src/input/search.ts +1 -1
- package/src/input/selection.ts +2 -2
- package/src/input/session-picker-modal.ts +1 -1
- package/src/main.ts +1 -1
- package/src/panels/agent-inspector-panel.ts +3 -3
- package/src/panels/agent-logs-panel.ts +3 -3
- package/src/panels/approval-panel.ts +2 -2
- package/src/panels/automation-control-panel.ts +3 -3
- package/src/panels/base-panel.ts +14 -14
- package/src/panels/builtin/agent.ts +1 -0
- package/src/panels/builtin/operations.ts +2 -1
- package/src/panels/builtin/session.ts +2 -2
- package/src/panels/builtin/shared.ts +5 -5
- package/src/panels/cockpit-panel.ts +2 -2
- package/src/panels/communication-panel.ts +3 -3
- package/src/panels/context-visualizer-panel.ts +6 -3
- package/src/panels/control-plane-panel.ts +3 -3
- package/src/panels/cost-tracker-panel.ts +3 -3
- package/src/panels/debug-panel.ts +2 -2
- package/src/panels/diff-panel.ts +2 -2
- package/src/panels/docs-panel.ts +1 -1
- package/src/panels/eval-panel.ts +2 -2
- package/src/panels/file-explorer-panel.ts +3 -3
- package/src/panels/file-preview-panel.ts +3 -3
- package/src/panels/forensics-panel.ts +2 -2
- package/src/panels/git-panel.ts +1 -1
- package/src/panels/hooks-panel.ts +3 -3
- package/src/panels/incident-review-panel.ts +1 -1
- package/src/panels/intelligence-panel.ts +2 -2
- package/src/panels/knowledge-panel.ts +1 -1
- package/src/panels/local-auth-panel.ts +2 -2
- package/src/panels/marketplace-panel.ts +1 -1
- package/src/panels/mcp-panel.ts +3 -3
- package/src/panels/memory-panel.ts +1 -1
- package/src/panels/ops-control-panel.ts +3 -3
- package/src/panels/ops-strategy-panel.ts +2 -2
- package/src/panels/orchestration-panel.ts +2 -2
- package/src/panels/panel-list-panel.ts +6 -6
- package/src/panels/plan-dashboard-panel.ts +1 -1
- package/src/panels/plugins-panel.ts +2 -2
- package/src/panels/policy-panel.ts +2 -2
- package/src/panels/polish.ts +3 -3
- package/src/panels/provider-accounts-panel.ts +2 -2
- package/src/panels/provider-health-domains.ts +5 -1
- package/src/panels/provider-health-panel.ts +7 -3
- package/src/panels/provider-stats-panel.ts +3 -3
- package/src/panels/remote-panel.ts +3 -3
- package/src/panels/routes-panel.ts +3 -3
- package/src/panels/sandbox-panel.ts +2 -2
- package/src/panels/schedule-panel.ts +1 -1
- package/src/panels/security-panel.ts +2 -2
- package/src/panels/services-panel.ts +2 -2
- package/src/panels/session-browser-panel.ts +3 -3
- package/src/panels/settings-sync-panel.ts +2 -2
- package/src/panels/skills-panel.ts +6 -6
- package/src/panels/subscription-panel.ts +2 -2
- package/src/panels/symbol-outline-panel.ts +3 -3
- package/src/panels/system-messages-panel.ts +4 -4
- package/src/panels/tasks-panel.ts +2 -2
- package/src/panels/thinking-panel.ts +3 -3
- package/src/panels/token-budget-panel.ts +7 -3
- package/src/panels/tool-inspector-panel.ts +3 -3
- package/src/panels/types.ts +5 -5
- package/src/panels/watchers-panel.ts +3 -3
- package/src/panels/welcome-panel.ts +1 -1
- package/src/panels/worktree-panel.ts +2 -2
- package/src/panels/wrfc-panel.ts +3 -3
- package/src/permissions/prompt.ts +3 -22
- package/src/plugins/loader.ts +15 -304
- package/src/renderer/agent-detail-modal.ts +1 -1
- package/src/renderer/autocomplete-overlay.ts +2 -2
- package/src/renderer/bookmark-modal.ts +1 -1
- package/src/renderer/bottom-bar.ts +2 -2
- package/src/renderer/buffer.ts +1 -1
- package/src/renderer/code-block.ts +2 -2
- package/src/renderer/compositor.ts +2 -2
- package/src/renderer/context-inspector.ts +1 -1
- package/src/renderer/conversation-layout.ts +2 -2
- package/src/renderer/conversation-overlays.ts +1 -1
- package/src/renderer/conversation-surface.ts +2 -2
- package/src/renderer/diff-view.ts +2 -2
- package/src/renderer/diff.ts +1 -1
- package/src/renderer/file-picker-overlay.ts +2 -2
- package/src/renderer/file-tree.ts +2 -2
- package/src/renderer/help-overlay.ts +1 -1
- package/src/renderer/history-search-overlay.ts +2 -2
- package/src/renderer/live-tail-modal.ts +1 -1
- package/src/renderer/markdown.ts +2 -2
- package/src/renderer/modal-factory.ts +3 -3
- package/src/renderer/model-picker-overlay.ts +2 -2
- package/src/renderer/overlay-box.ts +2 -2
- package/src/renderer/panel-composite.ts +1 -1
- package/src/renderer/panel-picker-overlay.ts +2 -2
- package/src/renderer/panel-tab-bar.ts +1 -1
- package/src/renderer/panel-workspace-bar.ts +1 -1
- package/src/renderer/process-indicator.ts +2 -2
- package/src/renderer/process-modal.ts +1 -1
- package/src/renderer/profile-picker-modal.ts +2 -2
- package/src/renderer/progress.ts +2 -2
- package/src/renderer/search-overlay.ts +2 -2
- package/src/renderer/selection-modal-overlay.ts +2 -2
- package/src/renderer/session-picker-modal.ts +2 -2
- package/src/renderer/settings-modal.ts +2 -2
- package/src/renderer/shell-surface.ts +1 -1
- package/src/renderer/system-message.ts +1 -1
- package/src/renderer/tab-strip.ts +2 -2
- package/src/renderer/text-layout.ts +1 -1
- package/src/renderer/thinking.ts +1 -1
- package/src/renderer/tool-call.ts +2 -2
- package/src/renderer/ui-factory.ts +2 -2
- package/src/runtime/bootstrap-command-context.ts +7 -8
- package/src/runtime/bootstrap-command-parts.ts +4 -6
- package/src/runtime/bootstrap-core.ts +5 -4
- package/src/runtime/bootstrap-hook-bridge.ts +16 -175
- package/src/runtime/bootstrap-shell.ts +5 -5
- package/src/runtime/bootstrap.ts +6 -5
- package/src/runtime/context.ts +4 -20
- package/src/runtime/diagnostics/panels/index.ts +1 -1
- package/src/runtime/diagnostics/panels/ops.ts +1 -1
- package/src/runtime/diagnostics/panels/panel-resources.ts +118 -0
- package/src/runtime/perf/panel-contracts.ts +32 -0
- package/src/runtime/perf/panel-health-monitor.ts +18 -0
- package/src/runtime/services.ts +6 -6
- package/src/runtime/store/domains/conversation.ts +1 -181
- package/src/runtime/store/domains/permissions.ts +1 -143
- package/src/runtime/store/helpers/reducers/conversation.ts +1 -228
- package/src/runtime/store/helpers/reducers/lifecycle.ts +1 -440
- package/src/runtime/store/selectors/index.ts +11 -6
- package/src/runtime/store/state.ts +12 -4
- package/src/runtime/ui-read-models-observability-security.ts +2 -2
- package/src/runtime/ui-read-models-observability-system.ts +1 -1
- package/src/runtime/ui-service-queries.ts +1 -1
- package/src/runtime/ui-services.ts +1 -1
- package/src/shell/ui-openers.ts +1 -1
- package/src/tools/index.ts +1 -186
- package/src/types/grid.ts +48 -0
- package/src/utils/clipboard.ts +21 -0
- package/src/utils/splash-lines.ts +1 -1
- package/src/utils/terminal-width.ts +185 -0
- package/src/version.ts +1 -1
- package/src/acp/connection.ts +0 -447
- package/src/acp/index.ts +0 -7
- package/src/acp/manager.ts +0 -1
- package/src/adapters/bluebubbles/index.ts +0 -127
- package/src/adapters/discord/index.ts +0 -297
- package/src/adapters/github/index.ts +0 -73
- package/src/adapters/google-chat/index.ts +0 -119
- package/src/adapters/imessage/index.ts +0 -92
- package/src/adapters/index.ts +0 -15
- package/src/adapters/matrix/index.ts +0 -116
- package/src/adapters/mattermost/index.ts +0 -151
- package/src/adapters/msteams/index.ts +0 -180
- package/src/adapters/ntfy/index.ts +0 -118
- package/src/adapters/signal/index.ts +0 -92
- package/src/adapters/slack/index.ts +0 -323
- package/src/adapters/telegram/index.ts +0 -160
- package/src/adapters/types.ts +0 -97
- package/src/adapters/webhook/index.ts +0 -178
- package/src/adapters/whatsapp/index.ts +0 -135
- package/src/agents/message-bus-core.ts +0 -312
- package/src/agents/message-bus.ts +0 -2
- package/src/agents/orchestrator-prompts.ts +0 -351
- package/src/agents/orchestrator-runner.ts +0 -668
- package/src/agents/orchestrator.ts +0 -438
- package/src/agents/session.ts +0 -108
- package/src/agents/worktree.ts +0 -153
- package/src/agents/wrfc-config.ts +0 -47
- package/src/agents/wrfc-controller.ts +0 -747
- package/src/agents/wrfc-gate-runtime.ts +0 -75
- package/src/agents/wrfc-reporting.ts +0 -284
- package/src/agents/wrfc-runtime-events.ts +0 -150
- package/src/agents/wrfc-types.ts +0 -67
- package/src/automation/delivery-manager.ts +0 -368
- package/src/automation/index.ts +0 -72
- package/src/automation/manager-runtime-delivery.ts +0 -139
- package/src/automation/manager-runtime-events.ts +0 -131
- package/src/automation/manager-runtime-execution.ts +0 -511
- package/src/automation/manager-runtime-helpers.ts +0 -433
- package/src/automation/manager-runtime-job-mutations.ts +0 -175
- package/src/automation/manager-runtime-reconcile.ts +0 -148
- package/src/automation/manager-runtime-scheduling.ts +0 -189
- package/src/automation/manager-runtime-sync.ts +0 -54
- package/src/automation/manager-runtime.ts +0 -721
- package/src/automation/manager.ts +0 -10
- package/src/automation/service.ts +0 -242
- package/src/channels/builtin/account-actions.ts +0 -490
- package/src/channels/builtin/accounts.ts +0 -433
- package/src/channels/builtin/contracts.ts +0 -405
- package/src/channels/builtin/plugins.ts +0 -308
- package/src/channels/builtin/rendering.ts +0 -174
- package/src/channels/builtin/setup-schema.ts +0 -504
- package/src/channels/builtin/shared.ts +0 -96
- package/src/channels/builtin/surfaces.ts +0 -57
- package/src/channels/builtin/targets.ts +0 -693
- package/src/channels/builtin-runtime.ts +0 -443
- package/src/channels/delivery/shared.ts +0 -199
- package/src/channels/delivery/strategies-bridge.ts +0 -246
- package/src/channels/delivery/strategies-core.ts +0 -299
- package/src/channels/delivery/strategies-enterprise.ts +0 -178
- package/src/channels/delivery/types.ts +0 -59
- package/src/channels/delivery-router.ts +0 -127
- package/src/channels/index.ts +0 -77
- package/src/channels/plugin-registry.ts +0 -551
- package/src/channels/provider-runtime.ts +0 -330
- package/src/channels/reply-pipeline.ts +0 -522
- package/src/channels/route-manager.ts +0 -340
- package/src/channels/surface-registry.ts +0 -186
- package/src/config/helper-model.ts +0 -1
- package/src/config/manager.ts +0 -8
- package/src/config/subscription-auth.ts +0 -31
- package/src/config/tool-llm.ts +0 -110
- package/src/control-plane/approval-broker.ts +0 -351
- package/src/control-plane/gateway.ts +0 -1
- package/src/control-plane/index.ts +0 -54
- package/src/control-plane/media-contract-schemas.ts +0 -1
- package/src/control-plane/method-catalog-admin.ts +0 -1
- package/src/control-plane/method-catalog-channels.ts +0 -1
- package/src/control-plane/method-catalog-control-automation.ts +0 -1
- package/src/control-plane/method-catalog-control-core.ts +0 -1
- package/src/control-plane/method-catalog-control.ts +0 -1
- package/src/control-plane/method-catalog-events.ts +0 -1
- package/src/control-plane/method-catalog-knowledge.ts +0 -1
- package/src/control-plane/method-catalog-media.ts +0 -1
- package/src/control-plane/method-catalog-runtime.ts +0 -1
- package/src/control-plane/method-catalog-shared.ts +0 -1
- package/src/control-plane/method-catalog.ts +0 -1
- package/src/control-plane/operator-contract-schemas-admin.ts +0 -1
- package/src/control-plane/operator-contract-schemas-channels.ts +0 -1
- package/src/control-plane/operator-contract-schemas-control.ts +0 -1
- package/src/control-plane/operator-contract-schemas-domains.ts +0 -1
- package/src/control-plane/operator-contract-schemas-knowledge.ts +0 -1
- package/src/control-plane/operator-contract-schemas-media.ts +0 -1
- package/src/control-plane/operator-contract-schemas-permissions.ts +0 -1
- package/src/control-plane/operator-contract-schemas-remote.ts +0 -1
- package/src/control-plane/operator-contract-schemas-runtime.ts +0 -1
- package/src/control-plane/operator-contract-schemas-shared.ts +0 -1
- package/src/control-plane/operator-contract-schemas-telemetry.ts +0 -1
- package/src/control-plane/operator-contract-schemas.ts +0 -1
- package/src/control-plane/operator-contract.ts +0 -165
- package/src/control-plane/session-broker.ts +0 -780
- package/src/core/compaction-sections.ts +0 -492
- package/src/core/compaction-types.ts +0 -147
- package/src/core/context-compaction.ts +0 -542
- package/src/core/conversation-compaction.ts +0 -68
- package/src/core/conversation-diff.ts +0 -55
- package/src/core/conversation-utils.ts +0 -72
- package/src/core/event-replay.ts +0 -287
- package/src/core/orchestrator-context-runtime.ts +0 -407
- package/src/core/orchestrator-follow-up-runtime.ts +0 -134
- package/src/core/orchestrator-runtime.ts +0 -132
- package/src/core/orchestrator-tool-runtime.ts +0 -468
- package/src/core/orchestrator-turn-helpers.ts +0 -355
- package/src/core/orchestrator-turn-loop.ts +0 -443
- package/src/core/plan-command-handler.ts +0 -169
- package/src/core/transcript-events/classify.ts +0 -95
- package/src/core/transcript-events/index.ts +0 -15
- package/src/daemon/control-plane.ts +0 -522
- package/src/daemon/facade-composition.ts +0 -398
- package/src/daemon/facade.ts +0 -638
- package/src/daemon/helpers.ts +0 -74
- package/src/daemon/http/router-route-contexts.ts +0 -370
- package/src/daemon/http/router.ts +0 -531
- package/src/daemon/http-listener.ts +0 -301
- package/src/daemon/index.ts +0 -1
- package/src/daemon/server.ts +0 -1
- package/src/daemon/service-manager.ts +0 -413
- package/src/daemon/surface-actions.ts +0 -183
- package/src/daemon/surface-delivery.ts +0 -530
- package/src/daemon/surface-policy.ts +0 -60
- package/src/daemon/transport-events.ts +0 -110
- package/src/daemon/types.ts +0 -191
- package/src/export/markdown.ts +0 -213
- package/src/export/session-export.ts +0 -1
- package/src/git/index.ts +0 -1
- package/src/git/service.ts +0 -414
- package/src/hooks/chain-engine.ts +0 -414
- package/src/hooks/dispatcher.ts +0 -414
- package/src/hooks/hook-api.ts +0 -170
- package/src/hooks/index.ts +0 -48
- package/src/hooks/runners/agent.ts +0 -93
- package/src/hooks/runners/prompt.ts +0 -69
- package/src/hooks/workbench.ts +0 -360
- package/src/integrations/index.ts +0 -42
- package/src/integrations/notifier.ts +0 -206
- package/src/integrations/webhooks.ts +0 -1
- package/src/knowledge/consolidation.ts +0 -346
- package/src/knowledge/graphql.ts +0 -324
- package/src/knowledge/index.ts +0 -60
- package/src/knowledge/ingest-compile.ts +0 -386
- package/src/knowledge/ingest-context.ts +0 -18
- package/src/knowledge/ingest-inputs.ts +0 -387
- package/src/knowledge/ingest.ts +0 -1
- package/src/knowledge/internal.ts +0 -257
- package/src/knowledge/knowledge-api.ts +0 -432
- package/src/knowledge/lint.ts +0 -121
- package/src/knowledge/memory-sync.ts +0 -62
- package/src/knowledge/packet.ts +0 -370
- package/src/knowledge/scheduling.ts +0 -283
- package/src/knowledge/service.ts +0 -715
- package/src/mcp/client.ts +0 -383
- package/src/mcp/index.ts +0 -12
- package/src/mcp/mcp-api.ts +0 -90
- package/src/mcp/registry.ts +0 -1
- package/src/media/builtin-image-understanding.ts +0 -303
- package/src/media/builtin-providers.ts +0 -26
- package/src/media/index.ts +0 -18
- package/src/multimodal/index.ts +0 -13
- package/src/multimodal/service.ts +0 -492
- package/src/permissions/briefs/build.ts +0 -88
- package/src/permissions/manager.ts +0 -1
- package/src/plugins/api.ts +0 -383
- package/src/plugins/manager.ts +0 -481
- package/src/profiles/shape.ts +0 -58
- package/src/providers/amazon-bedrock-mantle.ts +0 -50
- package/src/providers/amazon-bedrock.ts +0 -61
- package/src/providers/anthropic-compat.ts +0 -373
- package/src/providers/anthropic-sdk-provider.ts +0 -230
- package/src/providers/anthropic-vertex.ts +0 -59
- package/src/providers/anthropic.ts +0 -469
- package/src/providers/auto-register.ts +0 -417
- package/src/providers/builtin-catalog.ts +0 -326
- package/src/providers/builtin-registry.ts +0 -575
- package/src/providers/cache-planner.ts +0 -258
- package/src/providers/capabilities.ts +0 -1
- package/src/providers/custom-loader.ts +0 -425
- package/src/providers/discovered-compat.ts +0 -7
- package/src/providers/discovered-factory.ts +0 -61
- package/src/providers/discovered-traits.ts +0 -138
- package/src/providers/gemini.ts +0 -462
- package/src/providers/github-copilot.ts +0 -254
- package/src/providers/index.ts +0 -1
- package/src/providers/interface.ts +0 -185
- package/src/providers/llama-cpp.ts +0 -402
- package/src/providers/lm-studio-helpers.ts +0 -367
- package/src/providers/lm-studio.ts +0 -484
- package/src/providers/model-catalog-cache.ts +0 -221
- package/src/providers/model-catalog-notifications.ts +0 -97
- package/src/providers/model-catalog-synthetic.ts +0 -202
- package/src/providers/model-catalog.ts +0 -211
- package/src/providers/model-limits.ts +0 -1
- package/src/providers/ollama.ts +0 -469
- package/src/providers/openai-codex.ts +0 -472
- package/src/providers/openai-compat.ts +0 -615
- package/src/providers/openai.ts +0 -231
- package/src/providers/optimizer.ts +0 -1
- package/src/providers/provider-api.ts +0 -1
- package/src/providers/registry-helpers.ts +0 -34
- package/src/providers/registry-models.ts +0 -77
- package/src/providers/registry-types.ts +0 -67
- package/src/providers/registry.ts +0 -1
- package/src/providers/runtime-metadata.ts +0 -149
- package/src/providers/runtime-snapshot.ts +0 -130
- package/src/providers/synthetic.ts +0 -561
- package/src/providers/tier-prompts.ts +0 -84
- package/src/providers/tool-formats.ts +0 -414
- package/src/runtime/auth/inspection.ts +0 -125
- package/src/runtime/bootstrap-background.ts +0 -157
- package/src/runtime/bootstrap-helpers.ts +0 -88
- package/src/runtime/bootstrap-runtime-events.ts +0 -254
- package/src/runtime/bootstrap-services.ts +0 -197
- package/src/runtime/compaction/index.ts +0 -1
- package/src/runtime/compaction/lifecycle.ts +0 -1
- package/src/runtime/compaction/manager.ts +0 -474
- package/src/runtime/compaction/quality-score.ts +0 -1
- package/src/runtime/compaction/resume-repair.ts +0 -1
- package/src/runtime/compaction/strategies/autocompact.ts +0 -1
- package/src/runtime/compaction/strategies/boundary-commit.ts +0 -1
- package/src/runtime/compaction/strategies/collapse.ts +0 -1
- package/src/runtime/compaction/strategies/index.ts +0 -1
- package/src/runtime/compaction/strategies/microcompact.ts +0 -1
- package/src/runtime/compaction/strategies/reactive.ts +0 -1
- package/src/runtime/compaction/types.ts +0 -1
- package/src/runtime/ecosystem/recommendations.ts +0 -117
- package/src/runtime/emitters/agents.ts +0 -96
- package/src/runtime/emitters/automation.ts +0 -112
- package/src/runtime/emitters/communication.ts +0 -53
- package/src/runtime/emitters/compaction.ts +0 -161
- package/src/runtime/emitters/control-plane.ts +0 -65
- package/src/runtime/emitters/deliveries.ts +0 -65
- package/src/runtime/emitters/forensics.ts +0 -17
- package/src/runtime/emitters/index.ts +0 -59
- package/src/runtime/emitters/knowledge.ts +0 -129
- package/src/runtime/emitters/mcp.ts +0 -95
- package/src/runtime/emitters/ops.ts +0 -163
- package/src/runtime/emitters/orchestration.ts +0 -87
- package/src/runtime/emitters/permissions.ts +0 -98
- package/src/runtime/emitters/planner.ts +0 -23
- package/src/runtime/emitters/plugins.ts +0 -78
- package/src/runtime/emitters/providers.ts +0 -30
- package/src/runtime/emitters/routes.ts +0 -57
- package/src/runtime/emitters/security.ts +0 -53
- package/src/runtime/emitters/session.ts +0 -93
- package/src/runtime/emitters/surfaces.ts +0 -57
- package/src/runtime/emitters/tasks.ts +0 -69
- package/src/runtime/emitters/tools.ts +0 -140
- package/src/runtime/emitters/transport.ts +0 -78
- package/src/runtime/emitters/turn.ts +0 -155
- package/src/runtime/emitters/ui.ts +0 -57
- package/src/runtime/emitters/watchers.ts +0 -57
- package/src/runtime/emitters/workflows.ts +0 -79
- package/src/runtime/eval/index.ts +0 -48
- package/src/runtime/eval/runner.ts +0 -163
- package/src/runtime/eval/suites.ts +0 -264
- package/src/runtime/events/domain-map.ts +0 -148
- package/src/runtime/events/index.ts +0 -1
- package/src/runtime/events/turn.ts +0 -1
- package/src/runtime/events/workflows.ts +0 -1
- package/src/runtime/forensics/collector.ts +0 -693
- package/src/runtime/forensics/index.ts +0 -23
- package/src/runtime/foundation-clients.ts +0 -78
- package/src/runtime/foundation-services.ts +0 -96
- package/src/runtime/guidance.ts +0 -183
- package/src/runtime/health/effect-handlers.ts +0 -189
- package/src/runtime/health/index.ts +0 -70
- package/src/runtime/health/wiring.ts +0 -115
- package/src/runtime/integration/helpers.ts +0 -640
- package/src/runtime/lifecycle.ts +0 -107
- package/src/runtime/mcp/index.ts +0 -68
- package/src/runtime/mcp/manager.ts +0 -513
- package/src/runtime/network/inbound.ts +0 -131
- package/src/runtime/network/index.ts +0 -30
- package/src/runtime/network/outbound.ts +0 -292
- package/src/runtime/network/shared.ts +0 -82
- package/src/runtime/operator-client.ts +0 -235
- package/src/runtime/ops/control-plane.ts +0 -363
- package/src/runtime/ops/index.ts +0 -122
- package/src/runtime/ops/playbooks/index.ts +0 -10
- package/src/runtime/ops/playbooks/session-unrecoverable.ts +0 -196
- package/src/runtime/ops/playbooks/stuck-turn.ts +0 -197
- package/src/runtime/ops/runtime-context.ts +0 -100
- package/src/runtime/ops-api.ts +0 -27
- package/src/runtime/orchestration/spawn-policy.ts +0 -83
- package/src/runtime/peer-client.ts +0 -404
- package/src/runtime/perf/index.ts +0 -57
- package/src/runtime/perf/slo-collector.ts +0 -375
- package/src/runtime/permissions/index.ts +0 -190
- package/src/runtime/permissions/policy-runtime.ts +0 -1
- package/src/runtime/permissions/preflight.ts +0 -101
- package/src/runtime/permissions/rule-suggestions.ts +0 -36
- package/src/runtime/plugins/hot-reload.ts +0 -221
- package/src/runtime/plugins/index.ts +0 -84
- package/src/runtime/plugins/lifecycle.ts +0 -95
- package/src/runtime/plugins/manager.ts +0 -474
- package/src/runtime/plugins/manifest.ts +0 -167
- package/src/runtime/plugins/quarantine.ts +0 -202
- package/src/runtime/plugins/trust.ts +0 -291
- package/src/runtime/plugins/types.ts +0 -205
- package/src/runtime/provider-accounts/registry.ts +0 -326
- package/src/runtime/remote/distributed-runtime-contract-schemas.ts +0 -386
- package/src/runtime/remote/index.ts +0 -488
- package/src/runtime/remote/runner-registry.ts +0 -438
- package/src/runtime/remote/supervisor.ts +0 -70
- package/src/runtime/runtime-hook-api.ts +0 -5
- package/src/runtime/runtime-knowledge-api.ts +0 -14
- package/src/runtime/runtime-mcp-api.ts +0 -5
- package/src/runtime/runtime-ops-api.ts +0 -86
- package/src/runtime/runtime-provider-api.ts +0 -18
- package/src/runtime/session-maintenance.ts +0 -188
- package/src/runtime/session-persistence.ts +0 -288
- package/src/runtime/session-return-context.ts +0 -195
- package/src/runtime/settings/control-plane-store.ts +0 -258
- package/src/runtime/settings/control-plane.ts +0 -599
- package/src/runtime/shell-command-extensions.ts +0 -54
- package/src/runtime/shell-command-ops.ts +0 -207
- package/src/runtime/shell-command-platform.ts +0 -47
- package/src/runtime/shell-command-services.ts +0 -143
- package/src/runtime/shell-command-workspace.ts +0 -31
- package/src/runtime/tasks/adapters/acp-adapter.ts +0 -211
- package/src/runtime/tasks/adapters/agent-adapter.ts +0 -208
- package/src/runtime/tasks/adapters/index.ts +0 -16
- package/src/runtime/tasks/adapters/process-adapter.ts +0 -214
- package/src/runtime/tasks/adapters/scheduler-adapter.ts +0 -193
- package/src/runtime/tasks/index.ts +0 -68
- package/src/runtime/tasks/manager.ts +0 -415
- package/src/runtime/telemetry/api-helpers.ts +0 -517
- package/src/runtime/telemetry/api.ts +0 -768
- package/src/runtime/telemetry/index.ts +0 -178
- package/src/runtime/telemetry/instrumentation/domain-bridge-agent-session.ts +0 -440
- package/src/runtime/telemetry/instrumentation/domain-bridge-plugin-mcp.ts +0 -200
- package/src/runtime/telemetry/instrumentation/domain-bridge-shared.ts +0 -18
- package/src/runtime/telemetry/instrumentation/domain-bridge-transport-task.ts +0 -204
- package/src/runtime/telemetry/instrumentation/domain-bridge.ts +0 -125
- package/src/runtime/telemetry/instrumentation/index.ts +0 -67
- package/src/runtime/tools/context.ts +0 -114
- package/src/runtime/tools/index.ts +0 -46
- package/src/runtime/tools/phased-executor.ts +0 -448
- package/src/runtime/tools/phases/budget.ts +0 -130
- package/src/runtime/tools/phases/execute.ts +0 -69
- package/src/runtime/tools/phases/index.ts +0 -13
- package/src/runtime/tools/phases/map-output.ts +0 -98
- package/src/runtime/tools/phases/permission.ts +0 -133
- package/src/runtime/tools/phases/posthook.ts +0 -57
- package/src/runtime/tools/phases/prehook.ts +0 -68
- package/src/runtime/tools/phases/validate.ts +0 -53
- package/src/runtime/transports/direct.ts +0 -73
- package/src/runtime/transports/http-helpers.ts +0 -218
- package/src/runtime/transports/http-types.ts +0 -364
- package/src/runtime/transports/http.ts +0 -629
- package/src/runtime/transports/realtime.ts +0 -50
- package/src/runtime/transports/remote-events.ts +0 -16
- package/src/runtime/transports/shared.ts +0 -39
- package/src/runtime/transports/ui-runtime-events.ts +0 -35
- package/src/runtime/ui-read-models-core.ts +0 -95
- package/src/runtime/ui-read-models-operations.ts +0 -203
- package/src/runtime/worktree/registry.ts +0 -252
- package/src/sessions/manager.ts +0 -14
- package/src/state/file-watcher.ts +0 -294
- package/src/state/index.ts +0 -56
- package/src/state/knowledge-injection.ts +0 -214
- package/src/state/memory-embedding-http.ts +0 -642
- package/src/state/memory-embeddings.ts +0 -312
- package/src/state/memory-ingest.ts +0 -132
- package/src/state/memory-registry.ts +0 -111
- package/src/state/memory-store-helpers.ts +0 -160
- package/src/state/memory-store.ts +0 -728
- package/src/state/memory-vector-store.ts +0 -418
- package/src/templates/manager.ts +0 -187
- package/src/tools/agent/index.ts +0 -610
- package/src/tools/agent/manager.ts +0 -476
- package/src/tools/analyze/git-modes.ts +0 -380
- package/src/tools/analyze/index.ts +0 -128
- package/src/tools/channel/agent-tools.ts +0 -16
- package/src/tools/channel/index.ts +0 -268
- package/src/tools/control/index.ts +0 -90
- package/src/tools/edit/core.ts +0 -619
- package/src/tools/edit/index.ts +0 -4
- package/src/tools/edit/phased.ts +0 -33
- package/src/tools/fetch/index.ts +0 -3
- package/src/tools/fetch/phased.ts +0 -34
- package/src/tools/fetch/runtime.ts +0 -499
- package/src/tools/mcp/index.ts +0 -190
- package/src/tools/remote-trigger/index.ts +0 -130
- package/src/tools/shared/auto-heal.ts +0 -282
- package/src/tools/state/index.ts +0 -688
- package/src/tools/web-search/index.ts +0 -38
- package/src/tools/write/index.ts +0 -604
- package/src/tools/write/phased.ts +0 -41
- package/src/types/generated/foundation-client-types.ts +0 -22
- package/src/watchers/index.ts +0 -11
- package/src/watchers/registry.ts +0 -517
- package/src/web-search/index.ts +0 -26
- package/src/web-search/provider-registry.ts +0 -64
- package/src/web-search/providers/brave.ts +0 -100
- package/src/web-search/providers/duckduckgo.ts +0 -270
- package/src/web-search/providers/exa.ts +0 -77
- package/src/web-search/providers/firecrawl.ts +0 -90
- package/src/web-search/providers/perplexity.ts +0 -86
- package/src/web-search/providers/searxng.ts +0 -88
- package/src/web-search/providers/shared.ts +0 -249
- package/src/web-search/providers/tavily.ts +0 -90
- package/src/web-search/service.ts +0 -142
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import type { Tool } from '@pellux/goodvibes-sdk/platform/types/tools';
|
|
2
|
-
import type { WebSearchService } from '@pellux/goodvibes-sdk/platform/web-search/index';
|
|
3
|
-
import { WEB_SEARCH_TOOL_SCHEMA } from '@pellux/goodvibes-sdk/platform/tools/web-search/schema';
|
|
4
|
-
|
|
5
|
-
export function createWebSearchTool(service: WebSearchService): Tool {
|
|
6
|
-
return {
|
|
7
|
-
definition: {
|
|
8
|
-
name: 'web_search',
|
|
9
|
-
description:
|
|
10
|
-
'Search the web through a provider-backed search layer.'
|
|
11
|
-
+ ' Returns normalized ranked results, optional instant-answer data, and optional fetched evidence.',
|
|
12
|
-
parameters: WEB_SEARCH_TOOL_SCHEMA as unknown as Record<string, unknown>,
|
|
13
|
-
sideEffects: ['network'],
|
|
14
|
-
concurrency: 'parallel',
|
|
15
|
-
supportsProgress: true,
|
|
16
|
-
supportsStreamingOutput: true,
|
|
17
|
-
},
|
|
18
|
-
|
|
19
|
-
async execute(args: Record<string, unknown>) {
|
|
20
|
-
const query = typeof args.query === 'string' ? args.query.trim() : '';
|
|
21
|
-
if (!query) return { success: false, error: 'Missing query' };
|
|
22
|
-
const output = await service.search({
|
|
23
|
-
query,
|
|
24
|
-
...(typeof args.providerId === 'string' ? { providerId: args.providerId } : {}),
|
|
25
|
-
...(typeof args.maxResults === 'number' ? { maxResults: args.maxResults } : {}),
|
|
26
|
-
...(typeof args.verbosity === 'string' ? { verbosity: args.verbosity as import('@pellux/goodvibes-sdk/platform/web-search/types').WebSearchVerbosity } : {}),
|
|
27
|
-
...(typeof args.region === 'string' ? { region: args.region } : {}),
|
|
28
|
-
...(typeof args.safeSearch === 'string' ? { safeSearch: args.safeSearch as import('@pellux/goodvibes-sdk/platform/web-search/types').WebSearchSafeSearch } : {}),
|
|
29
|
-
...(typeof args.timeRange === 'string' ? { timeRange: args.timeRange as import('@pellux/goodvibes-sdk/platform/web-search/types').WebSearchTimeRange } : {}),
|
|
30
|
-
...(typeof args.includeInstantAnswer === 'boolean' ? { includeInstantAnswer: args.includeInstantAnswer } : {}),
|
|
31
|
-
...(typeof args.includeEvidence === 'boolean' ? { includeEvidence: args.includeEvidence } : {}),
|
|
32
|
-
...(typeof args.evidenceTopN === 'number' ? { evidenceTopN: args.evidenceTopN } : {}),
|
|
33
|
-
...(typeof args.evidenceExtract === 'string' ? { evidenceExtract: args.evidenceExtract as import('@pellux/goodvibes-sdk/platform/tools/fetch/schema').FetchExtractMode } : {}),
|
|
34
|
-
});
|
|
35
|
-
return { success: true, output: JSON.stringify(output) };
|
|
36
|
-
},
|
|
37
|
-
};
|
|
38
|
-
}
|
package/src/tools/write/index.ts
DELETED
|
@@ -1,604 +0,0 @@
|
|
|
1
|
-
import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync, copyFileSync, unlinkSync, realpathSync } from 'node:fs';
|
|
2
|
-
import { dirname, extname, join, relative, resolve } from 'node:path';
|
|
3
|
-
import { randomBytes } from 'node:crypto';
|
|
4
|
-
import type { Tool, ToolDefinition } from '@pellux/goodvibes-sdk/platform/types/tools';
|
|
5
|
-
import { WRITE_SCHEMA, type WriteInput, type WriteFileInput, type WriteMode } from '@pellux/goodvibes-sdk/platform/tools/write/schema';
|
|
6
|
-
import { runValidators, formatValidatorFailure, type ValidatorName } from '@pellux/goodvibes-sdk/platform/tools/shared/validators';
|
|
7
|
-
import { FileStateCache } from '@pellux/goodvibes-sdk/platform/state/file-cache';
|
|
8
|
-
import { ProjectIndex } from '@pellux/goodvibes-sdk/platform/state/project-index';
|
|
9
|
-
import { FileUndoManager } from '@pellux/goodvibes-sdk/platform/state/file-undo';
|
|
10
|
-
import type { ConfigManager } from '@pellux/goodvibes-sdk/platform/config/manager';
|
|
11
|
-
import type { ToolLLM } from '@pellux/goodvibes-sdk/platform/config/tool-llm';
|
|
12
|
-
import { AutoHealer } from '@pellux/goodvibes-sdk/platform/tools/shared/auto-heal';
|
|
13
|
-
import { isNotebookFile } from '@pellux/goodvibes-sdk/platform/utils/notebook';
|
|
14
|
-
import { logger } from '@pellux/goodvibes-sdk/platform/utils/logger';
|
|
15
|
-
import type { SessionChangeTracker } from '@pellux/goodvibes-sdk/platform/sessions/change-tracker';
|
|
16
|
-
import { summarizeError } from '@pellux/goodvibes-sdk/platform/utils/error-display';
|
|
17
|
-
|
|
18
|
-
// ---------------------------------------------------------------------------
|
|
19
|
-
// Result types
|
|
20
|
-
// ---------------------------------------------------------------------------
|
|
21
|
-
|
|
22
|
-
interface FileWriteResult {
|
|
23
|
-
path: string;
|
|
24
|
-
resolved_path: string;
|
|
25
|
-
bytes_written: number;
|
|
26
|
-
mode_applied: WriteMode;
|
|
27
|
-
backup_path?: string;
|
|
28
|
-
/** true if this was a dry-run entry */
|
|
29
|
-
would_write?: boolean;
|
|
30
|
-
/** decoded content — used internally to avoid double resolveContent call */
|
|
31
|
-
_content?: string;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
interface WriteOutput {
|
|
35
|
-
files_written: number;
|
|
36
|
-
bytes_written: number;
|
|
37
|
-
files?: FileWriteResult[];
|
|
38
|
-
dry_run?: boolean;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
// ---------------------------------------------------------------------------
|
|
42
|
-
// Helpers
|
|
43
|
-
// ---------------------------------------------------------------------------
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Decode content from either the raw string or base64 field.
|
|
47
|
-
* Returns the decoded string content.
|
|
48
|
-
*/
|
|
49
|
-
function resolveContent(fileInput: WriteFileInput): string {
|
|
50
|
-
if (fileInput.content_base64 !== undefined) {
|
|
51
|
-
return Buffer.from(fileInput.content_base64, 'base64').toString('utf-8');
|
|
52
|
-
}
|
|
53
|
-
return fileInput.content ?? '';
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Build a backup destination path inside .goodvibes/.backups/.
|
|
58
|
-
* e.g. src/foo.ts -> <projectRoot>/.goodvibes/.backups/src/foo.ts.1700000000000
|
|
59
|
-
*/
|
|
60
|
-
function buildBackupPath(resolvedPath: string, projectRoot: string): string {
|
|
61
|
-
const rel = relative(projectRoot, resolvedPath);
|
|
62
|
-
return join(projectRoot, '.goodvibes', '.backups', `${rel}.${Date.now()}`);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
function nearestExistingPath(path: string): string {
|
|
66
|
-
let current = path;
|
|
67
|
-
while (!existsSync(current)) {
|
|
68
|
-
const parent = dirname(current);
|
|
69
|
-
if (parent === current) return current;
|
|
70
|
-
current = parent;
|
|
71
|
-
}
|
|
72
|
-
return current;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
function isInsideRoot(root: string, candidate: string): boolean {
|
|
76
|
-
const rel = relative(root, candidate);
|
|
77
|
-
return rel === '' || (!rel.startsWith('..') && !rel.includes('/..') && !rel.startsWith('/'));
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
function resolveAndValidatePath(inputPath: string, projectRoot: string): string {
|
|
81
|
-
const root = realpathSync(resolve(projectRoot));
|
|
82
|
-
const resolved = resolve(root, inputPath);
|
|
83
|
-
const rel = relative(root, resolved);
|
|
84
|
-
if (rel.startsWith('..') || rel.includes('/..')) {
|
|
85
|
-
throw new Error(`Path '${inputPath}' is outside the project root`);
|
|
86
|
-
}
|
|
87
|
-
const existingPath = nearestExistingPath(resolved);
|
|
88
|
-
const realExistingPath = realpathSync(existingPath);
|
|
89
|
-
if (!isInsideRoot(root, realExistingPath)) {
|
|
90
|
-
throw new Error(`Path '${inputPath}' is outside the project root`);
|
|
91
|
-
}
|
|
92
|
-
if (existsSync(resolved)) {
|
|
93
|
-
const realTargetPath = realpathSync(resolved);
|
|
94
|
-
if (!isInsideRoot(root, realTargetPath)) {
|
|
95
|
-
throw new Error(`Path '${inputPath}' is outside the project root`);
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
return resolved;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
/** Module-level constant — avoids re-allocating the Set on every validation call. */
|
|
102
|
-
const VALID_CELL_TYPES = new Set(['code', 'markdown', 'raw']);
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* Validate that a string contains well-formed Jupyter notebook JSON.
|
|
106
|
-
* Checks required top-level fields and per-cell structure.
|
|
107
|
-
* On success, returns the parsed notebook object to avoid a redundant JSON.parse at the call site.
|
|
108
|
-
*/
|
|
109
|
-
function validateNotebookContent(
|
|
110
|
-
content: string,
|
|
111
|
-
): { valid: true; notebook: Record<string, unknown> } | { valid: false; error: string } {
|
|
112
|
-
let parsed: unknown;
|
|
113
|
-
try {
|
|
114
|
-
parsed = JSON.parse(content);
|
|
115
|
-
} catch (err) {
|
|
116
|
-
return { valid: false, error: `Invalid JSON: ${summarizeError(err)}` };
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {
|
|
120
|
-
return { valid: false, error: 'Notebook must be a JSON object' };
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
const nb = parsed as Record<string, unknown>;
|
|
124
|
-
|
|
125
|
-
if (!('nbformat' in nb) || typeof nb['nbformat'] !== 'number') {
|
|
126
|
-
return { valid: false, error: "Notebook must have a numeric 'nbformat' field" };
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
if (!('cells' in nb) || !Array.isArray(nb['cells'])) {
|
|
130
|
-
return { valid: false, error: "Notebook must have a 'cells' array" };
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
for (let i = 0; i < (nb['cells'] as unknown[]).length; i++) {
|
|
134
|
-
const cell = (nb['cells'] as unknown[])[i];
|
|
135
|
-
if (typeof cell !== 'object' || cell === null || Array.isArray(cell)) {
|
|
136
|
-
return { valid: false, error: `Cell ${i} must be an object` };
|
|
137
|
-
}
|
|
138
|
-
const c = cell as Record<string, unknown>;
|
|
139
|
-
|
|
140
|
-
if (!('cell_type' in c) || !VALID_CELL_TYPES.has(c['cell_type'] as string)) {
|
|
141
|
-
return { valid: false, error: `Cell ${i} has missing or invalid 'cell_type' (must be 'code', 'markdown', or 'raw')` };
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
if (!('source' in c) || (typeof c['source'] !== 'string' && !Array.isArray(c['source']))) {
|
|
145
|
-
return { valid: false, error: `Cell ${i} must have a 'source' field (string or array)` };
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
if (c['cell_type'] === 'code') {
|
|
149
|
-
if ('outputs' in c && !Array.isArray(c['outputs'])) {
|
|
150
|
-
return { valid: false, error: `Cell ${i} 'outputs' must be an array` };
|
|
151
|
-
}
|
|
152
|
-
if ('execution_count' in c && c['execution_count'] !== null && typeof c['execution_count'] !== 'number') {
|
|
153
|
-
return { valid: false, error: `Cell ${i} 'execution_count' must be a number or null` };
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
return { valid: true, notebook: nb };
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
/**
|
|
162
|
-
* Atomically write content to a file.
|
|
163
|
-
* Writes to a temp file first, then renames to the target path.
|
|
164
|
-
*/
|
|
165
|
-
function atomicWrite(targetPath: string, content: string, encoding: BufferEncoding = 'utf-8'): void {
|
|
166
|
-
const rand = randomBytes(4).toString('hex');
|
|
167
|
-
const tmpPath = `${targetPath}.tmp.${rand}`;
|
|
168
|
-
try {
|
|
169
|
-
writeFileSync(tmpPath, content, { encoding });
|
|
170
|
-
renameSync(tmpPath, targetPath);
|
|
171
|
-
} catch (err) {
|
|
172
|
-
// Clean up temp file if rename failed
|
|
173
|
-
try {
|
|
174
|
-
unlinkSync(tmpPath);
|
|
175
|
-
} catch {
|
|
176
|
-
// Ignore cleanup errors
|
|
177
|
-
}
|
|
178
|
-
throw err;
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
// ---------------------------------------------------------------------------
|
|
183
|
-
// Core write logic
|
|
184
|
-
// ---------------------------------------------------------------------------
|
|
185
|
-
|
|
186
|
-
/**
|
|
187
|
-
* Process a single file write entry.
|
|
188
|
-
* Returns null if successful (mutates results array) or a string error message.
|
|
189
|
-
*/
|
|
190
|
-
function processSingleWrite(
|
|
191
|
-
fileInput: WriteFileInput,
|
|
192
|
-
projectRoot: string,
|
|
193
|
-
dryRun: boolean,
|
|
194
|
-
): { ok: true; result: FileWriteResult } | { ok: false; error: string } {
|
|
195
|
-
// Resolve and validate path
|
|
196
|
-
let resolvedPath: string;
|
|
197
|
-
try {
|
|
198
|
-
resolvedPath = resolveAndValidatePath(fileInput.path, projectRoot);
|
|
199
|
-
} catch (err) {
|
|
200
|
-
return { ok: false, error: `Path error for '${fileInput.path}': ${summarizeError(err)}` };
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
const mode: WriteMode = fileInput.mode ?? 'fail_if_exists';
|
|
204
|
-
|
|
205
|
-
// Validate encoding
|
|
206
|
-
const VALID_ENCODINGS = new Set(['utf-8', 'utf8', 'ascii', 'latin1', 'base64', 'hex', 'binary']);
|
|
207
|
-
if (fileInput.encoding && !VALID_ENCODINGS.has(fileInput.encoding)) {
|
|
208
|
-
return {
|
|
209
|
-
ok: false,
|
|
210
|
-
error: `Invalid encoding: '${fileInput.encoding}'. Valid: ${[...VALID_ENCODINGS].join(', ')}`,
|
|
211
|
-
};
|
|
212
|
-
}
|
|
213
|
-
const encoding: BufferEncoding = (fileInput.encoding as BufferEncoding) ?? 'utf-8';
|
|
214
|
-
|
|
215
|
-
// Validate base64 input
|
|
216
|
-
if (fileInput.content_base64 !== undefined) {
|
|
217
|
-
const b64Regex = /^[A-Za-z0-9+/]*={0,2}$/;
|
|
218
|
-
if (!b64Regex.test(fileInput.content_base64.replace(/\s/g, ''))) {
|
|
219
|
-
return {
|
|
220
|
-
ok: false,
|
|
221
|
-
error: `Invalid base64 content for '${fileInput.path}': content is not valid base64.`,
|
|
222
|
-
};
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
let content = resolveContent(fileInput);
|
|
227
|
-
|
|
228
|
-
// Notebook validation and normalization
|
|
229
|
-
if (isNotebookFile(resolvedPath)) {
|
|
230
|
-
const validation = validateNotebookContent(content);
|
|
231
|
-
if (!validation.valid) {
|
|
232
|
-
return {
|
|
233
|
-
ok: false,
|
|
234
|
-
error: `Invalid notebook content for '${fileInput.path}': ${validation.error}`,
|
|
235
|
-
};
|
|
236
|
-
}
|
|
237
|
-
// Re-serialize with consistent formatting (1-space indent, trailing newline).
|
|
238
|
-
// Use the already-parsed notebook from the validator to avoid a redundant JSON.parse.
|
|
239
|
-
content = JSON.stringify(validation.notebook, null, 1) + '\n';
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
const byteSize = Buffer.byteLength(content, encoding);
|
|
243
|
-
|
|
244
|
-
// Check existence
|
|
245
|
-
const alreadyExists = existsSync(resolvedPath);
|
|
246
|
-
|
|
247
|
-
if (alreadyExists && mode === 'fail_if_exists') {
|
|
248
|
-
return {
|
|
249
|
-
ok: false,
|
|
250
|
-
error: `File already exists: '${fileInput.path}'. Use mode 'overwrite' or 'backup' to replace it.`,
|
|
251
|
-
};
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
const result: FileWriteResult = {
|
|
255
|
-
path: fileInput.path,
|
|
256
|
-
resolved_path: resolvedPath,
|
|
257
|
-
bytes_written: byteSize,
|
|
258
|
-
mode_applied: mode,
|
|
259
|
-
_content: content,
|
|
260
|
-
};
|
|
261
|
-
|
|
262
|
-
if (dryRun) {
|
|
263
|
-
result.would_write = true;
|
|
264
|
-
if (alreadyExists && mode === 'backup') {
|
|
265
|
-
result.backup_path = buildBackupPath(resolvedPath, projectRoot);
|
|
266
|
-
}
|
|
267
|
-
return { ok: true, result };
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
// Backup if needed
|
|
271
|
-
if (alreadyExists && mode === 'backup') {
|
|
272
|
-
const backupPath = buildBackupPath(resolvedPath, projectRoot);
|
|
273
|
-
try {
|
|
274
|
-
mkdirSync(dirname(backupPath), { recursive: true });
|
|
275
|
-
copyFileSync(resolvedPath, backupPath);
|
|
276
|
-
result.backup_path = backupPath;
|
|
277
|
-
} catch (err) {
|
|
278
|
-
return {
|
|
279
|
-
ok: false,
|
|
280
|
-
error: `Backup failed for '${fileInput.path}': ${summarizeError(err)}`,
|
|
281
|
-
};
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
// Auto-create parent directories
|
|
286
|
-
try {
|
|
287
|
-
mkdirSync(dirname(resolvedPath), { recursive: true });
|
|
288
|
-
} catch (err) {
|
|
289
|
-
return {
|
|
290
|
-
ok: false,
|
|
291
|
-
error: `Failed to create parent directories for '${fileInput.path}': ${summarizeError(err)}`,
|
|
292
|
-
};
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
// Atomic write
|
|
296
|
-
try {
|
|
297
|
-
atomicWrite(resolvedPath, content, encoding);
|
|
298
|
-
} catch (err) {
|
|
299
|
-
return {
|
|
300
|
-
ok: false,
|
|
301
|
-
error: `Write failed for '${fileInput.path}': ${summarizeError(err)}`,
|
|
302
|
-
};
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
return { ok: true, result };
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
// ---------------------------------------------------------------------------
|
|
309
|
-
// Format output
|
|
310
|
-
// ---------------------------------------------------------------------------
|
|
311
|
-
|
|
312
|
-
function formatOutput(
|
|
313
|
-
results: FileWriteResult[],
|
|
314
|
-
errors: string[],
|
|
315
|
-
verbosity: string,
|
|
316
|
-
dryRun: boolean,
|
|
317
|
-
): WriteOutput {
|
|
318
|
-
const totalBytes = results.reduce((acc, r) => acc + r.bytes_written, 0);
|
|
319
|
-
const base: WriteOutput = {
|
|
320
|
-
files_written: results.length,
|
|
321
|
-
bytes_written: totalBytes,
|
|
322
|
-
};
|
|
323
|
-
|
|
324
|
-
if (dryRun) {
|
|
325
|
-
base.dry_run = true;
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
if (verbosity === 'count_only') {
|
|
329
|
-
return base;
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
if (verbosity === 'minimal') {
|
|
333
|
-
base.files = results.map(({ _content: _, ...r }) => ({
|
|
334
|
-
path: r.path,
|
|
335
|
-
resolved_path: r.resolved_path,
|
|
336
|
-
bytes_written: r.bytes_written,
|
|
337
|
-
mode_applied: r.mode_applied,
|
|
338
|
-
...(r.backup_path ? { backup_path: r.backup_path } : {}),
|
|
339
|
-
...(r.would_write ? { would_write: r.would_write } : {}),
|
|
340
|
-
}));
|
|
341
|
-
return base;
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
// standard and verbose both include full results (strip internal _content field)
|
|
345
|
-
base.files = results.map(({ _content: _, ...r }) => r);
|
|
346
|
-
return base;
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
// ---------------------------------------------------------------------------
|
|
350
|
-
// Tool factory
|
|
351
|
-
// ---------------------------------------------------------------------------
|
|
352
|
-
|
|
353
|
-
export function createWriteTool(options?: {
|
|
354
|
-
projectRoot: string;
|
|
355
|
-
fileCache?: FileStateCache;
|
|
356
|
-
projectIndex?: ProjectIndex;
|
|
357
|
-
fileUndoManager?: FileUndoManager;
|
|
358
|
-
configManager?: Pick<ConfigManager, 'get'>;
|
|
359
|
-
toolLLM?: Pick<ToolLLM, 'chat'>;
|
|
360
|
-
changeTracker?: Pick<SessionChangeTracker, 'recordChange'>;
|
|
361
|
-
}): Tool {
|
|
362
|
-
if (typeof options?.projectRoot !== 'string' || options.projectRoot.trim().length === 0) {
|
|
363
|
-
throw new Error('createWriteTool requires projectRoot');
|
|
364
|
-
}
|
|
365
|
-
const projectRoot = options.projectRoot;
|
|
366
|
-
const definition: ToolDefinition = {
|
|
367
|
-
name: 'write',
|
|
368
|
-
description:
|
|
369
|
-
'Write one or more files to disk. Supports batch writes, automatic parent directory creation, ' +
|
|
370
|
-
'and three overwrite modes: fail_if_exists (default), overwrite, backup. ' +
|
|
371
|
-
'Use content_base64 for content containing special characters.',
|
|
372
|
-
parameters: WRITE_SCHEMA as Record<string, unknown>,
|
|
373
|
-
sideEffects: ['write_fs'],
|
|
374
|
-
concurrency: 'serial',
|
|
375
|
-
supportsProgress: true,
|
|
376
|
-
};
|
|
377
|
-
|
|
378
|
-
return {
|
|
379
|
-
definition,
|
|
380
|
-
async execute(args: Record<string, unknown>) {
|
|
381
|
-
// Runtime validation before cast: ensure required fields exist.
|
|
382
|
-
if (!args['files'] || !Array.isArray(args['files']) || (args['files'] as unknown[]).length === 0) {
|
|
383
|
-
return {
|
|
384
|
-
success: false,
|
|
385
|
-
error: "Invalid input: 'files' must be a non-empty array.",
|
|
386
|
-
};
|
|
387
|
-
}
|
|
388
|
-
const input = args as unknown as WriteInput;
|
|
389
|
-
const verbosity = input.verbosity ?? 'count_only';
|
|
390
|
-
const dryRun = input.dry_run ?? false;
|
|
391
|
-
|
|
392
|
-
const results: FileWriteResult[] = [];
|
|
393
|
-
const errors: string[] = [];
|
|
394
|
-
const transactionMode = input.transaction?.mode ?? 'none';
|
|
395
|
-
// Snapshots for atomic rollback: map from resolvedPath -> original content (null = new file)
|
|
396
|
-
const snapshots = new Map<string, string | null>();
|
|
397
|
-
|
|
398
|
-
for (const fileInput of input.files) {
|
|
399
|
-
if (!fileInput.path || typeof fileInput.path !== 'string') {
|
|
400
|
-
errors.push(`Invalid file entry: missing or invalid 'path' field.`);
|
|
401
|
-
continue;
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
// Capture before-content for undo and atomic transaction snapshots BEFORE the write happens
|
|
405
|
-
let beforeContent: string | null = null;
|
|
406
|
-
if (!dryRun && fileInput.path) {
|
|
407
|
-
let resolvedForUndo: string | undefined;
|
|
408
|
-
try {
|
|
409
|
-
resolvedForUndo = resolveAndValidatePath(fileInput.path, projectRoot);
|
|
410
|
-
} catch {
|
|
411
|
-
resolvedForUndo = undefined;
|
|
412
|
-
}
|
|
413
|
-
if (resolvedForUndo && existsSync(resolvedForUndo)) {
|
|
414
|
-
try {
|
|
415
|
-
beforeContent = readFileSync(resolvedForUndo, 'utf-8');
|
|
416
|
-
} catch {
|
|
417
|
-
beforeContent = null;
|
|
418
|
-
}
|
|
419
|
-
}
|
|
420
|
-
// Store snapshot for atomic transaction rollback
|
|
421
|
-
if (transactionMode === 'atomic' && resolvedForUndo && !snapshots.has(resolvedForUndo)) {
|
|
422
|
-
snapshots.set(resolvedForUndo, beforeContent);
|
|
423
|
-
}
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
const outcome = processSingleWrite(fileInput, projectRoot, dryRun);
|
|
427
|
-
|
|
428
|
-
if (!outcome.ok) {
|
|
429
|
-
errors.push(outcome.error);
|
|
430
|
-
logger.debug('write tool: file write failed', { path: fileInput.path, error: outcome.error });
|
|
431
|
-
|
|
432
|
-
// Atomic transaction: rollback all successfully written files
|
|
433
|
-
if (transactionMode === 'atomic' && results.length > 0) {
|
|
434
|
-
const rolledBack: string[] = [];
|
|
435
|
-
for (const written of results) {
|
|
436
|
-
try {
|
|
437
|
-
const snapshot = snapshots.get(written.resolved_path);
|
|
438
|
-
if (snapshot === null || snapshot === undefined) {
|
|
439
|
-
// File was new - delete it
|
|
440
|
-
unlinkSync(written.resolved_path);
|
|
441
|
-
} else {
|
|
442
|
-
// File existed before - restore original
|
|
443
|
-
atomicWrite(written.resolved_path, snapshot);
|
|
444
|
-
}
|
|
445
|
-
rolledBack.push(written.path);
|
|
446
|
-
} catch (rollbackErr) {
|
|
447
|
-
logger.debug('write tool: atomic rollback failed (non-fatal)', {
|
|
448
|
-
path: written.resolved_path,
|
|
449
|
-
error: String(rollbackErr),
|
|
450
|
-
});
|
|
451
|
-
}
|
|
452
|
-
}
|
|
453
|
-
const failMsg = `Atomic transaction failed on '${fileInput.path}': ${outcome.error}. Rolled back ${rolledBack.length} file(s): ${rolledBack.join(', ')}`;
|
|
454
|
-
return {
|
|
455
|
-
success: false,
|
|
456
|
-
error: failMsg,
|
|
457
|
-
};
|
|
458
|
-
}
|
|
459
|
-
|
|
460
|
-
continue;
|
|
461
|
-
}
|
|
462
|
-
|
|
463
|
-
results.push(outcome.result);
|
|
464
|
-
|
|
465
|
-
// State integration — only for real writes, not dry runs
|
|
466
|
-
if (!dryRun) {
|
|
467
|
-
let content = outcome.result._content ?? '';
|
|
468
|
-
|
|
469
|
-
// Auto-heal: if file is JS/TS and auto-heal is enabled, run syntax check
|
|
470
|
-
if (options?.configManager?.get('tools.autoHeal')) {
|
|
471
|
-
const ext = extname(outcome.result.resolved_path).toLowerCase();
|
|
472
|
-
const isJsTs = ['.js', '.ts', '.jsx', '.tsx', '.mjs', '.cjs'].includes(ext);
|
|
473
|
-
if (isJsTs) {
|
|
474
|
-
try {
|
|
475
|
-
const loader = (ext === '.mjs' || ext === '.cjs') ? 'js' : ext.slice(1) as 'ts' | 'tsx' | 'js' | 'jsx';
|
|
476
|
-
const transpiler = new Bun.Transpiler({ loader });
|
|
477
|
-
transpiler.transformSync(content);
|
|
478
|
-
} catch (syntaxErr) {
|
|
479
|
-
const syntaxErrors = [String(syntaxErr)];
|
|
480
|
-
const healResult = options.toolLLM && options.configManager
|
|
481
|
-
? await new AutoHealer(options.configManager, options.toolLLM).heal(outcome.result.resolved_path, content, syntaxErrors)
|
|
482
|
-
: { healed: false, content };
|
|
483
|
-
if (healResult.healed) {
|
|
484
|
-
logger.debug('write tool: auto-heal succeeded', {
|
|
485
|
-
path: outcome.result.resolved_path,
|
|
486
|
-
method: healResult.method,
|
|
487
|
-
});
|
|
488
|
-
content = healResult.content;
|
|
489
|
-
// Rewrite file with healed content
|
|
490
|
-
try {
|
|
491
|
-
atomicWrite(outcome.result.resolved_path, content);
|
|
492
|
-
} catch (writeErr) {
|
|
493
|
-
logger.debug('write tool: auto-heal rewrite failed (non-fatal)', {
|
|
494
|
-
path: outcome.result.resolved_path,
|
|
495
|
-
error: String(writeErr),
|
|
496
|
-
});
|
|
497
|
-
}
|
|
498
|
-
}
|
|
499
|
-
}
|
|
500
|
-
}
|
|
501
|
-
}
|
|
502
|
-
|
|
503
|
-
const byteSize = Buffer.byteLength(content, 'utf-8');
|
|
504
|
-
const tokenEstimate = Math.ceil(byteSize / 4);
|
|
505
|
-
|
|
506
|
-
if (options?.fileCache) {
|
|
507
|
-
try {
|
|
508
|
-
options.fileCache.update(outcome.result.resolved_path, content, { tool: 'write' });
|
|
509
|
-
} catch (err) {
|
|
510
|
-
logger.debug('write tool: fileCache.update failed (non-fatal)', {
|
|
511
|
-
path: outcome.result.resolved_path,
|
|
512
|
-
error: summarizeError(err),
|
|
513
|
-
});
|
|
514
|
-
}
|
|
515
|
-
}
|
|
516
|
-
|
|
517
|
-
if (options?.projectIndex) {
|
|
518
|
-
try {
|
|
519
|
-
options.projectIndex.upsertFile(outcome.result.resolved_path, tokenEstimate);
|
|
520
|
-
} catch (err) {
|
|
521
|
-
logger.debug('write tool: projectIndex.upsertFile failed (non-fatal)', {
|
|
522
|
-
path: outcome.result.resolved_path,
|
|
523
|
-
error: summarizeError(err),
|
|
524
|
-
});
|
|
525
|
-
}
|
|
526
|
-
}
|
|
527
|
-
|
|
528
|
-
// Snapshot for /undo file support
|
|
529
|
-
if (options?.fileUndoManager) {
|
|
530
|
-
try {
|
|
531
|
-
options.fileUndoManager.snapshot({
|
|
532
|
-
path: outcome.result.resolved_path,
|
|
533
|
-
beforeContent,
|
|
534
|
-
afterContent: content,
|
|
535
|
-
tool: 'write',
|
|
536
|
-
});
|
|
537
|
-
} catch (err) {
|
|
538
|
-
logger.debug('write tool: fileUndoManager.snapshot failed (non-fatal)', {
|
|
539
|
-
path: outcome.result.resolved_path,
|
|
540
|
-
error: summarizeError(err),
|
|
541
|
-
});
|
|
542
|
-
}
|
|
543
|
-
}
|
|
544
|
-
|
|
545
|
-
logger.debug('write tool: wrote file', {
|
|
546
|
-
path: outcome.result.resolved_path,
|
|
547
|
-
bytes: byteSize,
|
|
548
|
-
mode: outcome.result.mode_applied,
|
|
549
|
-
});
|
|
550
|
-
// Track for /diff session change view
|
|
551
|
-
options?.changeTracker?.recordChange(outcome.result.resolved_path);
|
|
552
|
-
}
|
|
553
|
-
}
|
|
554
|
-
|
|
555
|
-
if (errors.length > 0 && results.length === 0) {
|
|
556
|
-
return {
|
|
557
|
-
success: false,
|
|
558
|
-
error: errors.join('\n'),
|
|
559
|
-
};
|
|
560
|
-
}
|
|
561
|
-
|
|
562
|
-
const output = formatOutput(results, errors, verbosity, dryRun);
|
|
563
|
-
|
|
564
|
-
// Attach partial errors to output if some succeeded and some failed
|
|
565
|
-
const finalOutput: Record<string, unknown> = { ...output };
|
|
566
|
-
if (errors.length > 0) {
|
|
567
|
-
finalOutput.errors = errors;
|
|
568
|
-
}
|
|
569
|
-
|
|
570
|
-
// Post-write validation — run after all files are written, even if partial errors occurred
|
|
571
|
-
if (!dryRun && results.length > 0 && input.validate?.after && input.validate.after.length > 0) {
|
|
572
|
-
const validatorNames = input.validate.after as ValidatorName[];
|
|
573
|
-
logger.debug('write tool: running post-write validators', { validators: validatorNames });
|
|
574
|
-
try {
|
|
575
|
-
const failures = await runValidators(validatorNames, projectRoot);
|
|
576
|
-
if (failures.length > 0) {
|
|
577
|
-
finalOutput.validation_failures = failures.map((f) => ({
|
|
578
|
-
validator: f.validator,
|
|
579
|
-
passed: false,
|
|
580
|
-
exit_code: f.exitCode,
|
|
581
|
-
stdout: f.stdout.trim(),
|
|
582
|
-
stderr: f.stderr.trim(),
|
|
583
|
-
message: formatValidatorFailure(f),
|
|
584
|
-
}));
|
|
585
|
-
logger.debug('write tool: post-write validators failed', {
|
|
586
|
-
count: failures.length,
|
|
587
|
-
validators: failures.map((f) => f.validator),
|
|
588
|
-
});
|
|
589
|
-
} else {
|
|
590
|
-
finalOutput.validation_passed = true;
|
|
591
|
-
}
|
|
592
|
-
} catch (validationErr) {
|
|
593
|
-
logger.debug('write tool: validator execution error (non-fatal)', { error: String(validationErr) });
|
|
594
|
-
finalOutput.validation_error = String(validationErr);
|
|
595
|
-
}
|
|
596
|
-
}
|
|
597
|
-
|
|
598
|
-
return {
|
|
599
|
-
success: errors.length === 0,
|
|
600
|
-
output: JSON.stringify(finalOutput),
|
|
601
|
-
};
|
|
602
|
-
},
|
|
603
|
-
};
|
|
604
|
-
}
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Phased wrapper for the write tool.
|
|
3
|
-
*
|
|
4
|
-
* Delegates entirely to the existing `createWriteTool` implementation and adds
|
|
5
|
-
* the PhasedTool metadata required by the phased executor.
|
|
6
|
-
*/
|
|
7
|
-
import { asPhasedTool } from '@pellux/goodvibes-sdk/platform/runtime/tools/adapter';
|
|
8
|
-
import { createWriteTool } from '@pellux/goodvibes-sdk/platform/tools/write/index';
|
|
9
|
-
import type { FileStateCache } from '@pellux/goodvibes-sdk/platform/state/file-cache';
|
|
10
|
-
import type { ProjectIndex } from '@pellux/goodvibes-sdk/platform/state/project-index';
|
|
11
|
-
import type { FileUndoManager } from '@pellux/goodvibes-sdk/platform/state/file-undo';
|
|
12
|
-
|
|
13
|
-
// ---------------------------------------------------------------------------
|
|
14
|
-
// Deps type
|
|
15
|
-
// ---------------------------------------------------------------------------
|
|
16
|
-
|
|
17
|
-
/** Dependencies forwarded to the underlying write tool factory. */
|
|
18
|
-
export interface WriteDeps {
|
|
19
|
-
fileCache?: FileStateCache;
|
|
20
|
-
projectIndex?: ProjectIndex;
|
|
21
|
-
fileUndoManager?: FileUndoManager;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
// ---------------------------------------------------------------------------
|
|
25
|
-
// Factory
|
|
26
|
-
// ---------------------------------------------------------------------------
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Create a phased write tool.
|
|
30
|
-
*
|
|
31
|
-
* Category : `write` — routes to the mutating-filesystem concurrency pool.
|
|
32
|
-
* Cancellable: `false` — write operations are not safe to interrupt mid-flight;
|
|
33
|
-
* a partial write leaves files in an inconsistent state.
|
|
34
|
-
*
|
|
35
|
-
* @param deps - Optional dependency overrides (shared cache instances, undo manager).
|
|
36
|
-
* @returns A PhasedTool that delegates execution to `createWriteTool`.
|
|
37
|
-
*/
|
|
38
|
-
export function createPhasedWriteTool(projectRoot: string, deps: WriteDeps = {}) {
|
|
39
|
-
const inner = createWriteTool({ ...deps, projectRoot });
|
|
40
|
-
return asPhasedTool(inner, { category: 'write', cancellable: false });
|
|
41
|
-
}
|