refactor: moved org-agent to its own repository as a submodule
This commit is contained in:
219
notes/20260314_org_gtd_automation_strategies.org
Normal file
219
notes/20260314_org_gtd_automation_strategies.org
Normal file
@@ -0,0 +1,219 @@
|
||||
#+TITLE: Org-GTD Automation Strategies for OpenClaw Integration
|
||||
#+author: User
|
||||
#+created: [2026-03-16 Mon 14:28]
|
||||
#+ID: 20260314_org_gtd_automation_strategies
|
||||
#+FILETAGS: org-mode gtd automation emacs org-gtd
|
||||
|
||||
* Research: Automating Org-GTD for OpenClaw Integration
|
||||
|
||||
** The Core Problem
|
||||
|
||||
`org-gtd.el` is designed for *interactive* Emacs use. Most functions rely on:
|
||||
- `point` being at a specific entry
|
||||
- Interactive prompts (`completing-read`, `yes-or-no-p`)
|
||||
- Context from the current buffer position
|
||||
|
||||
This creates friction for automation—OpenClaw cannot "stand on an item" like a human user.
|
||||
|
||||
** Approaches to Automation
|
||||
|
||||
*** Approach 1: ID-Based Operations (Recommended)
|
||||
|
||||
Org entries have unique IDs. We can use `org-id` to locate entries programmatically:
|
||||
|
||||
#+begin_src elisp
|
||||
;; Move to entry by ID, then execute org-gtd function
|
||||
(defun org-gtd-automate-by-id (entry-id command)
|
||||
"Execute org-gtd COMMAND at entry with ENTRY-ID."
|
||||
(let ((marker (org-id-find entry-id 'marker)))
|
||||
(when marker
|
||||
(with-current-buffer (marker-buffer marker)
|
||||
(goto-char (marker-position marker))
|
||||
(funcall command)))))
|
||||
|
||||
;; Example usage in batch mode:
|
||||
;; emacs --batch -l org-gtd \
|
||||
;; --eval '(org-gtd-automate-by-id "my-entry-id" #'org-gtd-archive-item)'
|
||||
#+end_src
|
||||
|
||||
*Advantages:*
|
||||
- Works with any org-gtd function
|
||||
- No regex parsing needed
|
||||
- Preserves all org-gtd logic
|
||||
|
||||
*Limitations:*
|
||||
- Requires entries to have IDs (add `:ID:` property)
|
||||
- Functions with interactive prompts will still block
|
||||
|
||||
*** Approach 2: Custom Non-Interactive Wrappers
|
||||
|
||||
Write wrapper functions that accept arguments instead of using interactive prompts:
|
||||
|
||||
#+begin_src elisp
|
||||
(defun org-gtd-set-status-noninteractive (entry-id new-status)
|
||||
"Set status of entry with ENTRY-ID to NEW-STATUS (TODO, NEXT, WAIT, DONE)."
|
||||
(let ((marker (org-id-find entry-id 'marker)))
|
||||
(when marker
|
||||
(with-current-buffer (marker-buffer marker)
|
||||
(goto-char (marker-position marker))
|
||||
(org-todo new-status)))))
|
||||
|
||||
(defun org-gtd-archive-by-id (entry-id)
|
||||
"Archive entry with ENTRY-ID."
|
||||
(let ((marker (org-id-find entry-id 'marker)))
|
||||
(when marker
|
||||
(with-current-buffer (marker-buffer marker)
|
||||
(goto-char (marker-position marker))
|
||||
(org-archive-subtree)))))
|
||||
#+end_src
|
||||
|
||||
*Advantages:*
|
||||
- Clean API for batch operations
|
||||
- No interactive prompts
|
||||
- Can chain multiple operations
|
||||
|
||||
*** Approach 3: Plain Org Mode (Most Automation-Friendly)
|
||||
|
||||
Instead of `org-gtd.el`, use standard Org features that are designed for automation:
|
||||
|
||||
#+begin_src org
|
||||
,* TODO Project Alpha
|
||||
:PROPERTIES:
|
||||
:ID: proj-alpha-001
|
||||
:CATEGORY: proj-alpha
|
||||
:GTD_TYPE: project
|
||||
:END:
|
||||
,** NEXT First action
|
||||
:PROPERTIES:
|
||||
:ID: action-001
|
||||
:GTD_TYPE: next
|
||||
:END:
|
||||
,** TODO Second action
|
||||
,** WAIT Waiting for response
|
||||
|
||||
,* TODO Standalone next action :context_home:
|
||||
:PROPERTIES:
|
||||
:GTD_TYPE: next
|
||||
:END:
|
||||
#+end_src
|
||||
|
||||
*Standard Org functions I can use:*
|
||||
- `org-todo` — Change TODO state
|
||||
- `org-set-property` — Set/change properties
|
||||
- `org-archive-subtree` — Archive entries
|
||||
- `org-refile` — Move entries between files
|
||||
- `org-id-find` — Locate by ID
|
||||
- `org-map-entries` — Batch operations across entries
|
||||
|
||||
** File Structure for Automation
|
||||
|
||||
*Recommended layout:*
|
||||
|
||||
#+begin_example
|
||||
~/memex/gtd/
|
||||
├── inbox.org # Captured items (process to main)
|
||||
├── main.org # Active projects and next actions
|
||||
├── someday.org # Someday/maybe items
|
||||
├── waiting.org # Delegated/waiting items
|
||||
├── archive.org # Completed items
|
||||
└── templates/ # Capture templates
|
||||
#+end_example
|
||||
|
||||
** Comparison: org-gtd.el vs Plain Org
|
||||
|
||||
| Feature | org-gtd.el | Plain Org |
|
||||
|---------|------------|-----------|
|
||||
| Interactive workflow | Excellent | Good |
|
||||
| Batch automation | Poor | Excellent |
|
||||
| Learning curve | Medium | Low |
|
||||
| Community support | Active | Massive |
|
||||
| GTD semantics | Built-in | Manual setup |
|
||||
| Custom agenda views | Good | Excellent |
|
||||
|
||||
** Recommendation
|
||||
|
||||
For your use case (hybrid interactive + automation):
|
||||
|
||||
1. *Use plain Org Mode* with custom properties for GTD semantics
|
||||
2. *Define your own TODO states:* TODO → NEXT → WAIT → DONE/CNCL
|
||||
3. *Use ID properties* on all entries for automation targeting
|
||||
4. *Create agenda views* for daily/weekly reviews
|
||||
5. *Reserve interactive work* for capture, clarification, and review
|
||||
6. *Use automation for:*
|
||||
- Archiving completed items
|
||||
- Moving waiting items to active
|
||||
- Generating reports
|
||||
- Refiling from inbox to projects
|
||||
|
||||
** Sample Automation Commands
|
||||
|
||||
*Archive all DONE items over 30 days old:*
|
||||
|
||||
#+begin_src elisp
|
||||
(defun org-gtd-archive-old-done ()
|
||||
"Archive DONE items older than 30 days."
|
||||
(org-map-entries
|
||||
(lambda ()
|
||||
(when (string= (org-get-todo-state) "DONE")
|
||||
(let ((closed (org-entry-get nil "CLOSED")))
|
||||
(when (and closed
|
||||
(> (org-time-stamp-to-now closed) 30))
|
||||
(org-archive-subtree)))))
|
||||
t 'agenda))
|
||||
#+end_src
|
||||
|
||||
*Find stuck projects (PROJ without NEXT):*
|
||||
|
||||
#+begin_src elisp
|
||||
(defun org-gtd-find-stuck-projects ()
|
||||
"Return list of IDs for projects without NEXT actions."
|
||||
(let (stuck)
|
||||
(org-map-entries
|
||||
(lambda ()
|
||||
(when (string= (org-get-todo-state) "PROJ")
|
||||
(let ((id (org-entry-get nil "ID"))
|
||||
(has-next nil))
|
||||
(org-map-entries
|
||||
(lambda ()
|
||||
(when (string= (org-get-todo-state) "NEXT")
|
||||
(setq has-next t)))
|
||||
nil 'tree)
|
||||
(unless has-next
|
||||
(push id stuck))))))
|
||||
stuck))
|
||||
#+end_src
|
||||
|
||||
** Integration Points with OpenClaw
|
||||
|
||||
*OpenClaw can:*
|
||||
1. Read your gtd.org files to find next actions
|
||||
2. Create new entries via `write` tool (append to inbox.org)
|
||||
3. Archive completed items by locating via ID
|
||||
4. Generate weekly reports (parse files, output summaries)
|
||||
5. Trigger reviews based on HEARTBEAT.md schedules
|
||||
|
||||
*OpenClaw cannot (easily):*
|
||||
1. Toggle states interactively (requires cursor position)
|
||||
2. Process inbox items (clarification requires human judgment)
|
||||
3. Run org-agenda (needs Emacs UI)
|
||||
|
||||
** Summary
|
||||
|
||||
- org-gtd.el is optimized for *interactive* use
|
||||
- Batch automation works best with *plain Org + ID properties*
|
||||
- Consider a hybrid: org-gtd for capture/review, custom functions for automation
|
||||
- The "projects as hierarchy" approach (from Desmond Rivet's blog) is automation-friendly
|
||||
|
||||
** Related
|
||||
|
||||
- [[file:20260314_agora_open_source_business_models.org][Agora Open Source Business Models]]
|
||||
- [[file:agora-pds-relay-architecture.org][Agora PDS & Relay Architecture]]
|
||||
- Desmond Rivet's GTD implementation: https://desmondrivet.com/2023/12/05/gtd-org-mode
|
||||
- org-gtd.el: https://github.com/Trevoke/org-gtd.el
|
||||
|
||||
** Next Steps
|
||||
|
||||
TODO Test org-id based automation on sample files
|
||||
TODO Create wrapper functions for common operations
|
||||
TODO Design plain Org GTD structure for memex
|
||||
TODO Implement capture templates for OpenClaw integration
|
||||
Reference in New Issue
Block a user