Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit ada875d

Browse files
authored
fix(lore): accept -q/--query alias on lore appraise (#28) (#81)
Signed-off-by: SAY-5 <[email protected]> Co-authored-by: SAY-5 <[email protected]>
1 parent 6d9f6c0 commit ada875d

3 files changed

Lines changed: 49 additions & 3 deletions

File tree

internal/command/cobra.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,11 +146,16 @@ func countPositional(args []ArgSpec) int {
146146

147147
// cobraPositionalValidator returns the cobra args validator for the
148148
// spec's positional args. If any positional is Variadic, the count is
149-
// a minimum (cobra.MinimumNArgs). Otherwise exactly-N applies.
149+
// a minimum (cobra.MinimumNArgs); a Variadic positional with
150+
// Required=false drops the floor to 0 so a sibling flag may supply
151+
// the value instead. Otherwise exactly-N applies.
150152
func cobraPositionalValidator(args []ArgSpec) cobra.PositionalArgs {
151153
n := countPositional(args)
152154
for _, a := range args {
153155
if a.Kind == ArgPositional && a.Variadic && !a.MCPOnly {
156+
if !a.Required {
157+
return cobra.MinimumNArgs(0)
158+
}
154159
return cobra.MinimumNArgs(n)
155160
}
156161
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package command
2+
3+
import "testing"
4+
5+
// TestCobraPositionalValidator_VariadicRequired keeps the
6+
// historical behavior: a Required variadic positional demands at
7+
// least one positional CLI arg.
8+
func TestCobraPositionalValidator_VariadicRequired(t *testing.T) {
9+
args := []ArgSpec{
10+
{Name: "query", Kind: ArgPositional, Type: ArgString, Required: true, Variadic: true, Help: "q"},
11+
}
12+
v := cobraPositionalValidator(args)
13+
if err := v(nil, []string{}); err == nil {
14+
t.Fatal("expected error for missing required positional, got nil")
15+
}
16+
if err := v(nil, []string{"foo"}); err != nil {
17+
t.Fatalf("unexpected error with one positional: %v", err)
18+
}
19+
}
20+
21+
// TestCobraPositionalValidator_VariadicOptional asserts the new
22+
// affordance: a non-Required variadic positional accepts zero
23+
// positional args so a sibling flag can supply the value.
24+
func TestCobraPositionalValidator_VariadicOptional(t *testing.T) {
25+
args := []ArgSpec{
26+
{Name: "query", Kind: ArgPositional, Type: ArgString, Variadic: true, Help: "q"},
27+
{Name: "query_flag", CLIFlagName: "query", Short: "q", Kind: ArgFlag, Type: ArgString, CLIOnly: true, Help: "q via flag"},
28+
}
29+
v := cobraPositionalValidator(args)
30+
if err := v(nil, []string{}); err != nil {
31+
t.Fatalf("expected zero positionals to be allowed when Required=false: %v", err)
32+
}
33+
if err := v(nil, []string{"foo", "bar"}); err != nil {
34+
t.Fatalf("unexpected error with two positionals: %v", err)
35+
}
36+
}

internal/lore/appraise_cmd.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212

1313
type AppraiseInput struct {
1414
Query string `json:"query" jsonschema:"search query; BM25+recency+title-boost ranked"`
15+
QueryFlag string `json:"query_flag,omitempty" jsonschema:"-"`
1516
AllProjects bool `json:"all_projects,omitempty" jsonschema:"search every project (recommended for research)"`
1617
Limit int `json:"limit,omitempty" jsonschema:"max results (default 10)"`
1718
Since string `json:"since,omitempty" jsonschema:"entries within window: 7d|2w|1m"`
@@ -31,7 +32,8 @@ var AppraiseCommand = &command.Command[AppraiseInput, AppraiseCmdOutput]{
3132
Short: "search lore before researching or inscribing",
3233
Long: "Search lore before storing new knowledge or spawning research subagents. Returns ranked entries with project, kind, age, and summary — if current results exist, use them instead of re-deriving.",
3334
Args: []command.ArgSpec{
34-
{Name: "query", Kind: command.ArgPositional, Type: command.ArgString, Required: true, Variadic: true, Help: "search query (remaining positional args joined on CLI)"},
35+
{Name: "query", Kind: command.ArgPositional, Type: command.ArgString, Variadic: true, Help: "search query (remaining positional args joined on CLI)"},
36+
{Name: "query_flag", CLIFlagName: "query", Short: "q", Kind: command.ArgFlag, Type: command.ArgString, CLIOnly: true, Help: "search query (alternative to positional form)"},
3537
{Name: "all_projects", Kind: command.ArgFlag, Type: command.ArgBool, Help: "search every project"},
3638
{Name: "limit", Kind: command.ArgFlag, Type: command.ArgInt, Help: "max results (default 10)"},
3739
{Name: "since", Kind: command.ArgFlag, Type: command.ArgString, Help: "entries within window (7d|2w|1m)"},
@@ -40,7 +42,10 @@ var AppraiseCommand = &command.Command[AppraiseInput, AppraiseCmdOutput]{
4042
Handler: func(ctx context.Context, d command.Deps, in AppraiseInput) (AppraiseCmdOutput, error) {
4143
query := strings.TrimSpace(in.Query)
4244
if query == "" {
43-
return AppraiseCmdOutput{}, errors.New("query required")
45+
query = strings.TrimSpace(in.QueryFlag)
46+
}
47+
if query == "" {
48+
return AppraiseCmdOutput{}, errors.New("query required: pass as positional arg or via -q/--query")
4449
}
4550
db, err := d.OpenDB(ctx)
4651
if err != nil {

0 commit comments

Comments
 (0)