3WLUGWU24VFKJ6AAFNOHE4EB5VF6M3NQRUTNXMI5DVMCMAI3ZFBQC IWZF5VWU3D57MRTTJOW3T76BLZJN76QJURLCBMJFXIMS2W2VEU2AC NQGY27YH53426MZ5LOSNZDDOXLWV2AOJGUJAJPXWUVX6EJ24KZ4AC MEKBQ4ELV5T3ZU5WD7FBAWXQLBCNJGD57RYBTEVAMMLO4LHOCKQAC F7MUSI5FFYOWTCR4CBL42CT3GE6UL66CQVJANCIISBLAMKRMQQ6AC QBTJ7AO3MLEDPYFWBLHZAVKTUDH2ST5NCKNDENWWHMKLCIBTAQ7QC ALIV37TMXXHTQ3Q2HHHEXLOQDNUZVZ3NNO6WN46DQBPJELDXJOXAC "Always read relevant text first before editing.""open_file and switch_buffer place point at the beginning of the buffer.""search_forward/search_backward wrap by default; pass wrap=false for strict no-wrap.""For search ops, use needle (text/query aliases are accepted).""Search ops return found=false when no match; set required=true to fail hard.""References are 1-based over prior ops in the same exec_ops call, e.g. $2.point.""Use point/selection editing: goto_char, search_forward/backward, set_region.""Edit only via insert_text, delete_selection, replace_selection, replace_match, replace_in_selection.""Do not save files; saving is always the user's explicit choice.""All edits happen in CRDT-managed replicas; avoid speculative rewrites.""Return concise text once edits are done.")
"Always read relevant text first before editing.""open_file and switch_buffer place point at the beginning of the buffer.""Use move and search for navigation; both use a direction parameter.""For search ops, use needle (text/query aliases are accepted).""move returns moved_chars; search returns match_length (0 when not found).""Use set_mark and clear_region to control selections.""Edit only via insert_text, delete_selection, and replace_selection.""Do not save files; saving is always the user's explicit choice.""All edits happen in CRDT-managed replicas; avoid speculative rewrites.""Return concise text once edits are done.")
("open_file"(let* ((path0 (or (madrigal--alist-get* 'path raw-op)(madrigal--alist-get* :path raw-op)))(create0 (or (madrigal--alist-get* 'create raw-op)
("open_file"(let* ((path0 (or (madrigal--alist-get* 'path raw-op)(madrigal--alist-get* :path raw-op)))(create0 (or (madrigal--alist-get* 'create raw-op)
(let ((buf (find-file-noselect path)))(madrigal--ensure-shared-in-server buf)(setq network-name (madrigal--buffer-network-name buf))(setq replica (madrigal--ensure-agent-replica agent network-name))(with-current-buffer replica(goto-char (point-min)))(setq row (append row(list (cons 'path path)(cons 'network_name network-name)(cons 'buffer (buffer-name replica))))))))("list_buffers"(let (names)(maphash (lambda (k _v) (push k names))(crdt--session-buffer-table madrigal--server-session))(setq row (append row (list (cons 'buffers (nreverse names)))))))("switch_buffer"(let* ((name0 (or (madrigal--alist-get* 'network_name raw-op)(madrigal--alist-get* :network_name raw-op)(madrigal--alist-get* 'buffer raw-op)(madrigal--alist-get* :buffer raw-op)))(name (madrigal--resolve-ref name0 results)))(setq replica (madrigal--ensure-agent-replica agent name))(with-current-buffer replica(goto-char (point-min)))(setq network-name name)(setq row (append row(list (cons 'network_name network-name)(cons 'buffer (buffer-name replica)))))))("get_point"(with-current-buffer replica(setq row (append row(list (cons 'point (point))(cons 'region_active (and (use-region-p) t))(cons 'region_start (and (use-region-p) (region-beginning)))(cons 'region_end (and (use-region-p) (region-end))))))))("goto_char"(let* ((pos0 (or (madrigal--alist-get* 'pos raw-op)(madrigal--alist-get* :pos raw-op)))(pos (madrigal--require-integer(madrigal--resolve-ref pos0 results) "pos")))(with-current-buffer replica(madrigal--require-pos-in-buffer replica pos "pos")(goto-char pos)(setq row (append row (list (cons 'point (point))))))))("search_forward"(let* ((needle0 (or (madrigal--alist-get* 'needle raw-op)(madrigal--alist-get* :needle raw-op)(madrigal--alist-get* 'text raw-op)(madrigal--alist-get* :text raw-op)(madrigal--alist-get* 'query raw-op)(madrigal--alist-get* :query raw-op)))(count0 (or (madrigal--alist-get* 'count raw-op)(madrigal--alist-get* :count raw-op)1))(set-region0 (or (madrigal--alist-get* 'set_region raw-op)(madrigal--alist-get* :set_region raw-op)nil))(required0 (or (madrigal--alist-get* 'required raw-op)(madrigal--alist-get* :required raw-op)nil))(wrap-present (or (madrigal--obj-has-key-p raw-op 'wrap)(madrigal--obj-has-key-p raw-op :wrap)))(wrap0 (or (madrigal--alist-get* 'wrap raw-op)(madrigal--alist-get* :wrap raw-op)))(needle (format "%s" (madrigal--resolve-ref needle0 results)))(count (madrigal--require-integer(madrigal--resolve-ref count0 results) "count"))(set-region-p (not (memq set-region0 '(nil :false false))))(required-p (not (memq required0 '(nil :false false))))(wrap-p (if wrap-present(not (memq wrap0 '(nil :false false)))t)))(when (string-empty-p needle)(error "madrigal: needle must be non-empty"))(when (<= count 0)(error "madrigal: count must be > 0"))(with-current-buffer replica(let ((found nil)(wrapped nil)(missing nil))(cl-loop repeat count do(progn(setq found (search-forward needle nil t))(unless found(when wrap-p(goto-char (point-min))(setq wrapped t)(setq found (search-forward needle nil t))))(unless found(setq missing t)(cl-return))))(when (and missing required-p)(error "madrigal: search_forward needle not found"))(when (and found set-region-p)(madrigal--set-region replica (- (point) (length needle)) (point)))(setq row (append row(list (cons 'found (and found t))(cons 'point (point))(cons 'match_start (and found (- (point) (length needle))))(cons 'match_end (and found (point)))(cons 'wrapped wrapped))))))))("search_backward"(let* ((needle0 (or (madrigal--alist-get* 'needle raw-op)(madrigal--alist-get* :needle raw-op)(madrigal--alist-get* 'text raw-op)(madrigal--alist-get* :text raw-op)(madrigal--alist-get* 'query raw-op)(madrigal--alist-get* :query raw-op)))(count0 (or (madrigal--alist-get* 'count raw-op)(madrigal--alist-get* :count raw-op)1))(set-region0 (or (madrigal--alist-get* 'set_region raw-op)(madrigal--alist-get* :set_region raw-op)nil))(required0 (or (madrigal--alist-get* 'required raw-op)(madrigal--alist-get* :required raw-op)nil))(wrap-present (or (madrigal--obj-has-key-p raw-op 'wrap)(madrigal--obj-has-key-p raw-op :wrap)))(wrap0 (or (madrigal--alist-get* 'wrap raw-op)(madrigal--alist-get* :wrap raw-op)))(needle (format "%s" (madrigal--resolve-ref needle0 results)))(count (madrigal--require-integer(madrigal--resolve-ref count0 results) "count"))(set-region-p (not (memq set-region0 '(nil :false false))))(required-p (not (memq required0 '(nil :false false))))(wrap-p (if wrap-present(not (memq wrap0 '(nil :false false)))t)))(when (string-empty-p needle)(error "madrigal: needle must be non-empty"))(when (<= count 0)(error "madrigal: count must be > 0"))
(let ((buf (find-file-noselect path)))(madrigal--ensure-shared-in-server buf)(setq network-name (madrigal--buffer-network-name buf))(setq replica (madrigal--ensure-agent-replica agent network-name))
(let ((found nil)(wrapped nil)(missing nil))(cl-loop repeat count do(progn(setq found (search-backward needle nil t))(unless found(when wrap-p(goto-char (point-max))(setq wrapped t)(setq found (search-backward needle nil t))))(unless found(setq missing t)(cl-return))))(when (and missing required-p)(error "madrigal: search_backward needle not found"))(when (and found set-region-p)(madrigal--set-region replica found (+ found (length needle))))(when found(goto-char found))(setq row (append row(list (cons 'found (and found t))(cons 'point (point))(cons 'match_start found)(cons 'match_end (and found (+ found (length needle))))(cons 'wrapped wrapped))))))))("set_region"(let* ((start0 (or (madrigal--alist-get* 'start raw-op)(madrigal--alist-get* :start raw-op)))(end0 (or (madrigal--alist-get* 'end raw-op)(madrigal--alist-get* :end raw-op)))(start (madrigal--require-integer(madrigal--resolve-ref start0 results) "start"))(end (madrigal--require-integer(madrigal--resolve-ref end0 results) "end")))(let ((bounds (madrigal--set-region replica start end)))(setq row (append row(list (cons 'region_start (car bounds))(cons 'region_end (cdr bounds))(cons 'point (with-current-buffer replica (point)))))))))("clear_region"(madrigal--clear-region replica)(setq row (append row (list (cons 'region_active nil)))))("read_region"(let* ((start0 (or (madrigal--alist-get* 'start raw-op)(madrigal--alist-get* :start raw-op)))(end0 (or (madrigal--alist-get* 'end raw-op)(madrigal--alist-get* :end raw-op)))(start (madrigal--require-integer(madrigal--resolve-ref start0 results) "start"))(end (madrigal--require-integer(madrigal--resolve-ref end0 results) "end")))(with-current-buffer replica(madrigal--require-pos-in-buffer replica start "start")(madrigal--require-pos-in-buffer replica end "end")(let ((s start)(e end))(setq row (append row(list (cons 'text(buffer-substring-no-properties(min s e)(max s e))))))))))("insert_text"(let* ((text0 (or (madrigal--alist-get* 'text raw-op)(madrigal--alist-get* :text raw-op)))(text (format "%s" (madrigal--resolve-ref text0 results))))(with-current-buffer replica(insert text)
(goto-char (point-min)))
(list (cons 'point (point))(cons 'inserted (length text))))))))("delete_selection"(with-current-buffer replica(pcase-let ((`(,s . ,e) (madrigal--region-bounds-required replica)))(delete-region s e)(madrigal--clear-region replica)(setq row (append row(list (cons 'deleted (- e s))(cons 'point (point))))))))("replace_selection"(let* ((text0 (or (madrigal--alist-get* 'text raw-op)(madrigal--alist-get* :text raw-op)))(text (format "%s" (madrigal--resolve-ref text0 results))))
(list (cons 'path path)(cons 'network_name network-name)(cons 'buffer (buffer-name replica))))))))("list_buffers"(let (names)(maphash (lambda (k _v) (push k names))(crdt--session-buffer-table madrigal--server-session))(setq row (append row (list (cons 'buffers (nreverse names)))))))("switch_buffer"(let* ((name0 (or (madrigal--alist-get* 'network_name raw-op)(madrigal--alist-get* :network_name raw-op)(madrigal--alist-get* 'buffer raw-op)(madrigal--alist-get* :buffer raw-op)))(name (madrigal--resolve-ref name0 results)))(setq replica (madrigal--ensure-agent-replica agent name))
(pcase-let ((`(,s . ,e) (madrigal--region-bounds-required replica)))(delete-region s e)(goto-char s)(insert text)(madrigal--clear-region replica)(setq row (append row(list (cons 'point (point))(cons 'inserted (length text)))))))))("replace_match"(let* ((needle0 (or (madrigal--alist-get* 'needle raw-op)(madrigal--alist-get* :needle raw-op)))(text0 (or (madrigal--alist-get* 'text raw-op)(madrigal--alist-get* :text raw-op)))
(goto-char (point-min)))(setq network-name name)(setq row (append row(list (cons 'network_name network-name)(cons 'buffer (buffer-name replica)))))))("move"(let* ((direction0 (or (madrigal--alist-get* 'direction raw-op)(madrigal--alist-get* :direction raw-op)'forward))(unit0 (or (madrigal--alist-get* 'unit raw-op)(madrigal--alist-get* :unit raw-op)(madrigal--alist-get* 'by raw-op)(madrigal--alist-get* :by raw-op)'char))
(needle (format "%s" (madrigal--resolve-ref needle0 results)))(text (format "%s" (madrigal--resolve-ref text0 results)))
(direction (downcase (format "%s" (madrigal--resolve-ref direction0 results))))(unit (downcase (format "%s" (madrigal--resolve-ref unit0 results))))
(madrigal--resolve-ref count0 results) "count")))(when (string-empty-p needle)(error "madrigal: needle must be non-empty"))
(madrigal--resolve-ref count0 results) "count"))(forward-p (string= direction "forward")))(unless (member direction '("forward" "backward"))(error "madrigal: move direction must be forward/backward"))(unless (member unit '("char" "line" "word" "symbol" "sexp" "buffer"))(error "madrigal: move unit must be char/line/word/symbol/sexp/buffer"))
(with-current-buffer replica(let ((before (point)))(pcase unit("char" (funcall (if forward-p #'forward-char #'backward-char) count))("line" (forward-line (if forward-p count (- count))))("word" (funcall (if forward-p #'forward-word #'backward-word) count))("symbol" (forward-symbol (if forward-p count (- count))))("sexp" (funcall (if forward-p #'forward-sexp #'backward-sexp) count))("buffer" (goto-char (if forward-p (point-max) (point-min)))))(setq row (append row(list (cons 'moved_chars (abs (- (point) before))))))))))("search"(let* ((direction0 (or (madrigal--alist-get* 'direction raw-op)(madrigal--alist-get* :direction raw-op)'forward))(needle0 (or (madrigal--alist-get* 'needle raw-op)(madrigal--alist-get* :needle raw-op)(madrigal--alist-get* 'text raw-op)(madrigal--alist-get* :text raw-op)(madrigal--alist-get* 'query raw-op)(madrigal--alist-get* :query raw-op)))(direction (downcase (format "%s" (madrigal--resolve-ref direction0 results))))(needle (format "%s" (madrigal--resolve-ref needle0 results)))(forward-p (string= direction "forward"))(backward-p (string= direction "backward")))(unless (or forward-p backward-p)(error "madrigal: search direction must be forward/backward"))(when (string-empty-p needle)(error "madrigal: needle must be non-empty"))
(let ((replaced 0)(first-pos nil)(last-pos nil))(while (and (< replaced count)(search-forward needle nil t))(let ((mstart (- (point) (length needle)))(mend (point)))(delete-region mstart mend)(goto-char mstart)(insert text)(setq replaced (1+ replaced)last-pos (point))(unless first-pos(setq first-pos mstart))))(when (= replaced 0)(error "madrigal: needle not found from current point"))
(let ((found nil)(match-len (length needle)))(setq found (if forward-p(search-forward needle nil t)(search-backward needle nil t)))(setq row (append row(list (cons 'match_length (if found match-len 0)))))))))("set_mark"(with-current-buffer replica(push-mark (point) t t)(setq mark-active tdeactivate-mark nil)(setq row (append row(list (cons 'mark_set t)(cons 'region_active (and (use-region-p) t)))))))("clear_region"(madrigal--clear-region replica)(setq row (append row (list (cons 'region_active nil)))))("read_selection"(with-current-buffer replica(if (use-region-p)(let* ((s (region-beginning))(e (region-end))(text (buffer-substring-no-properties s e)))
(list (cons 'replaced replaced)(cons 'first_pos first-pos)(cons 'point (or last-pos (point))))))))))("replace_in_selection"(let* ((bounds (madrigal--region-bounds-required replica))(old0 (or (madrigal--alist-get* 'old_text raw-op)(madrigal--alist-get* :old_text raw-op)))(text0 (or (madrigal--alist-get* 'text raw-op)(madrigal--alist-get* :text raw-op)))(strict0 (or (madrigal--alist-get* 'strict raw-op)(madrigal--alist-get* :strict raw-op)t))(old-text (format "%s" (madrigal--resolve-ref old0 results)))(text (format "%s" (madrigal--resolve-ref text0 results)))(strictp (not (memq strict0 '(nil :false false)))))
(list (cons 'text text)(cons 'length (length text))))))(setq row (append row(list (cons 'text "")(cons 'length 0)))))))("insert_text"(let* ((text0 (or (madrigal--alist-get* 'text raw-op)(madrigal--alist-get* :text raw-op)))(text (format "%s" (madrigal--resolve-ref text0 results))))
(let* ((s (car bounds))(e (cdr bounds))(current (buffer-substring-no-properties s e)))(when (and strictp (not (string= current old-text)))(error "madrigal: replace_in_selection mismatch at [%d,%d]" s e))
(insert text)(setq row (append row(list (cons 'success t)))))))("delete_selection"(with-current-buffer replica(pcase-let ((`(,s . ,e) (madrigal--region-bounds-required replica)))(delete-region s e)(madrigal--clear-region replica)(setq row (append row(list (cons 'success t)))))))("replace_selection"(let* ((text0 (or (madrigal--alist-get* 'text raw-op)(madrigal--alist-get* :text raw-op)))(text (format "%s" (madrigal--resolve-ref text0 results))))(with-current-buffer replica(pcase-let ((`(,s . ,e) (madrigal--region-bounds-required replica)))
(list (cons 'point (point))(cons 'inserted (length text)))))))))("save_buffer"(if (not madrigal-allow-save-buffer-op)
(list (cons 'success t))))))))("save_buffer"(if (not madrigal-allow-save-buffer-op)(setq row (append row(list (cons 'saved nil)(cons 'skipped t)(cons 'reason "user-save-required"))))(let ((server-buffer (madrigal--server-buffer-from-network-name network-name)))(unless (buffer-live-p server-buffer)(error "madrigal: no server buffer for %s" network-name))(unless (madrigal--flush-replica-to-serverreplica agent-session server-buffer madrigal-save-sync-timeout)(error "madrigal: timed out waiting for CRDT sync before save"))(with-current-buffer server-buffer(when (and buffer-file-name (buffer-modified-p))(save-buffer))
(list (cons 'saved nil)(cons 'skipped t)(cons 'reason "user-save-required"))))(let ((server-buffer (madrigal--server-buffer-from-network-name network-name)))(unless (buffer-live-p server-buffer)(error "madrigal: no server buffer for %s" network-name))(unless (madrigal--flush-replica-to-serverreplica agent-session server-buffer madrigal-save-sync-timeout)(error "madrigal: timed out waiting for CRDT sync before save"))(with-current-buffer server-buffer(when (and buffer-file-name (buffer-modified-p))(save-buffer))(setq row (append row(list (cons 'saved (and buffer-file-name t))(cons 'path buffer-file-name))))))))(_(error "madrigal: unknown op %s" op-name)))
(list (cons 'saved (and buffer-file-name t))(cons 'path buffer-file-name))))))))(_(error "madrigal: unknown op %s" op-name)))
"Operations: open_file, list_buffers, switch_buffer, get_point, goto_char, ""search_forward, search_backward, set_region, clear_region, read_region, ""insert_text, delete_selection, replace_selection, replace_match, replace_in_selection. "
"Operations: open_file, list_buffers, switch_buffer, move, search, set_mark, clear_region, read_selection, ""insert_text, delete_selection, replace_selection. "
"search_forward/search_backward support needle plus text/query aliases, optional wrap boolean (default true), and optional required boolean (default false). ""Supports references like $1.point to consume previous step outputs.")
"move returns moved_chars. search supports direction (forward/backward) and needle (text/query aliases); it returns match_length (0 when not found). ""Supports references like $1.field to consume previous step outputs.")