From 6e283c128475772d68300f78fa1fb77d5508ca25 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 17 Feb 2026 20:51:41 +0000 Subject: [PATCH] feat(coredeno): sidecar types, permission flags, socket path Options, Permissions with Deno --allow-* flag generation, DefaultSocketPath with XDG_RUNTIME_DIR support, Sidecar struct. Co-Authored-By: Claude Opus 4.6 --- pkg/coredeno/coredeno.go | 72 +++++++++++++++++++++++++++++++++++ pkg/coredeno/coredeno_test.go | 54 ++++++++++++++++++++++++++ 2 files changed, 126 insertions(+) create mode 100644 pkg/coredeno/coredeno.go create mode 100644 pkg/coredeno/coredeno_test.go diff --git a/pkg/coredeno/coredeno.go b/pkg/coredeno/coredeno.go new file mode 100644 index 0000000..8055087 --- /dev/null +++ b/pkg/coredeno/coredeno.go @@ -0,0 +1,72 @@ +package coredeno + +import ( + "context" + "fmt" + "os" + "os/exec" + "path/filepath" + "strings" + "sync" +) + +// Options configures the CoreDeno sidecar. +type Options struct { + DenoPath string // path to deno binary (default: "deno") + SocketPath string // Unix socket path for gRPC +} + +// Permissions declares per-module Deno permission flags. +type Permissions struct { + Read []string + Write []string + Net []string + Run []string +} + +// Flags converts permissions to Deno --allow-* CLI flags. +func (p Permissions) Flags() []string { + var flags []string + if len(p.Read) > 0 { + flags = append(flags, fmt.Sprintf("--allow-read=%s", strings.Join(p.Read, ","))) + } + if len(p.Write) > 0 { + flags = append(flags, fmt.Sprintf("--allow-write=%s", strings.Join(p.Write, ","))) + } + if len(p.Net) > 0 { + flags = append(flags, fmt.Sprintf("--allow-net=%s", strings.Join(p.Net, ","))) + } + if len(p.Run) > 0 { + flags = append(flags, fmt.Sprintf("--allow-run=%s", strings.Join(p.Run, ","))) + } + return flags +} + +// DefaultSocketPath returns the default Unix socket path. +func DefaultSocketPath() string { + xdg := os.Getenv("XDG_RUNTIME_DIR") + if xdg == "" { + xdg = "/tmp" + } + return filepath.Join(xdg, "core", "deno.sock") +} + +// Sidecar manages a Deno child process. +type Sidecar struct { + opts Options + mu sync.RWMutex + cmd *exec.Cmd + ctx context.Context + cancel context.CancelFunc +} + +// NewSidecar creates a Sidecar with the given options. +func NewSidecar(opts Options) *Sidecar { + if opts.DenoPath == "" { + opts.DenoPath = "deno" + } + if opts.SocketPath == "" { + opts.SocketPath = DefaultSocketPath() + } + return &Sidecar{opts: opts} +} diff --git a/pkg/coredeno/coredeno_test.go b/pkg/coredeno/coredeno_test.go new file mode 100644 index 0000000..dec79bf --- /dev/null +++ b/pkg/coredeno/coredeno_test.go @@ -0,0 +1,54 @@ +package coredeno + +import ( + "os" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestNewSidecar_Good(t *testing.T) { + opts := Options{ + DenoPath: "echo", + SocketPath: "/tmp/test-core-deno.sock", + } + sc := NewSidecar(opts) + require.NotNil(t, sc) + assert.Equal(t, "echo", sc.opts.DenoPath) + assert.Equal(t, "/tmp/test-core-deno.sock", sc.opts.SocketPath) +} + +func TestDefaultSocketPath_Good(t *testing.T) { + path := DefaultSocketPath() + assert.Contains(t, path, "core/deno.sock") +} + +func TestSidecar_PermissionFlags_Good(t *testing.T) { + perms := Permissions{ + Read: []string{"./data/"}, + Write: []string{"./data/config.json"}, + Net: []string{"pool.lthn.io:3333"}, + Run: []string{"xmrig"}, + } + flags := perms.Flags() + assert.Contains(t, flags, "--allow-read=./data/") + assert.Contains(t, flags, "--allow-write=./data/config.json") + assert.Contains(t, flags, "--allow-net=pool.lthn.io:3333") + assert.Contains(t, flags, "--allow-run=xmrig") +} + +func TestSidecar_PermissionFlags_Empty(t *testing.T) { + perms := Permissions{} + flags := perms.Flags() + assert.Empty(t, flags) +} + +func TestDefaultSocketPath_XDG(t *testing.T) { + orig := os.Getenv("XDG_RUNTIME_DIR") + defer os.Setenv("XDG_RUNTIME_DIR", orig) + + os.Setenv("XDG_RUNTIME_DIR", "/run/user/1000") + path := DefaultSocketPath() + assert.Equal(t, "/run/user/1000/core/deno.sock", path) +}