feat(gsd): add renderCall/renderResult previews to DB tools (#2273)
Add inline rendering to gsd_decision_save, gsd_requirement_update, gsd_summary_save, and gsd_milestone_generate_id so the TUI shows meaningful context during and after tool execution instead of generic static labels. Before: '⏳ Save Decision' (no context) After: '⏳ decision_save [architecture] Use SQLite — better-sqlite3' '✓ Decision D042 saved → DECISIONS.md' Follows the established pattern from context7 and search-the-web: {toolTitle bold name} {accent primary arg} {muted/dim metadata} Closes #2236
This commit is contained in:
parent
58631bba2b
commit
98f5daeda8
1 changed files with 61 additions and 0 deletions
|
|
@ -1,5 +1,6 @@
|
|||
import { Type } from "@sinclair/typebox";
|
||||
import type { ExtensionAPI } from "@gsd/pi-coding-agent";
|
||||
import { Text } from "@gsd/pi-tui";
|
||||
|
||||
import { findMilestoneIds, nextMilestoneId, claimReservedId, getReservedMilestoneIds } from "../guided-flow.js";
|
||||
import { loadEffectiveGSDPreferences } from "../preferences.js";
|
||||
|
|
@ -87,6 +88,22 @@ export function registerDbTools(pi: ExtensionAPI): void {
|
|||
], { description: "Who made this decision: 'human' (user directed), 'agent' (LLM decided autonomously), or 'collaborative' (discussed and agreed). Default: 'agent'" })),
|
||||
}),
|
||||
execute: decisionSaveExecute,
|
||||
renderCall(args: any, theme: any) {
|
||||
let text = theme.fg("toolTitle", theme.bold("decision_save "));
|
||||
if (args.scope) text += theme.fg("accent", `[${args.scope}] `);
|
||||
if (args.decision) text += theme.fg("muted", args.decision);
|
||||
if (args.choice) text += theme.fg("dim", ` — ${args.choice}`);
|
||||
return new Text(text, 0, 0);
|
||||
},
|
||||
renderResult(result: any, _options: any, theme: any) {
|
||||
const d = result.details;
|
||||
if (result.isError || d?.error) {
|
||||
return new Text(theme.fg("error", `Error: ${d?.error ?? "unknown"}`), 0, 0);
|
||||
}
|
||||
let text = theme.fg("success", `Decision ${d?.id ?? ""} saved`);
|
||||
if (d?.id) text += theme.fg("dim", ` → DECISIONS.md`);
|
||||
return new Text(text, 0, 0);
|
||||
},
|
||||
};
|
||||
|
||||
pi.registerTool(decisionSaveTool);
|
||||
|
|
@ -157,6 +174,22 @@ export function registerDbTools(pi: ExtensionAPI): void {
|
|||
supporting_slices: Type.Optional(Type.String({ description: "Supporting slices" })),
|
||||
}),
|
||||
execute: requirementUpdateExecute,
|
||||
renderCall(args: any, theme: any) {
|
||||
let text = theme.fg("toolTitle", theme.bold("requirement_update "));
|
||||
if (args.id) text += theme.fg("accent", args.id);
|
||||
const fields = ["status", "validation", "notes", "description"].filter((f) => args[f]);
|
||||
if (fields.length > 0) text += theme.fg("dim", ` (${fields.join(", ")})`);
|
||||
return new Text(text, 0, 0);
|
||||
},
|
||||
renderResult(result: any, _options: any, theme: any) {
|
||||
const d = result.details;
|
||||
if (result.isError || d?.error) {
|
||||
return new Text(theme.fg("error", `Error: ${d?.error ?? "unknown"}`), 0, 0);
|
||||
}
|
||||
let text = theme.fg("success", `Requirement ${d?.id ?? ""} updated`);
|
||||
text += theme.fg("dim", ` → REQUIREMENTS.md`);
|
||||
return new Text(text, 0, 0);
|
||||
},
|
||||
};
|
||||
|
||||
pi.registerTool(requirementUpdateTool);
|
||||
|
|
@ -235,6 +268,22 @@ export function registerDbTools(pi: ExtensionAPI): void {
|
|||
content: Type.String({ description: "The full markdown content of the artifact" }),
|
||||
}),
|
||||
execute: summarySaveExecute,
|
||||
renderCall(args: any, theme: any) {
|
||||
let text = theme.fg("toolTitle", theme.bold("summary_save "));
|
||||
if (args.artifact_type) text += theme.fg("accent", args.artifact_type);
|
||||
const path = [args.milestone_id, args.slice_id, args.task_id].filter(Boolean).join("/");
|
||||
if (path) text += theme.fg("dim", ` ${path}`);
|
||||
return new Text(text, 0, 0);
|
||||
},
|
||||
renderResult(result: any, _options: any, theme: any) {
|
||||
const d = result.details;
|
||||
if (result.isError || d?.error) {
|
||||
return new Text(theme.fg("error", `Error: ${d?.error ?? "unknown"}`), 0, 0);
|
||||
}
|
||||
let text = theme.fg("success", `${d?.artifact_type ?? "Artifact"} saved`);
|
||||
if (d?.path) text += theme.fg("dim", ` → ${d.path}`);
|
||||
return new Text(text, 0, 0);
|
||||
},
|
||||
};
|
||||
|
||||
pi.registerTool(summarySaveTool);
|
||||
|
|
@ -307,6 +356,18 @@ export function registerDbTools(pi: ExtensionAPI): void {
|
|||
],
|
||||
parameters: Type.Object({}),
|
||||
execute: milestoneGenerateIdExecute,
|
||||
renderCall(_args: any, theme: any) {
|
||||
return new Text(theme.fg("toolTitle", theme.bold("milestone_generate_id")), 0, 0);
|
||||
},
|
||||
renderResult(result: any, _options: any, theme: any) {
|
||||
const d = result.details;
|
||||
if (result.isError || d?.error) {
|
||||
return new Text(theme.fg("error", `Error: ${d?.error ?? "unknown"}`), 0, 0);
|
||||
}
|
||||
let text = theme.fg("success", `Generated ${d?.id ?? "ID"}`);
|
||||
if (d?.source === "reserved") text += theme.fg("dim", " (reserved)");
|
||||
return new Text(text, 0, 0);
|
||||
},
|
||||
};
|
||||
|
||||
pi.registerTool(milestoneGenerateIdTool);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue