Documentation
¶
Overview ¶
Package install owns the SOUL.md install conventions: harness detection, the per-framework target table, the overwrite gate, and the install receipt written by install.sh. Paths are injected so everything is testable without touching the real home directory.
Index ¶
- Constants
- Variables
- func DescribeOpenClawWorkspaces(workspaces []OpenClawWorkspace) string
- func DetectHarness(cwd, home string) string
- func OpenClawSoulPath(workspaces []OpenClawWorkspace, pick, home string) (string, error)
- func SkillDir(target string, project bool, cwd, home string) (string, error)
- func SkillName(body string) (string, error)
- func TargetPath(target, cwd, home string) (string, error)
- func WriteReceipt(binPath string, r Receipt) error
- type OpenClawWorkspace
- type Options
- type Receipt
- type Result
- type SkillOptions
- type SkillResult
Constants ¶
const ReceiptName = "positronick-install-receipt.json"
ReceiptName is the filename install.sh writes next to the binary — a cross-repo contract with install.sh and positronick.com/install.sh.
Variables ¶
var SkillTargets = []string{"agents", "claude", "cursor", "grok", "codex", "openclaw"}
SkillTargets are the supported `skill install` destinations, in the order they are documented. agents is the shared standard (Codex, Cursor, Grok Build and OpenClaw all read it); codex has no user-level directory of its own and shares agents'.
var Targets = []string{"hermes", "claude", "cursor", "openclaw", "grok"}
Targets are the supported install targets, in detection-priority order.
Functions ¶
func DescribeOpenClawWorkspaces ¶ added in v0.2.0
func DescribeOpenClawWorkspaces(workspaces []OpenClawWorkspace) string
DescribeOpenClawWorkspaces renders "<id> (<path>), <id> (<path>)..." — shared by every "several OpenClaw agents configured" error message (ResolveOpenClawWorkspaces callers included) so the format lives in one place.
func DetectHarness ¶
DetectHarness returns the install target for the first harness marker directory found — all markers are checked in cwd first (a project-local harness wins), then in home — or "" when none exists. Only directories count; an empty cwd/home is skipped.
func OpenClawSoulPath ¶ added in v0.2.0
func OpenClawSoulPath(workspaces []OpenClawWorkspace, pick, home string) (string, error)
OpenClawSoulPath resolves the SOUL.md destination among the configured OpenClaw workspaces: pick == "" requires exactly one workspace; otherwise pick is matched against a workspace ID, then treated as a directory when it looks like one (a path separator or a leading ~/.). home expands a leading "~" in pick — this package is injected-home throughout, so it never reads the real user home itself.
func SkillDir ¶ added in v0.2.0
SkillDir returns the conventional skills directory for a target: a user-level (home-anchored) directory by default, or a project-level (cwd-anchored) directory when project is true. codex has no directory of its own at either level — it shares agents' (openclaw shares it too at project level; its user-level directory stays its own).
func SkillName ¶ added in v0.2.0
SkillName parses the SKILL.md frontmatter `name:` field. body must start with a "---" frontmatter block; a missing block or a missing/empty name field is an error. No YAML library — this is a narrow, pure scan.
func TargetPath ¶
TargetPath returns the conventional SOUL.md location for a target. hermes, claude, openclaw and grok are home-anchored; cursor is project-local (its rules live inside the repository). openclaw's result is the no-config default (~/.openclaw/workspace/SOUL.md) — the actual OpenClaw destination for `soul install` is resolved per-machine by ResolveOpenClawWorkspaces + OpenClawSoulPath, since OpenClaw reads SOUL.md from its configured agent workspace, not ~/.openclaw.
func WriteReceipt ¶
WriteReceipt writes the receipt next to the binary at binPath, in the same shape install.sh produces.
Types ¶
type OpenClawWorkspace ¶ added in v0.2.0
OpenClawWorkspace is one configured OpenClaw agent: its id and the workspace directory it reads SOUL.md from.
func ResolveOpenClawWorkspaces ¶ added in v0.2.0
func ResolveOpenClawWorkspaces(home string, getenv func(string) string, readFile func(string) ([]byte, error)) ([]OpenClawWorkspace, error)
ResolveOpenClawWorkspaces returns every configured OpenClaw agent and the workspace directory it reads SOUL.md from, sorted with the default agent first, then by id. home, getenv and readFile are injected so this is testable without touching the real filesystem/environment.
type Options ¶
type Options struct {
// Target is one of Targets. It picks the destination (when Path is
// empty) and the formatting (cursor wraps the body in mdc frontmatter).
// An empty Target with a Path writes the body verbatim to Path.
Target string
// Path, when set, overrides the target's conventional destination.
Path string
// SoulName fills the cursor frontmatter description.
SoulName string
// Cwd and Home anchor the conventional paths (injected for tests).
Cwd, Home string
// Force overwrites an existing file without asking.
Force bool
// Link, with Target "claude" or "grok", appends the link line to
// ~/.claude/CLAUDE.md or $GROK_HOME/AGENTS.md when not already present.
Link bool
// Interactive enables the Confirm prompt for overwrites.
Interactive bool
// Confirm asks the user to approve overwriting the named file. Required
// when Interactive and the destination exists.
Confirm func(prompt string) (bool, error)
// OverwriteHint names the flag suggested when refusing to overwrite
// non-interactively; defaults to "--force".
OverwriteHint string
// Fetch returns the verbatim SOUL.md body. It is called only after the
// overwrite gate passes: the server's .md endpoint bumps the public
// download counter, and a refused install is not a download.
Fetch func() (string, error)
}
Options configures one SOUL.md install.
type Receipt ¶
Receipt records how the binary was installed. install.sh writes {"method":"installer","version":"..."}; `self update` rewrites it after a successful in-place update.
func ReadReceipt ¶
ReadReceipt reads the receipt next to the resolved binary at binPath. A missing, unreadable or malformed receipt yields method "unknown" — the binary is then treated like a package-manager install, which `self update` must never replace in place.
type SkillOptions ¶ added in v0.2.0
type SkillOptions struct {
// Dir is the destination's parent directory: either a target's
// conventional skills directory (SkillDir) or an explicit --path
// override. The install folder itself is always Slug.
Dir string
// Slug is the listing's slug: it names the install folder
// (<Dir>/<Slug>/SKILL.md) and must equal the fetched body's
// frontmatter name.
Slug string
// Force overwrites an existing file without asking.
Force bool
// Interactive enables the Confirm prompt for overwrites.
Interactive bool
// Confirm asks the user to approve overwriting the named file. Required
// when Interactive and the destination exists.
Confirm func(prompt string) (bool, error)
// OverwriteHint names the flag suggested when refusing to overwrite
// non-interactively; defaults to "--force".
OverwriteHint string
// Fetch returns the verbatim SKILL.md body. It is called only after the
// overwrite gate passes: the server's .md endpoint bumps the public
// download counter, and a refused install is not a download.
Fetch func() (string, error)
}
SkillOptions configures one hosted-SKILL.md install.
type SkillResult ¶ added in v0.2.0
SkillResult reports where a skill install landed, the name its frontmatter carried, and how many bytes were written.
func Skill ¶ added in v0.2.0
func Skill(opts SkillOptions) (*SkillResult, error)
Skill resolves <Dir>/<Slug>/SKILL.md, gates overwrites (reusing the same gate Install uses), fetches the body, verifies its frontmatter name equals Slug, and writes it verbatim. The name check runs after the gate but the file is written only once both pass, so a mismatch — like a refused overwrite — leaves nothing on disk.