@opencoven/coven-code 0.0.4 → 0.0.6
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 +29 -130
- package/bin/coven-code +26 -0
- package/install.js +117 -0
- package/package.json +26 -23
- package/bin/coven-code-sdk.mjs +0 -12
- package/bin/coven-code.mjs +0 -19
- package/docs/CLI.md +0 -256
- package/docs/CONFIGURATION.md +0 -107
- package/docs/DEMO.md +0 -453
- package/docs/DEVELOPMENT.md +0 -104
- package/docs/DOGFOOD-PROTOCOL.md +0 -263
- package/docs/MCP-SKILLS-PLUGINS.md +0 -127
- package/docs/README.md +0 -39
- package/docs/RELEASE.md +0 -33
- package/docs/SDK.md +0 -107
- package/docs/superpowers/plans/2026-05-25-coven-code-panel-tui.md +0 -904
- package/docs/superpowers/plans/2026-05-25-coven-code-rebrand.md +0 -670
- package/docs/superpowers/specs/2026-05-25-coven-code-panel-tui-design.md +0 -235
- package/docs/superpowers/specs/2026-05-26-slash-first-tui-review.md +0 -63
- package/src/agent/fixture.mjs +0 -95
- package/src/agent/lane.mjs +0 -136
- package/src/cli/dispatch.mjs +0 -66
- package/src/cli/execute.mjs +0 -452
- package/src/cli/help.mjs +0 -58
- package/src/cli/interactive-core.mjs +0 -28
- package/src/cli/interactive-io.mjs +0 -101
- package/src/cli/interactive-slash.mjs +0 -184
- package/src/cli/notifications.mjs +0 -13
- package/src/cli/parse.mjs +0 -83
- package/src/cli/reasoning.mjs +0 -45
- package/src/cli/refs.mjs +0 -162
- package/src/cli/repl.mjs +0 -60
- package/src/cli/slash-commands.mjs +0 -375
- package/src/cli/stream-json.mjs +0 -225
- package/src/cli/tui-actions.mjs +0 -72
- package/src/cli/tui-blessed.mjs +0 -198
- package/src/cli/tui-keys.mjs +0 -80
- package/src/cli/tui-lane.mjs +0 -73
- package/src/cli/tui-render.mjs +0 -169
- package/src/cli/tui-submit.mjs +0 -82
- package/src/cli/tui.mjs +0 -174
- package/src/commands/agents.mjs +0 -53
- package/src/commands/config.mjs +0 -27
- package/src/commands/ide.mjs +0 -17
- package/src/commands/login.mjs +0 -84
- package/src/commands/mcp.mjs +0 -176
- package/src/commands/permissions-eval.mjs +0 -122
- package/src/commands/permissions-rules.mjs +0 -53
- package/src/commands/permissions-text.mjs +0 -112
- package/src/commands/permissions.mjs +0 -62
- package/src/commands/plugins.mjs +0 -86
- package/src/commands/review.mjs +0 -74
- package/src/commands/skill.mjs +0 -23
- package/src/commands/threads.mjs +0 -165
- package/src/commands/tools.mjs +0 -77
- package/src/commands/update.mjs +0 -31
- package/src/commands/usage.mjs +0 -34
- package/src/constants.mjs +0 -52
- package/src/main.mjs +0 -87
- package/src/mcp/discover.mjs +0 -154
- package/src/mcp/local.mjs +0 -55
- package/src/mcp/parsers.mjs +0 -46
- package/src/mcp/permissions.mjs +0 -52
- package/src/mcp/probe.mjs +0 -85
- package/src/mcp/registry.mjs +0 -96
- package/src/mcp/remote-oauth.mjs +0 -55
- package/src/mcp/remote-session.mjs +0 -54
- package/src/mcp/remote-sse.mjs +0 -82
- package/src/mcp/remote.mjs +0 -74
- package/src/plugins/api.mjs +0 -187
- package/src/plugins/configuration.mjs +0 -124
- package/src/plugins/discover.mjs +0 -84
- package/src/plugins/helpers.mjs +0 -187
- package/src/plugins/subsystems.mjs +0 -198
- package/src/plugins/validators.mjs +0 -142
- package/src/sdk-execute.mjs +0 -82
- package/src/sdk-install.mjs +0 -187
- package/src/sdk-settings.mjs +0 -88
- package/src/sdk.mjs +0 -163
- package/src/settings/load.mjs +0 -134
- package/src/settings/paths.mjs +0 -101
- package/src/skills/builtin/building-skills/SKILL.md +0 -20
- package/src/skills/discover.mjs +0 -95
- package/src/threads/store.mjs +0 -176
- package/src/tools/builtin/bash.mjs +0 -110
- package/src/tools/builtin/create-file.mjs +0 -66
- package/src/tools/builtin/edit-file.mjs +0 -76
- package/src/tools/builtin/finder.mjs +0 -73
- package/src/tools/builtin/glob.mjs +0 -74
- package/src/tools/builtin/grep.mjs +0 -82
- package/src/tools/builtin/index.mjs +0 -83
- package/src/tools/builtin/librarian.mjs +0 -97
- package/src/tools/builtin/look-at.mjs +0 -92
- package/src/tools/builtin/mcp.mjs +0 -51
- package/src/tools/builtin/mermaid.mjs +0 -59
- package/src/tools/builtin/oracle.mjs +0 -56
- package/src/tools/builtin/painter.mjs +0 -81
- package/src/tools/builtin/plugin-tool.mjs +0 -53
- package/src/tools/builtin/read-mcp-resource.mjs +0 -63
- package/src/tools/builtin/read-web-page.mjs +0 -72
- package/src/tools/builtin/read.mjs +0 -59
- package/src/tools/builtin/runtime-content.mjs +0 -31
- package/src/tools/builtin/runtime-decisions.mjs +0 -115
- package/src/tools/builtin/runtime.mjs +0 -85
- package/src/tools/builtin/task.mjs +0 -63
- package/src/tools/builtin/toolbox-tool.mjs +0 -57
- package/src/tools/builtin/undo-edit.mjs +0 -97
- package/src/tools/builtin/web-search.mjs +0 -128
- package/src/tools/toolbox.mjs +0 -273
- package/src/util/fs.mjs +0 -13
- package/src/util/glob.mjs +0 -46
- package/src/util/html.mjs +0 -21
- package/src/util/media.mjs +0 -13
- package/src/util/shell.mjs +0 -24
- package/src/util/table.mjs +0 -11
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
import { readFileSync } from 'node:fs';
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
import { resolvePermissionDecision } from '../../commands/permissions.mjs';
|
|
4
|
-
import { runPluginEventHandlers } from '../../plugins/discover.mjs';
|
|
5
|
-
import { walkFiles } from '../../util/glob.mjs';
|
|
6
|
-
import { isToolDisabled } from '../toolbox.mjs';
|
|
7
|
-
import {
|
|
8
|
-
applyToolCallDecision,
|
|
9
|
-
createToolUseID,
|
|
10
|
-
permissionDeniedOutput,
|
|
11
|
-
pluginTextToolRunResult,
|
|
12
|
-
pluginToolCallEvent,
|
|
13
|
-
pluginToolResultEvent,
|
|
14
|
-
pluginToolUseBlock,
|
|
15
|
-
relativeToolPath,
|
|
16
|
-
toolCallDecisionToolRun,
|
|
17
|
-
validateToolCallDecision,
|
|
18
|
-
} from './runtime.mjs';
|
|
19
|
-
|
|
20
|
-
export const TOOL_NAME = 'Grep';
|
|
21
|
-
|
|
22
|
-
export async function executePromptGrepToolRequest(request, parsed = {}, plugins = { handlers: {} }, threadId = '') {
|
|
23
|
-
if (isToolDisabled(TOOL_NAME, 'built-in', parsed)) return { output: `Tool disabled: ${TOOL_NAME}` };
|
|
24
|
-
request = { ...request, flags: normalizeGrepInput(request.flags) };
|
|
25
|
-
if (!request.flags.pattern) return { output: 'Grep requires --pattern' };
|
|
26
|
-
const toolUseID = createToolUseID();
|
|
27
|
-
const callDecision = await runPluginEventHandlers(
|
|
28
|
-
plugins.handlers['tool.call'],
|
|
29
|
-
pluginToolCallEvent(TOOL_NAME, request.flags, threadId, toolUseID),
|
|
30
|
-
validateToolCallDecision,
|
|
31
|
-
);
|
|
32
|
-
const callResult = applyToolCallDecision(TOOL_NAME, request, callDecision);
|
|
33
|
-
if (callResult.output) return toolCallDecisionToolRun(TOOL_NAME, request.flags, toolUseID, callResult);
|
|
34
|
-
request = { ...callResult.request, flags: normalizeGrepInput(callResult.request.flags) };
|
|
35
|
-
const decision = resolvePermissionDecision(TOOL_NAME, request.flags, parsed, { threadId });
|
|
36
|
-
if (!parsed.dangerouslyAllowAll && decision.action !== 'allow') {
|
|
37
|
-
return {
|
|
38
|
-
output: permissionDeniedOutput(TOOL_NAME, decision),
|
|
39
|
-
permissionDenials: [{ tool: TOOL_NAME, action: decision.action, reason: 'permission' }],
|
|
40
|
-
};
|
|
41
|
-
}
|
|
42
|
-
const output = grepBuiltinFiles(request.flags.pattern, request.flags.path);
|
|
43
|
-
const resultDecision = await runPluginEventHandlers(
|
|
44
|
-
plugins.handlers['tool.result'],
|
|
45
|
-
pluginToolResultEvent(TOOL_NAME, request.flags, 'done', output, threadId, toolUseID),
|
|
46
|
-
);
|
|
47
|
-
return {
|
|
48
|
-
...pluginTextToolRunResult(resultDecision, output),
|
|
49
|
-
toolUse: pluginToolUseBlock(TOOL_NAME, request.flags, toolUseID),
|
|
50
|
-
};
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
function normalizeGrepInput(input = {}) {
|
|
54
|
-
const pattern = input.pattern ?? input.regex ?? input.query;
|
|
55
|
-
const searchPath = input.path ?? input.dir ?? input.cwd ?? '.';
|
|
56
|
-
return {
|
|
57
|
-
...input,
|
|
58
|
-
pattern: pattern ? String(pattern) : '',
|
|
59
|
-
path: searchPath ? String(searchPath) : '.',
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
function grepBuiltinFiles(pattern, searchPath = '.') {
|
|
64
|
-
const root = path.isAbsolute(searchPath) ? searchPath : path.resolve(process.cwd(), searchPath);
|
|
65
|
-
const files = walkFiles(root).sort();
|
|
66
|
-
const re = new RegExp(pattern);
|
|
67
|
-
const matches = [];
|
|
68
|
-
for (const filePath of files) {
|
|
69
|
-
let content = '';
|
|
70
|
-
try {
|
|
71
|
-
content = readFileSync(filePath, 'utf8');
|
|
72
|
-
} catch {
|
|
73
|
-
continue;
|
|
74
|
-
}
|
|
75
|
-
const lines = content.split(/\r?\n/);
|
|
76
|
-
for (let index = 0; index < lines.length; index += 1) {
|
|
77
|
-
if (!re.test(lines[index])) continue;
|
|
78
|
-
matches.push(`${relativeToolPath(filePath)}:${index + 1}:${lines[index]}`);
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
return matches.join('\n');
|
|
82
|
-
}
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
import { loadPlugins } from '../../plugins/discover.mjs';
|
|
2
|
-
import { parseToolUseArgs } from '../toolbox.mjs';
|
|
3
|
-
import { splitShellWords } from '../../util/shell.mjs';
|
|
4
|
-
import { executePromptBashToolRequest } from './bash.mjs';
|
|
5
|
-
import { executePromptCreateFileToolRequest } from './create-file.mjs';
|
|
6
|
-
import { executePromptEditFileToolRequest } from './edit-file.mjs';
|
|
7
|
-
import { executePromptFinderToolRequest } from './finder.mjs';
|
|
8
|
-
import { executePromptGlobToolRequest } from './glob.mjs';
|
|
9
|
-
import { executePromptGrepToolRequest } from './grep.mjs';
|
|
10
|
-
import { executePromptLibrarianToolRequest } from './librarian.mjs';
|
|
11
|
-
import { executePromptLookAtToolRequest } from './look-at.mjs';
|
|
12
|
-
import { executePromptMcpToolRequest } from './mcp.mjs';
|
|
13
|
-
import { executePromptMermaidToolRequest } from './mermaid.mjs';
|
|
14
|
-
import { executePromptOracleToolRequest } from './oracle.mjs';
|
|
15
|
-
import { executePromptPainterToolRequest } from './painter.mjs';
|
|
16
|
-
import { executePromptPluginToolRequest } from './plugin-tool.mjs';
|
|
17
|
-
import { executePromptReadMcpResourceToolRequest } from './read-mcp-resource.mjs';
|
|
18
|
-
import { executePromptReadToolRequest } from './read.mjs';
|
|
19
|
-
import { executePromptReadWebPageToolRequest } from './read-web-page.mjs';
|
|
20
|
-
import { executePromptTaskToolRequest } from './task.mjs';
|
|
21
|
-
import { executePromptToolboxToolRequest } from './toolbox-tool.mjs';
|
|
22
|
-
import { executePromptUndoEditToolRequest } from './undo-edit.mjs';
|
|
23
|
-
import { executePromptWebSearchToolRequest } from './web-search.mjs';
|
|
24
|
-
|
|
25
|
-
const BUILTIN_DISPATCH = new Map([
|
|
26
|
-
['Bash', (request, stdin, parsed, plugins, threadId) =>
|
|
27
|
-
executePromptBashToolRequest(request, stdin, parsed, plugins, threadId)],
|
|
28
|
-
['Read', (request, _stdin, parsed, plugins, threadId) =>
|
|
29
|
-
executePromptReadToolRequest(request, parsed, plugins, threadId)],
|
|
30
|
-
['Grep', (request, _stdin, parsed, plugins, threadId) =>
|
|
31
|
-
executePromptGrepToolRequest(request, parsed, plugins, threadId)],
|
|
32
|
-
['glob', (request, _stdin, parsed, plugins, threadId) =>
|
|
33
|
-
executePromptGlobToolRequest(request, parsed, plugins, threadId)],
|
|
34
|
-
['create_file', (request, _stdin, parsed, plugins, threadId) =>
|
|
35
|
-
executePromptCreateFileToolRequest(request, parsed, plugins, threadId)],
|
|
36
|
-
['edit_file', (request, _stdin, parsed, plugins, threadId) =>
|
|
37
|
-
executePromptEditFileToolRequest(request, parsed, plugins, threadId)],
|
|
38
|
-
['undo_edit', (request, _stdin, parsed, plugins, threadId) =>
|
|
39
|
-
executePromptUndoEditToolRequest(request, parsed, plugins, threadId)],
|
|
40
|
-
['Task', (request, _stdin, parsed, plugins, threadId) =>
|
|
41
|
-
executePromptTaskToolRequest(request, parsed, plugins, threadId)],
|
|
42
|
-
['oracle', (request, _stdin, parsed, plugins, threadId) =>
|
|
43
|
-
executePromptOracleToolRequest(request, parsed, plugins, threadId)],
|
|
44
|
-
['librarian', (request, _stdin, parsed, plugins, threadId) =>
|
|
45
|
-
executePromptLibrarianToolRequest(request, parsed, plugins, threadId)],
|
|
46
|
-
['painter', (request, _stdin, parsed, plugins, threadId) =>
|
|
47
|
-
executePromptPainterToolRequest(request, parsed, plugins, threadId)],
|
|
48
|
-
['mermaid', (request, _stdin, parsed, plugins, threadId) =>
|
|
49
|
-
executePromptMermaidToolRequest(request, parsed, plugins, threadId)],
|
|
50
|
-
['look_at', (request, _stdin, parsed, plugins, threadId) =>
|
|
51
|
-
executePromptLookAtToolRequest(request, parsed, plugins, threadId)],
|
|
52
|
-
['web_search', (request, _stdin, parsed, plugins, threadId) =>
|
|
53
|
-
executePromptWebSearchToolRequest(request, parsed, plugins, threadId)],
|
|
54
|
-
['read_web_page', (request, _stdin, parsed, plugins, threadId) =>
|
|
55
|
-
executePromptReadWebPageToolRequest(request, parsed, plugins, threadId)],
|
|
56
|
-
['find_thread', (request, _stdin, parsed, plugins, threadId) =>
|
|
57
|
-
executePromptFinderToolRequest(request, parsed, plugins, threadId, 'find_thread')],
|
|
58
|
-
['finder', (request, _stdin, parsed, plugins, threadId) =>
|
|
59
|
-
executePromptFinderToolRequest(request, parsed, plugins, threadId)],
|
|
60
|
-
['read_mcp_resource', (request, _stdin, parsed, plugins, threadId) =>
|
|
61
|
-
executePromptReadMcpResourceToolRequest(request, parsed, plugins, threadId)],
|
|
62
|
-
]);
|
|
63
|
-
|
|
64
|
-
export async function executePromptToolRequest(prompt, stdin, threadId, parsed = {}, plugins) {
|
|
65
|
-
const request = parsePromptToolRequest(prompt);
|
|
66
|
-
if (!request) return undefined;
|
|
67
|
-
const resolvedPlugins = plugins ?? await loadPlugins(process.cwd());
|
|
68
|
-
if (request.toolName.startsWith('mcp__')) {
|
|
69
|
-
return executePromptMcpToolRequest(request, parsed, threadId, resolvedPlugins);
|
|
70
|
-
}
|
|
71
|
-
const builtin = BUILTIN_DISPATCH.get(request.toolName);
|
|
72
|
-
if (builtin) return builtin(request, stdin, parsed, resolvedPlugins, threadId);
|
|
73
|
-
const pluginTool = resolvedPlugins.tools.find((entry) => entry.name === request.toolName);
|
|
74
|
-
if (pluginTool) return executePromptPluginToolRequest(pluginTool, request, parsed, resolvedPlugins, threadId);
|
|
75
|
-
return executePromptToolboxToolRequest(request, stdin, parsed, resolvedPlugins, threadId);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
export function parsePromptToolRequest(prompt) {
|
|
79
|
-
const match = prompt.match(/\b(?:use|run|call)\s+([A-Za-z0-9_-]+(?:__[A-Za-z0-9_-]+)?)([^\r\n]*)/i);
|
|
80
|
-
if (!match) return undefined;
|
|
81
|
-
const useArgs = parseToolUseArgs([match[1], ...splitShellWords(match[2] ?? '')]);
|
|
82
|
-
return { toolName: useArgs.toolName, flags: useArgs.flags };
|
|
83
|
-
}
|
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
import { readFileSync } from 'node:fs';
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
import { resolvePermissionDecision } from '../../commands/permissions.mjs';
|
|
4
|
-
import { runPluginEventHandlers } from '../../plugins/discover.mjs';
|
|
5
|
-
import { walkFiles } from '../../util/glob.mjs';
|
|
6
|
-
import { isToolDisabled } from '../toolbox.mjs';
|
|
7
|
-
import {
|
|
8
|
-
applyToolCallDecision,
|
|
9
|
-
createToolUseID,
|
|
10
|
-
permissionDeniedOutput,
|
|
11
|
-
pluginTextToolRunResult,
|
|
12
|
-
pluginToolCallEvent,
|
|
13
|
-
pluginToolResultEvent,
|
|
14
|
-
pluginToolUseBlock,
|
|
15
|
-
toolCallDecisionToolRun,
|
|
16
|
-
validateToolCallDecision,
|
|
17
|
-
} from './runtime.mjs';
|
|
18
|
-
|
|
19
|
-
export const TOOL_NAME = 'librarian';
|
|
20
|
-
|
|
21
|
-
export async function executePromptLibrarianToolRequest(request, parsed = {}, plugins = { handlers: {} }, threadId = '') {
|
|
22
|
-
if (isToolDisabled(TOOL_NAME, 'built-in', parsed)) return { output: `Tool disabled: ${TOOL_NAME}` };
|
|
23
|
-
request = { ...request, flags: normalizeLibrarianInput(request.flags) };
|
|
24
|
-
if (!request.flags.query) return { output: 'librarian requires --query' };
|
|
25
|
-
const toolUseID = createToolUseID();
|
|
26
|
-
const callDecision = await runPluginEventHandlers(
|
|
27
|
-
plugins.handlers['tool.call'],
|
|
28
|
-
pluginToolCallEvent(TOOL_NAME, request.flags, threadId, toolUseID),
|
|
29
|
-
validateToolCallDecision,
|
|
30
|
-
);
|
|
31
|
-
const callResult = applyToolCallDecision(TOOL_NAME, request, callDecision);
|
|
32
|
-
if (callResult.output) return toolCallDecisionToolRun(TOOL_NAME, request.flags, toolUseID, callResult);
|
|
33
|
-
request = { ...callResult.request, flags: normalizeLibrarianInput(callResult.request.flags) };
|
|
34
|
-
const decision = resolvePermissionDecision(TOOL_NAME, request.flags, parsed, { threadId });
|
|
35
|
-
if (!parsed.dangerouslyAllowAll && decision.action !== 'allow') {
|
|
36
|
-
return {
|
|
37
|
-
output: permissionDeniedOutput(TOOL_NAME, decision),
|
|
38
|
-
permissionDenials: [{ tool: TOOL_NAME, action: decision.action, reason: 'permission' }],
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
const output = searchWorkspaceForLibrarian(request.flags);
|
|
42
|
-
const resultDecision = await runPluginEventHandlers(
|
|
43
|
-
plugins.handlers['tool.result'],
|
|
44
|
-
pluginToolResultEvent(TOOL_NAME, request.flags, 'done', output, threadId, toolUseID),
|
|
45
|
-
);
|
|
46
|
-
return {
|
|
47
|
-
...pluginTextToolRunResult(resultDecision, output),
|
|
48
|
-
toolUse: pluginToolUseBlock(TOOL_NAME, request.flags, toolUseID),
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
function normalizeLibrarianInput(input = {}) {
|
|
53
|
-
const query = input.query ?? input.q ?? input.prompt ?? input.question ?? input.topic;
|
|
54
|
-
const limit = Number.parseInt(String(input.limit ?? 5), 10);
|
|
55
|
-
return {
|
|
56
|
-
...input,
|
|
57
|
-
query: query ? String(query) : '',
|
|
58
|
-
limit: Number.isFinite(limit) && limit > 0 ? Math.min(limit, 20) : 5,
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
function searchWorkspaceForLibrarian(input) {
|
|
63
|
-
const matches = findWorkspaceTextMatches(input.query, input.limit);
|
|
64
|
-
return [
|
|
65
|
-
`Librarian search: ${input.query}`,
|
|
66
|
-
'scope: current workspace',
|
|
67
|
-
'matches:',
|
|
68
|
-
...(matches.length ? matches.map(formatLibrarianMatch) : ['- no local matches found']),
|
|
69
|
-
].join('\n');
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
function findWorkspaceTextMatches(query, limit) {
|
|
73
|
-
const needle = query.toLowerCase();
|
|
74
|
-
const root = process.cwd();
|
|
75
|
-
return walkFiles(root)
|
|
76
|
-
.map((filePath) => path.relative(root, filePath))
|
|
77
|
-
.filter((relativePath) => !relativePath.split(path.sep).some((part) => part === '.git' || part === 'node_modules'))
|
|
78
|
-
.sort()
|
|
79
|
-
.flatMap((relativePath) => {
|
|
80
|
-
let text;
|
|
81
|
-
try {
|
|
82
|
-
text = readFileSync(path.join(root, relativePath), 'utf8');
|
|
83
|
-
} catch {
|
|
84
|
-
return [];
|
|
85
|
-
}
|
|
86
|
-
return text.split(/\r?\n/).flatMap((line, index) => (
|
|
87
|
-
line.toLowerCase().includes(needle)
|
|
88
|
-
? [{ path: relativePath, line: index + 1, text: line.trim() }]
|
|
89
|
-
: []
|
|
90
|
-
));
|
|
91
|
-
})
|
|
92
|
-
.slice(0, limit);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
function formatLibrarianMatch(match) {
|
|
96
|
-
return `- ${match.path}:${match.line}: ${match.text}`;
|
|
97
|
-
}
|
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
import { readFileSync } from 'node:fs';
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
import { fileURLToPath } from 'node:url';
|
|
4
|
-
import { resolvePermissionDecision } from '../../commands/permissions.mjs';
|
|
5
|
-
import { runPluginEventHandlers } from '../../plugins/discover.mjs';
|
|
6
|
-
import { detectImageMediaType } from '../../util/media.mjs';
|
|
7
|
-
import { isToolDisabled } from '../toolbox.mjs';
|
|
8
|
-
import {
|
|
9
|
-
applyToolCallDecision,
|
|
10
|
-
createToolUseID,
|
|
11
|
-
permissionDeniedOutput,
|
|
12
|
-
pluginTextToolRunResult,
|
|
13
|
-
pluginToolCallEvent,
|
|
14
|
-
pluginToolResultEvent,
|
|
15
|
-
pluginToolUseBlock,
|
|
16
|
-
toolCallDecisionToolRun,
|
|
17
|
-
validateToolCallDecision,
|
|
18
|
-
} from './runtime.mjs';
|
|
19
|
-
|
|
20
|
-
export const TOOL_NAME = 'look_at';
|
|
21
|
-
|
|
22
|
-
export async function executePromptLookAtToolRequest(request, parsed = {}, plugins = { handlers: {} }, threadId = '') {
|
|
23
|
-
if (isToolDisabled(TOOL_NAME, 'built-in', parsed)) return { output: `Tool disabled: ${TOOL_NAME}` };
|
|
24
|
-
request = { ...request, flags: normalizeLookAtInput(request.flags) };
|
|
25
|
-
if (!request.flags.path) return { output: 'look_at requires --path' };
|
|
26
|
-
const toolUseID = createToolUseID();
|
|
27
|
-
const callDecision = await runPluginEventHandlers(
|
|
28
|
-
plugins.handlers['tool.call'],
|
|
29
|
-
pluginToolCallEvent(TOOL_NAME, request.flags, threadId, toolUseID),
|
|
30
|
-
validateToolCallDecision,
|
|
31
|
-
);
|
|
32
|
-
const callResult = applyToolCallDecision(TOOL_NAME, request, callDecision);
|
|
33
|
-
if (callResult.output) return toolCallDecisionToolRun(TOOL_NAME, request.flags, toolUseID, callResult);
|
|
34
|
-
request = { ...callResult.request, flags: normalizeLookAtInput(callResult.request.flags) };
|
|
35
|
-
const decision = resolvePermissionDecision(TOOL_NAME, request.flags, parsed, { threadId });
|
|
36
|
-
if (!parsed.dangerouslyAllowAll && decision.action !== 'allow') {
|
|
37
|
-
return {
|
|
38
|
-
output: permissionDeniedOutput(TOOL_NAME, decision),
|
|
39
|
-
permissionDenials: [{ tool: TOOL_NAME, action: decision.action, reason: 'permission' }],
|
|
40
|
-
};
|
|
41
|
-
}
|
|
42
|
-
const output = inspectLookAtMedia(request.flags);
|
|
43
|
-
const resultDecision = await runPluginEventHandlers(
|
|
44
|
-
plugins.handlers['tool.result'],
|
|
45
|
-
pluginToolResultEvent(TOOL_NAME, request.flags, 'done', output, threadId, toolUseID),
|
|
46
|
-
);
|
|
47
|
-
return {
|
|
48
|
-
...pluginTextToolRunResult(resultDecision, output),
|
|
49
|
-
toolUse: pluginToolUseBlock(TOOL_NAME, request.flags, toolUseID),
|
|
50
|
-
};
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
function normalizeLookAtInput(input = {}) {
|
|
54
|
-
const source = input.path ?? input.file ?? input.image ?? input.pdf ?? input.url;
|
|
55
|
-
const goal = input.goal ?? input.prompt ?? input.instructions ?? input.question ?? '';
|
|
56
|
-
return {
|
|
57
|
-
...input,
|
|
58
|
-
path: source ? String(source) : '',
|
|
59
|
-
goal: String(goal),
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
function inspectLookAtMedia(input) {
|
|
64
|
-
try {
|
|
65
|
-
const resolved = resolveLookAtPath(input.path);
|
|
66
|
-
const raw = readFileSync(resolved);
|
|
67
|
-
return formatLookAtMediaResult(input.path, raw, input.goal);
|
|
68
|
-
} catch (error) {
|
|
69
|
-
return `Unable to look at ${input.path}: ${error.message}`;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
function resolveLookAtPath(source) {
|
|
74
|
-
if (source.startsWith('file://')) return fileURLToPath(source);
|
|
75
|
-
return path.resolve(process.cwd(), source);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
function formatLookAtMediaResult(source, raw, goal) {
|
|
79
|
-
return [
|
|
80
|
-
`Looked at: ${source}`,
|
|
81
|
-
`media_type: ${detectLookAtMediaType(raw)}`,
|
|
82
|
-
`bytes: ${raw.length}`,
|
|
83
|
-
`goal: ${goal || '(none)'}`,
|
|
84
|
-
].join('\n');
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
function detectLookAtMediaType(raw) {
|
|
88
|
-
const imageType = detectImageMediaType(raw);
|
|
89
|
-
if (imageType) return imageType;
|
|
90
|
-
if (raw.subarray(0, 5).toString('ascii') === '%PDF-') return 'application/pdf';
|
|
91
|
-
return 'application/octet-stream';
|
|
92
|
-
}
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import { resolvePermissionDecision } from '../../commands/permissions.mjs';
|
|
2
|
-
import { listConfiguredMcpServers } from '../../mcp/discover.mjs';
|
|
3
|
-
import { callMcpTool, isMcpToolIncluded, parseMcpToolName } from '../../mcp/probe.mjs';
|
|
4
|
-
import { runPluginEventHandlers } from '../../plugins/discover.mjs';
|
|
5
|
-
import { isToolDisabled } from '../toolbox.mjs';
|
|
6
|
-
import {
|
|
7
|
-
applyToolCallDecision,
|
|
8
|
-
createToolUseID,
|
|
9
|
-
permissionDeniedOutput,
|
|
10
|
-
pluginTextToolRunResult,
|
|
11
|
-
pluginToolCallEvent,
|
|
12
|
-
pluginToolResultEvent,
|
|
13
|
-
pluginToolUseBlock,
|
|
14
|
-
toolCallDecisionToolRun,
|
|
15
|
-
validateToolCallDecision,
|
|
16
|
-
} from './runtime.mjs';
|
|
17
|
-
|
|
18
|
-
export async function executePromptMcpToolRequest(request, parsed = {}, threadId = '', plugins = { handlers: {} }) {
|
|
19
|
-
const parsedName = parseMcpToolName(request.toolName);
|
|
20
|
-
if (!parsedName) return { output: `Unknown tool: ${request.toolName}` };
|
|
21
|
-
if (isToolDisabled(request.toolName, 'local-mcp', parsed)) return { output: `Tool disabled: ${request.toolName}` };
|
|
22
|
-
const toolUseID = createToolUseID();
|
|
23
|
-
const callDecision = await runPluginEventHandlers(
|
|
24
|
-
plugins.handlers['tool.call'],
|
|
25
|
-
pluginToolCallEvent(request.toolName, request.flags, threadId, toolUseID),
|
|
26
|
-
validateToolCallDecision,
|
|
27
|
-
);
|
|
28
|
-
const callResult = applyToolCallDecision(request.toolName, request, callDecision);
|
|
29
|
-
if (callResult.output) return toolCallDecisionToolRun(request.toolName, request.flags, toolUseID, callResult);
|
|
30
|
-
request = callResult.request;
|
|
31
|
-
const decision = resolvePermissionDecision(request.toolName, request.flags, parsed, { threadId });
|
|
32
|
-
if (!parsed.dangerouslyAllowAll && decision.action !== 'allow') {
|
|
33
|
-
return {
|
|
34
|
-
output: permissionDeniedOutput(request.toolName, decision),
|
|
35
|
-
permissionDenials: [{ tool: request.toolName, action: decision.action, reason: 'permission' }],
|
|
36
|
-
};
|
|
37
|
-
}
|
|
38
|
-
const server = listConfiguredMcpServers(parsed)
|
|
39
|
-
.find((entry) => entry.name === parsedName.serverName && entry.status === 'approved');
|
|
40
|
-
if (!server) return { output: `Unknown MCP server: ${parsedName.serverName}` };
|
|
41
|
-
if (!isMcpToolIncluded(server.config, parsedName.toolName)) return { output: `Tool not available: ${request.toolName}` };
|
|
42
|
-
const output = await callMcpTool(server.config, parsedName.toolName, request.flags, server.name);
|
|
43
|
-
const resultDecision = await runPluginEventHandlers(
|
|
44
|
-
plugins.handlers['tool.result'],
|
|
45
|
-
pluginToolResultEvent(request.toolName, request.flags, 'done', output, threadId, toolUseID),
|
|
46
|
-
);
|
|
47
|
-
return {
|
|
48
|
-
...pluginTextToolRunResult(resultDecision, output),
|
|
49
|
-
toolUse: pluginToolUseBlock(request.toolName, request.flags, toolUseID),
|
|
50
|
-
};
|
|
51
|
-
}
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import { resolvePermissionDecision } from '../../commands/permissions.mjs';
|
|
2
|
-
import { runPluginEventHandlers } from '../../plugins/discover.mjs';
|
|
3
|
-
import { isToolDisabled } from '../toolbox.mjs';
|
|
4
|
-
import {
|
|
5
|
-
applyToolCallDecision,
|
|
6
|
-
createToolUseID,
|
|
7
|
-
permissionDeniedOutput,
|
|
8
|
-
pluginTextToolRunResult,
|
|
9
|
-
pluginToolCallEvent,
|
|
10
|
-
pluginToolResultEvent,
|
|
11
|
-
pluginToolUseBlock,
|
|
12
|
-
toolCallDecisionToolRun,
|
|
13
|
-
validateToolCallDecision,
|
|
14
|
-
} from './runtime.mjs';
|
|
15
|
-
|
|
16
|
-
export const TOOL_NAME = 'mermaid';
|
|
17
|
-
|
|
18
|
-
export async function executePromptMermaidToolRequest(request, parsed = {}, plugins = { handlers: {} }, threadId = '') {
|
|
19
|
-
if (isToolDisabled(TOOL_NAME, 'built-in', parsed)) return { output: `Tool disabled: ${TOOL_NAME}` };
|
|
20
|
-
request = { ...request, flags: normalizeMermaidInput(request.flags) };
|
|
21
|
-
if (!request.flags.code) return { output: 'mermaid requires --code' };
|
|
22
|
-
const toolUseID = createToolUseID();
|
|
23
|
-
const callDecision = await runPluginEventHandlers(
|
|
24
|
-
plugins.handlers['tool.call'],
|
|
25
|
-
pluginToolCallEvent(TOOL_NAME, request.flags, threadId, toolUseID),
|
|
26
|
-
validateToolCallDecision,
|
|
27
|
-
);
|
|
28
|
-
const callResult = applyToolCallDecision(TOOL_NAME, request, callDecision);
|
|
29
|
-
if (callResult.output) return toolCallDecisionToolRun(TOOL_NAME, request.flags, toolUseID, callResult);
|
|
30
|
-
request = { ...callResult.request, flags: normalizeMermaidInput(callResult.request.flags) };
|
|
31
|
-
const decision = resolvePermissionDecision(TOOL_NAME, request.flags, parsed, { threadId });
|
|
32
|
-
if (!parsed.dangerouslyAllowAll && decision.action !== 'allow') {
|
|
33
|
-
return {
|
|
34
|
-
output: permissionDeniedOutput(TOOL_NAME, decision),
|
|
35
|
-
permissionDenials: [{ tool: TOOL_NAME, action: decision.action, reason: 'permission' }],
|
|
36
|
-
};
|
|
37
|
-
}
|
|
38
|
-
const output = mermaidOutput(request.flags.code);
|
|
39
|
-
const resultDecision = await runPluginEventHandlers(
|
|
40
|
-
plugins.handlers['tool.result'],
|
|
41
|
-
pluginToolResultEvent(TOOL_NAME, request.flags, 'done', output, threadId, toolUseID),
|
|
42
|
-
);
|
|
43
|
-
return {
|
|
44
|
-
...pluginTextToolRunResult(resultDecision, output),
|
|
45
|
-
toolUse: pluginToolUseBlock(TOOL_NAME, request.flags, toolUseID),
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
function normalizeMermaidInput(input = {}) {
|
|
50
|
-
const code = input.code ?? input.diagram ?? input.mermaid ?? input.source;
|
|
51
|
-
return {
|
|
52
|
-
...input,
|
|
53
|
-
code: code ? String(code) : '',
|
|
54
|
-
};
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
function mermaidOutput(code) {
|
|
58
|
-
return `\`\`\`mermaid\n${String(code).trim()}\n\`\`\``;
|
|
59
|
-
}
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import { fixtureAgentResponse } from '../../agent/fixture.mjs';
|
|
2
|
-
import { resolvePermissionDecision } from '../../commands/permissions.mjs';
|
|
3
|
-
import { runPluginEventHandlers } from '../../plugins/discover.mjs';
|
|
4
|
-
import { isToolDisabled } from '../toolbox.mjs';
|
|
5
|
-
import {
|
|
6
|
-
applyToolCallDecision,
|
|
7
|
-
createToolUseID,
|
|
8
|
-
permissionDeniedOutput,
|
|
9
|
-
pluginTextToolRunResult,
|
|
10
|
-
pluginToolCallEvent,
|
|
11
|
-
pluginToolResultEvent,
|
|
12
|
-
pluginToolUseBlock,
|
|
13
|
-
toolCallDecisionToolRun,
|
|
14
|
-
validateToolCallDecision,
|
|
15
|
-
} from './runtime.mjs';
|
|
16
|
-
|
|
17
|
-
export const TOOL_NAME = 'oracle';
|
|
18
|
-
|
|
19
|
-
export async function executePromptOracleToolRequest(request, parsed = {}, plugins = { handlers: {} }, threadId = '') {
|
|
20
|
-
if (isToolDisabled(TOOL_NAME, 'built-in', parsed)) return { output: `Tool disabled: ${TOOL_NAME}` };
|
|
21
|
-
request = { ...request, flags: normalizeOracleInput(request.flags) };
|
|
22
|
-
if (!request.flags.prompt) return { output: 'oracle requires --prompt' };
|
|
23
|
-
const toolUseID = createToolUseID();
|
|
24
|
-
const callDecision = await runPluginEventHandlers(
|
|
25
|
-
plugins.handlers['tool.call'],
|
|
26
|
-
pluginToolCallEvent(TOOL_NAME, request.flags, threadId, toolUseID),
|
|
27
|
-
validateToolCallDecision,
|
|
28
|
-
);
|
|
29
|
-
const callResult = applyToolCallDecision(TOOL_NAME, request, callDecision);
|
|
30
|
-
if (callResult.output) return toolCallDecisionToolRun(TOOL_NAME, request.flags, toolUseID, callResult);
|
|
31
|
-
request = { ...callResult.request, flags: normalizeOracleInput(callResult.request.flags) };
|
|
32
|
-
const decision = resolvePermissionDecision(TOOL_NAME, request.flags, parsed, { threadId });
|
|
33
|
-
if (!parsed.dangerouslyAllowAll && decision.action !== 'allow') {
|
|
34
|
-
return {
|
|
35
|
-
output: permissionDeniedOutput(TOOL_NAME, decision),
|
|
36
|
-
permissionDenials: [{ tool: TOOL_NAME, action: decision.action, reason: 'permission' }],
|
|
37
|
-
};
|
|
38
|
-
}
|
|
39
|
-
const output = `Oracle: ${fixtureAgentResponse(request.flags.prompt, '')}`;
|
|
40
|
-
const resultDecision = await runPluginEventHandlers(
|
|
41
|
-
plugins.handlers['tool.result'],
|
|
42
|
-
pluginToolResultEvent(TOOL_NAME, request.flags, 'done', output, threadId, toolUseID),
|
|
43
|
-
);
|
|
44
|
-
return {
|
|
45
|
-
...pluginTextToolRunResult(resultDecision, output),
|
|
46
|
-
toolUse: pluginToolUseBlock(TOOL_NAME, request.flags, toolUseID),
|
|
47
|
-
};
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
function normalizeOracleInput(input = {}) {
|
|
51
|
-
const prompt = input.prompt ?? input.question ?? input.query ?? input.message;
|
|
52
|
-
return {
|
|
53
|
-
...input,
|
|
54
|
-
prompt: prompt ? String(prompt) : '',
|
|
55
|
-
};
|
|
56
|
-
}
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
import { mkdirSync, writeFileSync } from 'node:fs';
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
import { resolvePermissionDecision } from '../../commands/permissions.mjs';
|
|
4
|
-
import { runPluginEventHandlers } from '../../plugins/discover.mjs';
|
|
5
|
-
import { isToolDisabled } from '../toolbox.mjs';
|
|
6
|
-
import {
|
|
7
|
-
applyToolCallDecision,
|
|
8
|
-
createToolUseID,
|
|
9
|
-
permissionDeniedOutput,
|
|
10
|
-
pluginTextToolRunResult,
|
|
11
|
-
pluginToolCallEvent,
|
|
12
|
-
pluginToolResultEvent,
|
|
13
|
-
pluginToolUseBlock,
|
|
14
|
-
toolCallDecisionToolRun,
|
|
15
|
-
validateToolCallDecision,
|
|
16
|
-
} from './runtime.mjs';
|
|
17
|
-
|
|
18
|
-
export const TOOL_NAME = 'painter';
|
|
19
|
-
|
|
20
|
-
const PAINTER_PLACEHOLDER_PNG = Buffer.from(
|
|
21
|
-
'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M/wHwAFeAKU5XgS2wAAAABJRU5ErkJggg==',
|
|
22
|
-
'base64',
|
|
23
|
-
);
|
|
24
|
-
|
|
25
|
-
export async function executePromptPainterToolRequest(request, parsed = {}, plugins = { handlers: {} }, threadId = '') {
|
|
26
|
-
if (isToolDisabled(TOOL_NAME, 'built-in', parsed)) return { output: `Tool disabled: ${TOOL_NAME}` };
|
|
27
|
-
request = { ...request, flags: normalizePainterInput(request.flags) };
|
|
28
|
-
if (!request.flags.prompt) return { output: 'painter requires --prompt' };
|
|
29
|
-
const toolUseID = createToolUseID();
|
|
30
|
-
const callDecision = await runPluginEventHandlers(
|
|
31
|
-
plugins.handlers['tool.call'],
|
|
32
|
-
pluginToolCallEvent(TOOL_NAME, request.flags, threadId, toolUseID),
|
|
33
|
-
validateToolCallDecision,
|
|
34
|
-
);
|
|
35
|
-
const callResult = applyToolCallDecision(TOOL_NAME, request, callDecision);
|
|
36
|
-
if (callResult.output) return toolCallDecisionToolRun(TOOL_NAME, request.flags, toolUseID, callResult);
|
|
37
|
-
request = { ...callResult.request, flags: normalizePainterInput(callResult.request.flags) };
|
|
38
|
-
const decision = resolvePermissionDecision(TOOL_NAME, request.flags, parsed, { threadId });
|
|
39
|
-
if (!parsed.dangerouslyAllowAll && decision.action !== 'allow') {
|
|
40
|
-
return {
|
|
41
|
-
output: permissionDeniedOutput(TOOL_NAME, decision),
|
|
42
|
-
permissionDenials: [{ tool: TOOL_NAME, action: decision.action, reason: 'permission' }],
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
|
-
const output = writePainterArtifact(request.flags);
|
|
46
|
-
const resultDecision = await runPluginEventHandlers(
|
|
47
|
-
plugins.handlers['tool.result'],
|
|
48
|
-
pluginToolResultEvent(TOOL_NAME, request.flags, 'done', output, threadId, toolUseID),
|
|
49
|
-
);
|
|
50
|
-
return {
|
|
51
|
-
...pluginTextToolRunResult(resultDecision, output),
|
|
52
|
-
toolUse: pluginToolUseBlock(TOOL_NAME, request.flags, toolUseID),
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
function normalizePainterInput(input = {}) {
|
|
57
|
-
const prompt = input.prompt ?? input.description ?? input.text ?? '';
|
|
58
|
-
const output = input.output ?? input.path ?? input.file ?? 'coven-code-painter-output.png';
|
|
59
|
-
const references = [input.reference, input.references, input.image, input.images]
|
|
60
|
-
.flat()
|
|
61
|
-
.filter(Boolean)
|
|
62
|
-
.map(String);
|
|
63
|
-
return {
|
|
64
|
-
...input,
|
|
65
|
-
prompt: String(prompt),
|
|
66
|
-
output: String(output),
|
|
67
|
-
references,
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
function writePainterArtifact(input) {
|
|
72
|
-
const outputPath = path.resolve(process.cwd(), input.output);
|
|
73
|
-
mkdirSync(path.dirname(outputPath), { recursive: true });
|
|
74
|
-
writeFileSync(outputPath, PAINTER_PLACEHOLDER_PNG);
|
|
75
|
-
return [
|
|
76
|
-
`Generated image: ${input.output}`,
|
|
77
|
-
'media_type: image/png',
|
|
78
|
-
`prompt: ${input.prompt}`,
|
|
79
|
-
...(input.references.length ? [`references: ${input.references.join(', ')}`] : []),
|
|
80
|
-
].join('\n');
|
|
81
|
-
}
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import { resolvePermissionDecision } from '../../commands/permissions.mjs';
|
|
2
|
-
import { createPluginToolContext, runPluginEventHandlers } from '../../plugins/discover.mjs';
|
|
3
|
-
import { isToolDisabled } from '../toolbox.mjs';
|
|
4
|
-
import {
|
|
5
|
-
applyToolCallDecision,
|
|
6
|
-
createToolUseID,
|
|
7
|
-
normalizePluginToolExecuteOutput,
|
|
8
|
-
normalizePluginToolOutput,
|
|
9
|
-
permissionDeniedOutput,
|
|
10
|
-
pluginToolCallEvent,
|
|
11
|
-
pluginToolResultDecisionExitCode,
|
|
12
|
-
pluginToolResultDecisionOutput,
|
|
13
|
-
pluginToolResultEvent,
|
|
14
|
-
pluginToolUseBlock,
|
|
15
|
-
toolCallDecisionToolRun,
|
|
16
|
-
validateToolCallDecision,
|
|
17
|
-
} from './runtime.mjs';
|
|
18
|
-
|
|
19
|
-
export async function executePromptPluginToolRequest(tool, request, parsed = {}, plugins = { handlers: {} }, threadId = '') {
|
|
20
|
-
if (isToolDisabled(tool.name, 'plugin', parsed)) return { output: `Tool disabled: ${tool.name}` };
|
|
21
|
-
const toolUseID = createToolUseID();
|
|
22
|
-
const callDecision = await runPluginEventHandlers(
|
|
23
|
-
plugins.handlers['tool.call'],
|
|
24
|
-
pluginToolCallEvent(tool.name, request.flags, threadId, toolUseID),
|
|
25
|
-
validateToolCallDecision,
|
|
26
|
-
);
|
|
27
|
-
const callResult = applyToolCallDecision(tool.name, request, callDecision);
|
|
28
|
-
if (callResult.output) return toolCallDecisionToolRun(tool.name, request.flags, toolUseID, callResult);
|
|
29
|
-
request = callResult.request;
|
|
30
|
-
const decision = resolvePermissionDecision(tool.name, request.flags, parsed, { threadId });
|
|
31
|
-
if (!parsed.dangerouslyAllowAll && decision.action !== 'allow') {
|
|
32
|
-
return {
|
|
33
|
-
output: permissionDeniedOutput(tool.name, decision),
|
|
34
|
-
permissionDenials: [{ tool: tool.name, action: decision.action, reason: 'permission' }],
|
|
35
|
-
};
|
|
36
|
-
}
|
|
37
|
-
const output = typeof tool.execute === 'function' ? await tool.execute(request.flags, createPluginToolContext()) : undefined;
|
|
38
|
-
const normalizedOutput = normalizePluginToolExecuteOutput(output);
|
|
39
|
-
const resultDecision = await runPluginEventHandlers(
|
|
40
|
-
plugins.handlers['tool.result'],
|
|
41
|
-
pluginToolResultEvent(tool.name, request.flags, 'done', normalizedOutput.raw, threadId, toolUseID),
|
|
42
|
-
);
|
|
43
|
-
const finalOutput = normalizePluginToolOutput(
|
|
44
|
-
pluginToolResultDecisionOutput(resultDecision, normalizedOutput.raw),
|
|
45
|
-
);
|
|
46
|
-
const exitCode = pluginToolResultDecisionExitCode(resultDecision);
|
|
47
|
-
return {
|
|
48
|
-
output: finalOutput.text,
|
|
49
|
-
toolResultOutput: finalOutput.raw,
|
|
50
|
-
exitCode,
|
|
51
|
-
toolUse: pluginToolUseBlock(tool.name, request.flags, toolUseID),
|
|
52
|
-
};
|
|
53
|
-
}
|