Documentation
¶
Overview ¶
Package capability runs curated host actions on behalf of a contained island — the execution half of the capability broker (docs/capability-broker-spec.md). An Adapter maps a (target, args) request to a host action without ever reaching a shell. Who may invoke what (grants) lives in internal/project; this package is only ever reached after a grant check.
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ( ErrTargetNotFound = errors.New("capability target not found") ErrTargetUntrusted = errors.New("capability target failed its trust checks") ErrTimeout = errors.New("capability execution timed out") )
Sentinel errors let the API layer map adapter failures to HTTP status codes without leaking host detail. A target that *ran* and exited non-zero is NOT an error — it returns a Result with a non-zero ExitCode and a nil error.
Functions ¶
This section is empty.
Types ¶
type Adapter ¶
Adapter maps a (target, args) request to a host action. Implementations MUST never construct a shell command from request data: exec a fixed program with a fixed argv and pass args out-of-band (JSON on stdin). Name identifies the adapter for the Ledger ("script" | "shortcuts").
func DefaultAdapter ¶
DefaultAdapter returns the capability adapter for this daemon host. Linux (and other Unix) get the script adapter, backed by ~/.dejima/capabilities/. macOS will get the Apple Shortcuts adapter in Phase 4; until then it errs rather than silently falling back to scripts (a Mac user expects Shortcuts, not a scripts dir). Selection is by host OS because the adapter is the daemon-side mapping; the wire contract (Request/Result) is identical across adapters.
type Result ¶
Result is the outcome of a target that started. Output is captured stdout+ stderr (bounded); ExitCode is the process exit status.
type ScriptAdapter ¶
type ScriptAdapter struct {
Dir string
Timeout time.Duration // 0 → defaultScriptTimeout
MaxOutput int64 // 0 → defaultScriptMaxOutput
}
ScriptAdapter runs a user-authored executable in Dir (e.g. ~/.dejima/capabilities/) addressed by basename. The directory is the curated allowlist: the island can't write to it, and each target must pass strict trust checks (regular file, owned by the daemon user, not group/world- writable, executable) before it runs. Args arrive as a JSON object on stdin; nothing from the request reaches a shell.
func (*ScriptAdapter) Name ¶
func (a *ScriptAdapter) Name() string
type ShortcutsAdapter ¶
type ShortcutsAdapter struct {
Timeout time.Duration // 0 → defaultScriptTimeout
MaxOutput int64 // 0 → defaultScriptMaxOutput
}
ShortcutsAdapter runs a macOS Apple Shortcut by name via the `shortcuts` CLI. The user's Shortcuts library is the curated allowlist: the operator grants a Shortcut name, and the brain can invoke only granted ones. Args are handed to the shortcut as JSON on a temp input file; the shortcut's result is captured from stdout. The target is matched by exact name (no path to traverse) and only ever appears on argv — never a shell.
Environment caveat (see docs/capability-broker-spec.md): the `shortcuts` CLI talks to a GUI-session helper. A shortcut LOOKS UP fine from a background / daemon context (a missing name returns "Couldn't find shortcut"), but whether a system LaunchDaemon can actually EXECUTE one — versus needing the user's logged-in aqua session — must be verified live with a real Shortcut.
func (*ShortcutsAdapter) Name ¶
func (a *ShortcutsAdapter) Name() string