Skip to content

Commit c4b4159

Browse files
committed
feat: enhance GitHub bundle import functionality and improve CLI command handling
1 parent ae1b4ae commit c4b4159

18 files changed

Lines changed: 465 additions & 35 deletions

docs/harness-v3.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,9 @@ blue harness dataset pull \
467467
blue harness dataset pull \
468468
--source https://github.com/example/harness-datasets \
469469
--bundle-path harness/datasets/demo-bundle
470+
471+
blue harness dataset pull \
472+
--source https://github.com/IceWhaleTech/ZimaOS-Blue
470473
```
471474

472475
The web UI now exposes the same manual flow from `Automation -> Harness -> Datasets & versions -> Import bundle`.

server/cmd/blue/cli_dispatch.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ func cliDispatch(args []string) bool {
6868
return false // config uses viper, let cobra handle it
6969
case "models":
7070
return false // models subcommands need cobra arg validation
71-
case "skills":
71+
case "skills", "skill":
7272
return false // skills subcommands need cobra arg validation
7373
case "context":
7474
if shouldIPCDispatchContext(rest) {

server/cmd/blue/cli_dispatch_test.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,31 @@ func TestCLIDispatch_BrowserNavigateRoutesThroughIPC(t *testing.T) {
132132
}
133133
}
134134

135+
func TestCLIDispatch_SkillAliasFallsThroughToCobra(t *testing.T) {
136+
oldRoundTrip := ipcRoundTripFunc
137+
oldIPCExit := ipcExit
138+
oldCLIExit := cliDispatchExit
139+
oldJSONOutput := jsonOutput
140+
defer func() {
141+
ipcRoundTripFunc = oldRoundTrip
142+
ipcExit = oldIPCExit
143+
cliDispatchExit = oldCLIExit
144+
jsonOutput = oldJSONOutput
145+
}()
146+
147+
ipcRoundTripFunc = func(req *sockipc.Request) (*sockipc.Response, error) {
148+
t.Fatalf("unexpected IPC request: %+v", req)
149+
return nil, nil
150+
}
151+
ipcExit = func(code int) { panic(cliDispatchExitPanic{code: code}) }
152+
cliDispatchExit = func(code int) { panic(cliDispatchExitPanic{code: code}) }
153+
154+
handled, exitCode, stdout := runCLIDispatchForTest([]string{"skill", "install", "humanizer"})
155+
if handled {
156+
t.Fatalf("expected cliDispatch to fall through to cobra, handled=true exitCode=%d stdout=%q", exitCode, stdout)
157+
}
158+
}
159+
135160
func runCLIDispatchForTest(args []string) (handled bool, exitCode int, stdout string) {
136161
oldStdout := os.Stdout
137162
r, w, err := os.Pipe()

server/cmd/blue/harness_dataset_bundle.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ func init() {
8686
harnessDatasetImportCmd.Flags().StringVar(&harnessDatasetBundleLocalPath, "path", "", "local bundle directory path")
8787
harnessDatasetImportCmd.Flags().StringVar(&harnessDatasetBundleVersion, "version", "", "bundle version to import (defaults to dataset.yaml default_version)")
8888
harnessDatasetPullCmd.Flags().StringVar(&harnessDatasetBundleSource, "source", "", "GitHub repo or tree URL for the bundle source")
89-
harnessDatasetPullCmd.Flags().StringVar(&harnessDatasetBundlePath, "bundle-path", "", "bundle path inside the GitHub repo when --source is a repo URL")
89+
harnessDatasetPullCmd.Flags().StringVar(&harnessDatasetBundlePath, "bundle-path", "", "bundle path inside the GitHub repo when --source is a repo URL (defaults to harness/datasets/pinchbench for IceWhaleTech/ZimaOS-Blue)")
9090
harnessDatasetPullCmd.Flags().StringVar(&harnessDatasetBundleVersion, "version", "", "bundle version to import (defaults to dataset.yaml default_version)")
9191
harnessDatasetCmd.AddCommand(harnessDatasetImportCmd)
9292
harnessDatasetCmd.AddCommand(harnessDatasetPullCmd)
@@ -382,6 +382,9 @@ func resolveHarnessDatasetGitHubSource(source, bundlePath string) (harnessDatase
382382
}
383383
if matches := skillbundle.GitHubRepoURLPattern.FindStringSubmatch(source); len(matches) == 3 {
384384
bundlePath = strings.Trim(strings.TrimSpace(bundlePath), "/")
385+
if bundlePath == "" {
386+
bundlePath = harnesspkg.DefaultDatasetBundleGitHubPathForRepo(matches[1], matches[2])
387+
}
385388
if bundlePath == "" {
386389
return harnessDatasetGitHubSource{}, fmt.Errorf("--bundle-path is required for GitHub repo URLs")
387390
}

server/cmd/blue/harness_dataset_bundle_test.go

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,54 @@ func TestLoadHarnessDatasetBundleFromGitHubRepoURLWithBundlePath(t *testing.T) {
251251
}
252252
}
253253

254+
func TestLoadHarnessDatasetBundleFromOfficialRepoURLDefaultsPinchBenchBundlePath(t *testing.T) {
255+
resetHarnessCLIState(t)
256+
257+
datasetYAML, manifestJSON, evalSpecYAML := harnessDatasetBundleFixtureContents()
258+
oldClient := harnessDatasetBundleHTTPClient
259+
harnessDatasetBundleHTTPClient = &http.Client{
260+
Transport: roundTripFunc(func(req *http.Request) (*http.Response, error) {
261+
var body string
262+
switch {
263+
case strings.Contains(req.URL.String(), "/main/harness/datasets/pinchbench/dataset.yaml"):
264+
body = datasetYAML
265+
case strings.Contains(req.URL.String(), "/main/harness/datasets/pinchbench/versions/v1/manifest.json"):
266+
body = manifestJSON
267+
case strings.Contains(req.URL.String(), "/main/harness/datasets/pinchbench/versions/v1/eval-specs/default.yaml"):
268+
body = evalSpecYAML
269+
default:
270+
return &http.Response{
271+
StatusCode: http.StatusNotFound,
272+
Body: io.NopCloser(strings.NewReader("not found")),
273+
Header: make(http.Header),
274+
}, nil
275+
}
276+
return &http.Response{
277+
StatusCode: http.StatusOK,
278+
Body: io.NopCloser(strings.NewReader(body)),
279+
Header: make(http.Header),
280+
}, nil
281+
}),
282+
}
283+
t.Cleanup(func() {
284+
harnessDatasetBundleHTTPClient = oldClient
285+
})
286+
287+
req, err := loadHarnessDatasetBundleFromGitHubSource("https://github.com/IceWhaleTech/ZimaOS-Blue", "", "")
288+
if err != nil {
289+
t.Fatalf("loadHarnessDatasetBundleFromGitHubSource: %v", err)
290+
}
291+
if req.SourceType != "dataset_bundle_github" {
292+
t.Fatalf("source_type = %q, want dataset_bundle_github", req.SourceType)
293+
}
294+
if req.SourceRef != "https://github.com/IceWhaleTech/ZimaOS-Blue/tree/main/harness/datasets/pinchbench" {
295+
t.Fatalf("source_ref = %q, want canonical pinchbench tree url", req.SourceRef)
296+
}
297+
if req.Dataset.Name != "demo-bundle" || req.Version.Version != "v1" {
298+
t.Fatalf("request = %#v, want demo-bundle/v1", req)
299+
}
300+
}
301+
254302
func TestLoadHarnessDatasetBundleFromDirUsesRequestedVersionOverride(t *testing.T) {
255303
bundleDir := writeHarnessDatasetBundleMultiVersionFixture(t, t.TempDir())
256304

server/cmd/blue/main_startup_test.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,3 +123,13 @@ func TestRootCommand_RegistersCustomCompletionCommand(t *testing.T) {
123123
t.Fatalf("expected custom completion command to be registered, got %#v", cmd)
124124
}
125125
}
126+
127+
func TestRootCommand_RegistersSkillsAlias(t *testing.T) {
128+
cmd, _, err := rootCmd.Find([]string{"skill"})
129+
if err != nil {
130+
t.Fatalf("rootCmd.Find(skill): %v", err)
131+
}
132+
if cmd == nil || cmd.Name() != "skills" {
133+
t.Fatalf("expected skill alias to resolve to skills command, got %#v", cmd)
134+
}
135+
}

server/cmd/blue/skills.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,9 @@ var (
4040

4141
// skillsCmd represents the skills command
4242
var skillsCmd = &cobra.Command{
43-
Use: "skills",
44-
Short: "Skill management",
43+
Use: "skills",
44+
Aliases: []string{"skill"},
45+
Short: "Skill management",
4546
Long: `Manage ZimaOS-Blue skills.
4647
4748
Subcommands:
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package harness
2+
3+
import "strings"
4+
5+
const defaultPinchBenchDatasetBundleGitHubPath = "harness/datasets/pinchbench"
6+
7+
func DefaultDatasetBundleGitHubPathForRepo(owner, repo string) string {
8+
if strings.EqualFold(strings.TrimSpace(owner), "IceWhaleTech") &&
9+
strings.EqualFold(strings.TrimSpace(repo), "ZimaOS-Blue") {
10+
return defaultPinchBenchDatasetBundleGitHubPath
11+
}
12+
return ""
13+
}

server/internal/harness/dataset_bundle_import_source_test.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,56 @@ func TestLoadImportDatasetBundleRequestFromGitHubSourceUsesFallback(t *testing.T
8383
}
8484
}
8585

86+
func TestLoadImportDatasetBundleRequestFromOfficialRepoURLDefaultsPinchBenchBundlePath(t *testing.T) {
87+
datasetYAML, manifestJSON, evalSpecYAML := testDatasetBundleFixtureContents()
88+
oldClient := datasetBundleLoaderHTTPClient
89+
datasetBundleLoaderHTTPClient = &http.Client{
90+
Transport: datasetBundleRoundTripFunc(func(req *http.Request) (*http.Response, error) {
91+
var body string
92+
switch {
93+
case strings.Contains(req.URL.String(), "/main/harness/datasets/pinchbench/dataset.yaml"):
94+
body = datasetYAML
95+
case strings.Contains(req.URL.String(), "/main/harness/datasets/pinchbench/versions/v1/manifest.json"):
96+
body = manifestJSON
97+
case strings.Contains(req.URL.String(), "/main/harness/datasets/pinchbench/versions/v1/eval-specs/default.yaml"):
98+
body = evalSpecYAML
99+
default:
100+
return &http.Response{
101+
StatusCode: http.StatusNotFound,
102+
Body: io.NopCloser(strings.NewReader("not found")),
103+
Header: make(http.Header),
104+
}, nil
105+
}
106+
return &http.Response{
107+
StatusCode: http.StatusOK,
108+
Body: io.NopCloser(strings.NewReader(body)),
109+
Header: make(http.Header),
110+
}, nil
111+
}),
112+
}
113+
t.Cleanup(func() {
114+
datasetBundleLoaderHTTPClient = oldClient
115+
})
116+
117+
req, err := loadImportDatasetBundleRequestFromGitHubSource(
118+
"https://github.com/IceWhaleTech/ZimaOS-Blue",
119+
"",
120+
"",
121+
)
122+
if err != nil {
123+
t.Fatalf("loadImportDatasetBundleRequestFromGitHubSource: %v", err)
124+
}
125+
if req.SourceType != "dataset_bundle_github" {
126+
t.Fatalf("source_type = %q, want dataset_bundle_github", req.SourceType)
127+
}
128+
if req.SourceRef != "https://github.com/IceWhaleTech/ZimaOS-Blue/tree/main/harness/datasets/pinchbench" {
129+
t.Fatalf("source_ref = %q, want canonical pinchbench tree url", req.SourceRef)
130+
}
131+
if req.Version.Version != "v1" || len(req.EvalSpecs) != 1 || req.EvalSpecs[0].Name != "Default Demo Eval" {
132+
t.Fatalf("request = %#v, want v1 with imported eval spec", req)
133+
}
134+
}
135+
86136
func TestHandler_ImportDatasetBundleFromLocalSource(t *testing.T) {
87137
controller := newTestController(t)
88138
handler := NewHandler(controller)

server/internal/harness/dataset_bundle_loader.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,9 @@ func resolveDatasetBundleGitHubSource(source, bundlePath string) (datasetBundleG
296296
}
297297
if matches := skillbundle.GitHubRepoURLPattern.FindStringSubmatch(source); len(matches) == 3 {
298298
bundlePath = strings.Trim(strings.TrimSpace(bundlePath), "/")
299+
if bundlePath == "" {
300+
bundlePath = DefaultDatasetBundleGitHubPathForRepo(matches[1], matches[2])
301+
}
299302
if bundlePath == "" {
300303
return datasetBundleGitHubSource{}, fmt.Errorf("bundle_path is required for GitHub repo URLs")
301304
}

0 commit comments

Comments
 (0)