@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,4 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
+
import { dirname } from "path";
|
|
2
3
|
import { FallbackToolUseRejectedMessage } from "../../components/FallbackToolUseRejectedMessage.js";
|
|
3
4
|
import * as React from "react";
|
|
4
5
|
import { createUserMessage } from "../../utils/messages.js";
|
|
@@ -6,12 +7,39 @@ import { getCommands } from "../../commands.js";
|
|
|
6
7
|
import {
|
|
7
8
|
loadCustomCommands
|
|
8
9
|
} from "../../services/customCommands.js";
|
|
10
|
+
import {
|
|
11
|
+
getAllSkillEntries,
|
|
12
|
+
getSkill,
|
|
13
|
+
loadSkillContent
|
|
14
|
+
} from "../../utils/skillLoader.js";
|
|
15
|
+
import { substituteVariables } from "../../utils/stringSubstitution.js";
|
|
16
|
+
import { getCwd } from "../../utils/state.js";
|
|
17
|
+
import { getHookManager } from "../../utils/hookManager.js";
|
|
18
|
+
import { emitReminderEvent } from "../../services/systemReminder.js";
|
|
9
19
|
import { TOOL_NAME_FOR_PROMPT } from "./prompt.js";
|
|
10
20
|
import { Box, Text } from "ink";
|
|
11
21
|
const inputSchema = z.strictObject({
|
|
12
22
|
skill: z.string().describe('The skill name. E.g., "commit", "review-pr", or "pdf"'),
|
|
13
23
|
args: z.string().optional().describe("Optional arguments for the skill")
|
|
14
24
|
});
|
|
25
|
+
function buildSkillHooks(skill) {
|
|
26
|
+
if (!skill.config.hooks?.length) return [];
|
|
27
|
+
return skill.config.hooks.map((h, i) => ({
|
|
28
|
+
name: `skill:${skill.name}:${h.event}:${i}`,
|
|
29
|
+
filePath: skill.filePath,
|
|
30
|
+
config: {
|
|
31
|
+
event: h.event,
|
|
32
|
+
matcher: h.matcher,
|
|
33
|
+
type: h.type || "command",
|
|
34
|
+
command: h.command,
|
|
35
|
+
prompt: h.prompt,
|
|
36
|
+
timeout: h.timeout
|
|
37
|
+
},
|
|
38
|
+
pluginName: `skill:${skill.name}`,
|
|
39
|
+
event: h.event,
|
|
40
|
+
matcher: h.matcher
|
|
41
|
+
}));
|
|
42
|
+
}
|
|
15
43
|
function normalizeCommandModelName(model) {
|
|
16
44
|
if (typeof model !== "string") return void 0;
|
|
17
45
|
const trimmed = model.trim();
|
|
@@ -25,6 +53,60 @@ function getCharBudget() {
|
|
|
25
53
|
const raw = Number(process.env.SLASH_COMMAND_TOOL_CHAR_BUDGET);
|
|
26
54
|
return Number.isFinite(raw) && raw > 0 ? raw : 15e3;
|
|
27
55
|
}
|
|
56
|
+
function formatCommandLine(cmd) {
|
|
57
|
+
const name = `/${cmd.name}`;
|
|
58
|
+
const args = cmd.argumentHint ? ` ${cmd.argumentHint}` : "";
|
|
59
|
+
const whenToUse = cmd.whenToUse ? `- ${cmd.whenToUse}` : "";
|
|
60
|
+
return `- ${name}${args}: ${cmd.description} ${whenToUse}`.trim();
|
|
61
|
+
}
|
|
62
|
+
function formatSkillLine(skill, key) {
|
|
63
|
+
const name = `/${key}`;
|
|
64
|
+
const args = skill.config.argumentHint ? ` ${skill.config.argumentHint}` : "";
|
|
65
|
+
return `- ${name}${args}: ${skill.config.description}`.trim();
|
|
66
|
+
}
|
|
67
|
+
async function convertSkillToCommand(skill) {
|
|
68
|
+
const content = await loadSkillContent(skill);
|
|
69
|
+
const baseDir = dirname(skill.filePath);
|
|
70
|
+
return {
|
|
71
|
+
type: "prompt",
|
|
72
|
+
name: skill.name,
|
|
73
|
+
description: skill.config.description,
|
|
74
|
+
isEnabled: true,
|
|
75
|
+
isHidden: false,
|
|
76
|
+
aliases: [],
|
|
77
|
+
progressMessage: `Running ${skill.name}...`,
|
|
78
|
+
scope: skill.source === "user" ? "user" : "project",
|
|
79
|
+
allowedTools: skill.config.allowedTools,
|
|
80
|
+
model: skill.config.model,
|
|
81
|
+
disableModelInvocation: skill.config.disableModelInvocation,
|
|
82
|
+
argumentHint: skill.config.argumentHint,
|
|
83
|
+
userFacingName: () => skill.name,
|
|
84
|
+
async getPromptForCommand(args) {
|
|
85
|
+
let prompt = content;
|
|
86
|
+
prompt = prompt.replace(/\{baseDir\}/g, baseDir);
|
|
87
|
+
prompt = await substituteVariables(prompt, args || "", {
|
|
88
|
+
cwd: getCwd(),
|
|
89
|
+
env: { BASE_DIR: baseDir },
|
|
90
|
+
allowDynamicCommands: true
|
|
91
|
+
});
|
|
92
|
+
if (args.trim() && !content.includes("$ARGUMENTS") && !content.includes("$0")) {
|
|
93
|
+
prompt += `
|
|
94
|
+
|
|
95
|
+
Additional context: ${args}`;
|
|
96
|
+
}
|
|
97
|
+
return [{ role: "user", content: prompt }];
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
async function resolveSkillOrCommand(skillName, commands) {
|
|
102
|
+
const cmd = findCommand(skillName, commands);
|
|
103
|
+
if (cmd) return cmd;
|
|
104
|
+
const skillObj = getSkill(skillName);
|
|
105
|
+
if (skillObj) {
|
|
106
|
+
return convertSkillToCommand(skillObj);
|
|
107
|
+
}
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
28
110
|
const SlashCommandTool = {
|
|
29
111
|
name: TOOL_NAME_FOR_PROMPT,
|
|
30
112
|
async description(input) {
|
|
@@ -48,29 +130,41 @@ const SlashCommandTool = {
|
|
|
48
130
|
return true;
|
|
49
131
|
},
|
|
50
132
|
async prompt() {
|
|
51
|
-
const all = await
|
|
133
|
+
const [all, allSkillEntries] = await Promise.all([
|
|
134
|
+
loadCustomCommands(),
|
|
135
|
+
Promise.resolve(getAllSkillEntries())
|
|
136
|
+
]);
|
|
52
137
|
const commands = all.filter(
|
|
53
138
|
(cmd) => cmd.type === "prompt" && cmd.isSkill !== true && cmd.disableModelInvocation !== true
|
|
54
139
|
);
|
|
55
|
-
const
|
|
140
|
+
const commandBaseNames = new Set(
|
|
141
|
+
commands.map((c) => c.name.replace(/^(user|project|plugin:[^:]+):/, ""))
|
|
142
|
+
);
|
|
143
|
+
const skillEntries = allSkillEntries.filter(
|
|
144
|
+
([key, skill]) => !commandBaseNames.has(skill.name) && skill.config.disableModelInvocation !== true && skill.config.userInvocable !== false
|
|
145
|
+
);
|
|
146
|
+
const budget = getCharBudget();
|
|
147
|
+
const lines = [];
|
|
56
148
|
let used = 0;
|
|
149
|
+
let totalCount = commands.length + skillEntries.length;
|
|
150
|
+
let includedCount = 0;
|
|
57
151
|
for (const cmd of commands) {
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
152
|
+
const line = formatCommandLine(cmd);
|
|
153
|
+
if (used + line.length + 1 > budget) break;
|
|
154
|
+
lines.push(line);
|
|
155
|
+
used += line.length + 1;
|
|
156
|
+
includedCount++;
|
|
157
|
+
}
|
|
158
|
+
for (const [key, skill] of skillEntries) {
|
|
159
|
+
const line = formatSkillLine(skill, key);
|
|
160
|
+
if (used + line.length + 1 > budget) break;
|
|
161
|
+
lines.push(line);
|
|
62
162
|
used += line.length + 1;
|
|
63
|
-
|
|
64
|
-
limited.push(cmd);
|
|
163
|
+
includedCount++;
|
|
65
164
|
}
|
|
66
|
-
const availableLines =
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
const whenToUse = cmd.whenToUse ? `- ${cmd.whenToUse}` : "";
|
|
70
|
-
return `- ${name}${args}: ${cmd.description} ${whenToUse}`.trim();
|
|
71
|
-
}).join("\n") : "";
|
|
72
|
-
const truncatedNotice = commands.length > limited.length ? `
|
|
73
|
-
(Showing ${limited.length} of ${commands.length} commands due to token limits)` : "";
|
|
165
|
+
const availableLines = lines.length > 0 ? lines.join("\n") : "";
|
|
166
|
+
const truncatedNotice = totalCount > includedCount ? `
|
|
167
|
+
(Showing ${includedCount} of ${totalCount} skills due to token limits)` : "";
|
|
74
168
|
return `Execute a skill within the main conversation
|
|
75
169
|
|
|
76
170
|
<skills_instructions>
|
|
@@ -130,7 +224,7 @@ ${availableLines}${truncatedNotice}
|
|
|
130
224
|
};
|
|
131
225
|
}
|
|
132
226
|
const commands = context?.options?.commands ?? await getCommands();
|
|
133
|
-
const cmd =
|
|
227
|
+
const cmd = await resolveSkillOrCommand(parsed.skillName, commands);
|
|
134
228
|
if (!cmd) {
|
|
135
229
|
return {
|
|
136
230
|
result: false,
|
|
@@ -167,7 +261,7 @@ ${availableLines}${truncatedNotice}
|
|
|
167
261
|
throw new Error(`Invalid skill name: ${skill}`);
|
|
168
262
|
}
|
|
169
263
|
const commands = context.options?.commands ?? await getCommands();
|
|
170
|
-
const cmd =
|
|
264
|
+
const cmd = await resolveSkillOrCommand(parsed.skillName, commands);
|
|
171
265
|
if (!cmd) {
|
|
172
266
|
throw new Error(`Unknown skill: ${parsed.skillName}`);
|
|
173
267
|
}
|
|
@@ -186,6 +280,59 @@ ${availableLines}${truncatedNotice}
|
|
|
186
280
|
`Unexpected ${cmd.type} command. Expected 'prompt' command. Use /${parsed.skillName} directly in the main conversation.`
|
|
187
281
|
);
|
|
188
282
|
}
|
|
283
|
+
const skillObj = getSkill(parsed.skillName);
|
|
284
|
+
if (skillObj?.config.context === "fork") {
|
|
285
|
+
const content = await loadSkillContent(skillObj);
|
|
286
|
+
const baseDir = dirname(skillObj.filePath);
|
|
287
|
+
let forkPrompt = content.replace(/\{baseDir\}/g, baseDir);
|
|
288
|
+
forkPrompt = await substituteVariables(forkPrompt, args || "", {
|
|
289
|
+
cwd: getCwd(),
|
|
290
|
+
env: { BASE_DIR: baseDir },
|
|
291
|
+
allowDynamicCommands: true
|
|
292
|
+
});
|
|
293
|
+
if (args?.trim() && !content.includes("$ARGUMENTS") && !content.includes("$0")) {
|
|
294
|
+
forkPrompt += `
|
|
295
|
+
|
|
296
|
+
Additional context: ${args}`;
|
|
297
|
+
}
|
|
298
|
+
const forkAgentType = skillObj.config.agent || "general-purpose";
|
|
299
|
+
const forkModel = normalizeCommandModelName(skillObj.config.model);
|
|
300
|
+
const output2 = { success: true, skillName: parsed.skillName };
|
|
301
|
+
const forkInstruction = `This skill runs in fork mode. You MUST immediately call the Task tool with:
|
|
302
|
+
- description: "Skill: ${parsed.skillName}"
|
|
303
|
+
- subagent_type: "${forkAgentType}"
|
|
304
|
+
` + (forkModel ? `- model: "${forkModel}"
|
|
305
|
+
` : "") + `- prompt: The full skill content below
|
|
306
|
+
|
|
307
|
+
<skill-content>
|
|
308
|
+
${forkPrompt}
|
|
309
|
+
</skill-content>`;
|
|
310
|
+
yield {
|
|
311
|
+
type: "result",
|
|
312
|
+
data: output2,
|
|
313
|
+
resultForAssistant: this.renderResultForAssistant(output2),
|
|
314
|
+
newMessages: [
|
|
315
|
+
createUserMessage(
|
|
316
|
+
`<command-name>${parsed.skillName}</command-name>
|
|
317
|
+
<command-message>${parsed.skillName} is running in fork mode\u2026</command-message>`
|
|
318
|
+
),
|
|
319
|
+
createUserMessage(forkInstruction)
|
|
320
|
+
]
|
|
321
|
+
};
|
|
322
|
+
return;
|
|
323
|
+
}
|
|
324
|
+
let cleanupSkillHooks;
|
|
325
|
+
const resolvedSkill = getSkill(parsed.skillName);
|
|
326
|
+
if (resolvedSkill?.config.hooks?.length) {
|
|
327
|
+
const hookMgr = getHookManager();
|
|
328
|
+
if (hookMgr) {
|
|
329
|
+
const skillHooks = buildSkillHooks(resolvedSkill);
|
|
330
|
+
if (skillHooks.length > 0) {
|
|
331
|
+
cleanupSkillHooks = hookMgr.addHooks(skillHooks);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
emitReminderEvent("skill:invoked", { skillName: parsed.skillName });
|
|
189
336
|
const combinedArgs = args || "";
|
|
190
337
|
const prompt = await cmd.getPromptForCommand(combinedArgs);
|
|
191
338
|
const expandedMessages = prompt.map((msg) => {
|
|
@@ -209,6 +356,7 @@ ${availableLines}${truncatedNotice}
|
|
|
209
356
|
const model = normalizeCommandModelName(cmd.model);
|
|
210
357
|
const maxThinkingTokens = typeof cmd.maxThinkingTokens === "number" ? cmd.maxThinkingTokens : void 0;
|
|
211
358
|
const output = { success: true, skillName: parsed.skillName };
|
|
359
|
+
const _cleanupRef = cleanupSkillHooks;
|
|
212
360
|
yield {
|
|
213
361
|
type: "result",
|
|
214
362
|
data: output,
|
|
@@ -241,12 +389,20 @@ ${availableLines}${truncatedNotice}
|
|
|
241
389
|
}
|
|
242
390
|
} : void 0
|
|
243
391
|
};
|
|
392
|
+
if (_cleanupRef) _cleanupRef();
|
|
244
393
|
}
|
|
245
394
|
};
|
|
246
395
|
function parseSkillName(skill) {
|
|
247
396
|
const trimmed = skill.trim();
|
|
248
397
|
const withoutSlash = trimmed.startsWith("/") ? trimmed.slice(1) : trimmed;
|
|
249
398
|
if (!withoutSlash) return null;
|
|
399
|
+
if (withoutSlash.includes(":")) {
|
|
400
|
+
const colonIdx = withoutSlash.indexOf(":");
|
|
401
|
+
const pluginName = withoutSlash.slice(0, colonIdx);
|
|
402
|
+
const skillPart = withoutSlash.slice(colonIdx + 1);
|
|
403
|
+
if (!pluginName || !skillPart) return null;
|
|
404
|
+
return { skillName: withoutSlash, pluginName };
|
|
405
|
+
}
|
|
250
406
|
return { skillName: withoutSlash };
|
|
251
407
|
}
|
|
252
408
|
function findCommand(skillName, commands) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/tools/SlashCommandTool/SlashCommandTool.tsx"],
|
|
4
|
-
"sourcesContent": ["/**\n * Slash Command Tool\n *\n * Executes custom slash commands (skills) within the main conversation.\n * Compatible with Claude Code CLI Skill tool specification.\n */\n\nimport { z } from 'zod'\nimport { FallbackToolUseRejectedMessage } from '@components/FallbackToolUseRejectedMessage'\nimport { Tool } from '@tool'\nimport * as React from 'react'\nimport type { Message } from '@query'\nimport { createUserMessage } from '@utils/messages'\nimport { getCommands } from '@commands'\nimport {\n loadCustomCommands,\n type CustomCommandWithScope,\n} from '@services/customCommands'\nimport { TOOL_NAME_FOR_PROMPT } from './prompt'\nimport { Box, Text } from 'ink'\n\nconst inputSchema = z.strictObject({\n skill: z\n .string()\n .describe('The skill name. E.g., \"commit\", \"review-pr\", or \"pdf\"'),\n args: z.string().optional().describe('Optional arguments for the skill'),\n})\n\ntype Input = z.infer<typeof inputSchema>\ntype Output = {\n success: boolean\n skillName: string\n}\n\nfunction normalizeCommandModelName(model: unknown): string | undefined {\n if (typeof model !== 'string') return undefined\n const trimmed = model.trim()\n if (!trimmed || trimmed === 'inherit') return undefined\n if (trimmed === 'haiku') return 'quick'\n if (trimmed === 'sonnet') return 'task'\n if (trimmed === 'opus') return 'main'\n return trimmed\n}\n\nfunction getCharBudget(): number {\n const raw = Number(process.env.SLASH_COMMAND_TOOL_CHAR_BUDGET)\n return Number.isFinite(raw) && raw > 0 ? raw : 15000\n}\n\nexport const SlashCommandTool = {\n name: TOOL_NAME_FOR_PROMPT,\n async description(input?: Input) {\n const skill = input?.skill\n return skill\n ? `Execute skill: ${skill}`\n : 'Execute a skill within the main conversation'\n },\n userFacingName() {\n return 'Skill'\n },\n inputSchema,\n isReadOnly() {\n return false\n },\n isConcurrencySafe() {\n return false\n },\n async isEnabled() {\n return true\n },\n needsPermissions() {\n return true\n },\n async prompt() {\n const all = await loadCustomCommands()\n const commands = all.filter(\n cmd =>\n cmd.type === 'prompt' &&\n (cmd as any).isSkill !== true &&\n (cmd as any).disableModelInvocation !== true,\n )\n\n const limited: CustomCommandWithScope[] = []\n let used = 0\n for (const cmd of commands) {\n const name = `/${cmd.name}`\n const args = (cmd as any).argumentHint\n ? ` ${(cmd as any).argumentHint}`\n : ''\n const whenToUse = (cmd as any).whenToUse\n ? `- ${(cmd as any).whenToUse}`\n : ''\n const line = `- ${name}${args}: ${cmd.description} ${whenToUse}`.trim()\n used += line.length + 1\n if (used > getCharBudget()) break\n limited.push(cmd)\n }\n\n const availableLines =\n limited.length > 0\n ? limited\n .map(cmd => {\n const name = `/${cmd.name}`\n const args = (cmd as any).argumentHint\n ? ` ${(cmd as any).argumentHint}`\n : ''\n const whenToUse = (cmd as any).whenToUse\n ? `- ${(cmd as any).whenToUse}`\n : ''\n return `- ${name}${args}: ${cmd.description} ${whenToUse}`.trim()\n })\n .join('\\n')\n : ''\n\n const truncatedNotice =\n commands.length > limited.length\n ? `\\n(Showing ${limited.length} of ${commands.length} commands due to token limits)`\n : ''\n\n return `Execute a skill within the main conversation\n\n<skills_instructions>\nWhen users ask you to perform tasks, check if any of the available skills below can help complete the task more effectively. Skills provide specialized capabilities and domain knowledge.\n\nWhen users ask you to run a \"slash command\" or reference \"/<something>\" (e.g., \"/commit\", \"/review-pr\"), they are referring to a skill. Use this tool to invoke the corresponding skill.\n\n<example>\nUser: \"run /commit\"\nAssistant: [Calls Skill tool with skill: \"commit\"]\n</example>\n\nHow to invoke:\n- Use this tool with the skill name and optional arguments\n- Examples:\n - \\`skill: \"pdf\"\\` - invoke the pdf skill\n - \\`skill: \"commit\", args: \"-m 'Fix bug'\"\\` - invoke with arguments\n - \\`skill: \"review-pr\", args: \"123\"\\` - invoke with arguments\n - \\`skill: \"ms-office-suite:pdf\"\\` - invoke using fully qualified name\n\nImportant:\n- When a skill is relevant, you must invoke this tool IMMEDIATELY as your first action\n- NEVER just announce or mention a skill in your text response without actually calling this tool\n- This is a BLOCKING REQUIREMENT: invoke the relevant Skill tool BEFORE generating any other response about the task\n- Only use skills listed in <available_skills> below\n- Do not invoke a skill that is already running\n- Do not use this tool for built-in CLI commands (like /help, /clear, etc.)\n</skills_instructions>\n\n${\n availableLines\n ? `<available_skills>\n${availableLines}${truncatedNotice}\n</available_skills>\n`\n : ''\n}`\n },\n renderToolUseMessage({ skill, args }: Input, _options: { verbose: boolean }) {\n return args ? `${skill} ${args}` : skill\n },\n renderToolUseRejectedMessage() {\n return <FallbackToolUseRejectedMessage />\n },\n renderToolResultMessage(output: Output) {\n if (!output) {\n return (\n <Box paddingLeft={2}>\n <Text>Skill executed</Text>\n </Box>\n )\n }\n\n return (\n <Box paddingLeft={2}>\n <Text color=\"green\">\u2713 Launching skill: /{output.skillName}</Text>\n </Box>\n )\n },\n renderResultForAssistant(output: Output) {\n return `Launching skill: /${output.skillName}`\n },\n async validateInput({ skill }: Input, context) {\n const parsed = parseSkillName(skill)\n if (!parsed) {\n return {\n result: false,\n message: `Invalid skill name: ${skill}`,\n errorCode: 1,\n }\n }\n\n const commands = context?.options?.commands ?? (await getCommands())\n const cmd = findCommand(parsed.skillName, commands)\n\n if (!cmd) {\n return {\n result: false,\n message: `Unknown skill: ${parsed.skillName}`,\n errorCode: 2,\n }\n }\n\n if ((cmd as any).disableModelInvocation) {\n return {\n result: false,\n message: `Skill ${parsed.skillName} cannot be used with ${TOOL_NAME_FOR_PROMPT} tool due to disable-model-invocation`,\n errorCode: 4,\n }\n }\n\n if ((cmd as any).disableNonInteractive) {\n return {\n result: false,\n message: `Skill ${parsed.skillName} cannot be used with ${TOOL_NAME_FOR_PROMPT} tool because it is non-interactive`,\n errorCode: 6,\n }\n }\n\n if (cmd.type !== 'prompt') {\n return {\n result: false,\n message: `Skill ${parsed.skillName} is not a prompt-based command`,\n errorCode: 5,\n }\n }\n\n return { result: true }\n },\n async *call({ skill, args }: Input, context) {\n const parsed = parseSkillName(skill)\n if (!parsed) {\n throw new Error(`Invalid skill name: ${skill}`)\n }\n\n const commands = context.options?.commands ?? (await getCommands())\n const cmd = findCommand(parsed.skillName, commands)\n\n if (!cmd) {\n throw new Error(`Unknown skill: ${parsed.skillName}`)\n }\n\n if ((cmd as any).disableModelInvocation) {\n throw new Error(\n `Skill ${parsed.skillName} cannot be used with ${TOOL_NAME_FOR_PROMPT} tool due to disable-model-invocation`,\n )\n }\n\n if ((cmd as any).disableNonInteractive) {\n throw new Error(\n `Skill ${parsed.skillName} cannot be used with ${TOOL_NAME_FOR_PROMPT} tool because it is non-interactive`,\n )\n }\n\n if (cmd.type !== 'prompt') {\n throw new Error(\n `Unexpected ${cmd.type} command. Expected 'prompt' command. Use /${parsed.skillName} directly in the main conversation.`,\n )\n }\n\n const combinedArgs = args || ''\n const prompt = await cmd.getPromptForCommand(combinedArgs)\n const expandedMessages: Message[] = prompt.map(msg => {\n const userMessage = createUserMessage(\n typeof msg.content === 'string'\n ? msg.content\n : (msg.content as any[])\n .map(block => (block.type === 'text' ? block.text : ''))\n .join('\\n'),\n )\n userMessage.options = {\n ...userMessage.options,\n isCustomCommand: true,\n commandName: cmd.userFacingName(),\n commandArgs: combinedArgs,\n }\n return userMessage\n })\n\n const commandNameForMeta = cmd.userFacingName()\n const progressMessage = (cmd as any).progressMessage || 'running'\n const metaMessage =\n createUserMessage(`<command-name>${commandNameForMeta}</command-name>\n<command-message>${commandNameForMeta} is ${progressMessage}\u2026</command-message>\n<command-args>${combinedArgs}</command-args>`)\n\n const allowedTools: string[] = Array.isArray((cmd as any).allowedTools)\n ? (cmd as any).allowedTools\n : []\n const model = normalizeCommandModelName((cmd as any).model)\n const maxThinkingTokens: number | undefined =\n typeof (cmd as any).maxThinkingTokens === 'number'\n ? (cmd as any).maxThinkingTokens\n : undefined\n\n const output: Output = { success: true, skillName: parsed.skillName }\n\n yield {\n type: 'result' as const,\n data: output,\n resultForAssistant: this.renderResultForAssistant(output),\n newMessages: [metaMessage, ...expandedMessages],\n contextModifier:\n allowedTools.length > 0 || model || maxThinkingTokens !== undefined\n ? {\n modifyContext(ctx: any) {\n const next = { ...ctx }\n\n if (allowedTools.length > 0) {\n const prev = Array.isArray(\n (next.options as any)?.commandAllowedTools,\n )\n ? ((next.options as any).commandAllowedTools as string[])\n : []\n next.options = {\n ...(next.options || {}),\n commandAllowedTools: [\n ...new Set([...prev, ...allowedTools]),\n ],\n }\n }\n\n if (model) {\n next.options = { ...(next.options || {}), model }\n }\n\n if (maxThinkingTokens !== undefined) {\n next.options = {\n ...(next.options || {}),\n maxThinkingTokens,\n }\n }\n\n return next\n },\n }\n : undefined,\n }\n },\n} satisfies Tool<typeof inputSchema, Output>\n\nfunction parseSkillName(skill: string): { skillName: string } | null {\n const trimmed = skill.trim()\n // Remove leading slash if present\n const withoutSlash = trimmed.startsWith('/') ? trimmed.slice(1) : trimmed\n if (!withoutSlash) return null\n return { skillName: withoutSlash }\n}\n\nfunction findCommand(skillName: string, commands: any[]): any | null {\n return (\n commands.find(\n (c: any) =>\n c?.name === skillName ||\n c?.userFacingName?.() === skillName ||\n (Array.isArray(c?.aliases) && c.aliases.includes(skillName)),\n ) ?? null\n )\n}\n"],
|
|
5
|
-
"mappings": "
|
|
6
|
-
"names": []
|
|
4
|
+
"sourcesContent": ["/**\n * Unified Skill Tool\n *\n * Single meta-tool for discovering and executing skills within the main conversation.\n * Implements Claude Code's unified architecture with 3-stage progressive disclosure:\n * Stage 1: Metadata (name + description) in <available_skills> prompt (~100 tokens/skill)\n * Stage 2: Model uses stage 1 info to decide whether to invoke\n * Stage 3: Full SKILL.md content + {baseDir} resolution loaded on invocation (~5-20k tokens)\n *\n * Merges both commands/ (legacy) and skills/ (primary) data sources.\n */\n\nimport { z } from 'zod'\nimport { dirname } from 'path'\nimport { FallbackToolUseRejectedMessage } from '@components/FallbackToolUseRejectedMessage'\nimport { Tool } from '@tool'\nimport * as React from 'react'\nimport type { Message } from '@query'\nimport type { MessageParam } from '@anthropic-ai/sdk/resources/index.mjs'\nimport { createUserMessage } from '@utils/messages'\nimport { getCommands } from '@commands'\nimport {\n loadCustomCommands,\n type CustomCommandWithScope,\n} from '@services/customCommands'\nimport {\n loadAllSkills,\n getAllSkillEntries,\n getSkill,\n loadSkillContent,\n} from '@utils/skillLoader'\nimport type { LoadedSkill } from '../../types/plugin'\nimport { substituteVariables } from '@utils/stringSubstitution'\nimport { getCwd } from '@utils/state'\nimport { getHookManager } from '@utils/hookManager'\nimport { emitReminderEvent } from '@services/systemReminder'\nimport { TOOL_NAME_FOR_PROMPT } from './prompt'\nimport { Box, Text } from 'ink'\nimport type {\n LoadedHook,\n HookEvent as PluginHookEvent,\n} from '../../types/plugin'\n\nconst inputSchema = z.strictObject({\n skill: z\n .string()\n .describe('The skill name. E.g., \"commit\", \"review-pr\", or \"pdf\"'),\n args: z.string().optional().describe('Optional arguments for the skill'),\n})\n\ntype Input = z.infer<typeof inputSchema>\ntype Output = {\n success: boolean\n skillName: string\n}\n\n/**\n * Convert skill hook definitions into LoadedHook objects for temporary registration\n */\nfunction buildSkillHooks(skill: LoadedSkill): LoadedHook[] {\n if (!skill.config.hooks?.length) return []\n return skill.config.hooks.map((h, i) => ({\n name: `skill:${skill.name}:${h.event}:${i}`,\n filePath: skill.filePath,\n config: {\n event: h.event as PluginHookEvent,\n matcher: h.matcher,\n type: h.type || 'command',\n command: h.command,\n prompt: h.prompt,\n timeout: h.timeout,\n },\n pluginName: `skill:${skill.name}`,\n event: h.event as PluginHookEvent,\n matcher: h.matcher,\n }))\n}\n\nfunction normalizeCommandModelName(model: unknown): string | undefined {\n if (typeof model !== 'string') return undefined\n const trimmed = model.trim()\n if (!trimmed || trimmed === 'inherit') return undefined\n if (trimmed === 'haiku') return 'quick'\n if (trimmed === 'sonnet') return 'task'\n if (trimmed === 'opus') return 'main'\n return trimmed\n}\n\nfunction getCharBudget(): number {\n const raw = Number(process.env.SLASH_COMMAND_TOOL_CHAR_BUDGET)\n return Number.isFinite(raw) && raw > 0 ? raw : 15000\n}\n\n/**\n * Format a command entry for Stage 1 <available_skills> listing\n */\nfunction formatCommandLine(cmd: CustomCommandWithScope): string {\n const name = `/${cmd.name}`\n const args = (cmd as any).argumentHint ? ` ${(cmd as any).argumentHint}` : ''\n const whenToUse = (cmd as any).whenToUse ? `- ${(cmd as any).whenToUse}` : ''\n return `- ${name}${args}: ${cmd.description} ${whenToUse}`.trim()\n}\n\n/**\n * Format a skill entry for Stage 1 <available_skills> listing\n * Uses namespaced key for plugin skills (plugin:skill)\n */\nfunction formatSkillLine(skill: LoadedSkill, key: string): string {\n const name = `/${key}`\n const args = skill.config.argumentHint ? ` ${skill.config.argumentHint}` : ''\n return `- ${name}${args}: ${skill.config.description}`.trim()\n}\n\n/**\n * Convert a LoadedSkill into a Command-like object for execution (Stage 3).\n * Loads full content, resolves {baseDir}, applies $ARGUMENTS substitution.\n */\nasync function convertSkillToCommand(\n skill: LoadedSkill,\n): Promise<CustomCommandWithScope> {\n const content = await loadSkillContent(skill)\n const baseDir = dirname(skill.filePath)\n\n return {\n type: 'prompt' as const,\n name: skill.name,\n description: skill.config.description,\n isEnabled: true,\n isHidden: false,\n aliases: [],\n progressMessage: `Running ${skill.name}...`,\n scope: skill.source === 'user' ? 'user' : 'project',\n allowedTools: skill.config.allowedTools,\n model: skill.config.model,\n disableModelInvocation: skill.config.disableModelInvocation,\n argumentHint: skill.config.argumentHint,\n userFacingName: () => skill.name,\n async getPromptForCommand(args: string): Promise<MessageParam[]> {\n // Stage 3: Full content with {baseDir} resolution\n let prompt = content\n\n // 1. Resolve {baseDir} pattern (Claude Code skill spec)\n prompt = prompt.replace(/\\{baseDir\\}/g, baseDir)\n\n // 2. Apply standard substitution ($ARGUMENTS, ${VAR}, !`commands`, etc.)\n // Skills are user-installed, so dynamic commands are allowed\n prompt = await substituteVariables(prompt, args || '', {\n cwd: getCwd(),\n env: { BASE_DIR: baseDir },\n allowDynamicCommands: true,\n })\n\n // 3. Append args if no placeholders used\n if (\n args.trim() &&\n !content.includes('$ARGUMENTS') &&\n !content.includes('$0')\n ) {\n prompt += `\\n\\nAdditional context: ${args}`\n }\n\n return [{ role: 'user', content: prompt }]\n },\n } as any\n}\n\n/**\n * Resolve a skill name to a command, checking commands first then skills.\n */\nasync function resolveSkillOrCommand(\n skillName: string,\n commands: any[],\n): Promise<any | null> {\n // 1. Check commands registry first\n const cmd = findCommand(skillName, commands)\n if (cmd) return cmd\n\n // 2. Fall back to skills from skillLoader\n const skillObj = getSkill(skillName)\n if (skillObj) {\n return convertSkillToCommand(skillObj)\n }\n\n return null\n}\n\nexport const SlashCommandTool = {\n name: TOOL_NAME_FOR_PROMPT,\n async description(input?: Input) {\n const skill = input?.skill\n return skill\n ? `Execute skill: ${skill}`\n : 'Execute a skill within the main conversation'\n },\n userFacingName() {\n return 'Skill'\n },\n inputSchema,\n isReadOnly() {\n return false\n },\n isConcurrencySafe() {\n return false\n },\n async isEnabled() {\n return true\n },\n needsPermissions() {\n return true\n },\n async prompt() {\n // Stage 1: Load metadata from both commands/ and skills/ pipelines\n const [all, allSkillEntries] = await Promise.all([\n loadCustomCommands(),\n Promise.resolve(getAllSkillEntries()),\n ])\n\n // Commands from commands/ dirs (existing behavior)\n const commands = all.filter(\n cmd =>\n cmd.type === 'prompt' &&\n (cmd as any).isSkill !== true &&\n (cmd as any).disableModelInvocation !== true,\n )\n\n // Skills from skills/ dirs \u2014 deduplicate against commands\n const commandBaseNames = new Set(\n commands.map(c => c.name.replace(/^(user|project|plugin:[^:]+):/, '')),\n )\n const skillEntries = allSkillEntries.filter(\n ([key, skill]) =>\n !commandBaseNames.has(skill.name) &&\n skill.config.disableModelInvocation !== true &&\n skill.config.userInvocable !== false,\n )\n\n // Build unified <available_skills> listing with character budget\n // Stage 1: only name + description (frontmatter metadata)\n const budget = getCharBudget()\n const lines: string[] = []\n let used = 0\n let totalCount = commands.length + skillEntries.length\n let includedCount = 0\n\n // Commands first, then skills (both contribute to same budget)\n for (const cmd of commands) {\n const line = formatCommandLine(cmd)\n if (used + line.length + 1 > budget) break\n lines.push(line)\n used += line.length + 1\n includedCount++\n }\n for (const [key, skill] of skillEntries) {\n const line = formatSkillLine(skill, key)\n if (used + line.length + 1 > budget) break\n lines.push(line)\n used += line.length + 1\n includedCount++\n }\n\n const availableLines = lines.length > 0 ? lines.join('\\n') : ''\n const truncatedNotice =\n totalCount > includedCount\n ? `\\n(Showing ${includedCount} of ${totalCount} skills due to token limits)`\n : ''\n\n return `Execute a skill within the main conversation\n\n<skills_instructions>\nWhen users ask you to perform tasks, check if any of the available skills below can help complete the task more effectively. Skills provide specialized capabilities and domain knowledge.\n\nWhen users ask you to run a \"slash command\" or reference \"/<something>\" (e.g., \"/commit\", \"/review-pr\"), they are referring to a skill. Use this tool to invoke the corresponding skill.\n\n<example>\nUser: \"run /commit\"\nAssistant: [Calls Skill tool with skill: \"commit\"]\n</example>\n\nHow to invoke:\n- Use this tool with the skill name and optional arguments\n- Examples:\n - \\`skill: \"pdf\"\\` - invoke the pdf skill\n - \\`skill: \"commit\", args: \"-m 'Fix bug'\"\\` - invoke with arguments\n - \\`skill: \"review-pr\", args: \"123\"\\` - invoke with arguments\n - \\`skill: \"ms-office-suite:pdf\"\\` - invoke using fully qualified name\n\nImportant:\n- When a skill is relevant, you must invoke this tool IMMEDIATELY as your first action\n- NEVER just announce or mention a skill in your text response without actually calling this tool\n- This is a BLOCKING REQUIREMENT: invoke the relevant Skill tool BEFORE generating any other response about the task\n- Only use skills listed in <available_skills> below\n- Do not invoke a skill that is already running\n- Do not use this tool for built-in CLI commands (like /help, /clear, etc.)\n</skills_instructions>\n\n${\n availableLines\n ? `<available_skills>\n${availableLines}${truncatedNotice}\n</available_skills>\n`\n : ''\n}`\n },\n renderToolUseMessage({ skill, args }: Input, _options: { verbose: boolean }) {\n return args ? `${skill} ${args}` : skill\n },\n renderToolUseRejectedMessage() {\n return <FallbackToolUseRejectedMessage />\n },\n renderToolResultMessage(output: Output) {\n if (!output) {\n return (\n <Box paddingLeft={2}>\n <Text>Skill executed</Text>\n </Box>\n )\n }\n\n return (\n <Box paddingLeft={2}>\n <Text color=\"green\">\u2713 Launching skill: /{output.skillName}</Text>\n </Box>\n )\n },\n renderResultForAssistant(output: Output) {\n return `Launching skill: /${output.skillName}`\n },\n async validateInput({ skill }: Input, context) {\n const parsed = parseSkillName(skill)\n if (!parsed) {\n return {\n result: false,\n message: `Invalid skill name: ${skill}`,\n errorCode: 1,\n }\n }\n\n const commands = context?.options?.commands ?? (await getCommands())\n const cmd = await resolveSkillOrCommand(parsed.skillName, commands)\n\n if (!cmd) {\n return {\n result: false,\n message: `Unknown skill: ${parsed.skillName}`,\n errorCode: 2,\n }\n }\n\n if ((cmd as any).disableModelInvocation) {\n return {\n result: false,\n message: `Skill ${parsed.skillName} cannot be used with ${TOOL_NAME_FOR_PROMPT} tool due to disable-model-invocation`,\n errorCode: 4,\n }\n }\n\n if ((cmd as any).disableNonInteractive) {\n return {\n result: false,\n message: `Skill ${parsed.skillName} cannot be used with ${TOOL_NAME_FOR_PROMPT} tool because it is non-interactive`,\n errorCode: 6,\n }\n }\n\n if (cmd.type !== 'prompt') {\n return {\n result: false,\n message: `Skill ${parsed.skillName} is not a prompt-based command`,\n errorCode: 5,\n }\n }\n\n return { result: true }\n },\n async *call({ skill, args }: Input, context) {\n const parsed = parseSkillName(skill)\n if (!parsed) {\n throw new Error(`Invalid skill name: ${skill}`)\n }\n\n const commands = context.options?.commands ?? (await getCommands())\n const cmd = await resolveSkillOrCommand(parsed.skillName, commands)\n\n if (!cmd) {\n throw new Error(`Unknown skill: ${parsed.skillName}`)\n }\n\n if ((cmd as any).disableModelInvocation) {\n throw new Error(\n `Skill ${parsed.skillName} cannot be used with ${TOOL_NAME_FOR_PROMPT} tool due to disable-model-invocation`,\n )\n }\n\n if ((cmd as any).disableNonInteractive) {\n throw new Error(\n `Skill ${parsed.skillName} cannot be used with ${TOOL_NAME_FOR_PROMPT} tool because it is non-interactive`,\n )\n }\n\n if (cmd.type !== 'prompt') {\n throw new Error(\n `Unexpected ${cmd.type} command. Expected 'prompt' command. Use /${parsed.skillName} directly in the main conversation.`,\n )\n }\n\n // Check if skill has context: fork \u2014 delegate to TaskTool subagent\n const skillObj = getSkill(parsed.skillName)\n if (skillObj?.config.context === 'fork') {\n const content = await loadSkillContent(skillObj)\n const baseDir = dirname(skillObj.filePath)\n let forkPrompt = content.replace(/\\{baseDir\\}/g, baseDir)\n forkPrompt = await substituteVariables(forkPrompt, args || '', {\n cwd: getCwd(),\n env: { BASE_DIR: baseDir },\n allowDynamicCommands: true,\n })\n if (\n args?.trim() &&\n !content.includes('$ARGUMENTS') &&\n !content.includes('$0')\n ) {\n forkPrompt += `\\n\\nAdditional context: ${args}`\n }\n\n const forkAgentType = skillObj.config.agent || 'general-purpose'\n const forkModel = normalizeCommandModelName(skillObj.config.model)\n const output: Output = { success: true, skillName: parsed.skillName }\n\n // Instruct the model to delegate to TaskTool with the fork context\n const forkInstruction =\n `This skill runs in fork mode. You MUST immediately call the Task tool with:\\n` +\n `- description: \"Skill: ${parsed.skillName}\"\\n` +\n `- subagent_type: \"${forkAgentType}\"\\n` +\n (forkModel ? `- model: \"${forkModel}\"\\n` : '') +\n `- prompt: The full skill content below\\n\\n` +\n `<skill-content>\\n${forkPrompt}\\n</skill-content>`\n\n yield {\n type: 'result' as const,\n data: output,\n resultForAssistant: this.renderResultForAssistant(output),\n newMessages: [\n createUserMessage(\n `<command-name>${parsed.skillName}</command-name>\\n<command-message>${parsed.skillName} is running in fork mode\u2026</command-message>`,\n ),\n createUserMessage(forkInstruction),\n ],\n }\n return\n }\n\n // Register skill-level hooks if present (lifecycle: skill start \u2192 end)\n let cleanupSkillHooks: (() => void) | undefined\n const resolvedSkill = getSkill(parsed.skillName)\n if (resolvedSkill?.config.hooks?.length) {\n const hookMgr = getHookManager()\n if (hookMgr) {\n const skillHooks = buildSkillHooks(resolvedSkill)\n if (skillHooks.length > 0) {\n cleanupSkillHooks = hookMgr.addHooks(skillHooks)\n }\n }\n }\n\n emitReminderEvent('skill:invoked', { skillName: parsed.skillName })\n\n const combinedArgs = args || ''\n const prompt = await cmd.getPromptForCommand(combinedArgs)\n const expandedMessages: Message[] = prompt.map(msg => {\n const userMessage = createUserMessage(\n typeof msg.content === 'string'\n ? msg.content\n : (msg.content as any[])\n .map(block => (block.type === 'text' ? block.text : ''))\n .join('\\n'),\n )\n userMessage.options = {\n ...userMessage.options,\n isCustomCommand: true,\n commandName: cmd.userFacingName(),\n commandArgs: combinedArgs,\n }\n return userMessage\n })\n\n const commandNameForMeta = cmd.userFacingName()\n const progressMessage = (cmd as any).progressMessage || 'running'\n const metaMessage =\n createUserMessage(`<command-name>${commandNameForMeta}</command-name>\n<command-message>${commandNameForMeta} is ${progressMessage}\u2026</command-message>\n<command-args>${combinedArgs}</command-args>`)\n\n const allowedTools: string[] = Array.isArray((cmd as any).allowedTools)\n ? (cmd as any).allowedTools\n : []\n const model = normalizeCommandModelName((cmd as any).model)\n const maxThinkingTokens: number | undefined =\n typeof (cmd as any).maxThinkingTokens === 'number'\n ? (cmd as any).maxThinkingTokens\n : undefined\n\n const output: Output = { success: true, skillName: parsed.skillName }\n\n // Capture cleanup ref in contextModifier so hooks stay active during skill execution\n const _cleanupRef = cleanupSkillHooks\n\n yield {\n type: 'result' as const,\n data: output,\n resultForAssistant: this.renderResultForAssistant(output),\n newMessages: [metaMessage, ...expandedMessages],\n contextModifier:\n allowedTools.length > 0 || model || maxThinkingTokens !== undefined\n ? {\n modifyContext(ctx: any) {\n const next = { ...ctx }\n\n if (allowedTools.length > 0) {\n const prev = Array.isArray(\n (next.options as any)?.commandAllowedTools,\n )\n ? ((next.options as any).commandAllowedTools as string[])\n : []\n next.options = {\n ...(next.options || {}),\n commandAllowedTools: [\n ...new Set([...prev, ...allowedTools]),\n ],\n }\n }\n\n if (model) {\n next.options = { ...(next.options || {}), model }\n }\n\n if (maxThinkingTokens !== undefined) {\n next.options = {\n ...(next.options || {}),\n maxThinkingTokens,\n }\n }\n\n return next\n },\n }\n : undefined,\n }\n\n // Cleanup skill hooks after yield (generator resumes here when done)\n if (_cleanupRef) _cleanupRef()\n },\n} satisfies Tool\n\nfunction parseSkillName(\n skill: string,\n): { skillName: string; pluginName?: string } | null {\n const trimmed = skill.trim()\n // Remove leading slash if present\n const withoutSlash = trimmed.startsWith('/') ? trimmed.slice(1) : trimmed\n if (!withoutSlash) return null\n\n // Parse \"plugin:skill\" namespace syntax\n if (withoutSlash.includes(':')) {\n const colonIdx = withoutSlash.indexOf(':')\n const pluginName = withoutSlash.slice(0, colonIdx)\n const skillPart = withoutSlash.slice(colonIdx + 1)\n if (!pluginName || !skillPart) return null\n return { skillName: withoutSlash, pluginName }\n }\n\n return { skillName: withoutSlash }\n}\n\nfunction findCommand(skillName: string, commands: any[]): any | null {\n return (\n commands.find(\n (c: any) =>\n c?.name === skillName ||\n c?.userFacingName?.() === skillName ||\n (Array.isArray(c?.aliases) && c.aliases.includes(skillName)),\n ) ?? null\n )\n}\n"],
|
|
5
|
+
"mappings": "AAYA,SAAS,SAAS;AAClB,SAAS,eAAe;AACxB,SAAS,sCAAsC;AAE/C,YAAY,WAAW;AAGvB,SAAS,yBAAyB;AAClC,SAAS,mBAAmB;AAC5B;AAAA,EACE;AAAA,OAEK;AACP;AAAA,EAEE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP,SAAS,2BAA2B;AACpC,SAAS,cAAc;AACvB,SAAS,sBAAsB;AAC/B,SAAS,yBAAyB;AAClC,SAAS,4BAA4B;AACrC,SAAS,KAAK,YAAY;AAM1B,MAAM,cAAc,EAAE,aAAa;AAAA,EACjC,OAAO,EACJ,OAAO,EACP,SAAS,uDAAuD;AAAA,EACnE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,kCAAkC;AACzE,CAAC;AAWD,SAAS,gBAAgB,OAAkC;AACzD,MAAI,CAAC,MAAM,OAAO,OAAO,OAAQ,QAAO,CAAC;AACzC,SAAO,MAAM,OAAO,MAAM,IAAI,CAAC,GAAG,OAAO;AAAA,IACvC,MAAM,SAAS,MAAM,IAAI,IAAI,EAAE,KAAK,IAAI,CAAC;AAAA,IACzC,UAAU,MAAM;AAAA,IAChB,QAAQ;AAAA,MACN,OAAO,EAAE;AAAA,MACT,SAAS,EAAE;AAAA,MACX,MAAM,EAAE,QAAQ;AAAA,MAChB,SAAS,EAAE;AAAA,MACX,QAAQ,EAAE;AAAA,MACV,SAAS,EAAE;AAAA,IACb;AAAA,IACA,YAAY,SAAS,MAAM,IAAI;AAAA,IAC/B,OAAO,EAAE;AAAA,IACT,SAAS,EAAE;AAAA,EACb,EAAE;AACJ;AAEA,SAAS,0BAA0B,OAAoC;AACrE,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,QAAM,UAAU,MAAM,KAAK;AAC3B,MAAI,CAAC,WAAW,YAAY,UAAW,QAAO;AAC9C,MAAI,YAAY,QAAS,QAAO;AAChC,MAAI,YAAY,SAAU,QAAO;AACjC,MAAI,YAAY,OAAQ,QAAO;AAC/B,SAAO;AACT;AAEA,SAAS,gBAAwB;AAC/B,QAAM,MAAM,OAAO,QAAQ,IAAI,8BAA8B;AAC7D,SAAO,OAAO,SAAS,GAAG,KAAK,MAAM,IAAI,MAAM;AACjD;AAKA,SAAS,kBAAkB,KAAqC;AAC9D,QAAM,OAAO,IAAI,IAAI,IAAI;AACzB,QAAM,OAAQ,IAAY,eAAe,IAAK,IAAY,YAAY,KAAK;AAC3E,QAAM,YAAa,IAAY,YAAY,KAAM,IAAY,SAAS,KAAK;AAC3E,SAAO,KAAK,IAAI,GAAG,IAAI,KAAK,IAAI,WAAW,IAAI,SAAS,GAAG,KAAK;AAClE;AAMA,SAAS,gBAAgB,OAAoB,KAAqB;AAChE,QAAM,OAAO,IAAI,GAAG;AACpB,QAAM,OAAO,MAAM,OAAO,eAAe,IAAI,MAAM,OAAO,YAAY,KAAK;AAC3E,SAAO,KAAK,IAAI,GAAG,IAAI,KAAK,MAAM,OAAO,WAAW,GAAG,KAAK;AAC9D;AAMA,eAAe,sBACb,OACiC;AACjC,QAAM,UAAU,MAAM,iBAAiB,KAAK;AAC5C,QAAM,UAAU,QAAQ,MAAM,QAAQ;AAEtC,SAAO;AAAA,IACL,MAAM;AAAA,IACN,MAAM,MAAM;AAAA,IACZ,aAAa,MAAM,OAAO;AAAA,IAC1B,WAAW;AAAA,IACX,UAAU;AAAA,IACV,SAAS,CAAC;AAAA,IACV,iBAAiB,WAAW,MAAM,IAAI;AAAA,IACtC,OAAO,MAAM,WAAW,SAAS,SAAS;AAAA,IAC1C,cAAc,MAAM,OAAO;AAAA,IAC3B,OAAO,MAAM,OAAO;AAAA,IACpB,wBAAwB,MAAM,OAAO;AAAA,IACrC,cAAc,MAAM,OAAO;AAAA,IAC3B,gBAAgB,MAAM,MAAM;AAAA,IAC5B,MAAM,oBAAoB,MAAuC;AAE/D,UAAI,SAAS;AAGb,eAAS,OAAO,QAAQ,gBAAgB,OAAO;AAI/C,eAAS,MAAM,oBAAoB,QAAQ,QAAQ,IAAI;AAAA,QACrD,KAAK,OAAO;AAAA,QACZ,KAAK,EAAE,UAAU,QAAQ;AAAA,QACzB,sBAAsB;AAAA,MACxB,CAAC;AAGD,UACE,KAAK,KAAK,KACV,CAAC,QAAQ,SAAS,YAAY,KAC9B,CAAC,QAAQ,SAAS,IAAI,GACtB;AACA,kBAAU;AAAA;AAAA,sBAA2B,IAAI;AAAA,MAC3C;AAEA,aAAO,CAAC,EAAE,MAAM,QAAQ,SAAS,OAAO,CAAC;AAAA,IAC3C;AAAA,EACF;AACF;AAKA,eAAe,sBACb,WACA,UACqB;AAErB,QAAM,MAAM,YAAY,WAAW,QAAQ;AAC3C,MAAI,IAAK,QAAO;AAGhB,QAAM,WAAW,SAAS,SAAS;AACnC,MAAI,UAAU;AACZ,WAAO,sBAAsB,QAAQ;AAAA,EACvC;AAEA,SAAO;AACT;AAEO,MAAM,mBAAmB;AAAA,EAC9B,MAAM;AAAA,EACN,MAAM,YAAY,OAAe;AAC/B,UAAM,QAAQ,OAAO;AACrB,WAAO,QACH,kBAAkB,KAAK,KACvB;AAAA,EACN;AAAA,EACA,iBAAiB;AACf,WAAO;AAAA,EACT;AAAA,EACA;AAAA,EACA,aAAa;AACX,WAAO;AAAA,EACT;AAAA,EACA,oBAAoB;AAClB,WAAO;AAAA,EACT;AAAA,EACA,MAAM,YAAY;AAChB,WAAO;AAAA,EACT;AAAA,EACA,mBAAmB;AACjB,WAAO;AAAA,EACT;AAAA,EACA,MAAM,SAAS;AAEb,UAAM,CAAC,KAAK,eAAe,IAAI,MAAM,QAAQ,IAAI;AAAA,MAC/C,mBAAmB;AAAA,MACnB,QAAQ,QAAQ,mBAAmB,CAAC;AAAA,IACtC,CAAC;AAGD,UAAM,WAAW,IAAI;AAAA,MACnB,SACE,IAAI,SAAS,YACZ,IAAY,YAAY,QACxB,IAAY,2BAA2B;AAAA,IAC5C;AAGA,UAAM,mBAAmB,IAAI;AAAA,MAC3B,SAAS,IAAI,OAAK,EAAE,KAAK,QAAQ,iCAAiC,EAAE,CAAC;AAAA,IACvE;AACA,UAAM,eAAe,gBAAgB;AAAA,MACnC,CAAC,CAAC,KAAK,KAAK,MACV,CAAC,iBAAiB,IAAI,MAAM,IAAI,KAChC,MAAM,OAAO,2BAA2B,QACxC,MAAM,OAAO,kBAAkB;AAAA,IACnC;AAIA,UAAM,SAAS,cAAc;AAC7B,UAAM,QAAkB,CAAC;AACzB,QAAI,OAAO;AACX,QAAI,aAAa,SAAS,SAAS,aAAa;AAChD,QAAI,gBAAgB;AAGpB,eAAW,OAAO,UAAU;AAC1B,YAAM,OAAO,kBAAkB,GAAG;AAClC,UAAI,OAAO,KAAK,SAAS,IAAI,OAAQ;AACrC,YAAM,KAAK,IAAI;AACf,cAAQ,KAAK,SAAS;AACtB;AAAA,IACF;AACA,eAAW,CAAC,KAAK,KAAK,KAAK,cAAc;AACvC,YAAM,OAAO,gBAAgB,OAAO,GAAG;AACvC,UAAI,OAAO,KAAK,SAAS,IAAI,OAAQ;AACrC,YAAM,KAAK,IAAI;AACf,cAAQ,KAAK,SAAS;AACtB;AAAA,IACF;AAEA,UAAM,iBAAiB,MAAM,SAAS,IAAI,MAAM,KAAK,IAAI,IAAI;AAC7D,UAAM,kBACJ,aAAa,gBACT;AAAA,WAAc,aAAa,OAAO,UAAU,iCAC5C;AAEN,WAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA8BT,iBACI;AAAA,EACJ,cAAc,GAAG,eAAe;AAAA;AAAA,IAG5B,EACN;AAAA,EACE;AAAA,EACA,qBAAqB,EAAE,OAAO,KAAK,GAAU,UAAgC;AAC3E,WAAO,OAAO,GAAG,KAAK,IAAI,IAAI,KAAK;AAAA,EACrC;AAAA,EACA,+BAA+B;AAC7B,WAAO,oCAAC,oCAA+B;AAAA,EACzC;AAAA,EACA,wBAAwB,QAAgB;AACtC,QAAI,CAAC,QAAQ;AACX,aACE,oCAAC,OAAI,aAAa,KAChB,oCAAC,YAAK,gBAAc,CACtB;AAAA,IAEJ;AAEA,WACE,oCAAC,OAAI,aAAa,KAChB,oCAAC,QAAK,OAAM,WAAQ,6BAAqB,OAAO,SAAU,CAC5D;AAAA,EAEJ;AAAA,EACA,yBAAyB,QAAgB;AACvC,WAAO,qBAAqB,OAAO,SAAS;AAAA,EAC9C;AAAA,EACA,MAAM,cAAc,EAAE,MAAM,GAAU,SAAS;AAC7C,UAAM,SAAS,eAAe,KAAK;AACnC,QAAI,CAAC,QAAQ;AACX,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,SAAS,uBAAuB,KAAK;AAAA,QACrC,WAAW;AAAA,MACb;AAAA,IACF;AAEA,UAAM,WAAW,SAAS,SAAS,YAAa,MAAM,YAAY;AAClE,UAAM,MAAM,MAAM,sBAAsB,OAAO,WAAW,QAAQ;AAElE,QAAI,CAAC,KAAK;AACR,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,SAAS,kBAAkB,OAAO,SAAS;AAAA,QAC3C,WAAW;AAAA,MACb;AAAA,IACF;AAEA,QAAK,IAAY,wBAAwB;AACvC,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,SAAS,SAAS,OAAO,SAAS,wBAAwB,oBAAoB;AAAA,QAC9E,WAAW;AAAA,MACb;AAAA,IACF;AAEA,QAAK,IAAY,uBAAuB;AACtC,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,SAAS,SAAS,OAAO,SAAS,wBAAwB,oBAAoB;AAAA,QAC9E,WAAW;AAAA,MACb;AAAA,IACF;AAEA,QAAI,IAAI,SAAS,UAAU;AACzB,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,SAAS,SAAS,OAAO,SAAS;AAAA,QAClC,WAAW;AAAA,MACb;AAAA,IACF;AAEA,WAAO,EAAE,QAAQ,KAAK;AAAA,EACxB;AAAA,EACA,OAAO,KAAK,EAAE,OAAO,KAAK,GAAU,SAAS;AAC3C,UAAM,SAAS,eAAe,KAAK;AACnC,QAAI,CAAC,QAAQ;AACX,YAAM,IAAI,MAAM,uBAAuB,KAAK,EAAE;AAAA,IAChD;AAEA,UAAM,WAAW,QAAQ,SAAS,YAAa,MAAM,YAAY;AACjE,UAAM,MAAM,MAAM,sBAAsB,OAAO,WAAW,QAAQ;AAElE,QAAI,CAAC,KAAK;AACR,YAAM,IAAI,MAAM,kBAAkB,OAAO,SAAS,EAAE;AAAA,IACtD;AAEA,QAAK,IAAY,wBAAwB;AACvC,YAAM,IAAI;AAAA,QACR,SAAS,OAAO,SAAS,wBAAwB,oBAAoB;AAAA,MACvE;AAAA,IACF;AAEA,QAAK,IAAY,uBAAuB;AACtC,YAAM,IAAI;AAAA,QACR,SAAS,OAAO,SAAS,wBAAwB,oBAAoB;AAAA,MACvE;AAAA,IACF;AAEA,QAAI,IAAI,SAAS,UAAU;AACzB,YAAM,IAAI;AAAA,QACR,cAAc,IAAI,IAAI,6CAA6C,OAAO,SAAS;AAAA,MACrF;AAAA,IACF;AAGA,UAAM,WAAW,SAAS,OAAO,SAAS;AAC1C,QAAI,UAAU,OAAO,YAAY,QAAQ;AACvC,YAAM,UAAU,MAAM,iBAAiB,QAAQ;AAC/C,YAAM,UAAU,QAAQ,SAAS,QAAQ;AACzC,UAAI,aAAa,QAAQ,QAAQ,gBAAgB,OAAO;AACxD,mBAAa,MAAM,oBAAoB,YAAY,QAAQ,IAAI;AAAA,QAC7D,KAAK,OAAO;AAAA,QACZ,KAAK,EAAE,UAAU,QAAQ;AAAA,QACzB,sBAAsB;AAAA,MACxB,CAAC;AACD,UACE,MAAM,KAAK,KACX,CAAC,QAAQ,SAAS,YAAY,KAC9B,CAAC,QAAQ,SAAS,IAAI,GACtB;AACA,sBAAc;AAAA;AAAA,sBAA2B,IAAI;AAAA,MAC/C;AAEA,YAAM,gBAAgB,SAAS,OAAO,SAAS;AAC/C,YAAM,YAAY,0BAA0B,SAAS,OAAO,KAAK;AACjE,YAAMA,UAAiB,EAAE,SAAS,MAAM,WAAW,OAAO,UAAU;AAGpE,YAAM,kBACJ;AAAA,yBAC0B,OAAO,SAAS;AAAA,oBACrB,aAAa;AAAA,KACjC,YAAY,aAAa,SAAS;AAAA,IAAQ,MAC3C;AAAA;AAAA;AAAA,EACoB,UAAU;AAAA;AAEhC,YAAM;AAAA,QACJ,MAAM;AAAA,QACN,MAAMA;AAAA,QACN,oBAAoB,KAAK,yBAAyBA,OAAM;AAAA,QACxD,aAAa;AAAA,UACX;AAAA,YACE,iBAAiB,OAAO,SAAS;AAAA,mBAAqC,OAAO,SAAS;AAAA,UACxF;AAAA,UACA,kBAAkB,eAAe;AAAA,QACnC;AAAA,MACF;AACA;AAAA,IACF;AAGA,QAAI;AACJ,UAAM,gBAAgB,SAAS,OAAO,SAAS;AAC/C,QAAI,eAAe,OAAO,OAAO,QAAQ;AACvC,YAAM,UAAU,eAAe;AAC/B,UAAI,SAAS;AACX,cAAM,aAAa,gBAAgB,aAAa;AAChD,YAAI,WAAW,SAAS,GAAG;AACzB,8BAAoB,QAAQ,SAAS,UAAU;AAAA,QACjD;AAAA,MACF;AAAA,IACF;AAEA,sBAAkB,iBAAiB,EAAE,WAAW,OAAO,UAAU,CAAC;AAElE,UAAM,eAAe,QAAQ;AAC7B,UAAM,SAAS,MAAM,IAAI,oBAAoB,YAAY;AACzD,UAAM,mBAA8B,OAAO,IAAI,SAAO;AACpD,YAAM,cAAc;AAAA,QAClB,OAAO,IAAI,YAAY,WACnB,IAAI,UACH,IAAI,QACF,IAAI,WAAU,MAAM,SAAS,SAAS,MAAM,OAAO,EAAG,EACtD,KAAK,IAAI;AAAA,MAClB;AACA,kBAAY,UAAU;AAAA,QACpB,GAAG,YAAY;AAAA,QACf,iBAAiB;AAAA,QACjB,aAAa,IAAI,eAAe;AAAA,QAChC,aAAa;AAAA,MACf;AACA,aAAO;AAAA,IACT,CAAC;AAED,UAAM,qBAAqB,IAAI,eAAe;AAC9C,UAAM,kBAAmB,IAAY,mBAAmB;AACxD,UAAM,cACJ,kBAAkB,iBAAiB,kBAAkB;AAAA,mBACxC,kBAAkB,OAAO,eAAe;AAAA,gBAC3C,YAAY,iBAAiB;AAEzC,UAAM,eAAyB,MAAM,QAAS,IAAY,YAAY,IACjE,IAAY,eACb,CAAC;AACL,UAAM,QAAQ,0BAA2B,IAAY,KAAK;AAC1D,UAAM,oBACJ,OAAQ,IAAY,sBAAsB,WACrC,IAAY,oBACb;AAEN,UAAM,SAAiB,EAAE,SAAS,MAAM,WAAW,OAAO,UAAU;AAGpE,UAAM,cAAc;AAEpB,UAAM;AAAA,MACJ,MAAM;AAAA,MACN,MAAM;AAAA,MACN,oBAAoB,KAAK,yBAAyB,MAAM;AAAA,MACxD,aAAa,CAAC,aAAa,GAAG,gBAAgB;AAAA,MAC9C,iBACE,aAAa,SAAS,KAAK,SAAS,sBAAsB,SACtD;AAAA,QACE,cAAc,KAAU;AACtB,gBAAM,OAAO,EAAE,GAAG,IAAI;AAEtB,cAAI,aAAa,SAAS,GAAG;AAC3B,kBAAM,OAAO,MAAM;AAAA,cAChB,KAAK,SAAiB;AAAA,YACzB,IACM,KAAK,QAAgB,sBACvB,CAAC;AACL,iBAAK,UAAU;AAAA,cACb,GAAI,KAAK,WAAW,CAAC;AAAA,cACrB,qBAAqB;AAAA,gBACnB,GAAG,oBAAI,IAAI,CAAC,GAAG,MAAM,GAAG,YAAY,CAAC;AAAA,cACvC;AAAA,YACF;AAAA,UACF;AAEA,cAAI,OAAO;AACT,iBAAK,UAAU,EAAE,GAAI,KAAK,WAAW,CAAC,GAAI,MAAM;AAAA,UAClD;AAEA,cAAI,sBAAsB,QAAW;AACnC,iBAAK,UAAU;AAAA,cACb,GAAI,KAAK,WAAW,CAAC;AAAA,cACrB;AAAA,YACF;AAAA,UACF;AAEA,iBAAO;AAAA,QACT;AAAA,MACF,IACA;AAAA,IACR;AAGA,QAAI,YAAa,aAAY;AAAA,EAC/B;AACF;AAEA,SAAS,eACP,OACmD;AACnD,QAAM,UAAU,MAAM,KAAK;AAE3B,QAAM,eAAe,QAAQ,WAAW,GAAG,IAAI,QAAQ,MAAM,CAAC,IAAI;AAClE,MAAI,CAAC,aAAc,QAAO;AAG1B,MAAI,aAAa,SAAS,GAAG,GAAG;AAC9B,UAAM,WAAW,aAAa,QAAQ,GAAG;AACzC,UAAM,aAAa,aAAa,MAAM,GAAG,QAAQ;AACjD,UAAM,YAAY,aAAa,MAAM,WAAW,CAAC;AACjD,QAAI,CAAC,cAAc,CAAC,UAAW,QAAO;AACtC,WAAO,EAAE,WAAW,cAAc,WAAW;AAAA,EAC/C;AAEA,SAAO,EAAE,WAAW,aAAa;AACnC;AAEA,SAAS,YAAY,WAAmB,UAA6B;AACnE,SACE,SAAS;AAAA,IACP,CAAC,MACC,GAAG,SAAS,aACZ,GAAG,iBAAiB,MAAM,aACzB,MAAM,QAAQ,GAAG,OAAO,KAAK,EAAE,QAAQ,SAAS,SAAS;AAAA,EAC9D,KAAK;AAET;",
|
|
6
|
+
"names": ["output"]
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/tools/TaskCreateTool/TaskCreateTool.tsx"],
|
|
4
|
-
"sourcesContent": ["import { Box, Text } from 'ink'\nimport * as React from 'react'\nimport { z } from 'zod'\nimport { FallbackToolUseRejectedMessage } from '@components/FallbackToolUseRejectedMessage'\nimport { Tool } from '@tool'\nimport { createTask } from '@services/taskStore'\nimport { DESCRIPTION, PROMPT } from './prompt'\nimport { getTheme } from '@utils/theme'\n\nconst inputSchema = z.strictObject({\n subject: z.string().describe('A brief title for the task'),\n description: z\n .string()\n .describe('A detailed description of what needs to be done'),\n activeForm: z\n .string()\n .optional()\n .describe(\n 'Present continuous form shown in spinner when in_progress (e.g., \"Running tests\")',\n ),\n metadata: z\n .record(z.unknown())\n .optional()\n .describe('Arbitrary metadata to attach to the task'),\n})\n\nexport const TaskCreateTool = {\n name: 'TaskCreate',\n async description() {\n return DESCRIPTION\n },\n async prompt() {\n return PROMPT\n },\n inputSchema,\n userFacingName() {\n return 'Create Task'\n },\n async isEnabled() {\n return true\n },\n isReadOnly() {\n return false\n },\n isConcurrencySafe() {\n return false\n },\n needsPermissions() {\n return false\n },\n renderToolUseMessage(input: z.infer<typeof inputSchema>) {\n const subject = input.subject || ''\n const truncated =\n subject.length > 50 ? subject.slice(0, 50) + '...' : subject\n return `subject: \"${truncated}\"`\n },\n renderToolUseRejectedMessage() {\n return <FallbackToolUseRejectedMessage />\n },\n renderToolResultMessage(output: { taskId: string; subject: string }) {\n if (!output || !output.taskId) {\n return (\n <Box flexDirection=\"row\">\n <Text> \u23BF </Text>\n <Text>Task created</Text>\n </Box>\n )\n }\n\n return (\n <Box flexDirection=\"row\">\n <Text> \u23BF </Text>\n <Text color={getTheme().success}>\n Task #{output.taskId} created: {output.subject}\n </Text>\n </Box>\n )\n },\n renderResultForAssistant(result: { taskId: string; subject: string }) {\n return `Task #${result.taskId} created successfully: ${result.subject}`\n },\n async validateInput({ subject, description }: z.infer<typeof inputSchema>) {\n if (!subject?.trim()) {\n return {\n result: false,\n message: 'Task subject cannot be empty',\n }\n }\n if (!description?.trim()) {\n return {\n result: false,\n message: 'Task description cannot be empty',\n }\n }\n return { result: true }\n },\n async *call(input: z.infer<typeof inputSchema>) {\n try {\n const task = createTask({\n subject: input.subject,\n description: input.description,\n activeForm: input.activeForm,\n metadata: input.metadata,\n })\n\n const result = {\n taskId: task.id,\n subject: task.subject,\n }\n\n yield {\n type: 'result',\n data: result,\n resultForAssistant: this.renderResultForAssistant(result),\n }\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : 'Unknown error occurred'\n yield {\n type: 'result',\n data: { error: errorMessage },\n resultForAssistant: `Error creating task: ${errorMessage}`,\n }\n }\n },\n} satisfies Tool
|
|
4
|
+
"sourcesContent": ["import { Box, Text } from 'ink'\nimport * as React from 'react'\nimport { z } from 'zod'\nimport { FallbackToolUseRejectedMessage } from '@components/FallbackToolUseRejectedMessage'\nimport { Tool } from '@tool'\nimport { createTask } from '@services/taskStore'\nimport { DESCRIPTION, PROMPT } from './prompt'\nimport { getTheme } from '@utils/theme'\n\nconst inputSchema = z.strictObject({\n subject: z.string().describe('A brief title for the task'),\n description: z\n .string()\n .describe('A detailed description of what needs to be done'),\n activeForm: z\n .string()\n .optional()\n .describe(\n 'Present continuous form shown in spinner when in_progress (e.g., \"Running tests\")',\n ),\n metadata: z\n .record(z.unknown())\n .optional()\n .describe('Arbitrary metadata to attach to the task'),\n})\n\nexport const TaskCreateTool = {\n name: 'TaskCreate',\n async description() {\n return DESCRIPTION\n },\n async prompt() {\n return PROMPT\n },\n inputSchema,\n userFacingName() {\n return 'Create Task'\n },\n async isEnabled() {\n return true\n },\n isReadOnly() {\n return false\n },\n isConcurrencySafe() {\n return false\n },\n needsPermissions() {\n return false\n },\n renderToolUseMessage(input: z.infer<typeof inputSchema>) {\n const subject = input.subject || ''\n const truncated =\n subject.length > 50 ? subject.slice(0, 50) + '...' : subject\n return `subject: \"${truncated}\"`\n },\n renderToolUseRejectedMessage() {\n return <FallbackToolUseRejectedMessage />\n },\n renderToolResultMessage(output: { taskId: string; subject: string }) {\n if (!output || !output.taskId) {\n return (\n <Box flexDirection=\"row\">\n <Text> \u23BF </Text>\n <Text>Task created</Text>\n </Box>\n )\n }\n\n return (\n <Box flexDirection=\"row\">\n <Text> \u23BF </Text>\n <Text color={getTheme().success}>\n Task #{output.taskId} created: {output.subject}\n </Text>\n </Box>\n )\n },\n renderResultForAssistant(result: { taskId: string; subject: string }) {\n return `Task #${result.taskId} created successfully: ${result.subject}`\n },\n async validateInput({ subject, description }: z.infer<typeof inputSchema>) {\n if (!subject?.trim()) {\n return {\n result: false,\n message: 'Task subject cannot be empty',\n }\n }\n if (!description?.trim()) {\n return {\n result: false,\n message: 'Task description cannot be empty',\n }\n }\n return { result: true }\n },\n async *call(input: z.infer<typeof inputSchema>) {\n try {\n const task = createTask({\n subject: input.subject,\n description: input.description,\n activeForm: input.activeForm,\n metadata: input.metadata,\n })\n\n const result = {\n taskId: task.id,\n subject: task.subject,\n }\n\n yield {\n type: 'result',\n data: result,\n resultForAssistant: this.renderResultForAssistant(result),\n }\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : 'Unknown error occurred'\n yield {\n type: 'result',\n data: { error: errorMessage },\n resultForAssistant: `Error creating task: ${errorMessage}`,\n }\n }\n },\n} satisfies Tool\n"],
|
|
5
5
|
"mappings": "AAAA,SAAS,KAAK,YAAY;AAC1B,YAAY,WAAW;AACvB,SAAS,SAAS;AAClB,SAAS,sCAAsC;AAE/C,SAAS,kBAAkB;AAC3B,SAAS,aAAa,cAAc;AACpC,SAAS,gBAAgB;AAEzB,MAAM,cAAc,EAAE,aAAa;AAAA,EACjC,SAAS,EAAE,OAAO,EAAE,SAAS,4BAA4B;AAAA,EACzD,aAAa,EACV,OAAO,EACP,SAAS,iDAAiD;AAAA,EAC7D,YAAY,EACT,OAAO,EACP,SAAS,EACT;AAAA,IACC;AAAA,EACF;AAAA,EACF,UAAU,EACP,OAAO,EAAE,QAAQ,CAAC,EAClB,SAAS,EACT,SAAS,0CAA0C;AACxD,CAAC;AAEM,MAAM,iBAAiB;AAAA,EAC5B,MAAM;AAAA,EACN,MAAM,cAAc;AAClB,WAAO;AAAA,EACT;AAAA,EACA,MAAM,SAAS;AACb,WAAO;AAAA,EACT;AAAA,EACA;AAAA,EACA,iBAAiB;AACf,WAAO;AAAA,EACT;AAAA,EACA,MAAM,YAAY;AAChB,WAAO;AAAA,EACT;AAAA,EACA,aAAa;AACX,WAAO;AAAA,EACT;AAAA,EACA,oBAAoB;AAClB,WAAO;AAAA,EACT;AAAA,EACA,mBAAmB;AACjB,WAAO;AAAA,EACT;AAAA,EACA,qBAAqB,OAAoC;AACvD,UAAM,UAAU,MAAM,WAAW;AACjC,UAAM,YACJ,QAAQ,SAAS,KAAK,QAAQ,MAAM,GAAG,EAAE,IAAI,QAAQ;AACvD,WAAO,aAAa,SAAS;AAAA,EAC/B;AAAA,EACA,+BAA+B;AAC7B,WAAO,oCAAC,oCAA+B;AAAA,EACzC;AAAA,EACA,wBAAwB,QAA6C;AACnE,QAAI,CAAC,UAAU,CAAC,OAAO,QAAQ;AAC7B,aACE,oCAAC,OAAI,eAAc,SACjB,oCAAC,YAAK,qBAAoB,GAC1B,oCAAC,YAAK,cAAY,CACpB;AAAA,IAEJ;AAEA,WACE,oCAAC,OAAI,eAAc,SACjB,oCAAC,YAAK,qBAAoB,GAC1B,oCAAC,QAAK,OAAO,SAAS,EAAE,WAAS,UACxB,OAAO,QAAO,cAAW,OAAO,OACzC,CACF;AAAA,EAEJ;AAAA,EACA,yBAAyB,QAA6C;AACpE,WAAO,SAAS,OAAO,MAAM,0BAA0B,OAAO,OAAO;AAAA,EACvE;AAAA,EACA,MAAM,cAAc,EAAE,SAAS,YAAY,GAAgC;AACzE,QAAI,CAAC,SAAS,KAAK,GAAG;AACpB,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,SAAS;AAAA,MACX;AAAA,IACF;AACA,QAAI,CAAC,aAAa,KAAK,GAAG;AACxB,aAAO;AAAA,QACL,QAAQ;AAAA,QACR,SAAS;AAAA,MACX;AAAA,IACF;AACA,WAAO,EAAE,QAAQ,KAAK;AAAA,EACxB;AAAA,EACA,OAAO,KAAK,OAAoC;AAC9C,QAAI;AACF,YAAM,OAAO,WAAW;AAAA,QACtB,SAAS,MAAM;AAAA,QACf,aAAa,MAAM;AAAA,QACnB,YAAY,MAAM;AAAA,QAClB,UAAU,MAAM;AAAA,MAClB,CAAC;AAED,YAAM,SAAS;AAAA,QACb,QAAQ,KAAK;AAAA,QACb,SAAS,KAAK;AAAA,MAChB;AAEA,YAAM;AAAA,QACJ,MAAM;AAAA,QACN,MAAM;AAAA,QACN,oBAAoB,KAAK,yBAAyB,MAAM;AAAA,MAC1D;AAAA,IACF,SAAS,OAAO;AACd,YAAM,eACJ,iBAAiB,QAAQ,MAAM,UAAU;AAC3C,YAAM;AAAA,QACJ,MAAM;AAAA,QACN,MAAM,EAAE,OAAO,aAAa;AAAA,QAC5B,oBAAoB,wBAAwB,YAAY;AAAA,MAC1D;AAAA,IACF;AAAA,EACF;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/tools/TaskGetTool/TaskGetTool.tsx"],
|
|
4
|
-
"sourcesContent": ["import { Box, Text } from 'ink'\nimport * as React from 'react'\nimport { z } from 'zod'\nimport { FallbackToolUseRejectedMessage } from '@components/FallbackToolUseRejectedMessage'\nimport { Tool } from '@tool'\nimport { getTaskById, Task } from '@services/taskStore'\nimport { DESCRIPTION, PROMPT } from './prompt'\nimport { getTheme } from '@utils/theme'\n\nconst inputSchema = z.strictObject({\n taskId: z.string().describe('The ID of the task to retrieve'),\n})\n\nexport const TaskGetTool = {\n name: 'TaskGet',\n async description() {\n return DESCRIPTION\n },\n async prompt() {\n return PROMPT\n },\n inputSchema,\n userFacingName() {\n return 'Get Task'\n },\n async isEnabled() {\n return true\n },\n isReadOnly() {\n return true\n },\n isConcurrencySafe() {\n return true\n },\n needsPermissions() {\n return false\n },\n renderToolUseMessage(input: z.infer<typeof inputSchema>) {\n return `taskId: ${input.taskId}`\n },\n renderToolUseRejectedMessage() {\n return <FallbackToolUseRejectedMessage />\n },\n renderToolResultMessage(output: Task | { error: string }) {\n if (!output || 'error' in output) {\n return (\n <Box flexDirection=\"row\">\n <Text> \u23BF </Text>\n <Text color={getTheme().error}>\n {output && 'error' in output ? output.error : 'Task not found'}\n </Text>\n </Box>\n )\n }\n\n const statusColor =\n output.status === 'completed'\n ? getTheme().success\n : output.status === 'in_progress'\n ? getTheme().warning\n : getTheme().secondaryText\n\n return (\n <Box flexDirection=\"column\">\n <Box flexDirection=\"row\">\n <Text> \u23BF </Text>\n <Text bold>#{output.id}</Text>\n <Text> </Text>\n <Text>{output.subject}</Text>\n </Box>\n <Box flexDirection=\"row\" paddingLeft={5}>\n <Text color={statusColor}>[{output.status}]</Text>\n {output.owner && (\n <Text color={getTheme().secondaryText}> owner: {output.owner}</Text>\n )}\n </Box>\n </Box>\n )\n },\n renderResultForAssistant(result: Task | { error: string }) {\n if ('error' in result) {\n return `Error: ${result.error}`\n }\n\n const lines: string[] = [\n `Task #${result.id}:`,\n ` Subject: ${result.subject}`,\n ` Status: ${result.status}`,\n ` Description: ${result.description}`,\n ]\n\n if (result.activeForm) {\n lines.push(` Active Form: ${result.activeForm}`)\n }\n if (result.owner) {\n lines.push(` Owner: ${result.owner}`)\n }\n if (result.blocks && result.blocks.length > 0) {\n lines.push(` Blocks: [${result.blocks.join(', ')}]`)\n }\n if (result.blockedBy && result.blockedBy.length > 0) {\n lines.push(` Blocked By: [${result.blockedBy.join(', ')}]`)\n }\n if (result.metadata && Object.keys(result.metadata).length > 0) {\n lines.push(` Metadata: ${JSON.stringify(result.metadata)}`)\n }\n\n return lines.join('\\n')\n },\n async validateInput({ taskId }: z.infer<typeof inputSchema>) {\n if (!taskId?.trim()) {\n return {\n result: false,\n message: 'Task ID is required',\n }\n }\n return { result: true }\n },\n async *call(input: z.infer<typeof inputSchema>) {\n try {\n const task = getTaskById(input.taskId)\n\n if (!task) {\n const result = { error: `Task with ID '${input.taskId}' not found` }\n yield {\n type: 'result',\n data: result,\n resultForAssistant: this.renderResultForAssistant(result),\n }\n return\n }\n\n yield {\n type: 'result',\n data: task,\n resultForAssistant: this.renderResultForAssistant(task),\n }\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : 'Unknown error occurred'\n const result = { error: errorMessage }\n yield {\n type: 'result',\n data: result,\n resultForAssistant: `Error getting task: ${errorMessage}`,\n }\n }\n },\n} satisfies Tool
|
|
4
|
+
"sourcesContent": ["import { Box, Text } from 'ink'\nimport * as React from 'react'\nimport { z } from 'zod'\nimport { FallbackToolUseRejectedMessage } from '@components/FallbackToolUseRejectedMessage'\nimport { Tool } from '@tool'\nimport { getTaskById, Task } from '@services/taskStore'\nimport { DESCRIPTION, PROMPT } from './prompt'\nimport { getTheme } from '@utils/theme'\n\nconst inputSchema = z.strictObject({\n taskId: z.string().describe('The ID of the task to retrieve'),\n})\n\nexport const TaskGetTool = {\n name: 'TaskGet',\n async description() {\n return DESCRIPTION\n },\n async prompt() {\n return PROMPT\n },\n inputSchema,\n userFacingName() {\n return 'Get Task'\n },\n async isEnabled() {\n return true\n },\n isReadOnly() {\n return true\n },\n isConcurrencySafe() {\n return true\n },\n needsPermissions() {\n return false\n },\n renderToolUseMessage(input: z.infer<typeof inputSchema>) {\n return `taskId: ${input.taskId}`\n },\n renderToolUseRejectedMessage() {\n return <FallbackToolUseRejectedMessage />\n },\n renderToolResultMessage(output: Task | { error: string }) {\n if (!output || 'error' in output) {\n return (\n <Box flexDirection=\"row\">\n <Text> \u23BF </Text>\n <Text color={getTheme().error}>\n {output && 'error' in output ? output.error : 'Task not found'}\n </Text>\n </Box>\n )\n }\n\n const statusColor =\n output.status === 'completed'\n ? getTheme().success\n : output.status === 'in_progress'\n ? getTheme().warning\n : getTheme().secondaryText\n\n return (\n <Box flexDirection=\"column\">\n <Box flexDirection=\"row\">\n <Text> \u23BF </Text>\n <Text bold>#{output.id}</Text>\n <Text> </Text>\n <Text>{output.subject}</Text>\n </Box>\n <Box flexDirection=\"row\" paddingLeft={5}>\n <Text color={statusColor}>[{output.status}]</Text>\n {output.owner && (\n <Text color={getTheme().secondaryText}> owner: {output.owner}</Text>\n )}\n </Box>\n </Box>\n )\n },\n renderResultForAssistant(result: Task | { error: string }) {\n if ('error' in result) {\n return `Error: ${result.error}`\n }\n\n const lines: string[] = [\n `Task #${result.id}:`,\n ` Subject: ${result.subject}`,\n ` Status: ${result.status}`,\n ` Description: ${result.description}`,\n ]\n\n if (result.activeForm) {\n lines.push(` Active Form: ${result.activeForm}`)\n }\n if (result.owner) {\n lines.push(` Owner: ${result.owner}`)\n }\n if (result.blocks && result.blocks.length > 0) {\n lines.push(` Blocks: [${result.blocks.join(', ')}]`)\n }\n if (result.blockedBy && result.blockedBy.length > 0) {\n lines.push(` Blocked By: [${result.blockedBy.join(', ')}]`)\n }\n if (result.metadata && Object.keys(result.metadata).length > 0) {\n lines.push(` Metadata: ${JSON.stringify(result.metadata)}`)\n }\n\n return lines.join('\\n')\n },\n async validateInput({ taskId }: z.infer<typeof inputSchema>) {\n if (!taskId?.trim()) {\n return {\n result: false,\n message: 'Task ID is required',\n }\n }\n return { result: true }\n },\n async *call(input: z.infer<typeof inputSchema>) {\n try {\n const task = getTaskById(input.taskId)\n\n if (!task) {\n const result = { error: `Task with ID '${input.taskId}' not found` }\n yield {\n type: 'result',\n data: result,\n resultForAssistant: this.renderResultForAssistant(result),\n }\n return\n }\n\n yield {\n type: 'result',\n data: task,\n resultForAssistant: this.renderResultForAssistant(task),\n }\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : 'Unknown error occurred'\n const result = { error: errorMessage }\n yield {\n type: 'result',\n data: result,\n resultForAssistant: `Error getting task: ${errorMessage}`,\n }\n }\n },\n} satisfies Tool\n"],
|
|
5
5
|
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/tools/TaskListTool/TaskListTool.tsx"],
|
|
4
|
-
"sourcesContent": ["import { Box, Text } from 'ink'\nimport * as React from 'react'\nimport { z } from 'zod'\nimport { FallbackToolUseRejectedMessage } from '@components/FallbackToolUseRejectedMessage'\nimport { Tool } from '@tool'\nimport { getTaskList, getTaskStatistics } from '@services/taskStore'\nimport { DESCRIPTION, PROMPT } from './prompt'\nimport { getTheme } from '@utils/theme'\n\nconst inputSchema = z.strictObject({})\n\ntype TaskSummary = {\n id: string\n subject: string\n status: 'pending' | 'in_progress' | 'completed'\n owner?: string\n blockedBy?: string[]\n}\n\ntype TaskListOutput = {\n tasks: TaskSummary[]\n stats: {\n total: number\n pending: number\n inProgress: number\n completed: number\n }\n}\n\nexport const TaskListTool = {\n name: 'TaskList',\n async description() {\n return DESCRIPTION\n },\n async prompt() {\n return PROMPT\n },\n inputSchema,\n userFacingName() {\n return 'List Tasks'\n },\n async isEnabled() {\n return true\n },\n isReadOnly() {\n return true\n },\n isConcurrencySafe() {\n return true\n },\n needsPermissions() {\n return false\n },\n renderToolUseMessage() {\n return ''\n },\n renderToolUseRejectedMessage() {\n return <FallbackToolUseRejectedMessage />\n },\n renderToolResultMessage(output: TaskListOutput) {\n if (!output || !output.tasks) {\n return (\n <Box flexDirection=\"row\">\n <Text> \u23BF </Text>\n <Text>No tasks found</Text>\n </Box>\n )\n }\n\n const { tasks, stats } = output\n\n if (tasks.length === 0) {\n return (\n <Box flexDirection=\"row\">\n <Text> \u23BF </Text>\n <Text color={getTheme().secondaryText}>No tasks in list</Text>\n </Box>\n )\n }\n\n return (\n <Box flexDirection=\"column\">\n <Box flexDirection=\"row\">\n <Text> \u23BF </Text>\n <Text>\n {stats.total} task(s): {stats.pending} pending, {stats.inProgress}{' '}\n in progress, {stats.completed} completed\n </Text>\n </Box>\n {tasks.slice(0, 5).map(task => {\n const statusColor =\n task.status === 'completed'\n ? getTheme().success\n : task.status === 'in_progress'\n ? getTheme().warning\n : getTheme().secondaryText\n\n return (\n <Box key={task.id} flexDirection=\"row\" paddingLeft={5}>\n <Text color={statusColor}>#{task.id}</Text>\n <Text> </Text>\n <Text>\n {task.subject.length > 40\n ? task.subject.slice(0, 40) + '...'\n : task.subject}\n </Text>\n {task.blockedBy && task.blockedBy.length > 0 && (\n <Text color={getTheme().error}>\n {' '}\n (blocked by: {task.blockedBy.join(', ')})\n </Text>\n )}\n </Box>\n )\n })}\n {tasks.length > 5 && (\n <Box paddingLeft={5}>\n <Text color={getTheme().secondaryText}>\n ... and {tasks.length - 5} more\n </Text>\n </Box>\n )}\n </Box>\n )\n },\n renderResultForAssistant(result: TaskListOutput) {\n const { tasks, stats } = result\n\n if (tasks.length === 0) {\n return 'No tasks in the task list.'\n }\n\n const lines: string[] = [\n `Task List (${stats.total} total: ${stats.pending} pending, ${stats.inProgress} in progress, ${stats.completed} completed):`,\n '',\n ]\n\n for (const task of tasks) {\n let line = `#${task.id} [${task.status}] ${task.subject}`\n if (task.owner) {\n line += ` (owner: ${task.owner})`\n }\n if (task.blockedBy && task.blockedBy.length > 0) {\n line += ` (blocked by: ${task.blockedBy.join(', ')})`\n }\n lines.push(line)\n }\n\n return lines.join('\\n')\n },\n async *call() {\n try {\n const tasks = getTaskList()\n const stats = getTaskStatistics()\n\n const result: TaskListOutput = {\n tasks,\n stats,\n }\n\n yield {\n type: 'result',\n data: result,\n resultForAssistant: this.renderResultForAssistant(result),\n }\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : 'Unknown error occurred'\n yield {\n type: 'result',\n data: {\n tasks: [],\n stats: { total: 0, pending: 0, inProgress: 0, completed: 0 },\n },\n resultForAssistant: `Error listing tasks: ${errorMessage}`,\n }\n }\n },\n} satisfies Tool
|
|
4
|
+
"sourcesContent": ["import { Box, Text } from 'ink'\nimport * as React from 'react'\nimport { z } from 'zod'\nimport { FallbackToolUseRejectedMessage } from '@components/FallbackToolUseRejectedMessage'\nimport { Tool } from '@tool'\nimport { getTaskList, getTaskStatistics } from '@services/taskStore'\nimport { DESCRIPTION, PROMPT } from './prompt'\nimport { getTheme } from '@utils/theme'\n\nconst inputSchema = z.strictObject({})\n\ntype TaskSummary = {\n id: string\n subject: string\n status: 'pending' | 'in_progress' | 'completed'\n owner?: string\n blockedBy?: string[]\n}\n\ntype TaskListOutput = {\n tasks: TaskSummary[]\n stats: {\n total: number\n pending: number\n inProgress: number\n completed: number\n }\n}\n\nexport const TaskListTool = {\n name: 'TaskList',\n async description() {\n return DESCRIPTION\n },\n async prompt() {\n return PROMPT\n },\n inputSchema,\n userFacingName() {\n return 'List Tasks'\n },\n async isEnabled() {\n return true\n },\n isReadOnly() {\n return true\n },\n isConcurrencySafe() {\n return true\n },\n needsPermissions() {\n return false\n },\n renderToolUseMessage() {\n return ''\n },\n renderToolUseRejectedMessage() {\n return <FallbackToolUseRejectedMessage />\n },\n renderToolResultMessage(output: TaskListOutput) {\n if (!output || !output.tasks) {\n return (\n <Box flexDirection=\"row\">\n <Text> \u23BF </Text>\n <Text>No tasks found</Text>\n </Box>\n )\n }\n\n const { tasks, stats } = output\n\n if (tasks.length === 0) {\n return (\n <Box flexDirection=\"row\">\n <Text> \u23BF </Text>\n <Text color={getTheme().secondaryText}>No tasks in list</Text>\n </Box>\n )\n }\n\n return (\n <Box flexDirection=\"column\">\n <Box flexDirection=\"row\">\n <Text> \u23BF </Text>\n <Text>\n {stats.total} task(s): {stats.pending} pending, {stats.inProgress}{' '}\n in progress, {stats.completed} completed\n </Text>\n </Box>\n {tasks.slice(0, 5).map(task => {\n const statusColor =\n task.status === 'completed'\n ? getTheme().success\n : task.status === 'in_progress'\n ? getTheme().warning\n : getTheme().secondaryText\n\n return (\n <Box key={task.id} flexDirection=\"row\" paddingLeft={5}>\n <Text color={statusColor}>#{task.id}</Text>\n <Text> </Text>\n <Text>\n {task.subject.length > 40\n ? task.subject.slice(0, 40) + '...'\n : task.subject}\n </Text>\n {task.blockedBy && task.blockedBy.length > 0 && (\n <Text color={getTheme().error}>\n {' '}\n (blocked by: {task.blockedBy.join(', ')})\n </Text>\n )}\n </Box>\n )\n })}\n {tasks.length > 5 && (\n <Box paddingLeft={5}>\n <Text color={getTheme().secondaryText}>\n ... and {tasks.length - 5} more\n </Text>\n </Box>\n )}\n </Box>\n )\n },\n renderResultForAssistant(result: TaskListOutput) {\n const { tasks, stats } = result\n\n if (tasks.length === 0) {\n return 'No tasks in the task list.'\n }\n\n const lines: string[] = [\n `Task List (${stats.total} total: ${stats.pending} pending, ${stats.inProgress} in progress, ${stats.completed} completed):`,\n '',\n ]\n\n for (const task of tasks) {\n let line = `#${task.id} [${task.status}] ${task.subject}`\n if (task.owner) {\n line += ` (owner: ${task.owner})`\n }\n if (task.blockedBy && task.blockedBy.length > 0) {\n line += ` (blocked by: ${task.blockedBy.join(', ')})`\n }\n lines.push(line)\n }\n\n return lines.join('\\n')\n },\n async *call() {\n try {\n const tasks = getTaskList()\n const stats = getTaskStatistics()\n\n const result: TaskListOutput = {\n tasks,\n stats,\n }\n\n yield {\n type: 'result',\n data: result,\n resultForAssistant: this.renderResultForAssistant(result),\n }\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : 'Unknown error occurred'\n yield {\n type: 'result',\n data: {\n tasks: [],\n stats: { total: 0, pending: 0, inProgress: 0, completed: 0 },\n },\n resultForAssistant: `Error listing tasks: ${errorMessage}`,\n }\n }\n },\n} satisfies Tool\n"],
|
|
5
5
|
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/tools/TaskOutputTool/TaskOutputTool.tsx"],
|
|
4
|
-
"sourcesContent": ["/**\n * Task Output Tool\n *\n * Retrieves output from background tasks (shells, agents, remote sessions).\n * Supports both background shell commands and agent transcripts.\n */\n\nimport { Box, Text } from 'ink'\nimport React from 'react'\nimport { z } from 'zod'\nimport { Tool } from '@tool'\nimport { DESCRIPTION, PROMPT, TOOL_NAME } from './prompt'\nimport { BackgroundShellManager } from '@utils/BackgroundShellManager'\nimport {\n getAgentTranscript,\n listAgentTranscripts,\n type AgentTranscript,\n type AgentStatus,\n} from '@utils/agentTranscripts'\nimport { SEMANTIC_COLORS } from '@constants/colors'\n\nconst inputSchema = z.strictObject({\n task_id: z.string().describe('The task ID to get output from'),\n block: z\n .boolean()\n .default(true)\n .optional()\n .describe('Whether to wait for completion'),\n timeout: z\n .number()\n .min(0)\n .max(600000)\n .default(30000)\n .optional()\n .describe('Max wait time in ms'),\n})\n\ntype Output = {\n task_id: string\n task_type: 'shell' | 'agent'\n status: 'running' | 'completed' | 'failed' | 'interrupted' | 'not_found'\n output: string\n exitCode?: number\n // Agent-specific fields\n agentType?: string\n description?: string\n messageCount?: number\n toolUseCount?: number\n tokenUsage?: {\n inputTokens: number\n outputTokens: number\n }\n}\n\nexport const TaskOutputTool = {\n name: TOOL_NAME,\n async description() {\n return DESCRIPTION\n },\n userFacingName() {\n return 'Task Output'\n },\n inputSchema,\n isReadOnly() {\n return true\n },\n isConcurrencySafe() {\n return true\n },\n async isEnabled() {\n return true\n },\n needsPermissions() {\n return false\n },\n async prompt() {\n return PROMPT\n },\n renderToolUseMessage(input: z.infer<typeof inputSchema>) {\n const blocking = input.block !== false ? 'blocking' : 'non-blocking'\n return `task_id: \"${input.task_id}\", mode: ${blocking}`\n },\n renderToolUseRejectedMessage() {\n return (\n <Box paddingLeft={2}>\n <Text color={SEMANTIC_COLORS.dim}>Task output request rejected</Text>\n </Box>\n )\n },\n renderToolResultMessage(output: Output, options?: { verbose?: boolean }) {\n if (!output) {\n return (\n <Box paddingLeft={2}>\n <Text>Task output retrieved</Text>\n </Box>\n )\n }\n\n const verbose = options?.verbose ?? false\n const statusColor =\n output.status === 'completed'\n ? 'green'\n : output.status === 'running'\n ? 'yellow'\n : output.status === 'failed' || output.status === 'interrupted'\n ? 'red'\n : 'gray'\n\n // Determine output truncation based on displayMode (via verbose flag)\n // minimal (verbose=false): Show only status line, no output content\n // compact (verbose=false): Show status + truncated output (200 chars)\n // detailed (verbose=true): Show status + full output (up to 2000 chars)\n const getOutputPreview = () => {\n if (!output.output) return null\n\n // For minimal mode, don't show output content at all in the summary\n // The full content is available via the tool result\n if (!verbose) {\n // Compact mode: show truncated output\n const maxLen = 200\n if (output.output.length <= maxLen) return output.output\n return output.output.substring(0, maxLen) + '...'\n }\n\n // Detailed mode: show more output\n const maxLen = 2000\n if (output.output.length <= maxLen) return output.output\n return output.output.substring(0, maxLen) + '...'\n }\n\n const outputPreview = getOutputPreview()\n\n return (\n <Box flexDirection=\"column\" paddingLeft={2}>\n <Box flexDirection=\"row\">\n <Text>{output.task_type === 'agent' ? 'Agent' : 'Task'} </Text>\n <Text bold>{output.task_id}</Text>\n <Text>: </Text>\n <Text color={statusColor}>{output.status}</Text>\n {output.exitCode !== undefined && (\n <Text color={SEMANTIC_COLORS.dim}> (exit: {output.exitCode})</Text>\n )}\n </Box>\n {output.task_type === 'agent' && output.agentType && (\n <Box>\n <Text color={SEMANTIC_COLORS.dim}>Type: {output.agentType}</Text>\n {output.messageCount !== undefined && (\n <Text color={SEMANTIC_COLORS.dim}>\n {' '}\n | Messages: {output.messageCount}\n </Text>\n )}\n {output.toolUseCount !== undefined && (\n <Text color={SEMANTIC_COLORS.dim}>\n {' '}\n | Tools: {output.toolUseCount}\n </Text>\n )}\n {output.tokenUsage && verbose && (\n <Text color={SEMANTIC_COLORS.dim}>\n {' '}\n | Tokens:{' '}\n {output.tokenUsage.inputTokens + output.tokenUsage.outputTokens}\n </Text>\n )}\n </Box>\n )}\n {outputPreview && (\n <Box marginTop={1}>\n <Text color={SEMANTIC_COLORS.dim}>{outputPreview}</Text>\n </Box>\n )}\n </Box>\n )\n },\n renderResultForAssistant(output: Output) {\n if (!output) {\n return 'Task output retrieved'\n }\n\n const lines = [\n `Task ID: ${output.task_id}`,\n `Task Type: ${output.task_type}`,\n `Status: ${output.status}`,\n ]\n\n if (output.task_type === 'agent') {\n if (output.agentType) lines.push(`Agent Type: ${output.agentType}`)\n if (output.description) lines.push(`Description: ${output.description}`)\n if (output.messageCount !== undefined)\n lines.push(`Messages: ${output.messageCount}`)\n if (output.toolUseCount !== undefined)\n lines.push(`Tool Uses: ${output.toolUseCount}`)\n if (output.tokenUsage) {\n lines.push(\n `Tokens: ${output.tokenUsage.inputTokens + output.tokenUsage.outputTokens} (in: ${output.tokenUsage.inputTokens}, out: ${output.tokenUsage.outputTokens})`,\n )\n }\n }\n\n if (output.exitCode !== undefined) {\n lines.push(`Exit Code: ${output.exitCode}`)\n }\n\n if (output.output) {\n lines.push('', 'Output:', output.output)\n }\n\n return lines.join('\\n')\n },\n async *call(input: z.infer<typeof inputSchema>, _context: any) {\n const { task_id, block = true, timeout = 30000 } = input\n\n // First, check if this is an agent transcript\n const transcript = getAgentTranscript(task_id)\n if (transcript) {\n // Handle agent transcript\n let currentTranscript = transcript\n\n // If blocking and agent is running, poll for completion\n if (block && transcript.status === 'running') {\n const startTime = Date.now()\n const pollInterval = 500 // 500ms\n\n while (Date.now() - startTime < timeout) {\n const updated = getAgentTranscript(task_id)\n if (!updated || updated.status !== 'running') {\n currentTranscript = updated || currentTranscript\n break\n }\n await new Promise(resolve => setTimeout(resolve, pollInterval))\n }\n }\n\n // Extract final text output from transcript messages\n let outputText = ''\n const lastMessage =\n currentTranscript.messages[currentTranscript.messages.length - 1]\n if (lastMessage?.type === 'assistant') {\n const textBlocks = lastMessage.message.content.filter(\n (block: any) => block.type === 'text',\n )\n outputText = textBlocks.map((block: any) => block.text).join('\\n')\n }\n\n const output: Output = {\n task_id,\n task_type: 'agent',\n status: currentTranscript.status as Output['status'],\n output: outputText,\n agentType: currentTranscript.agentType,\n description: currentTranscript.description,\n messageCount: currentTranscript.messages.length,\n toolUseCount: currentTranscript.toolUseCount,\n tokenUsage: currentTranscript.tokenUsage,\n }\n\n yield {\n type: 'result',\n data: output,\n resultForAssistant: this.renderResultForAssistant(output),\n }\n return\n }\n\n // Fall back to background shell\n const manager = BackgroundShellManager.getInstance()\n const shell = manager.get(task_id)\n\n if (!shell) {\n const output: Output = {\n task_id,\n task_type: 'shell',\n status: 'not_found',\n output: `No task found with ID: ${task_id}. This could be a background shell or agent ID.`,\n }\n yield {\n type: 'result',\n data: output,\n resultForAssistant: this.renderResultForAssistant(output),\n }\n return\n }\n\n // If blocking, wait for completion\n if (block && shell.status === 'running') {\n await new Promise<void>((resolve, reject) => {\n const timeoutId = setTimeout(() => {\n manager.removeListener('statusChange', listener)\n resolve()\n }, timeout)\n\n const listener = (shellId: string, status: string) => {\n if (shellId === task_id && status !== 'running') {\n clearTimeout(timeoutId)\n manager.removeListener('statusChange', listener)\n resolve()\n }\n }\n\n manager.on('statusChange', listener)\n })\n }\n\n // Get all output\n const shellOutput = manager.getAllOutput(task_id)\n const currentShell = manager.get(task_id)\n\n const output: Output = {\n task_id,\n task_type: 'shell',\n status:\n currentShell?.status === 'running'\n ? 'running'\n : currentShell?.exitCode === 0\n ? 'completed'\n : 'failed',\n output: shellOutput\n ? [...shellOutput.stdout, ...shellOutput.stderr].join('\\n')\n : '',\n exitCode: currentShell?.exitCode,\n }\n\n yield {\n type: 'result',\n data: output,\n resultForAssistant: this.renderResultForAssistant(output),\n }\n },\n} satisfies Tool<typeof inputSchema, Output>\n"],
|
|
4
|
+
"sourcesContent": ["/**\n * Task Output Tool\n *\n * Retrieves output from background tasks (shells, agents, remote sessions).\n * Supports both background shell commands and agent transcripts.\n */\n\nimport { Box, Text } from 'ink'\nimport React from 'react'\nimport { z } from 'zod'\nimport { Tool } from '@tool'\nimport { DESCRIPTION, PROMPT, TOOL_NAME } from './prompt'\nimport { BackgroundShellManager } from '@utils/BackgroundShellManager'\nimport {\n getAgentTranscript,\n listAgentTranscripts,\n type AgentTranscript,\n type AgentStatus,\n} from '@utils/agentTranscripts'\nimport { SEMANTIC_COLORS } from '@constants/colors'\n\nconst inputSchema = z.strictObject({\n task_id: z.string().describe('The task ID to get output from'),\n block: z\n .boolean()\n .default(true)\n .optional()\n .describe('Whether to wait for completion'),\n timeout: z\n .number()\n .min(0)\n .max(600000)\n .default(30000)\n .optional()\n .describe('Max wait time in ms'),\n})\n\ntype Output = {\n task_id: string\n task_type: 'shell' | 'agent'\n status: 'running' | 'completed' | 'failed' | 'interrupted' | 'not_found'\n output: string\n exitCode?: number\n // Agent-specific fields\n agentType?: string\n description?: string\n messageCount?: number\n toolUseCount?: number\n tokenUsage?: {\n inputTokens: number\n outputTokens: number\n }\n}\n\nexport const TaskOutputTool = {\n name: TOOL_NAME,\n async description() {\n return DESCRIPTION\n },\n userFacingName() {\n return 'Task Output'\n },\n inputSchema,\n isReadOnly() {\n return true\n },\n isConcurrencySafe() {\n return true\n },\n async isEnabled() {\n return true\n },\n needsPermissions() {\n return false\n },\n async prompt() {\n return PROMPT\n },\n renderToolUseMessage(input: z.infer<typeof inputSchema>) {\n const blocking = input.block !== false ? 'blocking' : 'non-blocking'\n return `task_id: \"${input.task_id}\", mode: ${blocking}`\n },\n renderToolUseRejectedMessage() {\n return (\n <Box paddingLeft={2}>\n <Text color={SEMANTIC_COLORS.dim}>Task output request rejected</Text>\n </Box>\n )\n },\n renderToolResultMessage(output: Output, options?: { verbose?: boolean }) {\n if (!output) {\n return (\n <Box paddingLeft={2}>\n <Text>Task output retrieved</Text>\n </Box>\n )\n }\n\n const verbose = options?.verbose ?? false\n const statusColor =\n output.status === 'completed'\n ? 'green'\n : output.status === 'running'\n ? 'yellow'\n : output.status === 'failed' || output.status === 'interrupted'\n ? 'red'\n : 'gray'\n\n // Determine output truncation based on displayMode (via verbose flag)\n // minimal (verbose=false): Show only status line, no output content\n // compact (verbose=false): Show status + truncated output (200 chars)\n // detailed (verbose=true): Show status + full output (up to 2000 chars)\n const getOutputPreview = () => {\n if (!output.output) return null\n\n // For minimal mode, don't show output content at all in the summary\n // The full content is available via the tool result\n if (!verbose) {\n // Compact mode: show truncated output\n const maxLen = 200\n if (output.output.length <= maxLen) return output.output\n return output.output.substring(0, maxLen) + '...'\n }\n\n // Detailed mode: show more output\n const maxLen = 2000\n if (output.output.length <= maxLen) return output.output\n return output.output.substring(0, maxLen) + '...'\n }\n\n const outputPreview = getOutputPreview()\n\n return (\n <Box flexDirection=\"column\" paddingLeft={2}>\n <Box flexDirection=\"row\">\n <Text>{output.task_type === 'agent' ? 'Agent' : 'Task'} </Text>\n <Text bold>{output.task_id}</Text>\n <Text>: </Text>\n <Text color={statusColor}>{output.status}</Text>\n {output.exitCode !== undefined && (\n <Text color={SEMANTIC_COLORS.dim}> (exit: {output.exitCode})</Text>\n )}\n </Box>\n {output.task_type === 'agent' && output.agentType && (\n <Box>\n <Text color={SEMANTIC_COLORS.dim}>Type: {output.agentType}</Text>\n {output.messageCount !== undefined && (\n <Text color={SEMANTIC_COLORS.dim}>\n {' '}\n | Messages: {output.messageCount}\n </Text>\n )}\n {output.toolUseCount !== undefined && (\n <Text color={SEMANTIC_COLORS.dim}>\n {' '}\n | Tools: {output.toolUseCount}\n </Text>\n )}\n {output.tokenUsage && verbose && (\n <Text color={SEMANTIC_COLORS.dim}>\n {' '}\n | Tokens:{' '}\n {output.tokenUsage.inputTokens + output.tokenUsage.outputTokens}\n </Text>\n )}\n </Box>\n )}\n {outputPreview && (\n <Box marginTop={1}>\n <Text color={SEMANTIC_COLORS.dim}>{outputPreview}</Text>\n </Box>\n )}\n </Box>\n )\n },\n renderResultForAssistant(output: Output) {\n if (!output) {\n return 'Task output retrieved'\n }\n\n const lines = [\n `Task ID: ${output.task_id}`,\n `Task Type: ${output.task_type}`,\n `Status: ${output.status}`,\n ]\n\n if (output.task_type === 'agent') {\n if (output.agentType) lines.push(`Agent Type: ${output.agentType}`)\n if (output.description) lines.push(`Description: ${output.description}`)\n if (output.messageCount !== undefined)\n lines.push(`Messages: ${output.messageCount}`)\n if (output.toolUseCount !== undefined)\n lines.push(`Tool Uses: ${output.toolUseCount}`)\n if (output.tokenUsage) {\n lines.push(\n `Tokens: ${output.tokenUsage.inputTokens + output.tokenUsage.outputTokens} (in: ${output.tokenUsage.inputTokens}, out: ${output.tokenUsage.outputTokens})`,\n )\n }\n }\n\n if (output.exitCode !== undefined) {\n lines.push(`Exit Code: ${output.exitCode}`)\n }\n\n if (output.output) {\n lines.push('', 'Output:', output.output)\n }\n\n return lines.join('\\n')\n },\n async *call(input: z.infer<typeof inputSchema>, _context: any) {\n const { task_id, block = true, timeout = 30000 } = input\n\n // First, check if this is an agent transcript\n const transcript = getAgentTranscript(task_id)\n if (transcript) {\n // Handle agent transcript\n let currentTranscript = transcript\n\n // If blocking and agent is running, poll for completion\n if (block && transcript.status === 'running') {\n const startTime = Date.now()\n const pollInterval = 500 // 500ms\n\n while (Date.now() - startTime < timeout) {\n const updated = getAgentTranscript(task_id)\n if (!updated || updated.status !== 'running') {\n currentTranscript = updated || currentTranscript\n break\n }\n await new Promise(resolve => setTimeout(resolve, pollInterval))\n }\n }\n\n // Extract final text output from transcript messages\n let outputText = ''\n const lastMessage =\n currentTranscript.messages[currentTranscript.messages.length - 1]\n if (lastMessage?.type === 'assistant') {\n const textBlocks = lastMessage.message.content.filter(\n (block: any) => block.type === 'text',\n )\n outputText = textBlocks.map((block: any) => block.text).join('\\n')\n }\n\n const output: Output = {\n task_id,\n task_type: 'agent',\n status: currentTranscript.status as Output['status'],\n output: outputText,\n agentType: currentTranscript.agentType,\n description: currentTranscript.description,\n messageCount: currentTranscript.messages.length,\n toolUseCount: currentTranscript.toolUseCount,\n tokenUsage: currentTranscript.tokenUsage,\n }\n\n yield {\n type: 'result',\n data: output,\n resultForAssistant: this.renderResultForAssistant(output),\n }\n return\n }\n\n // Fall back to background shell\n const manager = BackgroundShellManager.getInstance()\n const shell = manager.get(task_id)\n\n if (!shell) {\n const output: Output = {\n task_id,\n task_type: 'shell',\n status: 'not_found',\n output: `No task found with ID: ${task_id}. This could be a background shell or agent ID.`,\n }\n yield {\n type: 'result',\n data: output,\n resultForAssistant: this.renderResultForAssistant(output),\n }\n return\n }\n\n // If blocking, wait for completion\n if (block && shell.status === 'running') {\n await new Promise<void>((resolve, reject) => {\n const timeoutId = setTimeout(() => {\n manager.removeListener('statusChange', listener)\n resolve()\n }, timeout)\n\n const listener = (shellId: string, status: string) => {\n if (shellId === task_id && status !== 'running') {\n clearTimeout(timeoutId)\n manager.removeListener('statusChange', listener)\n resolve()\n }\n }\n\n manager.on('statusChange', listener)\n })\n }\n\n // Get all output\n const shellOutput = manager.getAllOutput(task_id)\n const currentShell = manager.get(task_id)\n\n const output: Output = {\n task_id,\n task_type: 'shell',\n status:\n currentShell?.status === 'running'\n ? 'running'\n : currentShell?.exitCode === 0\n ? 'completed'\n : 'failed',\n output: shellOutput\n ? [...shellOutput.stdout, ...shellOutput.stderr].join('\\n')\n : '',\n exitCode: currentShell?.exitCode,\n }\n\n yield {\n type: 'result',\n data: output,\n resultForAssistant: this.renderResultForAssistant(output),\n }\n },\n} satisfies Tool\n"],
|
|
5
5
|
"mappings": "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",
|
|
6
6
|
"names": ["maxLen", "block", "output"]
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/tools/TaskStopTool/TaskStopTool.tsx"],
|
|
4
|
-
"sourcesContent": ["/**\n * Task Stop Tool\n *\n * Stops a running background task by its ID.\n * Supports both background shell commands and agent tasks.\n */\n\nimport { Box, Text } from 'ink'\nimport React from 'react'\nimport { z } from 'zod'\nimport { Tool } from '@tool'\nimport { DESCRIPTION, PROMPT, TOOL_NAME } from './prompt'\nimport { BackgroundShellManager } from '@utils/BackgroundShellManager'\nimport {\n getAgentTranscript,\n interruptAgentTranscript,\n} from '@utils/agentTranscripts'\nimport { SEMANTIC_COLORS } from '@constants/colors'\n\nconst inputSchema = z.strictObject({\n task_id: z.string().describe('The ID of the background task to stop'),\n shell_id: z.string().optional().describe('Deprecated: use task_id instead'),\n})\n\ntype Output = {\n success: boolean\n message: string\n task_id: string\n task_type: 'shell' | 'agent' | 'unknown'\n}\n\nexport const TaskStopTool = {\n name: TOOL_NAME,\n async description() {\n return DESCRIPTION\n },\n userFacingName() {\n return 'Task Stop'\n },\n inputSchema,\n isReadOnly() {\n return false\n },\n isConcurrencySafe() {\n return true\n },\n async isEnabled() {\n return true\n },\n needsPermissions() {\n return false // Stopping tasks doesn't require user permission\n },\n async prompt() {\n return PROMPT\n },\n renderToolUseMessage(input: z.infer<typeof inputSchema>) {\n const taskId = input.task_id || input.shell_id || ''\n return `task_id: \"${taskId}\"`\n },\n renderToolUseRejectedMessage() {\n return (\n <Box paddingLeft={2}>\n <Text color={SEMANTIC_COLORS.dim}>Task stop request rejected</Text>\n </Box>\n )\n },\n renderToolResultMessage(output: Output) {\n if (!output) {\n return (\n <Box paddingLeft={2}>\n <Text>Task stop completed</Text>\n </Box>\n )\n }\n\n const statusColor = output.success ? 'green' : 'red'\n\n return (\n <Box flexDirection=\"column\" paddingLeft={2}>\n <Box flexDirection=\"row\">\n <Text>{output.task_type === 'agent' ? 'Agent' : 'Task'} </Text>\n <Text bold>{output.task_id}</Text>\n <Text>: </Text>\n <Text color={statusColor}>\n {output.success ? 'stopped' : 'failed'}\n </Text>\n </Box>\n {!output.success && (\n <Box marginTop={1}>\n <Text color={SEMANTIC_COLORS.dim}>{output.message}</Text>\n </Box>\n )}\n </Box>\n )\n },\n renderResultForAssistant(output: Output) {\n return output.message\n },\n async *call(input: z.infer<typeof inputSchema>, _context: any) {\n // Support deprecated shell_id parameter\n const taskId = input.task_id || input.shell_id\n\n if (!taskId) {\n const output: Output = {\n success: false,\n message: 'Error: No task_id provided',\n task_id: '',\n task_type: 'unknown',\n }\n yield {\n type: 'result',\n data: output,\n resultForAssistant: this.renderResultForAssistant(output),\n }\n return\n }\n\n // First, check if this is an agent transcript\n const transcript = getAgentTranscript(taskId)\n if (transcript) {\n // Handle agent transcript\n if (transcript.status !== 'running') {\n const output: Output = {\n success: false,\n message: `Error: Agent '${taskId}' is already ${transcript.status}`,\n task_id: taskId,\n task_type: 'agent',\n }\n yield {\n type: 'result',\n data: output,\n resultForAssistant: this.renderResultForAssistant(output),\n }\n return\n }\n\n // Interrupt the agent\n const updated = interruptAgentTranscript(taskId)\n const success = updated !== null && updated.status === 'interrupted'\n\n const output: Output = {\n success,\n message: success\n ? `Successfully stopped agent '${taskId}'`\n : `Failed to stop agent '${taskId}'`,\n task_id: taskId,\n task_type: 'agent',\n }\n\n yield {\n type: 'result',\n data: output,\n resultForAssistant: this.renderResultForAssistant(output),\n }\n return\n }\n\n // Fall back to background shell\n const manager = BackgroundShellManager.getInstance()\n const shell = manager.get(taskId)\n\n if (!shell) {\n const output: Output = {\n success: false,\n message: `Error: No task found with ID '${taskId}'. This could be a background shell or agent ID.`,\n task_id: taskId,\n task_type: 'unknown',\n }\n yield {\n type: 'result',\n data: output,\n resultForAssistant: this.renderResultForAssistant(output),\n }\n return\n }\n\n if (shell.status !== 'running') {\n const output: Output = {\n success: false,\n message: `Error: Task '${taskId}' is already ${shell.status}`,\n task_id: taskId,\n task_type: 'shell',\n }\n yield {\n type: 'result',\n data: output,\n resultForAssistant: this.renderResultForAssistant(output),\n }\n return\n }\n\n // Kill the shell\n const killed = manager.kill(taskId)\n\n const output: Output = {\n success: killed,\n message: killed\n ? `Successfully stopped background task '${taskId}'`\n : `Failed to stop background task '${taskId}'`,\n task_id: taskId,\n task_type: 'shell',\n }\n\n yield {\n type: 'result',\n data: output,\n resultForAssistant: this.renderResultForAssistant(output),\n }\n },\n} satisfies Tool
|
|
4
|
+
"sourcesContent": ["/**\n * Task Stop Tool\n *\n * Stops a running background task by its ID.\n * Supports both background shell commands and agent tasks.\n */\n\nimport { Box, Text } from 'ink'\nimport React from 'react'\nimport { z } from 'zod'\nimport { Tool } from '@tool'\nimport { DESCRIPTION, PROMPT, TOOL_NAME } from './prompt'\nimport { BackgroundShellManager } from '@utils/BackgroundShellManager'\nimport {\n getAgentTranscript,\n interruptAgentTranscript,\n} from '@utils/agentTranscripts'\nimport { SEMANTIC_COLORS } from '@constants/colors'\n\nconst inputSchema = z.strictObject({\n task_id: z.string().describe('The ID of the background task to stop'),\n shell_id: z.string().optional().describe('Deprecated: use task_id instead'),\n})\n\ntype Output = {\n success: boolean\n message: string\n task_id: string\n task_type: 'shell' | 'agent' | 'unknown'\n}\n\nexport const TaskStopTool = {\n name: TOOL_NAME,\n async description() {\n return DESCRIPTION\n },\n userFacingName() {\n return 'Task Stop'\n },\n inputSchema,\n isReadOnly() {\n return false\n },\n isConcurrencySafe() {\n return true\n },\n async isEnabled() {\n return true\n },\n needsPermissions() {\n return false // Stopping tasks doesn't require user permission\n },\n async prompt() {\n return PROMPT\n },\n renderToolUseMessage(input: z.infer<typeof inputSchema>) {\n const taskId = input.task_id || input.shell_id || ''\n return `task_id: \"${taskId}\"`\n },\n renderToolUseRejectedMessage() {\n return (\n <Box paddingLeft={2}>\n <Text color={SEMANTIC_COLORS.dim}>Task stop request rejected</Text>\n </Box>\n )\n },\n renderToolResultMessage(output: Output) {\n if (!output) {\n return (\n <Box paddingLeft={2}>\n <Text>Task stop completed</Text>\n </Box>\n )\n }\n\n const statusColor = output.success ? 'green' : 'red'\n\n return (\n <Box flexDirection=\"column\" paddingLeft={2}>\n <Box flexDirection=\"row\">\n <Text>{output.task_type === 'agent' ? 'Agent' : 'Task'} </Text>\n <Text bold>{output.task_id}</Text>\n <Text>: </Text>\n <Text color={statusColor}>\n {output.success ? 'stopped' : 'failed'}\n </Text>\n </Box>\n {!output.success && (\n <Box marginTop={1}>\n <Text color={SEMANTIC_COLORS.dim}>{output.message}</Text>\n </Box>\n )}\n </Box>\n )\n },\n renderResultForAssistant(output: Output) {\n return output.message\n },\n async *call(input: z.infer<typeof inputSchema>, _context: any) {\n // Support deprecated shell_id parameter\n const taskId = input.task_id || input.shell_id\n\n if (!taskId) {\n const output: Output = {\n success: false,\n message: 'Error: No task_id provided',\n task_id: '',\n task_type: 'unknown',\n }\n yield {\n type: 'result',\n data: output,\n resultForAssistant: this.renderResultForAssistant(output),\n }\n return\n }\n\n // First, check if this is an agent transcript\n const transcript = getAgentTranscript(taskId)\n if (transcript) {\n // Handle agent transcript\n if (transcript.status !== 'running') {\n const output: Output = {\n success: false,\n message: `Error: Agent '${taskId}' is already ${transcript.status}`,\n task_id: taskId,\n task_type: 'agent',\n }\n yield {\n type: 'result',\n data: output,\n resultForAssistant: this.renderResultForAssistant(output),\n }\n return\n }\n\n // Interrupt the agent\n const updated = interruptAgentTranscript(taskId)\n const success = updated !== null && updated.status === 'interrupted'\n\n const output: Output = {\n success,\n message: success\n ? `Successfully stopped agent '${taskId}'`\n : `Failed to stop agent '${taskId}'`,\n task_id: taskId,\n task_type: 'agent',\n }\n\n yield {\n type: 'result',\n data: output,\n resultForAssistant: this.renderResultForAssistant(output),\n }\n return\n }\n\n // Fall back to background shell\n const manager = BackgroundShellManager.getInstance()\n const shell = manager.get(taskId)\n\n if (!shell) {\n const output: Output = {\n success: false,\n message: `Error: No task found with ID '${taskId}'. This could be a background shell or agent ID.`,\n task_id: taskId,\n task_type: 'unknown',\n }\n yield {\n type: 'result',\n data: output,\n resultForAssistant: this.renderResultForAssistant(output),\n }\n return\n }\n\n if (shell.status !== 'running') {\n const output: Output = {\n success: false,\n message: `Error: Task '${taskId}' is already ${shell.status}`,\n task_id: taskId,\n task_type: 'shell',\n }\n yield {\n type: 'result',\n data: output,\n resultForAssistant: this.renderResultForAssistant(output),\n }\n return\n }\n\n // Kill the shell\n const killed = manager.kill(taskId)\n\n const output: Output = {\n success: killed,\n message: killed\n ? `Successfully stopped background task '${taskId}'`\n : `Failed to stop background task '${taskId}'`,\n task_id: taskId,\n task_type: 'shell',\n }\n\n yield {\n type: 'result',\n data: output,\n resultForAssistant: this.renderResultForAssistant(output),\n }\n },\n} satisfies Tool\n"],
|
|
5
5
|
"mappings": "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",
|
|
6
6
|
"names": ["output"]
|
|
7
7
|
}
|