Adds 'hyperguild brain pass-rate <skill> [--window 7d] [--json]' calling the new /pass-rate endpoint. Human output: tdd: 47 / 50 = 94% (window: 7d) or 'no data (window: 7d)' when pass_rate is null. PassRateResult mirrors the response envelope; PassRate is *float64 so null is preserved across decode.
107 lines
3.0 KiB
Go
107 lines
3.0 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"errors"
|
|
"flag"
|
|
"fmt"
|
|
"io"
|
|
)
|
|
|
|
func runBrain(ctx context.Context, args []string, stdin io.Reader, stdout, stderr io.Writer) error {
|
|
if len(args) == 0 {
|
|
return errors.New("subcommand required (query|write|pass-rate)")
|
|
}
|
|
switch args[0] {
|
|
case "query":
|
|
return runBrainQuery(ctx, args[1:], stdin, stdout, stderr)
|
|
case "write":
|
|
return runBrainWrite(ctx, args[1:], stdin, stdout, stderr)
|
|
case "pass-rate":
|
|
return runBrainPassRate(ctx, args[1:], stdin, stdout, stderr)
|
|
default:
|
|
return fmt.Errorf("unknown subcommand: %s (expected query|write|pass-rate)", args[0])
|
|
}
|
|
}
|
|
|
|
func runBrainQuery(ctx context.Context, args []string, _ io.Reader, stdout, stderr io.Writer) error {
|
|
fs := flag.NewFlagSet("brain query", flag.ContinueOnError)
|
|
fs.SetOutput(stderr)
|
|
asJSON := fs.Bool("json", false, "output JSON instead of human-readable")
|
|
limit := fs.Int("limit", 5, "maximum number of results")
|
|
if err := fs.Parse(args); err != nil {
|
|
return fmt.Errorf("parse flags: %w", err)
|
|
}
|
|
if fs.NArg() < 1 {
|
|
return errors.New("topic required")
|
|
}
|
|
topic := fs.Arg(0)
|
|
|
|
res, err := newBrainClient().Query(ctx, topic, *limit)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if *asJSON {
|
|
enc := json.NewEncoder(stdout)
|
|
enc.SetIndent("", " ")
|
|
return enc.Encode(res)
|
|
}
|
|
for _, hit := range res.Results {
|
|
fmt.Fprintf(stdout, "%s score=%d %s\n", hit.Path, hit.Score, hit.Title) //nolint:errcheck
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func runBrainWrite(ctx context.Context, args []string, stdin io.Reader, stdout, stderr io.Writer) error {
|
|
fs := flag.NewFlagSet("brain write", flag.ContinueOnError)
|
|
fs.SetOutput(stderr)
|
|
if err := fs.Parse(args); err != nil {
|
|
return fmt.Errorf("parse flags: %w", err)
|
|
}
|
|
if fs.NArg() < 2 {
|
|
return errors.New("type and slug required (e.g. brain write knowledge my-slug)")
|
|
}
|
|
kind := fs.Arg(0)
|
|
slug := fs.Arg(1)
|
|
|
|
res, err := newBrainClient().Write(ctx, kind, slug, stdin)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
fmt.Fprintln(stdout, res.Path) //nolint:errcheck
|
|
return nil
|
|
}
|
|
|
|
func runBrainPassRate(ctx context.Context, args []string, _ io.Reader, stdout, stderr io.Writer) error {
|
|
fs := flag.NewFlagSet("brain pass-rate", flag.ContinueOnError)
|
|
fs.SetOutput(stderr)
|
|
asJSON := fs.Bool("json", false, "output JSON instead of human-readable")
|
|
window := fs.String("window", "7d", "lookback window (e.g. 1h, 24h, 7d, 30d)")
|
|
if err := fs.Parse(args); err != nil {
|
|
return fmt.Errorf("parse flags: %w", err)
|
|
}
|
|
if fs.NArg() < 1 {
|
|
return errors.New("skill required")
|
|
}
|
|
skill := fs.Arg(0)
|
|
|
|
res, err := newBrainClient().PassRate(ctx, skill, *window)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if *asJSON {
|
|
enc := json.NewEncoder(stdout)
|
|
enc.SetIndent("", " ")
|
|
return enc.Encode(res)
|
|
}
|
|
if res.PassRate == nil {
|
|
fmt.Fprintf(stdout, "%s: no data (window: %s)\n", res.Skill, res.Window) //nolint:errcheck
|
|
return nil
|
|
}
|
|
fmt.Fprintf(stdout, "%s: %d / %d = %.0f%% (window: %s)\n", res.Skill, res.Pass, res.Total, *res.PassRate*100, res.Window) //nolint:errcheck
|
|
return nil
|
|
}
|