summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-03-27 11:33:33 +0200
committerPaul Buetow <paul@buetow.org>2026-03-27 11:33:33 +0200
commitf57ccb885d20c48e1dae65b8ad5c46375b9a11a9 (patch)
treea023c5f5af65cfe8f20354c388c683c57437e5d2
parent56e9f980e52a53197ace71acdb277ba0e0368916 (diff)
docs: document askcli exports
-rw-r--r--internal/askcli/completion.go2
-rw-r--r--internal/askcli/dispatch.go6
-rw-r--r--internal/askcli/formatter.go5
-rw-r--r--internal/askcli/task_selector.go2
-rw-r--r--internal/askcli/taskexec.go3
-rw-r--r--internal/askcli/taskexport.go2
6 files changed, 20 insertions, 0 deletions
diff --git a/internal/askcli/completion.go b/internal/askcli/completion.go
index 0f6c47b..b4d8620 100644
--- a/internal/askcli/completion.go
+++ b/internal/askcli/completion.go
@@ -85,10 +85,12 @@ func fishAddDependencyModifierCompletionContext(positional []string, current str
return current == "depends" || strings.HasPrefix(current, "depends:")
}
+// FishCompletion returns the default Fish completion script for the ask CLI.
func FishCompletion() string {
return FishCompletionFor("ask")
}
+// FishCompletionFor returns a Fish completion script that points to the provided binary path.
func FishCompletionFor(binaryPath string) string {
var b strings.Builder
writeFishPreamble(&b)
diff --git a/internal/askcli/dispatch.go b/internal/askcli/dispatch.go
index 4612555..142f7b4 100644
--- a/internal/askcli/dispatch.go
+++ b/internal/askcli/dispatch.go
@@ -6,15 +6,20 @@ import (
"io"
)
+// Runner performs CLI work that would otherwise be handled by ask itself.
+//
+// The interface is implemented by the executor that ultimately proxies commands to Taskwarrior.
type Runner interface {
Run(ctx context.Context, args []string, stdin io.Reader, stdout, stderr io.Writer) (int, error)
}
+// Dispatcher translates CLI arguments into concrete subcommands and presents the output.
type Dispatcher struct {
runner Runner
jsonOutput bool
}
+// NewDispatcher creates a Dispatcher backed by the provided Runner or a default executor when nil.
func NewDispatcher(runner Runner) *Dispatcher {
if runner == nil {
e := NewExecutor("ask")
@@ -36,6 +41,7 @@ func parseGlobalFlags(args []string) ([]string, bool) {
return filtered, jsonOutput
}
+// Dispatch parses CLI arguments, handles global flags, and routes the request to the matching subcommand.
func (d *Dispatcher) Dispatch(ctx context.Context, args []string, stdin io.Reader, stdout, stderr io.Writer) (int, error) {
args, jsonOutput := parseGlobalFlags(args)
d.jsonOutput = jsonOutput
diff --git a/internal/askcli/formatter.go b/internal/askcli/formatter.go
index 743637b..2327a94 100644
--- a/internal/askcli/formatter.go
+++ b/internal/askcli/formatter.go
@@ -9,10 +9,12 @@ import (
"codeberg.org/snonux/hexai/internal/termprint"
)
+// FormatTaskList renders a table of tasks using the terminal's width when possible.
func FormatTaskList(tasks []TaskExport, aliases map[string]string) string {
return FormatTaskListForWidth(tasks, aliases, 0)
}
+// FormatTaskListForWidth renders a table of tasks constrained to the provided terminal width.
func FormatTaskListForWidth(tasks []TaskExport, aliases map[string]string, terminalWidth int) string {
widths := taskListWidthsFor(tasks, aliases, terminalWidth)
var b strings.Builder
@@ -133,6 +135,7 @@ func detectTaskListTerminalWidth(w io.Writer) int {
return termprint.DetectTerminalWidth(w)
}
+// FormatTaskInfo builds a human-readable block describing a single task.
func FormatTaskInfo(t TaskExport, alias string, dependencyAliases map[string]string) string {
var b strings.Builder
fmt.Fprintf(&b, "ID: %s\n", alias)
@@ -160,10 +163,12 @@ func FormatTaskInfo(t TaskExport, alias string, dependencyAliases map[string]str
return b.String()
}
+// FormatSuccess returns the success string written to stdout after a task command runs.
func FormatSuccess(alias string) string {
return fmt.Sprintf("ok %s\n", alias)
}
+// FormatError formats error output using the optional task identifier when available.
func FormatError(err error, taskID string) string {
if taskID != "" {
return fmt.Sprintf("error %s: %v\n", taskID, err)
diff --git a/internal/askcli/task_selector.go b/internal/askcli/task_selector.go
index 220aa7c..82dc06f 100644
--- a/internal/askcli/task_selector.go
+++ b/internal/askcli/task_selector.go
@@ -137,6 +137,7 @@ func NormalizeUUID(s string) string {
return strings.TrimPrefix(s, "uuid:")
}
+// IsNumericID reports whether the string is entirely numeric.
func IsNumericID(s string) bool {
if s == "" {
return false
@@ -149,6 +150,7 @@ func IsNumericID(s string) bool {
return true
}
+// RejectNumericID returns the error message emitted when numeric Taskwarrior IDs are passed.
func RejectNumericID() string {
return "error: use a task alias ID or UUID, not a numeric Taskwarrior task ID\n"
}
diff --git a/internal/askcli/taskexec.go b/internal/askcli/taskexec.go
index 59d9b55..b188230 100644
--- a/internal/askcli/taskexec.go
+++ b/internal/askcli/taskexec.go
@@ -16,6 +16,7 @@ type repoTopLevelDetector func(context.Context) (string, error)
type commandRunner func(context.Context, string, []string, io.Reader, io.Writer, io.Writer) error
+// Executor encapsulates how ask communicates with the Taskwarrior binary.
type Executor struct {
commandName string
findBinary binaryFinder
@@ -23,6 +24,7 @@ type Executor struct {
runCommand commandRunner
}
+// NewExecutor constructs an Executor that invokes Taskwarrior via the given command name.
func NewExecutor(commandName string) Executor {
return Executor{
commandName: strings.TrimSpace(commandName),
@@ -43,6 +45,7 @@ func (e Executor) taskArgs(repoRoot string, args []string) ([]string, error) {
return append([]string{"rc.verbose=nothing", "rc.confirmation=off", "project:" + projectName, "+agent"}, args...), nil
}
+// Run delegates CLI arguments to Taskwarrior, enforcing agent defaults and error handling.
func (e Executor) Run(ctx context.Context, args []string, stdin io.Reader, stdout, stderr io.Writer) (int, error) {
executor := normalizeExecutor(e)
taskPath, err := executor.findBinary()
diff --git a/internal/askcli/taskexport.go b/internal/askcli/taskexport.go
index ca67ef5..d633d3c 100644
--- a/internal/askcli/taskexport.go
+++ b/internal/askcli/taskexport.go
@@ -6,6 +6,7 @@ import (
"io"
)
+// TaskExport mirrors the JSON structure returned by Taskwarrior export commands.
type TaskExport struct {
UUID string `json:"uuid"`
Description string `json:"description"`
@@ -21,6 +22,7 @@ type TaskExport struct {
} `json:"annotations"`
}
+// ParseTaskExport decodes Taskwarrior JSON from the supplied reader.
func ParseTaskExport(r io.Reader) ([]TaskExport, error) {
data, err := io.ReadAll(r)
if err != nil {