@within-7/minto 0.3.10 → 0.4.1
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/dist/Tool.js.map +2 -2
- package/dist/commands/agents/AgentsCommand.js +2 -2
- package/dist/commands/agents/AgentsCommand.js.map +2 -2
- package/dist/commands/ctx_viz.js +1 -1
- package/dist/commands/effort.js +87 -0
- package/dist/commands/effort.js.map +7 -0
- package/dist/commands/export.js +19 -9
- package/dist/commands/export.js.map +2 -2
- package/dist/commands/ide.js +18 -0
- package/dist/commands/ide.js.map +7 -0
- package/dist/commands/mcp-interactive.js +14 -8
- package/dist/commands/mcp-interactive.js.map +2 -2
- package/dist/commands/memory.js +168 -0
- package/dist/commands/memory.js.map +7 -0
- package/dist/commands/model.js +45 -2
- package/dist/commands/model.js.map +2 -2
- package/dist/commands/outputStyle.js +64 -0
- package/dist/commands/outputStyle.js.map +7 -0
- package/dist/commands/plugin/utils.js +33 -1
- package/dist/commands/plugin/utils.js.map +2 -2
- package/dist/commands/plugin.js +10 -1
- package/dist/commands/plugin.js.map +2 -2
- package/dist/commands/refreshCommands.js +2 -0
- package/dist/commands/refreshCommands.js.map +2 -2
- package/dist/commands/review.js +51 -0
- package/dist/commands/review.js.map +7 -0
- package/dist/commands/terminalSetup.js +6 -0
- package/dist/commands/terminalSetup.js.map +2 -2
- package/dist/commands/undo.js +8 -0
- package/dist/commands/undo.js.map +2 -2
- package/dist/commands/vim.js +22 -0
- package/dist/commands/vim.js.map +7 -0
- package/dist/commands.js +12 -0
- package/dist/commands.js.map +2 -2
- package/dist/components/HighlightedCode.js +1 -0
- package/dist/components/HighlightedCode.js.map +2 -2
- package/dist/components/ModelSelector/ModelSelector.js +250 -143
- package/dist/components/ModelSelector/ModelSelector.js.map +2 -2
- package/dist/components/PromptInput.js +21 -6
- package/dist/components/PromptInput.js.map +2 -2
- package/dist/components/PulseLabel.js +44 -0
- package/dist/components/PulseLabel.js.map +7 -0
- package/dist/components/RequestStatusIndicator.js +1 -1
- package/dist/components/RequestStatusIndicator.js.map +1 -1
- package/dist/components/Spinner.js +12 -42
- package/dist/components/Spinner.js.map +3 -3
- package/dist/components/StartupStatus.js +57 -0
- package/dist/components/StartupStatus.js.map +7 -0
- package/dist/components/SubagentBlock.js +43 -6
- package/dist/components/SubagentBlock.js.map +2 -2
- package/dist/components/TabbedListView/TabBar.js +13 -8
- package/dist/components/TabbedListView/TabBar.js.map +2 -2
- package/dist/components/TabbedListView/TabbedListView.js +1 -1
- package/dist/components/TabbedListView/TabbedListView.js.map +2 -2
- package/dist/components/TodoPanel.js +1 -1
- package/dist/components/TodoPanel.js.map +1 -1
- package/dist/components/ToolUseLoader.js +5 -0
- package/dist/components/ToolUseLoader.js.map +2 -2
- package/dist/components/TrustDialog.js +0 -2
- package/dist/components/TrustDialog.js.map +2 -2
- package/dist/components/messages/TaskInModuleView.js +1 -1
- package/dist/components/messages/TaskInModuleView.js.map +2 -2
- package/dist/components/messages/TaskToolMessage.js +1 -1
- package/dist/components/messages/TaskToolMessage.js.map +2 -2
- package/dist/components/messages/UserPromptMessage.js +6 -1
- package/dist/components/messages/UserPromptMessage.js.map +2 -2
- package/dist/constants/modelCapabilities.js +103 -18
- package/dist/constants/modelCapabilities.js.map +2 -2
- package/dist/constants/product.js +2 -0
- package/dist/constants/product.js.map +2 -2
- package/dist/constants/prompts/agentPrompt.js +30 -0
- package/dist/constants/prompts/agentPrompt.js.map +7 -0
- package/dist/constants/prompts/codeConventions.js +27 -0
- package/dist/constants/prompts/codeConventions.js.map +7 -0
- package/dist/constants/prompts/doingTasks.js +15 -0
- package/dist/constants/prompts/doingTasks.js.map +7 -0
- package/dist/constants/prompts/envInfo.js +17 -0
- package/dist/constants/prompts/envInfo.js.map +7 -0
- package/dist/constants/prompts/executingWithCare.js +17 -0
- package/dist/constants/prompts/executingWithCare.js.map +7 -0
- package/dist/constants/prompts/identity.js +10 -0
- package/dist/constants/prompts/identity.js.map +7 -0
- package/dist/constants/prompts/index.js +78 -0
- package/dist/constants/prompts/index.js.map +7 -0
- package/dist/constants/prompts/taskManagement.js +60 -0
- package/dist/constants/prompts/taskManagement.js.map +7 -0
- package/dist/constants/prompts/toneAndStyle.js +62 -0
- package/dist/constants/prompts/toneAndStyle.js.map +7 -0
- package/dist/constants/prompts/toolUsagePolicy.js +38 -0
- package/dist/constants/prompts/toolUsagePolicy.js.map +7 -0
- package/dist/constants/prompts.js +5 -176
- package/dist/constants/prompts.js.map +2 -2
- package/dist/constants/providerRegistry.js +235 -0
- package/dist/constants/providerRegistry.js.map +7 -0
- package/dist/constants/providers.js +35 -0
- package/dist/constants/providers.js.map +7 -0
- package/dist/context/PermissionContext.js +0 -1
- package/dist/context/PermissionContext.js.map +2 -2
- package/dist/context.js +87 -31
- package/dist/context.js.map +2 -2
- package/dist/core/backupHook.js +2 -2
- package/dist/core/backupHook.js.map +2 -2
- package/dist/core/config/defaults.js +4 -1
- package/dist/core/config/defaults.js.map +2 -2
- package/dist/core/config/schema.js +7 -1
- package/dist/core/config/schema.js.map +2 -2
- package/dist/core/costTracker.js +18 -0
- package/dist/core/costTracker.js.map +2 -2
- package/dist/core/index.js +0 -1
- package/dist/core/index.js.map +2 -2
- package/dist/core/tokenStatsManager.js +22 -4
- package/dist/core/tokenStatsManager.js.map +2 -2
- package/dist/entrypoints/cli.js +65 -84
- package/dist/entrypoints/cli.js.map +2 -2
- package/dist/hooks/useAgentTokenStats.js +1 -1
- package/dist/hooks/useAgentTokenStats.js.map +2 -2
- package/dist/hooks/useAgentTranscripts.js +2 -1
- package/dist/hooks/useAgentTranscripts.js.map +2 -2
- package/dist/hooks/useBackgroundShells.js +29 -0
- package/dist/hooks/useBackgroundShells.js.map +7 -0
- package/dist/hooks/useCanUseTool.js +1 -1
- package/dist/hooks/useCanUseTool.js.map +2 -2
- package/dist/hooks/useDeferredLoading.js +64 -0
- package/dist/hooks/useDeferredLoading.js.map +7 -0
- package/dist/hooks/useHookStatus.js +1 -1
- package/dist/hooks/useHookStatus.js.map +2 -2
- package/dist/hooks/useSessionTracking.js +55 -0
- package/dist/hooks/useSessionTracking.js.map +7 -0
- package/dist/hooks/useTerminalSize.js +21 -0
- package/dist/hooks/useTerminalSize.js.map +2 -2
- package/dist/hooks/useTextInput.js +1 -0
- package/dist/hooks/useTextInput.js.map +2 -2
- package/dist/hooks/useUnifiedCompletion.js +3 -2
- package/dist/hooks/useUnifiedCompletion.js.map +2 -2
- package/dist/i18n/locales/en.js +8 -9
- package/dist/i18n/locales/en.js.map +2 -2
- package/dist/i18n/locales/zh-CN.js +8 -9
- package/dist/i18n/locales/zh-CN.js.map +2 -2
- package/dist/i18n/types.js.map +1 -1
- package/dist/messages.js +41 -17
- package/dist/messages.js.map +2 -2
- package/dist/permissions.js +94 -1
- package/dist/permissions.js.map +2 -2
- package/dist/query.js +27 -19
- package/dist/query.js.map +2 -2
- package/dist/screens/REPL.js +83 -74
- package/dist/screens/REPL.js.map +2 -2
- package/dist/services/adapters/responsesAPI.js +6 -0
- package/dist/services/adapters/responsesAPI.js.map +2 -2
- package/dist/services/agentTeams/index.js +35 -0
- package/dist/services/agentTeams/index.js.map +7 -0
- package/dist/services/agentTeams/mailbox.js +114 -0
- package/dist/services/agentTeams/mailbox.js.map +7 -0
- package/dist/services/agentTeams/teamManager.js +149 -0
- package/dist/services/agentTeams/teamManager.js.map +7 -0
- package/dist/services/agentTeams/teamTaskStore.js +114 -0
- package/dist/services/agentTeams/teamTaskStore.js.map +7 -0
- package/dist/services/agentTeams/teammateSpawner.js +80 -0
- package/dist/services/agentTeams/teammateSpawner.js.map +7 -0
- package/dist/services/checkpointManager.js +16 -3
- package/dist/services/checkpointManager.js.map +2 -2
- package/dist/services/claude.js +19 -1728
- package/dist/services/claude.js.map +3 -3
- package/dist/services/gpt5ConnectionTest.js +4 -2
- package/dist/services/gpt5ConnectionTest.js.map +2 -2
- package/dist/services/hookExecutor.js +411 -127
- package/dist/services/hookExecutor.js.map +2 -2
- package/dist/services/llm/anthropicProvider.js +807 -0
- package/dist/services/llm/anthropicProvider.js.map +7 -0
- package/dist/services/llm/dispatch.js +218 -0
- package/dist/services/llm/dispatch.js.map +7 -0
- package/dist/services/llm/index.js +44 -0
- package/dist/services/llm/index.js.map +7 -0
- package/dist/services/llm/mintoContext.js +69 -0
- package/dist/services/llm/mintoContext.js.map +7 -0
- package/dist/services/llm/openaiProvider.js +622 -0
- package/dist/services/llm/openaiProvider.js.map +7 -0
- package/dist/services/llm/types.js +157 -0
- package/dist/services/llm/types.js.map +7 -0
- package/dist/services/mcpClient.js +183 -33
- package/dist/services/mcpClient.js.map +2 -2
- package/dist/services/notifier.js +14 -0
- package/dist/services/notifier.js.map +2 -2
- package/dist/services/oauth.js +4 -2
- package/dist/services/oauth.js.map +2 -2
- package/dist/services/openai.js +66 -56
- package/dist/services/openai.js.map +3 -3
- package/dist/services/outputStyles.js +102 -21
- package/dist/services/outputStyles.js.map +2 -2
- package/dist/services/plugins/skillMarketplace.js +4 -1
- package/dist/services/plugins/skillMarketplace.js.map +2 -2
- package/dist/services/sentry.js +1 -1
- package/dist/services/sentry.js.map +2 -2
- package/dist/services/sessionMemory.js +16 -3
- package/dist/services/sessionMemory.js.map +2 -2
- package/dist/services/systemReminder.js +350 -3
- package/dist/services/systemReminder.js.map +2 -2
- package/dist/services/taskStore.js +19 -0
- package/dist/services/taskStore.js.map +2 -2
- package/dist/tools/ArchitectTool/ArchitectTool.js.map +1 -1
- package/dist/tools/AskUserQuestionTool/AskUserQuestionTool.js.map +1 -1
- package/dist/tools/BashOutputTool/BashOutputTool.js.map +1 -1
- package/dist/tools/BashTool/BashTool.js +28 -0
- package/dist/tools/BashTool/BashTool.js.map +2 -2
- package/dist/tools/FileEditTool/FileEditTool.js +1 -1
- package/dist/tools/FileEditTool/FileEditTool.js.map +2 -2
- package/dist/tools/FileReadTool/FileReadTool.js +14 -0
- package/dist/tools/FileReadTool/FileReadTool.js.map +2 -2
- package/dist/tools/FileWriteTool/FileWriteTool.js +3 -1
- package/dist/tools/FileWriteTool/FileWriteTool.js.map +2 -2
- package/dist/tools/GlobTool/GlobTool.js.map +1 -1
- package/dist/tools/GrepTool/GrepTool.js.map +1 -1
- package/dist/tools/KillShellTool/KillShellTool.js.map +1 -1
- package/dist/tools/ListMcpResourcesTool/ListMcpResourcesTool.js.map +2 -2
- package/dist/tools/LspTool/LspTool.js +11 -2
- package/dist/tools/LspTool/LspTool.js.map +2 -2
- package/dist/tools/MCPTool/MCPTool.js.map +1 -1
- package/dist/tools/MemoryReadTool/MemoryReadTool.js +2 -1
- package/dist/tools/MemoryReadTool/MemoryReadTool.js.map +2 -2
- package/dist/tools/MemoryWriteTool/MemoryWriteTool.js +2 -1
- package/dist/tools/MemoryWriteTool/MemoryWriteTool.js.map +2 -2
- package/dist/tools/MultiEditTool/MultiEditTool.js.map +1 -1
- package/dist/tools/NotebookEditTool/NotebookEditTool.js.map +1 -1
- package/dist/tools/NotebookReadTool/NotebookReadTool.js.map +1 -1
- package/dist/tools/PlanModeTool/EnterPlanModeTool.js +8 -2
- package/dist/tools/PlanModeTool/EnterPlanModeTool.js.map +2 -2
- package/dist/tools/PlanModeTool/ExitPlanModeTool.js +2 -0
- package/dist/tools/PlanModeTool/ExitPlanModeTool.js.map +2 -2
- package/dist/tools/ReadMcpResourceTool/ReadMcpResourceTool.js.map +1 -1
- package/dist/tools/SlashCommandTool/SlashCommandTool.js +174 -18
- package/dist/tools/SlashCommandTool/SlashCommandTool.js.map +3 -3
- package/dist/tools/TaskCreateTool/TaskCreateTool.js.map +1 -1
- package/dist/tools/TaskGetTool/TaskGetTool.js.map +1 -1
- package/dist/tools/TaskListTool/TaskListTool.js.map +1 -1
- package/dist/tools/TaskOutputTool/TaskOutputTool.js.map +1 -1
- package/dist/tools/TaskStopTool/TaskStopTool.js.map +1 -1
- package/dist/tools/TaskTool/TaskTool.js +75 -5
- package/dist/tools/TaskTool/TaskTool.js.map +2 -2
- package/dist/tools/TaskTool/prompt.js +12 -6
- package/dist/tools/TaskTool/prompt.js.map +2 -2
- package/dist/tools/TaskUpdateTool/TaskUpdateTool.js.map +1 -1
- package/dist/tools/ThinkTool/ThinkTool.js.map +1 -1
- package/dist/tools/TodoWriteTool/TodoWriteTool.js.map +1 -1
- package/dist/tools/URLFetcherTool/URLFetcherTool.js.map +1 -1
- package/dist/tools/WebSearchTool/WebSearchTool.js.map +1 -1
- package/dist/tools/WebSearchTool/searchProviders.js +2 -1
- package/dist/tools/WebSearchTool/searchProviders.js.map +2 -2
- package/dist/tools/lsTool/lsTool.js.map +2 -2
- package/dist/tools/lsTool/prompt.js.map +1 -1
- package/dist/tools.js +14 -3
- package/dist/tools.js.map +2 -2
- package/dist/types/PermissionMode.js +21 -1
- package/dist/types/PermissionMode.js.map +2 -2
- package/dist/types/agentTeams.js +1 -0
- package/dist/types/agentTeams.js.map +7 -0
- package/dist/types/hooks.js +8 -2
- package/dist/types/hooks.js.map +2 -2
- package/dist/types/plugin.js +1 -1
- package/dist/types/plugin.js.map +2 -2
- package/dist/utils/agentLoader.js +25 -3
- package/dist/utils/agentLoader.js.map +2 -2
- package/dist/utils/animationManager.js +1 -1
- package/dist/utils/animationManager.js.map +2 -2
- package/dist/utils/ask.js +1 -1
- package/dist/utils/async.js +5 -1
- package/dist/utils/async.js.map +2 -2
- package/dist/utils/autoCompactCore.js +60 -0
- package/dist/utils/autoCompactCore.js.map +2 -2
- package/dist/utils/config.js +26 -128
- package/dist/utils/config.js.map +2 -2
- package/dist/utils/configSchema.js +227 -0
- package/dist/utils/configSchema.js.map +7 -0
- package/dist/utils/debugLogger.js.map +2 -2
- package/dist/utils/env.js +4 -3
- package/dist/utils/env.js.map +2 -2
- package/dist/utils/envConfig.js +34 -0
- package/dist/utils/envConfig.js.map +3 -3
- package/dist/utils/gpt5.js +146 -0
- package/dist/utils/gpt5.js.map +7 -0
- package/dist/utils/hookManager.js +374 -140
- package/dist/utils/hookManager.js.map +2 -2
- package/dist/utils/markdown.js +47 -0
- package/dist/utils/markdown.js.map +2 -2
- package/dist/utils/memoizeWithTTL.js +25 -0
- package/dist/utils/memoizeWithTTL.js.map +7 -0
- package/dist/utils/model.js +34 -9
- package/dist/utils/model.js.map +2 -2
- package/dist/utils/pluginInstaller.js +34 -5
- package/dist/utils/pluginInstaller.js.map +2 -2
- package/dist/utils/pluginLoader.js +201 -32
- package/dist/utils/pluginLoader.js.map +2 -2
- package/dist/utils/safeFetch.js +45 -0
- package/dist/utils/safeFetch.js.map +7 -0
- package/dist/utils/skillLoader.js +59 -6
- package/dist/utils/skillLoader.js.map +2 -2
- package/dist/utils/streamingState.js +52 -0
- package/dist/utils/streamingState.js.map +7 -0
- package/dist/utils/style.js +6 -3
- package/dist/utils/style.js.map +2 -2
- package/dist/utils/teamConfig.js +9 -3
- package/dist/utils/teamConfig.js.map +2 -2
- package/dist/utils/toolRiskClassification.js +0 -6
- package/dist/utils/toolRiskClassification.js.map +2 -2
- package/dist/version.js +2 -2
- package/dist/version.js.map +1 -1
- package/package.json +7 -6
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { spawn } from "child_process";
|
|
2
|
+
import { existsSync, readFileSync } from "fs";
|
|
2
3
|
import { EventEmitter } from "events";
|
|
3
4
|
import {
|
|
4
5
|
HookEvent
|
|
5
6
|
} from "../types/hooks.js";
|
|
6
7
|
import { getCwd } from "../utils/state.js";
|
|
7
8
|
import { logError } from "../utils/log.js";
|
|
9
|
+
import { emitReminderEvent } from "./systemReminder.js";
|
|
8
10
|
const logInfo = (msg) => {
|
|
9
11
|
if (process.env.DEBUG) console.log(`[INFO] ${msg}`);
|
|
10
12
|
};
|
|
@@ -12,132 +14,326 @@ const logDebug = (msg, ...args) => {
|
|
|
12
14
|
if (process.env.DEBUG) console.log(`[DEBUG] ${msg}`, ...args);
|
|
13
15
|
};
|
|
14
16
|
const hookStatusEmitter = new EventEmitter();
|
|
17
|
+
const executedOnceHooks = /* @__PURE__ */ new Set();
|
|
18
|
+
function resetOnceHooks() {
|
|
19
|
+
executedOnceHooks.clear();
|
|
20
|
+
}
|
|
15
21
|
function formatHookStatusMessage(event, toolName, hookName, success, errorMessage) {
|
|
16
22
|
const eventPart = toolName ? `${event}:${toolName}` : event;
|
|
17
23
|
const statusPart = success ? "succeeded" : "failed";
|
|
18
24
|
const detailPart = success ? "Success" : errorMessage || "Error";
|
|
19
25
|
return `${eventPart} hook ${statusPart}: ${detailPart}`;
|
|
20
26
|
}
|
|
27
|
+
function emitStatusEvent(event, toolName, hookName, success, errorMessage) {
|
|
28
|
+
hookStatusEmitter.emit("status", {
|
|
29
|
+
event,
|
|
30
|
+
toolName,
|
|
31
|
+
success,
|
|
32
|
+
message: formatHookStatusMessage(
|
|
33
|
+
event,
|
|
34
|
+
toolName,
|
|
35
|
+
hookName,
|
|
36
|
+
success,
|
|
37
|
+
errorMessage
|
|
38
|
+
),
|
|
39
|
+
timestamp: Date.now(),
|
|
40
|
+
hookName
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
function substituteArguments(command, input) {
|
|
44
|
+
if (!command.includes("$ARGUMENTS")) {
|
|
45
|
+
return command;
|
|
46
|
+
}
|
|
47
|
+
const inputJson = JSON.stringify(input);
|
|
48
|
+
const escaped = inputJson.replace(/'/g, "'\\''");
|
|
49
|
+
return command.replace(/\$ARGUMENTS/g, `'${escaped}'`);
|
|
50
|
+
}
|
|
21
51
|
async function executeHook(hook, input, options) {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
52
|
+
const hookType = hook.config.type || "command";
|
|
53
|
+
if (hook.config.once) {
|
|
54
|
+
const hookKey = `${hook.pluginName}:${hook.name}:${hook.event}`;
|
|
55
|
+
if (executedOnceHooks.has(hookKey)) {
|
|
56
|
+
logDebug(`Skipping once-hook (already executed): ${hookKey}`);
|
|
57
|
+
return { success: true };
|
|
58
|
+
}
|
|
59
|
+
executedOnceHooks.add(hookKey);
|
|
27
60
|
}
|
|
28
|
-
const timeout = hook.config.timeout || options.timeout || 3e4;
|
|
29
61
|
const toolName = "tool_name" in input ? input.tool_name : void 0;
|
|
62
|
+
if (hook.config.async) {
|
|
63
|
+
executeHookAsync(hook, input, options, hookType, toolName).catch((err) => {
|
|
64
|
+
logDebug(`Async hook ${hook.name} error: ${err}`);
|
|
65
|
+
});
|
|
66
|
+
return { success: true };
|
|
67
|
+
}
|
|
68
|
+
switch (hookType) {
|
|
69
|
+
case "command":
|
|
70
|
+
return executeCommandHook(hook, input, options, toolName);
|
|
71
|
+
case "prompt":
|
|
72
|
+
return executePromptHook(hook, input, options, toolName);
|
|
73
|
+
case "agent":
|
|
74
|
+
return executeAgentHook(hook, input, options, toolName);
|
|
75
|
+
default:
|
|
76
|
+
return {
|
|
77
|
+
success: false,
|
|
78
|
+
error: `Unknown hook type: ${hookType}`
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
async function executeHookAsync(hook, input, options, hookType, toolName) {
|
|
83
|
+
try {
|
|
84
|
+
let result;
|
|
85
|
+
switch (hookType) {
|
|
86
|
+
case "command":
|
|
87
|
+
result = await executeCommandHook(hook, input, options, toolName);
|
|
88
|
+
break;
|
|
89
|
+
case "prompt":
|
|
90
|
+
result = await executePromptHook(hook, input, options, toolName);
|
|
91
|
+
break;
|
|
92
|
+
case "agent":
|
|
93
|
+
result = await executeAgentHook(hook, input, options, toolName);
|
|
94
|
+
break;
|
|
95
|
+
default:
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
if (result.output?.systemMessage) {
|
|
99
|
+
hookStatusEmitter.emit("asyncResult", {
|
|
100
|
+
hookName: hook.name,
|
|
101
|
+
systemMessage: result.output.systemMessage
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
} catch {
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
async function executeCommandHook(hook, input, options, toolName) {
|
|
108
|
+
if (!hook.config.command) {
|
|
109
|
+
return { success: false, error: "Command hook missing command field" };
|
|
110
|
+
}
|
|
111
|
+
const timeout = (hook.config.timeout ? hook.config.timeout * 1e3 : void 0) || options.timeout || 3e4;
|
|
30
112
|
try {
|
|
31
113
|
logDebug(`Executing hook: ${hook.name}`);
|
|
32
|
-
|
|
33
|
-
|
|
114
|
+
const command = substituteArguments(hook.config.command, input);
|
|
115
|
+
logDebug(`Command: ${command}`);
|
|
116
|
+
const result = await executeBashCommand(command, input, {
|
|
34
117
|
...options,
|
|
35
118
|
timeout,
|
|
36
119
|
pluginRoot: options.pluginRoot
|
|
37
120
|
});
|
|
38
121
|
if (result.timedOut) {
|
|
39
|
-
logError(`Hook ${hook.name} timed out after ${timeout}ms`);
|
|
40
122
|
const errorMsg = `Hook execution timed out after ${timeout}ms`;
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
success: false,
|
|
45
|
-
message: formatHookStatusMessage(
|
|
46
|
-
hook.event,
|
|
47
|
-
toolName,
|
|
48
|
-
hook.name,
|
|
49
|
-
false,
|
|
50
|
-
errorMsg
|
|
51
|
-
),
|
|
52
|
-
timestamp: Date.now(),
|
|
53
|
-
hookName: hook.name
|
|
54
|
-
});
|
|
55
|
-
return {
|
|
56
|
-
success: false,
|
|
57
|
-
timedOut: true,
|
|
58
|
-
error: errorMsg
|
|
59
|
-
};
|
|
123
|
+
logError(`Hook ${hook.name} timed out after ${timeout}ms`);
|
|
124
|
+
emitStatusEvent(hook.event, toolName, hook.name, false, errorMsg);
|
|
125
|
+
return { success: false, timedOut: true, error: errorMsg };
|
|
60
126
|
}
|
|
61
|
-
if (result.
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
toolName,
|
|
66
|
-
success: false,
|
|
67
|
-
message: formatHookStatusMessage(
|
|
68
|
-
hook.event,
|
|
69
|
-
toolName,
|
|
70
|
-
hook.name,
|
|
71
|
-
false,
|
|
72
|
-
result.error
|
|
73
|
-
),
|
|
74
|
-
timestamp: Date.now(),
|
|
75
|
-
hookName: hook.name
|
|
76
|
-
});
|
|
127
|
+
if (result.exitCode === 2) {
|
|
128
|
+
const reason = result.stderr.trim() || "Blocked by hook";
|
|
129
|
+
logDebug(`Hook ${hook.name} exit code 2 (block): ${reason}`);
|
|
130
|
+
emitStatusEvent(hook.event, toolName, hook.name, true);
|
|
77
131
|
return {
|
|
78
|
-
success:
|
|
79
|
-
|
|
132
|
+
success: true,
|
|
133
|
+
decision: "block",
|
|
134
|
+
blockedByExitCode2: true,
|
|
135
|
+
blockReason: reason,
|
|
136
|
+
output: {
|
|
137
|
+
decision: "block",
|
|
138
|
+
reason,
|
|
139
|
+
systemMessage: reason
|
|
140
|
+
}
|
|
80
141
|
};
|
|
81
142
|
}
|
|
82
|
-
|
|
143
|
+
if (result.exitCode !== 0 && result.exitCode !== null) {
|
|
144
|
+
const errorMsg = `Command exited with code ${result.exitCode}: ${result.stderr}`;
|
|
145
|
+
logError(`Hook ${hook.name} failed: ${errorMsg}`);
|
|
146
|
+
emitStatusEvent(hook.event, toolName, hook.name, false, errorMsg);
|
|
147
|
+
return { success: false, error: errorMsg };
|
|
148
|
+
}
|
|
149
|
+
const output = parseHookOutput(result.stdout, input.hook_event_name);
|
|
83
150
|
if (!output) {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
toolName,
|
|
87
|
-
success: true,
|
|
88
|
-
message: formatHookStatusMessage(hook.event, toolName, hook.name, true),
|
|
89
|
-
timestamp: Date.now(),
|
|
90
|
-
hookName: hook.name
|
|
91
|
-
});
|
|
92
|
-
return {
|
|
93
|
-
success: true
|
|
94
|
-
};
|
|
151
|
+
emitStatusEvent(hook.event, toolName, hook.name, true);
|
|
152
|
+
return { success: true };
|
|
95
153
|
}
|
|
96
154
|
logDebug(`Hook ${hook.name} output:`, output);
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
success: true,
|
|
101
|
-
message: formatHookStatusMessage(hook.event, toolName, hook.name, true),
|
|
102
|
-
timestamp: Date.now(),
|
|
103
|
-
hookName: hook.name
|
|
104
|
-
});
|
|
105
|
-
return {
|
|
106
|
-
success: true,
|
|
107
|
-
decision: output.decision,
|
|
108
|
-
output
|
|
109
|
-
};
|
|
155
|
+
emitStatusEvent(hook.event, toolName, hook.name, true);
|
|
156
|
+
const decision = resolveDecision(output);
|
|
157
|
+
return { success: true, decision, output };
|
|
110
158
|
} catch (error) {
|
|
111
159
|
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
112
160
|
logError(`Hook ${hook.name} execution error: ${errorMsg}`);
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
161
|
+
emitStatusEvent(hook.event, toolName, hook.name, false, errorMsg);
|
|
162
|
+
return { success: false, error: errorMsg };
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
async function executePromptHook(hook, input, options, toolName) {
|
|
166
|
+
if (!hook.config.prompt) {
|
|
167
|
+
return { success: false, error: "Prompt hook missing prompt field" };
|
|
168
|
+
}
|
|
169
|
+
const timeout = (hook.config.timeout ? hook.config.timeout * 1e3 : void 0) || 3e4;
|
|
170
|
+
try {
|
|
171
|
+
const inputJson = JSON.stringify(input);
|
|
172
|
+
const prompt = hook.config.prompt.replace(/\$ARGUMENTS/g, inputJson);
|
|
173
|
+
logDebug(`Executing prompt hook: ${hook.name}`);
|
|
174
|
+
const { queryQuick } = await import("./claude.js");
|
|
175
|
+
const abortController = new AbortController();
|
|
176
|
+
const timer = setTimeout(() => abortController.abort(), timeout);
|
|
177
|
+
try {
|
|
178
|
+
const result = await queryQuick({
|
|
179
|
+
systemPrompt: [
|
|
180
|
+
'You are a hook evaluator. Respond ONLY with JSON: { "ok": boolean, "reason": string }.',
|
|
181
|
+
"ok=true means allow the action, ok=false means block it."
|
|
182
|
+
],
|
|
183
|
+
userPrompt: prompt,
|
|
184
|
+
signal: abortController.signal
|
|
185
|
+
});
|
|
186
|
+
clearTimeout(timer);
|
|
187
|
+
const text = result.message.content.filter((b) => b.type === "text").map((b) => b.text).join("");
|
|
188
|
+
const jsonMatch = text.match(/\{[\s\S]*\}/);
|
|
189
|
+
if (jsonMatch) {
|
|
190
|
+
const parsed = JSON.parse(jsonMatch[0]);
|
|
191
|
+
const decision = parsed.ok ? "approve" : "block";
|
|
192
|
+
emitStatusEvent(hook.event, toolName, hook.name, true);
|
|
193
|
+
return {
|
|
194
|
+
success: true,
|
|
195
|
+
decision,
|
|
196
|
+
output: { decision, reason: parsed.reason }
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
} catch {
|
|
200
|
+
clearTimeout(timer);
|
|
201
|
+
}
|
|
202
|
+
logDebug(`Prompt hook ${hook.name}: parse failed, defaulting to allow`);
|
|
203
|
+
emitStatusEvent(hook.event, toolName, hook.name, true);
|
|
204
|
+
return { success: true, decision: "approve" };
|
|
205
|
+
} catch (error) {
|
|
206
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
207
|
+
logError(`Prompt hook ${hook.name} error: ${errorMsg}`);
|
|
208
|
+
emitStatusEvent(hook.event, toolName, hook.name, false, errorMsg);
|
|
209
|
+
return { success: true, decision: "approve" };
|
|
131
210
|
}
|
|
132
211
|
}
|
|
212
|
+
async function executeAgentHook(hook, input, options, toolName) {
|
|
213
|
+
if (!hook.config.prompt) {
|
|
214
|
+
return { success: false, error: "Agent hook missing prompt field" };
|
|
215
|
+
}
|
|
216
|
+
const timeout = (hook.config.timeout ? hook.config.timeout * 1e3 : void 0) || 6e4;
|
|
217
|
+
try {
|
|
218
|
+
const inputJson = JSON.stringify(input);
|
|
219
|
+
const prompt = hook.config.prompt.replace(/\$ARGUMENTS/g, inputJson);
|
|
220
|
+
logDebug(`Executing agent hook: ${hook.name}`);
|
|
221
|
+
const { queryQuick } = await import("./claude.js");
|
|
222
|
+
const abortController = new AbortController();
|
|
223
|
+
const timer = setTimeout(() => abortController.abort(), timeout);
|
|
224
|
+
try {
|
|
225
|
+
const result = await queryQuick({
|
|
226
|
+
systemPrompt: [
|
|
227
|
+
"You are a hook agent evaluator. You have read-only access to the codebase.",
|
|
228
|
+
'Evaluate the request and respond ONLY with JSON: { "ok": boolean, "reason": string }.',
|
|
229
|
+
"ok=true means allow the action, ok=false means block it."
|
|
230
|
+
],
|
|
231
|
+
userPrompt: prompt,
|
|
232
|
+
signal: abortController.signal
|
|
233
|
+
});
|
|
234
|
+
clearTimeout(timer);
|
|
235
|
+
const text = result.message.content.filter((b) => b.type === "text").map((b) => b.text).join("");
|
|
236
|
+
const jsonMatch = text.match(/\{[\s\S]*\}/);
|
|
237
|
+
if (jsonMatch) {
|
|
238
|
+
const parsed = JSON.parse(jsonMatch[0]);
|
|
239
|
+
const decision = parsed.ok ? "approve" : "block";
|
|
240
|
+
emitStatusEvent(hook.event, toolName, hook.name, true);
|
|
241
|
+
return {
|
|
242
|
+
success: true,
|
|
243
|
+
decision,
|
|
244
|
+
output: { decision, reason: parsed.reason }
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
} catch {
|
|
248
|
+
clearTimeout(timer);
|
|
249
|
+
}
|
|
250
|
+
logDebug(`Agent hook ${hook.name}: parse failed, defaulting to allow`);
|
|
251
|
+
emitStatusEvent(hook.event, toolName, hook.name, true);
|
|
252
|
+
return { success: true, decision: "approve" };
|
|
253
|
+
} catch (error) {
|
|
254
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
255
|
+
logError(`Agent hook ${hook.name} error: ${errorMsg}`);
|
|
256
|
+
emitStatusEvent(hook.event, toolName, hook.name, false, errorMsg);
|
|
257
|
+
return { success: true, decision: "approve" };
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
function resolveDecision(output) {
|
|
261
|
+
if (output.hookSpecificOutput) {
|
|
262
|
+
const specific = output.hookSpecificOutput;
|
|
263
|
+
if (specific.permissionDecision) {
|
|
264
|
+
const mapping = {
|
|
265
|
+
allow: "approve",
|
|
266
|
+
deny: "block",
|
|
267
|
+
ask: "ask",
|
|
268
|
+
approve: "approve",
|
|
269
|
+
block: "block"
|
|
270
|
+
};
|
|
271
|
+
return mapping[specific.permissionDecision] ?? output.decision;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
return output.decision;
|
|
275
|
+
}
|
|
276
|
+
let claudeEnvFilePath;
|
|
277
|
+
function loadEnvFile() {
|
|
278
|
+
const envFile = claudeEnvFilePath || process.env.CLAUDE_ENV_FILE;
|
|
279
|
+
if (!envFile || !existsSync(envFile)) return {};
|
|
280
|
+
try {
|
|
281
|
+
const content = readFileSync(envFile, "utf-8");
|
|
282
|
+
const vars = {};
|
|
283
|
+
for (const line of content.split("\n")) {
|
|
284
|
+
const trimmed = line.trim();
|
|
285
|
+
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
286
|
+
const eqIdx = trimmed.indexOf("=");
|
|
287
|
+
if (eqIdx <= 0) continue;
|
|
288
|
+
const key = trimmed.slice(0, eqIdx).trim();
|
|
289
|
+
let value = trimmed.slice(eqIdx + 1).trim();
|
|
290
|
+
if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
|
|
291
|
+
value = value.slice(1, -1);
|
|
292
|
+
}
|
|
293
|
+
vars[key] = value;
|
|
294
|
+
}
|
|
295
|
+
return vars;
|
|
296
|
+
} catch {
|
|
297
|
+
return {};
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
function extractFilePathsFromInput(toolInput) {
|
|
301
|
+
if (!toolInput) return "";
|
|
302
|
+
const paths = [];
|
|
303
|
+
if (typeof toolInput.file_path === "string") paths.push(toolInput.file_path);
|
|
304
|
+
if (typeof toolInput.path === "string") paths.push(toolInput.path);
|
|
305
|
+
if (typeof toolInput.notebook_path === "string")
|
|
306
|
+
paths.push(toolInput.notebook_path);
|
|
307
|
+
return paths.join(":");
|
|
308
|
+
}
|
|
133
309
|
async function executeBashCommand(command, input, options) {
|
|
134
310
|
return new Promise((resolve) => {
|
|
311
|
+
const envFileVars = loadEnvFile();
|
|
312
|
+
const toolName = "tool_name" in input ? input.tool_name : void 0;
|
|
313
|
+
const toolInput = "tool_input" in input ? input.tool_input : void 0;
|
|
314
|
+
const toolInputJson = toolInput ? JSON.stringify(toolInput) : "";
|
|
315
|
+
const filePaths = extractFilePathsFromInput(toolInput);
|
|
316
|
+
const shellCommand = toolName === "Bash" && toolInput?.command ? String(toolInput.command) : "";
|
|
317
|
+
const projectDir = getCwd();
|
|
135
318
|
const env = {
|
|
136
319
|
...process.env,
|
|
320
|
+
...envFileVars,
|
|
321
|
+
// CC-compatible env vars
|
|
137
322
|
CLAUDE_PLUGIN_ROOT: options.pluginRoot,
|
|
138
323
|
CLAUDE_SESSION_ID: options.sessionId,
|
|
139
|
-
CLAUDE_CWD:
|
|
140
|
-
CLAUDE_TRANSCRIPT_PATH: options.transcriptPath || ""
|
|
324
|
+
CLAUDE_CWD: projectDir,
|
|
325
|
+
CLAUDE_TRANSCRIPT_PATH: options.transcriptPath || "",
|
|
326
|
+
CLAUDE_PROJECT_DIR: projectDir,
|
|
327
|
+
CLAUDE_WORKSPACE_DIR: projectDir,
|
|
328
|
+
CLAUDE_TOOL_INPUT: toolInputJson,
|
|
329
|
+
CLAUDE_FILE_PATHS: filePaths,
|
|
330
|
+
CLAUDE_SHELL_COMMAND: shellCommand,
|
|
331
|
+
// Minto-prefixed duplicates
|
|
332
|
+
MINTO_PROJECT_DIR: projectDir,
|
|
333
|
+
MINTO_WORKSPACE_DIR: projectDir,
|
|
334
|
+
MINTO_TOOL_INPUT: toolInputJson,
|
|
335
|
+
MINTO_FILE_PATHS: filePaths,
|
|
336
|
+
MINTO_SHELL_COMMAND: shellCommand
|
|
141
337
|
};
|
|
142
338
|
const child = spawn("bash", ["-c", command], {
|
|
143
339
|
env,
|
|
@@ -164,32 +360,17 @@ async function executeBashCommand(command, input, options) {
|
|
|
164
360
|
child.on("close", (code) => {
|
|
165
361
|
clearTimeout(timer);
|
|
166
362
|
if (timedOut) {
|
|
167
|
-
resolve({
|
|
168
|
-
stdout: "",
|
|
169
|
-
stderr: "",
|
|
170
|
-
timedOut: true
|
|
171
|
-
});
|
|
172
|
-
return;
|
|
173
|
-
}
|
|
174
|
-
if (code !== 0 && code !== null) {
|
|
175
|
-
resolve({
|
|
176
|
-
stdout,
|
|
177
|
-
stderr,
|
|
178
|
-
error: `Command exited with code ${code}: ${stderr}`
|
|
179
|
-
});
|
|
363
|
+
resolve({ stdout: "", stderr: "", exitCode: null, timedOut: true });
|
|
180
364
|
return;
|
|
181
365
|
}
|
|
182
|
-
resolve({
|
|
183
|
-
stdout,
|
|
184
|
-
stderr
|
|
185
|
-
});
|
|
366
|
+
resolve({ stdout, stderr, exitCode: code });
|
|
186
367
|
});
|
|
187
368
|
child.on("error", (error) => {
|
|
188
369
|
clearTimeout(timer);
|
|
189
370
|
resolve({
|
|
190
371
|
stdout: "",
|
|
191
|
-
stderr:
|
|
192
|
-
|
|
372
|
+
stderr: error.message,
|
|
373
|
+
exitCode: 1
|
|
193
374
|
});
|
|
194
375
|
});
|
|
195
376
|
try {
|
|
@@ -202,13 +383,13 @@ async function executeBashCommand(command, input, options) {
|
|
|
202
383
|
child.kill();
|
|
203
384
|
resolve({
|
|
204
385
|
stdout: "",
|
|
205
|
-
stderr:
|
|
206
|
-
|
|
386
|
+
stderr: `Failed to write to stdin: ${error instanceof Error ? error.message : String(error)}`,
|
|
387
|
+
exitCode: 1
|
|
207
388
|
});
|
|
208
389
|
}
|
|
209
390
|
});
|
|
210
391
|
}
|
|
211
|
-
function parseHookOutput(stdout) {
|
|
392
|
+
function parseHookOutput(stdout, eventName) {
|
|
212
393
|
if (!stdout.trim()) {
|
|
213
394
|
return null;
|
|
214
395
|
}
|
|
@@ -218,11 +399,45 @@ function parseHookOutput(stdout) {
|
|
|
218
399
|
logDebug("No JSON found in hook output");
|
|
219
400
|
return null;
|
|
220
401
|
}
|
|
221
|
-
const
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
402
|
+
const raw = JSON.parse(jsonMatch[0]);
|
|
403
|
+
const output = {};
|
|
404
|
+
if (raw.continue !== void 0) output.continue = raw.continue;
|
|
405
|
+
if (raw.stopReason) output.stopReason = raw.stopReason;
|
|
406
|
+
if (raw.suppressOutput !== void 0)
|
|
407
|
+
output.suppressOutput = raw.suppressOutput;
|
|
408
|
+
if (raw.systemMessage) output.systemMessage = raw.systemMessage;
|
|
409
|
+
if (raw.decision) {
|
|
410
|
+
if (["approve", "block", "ask"].includes(raw.decision)) {
|
|
411
|
+
output.decision = raw.decision;
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
if (raw.reason) output.reason = raw.reason;
|
|
415
|
+
const specific = raw.hookSpecificOutput || raw;
|
|
416
|
+
if (eventName === HookEvent.PreToolUse) {
|
|
417
|
+
if (specific.permissionDecision || specific.updatedInput || specific.permissionDecisionReason) {
|
|
418
|
+
output.hookSpecificOutput = {
|
|
419
|
+
hookEventName: HookEvent.PreToolUse,
|
|
420
|
+
permissionDecision: specific.permissionDecision,
|
|
421
|
+
permissionDecisionReason: specific.permissionDecisionReason,
|
|
422
|
+
updatedInput: specific.updatedInput
|
|
423
|
+
};
|
|
424
|
+
}
|
|
425
|
+
} else if (eventName === HookEvent.PostToolUse || eventName === HookEvent.UserPromptSubmit || eventName === HookEvent.SessionStart) {
|
|
426
|
+
if (specific.additionalContext) {
|
|
427
|
+
output.hookSpecificOutput = {
|
|
428
|
+
hookEventName: eventName,
|
|
429
|
+
additionalContext: specific.additionalContext
|
|
430
|
+
};
|
|
431
|
+
}
|
|
432
|
+
if (eventName === HookEvent.SessionStart && specific.envFile) {
|
|
433
|
+
claudeEnvFilePath = specific.envFile;
|
|
434
|
+
process.env.CLAUDE_ENV_FILE = specific.envFile;
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
if (eventName === HookEvent.Notification) {
|
|
438
|
+
if (raw.suppressNotification !== void 0) {
|
|
439
|
+
;
|
|
440
|
+
output.suppressNotification = raw.suppressNotification;
|
|
226
441
|
}
|
|
227
442
|
}
|
|
228
443
|
return output;
|
|
@@ -239,18 +454,37 @@ async function executeHooksForEvent(event, hooks, input, options) {
|
|
|
239
454
|
return [];
|
|
240
455
|
}
|
|
241
456
|
logInfo(`Executing ${matchingHooks.length} hook(s) for event: ${event}`);
|
|
242
|
-
const results = await Promise.
|
|
457
|
+
const results = await Promise.allSettled(
|
|
243
458
|
matchingHooks.map((hook) => executeHook(hook, input, options))
|
|
244
459
|
);
|
|
245
|
-
return results
|
|
460
|
+
return results.map(
|
|
461
|
+
(r) => r.status === "fulfilled" ? r.value : { success: false, error: String(r.reason) }
|
|
462
|
+
);
|
|
246
463
|
}
|
|
247
464
|
function processHookDecisions(results) {
|
|
248
|
-
|
|
465
|
+
let additionalContext;
|
|
466
|
+
let updatedInput;
|
|
467
|
+
for (const r of results) {
|
|
468
|
+
if (!r.success || !r.output) continue;
|
|
469
|
+
const specific = r.output.hookSpecificOutput;
|
|
470
|
+
if (specific?.additionalContext) {
|
|
471
|
+
additionalContext = additionalContext ? `${additionalContext}
|
|
472
|
+
${specific.additionalContext}` : specific.additionalContext;
|
|
473
|
+
}
|
|
474
|
+
if (specific?.updatedInput) {
|
|
475
|
+
updatedInput = { ...updatedInput || {}, ...specific.updatedInput };
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
const blockedResult = results.find(
|
|
479
|
+
(r) => r.success && r.decision === "block" || r.blockedByExitCode2
|
|
480
|
+
);
|
|
249
481
|
if (blockedResult) {
|
|
482
|
+
const reason = blockedResult.blockReason || blockedResult.output?.reason || "Blocked by hook";
|
|
483
|
+
emitReminderEvent("hook:blocking_error", { hookName: "hook", reason });
|
|
250
484
|
return {
|
|
251
485
|
shouldContinue: false,
|
|
252
486
|
shouldAskUser: false,
|
|
253
|
-
reason
|
|
487
|
+
reason
|
|
254
488
|
};
|
|
255
489
|
}
|
|
256
490
|
const askResult = results.find((r) => r.success && r.decision === "ask");
|
|
@@ -263,15 +497,25 @@ function processHookDecisions(results) {
|
|
|
263
497
|
}
|
|
264
498
|
const failedResult = results.find((r) => !r.success);
|
|
265
499
|
if (failedResult) {
|
|
500
|
+
const reason = `Hook execution failed: ${failedResult.error}`;
|
|
501
|
+
emitReminderEvent("hook:stopped_continuation", { hookName: "hook", reason });
|
|
266
502
|
return {
|
|
267
503
|
shouldContinue: false,
|
|
268
504
|
shouldAskUser: true,
|
|
269
|
-
reason
|
|
505
|
+
reason
|
|
270
506
|
};
|
|
271
507
|
}
|
|
508
|
+
if (additionalContext) {
|
|
509
|
+
emitReminderEvent("hook:additional_context", {
|
|
510
|
+
hookName: "hook",
|
|
511
|
+
content: additionalContext
|
|
512
|
+
});
|
|
513
|
+
}
|
|
272
514
|
return {
|
|
273
515
|
shouldContinue: true,
|
|
274
|
-
shouldAskUser: false
|
|
516
|
+
shouldAskUser: false,
|
|
517
|
+
updatedInput,
|
|
518
|
+
additionalContext
|
|
275
519
|
};
|
|
276
520
|
}
|
|
277
521
|
function createPreToolUseInput(sessionId, transcriptPath, toolName, toolInput) {
|
|
@@ -387,14 +631,16 @@ function createSubagentStopInput(sessionId, transcriptPath, agentType, agentId,
|
|
|
387
631
|
stop_hook_active: stopHookActive ?? false
|
|
388
632
|
};
|
|
389
633
|
}
|
|
390
|
-
function createNotificationInput(sessionId, transcriptPath, message) {
|
|
634
|
+
function createNotificationInput(sessionId, transcriptPath, message, title, type) {
|
|
391
635
|
return {
|
|
392
636
|
hook_event_name: HookEvent.Notification,
|
|
393
637
|
session_id: sessionId,
|
|
394
638
|
transcript_path: transcriptPath,
|
|
395
639
|
cwd: getCwd(),
|
|
396
640
|
permission_mode: "default",
|
|
397
|
-
message
|
|
641
|
+
message,
|
|
642
|
+
...title ? { title } : {},
|
|
643
|
+
...type ? { notification_type: type } : {}
|
|
398
644
|
};
|
|
399
645
|
}
|
|
400
646
|
function createPreCompactInput(sessionId, transcriptPath, trigger, customInstructions) {
|
|
@@ -422,7 +668,42 @@ function createPostCompactInput(sessionId, transcriptPath, trigger, summary, com
|
|
|
422
668
|
compressed_tokens: compressedTokens
|
|
423
669
|
};
|
|
424
670
|
}
|
|
671
|
+
function createConfigChangeInput(sessionId, transcriptPath, source, filePath) {
|
|
672
|
+
return {
|
|
673
|
+
hook_event_name: HookEvent.ConfigChange,
|
|
674
|
+
session_id: sessionId,
|
|
675
|
+
transcript_path: transcriptPath,
|
|
676
|
+
cwd: getCwd(),
|
|
677
|
+
permission_mode: "default",
|
|
678
|
+
source,
|
|
679
|
+
file_path: filePath
|
|
680
|
+
};
|
|
681
|
+
}
|
|
682
|
+
function createTaskCompletedInput(sessionId, transcriptPath, taskId, subject, description) {
|
|
683
|
+
return {
|
|
684
|
+
hook_event_name: HookEvent.TaskCompleted,
|
|
685
|
+
session_id: sessionId,
|
|
686
|
+
transcript_path: transcriptPath,
|
|
687
|
+
cwd: getCwd(),
|
|
688
|
+
permission_mode: "default",
|
|
689
|
+
task_id: taskId,
|
|
690
|
+
subject,
|
|
691
|
+
description
|
|
692
|
+
};
|
|
693
|
+
}
|
|
694
|
+
function createTeammateIdleInput(sessionId, transcriptPath, teammateName, teamName) {
|
|
695
|
+
return {
|
|
696
|
+
hook_event_name: HookEvent.TeammateIdle,
|
|
697
|
+
session_id: sessionId,
|
|
698
|
+
transcript_path: transcriptPath,
|
|
699
|
+
cwd: getCwd(),
|
|
700
|
+
permission_mode: "default",
|
|
701
|
+
teammate_name: teammateName,
|
|
702
|
+
team_name: teamName
|
|
703
|
+
};
|
|
704
|
+
}
|
|
425
705
|
export {
|
|
706
|
+
createConfigChangeInput,
|
|
426
707
|
createNotificationInput,
|
|
427
708
|
createPermissionRequestInput,
|
|
428
709
|
createPostCompactInput,
|
|
@@ -435,10 +716,13 @@ export {
|
|
|
435
716
|
createStopInput,
|
|
436
717
|
createSubagentStartInput,
|
|
437
718
|
createSubagentStopInput,
|
|
719
|
+
createTaskCompletedInput,
|
|
720
|
+
createTeammateIdleInput,
|
|
438
721
|
createUserPromptSubmitInput,
|
|
439
722
|
executeHook,
|
|
440
723
|
executeHooksForEvent,
|
|
441
724
|
hookStatusEmitter,
|
|
442
|
-
processHookDecisions
|
|
725
|
+
processHookDecisions,
|
|
726
|
+
resetOnceHooks
|
|
443
727
|
};
|
|
444
728
|
//# sourceMappingURL=hookExecutor.js.map
|