Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
520034c
fix: 修复命令行参数显示逻辑,确保在命令存在时正确显示标志和参数数量
kooksee May 7, 2026
bceba12
feat: 添加运行模式选项,支持一次性、流式和交互运行
kooksee May 7, 2026
b7e2cea
fix: 增强命令行参数结构体注释,改进输出捕获逻辑
kooksee May 7, 2026
d115383
test: 添加测试以验证 fmt.Println 输出在 HTTP 响应中被捕获
kooksee May 7, 2026
5a63807
feat: 添加 --raw-envelope 标志以支持 NDJSON 包装输出
kooksee May 7, 2026
d4bcce5
feat: 添加支持技能输出格式和输出目录选项,增强命令行功能
kooksee May 7, 2026
693fe51
feat: 添加技能元数据支持,增强命令描述和参数提示
kooksee May 7, 2026
a91387d
feat: 更新技能名称格式,使用连字符替代下划线,添加新技能文档
kooksee May 8, 2026
2715060
feat: 更新 --raw-envelope 标志的描述,增强测试以验证输出包装行为
kooksee May 8, 2026
ebcfeeb
feat: 更新 --raw-envelope 标志的描述,添加详细提交结果结构以增强响应处理
kooksee May 8, 2026
dcc7723
feat: 统一命令行选项的继承控制,移除冗余字段,增强帮助信息的显示逻辑
kooksee May 8, 2026
6b9af2a
feat: 更新文档以明确标志继承策略,增强使用规范说明
kooksee May 8, 2026
b3bb5c5
feat: 更新 SKILL.md 文件以符合 Agent Skills 规范,添加字段校验和文档说明
kooksee May 8, 2026
2ec029d
feat: 添加 agent.exclude 元数据以排除基础设施命令,更新文档说明
kooksee May 9, 2026
ed7bd00
test: 更新 TestServeSDKClientCallStreamTool 以验证结构化内容和响应数据
kooksee May 9, 2026
e866cb3
feat(mcp): add MCP client command and web UI integration
kooksee May 9, 2026
485af9e
feat: 重构工具调用结果结构,更新输出模式和测试用例
kooksee May 9, 2026
e12d565
feat: 仅将可继承选项传递给子命令,更新系统标志以包含 ListFormatFlag
kooksee May 9, 2026
0e8b4b3
feat: 更新每个工具的使用指南描述,使用简洁摘要替代详细说明
kooksee May 9, 2026
5226af6
feat: 重构命令提示描述生成,提供更丰富的使用指南和参数摘要
kooksee May 9, 2026
527115b
feat: 添加提示标题以增强命令提示的可读性
kooksee May 9, 2026
bd05ed1
feat: 更新测试用例以验证Plain Handler不应包含StructuredContent
kooksee May 9, 2026
f0f957a
feat: 更新工具结果构建逻辑,确保内容文本符合MCP规范,返回结果的JSON表示
kooksee May 10, 2026
d68d368
feat: 重构工具结果处理逻辑,统一返回结构,更新测试用例以验证无结构内容
kooksee May 10, 2026
df31f3e
feat: 修复 MCP 工具调用重复响应,统一返回结构为 {data, message} JSON 信封,并更新相关文档
kooksee May 10, 2026
6d2c69b
feat: 添加错误检查忽略注释以优化资源清理逻辑
kooksee May 10, 2026
cfb0ac1
feat: 添加 v0.4.0 版本变更记录,包含新增功能、修复和变更说明
kooksee May 10, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@

- 参数形态支持:位置参数、query(`&`)、form(空格分隔 `k=v`)、JSON。
- 测试优先使用表驱动与子测试,覆盖 flag 继承、argv0 分发、参数解析边界。
- Unary/Stream 响应输出采用 NDJSON envelope:`{"$":"resp|error","type":"...","data":...}`。
- `Handler` / `ResponseHandler` / `ResponseStreamHandler` 在能力语义上本质一致;差异主要是编程模型与输出组织方式,不应改变业务语义判断。
- `--raw-envelope` 仅作用于 `ResponseHandler` / `ResponseStreamHandler` 的输出包装;普通 `Handler` 的手动 stdout/stderr 输出不会被自动 envelope 化。

## 集成点与依赖

Expand Down
2 changes: 1 addition & 1 deletion .version/VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v0.3.0
v0.4.0
1 change: 1 addition & 0 deletions .version/changelog/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
## 当前版本文件

- [`Unreleased.md`](Unreleased.md)
- [`v0.4.0.md`](v0.4.0.md)
- [`v0.3.0.md`](v0.3.0.md)
- [`v0.2.0.md`](v0.2.0.md)
- [`v0.1.0.md`](v0.1.0.md)
Expand Down
30 changes: 30 additions & 0 deletions .version/changelog/v0.4.0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# [v0.4.0] - 2026-05-10

## 新增

- `llms-txt --format skill`:支持生成符合 [Agent Skills 规范](https://agentskills.io/specification) 的 SKILL.md 文件,含 YAML frontmatter 校验(`name`、`description`、`compatibility` 字段约束)。
- `Command.Metadata` 的 `skill.*` 前缀约定:可通过 Metadata 配置 SKILL.md 的标准字段(`name`、`description`、`license`、`compatibility`、`allowed-tools`)及自定义 `metadata:` 嵌套属性。
- MCP 工具排除机制:通过 `Metadata["agent.exclude"] = "true"` 将命令及其子命令从 MCP tools/resources/prompts 中排除;内置基础设施命令(`mcp`、`completion`、`doc`、`llms-txt`、`readline`、`richline`、`web`、`webtty`)已默认标记排除。
- `llms-txt` 输出同步排除 `agent.exclude` 命令:Markdown、JSON、Skill 三种格式均过滤标记了 `agent.exclude` 的命令,与 MCP 行为一致。
- `mcp client` 子命令:内置 MCP 客户端,支持 `tools`、`resources`、`prompts`、`call`、`info` 操作,可连接自身(in-process)或外部 MCP 服务(`--command` stdio)。
- Web UI MCP 管理页面:在 `web` 命令的 Web 控制台中新增 MCP 标签页,提供 Tools/Resources/Prompts 浏览与 Tool 调用测试功能。
- `internal/mcpclient` 包:封装 MCP go-sdk 客户端,提供 `ConnectInProcess` 和 `ConnectStdio` 两种连接方式。

## 修复

- MCP 工具调用重复响应:修复 `ResponseHandler` / `ResponseStreamHandler` 的返回值同时出现在 Content text 和 StructuredContent 的问题。响应统一为 `{data, message}` 信封,仅通过 Content text 输出。
- 全局 flag 继承未生效:修复 `GlobalFlags()` 中设置了 `Inherit: false` 的 flag(如 `--list-format`)仍然被无条件注册到子命令的问题。

## 变更

- 简化 `Option` 继承配置:移除 `NoInherit`,统一使用 `Inherit bool` 控制是否向子命令继承(默认不继承)。
- 将 `--list-commands`、`--list-flags`、`--list-format` 调整为 `Inherit=false`,仅保留根命令可见/可用,避免扩散到子命令。
- 移除冗余 `DefaultOptionInherit` 常量;继承控制统一由 `Inherit` 字段显式声明。
- 移除未使用的 `Option.Category` 字段;flag 继承行为统一由 `Inherit` 控制。
- MCP 工具调用响应统一为 `{data, message}` JSON 信封:`data` 承载类型化结果或 stdout 文本,`message` 承载错误详情;移除原有 `structuredContent` 与 `ok/stdout/stderr/error/combined` 冗余字段。
- MCP `outputSchema` 字段从 `output`/`error`/`result` 收敛为 `data`/`message`,与响应信封保持一致。

## 文档

- 同步 MCP.md 输出结构(section 3/5/11):反映 `{data, message}` 统一信封与 `outputSchema` 字段变更。
- 同步 DESIGN.md 执行上下文矩阵:更新 MCP callTool 节点描述。
13 changes: 9 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ README 仅保留“快速上手 + 能力入口”。详细设计与流程请跳

## 核心能力

- 命令树与子命令继承(支持嵌套)
- 命令树与可控子命令继承(支持嵌套)
- 选项多来源配置(命令行、环境变量、默认值)
- 中间件链式编排
- 自动帮助信息与全局标志
Expand Down Expand Up @@ -96,7 +96,7 @@ cmd := redant.Command{

### 第三步:加子命令

用 `Children` 挂载子命令,标志自动继承
用 `Children` 挂载子命令。标志默认不继承,需显式设置 `Inherit: true` 才会向子命令下沉

```go
root := redant.Command{
Expand All @@ -113,6 +113,11 @@ root := redant.Command{
},
},
}

root.Options = redant.OptionSet{
// 显式允许子命令继承
{Flag: "verbose", Value: redant.BoolOf(new(bool)), Inherit: true},
}
```

更多进阶用法(中间件、结构化响应、MCP/Web 集成)见 [`docs/USAGE_AT_A_GLANCE.md`](docs/USAGE_AT_A_GLANCE.md)。
Expand All @@ -128,8 +133,8 @@ root := redant.Command{
常用全局标志:

- `--help, -h`
- `--list-commands`
- `--list-flags`
- `--list-commands`(根命令)
- `--list-flags`(根命令)

详细解析规则见:[`docs/USAGE_AT_A_GLANCE.md`](docs/USAGE_AT_A_GLANCE.md)。

Expand Down
82 changes: 67 additions & 15 deletions args.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,22 +63,63 @@ import (

// ArgValidator is a function that validates an argument.

const internalArgsOverrideFlag = "redant-args"
const (
HelpFlag = "help"
HelpShorthand = "h"

ListCommandsFlag = "list-commands"
ListFlagsFlag = "list-flags"
ListFormatFlag = "list-format"

ListFormatText = "text"
ListFormatJSON = "json"

InternalArgsOverrideFlag = "redant-args"

// AgentExcludeKey is the Metadata key used to exclude a command (and its
// children) from MCP tool/resource/prompt exposure.
AgentExcludeKey = "agent.exclude"

internalArgsOverrideFlag = InternalArgsOverrideFlag
rawEnvelopeFlag = "raw-envelope"

helpFlag = HelpFlag
helpShorthand = HelpShorthand

listCommandsFlag = ListCommandsFlag
listFlagsFlag = ListFlagsFlag
listFormatFlag = ListFormatFlag

listFormatText = ListFormatText
listFormatJSON = ListFormatJSON
)

// InfraMetadata is the standard Metadata map for built-in infrastructure
// commands (e.g. mcp, completion, doc) that should be excluded from
// MCP tool exposure. Use it as the Metadata field of infrastructure commands:
//
// &redant.Command{Use: "mcp", Metadata: redant.InfraMetadata, ...}
var InfraMetadata = map[string]string{AgentExcludeKey: "true"}

type ArgSet []Arg

type Arg struct {
Name string `json:"name,omitempty"`
// Name is the argument name used for display and lookup. (required)
Name string `json:"name,omitempty"`

// Description is human-readable help text for this argument. (optional)
Description string `json:"description,omitempty"`
// Required means this value must be set by some means.
// If `Default` is set, then `Required` is ignored.

// Required means this value must be set by some means. (optional)
// If Default is set, the argument is always considered satisfied.
Required bool `json:"required,omitempty"`

// Default is the default value for this argument.
// Default is the default value for this argument. (optional)
Default string `json:"default,omitempty"`

// Value includes the types listed in values.go.
// Used for type determination and automatic parsing.
// Value holds the typed receiver for automatic parsing. (optional)
// Includes the types listed in values.go (String, Int, Enum, etc.).
// When nil, the raw string value is used as-is.
Value pflag.Value `json:"value,omitempty"`
}

Expand Down Expand Up @@ -255,32 +296,43 @@ func ParseJSONArgs(jsonStr string) (map[string][]string, error) {
func GlobalFlags() OptionSet {
return OptionSet{
{
Flag: "help",
Shorthand: "h",
Flag: helpFlag,
Shorthand: helpShorthand,
Description: "Show help for command.",
Value: BoolOf(new(bool)),
Inherit: true,
},
{
Flag: "list-commands",
Flag: listCommandsFlag,
Description: "List all commands, including subcommands.",
Value: BoolOf(new(bool)),
Inherit: false,
},
{
Flag: "list-flags",
Flag: listFlagsFlag,
Description: "List all flags.",
Value: BoolOf(new(bool)),
Inherit: false,
},
{
Flag: listFormatFlag,
Description: fmt.Sprintf("Output format for --%s and --%s.", listCommandsFlag, listFlagsFlag),
Default: listFormatText,
Value: EnumOf(new(string), listFormatText, listFormatJSON),
Inherit: false,
},
{
Flag: "list-format",
Description: "Output format for --list-commands and --list-flags.",
Default: "text",
Value: EnumOf(new(string), "text", "json"),
Flag: rawEnvelopeFlag,
Description: "Output structured NDJSON envelope instead of plain JSON data.",
Value: BoolOf(new(bool)),
Inherit: true,
},
{
Flag: internalArgsOverrideFlag,
Description: "Internal: override parsed args using repeated/CSV values.",
Value: StringArrayOf(new([]string)),
Hidden: true,
Inherit: true,
},
}
}
Expand Down
5 changes: 3 additions & 2 deletions cmds/completioncmd/completion.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ import (
func New() *redant.Command {
var shell string
return &redant.Command{
Use: "completion [shell]",
Short: "Generate the autocompletion script for the specified shell",
Use: "completion [shell]",
Short: "Generate the autocompletion script for the specified shell",
Metadata: redant.InfraMetadata,
Long: `Generate the autocompletion script for redant for the specified shell.
See each sub-command's help for details on how to use the generated script.`,
Args: []redant.Arg{
Expand Down
47 changes: 6 additions & 41 deletions cmds/completioncmd/testdata/testapp.bash.golden
Original file line number Diff line number Diff line change
Expand Up @@ -32,86 +32,51 @@ testapp() {
opts+='--list-flags '
opts+='--list-format '
opts+='--output '
opts+='--raw-envelope '
opts+='--verbose '
opts+='-v '
local subcmds="completion hello project "
COMPREPLY=( $(compgen -W "$opts $subcmds" -- "$cur") )
;; "testapp completion")
# Completions for completion
local opts="--help "
opts+='--config '
opts+='--help '
opts+='-h '
opts+='--list-commands '
opts+='--list-flags '
opts+='--list-format '
opts+='--output '
opts+='--verbose '
opts+='-v '
opts+='--raw-envelope '
COMPREPLY=( $(compgen -W "$opts" -- "$cur") )
;; "testapp hello")
# Completions for hello
local opts="--help "
opts+='--config '
opts+='--help '
opts+='-h '
opts+='--list-commands '
opts+='--list-flags '
opts+='--list-format '
opts+='--output '
opts+='--verbose '
opts+='-v '
opts+='--raw-envelope '
COMPREPLY=( $(compgen -W "$opts" -- "$cur") )
;; "testapp project")
# Completions for project
local opts="--help "
opts+='--config '
opts+='--help '
opts+='-h '
opts+='--list-commands '
opts+='--list-flags '
opts+='--list-format '
opts+='--output '
opts+='--verbose '
opts+='-v '
opts+='--raw-envelope '
opts+='--all '
opts+='--namespace '
local subcmds="repo "
COMPREPLY=( $(compgen -W "$opts $subcmds" -- "$cur") )
;; "testapp project repo")
# Completions for repo
local opts="--help "
opts+='--config '
opts+='--help '
opts+='-h '
opts+='--list-commands '
opts+='--list-flags '
opts+='--list-format '
opts+='--output '
opts+='--verbose '
opts+='-v '
opts+='--all '
opts+='--namespace '
opts+='--raw-envelope '
opts+='--force '
opts+='--region '
local subcmds="create "
COMPREPLY=( $(compgen -W "$opts $subcmds" -- "$cur") )
;; "testapp project repo create")
# Completions for create
local opts="--help "
opts+='--config '
opts+='--help '
opts+='-h '
opts+='--list-commands '
opts+='--list-flags '
opts+='--list-format '
opts+='--output '
opts+='--verbose '
opts+='-v '
opts+='--all '
opts+='--namespace '
opts+='--force '
opts+='--region '
opts+='--raw-envelope '
opts+='--private '
opts+='--tags '
opts+='--template '
Expand Down
Loading
Loading