From dc17b7469c2055961892bbb3175d4ab0fb1d1180 Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Sat, 6 Jun 2026 09:02:07 +0300 Subject: Add 'ask edit ID' to edit task description in $EDITOR; bump to 0.41.0 Amp-Thread-ID: https://ampcode.com/threads/T-019e9b82-6ba0-77a4-b4a0-5c2cbf9bf39f Co-authored-by: Amp --- internal/askcli/command_edit.go | 49 ++++++++++++++++++++++++++++++++++------- 1 file changed, 41 insertions(+), 8 deletions(-) (limited to 'internal/askcli/command_edit.go') diff --git a/internal/askcli/command_edit.go b/internal/askcli/command_edit.go index 585f550..27c9106 100644 --- a/internal/askcli/command_edit.go +++ b/internal/askcli/command_edit.go @@ -1,23 +1,28 @@ package askcli import ( + "bytes" "context" "io" "codeberg.org/snonux/hexai/internal/editor" ) -// captureFromEditor opens the user's editor on a temporary file and returns its -// trimmed contents after the editor exits. It is a variable so tests can stub it. -var captureFromEditor = func() (string, error) { - return editor.OpenTempAndEdit(nil) +// captureFromEditor opens the user's editor on a temporary file pre-filled with +// the given initial content and returns its trimmed contents after the editor +// exits. It is a variable so tests can stub it. +var captureFromEditor = func(initial []byte) (string, error) { + return editor.OpenTempAndEdit(initial) } -// handleEdit opens the configured editor on a temporary file and creates a new -// task from the resulting (possibly multi-line) content. +// handleEdit opens the configured editor on a temporary file. With no selector +// it creates a new task from the resulting content. With a task ID/UUID selector +// it pre-fills the editor with the task's current description and updates it. func (d *Dispatcher) handleEdit(ctx context.Context, args []string, stdout, stderr io.Writer) (int, error) { - _ = args - description, err := captureFromEditor() + if len(args) >= 2 { + return d.editTaskDescription(ctx, args[1], stdout, stderr) + } + description, err := captureFromEditor(nil) if err != nil { writeInfoError(stderr, err) return 1, nil @@ -28,3 +33,31 @@ func (d *Dispatcher) handleEdit(ctx context.Context, args []string, stdout, stde } return d.createTask(ctx, nil, description, nil, stdout, stderr) } + +// editTaskDescription resolves a task selector, opens the editor pre-filled with +// the task's current description, and modifies the task with the new content. +func (d *Dispatcher) editTaskDescription(ctx context.Context, selector string, stdout, stderr io.Writer) (int, error) { + resolved, tasks, code, err := d.resolveTaskSelector(ctx, selector, stderr) + if err != nil { + writeInfoError(stderr, err) + return code, nil + } + + description, err := captureFromEditor([]byte(tasks[0].Description)) + if err != nil { + writeInfoError(stderr, err) + return 1, nil + } + if description == "" { + _, _ = io.WriteString(stderr, "error: ask edit aborted: empty description\n") + return 1, nil + } + + var outBuf bytes.Buffer + code, err = d.runner.Run(ctx, []string{"uuid:" + resolved.UUID, "modify", description}, nil, &outBuf, io.Discard) + if code != 0 { + return code, err + } + _, _ = io.WriteString(stdout, FormatSuccess(displayResolvedTaskID(resolved))) + return 0, nil +} -- cgit v1.2.3