platform

package
v0.4.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 24, 2026 License: MIT Imports: 8 Imported by: 0

Documentation

Overview

Package platform adapts brainjar's composed prompts to agent-specific config files on disk. Each adapter knows where its platform reads config from, how to merge brainjar-owned content with user-authored content, and how to install the hook + MCP plumbing that keeps the file current as state changes.

Adapters register themselves at init time via Register and are resolved by name through Get. Concrete adapters live in sibling subpackages (e.g. internal/platform/claude) and are bundled into the CLI by blank-importing each subpackage from internal/cli.

Index

Constants

View Source
const DefaultName = "claude"

DefaultName is the platform used when a workspace is initialized without an explicit choice.

Variables

View Source
var ErrUnsupportedByPlatform = errors.New("platform: operation not supported")

ErrUnsupportedByPlatform signals that an operation is not implemented by the active adapter (e.g. Hooks on a platform with no hook surface). The CLI maps it to a usage error (exit 2).

View Source
var ErrUnsupportedScope = errors.New("platform: scope not supported")

ErrUnsupportedScope signals that an operation is implemented but the requested scope isn't (e.g. HookScopeLocal on a platform that has no gitignored-override file). Like ErrUnsupportedByPlatform, this is a usage error, not a system error.

Functions

func Names

func Names() []string

Names returns the sorted slugs of every registered adapter. Used by CLI surfaces that need to list what's available.

func Register

func Register(p Platform)

Register adds p to the registry under its Name(). Intended to be called from an adapter's init(). Panics on duplicate registration — duplicate adapter slugs are a programming error, not a runtime one.

Types

type Capabilities

type Capabilities struct {
	Sync   bool     `json:"sync"`
	Hooks  bool     `json:"hooks"`
	MCP    bool     `json:"mcp"`
	Spawn  bool     `json:"spawn"`
	Scopes ScopeSet `json:"scopes"`
}

Capabilities enumerates what an adapter can do. The zero value means "supports nothing" — every adapter must implement Capabilities() and set the fields explicitly.

type HookScope

type HookScope int

HookScope selects which settings file a feature-group operation (hooks or MCP) targets. The three scopes mirror the tiers every supported platform exposes:

  • Project scope writes to the platform's committed per-repository settings (e.g. <projectRoot>/.claude/settings.json). Everyone who clones the repo inherits the entry.
  • Local scope writes to the platform's per-repository override file that is conventionally gitignored (e.g. <projectRoot>/.claude/settings.local.json). The entry fires only for this checkout and is not shared with collaborators.
  • User scope writes to the platform's global user settings (e.g. ~/.claude/settings.json), so the entry applies in every project.
const (
	HookScopeProject HookScope = iota
	HookScopeLocal
	HookScopeUser
)

func ParseHookScope

func ParseHookScope(s string) (HookScope, error)

ParseHookScope maps a CLI slug to a HookScope. Empty is treated as project to keep the default easy.

func (HookScope) NeedsProjectRoot

func (s HookScope) NeedsProjectRoot() bool

NeedsProjectRoot reports whether the scope requires a project root. User scope is filesystem-rooted at the user's home and ignores the projectRoot argument; project and local scope both need one.

func (HookScope) String

func (s HookScope) String() string

String returns the canonical slug used on the CLI, in JSON output, and in error messages. Keep in sync with ParseHookScope.

type HookStatus

type HookStatus struct {
	Installed bool   `json:"installed"`
	UpToDate  bool   `json:"up_to_date"`
	Command   string `json:"command,omitempty"`
}

HookStatus is the result of Platform.HooksStatus. Installed reports whether any brainjar-owned hook is present; UpToDate reports whether the installed command matches what InstallHooks would write now.

type MCPStatus

type MCPStatus struct {
	Installed bool     `json:"installed"`
	UpToDate  bool     `json:"up_to_date"`
	Approved  *bool    `json:"approved,omitempty"`
	Command   string   `json:"command,omitempty"`
	Args      []string `json:"args,omitempty"`
}

MCPStatus is the result of Platform.MCPStatus. Installed reports whether brainjar is registered; UpToDate reports whether the stored command + args match what InstallMCP would write now. Approved is populated only for platforms that have a separate approval step (nil means "not applicable").

type Platform

type Platform interface {

	// Name returns the canonical slug used to look this adapter up in
	// the registry and in user-facing config (e.g. "claude").
	Name() string

	// Capabilities reports which features and scopes the adapter
	// supports. The CLI uses it to render precise error messages and
	// to power `brainjar platform list`.
	Capabilities() Capabilities

	// Sync writes prompt into the platform's managed section inside
	// projectRoot. Idempotent: if the managed section already matches,
	// Sync makes no filesystem change. Content outside the managed
	// section is preserved byte-for-byte.
	Sync(ctx context.Context, prompt string, projectRoot string) error

	// InstallHooks registers brainjar-owned hook entries in the
	// platform's settings file at the scope requested. User-authored
	// hooks and unrelated settings are preserved. Re-invoking with the
	// same binary is a no-op; re-invoking after the binary path
	// changes upserts. projectRoot is used when scope is
	// HookScopeProject or HookScopeLocal and ignored when scope is
	// HookScopeUser.
	InstallHooks(ctx context.Context, scope HookScope, projectRoot string) error

	// RemoveHooks strips only brainjar-owned entries from the
	// platform's settings file at the requested scope. User hooks and
	// other settings survive.
	RemoveHooks(ctx context.Context, scope HookScope, projectRoot string) error

	// HooksStatus reports whether brainjar hooks are installed at the
	// requested scope and whether the installed command matches what
	// InstallHooks would write now.
	HooksStatus(ctx context.Context, scope HookScope, projectRoot string) (HookStatus, error)

	// InstallMCP registers brainjar as an MCP server in the platform's
	// config at the given scope. projectRoot is used when scope needs
	// it; home is the resolved --home value baked into the registered
	// command args so the server targets the right brainjar workspace.
	InstallMCP(ctx context.Context, scope HookScope, projectRoot, home string) error

	// RemoveMCP strips only brainjar-owned MCP entries at the given
	// scope. Other entries are preserved.
	RemoveMCP(ctx context.Context, scope HookScope, projectRoot string) error

	// MCPStatus reports whether brainjar is registered at the given
	// scope and whether the installed command + args match what
	// InstallMCP would write now for the given home. Pass the same
	// home that would be used for a re-install so UpToDate reflects
	// real drift (e.g. the user changed --home since install).
	MCPStatus(ctx context.Context, scope HookScope, projectRoot, home string) (MCPStatus, error)

	// Spawn returns an *exec.Cmd ready to start the platform's agent
	// binary with prompt injected as its session system prompt. The
	// caller runs the Cmd, wires stdio, forwards signals, and
	// propagates the exit code.
	//
	// Prompt injection is platform-specific (--append-system-prompt for
	// Claude, --system-prompt for Codex, …). Adapters choose the flag,
	// the binary name, and any mandatory positional args.
	//
	// extraArgs are appended after the platform's injection flag so the
	// user can still pass agent-native flags (--model, --add-dir, …).
	//
	// Adapters that have no CLI injection surface return
	// ErrUnsupportedByPlatform. The CLI maps that to exit 2 with a
	// user-facing hint.
	//
	// Spawn does not touch the filesystem and does not preconfigure
	// stdio — the caller wires Stdin/Stdout/Stderr. exec.LookPath runs
	// when the caller Start()s the Cmd, so an absent binary surfaces
	// as exec.ErrNotFound at that point.
	Spawn(ctx context.Context, prompt string, extraArgs []string) (*exec.Cmd, error)

	// MapModelPrefs translates a generic ModelPrefs into a params map
	// the platform's runtime understands (e.g. Claude model IDs).
	MapModelPrefs(prefs *models.ModelPrefs) map[string]any
}

Platform is a filesystem adapter for one agent runtime (Claude, Codex, Cursor, …). Every method is local-only — no network, no daemon.

Methods are grouped by concern: identity, prompt sync, hook plumbing, MCP registration, and a model-preference translator. Feature groups follow a uniform Install / Remove / Status triad so the CLI surface stays consistent across adapters and scopes.

func Get

func Get(name string) (Platform, error)

Get resolves an adapter by name. Empty or unknown names return a BadRequest error with a config-pointing hint.

type ScopeSet

type ScopeSet struct {
	Project bool `json:"project"`
	Local   bool `json:"local"`
	User    bool `json:"user"`
}

ScopeSet records which scopes an adapter accepts. A given method may still refuse individual scopes (e.g. Cursor's Sync has no User path), but the ScopeSet is the union across the adapter's operations.

Directories

Path Synopsis
Package adapterkit holds the helpers shared by every brainjar Platform adapter: marker constants, brainjar brand strings, atomic file / JSON I/O, hook-entry identity, and the managed-section merge algorithm.
Package adapterkit holds the helpers shared by every brainjar Platform adapter: marker constants, brainjar brand strings, atomic file / JSON I/O, hook-entry identity, and the managed-section merge algorithm.
Package claude is the brainjar Platform adapter for Claude Code.
Package claude is the brainjar Platform adapter for Claude Code.
Package codex is the brainjar Platform adapter for OpenAI Codex CLI.
Package codex is the brainjar Platform adapter for OpenAI Codex CLI.
Package cursor is the brainjar Platform adapter for the Cursor IDE (cursor.com).
Package cursor is the brainjar Platform adapter for the Cursor IDE (cursor.com).
Package testutil provides shared test contracts that every platform adapter runs against.
Package testutil provides shared test contracts that every platform adapter runs against.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL