summaryrefslogtreecommitdiff
path: root/internal/askcli/command_edit.go
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-06-06 09:02:07 +0300
committerPaul Buetow <paul@buetow.org>2026-06-06 09:02:07 +0300
commitdc17b7469c2055961892bbb3175d4ab0fb1d1180 (patch)
tree541bf267994875abeedce0fddf399c95174d5fba /internal/askcli/command_edit.go
parent1433f7a13ede0c819ec4f8fd4027ad3df8daa94f (diff)
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 <amp@ampcode.com>
Diffstat (limited to 'internal/askcli/command_edit.go')
-rw-r--r--internal/askcli/command_edit.go49
1 files changed, 41 insertions, 8 deletions
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
+}