@caupulican/pi-adaptative 0.80.103 → 0.81.0
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 +120 -0
- package/dist/cli/session-picker.d.ts +1 -1
- package/dist/cli/session-picker.d.ts.map +1 -1
- package/dist/cli/session-picker.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +7 -1
- package/dist/cli.js.map +1 -1
- package/dist/core/agent-session-runtime.d.ts +1 -1
- package/dist/core/agent-session-runtime.d.ts.map +1 -1
- package/dist/core/agent-session-runtime.js +6 -6
- package/dist/core/agent-session-runtime.js.map +1 -1
- package/dist/core/agent-session-services.d.ts +1 -1
- package/dist/core/agent-session-services.d.ts.map +1 -1
- package/dist/core/agent-session-services.js.map +1 -1
- package/dist/core/agent-session.d.ts +152 -512
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +635 -4590
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/autonomy/session-lane-record.d.ts +1 -1
- package/dist/core/autonomy/session-lane-record.d.ts.map +1 -1
- package/dist/core/autonomy/session-lane-record.js.map +1 -1
- package/dist/core/autonomy/status.d.ts +1 -0
- package/dist/core/autonomy/status.d.ts.map +1 -1
- package/dist/core/autonomy/status.js +1 -0
- package/dist/core/autonomy/status.js.map +1 -1
- package/dist/core/autonomy-telemetry.d.ts +80 -0
- package/dist/core/autonomy-telemetry.d.ts.map +1 -0
- package/dist/core/autonomy-telemetry.js +266 -0
- package/dist/core/autonomy-telemetry.js.map +1 -0
- package/dist/core/background-lane-controller.d.ts +186 -0
- package/dist/core/background-lane-controller.d.ts.map +1 -0
- package/dist/core/background-lane-controller.js +691 -0
- package/dist/core/background-lane-controller.js.map +1 -0
- package/dist/core/bash-execution-controller.d.ts +51 -0
- package/dist/core/bash-execution-controller.d.ts.map +1 -0
- package/dist/core/bash-execution-controller.js +96 -0
- package/dist/core/bash-execution-controller.js.map +1 -0
- package/dist/core/bash-executor.d.ts.map +1 -1
- package/dist/core/bash-executor.js +9 -2
- package/dist/core/bash-executor.js.map +1 -1
- package/dist/core/compaction-support.d.ts +56 -0
- package/dist/core/compaction-support.d.ts.map +1 -0
- package/dist/core/compaction-support.js +99 -0
- package/dist/core/compaction-support.js.map +1 -0
- package/dist/core/context/artifact-retrieval.d.ts +1 -1
- package/dist/core/context/artifact-retrieval.d.ts.map +1 -1
- package/dist/core/context/artifact-retrieval.js +1 -1
- package/dist/core/context/artifact-retrieval.js.map +1 -1
- package/dist/core/context/context-composition.d.ts.map +1 -1
- package/dist/core/context/context-composition.js +1 -1
- package/dist/core/context/context-composition.js.map +1 -1
- package/dist/core/context/tool-output-packer.d.ts +1 -1
- package/dist/core/context/tool-output-packer.d.ts.map +1 -1
- package/dist/core/context/tool-output-packer.js +1 -1
- package/dist/core/context/tool-output-packer.js.map +1 -1
- package/dist/core/context-gc.d.ts.map +1 -1
- package/dist/core/context-gc.js +1 -1
- package/dist/core/context-gc.js.map +1 -1
- package/dist/core/context-pipeline.d.ts +223 -0
- package/dist/core/context-pipeline.d.ts.map +1 -0
- package/dist/core/context-pipeline.js +594 -0
- package/dist/core/context-pipeline.js.map +1 -0
- package/dist/core/cost/daily-usage.d.ts +1 -1
- package/dist/core/cost/daily-usage.d.ts.map +1 -1
- package/dist/core/cost/daily-usage.js +1 -1
- package/dist/core/cost/daily-usage.js.map +1 -1
- package/dist/core/cost/session-usage.d.ts +1 -1
- package/dist/core/cost/session-usage.d.ts.map +1 -1
- package/dist/core/cost/session-usage.js +1 -1
- package/dist/core/cost/session-usage.js.map +1 -1
- package/dist/core/delegation/session-worker-result.d.ts +1 -1
- package/dist/core/delegation/session-worker-result.d.ts.map +1 -1
- package/dist/core/delegation/session-worker-result.js.map +1 -1
- package/dist/core/exec.d.ts +2 -0
- package/dist/core/exec.d.ts.map +1 -1
- package/dist/core/exec.js +15 -9
- package/dist/core/exec.js.map +1 -1
- package/dist/core/export-html/index.d.ts +1 -1
- package/dist/core/export-html/index.d.ts.map +1 -1
- package/dist/core/export-html/index.js +2 -2
- package/dist/core/export-html/index.js.map +1 -1
- package/dist/core/extensions/builtin.d.ts.map +1 -1
- package/dist/core/extensions/builtin.js +2 -2
- package/dist/core/extensions/builtin.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +1 -1
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +2 -4
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/goal-loop-controller.d.ts +24 -0
- package/dist/core/goal-loop-controller.d.ts.map +1 -0
- package/dist/core/goal-loop-controller.js +83 -0
- package/dist/core/goal-loop-controller.js.map +1 -0
- package/dist/core/goals/goal-runtime-snapshot.d.ts +1 -1
- package/dist/core/goals/goal-runtime-snapshot.d.ts.map +1 -1
- package/dist/core/goals/goal-runtime-snapshot.js.map +1 -1
- package/dist/core/goals/session-goal-state.d.ts +1 -1
- package/dist/core/goals/session-goal-state.d.ts.map +1 -1
- package/dist/core/goals/session-goal-state.js.map +1 -1
- package/dist/core/index.d.ts +1 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/learning/learning-audit.d.ts +1 -1
- package/dist/core/learning/learning-audit.d.ts.map +1 -1
- package/dist/core/learning/learning-audit.js.map +1 -1
- package/dist/core/learning/session-learning-decision.d.ts +1 -1
- package/dist/core/learning/session-learning-decision.d.ts.map +1 -1
- package/dist/core/learning/session-learning-decision.js.map +1 -1
- package/dist/core/local-runtime-controller.d.ts +99 -0
- package/dist/core/local-runtime-controller.d.ts.map +1 -0
- package/dist/core/local-runtime-controller.js +214 -0
- package/dist/core/local-runtime-controller.js.map +1 -0
- package/dist/core/memory/providers/transcript-recall.d.ts.map +1 -1
- package/dist/core/memory/providers/transcript-recall.js +1 -1
- package/dist/core/memory/providers/transcript-recall.js.map +1 -1
- package/dist/core/memory-controller.d.ts +139 -0
- package/dist/core/memory-controller.d.ts.map +1 -0
- package/dist/core/memory-controller.js +323 -0
- package/dist/core/memory-controller.js.map +1 -0
- package/dist/core/model-router/status.d.ts +1 -1
- package/dist/core/model-router/status.d.ts.map +1 -1
- package/dist/core/model-router/status.js.map +1 -1
- package/dist/core/model-router-controller.d.ts +140 -0
- package/dist/core/model-router-controller.d.ts.map +1 -0
- package/dist/core/model-router-controller.js +623 -0
- package/dist/core/model-router-controller.js.map +1 -0
- package/dist/core/model-selection-controller.d.ts +95 -0
- package/dist/core/model-selection-controller.d.ts.map +1 -0
- package/dist/core/model-selection-controller.js +252 -0
- package/dist/core/model-selection-controller.js.map +1 -0
- package/dist/core/models/model-ref.d.ts +13 -0
- package/dist/core/models/model-ref.d.ts.map +1 -1
- package/dist/core/models/model-ref.js +22 -0
- package/dist/core/models/model-ref.js.map +1 -1
- package/dist/core/profile-filter-controller.d.ts +77 -0
- package/dist/core/profile-filter-controller.d.ts.map +1 -0
- package/dist/core/profile-filter-controller.js +159 -0
- package/dist/core/profile-filter-controller.js.map +1 -0
- package/dist/core/reflection-controller.d.ts +111 -0
- package/dist/core/reflection-controller.d.ts.map +1 -0
- package/dist/core/reflection-controller.js +412 -0
- package/dist/core/reflection-controller.js.map +1 -0
- package/dist/core/research/model-fitness.d.ts +12 -0
- package/dist/core/research/model-fitness.d.ts.map +1 -1
- package/dist/core/research/model-fitness.js +21 -0
- package/dist/core/research/model-fitness.js.map +1 -1
- package/dist/core/research/session-evidence-bundle.d.ts +1 -1
- package/dist/core/research/session-evidence-bundle.d.ts.map +1 -1
- package/dist/core/research/session-evidence-bundle.js.map +1 -1
- package/dist/core/runtime-builder.d.ts +222 -0
- package/dist/core/runtime-builder.d.ts.map +1 -0
- package/dist/core/runtime-builder.js +640 -0
- package/dist/core/runtime-builder.js.map +1 -0
- package/dist/core/sdk.d.ts +2 -2
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +3 -4
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-analytics.d.ts +96 -0
- package/dist/core/session-analytics.d.ts.map +1 -0
- package/dist/core/session-analytics.js +331 -0
- package/dist/core/session-analytics.js.map +1 -0
- package/dist/core/session-manager-factory.d.ts +18 -0
- package/dist/core/session-manager-factory.d.ts.map +1 -0
- package/dist/core/session-manager-factory.js +32 -0
- package/dist/core/session-manager-factory.js.map +1 -0
- package/dist/core/session-tree-navigator.d.ts +68 -0
- package/dist/core/session-tree-navigator.d.ts.map +1 -0
- package/dist/core/session-tree-navigator.js +217 -0
- package/dist/core/session-tree-navigator.js.map +1 -0
- package/dist/core/system-prompt-builder.d.ts +63 -0
- package/dist/core/system-prompt-builder.d.ts.map +1 -0
- package/dist/core/system-prompt-builder.js +181 -0
- package/dist/core/system-prompt-builder.js.map +1 -0
- package/dist/core/tool-gate-controller.d.ts +36 -0
- package/dist/core/tool-gate-controller.d.ts.map +1 -0
- package/dist/core/tool-gate-controller.js +94 -0
- package/dist/core/tool-gate-controller.js.map +1 -0
- package/dist/core/tools/artifact-retrieve.d.ts.map +1 -1
- package/dist/core/tools/artifact-retrieve.js +1 -1
- package/dist/core/tools/artifact-retrieve.js.map +1 -1
- package/dist/core/tools/bash.d.ts +4 -2
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +49 -7
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/file-mutation-queue.d.ts +6 -0
- package/dist/core/tools/file-mutation-queue.d.ts.map +1 -1
- package/dist/core/tools/file-mutation-queue.js +61 -1
- package/dist/core/tools/file-mutation-queue.js.map +1 -1
- package/dist/core/tools/find.d.ts +1 -1
- package/dist/core/tools/find.d.ts.map +1 -1
- package/dist/core/tools/find.js +1 -1
- package/dist/core/tools/find.js.map +1 -1
- package/dist/core/tools/grep.d.ts +1 -1
- package/dist/core/tools/grep.d.ts.map +1 -1
- package/dist/core/tools/grep.js +1 -1
- package/dist/core/tools/grep.js.map +1 -1
- package/dist/core/tools/index.d.ts +1 -1
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js +1 -1
- package/dist/core/tools/index.js.map +1 -1
- package/dist/core/tools/ls.d.ts +1 -1
- package/dist/core/tools/ls.d.ts.map +1 -1
- package/dist/core/tools/ls.js +1 -1
- package/dist/core/tools/ls.js.map +1 -1
- package/dist/core/tools/output-accumulator.d.ts +1 -1
- package/dist/core/tools/output-accumulator.d.ts.map +1 -1
- package/dist/core/tools/output-accumulator.js +1 -1
- package/dist/core/tools/output-accumulator.js.map +1 -1
- package/dist/core/tools/read.d.ts +1 -1
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js +1 -1
- package/dist/core/tools/read.js.map +1 -1
- package/dist/core/tools/render-utils.d.ts.map +1 -1
- package/dist/core/tools/render-utils.js +1 -1
- package/dist/core/tools/render-utils.js.map +1 -1
- package/dist/index.d.ts +2 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -4
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +13 -12
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/auth-dialogs-controller.d.ts +59 -0
- package/dist/modes/interactive/auth-dialogs-controller.d.ts.map +1 -0
- package/dist/modes/interactive/auth-dialogs-controller.js +398 -0
- package/dist/modes/interactive/auth-dialogs-controller.js.map +1 -0
- package/dist/modes/interactive/auto-learn-controller.d.ts +168 -0
- package/dist/modes/interactive/auto-learn-controller.d.ts.map +1 -0
- package/dist/modes/interactive/auto-learn-controller.js +1239 -0
- package/dist/modes/interactive/auto-learn-controller.js.map +1 -0
- package/dist/modes/interactive/autocomplete-provider.d.ts +26 -0
- package/dist/modes/interactive/autocomplete-provider.d.ts.map +1 -0
- package/dist/modes/interactive/autocomplete-provider.js +103 -0
- package/dist/modes/interactive/autocomplete-provider.js.map +1 -0
- package/dist/modes/interactive/autonomy-commands.d.ts +38 -0
- package/dist/modes/interactive/autonomy-commands.d.ts.map +1 -0
- package/dist/modes/interactive/autonomy-commands.js +142 -0
- package/dist/modes/interactive/autonomy-commands.js.map +1 -0
- package/dist/modes/interactive/clipboard-input.d.ts +37 -0
- package/dist/modes/interactive/clipboard-input.d.ts.map +1 -0
- package/dist/modes/interactive/clipboard-input.js +59 -0
- package/dist/modes/interactive/clipboard-input.js.map +1 -0
- package/dist/modes/interactive/compaction-queue.d.ts +30 -0
- package/dist/modes/interactive/compaction-queue.d.ts.map +1 -0
- package/dist/modes/interactive/compaction-queue.js +91 -0
- package/dist/modes/interactive/compaction-queue.js.map +1 -0
- package/dist/modes/interactive/components/bash-execution.d.ts +1 -1
- package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/bash-execution.js +1 -1
- package/dist/modes/interactive/components/bash-execution.js.map +1 -1
- package/dist/modes/interactive/components/branch-summary-message.d.ts +1 -1
- package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.d.ts +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
- package/dist/modes/interactive/components/custom-message.d.ts +1 -1
- package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-message.js.map +1 -1
- package/dist/modes/interactive/components/session-selector-search.d.ts +1 -1
- package/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -1
- package/dist/modes/interactive/components/session-selector-search.js.map +1 -1
- package/dist/modes/interactive/components/session-selector.d.ts +1 -1
- package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/session-selector.js.map +1 -1
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js +2 -2
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/components/tree-selector.d.ts +1 -1
- package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/tree-selector.js.map +1 -1
- package/dist/modes/interactive/config-backup.d.ts +27 -0
- package/dist/modes/interactive/config-backup.d.ts.map +1 -0
- package/dist/modes/interactive/config-backup.js +146 -0
- package/dist/modes/interactive/config-backup.js.map +1 -0
- package/dist/modes/interactive/editor-overlay-host.d.ts +48 -0
- package/dist/modes/interactive/editor-overlay-host.d.ts.map +1 -0
- package/dist/modes/interactive/editor-overlay-host.js +43 -0
- package/dist/modes/interactive/editor-overlay-host.js.map +1 -0
- package/dist/modes/interactive/extension-ui-host.d.ts +165 -0
- package/dist/modes/interactive/extension-ui-host.d.ts.map +1 -0
- package/dist/modes/interactive/extension-ui-host.js +610 -0
- package/dist/modes/interactive/extension-ui-host.js.map +1 -0
- package/dist/modes/interactive/external-editor.d.ts +18 -0
- package/dist/modes/interactive/external-editor.d.ts.map +1 -0
- package/dist/modes/interactive/external-editor.js +107 -0
- package/dist/modes/interactive/external-editor.js.map +1 -0
- package/dist/modes/interactive/history-reload-math.d.ts +24 -0
- package/dist/modes/interactive/history-reload-math.d.ts.map +1 -0
- package/dist/modes/interactive/history-reload-math.js +129 -0
- package/dist/modes/interactive/history-reload-math.js.map +1 -0
- package/dist/modes/interactive/interactive-mode.d.ts +22 -238
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +714 -5910
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/key-handlers.d.ts +46 -0
- package/dist/modes/interactive/key-handlers.d.ts.map +1 -0
- package/dist/modes/interactive/key-handlers.js +80 -0
- package/dist/modes/interactive/key-handlers.js.map +1 -0
- package/dist/modes/interactive/local-model-commands.d.ts +68 -0
- package/dist/modes/interactive/local-model-commands.d.ts.map +1 -0
- package/dist/modes/interactive/local-model-commands.js +288 -0
- package/dist/modes/interactive/local-model-commands.js.map +1 -0
- package/dist/modes/interactive/profile-menu-controller.d.ts +77 -0
- package/dist/modes/interactive/profile-menu-controller.d.ts.map +1 -0
- package/dist/modes/interactive/profile-menu-controller.js +917 -0
- package/dist/modes/interactive/profile-menu-controller.js.map +1 -0
- package/dist/modes/interactive/report-commands.d.ts +46 -0
- package/dist/modes/interactive/report-commands.d.ts.map +1 -0
- package/dist/modes/interactive/report-commands.js +255 -0
- package/dist/modes/interactive/report-commands.js.map +1 -0
- package/dist/modes/interactive/resource-display.d.ts +73 -0
- package/dist/modes/interactive/resource-display.d.ts.map +1 -0
- package/dist/modes/interactive/resource-display.js +278 -0
- package/dist/modes/interactive/resource-display.js.map +1 -0
- package/dist/modes/interactive/resource-shell-commands.d.ts +64 -0
- package/dist/modes/interactive/resource-shell-commands.d.ts.map +1 -0
- package/dist/modes/interactive/resource-shell-commands.js +202 -0
- package/dist/modes/interactive/resource-shell-commands.js.map +1 -0
- package/dist/modes/interactive/session-flow-commands.d.ts +139 -0
- package/dist/modes/interactive/session-flow-commands.d.ts.map +1 -0
- package/dist/modes/interactive/session-flow-commands.js +458 -0
- package/dist/modes/interactive/session-flow-commands.js.map +1 -0
- package/dist/modes/interactive/session-io-commands.d.ts +73 -0
- package/dist/modes/interactive/session-io-commands.d.ts.map +1 -0
- package/dist/modes/interactive/session-io-commands.js +202 -0
- package/dist/modes/interactive/session-io-commands.js.map +1 -0
- package/dist/modes/interactive/settings-selector-flow.d.ts +42 -0
- package/dist/modes/interactive/settings-selector-flow.d.ts.map +1 -0
- package/dist/modes/interactive/settings-selector-flow.js +287 -0
- package/dist/modes/interactive/settings-selector-flow.js.map +1 -0
- package/dist/modes/interactive/signal-lifecycle.d.ts +55 -0
- package/dist/modes/interactive/signal-lifecycle.d.ts.map +1 -0
- package/dist/modes/interactive/signal-lifecycle.js +177 -0
- package/dist/modes/interactive/signal-lifecycle.js.map +1 -0
- package/dist/modes/interactive/startup-checks.d.ts +38 -0
- package/dist/modes/interactive/startup-checks.d.ts.map +1 -0
- package/dist/modes/interactive/startup-checks.js +189 -0
- package/dist/modes/interactive/startup-checks.js.map +1 -0
- package/dist/modes/rpc/rpc-client.d.ts +1 -1
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +1 -1
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/dist/utils/paths.d.ts +2 -14
- package/dist/utils/paths.d.ts.map +1 -1
- package/dist/utils/paths.js +5 -30
- package/dist/utils/paths.js.map +1 -1
- package/dist/utils/process-memory.d.ts +8 -0
- package/dist/utils/process-memory.d.ts.map +1 -0
- package/dist/utils/process-memory.js +11 -0
- package/dist/utils/process-memory.js.map +1 -0
- package/dist/utils/shell.d.ts +0 -9
- package/dist/utils/shell.d.ts.map +1 -1
- package/dist/utils/shell.js +0 -37
- package/dist/utils/shell.js.map +1 -1
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/examples/sdk/11-sessions.ts +8 -8
- package/examples/sdk/13-session-runtime.ts +1 -1
- package/npm-shrinkwrap.json +12 -12
- package/package.json +4 -4
- package/dist/core/compaction/branch-summarization.d.ts +0 -88
- package/dist/core/compaction/branch-summarization.d.ts.map +0 -1
- package/dist/core/compaction/branch-summarization.js +0 -243
- package/dist/core/compaction/branch-summarization.js.map +0 -1
- package/dist/core/compaction/compaction.d.ts +0 -143
- package/dist/core/compaction/compaction.d.ts.map +0 -1
- package/dist/core/compaction/compaction.js +0 -659
- package/dist/core/compaction/compaction.js.map +0 -1
- package/dist/core/compaction/index.d.ts +0 -7
- package/dist/core/compaction/index.d.ts.map +0 -1
- package/dist/core/compaction/index.js +0 -7
- package/dist/core/compaction/index.js.map +0 -1
- package/dist/core/compaction/utils.d.ts +0 -38
- package/dist/core/compaction/utils.d.ts.map +0 -1
- package/dist/core/compaction/utils.js +0 -153
- package/dist/core/compaction/utils.js.map +0 -1
- package/dist/core/message-retention.d.ts +0 -26
- package/dist/core/message-retention.d.ts.map +0 -1
- package/dist/core/message-retention.js +0 -95
- package/dist/core/message-retention.js.map +0 -1
- package/dist/core/messages.d.ts +0 -77
- package/dist/core/messages.d.ts.map +0 -1
- package/dist/core/messages.js +0 -123
- package/dist/core/messages.js.map +0 -1
- package/dist/core/session-manager.d.ts +0 -337
- package/dist/core/session-manager.d.ts.map +0 -1
- package/dist/core/session-manager.js +0 -1328
- package/dist/core/session-manager.js.map +0 -1
- package/dist/core/tools/truncate.d.ts +0 -70
- package/dist/core/tools/truncate.d.ts.map +0 -1
- package/dist/core/tools/truncate.js +0 -215
- package/dist/core/tools/truncate.js.map +0 -1
|
@@ -0,0 +1,917 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resource-profile & external-source menu controller.
|
|
3
|
+
*
|
|
4
|
+
* Extracted verbatim from interactive-mode.ts (god-file decomposition). Owns the /profiles command
|
|
5
|
+
* and the resource-hub menu tree: active-profile selection, profile create/delete/persist, the
|
|
6
|
+
* library (per-profile resource grants) editor, and external-source root management. It holds NO
|
|
7
|
+
* state of its own — every profile/source fact lives in settingsManager / the profile registry /
|
|
8
|
+
* the session resourceLoader — so it takes narrow deps (a live session accessor plus a UI callback
|
|
9
|
+
* surface, including the editor-overlay-backed showSelector) rather than the whole InteractiveMode
|
|
10
|
+
* instance.
|
|
11
|
+
*/
|
|
12
|
+
import * as fs from "node:fs";
|
|
13
|
+
import * as path from "node:path";
|
|
14
|
+
import { getAgentDir } from "../../config.js";
|
|
15
|
+
import { resolveCliModel } from "../../core/model-resolver.js";
|
|
16
|
+
import { resourceProfileSettingsChangedKinds } from "../../core/resource-profile-equality.js";
|
|
17
|
+
import { validateSkillName } from "../../core/skills.js";
|
|
18
|
+
import { allToolNames } from "../../core/tools/index.js";
|
|
19
|
+
import { parseFrontmatter } from "../../utils/frontmatter.js";
|
|
20
|
+
import { ExtensionInputComponent } from "./components/extension-input.js";
|
|
21
|
+
import { ProfileResourceEditorComponent, resolveResourceEditPath, } from "./components/profile-resource-editor.js";
|
|
22
|
+
import { ProfileSelectorComponent } from "./components/profile-selector.js";
|
|
23
|
+
import { SelectSubmenu } from "./components/settings-selector.js";
|
|
24
|
+
import { getAvailableThemesWithPaths } from "./theme/theme.js";
|
|
25
|
+
export class ProfileMenuController {
|
|
26
|
+
deps;
|
|
27
|
+
constructor(deps) {
|
|
28
|
+
this.deps = deps;
|
|
29
|
+
}
|
|
30
|
+
get session() {
|
|
31
|
+
return this.deps.getSession();
|
|
32
|
+
}
|
|
33
|
+
get sessionManager() {
|
|
34
|
+
return this.deps.getSession().sessionManager;
|
|
35
|
+
}
|
|
36
|
+
get settingsManager() {
|
|
37
|
+
return this.deps.getSession().settingsManager;
|
|
38
|
+
}
|
|
39
|
+
get ui() {
|
|
40
|
+
return this.deps.ui;
|
|
41
|
+
}
|
|
42
|
+
async handleResourcesHubAction(action) {
|
|
43
|
+
switch (action) {
|
|
44
|
+
case "nudge-add-source":
|
|
45
|
+
void this.addExternalResourceRootFlow().then(() => {
|
|
46
|
+
void this.ui.showSettingsSelector();
|
|
47
|
+
});
|
|
48
|
+
break;
|
|
49
|
+
case "active-profile":
|
|
50
|
+
void this.openActiveProfileSelector();
|
|
51
|
+
break;
|
|
52
|
+
case "manage-library":
|
|
53
|
+
void this.openLibraryManagerFlow();
|
|
54
|
+
break;
|
|
55
|
+
case "manage-profiles":
|
|
56
|
+
void this.openManageProfilesFlow();
|
|
57
|
+
break;
|
|
58
|
+
case "sources":
|
|
59
|
+
void this.openSourcesManagerFlow();
|
|
60
|
+
break;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
async openActiveProfileSelector() {
|
|
64
|
+
const registry = this.settingsManager.getProfileRegistry();
|
|
65
|
+
const profiles = registry.listProfiles();
|
|
66
|
+
const activeNames = this.settingsManager.getActiveResourceProfileNames();
|
|
67
|
+
const options = [
|
|
68
|
+
{ value: "(none)", label: "(none)", description: "No active profile/situation (all resources enabled)" },
|
|
69
|
+
...profiles.map((p) => ({
|
|
70
|
+
value: p.name,
|
|
71
|
+
label: p.name,
|
|
72
|
+
description: p.description || p.source,
|
|
73
|
+
})),
|
|
74
|
+
];
|
|
75
|
+
this.ui.showSelector((done) => {
|
|
76
|
+
const selector = new SelectSubmenu("Profile / Situation", "Select the active runtime profile/situation for this session. This is session-only unless saved elsewhere.", options, activeNames[0] || "(none)", (value) => {
|
|
77
|
+
done();
|
|
78
|
+
void this.applyProfile(value === "(none)" ? "" : value).then(() => {
|
|
79
|
+
void this.ui.showSettingsSelector();
|
|
80
|
+
});
|
|
81
|
+
}, () => {
|
|
82
|
+
done();
|
|
83
|
+
void this.ui.showSettingsSelector();
|
|
84
|
+
});
|
|
85
|
+
return { component: selector, focus: selector.getSelectList() };
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
async openManageProfilesFlow() {
|
|
89
|
+
const registry = this.settingsManager.getProfileRegistry();
|
|
90
|
+
const profiles = registry.listProfiles();
|
|
91
|
+
const editableProfiles = profiles.map((p) => ({
|
|
92
|
+
value: p.name,
|
|
93
|
+
label: p.name,
|
|
94
|
+
description: p.description || p.source,
|
|
95
|
+
}));
|
|
96
|
+
const options = [
|
|
97
|
+
{
|
|
98
|
+
value: "create",
|
|
99
|
+
label: "+ Create profile / situation...",
|
|
100
|
+
description: "Create a new resource profile/situation definition.",
|
|
101
|
+
},
|
|
102
|
+
];
|
|
103
|
+
if (this.settingsManager.getActiveResourceProfileNames().length > 0) {
|
|
104
|
+
options.push({
|
|
105
|
+
value: "persist",
|
|
106
|
+
label: "Persist active profile / situation to...",
|
|
107
|
+
description: "Save the current active profile/situation selection so it survives restart.",
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
if (editableProfiles.length > 0) {
|
|
111
|
+
options.push({
|
|
112
|
+
value: "delete",
|
|
113
|
+
label: "Delete profile / situation...",
|
|
114
|
+
description: "Remove a profile/situation definition from where it is stored.",
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
this.ui.showSelector((done) => {
|
|
118
|
+
const selector = new SelectSubmenu("Manage Profiles / Situations", "Create, delete, or persist profile/situation definitions.", options, "", (value) => {
|
|
119
|
+
done();
|
|
120
|
+
if (value === "create") {
|
|
121
|
+
void this.createProfileFlow().then(() => {
|
|
122
|
+
void this.ui.showSettingsSelector();
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
else if (value === "persist") {
|
|
126
|
+
void this.openPersistProfileSelector();
|
|
127
|
+
}
|
|
128
|
+
else if (value === "delete") {
|
|
129
|
+
void this.openDeleteProfileSelector();
|
|
130
|
+
}
|
|
131
|
+
}, () => {
|
|
132
|
+
done();
|
|
133
|
+
void this.ui.showSettingsSelector();
|
|
134
|
+
});
|
|
135
|
+
return { component: selector, focus: selector.getSelectList() };
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
async openPersistProfileSelector() {
|
|
139
|
+
const scopeOptions = [
|
|
140
|
+
{ value: "session", label: "session", description: "Runtime only (not written to disk)" },
|
|
141
|
+
{
|
|
142
|
+
value: "directory",
|
|
143
|
+
label: "directory",
|
|
144
|
+
description: "~/.pi/agent/resource-profiles/<hash>/settings.json",
|
|
145
|
+
},
|
|
146
|
+
{ value: "project", label: "project", description: ".pi/settings.json" },
|
|
147
|
+
{ value: "global", label: "global", description: "~/.pi/agent/settings.json" },
|
|
148
|
+
];
|
|
149
|
+
this.ui.showSelector((done) => {
|
|
150
|
+
const selector = new SelectSubmenu("Persist Active Profile / Situation", "Choose where to write the active profile/situation selection.", scopeOptions, "directory", (value) => {
|
|
151
|
+
done();
|
|
152
|
+
this.persistActiveProfile(value);
|
|
153
|
+
void this.ui.showSettingsSelector();
|
|
154
|
+
}, () => {
|
|
155
|
+
done();
|
|
156
|
+
void this.openManageProfilesFlow();
|
|
157
|
+
});
|
|
158
|
+
return { component: selector, focus: selector.getSelectList() };
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
async openDeleteProfileSelector() {
|
|
162
|
+
const registry = this.settingsManager.getProfileRegistry();
|
|
163
|
+
const editableProfiles = registry.listProfiles().map((p) => ({
|
|
164
|
+
value: p.name,
|
|
165
|
+
label: p.name,
|
|
166
|
+
description: p.description || p.source,
|
|
167
|
+
}));
|
|
168
|
+
this.ui.showSelector((done) => {
|
|
169
|
+
const selector = new SelectSubmenu("Delete Profile / Situation", "Pick a profile/situation to delete.", editableProfiles, "", (value) => {
|
|
170
|
+
done();
|
|
171
|
+
this.deleteProfileFromSource(value);
|
|
172
|
+
void this.ui.showSettingsSelector();
|
|
173
|
+
}, () => {
|
|
174
|
+
done();
|
|
175
|
+
void this.openManageProfilesFlow();
|
|
176
|
+
});
|
|
177
|
+
return { component: selector, focus: selector.getSelectList() };
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
async openSourcesManagerFlow() {
|
|
181
|
+
const externalRoots = this.settingsManager.getExternalResourceRoots();
|
|
182
|
+
const trustedRoots = this.settingsManager.getTrustedResourceRoots();
|
|
183
|
+
const options = [
|
|
184
|
+
{
|
|
185
|
+
value: "add",
|
|
186
|
+
label: "+ Add external root...",
|
|
187
|
+
description: "Register a new external directory root (requires trust)",
|
|
188
|
+
},
|
|
189
|
+
];
|
|
190
|
+
for (const r of externalRoots) {
|
|
191
|
+
const isTrusted = trustedRoots.includes(r);
|
|
192
|
+
options.push({
|
|
193
|
+
value: `remove:${r}`,
|
|
194
|
+
label: `Remove: ${r}`,
|
|
195
|
+
description: isTrusted ? "Trusted external root" : "Untrusted external root",
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
this.ui.showSelector((done) => {
|
|
199
|
+
const selector = new SelectSubmenu("Sources", "Manage external resource roots. Adding a root requires trust confirmation.", options, "", (value) => {
|
|
200
|
+
done();
|
|
201
|
+
if (value === "add") {
|
|
202
|
+
void this.addExternalResourceRootFlow().then(() => {
|
|
203
|
+
void this.ui.showSettingsSelector();
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
else if (value.startsWith("remove:")) {
|
|
207
|
+
const root = value.slice("remove:".length);
|
|
208
|
+
void this.removeExternalResourceRootFlow(root).then(() => {
|
|
209
|
+
void this.ui.showSettingsSelector();
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
}, () => {
|
|
213
|
+
done();
|
|
214
|
+
void this.ui.showSettingsSelector();
|
|
215
|
+
});
|
|
216
|
+
return { component: selector, focus: selector.getSelectList() };
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
async openLibraryManagerFlow() {
|
|
220
|
+
const activeNames = this.settingsManager.getActiveResourceProfileNames();
|
|
221
|
+
const activeName = activeNames[0];
|
|
222
|
+
if (!activeName || activeName === "(none)") {
|
|
223
|
+
this.ui.showSelector((done) => {
|
|
224
|
+
const selector = new SelectSubmenu("No Active Profile / Situation", "Select or create a profile/situation to manage the library.", [
|
|
225
|
+
{
|
|
226
|
+
value: "select",
|
|
227
|
+
label: "Select existing profile / situation...",
|
|
228
|
+
description: "Choose an existing profile/situation to activate.",
|
|
229
|
+
},
|
|
230
|
+
{
|
|
231
|
+
value: "create",
|
|
232
|
+
label: "Create new profile / situation...",
|
|
233
|
+
description: "Create a new profile/situation definition.",
|
|
234
|
+
},
|
|
235
|
+
], "select", (value) => {
|
|
236
|
+
done();
|
|
237
|
+
if (value === "create") {
|
|
238
|
+
void this.createProfileAndOpenLibraryFlow();
|
|
239
|
+
}
|
|
240
|
+
else {
|
|
241
|
+
void this.selectProfileAndOpenLibraryFlow();
|
|
242
|
+
}
|
|
243
|
+
}, () => {
|
|
244
|
+
done();
|
|
245
|
+
void this.ui.showSettingsSelector();
|
|
246
|
+
});
|
|
247
|
+
return { component: selector, focus: selector.getSelectList() };
|
|
248
|
+
});
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
const registry = this.settingsManager.getProfileRegistry();
|
|
252
|
+
const profile = registry.getProfile(activeName);
|
|
253
|
+
if (!profile) {
|
|
254
|
+
this.ui.showError(`Active profile/situation "${activeName}" not found in registry.`);
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
const scope = this.scopeForProfileSource(profile.source);
|
|
258
|
+
void this.openLibraryEditorForProfile(profile.name, scope);
|
|
259
|
+
}
|
|
260
|
+
async createProfileAndOpenLibraryFlow() {
|
|
261
|
+
const name = await new Promise((resolve) => {
|
|
262
|
+
this.ui.showSelector((done) => {
|
|
263
|
+
const input = new ExtensionInputComponent("Create Profile / Situation", "Enter profile/situation name", (value) => {
|
|
264
|
+
done();
|
|
265
|
+
resolve(value);
|
|
266
|
+
}, () => {
|
|
267
|
+
done();
|
|
268
|
+
resolve(undefined);
|
|
269
|
+
}, { tui: this.ui.tui });
|
|
270
|
+
return { component: input, focus: input };
|
|
271
|
+
});
|
|
272
|
+
});
|
|
273
|
+
if (name === undefined) {
|
|
274
|
+
void this.openLibraryManagerFlow();
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
const trimmed = name.trim();
|
|
278
|
+
if (!trimmed) {
|
|
279
|
+
this.ui.showWarning("Profile/situation name cannot be empty.");
|
|
280
|
+
void this.openLibraryManagerFlow();
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
283
|
+
try {
|
|
284
|
+
const profileModel = await this.selectProfileModelForCreate();
|
|
285
|
+
if (profileModel === undefined) {
|
|
286
|
+
void this.openLibraryManagerFlow();
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
289
|
+
this.settingsManager.setProfileDefinition(trimmed, {
|
|
290
|
+
name: trimmed,
|
|
291
|
+
model: profileModel ?? undefined,
|
|
292
|
+
resources: {},
|
|
293
|
+
}, "directory");
|
|
294
|
+
await this.applyProfile(trimmed);
|
|
295
|
+
void this.openLibraryEditorForProfile(trimmed, "directory");
|
|
296
|
+
}
|
|
297
|
+
catch (error) {
|
|
298
|
+
this.ui.showError(error instanceof Error ? error.message : String(error));
|
|
299
|
+
void this.openLibraryManagerFlow();
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
async selectProfileAndOpenLibraryFlow() {
|
|
303
|
+
const registry = this.settingsManager.getProfileRegistry();
|
|
304
|
+
const profiles = registry.listProfiles();
|
|
305
|
+
const editableProfiles = profiles.map((p) => ({
|
|
306
|
+
value: p.name,
|
|
307
|
+
label: p.name,
|
|
308
|
+
description: p.description || p.source,
|
|
309
|
+
}));
|
|
310
|
+
if (editableProfiles.length === 0) {
|
|
311
|
+
this.ui.showWarning("No existing profiles/situations to select. Please create one.");
|
|
312
|
+
void this.createProfileAndOpenLibraryFlow();
|
|
313
|
+
return;
|
|
314
|
+
}
|
|
315
|
+
this.ui.showSelector((done) => {
|
|
316
|
+
const selector = new SelectSubmenu("Select Profile / Situation", "Pick a profile/situation to activate and edit.", editableProfiles, "", (value) => {
|
|
317
|
+
done();
|
|
318
|
+
void this.applyProfile(value).then(() => {
|
|
319
|
+
const profile = registry.getProfile(value);
|
|
320
|
+
const scope = this.scopeForProfileSource(profile.source);
|
|
321
|
+
void this.openLibraryEditorForProfile(value, scope);
|
|
322
|
+
});
|
|
323
|
+
}, () => {
|
|
324
|
+
done();
|
|
325
|
+
void this.openLibraryManagerFlow();
|
|
326
|
+
});
|
|
327
|
+
return { component: selector, focus: selector.getSelectList() };
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
async getProfileResourceKinds() {
|
|
331
|
+
const loader = this.session.resourceLoader;
|
|
332
|
+
const base = (p) => p.split(/[\\/]/).pop() ?? p;
|
|
333
|
+
const allDiscoverableExtensions = await loader.getDiscoverableExtensionPaths();
|
|
334
|
+
// Defined BEFORE the skills/prompts arrays below that call it (const = TDZ: defining it
|
|
335
|
+
// later crashes the whole app with a ReferenceError when the library editor opens).
|
|
336
|
+
const getFrontmatterDescription = (filePath) => {
|
|
337
|
+
try {
|
|
338
|
+
const content = fs.readFileSync(filePath, "utf-8");
|
|
339
|
+
const { frontmatter } = parseFrontmatter(content);
|
|
340
|
+
if (typeof frontmatter.description === "string")
|
|
341
|
+
return frontmatter.description;
|
|
342
|
+
}
|
|
343
|
+
catch { }
|
|
344
|
+
return undefined;
|
|
345
|
+
};
|
|
346
|
+
// The editor's universe must be profile-INDEPENDENT (discovery, not loading): the loaded
|
|
347
|
+
// getters are narrowed by the active profile, so building the lists from them makes
|
|
348
|
+
// currently-blocked skills/prompts/context files ungrantable — including expanding the
|
|
349
|
+
// very profile you are running under. Union the loaded (rich metadata) sets with the
|
|
350
|
+
// full pre-filter discovery paths.
|
|
351
|
+
const loadedSkills = loader.getSkills().skills;
|
|
352
|
+
const loadedSkillPaths = new Set(loadedSkills.map((skill) => skill.filePath));
|
|
353
|
+
const skillIdFromPath = (skillPath) => {
|
|
354
|
+
const parts = skillPath.split(/[\\/]/);
|
|
355
|
+
const last = parts.pop() ?? skillPath;
|
|
356
|
+
if (/^skill\.md$/i.test(last))
|
|
357
|
+
return parts.pop() ?? last;
|
|
358
|
+
return last.replace(/\.md$/i, "");
|
|
359
|
+
};
|
|
360
|
+
const skills = [
|
|
361
|
+
...loadedSkills.map((skill) => ({ id: skill.name, path: skill.filePath, description: skill.description })),
|
|
362
|
+
...loader
|
|
363
|
+
.getDiscoverableSkillPaths()
|
|
364
|
+
.filter((skillPath) => !loadedSkillPaths.has(skillPath))
|
|
365
|
+
.map((skillPath) => ({
|
|
366
|
+
id: skillIdFromPath(skillPath),
|
|
367
|
+
path: skillPath,
|
|
368
|
+
description: getFrontmatterDescription(skillPath),
|
|
369
|
+
})),
|
|
370
|
+
];
|
|
371
|
+
const loadedPrompts = loader.getPrompts().prompts;
|
|
372
|
+
const loadedPromptPaths = new Set(loadedPrompts.map((prompt) => prompt.filePath));
|
|
373
|
+
const prompts = [
|
|
374
|
+
...loadedPrompts.map((prompt) => ({
|
|
375
|
+
id: prompt.name,
|
|
376
|
+
path: prompt.filePath,
|
|
377
|
+
description: prompt.description,
|
|
378
|
+
})),
|
|
379
|
+
...loader
|
|
380
|
+
.getDiscoverablePromptPaths()
|
|
381
|
+
.filter((promptPath) => !loadedPromptPaths.has(promptPath))
|
|
382
|
+
.map((promptPath) => ({
|
|
383
|
+
id: (promptPath.split(/[\\/]/).pop() ?? promptPath).replace(/\.md$/i, ""),
|
|
384
|
+
path: promptPath,
|
|
385
|
+
description: getFrontmatterDescription(promptPath),
|
|
386
|
+
})),
|
|
387
|
+
];
|
|
388
|
+
const themes = getAvailableThemesWithPaths();
|
|
389
|
+
const loadedAgentPaths = new Set(loader.getAgentsFiles().agentsFiles.map((file) => file.path));
|
|
390
|
+
const agents = [
|
|
391
|
+
...loader.getAgentsFiles().agentsFiles.map((file) => ({ path: file.path })),
|
|
392
|
+
...loader
|
|
393
|
+
.getDiscoverableAgentsFilePaths()
|
|
394
|
+
.filter((agentPath) => !loadedAgentPaths.has(agentPath))
|
|
395
|
+
.map((agentPath) => ({ path: agentPath })),
|
|
396
|
+
];
|
|
397
|
+
const getAgentDescription = (filePath) => {
|
|
398
|
+
try {
|
|
399
|
+
const content = fs.readFileSync(filePath, "utf-8");
|
|
400
|
+
const { frontmatter } = parseFrontmatter(content);
|
|
401
|
+
if (typeof frontmatter.description === "string") {
|
|
402
|
+
return frontmatter.description;
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
catch { }
|
|
406
|
+
return undefined;
|
|
407
|
+
};
|
|
408
|
+
const getExtensionDescription = (filePath) => {
|
|
409
|
+
try {
|
|
410
|
+
let dir = filePath;
|
|
411
|
+
if (fs.existsSync(filePath) && !fs.statSync(filePath).isDirectory()) {
|
|
412
|
+
dir = path.dirname(filePath);
|
|
413
|
+
}
|
|
414
|
+
const pkgPath = path.join(dir, "package.json");
|
|
415
|
+
if (fs.existsSync(pkgPath)) {
|
|
416
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
|
|
417
|
+
if (typeof pkg.description === "string") {
|
|
418
|
+
return pkg.description;
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
catch { }
|
|
423
|
+
return undefined;
|
|
424
|
+
};
|
|
425
|
+
return [
|
|
426
|
+
{
|
|
427
|
+
kind: "tools",
|
|
428
|
+
label: "Tools",
|
|
429
|
+
// Built-ins plus every currently registered tool (extension tools included), so
|
|
430
|
+
// an extension tool can be granted by name without hand-editing settings JSON.
|
|
431
|
+
items: [...new Set([...allToolNames, ...this.session.getAllTools().map((tool) => tool.name)])].map((name) => ({ id: name })),
|
|
432
|
+
},
|
|
433
|
+
{
|
|
434
|
+
kind: "skills",
|
|
435
|
+
label: "Skills",
|
|
436
|
+
items: skills,
|
|
437
|
+
},
|
|
438
|
+
{
|
|
439
|
+
kind: "extensions",
|
|
440
|
+
label: "Extensions",
|
|
441
|
+
items: allDiscoverableExtensions.map((e) => ({
|
|
442
|
+
id: base(e),
|
|
443
|
+
path: e,
|
|
444
|
+
description: getExtensionDescription(e),
|
|
445
|
+
})),
|
|
446
|
+
},
|
|
447
|
+
{
|
|
448
|
+
kind: "agents",
|
|
449
|
+
label: "Agents",
|
|
450
|
+
items: agents.map((f) => ({
|
|
451
|
+
id: base(f.path),
|
|
452
|
+
path: f.path,
|
|
453
|
+
description: getAgentDescription(f.path),
|
|
454
|
+
})),
|
|
455
|
+
},
|
|
456
|
+
{
|
|
457
|
+
kind: "prompts",
|
|
458
|
+
label: "Prompts",
|
|
459
|
+
items: prompts,
|
|
460
|
+
},
|
|
461
|
+
{
|
|
462
|
+
kind: "themes",
|
|
463
|
+
label: "Themes",
|
|
464
|
+
items: themes.map((t) => ({
|
|
465
|
+
id: t.name,
|
|
466
|
+
path: t.path,
|
|
467
|
+
})),
|
|
468
|
+
},
|
|
469
|
+
];
|
|
470
|
+
}
|
|
471
|
+
async openLibraryEditorForProfile(profileName, initialScope) {
|
|
472
|
+
const currentScope = initialScope;
|
|
473
|
+
const registry = this.settingsManager.getProfileRegistry();
|
|
474
|
+
const profile = registry.getProfile(profileName);
|
|
475
|
+
if (!profile) {
|
|
476
|
+
this.ui.showError(`Profile not found: ${profileName}`);
|
|
477
|
+
return;
|
|
478
|
+
}
|
|
479
|
+
const kinds = await this.getProfileResourceKinds();
|
|
480
|
+
const originalResources = profile.resources;
|
|
481
|
+
const isActiveProfile = this.settingsManager.getActiveResourceProfileNames().includes(profile.name);
|
|
482
|
+
this.ui.showSelector((done) => {
|
|
483
|
+
const editor = new ProfileResourceEditorComponent({
|
|
484
|
+
profileName: profile.name,
|
|
485
|
+
profileScope: currentScope,
|
|
486
|
+
initialResources: profile.resources,
|
|
487
|
+
kinds,
|
|
488
|
+
cwd: this.sessionManager.getCwd(),
|
|
489
|
+
agentDir: getAgentDir(),
|
|
490
|
+
externalResourceRoots: this.settingsManager.getExternalResourceRoots(),
|
|
491
|
+
onSave: (resources) => {
|
|
492
|
+
done();
|
|
493
|
+
try {
|
|
494
|
+
this.settingsManager.setProfileDefinition(profileName, {
|
|
495
|
+
name: profileName,
|
|
496
|
+
description: profile.description,
|
|
497
|
+
model: profile.model,
|
|
498
|
+
thinking: profile.thinking,
|
|
499
|
+
resources,
|
|
500
|
+
}, currentScope);
|
|
501
|
+
this.ui.showStatus(`Saved profile "${profileName}" to ${currentScope}.`);
|
|
502
|
+
if (isActiveProfile) {
|
|
503
|
+
const changedKinds = resourceProfileSettingsChangedKinds(originalResources, resources);
|
|
504
|
+
if (changedKinds.size === 1 && changedKinds.has("extensions")) {
|
|
505
|
+
void this.ui.reconcileExtensionsAndRefreshUI(profileName);
|
|
506
|
+
}
|
|
507
|
+
else if (changedKinds.size > 0) {
|
|
508
|
+
void this.refreshAfterProfileMutation(profileName);
|
|
509
|
+
}
|
|
510
|
+
else {
|
|
511
|
+
this.ui.requestRender();
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
catch (error) {
|
|
516
|
+
this.ui.showError(error instanceof Error ? error.message : String(error));
|
|
517
|
+
}
|
|
518
|
+
},
|
|
519
|
+
onCancel: () => {
|
|
520
|
+
done();
|
|
521
|
+
void this.openLibraryManagerFlow();
|
|
522
|
+
},
|
|
523
|
+
onScopeChange: () => {
|
|
524
|
+
done();
|
|
525
|
+
void this.promptScopeChangeForProfile(profileName, currentScope);
|
|
526
|
+
},
|
|
527
|
+
onEdit: async (id, pathValue, kind) => {
|
|
528
|
+
done();
|
|
529
|
+
const resolvedEditPath = resolveResourceEditPath(id, pathValue, kind);
|
|
530
|
+
if (!resolvedEditPath) {
|
|
531
|
+
this.ui.showWarning(`Resource "${id}" of kind "${kind}" has no editable file path.`);
|
|
532
|
+
void this.openLibraryEditorForProfile(profileName, currentScope);
|
|
533
|
+
return;
|
|
534
|
+
}
|
|
535
|
+
if (!fs.existsSync(resolvedEditPath)) {
|
|
536
|
+
this.ui.showError(`Resolved path for "${id}" does not exist: ${resolvedEditPath}`);
|
|
537
|
+
void this.openLibraryEditorForProfile(profileName, currentScope);
|
|
538
|
+
return;
|
|
539
|
+
}
|
|
540
|
+
await this.ui.openEditorForPath(resolvedEditPath);
|
|
541
|
+
await this.ui.handleReloadCommand();
|
|
542
|
+
void this.openLibraryEditorForProfile(profileName, currentScope);
|
|
543
|
+
},
|
|
544
|
+
});
|
|
545
|
+
return { component: editor, focus: editor };
|
|
546
|
+
});
|
|
547
|
+
}
|
|
548
|
+
async promptScopeChangeForProfile(profileName, currentScope) {
|
|
549
|
+
const scopeOptions = [
|
|
550
|
+
{ value: "session", label: "session", description: "Runtime only (not written to disk)" },
|
|
551
|
+
{
|
|
552
|
+
value: "directory",
|
|
553
|
+
label: "directory",
|
|
554
|
+
description: "~/.pi/agent/resource-profiles/<hash>/settings.json",
|
|
555
|
+
},
|
|
556
|
+
{ value: "project", label: "project", description: ".pi/settings.json" },
|
|
557
|
+
{ value: "global", label: "global", description: "~/.pi/agent/settings.json" },
|
|
558
|
+
];
|
|
559
|
+
this.ui.showSelector((done) => {
|
|
560
|
+
const selector = new SelectSubmenu("Change Profile / Situation Scope", `Select new scope for profile/situation "${profileName}".`, scopeOptions, currentScope, (value) => {
|
|
561
|
+
done();
|
|
562
|
+
void this.openLibraryEditorForProfile(profileName, value);
|
|
563
|
+
}, () => {
|
|
564
|
+
done();
|
|
565
|
+
void this.openLibraryEditorForProfile(profileName, currentScope);
|
|
566
|
+
});
|
|
567
|
+
return { component: selector, focus: selector.getSelectList() };
|
|
568
|
+
});
|
|
569
|
+
}
|
|
570
|
+
async handleProfilesCommand(profileName) {
|
|
571
|
+
if (profileName) {
|
|
572
|
+
await this.applyProfile(profileName);
|
|
573
|
+
return;
|
|
574
|
+
}
|
|
575
|
+
const registry = this.settingsManager.getProfileRegistry();
|
|
576
|
+
const profiles = registry.listProfiles();
|
|
577
|
+
if (profiles.length === 0) {
|
|
578
|
+
this.ui.showWarning("No profiles found. Add resourceProfiles to settings or JSON files under ~/.pi/agent/profiles/.");
|
|
579
|
+
return;
|
|
580
|
+
}
|
|
581
|
+
this.ui.showSelector((done) => {
|
|
582
|
+
const selector = new ProfileSelectorComponent(profiles, this.settingsManager.getActiveResourceProfileNames(), (profile) => {
|
|
583
|
+
done();
|
|
584
|
+
void this.applyProfile(profile);
|
|
585
|
+
}, () => {
|
|
586
|
+
done();
|
|
587
|
+
this.ui.requestRender();
|
|
588
|
+
});
|
|
589
|
+
return { component: selector, focus: selector.getSelectList() };
|
|
590
|
+
});
|
|
591
|
+
}
|
|
592
|
+
async applyProfile(profileName) {
|
|
593
|
+
const normalizedName = profileName.trim();
|
|
594
|
+
const normalizedLower = normalizedName.toLowerCase();
|
|
595
|
+
if (normalizedName.length === 0 || normalizedLower === "none" || normalizedLower === "(none)") {
|
|
596
|
+
try {
|
|
597
|
+
this.settingsManager.setRuntimeResourceProfiles([]);
|
|
598
|
+
// Clearing must also survive restarts (otherwise the old global selection returns).
|
|
599
|
+
this.settingsManager.setActiveProfile(undefined, "global");
|
|
600
|
+
this.session.sessionManager.appendCustomEntry("pi.activeResourceProfiles", {
|
|
601
|
+
profiles: [],
|
|
602
|
+
});
|
|
603
|
+
await this.ui.handleReloadCommand();
|
|
604
|
+
const activeProfileName = this.settingsManager.getActiveResourceProfileNames()[0] ?? "(none)";
|
|
605
|
+
this.ui.footerDataProvider.setExtensionStatus("profile", activeProfileName);
|
|
606
|
+
this.ui.invalidateFooter();
|
|
607
|
+
this.ui.updateEditorBorderColor();
|
|
608
|
+
this.ui.showStatus(`Profile: ${activeProfileName}`);
|
|
609
|
+
}
|
|
610
|
+
catch (error) {
|
|
611
|
+
this.ui.showError(error instanceof Error ? error.message : String(error));
|
|
612
|
+
}
|
|
613
|
+
return;
|
|
614
|
+
}
|
|
615
|
+
const registry = this.settingsManager.getProfileRegistry();
|
|
616
|
+
const profile = normalizedName.startsWith("./") || normalizedName.startsWith("../")
|
|
617
|
+
? registry.resolveProfileRef(normalizedName, this.sessionManager.getCwd())
|
|
618
|
+
: registry.getProfile(normalizedName);
|
|
619
|
+
if (!profile) {
|
|
620
|
+
this.ui.showError(`Profile not found: ${profileName}`);
|
|
621
|
+
return;
|
|
622
|
+
}
|
|
623
|
+
try {
|
|
624
|
+
let appliedModel;
|
|
625
|
+
if (profile.model) {
|
|
626
|
+
this.session.modelRegistry.refresh();
|
|
627
|
+
const resolved = resolveCliModel({ cliModel: profile.model, modelRegistry: this.session.modelRegistry });
|
|
628
|
+
if (resolved.error) {
|
|
629
|
+
this.ui.showError(resolved.error);
|
|
630
|
+
return;
|
|
631
|
+
}
|
|
632
|
+
if (resolved.warning) {
|
|
633
|
+
this.ui.showWarning(resolved.warning);
|
|
634
|
+
}
|
|
635
|
+
if (resolved.model) {
|
|
636
|
+
await this.session.setModel(resolved.model, { persistSettings: false });
|
|
637
|
+
appliedModel = resolved.model;
|
|
638
|
+
}
|
|
639
|
+
if (resolved.thinkingLevel && !profile.thinking) {
|
|
640
|
+
this.session.setThinkingLevel(resolved.thinkingLevel, { persistSettings: false });
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
if (profile.thinking) {
|
|
644
|
+
this.session.setThinkingLevel(profile.thinking, { persistSettings: false });
|
|
645
|
+
}
|
|
646
|
+
this.settingsManager.setRuntimeResourceProfiles([profile.name]);
|
|
647
|
+
// Selection must survive pi restarts: persist globally (like model/theme selections).
|
|
648
|
+
// Runtime + session-entry alone made every /profile choice evaporate on exit.
|
|
649
|
+
this.settingsManager.setActiveProfile(profile.name, "global");
|
|
650
|
+
this.session.sessionManager.appendCustomEntry("pi.activeResourceProfiles", {
|
|
651
|
+
profiles: [profile.name],
|
|
652
|
+
});
|
|
653
|
+
await this.ui.handleReloadCommand();
|
|
654
|
+
this.ui.footerDataProvider.setExtensionStatus("profile", profile.name);
|
|
655
|
+
this.ui.invalidateFooter();
|
|
656
|
+
this.ui.updateEditorBorderColor();
|
|
657
|
+
this.ui.showStatus(`Profile: ${profile.name}`);
|
|
658
|
+
if (appliedModel) {
|
|
659
|
+
void this.ui.maybeWarnAboutAnthropicSubscriptionAuth(appliedModel);
|
|
660
|
+
this.ui.checkDaxnutsEasterEgg(appliedModel);
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
catch (error) {
|
|
664
|
+
this.ui.showError(error instanceof Error ? error.message : String(error));
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
/** Map where a profile currently lives to the scope we should write it back to. */
|
|
668
|
+
scopeForProfileSource(source) {
|
|
669
|
+
switch (source) {
|
|
670
|
+
case "profile-file":
|
|
671
|
+
return "reusable-file";
|
|
672
|
+
case "directory-overlay":
|
|
673
|
+
case "embedded":
|
|
674
|
+
return "directory";
|
|
675
|
+
case "inline":
|
|
676
|
+
return "session";
|
|
677
|
+
default:
|
|
678
|
+
return "global"; // "settings"
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
async refreshAfterProfileMutation(profileName) {
|
|
682
|
+
if (this.settingsManager.getActiveResourceProfileNames().includes(profileName)) {
|
|
683
|
+
await this.ui.handleReloadCommand();
|
|
684
|
+
const active = this.settingsManager.getActiveResourceProfileNames()[0] ?? "(none)";
|
|
685
|
+
this.ui.footerDataProvider.setExtensionStatus("profile", active);
|
|
686
|
+
this.ui.invalidateFooter();
|
|
687
|
+
this.ui.updateEditorBorderColor();
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
async createProfileFlow() {
|
|
691
|
+
const name = await new Promise((resolve) => {
|
|
692
|
+
this.ui.showSelector((done) => {
|
|
693
|
+
const input = new ExtensionInputComponent("Create Profile / Situation", "Enter profile/situation name", (value) => {
|
|
694
|
+
done();
|
|
695
|
+
resolve(value);
|
|
696
|
+
}, () => {
|
|
697
|
+
done();
|
|
698
|
+
resolve(undefined);
|
|
699
|
+
}, { tui: this.ui.tui });
|
|
700
|
+
return { component: input, focus: input };
|
|
701
|
+
});
|
|
702
|
+
});
|
|
703
|
+
if (name === undefined) {
|
|
704
|
+
this.ui.requestRender();
|
|
705
|
+
return;
|
|
706
|
+
}
|
|
707
|
+
const trimmed = name.trim();
|
|
708
|
+
if (!trimmed) {
|
|
709
|
+
this.ui.showError("Profile/situation name cannot be empty");
|
|
710
|
+
return this.createProfileFlow();
|
|
711
|
+
}
|
|
712
|
+
// Validate name rules using validateSkillName
|
|
713
|
+
const errors = validateSkillName(trimmed);
|
|
714
|
+
if (errors.length > 0) {
|
|
715
|
+
this.ui.showError(`Invalid profile/situation name: ${errors.join(", ")}`);
|
|
716
|
+
return this.createProfileFlow();
|
|
717
|
+
}
|
|
718
|
+
// Collision check
|
|
719
|
+
const existing = this.settingsManager.getProfileRegistry().getProfile(trimmed);
|
|
720
|
+
if (existing) {
|
|
721
|
+
this.ui.showError(`Profile/situation "${trimmed}" already exists`);
|
|
722
|
+
return this.createProfileFlow();
|
|
723
|
+
}
|
|
724
|
+
const profileModel = await this.selectProfileModelForCreate();
|
|
725
|
+
if (profileModel === undefined) {
|
|
726
|
+
this.ui.requestRender();
|
|
727
|
+
return;
|
|
728
|
+
}
|
|
729
|
+
// Open the resource editor on the NEW profile
|
|
730
|
+
void this.openNewProfileEditor(trimmed, profileModel ?? undefined);
|
|
731
|
+
}
|
|
732
|
+
async selectProfileModelForCreate() {
|
|
733
|
+
const modelOptions = [
|
|
734
|
+
{
|
|
735
|
+
value: "(none)",
|
|
736
|
+
label: "(none)",
|
|
737
|
+
description: "Do not pin a foreground profile model; use the session/default model",
|
|
738
|
+
},
|
|
739
|
+
...this.ui.getAutoLearnModelOptions(),
|
|
740
|
+
];
|
|
741
|
+
return await new Promise((resolve) => {
|
|
742
|
+
this.ui.showSelector((done) => {
|
|
743
|
+
const selector = new SelectSubmenu("Profile Model", "Pick the foreground model for this profile from authenticated/configured providers.", modelOptions, "(none)", (value) => {
|
|
744
|
+
done();
|
|
745
|
+
resolve(value === "(none)" ? null : value);
|
|
746
|
+
}, () => {
|
|
747
|
+
done();
|
|
748
|
+
resolve(undefined);
|
|
749
|
+
});
|
|
750
|
+
return { component: selector, focus: selector.getSelectList() };
|
|
751
|
+
});
|
|
752
|
+
});
|
|
753
|
+
}
|
|
754
|
+
async openNewProfileEditor(profileName, profileModel) {
|
|
755
|
+
const scope = "reusable-file";
|
|
756
|
+
const kinds = await this.getProfileResourceKinds();
|
|
757
|
+
this.ui.showSelector((done) => {
|
|
758
|
+
const editor = new ProfileResourceEditorComponent({
|
|
759
|
+
profileName,
|
|
760
|
+
profileScope: scope,
|
|
761
|
+
initialResources: {},
|
|
762
|
+
kinds,
|
|
763
|
+
cwd: this.sessionManager.getCwd(),
|
|
764
|
+
agentDir: getAgentDir(),
|
|
765
|
+
externalResourceRoots: this.settingsManager.getExternalResourceRoots(),
|
|
766
|
+
onSave: (resources) => {
|
|
767
|
+
done();
|
|
768
|
+
try {
|
|
769
|
+
this.settingsManager.setProfileDefinition(profileName, {
|
|
770
|
+
name: profileName,
|
|
771
|
+
model: profileModel,
|
|
772
|
+
resources,
|
|
773
|
+
}, scope);
|
|
774
|
+
this.ui.showStatus(`Saved profile "${profileName}" to ${scope}.`);
|
|
775
|
+
this.ui.requestRender();
|
|
776
|
+
}
|
|
777
|
+
catch (error) {
|
|
778
|
+
this.ui.showError(error instanceof Error ? error.message : String(error));
|
|
779
|
+
}
|
|
780
|
+
},
|
|
781
|
+
onCancel: () => {
|
|
782
|
+
done();
|
|
783
|
+
this.ui.requestRender();
|
|
784
|
+
},
|
|
785
|
+
onEdit: async (id, pathValue, kind) => {
|
|
786
|
+
done();
|
|
787
|
+
const resolvedEditPath = resolveResourceEditPath(id, pathValue, kind);
|
|
788
|
+
if (!resolvedEditPath) {
|
|
789
|
+
this.ui.showWarning(`Resource "${id}" of kind "${kind}" has no editable file path.`);
|
|
790
|
+
void this.openNewProfileEditor(profileName, profileModel);
|
|
791
|
+
return;
|
|
792
|
+
}
|
|
793
|
+
if (!fs.existsSync(resolvedEditPath)) {
|
|
794
|
+
this.ui.showError(`Resolved path for "${id}" does not exist: ${resolvedEditPath}`);
|
|
795
|
+
void this.openNewProfileEditor(profileName, profileModel);
|
|
796
|
+
return;
|
|
797
|
+
}
|
|
798
|
+
await this.ui.openEditorForPath(resolvedEditPath);
|
|
799
|
+
await this.ui.handleReloadCommand();
|
|
800
|
+
void this.openNewProfileEditor(profileName, profileModel);
|
|
801
|
+
},
|
|
802
|
+
});
|
|
803
|
+
return { component: editor, focus: editor };
|
|
804
|
+
});
|
|
805
|
+
}
|
|
806
|
+
persistActiveProfile(scope) {
|
|
807
|
+
const active = this.settingsManager.getActiveResourceProfileNames()[0];
|
|
808
|
+
if (!active) {
|
|
809
|
+
this.ui.showError("No active profile to persist. Select one with /profiles first.");
|
|
810
|
+
return;
|
|
811
|
+
}
|
|
812
|
+
try {
|
|
813
|
+
if (scope === "session") {
|
|
814
|
+
this.settingsManager.setRuntimeResourceProfiles([active]);
|
|
815
|
+
}
|
|
816
|
+
else {
|
|
817
|
+
this.settingsManager.setActiveProfile(active, scope);
|
|
818
|
+
}
|
|
819
|
+
this.ui.showStatus(`Active profile "${active}" persisted to ${scope}.`);
|
|
820
|
+
}
|
|
821
|
+
catch (error) {
|
|
822
|
+
this.ui.showError(error instanceof Error ? error.message : String(error));
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
deleteProfileFromSource(profileName) {
|
|
826
|
+
const profile = this.settingsManager.getProfileRegistry().getProfile(profileName);
|
|
827
|
+
if (!profile) {
|
|
828
|
+
this.ui.showError(`Profile not found: ${profileName}`);
|
|
829
|
+
return;
|
|
830
|
+
}
|
|
831
|
+
const scope = this.scopeForProfileSource(profile.source);
|
|
832
|
+
try {
|
|
833
|
+
this.settingsManager.deleteProfile(profileName, scope);
|
|
834
|
+
this.ui.showStatus(`Deleted profile "${profileName}" from ${scope}.`);
|
|
835
|
+
void this.refreshAfterProfileMutation(profileName);
|
|
836
|
+
}
|
|
837
|
+
catch (error) {
|
|
838
|
+
this.ui.showError(error instanceof Error ? error.message : String(error));
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
async addExternalResourceRootFlow() {
|
|
842
|
+
const rootPath = await new Promise((resolve) => {
|
|
843
|
+
this.ui.showSelector((done) => {
|
|
844
|
+
const input = new ExtensionInputComponent("Add External Root", "Enter external root directory path", (value) => {
|
|
845
|
+
done();
|
|
846
|
+
resolve(value);
|
|
847
|
+
}, () => {
|
|
848
|
+
done();
|
|
849
|
+
resolve(undefined);
|
|
850
|
+
}, { tui: this.ui.tui });
|
|
851
|
+
return { component: input, focus: input };
|
|
852
|
+
});
|
|
853
|
+
});
|
|
854
|
+
if (rootPath === undefined) {
|
|
855
|
+
this.ui.requestRender();
|
|
856
|
+
return;
|
|
857
|
+
}
|
|
858
|
+
const trimmed = rootPath.trim();
|
|
859
|
+
if (!trimmed) {
|
|
860
|
+
this.ui.showError("Directory path cannot be empty");
|
|
861
|
+
return;
|
|
862
|
+
}
|
|
863
|
+
const canonical = this.settingsManager.canonicalizePath(trimmed);
|
|
864
|
+
if (!canonical) {
|
|
865
|
+
this.ui.showError(`Invalid path: ${trimmed}`);
|
|
866
|
+
return;
|
|
867
|
+
}
|
|
868
|
+
// Prompt for trust confirmation (Yes/No)
|
|
869
|
+
const trust = await new Promise((resolve) => {
|
|
870
|
+
this.ui.showSelector((done) => {
|
|
871
|
+
const submenu = new SelectSubmenu("Trust external source?", "This directory can load custom extensions that execute arbitrary code on your machine.", [
|
|
872
|
+
{ value: "yes", label: "Yes", description: "Trust this directory and enable loading resources." },
|
|
873
|
+
{ value: "no", label: "No", description: "Do not trust this directory. Skip loading resources." },
|
|
874
|
+
], "no", (value) => {
|
|
875
|
+
done();
|
|
876
|
+
resolve(value === "yes");
|
|
877
|
+
}, () => {
|
|
878
|
+
done();
|
|
879
|
+
resolve(false);
|
|
880
|
+
});
|
|
881
|
+
return { component: submenu, focus: submenu.getSelectList() };
|
|
882
|
+
});
|
|
883
|
+
});
|
|
884
|
+
if (!trust) {
|
|
885
|
+
this.ui.showStatus("Aborted. External root was not trusted.");
|
|
886
|
+
return;
|
|
887
|
+
}
|
|
888
|
+
try {
|
|
889
|
+
const currentRoots = this.settingsManager.getExternalResourceRoots();
|
|
890
|
+
if (!currentRoots.includes(canonical)) {
|
|
891
|
+
this.settingsManager.setExternalResourceRoots([...currentRoots, canonical], "global");
|
|
892
|
+
}
|
|
893
|
+
this.settingsManager.addTrustedResourceRoot(canonical, "global");
|
|
894
|
+
this.ui.showStatus(`Added trusted external root: ${canonical}`);
|
|
895
|
+
await this.ui.handleReloadCommand();
|
|
896
|
+
}
|
|
897
|
+
catch (error) {
|
|
898
|
+
this.ui.showError(error instanceof Error ? error.message : String(error));
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
async removeExternalResourceRootFlow(root) {
|
|
902
|
+
try {
|
|
903
|
+
const currentRoots = this.settingsManager.getExternalResourceRoots();
|
|
904
|
+
const currentTrusted = this.settingsManager.getTrustedResourceRoots();
|
|
905
|
+
const newRoots = currentRoots.filter((r) => r !== root);
|
|
906
|
+
const newTrusted = currentTrusted.filter((r) => r !== root);
|
|
907
|
+
this.settingsManager.setExternalResourceRoots(newRoots, "global");
|
|
908
|
+
this.settingsManager.setTrustedResourceRoots(newTrusted, "global");
|
|
909
|
+
this.ui.showStatus(`Removed external root: ${root}`);
|
|
910
|
+
await this.ui.handleReloadCommand();
|
|
911
|
+
}
|
|
912
|
+
catch (error) {
|
|
913
|
+
this.ui.showError(error instanceof Error ? error.message : String(error));
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
}
|
|
917
|
+
//# sourceMappingURL=profile-menu-controller.js.map
|