From d444643895f33dc91b2dd6d3ef8af90598a7ab68 Mon Sep 17 00:00:00 2001 From: Craig Jennings Date: Sat, 6 Jun 2026 18:23:41 -0500 Subject: feat(pearl): add multi-account config, rename module to pearl-config The pearl package moved from a single Linear workspace to multi-account, so the config follows. pearl-accounts now declares two workspaces, one for work and one personal, each resolving its own API key from authinfo and rendering to its own Org file. pearl-default-account picks which one opens, and pearl-switch-account swaps at runtime. This replaces the old single-account setup (pearl-org-file-path plus one pearl-api-key lookup). The module file moves from linear-config.el to pearl-config.el to match the package name. init.el, the module-headers allowlist, and the module-inventory row follow the rename. --- docs/design/module-inventory.org | 2 +- init.el | 2 +- modules/linear-config.el | 58 ---------------------------------- modules/pearl-config.el | 66 +++++++++++++++++++++++++++++++++++++++ tests/test-init-module-headers.el | 2 +- 5 files changed, 69 insertions(+), 61 deletions(-) delete mode 100644 modules/linear-config.el create mode 100644 modules/pearl-config.el diff --git a/docs/design/module-inventory.org b/docs/design/module-inventory.org index 385bdbd5..2d4baf81 100644 --- a/docs/design/module-inventory.org +++ b/docs/design/module-inventory.org @@ -220,7 +220,7 @@ owns the intentional end-of-startup buffer-bury timer. | Module | Layer | Cat | Current | Target | Runtime requires | Top-level side effects | Direct load | |--------+-------+-----+---------+--------+------------------+------------------------+-------------| -| =linear-config= | 3 | D/P | eager | command | system-lib | package config | yes | +| =pearl-config= | 3 | D/P | eager | command | system-lib | package config | yes | | =local-repository= | 4 | O/D/P | eager | command | elpa-mirror | none | yes | | =lorem-optimum= | 4 | O/L | eager | command | cl-lib | none | yes | | =mail-config= | 3 | D/P | eager | command | user-constants, system-lib, mu4e-attachments, keybindings | cj/email-map under cj/custom-keymap, add-hook, 2 advice, 1 global key | yes | diff --git a/init.el b/init.el index 390de45e..fb6d55af 100644 --- a/init.el +++ b/init.el @@ -73,7 +73,7 @@ (require 'diff-config) ;; diff and merge functionality w/in Emacs (require 'erc-config) ;; seamless IRC client (require 'slack-config) ;; slack client via emacs-slack -(require 'linear-config) ;; Linear.app issue tracking (deepsat workspace) +(require 'pearl-config) ;; Linear.app issue tracking via pearl (deepsat + craigjennings) (require 'telega-config) ;; telegram client via telega.el (TDLib in docker) (require 'signal-config) ;; signal client via forked signel + signal-cli (require 'eshell-config) ;; emacs shell configuration diff --git a/modules/linear-config.el b/modules/linear-config.el deleted file mode 100644 index 8fbae30c..00000000 --- a/modules/linear-config.el +++ /dev/null @@ -1,58 +0,0 @@ -;;; linear-config.el --- Linear.app integration -*- lexical-binding: t; -*- -;; author: Craig Jennings - -;;; Commentary: -;; -;; Layer: 3 (Domain Workflow). -;; Category: D/P. -;; Load shape: deferred (command-loaded). -;; Top-level side effects: package configuration via use-package. -;; Runtime requires: none. -;; Direct test load: no. -;; -;; Near-vanilla pearl setup: close to what pearl's README documents for a -;; first-time install (local checkout instead of a package archive), with two -;; deliberate tweaks layered on after dogfooding the out-of-box experience — a -;; global C-; L prefix (see below) and the shorter assignee @-tag. -;; -;; pearl owns its own keymap. `pearl-mode' turns on automatically in any buffer -;; pearl renders (it carries a `#+LINEAR-SOURCE' header) and binds the whole -;; command surface under `pearl-keymap-prefix' (default "C-; L"). This config -;; also binds that same `pearl-prefix-map' globally under C-; L (`:bind-keymap'), -;; so the full command surface is reachable from any buffer; the first press -;; autoloads pearl. `M-x pearl-menu' / `M-x pearl-list-issues' still work too. -;; -;; Authentication: the Linear personal API key is read from authinfo.gpg. Add: -;; machine api.linear.app login apikey password lin_api_YOURKEYHERE -;; Generate it in Linear: Settings -> Security & access -> Personal API keys. - -;;; Code: - -(use-package pearl - :ensure nil ;; local checkout, not from an archive - :load-path "~/code/pearl" - :commands (pearl-menu pearl-list-issues pearl-create-issue pearl-run-linear-view) - ;; Bind pearl's command map globally under C-; L, so the full surface is - ;; reachable from any buffer (not only inside a pearl-rendered one). The - ;; first press autoloads pearl; it's the same `pearl-prefix-map' that - ;; `pearl-mode' binds in-buffer, so behavior is identical everywhere. - :bind-keymap ("C-; L" . pearl-prefix-map) - :custom - (pearl-org-file-path (expand-file-name "gtd/linear.org" org-directory)) - ;; Shorten the assignee @-tag to the first name only (e.g. @first instead of - ;; @first_last), trading disambiguation for a tighter tag line. - (pearl-assignee-tag-short t) - ;; Optional defaults — uncomment and fill in to skip the prompts. Set them - ;; HERE, at init level, not via M-x pearl-set-default-view / - ;; pearl-set-default-team: those persist through `customize-save-variable', - ;; and this config redirects `custom-file' to a throwaway temp file - ;; (system-defaults.el), so a setter's value is discarded on the next - ;; restart. These :custom lines re-apply on every startup instead. - ;; (pearl-default-view "My active work") ;; the local view `C-; L l' opens - ;; (pearl-default-team-id "9fca2cf6-390c-4102-a9ff-f94a4ed823c5") ;; DeepSat SE; skips the team prompt on create / by-project - :config - (setq pearl-api-key - (auth-source-pick-first-password :host "api.linear.app"))) - -(provide 'linear-config) -;;; linear-config.el ends here diff --git a/modules/pearl-config.el b/modules/pearl-config.el new file mode 100644 index 00000000..b58812ee --- /dev/null +++ b/modules/pearl-config.el @@ -0,0 +1,66 @@ +;;; pearl-config.el --- Linear.app integration via pearl -*- lexical-binding: t; -*- +;; author: Craig Jennings + +;;; Commentary: +;; +;; Layer: 3 (Domain Workflow). +;; Category: D/P. +;; Load shape: deferred (command-loaded). +;; Top-level side effects: package configuration via use-package. +;; Runtime requires: none. +;; Direct test load: no. +;; +;; Near-vanilla pearl setup (local checkout instead of a package archive), in +;; multi-account mode: two Linear workspaces, deepsat (work) and craigjennings +;; (personal), named by Linear's own urlKey. Each account renders to its own +;; Org file, deepsat.pearl.org / craigjennings.pearl.org, so they never collide. +;; `M-x pearl-switch-account' swaps the active one; the mode line shows it. +;; +;; pearl owns its own keymap. `pearl-mode' turns on automatically in any buffer +;; pearl renders (it carries a `#+LINEAR-SOURCE' header) and binds the whole +;; command surface under `pearl-keymap-prefix' (default "C-; L"). This config +;; also binds that same `pearl-prefix-map' globally under C-; L (`:bind-keymap'), +;; so the full command surface is reachable from any buffer; the first press +;; autoloads pearl. `M-x pearl-menu' / `M-x pearl-list-issues' still work too. +;; +;; Authentication: each account reads its key from authinfo.gpg by a distinct +;; login under the api.linear.app host: +;; machine api.linear.app login apikey password lin_api_ +;; machine api.linear.app login pearl-personal password lin_api_ +;; Generate keys in Linear: Settings -> Security & access -> Personal API keys. + +;;; Code: + +(use-package pearl + :ensure nil ;; local checkout, not from an archive + :load-path "~/code/pearl" + :commands (pearl-menu pearl-list-issues pearl-create-issue + pearl-run-linear-view pearl-switch-account) + ;; Bind pearl's command map globally under C-; L, so the full surface is + ;; reachable from any buffer (not only inside a pearl-rendered one). The + ;; first press autoloads pearl; it's the same `pearl-prefix-map' that + ;; `pearl-mode' binds in-buffer, so behavior is identical everywhere. + :bind-keymap ("C-; L" . pearl-prefix-map) + :custom + ;; Shorten the assignee @-tag to the first name only (e.g. @first instead of + ;; @first_last), trading disambiguation for a tighter tag line. + (pearl-assignee-tag-short t) + ;; Two workspaces, keyed by Linear's urlKey. Each resolves its API key from + ;; authinfo.gpg by its own login (see Commentary), renders to its own Org + ;; file, and carries a default team so create / by-project skip the prompt. + (pearl-accounts + '(("deepsat" + :api-key-source (:auth-source :host "api.linear.app" :user "apikey") + :org-file "~/org/gtd/deepsat.pearl.org" + :default-team-id "9fca2cf6-390c-4102-a9ff-f94a4ed823c5") ;; DeepSat SE + ("craigjennings" + :api-key-source (:auth-source :host "api.linear.app" :user "pearl-personal") + :org-file "~/org/gtd/craigjennings.pearl.org" + :default-team-id "ee285e6c-fcc9-4dd6-9292-c47f2df75b82"))) ;; Pearl + ;; Which workspace pearl opens into. Dogfooding the personal account through + ;; Sunday; flip back to "deepsat" to make work primary again (one string), or + ;; switch per-session at runtime with `M-x pearl-switch-account'. + (pearl-default-account "craigjennings")) + +(provide 'pearl-config) +;;; pearl-config.el ends here diff --git a/tests/test-init-module-headers.el b/tests/test-init-module-headers.el index 2680a19c..bbda2388 100644 --- a/tests/test-init-module-headers.el +++ b/tests/test-init-module-headers.el @@ -113,7 +113,7 @@ "jumper" "latex-config" ;; Batch 9 — Remaining domain / integration / optional modules (Layer 2-4) - "linear-config" + "pearl-config" "local-repository" "lorem-optimum" "mail-config" -- cgit v1.2.3