@nexus-cortex/tui 4.47.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/LICENSE +202 -0
- package/NOTICE +2 -0
- package/README.md +13 -0
- package/bin/cli-full.js +23 -0
- package/bin/cortex-ui.js +26 -0
- package/bin/ink-ui.js +108 -0
- package/bin/launcher-dev.js +266 -0
- package/bin/launcher.js +516 -0
- package/dist/commands/agent/InteractiveAgentMenu.d.ts +100 -0
- package/dist/commands/agent/InteractiveAgentMenu.d.ts.map +1 -0
- package/dist/commands/agent/InteractiveAgentMenu.js +909 -0
- package/dist/commands/agent/InteractiveAgentMenu.js.map +1 -0
- package/dist/commands/agent/index.d.ts +55 -0
- package/dist/commands/agent/index.d.ts.map +1 -0
- package/dist/commands/agent/index.js +714 -0
- package/dist/commands/agent/index.js.map +1 -0
- package/dist/commands/chat/interactive.d.ts +13 -0
- package/dist/commands/chat/interactive.d.ts.map +1 -0
- package/dist/commands/chat/interactive.js +2055 -0
- package/dist/commands/chat/interactive.js.map +1 -0
- package/dist/commands/system-message/EditorLauncher.d.ts +65 -0
- package/dist/commands/system-message/EditorLauncher.d.ts.map +1 -0
- package/dist/commands/system-message/EditorLauncher.js +143 -0
- package/dist/commands/system-message/EditorLauncher.js.map +1 -0
- package/dist/commands/system-message/InlineEditor.d.ts +23 -0
- package/dist/commands/system-message/InlineEditor.d.ts.map +1 -0
- package/dist/commands/system-message/InlineEditor.js +225 -0
- package/dist/commands/system-message/InlineEditor.js.map +1 -0
- package/dist/commands/system-message/InteractiveMenu.d.ts +76 -0
- package/dist/commands/system-message/InteractiveMenu.d.ts.map +1 -0
- package/dist/commands/system-message/InteractiveMenu.js +979 -0
- package/dist/commands/system-message/InteractiveMenu.js.map +1 -0
- package/dist/commands/system-message/index.d.ts +56 -0
- package/dist/commands/system-message/index.d.ts.map +1 -0
- package/dist/commands/system-message/index.js +694 -0
- package/dist/commands/system-message/index.js.map +1 -0
- package/dist/commands/ui/artifacts.d.ts +14 -0
- package/dist/commands/ui/artifacts.d.ts.map +1 -0
- package/dist/commands/ui/artifacts.js +22 -0
- package/dist/commands/ui/artifacts.js.map +1 -0
- package/dist/commands/ui/config.d.ts +12 -0
- package/dist/commands/ui/config.d.ts.map +1 -0
- package/dist/commands/ui/config.js +26 -0
- package/dist/commands/ui/config.js.map +1 -0
- package/dist/commands/ui/context.d.ts +16 -0
- package/dist/commands/ui/context.d.ts.map +1 -0
- package/dist/commands/ui/context.js +28 -0
- package/dist/commands/ui/context.js.map +1 -0
- package/dist/commands/ui/middleware.d.ts +14 -0
- package/dist/commands/ui/middleware.d.ts.map +1 -0
- package/dist/commands/ui/middleware.js +22 -0
- package/dist/commands/ui/middleware.js.map +1 -0
- package/dist/commands/ui/models.d.ts +14 -0
- package/dist/commands/ui/models.d.ts.map +1 -0
- package/dist/commands/ui/models.js +50 -0
- package/dist/commands/ui/models.js.map +1 -0
- package/dist/commands/ui/permissions.d.ts +14 -0
- package/dist/commands/ui/permissions.d.ts.map +1 -0
- package/dist/commands/ui/permissions.js +22 -0
- package/dist/commands/ui/permissions.js.map +1 -0
- package/dist/commands/ui/sessions.d.ts +13 -0
- package/dist/commands/ui/sessions.d.ts.map +1 -0
- package/dist/commands/ui/sessions.js +45 -0
- package/dist/commands/ui/sessions.js.map +1 -0
- package/dist/commands/ui/system-messages.d.ts +5 -0
- package/dist/commands/ui/system-messages.d.ts.map +1 -0
- package/dist/commands/ui/system-messages.js +19 -0
- package/dist/commands/ui/system-messages.js.map +1 -0
- package/dist/commands/ui/themes.d.ts +12 -0
- package/dist/commands/ui/themes.d.ts.map +1 -0
- package/dist/commands/ui/themes.js +40 -0
- package/dist/commands/ui/themes.js.map +1 -0
- package/dist/commands/ui/tmux.d.ts +5 -0
- package/dist/commands/ui/tmux.d.ts.map +1 -0
- package/dist/commands/ui/tmux.js +19 -0
- package/dist/commands/ui/tmux.js.map +1 -0
- package/dist/cortex.d.ts +12 -0
- package/dist/cortex.d.ts.map +1 -0
- package/dist/cortex.js +320 -0
- package/dist/cortex.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +112 -0
- package/dist/index.js.map +1 -0
- package/dist/ink-ui/CortexApp.d.ts +28 -0
- package/dist/ink-ui/CortexApp.d.ts.map +1 -0
- package/dist/ink-ui/CortexApp.js +2291 -0
- package/dist/ink-ui/CortexApp.js.map +1 -0
- package/dist/ink-ui/SimpleInputBuffer.d.ts +63 -0
- package/dist/ink-ui/SimpleInputBuffer.d.ts.map +1 -0
- package/dist/ink-ui/SimpleInputBuffer.js +369 -0
- package/dist/ink-ui/SimpleInputBuffer.js.map +1 -0
- package/dist/ink-ui/commands/slashCommands.d.ts +40 -0
- package/dist/ink-ui/commands/slashCommands.d.ts.map +1 -0
- package/dist/ink-ui/commands/slashCommands.js +111 -0
- package/dist/ink-ui/commands/slashCommands.js.map +1 -0
- package/dist/ink-ui/commands/types.d.ts +161 -0
- package/dist/ink-ui/commands/types.d.ts.map +1 -0
- package/dist/ink-ui/commands/types.js +12 -0
- package/dist/ink-ui/commands/types.js.map +1 -0
- package/dist/ink-ui/components/ApprovalDialog.d.ts +21 -0
- package/dist/ink-ui/components/ApprovalDialog.d.ts.map +1 -0
- package/dist/ink-ui/components/ApprovalDialog.js +81 -0
- package/dist/ink-ui/components/ApprovalDialog.js.map +1 -0
- package/dist/ink-ui/components/CommandSuggestions.d.ts +19 -0
- package/dist/ink-ui/components/CommandSuggestions.d.ts.map +1 -0
- package/dist/ink-ui/components/CommandSuggestions.js +36 -0
- package/dist/ink-ui/components/CommandSuggestions.js.map +1 -0
- package/dist/ink-ui/components/DiffPreview.d.ts +60 -0
- package/dist/ink-ui/components/DiffPreview.d.ts.map +1 -0
- package/dist/ink-ui/components/DiffPreview.js +195 -0
- package/dist/ink-ui/components/DiffPreview.js.map +1 -0
- package/dist/ink-ui/components/DocumentPreview.d.ts +50 -0
- package/dist/ink-ui/components/DocumentPreview.d.ts.map +1 -0
- package/dist/ink-ui/components/DocumentPreview.js +92 -0
- package/dist/ink-ui/components/DocumentPreview.js.map +1 -0
- package/dist/ink-ui/components/MarkdownText.d.ts +27 -0
- package/dist/ink-ui/components/MarkdownText.d.ts.map +1 -0
- package/dist/ink-ui/components/MarkdownText.js +342 -0
- package/dist/ink-ui/components/MarkdownText.js.map +1 -0
- package/dist/ink-ui/components/MenuRenderer.d.ts +26 -0
- package/dist/ink-ui/components/MenuRenderer.d.ts.map +1 -0
- package/dist/ink-ui/components/MenuRenderer.js +264 -0
- package/dist/ink-ui/components/MenuRenderer.js.map +1 -0
- package/dist/ink-ui/components/ModelPickerDialog.d.ts +33 -0
- package/dist/ink-ui/components/ModelPickerDialog.d.ts.map +1 -0
- package/dist/ink-ui/components/ModelPickerDialog.js +98 -0
- package/dist/ink-ui/components/ModelPickerDialog.js.map +1 -0
- package/dist/ink-ui/components/StreamDisplay.d.ts +31 -0
- package/dist/ink-ui/components/StreamDisplay.d.ts.map +1 -0
- package/dist/ink-ui/components/StreamDisplay.js +573 -0
- package/dist/ink-ui/components/StreamDisplay.js.map +1 -0
- package/dist/ink-ui/components/SubAgentPanel.d.ts +98 -0
- package/dist/ink-ui/components/SubAgentPanel.d.ts.map +1 -0
- package/dist/ink-ui/components/SubAgentPanel.js +155 -0
- package/dist/ink-ui/components/SubAgentPanel.js.map +1 -0
- package/dist/ink-ui/components/ThinkingDisplay.d.ts +46 -0
- package/dist/ink-ui/components/ThinkingDisplay.d.ts.map +1 -0
- package/dist/ink-ui/components/ThinkingDisplay.js +176 -0
- package/dist/ink-ui/components/ThinkingDisplay.js.map +1 -0
- package/dist/ink-ui/components/ToolCallDisplay.d.ts +51 -0
- package/dist/ink-ui/components/ToolCallDisplay.d.ts.map +1 -0
- package/dist/ink-ui/components/ToolCallDisplay.js +378 -0
- package/dist/ink-ui/components/ToolCallDisplay.js.map +1 -0
- package/dist/ink-ui/components/WritePreview.d.ts +42 -0
- package/dist/ink-ui/components/WritePreview.d.ts.map +1 -0
- package/dist/ink-ui/components/WritePreview.js +100 -0
- package/dist/ink-ui/components/WritePreview.js.map +1 -0
- package/dist/ink-ui/contexts/KeypressContext.d.ts +32 -0
- package/dist/ink-ui/contexts/KeypressContext.d.ts.map +1 -0
- package/dist/ink-ui/contexts/KeypressContext.js +529 -0
- package/dist/ink-ui/contexts/KeypressContext.js.map +1 -0
- package/dist/ink-ui/contexts/SessionContext.d.ts +46 -0
- package/dist/ink-ui/contexts/SessionContext.d.ts.map +1 -0
- package/dist/ink-ui/contexts/SessionContext.js +162 -0
- package/dist/ink-ui/contexts/SessionContext.js.map +1 -0
- package/dist/ink-ui/core-stubs.d.ts +270 -0
- package/dist/ink-ui/core-stubs.d.ts.map +1 -0
- package/dist/ink-ui/core-stubs.js +276 -0
- package/dist/ink-ui/core-stubs.js.map +1 -0
- package/dist/ink-ui/cortex-types.d.ts +214 -0
- package/dist/ink-ui/cortex-types.d.ts.map +1 -0
- package/dist/ink-ui/cortex-types.js +52 -0
- package/dist/ink-ui/cortex-types.js.map +1 -0
- package/dist/ink-ui/hooks/useCortexStream.d.ts +75 -0
- package/dist/ink-ui/hooks/useCortexStream.d.ts.map +1 -0
- package/dist/ink-ui/hooks/useCortexStream.js +518 -0
- package/dist/ink-ui/hooks/useCortexStream.js.map +1 -0
- package/dist/ink-ui/hooks/useFocus.d.ts +11 -0
- package/dist/ink-ui/hooks/useFocus.d.ts.map +1 -0
- package/dist/ink-ui/hooks/useFocus.js +51 -0
- package/dist/ink-ui/hooks/useFocus.js.map +1 -0
- package/dist/ink-ui/hooks/useHistoryManager.d.ts +23 -0
- package/dist/ink-ui/hooks/useHistoryManager.d.ts.map +1 -0
- package/dist/ink-ui/hooks/useHistoryManager.js +63 -0
- package/dist/ink-ui/hooks/useHistoryManager.js.map +1 -0
- package/dist/ink-ui/hooks/useKeypress.d.ts +18 -0
- package/dist/ink-ui/hooks/useKeypress.d.ts.map +1 -0
- package/dist/ink-ui/hooks/useKeypress.js +27 -0
- package/dist/ink-ui/hooks/useKeypress.js.map +1 -0
- package/dist/ink-ui/hooks/useReactApprovalHandler.d.ts +74 -0
- package/dist/ink-ui/hooks/useReactApprovalHandler.d.ts.map +1 -0
- package/dist/ink-ui/hooks/useReactApprovalHandler.js +83 -0
- package/dist/ink-ui/hooks/useReactApprovalHandler.js.map +1 -0
- package/dist/ink-ui/hooks/useTerminalSize.d.ts +10 -0
- package/dist/ink-ui/hooks/useTerminalSize.d.ts.map +1 -0
- package/dist/ink-ui/hooks/useTerminalSize.js +28 -0
- package/dist/ink-ui/hooks/useTerminalSize.js.map +1 -0
- package/dist/ink-ui/semantic-colors.d.ts +8 -0
- package/dist/ink-ui/semantic-colors.d.ts.map +1 -0
- package/dist/ink-ui/semantic-colors.js +24 -0
- package/dist/ink-ui/semantic-colors.js.map +1 -0
- package/dist/ink-ui/state/extensions.d.ts +68 -0
- package/dist/ink-ui/state/extensions.d.ts.map +1 -0
- package/dist/ink-ui/state/extensions.js +97 -0
- package/dist/ink-ui/state/extensions.js.map +1 -0
- package/dist/ink-ui/themes/ansi-light.d.ts +8 -0
- package/dist/ink-ui/themes/ansi-light.d.ts.map +1 -0
- package/dist/ink-ui/themes/ansi-light.js +143 -0
- package/dist/ink-ui/themes/ansi-light.js.map +1 -0
- package/dist/ink-ui/themes/ansi.d.ts +8 -0
- package/dist/ink-ui/themes/ansi.d.ts.map +1 -0
- package/dist/ink-ui/themes/ansi.js +153 -0
- package/dist/ink-ui/themes/ansi.js.map +1 -0
- package/dist/ink-ui/themes/atom-one-dark.d.ts +8 -0
- package/dist/ink-ui/themes/atom-one-dark.d.ts.map +1 -0
- package/dist/ink-ui/themes/atom-one-dark.js +140 -0
- package/dist/ink-ui/themes/atom-one-dark.js.map +1 -0
- package/dist/ink-ui/themes/ayu-light.d.ts +8 -0
- package/dist/ink-ui/themes/ayu-light.d.ts.map +1 -0
- package/dist/ink-ui/themes/ayu-light.js +132 -0
- package/dist/ink-ui/themes/ayu-light.js.map +1 -0
- package/dist/ink-ui/themes/ayu.d.ts +8 -0
- package/dist/ink-ui/themes/ayu.d.ts.map +1 -0
- package/dist/ink-ui/themes/ayu.js +106 -0
- package/dist/ink-ui/themes/ayu.js.map +1 -0
- package/dist/ink-ui/themes/color-utils.d.ts +23 -0
- package/dist/ink-ui/themes/color-utils.d.ts.map +1 -0
- package/dist/ink-ui/themes/color-utils.js +237 -0
- package/dist/ink-ui/themes/color-utils.js.map +1 -0
- package/dist/ink-ui/themes/default-light.d.ts +8 -0
- package/dist/ink-ui/themes/default-light.d.ts.map +1 -0
- package/dist/ink-ui/themes/default-light.js +100 -0
- package/dist/ink-ui/themes/default-light.js.map +1 -0
- package/dist/ink-ui/themes/default.d.ts +8 -0
- package/dist/ink-ui/themes/default.d.ts.map +1 -0
- package/dist/ink-ui/themes/default.js +143 -0
- package/dist/ink-ui/themes/default.js.map +1 -0
- package/dist/ink-ui/themes/dracula.d.ts +8 -0
- package/dist/ink-ui/themes/dracula.d.ts.map +1 -0
- package/dist/ink-ui/themes/dracula.js +117 -0
- package/dist/ink-ui/themes/dracula.js.map +1 -0
- package/dist/ink-ui/themes/github-dark.d.ts +8 -0
- package/dist/ink-ui/themes/github-dark.d.ts.map +1 -0
- package/dist/ink-ui/themes/github-dark.js +140 -0
- package/dist/ink-ui/themes/github-dark.js.map +1 -0
- package/dist/ink-ui/themes/github-light.d.ts +8 -0
- package/dist/ink-ui/themes/github-light.d.ts.map +1 -0
- package/dist/ink-ui/themes/github-light.js +142 -0
- package/dist/ink-ui/themes/github-light.js.map +1 -0
- package/dist/ink-ui/themes/googlecode.d.ts +8 -0
- package/dist/ink-ui/themes/googlecode.d.ts.map +1 -0
- package/dist/ink-ui/themes/googlecode.js +139 -0
- package/dist/ink-ui/themes/googlecode.js.map +1 -0
- package/dist/ink-ui/themes/no-color.d.ts +8 -0
- package/dist/ink-ui/themes/no-color.d.ts.map +1 -0
- package/dist/ink-ui/themes/no-color.js +118 -0
- package/dist/ink-ui/themes/no-color.js.map +1 -0
- package/dist/ink-ui/themes/semantic-tokens.d.ts +40 -0
- package/dist/ink-ui/themes/semantic-tokens.d.ts.map +1 -0
- package/dist/ink-ui/themes/semantic-tokens.js +100 -0
- package/dist/ink-ui/themes/semantic-tokens.js.map +1 -0
- package/dist/ink-ui/themes/shades-of-purple.d.ts +12 -0
- package/dist/ink-ui/themes/shades-of-purple.d.ts.map +1 -0
- package/dist/ink-ui/themes/shades-of-purple.js +306 -0
- package/dist/ink-ui/themes/shades-of-purple.js.map +1 -0
- package/dist/ink-ui/themes/theme-manager.d.ts +67 -0
- package/dist/ink-ui/themes/theme-manager.d.ts.map +1 -0
- package/dist/ink-ui/themes/theme-manager.js +263 -0
- package/dist/ink-ui/themes/theme-manager.js.map +1 -0
- package/dist/ink-ui/themes/theme.d.ts +134 -0
- package/dist/ink-ui/themes/theme.d.ts.map +1 -0
- package/dist/ink-ui/themes/theme.js +390 -0
- package/dist/ink-ui/themes/theme.js.map +1 -0
- package/dist/ink-ui/themes/xcode.d.ts +8 -0
- package/dist/ink-ui/themes/xcode.d.ts.map +1 -0
- package/dist/ink-ui/themes/xcode.js +147 -0
- package/dist/ink-ui/themes/xcode.js.map +1 -0
- package/dist/ink-ui/types.d.ts +306 -0
- package/dist/ink-ui/types.d.ts.map +1 -0
- package/dist/ink-ui/types.js +65 -0
- package/dist/ink-ui/types.js.map +1 -0
- package/dist/ink-ui/utils/input.d.ts +18 -0
- package/dist/ink-ui/utils/input.d.ts.map +1 -0
- package/dist/ink-ui/utils/input.js +51 -0
- package/dist/ink-ui/utils/input.js.map +1 -0
- package/dist/ink-ui/utils/mouse.d.ts +33 -0
- package/dist/ink-ui/utils/mouse.d.ts.map +1 -0
- package/dist/ink-ui/utils/mouse.js +182 -0
- package/dist/ink-ui/utils/mouse.js.map +1 -0
- package/dist/services/BuiltinCommandLoader.d.ts +21 -0
- package/dist/services/BuiltinCommandLoader.d.ts.map +1 -0
- package/dist/services/BuiltinCommandLoader.js +182 -0
- package/dist/services/BuiltinCommandLoader.js.map +1 -0
- package/dist/services/CommandService.d.ts +39 -0
- package/dist/services/CommandService.d.ts.map +1 -0
- package/dist/services/CommandService.js +49 -0
- package/dist/services/CommandService.js.map +1 -0
- package/dist/services/FileCommandLoader.d.ts +16 -0
- package/dist/services/FileCommandLoader.d.ts.map +1 -0
- package/dist/services/FileCommandLoader.js +19 -0
- package/dist/services/FileCommandLoader.js.map +1 -0
- package/dist/services/McpPromptLoader.d.ts +16 -0
- package/dist/services/McpPromptLoader.d.ts.map +1 -0
- package/dist/services/McpPromptLoader.js +19 -0
- package/dist/services/McpPromptLoader.js.map +1 -0
- package/dist/services/index.d.ts +8 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/index.js +8 -0
- package/dist/services/index.js.map +1 -0
- package/dist/ui/ChalkMenuRenderer.d.ts +22 -0
- package/dist/ui/ChalkMenuRenderer.d.ts.map +1 -0
- package/dist/ui/ChalkMenuRenderer.js +478 -0
- package/dist/ui/ChalkMenuRenderer.js.map +1 -0
- package/dist/ui/ChalkModelPicker.d.ts +20 -0
- package/dist/ui/ChalkModelPicker.d.ts.map +1 -0
- package/dist/ui/ChalkModelPicker.js +363 -0
- package/dist/ui/ChalkModelPicker.js.map +1 -0
- package/dist/ui/ChalkThemePicker.d.ts +20 -0
- package/dist/ui/ChalkThemePicker.d.ts.map +1 -0
- package/dist/ui/ChalkThemePicker.js +370 -0
- package/dist/ui/ChalkThemePicker.js.map +1 -0
- package/dist/ui/InkApprovalDialog.d.ts +8 -0
- package/dist/ui/InkApprovalDialog.d.ts.map +1 -0
- package/dist/ui/InkApprovalDialog.js +25 -0
- package/dist/ui/InkApprovalDialog.js.map +1 -0
- package/dist/ui/InkCommandPalette.d.ts +43 -0
- package/dist/ui/InkCommandPalette.d.ts.map +1 -0
- package/dist/ui/InkCommandPalette.js +105 -0
- package/dist/ui/InkCommandPalette.js.map +1 -0
- package/dist/ui/InkConfigMenu.d.ts +24 -0
- package/dist/ui/InkConfigMenu.d.ts.map +1 -0
- package/dist/ui/InkConfigMenu.js +259 -0
- package/dist/ui/InkConfigMenu.js.map +1 -0
- package/dist/ui/InkHelp.d.ts +25 -0
- package/dist/ui/InkHelp.d.ts.map +1 -0
- package/dist/ui/InkHelp.js +55 -0
- package/dist/ui/InkHelp.js.map +1 -0
- package/dist/ui/InkMenuPicker.d.ts +19 -0
- package/dist/ui/InkMenuPicker.d.ts.map +1 -0
- package/dist/ui/InkMenuPicker.js +33 -0
- package/dist/ui/InkMenuPicker.js.map +1 -0
- package/dist/ui/InkModelPicker.d.ts +23 -0
- package/dist/ui/InkModelPicker.d.ts.map +1 -0
- package/dist/ui/InkModelPicker.js +53 -0
- package/dist/ui/InkModelPicker.js.map +1 -0
- package/dist/ui/PersistentInput.d.ts +91 -0
- package/dist/ui/PersistentInput.d.ts.map +1 -0
- package/dist/ui/PersistentInput.js +283 -0
- package/dist/ui/PersistentInput.js.map +1 -0
- package/dist/ui/RawInput.d.ts +27 -0
- package/dist/ui/RawInput.d.ts.map +1 -0
- package/dist/ui/RawInput.js +731 -0
- package/dist/ui/RawInput.js.map +1 -0
- package/dist/ui/SlashCommandAutocomplete.d.ts +94 -0
- package/dist/ui/SlashCommandAutocomplete.d.ts.map +1 -0
- package/dist/ui/SlashCommandAutocomplete.js +274 -0
- package/dist/ui/SlashCommandAutocomplete.js.map +1 -0
- package/dist/ui/SplashScreen.d.ts +76 -0
- package/dist/ui/SplashScreen.d.ts.map +1 -0
- package/dist/ui/SplashScreen.js +316 -0
- package/dist/ui/SplashScreen.js.map +1 -0
- package/dist/ui/components/ArtifactDashboard.d.ts +16 -0
- package/dist/ui/components/ArtifactDashboard.d.ts.map +1 -0
- package/dist/ui/components/ArtifactDashboard.js +102 -0
- package/dist/ui/components/ArtifactDashboard.js.map +1 -0
- package/dist/ui/components/ChatInput.d.ts +36 -0
- package/dist/ui/components/ChatInput.d.ts.map +1 -0
- package/dist/ui/components/ChatInput.js +11 -0
- package/dist/ui/components/ChatInput.js.map +1 -0
- package/dist/ui/components/ConfigWizard.d.ts +17 -0
- package/dist/ui/components/ConfigWizard.d.ts.map +1 -0
- package/dist/ui/components/ConfigWizard.js +134 -0
- package/dist/ui/components/ConfigWizard.js.map +1 -0
- package/dist/ui/components/ContextViewer.d.ts +18 -0
- package/dist/ui/components/ContextViewer.d.ts.map +1 -0
- package/dist/ui/components/ContextViewer.js +85 -0
- package/dist/ui/components/ContextViewer.js.map +1 -0
- package/dist/ui/components/MiddlewareDashboard.d.ts +16 -0
- package/dist/ui/components/MiddlewareDashboard.d.ts.map +1 -0
- package/dist/ui/components/MiddlewareDashboard.js +98 -0
- package/dist/ui/components/MiddlewareDashboard.js.map +1 -0
- package/dist/ui/components/ModelPicker.d.ts +24 -0
- package/dist/ui/components/ModelPicker.d.ts.map +1 -0
- package/dist/ui/components/ModelPicker.js +96 -0
- package/dist/ui/components/ModelPicker.js.map +1 -0
- package/dist/ui/components/MultiLineInput.d.ts +27 -0
- package/dist/ui/components/MultiLineInput.d.ts.map +1 -0
- package/dist/ui/components/MultiLineInput.js +182 -0
- package/dist/ui/components/MultiLineInput.js.map +1 -0
- package/dist/ui/components/PermissionsBrowser.d.ts +16 -0
- package/dist/ui/components/PermissionsBrowser.d.ts.map +1 -0
- package/dist/ui/components/PermissionsBrowser.js +110 -0
- package/dist/ui/components/PermissionsBrowser.js.map +1 -0
- package/dist/ui/components/SessionBrowser.d.ts +19 -0
- package/dist/ui/components/SessionBrowser.d.ts.map +1 -0
- package/dist/ui/components/SessionBrowser.js +66 -0
- package/dist/ui/components/SessionBrowser.js.map +1 -0
- package/dist/ui/components/StatusBar.d.ts +32 -0
- package/dist/ui/components/StatusBar.d.ts.map +1 -0
- package/dist/ui/components/StatusBar.js +27 -0
- package/dist/ui/components/StatusBar.js.map +1 -0
- package/dist/ui/components/SystemMessageBrowser.d.ts +11 -0
- package/dist/ui/components/SystemMessageBrowser.d.ts.map +1 -0
- package/dist/ui/components/SystemMessageBrowser.js +106 -0
- package/dist/ui/components/SystemMessageBrowser.js.map +1 -0
- package/dist/ui/components/ThemePicker.d.ts +11 -0
- package/dist/ui/components/ThemePicker.d.ts.map +1 -0
- package/dist/ui/components/ThemePicker.js +62 -0
- package/dist/ui/components/ThemePicker.js.map +1 -0
- package/dist/ui/components/TmuxBrowser.d.ts +11 -0
- package/dist/ui/components/TmuxBrowser.d.ts.map +1 -0
- package/dist/ui/components/TmuxBrowser.js +85 -0
- package/dist/ui/components/TmuxBrowser.js.map +1 -0
- package/dist/ui/components/index.d.ts +22 -0
- package/dist/ui/components/index.d.ts.map +1 -0
- package/dist/ui/components/index.js +21 -0
- package/dist/ui/components/index.js.map +1 -0
- package/package.json +70 -0
|
@@ -0,0 +1,979 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* Interactive System Message Menu
|
|
4
|
+
*
|
|
5
|
+
* Ink-based terminal UI for managing system messages
|
|
6
|
+
* Provides list view, navigation, CRUD operations, and AI-powered creation/editing
|
|
7
|
+
*/
|
|
8
|
+
import { useState, useEffect } from 'react';
|
|
9
|
+
import { Box, Text, useInput, useApp } from 'ink';
|
|
10
|
+
import TextInput from 'ink-text-input';
|
|
11
|
+
import Spinner from 'ink-spinner';
|
|
12
|
+
import { InlineEditor } from './InlineEditor.js';
|
|
13
|
+
import * as path from 'path';
|
|
14
|
+
/**
|
|
15
|
+
* Priority presets for easy selection
|
|
16
|
+
* Lower priority number = injected first (matches injection system)
|
|
17
|
+
* Priority 0 = excluded from injection entirely
|
|
18
|
+
*/
|
|
19
|
+
const PRIORITY_PRESETS = [
|
|
20
|
+
{ value: 0, label: 'Disabled (0)', description: 'Excluded from injection - message will not be loaded' },
|
|
21
|
+
{ value: 1, label: 'Critical (1)', description: 'Safety rules - injected first (before everything)' },
|
|
22
|
+
{ value: 5, label: 'High (5)', description: 'Core behavioral instructions - after system prompt' },
|
|
23
|
+
{ value: 8, label: 'Medium (8)', description: 'General guidance - after core messages' },
|
|
24
|
+
{ value: 15, label: 'Low (15)', description: 'Preferences - after periodic reminders (10)' },
|
|
25
|
+
{ value: 50, label: 'Optional (50)', description: 'Optional enhancements - injected last' },
|
|
26
|
+
];
|
|
27
|
+
/**
|
|
28
|
+
* Interactive System Message Menu Component
|
|
29
|
+
*/
|
|
30
|
+
export const InteractiveMenu = ({ store, runtimeDir, builtinDir, initialMessageId, generateProfile, conversationalCreator, editAssistant, onExit, }) => {
|
|
31
|
+
const { exit: inkExit } = useApp();
|
|
32
|
+
// Use onExit callback if provided (for graceful return to CLI), otherwise fall back to Ink's exit
|
|
33
|
+
const handleExit = () => {
|
|
34
|
+
if (onExit) {
|
|
35
|
+
onExit();
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
inkExit();
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
const [messages, setMessages] = useState([]);
|
|
42
|
+
const [selectedIndex, setSelectedIndex] = useState(0);
|
|
43
|
+
const [menuState, setMenuState] = useState('list');
|
|
44
|
+
const [confirmAction, setConfirmAction] = useState(null);
|
|
45
|
+
const [statusMessage, setStatusMessage] = useState('');
|
|
46
|
+
const [errorMessage, setErrorMessage] = useState('');
|
|
47
|
+
// Editing state
|
|
48
|
+
const [editingMessage, setEditingMessage] = useState(null);
|
|
49
|
+
const [editingContent, setEditingContent] = useState('');
|
|
50
|
+
const [editingFilePath, setEditingFilePath] = useState('');
|
|
51
|
+
// AI edit state
|
|
52
|
+
const [aiEditRequest, setAiEditRequest] = useState('');
|
|
53
|
+
const [aiEditResult, setAiEditResult] = useState(null);
|
|
54
|
+
// Creation state
|
|
55
|
+
const [createDescription, setCreateDescription] = useState('');
|
|
56
|
+
const [generatingMessage, setGeneratingMessage] = useState('');
|
|
57
|
+
// Conversation state for multi-turn creation
|
|
58
|
+
const [conversationMessages, setConversationMessages] = useState([]);
|
|
59
|
+
const [conversationInput, setConversationInput] = useState('');
|
|
60
|
+
const [conversationThinking, setConversationThinking] = useState(false);
|
|
61
|
+
// Edit choice state
|
|
62
|
+
const [editChoiceIndex, setEditChoiceIndex] = useState(0);
|
|
63
|
+
// Priority selection state
|
|
64
|
+
const [prioritySelectIndex, setPrioritySelectIndex] = useState(3); // Default to Medium (8)
|
|
65
|
+
const [selectedPriority, setSelectedPriority] = useState(8);
|
|
66
|
+
const [customPriorityInput, setCustomPriorityInput] = useState('');
|
|
67
|
+
const [showCustomPriority, setShowCustomPriority] = useState(false);
|
|
68
|
+
// Load messages on mount
|
|
69
|
+
useEffect(() => {
|
|
70
|
+
loadMessages();
|
|
71
|
+
// Subscribe to store changes for hot-reload
|
|
72
|
+
const listener = () => {
|
|
73
|
+
loadMessages();
|
|
74
|
+
};
|
|
75
|
+
store.onChange(listener);
|
|
76
|
+
return () => {
|
|
77
|
+
store.removeListener(listener);
|
|
78
|
+
};
|
|
79
|
+
}, []);
|
|
80
|
+
// Set initial selection
|
|
81
|
+
useEffect(() => {
|
|
82
|
+
if (initialMessageId && messages.length > 0) {
|
|
83
|
+
const index = messages.findIndex((m) => m.id === initialMessageId);
|
|
84
|
+
if (index !== -1) {
|
|
85
|
+
setSelectedIndex(index);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}, [messages, initialMessageId]);
|
|
89
|
+
/**
|
|
90
|
+
* Load messages from store
|
|
91
|
+
*/
|
|
92
|
+
const loadMessages = () => {
|
|
93
|
+
const allMessages = store.getAll();
|
|
94
|
+
// Sort by priority (lower = injected first, show first in list)
|
|
95
|
+
allMessages.sort((a, b) => {
|
|
96
|
+
if (a.priority !== b.priority) {
|
|
97
|
+
return a.priority - b.priority; // Lower priority number first
|
|
98
|
+
}
|
|
99
|
+
return a.id.localeCompare(b.id);
|
|
100
|
+
});
|
|
101
|
+
setMessages(allMessages);
|
|
102
|
+
};
|
|
103
|
+
/**
|
|
104
|
+
* Get currently selected message
|
|
105
|
+
*/
|
|
106
|
+
const selectedMessage = messages[selectedIndex];
|
|
107
|
+
/**
|
|
108
|
+
* Handle keyboard input for list state
|
|
109
|
+
*/
|
|
110
|
+
useInput((input, key) => {
|
|
111
|
+
// Loading/generating state - block all input
|
|
112
|
+
if (menuState === 'loading' || menuState === 'create-generating' || menuState === 'ai-edit-processing') {
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
// Confirmation prompt state
|
|
116
|
+
if (menuState === 'confirm' && confirmAction) {
|
|
117
|
+
if (input.toLowerCase() === 'y') {
|
|
118
|
+
executeConfirmedAction(confirmAction);
|
|
119
|
+
setMenuState('list');
|
|
120
|
+
setConfirmAction(null);
|
|
121
|
+
}
|
|
122
|
+
else if (input.toLowerCase() === 'n' || key.escape) {
|
|
123
|
+
setMenuState('list');
|
|
124
|
+
setConfirmAction(null);
|
|
125
|
+
setStatusMessage('Action cancelled');
|
|
126
|
+
}
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
// List navigation state
|
|
130
|
+
if (menuState === 'list') {
|
|
131
|
+
// Navigation
|
|
132
|
+
if (key.upArrow) {
|
|
133
|
+
setSelectedIndex((prev) => Math.max(0, prev - 1));
|
|
134
|
+
setStatusMessage('');
|
|
135
|
+
setErrorMessage('');
|
|
136
|
+
}
|
|
137
|
+
else if (key.downArrow) {
|
|
138
|
+
setSelectedIndex((prev) => Math.min(messages.length - 1, prev + 1));
|
|
139
|
+
setStatusMessage('');
|
|
140
|
+
setErrorMessage('');
|
|
141
|
+
}
|
|
142
|
+
// Actions
|
|
143
|
+
else if (key.return && selectedMessage) {
|
|
144
|
+
// Edit message - start with priority confirmation
|
|
145
|
+
// Find the matching priority preset or use custom
|
|
146
|
+
const currentPriority = selectedMessage.priority;
|
|
147
|
+
const presetIndex = PRIORITY_PRESETS.findIndex(p => p.value === currentPriority);
|
|
148
|
+
if (presetIndex !== -1) {
|
|
149
|
+
setPrioritySelectIndex(presetIndex);
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
setPrioritySelectIndex(PRIORITY_PRESETS.length); // Custom option
|
|
153
|
+
}
|
|
154
|
+
setSelectedPriority(currentPriority);
|
|
155
|
+
setShowCustomPriority(false);
|
|
156
|
+
setCustomPriorityInput('');
|
|
157
|
+
setMenuState('edit-priority');
|
|
158
|
+
}
|
|
159
|
+
else if (input === ' ' && selectedMessage) {
|
|
160
|
+
// Toggle enabled state
|
|
161
|
+
handleToggle(selectedMessage.id);
|
|
162
|
+
}
|
|
163
|
+
else if (input === '+') {
|
|
164
|
+
// Create new message - start with priority selection
|
|
165
|
+
setCreateDescription('');
|
|
166
|
+
setConversationMessages([]);
|
|
167
|
+
setConversationInput('');
|
|
168
|
+
setPrioritySelectIndex(3); // Default to Medium (8)
|
|
169
|
+
setSelectedPriority(8);
|
|
170
|
+
setShowCustomPriority(false);
|
|
171
|
+
setCustomPriorityInput('');
|
|
172
|
+
setMenuState('create-priority');
|
|
173
|
+
}
|
|
174
|
+
else if (input.toLowerCase() === 'r' && selectedMessage) {
|
|
175
|
+
// Reset to default
|
|
176
|
+
if (selectedMessage.source === 'runtime' || selectedMessage.source === 'workspace') {
|
|
177
|
+
setConfirmAction({ type: 'reset', messageId: selectedMessage.id });
|
|
178
|
+
setMenuState('confirm');
|
|
179
|
+
}
|
|
180
|
+
else {
|
|
181
|
+
setErrorMessage('Cannot reset builtin message');
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
else if (input.toLowerCase() === 'd' && selectedMessage) {
|
|
185
|
+
// Delete message
|
|
186
|
+
if (selectedMessage.source === 'runtime') {
|
|
187
|
+
setConfirmAction({ type: 'delete', messageId: selectedMessage.id });
|
|
188
|
+
setMenuState('confirm');
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
setErrorMessage('Can only delete runtime messages');
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
else if (input.toLowerCase() === 'q' || key.escape) {
|
|
195
|
+
// Quit - use handleExit for graceful return to CLI
|
|
196
|
+
handleExit();
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}, { isActive: menuState === 'list' || menuState === 'confirm' });
|
|
200
|
+
/**
|
|
201
|
+
* Handle keyboard input for edit choice state
|
|
202
|
+
*/
|
|
203
|
+
useInput((_input, key) => {
|
|
204
|
+
if (key.upArrow || key.downArrow) {
|
|
205
|
+
setEditChoiceIndex((prev) => (prev === 0 ? 1 : 0));
|
|
206
|
+
}
|
|
207
|
+
else if (key.return) {
|
|
208
|
+
if (editChoiceIndex === 0 && selectedMessage) {
|
|
209
|
+
// Direct edit - update priority first if changed, then edit
|
|
210
|
+
handleDirectEditWithPriority(selectedMessage.id, selectedPriority).catch((err) => {
|
|
211
|
+
setErrorMessage(`Edit failed: ${err.message}`);
|
|
212
|
+
setMenuState('list');
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
else if (editChoiceIndex === 1 && selectedMessage) {
|
|
216
|
+
// AI-assisted edit - update priority first if changed, then edit
|
|
217
|
+
handleAiEditStartWithPriority(selectedMessage.id, selectedPriority).catch((err) => {
|
|
218
|
+
setErrorMessage(`Edit failed: ${err.message}`);
|
|
219
|
+
setMenuState('list');
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
else if (key.escape) {
|
|
224
|
+
setMenuState('list');
|
|
225
|
+
}
|
|
226
|
+
}, { isActive: menuState === 'edit-choice' });
|
|
227
|
+
/**
|
|
228
|
+
* Handle keyboard input for AI edit request state (escape to cancel)
|
|
229
|
+
*/
|
|
230
|
+
useInput((_input, key) => {
|
|
231
|
+
if (key.escape) {
|
|
232
|
+
setAiEditRequest('');
|
|
233
|
+
setMenuState('list');
|
|
234
|
+
}
|
|
235
|
+
}, { isActive: menuState === 'ai-edit-request' });
|
|
236
|
+
/**
|
|
237
|
+
* Handle keyboard input for conversation state (escape to cancel)
|
|
238
|
+
*/
|
|
239
|
+
useInput((_input, key) => {
|
|
240
|
+
if (key.escape && !conversationThinking) {
|
|
241
|
+
handleConversationCancel();
|
|
242
|
+
}
|
|
243
|
+
}, { isActive: menuState === 'create-conversation' || menuState === 'create-description' });
|
|
244
|
+
/**
|
|
245
|
+
* Handle keyboard input for priority selection (create and edit)
|
|
246
|
+
*/
|
|
247
|
+
useInput((input, key) => {
|
|
248
|
+
if (showCustomPriority) {
|
|
249
|
+
// In custom priority input mode - only handle escape
|
|
250
|
+
if (key.escape) {
|
|
251
|
+
setShowCustomPriority(false);
|
|
252
|
+
setCustomPriorityInput('');
|
|
253
|
+
}
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
if (key.upArrow) {
|
|
257
|
+
setPrioritySelectIndex((prev) => Math.max(0, prev - 1));
|
|
258
|
+
}
|
|
259
|
+
else if (key.downArrow) {
|
|
260
|
+
setPrioritySelectIndex((prev) => Math.min(PRIORITY_PRESETS.length, prev + 1)); // +1 for custom option
|
|
261
|
+
}
|
|
262
|
+
else if (key.return) {
|
|
263
|
+
if (prioritySelectIndex < PRIORITY_PRESETS.length) {
|
|
264
|
+
// Selected a preset
|
|
265
|
+
const preset = PRIORITY_PRESETS[prioritySelectIndex];
|
|
266
|
+
if (preset) {
|
|
267
|
+
setSelectedPriority(preset.value);
|
|
268
|
+
if (menuState === 'create-priority') {
|
|
269
|
+
// Continue to description step
|
|
270
|
+
setMenuState('create-description');
|
|
271
|
+
}
|
|
272
|
+
else if (menuState === 'edit-priority') {
|
|
273
|
+
// Continue to edit choice
|
|
274
|
+
setMenuState('edit-choice');
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
else {
|
|
279
|
+
// Selected "Custom" option
|
|
280
|
+
setShowCustomPriority(true);
|
|
281
|
+
setCustomPriorityInput('');
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
else if (key.escape) {
|
|
285
|
+
setMenuState('list');
|
|
286
|
+
}
|
|
287
|
+
else if (input === 'c' || input === 'C') {
|
|
288
|
+
// Shortcut for custom priority
|
|
289
|
+
setShowCustomPriority(true);
|
|
290
|
+
setCustomPriorityInput('');
|
|
291
|
+
}
|
|
292
|
+
}, { isActive: (menuState === 'create-priority' || menuState === 'edit-priority') && !showCustomPriority });
|
|
293
|
+
/**
|
|
294
|
+
* Handle custom priority input submission
|
|
295
|
+
*/
|
|
296
|
+
const handleCustomPrioritySubmit = () => {
|
|
297
|
+
const value = parseInt(customPriorityInput, 10);
|
|
298
|
+
if (!isNaN(value) && value >= 1 && value <= 100) {
|
|
299
|
+
setSelectedPriority(value);
|
|
300
|
+
setShowCustomPriority(false);
|
|
301
|
+
setCustomPriorityInput('');
|
|
302
|
+
if (menuState === 'create-priority') {
|
|
303
|
+
setMenuState('create-description');
|
|
304
|
+
}
|
|
305
|
+
else if (menuState === 'edit-priority') {
|
|
306
|
+
setMenuState('edit-choice');
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
else {
|
|
310
|
+
setErrorMessage('Priority must be a number between 1 and 100');
|
|
311
|
+
}
|
|
312
|
+
};
|
|
313
|
+
/**
|
|
314
|
+
* Execute confirmed action
|
|
315
|
+
*/
|
|
316
|
+
const executeConfirmedAction = async (action) => {
|
|
317
|
+
setMenuState('loading');
|
|
318
|
+
setStatusMessage('');
|
|
319
|
+
setErrorMessage('');
|
|
320
|
+
try {
|
|
321
|
+
switch (action.type) {
|
|
322
|
+
case 'reset':
|
|
323
|
+
await handleReset(action.messageId);
|
|
324
|
+
break;
|
|
325
|
+
case 'delete':
|
|
326
|
+
await handleDelete(action.messageId);
|
|
327
|
+
break;
|
|
328
|
+
case 'create':
|
|
329
|
+
await handleLegacyCreate();
|
|
330
|
+
break;
|
|
331
|
+
case 'save-ai-edit':
|
|
332
|
+
await saveAiEdit(action.messageId, action.newContent);
|
|
333
|
+
break;
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
catch (error) {
|
|
337
|
+
setErrorMessage(error.message);
|
|
338
|
+
}
|
|
339
|
+
finally {
|
|
340
|
+
setMenuState('list');
|
|
341
|
+
}
|
|
342
|
+
};
|
|
343
|
+
/**
|
|
344
|
+
* Handle direct edit action - opens inline editor
|
|
345
|
+
*/
|
|
346
|
+
const handleDirectEdit = async (messageId) => {
|
|
347
|
+
const message = store.getMessage(messageId);
|
|
348
|
+
if (!message) {
|
|
349
|
+
setErrorMessage(`Message '${messageId}' not found`);
|
|
350
|
+
return;
|
|
351
|
+
}
|
|
352
|
+
try {
|
|
353
|
+
// Determine file path
|
|
354
|
+
let filePath;
|
|
355
|
+
// Special case: CORTEX.md is in .cortex/, not .cortex/system-messages/
|
|
356
|
+
// Uses same lookup logic as SystemMessageStore/SystemMessageLoader:
|
|
357
|
+
// 1. Project-level: {projectRoot}/.cortex/CORTEX.md
|
|
358
|
+
// 2. Global fallback: ~/.cortex/CORTEX.md
|
|
359
|
+
if (messageId === 'cortex') {
|
|
360
|
+
const fs = await import('fs/promises');
|
|
361
|
+
// Try project-level first
|
|
362
|
+
const projectRoot = path.dirname(path.dirname(runtimeDir));
|
|
363
|
+
const projectCortexPath = path.join(projectRoot, '.cortex', 'CORTEX.md');
|
|
364
|
+
try {
|
|
365
|
+
await fs.access(projectCortexPath);
|
|
366
|
+
filePath = projectCortexPath;
|
|
367
|
+
}
|
|
368
|
+
catch {
|
|
369
|
+
// Try global fallback
|
|
370
|
+
const homeDir = process.env.HOME || process.env.USERPROFILE || '~';
|
|
371
|
+
const globalCortexPath = path.join(homeDir, '.cortex', 'CORTEX.md');
|
|
372
|
+
try {
|
|
373
|
+
await fs.access(globalCortexPath);
|
|
374
|
+
filePath = globalCortexPath;
|
|
375
|
+
}
|
|
376
|
+
catch {
|
|
377
|
+
// Neither exists - use project path (will fail later with helpful error)
|
|
378
|
+
filePath = projectCortexPath;
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
else if (message.source === 'runtime') {
|
|
383
|
+
filePath = path.join(runtimeDir, message.path);
|
|
384
|
+
}
|
|
385
|
+
else if (message.source === 'builtin') {
|
|
386
|
+
// Create runtime override
|
|
387
|
+
const fileName = messageId.toUpperCase() + '.md';
|
|
388
|
+
filePath = path.join(runtimeDir, 'messages', fileName);
|
|
389
|
+
// Copy builtin to runtime if doesn't exist
|
|
390
|
+
const builtinPath = path.join(builtinDir, message.path);
|
|
391
|
+
const fs = await import('fs/promises');
|
|
392
|
+
try {
|
|
393
|
+
await fs.access(filePath);
|
|
394
|
+
}
|
|
395
|
+
catch {
|
|
396
|
+
// File doesn't exist, copy from builtin
|
|
397
|
+
const content = await fs.readFile(builtinPath, 'utf-8');
|
|
398
|
+
await fs.mkdir(path.dirname(filePath), { recursive: true });
|
|
399
|
+
await fs.writeFile(filePath, content, 'utf-8');
|
|
400
|
+
// Add to registry
|
|
401
|
+
const { SystemMessageRegistry } = await import('@nexus-cortex/core/system-messages/SystemMessageRegistry.js');
|
|
402
|
+
const registry = new SystemMessageRegistry(runtimeDir);
|
|
403
|
+
await registry.load();
|
|
404
|
+
const entry = SystemMessageRegistry.createEntry(messageId, message.type, `messages/${fileName}`, {
|
|
405
|
+
priority: message.priority,
|
|
406
|
+
description: message.metadata.description,
|
|
407
|
+
displayName: message.metadata.displayName,
|
|
408
|
+
});
|
|
409
|
+
await registry.add(entry);
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
else {
|
|
413
|
+
filePath = path.join(builtinDir, message.path);
|
|
414
|
+
}
|
|
415
|
+
// Load file content
|
|
416
|
+
const fs = await import('fs/promises');
|
|
417
|
+
const content = await fs.readFile(filePath, 'utf-8');
|
|
418
|
+
// Set editing state and open inline editor
|
|
419
|
+
setEditingMessage(message);
|
|
420
|
+
setEditingContent(content);
|
|
421
|
+
setEditingFilePath(filePath);
|
|
422
|
+
setMenuState('editing');
|
|
423
|
+
}
|
|
424
|
+
catch (error) {
|
|
425
|
+
setErrorMessage(`Failed to open editor: ${error.message}`);
|
|
426
|
+
setMenuState('list');
|
|
427
|
+
}
|
|
428
|
+
};
|
|
429
|
+
/**
|
|
430
|
+
* Start AI-assisted edit
|
|
431
|
+
*/
|
|
432
|
+
const handleAiEditStart = async (messageId) => {
|
|
433
|
+
const message = store.getMessage(messageId);
|
|
434
|
+
if (!message) {
|
|
435
|
+
setErrorMessage(`Message '${messageId}' not found`);
|
|
436
|
+
return;
|
|
437
|
+
}
|
|
438
|
+
try {
|
|
439
|
+
// Load current content
|
|
440
|
+
let filePath;
|
|
441
|
+
// Special case: CORTEX.md is in .cortex/, not .cortex/system-messages/
|
|
442
|
+
if (messageId === 'cortex') {
|
|
443
|
+
const projectRoot = path.dirname(path.dirname(runtimeDir));
|
|
444
|
+
filePath = path.join(projectRoot, message.path);
|
|
445
|
+
}
|
|
446
|
+
else if (message.source === 'runtime') {
|
|
447
|
+
filePath = path.join(runtimeDir, message.path);
|
|
448
|
+
}
|
|
449
|
+
else if (message.source === 'builtin') {
|
|
450
|
+
filePath = path.join(builtinDir, message.path);
|
|
451
|
+
}
|
|
452
|
+
else {
|
|
453
|
+
filePath = path.join(builtinDir, message.path);
|
|
454
|
+
}
|
|
455
|
+
const fs = await import('fs/promises');
|
|
456
|
+
const content = await fs.readFile(filePath, 'utf-8');
|
|
457
|
+
setEditingMessage(message);
|
|
458
|
+
setEditingContent(content);
|
|
459
|
+
setEditingFilePath(filePath);
|
|
460
|
+
setAiEditRequest('');
|
|
461
|
+
setAiEditResult(null);
|
|
462
|
+
setMenuState('ai-edit-request');
|
|
463
|
+
}
|
|
464
|
+
catch (error) {
|
|
465
|
+
setErrorMessage(`Failed to load message content: ${error.message}`);
|
|
466
|
+
setMenuState('list');
|
|
467
|
+
}
|
|
468
|
+
};
|
|
469
|
+
/**
|
|
470
|
+
* Update priority in registry if changed
|
|
471
|
+
*/
|
|
472
|
+
const updatePriorityIfChanged = async (messageId, newPriority) => {
|
|
473
|
+
const message = store.getMessage(messageId);
|
|
474
|
+
if (!message || message.priority === newPriority) {
|
|
475
|
+
return; // No change needed
|
|
476
|
+
}
|
|
477
|
+
try {
|
|
478
|
+
// Use the store's method to update priority (handles registry + in-memory update)
|
|
479
|
+
await store.updateMessagePriority(messageId, newPriority);
|
|
480
|
+
// Refresh local messages state
|
|
481
|
+
loadMessages();
|
|
482
|
+
setStatusMessage(`Priority updated to ${newPriority}`);
|
|
483
|
+
}
|
|
484
|
+
catch (error) {
|
|
485
|
+
console.error('Failed to update priority:', error);
|
|
486
|
+
setErrorMessage(`Failed to update priority: ${error.message}`);
|
|
487
|
+
}
|
|
488
|
+
};
|
|
489
|
+
/**
|
|
490
|
+
* Handle direct edit with priority update
|
|
491
|
+
*/
|
|
492
|
+
const handleDirectEditWithPriority = async (messageId, priority) => {
|
|
493
|
+
await updatePriorityIfChanged(messageId, priority);
|
|
494
|
+
await handleDirectEdit(messageId);
|
|
495
|
+
};
|
|
496
|
+
/**
|
|
497
|
+
* Handle AI-assisted edit with priority update
|
|
498
|
+
*/
|
|
499
|
+
const handleAiEditStartWithPriority = async (messageId, priority) => {
|
|
500
|
+
await updatePriorityIfChanged(messageId, priority);
|
|
501
|
+
await handleAiEditStart(messageId);
|
|
502
|
+
};
|
|
503
|
+
/**
|
|
504
|
+
* Handle AI edit request submission
|
|
505
|
+
*/
|
|
506
|
+
const handleAiEditSubmit = async () => {
|
|
507
|
+
if (!aiEditRequest.trim() || !editAssistant || !editingMessage) {
|
|
508
|
+
return;
|
|
509
|
+
}
|
|
510
|
+
setMenuState('ai-edit-processing');
|
|
511
|
+
setErrorMessage('');
|
|
512
|
+
try {
|
|
513
|
+
const result = await editAssistant(editingContent, aiEditRequest);
|
|
514
|
+
setAiEditResult(result);
|
|
515
|
+
// Show confirmation to save
|
|
516
|
+
setConfirmAction({
|
|
517
|
+
type: 'save-ai-edit',
|
|
518
|
+
messageId: editingMessage.id,
|
|
519
|
+
newContent: result.content,
|
|
520
|
+
});
|
|
521
|
+
setMenuState('confirm');
|
|
522
|
+
}
|
|
523
|
+
catch (error) {
|
|
524
|
+
setErrorMessage(`AI edit failed: ${error.message}`);
|
|
525
|
+
setMenuState('list');
|
|
526
|
+
}
|
|
527
|
+
};
|
|
528
|
+
/**
|
|
529
|
+
* Save AI-edited content
|
|
530
|
+
*/
|
|
531
|
+
const saveAiEdit = async (messageId, newContent) => {
|
|
532
|
+
const message = store.getMessage(messageId);
|
|
533
|
+
if (!message) {
|
|
534
|
+
throw new Error(`Message '${messageId}' not found`);
|
|
535
|
+
}
|
|
536
|
+
// Determine file path
|
|
537
|
+
let filePath;
|
|
538
|
+
if (message.source === 'runtime') {
|
|
539
|
+
filePath = path.join(runtimeDir, message.path);
|
|
540
|
+
}
|
|
541
|
+
else if (message.source === 'builtin') {
|
|
542
|
+
// Create runtime override
|
|
543
|
+
const fileName = messageId.toUpperCase() + '.md';
|
|
544
|
+
filePath = path.join(runtimeDir, 'messages', fileName);
|
|
545
|
+
// Ensure directory exists
|
|
546
|
+
const fs = await import('fs/promises');
|
|
547
|
+
await fs.mkdir(path.dirname(filePath), { recursive: true });
|
|
548
|
+
// Add to registry if new
|
|
549
|
+
const { SystemMessageRegistry } = await import('@nexus-cortex/core/system-messages/SystemMessageRegistry.js');
|
|
550
|
+
const registry = new SystemMessageRegistry(runtimeDir);
|
|
551
|
+
await registry.load();
|
|
552
|
+
try {
|
|
553
|
+
await fs.access(filePath);
|
|
554
|
+
}
|
|
555
|
+
catch {
|
|
556
|
+
// File doesn't exist, add to registry
|
|
557
|
+
const entry = SystemMessageRegistry.createEntry(messageId, message.type, `messages/${fileName}`, {
|
|
558
|
+
priority: message.priority,
|
|
559
|
+
description: message.metadata.description,
|
|
560
|
+
displayName: message.metadata.displayName,
|
|
561
|
+
});
|
|
562
|
+
await registry.add(entry);
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
else {
|
|
566
|
+
throw new Error('Cannot edit workspace messages');
|
|
567
|
+
}
|
|
568
|
+
// Write file
|
|
569
|
+
const fs = await import('fs/promises');
|
|
570
|
+
await fs.writeFile(filePath, newContent, 'utf-8');
|
|
571
|
+
// Immediately reload the message in the store to pick up content changes (like displayName)
|
|
572
|
+
await store.reloadMessageFile(filePath, 'runtime');
|
|
573
|
+
const summary = aiEditResult?.summary || 'Content updated';
|
|
574
|
+
setStatusMessage(`Message '${messageId}' updated: ${summary}`);
|
|
575
|
+
// Clear editing state
|
|
576
|
+
setEditingMessage(null);
|
|
577
|
+
setEditingContent('');
|
|
578
|
+
setEditingFilePath('');
|
|
579
|
+
setAiEditRequest('');
|
|
580
|
+
setAiEditResult(null);
|
|
581
|
+
// Refresh list to show updated data
|
|
582
|
+
loadMessages();
|
|
583
|
+
};
|
|
584
|
+
/**
|
|
585
|
+
* Handle save from inline editor
|
|
586
|
+
*/
|
|
587
|
+
const handleEditorSave = async (newContent) => {
|
|
588
|
+
if (!editingFilePath || !editingMessage) {
|
|
589
|
+
return;
|
|
590
|
+
}
|
|
591
|
+
try {
|
|
592
|
+
// Write file
|
|
593
|
+
const fs = await import('fs/promises');
|
|
594
|
+
await fs.writeFile(editingFilePath, newContent, 'utf-8');
|
|
595
|
+
// Immediately reload the message in the store to pick up content changes (like displayName)
|
|
596
|
+
await store.reloadMessageFile(editingFilePath, 'runtime');
|
|
597
|
+
setStatusMessage(`Message '${editingMessage.id}' saved successfully`);
|
|
598
|
+
setMenuState('list');
|
|
599
|
+
// Clear editing state
|
|
600
|
+
setEditingMessage(null);
|
|
601
|
+
setEditingContent('');
|
|
602
|
+
setEditingFilePath('');
|
|
603
|
+
// Refresh list to show updated data
|
|
604
|
+
loadMessages();
|
|
605
|
+
}
|
|
606
|
+
catch (error) {
|
|
607
|
+
setErrorMessage(`Failed to save: ${error.message}`);
|
|
608
|
+
setMenuState('list');
|
|
609
|
+
}
|
|
610
|
+
};
|
|
611
|
+
/**
|
|
612
|
+
* Handle cancel from inline editor
|
|
613
|
+
*/
|
|
614
|
+
const handleEditorCancel = () => {
|
|
615
|
+
setMenuState('list');
|
|
616
|
+
// Clear editing state
|
|
617
|
+
setEditingMessage(null);
|
|
618
|
+
setEditingContent('');
|
|
619
|
+
setEditingFilePath('');
|
|
620
|
+
};
|
|
621
|
+
/**
|
|
622
|
+
* Handle toggle action
|
|
623
|
+
*/
|
|
624
|
+
const handleToggle = async (messageId) => {
|
|
625
|
+
try {
|
|
626
|
+
const newState = await store.toggleEnabled(messageId);
|
|
627
|
+
setStatusMessage(`Message '${messageId}' ${newState ? 'enabled' : 'disabled'}`);
|
|
628
|
+
loadMessages(); // Refresh list
|
|
629
|
+
}
|
|
630
|
+
catch (error) {
|
|
631
|
+
setErrorMessage(error.message);
|
|
632
|
+
}
|
|
633
|
+
};
|
|
634
|
+
/**
|
|
635
|
+
* Handle reset action
|
|
636
|
+
*/
|
|
637
|
+
const handleReset = async (messageId) => {
|
|
638
|
+
try {
|
|
639
|
+
await store.resetToDefault(messageId);
|
|
640
|
+
setStatusMessage(`Message '${messageId}' reset to default`);
|
|
641
|
+
loadMessages();
|
|
642
|
+
}
|
|
643
|
+
catch (error) {
|
|
644
|
+
setErrorMessage(error.message);
|
|
645
|
+
}
|
|
646
|
+
};
|
|
647
|
+
/**
|
|
648
|
+
* Handle delete action
|
|
649
|
+
*/
|
|
650
|
+
const handleDelete = async (messageId) => {
|
|
651
|
+
try {
|
|
652
|
+
await store.deleteMessage(messageId);
|
|
653
|
+
setStatusMessage(`Message '${messageId}' deleted`);
|
|
654
|
+
loadMessages();
|
|
655
|
+
// Adjust selection if needed
|
|
656
|
+
if (selectedIndex >= messages.length - 1) {
|
|
657
|
+
setSelectedIndex(Math.max(0, messages.length - 2));
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
catch (error) {
|
|
661
|
+
setErrorMessage(error.message);
|
|
662
|
+
}
|
|
663
|
+
};
|
|
664
|
+
/**
|
|
665
|
+
* Handle legacy create action (no AI)
|
|
666
|
+
*/
|
|
667
|
+
const handleLegacyCreate = async () => {
|
|
668
|
+
const id = `custom_${Date.now()}`;
|
|
669
|
+
try {
|
|
670
|
+
await store.createMessage({
|
|
671
|
+
id,
|
|
672
|
+
type: 'instruction',
|
|
673
|
+
displayName: `Custom Message ${Date.now()}`,
|
|
674
|
+
description: 'Custom system message',
|
|
675
|
+
priority: 50,
|
|
676
|
+
});
|
|
677
|
+
setStatusMessage(`Created new message '${id}' - edit to customize`);
|
|
678
|
+
loadMessages();
|
|
679
|
+
// Select the new message
|
|
680
|
+
const newIndex = messages.findIndex((m) => m.id === id);
|
|
681
|
+
if (newIndex !== -1) {
|
|
682
|
+
setSelectedIndex(newIndex);
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
catch (error) {
|
|
686
|
+
setErrorMessage(error.message);
|
|
687
|
+
}
|
|
688
|
+
};
|
|
689
|
+
/**
|
|
690
|
+
* Handle description submission - starts conversation
|
|
691
|
+
*/
|
|
692
|
+
const handleDescriptionSubmit = async () => {
|
|
693
|
+
if (!createDescription.trim()) {
|
|
694
|
+
setErrorMessage('Please enter a description for your system message');
|
|
695
|
+
return;
|
|
696
|
+
}
|
|
697
|
+
setErrorMessage('');
|
|
698
|
+
// Start the conversation flow
|
|
699
|
+
if (conversationalCreator) {
|
|
700
|
+
const initialMessage = {
|
|
701
|
+
role: 'user',
|
|
702
|
+
content: createDescription,
|
|
703
|
+
};
|
|
704
|
+
setConversationMessages([initialMessage]);
|
|
705
|
+
setConversationThinking(true);
|
|
706
|
+
setMenuState('create-conversation');
|
|
707
|
+
// Get first AI response (likely a clarifying question)
|
|
708
|
+
try {
|
|
709
|
+
const response = await conversationalCreator([initialMessage]);
|
|
710
|
+
setConversationThinking(false);
|
|
711
|
+
if (response.type === 'profile' && response.profile) {
|
|
712
|
+
// AI generated profile directly without questions
|
|
713
|
+
await createMessageFromProfile(response.profile);
|
|
714
|
+
}
|
|
715
|
+
else if (response.type === 'question' && response.question) {
|
|
716
|
+
// AI is asking a clarifying question
|
|
717
|
+
const questionText = response.question;
|
|
718
|
+
setConversationMessages((prev) => [
|
|
719
|
+
...prev,
|
|
720
|
+
{ role: 'assistant', content: questionText },
|
|
721
|
+
]);
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
catch (error) {
|
|
725
|
+
setConversationThinking(false);
|
|
726
|
+
setErrorMessage(`AI error: ${error.message}`);
|
|
727
|
+
setMenuState('list');
|
|
728
|
+
}
|
|
729
|
+
return;
|
|
730
|
+
}
|
|
731
|
+
// Fallback to legacy one-shot generation
|
|
732
|
+
setMenuState('create-generating');
|
|
733
|
+
setGeneratingMessage('Generating system message...');
|
|
734
|
+
try {
|
|
735
|
+
let profile;
|
|
736
|
+
if (generateProfile) {
|
|
737
|
+
// Use AI to generate the profile
|
|
738
|
+
profile = await generateProfile(createDescription);
|
|
739
|
+
}
|
|
740
|
+
else {
|
|
741
|
+
// Fallback: Create a basic profile
|
|
742
|
+
const safeId = createDescription
|
|
743
|
+
.toLowerCase()
|
|
744
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
745
|
+
.replace(/^-|-$/g, '')
|
|
746
|
+
.slice(0, 48) || `message-${Date.now()}`;
|
|
747
|
+
profile = {
|
|
748
|
+
id: safeId,
|
|
749
|
+
type: 'instruction',
|
|
750
|
+
displayName: createDescription.slice(0, 50),
|
|
751
|
+
description: createDescription.slice(0, 200),
|
|
752
|
+
priority: 50,
|
|
753
|
+
content: `# ${createDescription.slice(0, 50)}\n\n${createDescription}\n\n## Guidelines\n\n- Follow the instructions above\n- Be thorough and consistent`,
|
|
754
|
+
};
|
|
755
|
+
}
|
|
756
|
+
await createMessageFromProfile(profile);
|
|
757
|
+
}
|
|
758
|
+
catch (error) {
|
|
759
|
+
setErrorMessage(`Failed to create message: ${error.message}`);
|
|
760
|
+
setMenuState('list');
|
|
761
|
+
}
|
|
762
|
+
};
|
|
763
|
+
/**
|
|
764
|
+
* Handle user response in conversation flow
|
|
765
|
+
*/
|
|
766
|
+
const handleConversationSubmit = async () => {
|
|
767
|
+
if (!conversationInput.trim() || !conversationalCreator) {
|
|
768
|
+
return;
|
|
769
|
+
}
|
|
770
|
+
// Add user message to conversation
|
|
771
|
+
const userMessage = {
|
|
772
|
+
role: 'user',
|
|
773
|
+
content: conversationInput,
|
|
774
|
+
};
|
|
775
|
+
const updatedMessages = [...conversationMessages, userMessage];
|
|
776
|
+
setConversationMessages(updatedMessages);
|
|
777
|
+
setConversationInput('');
|
|
778
|
+
setConversationThinking(true);
|
|
779
|
+
setErrorMessage('');
|
|
780
|
+
try {
|
|
781
|
+
const response = await conversationalCreator(updatedMessages);
|
|
782
|
+
setConversationThinking(false);
|
|
783
|
+
if (response.type === 'profile' && response.profile) {
|
|
784
|
+
// AI generated the final profile
|
|
785
|
+
await createMessageFromProfile(response.profile);
|
|
786
|
+
}
|
|
787
|
+
else if (response.type === 'question' && response.question) {
|
|
788
|
+
// AI is asking another clarifying question
|
|
789
|
+
const questionText = response.question;
|
|
790
|
+
setConversationMessages((prev) => [
|
|
791
|
+
...prev,
|
|
792
|
+
{ role: 'assistant', content: questionText },
|
|
793
|
+
]);
|
|
794
|
+
}
|
|
795
|
+
}
|
|
796
|
+
catch (error) {
|
|
797
|
+
setConversationThinking(false);
|
|
798
|
+
setErrorMessage(`AI error: ${error.message}`);
|
|
799
|
+
}
|
|
800
|
+
};
|
|
801
|
+
/**
|
|
802
|
+
* Create message from generated profile
|
|
803
|
+
*/
|
|
804
|
+
const createMessageFromProfile = async (profile) => {
|
|
805
|
+
setMenuState('create-generating');
|
|
806
|
+
setGeneratingMessage('Saving system message...');
|
|
807
|
+
try {
|
|
808
|
+
// Create the message file
|
|
809
|
+
const fileName = profile.id.toUpperCase() + '.md';
|
|
810
|
+
const filePath = path.join(runtimeDir, 'messages', fileName);
|
|
811
|
+
const fs = await import('fs/promises');
|
|
812
|
+
await fs.mkdir(path.dirname(filePath), { recursive: true });
|
|
813
|
+
await fs.writeFile(filePath, profile.content, 'utf-8');
|
|
814
|
+
// Add to registry
|
|
815
|
+
const { SystemMessageRegistry } = await import('@nexus-cortex/core/system-messages/SystemMessageRegistry.js');
|
|
816
|
+
const registry = new SystemMessageRegistry(runtimeDir);
|
|
817
|
+
await registry.load();
|
|
818
|
+
const entry = SystemMessageRegistry.createEntry(profile.id, profile.type, `messages/${fileName}`, {
|
|
819
|
+
priority: selectedPriority, // Use user-selected priority
|
|
820
|
+
description: profile.description,
|
|
821
|
+
displayName: profile.displayName,
|
|
822
|
+
});
|
|
823
|
+
await registry.add(entry);
|
|
824
|
+
// Immediately reload the new message in the store
|
|
825
|
+
await store.reloadMessageFile(filePath, 'runtime');
|
|
826
|
+
setStatusMessage(`Created system message '${profile.id}' successfully!`);
|
|
827
|
+
// Reset all creation state
|
|
828
|
+
resetCreationState();
|
|
829
|
+
setMenuState('list');
|
|
830
|
+
// Refresh list and select the new message
|
|
831
|
+
loadMessages();
|
|
832
|
+
setTimeout(() => {
|
|
833
|
+
const newIndex = store.getAll().findIndex((m) => m.id === profile.id);
|
|
834
|
+
if (newIndex !== -1) {
|
|
835
|
+
setSelectedIndex(newIndex);
|
|
836
|
+
}
|
|
837
|
+
}, 50);
|
|
838
|
+
}
|
|
839
|
+
catch (error) {
|
|
840
|
+
setErrorMessage(`Failed to create message: ${error.message}`);
|
|
841
|
+
setMenuState('list');
|
|
842
|
+
}
|
|
843
|
+
};
|
|
844
|
+
/**
|
|
845
|
+
* Reset all creation-related state
|
|
846
|
+
*/
|
|
847
|
+
const resetCreationState = () => {
|
|
848
|
+
setCreateDescription('');
|
|
849
|
+
setConversationMessages([]);
|
|
850
|
+
setConversationInput('');
|
|
851
|
+
setConversationThinking(false);
|
|
852
|
+
setGeneratingMessage('');
|
|
853
|
+
};
|
|
854
|
+
/**
|
|
855
|
+
* Cancel conversation and return to list
|
|
856
|
+
*/
|
|
857
|
+
const handleConversationCancel = () => {
|
|
858
|
+
resetCreationState();
|
|
859
|
+
setMenuState('list');
|
|
860
|
+
};
|
|
861
|
+
/**
|
|
862
|
+
* Render priority selection
|
|
863
|
+
*/
|
|
864
|
+
const renderPrioritySelection = () => {
|
|
865
|
+
const isEditing = menuState === 'edit-priority';
|
|
866
|
+
const title = isEditing
|
|
867
|
+
? `Set Priority for '${selectedMessage?.metadata?.displayName || selectedMessage?.id}'`
|
|
868
|
+
: 'Step 1: Select Priority';
|
|
869
|
+
return (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { bold: true, color: "cyan", children: title }) }), isEditing && selectedMessage && (_jsx(Box, { marginBottom: 1, flexDirection: "column", children: _jsxs(Box, { children: [_jsx(Text, { dimColor: true, children: "Current priority: " }), _jsx(Text, { color: selectedMessage.priority === 0 ? 'red' : 'yellow', children: selectedMessage.priority }), selectedMessage.priority === 0 && (_jsx(Text, { color: "red", bold: true, children: " (EXCLUDED FROM INJECTION)" }))] }) })), _jsx(Box, { marginBottom: 1, children: _jsx(Text, { children: "Select priority level (lower number = injected first):" }) }), showCustomPriority ? (_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsxs(Box, { borderStyle: "single", borderColor: "cyan", paddingX: 1, children: [_jsx(Text, { color: "cyan", children: "Custom priority (1-100): " }), _jsx(TextInput, { value: customPriorityInput, onChange: setCustomPriorityInput, onSubmit: handleCustomPrioritySubmit, placeholder: "e.g., 75" })] }), errorMessage && (_jsx(Box, { marginTop: 1, children: _jsx(Text, { color: "red", children: errorMessage }) }))] })) : (_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [PRIORITY_PRESETS.map((preset, index) => {
|
|
870
|
+
const isSelected = index === prioritySelectIndex;
|
|
871
|
+
return (_jsxs(Box, { paddingLeft: isSelected ? 0 : 2, children: [isSelected && _jsx(Text, { color: "cyan", bold: true, children: '> ' }), _jsx(Text, { bold: isSelected, color: isSelected ? 'cyan' : undefined, children: preset.label }), _jsxs(Text, { dimColor: true, children: [" - ", preset.description] })] }, preset.value));
|
|
872
|
+
}), _jsxs(Box, { paddingLeft: prioritySelectIndex === PRIORITY_PRESETS.length ? 0 : 2, children: [prioritySelectIndex === PRIORITY_PRESETS.length && _jsx(Text, { color: "cyan", bold: true, children: '> ' }), _jsx(Text, { bold: prioritySelectIndex === PRIORITY_PRESETS.length, color: prioritySelectIndex === PRIORITY_PRESETS.length ? 'cyan' : undefined, children: "Custom..." }), _jsx(Text, { dimColor: true, children: " - Enter a specific priority value" })] })] })), _jsx(Box, { borderStyle: "single", borderColor: "gray", paddingX: 1, children: _jsx(Text, { dimColor: true, children: showCustomPriority
|
|
873
|
+
? 'Enter: Confirm | Esc: Back to presets'
|
|
874
|
+
: `${String.fromCharCode(8593)}/${String.fromCharCode(8595)}: Navigate | Enter: Select | C: Custom | Esc: Cancel` }) })] }));
|
|
875
|
+
};
|
|
876
|
+
const renderEditChoice = () => {
|
|
877
|
+
if (!selectedMessage)
|
|
878
|
+
return null;
|
|
879
|
+
const choices = [
|
|
880
|
+
{ label: 'Edit directly', description: 'Open in inline editor for manual editing' },
|
|
881
|
+
{ label: 'AI-assisted edit', description: 'Describe changes and let AI update the content' },
|
|
882
|
+
];
|
|
883
|
+
return (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Box, { marginBottom: 1, children: _jsxs(Text, { bold: true, color: "cyan", children: ["Edit '", selectedMessage.id, "'"] }) }), _jsx(Box, { marginBottom: 1, children: _jsx(Text, { children: "How would you like to edit this system message?" }) }), _jsx(Box, { flexDirection: "column", marginBottom: 1, children: choices.map((choice, index) => {
|
|
884
|
+
const isSelected = index === editChoiceIndex;
|
|
885
|
+
return (_jsxs(Box, { paddingLeft: isSelected ? 0 : 2, children: [isSelected && _jsx(Text, { color: "cyan", bold: true, children: '> ' }), _jsx(Text, { bold: isSelected, color: isSelected ? 'cyan' : undefined, children: choice.label }), _jsxs(Text, { dimColor: true, children: [" - ", choice.description] })] }, choice.label));
|
|
886
|
+
}) }), _jsx(Box, { borderStyle: "single", borderColor: "gray", paddingX: 1, children: _jsxs(Text, { dimColor: true, children: [String.fromCharCode(8593), "/", String.fromCharCode(8595), ": Navigate | Enter: Select | Esc: Cancel"] }) })] }));
|
|
887
|
+
};
|
|
888
|
+
/**
|
|
889
|
+
* Render AI edit request input
|
|
890
|
+
*/
|
|
891
|
+
const renderAiEditRequest = () => {
|
|
892
|
+
if (!editingMessage)
|
|
893
|
+
return null;
|
|
894
|
+
return (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Box, { marginBottom: 1, children: _jsxs(Text, { bold: true, color: "cyan", children: ["AI-Assisted Edit: '", editingMessage.id, "'"] }) }), _jsxs(Box, { marginBottom: 1, flexDirection: "column", children: [_jsx(Text, { children: "Describe what changes you want to make:" }), _jsx(Text, { dimColor: true, children: "(e.g., \"Add a section about error handling\", \"Make the tone more formal\")" })] }), _jsx(Box, { borderStyle: "single", borderColor: "cyan", paddingX: 1, paddingY: 0, children: _jsx(TextInput, { value: aiEditRequest, onChange: setAiEditRequest, onSubmit: handleAiEditSubmit, placeholder: "E.g., Add examples for edge cases, simplify the language, restructure into clearer sections..." }) }), errorMessage && (_jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: "red", children: ['!', " ", errorMessage] }) })), _jsx(Box, { borderStyle: "single", borderColor: "gray", paddingX: 1, marginTop: 1, children: _jsx(Text, { dimColor: true, children: "Enter: Generate Changes | Esc: Cancel" }) })] }));
|
|
895
|
+
};
|
|
896
|
+
/**
|
|
897
|
+
* Render AI edit processing state
|
|
898
|
+
*/
|
|
899
|
+
const renderAiEditProcessing = () => {
|
|
900
|
+
return (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { bold: true, color: "cyan", children: "Processing Your Edit Request" }) }), _jsxs(Box, { marginBottom: 1, children: [_jsx(Text, { color: "cyan", children: _jsx(Spinner, { type: "dots" }) }), _jsx(Text, { children: " AI is analyzing and updating the content..." })] }), _jsx(Box, { marginTop: 1, borderStyle: "single", borderColor: "gray", paddingX: 1, children: _jsxs(Text, { dimColor: true, children: ["Request: \"", aiEditRequest, "\""] }) })] }));
|
|
901
|
+
};
|
|
902
|
+
/**
|
|
903
|
+
* Render confirmation prompt
|
|
904
|
+
*/
|
|
905
|
+
const renderConfirmation = () => {
|
|
906
|
+
if (!confirmAction)
|
|
907
|
+
return null;
|
|
908
|
+
let promptText = '';
|
|
909
|
+
let warningText = '';
|
|
910
|
+
switch (confirmAction.type) {
|
|
911
|
+
case 'reset':
|
|
912
|
+
promptText = `Reset message '${confirmAction.messageId}' to builtin default?`;
|
|
913
|
+
warningText = 'Your custom changes will be lost.';
|
|
914
|
+
break;
|
|
915
|
+
case 'delete':
|
|
916
|
+
promptText = `Delete message '${confirmAction.messageId}'?`;
|
|
917
|
+
warningText = 'This action cannot be undone.';
|
|
918
|
+
break;
|
|
919
|
+
case 'create':
|
|
920
|
+
promptText = 'Create new custom message?';
|
|
921
|
+
break;
|
|
922
|
+
case 'save-ai-edit':
|
|
923
|
+
promptText = `Save AI-generated changes to '${confirmAction.messageId}'?`;
|
|
924
|
+
if (aiEditResult?.summary) {
|
|
925
|
+
warningText = `Changes: ${aiEditResult.summary}`;
|
|
926
|
+
}
|
|
927
|
+
break;
|
|
928
|
+
}
|
|
929
|
+
return (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { bold: true, color: "yellow", children: "Confirmation Required" }) }), _jsx(Box, { marginBottom: warningText ? 1 : 0, children: _jsx(Text, { children: promptText }) }), warningText && (_jsx(Box, { marginBottom: 1, children: _jsx(Text, { dimColor: true, children: warningText }) })), _jsx(Box, { children: _jsxs(Text, { children: ["Press ", _jsx(Text, { bold: true, color: "green", children: "Y" }), " to confirm, ", _jsx(Text, { bold: true, color: "red", children: "N" }), " to cancel"] }) })] }));
|
|
930
|
+
};
|
|
931
|
+
/**
|
|
932
|
+
* Render description input step
|
|
933
|
+
*/
|
|
934
|
+
const renderDescriptionInput = () => {
|
|
935
|
+
return (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { bold: true, color: "cyan", children: "Create New System Message" }) }), _jsxs(Box, { marginBottom: 1, flexDirection: "column", children: [_jsx(Text, { children: "Describe the system message you want to create:" }), _jsx(Text, { dimColor: true, children: "(What should it instruct, constrain, or provide context about?)" })] }), _jsx(Box, { borderStyle: "single", borderColor: "cyan", paddingX: 1, paddingY: 0, children: _jsx(TextInput, { value: createDescription, onChange: setCreateDescription, onSubmit: handleDescriptionSubmit, placeholder: "E.g., A code style guide for TypeScript that enforces consistent naming conventions..." }) }), errorMessage && (_jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: "red", children: ['!', " ", errorMessage] }) })), _jsx(Box, { borderStyle: "single", borderColor: "gray", paddingX: 1, marginTop: 1, children: _jsx(Text, { dimColor: true, children: "Enter: Continue | Esc: Cancel" }) })] }));
|
|
936
|
+
};
|
|
937
|
+
/**
|
|
938
|
+
* Render conversation mode - multi-turn creation
|
|
939
|
+
*/
|
|
940
|
+
const renderConversation = () => {
|
|
941
|
+
return (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { bold: true, color: "cyan", children: "Creating System Message - Conversation" }) }), _jsx(Box, { marginBottom: 1, children: _jsx(Text, { dimColor: true, children: "Answer the AI's questions to refine your system message" }) }), _jsxs(Box, { flexDirection: "column", borderStyle: "single", borderColor: "gray", paddingX: 1, paddingY: 1, marginBottom: 1, children: [conversationMessages.map((msg, index) => (_jsx(Box, { marginBottom: index < conversationMessages.length - 1 ? 1 : 0, children: msg.role === 'user' ? (_jsxs(Box, { children: [_jsx(Text, { color: "blue", bold: true, children: "You: " }), _jsx(Text, { children: msg.content })] })) : (_jsxs(Box, { children: [_jsx(Text, { color: "magenta", bold: true, children: "AI: " }), _jsx(Text, { children: msg.content })] })) }, index))), conversationThinking && (_jsxs(Box, { marginTop: 1, children: [_jsx(Text, { color: "cyan", children: _jsx(Spinner, { type: "dots" }) }), _jsx(Text, { dimColor: true, children: " AI is thinking..." })] }))] }), !conversationThinking && (_jsxs(Box, { borderStyle: "single", borderColor: "cyan", paddingX: 1, children: [_jsxs(Text, { color: "cyan", children: ['>', " "] }), _jsx(TextInput, { value: conversationInput, onChange: setConversationInput, onSubmit: handleConversationSubmit, placeholder: "Type your response..." })] })), errorMessage && (_jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: "red", children: ['!', " ", errorMessage] }) })), _jsx(Box, { borderStyle: "single", borderColor: "gray", paddingX: 1, marginTop: 1, children: _jsx(Text, { dimColor: true, children: "Enter: Submit response | Esc: Cancel creation" }) })] }));
|
|
942
|
+
};
|
|
943
|
+
/**
|
|
944
|
+
* Render generating state
|
|
945
|
+
*/
|
|
946
|
+
const renderGenerating = () => {
|
|
947
|
+
return (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { bold: true, color: "cyan", children: "Creating Your System Message" }) }), _jsxs(Box, { marginBottom: 1, children: [_jsx(Text, { color: "cyan", children: _jsx(Spinner, { type: "dots" }) }), _jsxs(Text, { children: [" ", generatingMessage] })] }), _jsx(Box, { marginTop: 1, borderStyle: "single", borderColor: "gray", paddingX: 1, children: _jsx(Text, { dimColor: true, children: "The AI is generating a detailed system message based on your description..." }) })] }));
|
|
948
|
+
};
|
|
949
|
+
/**
|
|
950
|
+
* Render message list
|
|
951
|
+
*/
|
|
952
|
+
const renderList = () => {
|
|
953
|
+
if (messages.length === 0) {
|
|
954
|
+
return (_jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, children: "No messages found" }) }));
|
|
955
|
+
}
|
|
956
|
+
return (_jsx(Box, { flexDirection: "column", marginTop: 1, children: messages.map((msg, index) => {
|
|
957
|
+
const isSelected = index === selectedIndex;
|
|
958
|
+
const enabledIcon = msg.enabled ? String.fromCharCode(10003) : String.fromCharCode(10007);
|
|
959
|
+
const sourceIcon = msg.source === 'runtime' ? String.fromCharCode(9998) :
|
|
960
|
+
msg.source === 'workspace' ? String.fromCharCode(9881) :
|
|
961
|
+
String.fromCharCode(128230);
|
|
962
|
+
// Priority 0 means excluded from injection
|
|
963
|
+
const isExcluded = msg.priority === 0;
|
|
964
|
+
return (_jsxs(Box, { paddingLeft: isSelected ? 0 : 2, children: [isSelected && _jsxs(Text, { color: "cyan", bold: true, children: [String.fromCharCode(9654), " "] }), _jsx(Text, { color: msg.enabled ? 'green' : 'red', children: enabledIcon }), _jsx(Text, { children: " " }), _jsx(Text, { children: sourceIcon }), _jsx(Text, { children: " " }), _jsx(Text, { bold: isSelected, color: isSelected ? 'cyan' : isExcluded ? 'gray' : undefined, strikethrough: isExcluded, children: msg.metadata?.displayName || msg.id }), isExcluded ? (_jsx(Text, { color: "yellow", children: " (DISABLED - priority 0)" })) : (_jsxs(Text, { dimColor: true, children: [" (", msg.type, ", priority: ", msg.priority, ")"] }))] }, msg.id));
|
|
965
|
+
}) }));
|
|
966
|
+
};
|
|
967
|
+
/**
|
|
968
|
+
* Render status bar
|
|
969
|
+
*/
|
|
970
|
+
const renderStatusBar = () => {
|
|
971
|
+
const hasAI = conversationalCreator || generateProfile;
|
|
972
|
+
return (_jsxs(Box, { flexDirection: "column", marginTop: 1, borderStyle: "single", borderColor: "gray", paddingX: 1, children: [_jsx(Box, { justifyContent: "space-between", children: _jsxs(Text, { dimColor: true, children: [String.fromCharCode(8593), "/", String.fromCharCode(8595), ": Navigate | Enter: Edit | Space: Toggle | +: New", hasAI ? ' (AI)' : '', " | R: Reset | D: Delete | Q: Quit"] }) }), statusMessage && (_jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: "green", children: [String.fromCharCode(10003), " ", statusMessage] }) })), errorMessage && (_jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: "red", children: [String.fromCharCode(10007), " ", errorMessage] }) })), selectedMessage && (_jsx(Box, { marginTop: 1, children: _jsxs(Text, { dimColor: true, children: ["Selected: ", selectedMessage.id, " | Source: ", selectedMessage.source, " |", ' ', "Path: ", selectedMessage.path] }) }))] }));
|
|
973
|
+
};
|
|
974
|
+
/**
|
|
975
|
+
* Main render
|
|
976
|
+
*/
|
|
977
|
+
return (_jsxs(Box, { flexDirection: "column", padding: menuState === 'editing' ? 0 : 1, children: [menuState === 'editing' && editingContent && editingFilePath && (_jsx(InlineEditor, { content: editingContent, filePath: editingFilePath, onSave: handleEditorSave, onCancel: handleEditorCancel })), menuState !== 'editing' && (_jsxs(_Fragment, { children: [_jsxs(Box, { borderStyle: "bold", borderColor: "cyan", paddingX: 1, children: [_jsx(Text, { bold: true, color: "cyan", children: "System Message Manager" }), _jsx(Text, { children: " " }), _jsxs(Text, { dimColor: true, children: ["(", messages.length, " messages)"] }), (conversationalCreator || generateProfile) && (_jsx(Text, { color: "magenta", children: " [AI-Assisted]" }))] }), menuState === 'loading' && (_jsxs(Box, { marginTop: 1, children: [_jsx(Text, { color: "cyan", children: _jsx(Spinner, { type: "dots" }) }), _jsx(Text, { children: " Processing..." })] })), (menuState === 'create-priority' || menuState === 'edit-priority') && renderPrioritySelection(), menuState === 'edit-choice' && renderEditChoice(), menuState === 'ai-edit-request' && renderAiEditRequest(), menuState === 'ai-edit-processing' && renderAiEditProcessing(), menuState === 'confirm' && renderConfirmation(), menuState === 'create-description' && renderDescriptionInput(), menuState === 'create-conversation' && renderConversation(), menuState === 'create-generating' && renderGenerating(), menuState === 'list' && renderList(), menuState === 'list' && renderStatusBar()] }))] }));
|
|
978
|
+
};
|
|
979
|
+
//# sourceMappingURL=InteractiveMenu.js.map
|