feat(ipuaro): add commands configuration

- Add CommandsConfigSchema with timeout option
- Integrate timeout configuration in RunCommandTool
- Add 22 new unit tests (19 schema + 3 integration)
- Complete v0.22.0 Extended Configuration milestone
This commit is contained in:
imfozilbek
2025-12-02 03:03:57 +05:00
parent c34d57c231
commit 9c94335729
6 changed files with 233 additions and 10 deletions

View File

@@ -6,6 +6,7 @@ import {
createSuccessResult,
type ToolResult,
} from "../../../domain/value-objects/ToolResult.js"
import type { CommandsConfig } from "../../../shared/constants/config.js"
import { CommandSecurity } from "./CommandSecurity.js"
const execAsync = promisify(exec)
@@ -60,7 +61,7 @@ export class RunCommandTool implements ITool {
{
name: "timeout",
type: "number",
description: "Timeout in milliseconds (default: 30000)",
description: "Timeout in milliseconds (default: from config or 30000, max: 600000)",
required: false,
},
]
@@ -69,10 +70,12 @@ export class RunCommandTool implements ITool {
private readonly security: CommandSecurity
private readonly execFn: typeof execAsync
private readonly configTimeout: number | null
constructor(security?: CommandSecurity, execFn?: typeof execAsync) {
constructor(security?: CommandSecurity, execFn?: typeof execAsync, config?: CommandsConfig) {
this.security = security ?? new CommandSecurity()
this.execFn = execFn ?? execAsync
this.configTimeout = config?.timeout ?? null
}
validateParams(params: Record<string, unknown>): string | null {
@@ -104,7 +107,7 @@ export class RunCommandTool implements ITool {
const callId = `${this.name}-${String(startTime)}`
const command = params.command as string
const timeout = (params.timeout as number) ?? DEFAULT_TIMEOUT
const timeout = (params.timeout as number) ?? this.configTimeout ?? DEFAULT_TIMEOUT
const securityCheck = this.security.check(command)

View File

@@ -125,6 +125,13 @@ export const AutocompleteConfigSchema = z.object({
maxSuggestions: z.number().int().positive().default(10),
})
/**
* Commands configuration schema.
*/
export const CommandsConfigSchema = z.object({
timeout: z.number().int().positive().nullable().default(null),
})
/**
* Full configuration schema.
*/
@@ -140,6 +147,7 @@ export const ConfigSchema = z.object({
session: SessionConfigSchema.default({}),
context: ContextConfigSchema.default({}),
autocomplete: AutocompleteConfigSchema.default({}),
commands: CommandsConfigSchema.default({}),
})
/**
@@ -157,6 +165,7 @@ export type DisplayConfig = z.infer<typeof DisplayConfigSchema>
export type SessionConfig = z.infer<typeof SessionConfigSchema>
export type ContextConfig = z.infer<typeof ContextConfigSchema>
export type AutocompleteConfig = z.infer<typeof AutocompleteConfigSchema>
export type CommandsConfig = z.infer<typeof CommandsConfigSchema>
/**
* Default configuration.