1package cli
2
3import (
4 "fmt"
5 "net/http"
6
7 "arche/internal/syncpkg"
8
9 "github.com/spf13/cobra"
10)
11
12var serveCmd = &cobra.Command{
13 Use: "serve",
14 Short: "Start a sync server for this repository",
15 Long: `Start an HTTP sync server allowing remote clients to push and pull objects,
16bookmarks, and issue events.
17
18Authentication is via bearer token. Set --token or configure it in
19.arche/config.toml under [serve]:
20
21 [serve]
22 token = "secret"
23
24.arche/ is local metadata — like .git/ — and is never committed to the
25object store, never synced, and never visible to remote peers. The token
26stays on this machine only.
27
28The server listens on localhost only by default. Use --bind 0.0.0.0 to
29accept connections from other hosts.`,
30 RunE: func(cmd *cobra.Command, args []string) error {
31 r := openRepo()
32 defer r.Close()
33
34 port, _ := cmd.Flags().GetInt("port")
35 bindAddr, _ := cmd.Flags().GetString("bind")
36 token, _ := cmd.Flags().GetString("token")
37
38 if port == 8765 && r.Cfg.Serve.Port != 0 {
39 port = r.Cfg.Serve.Port
40 }
41 if token == "" {
42 token = r.Cfg.Serve.Token
43 }
44 if token == "" {
45 fmt.Println("warning: no token configured — server accepts unauthenticated requests")
46 }
47
48 srv := syncpkg.NewServer(r, token)
49 addr := fmt.Sprintf("%s:%d", bindAddr, port)
50 fmt.Printf("arche serve: listening on http://%s\n", addr)
51 return http.ListenAndServe(addr, srv.Handler())
52 },
53}
54
55func init() {
56 serveCmd.Flags().Int("port", 8765, "port to listen on")
57 serveCmd.Flags().String("bind", "localhost", "address to bind")
58 serveCmd.Flags().String("token", "", "bearer token (overrides config)")
59}