6.7 KiB
Org-GTD Automation Strategies for OpenClaw Integration
- Research: Automating Org-GTD for OpenClaw Integration
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:
;; 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)'
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:
(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)))))
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:
* 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:
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:
~/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
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):
- Use plain Org Mode with custom properties for GTD semantics
- Define your own TODO states: TODO → NEXT → WAIT → DONE/CNCL
- Use ID properties on all entries for automation targeting
- Create agenda views for daily/weekly reviews
- Reserve interactive work for capture, clarification, and review
-
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:
(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))
Find stuck projects (PROJ without NEXT):
(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))
Integration Points with OpenClaw
OpenClaw can:
- Read your gtd.org files to find next actions
- Create new entries via `write` tool (append to inbox.org)
- Archive completed items by locating via ID
- Generate weekly reports (parse files, output summaries)
- Trigger reviews based on HEARTBEAT.md schedules
OpenClaw cannot (easily):
- Toggle states interactively (requires cursor position)
- Process inbox items (clarification requires human judgment)
- 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
- Agora Open Source Business Models
- 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