nandi/oripublic Fork 0
db7446cc6b52b6bd9196294c1e66e5eb56754d5e
Commits
Clone
git clone https://git.rickub.com/nandi/ori.git
git clone ssh://git@rickub.com/nandi/ori.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

forked from bots-garden/ori

config.go · 77 lines · 2.3 KBGo Blame HistoryRaw
✨ Introduce new feature(s): ACP web client — Go backend (agent, bridge, httpserver, mockagent) + React SPA (Zed-like agent panel), tests, quality gate PASS 2434cc7 k33g yesterday1// Package config parses the command-line configuration of the ori server.
2//
3// It is deliberately tiny: three flags, validated once at startup, then passed
4// around as an immutable value.
5package config
6
7import (
8 "flag"
9 "fmt"
10 "os"
11 "path/filepath"
12 "strings"
13)
14
15// DefaultAgentCommand is the ACP agent spawned when --agent-cmd is not given.
16// It is the official Claude Code ACP adapter, the same one Zed uses.
17const DefaultAgentCommand = "npx -y @zed-industries/claude-code-acp"
18
19// Config holds the runtime configuration of the ori server.
20type Config struct {
21 // Addr is the TCP address the HTTP server listens on, e.g. ":8888".
22 Addr string
23 // Cwd is the absolute working directory handed to the agent session.
24 Cwd string
25 // AgentCommand is the command line used to spawn the ACP agent,
26 // split on whitespace (the first field is the executable).
27 AgentCommand []string
28}
29
30// FromArgs parses command-line arguments (without the program name) into a
31// Config. It returns an error for unknown flags, an empty agent command, or a
32// working directory that does not exist.
33//
34// Example:
35//
36// cfg, err := config.FromArgs([]string{"--addr", ":9000", "--cwd", "/tmp"})
37// if err != nil {
38// log.Fatal(err)
39// }
40// fmt.Println(cfg.Addr) // ":9000"
41func FromArgs(args []string) (Config, error) {
42 fs := flag.NewFlagSet("ori", flag.ContinueOnError)
43 addr := fs.String("addr", ":8888", "TCP address the HTTP server listens on")
44 cwd := fs.String("cwd", "", "working directory for the agent session (default: current directory)")
45 agentCmd := fs.String("agent-cmd", DefaultAgentCommand, "command spawning the ACP agent, split on whitespace")
46
47 if err := fs.Parse(args); err != nil {
48 return Config{}, err
49 }
50
51 command := strings.Fields(*agentCmd)
52 if len(command) == 0 {
53 return Config{}, fmt.Errorf("--agent-cmd must not be empty")
54 }
55
56 dir := *cwd
57 if dir == "" {
58 wd, err := os.Getwd()
59 if err != nil {
60 return Config{}, fmt.Errorf("resolve current directory: %w", err)
61 }
62 dir = wd
63 }
64 absDir, err := filepath.Abs(dir)
65 if err != nil {
66 return Config{}, fmt.Errorf("resolve --cwd: %w", err)
67 }
68 info, err := os.Stat(absDir)
69 if err != nil {
70 return Config{}, fmt.Errorf("--cwd: %w", err)
71 }
72 if !info.IsDir() {
73 return Config{}, fmt.Errorf("--cwd: %s is not a directory", absDir)
74 }
75
76 return Config{Addr: *addr, Cwd: absDir, AgentCommand: command}, nil
77}