fix(cli): rename bash tool to shell
This commit is contained in:
parent
387bff8fd9
commit
05fdbcce04
4 changed files with 38 additions and 20 deletions
|
|
@ -9,7 +9,7 @@
|
||||||
// Slash commands:
|
// Slash commands:
|
||||||
// /permission [kind] → triggers a permission request variant
|
// /permission [kind] → triggers a permission request variant
|
||||||
// /question [kind] → triggers a question request variant
|
// /question [kind] → triggers a question request variant
|
||||||
// /fmt <kind> → emits a specific tool/text type (text, reasoning, bash,
|
// /fmt <kind> → emits a specific tool/text type (text, reasoning, shell,
|
||||||
// write, edit, patch, task, question, error, mix)
|
// write, edit, patch, task, question, error, mix)
|
||||||
//
|
//
|
||||||
// Demo mode also handles permission and question replies locally, completing
|
// Demo mode also handles permission and question replies locally, completing
|
||||||
|
|
@ -33,7 +33,7 @@ const KINDS = [
|
||||||
"table",
|
"table",
|
||||||
"text",
|
"text",
|
||||||
"reasoning",
|
"reasoning",
|
||||||
"bash",
|
"shell",
|
||||||
"write",
|
"write",
|
||||||
"edit",
|
"edit",
|
||||||
"patch",
|
"patch",
|
||||||
|
|
@ -42,7 +42,7 @@ const KINDS = [
|
||||||
"error",
|
"error",
|
||||||
"mix",
|
"mix",
|
||||||
]
|
]
|
||||||
const PERMISSIONS = ["edit", "bash", "read", "task", "external", "doom"] as const
|
const PERMISSIONS = ["edit", "shell", "read", "task", "external", "doom"] as const
|
||||||
const QUESTIONS = ["multi", "single", "checklist", "custom"] as const
|
const QUESTIONS = ["multi", "single", "checklist", "custom"] as const
|
||||||
|
|
||||||
type PermissionKind = (typeof PERMISSIONS)[number]
|
type PermissionKind = (typeof PERMISSIONS)[number]
|
||||||
|
|
@ -436,7 +436,7 @@ function emitError(state: State, text: string): void {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function emitBash(state: State, signal?: AbortSignal): Promise<void> {
|
async function emitBash(state: State, signal?: AbortSignal): Promise<void> {
|
||||||
const ref = make(state, "bash", {
|
const ref = make(state, "shell", {
|
||||||
command: "git status",
|
command: "git status",
|
||||||
workdir: process.cwd(),
|
workdir: process.cwd(),
|
||||||
description: "Show git status",
|
description: "Show git status",
|
||||||
|
|
@ -623,16 +623,16 @@ function emitPermission(state: State, kind: PermissionKind = "edit"): void {
|
||||||
const root = process.cwd()
|
const root = process.cwd()
|
||||||
const file = path.join(root, "src", "demo-format.ts")
|
const file = path.join(root, "src", "demo-format.ts")
|
||||||
|
|
||||||
if (kind === "bash") {
|
if (kind === "shell") {
|
||||||
const command = "git status --short"
|
const command = "git status --short"
|
||||||
const ref = make(state, "bash", {
|
const ref = make(state, "shell", {
|
||||||
command,
|
command,
|
||||||
workdir: root,
|
workdir: root,
|
||||||
description: "Inspect worktree changes",
|
description: "Inspect worktree changes",
|
||||||
})
|
})
|
||||||
askPermission(state, {
|
askPermission(state, {
|
||||||
ref,
|
ref,
|
||||||
permission: "bash",
|
permission: "shell",
|
||||||
patterns: [command],
|
patterns: [command],
|
||||||
always: ["*"],
|
always: ["*"],
|
||||||
done: {
|
done: {
|
||||||
|
|
@ -862,7 +862,7 @@ async function emitFmt(state: State, kind: string, body: string, signal?: AbortS
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kind === "bash") {
|
if (kind === "shell") {
|
||||||
await emitBash(state, signal)
|
await emitBash(state, signal)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
@ -924,7 +924,7 @@ function intro(state: State): void {
|
||||||
`- /question [kind] (${QUESTIONS.join(", ")})`,
|
`- /question [kind] (${QUESTIONS.join(", ")})`,
|
||||||
`- /fmt <kind> (${KINDS.join(", ")})`,
|
`- /fmt <kind> (${KINDS.join(", ")})`,
|
||||||
"Examples:",
|
"Examples:",
|
||||||
"- /permission bash",
|
"- /permission shell",
|
||||||
"- /question custom",
|
"- /question custom",
|
||||||
"- /fmt markdown",
|
"- /fmt markdown",
|
||||||
"- /fmt table",
|
"- /fmt table",
|
||||||
|
|
|
||||||
|
|
@ -218,7 +218,7 @@ function shellCommit(
|
||||||
kind: "tool",
|
kind: "tool",
|
||||||
source: "tool",
|
source: "tool",
|
||||||
partID: `shell:${callID}`,
|
partID: `shell:${callID}`,
|
||||||
tool: "bash",
|
tool: "shell",
|
||||||
shell: { callID, command },
|
shell: { callID, command },
|
||||||
...next,
|
...next,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
// Per-tool display rules shared across `opencode run` output paths.
|
// Per-tool display rules shared across `opencode run` output paths.
|
||||||
//
|
//
|
||||||
// Each known tool (bash, edit, write, task, etc.) has a ToolRule that controls
|
// Each known tool (shell, edit, write, task, etc.) has a ToolRule that controls
|
||||||
// five display hooks:
|
// five display hooks:
|
||||||
//
|
//
|
||||||
// view → visibility policy for progress/final scrollback entries and
|
// view → visibility policy for progress/final scrollback entries and
|
||||||
|
|
@ -114,7 +114,7 @@ type ToolPermissionCtx = {
|
||||||
|
|
||||||
type ToolName =
|
type ToolName =
|
||||||
| "invalid"
|
| "invalid"
|
||||||
| "bash"
|
| "shell"
|
||||||
| "write"
|
| "write"
|
||||||
| "edit"
|
| "edit"
|
||||||
| "patch"
|
| "patch"
|
||||||
|
|
@ -648,7 +648,7 @@ function scrollBashProgress(p: ToolProps): string {
|
||||||
return fmt(out)
|
return fmt(out)
|
||||||
}
|
}
|
||||||
|
|
||||||
function scrollBashFinal(p: ToolProps): string {
|
function scrollShellFinal(p: ToolProps): string {
|
||||||
if (p.frame.status === "error") {
|
if (p.frame.status === "error") {
|
||||||
return fail(p.frame)
|
return fail(p.frame)
|
||||||
}
|
}
|
||||||
|
|
@ -657,13 +657,13 @@ function scrollBashFinal(p: ToolProps): string {
|
||||||
const time = span(p.frame.state)
|
const time = span(p.frame.state)
|
||||||
if (code === undefined) {
|
if (code === undefined) {
|
||||||
if (!time) {
|
if (!time) {
|
||||||
return "bash completed"
|
return "shell completed"
|
||||||
}
|
}
|
||||||
|
|
||||||
return `bash completed · ${time}`
|
return `shell completed · ${time}`
|
||||||
}
|
}
|
||||||
|
|
||||||
return `bash completed (exit ${code})${time ? ` · ${time}` : ""}`
|
return `shell completed (exit ${code})${time ? ` · ${time}` : ""}`
|
||||||
}
|
}
|
||||||
|
|
||||||
function scrollReadStart(p: ToolProps): string {
|
function scrollReadStart(p: ToolProps): string {
|
||||||
|
|
@ -976,16 +976,16 @@ const TOOL_RULES = {
|
||||||
start: () => "",
|
start: () => "",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
bash: {
|
shell: {
|
||||||
view: {
|
view: {
|
||||||
output: true,
|
output: true,
|
||||||
final: false,
|
final: false,
|
||||||
},
|
},
|
||||||
run: runBash,
|
run: runShell,
|
||||||
scroll: {
|
scroll: {
|
||||||
start: scrollBashStart,
|
start: scrollBashStart,
|
||||||
progress: scrollBashProgress,
|
progress: scrollBashProgress,
|
||||||
final: scrollBashFinal,
|
final: scrollShellFinal,
|
||||||
},
|
},
|
||||||
permission: permBash,
|
permission: permBash,
|
||||||
},
|
},
|
||||||
|
|
@ -1202,7 +1202,7 @@ export function toolFrame(commit: StreamCommit, raw: string): ToolFrame {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function runBash(p: ToolProps): ToolInline {
|
function runShell(p: ToolProps): ToolInline {
|
||||||
return {
|
return {
|
||||||
icon: "$",
|
icon: "$",
|
||||||
title: p.input.command || "",
|
title: p.input.command || "",
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ import { describe, expect, test } from "bun:test"
|
||||||
import { InstallationVersion } from "@opencode-ai/core/installation/version"
|
import { InstallationVersion } from "@opencode-ai/core/installation/version"
|
||||||
import path from "node:path"
|
import path from "node:path"
|
||||||
import { mergeInteractiveInput, mergeNonInteractiveInput, parseRunModel, pickRunModel } from "../src/mini"
|
import { mergeInteractiveInput, mergeNonInteractiveInput, parseRunModel, pickRunModel } from "../src/mini"
|
||||||
|
import { toolInlineInfo, toolView } from "../src/mini/tool"
|
||||||
|
|
||||||
async function cli(args: string[]) {
|
async function cli(args: string[]) {
|
||||||
const child = Bun.spawn([process.execPath, "run", "src/index.ts", ...args], {
|
const child = Bun.spawn([process.execPath, "run", "src/index.ts", ...args], {
|
||||||
|
|
@ -18,6 +19,23 @@ async function cli(args: string[]) {
|
||||||
}
|
}
|
||||||
|
|
||||||
describe("mini command", () => {
|
describe("mini command", () => {
|
||||||
|
test("renders the renamed shell tool with the shell rule", () => {
|
||||||
|
const part = {
|
||||||
|
id: "part-shell",
|
||||||
|
sessionID: "session-shell",
|
||||||
|
messageID: "message-shell",
|
||||||
|
callID: "call-shell",
|
||||||
|
tool: "shell",
|
||||||
|
state: {
|
||||||
|
status: "pending" as const,
|
||||||
|
input: { command: "pwd" },
|
||||||
|
},
|
||||||
|
} as const
|
||||||
|
|
||||||
|
expect(toolView(part.tool)).toEqual({ output: true, final: false })
|
||||||
|
expect(toolInlineInfo(part)).toMatchObject({ icon: "$", title: "pwd", mode: "block" })
|
||||||
|
})
|
||||||
|
|
||||||
test("uses piped stdin as the initial prompt", () => {
|
test("uses piped stdin as the initial prompt", () => {
|
||||||
expect(mergeInteractiveInput("from stdin", undefined)).toBe("from stdin")
|
expect(mergeInteractiveInput("from stdin", undefined)).toBe("from stdin")
|
||||||
expect(mergeInteractiveInput("from stdin", "from flag")).toBe("from stdin\nfrom flag")
|
expect(mergeInteractiveInput("from stdin", "from flag")).toBe("from stdin\nfrom flag")
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue