frameworks

package
v0.4.0 Latest Latest
Warning

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

Go to latest
Published: Aug 3, 2026 License: Apache-2.0 Imports: 15 Imported by: 0

Documentation

Overview

internal/cli/frameworks/picker.go

Index

Constants

View Source
const APIVersionV1 = "arctl.dev/v1"

Variables

This section is empty.

Functions

func ExecCapture

func ExecCapture(cmd Command, workDir string, vars map[string]any) (string, error)

ExecCapture runs a Command (inline command or script) in workDir, with vars substituted into argv. Captures combined stdout+stderr and returns it.

Commands run via os/exec with an arg list — never through a shell.

func ExecForeground

func ExecForeground(cmd Command, workDir string, vars map[string]any, extraEnv []string) error

ExecForeground runs a Command with stdout/stderr forwarded to the current process. Used by arctl run / build for live output.

func ProjectFrameworksDir

func ProjectFrameworksDir(projectRoot string) string

ProjectFrameworksDir returns the project-local framework directory under projectRoot.

func RenderArgs

func RenderArgs(args []string, vars map[string]any) ([]string, error)

RenderArgs runs Go text/template substitution on each arg independently. Missing values render as their zero value (empty string for strings) so framework commands can use `{{if .X}}--flag={{.X}}{{end}}` to emit-or-skip optional flags — callers only supply the vars that command actually owns. Args that render to an empty string are dropped from the final argv.

func RenderTemplates

func RenderTemplates(p *Framework, dst string, vars map[string]any) error

RenderTemplates walks the framework's templates directory and writes each file to dst. Files ending in `.tmpl` get text/template substitution applied AND the `.tmpl` extension stripped on output. Other files are copied verbatim.

func ToMCPArguments

func ToMCPArguments(args []string) []v1alpha1.MCPArgument

ToMCPArguments converts a flat string list to the v1alpha1 structured form (all positional, no overrides). Used by arctl init after Render.

func UserFrameworksDir

func UserFrameworksDir() string

UserFrameworksDir returns the user-level framework directory. Honors XDG_CONFIG_HOME; falls back to ~/.config/arctl/frameworks.

Types

type Command

type Command struct {
	Command []string `yaml:"command,omitempty"`
	Script  string   `yaml:"script,omitempty"`
}

Command is either an inline arg-list (preferred) or a path to a script.

type EnvSpec

type EnvSpec struct {
	Required []string `yaml:"required,omitempty"`
	Optional []string `yaml:"optional,omitempty"`
}

EnvSpec advertises which env vars the framework's runtime needs. arctl init writes these into .env.example; arctl run validates Required is satisfied.

type Framework

type Framework struct {
	APIVersion   string  `yaml:"apiVersion"`
	Name         string  `yaml:"name"`
	Type         string  `yaml:"type"` // "agent" or "mcp"
	Framework    string  `yaml:"framework"`
	Language     string  `yaml:"language"`
	Description  string  `yaml:"description,omitempty"`
	TemplatesDir string  `yaml:"templatesDir,omitempty"`
	Env          EnvSpec `yaml:"env,omitempty"`
	Build        Command `yaml:"build,omitempty"`
	Run          Command `yaml:"run,omitempty"`
	// LocalInstall runs before stdio `arctl run`. nil = no preflight.
	LocalInstall *Command `yaml:"localInstall,omitempty"`

	// Launch declares per-transport exec defaults for projects scaffolded
	// from this framework. arctl init writes the block matching the
	// requested --transport into the scaffolded mcp.yaml's
	// spec.source.package.launch.
	Launch *FrameworkLaunch `yaml:"launch,omitempty" json:"launch,omitempty"`

	// LocalLaunch overrides Launch for `arctl run` only. nil falls back to Launch.
	LocalLaunch *FrameworkLaunch `yaml:"localLaunch,omitempty" json:"localLaunch,omitempty"`

	// SourceDir is the on-disk root of this framework (its framework.yaml's directory).
	// Set by the loader, not in YAML.
	SourceDir string `yaml:"-"`
}

Framework is the parsed descriptor of a single framework framework.

func DiscoverFromDir

func DiscoverFromDir(root string) ([]*Framework, error)

DiscoverFromDir scans `root` for child directories each containing a `framework.yaml`. Returns parsed Framework values (with SourceDir populated). A missing root is not an error — returns empty slice.

func LoadEmbedded

func LoadEmbedded(stageDir string) ([]*Framework, error)

LoadEmbedded materializes every embedded framework directory into stageDir (one subdir per framework) and returns the parsed Framework values.

stageDir is typically a temp dir created by the caller; arctl shells out to scripts/templates inside it just like out-of-tree frameworks.

func ParseDescriptor

func ParseDescriptor(data []byte) (*Framework, error)

ParseDescriptor parses a framework.yaml.

func Pick

func Pick(opts PickOpts) (*Framework, error)

Pick resolves a framework given user-supplied flags and/or the registry's options. If both flags are set, lookup is direct. Otherwise:

  • interactive: present a picker (TODO: hook bubbletea in a follow-up; for v1 use simple prompts)
  • non-interactive: error with the available options listed.

type FrameworkLaunch

type FrameworkLaunch struct {
	Stdio *MCPLaunch `yaml:"stdio,omitempty" json:"stdio,omitempty"`
	HTTP  *MCPLaunch `yaml:"http,omitempty"  json:"http,omitempty"`
}

FrameworkLaunch declares the per-transport exec defaults a framework scaffolds into mcp.yaml. Each transport (stdio/http) is optional; a framework that only supports one transport may declare just that one. The block matching the user's --transport flag is selected at init.

func (*FrameworkLaunch) ForTransport

func (l *FrameworkLaunch) ForTransport(transport string) *MCPLaunch

ForTransport returns the launch defaults for the given transport, or nil if the framework didn't declare one. Callers fall back to writing no Launch when this is nil.

type LoadOpts

type LoadOpts struct {
	// StageDir is where embedded frameworks are written. Defaults to a tmp dir
	// when empty. arctl normally creates and cleans this on each run.
	StageDir string
	// UserDir is the user-level framework directory (typically UserFrameworksDir()).
	// When empty, the user source is skipped.
	UserDir string
	// ProjectRoot is the current project root for project-local frameworks (typically
	// the cwd or the resolved project dir). When empty, the project source is skipped.
	ProjectRoot string
}

LoadOpts configures top-level framework loading.

type MCPLaunch

type MCPLaunch struct {
	Command string   `yaml:"command,omitempty" json:"command,omitempty"`
	Args    []string `yaml:"args,omitempty"    json:"args,omitempty"`
}

MCPLaunch is one transport's default for spec.source.package.launch in a scaffolded mcp.yaml. Args is a flat list of positional strings; arctl init expands it into the v1alpha1 structured form when it writes mcp.yaml. Args support Go text/template substitution; the supported variable is {{.Port}} (the user's --port flag). Frameworks always declare all-positional defaults at this layer — named args / env overrides are a per-project concern.

func (*MCPLaunch) Render

func (l *MCPLaunch) Render(port int) (string, []string, error)

Render substitutes template variables in Args. The single supported variable today is {{.Port}}, matching the existing pattern used by build.command and run.command. Command is returned verbatim.

type PickOpts

type PickOpts struct {
	Registry       *Registry
	Type           string // "agent" or "mcp"
	Framework      string // optional, from --framework flag
	Language       string // optional, from --language flag
	NonInteractive bool   // when true, never prompt; error if ambiguous
}

PickOpts drives framework selection: explicit flags, interactive picker, or both.

type Registry

type Registry struct {
	// contains filtered or unexported fields
}

Registry indexes frameworks by (type, framework, language). Earlier-source wins on conflict.

func LoadAll

func LoadAll(opts LoadOpts) (*Registry, error)

LoadAll discovers frameworks from project-local, user, and embedded sources (in that order) and returns a populated Registry. Conflicts are recorded but not raised as errors; callers can surface r.Conflicts() to the user.

func NewRegistry

func NewRegistry() *Registry

NewRegistry returns an empty registry.

func (*Registry) Add

func (r *Registry) Add(p *Framework, src Source) error

Add inserts a framework. If the key is already taken, the earlier-source framework wins; the loser is recorded in Conflicts(). Returns nil for both wins and recorded losses.

func (*Registry) Conflicts

func (r *Registry) Conflicts() []registryConflict

Conflicts returns all conflicts seen during Add. Useful for warning logs.

func (*Registry) ListByType

func (r *Registry) ListByType(typ string) []*Framework

ListByType returns all frameworks of the given type, sorted by Name for stable order.

func (*Registry) Lookup

func (r *Registry) Lookup(typ, framework, language string) (*Framework, bool)

Lookup finds a framework by (type, framework, language).

type Source

type Source int

Source identifies where a framework was loaded from. Earlier sources win on conflict.

const (
	SourceInTree   Source = iota // embedded in the arctl binary
	SourceProject                // ./.arctl/frameworks/<name>/
	SourceUserHome               // $XDG_CONFIG_HOME/arctl/frameworks/<name>/
)

func (Source) String

func (s Source) String() string

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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