@nghyane/arcane 0.1.13 → 0.1.15
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 +28 -0
- package/package.json +21 -70
- package/scripts/format-prompts.ts +1 -3
- package/src/cli/args.ts +2 -7
- package/src/cli/config-cli.ts +1 -1
- package/src/cli/plugin-cli.ts +1 -1
- package/src/cli/setup-cli.ts +1 -1
- package/src/cli/update-cli.ts +1 -1
- package/src/cli/web-search-cli.ts +1 -1
- package/src/cli.ts +0 -1
- package/src/commands/config.ts +1 -1
- package/src/commands/grep.ts +1 -1
- package/src/commands/jupyter.ts +1 -1
- package/src/commands/plugin.ts +1 -1
- package/src/commands/setup.ts +1 -1
- package/src/commands/shell.ts +1 -1
- package/src/commands/ssh.ts +1 -1
- package/src/commands/stats.ts +1 -1
- package/src/commands/update.ts +1 -1
- package/src/config/model-registry.ts +3 -4
- package/src/config/model-resolver.ts +36 -9
- package/src/config/prompt-templates.ts +1 -9
- package/src/config/settings-schema.ts +32 -88
- package/src/config/settings.ts +3 -4
- package/src/debug/index.ts +1 -1
- package/src/debug/log-formatting.ts +1 -1
- package/src/debug/log-viewer.ts +2 -2
- package/src/discovery/helpers.ts +13 -3
- package/src/exa/index.ts +1 -35
- package/src/exa/render.ts +30 -190
- package/src/export/html/index.ts +1 -1
- package/src/extensibility/custom-tools/loader.ts +1 -1
- package/src/extensibility/custom-tools/types.ts +5 -1
- package/src/extensibility/custom-tools/wrapper.ts +1 -1
- package/src/extensibility/extensions/runner.ts +1 -1
- package/src/extensibility/extensions/types.ts +1 -1
- package/src/extensibility/extensions/wrapper.ts +7 -15
- package/src/extensibility/hooks/runner.ts +1 -1
- package/src/extensibility/hooks/types.ts +1 -1
- package/src/extensibility/plugins/doctor.ts +1 -1
- package/src/index.ts +13 -13
- package/src/lsp/index.ts +77 -24
- package/src/lsp/render.ts +34 -583
- package/src/lsp/types.ts +3 -3
- package/src/lsp/utils.ts +1 -1
- package/src/main.ts +1 -1
- package/src/mcp/tool-bridge.ts +1 -24
- package/src/modes/components/assistant-message.ts +7 -7
- package/src/modes/components/bash-execution.ts +50 -112
- package/src/modes/components/bordered-loader.ts +1 -1
- package/src/modes/components/branch-summary-message.ts +16 -10
- package/src/modes/components/compaction-summary-message.ts +20 -12
- package/src/modes/components/context-group.ts +106 -0
- package/src/modes/components/custom-message.ts +4 -5
- package/src/modes/components/diff.ts +2 -2
- package/src/modes/components/dynamic-border.ts +1 -1
- package/src/modes/components/extensions/extension-dashboard.ts +1 -1
- package/src/modes/components/extensions/extension-list.ts +1 -1
- package/src/modes/components/extensions/inspector-panel.ts +1 -1
- package/src/modes/components/footer.ts +2 -2
- package/src/modes/components/history-search.ts +1 -1
- package/src/modes/components/hook-editor.ts +1 -1
- package/src/modes/components/hook-input.ts +1 -1
- package/src/modes/components/hook-message.ts +4 -5
- package/src/modes/components/hook-selector.ts +1 -1
- package/src/modes/components/index.ts +0 -2
- package/src/modes/components/keybinding-hints.ts +1 -1
- package/src/modes/components/login-dialog.ts +1 -1
- package/src/modes/components/mcp-add-wizard.ts +1 -1
- package/src/modes/components/model-selector.ts +1 -1
- package/src/modes/components/oauth-selector.ts +1 -1
- package/src/modes/components/plugin-settings.ts +1 -1
- package/src/modes/components/python-execution.ts +51 -91
- package/src/modes/components/queue-mode-selector.ts +1 -1
- package/src/modes/components/session-selector.ts +1 -1
- package/src/modes/components/settings-defs.ts +5 -10
- package/src/modes/components/settings-selector.ts +1 -1
- package/src/modes/components/show-images-selector.ts +1 -1
- package/src/modes/components/skill-message.ts +4 -4
- package/src/modes/components/status-line/segments.ts +2 -2
- package/src/modes/components/status-line/separators.ts +1 -1
- package/src/modes/components/status-line-segment-editor.ts +1 -1
- package/src/modes/components/status-line.ts +1 -1
- package/src/modes/components/theme-selector.ts +1 -1
- package/src/modes/components/thinking-selector.ts +1 -1
- package/src/modes/components/todo-display.ts +2 -4
- package/src/modes/components/todo-reminder.ts +4 -4
- package/src/modes/components/tool-execution.ts +118 -440
- package/src/modes/components/tool-image-display.ts +107 -0
- package/src/modes/components/tree-selector.ts +2 -2
- package/src/modes/components/ttsr-notification.ts +4 -17
- package/src/modes/components/user-message-selector.ts +1 -1
- package/src/modes/components/user-message.ts +9 -10
- package/src/modes/components/welcome.ts +1 -1
- package/src/modes/controllers/command-controller.ts +1 -1
- package/src/modes/controllers/event-controller.ts +58 -187
- package/src/modes/controllers/extension-ui-controller.ts +1 -1
- package/src/modes/controllers/input-controller.ts +3 -1
- package/src/modes/controllers/mcp-command-controller.ts +1 -1
- package/src/modes/controllers/selector-controller.ts +3 -26
- package/src/modes/controllers/ssh-command-controller.ts +1 -1
- package/src/modes/interactive-mode.ts +3 -7
- package/src/modes/print-mode.ts +5 -5
- package/src/modes/rpc/rpc-mode.ts +1 -1
- package/src/modes/types.ts +1 -2
- package/src/modes/utils/ui-helpers.ts +34 -32
- package/src/patch/edit-tool.ts +742 -0
- package/src/patch/index.ts +32 -898
- package/src/patch/schemas.ts +208 -0
- package/src/patch/shared.ts +83 -151
- package/src/prompts/agents/explore.md +22 -37
- package/src/prompts/agents/init.md +1 -1
- package/src/prompts/agents/librarian.md +29 -20
- package/src/prompts/agents/oracle.md +9 -2
- package/src/prompts/agents/reviewer.md +14 -48
- package/src/prompts/agents/task.md +16 -8
- package/src/prompts/compaction/branch-summary.md +4 -1
- package/src/prompts/compaction/compaction-summary.md +4 -1
- package/src/prompts/system/subagent-system-prompt.md +1 -1
- package/src/prompts/system/system-prompt.md +162 -178
- package/src/prompts/system/verification-reminder.md +6 -0
- package/src/sdk.ts +0 -9
- package/src/session/agent-session.ts +244 -1459
- package/src/session/model-controller.ts +406 -0
- package/src/session/retry-utils.ts +71 -0
- package/src/session/session-manager.ts +22 -186
- package/src/session/session-types.ts +312 -0
- package/src/session/stats.ts +387 -0
- package/src/session/streaming-edit.ts +258 -0
- package/src/session/ttsr.ts +213 -0
- package/src/slash-commands/builtin-registry.ts +0 -8
- package/src/stt/recorder.ts +2 -2
- package/src/system-prompt.ts +1 -14
- package/src/task/agents.ts +7 -33
- package/src/task/executor.ts +50 -438
- package/src/task/index.ts +104 -71
- package/src/task/progress-tracker.ts +390 -0
- package/src/task/render.ts +371 -187
- package/src/task/subprocess-tool-registry.ts +1 -1
- package/src/task/types.ts +14 -47
- package/src/tools/ask.ts +31 -42
- package/src/tools/bash-interactive.ts +2 -2
- package/src/tools/bash-interceptor.ts +2 -2
- package/src/tools/bash-normalize.ts +1 -1
- package/src/tools/bash-skill-urls.ts +2 -2
- package/src/tools/bash.ts +87 -136
- package/src/tools/browser.ts +54 -84
- package/src/tools/create-tools.ts +186 -0
- package/src/tools/default-renderer.ts +104 -0
- package/src/tools/explore.ts +11 -10
- package/src/tools/fetch.ts +24 -114
- package/src/tools/find.ts +48 -132
- package/src/tools/gemini-image.ts +5 -15
- package/src/tools/github.ts +450 -0
- package/src/tools/grep.ts +43 -179
- package/src/tools/index.ts +35 -198
- package/src/tools/json-tree.ts +3 -3
- package/src/tools/librarian.ts +18 -18
- package/src/tools/list-limit.ts +2 -2
- package/src/tools/notebook.ts +35 -87
- package/src/tools/oracle.ts +25 -25
- package/src/tools/output-meta.ts +89 -4
- package/src/tools/output-utils.ts +2 -2
- package/src/tools/python.ts +86 -637
- package/src/tools/read.ts +36 -119
- package/src/tools/reviewer-tool.ts +19 -21
- package/src/tools/search-code.ts +128 -0
- package/src/tools/ssh.ts +67 -126
- package/src/tools/subagent-tool.ts +197 -123
- package/src/tools/todo-write.ts +15 -31
- package/src/tools/tool-errors.ts +0 -30
- package/src/tools/undo-edit.ts +30 -67
- package/src/tools/write.ts +78 -127
- package/src/tui/code-cell.ts +4 -4
- package/src/tui/file-list.ts +2 -2
- package/src/tui/output-block.ts +1 -1
- package/src/tui/status-line.ts +1 -1
- package/src/tui/tree-list.ts +2 -2
- package/src/tui/types.ts +1 -1
- package/src/tui/utils.ts +1 -1
- package/src/{tools → ui}/render-utils.ts +87 -126
- package/src/utils/external-editor.ts +4 -4
- package/src/utils/file-mentions.ts +1 -1
- package/src/utils/index.ts +30 -0
- package/src/utils/tools-manager.ts +9 -19
- package/src/web/github-client.ts +290 -0
- package/src/web/scrapers/github.ts +11 -62
- package/src/web/search/auth.ts +1 -3
- package/src/web/search/index.ts +82 -46
- package/src/web/search/provider.ts +11 -16
- package/src/web/search/providers/grep.ts +160 -0
- package/src/web/search/render.ts +48 -235
- package/src/web/search/types.ts +1 -1
- package/src/commands/commit.ts +0 -36
- package/src/commit/agentic/agent.ts +0 -311
- package/src/commit/agentic/fallback.ts +0 -96
- package/src/commit/agentic/index.ts +0 -359
- package/src/commit/agentic/prompts/analyze-file.md +0 -22
- package/src/commit/agentic/prompts/session-user.md +0 -25
- package/src/commit/agentic/prompts/split-confirm.md +0 -1
- package/src/commit/agentic/prompts/system.md +0 -38
- package/src/commit/agentic/state.ts +0 -69
- package/src/commit/agentic/tools/analyze-file.ts +0 -118
- package/src/commit/agentic/tools/git-file-diff.ts +0 -194
- package/src/commit/agentic/tools/git-hunk.ts +0 -50
- package/src/commit/agentic/tools/git-overview.ts +0 -84
- package/src/commit/agentic/tools/index.ts +0 -56
- package/src/commit/agentic/tools/propose-changelog.ts +0 -128
- package/src/commit/agentic/tools/propose-commit.ts +0 -154
- package/src/commit/agentic/tools/recent-commits.ts +0 -81
- package/src/commit/agentic/tools/split-commit.ts +0 -280
- package/src/commit/agentic/topo-sort.ts +0 -44
- package/src/commit/agentic/trivial.ts +0 -51
- package/src/commit/agentic/validation.ts +0 -200
- package/src/commit/analysis/conventional.ts +0 -165
- package/src/commit/analysis/index.ts +0 -4
- package/src/commit/analysis/scope.ts +0 -242
- package/src/commit/analysis/summary.ts +0 -112
- package/src/commit/analysis/validation.ts +0 -66
- package/src/commit/changelog/detect.ts +0 -37
- package/src/commit/changelog/generate.ts +0 -110
- package/src/commit/changelog/index.ts +0 -234
- package/src/commit/changelog/parse.ts +0 -44
- package/src/commit/cli.ts +0 -93
- package/src/commit/git/diff.ts +0 -148
- package/src/commit/git/errors.ts +0 -9
- package/src/commit/git/index.ts +0 -211
- package/src/commit/git/operations.ts +0 -54
- package/src/commit/index.ts +0 -5
- package/src/commit/map-reduce/index.ts +0 -64
- package/src/commit/map-reduce/map-phase.ts +0 -178
- package/src/commit/map-reduce/reduce-phase.ts +0 -145
- package/src/commit/map-reduce/utils.ts +0 -9
- package/src/commit/message.ts +0 -11
- package/src/commit/model-selection.ts +0 -69
- package/src/commit/pipeline.ts +0 -243
- package/src/commit/prompts/analysis-system.md +0 -148
- package/src/commit/prompts/analysis-user.md +0 -38
- package/src/commit/prompts/changelog-system.md +0 -50
- package/src/commit/prompts/changelog-user.md +0 -18
- package/src/commit/prompts/file-observer-system.md +0 -24
- package/src/commit/prompts/file-observer-user.md +0 -8
- package/src/commit/prompts/reduce-system.md +0 -50
- package/src/commit/prompts/reduce-user.md +0 -17
- package/src/commit/prompts/summary-retry.md +0 -3
- package/src/commit/prompts/summary-system.md +0 -38
- package/src/commit/prompts/summary-user.md +0 -13
- package/src/commit/prompts/types-description.md +0 -2
- package/src/commit/types.ts +0 -109
- package/src/commit/utils/exclusions.ts +0 -42
- package/src/mcp/render.ts +0 -123
- package/src/modes/components/agent-dashboard.ts +0 -1130
- package/src/modes/components/codemode-group.ts +0 -369
- package/src/modes/components/read-tool-group.ts +0 -119
- package/src/modes/components/visual-truncate.ts +0 -63
- package/src/prompts/system/subagent-user-prompt.md +0 -8
- package/src/prompts/tools/ask.md +0 -44
- package/src/prompts/tools/bash.md +0 -24
- package/src/prompts/tools/browser.md +0 -33
- package/src/prompts/tools/calculator.md +0 -12
- package/src/prompts/tools/explore.md +0 -29
- package/src/prompts/tools/fetch.md +0 -16
- package/src/prompts/tools/find.md +0 -18
- package/src/prompts/tools/gemini-image.md +0 -23
- package/src/prompts/tools/grep.md +0 -28
- package/src/prompts/tools/hashline.md +0 -232
- package/src/prompts/tools/librarian.md +0 -24
- package/src/prompts/tools/lsp.md +0 -28
- package/src/prompts/tools/oracle.md +0 -26
- package/src/prompts/tools/patch.md +0 -74
- package/src/prompts/tools/python.md +0 -66
- package/src/prompts/tools/read.md +0 -36
- package/src/prompts/tools/replace.md +0 -38
- package/src/prompts/tools/reviewer.md +0 -41
- package/src/prompts/tools/ssh.md +0 -51
- package/src/prompts/tools/task-summary.md +0 -28
- package/src/prompts/tools/task.md +0 -146
- package/src/prompts/tools/todo-write.md +0 -65
- package/src/prompts/tools/undo-edit.md +0 -7
- package/src/prompts/tools/web-search.md +0 -19
- package/src/prompts/tools/write.md +0 -18
- package/src/task/batch.ts +0 -102
- package/src/task/discovery.ts +0 -126
- package/src/task/parallel.ts +0 -84
- package/src/task/template.ts +0 -32
- package/src/tools/calculator.ts +0 -537
- package/src/tools/jtd-to-typescript.ts +0 -198
- package/src/tools/renderers.ts +0 -60
- package/src/tools/tool-result.ts +0 -86
- /package/src/{modes/theme → theme}/dark.json +0 -0
- /package/src/{modes/theme → theme}/defaults/dark-catppuccin.json +0 -0
- /package/src/{modes/theme → theme}/defaults/dark-dracula.json +0 -0
- /package/src/{modes/theme → theme}/defaults/dark-gruvbox.json +0 -0
- /package/src/{modes/theme → theme}/defaults/dark-solarized.json +0 -0
- /package/src/{modes/theme → theme}/defaults/dark-tokyo-night.json +0 -0
- /package/src/{modes/theme → theme}/defaults/index.ts +0 -0
- /package/src/{modes/theme → theme}/defaults/light-catppuccin.json +0 -0
- /package/src/{modes/theme → theme}/defaults/light-github.json +0 -0
- /package/src/{modes/theme → theme}/defaults/light-solarized.json +0 -0
- /package/src/{modes/theme → theme}/light.json +0 -0
- /package/src/{modes/theme → theme}/mermaid-cache.ts +0 -0
- /package/src/{modes/theme → theme}/theme-schema.json +0 -0
- /package/src/{modes/theme → theme}/theme.ts +0 -0
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* - Provide custom rendering for realtime/final display
|
|
8
8
|
*/
|
|
9
9
|
import type { Component } from "@nghyane/arcane-tui";
|
|
10
|
-
import type { Theme } from "../
|
|
10
|
+
import type { Theme } from "../theme/theme";
|
|
11
11
|
|
|
12
12
|
/** Event from subprocess tool execution (parsed from JSONL) */
|
|
13
13
|
export interface SubprocessToolEvent {
|
package/src/task/types.ts
CHANGED
|
@@ -1,58 +1,30 @@
|
|
|
1
1
|
import type { ThinkingLevel } from "@nghyane/arcane-agent";
|
|
2
2
|
import type { Usage } from "@nghyane/arcane-ai";
|
|
3
|
-
import { $env } from "@nghyane/arcane-utils";
|
|
4
3
|
import { type Static, Type } from "@sinclair/typebox";
|
|
5
4
|
|
|
6
5
|
/** Source of an agent definition */
|
|
7
6
|
export type AgentSource = "bundled" | "user" | "project";
|
|
8
7
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const number = Number.parseInt(value, 10);
|
|
12
|
-
return Number.isNaN(number) || number <= 0 ? defaultValue : number;
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
/** Maximum output bytes per agent */
|
|
16
|
-
export const MAX_OUTPUT_BYTES = parseNumber($env.ARCANE_TASK_MAX_OUTPUT_BYTES, 500_000);
|
|
17
|
-
|
|
18
|
-
/** Maximum output lines per agent */
|
|
19
|
-
export const MAX_OUTPUT_LINES = parseNumber($env.ARCANE_TASK_MAX_OUTPUT_LINES, 5000);
|
|
8
|
+
/** Discriminant for agent capability profile */
|
|
9
|
+
export type AgentKind = "local" | "remote" | "hybrid" | "reasoning";
|
|
20
10
|
|
|
21
11
|
/** EventBus channel for raw subagent events */
|
|
22
12
|
export const TASK_SUBAGENT_EVENT_CHANNEL = "task:subagent:event";
|
|
23
13
|
|
|
24
|
-
/**
|
|
25
|
-
export const TASK_SUBAGENT_PROGRESS_CHANNEL = "task:subagent:progress";
|
|
26
|
-
|
|
27
|
-
/** Single task item for execution */
|
|
28
|
-
export interface TaskItem {
|
|
29
|
-
id: string;
|
|
30
|
-
description: string;
|
|
31
|
-
assignment: string;
|
|
32
|
-
skills?: string[];
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/** Task schema — single task with optional context */
|
|
14
|
+
/** Task schema — simplified prompt + description */
|
|
36
15
|
export const taskSchema = Type.Object({
|
|
37
|
-
|
|
38
|
-
description:
|
|
39
|
-
|
|
16
|
+
prompt: Type.String({
|
|
17
|
+
description:
|
|
18
|
+
"The task for the agent to perform. Be specific about what needs to be done and include any relevant context.",
|
|
40
19
|
}),
|
|
41
20
|
description: Type.String({
|
|
42
|
-
description: "
|
|
43
|
-
}),
|
|
44
|
-
assignment: Type.String({
|
|
45
|
-
description:
|
|
46
|
-
"Complete instructions the subagent executes. Include target files, change description, edge cases, and acceptance criteria.",
|
|
21
|
+
description: "A very short description of the task that can be displayed to the user.",
|
|
47
22
|
}),
|
|
48
|
-
|
|
49
|
-
Type.
|
|
50
|
-
description:
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
skills: Type.Optional(
|
|
54
|
-
Type.Array(Type.String(), {
|
|
55
|
-
description: "Skill names to preload into the subagent.",
|
|
23
|
+
complexity: Type.Optional(
|
|
24
|
+
Type.Union([Type.Literal("low"), Type.Literal("high")], {
|
|
25
|
+
description:
|
|
26
|
+
"Task complexity. 'low' for mechanical/rote changes (rename, add import, update config). 'high' for changes requiring reasoning (refactors, bug fixes, new features). Default: high.",
|
|
27
|
+
default: "high",
|
|
56
28
|
}),
|
|
57
29
|
),
|
|
58
30
|
});
|
|
@@ -62,10 +34,11 @@ export type TaskParams = Static<TaskSchema>;
|
|
|
62
34
|
|
|
63
35
|
/** Agent definition (bundled or discovered) */
|
|
64
36
|
export interface AgentDefinition {
|
|
37
|
+
kind: AgentKind;
|
|
65
38
|
name: string;
|
|
66
39
|
description: string;
|
|
67
40
|
systemPrompt: string;
|
|
68
|
-
tools
|
|
41
|
+
tools: string[];
|
|
69
42
|
model?: string[];
|
|
70
43
|
thinkingLevel?: ThinkingLevel;
|
|
71
44
|
source: AgentSource;
|
|
@@ -104,19 +77,13 @@ export interface SingleResult {
|
|
|
104
77
|
description?: string;
|
|
105
78
|
lastIntent?: string;
|
|
106
79
|
exitCode: number;
|
|
107
|
-
output: string;
|
|
108
80
|
stderr: string;
|
|
109
|
-
truncated: boolean;
|
|
110
81
|
durationMs: number;
|
|
111
82
|
tokens: number;
|
|
112
83
|
error?: string;
|
|
113
84
|
aborted?: boolean;
|
|
114
85
|
/** Aggregated usage from the subprocess, accumulated incrementally from message_end events. */
|
|
115
86
|
usage?: Usage;
|
|
116
|
-
/** Output path for the task result */
|
|
117
|
-
outputPath?: string;
|
|
118
|
-
/** Output metadata for agent:// URL integration */
|
|
119
|
-
outputMeta?: { lineCount: number; charCount: number };
|
|
120
87
|
/** Full history of tool calls for nested display */
|
|
121
88
|
toolHistory?: Array<{ tool: string; args: string; status: "success" | "error" }>;
|
|
122
89
|
}
|
package/src/tools/ask.ts
CHANGED
|
@@ -18,38 +18,36 @@ import type { AgentTool, AgentToolContext, AgentToolResult, AgentToolUpdateCallb
|
|
|
18
18
|
import type { Component } from "@nghyane/arcane-tui";
|
|
19
19
|
import { TERMINAL, Text } from "@nghyane/arcane-tui";
|
|
20
20
|
import { type Static, Type } from "@sinclair/typebox";
|
|
21
|
-
import { renderPromptTemplate } from "../config/prompt-templates";
|
|
22
21
|
import type { RenderResultOptions } from "../extensibility/custom-tools/types";
|
|
23
|
-
import { type Theme, theme } from "../
|
|
24
|
-
import askDescription from "../prompts/tools/ask.md" with { type: "text" };
|
|
22
|
+
import { type Theme, theme } from "../theme/theme";
|
|
25
23
|
import { renderStatusLine } from "../tui";
|
|
24
|
+
import { formatErrorMessage } from "../ui/render-utils";
|
|
26
25
|
import type { ToolSession } from ".";
|
|
27
|
-
import { ToolUIKit } from "./render-utils";
|
|
28
26
|
|
|
29
27
|
// =============================================================================
|
|
30
28
|
// Types
|
|
31
29
|
// =============================================================================
|
|
32
30
|
|
|
33
31
|
const OptionItem = Type.Object({
|
|
34
|
-
label: Type.String({ description: "Display
|
|
32
|
+
label: Type.String({ description: "Display text for the option" }),
|
|
35
33
|
});
|
|
36
34
|
|
|
37
35
|
const QuestionItem = Type.Object({
|
|
38
|
-
id: Type.String({ description: "
|
|
39
|
-
question: Type.String({ description: "Question text" }),
|
|
40
|
-
options: Type.Array(OptionItem
|
|
36
|
+
id: Type.String({ description: "Unique question identifier" }),
|
|
37
|
+
question: Type.String({ description: "Question text to display" }),
|
|
38
|
+
options: Type.Array(OptionItem),
|
|
41
39
|
multi: Type.Optional(Type.Boolean({ description: "Allow multiple selections" })),
|
|
42
|
-
recommended: Type.Optional(Type.Number({ description: "Index of recommended option
|
|
40
|
+
recommended: Type.Optional(Type.Number({ description: "Index of the recommended option" })),
|
|
43
41
|
});
|
|
44
42
|
|
|
45
43
|
const askSchema = Type.Object({
|
|
46
|
-
questions: Type.Array(QuestionItem, {
|
|
44
|
+
questions: Type.Array(QuestionItem, { minItems: 1 }),
|
|
47
45
|
});
|
|
48
46
|
|
|
49
|
-
|
|
47
|
+
type AskToolInput = Static<typeof askSchema>;
|
|
50
48
|
|
|
51
49
|
/** Result for a single question */
|
|
52
|
-
|
|
50
|
+
interface QuestionResult {
|
|
53
51
|
id: string;
|
|
54
52
|
question: string;
|
|
55
53
|
options: string[];
|
|
@@ -243,15 +241,13 @@ type AskParams = AskToolInput;
|
|
|
243
241
|
* Allows gathering user preferences, clarifying instructions, and getting decisions
|
|
244
242
|
* on implementation choices as the agent works.
|
|
245
243
|
*/
|
|
246
|
-
export class AskTool implements AgentTool<typeof askSchema, AskToolDetails> {
|
|
244
|
+
export class AskTool implements AgentTool<typeof askSchema, AskToolDetails, Theme> {
|
|
247
245
|
readonly name = "ask";
|
|
248
246
|
readonly label = "Ask";
|
|
249
|
-
|
|
247
|
+
description = "Ask the user a question when genuinely blocked";
|
|
250
248
|
readonly parameters = askSchema;
|
|
251
249
|
|
|
252
|
-
constructor(private readonly session: ToolSession) {
|
|
253
|
-
this.description = renderPromptTemplate(askDescription);
|
|
254
|
-
}
|
|
250
|
+
constructor(private readonly session: ToolSession) {}
|
|
255
251
|
|
|
256
252
|
static createIf(session: ToolSession): AskTool | null {
|
|
257
253
|
return session.hasUI ? new AskTool(session) : null;
|
|
@@ -358,28 +354,9 @@ export class AskTool implements AgentTool<typeof askSchema, AskToolDetails> {
|
|
|
358
354
|
|
|
359
355
|
return { content: [{ type: "text" as const, text: responseText }], details };
|
|
360
356
|
}
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
// =============================================================================
|
|
364
|
-
// TUI Renderer
|
|
365
|
-
// =============================================================================
|
|
366
|
-
|
|
367
|
-
interface AskRenderArgs {
|
|
368
|
-
question?: string;
|
|
369
|
-
options?: Array<{ label: string }>;
|
|
370
|
-
multi?: boolean;
|
|
371
|
-
questions?: Array<{
|
|
372
|
-
id: string;
|
|
373
|
-
question: string;
|
|
374
|
-
options: Array<{ label: string }>;
|
|
375
|
-
multi?: boolean;
|
|
376
|
-
}>;
|
|
377
|
-
}
|
|
378
357
|
|
|
379
|
-
export const askToolRenderer = {
|
|
380
358
|
renderCall(args: AskRenderArgs, _options: RenderResultOptions, uiTheme: Theme): Component {
|
|
381
|
-
const
|
|
382
|
-
const label = ui.title("Ask");
|
|
359
|
+
const label = uiTheme.fg("toolTitle", uiTheme.bold("Ask"));
|
|
383
360
|
|
|
384
361
|
// Multi-part questions
|
|
385
362
|
if (args.questions && args.questions.length > 0) {
|
|
@@ -414,14 +391,14 @@ export const askToolRenderer = {
|
|
|
414
391
|
|
|
415
392
|
// Single question
|
|
416
393
|
if (!args.question) {
|
|
417
|
-
return new Text(
|
|
394
|
+
return new Text(formatErrorMessage("No question provided", uiTheme), 0, 0);
|
|
418
395
|
}
|
|
419
396
|
|
|
420
397
|
let text = `${label} ${uiTheme.fg("accent", args.question)}`;
|
|
421
398
|
const meta: string[] = [];
|
|
422
399
|
if (args.multi) meta.push("multi");
|
|
423
400
|
if (args.options?.length) meta.push(`options:${args.options.length}`);
|
|
424
|
-
text +=
|
|
401
|
+
text += meta.length > 0 ? ` ${uiTheme.fg("muted", meta.join(uiTheme.sep.dot))}` : "";
|
|
425
402
|
|
|
426
403
|
if (args.options?.length) {
|
|
427
404
|
for (let i = 0; i < args.options.length; i++) {
|
|
@@ -433,7 +410,7 @@ export const askToolRenderer = {
|
|
|
433
410
|
}
|
|
434
411
|
|
|
435
412
|
return new Text(text, 0, 0);
|
|
436
|
-
}
|
|
413
|
+
}
|
|
437
414
|
|
|
438
415
|
renderResult(
|
|
439
416
|
result: { content: Array<{ type: string; text?: string }>; details?: AskToolDetails },
|
|
@@ -519,5 +496,17 @@ export const askToolRenderer = {
|
|
|
519
496
|
}
|
|
520
497
|
|
|
521
498
|
return new Text(text, 0, 0);
|
|
522
|
-
}
|
|
523
|
-
}
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
interface AskRenderArgs {
|
|
503
|
+
question?: string;
|
|
504
|
+
options?: Array<{ label: string }>;
|
|
505
|
+
multi?: boolean;
|
|
506
|
+
questions?: Array<{
|
|
507
|
+
id: string;
|
|
508
|
+
question: string;
|
|
509
|
+
options: Array<{ label: string }>;
|
|
510
|
+
multi?: boolean;
|
|
511
|
+
}>;
|
|
512
|
+
}
|
|
@@ -12,10 +12,10 @@ import {
|
|
|
12
12
|
import type { Terminal as XtermTerminalType } from "@xterm/headless";
|
|
13
13
|
import xterm from "@xterm/headless";
|
|
14
14
|
import { NON_INTERACTIVE_ENV } from "../exec/non-interactive-env";
|
|
15
|
-
import type { Theme } from "../modes/theme/theme";
|
|
16
15
|
import { OutputSink, type OutputSummary } from "../session/streaming-output";
|
|
16
|
+
import type { Theme } from "../theme/theme";
|
|
17
17
|
import { getStateIcon } from "../tui";
|
|
18
|
-
import { replaceTabs } from "
|
|
18
|
+
import { replaceTabs } from "../ui/render-utils";
|
|
19
19
|
|
|
20
20
|
export interface BashInteractiveResult extends OutputSummary {
|
|
21
21
|
exitCode: number | undefined;
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import type { BashInterceptorRule } from "../config/settings-schema";
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
const DEFAULT_BASH_INTERCEPTOR_RULES: BashInterceptorRule[] = [
|
|
11
11
|
{
|
|
12
12
|
pattern: "^\\s*(cat|head|tail|less|more)\\s+",
|
|
13
13
|
tool: "read",
|
|
@@ -45,7 +45,7 @@ export const DEFAULT_BASH_INTERCEPTOR_RULES: BashInterceptorRule[] = [
|
|
|
45
45
|
},
|
|
46
46
|
];
|
|
47
47
|
|
|
48
|
-
|
|
48
|
+
interface InterceptionResult {
|
|
49
49
|
/** If true, the bash command should be blocked */
|
|
50
50
|
block: boolean;
|
|
51
51
|
/** Error message to return instead of executing */
|
|
@@ -20,7 +20,7 @@ interface InternalUrlResolver {
|
|
|
20
20
|
resolve(input: string): Promise<InternalResource>;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
interface InternalUrlExpansionOptions {
|
|
24
24
|
skills: readonly Skill[];
|
|
25
25
|
internalRouter?: InternalUrlResolver;
|
|
26
26
|
}
|
|
@@ -29,7 +29,7 @@ export interface InternalUrlExpansionOptions {
|
|
|
29
29
|
* Resolve a single skill:// URL to its absolute filesystem path.
|
|
30
30
|
* Does NOT read file content or verify existence.
|
|
31
31
|
*/
|
|
32
|
-
|
|
32
|
+
function resolveSkillUrlToPath(url: string, skills: readonly Skill[]): string {
|
|
33
33
|
const parsed = /^skill:\/\/([^/?#]+)(\/[^?#]*)?(?:[?#].*)?$/.exec(url);
|
|
34
34
|
if (!parsed) {
|
|
35
35
|
throw new ToolError(`Invalid skill:// URL: ${url}`);
|
package/src/tools/bash.ts
CHANGED
|
@@ -6,35 +6,30 @@ import { Text } from "@nghyane/arcane-tui";
|
|
|
6
6
|
import { $env, isEnoent } from "@nghyane/arcane-utils";
|
|
7
7
|
import { getProjectDir } from "@nghyane/arcane-utils/dirs";
|
|
8
8
|
import { type Static, Type } from "@sinclair/typebox";
|
|
9
|
-
import { renderPromptTemplate } from "../config/prompt-templates";
|
|
10
9
|
import { type BashResult, executeBash } from "../exec/bash-executor";
|
|
11
10
|
import type { RenderResultOptions } from "../extensibility/custom-tools/types";
|
|
12
|
-
import { truncateToVisualLines } from "../modes/components/visual-truncate";
|
|
13
|
-
import type { Theme } from "../modes/theme/theme";
|
|
14
|
-
import bashDescription from "../prompts/tools/bash.md" with { type: "text" };
|
|
15
11
|
import { DEFAULT_MAX_BYTES } from "../session/streaming-output";
|
|
12
|
+
import type { Theme } from "../theme/theme";
|
|
16
13
|
import { renderStatusLine } from "../tui";
|
|
17
|
-
import {
|
|
14
|
+
import { formatClickHint, PREVIEW_LIMITS, replaceTabs } from "../ui/render-utils";
|
|
18
15
|
import type { ToolSession } from ".";
|
|
19
16
|
import { type BashInteractiveResult, runInteractiveBashPty } from "./bash-interactive";
|
|
20
17
|
import { checkBashInterception } from "./bash-interceptor";
|
|
21
18
|
import { applyHeadTail } from "./bash-normalize";
|
|
22
19
|
import { expandInternalUrls } from "./bash-skill-urls";
|
|
23
|
-
import type
|
|
20
|
+
import { type OutputMeta, toolResult } from "./output-meta";
|
|
24
21
|
import { allocateOutputArtifact, createTailBuffer } from "./output-utils";
|
|
25
22
|
import { resolveToCwd } from "./path-utils";
|
|
26
|
-
import { formatBytes, replaceTabs, wrapBrackets } from "./render-utils";
|
|
27
23
|
import { ToolAbortError, ToolError } from "./tool-errors";
|
|
28
|
-
import { toolResult } from "./tool-result";
|
|
29
24
|
|
|
30
25
|
export const BASH_DEFAULT_PREVIEW_LINES = 10;
|
|
31
26
|
|
|
32
27
|
const bashSchema = Type.Object({
|
|
33
|
-
command: Type.String({ description: "
|
|
34
|
-
timeout: Type.Optional(Type.Number({ description: "Timeout in
|
|
35
|
-
cwd: Type.Optional(Type.String({ description: "Working directory
|
|
36
|
-
head: Type.Optional(Type.Number({ description: "Return only first N lines of output" })),
|
|
37
|
-
tail: Type.Optional(Type.Number({ description: "Return only last N lines of output" })),
|
|
28
|
+
command: Type.String({ description: "Shell command to execute" }),
|
|
29
|
+
timeout: Type.Optional(Type.Number({ description: "Timeout in milliseconds" })),
|
|
30
|
+
cwd: Type.Optional(Type.String({ description: "Working directory" })),
|
|
31
|
+
head: Type.Optional(Type.Number({ description: "Return only the first N lines of output" })),
|
|
32
|
+
tail: Type.Optional(Type.Number({ description: "Return only the last N lines of output" })),
|
|
38
33
|
});
|
|
39
34
|
|
|
40
35
|
export type BashToolInput = Static<typeof bashSchema>;
|
|
@@ -57,16 +52,14 @@ function isInteractiveResult(result: BashResult | BashInteractiveResult): result
|
|
|
57
52
|
*
|
|
58
53
|
* Executes bash commands with optional timeout and working directory.
|
|
59
54
|
*/
|
|
60
|
-
export class BashTool implements AgentTool<typeof bashSchema, BashToolDetails> {
|
|
55
|
+
export class BashTool implements AgentTool<typeof bashSchema, BashToolDetails, Theme> {
|
|
61
56
|
readonly name = "bash";
|
|
62
57
|
readonly label = "Bash";
|
|
63
|
-
|
|
58
|
+
description = "Execute a shell command";
|
|
64
59
|
readonly parameters = bashSchema;
|
|
65
60
|
readonly concurrency = "exclusive";
|
|
66
61
|
|
|
67
|
-
constructor(private readonly session: ToolSession) {
|
|
68
|
-
this.description = renderPromptTemplate(bashDescription);
|
|
69
|
-
}
|
|
62
|
+
constructor(private readonly session: ToolSession) {}
|
|
70
63
|
|
|
71
64
|
async execute(
|
|
72
65
|
_toolCallId: string,
|
|
@@ -183,11 +176,83 @@ export class BashTool implements AgentTool<typeof bashSchema, BashToolDetails> {
|
|
|
183
176
|
|
|
184
177
|
return resultBuilder.done();
|
|
185
178
|
}
|
|
186
|
-
}
|
|
187
179
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
180
|
+
buildRenderContext(info: {
|
|
181
|
+
args: BashToolInput;
|
|
182
|
+
result?: AgentToolResult<BashToolDetails>;
|
|
183
|
+
expanded: boolean;
|
|
184
|
+
getTextOutput: () => string;
|
|
185
|
+
}): Record<string, unknown> {
|
|
186
|
+
const context: Record<string, unknown> = {};
|
|
187
|
+
if (info.result) {
|
|
188
|
+
context.output = info.getTextOutput().trimEnd();
|
|
189
|
+
context.expanded = info.expanded;
|
|
190
|
+
context.previewLines = BASH_DEFAULT_PREVIEW_LINES;
|
|
191
|
+
if (typeof info.args.timeout === "number" && Number.isFinite(info.args.timeout)) {
|
|
192
|
+
context.timeout = Math.max(1, Math.min(3600, info.args.timeout));
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
return context;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
renderCall(args: BashRenderArgs, _options: RenderResultOptions, uiTheme: Theme): Component {
|
|
199
|
+
const cmdText = formatBashCommand(args, uiTheme);
|
|
200
|
+
const text = renderStatusLine({ icon: "pending", title: "Bash", description: cmdText }, uiTheme);
|
|
201
|
+
return new Text(text, 0, 0);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
renderResult(
|
|
205
|
+
result: {
|
|
206
|
+
content: Array<{ type: string; text?: string }>;
|
|
207
|
+
details?: BashToolDetails;
|
|
208
|
+
isError?: boolean;
|
|
209
|
+
},
|
|
210
|
+
options: RenderResultOptions & { renderContext?: BashRenderContext },
|
|
211
|
+
uiTheme: Theme,
|
|
212
|
+
args?: BashRenderArgs,
|
|
213
|
+
): Component {
|
|
214
|
+
const cmdText = args ? formatBashCommand(args, uiTheme) : "…";
|
|
215
|
+
const isError = result.isError === true;
|
|
216
|
+
const { renderContext } = options;
|
|
217
|
+
const output = (renderContext?.output ?? result.content?.find(c => c.type === "text")?.text ?? "").trimEnd();
|
|
218
|
+
const outputLines = output ? output.split("\n") : [];
|
|
219
|
+
const total = outputLines.length;
|
|
220
|
+
const truncation = result.details?.meta?.truncation;
|
|
221
|
+
|
|
222
|
+
const meta: string[] = [];
|
|
223
|
+
if (isError) meta.push("failed");
|
|
224
|
+
if (total > 0) meta.push(`${total} lines`);
|
|
225
|
+
|
|
226
|
+
const header = renderStatusLine(
|
|
227
|
+
{ icon: isError ? "error" : "success", title: "Bash", description: cmdText, meta },
|
|
228
|
+
uiTheme,
|
|
229
|
+
);
|
|
230
|
+
|
|
231
|
+
const expanded = renderContext?.expanded ?? options.expanded;
|
|
232
|
+
const showAll = isError || expanded;
|
|
233
|
+
const displayLines = showAll ? outputLines : outputLines.slice(-PREVIEW_LIMITS.OUTPUT_COLLAPSED);
|
|
234
|
+
const skipped = total - displayLines.length;
|
|
235
|
+
|
|
236
|
+
const bodyLines: string[] = [];
|
|
237
|
+
if (skipped > 0) {
|
|
238
|
+
bodyLines.push(uiTheme.fg("dim", `… (${skipped} earlier lines)`));
|
|
239
|
+
}
|
|
240
|
+
const hasTruncation = Boolean(truncation);
|
|
241
|
+
for (let i = 0; i < displayLines.length; i++) {
|
|
242
|
+
bodyLines.push(uiTheme.fg("toolOutput", replaceTabs(displayLines[i])));
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
if (hasTruncation) {
|
|
246
|
+
bodyLines.push(uiTheme.fg("warning", "output truncated"));
|
|
247
|
+
}
|
|
248
|
+
if (!showAll && skipped > 0) {
|
|
249
|
+
bodyLines.push(formatClickHint(uiTheme));
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
const lines = bodyLines.length > 0 ? [header, ...bodyLines] : [header];
|
|
253
|
+
return new Text(lines.join("\n"), 0, 0);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
191
256
|
|
|
192
257
|
interface BashRenderArgs {
|
|
193
258
|
command?: string;
|
|
@@ -231,117 +296,3 @@ function formatBashCommand(args: BashRenderArgs, _uiTheme: Theme): string {
|
|
|
231
296
|
|
|
232
297
|
return displayWorkdir ? `${prompt} cd ${displayWorkdir} && ${command}` : `${prompt} ${command}`;
|
|
233
298
|
}
|
|
234
|
-
|
|
235
|
-
// Preview line limit when not expanded (matches tool-execution behavior)
|
|
236
|
-
export const BASH_PREVIEW_LINES = 10;
|
|
237
|
-
|
|
238
|
-
export const bashToolRenderer = {
|
|
239
|
-
renderCall(args: BashRenderArgs, _options: RenderResultOptions, uiTheme: Theme): Component {
|
|
240
|
-
const cmdText = formatBashCommand(args, uiTheme);
|
|
241
|
-
const text = renderStatusLine({ icon: "pending", title: "Bash", description: cmdText }, uiTheme);
|
|
242
|
-
return new Text(text, 0, 0);
|
|
243
|
-
},
|
|
244
|
-
|
|
245
|
-
renderResult(
|
|
246
|
-
result: {
|
|
247
|
-
content: Array<{ type: string; text?: string }>;
|
|
248
|
-
details?: BashToolDetails;
|
|
249
|
-
isError?: boolean;
|
|
250
|
-
},
|
|
251
|
-
options: RenderResultOptions & { renderContext?: BashRenderContext },
|
|
252
|
-
uiTheme: Theme,
|
|
253
|
-
args?: BashRenderArgs,
|
|
254
|
-
): Component {
|
|
255
|
-
const cmdText = args ? formatBashCommand(args, uiTheme) : undefined;
|
|
256
|
-
const isError = result.isError === true;
|
|
257
|
-
const header = renderStatusLine({ icon: isError ? "error" : "success", title: "Bash" }, uiTheme);
|
|
258
|
-
const details = result.details;
|
|
259
|
-
const truncation = details?.meta?.truncation;
|
|
260
|
-
const outputBlock = new CachedOutputBlock();
|
|
261
|
-
|
|
262
|
-
return {
|
|
263
|
-
render: (width: number): string[] => {
|
|
264
|
-
// REACTIVE: read mutable options at render time
|
|
265
|
-
const { renderContext } = options;
|
|
266
|
-
const expanded = renderContext?.expanded ?? options.expanded;
|
|
267
|
-
const previewLines = renderContext?.previewLines ?? BASH_DEFAULT_PREVIEW_LINES;
|
|
268
|
-
|
|
269
|
-
// Get output from context (preferred) or fall back to result content
|
|
270
|
-
const output = renderContext?.output ?? result.content?.find(c => c.type === "text")?.text ?? "";
|
|
271
|
-
const displayOutput = output.trimEnd();
|
|
272
|
-
const showingFullOutput = expanded && renderContext?.isFullOutput === true;
|
|
273
|
-
|
|
274
|
-
// Build truncation warning
|
|
275
|
-
const timeoutSeconds = renderContext?.timeout;
|
|
276
|
-
const timeoutLine =
|
|
277
|
-
typeof timeoutSeconds === "number"
|
|
278
|
-
? uiTheme.fg(
|
|
279
|
-
"dim",
|
|
280
|
-
`${uiTheme.format.bracketLeft}Timeout: ${timeoutSeconds}s${uiTheme.format.bracketRight}`,
|
|
281
|
-
)
|
|
282
|
-
: undefined;
|
|
283
|
-
let warningLine: string | undefined;
|
|
284
|
-
if (truncation && !showingFullOutput) {
|
|
285
|
-
const warnings: string[] = [];
|
|
286
|
-
if (truncation?.artifactId) {
|
|
287
|
-
warnings.push(`Full output: artifact://${truncation.artifactId}`);
|
|
288
|
-
}
|
|
289
|
-
if (truncation.truncatedBy === "lines") {
|
|
290
|
-
warnings.push(`Truncated: showing ${truncation.outputLines} of ${truncation.totalLines} lines`);
|
|
291
|
-
} else {
|
|
292
|
-
warnings.push(
|
|
293
|
-
`Truncated: ${truncation.outputLines} lines shown (${formatBytes(truncation.outputBytes)} limit)`,
|
|
294
|
-
);
|
|
295
|
-
}
|
|
296
|
-
if (warnings.length > 0) {
|
|
297
|
-
warningLine = uiTheme.fg("warning", wrapBrackets(warnings.join(". "), uiTheme));
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
const outputLines: string[] = [];
|
|
302
|
-
const hasOutput = displayOutput.trim().length > 0;
|
|
303
|
-
if (hasOutput) {
|
|
304
|
-
if (expanded) {
|
|
305
|
-
outputLines.push(...displayOutput.split("\n").map(line => replaceTabs(line)));
|
|
306
|
-
} else {
|
|
307
|
-
const styledOutput = displayOutput
|
|
308
|
-
.split("\n")
|
|
309
|
-
.map(line => replaceTabs(line))
|
|
310
|
-
.join("\n");
|
|
311
|
-
const textContent = styledOutput;
|
|
312
|
-
const result = truncateToVisualLines(textContent, previewLines, width);
|
|
313
|
-
if (result.skippedCount > 0) {
|
|
314
|
-
outputLines.push(
|
|
315
|
-
uiTheme.fg(
|
|
316
|
-
"dim",
|
|
317
|
-
`… (${result.skippedCount} earlier lines, showing ${result.visualLines.length} of ${result.skippedCount + result.visualLines.length}) (ctrl+o to expand)`,
|
|
318
|
-
),
|
|
319
|
-
);
|
|
320
|
-
}
|
|
321
|
-
outputLines.push(...result.visualLines);
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
if (timeoutLine) outputLines.push(timeoutLine);
|
|
325
|
-
if (warningLine) outputLines.push(warningLine);
|
|
326
|
-
|
|
327
|
-
return outputBlock.render(
|
|
328
|
-
{
|
|
329
|
-
header,
|
|
330
|
-
state: isError ? "error" : "success",
|
|
331
|
-
sections: [
|
|
332
|
-
{ lines: cmdText ? [uiTheme.fg("dim", cmdText)] : [] },
|
|
333
|
-
{ label: uiTheme.fg("toolTitle", "Output"), lines: outputLines },
|
|
334
|
-
],
|
|
335
|
-
width,
|
|
336
|
-
},
|
|
337
|
-
uiTheme,
|
|
338
|
-
);
|
|
339
|
-
},
|
|
340
|
-
invalidate: () => {
|
|
341
|
-
outputBlock.invalidate();
|
|
342
|
-
},
|
|
343
|
-
};
|
|
344
|
-
},
|
|
345
|
-
mergeCallAndResult: true,
|
|
346
|
-
inline: true,
|
|
347
|
-
};
|