@oh-my-pi/pi-coding-agent 15.10.4 → 15.10.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +74 -0
- package/dist/types/capability/rule-buckets.d.ts +1 -1
- package/dist/types/capability/rule.d.ts +6 -1
- package/dist/types/cli/update-cli.d.ts +11 -1
- package/dist/types/config/model-registry.d.ts +18 -1
- package/dist/types/discovery/at-imports.d.ts +15 -0
- package/dist/types/edit/diff.d.ts +3 -2
- package/dist/types/eval/__tests__/helpers-local-roots.test.d.ts +1 -0
- package/dist/types/eval/backend.d.ts +7 -0
- package/dist/types/eval/js/context-manager.d.ts +1 -0
- package/dist/types/eval/js/executor.d.ts +2 -0
- package/dist/types/eval/js/index.d.ts +1 -1
- package/dist/types/eval/js/shared/helpers.d.ts +6 -0
- package/dist/types/eval/js/shared/runtime.d.ts +5 -0
- package/dist/types/eval/js/worker-protocol.d.ts +6 -0
- package/dist/types/eval/py/executor.d.ts +7 -0
- package/dist/types/eval/py/index.d.ts +1 -1
- package/dist/types/exa/index.d.ts +1 -19
- package/dist/types/exa/mcp-client.d.ts +10 -3
- package/dist/types/exa/types.d.ts +0 -83
- package/dist/types/export/ttsr.d.ts +14 -0
- package/dist/types/extensibility/extensions/types.d.ts +8 -1
- package/dist/types/extensibility/legacy-pi-ai-shim.d.ts +1 -1
- package/dist/types/internal-urls/local-protocol.d.ts +10 -0
- package/dist/types/mcp/oauth-flow.d.ts +2 -2
- package/dist/types/modes/components/custom-editor.d.ts +3 -0
- package/dist/types/modes/components/{status-line.d.ts → status-line/component.d.ts} +2 -32
- package/dist/types/modes/components/status-line/index.d.ts +1 -0
- package/dist/types/modes/components/status-line/types.d.ts +31 -2
- package/dist/types/modes/controllers/mcp-command-controller.d.ts +8 -0
- package/dist/types/modes/image-references.d.ts +8 -3
- package/dist/types/modes/interactive-mode.d.ts +9 -1
- package/dist/types/modes/theme/theme.d.ts +2 -1
- package/dist/types/modes/types.d.ts +3 -1
- package/dist/types/modes/utils/ui-helpers.d.ts +2 -2
- package/dist/types/session/agent-session.d.ts +0 -2
- package/dist/types/task/render.d.ts +1 -0
- package/dist/types/tools/ask.d.ts +1 -0
- package/dist/types/tools/browser/tab-worker.d.ts +15 -0
- package/dist/types/tools/index.d.ts +17 -2
- package/dist/types/tools/render-utils.d.ts +1 -1
- package/dist/types/tools/tool-timeouts.d.ts +1 -1
- package/dist/types/utils/block-context.d.ts +35 -0
- package/dist/types/utils/git.d.ts +6 -0
- package/dist/types/utils/image-loading.d.ts +12 -0
- package/package.json +29 -9
- package/src/capability/rule-buckets.ts +4 -2
- package/src/capability/rule.ts +10 -1
- package/src/cli/auth-broker-cli.ts +6 -7
- package/src/cli/auth-gateway-cli.ts +4 -3
- package/src/cli/list-models.ts +5 -0
- package/src/cli/update-cli.ts +138 -16
- package/src/commit/agentic/tools/split-commit.ts +8 -1
- package/src/config/model-provider-priority.ts +1 -0
- package/src/config/model-registry.ts +81 -2
- package/src/debug/index.ts +4 -8
- package/src/discovery/at-imports.ts +273 -0
- package/src/discovery/builtin-rules/index.ts +4 -0
- package/src/discovery/builtin-rules/ts-no-test-timers.md +55 -0
- package/src/discovery/builtin-rules/ts-redundant-clear-guard.md +75 -0
- package/src/discovery/helpers.ts +2 -1
- package/src/edit/diff.ts +114 -4
- package/src/edit/hashline/diff.ts +1 -1
- package/src/edit/hashline/execute.ts +1 -1
- package/src/edit/modes/patch.ts +6 -2
- package/src/edit/modes/replace.ts +1 -1
- package/src/edit/renderer.ts +12 -2
- package/src/eval/__tests__/helpers-local-roots.test.ts +58 -0
- package/src/eval/backend.ts +15 -0
- package/src/eval/js/context-manager.ts +4 -2
- package/src/eval/js/executor.ts +3 -0
- package/src/eval/js/index.ts +7 -1
- package/src/eval/js/shared/helpers.ts +53 -6
- package/src/eval/js/shared/runtime.ts +8 -0
- package/src/eval/js/worker-core.ts +1 -0
- package/src/eval/js/worker-protocol.ts +6 -0
- package/src/eval/py/executor.ts +12 -0
- package/src/eval/py/index.ts +7 -1
- package/src/eval/py/prelude.py +43 -4
- package/src/eval/py/runner.py +1 -0
- package/src/exa/index.ts +1 -26
- package/src/exa/mcp-client.ts +10 -10
- package/src/exa/types.ts +0 -97
- package/src/export/ttsr.ts +122 -1
- package/src/extensibility/extensions/types.ts +8 -1
- package/src/extensibility/legacy-pi-ai-shim.ts +1 -1
- package/src/extensibility/plugins/doctor.ts +1 -1
- package/src/extensibility/plugins/legacy-pi-compat.ts +6 -5
- package/src/goals/tools/goal-tool.ts +1 -1
- package/src/internal-urls/docs-index.generated.ts +7 -6
- package/src/internal-urls/local-protocol.ts +13 -0
- package/src/lsp/render.ts +8 -6
- package/src/mcp/oauth-flow.ts +3 -3
- package/src/mcp/render.ts +7 -1
- package/src/modes/components/agent-dashboard.ts +6 -4
- package/src/modes/components/custom-editor.ts +12 -6
- package/src/modes/components/login-dialog.ts +1 -1
- package/src/modes/components/oauth-selector.ts +4 -4
- package/src/modes/components/read-tool-group.ts +10 -3
- package/src/modes/components/{status-line.ts → status-line/component.ts} +18 -40
- package/src/modes/components/status-line/index.ts +1 -0
- package/src/modes/components/status-line/types.ts +23 -8
- package/src/modes/components/tool-execution.ts +1 -1
- package/src/modes/components/transcript-container.ts +17 -10
- package/src/modes/components/user-message.ts +6 -3
- package/src/modes/components/welcome.ts +1 -1
- package/src/modes/controllers/event-controller.ts +8 -0
- package/src/modes/controllers/extension-ui-controller.ts +143 -127
- package/src/modes/controllers/input-controller.ts +60 -11
- package/src/modes/controllers/mcp-command-controller.ts +52 -17
- package/src/modes/controllers/selector-controller.ts +4 -11
- package/src/modes/controllers/ssh-command-controller.ts +2 -2
- package/src/modes/image-references.ts +13 -7
- package/src/modes/interactive-mode.ts +35 -3
- package/src/modes/rpc/rpc-mode.ts +1 -1
- package/src/modes/setup-wizard/scenes/sign-in.ts +3 -11
- package/src/modes/theme/theme.ts +95 -1
- package/src/modes/types.ts +3 -1
- package/src/modes/utils/ui-helpers.ts +14 -5
- package/src/prompts/tools/bash.md +1 -1
- package/src/prompts/tools/eval.md +4 -4
- package/src/sdk.ts +31 -14
- package/src/session/agent-session.ts +290 -196
- package/src/session/session-manager.ts +1 -1
- package/src/slash-commands/builtin-registry.ts +9 -1
- package/src/system-prompt.ts +15 -9
- package/src/task/index.ts +9 -1
- package/src/task/render.ts +36 -14
- package/src/tools/ask.ts +14 -5
- package/src/tools/bash-interactive.ts +1 -1
- package/src/tools/bash.ts +14 -2
- package/src/tools/browser/render.ts +5 -2
- package/src/tools/browser/tab-worker.ts +211 -91
- package/src/tools/debug.ts +5 -2
- package/src/tools/eval-render.ts +6 -3
- package/src/tools/eval.ts +1 -1
- package/src/tools/gh-renderer.ts +29 -15
- package/src/tools/index.ts +32 -4
- package/src/tools/inspect-image-renderer.ts +12 -5
- package/src/tools/job.ts +9 -6
- package/src/tools/memory-render.ts +19 -5
- package/src/tools/read.ts +165 -18
- package/src/tools/render-utils.ts +3 -1
- package/src/tools/resolve.ts +1 -1
- package/src/tools/review.ts +1 -1
- package/src/tools/ssh.ts +4 -1
- package/src/tools/todo.ts +8 -1
- package/src/tools/tool-timeouts.ts +1 -1
- package/src/tools/write.ts +1 -1
- package/src/tui/code-cell.ts +1 -1
- package/src/utils/block-context.ts +312 -0
- package/src/utils/git.ts +41 -0
- package/src/utils/image-loading.ts +31 -1
- package/src/web/search/providers/codex.ts +1 -1
- package/src/web/search/render.ts +14 -6
- package/dist/types/exa/factory.d.ts +0 -13
- package/dist/types/exa/render.d.ts +0 -19
- package/dist/types/exa/researcher.d.ts +0 -9
- package/dist/types/exa/search.d.ts +0 -9
- package/dist/types/exa/websets.d.ts +0 -9
- package/src/exa/factory.ts +0 -60
- package/src/exa/render.ts +0 -244
- package/src/exa/researcher.ts +0 -36
- package/src/exa/search.ts +0 -47
- package/src/exa/websets.ts +0 -248
|
@@ -3558,7 +3558,7 @@ export class SessionManager {
|
|
|
3558
3558
|
}
|
|
3559
3559
|
const relocated = sourceCwdGone && (mostRecent === null || (mostRecentIsBreadcrumb && !hasCurrentCwdSession));
|
|
3560
3560
|
if (relocated) {
|
|
3561
|
-
|
|
3561
|
+
logger.info("Re-rooting moved session", { from: resolvedBreadcrumbCwd, to: resolvedCwd });
|
|
3562
3562
|
const manager = await SessionManager.open(breadcrumb.sessionFile, undefined, storage);
|
|
3563
3563
|
await manager.moveTo(cwd, sessionDir);
|
|
3564
3564
|
return manager;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as fs from "node:fs/promises";
|
|
2
2
|
import * as os from "node:os";
|
|
3
3
|
import * as path from "node:path";
|
|
4
|
-
import { getOAuthProviders } from "@oh-my-pi/pi-ai/
|
|
4
|
+
import { getOAuthProviders } from "@oh-my-pi/pi-ai/oauth";
|
|
5
5
|
import { Snowflake, setProjectDir } from "@oh-my-pi/pi-utils";
|
|
6
6
|
import { $ } from "bun";
|
|
7
7
|
import type { SettingPath, SettingValue } from "../config/settings";
|
|
@@ -100,6 +100,14 @@ const BUILTIN_SLASH_COMMAND_REGISTRY: ReadonlyArray<SlashCommandSpec> = [
|
|
|
100
100
|
runtime.ctx.editor.setText("");
|
|
101
101
|
},
|
|
102
102
|
},
|
|
103
|
+
{
|
|
104
|
+
name: "plan-review",
|
|
105
|
+
description: "Re-open the plan review for the latest plan (plan mode only)",
|
|
106
|
+
handleTui: async (_command, runtime) => {
|
|
107
|
+
await runtime.ctx.openPlanReview();
|
|
108
|
+
runtime.ctx.editor.setText("");
|
|
109
|
+
},
|
|
110
|
+
},
|
|
103
111
|
{
|
|
104
112
|
name: "goal",
|
|
105
113
|
description: "Toggle goal mode (persistent autonomous objective for this session)",
|
package/src/system-prompt.ts
CHANGED
|
@@ -10,6 +10,7 @@ import { contextFileCapability } from "./capability/context-file";
|
|
|
10
10
|
import { systemPromptCapability } from "./capability/system-prompt";
|
|
11
11
|
import type { SkillsSettings } from "./config/settings";
|
|
12
12
|
import { type ContextFile, loadCapability, type SystemPrompt as SystemPromptFile } from "./discovery";
|
|
13
|
+
import { expandAtImports } from "./discovery/at-imports";
|
|
13
14
|
import { loadSkills, type Skill } from "./extensibility/skills";
|
|
14
15
|
import { hasObsidian } from "./internal-urls/vault-protocol";
|
|
15
16
|
import customSystemPromptTemplate from "./prompts/system/custom-system-prompt.md" with { type: "text" };
|
|
@@ -254,15 +255,20 @@ export async function loadProjectContextFiles(
|
|
|
254
255
|
|
|
255
256
|
const result = await loadCapability(contextFileCapability.id, { cwd: resolvedCwd });
|
|
256
257
|
|
|
257
|
-
//
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
258
|
+
// Materialize ContextFile items, expanding any `@path/to/file` includes
|
|
259
|
+
// in their content. The expansion uses the file's own directory as the
|
|
260
|
+
// resolution base so relative imports work the same way Claude Code,
|
|
261
|
+
// Goose, and other tools document.
|
|
262
|
+
const files = await Promise.all(
|
|
263
|
+
result.items.map(async item => {
|
|
264
|
+
const contextFile = item as ContextFile;
|
|
265
|
+
return {
|
|
266
|
+
path: contextFile.path,
|
|
267
|
+
content: await expandAtImports(contextFile.content, contextFile.path),
|
|
268
|
+
depth: contextFile.depth,
|
|
269
|
+
};
|
|
270
|
+
}),
|
|
271
|
+
);
|
|
266
272
|
|
|
267
273
|
// Sort by depth (descending): higher depth (farther from cwd) comes first,
|
|
268
274
|
// so files closer to cwd appear later and are more prominent
|
package/src/task/index.ts
CHANGED
|
@@ -158,6 +158,8 @@ export const READ_ONLY_TOOL_NAMES: ReadonlySet<string> = new Set([
|
|
|
158
158
|
"search_tool_bm25",
|
|
159
159
|
]);
|
|
160
160
|
|
|
161
|
+
const PLAN_MODE_AGENT_TOOL_ALLOWLIST: ReadonlySet<string> = new Set(["ast_grep", "report_finding"]);
|
|
162
|
+
|
|
161
163
|
export function isReadOnlyAgent(agent: AgentDefinition): boolean {
|
|
162
164
|
return !!agent.tools?.length && agent.tools.every(tool => READ_ONLY_TOOL_NAMES.has(tool));
|
|
163
165
|
}
|
|
@@ -677,7 +679,13 @@ export class TaskTool implements AgentTool<TaskToolSchemaInstance, TaskToolDetai
|
|
|
677
679
|
}
|
|
678
680
|
|
|
679
681
|
const planModeState = this.session.getPlanModeState?.();
|
|
680
|
-
const
|
|
682
|
+
const planModeBaseTools = ["read", "search", "find", "lsp", "web_search"];
|
|
683
|
+
const planModeTools = [
|
|
684
|
+
...planModeBaseTools,
|
|
685
|
+
...(agent.tools ?? []).filter(
|
|
686
|
+
tool => PLAN_MODE_AGENT_TOOL_ALLOWLIST.has(tool) && !planModeBaseTools.includes(tool),
|
|
687
|
+
),
|
|
688
|
+
];
|
|
681
689
|
const effectiveAgent: typeof agent = planModeState?.enabled
|
|
682
690
|
? {
|
|
683
691
|
...agent,
|
package/src/task/render.ts
CHANGED
|
@@ -632,7 +632,7 @@ function renderAgentProgress(
|
|
|
632
632
|
const indent = prefix ? `${prefix} ` : "";
|
|
633
633
|
let statusLine: string;
|
|
634
634
|
if (progress.status === "running") {
|
|
635
|
-
const bullet = theme.
|
|
635
|
+
const bullet = theme.styledSymbol("status.done", "text");
|
|
636
636
|
const name = theme.fg("accent", description ? theme.bold(displayId) : displayId);
|
|
637
637
|
statusLine = `${indent}${bullet} ${name}`;
|
|
638
638
|
if (description) {
|
|
@@ -640,7 +640,9 @@ function renderAgentProgress(
|
|
|
640
640
|
statusLine += `${theme.fg("accent", ":")} ${desc}`;
|
|
641
641
|
}
|
|
642
642
|
} else {
|
|
643
|
-
|
|
643
|
+
const glyph =
|
|
644
|
+
progress.status === "completed" ? theme.styledSymbol("status.done", "accent") : theme.fg(iconColor, icon);
|
|
645
|
+
statusLine = `${indent}${glyph} ${theme.fg("accent", titlePart)}`;
|
|
644
646
|
}
|
|
645
647
|
|
|
646
648
|
// Show retry-blocked badge so the parent immediately sees that a child
|
|
@@ -807,12 +809,15 @@ function renderReviewResult(
|
|
|
807
809
|
|
|
808
810
|
// Verdict line
|
|
809
811
|
const verdictColor = summary.overall_correctness === "correct" ? "success" : "error";
|
|
810
|
-
const
|
|
812
|
+
const isCorrect = summary.overall_correctness === "correct";
|
|
813
|
+
const verdictIcon = isCorrect
|
|
814
|
+
? theme.styledSymbol("status.done", "accent")
|
|
815
|
+
: theme.fg(verdictColor, theme.status.error);
|
|
811
816
|
lines.push(
|
|
812
|
-
`${continuePrefix} Patch is ${theme.fg(verdictColor, summary.overall_correctness)} ${theme.fg(
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
)}
|
|
817
|
+
`${continuePrefix} Patch is ${theme.fg(verdictColor, summary.overall_correctness)} ${verdictIcon} ${theme.fg(
|
|
818
|
+
"dim",
|
|
819
|
+
`(${(summary.confidence * 100).toFixed(0)}% confidence)`,
|
|
820
|
+
)}`,
|
|
816
821
|
);
|
|
817
822
|
|
|
818
823
|
// Explanation preview (first ~80 chars when collapsed, full when expanded)
|
|
@@ -913,7 +918,7 @@ function renderAgentResult(
|
|
|
913
918
|
: needsWarning
|
|
914
919
|
? theme.status.warning
|
|
915
920
|
: success
|
|
916
|
-
? theme.status.
|
|
921
|
+
? theme.styledSymbol("status.done", "accent")
|
|
917
922
|
: theme.status.error;
|
|
918
923
|
const iconColor = needsWarning ? "warning" : success ? "success" : mergeFailed ? "warning" : "error";
|
|
919
924
|
const statusText = aborted
|
|
@@ -1071,7 +1076,7 @@ function renderAgentResult(
|
|
|
1071
1076
|
* Render the tool result.
|
|
1072
1077
|
*/
|
|
1073
1078
|
export function renderResult(
|
|
1074
|
-
result: { content: Array<{ type: string; text?: string }>; details?: TaskToolDetails },
|
|
1079
|
+
result: { content: Array<{ type: string; text?: string }>; details?: TaskToolDetails; isError?: boolean },
|
|
1075
1080
|
options: RenderResultOptions,
|
|
1076
1081
|
theme: Theme,
|
|
1077
1082
|
args?: TaskParams,
|
|
@@ -1082,15 +1087,25 @@ export function renderResult(
|
|
|
1082
1087
|
|
|
1083
1088
|
if (!details) {
|
|
1084
1089
|
const text = result.content.find(c => c.type === "text")?.text || "";
|
|
1085
|
-
const
|
|
1090
|
+
const errored = result.isError === true;
|
|
1091
|
+
const header = errored
|
|
1092
|
+
? renderStatusLine({ icon: "error", title: "Task", description: args?.agent }, theme)
|
|
1093
|
+
: renderStatusLine(
|
|
1094
|
+
{
|
|
1095
|
+
iconOverride: theme.styledSymbol("status.done", "accent"),
|
|
1096
|
+
title: "Task",
|
|
1097
|
+
description: args?.agent,
|
|
1098
|
+
},
|
|
1099
|
+
theme,
|
|
1100
|
+
);
|
|
1086
1101
|
return framedBlock(theme, width => ({
|
|
1087
1102
|
header,
|
|
1088
1103
|
sections: [
|
|
1089
1104
|
...(contextSectionRenderer ? [contextSectionRenderer(width)] : []),
|
|
1090
1105
|
...(text ? [{ separator: true, lines: [theme.fg("dim", truncateToWidth(text, width))] }] : []),
|
|
1091
1106
|
],
|
|
1092
|
-
state: "success",
|
|
1093
|
-
borderColor: "borderMuted",
|
|
1107
|
+
state: errored ? "error" : "success",
|
|
1108
|
+
borderColor: errored ? "error" : "borderMuted",
|
|
1094
1109
|
width,
|
|
1095
1110
|
}));
|
|
1096
1111
|
}
|
|
@@ -1102,11 +1117,18 @@ export function renderResult(
|
|
|
1102
1117
|
const isError = aborted || failed;
|
|
1103
1118
|
const agentCount = hasResults ? details.results.length : (details.progress?.length ?? 0);
|
|
1104
1119
|
const icon: ToolUIStatus = options.isPartial ? "running" : isError ? "error" : mergeFailed ? "warning" : "success";
|
|
1120
|
+
// Surface the dispatched agent type (e.g. `Reviewer`) alongside the count so
|
|
1121
|
+
// the header reads `Task 16 agents: Reviewer`. All tasks in one call share a
|
|
1122
|
+
// single `agent` type (top-level param), so one label covers the whole batch.
|
|
1123
|
+
const agentName = args?.agent?.trim();
|
|
1124
|
+
const countLabel = agentCount > 0 ? `${agentCount} ${agentCount === 1 ? "agent" : "agents"}` : undefined;
|
|
1125
|
+
const metaLabel = countLabel ? (agentName ? `${countLabel}: ${agentName}` : countLabel) : agentName;
|
|
1105
1126
|
const header = renderStatusLine(
|
|
1106
1127
|
{
|
|
1107
|
-
icon,
|
|
1128
|
+
icon: icon === "success" ? undefined : icon,
|
|
1129
|
+
iconOverride: icon === "success" ? theme.styledSymbol("status.done", "accent") : undefined,
|
|
1108
1130
|
title: "Task",
|
|
1109
|
-
meta:
|
|
1131
|
+
meta: metaLabel ? [metaLabel] : undefined,
|
|
1110
1132
|
},
|
|
1111
1133
|
theme,
|
|
1112
1134
|
);
|
package/src/tools/ask.ts
CHANGED
|
@@ -96,7 +96,7 @@ const OTHER_OPTION = "Other (type your own)";
|
|
|
96
96
|
const RECOMMENDED_SUFFIX = " (Recommended)";
|
|
97
97
|
|
|
98
98
|
function getDoneOptionLabel(): string {
|
|
99
|
-
return `${theme.
|
|
99
|
+
return `${theme.symbol("tool.ask")} Done selecting`;
|
|
100
100
|
}
|
|
101
101
|
|
|
102
102
|
/** Add "(Recommended)" suffix to the option at the given index if not already present */
|
|
@@ -407,6 +407,12 @@ export class AskTool implements AgentTool<typeof askSchema, AskToolDetails> {
|
|
|
407
407
|
readonly description: string;
|
|
408
408
|
readonly parameters = askSchema;
|
|
409
409
|
readonly strict = true;
|
|
410
|
+
// Run alone in its tool batch. The interactive selector/editor is a single
|
|
411
|
+
// shared UI surface (`ExtensionUiController.showHookSelector` has no queue and
|
|
412
|
+
// overwrites `ctx.hookSelector` on each call), so two concurrent `ask` calls
|
|
413
|
+
// would clobber each other: the second steals focus and orphans the first,
|
|
414
|
+
// whose promise then hangs until the user aborts the whole turn.
|
|
415
|
+
readonly concurrency = "exclusive";
|
|
410
416
|
readonly loadMode = "discoverable";
|
|
411
417
|
|
|
412
418
|
constructor(private readonly session: ToolSession) {
|
|
@@ -621,9 +627,7 @@ interface AskRenderArgs {
|
|
|
621
627
|
/** Render a custom free-text answer as a status line plus indented continuation rows. */
|
|
622
628
|
function renderCustomInputLines(uiTheme: Theme, customInput: string): string[] {
|
|
623
629
|
const lines = customInput.split("\n");
|
|
624
|
-
const out: string[] = [
|
|
625
|
-
` ${uiTheme.styledSymbol("status.success", "success")} ${uiTheme.fg("toolOutput", lines[0] ?? "")}`,
|
|
626
|
-
];
|
|
630
|
+
const out: string[] = [` ${uiTheme.styledSymbol("tool.ask", "accent")} ${uiTheme.fg("toolOutput", lines[0] ?? "")}`];
|
|
627
631
|
for (let i = 1; i < lines.length; i++) out.push(` ${uiTheme.fg("toolOutput", lines[i])}`);
|
|
628
632
|
return out;
|
|
629
633
|
}
|
|
@@ -814,7 +818,12 @@ export const askToolRenderer = {
|
|
|
814
818
|
const question = details.question;
|
|
815
819
|
const hasSelection =
|
|
816
820
|
details.customInput !== undefined || (details.selectedOptions && details.selectedOptions.length > 0);
|
|
817
|
-
const header = renderStatusLine(
|
|
821
|
+
const header = renderStatusLine(
|
|
822
|
+
hasSelection
|
|
823
|
+
? { iconOverride: uiTheme.styledSymbol("tool.ask", "accent"), title: "Ask" }
|
|
824
|
+
: { icon: "warning", title: "Ask" },
|
|
825
|
+
uiTheme,
|
|
826
|
+
);
|
|
818
827
|
const dOptions = details.options;
|
|
819
828
|
const dSelected = details.selectedOptions;
|
|
820
829
|
const dMulti = details.multi;
|
|
@@ -246,7 +246,7 @@ class BashInteractiveOverlayComponent implements Component {
|
|
|
246
246
|
this.#state === "running"
|
|
247
247
|
? formatStatusIcon("running", this.uiTheme)
|
|
248
248
|
: this.#state === "complete" && this.#exitCode === 0
|
|
249
|
-
?
|
|
249
|
+
? this.uiTheme.styledSymbol("tool.bash", "accent")
|
|
250
250
|
: formatStatusIcon("warning", this.uiTheme);
|
|
251
251
|
const title = this.uiTheme.fg("accent", "Console");
|
|
252
252
|
const statusBadge = `${this.uiTheme.fg("dim", this.uiTheme.format.bracketLeft)}${this.#stateText()}${this.uiTheme.fg("dim", this.uiTheme.format.bracketRight)}`;
|
package/src/tools/bash.ts
CHANGED
|
@@ -1151,11 +1151,23 @@ export function createShellRenderer<TArgs>(config: ShellRendererConfig<TArgs>) {
|
|
|
1151
1151
|
const renderArgs = toBashRenderArgs(args, config);
|
|
1152
1152
|
const cmdLines = args ? formatBashCommandLines(renderArgs, uiTheme) : undefined;
|
|
1153
1153
|
const isError = result.isError === true;
|
|
1154
|
-
const
|
|
1154
|
+
const isPartial = options.isPartial === true;
|
|
1155
|
+
const success = !isPartial && !isError;
|
|
1155
1156
|
const header =
|
|
1156
1157
|
config.showHeader === false
|
|
1157
1158
|
? undefined
|
|
1158
|
-
: renderStatusLine(
|
|
1159
|
+
: renderStatusLine(
|
|
1160
|
+
success
|
|
1161
|
+
? {
|
|
1162
|
+
iconOverride: uiTheme.styledSymbol("tool.bash", "accent"),
|
|
1163
|
+
title: config.resolveTitle(args, options),
|
|
1164
|
+
}
|
|
1165
|
+
: {
|
|
1166
|
+
icon: isPartial ? "pending" : "error",
|
|
1167
|
+
title: config.resolveTitle(args, options),
|
|
1168
|
+
},
|
|
1169
|
+
uiTheme,
|
|
1170
|
+
);
|
|
1159
1171
|
const details = result.details;
|
|
1160
1172
|
const outputBlock = new CachedOutputBlock();
|
|
1161
1173
|
|
|
@@ -146,7 +146,7 @@ function renderOpenOrCloseLine(
|
|
|
146
146
|
const action = (details?.action ?? args.action ?? "open") as "open" | "close" | "run";
|
|
147
147
|
const status = cellStatus(isPartial, isError);
|
|
148
148
|
const icon =
|
|
149
|
-
status === "complete" ? "
|
|
149
|
+
status === "complete" ? "done" : status === "error" ? "error" : status === "running" ? "running" : "pending";
|
|
150
150
|
|
|
151
151
|
let title: string;
|
|
152
152
|
if (action === "close") {
|
|
@@ -163,7 +163,10 @@ function renderOpenOrCloseLine(
|
|
|
163
163
|
const url = details?.url ?? args.url;
|
|
164
164
|
if (url) meta.push(shortenPath(url));
|
|
165
165
|
|
|
166
|
-
const header =
|
|
166
|
+
const header =
|
|
167
|
+
status === "complete"
|
|
168
|
+
? renderStatusLine({ iconOverride: theme.styledSymbol("tool.browser", "accent"), title, meta }, theme)
|
|
169
|
+
: renderStatusLine({ icon, title, meta }, theme);
|
|
167
170
|
if (!output) return new Text(header, 0, 0);
|
|
168
171
|
const outputLines = output.split("\n").map(line => theme.fg("toolOutput", replaceTabs(line)));
|
|
169
172
|
return new Text([header, ...outputLines].join("\n"), 0, 0);
|