#+TITLE:Org-Clubhouse Simple, unopinionated integration between Emacs's [[https://orgmode.org/][org-mode]] and the [[https://clubhouse.io/][Clubhouse]] issue tracker (This used to be at urbint/org-clubhouse, by the way, but moved here as it's more of a personal project than a company one) * Installation ** [[https://github.com/quelpa/quelpa][Quelpa]] #+BEGIN_SRC emacs-lisp (quelpa '(org-clubhouse :fetcher github :repo "glittershark/org-clubhouse")) #+END_SRC ** [[https://github.com/hlissner/doom-emacs/][DOOM Emacs]] #+BEGIN_SRC emacs-lisp ;; in packages.el (package! org-clubhouse :recipe (:fetcher github :repo "glittershark/org-clubhouse" :files ("*"))) ;; in config.el (def-package! org-clubhouse) #+END_SRC ** [[http://spacemacs.org/][Spacemacs]] #+BEGIN_SRC emacs-lisp ;; in .spacemacs (SPC+fed) dotspacemacs-additional-packages '((org-clubhouse :location (recipe :fetcher github :repo "glittershark/org-clubhouse"))) #+END_SRC * Setup Once installed, you'll need to set three global config vars: #+BEGIN_SRC emacs-lisp (setq org-clubhouse-auth-token "<your-token>" org-clubhouse-team-name "<your-team-name>" org-clubhouse-username "<your-username>") #+END_SRC You can generate a new personal API token by going to the "API Tokens" tab on the "Settings" page in the clubhouse UI. Note that ~org-clubhouse-username~ needs to be set to your *mention name*, not your username, as currently there's no way to get the ID of a user given their username in the clubhouse API * Usage ** Reading from clubhouse - ~org-clubhouse-headlines-from-query~ Create org-mode headlines from a [[https://help.clubhouse.io/hc/en-us/articles/360000046646-Searching-in-Clubhouse-Story-Search][clubhouse query]] at the cursor's current position, prompting for the headline indentation level and clubhouse query text - ~org-clubhouse-headline-from-story~ Prompts for headline indentation level and the title of a story (which will complete using the titles of all stories in your Clubhouse workspace) and creates an org-mode headline from that story - ~org-clubhouse-headline-from-story-id~ Creates an org-mode headline directly from the ID of a clubhouse story ** Writing to clubhouse - ~org-clubhouse-create-story~ Creates a new Clubhouse story from the current headline, or if a region of headlines is selected bulk-creates stories with all those headlines - ~org-clubhouse-create-epic~ Creates a new Clubhouse epic from the current headline, or if a region of headlines is selected bulk-creates epics with all those headlines - ~org-clubhouse-create-story-with-task-list~ Creates a Clubhouse story from the current headline, making all direct children of the headline into tasks in the task list of the story - ~org-clubhouse-push-task-list~ Writes each child element of the current clubhouse element as a task list item of the associated clubhouse ID. - ~org-clubhouse-update-story-title~ Updates the title of the Clubhouse story linked to the current headline with the text of the headline - ~org-clubhouse-update-description~ Update the status of the Clubhouse story linked to the current element with the contents of a drawer inside the element called DESCRIPTION, if any exists - ~org-clubhouse-claim~ Adds the user configured in ~org-clubhouse-username~ as the owner of the clubhouse story associated with the headline at point *** Automatically updating Clubhouse story statuses Org-clubhouse can be configured to update the status of stories as you update their todo-keyword in org-mode. To opt-into this behavior, set the ~org-clubhouse-mode~ minor-mode: #+BEGIN_SRC emacs-lisp (add-hook 'org-mode-hook #'org-clubhouse-mode nil nil) #+END_SRC The mapping from org-mode todo-keywords is configured via the ~org-clubhouse-state-alist~ variable, which should be an [[https://www.gnu.org/software/emacs/manual/html_node/elisp/Association-Lists.html][alist]] mapping (string) [[https://orgmode.org/manual/Workflow-states.html][org-mode todo-keywords]] to the (string) names of their corresponding workflow state. You can have todo-keywords that don't map to a workflow state (I use this in my workflow extensively) and org-clubhouse will just preserve the previous state of the story when moving to that state. An example config: #+BEGIN_SRC emacs-lisp (setq org-clubhouse-state-alist '(("TODO" . "To Do") ("ACTIVE" . "In Progress") ("DONE" . "Done"))) #+END_SRC * Philosophy I use org-mode every single day to manage tasks, notes, literate programming, etc. Part of what that means for me is that I already have a system for the structure of my .org files, and I don't want to sacrifice that system for any external tool. Updating statuses, ~org-clubhouse-create-story~, and ~org-clubhouse-headline-from-story~ are my bread and butter for that reason - rather than having some sort of bidirectional sync that pulls down full lists of all the stories in Clubhouse (or whatever issue tracker / project management tool I'm using at the time). I can be in a mode where I'm taking meeting notes, think of something that I need to do, make it a TODO headline, and make that TODO headline a clubhouse story. That's the same reason for the DESCRIPTION drawers rather than just sending the entire contents of a headline to Clubhouse - I almost always want to write things like personal notes, literate code, etc inside of the tasks I'm working on, and don't always want to share that with Clubhouse. * Configuration Refer to the beginning of the [[https://github.com/urbint/org-clubhouse/blob/master/org-clubhouse.el][org-clubhouse.el]] file in this repository for documentation on all supported configuration variables