usercmd

package
v0.4.0 Latest Latest
Warning

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

Go to latest
Published: Aug 13, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Overview

Package usercmd loads user-authored slash commands from markdown files dropped in ~/.yottacode/commands/ (user scope) and <cwd>/.yottacode/commands/ (project scope).

Layout mirrors Claude Code's custom-commands feature: filename becomes the command name, subdirectories become a colon-separated namespace (commands/frontend/component.md → /frontend:component), the body is sent to the agent as the user message for that turn (with $ARGUMENTS / $1..$9 substituted and @<path> file refs honored by the same pipeline that handles user-typed @-refs).

Index

Constants

This section is empty.

Variables

View Source
var Reserved = map[string]bool{
	"help":           true,
	"quit":           true,
	"clear":          true,
	"permissions":    true,
	"system":         true,
	"sessions":       true,
	"model":          true,
	"provider":       true,
	"doctor":         true,
	"redo":           true,
	"recall":         true,
	"summarize":      true,
	"checkpoints":    true,
	"memory":         true,
	"max-iterations": true,
	"setup":          true,
	"init":           true,
	"plan":           true,
	"loop":           true,
	"subagents":      true,
	"skills":         true,
	"git-commit":     true,
	"git-create-pr":  true,
	"git-review-pr":  true,
	"git-push":       true,
	"git-update-pr":  true,
}

Reserved is the set of built-in slash command names a custom file is forbidden from shadowing. Kept here (not derived from the TUI package's allSlash) so this package stays standalone-testable; the TUI's init() is the source of truth and a one-line drift test in the TUI package guards against new built-ins being forgotten.

Functions

func Load

func Load(cwd string) (cmds []Command, errs []LoadError)

Load walks both scope directories (user first, then project) and returns the merged command list plus per-file load errors.

Conflict resolution:

  • Same name within the SAME scope: both copies dropped, error emitted. We can't pick a winner safely (the user clearly intended different prompts) and silently keeping one would surprise them.
  • Same name across scopes: project wins. The user-scope copy is dropped with an info-level notice so the user understands why /foo doesn't behave like their global file.
  • Same name as a built-in: custom dropped with a warning. Built-ins can't be shadowed because the dispatcher walks built-ins first.

Errors are returned alongside the commands rather than as a single error — one broken file should not block a directory of working commands. The TUI iterates errs at startup and emits one styled notice per entry.

func ProjectCommandsDir

func ProjectCommandsDir(cwd string) string

ProjectCommandsDir returns <cwd>/.yottacode/commands/ — the per-repo custom-command directory. Commands here are committable so teams can share project-specific commands via git. Empty cwd returns "" so callers can detect "no project scope" without an error path.

func Substitute

func Substitute(body, args string) string

Substitute resolves $ARGUMENTS and $1..$9 in body using args. args is the post-name remainder a user typed after the command — for "/foo a b c", args is "a b c".

Tokenization is strings.Fields (whitespace-split, collapsing runs) to match what runSlash already does on the command line. Missing positionals (e.g. $3 when only two args were supplied) resolve to the empty string; the command author is responsible for handling the empty case in their prose if it matters.

func UserCommandsDir

func UserCommandsDir() (string, error)

UserCommandsDir returns ~/.yottacode/commands/ — the cross-project custom-command directory. Commands here apply to every yottacode session for this user.

Types

type Command

type Command struct {
	Name        string
	Description string
	ArgHint     string
	Body        string
	SourceFile  string
	Scope       Scope
}

Command is one loaded custom command. Body is the post-frontmatter markdown, unsubstituted (the TUI calls Substitute() with the user's args at invocation time).

type Level

type Level int

Level grades a LoadError as either a hard error (the file did not produce a usable command) or a warning (the file is fine but shadowed / dropped due to a collision). The TUI renders the two levels with different styles.

const (
	LevelError Level = iota
	LevelWarning
)

type LoadError

type LoadError struct {
	Path  string
	Err   error
	Level Level
}

LoadError describes one problem encountered during Load. The file path is always populated so the user can locate the offending file.

func (LoadError) Error

func (e LoadError) Error() string

type Scope

type Scope string

Scope tags where a command came from. Surfaces in /help so users can see whether a command they're looking at lives on disk (user or project) or is shipped with the binary (default).

const (
	ScopeUser    Scope = "user"
	ScopeProject Scope = "project"
)

Jump to

Keyboard shortcuts

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