Vectrum
Sign In
53 lines · 1.3 KB · Go
// Command harness is the CLI entry point: flag parsing, wiring, and (from
// Phase 1) the REPL.
package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"os"
	"path/filepath"
	"time"

	"harness/internal/metrics"
	"harness/internal/tools"
)

func main() {
	if err := run(); err != nil {
		fmt.Fprintln(os.Stderr, "harness:", err)
		os.Exit(1)
	}
}

func run() error {
	workdir := flag.String("C", ".", "working root the agent operates in")
	logPath := flag.String("metrics", metrics.DefaultPath, "JSONL event log path")
	flag.Parse()

	root, err := filepath.Abs(*workdir)
	if err != nil {
		return err
	}

	session := time.Now().UTC().Format("20060102T150405Z")
	log, err := metrics.Open(filepath.Join(root, *logPath), session)
	if err != nil {
		return err
	}
	defer log.Close()
	log.Log(metrics.Event{Type: "session_start", Extra: map[string]any{"root": root}})

	reg := tools.NewRegistry(log)
	// Tools land here in Phase 1 (read_file) and Phase 2 (the rest).

	fmt.Printf("harness session %s\nroot:    %s\nmetrics: %s\ntools:   %d registered\n",
		session, root, filepath.Join(root, *logPath), len(reg.List()))
	for _, t := range reg.List() {
		schema, _ := json.Marshal(json.RawMessage(t.InputSchema()))
		fmt.Printf("  %-12s %s\n               %s\n", t.Name(), t.Description(), schema)
	}
	fmt.Println("\nno agent loop yet — Phase 1.")
	return nil
}