assist

package
v1.6.2 Latest Latest
Warning

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

Go to latest
Published: Sep 9, 2026 License: GPL-3.0 Imports: 51 Imported by: 0

Documentation

Overview

Package assist implements `sling assist`: profile, skills/MCP install, prompt, resume.

Index

Constants

View Source
const (
	PatternMaterialPrefix = "v1p" // skeleton-only
	EdgeMaterialPrefix    = "v1e" // source|target|skeleton
)

Material prefixes distinguish pattern vs edge digests (composite signature).

View Source
const AgentBrowserVersion = "0.34.0"

AgentBrowserVersion is the pinned CLI release. Override with AGENT_BROWSER_VERSION. Pin checked against https://github.com/vercel-labs/agent-browser/releases (v0.34.0, 2026-08-11).

View Source
const AlgorithmVersion = "v1"

AlgorithmVersion labels the normalizer generation (not a material prefix).

View Source
const AssistDocsURL = "https://docs.slingdata.io/sling-cli/assist"

AssistDocsURL is linked from the failure hint.

View Source
const CompositeIDLen = PartIDLen * 2

CompositeIDLen is PatternID + EdgeID (16 hex chars, no separator).

View Source
const ExecsMaxEntries = 100

ExecsMaxEntries caps failure snapshots under ~/.sling/assist/errors/.

View Source
const HistoryMaxEntries = 100

HistoryMaxEntries caps entries under ~/.sling/assist/history/.

View Source
const OpenCodeVersion = "1.18.18"

OpenCodeVersion is the pinned CLI release. Override with OPENCODE_VERSION. Pin checked against https://github.com/anomalyco/opencode/releases (v1.18.18, 2026-08-13).

View Source
const PartIDLen = 8

PartIDLen is hex chars kept for each of pattern and edge digests.

View Source
const SchemaVersion = 1

SchemaVersion is the on-disk layout version.

View Source
const ShortExecIDLen = 8

ShortExecIDLen is the exec-id prefix length shown in the failure hint. ResolveLocalExec accepts any unique prefix.

View Source
const SignatureIDLen = PartIDLen

SignatureIDLen is an alias for PartIDLen.

View Source
const ZenFreeDisclosure = "free-model prompts may be used for training"

ZenFreeDisclosure is shown when the harness uses a free Zen model.

View Source
const ZenFreeModel = "opencode/big-pickle"

ZenFreeModel is the default free OpenCode Zen model id (`provider/model`).

Variables

View Source
var ErrUserAborted = errors.New("user aborted")

ErrUserAborted is returned by interactive forms when the user declines.

View Source
var PromptsYAML []byte
View Source
var SkillsFS embed.FS

Functions

func AgentBrowserAssetName

func AgentBrowserAssetName(goos, goarch string) (string, error)

AgentBrowserAssetName is the GitHub asset for goos/goarch (pinned layout, not /latest).

func ApplyHarnessProviderConfig

func ApplyHarnessProviderConfig() error

ApplyHarnessProviderConfig writes model (and provider) when missing.

func AssistDir

func AssistDir() string

AssistDir returns ~/.sling/assist/.

func AutoRefresh

func AutoRefresh(ctx context.Context) (string, error)

AutoRefresh updates installed skills to match the embedded bundle. It also removes retired skill directories. This function runs on each `sling assist` command. If no current skills exist, it does not install them. If the user ran uninstall, it does not install them again. Returns a notice line when something changed.

func AutoTrim

func AutoTrim() error

AutoTrim deletes the oldest entries until at most HistoryMaxEntries remain.

func AutoTrimExecs

func AutoTrimExecs() error

AutoTrimExecs deletes the oldest failure snapshots until at most ExecsMaxEntries remain. Covers both errors/executions/<id>/ and the legacy errors/<id>/ layout. Best-effort: a snapshot that cannot be removed is reported, and the rest still get trimmed.

func BundledAgentBrowserPath

func BundledAgentBrowserPath() string

BundledAgentBrowserPath is ~/.sling/bin/agent-browser/<version>/agent-browser[.exe].

func BundledOpenCodePath

func BundledOpenCodePath() string

BundledOpenCodePath is ~/.sling/bin/opencode/<version>/opencode[.exe].

func CanonicalSkillsDir

func CanonicalSkillsDir() string

CanonicalSkillsDir returns ~/.agents/skills/ (shared skill source of truth).

func EdgeMaterial

func EdgeMaterial(skeleton string, meta SignMeta) string

EdgeMaterial builds the edge-layer hash input (types + skeleton).

v1e|<source>|<target>|<skeleton>

Task type is omitted: it is redundant given source and target connector types.

func EnsureAssistReady

func EnsureAssistReady() error

func EnsureBinAgentBrowser

func EnsureBinAgentBrowser() (binPath string, err error)

EnsureBinAgentBrowser returns a usable agent-browser binary. Order: AGENT_BROWSER_PATH, $PATH, then a versioned download under ~/.sling/bin/agent-browser/<version>/.

func EnsureBinOpenCode

func EnsureBinOpenCode() (binPath string, err error)

EnsureBinOpenCode returns a usable opencode binary. Order: OPENCODE_PATH, $PATH, then a versioned download under ~/.sling/bin/opencode/<version>/.

func ErrorsDir

func ErrorsDir() string

ErrorsDir returns ~/.sling/assist/errors/ (legacy snapshot root). New snapshots live under ExecutionsDir(); readers scan both.

func ExecutionsDir

func ExecutionsDir() string

ExecutionsDir returns ~/.sling/assist/errors/executions/ (failure snapshots).

func ExitCodeOf

func ExitCodeOf(err error) (int, bool)

ExitCodeOf returns (code, true) when err is or wraps an AgentExitError.

func FormatRelative

func FormatRelative(t time.Time) string

FormatRelative returns a short human relative time like "3h ago", "yesterday", "2026-05-01" (for entries older than a week).

func HarnessProviderConfig

func HarnessProviderConfig() map[string]any

HarnessProviderConfig is the opencode.json fragment for the harness choice.

func HashMaterial

func HashMaterial(material string) string

HashMaterial is an alias for HashPart.

func HashPart

func HashPart(material string) string

HashPart returns the first PartIDLen hex chars of SHA-256(material).

func HistoryDir

func HistoryDir() string

HistoryDir returns ~/.sling/assist/history/.

func IsFreshInstall

func IsFreshInstall() bool

IsFreshInstall is true when env.yaml is the seeded default and there is no assist history (sessions or failure snapshots). Does not create dirs.

func LaunchAgent

func LaunchAgent(opts LaunchOptions) error

LaunchAgent execs the given CLI agent with the prompt.

func LaunchResume

func LaunchResume(agent, harnessSessionID, model string) error

LaunchResume execs the harness resume command. No prompt is sent.

func LogsRoot

func LogsRoot() string

LogsRoot returns ~/.sling/logs (SLING_LOG_DIR day files). Not used for failure snapshots.

func MD5OfEmbeddedSkill

func MD5OfEmbeddedSkill(rel string) (string, error)

MD5OfEmbeddedSkill returns the MD5 of an embedded skill file.

func MD5OfFile

func MD5OfFile(path string) (string, error)

MD5OfFile returns the MD5 hex of a file.

func Material

func Material(skeleton string, meta SignMeta) string

Material is an alias for EdgeMaterial (edge-layer input).

func MaybePrintErrorHint

func MaybePrintErrorHint(execID string)

MaybePrintErrorHint is kept for callers/tests that only have an exec id. Prefer PrintFailureFooter when error text is available.

func NestedLaunch

func NestedLaunch() bool

NestedLaunch reports an already-running CLI agent (or non-TTY stdin). When true, print the prompt instead of spawning another agent.

func OpenBrowser

func OpenBrowser(rawURL string) error

OpenBrowser opens url in the default browser. Always also print the URL.

func OpenCodeAssetName

func OpenCodeAssetName(goos, goarch string) (string, error)

OpenCodeAssetName is the GitHub asset for goos/goarch (pinned layout, not /latest).

func ParseSignatureID

func ParseSignatureID(raw string) (compact string, patternOnly bool, err error)

ParseSignatureID normalizes user input into compact 8 or 16 hex lowercase. Accepts "aabbccdd", "aabbccdd-eeff0011", "aabbccddeeff0011", or a Display() line. Returns compact hex and whether it is pattern-only (len 8) vs full composite (len 16).

func PatternMaterial

func PatternMaterial(skeleton string) string

PatternMaterial builds the pattern-layer hash input (skeleton only).

v1p|<skeleton>

func PrintFailureFooter

func PrintFailureFooter(opts FailureFooterOpts)

PrintFailureFooter prints one indented hint line after a failure. The error signature is not printed: it is agent context, written to meta.json by WriteFailureSnapshot and read back by Probe. Suppressed when HintInErrors is false or SLING_ASSIST_HINT is falsey.

func ProbeZenFreeModel

func ProbeZenFreeModel() (ok bool, detail string)

ProbeZenFreeModel reports whether the free Zen catalog is reachable.

func RecommendedAgent

func RecommendedAgent() string

RecommendedAgent is the first ranked CLI agent (authenticated on PATH, else the only one).

func RenderLanding

func RenderLanding(kind LandingKind, p PromptContext, width int) string

RenderLanding prints the TTY card for one probe state. width 0 → 80.

func RenderPrompt

func RenderPrompt(p PromptContext) (string, error)

RenderPrompt is the exported wrapper for (PromptContext).Render.

func ResolveAgent

func ResolveAgent(override string, prof Profile) (string, error)

ResolveAgent picks the agent to launch, in order: 1. --agent override (must be a known CLI agent and detected on disk). 2. profile.Agent (when not "auto"). 3. profile.Agent == "auto" → first detected CLI agent on $PATH.

func Route

func Route(p PromptContext) string

Route picks the prompt ladder rung. Pure Go, no LLM. Order: ask > recent failed run > zero connections > no project in cwd > default. Free function: PromptContext already has a Route field.

func RunReport

func RunReport(opts ReportCmd) error

RunReport prints the redacted draft, then optionally sends it.

func SaveEntry

func SaveEntry(a AnswersFile, prompt string, m Meta) (string, error)

SaveEntry writes <history>/<id>/{answers.yaml, prompt.md, meta.json}. id is generated from Created + slug if empty.

func SaveProfile

func SaveProfile(p Profile) error

SaveProfile writes env.SLING_ASSIST via EnvFile (preserves other keys/comments).

func Session

func Session(opts SessionOptions) (string, error)

Session probes local state, renders the five-section prompt, then prints or launches.

func SetPaths

func SetPaths(p Paths) (restore func())

SetPaths installs a path override; restore undoes it.

func ShortExecID

func ShortExecID(id string) string

ShortExecID trims an exec id to the prefix shown to users.

func ShortLabel

func ShortLabel(skeleton string) string

ShortLabel is a human-only slug from the skeleton (not part of the hash).

func Skeleton

func Skeleton(errText string) string

Skeleton normalizes a full error chain into a stable multi-line skeleton.

func Uninstall

func Uninstall(ctx context.Context, opts UninstallOptions) error

Uninstall removes sling skills/MCP only (never other tools' entries).

func VersionFilePath

func VersionFilePath() string

VersionFilePath returns ~/.sling/assist/version.

func WriteFailureSnapshot

func WriteFailureSnapshot(s FailureSnapshot)

WriteFailureSnapshot writes ~/.sling/assist/errors/executions/<exec_id>/{meta.json, error.txt, stderr.log}. Best-effort: no-op when execID is empty; never fails the caller run (errors are logged via g.Debug only).

Types

type AgentExitError

type AgentExitError struct {
	ExitCode int
	Agent    string
}

AgentExitError is returned when a launched CLI agent exits non-zero.

func (*AgentExitError) Error

func (e *AgentExitError) Error() string

type AnswersFile

type AnswersFile struct {
	SchemaVersion   int            `yaml:"schema_version" json:"schema_version"`
	Name            string         `yaml:"name" json:"name"`
	Task            string         `yaml:"task" json:"task"`
	TemplateVersion string         `yaml:"template_version,omitempty" json:"template_version"`
	SlingVersion    string         `yaml:"sling_version" json:"sling_version"`
	Created         time.Time      `yaml:"created" json:"created"`
	Agent           string         `yaml:"agent" json:"agent"`
	Parent          string         `yaml:"parent,omitempty" json:"parent"`
	Cwd             string         `yaml:"cwd" json:"cwd"`
	Answers         map[string]any `yaml:"answers" json:"answers"`
}

AnswersFile is the persisted state of an assist run — saved to <history>/<id>/answers.yaml.

type AuthStatus

type AuthStatus string

AuthStatus is an offline probe of whether a CLI agent looks signed in. Values: ok (credential file or env key present), none, unknown.

const (
	AuthOK      AuthStatus = "ok"
	AuthNone    AuthStatus = "none"
	AuthUnknown AuthStatus = "unknown"
)

func (AuthStatus) YesNo

func (s AuthStatus) YesNo() string

YesNo is the install-summary token: yes / no / —.

type CellState

type CellState int

CellState is one cell in the doctor matrix.

const (
	CellOK    CellState = iota // ✓
	CellFail                   // ✗
	CellNA                     // ⊘ unsupported
	CellEmpty                  // — not applicable
)

func (CellState) Glyph

func (s CellState) Glyph() string

Glyph returns the terminal marker for a cell state.

func (CellState) MarshalJSON

func (s CellState) MarshalJSON() ([]byte, error)

MarshalJSON encodes CellState as a stable string.

func (CellState) String

func (s CellState) String() string

String is the JSON/API token for a cell state.

type CheckResult

type CheckResult struct {
	State CellState `json:"state"`
	Skill string    `json:"skill,omitempty"` // set for per-skill checks
	Note  string    `json:"note,omitempty"`  // short detail, no glyph
}

CheckResult is a typed status from Client.CheckSkills / CheckMCP.

func (CheckResult) Render

func (r CheckResult) Render(clientName string) string

Render returns a CLI display line (e.g. "✓ claude: sling").

type Client

type Client interface {
	Name() string
	Kind() ClientKind
	Detect() bool
	WriteSkills(ctx context.Context, skillNames []string, scope Scope) error
	RemoveSkills(ctx context.Context, skillNames []string, scope Scope) error
	WriteMCP(ctx context.Context, scope Scope) error
	RemoveMCP(ctx context.Context, scope Scope) error
	// CheckSkills returns one typed result per skill (no glyph prefixes).
	CheckSkills(ctx context.Context, skillNames []string, scope Scope) []CheckResult
	// CheckMCP returns a typed MCP wiring status.
	CheckMCP(ctx context.Context, scope Scope) CheckResult
	// AuthState reports offline credential-file / env-key presence. Never launches a binary.
	AuthState() AuthStatus
}

Client is the per-tool install adapter contract. Each adapter takes care of its own redirect/translation of the canonical skills bundle and its own MCP config shape. Install/uninstall/doctor iterate over Detected() clients.

Methods that touch the filesystem accept context.Context for cancellation (submission/network work will share this seam). Implementations should honor ctx.Err() at entry when doing I/O.

func AllClients

func AllClients() []Client

AllClients returns the canonical ordered list of supported clients. Order matters for `agent: auto` resolution and for stable output.

func CLIAgents

func CLIAgents() []Client

CLIAgents returns only the launchable CLI-agent clients (excludes vscode).

func DetectedClients

func DetectedClients() []Client

DetectedClients returns the subset of AllClients() whose Detect() returned true.

func LookupClient

func LookupClient(name string) Client

LookupClient finds a client by name; returns nil if no match.

type ClientKind

type ClientKind int

ClientKind distinguishes launchable CLI agents from install-only UI surfaces. Only Kind() == CLIAgent clients are picked by the assist launcher.

const (
	KindCLIAgent ClientKind = iota
	KindUISurface
)

type ClientResult

type ClientResult struct {
	Name        string
	Kind        ClientKind
	WroteSkills bool
	WroteMCP    bool
	Authed      AuthStatus
	Notes       string
}

ClientResult is one row of the install summary.

type DoctorFinding

type DoctorFinding struct {
	ID      string `json:"id"`
	OK      bool   `json:"ok"`
	Summary string `json:"summary"`
	Detail  string `json:"detail,omitempty"`
	Hint    string `json:"hint,omitempty"`
}

DoctorFinding is one structured global check (profile, skill, env, version).

type DoctorMatrix

type DoctorMatrix struct {
	Clients []string    `json:"clients"`
	Rows    []MatrixRow `json:"rows"`
}

DoctorMatrix is the cross-check table for detected clients.

type DoctorOptions

type DoctorOptions struct {
	Scope Scope // must match install scope under test
}

DoctorOptions configures Doctor. Zero value uses ScopeUser.

type DoctorReport

type DoctorReport struct {
	OK           bool            `json:"ok"`
	SlingVersion string          `json:"sling_version"`
	Findings     []DoctorFinding `json:"findings"`
	Matrix       *DoctorMatrix   `json:"matrix,omitempty"`
	Lines        []string        `json:"-"` // CLI glyph prose
}

DoctorReport is the `sling assist setup --doctor` result.

func Doctor

func Doctor(ctx context.Context, opts ...DoctorOptions) (*DoctorReport, error)

Doctor probes the install end-to-end. opts[0].Scope defaults to ScopeUser.

func (*DoctorReport) Add

func (r *DoctorReport) Add(pass bool, line string)

Add maps glyph prose into a finding.

func (*DoctorReport) AddFinding

func (r *DoctorReport) AddFinding(f DoctorFinding)

AddFinding records a structured finding and a CLI display line.

func (*DoctorReport) MissingComponents

func (r *DoctorReport) MissingComponents() []string

MissingComponents lists install pieces that look incomplete on disk.

func (*DoctorReport) Render

func (r *DoctorReport) Render() string

Render is the CLI doctor report (glyph lines + matrix).

func (*DoctorReport) ToJSON

func (r *DoctorReport) ToJSON() ([]byte, error)

ToJSON returns a pretty-printed doctor.json payload.

type Entry

type Entry struct {
	ID      string
	Path    string
	Answers AnswersFile
	Meta    Meta
}

Entry is a loaded view of one history dir, used by the listing/picker.

func ListEntries

func ListEntries() ([]Entry, error)

ListEntries returns all entries in ~/.sling/assist/history/, most-recent first.

func LoadEntry

func LoadEntry(id string) (Entry, error)

LoadEntry reads <history>/<id>/.

func PickHistoryEntry

func PickHistoryEntry() (Entry, error)

PickHistoryEntry opens a searchable table of recent sessions. Returns ErrUserAborted when the user cancels.

type ErrorLookupResult

type ErrorLookupResult struct {
	Signature   string `json:"signature"`              // compact 8 or 16 hex
	PatternID   string `json:"pattern_id,omitempty"`   // first 8 of composite
	EdgeID      string `json:"edge_id,omitempty"`      // last 8 when full composite
	PatternOnly bool   `json:"pattern_only,omitempty"` // true when caller passed 8 hex
	Status      string `json:"status"`                 // known_config | known_bug | pending | unknown
	Title       string `json:"title,omitempty"`
	Guidance    string `json:"guidance,omitempty"`
	DocsURL     string `json:"docs_url,omitempty"`
	FixedIn     string `json:"fixed_in,omitempty"`
	IssueURL    string `json:"issue_url,omitempty"`
}

ErrorLookupResult is the response shape for `sling assist error <sig>`. Worker-backed known-issue lookup lands later; v1 returns local status only.

func LookupError

func LookupError(signature string) (ErrorLookupResult, error)

LookupError validates a signature id and returns guidance when known. Accepts composite (16 hex), pattern-only (8 hex), dashed form, or Display() line. Network lookup is not wired yet; well-formed ids return status "unknown".

type FailureFooterOpts

type FailureFooterOpts struct {
	ExecID   string
	ErrMsg   string
	SignMeta SignMeta
}

FailureFooterOpts controls the post-failure hint line. A command only — never an interactive prompt (TTY or not).

type FailureSnapshot

type FailureSnapshot struct {
	ExecID     string
	ErrMsg     string
	ConfigPath string // replication / pipeline config path when known
	ConnName   string // connection name for `sling conns test|discover`
	Rows       string
	Duration   string
	// RunLog is the captured log tail (env.RecentLogs). Written to stderr.log.
	RunLog string
	// ConfigBody is the replication/pipeline config file content. Written to
	// config.snapshot.yaml when set. Not used for conns test/discover.
	ConfigBody string
	// SignMeta optional connector types for error_signature.
	SignMeta SignMeta
	// Extra is merged into meta.json as-is (connector types, etc.).
	Extra map[string]any
}

FailureSnapshot is the minimal set of fields written when a command fails (run, conns test, conns discover) so `sling assist` can probe the error.

type HarnessConfirmResult

type HarnessConfirmResult struct {
	Agent        string
	HintInErrors bool
	Scope        string
	Components   []string
}

HarnessConfirmResult is the first-run / setup confirm form.

func RunHarnessConfirmForm

func RunHarnessConfirmForm(prefill Profile) (*HarnessConfirmResult, error)

RunHarnessConfirmForm lists detected agents with install+auth state.

type InstallFormResult

type InstallFormResult struct {
	Agent        string
	HintInErrors bool
	Scope        string
}

InstallFormResult is what the first-run install form returns.

func RunInstallForm

func RunInstallForm(prefill Profile) (*InstallFormResult, error)

RunInstallForm shows the first-run interactive form and returns the user's choices.

type InstallOptions

type InstallOptions struct {
	Reconfigure    bool
	SkillsOnly     bool
	MCPOnly        bool
	Scope          Scope
	NonInteractive bool
	DefaultAgent   string // used only on non-interactive first-run
}

InstallOptions controls `sling assist setup` (install path).

type InstallResult

type InstallResult struct {
	ProfileWritten     bool
	CanonicalSkillsDir string
	WiredClients       []ClientResult
	SkippedClients     []string // not detected
}

InstallResult summarizes what install touched.

func Install

func Install(ctx context.Context, opts InstallOptions) (*InstallResult, error)

Install is idempotent install/refresh. Honors ctx between clients.

type LandingKind

type LandingKind string

LandingKind is the bare-`sling` TTY card.

const (
	LandingFresh     LandingKind = "fresh"
	LandingNoProject LandingKind = "no_project"
	LandingProject   LandingKind = "project"
)

func ClassifyLanding

func ClassifyLanding(p PromptContext, fresh bool) LandingKind

ClassifyLanding picks the card. Fresh wins so a default home never falls through to the probe states.

type LaunchOptions

type LaunchOptions struct {
	Agent      string
	Prompt     string
	PromptPath string
	Model      string
	SessionID  string // pre-assigned harness id (claude, grok)
}

LaunchOptions is one agent exec (first run or resume).

type LocalExec

type LocalExec struct {
	ID         string
	When       time.Time
	Status     string // "ok" | "err" | "?"
	ConfigPath string // replication / pipeline config path
	ConnName   string // connection name for conns test/discover
	Rows       string
	Duration   string
	LogDir     string // absolute path to the exec's snapshot dir
}

LocalExec is one failed-run snapshot under ~/.sling/assist/errors/. New snapshots live in errors/executions/<id>/; legacy dirs stay readable.

func ListLocalExecs

func ListLocalExecs() ([]LocalExec, error)

ListLocalExecs scans errors/executions/<id>/ then legacy errors/<id>/ and returns the 20 most-recent execs by mtime. Unreadable dirs are skipped.

func LookupLocalExec

func LookupLocalExec(id string) (LocalExec, bool)

LookupLocalExec resolves an exec id to its snapshot. Accepts the full id or a unique prefix. Returns false when unknown or when a prefix is ambiguous.

func ResolveLocalExec

func ResolveLocalExec(id string) (LocalExec, error)

ResolveLocalExec is LookupLocalExec with a reason: unknown vs ambiguous.

type MatrixRow

type MatrixRow struct {
	Label string               `json:"label"`
	Cells map[string]CellState `json:"cells"` // client name → state
	Notes map[string]string    `json:"notes,omitempty"`
}

MatrixRow is one row in the agent × capability matrix.

type Meta

type Meta struct {
	ID               string         `json:"id"`
	Task             string         `json:"task"`
	Agent            string         `json:"agent"`
	Model            string         `json:"model,omitempty"`
	HarnessSessionID string         `json:"harness_session_id,omitempty"`
	LaunchedAt       *time.Time     `json:"launched_at"`
	Doctor           map[string]any `json:"doctor,omitempty"`
	Parent           string         `json:"parent,omitempty"`
}

Meta is the runtime side-record of an entry — saved to <history>/<id>/meta.json.

type Paths

type Paths struct {
	SlingHome string
	UserHome  string
	CWD       string
}

Paths is the injectable path seam (tests use SetPaths).

func CurrentPaths

func CurrentPaths() Paths

CurrentPaths returns the active path set (override or live).

type ProbeConn

type ProbeConn struct {
	Name   string
	Type   string
	Source string
}

ProbeConn is name/type/source from ConnEntries.List() (no payload fields).

type ProbeOptions

type ProbeOptions struct {
	Ask            string
	IncludeFailure bool
	ExecID         string // target this exec instead of the latest failure
}

ProbeOptions is the user-facing input to Probe. IncludeFailure pulls signature/lookup/excerpt into Context. Set it only when the ask targets the failure (investigate pick, empty-ask fallback, landing card); other asks keep the one-line recent-runs summary.

type Profile

type Profile struct {
	Agent               string `yaml:"agent" json:"agent"`                                           // claude | codex | … | auto
	HintInErrors        bool   `yaml:"hint_in_errors" json:"hint_in_errors"`                         // run-error footer
	DefaultInstallScope string `yaml:"default_install_scope,omitempty" json:"default_install_scope"` // user | project
}

Profile is stored under env.SLING_ASSIST in ~/.sling/env.yaml.

func DefaultProfile

func DefaultProfile() Profile

DefaultProfile returns sane first-run defaults.

func LoadProfile

func LoadProfile() (p Profile, exists bool, err error)

LoadProfile reads env.SLING_ASSIST. Missing key → (Profile{}, false, nil).

type PromptContext

type PromptContext struct {
	Version         string
	Cwd             string
	ProjectName     string
	ProjectRoot     string
	HasProject      bool
	FileCounts      map[string]int
	Connections     []ProbeConn
	ConnectionExtra int
	RecentRuns      []LocalExec
	TargetExec      *LocalExec // set by --id: investigate this failure
	MCPWired        bool
	Signature       string
	Lookup          *ErrorLookupResult
	ErrorExcerpt    string
	RunLogExcerpt   string
	Ask             string
	Suggestions     []string
	Route           string
	Agent           string
}

PromptContext is the assembled state for the five-section agent prompt.

func Probe

func Probe(opts ProbeOptions) PromptContext

Probe gathers local state for the agent prompt. It lists connections via ConnEntries.List() only (name/type/source).

func (PromptContext) Render

func (p PromptContext) Render() (string, error)

Render fills the five-section skeleton. Caps at ~maxPromptTokens.

func (PromptContext) SuggestedCommand

func (p PromptContext) SuggestedCommand() string

SuggestedCommand is the wave-7 ladder mapped to one runnable command.

type ProviderChoice

type ProviderChoice struct {
	Kind       string         // zen-free | anthropic | openai | google | xai
	Model      string         // provider/model
	Provider   map[string]any // opencode.json `provider` map; nil if unused
	Disclosure string         // set for zen-free
}

ProviderChoice is one harness LLM setup (Zen free vs keyed provider).

func HarnessProviderChoice

func HarnessProviderChoice() ProviderChoice

HarnessProviderChoice picks a keyed provider env if set, else free Zen.

type RankedAgent

type RankedAgent struct {
	Name    string
	Auth    AuthStatus
	Detect  bool
	Bundled bool // true when this is the downloadable opencode fallback
	Score   int  // lower is better
}

RankedAgent is a detected CLI agent with install + auth state for the confirm form.

func RankedCLIAgents

func RankedCLIAgents() []RankedAgent

RankedCLIAgents lists CLI agents on $PATH: authenticated first, then unknown, then none. Bundled OpenCode is appended only when no CLI agent is on $PATH (and a release asset exists).

type ReportCmd

type ReportCmd struct {
	ExecID      string
	Title       string // optional override
	Description string // optional custom context, shown above the error
	GitHub      bool
	Email       bool
	Submit      bool // skip the confirm prompt (for agents)
}

ReportCmd is the `sling assist report` entry.

type ReportDraft

type ReportDraft struct {
	Title       string `json:"title"`
	Description string `json:"description"`
	Config      string `json:"config"`
	LogExcerpt  string `json:"log_excerpt"`
	Version     string `json:"version"`
	OS          string `json:"os"`
	SourceType  string `json:"source_type"`
	TargetType  string `json:"target_type"`
	SignatureID string `json:"signature_id"`
	Skeleton    string `json:"skeleton"`
	ExecID      string `json:"exec_id"`
	ConnName    string `json:"conn_name,omitempty"`
	// CustomDescription is caller-supplied context, shown above the error.
	CustomDescription string `json:"custom_description,omitempty"`
}

ReportDraft is the composed, redacted report. Both routes consume it.

func ComposeReport

func ComposeReport(execID string) (ReportDraft, error)

ComposeReport builds a redacted report from a local failure snapshot.

func (ReportDraft) BodyMarkdown

func (d ReportDraft) BodyMarkdown() string

BodyMarkdown renders sections that match the GitHub issue template fields.

func (ReportDraft) ContactFormFits added in v1.6.1

func (d ReportDraft) ContactFormFits() bool

ContactFormFits reports whether ContactFormURL stays under the Cloudflare request-line budget. When false, callers should return BodyMarkdown for manual paste instead of the prefilled URL.

func (ReportDraft) ContactFormURL

func (d ReportDraft) ContactFormURL() string

ContactFormURL builds the contact-page URL with the full report body base64 encoded in the issue param. The form collects name/email and Turnstile. Never trims logs or config; oversized bodies go to a file instead (see deliverContactForm).

func (ReportDraft) GitHubIssueURL

func (d ReportDraft) GitHubIssueURL() string

GitHubIssueURL builds a prefilled new-issue URL. Issue forms (.yml) ignore query params except title, so the full report goes into body against the blank issue form.

type ReportParts added in v1.6.1

type ReportParts struct {
	ExecID            string
	ErrorText         string
	LogText           string
	ConfigBody        string
	Version           string
	OS                string
	SourceType        string
	TargetType        string
	ConnName          string
	CustomDescription string
}

ReportParts is raw evidence collected outside a local snapshot. ComposeReport redacts it the same way the exec-id ComposeReport redacts on-disk files.

func (ReportParts) ComposeReport added in v1.6.1

func (p ReportParts) ComposeReport() ReportDraft

ComposeReport builds a redacted ReportDraft from already-collected fields.

type Scope

type Scope int

Scope is `--scope user` (default) or `--scope project`.

const (
	ScopeUser Scope = iota
	ScopeProject
)

type SensitiveClass

type SensitiveClass struct {
	// ID is a stable key for manifests (e.g. "env.yaml", "claude.json").
	ID string `json:"id"`
	// Glob is matched against absolute or home-relative paths (slash-normalized).
	// Supports * and ** suffix style via pathMatch.
	Glob string `json:"glob"`
	// Class is the sensitivity tier.
	Class Sensitivity `json:"class"`
	// Reason is a short human explanation (never contains secret values).
	Reason string `json:"reason"`
}

SensitiveClass describes one path/category the assist package may touch.

func SensitivityManifest

func SensitivityManifest() []SensitiveClass

SensitivityManifest returns the static inventory of sensitive surface area. Used by submit/bundle builders to decide include / redact / exclude.

type Sensitivity

type Sensitivity int

Sensitivity classifies what may leave the machine in a log/submit bundle.

const (
	// SensitivityPublic is safe to ship as-is (no credentials by design).
	SensitivityPublic Sensitivity = iota
	// SensitivityInternal may contain operational detail; redact values before ship.
	SensitivityInternal
	// SensitivitySecret must never leave the machine (credentials, tokens, backups of same).
	SensitivitySecret
)

func ClassifyPath

func ClassifyPath(path string) Sensitivity

ClassifyPath returns the highest-sensitivity class matching path. Unknown paths default to SensitivityInternal (safe default: redact before ship). When multiple globs match, Secret > Internal > Public.

func (Sensitivity) String

func (s Sensitivity) String() string

type SessionOptions

type SessionOptions struct {
	Ask            string
	Name           string
	Agent          string
	Model          string
	Print          bool
	OutputFile     string
	Headless       bool
	ExecID         string // --id: investigate this failure
	ResumeID       string
	ResumeSet      bool // --resume present (empty id → picker already resolved)
	NonInteractive map[string]string
}

SessionOptions is the flags-only `sling assist` invocation.

type SetupAction

type SetupAction string

SetupAction is what RunSetupActionForm returns. Drives the post-doctor branching in `sling assist setup` for users who already have a profile.

const (
	SetupActionRefresh        SetupAction = "refresh"         // re-install everything (idempotent)
	SetupActionInstallMissing SetupAction = "install_missing" // install only the failing components
	SetupActionReconfigure    SetupAction = "reconfigure"     // re-prompt the profile form, then install
	SetupActionUninstall      SetupAction = "uninstall"       // wipe everything
	SetupActionExit           SetupAction = "exit"            // do nothing
)

func RunSetupActionForm

func RunSetupActionForm(report *DoctorReport) (SetupAction, error)

RunSetupActionForm runs after doctor has printed its report.

type SignMeta

type SignMeta struct {
	SourceType dbio.Type // e.g. dbio.TypeDbPrometheus
	TargetType dbio.Type // e.g. dbio.TypeDbPostgres
}

SignMeta holds connector types only (never hostnames, DB names, or task type). Task type (db-db, file-db, …) is not stored: it is fully determined by the Kind of SourceType and TargetType (see InferredTaskType).

func MakeSignMeta

func MakeSignMeta() (sm SignMeta)

func (SignMeta) InferredTaskType

func (m SignMeta) InferredTaskType() string

InferredTaskType returns the job-type slug (db-db, file-db, api-file, …) derived from connector kinds. Empty when either side is unknown. Not part of the hash material — source+target types already encode this.

type Signature

type Signature struct {
	ID              string // 16 hex chars (pattern||edge)
	PatternID       string // 8 hex — skeleton only
	EdgeID          string // 8 hex — types + skeleton
	Skeleton        string // normalized message body
	PatternMaterial string // v1p|<skeleton>
	EdgeMaterial    string // v1e|<source>|<target>|<skeleton>
	ShortLabel      string // human-only slug (not hashed)
	Algorithm       string // e.g. v1
	Meta            SignMeta
}

Signature is the full result of SignError (composite: pattern + edge).

PatternID  = hex(sha256("v1p|" + skeleton))[0:8]
EdgeID     = hex(sha256("v1e|" + src + "|" + tgt + "|" + skeleton))[0:8]
ID         = PatternID + EdgeID   // 16 hex, machine form
IDDashed   = PatternID + "-" + EdgeID

Same skeleton ⇒ same PatternID across all source/target pairs. Same skeleton + same types ⇒ same EdgeID and ID.

func SignError

func SignError(errText string, meta SignMeta) Signature

SignError normalizes errText + meta into a stable composite signature. Pure function: no I/O, deterministic across machines.

func (Signature) Display

func (s Signature) Display() string

Display formats the signature for the failure footer. Example: a1b2c3d4-e4f9c2a1 (prometheus→postgres · no_stream_columns)

func (Signature) IDDashed

func (s Signature) IDDashed() string

IDDashed returns pattern-edge with a hyphen for humans / copy-paste.

type UninstallOptions

type UninstallOptions struct {
	All            bool
	SkillsOnly     bool
	MCPOnly        bool
	Scope          Scope
	NonInteractive bool
	IncludeClients []string // empty = all detected
}

UninstallOptions controls `sling assist setup --uninstall`.

Jump to

Keyboard shortcuts

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