@noorm/marie-cli 0.1.18 → 0.1.25
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/README.md +7 -15
- package/SENTINEL.md +4 -7
- package/dist/cli-new/components/App.js +16 -63
- package/dist/cli-new/components/App.js.map +1 -1
- package/dist/cli-new/components/ApprovalDialog.js +2 -1
- package/dist/cli-new/components/ApprovalDialog.js.map +1 -1
- package/dist/cli-new/components/Banner.js +4 -3
- package/dist/cli-new/components/Banner.js.map +1 -1
- package/dist/cli-new/components/ChatArea.js +6 -7
- package/dist/cli-new/components/ChatArea.js.map +1 -1
- package/dist/cli-new/components/Header.js +13 -7
- package/dist/cli-new/components/Header.js.map +1 -1
- package/dist/cli-new/components/InputArea.js +73 -12
- package/dist/cli-new/components/InputArea.js.map +1 -1
- package/dist/cli-new/components/MessageBubble.js +26 -18
- package/dist/cli-new/components/MessageBubble.js.map +1 -1
- package/dist/cli-new/components/SessionSwitcher.js +4 -7
- package/dist/cli-new/components/SessionSwitcher.js.map +1 -1
- package/dist/cli-new/components/SetupWizard.js +80 -257
- package/dist/cli-new/components/SetupWizard.js.map +1 -1
- package/dist/cli-new/components/ToolCallDisplay.js +20 -5
- package/dist/cli-new/components/ToolCallDisplay.js.map +1 -1
- package/dist/cli-new/components/WizardSteps.js +22 -0
- package/dist/cli-new/components/WizardSteps.js.map +1 -0
- package/dist/cli-new/constants/SetupConstants.js +42 -0
- package/dist/cli-new/constants/SetupConstants.js.map +1 -0
- package/dist/cli-new/hooks/useGit.js +19 -62
- package/dist/cli-new/hooks/useGit.js.map +1 -1
- package/dist/cli-new/hooks/useMarie.js +26 -18
- package/dist/cli-new/hooks/useMarie.js.map +1 -1
- package/dist/cli-new/hooks/useSessions.js +1 -1
- package/dist/cli-new/hooks/useSessions.js.map +1 -1
- package/dist/cli-new/hooks/useSetupWizard.js +88 -0
- package/dist/cli-new/hooks/useSetupWizard.js.map +1 -0
- package/dist/cli-new/hooks/useUpdateCheck.js +4 -3
- package/dist/cli-new/hooks/useUpdateCheck.js.map +1 -1
- package/dist/cli-new/index.js +2 -4
- package/dist/cli-new/index.js.map +1 -1
- package/dist/cli-new/services/CommandService.js +104 -0
- package/dist/cli-new/services/CommandService.js.map +1 -0
- package/dist/cli-new/services/GitService.js +91 -0
- package/dist/cli-new/services/GitService.js.map +1 -0
- package/dist/cli-new/services/MarieService.js +77 -0
- package/dist/cli-new/services/MarieService.js.map +1 -0
- package/dist/cli-new/services/auth-server.js +128 -0
- package/dist/cli-new/services/auth-server.js.map +1 -0
- package/dist/cli-new/utils/version.js +24 -0
- package/dist/cli-new/utils/version.js.map +1 -0
- package/dist/monolith/adapters/CliMarieAdapter.js +12 -11
- package/dist/monolith/adapters/CliMarieAdapter.js.map +1 -1
- package/dist/monolith/cli/CliFileSystemPort.js +17 -3
- package/dist/monolith/cli/CliFileSystemPort.js.map +1 -1
- package/dist/monolith/cli/MarieToolDefinitionsCLI.js +39 -31
- package/dist/monolith/cli/MarieToolDefinitionsCLI.js.map +1 -1
- package/dist/monolith/cli/index.js +5 -20
- package/dist/monolith/cli/index.js.map +1 -1
- package/dist/monolith/cli/services/JoyAutomationServiceCLI.js +15 -62
- package/dist/monolith/cli/services/JoyAutomationServiceCLI.js.map +1 -1
- package/dist/monolith/cli/storage.js +142 -72
- package/dist/monolith/cli/storage.js.map +1 -1
- package/dist/monolith/domain/joy/RitualService.js +44 -46
- package/dist/monolith/domain/joy/RitualService.js.map +1 -1
- package/dist/monolith/domain/marie/MarieCortex.js +148 -0
- package/dist/monolith/domain/marie/MarieCortex.js.map +1 -0
- package/dist/monolith/domain/marie/PersonalityRenderer.js +97 -0
- package/dist/monolith/domain/marie/PersonalityRenderer.js.map +1 -0
- package/dist/monolith/infrastructure/Configuration.js +68 -0
- package/dist/monolith/infrastructure/Configuration.js.map +1 -0
- package/dist/monolith/infrastructure/CoreInfrastructure.js +204 -0
- package/dist/monolith/infrastructure/CoreInfrastructure.js.map +1 -0
- package/dist/monolith/infrastructure/ai/agents/MarieAscendant.js +3 -3
- package/dist/monolith/infrastructure/ai/agents/MarieAscendant.js.map +1 -1
- package/dist/monolith/infrastructure/ai/context/ContextArchiveService.js +6 -27
- package/dist/monolith/infrastructure/ai/context/ContextArchiveService.js.map +1 -1
- package/dist/monolith/infrastructure/ai/context/ContextManager.js +142 -131
- package/dist/monolith/infrastructure/ai/context/ContextManager.js.map +1 -1
- package/dist/monolith/infrastructure/ai/core/MarieEngine.js +115 -1077
- package/dist/monolith/infrastructure/ai/core/MarieEngine.js.map +1 -1
- package/dist/monolith/infrastructure/ai/core/MarieEventDispatcher.js +1 -37
- package/dist/monolith/infrastructure/ai/core/MarieEventDispatcher.js.map +1 -1
- package/dist/monolith/infrastructure/ai/core/MarieLockManager.js +6 -1
- package/dist/monolith/infrastructure/ai/core/MarieLockManager.js.map +1 -1
- package/dist/monolith/infrastructure/ai/core/MarieProgressTracker.js +172 -221
- package/dist/monolith/infrastructure/ai/core/MarieProgressTracker.js.map +1 -1
- package/dist/monolith/infrastructure/ai/core/MarieSanitizer.js +292 -141
- package/dist/monolith/infrastructure/ai/core/MarieSanitizer.js.map +1 -1
- package/dist/monolith/infrastructure/ai/core/MarieToolProcessor.js +331 -614
- package/dist/monolith/infrastructure/ai/core/MarieToolProcessor.js.map +1 -1
- package/dist/monolith/infrastructure/ai/core/MarieVitality.js +238 -0
- package/dist/monolith/infrastructure/ai/core/MarieVitality.js.map +1 -0
- package/dist/monolith/infrastructure/ai/core/SessionLogService.js +9 -2
- package/dist/monolith/infrastructure/ai/core/SessionLogService.js.map +1 -1
- package/dist/monolith/infrastructure/ai/providers/AIProvider.js +402 -1
- package/dist/monolith/infrastructure/ai/providers/AIProvider.js.map +1 -1
- package/dist/monolith/infrastructure/ai/providers/DreamBeesProvider.js +114 -0
- package/dist/monolith/infrastructure/ai/providers/DreamBeesProvider.js.map +1 -0
- package/dist/monolith/infrastructure/ai/providers/OpenRouterProvider.js +426 -392
- package/dist/monolith/infrastructure/ai/providers/OpenRouterProvider.js.map +1 -1
- package/dist/monolith/infrastructure/ai/providers/OpenRouterStreamParser.js +235 -241
- package/dist/monolith/infrastructure/ai/providers/OpenRouterStreamParser.js.map +1 -1
- package/dist/monolith/infrastructure/ai/workerAi.js +185 -0
- package/dist/monolith/infrastructure/ai/workerAi.js.map +1 -0
- package/dist/monolith/infrastructure/config/ConfigService.js +216 -503
- package/dist/monolith/infrastructure/config/ConfigService.js.map +1 -1
- package/dist/monolith/infrastructure/joy/CognitiveRituals.js +4 -165
- package/dist/monolith/infrastructure/joy/CognitiveRituals.js.map +1 -1
- package/dist/monolith/infrastructure/joy/JoyTools.js +14 -47
- package/dist/monolith/infrastructure/joy/JoyTools.js.map +1 -1
- package/dist/monolith/infrastructure/persistence/MarieMindAutonomics.js +4 -0
- package/dist/monolith/infrastructure/persistence/MarieMindAutonomics.js.map +1 -0
- package/dist/monolith/infrastructure/persistence/MarieMindEngine.js +11 -0
- package/dist/monolith/infrastructure/persistence/MarieMindEngine.js.map +1 -0
- package/dist/monolith/infrastructure/persistence/NoormmeAutonomics.js +123 -106
- package/dist/monolith/infrastructure/persistence/NoormmeAutonomics.js.map +1 -1
- package/dist/monolith/infrastructure/persistence/NoormmeEngine.js +508 -63
- package/dist/monolith/infrastructure/persistence/NoormmeEngine.js.map +1 -1
- package/dist/monolith/infrastructure/persistence/NoormmeSchema.js +68 -39
- package/dist/monolith/infrastructure/persistence/NoormmeSchema.js.map +1 -1
- package/dist/monolith/infrastructure/persistence/NoormmeSeeder.js +80 -67
- package/dist/monolith/infrastructure/persistence/NoormmeSeeder.js.map +1 -1
- package/dist/monolith/infrastructure/persistence/NoormmeTools.js +122 -75
- package/dist/monolith/infrastructure/persistence/NoormmeTools.js.map +1 -1
- package/dist/monolith/infrastructure/services/MarieMemoryStore.js +133 -134
- package/dist/monolith/infrastructure/services/MarieMemoryStore.js.map +1 -1
- package/dist/monolith/infrastructure/tools/MarieToolDefinitions.js +6 -30
- package/dist/monolith/infrastructure/tools/MarieToolDefinitions.js.map +1 -1
- package/dist/monolith/infrastructure/tools/PureStreamParser.js +68 -80
- package/dist/monolith/infrastructure/tools/PureStreamParser.js.map +1 -1
- package/dist/monolith/infrastructure/tools/SharedToolDefinitions.js +12 -11
- package/dist/monolith/infrastructure/tools/SharedToolDefinitions.js.map +1 -1
- package/dist/monolith/infrastructure/tools/SovereignTools.js +326 -0
- package/dist/monolith/infrastructure/tools/SovereignTools.js.map +1 -0
- package/dist/monolith/infrastructure/tools/ToolRegistry.js +45 -26
- package/dist/monolith/infrastructure/tools/ToolRegistry.js.map +1 -1
- package/dist/monolith/infrastructure/tools/definitions/AnalysisTools.js +39 -153
- package/dist/monolith/infrastructure/tools/definitions/AnalysisTools.js.map +1 -1
- package/dist/monolith/infrastructure/tools/definitions/AutomationTools.js +31 -46
- package/dist/monolith/infrastructure/tools/definitions/AutomationTools.js.map +1 -1
- package/dist/monolith/infrastructure/tools/definitions/ContextTools.js +41 -13
- package/dist/monolith/infrastructure/tools/definitions/ContextTools.js.map +1 -1
- package/dist/monolith/infrastructure/tools/definitions/CoreTools.js +10 -14
- package/dist/monolith/infrastructure/tools/definitions/CoreTools.js.map +1 -1
- package/dist/monolith/infrastructure/tools/definitions/DiagnosticTools.js +39 -70
- package/dist/monolith/infrastructure/tools/definitions/DiagnosticTools.js.map +1 -1
- package/dist/monolith/infrastructure/tools/definitions/NavigationTools.js +30 -181
- package/dist/monolith/infrastructure/tools/definitions/NavigationTools.js.map +1 -1
- package/dist/monolith/infrastructure/tools/definitions/PlanningTools.js +12 -9
- package/dist/monolith/infrastructure/tools/definitions/PlanningTools.js.map +1 -1
- package/dist/monolith/plumbing/Plumbing.js +238 -0
- package/dist/monolith/plumbing/Plumbing.js.map +1 -0
- package/dist/monolith/plumbing/PlumbingAnalysis.js +109 -0
- package/dist/monolith/plumbing/PlumbingAnalysis.js.map +1 -0
- package/dist/monolith/plumbing/PlumbingSystem.js +169 -0
- package/dist/monolith/plumbing/PlumbingSystem.js.map +1 -0
- package/dist/monolith/plumbing/analysis/ComplexityService.js +30 -34
- package/dist/monolith/plumbing/analysis/ComplexityService.js.map +1 -1
- package/dist/monolith/plumbing/analysis/DependencyService.js +55 -44
- package/dist/monolith/plumbing/analysis/DependencyService.js.map +1 -1
- package/dist/monolith/plumbing/analysis/DiscoveryService.js +40 -42
- package/dist/monolith/plumbing/analysis/DiscoveryService.js.map +1 -1
- package/dist/monolith/plumbing/analysis/JoyMapService.js +52 -56
- package/dist/monolith/plumbing/analysis/JoyMapService.js.map +1 -1
- package/dist/monolith/plumbing/analysis/LintService.js +118 -118
- package/dist/monolith/plumbing/analysis/LintService.js.map +1 -1
- package/dist/monolith/plumbing/analysis/MarieSentinelService.js +278 -268
- package/dist/monolith/plumbing/analysis/MarieSentinelService.js.map +1 -1
- package/dist/monolith/plumbing/analysis/QualityGuardrailService.js +116 -114
- package/dist/monolith/plumbing/analysis/QualityGuardrailService.js.map +1 -1
- package/dist/monolith/plumbing/analysis/SurgicalMender.js +57 -59
- package/dist/monolith/plumbing/analysis/SurgicalMender.js.map +1 -1
- package/dist/monolith/plumbing/analysis/TestService.js +89 -89
- package/dist/monolith/plumbing/analysis/TestService.js.map +1 -1
- package/dist/monolith/plumbing/filesystem/FileService.js +123 -195
- package/dist/monolith/plumbing/filesystem/FileService.js.map +1 -1
- package/dist/monolith/plumbing/filesystem/PathResolver.js +7 -8
- package/dist/monolith/plumbing/filesystem/PathResolver.js.map +1 -1
- package/dist/monolith/plumbing/git/GitService.js +4 -4
- package/dist/monolith/plumbing/git/GitService.js.map +1 -1
- package/dist/monolith/plumbing/lsp/SymbolService.js +5 -34
- package/dist/monolith/plumbing/lsp/SymbolService.js.map +1 -1
- package/dist/monolith/plumbing/terminal/ProcessRegistry.js +20 -22
- package/dist/monolith/plumbing/terminal/ProcessRegistry.js.map +1 -1
- package/dist/monolith/plumbing/terminal/TerminalService.js +127 -141
- package/dist/monolith/plumbing/terminal/TerminalService.js.map +1 -1
- package/dist/monolith/plumbing/utils/EnvironmentUtils.js +3 -23
- package/dist/monolith/plumbing/utils/EnvironmentUtils.js.map +1 -1
- package/dist/monolith/plumbing/utils/JsonUtils.js +252 -311
- package/dist/monolith/plumbing/utils/JsonUtils.js.map +1 -1
- package/dist/monolith/plumbing/utils/PlumbingCore.js +549 -0
- package/dist/monolith/plumbing/utils/PlumbingCore.js.map +1 -0
- package/dist/monolith/plumbing/utils/PrefixTree.js +61 -114
- package/dist/monolith/plumbing/utils/PrefixTree.js.map +1 -1
- package/dist/monolith/plumbing/utils/StreamTagDetector.js +89 -127
- package/dist/monolith/plumbing/utils/StreamTagDetector.js.map +1 -1
- package/dist/monolith/plumbing/utils/StringUtils.js +87 -89
- package/dist/monolith/plumbing/utils/StringUtils.js.map +1 -1
- package/dist/monolith/runtime/MarieRuntime.js +76 -499
- package/dist/monolith/runtime/MarieRuntime.js.map +1 -1
- package/dist/monolith/runtime/RuntimeAdapterBase.js +1 -1
- package/dist/monolith/runtime/RuntimeAdapterBase.js.map +1 -1
- package/dist/monolith/runtime/providerFactory.js +1 -7
- package/dist/monolith/runtime/providerFactory.js.map +1 -1
- package/dist/monolith/services/HealthService.js +29 -32
- package/dist/monolith/services/HealthService.js.map +1 -1
- package/dist/monolith/services/JoyAutomationService.js +58 -95
- package/dist/monolith/services/JoyAutomationService.js.map +1 -1
- package/dist/monolith/services/MarieAutomationService.js +59 -0
- package/dist/monolith/services/MarieAutomationService.js.map +1 -0
- package/dist/monolith/services/MarieGhostService.js +46 -173
- package/dist/monolith/services/MarieGhostService.js.map +1 -1
- package/dist/monolith/services/MarieServices.js +102 -0
- package/dist/monolith/services/MarieServices.js.map +1 -0
- package/dist/monolith/services/MarieTypes.js +2 -0
- package/dist/monolith/services/MarieTypes.js.map +1 -0
- package/dist/monolith/services/UpdateService.js +47 -49
- package/dist/monolith/services/UpdateService.js.map +1 -1
- package/dist/prompts.js +11 -5
- package/dist/prompts.js.map +1 -1
- package/dist/test_prefix_tree.js +9 -9
- package/dist/test_prefix_tree.js.map +1 -1
- package/package.json +18 -89
- package/run_test.js +5 -0
- package/.marie_visual_verify_1771225696548/progress_bar_check.txt +0 -1
- package/dist/extension.cjs +0 -1155
- package/dist/extension.js +0 -474
- package/dist/extension.js.map +0 -1
- package/dist/monolith/adapters/VscodeMarieAdapter.js +0 -81
- package/dist/monolith/adapters/VscodeMarieAdapter.js.map +0 -1
- package/dist/monolith/infrastructure/ai/core/GhostPort.js +0 -2
- package/dist/monolith/infrastructure/ai/core/GhostPort.js.map +0 -1
- package/dist/monolith/infrastructure/ai/core/VscodeFileSystemPort.js +0 -33
- package/dist/monolith/infrastructure/ai/core/VscodeFileSystemPort.js.map +0 -1
- package/dist/monolith/infrastructure/ai/providers/AnthropicProvider.js +0 -154
- package/dist/monolith/infrastructure/ai/providers/AnthropicProvider.js.map +0 -1
- package/dist/monolith/infrastructure/ai/providers/CerebrasProvider.js +0 -214
- package/dist/monolith/infrastructure/ai/providers/CerebrasProvider.js.map +0 -1
- package/dist/monolith/plumbing/ui/DecorationService.js +0 -54
- package/dist/monolith/plumbing/ui/DecorationService.js.map +0 -1
- package/dist/monolith/services/JoyLogService.js +0 -48
- package/dist/monolith/services/JoyLogService.js.map +0 -1
- package/dist/monolith/services/JoyService.js +0 -209
- package/dist/monolith/services/JoyService.js.map +0 -1
- package/dist/monolith/services/MarieSCMProvider.js +0 -41
- package/dist/monolith/services/MarieSCMProvider.js.map +0 -1
- package/dist/webview-ui/main.css +0 -1
- package/dist/webview-ui/main.js +0 -108
- package/lint_output.txt +0 -705
- package/lint_output_v2.txt +0 -711
- package/test-mind-p6.sqlite +0 -0
- package/test-mind-p6.sqlite-shm +0 -0
- package/test-mind-p6.sqlite-wal +0 -0
|
@@ -1,462 +1,320 @@
|
|
|
1
|
+
import { getTool, getRegisteredTools } from "../../tools/ToolRegistry.js";
|
|
1
2
|
import * as path from "path";
|
|
2
|
-
import { nodeRequire } from "../../../plumbing/utils/EnvironmentUtils.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { getWorkspaceRoot, nodeRequire, } from "../../../plumbing/utils/EnvironmentUtils.js";
|
|
4
|
+
import { getInstance, } from "../../persistence/NoormmeEngine.js";
|
|
5
|
+
import { getCapabilities, isMfaRequired } from "../../config/ConfigService.js";
|
|
5
6
|
const require = nodeRequire;
|
|
6
|
-
// Lazy-load vscode to avoid CLI errors
|
|
7
|
-
let vscodeModule = null;
|
|
8
|
-
let hasAttemptedVscodeLoad = false;
|
|
9
|
-
function getVscode() {
|
|
10
|
-
if (!hasAttemptedVscodeLoad) {
|
|
11
|
-
hasAttemptedVscodeLoad = true;
|
|
12
|
-
try {
|
|
13
|
-
vscodeModule = require("vscode");
|
|
14
|
-
}
|
|
15
|
-
catch {
|
|
16
|
-
vscodeModule = null;
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
return vscodeModule;
|
|
20
|
-
}
|
|
21
|
-
import { getStringArg } from "../../tools/ToolUtils.js";
|
|
22
7
|
import { getErrorMessage } from "../../../plumbing/utils/ErrorUtils.js";
|
|
23
8
|
import { withRetry, RetryConfig } from "../../../plumbing/utils/RetryUtils.js";
|
|
24
|
-
import { rollbackAll
|
|
25
|
-
import {
|
|
9
|
+
import { rollbackAll } from "../../../plumbing/filesystem/FileService.js";
|
|
10
|
+
import { similarity } from "../../../plumbing/utils/StringUtils.js";
|
|
11
|
+
import { repairJsonDetailed, } from "../../../plumbing/utils/JsonUtils.js";
|
|
12
|
+
import { safeStringify, safeSpread } from "./MarieSanitizer.js";
|
|
13
|
+
const PROACTIVE_REPAIRS = {
|
|
14
|
+
write_file: "write_to_file",
|
|
15
|
+
edit_file: "replace_file_content",
|
|
16
|
+
replace_in_file: "replace_file_content",
|
|
17
|
+
read_files: "read_file",
|
|
18
|
+
list_files: "list_dir",
|
|
19
|
+
search_files: "grep_search",
|
|
20
|
+
execute_command: "run_command",
|
|
21
|
+
get_folder_tree: "get_folder_structure",
|
|
22
|
+
multi_replace: "multi_replace_file_content",
|
|
23
|
+
delete_file: "discard_file",
|
|
24
|
+
discard_file: "delete_file",
|
|
25
|
+
};
|
|
26
26
|
/**
|
|
27
27
|
* Handles the validation and execution of AI tool calls.
|
|
28
|
+
* Principle 2: Compressed Common Path.
|
|
28
29
|
*/
|
|
29
30
|
export class MarieToolProcessor {
|
|
30
|
-
toolRegistry;
|
|
31
31
|
tracker;
|
|
32
32
|
approvalRequester;
|
|
33
33
|
state;
|
|
34
34
|
fs;
|
|
35
|
+
vitality;
|
|
35
36
|
static RETRY_CONFIG = new RetryConfig();
|
|
36
37
|
failureCircuitBreaker = new Map();
|
|
37
|
-
|
|
38
|
-
// READ
|
|
39
|
-
"read_file": ["READ"],
|
|
40
|
-
"view_file": ["READ"],
|
|
41
|
-
"list_dir": ["READ"],
|
|
42
|
-
"grep_search": ["READ"],
|
|
43
|
-
"find_by_name": ["READ"],
|
|
44
|
-
"get_file_diagnostics": ["READ"],
|
|
45
|
-
// WRITE
|
|
46
|
-
"write_to_file": ["WRITE"],
|
|
47
|
-
"replace_file_content": ["WRITE"],
|
|
48
|
-
"multi_replace_file_content": ["WRITE"],
|
|
49
|
-
"delete_file": ["WRITE"],
|
|
50
|
-
"rename_file": ["WRITE"],
|
|
51
|
-
"move_file": ["WRITE"],
|
|
52
|
-
// SHELL
|
|
53
|
-
"run_command": ["SHELL"],
|
|
54
|
-
// NETWORK
|
|
55
|
-
"search_web": ["NETWORK"],
|
|
56
|
-
"read_url_content": ["NETWORK"],
|
|
57
|
-
"read_browser_page": ["NETWORK"],
|
|
58
|
-
"open_browser_url": ["NETWORK"],
|
|
59
|
-
// SOVEREIGN OPS
|
|
60
|
-
"evolve_mind_structure": ["WRITE", "SHELL"],
|
|
61
|
-
"prune_sovereign_memory": ["WRITE"],
|
|
62
|
-
"complete_task_ritual": ["READ", "WRITE"],
|
|
63
|
-
// COMPLEX / MULTI
|
|
64
|
-
"execute_semantic_move": ["READ", "WRITE"],
|
|
65
|
-
"self_heal": ["READ", "WRITE", "SHELL"],
|
|
66
|
-
};
|
|
67
|
-
constructor(toolRegistry, tracker, approvalRequester, state, fs) {
|
|
68
|
-
this.toolRegistry = toolRegistry;
|
|
38
|
+
constructor(tracker, approvalRequester, state, fs, vitality) {
|
|
69
39
|
this.tracker = tracker;
|
|
70
40
|
this.approvalRequester = approvalRequester;
|
|
71
41
|
this.state = state;
|
|
72
42
|
this.fs = fs;
|
|
43
|
+
this.vitality = vitality;
|
|
73
44
|
}
|
|
74
45
|
async process(toolCall, signal) {
|
|
75
|
-
const { name,
|
|
76
|
-
const
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
this.tracker.recordHeuristicFix(toolCall.name);
|
|
80
|
-
}
|
|
81
|
-
// SUB-ATOMIC INTEGRITY: Persistent Tool Circuit Breaker
|
|
82
|
-
// Check if this tool + input has failed repeatedly in the recent past (persisted in NOORMME)
|
|
46
|
+
const { name, input, repaired, id } = toolCall;
|
|
47
|
+
const inputStr = safeStringify(input);
|
|
48
|
+
if (repaired)
|
|
49
|
+
this.tracker.recordHeuristicFix(name);
|
|
83
50
|
try {
|
|
84
|
-
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
);
|
|
89
|
-
if (
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
51
|
+
// 1. Pre-Execute: Circuit Breaker & Validation
|
|
52
|
+
const preError = await this.preExecute(name, input, inputStr);
|
|
53
|
+
if (preError)
|
|
54
|
+
return preError;
|
|
55
|
+
const tool = getTool(name);
|
|
56
|
+
if (!tool)
|
|
57
|
+
return `Error: Tool "${name}" not found.`;
|
|
58
|
+
// 2. Prepare: Logging & Backups
|
|
59
|
+
const toolStartTime = Date.now();
|
|
60
|
+
await this.prepareExecution(name, input, id, tool.isDestructive, signal);
|
|
61
|
+
// 3. Execute
|
|
62
|
+
const result = await withRetry(() => tool.execute(input, (update) => this.handleToolUpdate(update, name), signal), MarieToolProcessor.RETRY_CONFIG, `Tool: ${name}`, signal);
|
|
63
|
+
// 4. Post-Execute: Truncation, Metrics, Sentinels
|
|
64
|
+
return await this.postExecute(name, input, result, toolStartTime, id, tool.isDestructive, signal);
|
|
93
65
|
}
|
|
94
|
-
catch (
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
failureState.lastInput === inputStr &&
|
|
100
|
-
failureState.count >= 3) {
|
|
101
|
-
return `HALT: Protocol Violation. In-memory circuit breaker tripped for ${name}.`;
|
|
102
|
-
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
const repairedResult = await this.performFuzzyRepair(toolCall, error, signal);
|
|
68
|
+
if (repairedResult)
|
|
69
|
+
return repairedResult;
|
|
70
|
+
return await this.handleError(name, inputStr, error, id, signal);
|
|
103
71
|
}
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
return `Sovereign Denial: High-Entropy operation "${toolCall.name}" rejected by governor. 🛡️`;
|
|
116
|
-
}
|
|
72
|
+
}
|
|
73
|
+
async performFuzzyRepair(toolCall, error, signal) {
|
|
74
|
+
const errorMsg = getErrorMessage(error);
|
|
75
|
+
if (!errorMsg.includes("not found") &&
|
|
76
|
+
!errorMsg.includes("ENOENT") &&
|
|
77
|
+
!errorMsg.includes("registry"))
|
|
78
|
+
return null;
|
|
79
|
+
// 1. Proactive Mapping
|
|
80
|
+
if (PROACTIVE_REPAIRS[toolCall.name]) {
|
|
81
|
+
const mapped = PROACTIVE_REPAIRS[toolCall.name];
|
|
82
|
+
if (getTool(mapped)) {
|
|
117
83
|
this.tracker.emitEvent({
|
|
118
84
|
type: "reasoning",
|
|
119
85
|
runId: this.tracker.getRun().runId,
|
|
120
|
-
text:
|
|
86
|
+
text: `🩹 REPAIR: ${toolCall.name} -> ${mapped}`,
|
|
121
87
|
elapsedMs: this.tracker.elapsedMs(),
|
|
122
88
|
});
|
|
89
|
+
toolCall.name = mapped;
|
|
90
|
+
toolCall.repaired = true;
|
|
91
|
+
return this.process(toolCall, signal);
|
|
123
92
|
}
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
const
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
sanitizedInput.content.substring(0, 500) + "...[TRUNCATED]";
|
|
135
|
-
}
|
|
136
|
-
if (typeof sanitizedInput.replacementContent === "string" &&
|
|
137
|
-
sanitizedInput.replacementContent.length > 500) {
|
|
138
|
-
sanitizedInput.replacementContent =
|
|
139
|
-
sanitizedInput.replacementContent.substring(0, 500) +
|
|
140
|
-
"...[TRUNCATED]";
|
|
141
|
-
}
|
|
93
|
+
}
|
|
94
|
+
// 2. Fuzzy Tool Name
|
|
95
|
+
const tools = getRegisteredTools();
|
|
96
|
+
let bestMatch = { name: "", sim: 0 };
|
|
97
|
+
for (const t of tools) {
|
|
98
|
+
const sim = similarity(toolCall.name, t.name);
|
|
99
|
+
if (sim > bestMatch.sim)
|
|
100
|
+
bestMatch = { name: t.name, sim };
|
|
101
|
+
}
|
|
102
|
+
if (bestMatch.sim > 0.8 && bestMatch.name !== toolCall.name) {
|
|
142
103
|
this.tracker.emitEvent({
|
|
143
|
-
type: "
|
|
104
|
+
type: "reasoning",
|
|
144
105
|
runId: this.tracker.getRun().runId,
|
|
145
|
-
|
|
146
|
-
phase: "start",
|
|
147
|
-
name: toolCall.name,
|
|
148
|
-
input: sanitizedInput,
|
|
106
|
+
text: `🩹 FUZZY REPAIR: ${toolCall.name} -> ${bestMatch.name}`,
|
|
149
107
|
elapsedMs: this.tracker.elapsedMs(),
|
|
150
108
|
});
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
if (update.bytesWritten !== undefined && update.path) {
|
|
191
|
-
this.tracker.emitEvent({
|
|
192
|
-
type: "file_stream_delta",
|
|
193
|
-
runId: this.tracker.getRun().runId,
|
|
194
|
-
path: update.path,
|
|
195
|
-
bytesWritten: update.bytesWritten,
|
|
196
|
-
totalBytes: update.totalBytes,
|
|
197
|
-
elapsedMs: this.tracker.elapsedMs(),
|
|
198
|
-
});
|
|
199
|
-
}
|
|
200
|
-
else {
|
|
201
|
-
this.applyUpdate(update, toolCall.name);
|
|
202
|
-
}
|
|
203
|
-
}, signal), MarieToolProcessor.RETRY_CONFIG, `Tool: ${toolCall.name}`, signal);
|
|
204
|
-
// PROACTIVE TRUNCATION: Source-level safety cap (512KB)
|
|
205
|
-
if (typeof result === "string" && result.length > 512 * 1024) {
|
|
206
|
-
console.warn(`[MarieStability] Tool ${toolCall.name} output exceeded 512KB. Truncating at source.`);
|
|
207
|
-
result =
|
|
208
|
-
result.substring(0, 512 * 1024) +
|
|
209
|
-
"\n\n🚨 STABILITY ALERT: Output truncated at 512KB to prevent Extension Host lag.";
|
|
210
|
-
}
|
|
211
|
-
else if (result && typeof result === "object") {
|
|
212
|
-
const json = JSON.stringify(result);
|
|
213
|
-
if (json.length > 512 * 1024) {
|
|
214
|
-
console.warn(`[MarieStability] Tool ${toolCall.name} JSON output exceeded 512KB. Truncating at source.`);
|
|
215
|
-
result =
|
|
216
|
-
json.substring(0, 512 * 1024) +
|
|
217
|
-
"\n\n🚨 STABILITY ALERT: JSON output truncated at 512KB.";
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
// TRANSACTIONAL SUCCESS: Clear backups for this tool/turn
|
|
221
|
-
if (this.fs) {
|
|
222
|
-
this.fs.clearBackups();
|
|
223
|
-
}
|
|
224
|
-
// CIRCUIT BREAKER FLUSH: Tool succeeded
|
|
225
|
-
this.failureCircuitBreaker.delete(name);
|
|
226
|
-
// PHASE 7: Milestone Verification
|
|
227
|
-
try {
|
|
228
|
-
const { NoormmeEngine } = await import("../../persistence/NoormmeEngine.js");
|
|
229
|
-
const db = await NoormmeEngine.getInstance();
|
|
230
|
-
const originatingSessionId = this.tracker.getRun().originatingSessionId || "default";
|
|
231
|
-
const pendingGoals = await db.agent.cortex.sessions.getGoals(originatingSessionId);
|
|
232
|
-
for (const goal of pendingGoals) {
|
|
233
|
-
if (goal.status !== "completed" && goal.description.toLowerCase().includes(name.toLowerCase())) {
|
|
234
|
-
await db.agent.cortex.goalArchitect.markGoalAs(goal.id, "completed");
|
|
235
|
-
this.tracker.emitEvent({
|
|
236
|
-
type: "reasoning",
|
|
237
|
-
runId: this.tracker.getRun().runId,
|
|
238
|
-
text: `✅ **Milestone Achieved**: ${goal.description}`,
|
|
239
|
-
elapsedMs: this.tracker.elapsedMs(),
|
|
240
|
-
});
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
catch (e) {
|
|
245
|
-
console.warn("[MarieToolProcessor] Milestone verification failed", e);
|
|
246
|
-
}
|
|
247
|
-
const toolDurationMs = Date.now() - toolStartTime;
|
|
248
|
-
console.log(`[Marie] Tool ${toolCall.name} completed in ${toolDurationMs}ms.`);
|
|
109
|
+
toolCall.name = bestMatch.name;
|
|
110
|
+
toolCall.repaired = true;
|
|
111
|
+
return this.process(toolCall, signal);
|
|
112
|
+
}
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
repairJsonString(json) {
|
|
116
|
+
const { repaired } = repairJsonDetailed(json);
|
|
117
|
+
try {
|
|
118
|
+
JSON.parse(repaired);
|
|
119
|
+
return repaired;
|
|
120
|
+
}
|
|
121
|
+
catch {
|
|
122
|
+
return json;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
async preExecute(name, input, inputStr) {
|
|
126
|
+
// Persistent Circuit Breaker
|
|
127
|
+
try {
|
|
128
|
+
const db = await getInstance();
|
|
129
|
+
const failures = await db.execute("SELECT COUNT(*) as count FROM agent_actions WHERE tool_name = ? AND input_summary = ? AND status = 'failure' AND created_at > datetime('now', '-1 hour')", [name, inputStr.slice(0, 500)]);
|
|
130
|
+
if (failures[0]?.count >= 3)
|
|
131
|
+
return `HALT: Persistent circuit breaker tripped for ${name}. Pivot your strategy.`;
|
|
132
|
+
}
|
|
133
|
+
catch (e) {
|
|
134
|
+
const state = this.failureCircuitBreaker.get(name);
|
|
135
|
+
if (state && state.lastInput === inputStr && state.count >= 3)
|
|
136
|
+
return `HALT: In-memory circuit breaker tripped for ${name}.`;
|
|
137
|
+
}
|
|
138
|
+
// Validation
|
|
139
|
+
const validationError = this.validate(name, input);
|
|
140
|
+
if (validationError) {
|
|
141
|
+
this.recordError(name, validationError);
|
|
142
|
+
return `Error: ${validationError}`;
|
|
143
|
+
}
|
|
144
|
+
// Sovereign Affirmation (MFA)
|
|
145
|
+
if (this.requiresSovereignAffirmation(name, input)) {
|
|
146
|
+
if (!(await this.requestApproval(name, input)))
|
|
147
|
+
return `Sovereign Denial: Operation "${name}" rejected by governor. 🛡️`;
|
|
249
148
|
this.tracker.emitEvent({
|
|
250
|
-
type: "
|
|
149
|
+
type: "reasoning",
|
|
251
150
|
runId: this.tracker.getRun().runId,
|
|
252
|
-
|
|
253
|
-
phase: "complete",
|
|
254
|
-
name: toolCall.name,
|
|
255
|
-
message: typeof result === "string" ? result.substring(0, 100) : "Completed",
|
|
151
|
+
text: `🔐 **C-MFA AFFIRMED**: Sovereign clearance granted.`,
|
|
256
152
|
elapsedMs: this.tracker.elapsedMs(),
|
|
257
153
|
});
|
|
258
|
-
run.activeToolName = undefined;
|
|
259
|
-
run.activeFilePath = undefined; // Clear active file
|
|
260
|
-
run.lastToolName = toolCall.name;
|
|
261
|
-
this.tracker.emitProgressUpdate();
|
|
262
|
-
if (result && typeof result === "object") {
|
|
263
|
-
this.applyUpdate(result, toolCall.name);
|
|
264
|
-
}
|
|
265
|
-
// Phase 11: Code Impact Analysis
|
|
266
|
-
this.recordCodeStats(toolCall.name, input);
|
|
267
|
-
// Ascension Mastery: Record execution
|
|
268
|
-
this.state.techniqueExecutions.push({
|
|
269
|
-
name: toolCall.name,
|
|
270
|
-
durationMs: toolDurationMs,
|
|
271
|
-
success: true,
|
|
272
|
-
timestamp: Date.now(),
|
|
273
|
-
filePath: typeof execFile === "string" ? execFile : undefined,
|
|
274
|
-
});
|
|
275
|
-
this.state.toolHistory.push(toolCall.name);
|
|
276
|
-
if (this.state.toolHistory.length > 20)
|
|
277
|
-
this.state.toolHistory.shift();
|
|
278
|
-
this.state.victoryStreak++;
|
|
279
|
-
// Phase 7: Track sentimental metrics
|
|
280
|
-
const runMetrics = this.tracker.getRun();
|
|
281
|
-
if (!runMetrics.metrics)
|
|
282
|
-
runMetrics.metrics = { cherishedFiles: [], releasedDebtCount: 0 };
|
|
283
|
-
if (toolCall.name === "cherish_file" &&
|
|
284
|
-
input &&
|
|
285
|
-
typeof input === "object") {
|
|
286
|
-
try {
|
|
287
|
-
const p = getStringArg(input, "path");
|
|
288
|
-
if (p && !runMetrics.metrics.cherishedFiles.includes(p)) {
|
|
289
|
-
runMetrics.metrics.cherishedFiles.push(p);
|
|
290
|
-
this.tracker.emitProgressUpdate(`File cherished: ${p.split("/").pop()}`);
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
catch (e) {
|
|
294
|
-
console.warn("Failed to extract path for cherish_file metric", e);
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
else if (toolCall.name === "discard_file") {
|
|
298
|
-
runMetrics.metrics.releasedDebtCount++;
|
|
299
|
-
this.tracker.emitProgressUpdate("Technical debt released 🍂");
|
|
300
|
-
}
|
|
301
|
-
let finalResult = typeof result === "string" ? result : JSON.stringify(result);
|
|
302
|
-
// ZENITH AUTONOMY: Autonomous Dependency Sentinel
|
|
303
|
-
if (tool.isDestructive && execFile && typeof execFile === "string") {
|
|
304
|
-
const [zoningAlert, buildAlert] = await Promise.all([
|
|
305
|
-
this.runZoningSentinel(execFile, typeof result === "string" ? result : undefined, signal),
|
|
306
|
-
this.runBuildSentinel(execFile, signal),
|
|
307
|
-
]);
|
|
308
|
-
if (zoningAlert) {
|
|
309
|
-
finalResult += `\n\n🛡️ **ZENITH: Zoning Sentinel Alert**\n${zoningAlert}`;
|
|
310
|
-
}
|
|
311
|
-
if (buildAlert) {
|
|
312
|
-
finalResult += `\n\n🧱 **SINGULARITY: Build Sentinel Alert**\n${buildAlert}`;
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
return finalResult;
|
|
316
154
|
}
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
155
|
+
return null;
|
|
156
|
+
}
|
|
157
|
+
async prepareExecution(name, input, id, isDestructive, signal) {
|
|
158
|
+
this.tracker.recordLog(`[Marie] Tool ${name} starting. ID: ${id}`);
|
|
159
|
+
// UI Feedback: Active Path
|
|
160
|
+
const execFile = input?.path || input?.targetFile || input?.file || input?.filePath;
|
|
161
|
+
if (execFile && typeof execFile === "string") {
|
|
162
|
+
this.tracker.getRun().activeFilePath = execFile;
|
|
163
|
+
this.tracker.emitEvent({
|
|
164
|
+
type: "stage",
|
|
165
|
+
runId: this.tracker.getRun().runId,
|
|
166
|
+
stage: "editing",
|
|
167
|
+
label: `Editing ${path.basename(execFile)}...`,
|
|
168
|
+
elapsedMs: this.tracker.elapsedMs(),
|
|
169
|
+
});
|
|
323
170
|
this.tracker.emitProgressUpdate();
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
state.count = 1;
|
|
349
|
-
state.lastInput = inputStr;
|
|
350
|
-
}
|
|
351
|
-
this.failureCircuitBreaker.set(name, state);
|
|
352
|
-
this.recordError(name, rawMsg, isTerminal, toolCall.id);
|
|
353
|
-
console.error(`[Marie] Tool ${name} failed: ${rawMsg}`);
|
|
354
|
-
this.recordError(name, rawMsg, isTerminal, toolCall.id);
|
|
355
|
-
console.error(`[Marie] Tool ${name} failed: ${rawMsg}`);
|
|
356
|
-
// Ascension Mastery: Record failure
|
|
357
|
-
const failFile = toolCall.input?.path ||
|
|
358
|
-
toolCall.input?.targetFile ||
|
|
359
|
-
toolCall.input?.file ||
|
|
360
|
-
toolCall.input?.filePath;
|
|
361
|
-
this.state.techniqueExecutions.push({
|
|
362
|
-
name: name,
|
|
363
|
-
durationMs: 0,
|
|
364
|
-
success: false,
|
|
365
|
-
timestamp: Date.now(),
|
|
366
|
-
filePath: typeof failFile === "string" ? failFile : undefined,
|
|
171
|
+
if (isDestructive && this.fs)
|
|
172
|
+
await this.fs.backupFile(execFile, signal);
|
|
173
|
+
}
|
|
174
|
+
// Start Event
|
|
175
|
+
this.tracker.emitEvent({
|
|
176
|
+
type: "tool",
|
|
177
|
+
runId: this.tracker.getRun().runId,
|
|
178
|
+
id,
|
|
179
|
+
phase: "start",
|
|
180
|
+
name,
|
|
181
|
+
input: this.sanitizeForLogging(input),
|
|
182
|
+
elapsedMs: this.tracker.elapsedMs(),
|
|
183
|
+
});
|
|
184
|
+
this.tracker.recordToolUsage(name);
|
|
185
|
+
}
|
|
186
|
+
handleToolUpdate(update, name) {
|
|
187
|
+
if (update.bytesWritten !== undefined && update.path) {
|
|
188
|
+
this.tracker.emitEvent({
|
|
189
|
+
type: "file_stream_delta",
|
|
190
|
+
runId: this.tracker.getRun().runId,
|
|
191
|
+
path: update.path,
|
|
192
|
+
bytesWritten: update.bytesWritten,
|
|
193
|
+
totalBytes: update.totalBytes,
|
|
194
|
+
elapsedMs: this.tracker.elapsedMs(),
|
|
367
195
|
});
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
this.state.errorHotspots[failFile] =
|
|
372
|
-
(this.state.errorHotspots[failFile] || 0) + 1;
|
|
373
|
-
}
|
|
374
|
-
// PHASE 9: Report Consecutive Failures to Metrics
|
|
375
|
-
try {
|
|
376
|
-
const { NoormmeEngine } = await import("../../persistence/NoormmeEngine.js");
|
|
377
|
-
const db = await NoormmeEngine.getInstance();
|
|
378
|
-
const originatingSessionId = this.tracker.getRun().originatingSessionId || "default";
|
|
379
|
-
const failureCount = state.count;
|
|
380
|
-
await db.agent.cortex.metrics.recordMetric("consecutive_failures", failureCount, {
|
|
381
|
-
sessionId: originatingSessionId,
|
|
382
|
-
metadata: { toolName: name, filePath: failFile }
|
|
383
|
-
});
|
|
384
|
-
}
|
|
385
|
-
catch (e) {
|
|
386
|
-
console.warn("[MarieToolProcessor] Failed to report failure metrics", e);
|
|
387
|
-
}
|
|
388
|
-
if (isTerminal || state.count >= 3) {
|
|
389
|
-
const circuitBreakerSuffix = state.count >= 3 ? " [CIRCUIT BREAKER TRIPPED]" : "";
|
|
390
|
-
return `HALT: Critical protocol or parsing failure in ${name}: ${rawMsg}${circuitBreakerSuffix}${rollbackErrorMsg}`;
|
|
391
|
-
}
|
|
392
|
-
// Constructive Feedback Layer
|
|
393
|
-
const msgParts = [
|
|
394
|
-
`Error executing ${name}: ${rawMsg}${rollbackErrorMsg}`,
|
|
395
|
-
];
|
|
396
|
-
// Ascension-Aware Error Hotspot Hint
|
|
397
|
-
if (failFile && typeof failFile === "string") {
|
|
398
|
-
const hotspotCount = this.state.errorHotspots[failFile] || 0;
|
|
399
|
-
if (hotspotCount >= 2) {
|
|
400
|
-
msgParts.push(`\n\n🔥 CURSE HOTSPOT: This file (${failFile}) has failed ${hotspotCount} times. Technique adjustment required.`);
|
|
401
|
-
}
|
|
402
|
-
}
|
|
403
|
-
if (this.state.spiritPressure < 30) {
|
|
404
|
-
msgParts.push(`\n⚠️ Low spirit pressure (${this.state.spiritPressure}/100). Simplify your next action.`);
|
|
405
|
-
}
|
|
406
|
-
if (this.state.mood === "CAUTIOUS") {
|
|
407
|
-
msgParts.push(`\n🛡️ Ascension Mood: CAUTIOUS. Observe before acting. Verify the pattern.`);
|
|
408
|
-
}
|
|
409
|
-
if (rawMsg.includes("ENOENT") || rawMsg.includes("no such file")) {
|
|
410
|
-
msgParts.push(`\n\n💡 Reflection Hint: The file or directory does not exist. Use 'list_dir' to verify the path or 'grep_search' to locate it.`);
|
|
411
|
-
}
|
|
412
|
-
else if (rawMsg.includes("target content not found")) {
|
|
413
|
-
msgParts.push(`\n\n💡 Reflection Hint: The content you tried to replace wasn't found. Use 'read_file' (without line numbers) to verify the current file content before retrying.`);
|
|
414
|
-
}
|
|
415
|
-
else if (rawMsg.includes("Input is required")) {
|
|
416
|
-
msgParts.push(`\n\n💡 Reflection Hint: You missed a required argument. Check the tool schema.`);
|
|
417
|
-
}
|
|
418
|
-
else {
|
|
419
|
-
msgParts.push(`\n\n💡 Reflection Hint: Please analyze why this failed and propose a diverse alternative strategy.`);
|
|
420
|
-
}
|
|
421
|
-
if (state.count > 1) {
|
|
422
|
-
msgParts.push(`\n\n⚠️ REPEATED FAILURE: This exact tool call has failed ${state.count} times. If it fails again, the circuit breaker will trip and you will be forced to change strategy.`);
|
|
423
|
-
}
|
|
424
|
-
return msgParts.join("");
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
this.applyUpdate(update, name);
|
|
425
199
|
}
|
|
426
200
|
}
|
|
201
|
+
async postExecute(name, input, result, startTime, id, isDestructive, signal) {
|
|
202
|
+
let finalResult = typeof result === "string" ? result : safeStringify(result);
|
|
203
|
+
if (finalResult.length > 512 * 1024) {
|
|
204
|
+
finalResult =
|
|
205
|
+
finalResult.substring(0, 512 * 1024) +
|
|
206
|
+
"\n\n🚨 STABILITY ALERT: Output truncated at 512KB.";
|
|
207
|
+
}
|
|
208
|
+
if (this.fs)
|
|
209
|
+
this.fs.clearBackups();
|
|
210
|
+
this.failureCircuitBreaker.delete(name);
|
|
211
|
+
const duration = Date.now() - startTime;
|
|
212
|
+
this.tracker.emitEvent({
|
|
213
|
+
type: "tool",
|
|
214
|
+
runId: this.tracker.getRun().runId,
|
|
215
|
+
id,
|
|
216
|
+
phase: "complete",
|
|
217
|
+
name,
|
|
218
|
+
message: finalResult.substring(0, 100),
|
|
219
|
+
elapsedMs: this.tracker.elapsedMs(),
|
|
220
|
+
});
|
|
221
|
+
const run = this.tracker.getRun();
|
|
222
|
+
run.activeToolName = undefined;
|
|
223
|
+
run.activeFilePath = undefined;
|
|
224
|
+
this.tracker.emitProgressUpdate();
|
|
225
|
+
// Stats & History
|
|
226
|
+
this.recordCodeStats(name, input);
|
|
227
|
+
this.state.techniqueExecutions.push({
|
|
228
|
+
name,
|
|
229
|
+
durationMs: duration,
|
|
230
|
+
success: true,
|
|
231
|
+
timestamp: Date.now(),
|
|
232
|
+
filePath: input?.path || input?.targetFile,
|
|
233
|
+
});
|
|
234
|
+
this.state.toolHistory.push(name);
|
|
235
|
+
if (this.state.toolHistory.length > 20)
|
|
236
|
+
this.state.toolHistory.shift();
|
|
237
|
+
this.state.victoryStreak++;
|
|
238
|
+
// Sentinels
|
|
239
|
+
const execFile = input?.path || input?.targetFile || input?.file || input?.filePath;
|
|
240
|
+
if (isDestructive && execFile && typeof execFile === "string") {
|
|
241
|
+
const [zoning, build] = await Promise.all([
|
|
242
|
+
this.runZoningSentinel(execFile, finalResult, signal),
|
|
243
|
+
this.runBuildSentinel(execFile, signal),
|
|
244
|
+
]);
|
|
245
|
+
if (zoning)
|
|
246
|
+
finalResult += `\n\n🛡️ **ZENITH ALERT**\n${zoning}`;
|
|
247
|
+
if (build)
|
|
248
|
+
finalResult += `\n\n🧱 **SINGULARITY ALERT**\n${build}`;
|
|
249
|
+
}
|
|
250
|
+
return finalResult;
|
|
251
|
+
}
|
|
252
|
+
async handleError(name, inputStr, error, id, signal) {
|
|
253
|
+
const rawMsg = getErrorMessage(error);
|
|
254
|
+
const isTerminal = this.isTerminalError(name, rawMsg);
|
|
255
|
+
// Rollback
|
|
256
|
+
try {
|
|
257
|
+
if (this.fs)
|
|
258
|
+
await this.fs.rollbackAll(signal);
|
|
259
|
+
else
|
|
260
|
+
await rollbackAll(signal);
|
|
261
|
+
}
|
|
262
|
+
catch (e) {
|
|
263
|
+
console.error("Rollback failed", e);
|
|
264
|
+
}
|
|
265
|
+
// Circuit Breaker Increment
|
|
266
|
+
const state = this.failureCircuitBreaker.get(name) || {
|
|
267
|
+
count: 0,
|
|
268
|
+
lastInput: inputStr,
|
|
269
|
+
};
|
|
270
|
+
state.count = state.lastInput === inputStr ? state.count + 1 : 1;
|
|
271
|
+
state.lastInput = inputStr;
|
|
272
|
+
this.failureCircuitBreaker.set(name, state);
|
|
273
|
+
this.recordError(name, rawMsg, isTerminal, id);
|
|
274
|
+
this.state.totalErrorCount++;
|
|
275
|
+
this.state.victoryStreak = 0;
|
|
276
|
+
if (isTerminal || state.count >= 3)
|
|
277
|
+
return `HALT: Critical failure in ${name}: ${rawMsg}`;
|
|
278
|
+
return `Error executing ${name}: ${rawMsg}. Refine your strategy.`;
|
|
279
|
+
}
|
|
280
|
+
sanitizeForLogging(input) {
|
|
281
|
+
const sanitized = safeSpread(input);
|
|
282
|
+
if (typeof sanitized.content === "string" && sanitized.content.length > 500)
|
|
283
|
+
sanitized.content =
|
|
284
|
+
sanitized.content.substring(0, 500) + "...[TRUNCATED]";
|
|
285
|
+
if (typeof sanitized.replacementContent === "string" &&
|
|
286
|
+
sanitized.replacementContent.length > 500)
|
|
287
|
+
sanitized.replacementContent =
|
|
288
|
+
sanitized.replacementContent.substring(0, 500) + "...[TRUNCATED]";
|
|
289
|
+
return sanitized;
|
|
290
|
+
}
|
|
291
|
+
// --- Methods below are mostly unchanged logic, just kept for completeness ---
|
|
427
292
|
isTerminalError(toolName, message) {
|
|
428
|
-
// Critical ritual failures are terminal
|
|
429
293
|
if (toolName === "checkpoint_pass" && message.includes("failed"))
|
|
430
294
|
return true;
|
|
431
|
-
// Repeated parsing failures (marked by provider) are terminal
|
|
432
295
|
if (message.includes("Failed to parse tool arguments"))
|
|
433
296
|
return true;
|
|
434
297
|
return false;
|
|
435
298
|
}
|
|
436
299
|
validate(name, input) {
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
const
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
return `Sovereign Capability Breach: Tool "${name}" requires missing capabilities: [${missing.join(", ")}]. 🛑`;
|
|
445
|
-
}
|
|
300
|
+
const requirements = this.constructor.TOOL_CAPABILITIES[name] || [
|
|
301
|
+
"READ",
|
|
302
|
+
];
|
|
303
|
+
const allowed = getCapabilities();
|
|
304
|
+
const missing = requirements.filter((cap) => !allowed.includes(cap));
|
|
305
|
+
if (missing.length > 0)
|
|
306
|
+
return `Capability Breach: Tool "${name}" requires missing capabilities: [${missing.join(", ")}]. 🛑`;
|
|
446
307
|
if (!input || typeof input !== "object")
|
|
447
308
|
return "Input must be a valid object";
|
|
448
|
-
const tool =
|
|
309
|
+
const tool = getTool(name);
|
|
449
310
|
if (!tool)
|
|
450
|
-
return `Tool "${name}" not found
|
|
451
|
-
// Check required fields from schema
|
|
311
|
+
return `Tool "${name}" not found.`;
|
|
452
312
|
const schema = tool.input_schema;
|
|
453
313
|
if (schema.required && Array.isArray(schema.required)) {
|
|
454
|
-
const
|
|
455
|
-
if (
|
|
456
|
-
return `Missing required fields: ${
|
|
457
|
-
}
|
|
314
|
+
const missingFields = schema.required.filter((field) => !(field in input));
|
|
315
|
+
if (missingFields.length > 0)
|
|
316
|
+
return `Missing required fields: ${missingFields.join(", ")}`;
|
|
458
317
|
}
|
|
459
|
-
// Security: Workspace Boundary Enforcement
|
|
460
318
|
const pathFields = [
|
|
461
319
|
"path",
|
|
462
320
|
"targetFile",
|
|
@@ -467,257 +325,116 @@ export class MarieToolProcessor {
|
|
|
467
325
|
];
|
|
468
326
|
for (const field of pathFields) {
|
|
469
327
|
if (input[field] && typeof input[field] === "string") {
|
|
470
|
-
const
|
|
471
|
-
if (
|
|
472
|
-
return
|
|
328
|
+
const error = this.validatePath(input[field]);
|
|
329
|
+
if (error)
|
|
330
|
+
return error;
|
|
473
331
|
}
|
|
474
332
|
}
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
}
|
|
484
|
-
if (ConfigService.getAdversarialSensitivity() > 0.8) {
|
|
485
|
-
return `Sovereign Security Breach: Dangerous patterns detected in tool arguments. Execution blocked by Adversarial Guard. 🛑`;
|
|
486
|
-
}
|
|
333
|
+
return null;
|
|
334
|
+
}
|
|
335
|
+
validatePath(p) {
|
|
336
|
+
const root = getWorkspaceRoot();
|
|
337
|
+
if (!root)
|
|
338
|
+
return null;
|
|
339
|
+
if ((p.startsWith("/") || (p.length > 1 && p[1] === ":")) &&
|
|
340
|
+
!p.startsWith(root)) {
|
|
341
|
+
return `Security Error: Path ${p} is outside workspace boundary.`;
|
|
487
342
|
}
|
|
488
343
|
return null;
|
|
489
344
|
}
|
|
490
345
|
requiresSovereignAffirmation(name, input) {
|
|
491
|
-
if (!
|
|
346
|
+
if (!isMfaRequired())
|
|
492
347
|
return false;
|
|
493
|
-
// High-risk tools or arguments
|
|
494
348
|
if (name === "run_command") {
|
|
495
349
|
const cmd = (input.CommandLine || input.command || "").toLowerCase();
|
|
496
|
-
|
|
497
|
-
if (destructiveKeywords.some(kw => cmd.includes(kw)))
|
|
498
|
-
return true;
|
|
499
|
-
}
|
|
500
|
-
if (name === "delete_file" || name === "prune_sovereign_memory")
|
|
501
|
-
return true;
|
|
502
|
-
// Escalate if sanitizer found alerts
|
|
503
|
-
const alerts = MarieSanitizer.scanToolArguments(name, input);
|
|
504
|
-
return alerts.length > 0;
|
|
505
|
-
}
|
|
506
|
-
validatePath(p) {
|
|
507
|
-
const vscode = getVscode();
|
|
508
|
-
const workspaceFolders = vscode?.workspace.workspaceFolders;
|
|
509
|
-
if (!workspaceFolders || workspaceFolders.length === 0)
|
|
510
|
-
return null; // No workspace, no boundary to enforce
|
|
511
|
-
const workspaceRoot = workspaceFolders[0].uri.fsPath;
|
|
512
|
-
// Basic check for drive-letter-relative or absolute paths that bypass the root
|
|
513
|
-
const normalized = p.startsWith("~") ? p : p.includes(":") ? p : p; // PathResolver handles ~ expansion
|
|
514
|
-
// We'll trust resolvePath but check the result against workspace root if possible
|
|
515
|
-
// Since ToolProcessor doesn't have easy access to resolvePath without importing,
|
|
516
|
-
// we'll do a simple string check for now, matching FileService's logic.
|
|
517
|
-
// If the path starts with / or \ but NOT workspaceRoot, it's a breach.
|
|
518
|
-
if (p.startsWith("/") || (p.length > 1 && p[1] === ":")) {
|
|
519
|
-
if (!p.startsWith(workspaceRoot)) {
|
|
520
|
-
return `Security Error: Path ${p} is outside the workspace boundary (${workspaceRoot}). Access denied. 🛑`;
|
|
521
|
-
}
|
|
350
|
+
return ["sudo ", "rm ", "kill ", "chmod "].some((kw) => cmd.includes(kw));
|
|
522
351
|
}
|
|
523
|
-
|
|
524
|
-
if (!p.startsWith(workspaceRoot)) {
|
|
525
|
-
return `Security Error: Path ${p} is outside the workspace boundary (${workspaceRoot}). Access denied. 🛑`;
|
|
526
|
-
}
|
|
527
|
-
}
|
|
528
|
-
return null;
|
|
352
|
+
return ["delete_file", "prune_sovereign_memory"].includes(name);
|
|
529
353
|
}
|
|
530
354
|
async requestApproval(name, input) {
|
|
531
|
-
|
|
532
|
-
// Try to construct a diff for preview
|
|
533
|
-
let diff;
|
|
534
|
-
if (name === "replace_in_file" &&
|
|
535
|
-
input.targetContent &&
|
|
536
|
-
input.replacementContent) {
|
|
537
|
-
diff = { old: input.targetContent, new: input.replacementContent };
|
|
538
|
-
}
|
|
539
|
-
else if (name === "write_file" && input.content) {
|
|
540
|
-
diff = { old: "", new: input.content };
|
|
541
|
-
}
|
|
542
|
-
// Use the callback to request approval via the frontend
|
|
543
|
-
const approved = await this.approvalRequester(name, input, diff);
|
|
544
|
-
return approved;
|
|
355
|
+
return await this.approvalRequester(name, input);
|
|
545
356
|
}
|
|
546
357
|
applyUpdate(update, toolName) {
|
|
547
358
|
const run = this.tracker.getRun();
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
if (update.activeObjectiveId)
|
|
551
|
-
run.activeObjectiveId = update.activeObjectiveId;
|
|
552
|
-
if (update.lifecycleStage)
|
|
553
|
-
run.lifecycleStage = update.lifecycleStage;
|
|
554
|
-
if (update.totalPasses !== undefined)
|
|
555
|
-
run.totalPasses = update.totalPasses;
|
|
556
|
-
if (update.currentPass !== undefined)
|
|
557
|
-
run.currentPass =
|
|
558
|
-
update.currentPass === null ? undefined : update.currentPass;
|
|
559
|
-
if (update.passFocus !== undefined)
|
|
560
|
-
run.passFocus = update.passFocus;
|
|
561
|
-
if (update.passHistory) {
|
|
562
|
-
run.passHistory = [...(run.passHistory || []), ...update.passHistory];
|
|
563
|
-
}
|
|
564
|
-
if (update.metrics) {
|
|
565
|
-
run.metrics = {
|
|
566
|
-
cherishedFiles: Array.from(new Set([
|
|
567
|
-
...(run.metrics?.cherishedFiles || []),
|
|
568
|
-
...(update.metrics.cherishedFiles || []),
|
|
569
|
-
])),
|
|
570
|
-
releasedDebtCount: (run.metrics?.releasedDebtCount || 0) +
|
|
571
|
-
(update.metrics.releasedDebtCount || 0),
|
|
572
|
-
};
|
|
573
|
-
}
|
|
574
|
-
// Auto-increment currentPass on checkpoint_pass or if specifically requested
|
|
575
|
-
if (toolName === "checkpoint_pass" && run.currentPass !== undefined) {
|
|
359
|
+
Object.assign(run, safeSpread(update));
|
|
360
|
+
if (toolName === "checkpoint_pass" && run.currentPass !== undefined)
|
|
576
361
|
run.currentPass++;
|
|
577
|
-
|
|
578
|
-
if (run.currentPass !== undefined &&
|
|
579
|
-
run.totalPasses !== undefined &&
|
|
580
|
-
run.passFocus) {
|
|
581
|
-
this.tracker.emitPassTransition(run.currentPass, run.totalPasses, run.passFocus);
|
|
582
|
-
}
|
|
583
|
-
else {
|
|
584
|
-
this.tracker.emitProgressUpdate();
|
|
585
|
-
}
|
|
586
|
-
// Handle Roadmap Augmentation
|
|
587
|
-
if (toolName === "augment_roadmap" && update.totalPasses !== undefined) {
|
|
588
|
-
run.totalPasses = (run.totalPasses || 0) + update.totalPasses;
|
|
589
|
-
this.tracker.emitProgressUpdate(`Roadmap calibrated: ${run.totalPasses} total passes.`);
|
|
590
|
-
}
|
|
591
|
-
}
|
|
592
|
-
countLines(str) {
|
|
593
|
-
if (!str)
|
|
594
|
-
return 0;
|
|
595
|
-
let count = 1; // Start at 1 for single line
|
|
596
|
-
let pos = -1;
|
|
597
|
-
while ((pos = str.indexOf("\n", pos + 1)) !== -1) {
|
|
598
|
-
count++;
|
|
599
|
-
}
|
|
600
|
-
return count;
|
|
362
|
+
this.tracker.emitProgressUpdate();
|
|
601
363
|
}
|
|
602
364
|
recordCodeStats(toolName, input) {
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
}
|
|
618
|
-
else if (toolName === "multi_replace_file_content" &&
|
|
619
|
-
Array.isArray(input.replacementChunks)) {
|
|
620
|
-
let added = 0;
|
|
621
|
-
let removed = 0;
|
|
622
|
-
for (const chunk of input.replacementChunks) {
|
|
623
|
-
added += this.countLines(chunk.replacementContent);
|
|
624
|
-
removed += this.countLines(chunk.targetContent);
|
|
625
|
-
}
|
|
626
|
-
const path = input.targetFile || input.file || input.path || input.filePath;
|
|
627
|
-
if (path)
|
|
628
|
-
this.tracker.recordFileChange(path, added, removed);
|
|
629
|
-
}
|
|
630
|
-
}
|
|
631
|
-
catch (e) {
|
|
632
|
-
console.warn("Failed to record code stats", e);
|
|
633
|
-
}
|
|
365
|
+
const path = input.targetFile || input.file || input.path;
|
|
366
|
+
if (!path)
|
|
367
|
+
return;
|
|
368
|
+
const roundedInput = safeSpread(input);
|
|
369
|
+
const added = roundedInput.content
|
|
370
|
+
? roundedInput.content.split("\n").length
|
|
371
|
+
: roundedInput.replacementContent
|
|
372
|
+
? roundedInput.replacementContent.split("\n").length
|
|
373
|
+
: 0;
|
|
374
|
+
const removed = roundedInput.targetContent
|
|
375
|
+
? roundedInput.targetContent.split("\n").length
|
|
376
|
+
: 0;
|
|
377
|
+
if (added || removed)
|
|
378
|
+
this.tracker.recordFileChange(path, added, removed);
|
|
634
379
|
}
|
|
635
|
-
recordError(name, message,
|
|
380
|
+
recordError(name, message, terminal = false, id) {
|
|
636
381
|
this.tracker.emitEvent({
|
|
637
382
|
type: "tool",
|
|
638
383
|
runId: this.tracker.getRun().runId,
|
|
639
|
-
id
|
|
384
|
+
id,
|
|
640
385
|
phase: "error",
|
|
641
386
|
name,
|
|
642
|
-
message: (
|
|
387
|
+
message: (terminal ? "[TERMINAL] " : "") + message,
|
|
643
388
|
elapsedMs: this.tracker.elapsedMs(),
|
|
644
389
|
});
|
|
645
390
|
}
|
|
646
|
-
async runZoningSentinel(filePath,
|
|
391
|
+
async runZoningSentinel(filePath, result, signal) {
|
|
647
392
|
try {
|
|
648
|
-
if (signal?.aborted)
|
|
649
|
-
return null;
|
|
650
393
|
const { detectMigrationNeeds } = await import("../../../plumbing/analysis/CodeHealthService.js");
|
|
651
394
|
const { readFile } = await import("../../../plumbing/filesystem/FileService.js");
|
|
652
395
|
const content = await readFile(filePath, undefined, undefined, signal);
|
|
653
396
|
const { shouldMigrate, targetZone, reason } = detectMigrationNeeds(filePath, content);
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
runId: this.tracker.getRun().runId,
|
|
658
|
-
text: `🛡️ ZENITH: Zoning Sentinel detected a leak in \`${filePath.split("/").pop()}\`.`,
|
|
659
|
-
elapsedMs: this.tracker.elapsedMs(),
|
|
660
|
-
});
|
|
661
|
-
return `⚠️ **Dependency Leak**: ${reason}\nSuggested Zone: \`${targetZone}\`. Consider moving this file or refactoring its dependencies.`;
|
|
662
|
-
}
|
|
663
|
-
// Also check for cross-zone import leaks (Heuristic)
|
|
664
|
-
if (filePath.includes("/domain/") &&
|
|
665
|
-
(content.includes("/infrastructure/") || content.includes("/adapters/"))) {
|
|
666
|
-
return `⚠️ **Architectural Heresy**: Domain layer should not depend on Infrastructure. Found infrastructure imports in \`${path.basename(filePath)}\`.`;
|
|
667
|
-
}
|
|
668
|
-
return null;
|
|
397
|
+
return shouldMigrate
|
|
398
|
+
? `Dependency Leak: ${reason}. Target: ${targetZone}`
|
|
399
|
+
: null;
|
|
669
400
|
}
|
|
670
|
-
catch
|
|
671
|
-
console.warn("[Zenith] Zoning Sentinel failed", e);
|
|
401
|
+
catch {
|
|
672
402
|
return null;
|
|
673
403
|
}
|
|
674
404
|
}
|
|
675
405
|
async runBuildSentinel(filePath, signal) {
|
|
676
|
-
const vscode = getVscode();
|
|
677
|
-
const workingDir = vscode?.workspace.workspaceFolders?.[0].uri.fsPath || process.cwd();
|
|
678
406
|
try {
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
this.tracker.emitProgressUpdate("Initiating Sub-Atomic Integrity Audit... 🛡️");
|
|
683
|
-
const result = await QualityGuardrailService.evaluate(workingDir, filePath);
|
|
684
|
-
if (result.surgicalMends > 0) {
|
|
685
|
-
this.tracker.emitEvent({
|
|
686
|
-
type: "reasoning",
|
|
687
|
-
runId: this.tracker.getRun().runId,
|
|
688
|
-
text: `✨ SURGICAL MEND: Marie autonomously repaired ${result.surgicalMends} sub-atomic issue(s) in \`${path.basename(filePath)}\`.`,
|
|
689
|
-
elapsedMs: this.tracker.elapsedMs(),
|
|
690
|
-
});
|
|
691
|
-
}
|
|
692
|
-
if (!result.passed) {
|
|
693
|
-
this.tracker.emitEvent({
|
|
694
|
-
type: "reasoning",
|
|
695
|
-
runId: this.tracker.getRun().runId,
|
|
696
|
-
text: `🧱 SUB-ATOMIC REJECTION: Project integrity at risk (Score: ${result.score}/100).`,
|
|
697
|
-
elapsedMs: this.tracker.elapsedMs(),
|
|
698
|
-
});
|
|
699
|
-
let summary = `🚨 **SUB-ATOMIC INTEGRITY REJECTION** 🚨\n\nMarie has audited your change and found it architecturally or stylistically toxic.\n\n`;
|
|
700
|
-
summary += `**Quality Score**: ${result.score}/100\n`;
|
|
701
|
-
summary += result.violations.map((v) => `- ❌ ${v}`).join("\n");
|
|
702
|
-
summary += `\n\n**Action Required**: You must resolve these precision regressions. Use 'resolve_lint_errors' for location-specific data. Type sovereignty is absolute. 🚩`;
|
|
703
|
-
return summary;
|
|
704
|
-
}
|
|
705
|
-
if (result.score < 100) {
|
|
706
|
-
this.tracker.emitProgressUpdate(`Sub-Atomic Audit Passed (Score: ${result.score}/100) ✨`);
|
|
707
|
-
}
|
|
407
|
+
const { evaluateQualityGuardrail } = await import("../../../plumbing/analysis/QualityGuardrailService.js");
|
|
408
|
+
const res = await evaluateQualityGuardrail(getWorkspaceRoot() || "", filePath);
|
|
409
|
+
return res.passed ? null : `Quality rejection (Score: ${res.score}/100)`;
|
|
708
410
|
}
|
|
709
|
-
catch
|
|
710
|
-
|
|
711
|
-
// Fallback to basic VS Code diagnostics if service fails
|
|
712
|
-
if (vscode) {
|
|
713
|
-
const diagnostics = vscode.languages.getDiagnostics(vscode.Uri.file(filePath));
|
|
714
|
-
const errors = diagnostics.filter((d) => d.severity === vscode.DiagnosticSeverity.Error);
|
|
715
|
-
if (errors.length > 0) {
|
|
716
|
-
return `🚨 **Build Regressions Detected**: ${errors.length} error(s) found. Fix these immediately.`;
|
|
717
|
-
}
|
|
718
|
-
}
|
|
411
|
+
catch {
|
|
412
|
+
return null;
|
|
719
413
|
}
|
|
720
|
-
return null;
|
|
721
414
|
}
|
|
415
|
+
static TOOL_CAPABILITIES = {
|
|
416
|
+
read_file: ["READ"],
|
|
417
|
+
view_file: ["READ"],
|
|
418
|
+
list_dir: ["READ"],
|
|
419
|
+
grep_search: ["READ"],
|
|
420
|
+
find_by_name: ["READ"],
|
|
421
|
+
get_file_diagnostics: ["READ"],
|
|
422
|
+
write_to_file: ["WRITE"],
|
|
423
|
+
replace_file_content: ["WRITE"],
|
|
424
|
+
multi_replace_file_content: ["WRITE"],
|
|
425
|
+
delete_file: ["WRITE"],
|
|
426
|
+
rename_file: ["WRITE"],
|
|
427
|
+
move_file: ["WRITE"],
|
|
428
|
+
run_command: ["SHELL"],
|
|
429
|
+
search_web: ["NETWORK"],
|
|
430
|
+
read_url_content: ["NETWORK"],
|
|
431
|
+
read_browser_page: ["NETWORK"],
|
|
432
|
+
open_browser_url: ["NETWORK"],
|
|
433
|
+
evolve_mind_structure: ["WRITE", "SHELL"],
|
|
434
|
+
prune_sovereign_memory: ["WRITE"],
|
|
435
|
+
complete_task_ritual: ["READ", "WRITE"],
|
|
436
|
+
execute_semantic_move: ["READ", "WRITE"],
|
|
437
|
+
self_heal: ["READ", "WRITE", "SHELL"],
|
|
438
|
+
};
|
|
722
439
|
}
|
|
723
440
|
//# sourceMappingURL=MarieToolProcessor.js.map
|