feat(non-interactive-env): add banned command detection using SHELL_COMMAND_PATTERNS

- Detect and warn about interactive commands (vim, nano, less, etc.)
- Filter out descriptive entries with parentheses from pattern matching

🤖 GENERATED WITH ASSISTANCE OF OhMyOpenCode (https://github.com/code-yeongyu/oh-my-opencode)
This commit is contained in:
YeonGyu-Kim
2025-12-23 10:45:24 +09:00
parent 8495be6218
commit 61740e5561

View File

@@ -1,15 +1,28 @@
import type { PluginInput } from "@opencode-ai/plugin" import type { PluginInput } from "@opencode-ai/plugin"
import { HOOK_NAME, NON_INTERACTIVE_ENV } from "./constants" import { HOOK_NAME, NON_INTERACTIVE_ENV, SHELL_COMMAND_PATTERNS } from "./constants"
import { log } from "../../shared" import { log } from "../../shared"
export * from "./constants" export * from "./constants"
export * from "./types" export * from "./types"
const BANNED_COMMAND_PATTERNS = SHELL_COMMAND_PATTERNS.banned
.filter((cmd) => !cmd.includes("("))
.map((cmd) => new RegExp(`\\b${cmd}\\b`))
function detectBannedCommand(command: string): string | undefined {
for (let i = 0; i < BANNED_COMMAND_PATTERNS.length; i++) {
if (BANNED_COMMAND_PATTERNS[i].test(command)) {
return SHELL_COMMAND_PATTERNS.banned[i]
}
}
return undefined
}
export function createNonInteractiveEnvHook(_ctx: PluginInput) { export function createNonInteractiveEnvHook(_ctx: PluginInput) {
return { return {
"tool.execute.before": async ( "tool.execute.before": async (
input: { tool: string; sessionID: string; callID: string }, input: { tool: string; sessionID: string; callID: string },
output: { args: Record<string, unknown> } output: { args: Record<string, unknown>; message?: string }
): Promise<void> => { ): Promise<void> => {
if (input.tool.toLowerCase() !== "bash") { if (input.tool.toLowerCase() !== "bash") {
return return
@@ -25,6 +38,11 @@ export function createNonInteractiveEnvHook(_ctx: PluginInput) {
...NON_INTERACTIVE_ENV, ...NON_INTERACTIVE_ENV,
} }
const bannedCmd = detectBannedCommand(command)
if (bannedCmd) {
output.message = `⚠️ Warning: '${bannedCmd}' is an interactive command that may hang in non-interactive environments.`
}
log(`[${HOOK_NAME}] Set non-interactive environment variables`, { log(`[${HOOK_NAME}] Set non-interactive environment variables`, {
sessionID: input.sessionID, sessionID: input.sessionID,
env: NON_INTERACTIVE_ENV, env: NON_INTERACTIVE_ENV,