( ctx: CommandContext, config: PluginConfig, startupConfig: PluginConfig, setConfig: ConfigSetter, )
| 90 | } |
| 91 | |
| 92 | export function handleAgentWardCommand( |
| 93 | ctx: CommandContext, |
| 94 | config: PluginConfig, |
| 95 | startupConfig: PluginConfig, |
| 96 | setConfig: ConfigSetter, |
| 97 | ): { text: string } { |
| 98 | const tokens = (ctx.args ?? "").trim().split(/\s+/).filter(Boolean); |
| 99 | if (tokens.length === 0) { |
| 100 | return { text: "Usage:\n /agentward config get [key]\n /agentward config set <key> <value>\n /agentward config reset" }; |
| 101 | } |
| 102 | |
| 103 | const [subCmd, action, ...rest] = tokens; |
| 104 | |
| 105 | if (subCmd !== "config") { |
| 106 | return { text: `Unknown sub-command: /agentward ${subCmd}\nUsage: /agentward config [get|set|reset]` }; |
| 107 | } |
| 108 | |
| 109 | if (action === "get") { |
| 110 | const key = rest[0]; |
| 111 | if (!key) { |
| 112 | getLogger().info("[AgentWard Command] config get (all keys)"); |
| 113 | const tree = formatConfigTree(config); |
| 114 | return { text: `AgentWard Configuration:\n${tree}` }; |
| 115 | } |
| 116 | const value = getConfigAtPath(config, key); |
| 117 | if (value === undefined) { |
| 118 | getLogger().warn(`[AgentWard Command] config get: key not found: ${key}`); |
| 119 | return { text: `Config key not found: ${key}` }; |
| 120 | } |
| 121 | getLogger().info(`[AgentWard Command] config get ${key} = ${JSON.stringify(value)}`); |
| 122 | return { text: `${key} = ${JSON.stringify(value)}` }; |
| 123 | } |
| 124 | |
| 125 | if (action === "set") { |
| 126 | if (rest.length < 2) { |
| 127 | getLogger().warn(`[AgentWard Command] config set: missing arguments: ${rest.join(" ")}`); |
| 128 | return { text: "Usage: /agentward config set <key> <value>" }; |
| 129 | } |
| 130 | const [key, rawValue] = rest; |
| 131 | |
| 132 | getLogger().info(`[AgentWard Command] config set ${key} ${rawValue}`); |
| 133 | |
| 134 | if (!isValidConfigPath(config, key)) { |
| 135 | getLogger().warn(`[AgentWard Command] config set: invalid path: ${key}`); |
| 136 | return { text: `Invalid config path: ${key}\nOnly layers.* and notifications.* can be modified at runtime.` }; |
| 137 | } |
| 138 | |
| 139 | const value = parseValue(rawValue); |
| 140 | const existing = getConfigAtPath(config, key); |
| 141 | getLogger().info(`[AgentWard Command] config set: parsed=${JSON.stringify(value)} (type: ${typeof value}), existing=${JSON.stringify(existing)} (type: ${typeof existing})`); |
| 142 | if (!isTypeCompatible(existing, value)) { |
| 143 | getLogger().warn(`[AgentWard Command] config set: type mismatch for ${key}: expected ${typeof existing}, got ${typeof value}`); |
| 144 | return { text: `Type mismatch for ${key}: expected ${typeof existing}, got ${typeof value}.` }; |
| 145 | } |
| 146 | |
| 147 | const success = setConfigAtPath(config, key, value); |
| 148 | if (!success) { |
| 149 | getLogger().error(`[AgentWard Command] config set: setConfigAtPath failed for ${key}`); |
no test coverage detected