@within-7/minto 0.1.7 → 0.3.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/cli.js +155 -37
- package/dist/Tool.js +38 -0
- package/dist/Tool.js.map +3 -3
- package/dist/commands/agents/AgentsCommand.js +73 -49
- package/dist/commands/agents/AgentsCommand.js.map +2 -2
- package/dist/commands/agents/constants.js +1 -1
- package/dist/commands/agents/constants.js.map +1 -1
- package/dist/commands/agents/index.js +1 -1
- package/dist/commands/bug.js +74 -7
- package/dist/commands/bug.js.map +3 -3
- package/dist/commands/clear.js +3 -0
- package/dist/commands/clear.js.map +2 -2
- package/dist/commands/compact.js +37 -0
- package/dist/commands/compact.js.map +2 -2
- package/dist/commands/context.js +85 -0
- package/dist/commands/context.js.map +7 -0
- package/dist/commands/ctx_viz.js +18 -10
- package/dist/commands/ctx_viz.js.map +2 -2
- package/dist/commands/doctor.js +158 -12
- package/dist/commands/doctor.js.map +2 -2
- package/dist/commands/export.js +157 -0
- package/dist/commands/export.js.map +7 -0
- package/dist/commands/mcp-interactive.js +28 -18
- package/dist/commands/mcp-interactive.js.map +2 -2
- package/dist/commands/model.js +9 -7
- package/dist/commands/model.js.map +2 -2
- package/dist/commands/permissions.js +87 -0
- package/dist/commands/permissions.js.map +7 -0
- package/dist/commands/plugin/AddMarketplaceForm.js +3 -2
- package/dist/commands/plugin/AddMarketplaceForm.js.map +2 -2
- package/dist/commands/plugin/ConfirmDialog.js +2 -1
- package/dist/commands/plugin/ConfirmDialog.js.map +2 -2
- package/dist/commands/plugin/ErrorView.js +2 -1
- package/dist/commands/plugin/ErrorView.js.map +2 -2
- package/dist/commands/plugin/InstalledPluginsByMarketplace.js +5 -4
- package/dist/commands/plugin/InstalledPluginsByMarketplace.js.map +2 -2
- package/dist/commands/plugin/InstalledPluginsManager.js +5 -4
- package/dist/commands/plugin/InstalledPluginsManager.js.map +2 -2
- package/dist/commands/plugin/MainMenu.js +2 -1
- package/dist/commands/plugin/MainMenu.js.map +2 -2
- package/dist/commands/plugin/MarketplaceManager.js +5 -4
- package/dist/commands/plugin/MarketplaceManager.js.map +2 -2
- package/dist/commands/plugin/MarketplaceSelector.js +4 -3
- package/dist/commands/plugin/MarketplaceSelector.js.map +2 -2
- package/dist/commands/plugin/PlaceholderScreen.js +3 -2
- package/dist/commands/plugin/PlaceholderScreen.js.map +2 -2
- package/dist/commands/plugin/PluginBrowser.js +6 -5
- package/dist/commands/plugin/PluginBrowser.js.map +2 -2
- package/dist/commands/plugin/PluginDetailsInstall.js +5 -4
- package/dist/commands/plugin/PluginDetailsInstall.js.map +2 -2
- package/dist/commands/plugin/PluginDetailsManage.js +4 -3
- package/dist/commands/plugin/PluginDetailsManage.js.map +2 -2
- package/dist/commands/plugin.js +16 -15
- package/dist/commands/plugin.js.map +2 -2
- package/dist/commands/quit.js +3 -1
- package/dist/commands/quit.js.map +2 -2
- package/dist/commands/sandbox.js +105 -0
- package/dist/commands/sandbox.js.map +7 -0
- package/dist/commands/setup.js +2 -1
- package/dist/commands/setup.js.map +2 -2
- package/dist/commands/status.js +59 -0
- package/dist/commands/status.js.map +7 -0
- package/dist/commands/tasks.js +108 -0
- package/dist/commands/tasks.js.map +7 -0
- package/dist/commands/todos.js +123 -0
- package/dist/commands/todos.js.map +7 -0
- package/dist/commands/undo.js +245 -0
- package/dist/commands/undo.js.map +7 -0
- package/dist/commands.js +22 -2
- package/dist/commands.js.map +2 -2
- package/dist/components/AgentThinkingBlock.js +10 -18
- package/dist/components/AgentThinkingBlock.js.map +2 -2
- package/dist/components/AsciiLogo.js +7 -8
- package/dist/components/AsciiLogo.js.map +2 -2
- package/dist/components/AskUserQuestionDialog/AskUserQuestionDialog.js +3 -2
- package/dist/components/AskUserQuestionDialog/AskUserQuestionDialog.js.map +2 -2
- package/dist/components/AskUserQuestionDialog/QuestionView.js +2 -1
- package/dist/components/AskUserQuestionDialog/QuestionView.js.map +2 -2
- package/dist/components/BackgroundTasksPanel.js +78 -29
- package/dist/components/BackgroundTasksPanel.js.map +2 -2
- package/dist/components/BashStreamingProgress.js +24 -0
- package/dist/components/BashStreamingProgress.js.map +7 -0
- package/dist/components/CollapsibleHint.js +15 -0
- package/dist/components/CollapsibleHint.js.map +7 -0
- package/dist/components/Config.js +3 -2
- package/dist/components/Config.js.map +2 -2
- package/dist/components/ConsoleOAuthFlow.js +2 -1
- package/dist/components/ConsoleOAuthFlow.js.map +2 -2
- package/dist/components/Cost.js +2 -1
- package/dist/components/Cost.js.map +2 -2
- package/dist/components/FileEditToolUpdatedMessage.js +1 -1
- package/dist/components/FileEditToolUpdatedMessage.js.map +2 -2
- package/dist/components/HeaderBar.js +13 -8
- package/dist/components/HeaderBar.js.map +2 -2
- package/dist/components/HistorySearchOverlay.js +4 -3
- package/dist/components/HistorySearchOverlay.js.map +2 -2
- package/dist/components/HotkeyHelpPanel.js +134 -0
- package/dist/components/HotkeyHelpPanel.js.map +7 -0
- package/dist/components/InvalidConfigDialog.js +2 -1
- package/dist/components/InvalidConfigDialog.js.map +2 -2
- package/dist/components/Logo.js +24 -68
- package/dist/components/Logo.js.map +2 -2
- package/dist/components/MCPServerApprovalDialog.js +2 -1
- package/dist/components/MCPServerApprovalDialog.js.map +2 -2
- package/dist/components/MCPServerDialogCopy.js +2 -1
- package/dist/components/MCPServerDialogCopy.js.map +2 -2
- package/dist/components/MCPServerMultiselectDialog.js +2 -1
- package/dist/components/MCPServerMultiselectDialog.js.map +2 -2
- package/dist/components/Message.js +23 -7
- package/dist/components/Message.js.map +3 -3
- package/dist/components/MessageSelector.js +4 -3
- package/dist/components/MessageSelector.js.map +2 -2
- package/dist/components/ModeIndicator.js +2 -1
- package/dist/components/ModeIndicator.js.map +2 -2
- package/dist/components/ModelConfig.js +20 -6
- package/dist/components/ModelConfig.js.map +2 -2
- package/dist/components/ModelListManager.js +7 -6
- package/dist/components/ModelListManager.js.map +2 -2
- package/dist/components/ModelSelector/ModelSelector.js +27 -14
- package/dist/components/ModelSelector/ModelSelector.js.map +2 -2
- package/dist/components/Onboarding.js +22 -16
- package/dist/components/Onboarding.js.map +2 -2
- package/dist/components/OperationSummary.js +130 -0
- package/dist/components/OperationSummary.js.map +7 -0
- package/dist/components/ProgressBar.js +74 -0
- package/dist/components/ProgressBar.js.map +7 -0
- package/dist/components/PromptInput.js +210 -87
- package/dist/components/PromptInput.js.map +2 -2
- package/dist/components/RequestStatusIndicator.js +194 -0
- package/dist/components/RequestStatusIndicator.js.map +7 -0
- package/dist/components/SensitiveFileWarning.js +31 -0
- package/dist/components/SensitiveFileWarning.js.map +7 -0
- package/dist/components/Spinner.js +141 -27
- package/dist/components/Spinner.js.map +2 -2
- package/dist/components/SpinnerSymbol.js +21 -27
- package/dist/components/SpinnerSymbol.js.map +2 -2
- package/dist/components/StreamingBashOutput.js +9 -8
- package/dist/components/StreamingBashOutput.js.map +2 -2
- package/dist/components/StructuredDiff.js +6 -8
- package/dist/components/StructuredDiff.js.map +2 -2
- package/dist/components/SubagentBlock.js +5 -3
- package/dist/components/SubagentBlock.js.map +2 -2
- package/dist/components/SubagentProgress.js +17 -15
- package/dist/components/SubagentProgress.js.map +2 -2
- package/dist/components/TaskCard.js +30 -24
- package/dist/components/TaskCard.js.map +2 -2
- package/dist/components/TextInput.js +9 -1
- package/dist/components/TextInput.js.map +2 -2
- package/dist/components/TodoChangeBlock.js +1 -1
- package/dist/components/TodoChangeBlock.js.map +2 -2
- package/dist/components/TodoPanel.js +140 -31
- package/dist/components/TodoPanel.js.map +3 -3
- package/dist/components/TokenCounter.js +74 -0
- package/dist/components/TokenCounter.js.map +7 -0
- package/dist/components/TokenWarning.js +2 -1
- package/dist/components/TokenWarning.js.map +2 -2
- package/dist/components/ToolUseLoader.js +2 -2
- package/dist/components/ToolUseLoader.js.map +2 -2
- package/dist/components/TreeConnector.js +26 -0
- package/dist/components/TreeConnector.js.map +7 -0
- package/dist/components/TrustDialog.js +2 -1
- package/dist/components/TrustDialog.js.map +2 -2
- package/dist/components/TurnCompletionIndicator.js +18 -0
- package/dist/components/TurnCompletionIndicator.js.map +7 -0
- package/dist/components/binary-feedback/BinaryFeedbackView.js +2 -1
- package/dist/components/binary-feedback/BinaryFeedbackView.js.map +2 -2
- package/dist/components/messages/AssistantTextMessage.js +20 -9
- package/dist/components/messages/AssistantTextMessage.js.map +2 -2
- package/dist/components/messages/AssistantThinkingMessage.js +18 -3
- package/dist/components/messages/AssistantThinkingMessage.js.map +2 -2
- package/dist/components/messages/AssistantToolUseMessage.js +17 -10
- package/dist/components/messages/AssistantToolUseMessage.js.map +2 -2
- package/dist/components/messages/GroupRenderer.js +54 -0
- package/dist/components/messages/GroupRenderer.js.map +7 -0
- package/dist/components/messages/NestedTasksPreview.js +24 -0
- package/dist/components/messages/NestedTasksPreview.js.map +7 -0
- package/dist/components/messages/ParallelTasksGroupView.js +93 -0
- package/dist/components/messages/ParallelTasksGroupView.js.map +7 -0
- package/dist/components/messages/TaskInModuleView.js +218 -0
- package/dist/components/messages/TaskInModuleView.js.map +7 -0
- package/dist/components/messages/TaskOutputContent.js +56 -0
- package/dist/components/messages/TaskOutputContent.js.map +7 -0
- package/dist/components/messages/UserPromptMessage.js +2 -2
- package/dist/components/messages/UserPromptMessage.js.map +2 -2
- package/dist/components/messages/UserToolResultMessage/UserToolSuccessMessage.js +2 -3
- package/dist/components/messages/UserToolResultMessage/UserToolSuccessMessage.js.map +2 -2
- package/dist/components/permissions/FallbackPermissionRequest.js +4 -4
- package/dist/components/permissions/FallbackPermissionRequest.js.map +2 -2
- package/dist/components/permissions/FilesystemPermissionRequest/FilesystemPermissionRequest.js +4 -4
- package/dist/components/permissions/FilesystemPermissionRequest/FilesystemPermissionRequest.js.map +2 -2
- package/dist/constants/colors.js +120 -54
- package/dist/constants/colors.js.map +2 -2
- package/dist/constants/formatRules.js +102 -0
- package/dist/constants/formatRules.js.map +7 -0
- package/dist/constants/prompts.js +12 -34
- package/dist/constants/prompts.js.map +2 -2
- package/dist/constants/symbols.js +64 -6
- package/dist/constants/symbols.js.map +2 -2
- package/dist/constants/timing.js +5 -0
- package/dist/constants/timing.js.map +2 -2
- package/dist/constants/toolInputExamples.js +84 -0
- package/dist/constants/toolInputExamples.js.map +7 -0
- package/dist/core/backupManager.js +321 -0
- package/dist/core/backupManager.js.map +7 -0
- package/dist/core/config/defaults.js +84 -0
- package/dist/core/config/defaults.js.map +7 -0
- package/dist/core/config/index.js +111 -0
- package/dist/core/config/index.js.map +7 -0
- package/dist/core/config/loader.js +221 -0
- package/dist/core/config/loader.js.map +7 -0
- package/dist/core/config/migrations.js +128 -0
- package/dist/core/config/migrations.js.map +7 -0
- package/dist/core/config/schema.js +178 -0
- package/dist/core/config/schema.js.map +7 -0
- package/dist/core/costTracker.js +129 -0
- package/dist/core/costTracker.js.map +7 -0
- package/dist/core/gitAutoCommit.js +287 -0
- package/dist/core/gitAutoCommit.js.map +7 -0
- package/dist/core/index.js +8 -0
- package/dist/core/index.js.map +7 -0
- package/dist/core/operationTracker.js +212 -0
- package/dist/core/operationTracker.js.map +7 -0
- package/dist/core/permissions/auditLog.js +204 -0
- package/dist/core/permissions/auditLog.js.map +7 -0
- package/dist/core/permissions/engine/index.js +3 -0
- package/dist/core/permissions/engine/index.js.map +7 -0
- package/dist/core/permissions/engine/permissionEngine.js +106 -0
- package/dist/core/permissions/engine/permissionEngine.js.map +7 -0
- package/dist/core/permissions/engine/types.js +1 -0
- package/dist/core/permissions/engine/types.js.map +7 -0
- package/dist/core/permissions/index.js +84 -0
- package/dist/core/permissions/index.js.map +7 -0
- package/dist/core/permissions/ruleEngine.js +259 -0
- package/dist/core/permissions/ruleEngine.js.map +7 -0
- package/dist/core/permissions/rules/allowedToolsRule.js +62 -0
- package/dist/core/permissions/rules/allowedToolsRule.js.map +7 -0
- package/dist/core/permissions/rules/autoEscalationRule.js +296 -0
- package/dist/core/permissions/rules/autoEscalationRule.js.map +7 -0
- package/dist/core/permissions/rules/index.js +46 -0
- package/dist/core/permissions/rules/index.js.map +7 -0
- package/dist/core/permissions/rules/planModeRule.js +55 -0
- package/dist/core/permissions/rules/planModeRule.js.map +7 -0
- package/dist/core/permissions/rules/projectBoundaryRule.js +173 -0
- package/dist/core/permissions/rules/projectBoundaryRule.js.map +7 -0
- package/dist/core/permissions/rules/safeModeRule.js +65 -0
- package/dist/core/permissions/rules/safeModeRule.js.map +7 -0
- package/dist/core/permissions/rules/sensitivePathsRule.js +345 -0
- package/dist/core/permissions/rules/sensitivePathsRule.js.map +7 -0
- package/dist/core/permissions/types.js +127 -0
- package/dist/core/permissions/types.js.map +7 -0
- package/dist/core/tokenStats.js +9 -0
- package/dist/core/tokenStats.js.map +7 -0
- package/dist/core/tokenStatsManager.js +331 -0
- package/dist/core/tokenStatsManager.js.map +7 -0
- package/dist/core/tools/executor.js +143 -0
- package/dist/core/tools/executor.js.map +7 -0
- package/dist/core/tools/index.js +15 -0
- package/dist/core/tools/index.js.map +7 -0
- package/dist/core/tools/registry.js +183 -0
- package/dist/core/tools/registry.js.map +7 -0
- package/dist/core/tools/types.js +1 -0
- package/dist/core/tools/types.js.map +7 -0
- package/dist/cost-tracker.js +23 -15
- package/dist/cost-tracker.js.map +2 -2
- package/dist/entrypoints/cli.js +158 -130
- package/dist/entrypoints/cli.js.map +2 -2
- package/dist/entrypoints/mcp.js +12 -4
- package/dist/entrypoints/mcp.js.map +2 -2
- package/dist/history.js +14 -3
- package/dist/history.js.map +2 -2
- package/dist/hooks/useAgentTokenStats.js +72 -0
- package/dist/hooks/useAgentTokenStats.js.map +7 -0
- package/dist/hooks/useAgentTranscripts.js +140 -0
- package/dist/hooks/useAgentTranscripts.js.map +7 -0
- package/dist/hooks/useAnimationSync.js +53 -0
- package/dist/hooks/useAnimationSync.js.map +7 -0
- package/dist/hooks/useArrowKeyHistory.js +4 -2
- package/dist/hooks/useArrowKeyHistory.js.map +2 -2
- package/dist/hooks/useCanUseTool.js +3 -1
- package/dist/hooks/useCanUseTool.js.map +2 -2
- package/dist/hooks/useExitOnCtrlCD.js +9 -5
- package/dist/hooks/useExitOnCtrlCD.js.map +2 -2
- package/dist/hooks/useHookStatus.js +40 -0
- package/dist/hooks/useHookStatus.js.map +7 -0
- package/dist/hooks/useLogMessages.js +29 -2
- package/dist/hooks/useLogMessages.js.map +2 -2
- package/dist/hooks/useMessageGroups.js +43 -0
- package/dist/hooks/useMessageGroups.js.map +7 -0
- package/dist/hooks/useTerminalSize.js +62 -6
- package/dist/hooks/useTerminalSize.js.map +2 -2
- package/dist/hooks/useUnifiedCompletion.js +69 -0
- package/dist/hooks/useUnifiedCompletion.js.map +2 -2
- package/dist/i18n/index.js +109 -0
- package/dist/i18n/index.js.map +7 -0
- package/dist/i18n/locales/en.js +348 -0
- package/dist/i18n/locales/en.js.map +7 -0
- package/dist/i18n/locales/index.js +7 -0
- package/dist/i18n/locales/index.js.map +7 -0
- package/dist/i18n/locales/zh-CN.js +348 -0
- package/dist/i18n/locales/zh-CN.js.map +7 -0
- package/dist/i18n/types.js +8 -0
- package/dist/i18n/types.js.map +7 -0
- package/dist/permissions.js +28 -1
- package/dist/permissions.js.map +2 -2
- package/dist/query.js +253 -21
- package/dist/query.js.map +3 -3
- package/dist/screens/REPL.js +523 -194
- package/dist/screens/REPL.js.map +3 -3
- package/dist/services/adapters/chatCompletions.js +3 -1
- package/dist/services/adapters/chatCompletions.js.map +2 -2
- package/dist/services/adapters/messageNormalizer.js +354 -0
- package/dist/services/adapters/messageNormalizer.js.map +7 -0
- package/dist/services/adapters/responsesAPI.js +6 -3
- package/dist/services/adapters/responsesAPI.js.map +2 -2
- package/dist/services/checkpointManager.js +386 -0
- package/dist/services/checkpointManager.js.map +7 -0
- package/dist/services/claude.js +192 -14
- package/dist/services/claude.js.map +3 -3
- package/dist/services/compressionService.js +50 -1
- package/dist/services/compressionService.js.map +2 -2
- package/dist/services/contextMonitor.js +162 -0
- package/dist/services/contextMonitor.js.map +7 -0
- package/dist/services/customCommands.js +60 -41
- package/dist/services/customCommands.js.map +2 -2
- package/dist/services/hookExecutor.js +173 -1
- package/dist/services/hookExecutor.js.map +2 -2
- package/dist/services/intelligentCompactor.js +281 -0
- package/dist/services/intelligentCompactor.js.map +7 -0
- package/dist/services/lspConfig.js +109 -0
- package/dist/services/lspConfig.js.map +7 -0
- package/dist/services/mcpClient.js +338 -43
- package/dist/services/mcpClient.js.map +2 -2
- package/dist/services/modelOrchestrator.js +310 -0
- package/dist/services/modelOrchestrator.js.map +7 -0
- package/dist/services/openai.js +8 -1
- package/dist/services/openai.js.map +2 -2
- package/dist/services/outputStyles.js +138 -0
- package/dist/services/outputStyles.js.map +7 -0
- package/dist/services/plugins/index.js +5 -0
- package/dist/services/plugins/index.js.map +7 -0
- package/dist/services/plugins/lspServers.js +188 -0
- package/dist/services/plugins/lspServers.js.map +7 -0
- package/dist/services/plugins/pluginRuntime.js +229 -0
- package/dist/services/plugins/pluginRuntime.js.map +7 -0
- package/dist/services/plugins/pluginValidation.js +219 -0
- package/dist/services/plugins/pluginValidation.js.map +7 -0
- package/dist/services/plugins/skillMarketplace.js +556 -0
- package/dist/services/plugins/skillMarketplace.js.map +7 -0
- package/dist/services/responseStateManager.js +37 -3
- package/dist/services/responseStateManager.js.map +2 -2
- package/dist/services/sandbox/filesystemBoundary.js +341 -0
- package/dist/services/sandbox/filesystemBoundary.js.map +7 -0
- package/dist/services/sandbox/index.js +14 -0
- package/dist/services/sandbox/index.js.map +7 -0
- package/dist/services/sandbox/networkProxy.js +293 -0
- package/dist/services/sandbox/networkProxy.js.map +7 -0
- package/dist/services/sandbox/sandboxController.js +574 -0
- package/dist/services/sandbox/sandboxController.js.map +7 -0
- package/dist/services/sandbox/types.js +50 -0
- package/dist/services/sandbox/types.js.map +7 -0
- package/dist/services/sessionMemory.js +266 -0
- package/dist/services/sessionMemory.js.map +7 -0
- package/dist/services/taskRouter.js +324 -0
- package/dist/services/taskRouter.js.map +7 -0
- package/dist/tools/ArchitectTool/ArchitectTool.js +7 -1
- package/dist/tools/ArchitectTool/ArchitectTool.js.map +2 -2
- package/dist/tools/AskExpertModelTool/AskExpertModelTool.js +6 -2
- package/dist/tools/AskExpertModelTool/AskExpertModelTool.js.map +2 -2
- package/dist/tools/AskUserQuestionTool/AskUserQuestionTool.js +2 -1
- package/dist/tools/AskUserQuestionTool/AskUserQuestionTool.js.map +2 -2
- package/dist/tools/BaseTool.js +72 -0
- package/dist/tools/BaseTool.js.map +7 -0
- package/dist/tools/BashOutputTool/BashOutputToolResultMessage.js +3 -0
- package/dist/tools/BashOutputTool/BashOutputToolResultMessage.js.map +2 -2
- package/dist/tools/BashTool/BashTool.js +79 -3
- package/dist/tools/BashTool/BashTool.js.map +2 -2
- package/dist/tools/BashTool/BashToolResultMessage.js +3 -0
- package/dist/tools/BashTool/BashToolResultMessage.js.map +2 -2
- package/dist/tools/BashTool/OutputLine.js +54 -0
- package/dist/tools/BashTool/OutputLine.js.map +2 -2
- package/dist/tools/BashTool/prompt.js +336 -3
- package/dist/tools/BashTool/prompt.js.map +2 -2
- package/dist/tools/FileEditTool/FileEditTool.js +29 -4
- package/dist/tools/FileEditTool/FileEditTool.js.map +2 -2
- package/dist/tools/FileEditTool/prompt.js +6 -3
- package/dist/tools/FileEditTool/prompt.js.map +2 -2
- package/dist/tools/FileWriteTool/FileWriteTool.js +5 -5
- package/dist/tools/FileWriteTool/FileWriteTool.js.map +2 -2
- package/dist/tools/FileWriteTool/prompt.js +4 -2
- package/dist/tools/FileWriteTool/prompt.js.map +2 -2
- package/dist/tools/GlobTool/GlobTool.js +4 -2
- package/dist/tools/GlobTool/GlobTool.js.map +2 -2
- package/dist/tools/GrepTool/GrepTool.js +36 -7
- package/dist/tools/GrepTool/GrepTool.js.map +2 -2
- package/dist/tools/KillShellTool/KillShellToolResultMessage.js +3 -0
- package/dist/tools/KillShellTool/KillShellToolResultMessage.js.map +2 -2
- package/dist/tools/ListMcpResourcesTool/ListMcpResourcesTool.js +109 -0
- package/dist/tools/ListMcpResourcesTool/ListMcpResourcesTool.js.map +7 -0
- package/dist/tools/ListMcpResourcesTool/prompt.js +19 -0
- package/dist/tools/ListMcpResourcesTool/prompt.js.map +7 -0
- package/dist/tools/LspTool/LspTool.js +664 -0
- package/dist/tools/LspTool/LspTool.js.map +7 -0
- package/dist/tools/LspTool/prompt.js +27 -0
- package/dist/tools/LspTool/prompt.js.map +7 -0
- package/dist/tools/MCPTool/MCPTool.js +9 -1
- package/dist/tools/MCPTool/MCPTool.js.map +2 -2
- package/dist/tools/MemoryReadTool/MemoryReadTool.js +19 -6
- package/dist/tools/MemoryReadTool/MemoryReadTool.js.map +2 -2
- package/dist/tools/MemoryWriteTool/MemoryWriteTool.js +6 -6
- package/dist/tools/MemoryWriteTool/MemoryWriteTool.js.map +2 -2
- package/dist/tools/MultiEditTool/MultiEditTool.js +19 -2
- package/dist/tools/MultiEditTool/MultiEditTool.js.map +2 -2
- package/dist/tools/MultiEditTool/prompt.js +5 -3
- package/dist/tools/MultiEditTool/prompt.js.map +2 -2
- package/dist/tools/NotebookEditTool/NotebookEditTool.js +7 -2
- package/dist/tools/NotebookEditTool/NotebookEditTool.js.map +2 -2
- package/dist/tools/NotebookReadTool/NotebookReadTool.js.map +2 -2
- package/dist/tools/PlanModeTool/EnterPlanModeTool.js +75 -0
- package/dist/tools/PlanModeTool/EnterPlanModeTool.js.map +7 -0
- package/dist/tools/PlanModeTool/ExitPlanModeTool.js +109 -0
- package/dist/tools/PlanModeTool/ExitPlanModeTool.js.map +7 -0
- package/dist/tools/PlanModeTool/prompt.js +94 -0
- package/dist/tools/PlanModeTool/prompt.js.map +7 -0
- package/dist/tools/ReadMcpResourceTool/ReadMcpResourceTool.js +130 -0
- package/dist/tools/ReadMcpResourceTool/ReadMcpResourceTool.js.map +7 -0
- package/dist/tools/ReadMcpResourceTool/prompt.js +17 -0
- package/dist/tools/ReadMcpResourceTool/prompt.js.map +7 -0
- package/dist/tools/SkillTool/SkillTool.js +10 -4
- package/dist/tools/SkillTool/SkillTool.js.map +2 -2
- package/dist/tools/SkillTool/prompt.js +1 -1
- package/dist/tools/SkillTool/prompt.js.map +1 -1
- package/dist/tools/SlashCommandTool/SlashCommandTool.js +260 -0
- package/dist/tools/SlashCommandTool/SlashCommandTool.js.map +7 -0
- package/dist/tools/SlashCommandTool/prompt.js +35 -0
- package/dist/tools/SlashCommandTool/prompt.js.map +7 -0
- package/dist/tools/TaskOutputTool/TaskOutputTool.js +190 -0
- package/dist/tools/TaskOutputTool/TaskOutputTool.js.map +7 -0
- package/dist/tools/TaskOutputTool/prompt.js +15 -0
- package/dist/tools/TaskOutputTool/prompt.js.map +7 -0
- package/dist/tools/TaskTool/TaskTool.js +310 -104
- package/dist/tools/TaskTool/TaskTool.js.map +2 -2
- package/dist/tools/TaskTool/prompt.js.map +2 -2
- package/dist/tools/TodoWriteTool/TodoWriteTool.js +42 -77
- package/dist/tools/TodoWriteTool/TodoWriteTool.js.map +2 -2
- package/dist/tools/URLFetcherTool/URLFetcherTool.js +4 -1
- package/dist/tools/URLFetcherTool/URLFetcherTool.js.map +2 -2
- package/dist/tools/URLFetcherTool/cache.js +55 -8
- package/dist/tools/URLFetcherTool/cache.js.map +2 -2
- package/dist/tools.js +31 -2
- package/dist/tools.js.map +2 -2
- package/dist/types/hooks.js +4 -0
- package/dist/types/hooks.js.map +2 -2
- package/dist/types/marketplace.js.map +2 -2
- package/dist/types/messageGroup.js +36 -0
- package/dist/types/messageGroup.js.map +7 -0
- package/dist/types/plugin.js.map +2 -2
- package/dist/types/thinking.js +1 -0
- package/dist/types/thinking.js.map +7 -0
- package/dist/utils/BackgroundShellManager.js +136 -39
- package/dist/utils/BackgroundShellManager.js.map +2 -2
- package/dist/utils/CircuitBreaker.js +242 -0
- package/dist/utils/CircuitBreaker.js.map +7 -0
- package/dist/utils/MessageBatchBuffer.js +102 -0
- package/dist/utils/MessageBatchBuffer.js.map +7 -0
- package/dist/utils/PersistentShell.js +151 -1
- package/dist/utils/PersistentShell.js.map +2 -2
- package/dist/utils/agentLoader.js +1 -23
- package/dist/utils/agentLoader.js.map +2 -2
- package/dist/utils/agentTranscripts.js +641 -0
- package/dist/utils/agentTranscripts.js.map +7 -0
- package/dist/utils/animationManager.js +213 -0
- package/dist/utils/animationManager.js.map +7 -0
- package/dist/utils/animationSync.js +110 -0
- package/dist/utils/animationSync.js.map +7 -0
- package/dist/utils/ask.js +2 -0
- package/dist/utils/ask.js.map +2 -2
- package/dist/utils/asyncFile.js +215 -0
- package/dist/utils/asyncFile.js.map +7 -0
- package/dist/utils/backgroundAgentManager.js +231 -0
- package/dist/utils/backgroundAgentManager.js.map +7 -0
- package/dist/utils/config.js +108 -10
- package/dist/utils/config.js.map +2 -2
- package/dist/utils/conversationRecovery.js +19 -0
- package/dist/utils/conversationRecovery.js.map +2 -2
- package/dist/utils/credentials/CredentialStore.js +1 -0
- package/dist/utils/credentials/CredentialStore.js.map +7 -0
- package/dist/utils/credentials/EncryptedFileStore.js +157 -0
- package/dist/utils/credentials/EncryptedFileStore.js.map +7 -0
- package/dist/utils/credentials/index.js +37 -0
- package/dist/utils/credentials/index.js.map +7 -0
- package/dist/utils/credentials/migration.js +82 -0
- package/dist/utils/credentials/migration.js.map +7 -0
- package/dist/utils/exit.js +73 -0
- package/dist/utils/exit.js.map +7 -0
- package/dist/utils/format.js +73 -5
- package/dist/utils/format.js.map +2 -2
- package/dist/utils/generators.js +76 -6
- package/dist/utils/generators.js.map +2 -2
- package/dist/utils/globalErrorHandler.js +149 -0
- package/dist/utils/globalErrorHandler.js.map +7 -0
- package/dist/utils/groupHandlers/index.js +8 -0
- package/dist/utils/groupHandlers/index.js.map +7 -0
- package/dist/utils/groupHandlers/parallelTasksHandler.js +140 -0
- package/dist/utils/groupHandlers/parallelTasksHandler.js.map +7 -0
- package/dist/utils/groupHandlers/taskHandler.js +104 -0
- package/dist/utils/groupHandlers/taskHandler.js.map +7 -0
- package/dist/utils/groupHandlers/types.js +1 -0
- package/dist/utils/groupHandlers/types.js.map +7 -0
- package/dist/utils/logRotation.js +224 -0
- package/dist/utils/logRotation.js.map +7 -0
- package/dist/utils/markdown.js +13 -1
- package/dist/utils/markdown.js.map +2 -2
- package/dist/utils/marketplaceManager.js +3 -5
- package/dist/utils/marketplaceManager.js.map +2 -2
- package/dist/utils/memSafety.js +264 -0
- package/dist/utils/memSafety.js.map +7 -0
- package/dist/utils/messageGroupManager.js +274 -0
- package/dist/utils/messageGroupManager.js.map +7 -0
- package/dist/utils/messages.js +13 -4
- package/dist/utils/messages.js.map +2 -2
- package/dist/utils/model.js +119 -15
- package/dist/utils/model.js.map +3 -3
- package/dist/utils/permissions/filesystem.js +162 -6
- package/dist/utils/permissions/filesystem.js.map +2 -2
- package/dist/utils/plan/planMode.js +143 -0
- package/dist/utils/plan/planMode.js.map +7 -0
- package/dist/utils/pluginLoader.js +17 -21
- package/dist/utils/pluginLoader.js.map +2 -2
- package/dist/utils/ripgrep.js +55 -2
- package/dist/utils/ripgrep.js.map +2 -2
- package/dist/utils/safePath.js +132 -0
- package/dist/utils/safePath.js.map +7 -0
- package/dist/utils/sanitizeInput.js +32 -0
- package/dist/utils/sanitizeInput.js.map +7 -0
- package/dist/utils/secureKeyStorage.js +312 -0
- package/dist/utils/secureKeyStorage.js.map +7 -0
- package/dist/utils/sensitiveFiles.js +125 -0
- package/dist/utils/sensitiveFiles.js.map +7 -0
- package/dist/utils/session/sessionPlugins.js +67 -0
- package/dist/utils/session/sessionPlugins.js.map +7 -0
- package/dist/utils/taskDisplayUtils.js +257 -0
- package/dist/utils/taskDisplayUtils.js.map +7 -0
- package/dist/utils/teamConfig.js +2 -1
- package/dist/utils/teamConfig.js.map +2 -2
- package/dist/utils/theme.js +6 -6
- package/dist/utils/theme.js.map +1 -1
- package/dist/utils/todoStorage.js +92 -2
- package/dist/utils/todoStorage.js.map +2 -2
- package/dist/utils/toolRiskClassification.js +207 -0
- package/dist/utils/toolRiskClassification.js.map +7 -0
- package/dist/utils/toolTimeout.js +136 -0
- package/dist/utils/toolTimeout.js.map +7 -0
- package/dist/utils/tooling/safeRender.js +116 -0
- package/dist/utils/tooling/safeRender.js.map +7 -0
- package/dist/utils/userFriendlyError.js +346 -0
- package/dist/utils/userFriendlyError.js.map +7 -0
- package/dist/utils/vendor/ripgrep/arm64-darwin/rg +0 -0
- package/dist/version.js +2 -2
- package/dist/version.js.map +1 -1
- package/package.json +17 -5
- package/scripts/postinstall.js +128 -38
- package/dist/commands/agents.js +0 -2086
- package/dist/commands/agents.js.map +0 -7
- package/dist/commands/build.js +0 -74
- package/dist/commands/build.js.map +0 -7
- package/dist/commands/compression.js +0 -57
- package/dist/commands/compression.js.map +0 -7
- package/dist/commands/listen.js +0 -37
- package/dist/commands/listen.js.map +0 -7
- package/dist/commands/login.js +0 -37
- package/dist/commands/login.js.map +0 -7
- package/dist/commands/logout.js +0 -33
- package/dist/commands/logout.js.map +0 -7
- package/dist/commands/mcp.js +0 -40
- package/dist/commands/mcp.js.map +0 -7
- package/dist/commands/mcp_refresh.js +0 -40
- package/dist/commands/mcp_refresh.js.map +0 -7
- package/dist/commands/modelstatus.js +0 -21
- package/dist/commands/modelstatus.js.map +0 -7
- package/dist/commands/onboarding.js +0 -36
- package/dist/commands/onboarding.js.map +0 -7
- package/dist/commands/plugin-interactive.js +0 -446
- package/dist/commands/plugin-interactive.js.map +0 -7
- package/dist/commands/pr_comments.js +0 -61
- package/dist/commands/pr_comments.js.map +0 -7
- package/dist/commands/release-notes.js +0 -30
- package/dist/commands/release-notes.js.map +0 -7
- package/dist/commands/review.js +0 -51
- package/dist/commands/review.js.map +0 -7
- package/dist/components/Bug.js +0 -147
- package/dist/components/Bug.js.map +0 -7
- package/dist/components/ModelSelector.js +0 -2062
- package/dist/components/ModelSelector.js.map +0 -7
- package/dist/components/ModelStatusDisplay.js +0 -87
- package/dist/components/ModelStatusDisplay.js.map +0 -7
- package/dist/entrypoints/cli-wrapper.js +0 -61
- package/dist/entrypoints/cli-wrapper.js.map +0 -7
- package/dist/hooks/useCancelRequest.js +0 -28
- package/dist/hooks/useCancelRequest.js.map +0 -7
- package/dist/screens/Doctor.js +0 -22
- package/dist/screens/Doctor.js.map +0 -7
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/core/gitAutoCommit.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Git Auto-Commit System\n *\n * Provides automatic git commits after task completion.\n * Part of the \"\u96F6\u6210\u672C\u5F00\u7BB1\u5373\u7528\" (zero-cost out-of-box) optimization.\n *\n * Default: OFF - User must explicitly enable auto-commit.\n */\n\nimport { minimatch } from 'minimatch'\nimport { getIsGit } from '../utils/git'\nimport { execFileNoThrow } from '../utils/execFileNoThrow'\nimport { getCwd } from '../utils/state'\nimport { operationTracker, type OperationSummary } from './operationTracker'\n\n// ============================================================================\n// Types & Configuration\n// ============================================================================\n\n/**\n * Configuration for git auto-commit behavior\n */\nexport interface GitAutoCommitConfig {\n /** Whether auto-commit is enabled (default: false) */\n enabled: boolean\n\n /** Whether to commit after task completion (default: true) */\n commitAfterTask: boolean\n\n /** Glob patterns for files to exclude from auto-commit */\n excludePatterns: string[]\n\n /** Prefix for auto-generated commit messages */\n commitMessagePrefix: string\n}\n\n/**\n * Default configuration - auto-commit is OFF by default\n */\nexport const DEFAULT_GIT_CONFIG: GitAutoCommitConfig = {\n enabled: false, // Default OFF, user must enable\n commitAfterTask: true,\n excludePatterns: ['*.log', 'node_modules/**', 'dist/**', '.minto/**'],\n commitMessagePrefix: 'chore(minto): ',\n}\n\n/**\n * Result of an auto-commit operation\n */\nexport interface AutoCommitResult {\n success: boolean\n message: string\n commitHash?: string\n filesCommitted?: string[]\n}\n\n/**\n * Information about a changed file\n */\nexport interface ChangedFile {\n /** File path relative to repo root */\n path: string\n\n /** Change status: 'M' (modified), 'A' (added), 'D' (deleted), '?' (untracked) */\n status: 'M' | 'A' | 'D' | '?' | 'R' | 'C' | 'U'\n\n /** Number of lines added (for modified/added files) */\n linesAdded?: number\n\n /** Number of lines removed (for modified/deleted files) */\n linesRemoved?: number\n}\n\n/**\n * Summary of file changes for commit message generation\n */\nexport interface ChangeSummary {\n files: ChangedFile[]\n totalAdded: number\n totalRemoved: number\n}\n\n// ============================================================================\n// Core Functions\n// ============================================================================\n\n/**\n * Check if auto-commit should be performed\n *\n * @param config - Git auto-commit configuration\n * @returns true if auto-commit should proceed\n */\nexport async function shouldAutoCommit(\n config: GitAutoCommitConfig,\n): Promise<boolean> {\n // Check if auto-commit is enabled\n if (!config.enabled) {\n return false\n }\n\n // Check if we're in a git repository\n const isGitRepo = await getIsGit()\n if (!isGitRepo) {\n return false\n }\n\n // Check if there are changes to commit\n const changes = await getChangedFiles()\n if (changes.length === 0) {\n return false\n }\n\n // Filter out excluded files\n const filesToCommit = filterExcludedFiles(changes, config.excludePatterns)\n return filesToCommit.length > 0\n}\n\n/**\n * Perform an auto-commit with the given description\n *\n * @param config - Git auto-commit configuration\n * @param description - Short description of the changes\n * @returns Result of the commit operation\n */\nexport async function performAutoCommit(\n config: GitAutoCommitConfig,\n description: string,\n): Promise<AutoCommitResult> {\n // Validate we're in a git repo\n const isGitRepo = await getIsGit()\n if (!isGitRepo) {\n return {\n success: false,\n message: 'Not a git repository',\n }\n }\n\n // Get changed files\n const allChanges = await getChangedFiles()\n if (allChanges.length === 0) {\n return {\n success: false,\n message: 'No changes to commit',\n }\n }\n\n // Filter excluded files\n const filesToCommit = filterExcludedFiles(allChanges, config.excludePatterns)\n if (filesToCommit.length === 0) {\n return {\n success: false,\n message: 'All changed files are excluded by patterns',\n }\n }\n\n // Get detailed change summary for commit message\n const summary = await getChangeSummary(filesToCommit)\n\n // Stage files\n const stageResult = await stageFiles(filesToCommit.map(f => f.path))\n if (!stageResult.success) {\n return {\n success: false,\n message: `Failed to stage files: ${stageResult.error}`,\n }\n }\n\n // Generate commit message\n const commitMessage = generateCommitMessage(config, summary, description)\n\n // Create commit\n const commitResult = await createCommit(commitMessage)\n if (!commitResult.success) {\n return {\n success: false,\n message: `Failed to create commit: ${commitResult.error}`,\n }\n }\n\n return {\n success: true,\n message: `Committed ${filesToCommit.length} file(s)`,\n commitHash: commitResult.hash,\n filesCommitted: filesToCommit.map(f => f.path),\n }\n}\n\n/**\n * Generate a commit message from the change summary\n *\n * @param config - Git auto-commit configuration\n * @param summary - Summary of file changes\n * @param description - Short description of the changes\n * @returns Formatted commit message\n */\nexport function generateCommitMessage(\n config: GitAutoCommitConfig,\n summary: ChangeSummary,\n description: string,\n): string {\n // Sanitize description - remove leading/trailing whitespace, limit length\n const sanitizedDesc = description.trim().slice(0, 72)\n\n // Build title line\n const title = `${config.commitMessagePrefix}${sanitizedDesc}`\n\n // Build file list\n const fileCount = summary.files.length\n const fileLines = summary.files\n .slice(0, 10) // Limit to first 10 files\n .map(file => {\n const statusPrefix = getStatusLabel(file.status)\n if (file.linesAdded !== undefined || file.linesRemoved !== undefined) {\n const added = file.linesAdded ?? 0\n const removed = file.linesRemoved ?? 0\n return `- ${file.path} (${statusPrefix}, +${added} -${removed})`\n }\n return `- ${file.path} (${statusPrefix})`\n })\n\n // Add \"and X more\" if there are more files\n if (summary.files.length > 10) {\n fileLines.push(`- ... and ${summary.files.length - 10} more file(s)`)\n }\n\n // Build full message\n const lines = [\n title,\n '',\n `Modified ${fileCount} file(s):`,\n ...fileLines,\n '',\n '\uD83E\uDD16 Auto-committed by Minto',\n ]\n\n return lines.join('\\n')\n}\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Get list of changed files from git status\n */\nexport async function getChangedFiles(): Promise<ChangedFile[]> {\n const { stdout, code } = await execFileNoThrow(\n 'git',\n ['status', '--porcelain', '-u'],\n undefined,\n undefined,\n true,\n )\n\n if (code !== 0) {\n return []\n }\n\n const files: ChangedFile[] = []\n\n for (const line of stdout.split('\\n')) {\n if (!line.trim()) continue\n\n // Parse git status porcelain format: XY filename\n // X = index status, Y = working tree status\n const status = line.substring(0, 2).trim()\n const path = line.substring(3).trim()\n\n if (!path) continue\n\n // Map status codes to our simplified format\n const normalizedStatus = normalizeStatus(status)\n if (normalizedStatus) {\n files.push({\n path,\n status: normalizedStatus,\n })\n }\n }\n\n return files\n}\n\n/**\n * Get detailed change summary including line counts\n */\nasync function getChangeSummary(files: ChangedFile[]): Promise<ChangeSummary> {\n let totalAdded = 0\n let totalRemoved = 0\n\n // Get numstat for tracked files\n const trackedFiles = files.filter(f => f.status !== '?')\n if (trackedFiles.length > 0) {\n const { stdout, code } = await execFileNoThrow(\n 'git',\n ['diff', '--numstat', 'HEAD', '--', ...trackedFiles.map(f => f.path)],\n undefined,\n undefined,\n true,\n )\n\n if (code === 0) {\n for (const line of stdout.split('\\n')) {\n if (!line.trim()) continue\n\n const parts = line.split('\\t')\n if (parts.length >= 3) {\n const added = parseInt(parts[0], 10) || 0\n const removed = parseInt(parts[1], 10) || 0\n const path = parts[2]\n\n // Find and update the file in our list\n const file = files.find(f => f.path === path)\n if (file) {\n file.linesAdded = added\n file.linesRemoved = removed\n }\n\n totalAdded += added\n totalRemoved += removed\n }\n }\n }\n }\n\n // For untracked files, count all lines as added\n const untrackedFiles = files.filter(f => f.status === '?')\n for (const file of untrackedFiles) {\n const { stdout, code } = await execFileNoThrow(\n 'wc',\n ['-l', file.path],\n undefined,\n undefined,\n true,\n )\n\n if (code === 0) {\n const lineCount = parseInt(stdout.trim().split(/\\s+/)[0], 10) || 0\n file.linesAdded = lineCount\n file.linesRemoved = 0\n totalAdded += lineCount\n }\n }\n\n return {\n files,\n totalAdded,\n totalRemoved,\n }\n}\n\n/**\n * Filter out files matching exclusion patterns\n */\nexport function filterExcludedFiles(\n files: ChangedFile[],\n excludePatterns: string[],\n): ChangedFile[] {\n return files.filter(file => {\n for (const pattern of excludePatterns) {\n if (minimatch(file.path, pattern, { dot: true })) {\n return false\n }\n }\n return true\n })\n}\n\n/**\n * Stage files for commit\n */\nasync function stageFiles(\n paths: string[],\n): Promise<{ success: boolean; error?: string }> {\n if (paths.length === 0) {\n return { success: true }\n }\n\n const { code, stderr } = await execFileNoThrow(\n 'git',\n ['add', '--', ...paths],\n undefined,\n undefined,\n true,\n )\n\n if (code !== 0) {\n return { success: false, error: stderr || 'Unknown error' }\n }\n\n return { success: true }\n}\n\n/**\n * Create a git commit\n */\nasync function createCommit(\n message: string,\n): Promise<{ success: boolean; hash?: string; error?: string }> {\n const { code, stdout, stderr } = await execFileNoThrow(\n 'git',\n ['commit', '-m', message],\n undefined,\n undefined,\n true,\n )\n\n if (code !== 0) {\n return { success: false, error: stderr || 'Unknown error' }\n }\n\n // Extract commit hash from output\n // Output format: \"[branch hash] message\"\n const match = stdout.match(/\\[[\\w/-]+ ([a-f0-9]+)\\]/)\n const hash = match ? match[1] : undefined\n\n return { success: true, hash }\n}\n\n/**\n * Normalize git status code to our simplified format\n */\nfunction normalizeStatus(\n status: string,\n): 'M' | 'A' | 'D' | '?' | 'R' | 'C' | 'U' | null {\n // Handle the various git status codes\n // First character is staging area, second is working tree\n\n if (status.includes('?')) return '?'\n if (status.includes('A')) return 'A'\n if (status.includes('D')) return 'D'\n if (status.includes('R')) return 'R'\n if (status.includes('C')) return 'C'\n if (status.includes('U')) return 'U'\n if (status.includes('M') || status.includes(' M')) return 'M'\n\n // For any other changes (like ' M' for unstaged modifications)\n if (status.trim()) return 'M'\n\n return null\n}\n\n/**\n * Get human-readable label for status code\n */\nfunction getStatusLabel(status: string): string {\n switch (status) {\n case 'M':\n return 'modified'\n case 'A':\n return 'new'\n case 'D':\n return 'deleted'\n case '?':\n return 'new'\n case 'R':\n return 'renamed'\n case 'C':\n return 'copied'\n case 'U':\n return 'unmerged'\n default:\n return 'changed'\n }\n}\n\n// ============================================================================\n// Operation Tracker Integration\n// ============================================================================\n\n/**\n * Get files modified during the current session from operationTracker\n *\n * This provides additional context about which files were touched by Minto,\n * which can be used to prioritize or filter files for auto-commit.\n */\nexport function getTrackedOperations(): OperationSummary {\n return operationTracker.getSummary()\n}\n\n/**\n * Check if operationTracker has any file modifications recorded\n */\nexport function hasTrackedFileChanges(): boolean {\n const summary = operationTracker.getSummary()\n return summary.filesModified.length > 0 || summary.filesCreated.length > 0\n}\n\n/**\n * Enhance changed files with line count data from operationTracker\n *\n * When operationTracker has recorded line changes, use that data\n * instead of computing it via git diff (which is more expensive).\n */\nexport function enhanceWithTrackerData(\n files: ChangedFile[],\n trackerSummary: OperationSummary,\n): ChangedFile[] {\n // Build a map of tracked modifications for fast lookup\n const modifiedMap = new Map<string, { added: number; removed: number }>()\n for (const mod of trackerSummary.filesModified) {\n modifiedMap.set(mod.path, { added: mod.added, removed: mod.removed })\n }\n\n // Enhance file data with tracker info\n return files.map(file => {\n const tracked = modifiedMap.get(file.path)\n if (tracked) {\n return {\n ...file,\n linesAdded: file.linesAdded ?? tracked.added,\n linesRemoved: file.linesRemoved ?? tracked.removed,\n }\n }\n return file\n })\n}\n\n// ============================================================================\n// Testing Utilities\n// ============================================================================\n\n/**\n * Get current working directory (for testing)\n * Re-exported from state for convenience\n */\nexport { getCwd }\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export * from "./config/index.js";
|
|
2
|
+
export * from "./permissions/index.js";
|
|
3
|
+
export * from "./tools/index.js";
|
|
4
|
+
export * from "./costTracker.js";
|
|
5
|
+
export * from "./operationTracker.js";
|
|
6
|
+
export * from "./gitAutoCommit.js";
|
|
7
|
+
export * from "./backupManager.js";
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/core/index.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Core Module\n *\n * Centralized exports for core system functionality.\n */\n\n// Configuration\nexport * from './config'\n\n// Permissions\nexport * from './permissions'\n\n// Tools\nexport * from './tools'\n\n// Cost Tracking\nexport * from './costTracker'\n\n// Operation Tracking\nexport * from './operationTracker'\n\n// Git Auto-Commit\nexport * from './gitAutoCommit'\n\n// Backup Manager\nexport * from './backupManager'\n"],
|
|
5
|
+
"mappings": "AAOA,cAAc;AAGd,cAAc;AAGd,cAAc;AAGd,cAAc;AAGd,cAAc;AAGd,cAAc;AAGd,cAAc;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
import { EventEmitter } from "events";
|
|
2
|
+
class OperationTrackerImpl extends EventEmitter {
|
|
3
|
+
static instance = null;
|
|
4
|
+
/** All recorded operations in chronological order */
|
|
5
|
+
operations = [];
|
|
6
|
+
/** Counter for generating unique IDs */
|
|
7
|
+
idCounter = 0;
|
|
8
|
+
constructor() {
|
|
9
|
+
super();
|
|
10
|
+
this.setMaxListeners(50);
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Get the singleton instance
|
|
14
|
+
*/
|
|
15
|
+
static getInstance() {
|
|
16
|
+
if (!OperationTrackerImpl.instance) {
|
|
17
|
+
OperationTrackerImpl.instance = new OperationTrackerImpl();
|
|
18
|
+
}
|
|
19
|
+
return OperationTrackerImpl.instance;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Record a new operation
|
|
23
|
+
*
|
|
24
|
+
* @param input - Operation details to record
|
|
25
|
+
* @returns The recorded operation with generated id and timestamp
|
|
26
|
+
*/
|
|
27
|
+
record(input) {
|
|
28
|
+
const record = {
|
|
29
|
+
id: `op-${++this.idCounter}-${Date.now()}`,
|
|
30
|
+
type: input.type,
|
|
31
|
+
description: input.description,
|
|
32
|
+
timestamp: Date.now(),
|
|
33
|
+
duration: input.duration,
|
|
34
|
+
details: input.details
|
|
35
|
+
};
|
|
36
|
+
this.operations.push(record);
|
|
37
|
+
this.emit("operation", record);
|
|
38
|
+
return record;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Get aggregated summary of all operations
|
|
42
|
+
*/
|
|
43
|
+
getSummary() {
|
|
44
|
+
const filesRead = /* @__PURE__ */ new Set();
|
|
45
|
+
const filesModified = /* @__PURE__ */ new Map();
|
|
46
|
+
const filesCreated = /* @__PURE__ */ new Set();
|
|
47
|
+
const commandsRun = [];
|
|
48
|
+
let tasksCompleted = 0;
|
|
49
|
+
let totalDuration = 0;
|
|
50
|
+
let webSearches = 0;
|
|
51
|
+
for (const op of this.operations) {
|
|
52
|
+
if (op.duration) {
|
|
53
|
+
totalDuration += op.duration;
|
|
54
|
+
}
|
|
55
|
+
switch (op.type) {
|
|
56
|
+
case "file_read":
|
|
57
|
+
if (op.details?.filePath) {
|
|
58
|
+
filesRead.add(op.details.filePath);
|
|
59
|
+
}
|
|
60
|
+
break;
|
|
61
|
+
case "file_edit":
|
|
62
|
+
if (op.details?.filePath) {
|
|
63
|
+
const existing = filesModified.get(op.details.filePath);
|
|
64
|
+
if (existing) {
|
|
65
|
+
existing.added += op.details.linesAdded ?? 0;
|
|
66
|
+
existing.removed += op.details.linesRemoved ?? 0;
|
|
67
|
+
} else {
|
|
68
|
+
filesModified.set(op.details.filePath, {
|
|
69
|
+
path: op.details.filePath,
|
|
70
|
+
added: op.details.linesAdded ?? 0,
|
|
71
|
+
removed: op.details.linesRemoved ?? 0
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
break;
|
|
76
|
+
case "file_create":
|
|
77
|
+
if (op.details?.filePath) {
|
|
78
|
+
filesCreated.add(op.details.filePath);
|
|
79
|
+
}
|
|
80
|
+
break;
|
|
81
|
+
case "bash_command":
|
|
82
|
+
if (op.details?.command) {
|
|
83
|
+
commandsRun.push(op.details.command);
|
|
84
|
+
}
|
|
85
|
+
break;
|
|
86
|
+
case "web_search":
|
|
87
|
+
webSearches++;
|
|
88
|
+
break;
|
|
89
|
+
case "task":
|
|
90
|
+
tasksCompleted++;
|
|
91
|
+
break;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return {
|
|
95
|
+
filesRead: Array.from(filesRead),
|
|
96
|
+
filesModified: Array.from(filesModified.values()),
|
|
97
|
+
filesCreated: Array.from(filesCreated),
|
|
98
|
+
commandsRun,
|
|
99
|
+
tasksCompleted,
|
|
100
|
+
totalDuration,
|
|
101
|
+
webSearches
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Get all recorded operations
|
|
106
|
+
*/
|
|
107
|
+
getOperations() {
|
|
108
|
+
return [...this.operations];
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Get operation count by type
|
|
112
|
+
*/
|
|
113
|
+
getCountByType(type) {
|
|
114
|
+
return this.operations.filter((op) => op.type === type).length;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Get total operation count
|
|
118
|
+
*/
|
|
119
|
+
getTotalCount() {
|
|
120
|
+
return this.operations.length;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Subscribe to operation events
|
|
124
|
+
*
|
|
125
|
+
* @param callback - Called when an operation is recorded
|
|
126
|
+
* @returns Unsubscribe function
|
|
127
|
+
*/
|
|
128
|
+
onOperation(callback) {
|
|
129
|
+
this.on("operation", callback);
|
|
130
|
+
return () => this.off("operation", callback);
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Clear all recorded operations
|
|
134
|
+
*/
|
|
135
|
+
clear() {
|
|
136
|
+
this.operations = [];
|
|
137
|
+
this.idCounter = 0;
|
|
138
|
+
this.emit("clear");
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Reset for testing (only available in test environment)
|
|
142
|
+
*/
|
|
143
|
+
resetForTests() {
|
|
144
|
+
if (process.env.NODE_ENV !== "test") {
|
|
145
|
+
throw new Error("resetForTests can only be called in tests");
|
|
146
|
+
}
|
|
147
|
+
this.clear();
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
const operationTracker = OperationTrackerImpl.getInstance();
|
|
151
|
+
function recordOperation(input) {
|
|
152
|
+
return operationTracker.record(input);
|
|
153
|
+
}
|
|
154
|
+
function getOperationSummary() {
|
|
155
|
+
return operationTracker.getSummary();
|
|
156
|
+
}
|
|
157
|
+
function recordFileRead(filePath, description) {
|
|
158
|
+
operationTracker.record({
|
|
159
|
+
type: "file_read",
|
|
160
|
+
description: description ?? `Read ${filePath}`,
|
|
161
|
+
details: { filePath }
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
function recordFileEdit(filePath, linesAdded, linesRemoved, description) {
|
|
165
|
+
operationTracker.record({
|
|
166
|
+
type: "file_edit",
|
|
167
|
+
description: description ?? `Edit ${filePath}`,
|
|
168
|
+
details: { filePath, linesAdded, linesRemoved }
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
function recordFileCreate(filePath, description) {
|
|
172
|
+
operationTracker.record({
|
|
173
|
+
type: "file_create",
|
|
174
|
+
description: description ?? `Create ${filePath}`,
|
|
175
|
+
details: { filePath }
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
function recordBashCommand(command, duration, description) {
|
|
179
|
+
operationTracker.record({
|
|
180
|
+
type: "bash_command",
|
|
181
|
+
description: description ?? `Run: ${command}`,
|
|
182
|
+
duration,
|
|
183
|
+
details: { command }
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
function recordWebSearch(searchQuery, description) {
|
|
187
|
+
operationTracker.record({
|
|
188
|
+
type: "web_search",
|
|
189
|
+
description: description ?? `Search: ${searchQuery}`,
|
|
190
|
+
details: { searchQuery }
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
function recordTaskComplete(description, toolCount, duration) {
|
|
194
|
+
operationTracker.record({
|
|
195
|
+
type: "task",
|
|
196
|
+
description,
|
|
197
|
+
duration,
|
|
198
|
+
details: { toolCount }
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
export {
|
|
202
|
+
getOperationSummary,
|
|
203
|
+
operationTracker,
|
|
204
|
+
recordBashCommand,
|
|
205
|
+
recordFileCreate,
|
|
206
|
+
recordFileEdit,
|
|
207
|
+
recordFileRead,
|
|
208
|
+
recordOperation,
|
|
209
|
+
recordTaskComplete,
|
|
210
|
+
recordWebSearch
|
|
211
|
+
};
|
|
212
|
+
//# sourceMappingURL=operationTracker.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/core/operationTracker.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Operation Tracker\n *\n * Tracks file operations, bash commands, and tasks executed during a session.\n * Provides aggregated summaries for user feedback on what changes were made.\n *\n * Architecture:\n * - Singleton pattern for global access\n * - Event-driven updates for real-time UI\n * - Categorized operation tracking (file_read, file_edit, file_create, bash_command, web_search, task)\n *\n * Usage:\n * ```typescript\n * import { operationTracker, recordOperation } from '@core/operationTracker'\n *\n * // Record a file read\n * recordOperation({\n * type: 'file_read',\n * description: 'Read configuration file',\n * details: { filePath: '/path/to/config.json' }\n * })\n *\n * // Get summary of all operations\n * const summary = operationTracker.getSummary()\n *\n * // Subscribe to updates\n * const unsubscribe = operationTracker.onOperation((record) => {\n * console.log('Operation recorded:', record)\n * })\n * ```\n */\n\nimport { EventEmitter } from 'events'\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Type of operation that can be tracked\n */\nexport type OperationType =\n | 'file_read'\n | 'file_edit'\n | 'file_create'\n | 'bash_command'\n | 'web_search'\n | 'task'\n\n/**\n * Details specific to each operation type\n */\nexport interface OperationDetails {\n /** File path for file operations */\n filePath?: string\n\n /** Command string for bash operations */\n command?: string\n\n /** Lines added for file edits */\n linesAdded?: number\n\n /** Lines removed for file edits */\n linesRemoved?: number\n\n /** Number of tools used for task operations */\n toolCount?: number\n\n /** Search query for web search operations */\n searchQuery?: string\n}\n\n/**\n * A single recorded operation\n */\nexport interface OperationRecord {\n /** Unique identifier for the operation */\n id: string\n\n /** Type of operation */\n type: OperationType\n\n /** Human-readable description */\n description: string\n\n /** Unix timestamp when operation started */\n timestamp: number\n\n /** Duration in milliseconds (if completed) */\n duration?: number\n\n /** Additional details specific to operation type */\n details?: OperationDetails\n}\n\n/**\n * Aggregated summary of all operations\n */\nexport interface OperationSummary {\n /** List of files that were read */\n filesRead: string[]\n\n /** List of files that were modified with change stats */\n filesModified: { path: string; added: number; removed: number }[]\n\n /** List of files that were created */\n filesCreated: string[]\n\n /** List of bash commands that were run */\n commandsRun: string[]\n\n /** Number of tasks completed */\n tasksCompleted: number\n\n /** Total duration of all operations in milliseconds */\n totalDuration: number\n\n /** Number of web searches performed */\n webSearches: number\n}\n\n/**\n * Input for recording an operation (id and timestamp auto-generated)\n */\nexport interface OperationInput {\n type: OperationType\n description: string\n duration?: number\n details?: OperationDetails\n}\n\n// ============================================================================\n// Implementation\n// ============================================================================\n\n/**\n * OperationTrackerImpl - Centralized operation tracking\n */\nclass OperationTrackerImpl extends EventEmitter {\n private static instance: OperationTrackerImpl | null = null\n\n /** All recorded operations in chronological order */\n private operations: OperationRecord[] = []\n\n /** Counter for generating unique IDs */\n private idCounter = 0\n\n private constructor() {\n super()\n this.setMaxListeners(50)\n }\n\n /**\n * Get the singleton instance\n */\n static getInstance(): OperationTrackerImpl {\n if (!OperationTrackerImpl.instance) {\n OperationTrackerImpl.instance = new OperationTrackerImpl()\n }\n return OperationTrackerImpl.instance\n }\n\n /**\n * Record a new operation\n *\n * @param input - Operation details to record\n * @returns The recorded operation with generated id and timestamp\n */\n record(input: OperationInput): OperationRecord {\n const record: OperationRecord = {\n id: `op-${++this.idCounter}-${Date.now()}`,\n type: input.type,\n description: input.description,\n timestamp: Date.now(),\n duration: input.duration,\n details: input.details,\n }\n\n this.operations.push(record)\n this.emit('operation', record)\n\n return record\n }\n\n /**\n * Get aggregated summary of all operations\n */\n getSummary(): OperationSummary {\n const filesRead = new Set<string>()\n const filesModified = new Map<\n string,\n { path: string; added: number; removed: number }\n >()\n const filesCreated = new Set<string>()\n const commandsRun: string[] = []\n let tasksCompleted = 0\n let totalDuration = 0\n let webSearches = 0\n\n for (const op of this.operations) {\n // Accumulate duration\n if (op.duration) {\n totalDuration += op.duration\n }\n\n switch (op.type) {\n case 'file_read':\n if (op.details?.filePath) {\n filesRead.add(op.details.filePath)\n }\n break\n\n case 'file_edit':\n if (op.details?.filePath) {\n const existing = filesModified.get(op.details.filePath)\n if (existing) {\n // Accumulate changes to the same file\n existing.added += op.details.linesAdded ?? 0\n existing.removed += op.details.linesRemoved ?? 0\n } else {\n filesModified.set(op.details.filePath, {\n path: op.details.filePath,\n added: op.details.linesAdded ?? 0,\n removed: op.details.linesRemoved ?? 0,\n })\n }\n }\n break\n\n case 'file_create':\n if (op.details?.filePath) {\n filesCreated.add(op.details.filePath)\n }\n break\n\n case 'bash_command':\n if (op.details?.command) {\n commandsRun.push(op.details.command)\n }\n break\n\n case 'web_search':\n webSearches++\n break\n\n case 'task':\n tasksCompleted++\n break\n }\n }\n\n return {\n filesRead: Array.from(filesRead),\n filesModified: Array.from(filesModified.values()),\n filesCreated: Array.from(filesCreated),\n commandsRun,\n tasksCompleted,\n totalDuration,\n webSearches,\n }\n }\n\n /**\n * Get all recorded operations\n */\n getOperations(): OperationRecord[] {\n return [...this.operations]\n }\n\n /**\n * Get operation count by type\n */\n getCountByType(type: OperationType): number {\n return this.operations.filter(op => op.type === type).length\n }\n\n /**\n * Get total operation count\n */\n getTotalCount(): number {\n return this.operations.length\n }\n\n /**\n * Subscribe to operation events\n *\n * @param callback - Called when an operation is recorded\n * @returns Unsubscribe function\n */\n onOperation(callback: (record: OperationRecord) => void): () => void {\n this.on('operation', callback)\n return () => this.off('operation', callback)\n }\n\n /**\n * Clear all recorded operations\n */\n clear(): void {\n this.operations = []\n this.idCounter = 0\n this.emit('clear')\n }\n\n /**\n * Reset for testing (only available in test environment)\n */\n resetForTests(): void {\n if (process.env.NODE_ENV !== 'test') {\n throw new Error('resetForTests can only be called in tests')\n }\n this.clear()\n }\n}\n\n// ============================================================================\n// Exports\n// ============================================================================\n\n/** Singleton instance */\nexport const operationTracker = OperationTrackerImpl.getInstance()\n\n/**\n * Record an operation\n *\n * Convenience function for recording operations without accessing the singleton directly.\n */\nexport function recordOperation(input: OperationInput): OperationRecord {\n return operationTracker.record(input)\n}\n\n/**\n * Get operation summary\n *\n * Convenience function for getting summary without accessing the singleton directly.\n */\nexport function getOperationSummary(): OperationSummary {\n return operationTracker.getSummary()\n}\n\n/**\n * Record a file read operation\n */\nexport function recordFileRead(filePath: string, description?: string): void {\n operationTracker.record({\n type: 'file_read',\n description: description ?? `Read ${filePath}`,\n details: { filePath },\n })\n}\n\n/**\n * Record a file edit operation\n */\nexport function recordFileEdit(\n filePath: string,\n linesAdded: number,\n linesRemoved: number,\n description?: string,\n): void {\n operationTracker.record({\n type: 'file_edit',\n description: description ?? `Edit ${filePath}`,\n details: { filePath, linesAdded, linesRemoved },\n })\n}\n\n/**\n * Record a file create operation\n */\nexport function recordFileCreate(filePath: string, description?: string): void {\n operationTracker.record({\n type: 'file_create',\n description: description ?? `Create ${filePath}`,\n details: { filePath },\n })\n}\n\n/**\n * Record a bash command execution\n */\nexport function recordBashCommand(\n command: string,\n duration?: number,\n description?: string,\n): void {\n operationTracker.record({\n type: 'bash_command',\n description: description ?? `Run: ${command}`,\n duration,\n details: { command },\n })\n}\n\n/**\n * Record a web search operation\n */\nexport function recordWebSearch(\n searchQuery: string,\n description?: string,\n): void {\n operationTracker.record({\n type: 'web_search',\n description: description ?? `Search: ${searchQuery}`,\n details: { searchQuery },\n })\n}\n\n/**\n * Record a task completion\n */\nexport function recordTaskComplete(\n description: string,\n toolCount?: number,\n duration?: number,\n): void {\n operationTracker.record({\n type: 'task',\n description,\n duration,\n details: { toolCount },\n })\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
import { appendFileSync, existsSync, mkdirSync, readFileSync } from "fs";
|
|
2
|
+
import { join } from "path";
|
|
3
|
+
import { homedir } from "os";
|
|
4
|
+
import { getOriginalCwd } from "../../utils/state.js";
|
|
5
|
+
let sessionLog = [];
|
|
6
|
+
let sessionId = generateSessionId();
|
|
7
|
+
function generateSessionId() {
|
|
8
|
+
return `session_${Date.now()}_${Math.random().toString(36).substring(2, 8)}`;
|
|
9
|
+
}
|
|
10
|
+
function generateEntryId() {
|
|
11
|
+
return `audit_${Date.now()}_${Math.random().toString(36).substring(2, 6)}`;
|
|
12
|
+
}
|
|
13
|
+
function getAuditLogDir() {
|
|
14
|
+
return join(homedir(), ".minto", "audit");
|
|
15
|
+
}
|
|
16
|
+
function getAuditLogFilePath() {
|
|
17
|
+
const dir = getAuditLogDir();
|
|
18
|
+
const date = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
19
|
+
return join(dir, `audit-${date}.jsonl`);
|
|
20
|
+
}
|
|
21
|
+
function ensureAuditLogDir() {
|
|
22
|
+
const dir = getAuditLogDir();
|
|
23
|
+
if (!existsSync(dir)) {
|
|
24
|
+
mkdirSync(dir, { recursive: true });
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
function persistEntry(entry) {
|
|
28
|
+
try {
|
|
29
|
+
ensureAuditLogDir();
|
|
30
|
+
const filePath = getAuditLogFilePath();
|
|
31
|
+
const line = JSON.stringify(entry) + "\n";
|
|
32
|
+
appendFileSync(filePath, line, "utf-8");
|
|
33
|
+
} catch (error) {
|
|
34
|
+
console.error("[Audit] Failed to persist log entry:", error);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
function logSecurityEvent(params) {
|
|
38
|
+
const entry = {
|
|
39
|
+
id: generateEntryId(),
|
|
40
|
+
timestamp: Date.now(),
|
|
41
|
+
eventType: params.eventType,
|
|
42
|
+
toolName: params.toolName,
|
|
43
|
+
operation: params.operation,
|
|
44
|
+
target: params.target,
|
|
45
|
+
outcome: params.outcome,
|
|
46
|
+
riskLevel: params.riskLevel,
|
|
47
|
+
context: params.context,
|
|
48
|
+
projectDir: getOriginalCwd(),
|
|
49
|
+
userDecision: params.userDecision,
|
|
50
|
+
triggeredRule: params.triggeredRule,
|
|
51
|
+
sessionId
|
|
52
|
+
};
|
|
53
|
+
sessionLog.push(entry);
|
|
54
|
+
persistEntry(entry);
|
|
55
|
+
return entry;
|
|
56
|
+
}
|
|
57
|
+
function logPermissionGranted(toolName, operation, target, userDecision = "approved", context) {
|
|
58
|
+
return logSecurityEvent({
|
|
59
|
+
eventType: "permission_granted",
|
|
60
|
+
toolName,
|
|
61
|
+
operation,
|
|
62
|
+
target,
|
|
63
|
+
outcome: "allowed",
|
|
64
|
+
userDecision,
|
|
65
|
+
context
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
function logPermissionDenied(toolName, operation, target, triggeredRule, context) {
|
|
69
|
+
return logSecurityEvent({
|
|
70
|
+
eventType: "permission_denied",
|
|
71
|
+
toolName,
|
|
72
|
+
operation,
|
|
73
|
+
target,
|
|
74
|
+
outcome: "denied",
|
|
75
|
+
userDecision: "rejected",
|
|
76
|
+
triggeredRule,
|
|
77
|
+
context
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
function logOperationBlocked(toolName, operation, target, triggeredRule, riskLevel, context) {
|
|
81
|
+
return logSecurityEvent({
|
|
82
|
+
eventType: "permission_blocked",
|
|
83
|
+
toolName,
|
|
84
|
+
operation,
|
|
85
|
+
target,
|
|
86
|
+
outcome: "blocked",
|
|
87
|
+
riskLevel,
|
|
88
|
+
triggeredRule,
|
|
89
|
+
context
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
function logSensitivePathAccess(toolName, operation, target, category, outcome, userDecision) {
|
|
93
|
+
return logSecurityEvent({
|
|
94
|
+
eventType: "sensitive_path_access",
|
|
95
|
+
toolName,
|
|
96
|
+
operation,
|
|
97
|
+
target,
|
|
98
|
+
outcome,
|
|
99
|
+
riskLevel: "high",
|
|
100
|
+
userDecision,
|
|
101
|
+
context: { category }
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
function logExternalOperation(toolName, operation, target, riskLevel, outcome, userDecision) {
|
|
105
|
+
return logSecurityEvent({
|
|
106
|
+
eventType: "external_operation",
|
|
107
|
+
toolName,
|
|
108
|
+
operation,
|
|
109
|
+
target,
|
|
110
|
+
outcome,
|
|
111
|
+
riskLevel,
|
|
112
|
+
userDecision
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
function logDangerousCommand(command, outcome, pattern, userDecision) {
|
|
116
|
+
return logSecurityEvent({
|
|
117
|
+
eventType: "dangerous_command",
|
|
118
|
+
toolName: "Bash",
|
|
119
|
+
operation: "execute",
|
|
120
|
+
target: command,
|
|
121
|
+
outcome,
|
|
122
|
+
riskLevel: "high",
|
|
123
|
+
userDecision,
|
|
124
|
+
context: pattern ? { matchedPattern: pattern } : void 0
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
function getSessionLog() {
|
|
128
|
+
return [...sessionLog];
|
|
129
|
+
}
|
|
130
|
+
function getEntriesByType(eventType) {
|
|
131
|
+
return sessionLog.filter((entry) => entry.eventType === eventType);
|
|
132
|
+
}
|
|
133
|
+
function getEntriesByOutcome(outcome) {
|
|
134
|
+
return sessionLog.filter((entry) => entry.outcome === outcome);
|
|
135
|
+
}
|
|
136
|
+
function getSessionSecuritySummary() {
|
|
137
|
+
return {
|
|
138
|
+
totalEvents: sessionLog.length,
|
|
139
|
+
allowed: sessionLog.filter((e) => e.outcome === "allowed").length,
|
|
140
|
+
denied: sessionLog.filter((e) => e.outcome === "denied").length,
|
|
141
|
+
blocked: sessionLog.filter((e) => e.outcome === "blocked").length,
|
|
142
|
+
sensitiveAccesses: sessionLog.filter(
|
|
143
|
+
(e) => e.eventType === "sensitive_path_access"
|
|
144
|
+
).length,
|
|
145
|
+
externalOperations: sessionLog.filter(
|
|
146
|
+
(e) => e.eventType === "external_operation"
|
|
147
|
+
).length,
|
|
148
|
+
dangerousCommands: sessionLog.filter(
|
|
149
|
+
(e) => e.eventType === "dangerous_command"
|
|
150
|
+
).length,
|
|
151
|
+
highRiskEvents: sessionLog.filter(
|
|
152
|
+
(e) => e.riskLevel === "high" || e.riskLevel === "critical"
|
|
153
|
+
).length
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
function clearSessionLog() {
|
|
157
|
+
sessionLog = [];
|
|
158
|
+
}
|
|
159
|
+
function resetSession() {
|
|
160
|
+
sessionId = generateSessionId();
|
|
161
|
+
sessionLog = [];
|
|
162
|
+
}
|
|
163
|
+
function readAuditLog(date) {
|
|
164
|
+
const targetDate = date || (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
165
|
+
const filePath = join(getAuditLogDir(), `audit-${targetDate}.jsonl`);
|
|
166
|
+
if (!existsSync(filePath)) {
|
|
167
|
+
return [];
|
|
168
|
+
}
|
|
169
|
+
try {
|
|
170
|
+
const content = readFileSync(filePath, "utf-8");
|
|
171
|
+
return content.split("\n").filter((line) => line.trim()).map((line) => JSON.parse(line));
|
|
172
|
+
} catch (error) {
|
|
173
|
+
console.error("[Audit] Failed to read audit log:", error);
|
|
174
|
+
return [];
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
function getRecentSecurityEvents(count = 10) {
|
|
178
|
+
return sessionLog.slice(-count);
|
|
179
|
+
}
|
|
180
|
+
function formatAuditEntry(entry) {
|
|
181
|
+
const timestamp = new Date(entry.timestamp).toISOString();
|
|
182
|
+
const icon = entry.outcome === "allowed" ? "\u2705" : entry.outcome === "denied" ? "\u274C" : "\u{1F6AB}";
|
|
183
|
+
const risk = entry.riskLevel ? ` [${entry.riskLevel.toUpperCase()}]` : "";
|
|
184
|
+
return `${icon} [${timestamp}]${risk} ${entry.eventType}: ${entry.toolName} ${entry.operation} \u2192 ${entry.target}`;
|
|
185
|
+
}
|
|
186
|
+
export {
|
|
187
|
+
clearSessionLog,
|
|
188
|
+
formatAuditEntry,
|
|
189
|
+
getEntriesByOutcome,
|
|
190
|
+
getEntriesByType,
|
|
191
|
+
getRecentSecurityEvents,
|
|
192
|
+
getSessionLog,
|
|
193
|
+
getSessionSecuritySummary,
|
|
194
|
+
logDangerousCommand,
|
|
195
|
+
logExternalOperation,
|
|
196
|
+
logOperationBlocked,
|
|
197
|
+
logPermissionDenied,
|
|
198
|
+
logPermissionGranted,
|
|
199
|
+
logSecurityEvent,
|
|
200
|
+
logSensitivePathAccess,
|
|
201
|
+
readAuditLog,
|
|
202
|
+
resetSession
|
|
203
|
+
};
|
|
204
|
+
//# sourceMappingURL=auditLog.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/core/permissions/auditLog.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Security Audit Log\n *\n * Records all security-sensitive operations for accountability and debugging.\n * Logs are stored both in memory (for current session) and optionally on disk.\n */\n\nimport { appendFileSync, existsSync, mkdirSync, readFileSync } from 'fs'\nimport { join } from 'path'\nimport { homedir } from 'os'\nimport { getOriginalCwd } from '@utils/state'\n\n/**\n * Audit log entry type\n */\nexport type AuditEventType =\n | 'permission_granted' // User granted permission\n | 'permission_denied' // Permission was denied (user or rule)\n | 'permission_blocked' // Operation was blocked by security rule\n | 'sensitive_path_access' // Access to sensitive path\n | 'external_operation' // Operation outside project directory\n | 'dangerous_command' // Dangerous command execution\n | 'security_warning' // Security warning issued\n\n/**\n * Audit log entry\n */\nexport interface AuditLogEntry {\n /** Unique entry ID */\n id: string\n /** Timestamp */\n timestamp: number\n /** Event type */\n eventType: AuditEventType\n /** Tool name */\n toolName: string\n /** Operation details */\n operation: string\n /** Target path or command */\n target: string\n /** Outcome: allowed, denied, blocked */\n outcome: 'allowed' | 'denied' | 'blocked'\n /** Risk level if applicable */\n riskLevel?: 'low' | 'medium' | 'high' | 'critical'\n /** Additional context */\n context?: Record<string, unknown>\n /** Project directory */\n projectDir: string\n /** User decision (if applicable) */\n userDecision?: 'approved' | 'rejected' | 'auto'\n /** Rule that triggered (if applicable) */\n triggeredRule?: string\n /** Session ID */\n sessionId: string\n}\n\n/**\n * In-memory audit log for current session\n */\nlet sessionLog: AuditLogEntry[] = []\nlet sessionId: string = generateSessionId()\n\n/**\n * Generate a unique session ID\n */\nfunction generateSessionId(): string {\n return `session_${Date.now()}_${Math.random().toString(36).substring(2, 8)}`\n}\n\n/**\n * Generate a unique entry ID\n */\nfunction generateEntryId(): string {\n return `audit_${Date.now()}_${Math.random().toString(36).substring(2, 6)}`\n}\n\n/**\n * Get the audit log directory\n */\nfunction getAuditLogDir(): string {\n return join(homedir(), '.minto', 'audit')\n}\n\n/**\n * Get the current day's audit log file path\n */\nfunction getAuditLogFilePath(): string {\n const dir = getAuditLogDir()\n const date = new Date().toISOString().split('T')[0] // YYYY-MM-DD\n return join(dir, `audit-${date}.jsonl`)\n}\n\n/**\n * Ensure audit log directory exists\n */\nfunction ensureAuditLogDir(): void {\n const dir = getAuditLogDir()\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true })\n }\n}\n\n/**\n * Write entry to disk\n */\nfunction persistEntry(entry: AuditLogEntry): void {\n try {\n ensureAuditLogDir()\n const filePath = getAuditLogFilePath()\n const line = JSON.stringify(entry) + '\\n'\n appendFileSync(filePath, line, 'utf-8')\n } catch (error) {\n // Silently fail - audit logging should not break the application\n console.error('[Audit] Failed to persist log entry:', error)\n }\n}\n\n/**\n * Log a security event\n */\nexport function logSecurityEvent(params: {\n eventType: AuditEventType\n toolName: string\n operation: string\n target: string\n outcome: 'allowed' | 'denied' | 'blocked'\n riskLevel?: 'low' | 'medium' | 'high' | 'critical'\n context?: Record<string, unknown>\n userDecision?: 'approved' | 'rejected' | 'auto'\n triggeredRule?: string\n}): AuditLogEntry {\n const entry: AuditLogEntry = {\n id: generateEntryId(),\n timestamp: Date.now(),\n eventType: params.eventType,\n toolName: params.toolName,\n operation: params.operation,\n target: params.target,\n outcome: params.outcome,\n riskLevel: params.riskLevel,\n context: params.context,\n projectDir: getOriginalCwd(),\n userDecision: params.userDecision,\n triggeredRule: params.triggeredRule,\n sessionId,\n }\n\n // Add to in-memory log\n sessionLog.push(entry)\n\n // Persist to disk\n persistEntry(entry)\n\n return entry\n}\n\n/**\n * Log permission granted event\n */\nexport function logPermissionGranted(\n toolName: string,\n operation: string,\n target: string,\n userDecision: 'approved' | 'auto' = 'approved',\n context?: Record<string, unknown>,\n): AuditLogEntry {\n return logSecurityEvent({\n eventType: 'permission_granted',\n toolName,\n operation,\n target,\n outcome: 'allowed',\n userDecision,\n context,\n })\n}\n\n/**\n * Log permission denied event\n */\nexport function logPermissionDenied(\n toolName: string,\n operation: string,\n target: string,\n triggeredRule?: string,\n context?: Record<string, unknown>,\n): AuditLogEntry {\n return logSecurityEvent({\n eventType: 'permission_denied',\n toolName,\n operation,\n target,\n outcome: 'denied',\n userDecision: 'rejected',\n triggeredRule,\n context,\n })\n}\n\n/**\n * Log operation blocked by security rule\n */\nexport function logOperationBlocked(\n toolName: string,\n operation: string,\n target: string,\n triggeredRule: string,\n riskLevel: 'low' | 'medium' | 'high' | 'critical',\n context?: Record<string, unknown>,\n): AuditLogEntry {\n return logSecurityEvent({\n eventType: 'permission_blocked',\n toolName,\n operation,\n target,\n outcome: 'blocked',\n riskLevel,\n triggeredRule,\n context,\n })\n}\n\n/**\n * Log sensitive path access\n */\nexport function logSensitivePathAccess(\n toolName: string,\n operation: string,\n target: string,\n category: string,\n outcome: 'allowed' | 'denied' | 'blocked',\n userDecision?: 'approved' | 'rejected',\n): AuditLogEntry {\n return logSecurityEvent({\n eventType: 'sensitive_path_access',\n toolName,\n operation,\n target,\n outcome,\n riskLevel: 'high',\n userDecision,\n context: { category },\n })\n}\n\n/**\n * Log external operation (outside project directory)\n */\nexport function logExternalOperation(\n toolName: string,\n operation: string,\n target: string,\n riskLevel: 'low' | 'medium' | 'high' | 'critical',\n outcome: 'allowed' | 'denied' | 'blocked',\n userDecision?: 'approved' | 'rejected',\n): AuditLogEntry {\n return logSecurityEvent({\n eventType: 'external_operation',\n toolName,\n operation,\n target,\n outcome,\n riskLevel,\n userDecision,\n })\n}\n\n/**\n * Log dangerous command execution\n */\nexport function logDangerousCommand(\n command: string,\n outcome: 'allowed' | 'denied' | 'blocked',\n pattern?: string,\n userDecision?: 'approved' | 'rejected',\n): AuditLogEntry {\n return logSecurityEvent({\n eventType: 'dangerous_command',\n toolName: 'Bash',\n operation: 'execute',\n target: command,\n outcome,\n riskLevel: 'high',\n userDecision,\n context: pattern ? { matchedPattern: pattern } : undefined,\n })\n}\n\n/**\n * Get all entries from current session\n */\nexport function getSessionLog(): AuditLogEntry[] {\n return [...sessionLog]\n}\n\n/**\n * Get entries filtered by event type\n */\nexport function getEntriesByType(eventType: AuditEventType): AuditLogEntry[] {\n return sessionLog.filter(entry => entry.eventType === eventType)\n}\n\n/**\n * Get entries filtered by outcome\n */\nexport function getEntriesByOutcome(\n outcome: 'allowed' | 'denied' | 'blocked',\n): AuditLogEntry[] {\n return sessionLog.filter(entry => entry.outcome === outcome)\n}\n\n/**\n * Get security summary for current session\n */\nexport function getSessionSecuritySummary(): {\n totalEvents: number\n allowed: number\n denied: number\n blocked: number\n sensitiveAccesses: number\n externalOperations: number\n dangerousCommands: number\n highRiskEvents: number\n} {\n return {\n totalEvents: sessionLog.length,\n allowed: sessionLog.filter(e => e.outcome === 'allowed').length,\n denied: sessionLog.filter(e => e.outcome === 'denied').length,\n blocked: sessionLog.filter(e => e.outcome === 'blocked').length,\n sensitiveAccesses: sessionLog.filter(\n e => e.eventType === 'sensitive_path_access',\n ).length,\n externalOperations: sessionLog.filter(\n e => e.eventType === 'external_operation',\n ).length,\n dangerousCommands: sessionLog.filter(\n e => e.eventType === 'dangerous_command',\n ).length,\n highRiskEvents: sessionLog.filter(\n e => e.riskLevel === 'high' || e.riskLevel === 'critical',\n ).length,\n }\n}\n\n/**\n * Clear session log (for testing)\n */\nexport function clearSessionLog(): void {\n sessionLog = []\n}\n\n/**\n * Reset session (generates new session ID)\n */\nexport function resetSession(): void {\n sessionId = generateSessionId()\n sessionLog = []\n}\n\n/**\n * Read audit log entries from disk for a specific date\n */\nexport function readAuditLog(date?: string): AuditLogEntry[] {\n const targetDate = date || new Date().toISOString().split('T')[0]\n const filePath = join(getAuditLogDir(), `audit-${targetDate}.jsonl`)\n\n if (!existsSync(filePath)) {\n return []\n }\n\n try {\n const content = readFileSync(filePath, 'utf-8')\n return content\n .split('\\n')\n .filter(line => line.trim())\n .map(line => JSON.parse(line) as AuditLogEntry)\n } catch (error) {\n console.error('[Audit] Failed to read audit log:', error)\n return []\n }\n}\n\n/**\n * Get recent security events (last N entries)\n */\nexport function getRecentSecurityEvents(count: number = 10): AuditLogEntry[] {\n return sessionLog.slice(-count)\n}\n\n/**\n * Format audit entry for display\n */\nexport function formatAuditEntry(entry: AuditLogEntry): string {\n const timestamp = new Date(entry.timestamp).toISOString()\n const icon =\n entry.outcome === 'allowed'\n ? '\u2705'\n : entry.outcome === 'denied'\n ? '\u274C'\n : '\uD83D\uDEAB'\n const risk = entry.riskLevel ? ` [${entry.riskLevel.toUpperCase()}]` : ''\n\n return `${icon} [${timestamp}]${risk} ${entry.eventType}: ${entry.toolName} ${entry.operation} \u2192 ${entry.target}`\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|