|
@@ -43,6 +43,7 @@ import type { ApplyPatchTool } from "@/tool/apply_patch"
|
|
|
import type { WebFetchTool } from "@/tool/webfetch"
|
|
import type { WebFetchTool } from "@/tool/webfetch"
|
|
|
import type { TaskTool } from "@/tool/task"
|
|
import type { TaskTool } from "@/tool/task"
|
|
|
import type { QuestionTool } from "@/tool/question"
|
|
import type { QuestionTool } from "@/tool/question"
|
|
|
|
|
+import type { SkillTool } from "@/tool/skill"
|
|
|
import { useKeyboard, useRenderer, useTerminalDimensions, type JSX } from "@opentui/solid"
|
|
import { useKeyboard, useRenderer, useTerminalDimensions, type JSX } from "@opentui/solid"
|
|
|
import { useSDK } from "@tui/context/sdk"
|
|
import { useSDK } from "@tui/context/sdk"
|
|
|
import { useCommandDialog } from "@tui/component/dialog-command"
|
|
import { useCommandDialog } from "@tui/component/dialog-command"
|
|
@@ -1447,6 +1448,9 @@ function ToolPart(props: { last: boolean; part: ToolPart; message: AssistantMess
|
|
|
<Match when={props.part.tool === "question"}>
|
|
<Match when={props.part.tool === "question"}>
|
|
|
<Question {...toolprops} />
|
|
<Question {...toolprops} />
|
|
|
</Match>
|
|
</Match>
|
|
|
|
|
+ <Match when={props.part.tool === "skill"}>
|
|
|
|
|
+ <Skill {...toolprops} />
|
|
|
|
|
+ </Match>
|
|
|
<Match when={true}>
|
|
<Match when={true}>
|
|
|
<GenericTool {...toolprops} />
|
|
<GenericTool {...toolprops} />
|
|
|
</Match>
|
|
</Match>
|
|
@@ -1797,7 +1801,7 @@ function Task(props: ToolProps<typeof TaskTool>) {
|
|
|
|
|
|
|
|
return (
|
|
return (
|
|
|
<Switch>
|
|
<Switch>
|
|
|
- <Match when={props.metadata.summary?.length}>
|
|
|
|
|
|
|
+ <Match when={props.input.description || props.input.subagent_type}>
|
|
|
<BlockTool
|
|
<BlockTool
|
|
|
title={"# " + Locale.titlecase(props.input.subagent_type ?? "unknown") + " Task"}
|
|
title={"# " + Locale.titlecase(props.input.subagent_type ?? "unknown") + " Task"}
|
|
|
onClick={
|
|
onClick={
|
|
@@ -1809,7 +1813,7 @@ function Task(props: ToolProps<typeof TaskTool>) {
|
|
|
>
|
|
>
|
|
|
<box>
|
|
<box>
|
|
|
<text style={{ fg: theme.textMuted }}>
|
|
<text style={{ fg: theme.textMuted }}>
|
|
|
- {props.input.description} ({props.metadata.summary?.length} toolcalls)
|
|
|
|
|
|
|
+ {props.input.description} ({props.metadata.summary?.length ?? 0} toolcalls)
|
|
|
</text>
|
|
</text>
|
|
|
<Show when={current()}>
|
|
<Show when={current()}>
|
|
|
<text style={{ fg: current()!.state.status === "error" ? theme.error : theme.textMuted }}>
|
|
<text style={{ fg: current()!.state.status === "error" ? theme.error : theme.textMuted }}>
|
|
@@ -1818,22 +1822,17 @@ function Task(props: ToolProps<typeof TaskTool>) {
|
|
|
</text>
|
|
</text>
|
|
|
</Show>
|
|
</Show>
|
|
|
</box>
|
|
</box>
|
|
|
- <text fg={theme.text}>
|
|
|
|
|
- {keybind.print("session_child_cycle")}
|
|
|
|
|
- <span style={{ fg: theme.textMuted }}> view subagents</span>
|
|
|
|
|
- </text>
|
|
|
|
|
|
|
+ <Show when={props.metadata.sessionId}>
|
|
|
|
|
+ <text fg={theme.text}>
|
|
|
|
|
+ {keybind.print("session_child_cycle")}
|
|
|
|
|
+ <span style={{ fg: theme.textMuted }}> view subagents</span>
|
|
|
|
|
+ </text>
|
|
|
|
|
+ </Show>
|
|
|
</BlockTool>
|
|
</BlockTool>
|
|
|
</Match>
|
|
</Match>
|
|
|
<Match when={true}>
|
|
<Match when={true}>
|
|
|
- <InlineTool
|
|
|
|
|
- icon="◉"
|
|
|
|
|
- iconColor={color()}
|
|
|
|
|
- pending="Delegating..."
|
|
|
|
|
- complete={props.input.subagent_type ?? props.input.description}
|
|
|
|
|
- part={props.part}
|
|
|
|
|
- >
|
|
|
|
|
- <span style={{ fg: theme.text }}>{Locale.titlecase(props.input.subagent_type ?? "unknown")}</span> Task "
|
|
|
|
|
- {props.input.description}"
|
|
|
|
|
|
|
+ <InlineTool icon="#" pending="Delegating..." complete={props.input.subagent_type} part={props.part}>
|
|
|
|
|
+ {props.input.subagent_type} Task {props.input.description}
|
|
|
</InlineTool>
|
|
</InlineTool>
|
|
|
</Match>
|
|
</Match>
|
|
|
</Switch>
|
|
</Switch>
|
|
@@ -2038,6 +2037,14 @@ function Question(props: ToolProps<typeof QuestionTool>) {
|
|
|
)
|
|
)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+function Skill(props: ToolProps<typeof SkillTool>) {
|
|
|
|
|
+ return (
|
|
|
|
|
+ <InlineTool icon="→" pending="Loading skill..." complete={props.input.name} part={props.part}>
|
|
|
|
|
+ Skill "{props.input.name}"
|
|
|
|
|
+ </InlineTool>
|
|
|
|
|
+ )
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
function normalizePath(input?: string) {
|
|
function normalizePath(input?: string) {
|
|
|
if (!input) return ""
|
|
if (!input) return ""
|
|
|
if (path.isAbsolute(input)) {
|
|
if (path.isAbsolute(input)) {
|