<feed xmlns='http://www.w3.org/2005/Atom'>
<title>pearl, branch main</title>
<subtitle>Pearl Edits and Reflects Linear — manage Linear.app issues as org-mode in Emacs
</subtitle>
<id>https://git.cjennings.net/pearl/atom?h=main</id>
<link rel='self' href='https://git.cjennings.net/pearl/atom?h=main'/>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/pearl/'/>
<updated>2026-07-09T11:44:21+00:00</updated>
<entry>
<title>chore: ignore the generated task archive</title>
<updated>2026-07-09T11:44:21+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-07-09T11:44:21+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/pearl/commit/?id=5e609dcea19b0f776ee887bb41ac10a02194f281'/>
<id>urn:sha1:5e609dcea19b0f776ee887bb41ac10a02194f281</id>
<content type='text'>
</content>
</entry>
<entry>
<title>docs: spec for refining the current source</title>
<updated>2026-06-24T04:08:58+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-06-24T04:08:58+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/pearl/commit/?id=59cd35b9645cbe10a5e51ea6110bf8b2c382a7b6'/>
<id>urn:sha1:59cd35b9645cbe10a5e51ea6110bf8b2c382a7b6</id>
<content type='text'>
A spec for pearl-refine-current-source: mutate the active source via a refinements stack so a narrow sticks across refresh, re-fetch server-side for both filter and view sources, and factor a one-dimension reader out of the builder. Three design questions left open for sign-off before build.
</content>
</entry>
<entry>
<title>feat(sources): single-issue source (favorites + open-issue-by-id)</title>
<updated>2026-06-24T03:40:27+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-06-24T03:40:27+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/pearl/commit/?id=8869a083c3cc28c20efa63e8932347329b2865f4'/>
<id>urn:sha1:8869a083c3cc28c20efa63e8932347329b2865f4</id>
<content type='text'>
I wired the issue kind into the same pipeline every other source uses, so a favorited issue renders in the buffer as its own subtree instead of the v1 browser punt. The new pearl-open-issue-by-id command does the same for an issue you type by identifier or id. It's handy when someone hands you ENG-123 and you'd rather read it in Pearl than a browser.

Linear's issue(id:) accepts both the UUID and the human identifier, so there's no resolution step. I fetch by whatever was given and build the :type issue source from the returned node, so the stored id and identifier stay authoritative. Refresh re-fetches the one issue and merges by LINEAR-ID like the filter and view sources.

Tests cover the source constructor, the header round-trip, and the fetch/render and command paths across Normal, Boundary, and Error.
</content>
</entry>
<entry>
<title>docs(readme): document themeable faces and reflow tables</title>
<updated>2026-06-24T02:36:55+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-06-24T02:36:55+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/pearl/commit/?id=92ae9d8b56a9fabadf6ea8beb2163655c7a8ffb8'/>
<id>urn:sha1:92ae9d8b56a9fabadf6ea8beb2163655c7a8ffb8</id>
<content type='text'>
I added a "Faces and theming" subsection under Configuration: a table of the six pearl faces (where each shows, what it inherits), plus a note that the rest of the rendered surface inherits standard Org faces and isn't separately themeable yet.

I also reflowed the existing tables to a consistent width with per-row rules. Content is unchanged. The pass corrected two stale alignment defects in the Configuration table.
</content>
</entry>
<entry>
<title>fix(views): accept Linear's open filter when copying a view down</title>
<updated>2026-06-17T04:02:13+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-06-17T04:02:13+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/pearl/commit/?id=8061ec3d83fdd9896f84e4d8590eb878277e4949'/>
<id>urn:sha1:8061ec3d83fdd9896f84e4d8590eb878277e4949</id>
<content type='text'>
The copy-down reverse-compiler only treated state.type nin [completed, canceled, duplicate] (Pearl's own :open predicate) as open. Linear's UI authors open as nin [completed, canceled], without duplicate, so copying down any standard open-issues view refused with "state.type uses a nin that isn't Pearl's open predicate" and never reached the save.

A nin now maps to :open when every excluded type is a closed type and the set excludes both completed and canceled. That covers Linear's two-type form and Pearl's three-type form. A nin missing one of the two, or one that also excludes an open type like backlog, still refuses.
</content>
</entry>
<entry>
<title>fix(views): save a local view from any Custom View, not just favorites</title>
<updated>2026-06-16T21:49:08+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-06-16T21:49:08+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/pearl/commit/?id=0ab4afcd1e4e336cb69bd983e498bc441828ed5b'/>
<id>urn:sha1:0ab4afcd1e4e336cb69bd983e498bc441828ed5b</id>
<content type='text'>
pearl-save-linear-view-locally only listed favorited Linear views, while pearl-run-linear-view lists every Custom View in the workspace. A view you could run often wasn't offered to save, so the copy-down silently produced nothing. The command now saves the current buffer's view when one is showing, and otherwise prompts over all Custom Views.

Favorited custom views also came through nameless: the favorites query fetched customView id but not name, and Linear leaves the favorite's title blank for entity favorites. The picker showed a blank entry and the save dead-ended at a blank name. The query now selects customView name and pearl--normalize-favorite falls back to it, which also fixes blank names in pearl-pick-source.

The success message now names the saved view and how to run it or set it as the default.
</content>
</entry>
<entry>
<title>docs(readme): point the save FAQ at pearl-save-issue</title>
<updated>2026-06-16T05:02:22+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-06-16T05:02:22+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/pearl/commit/?id=e723aa663ea62e5ddfda4a7ca360adf9e88d36e2'/>
<id>urn:sha1:e723aa663ea62e5ddfda4a7ca360adf9e88d36e2</id>
<content type='text'>
The first FAQ entry still told users to push titles and descriptions through separate sync commands, which contradicts the unified save model. It now describes `pearl-save-issue` / `pearl-save-all` saving every changed field in one pass, with the lower-level sync commands kept as the footnote.
</content>
</entry>
<entry>
<title>chore(scripts): warn when apikey.txt is group/other-readable</title>
<updated>2026-06-16T05:00:45+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-06-16T05:00:45+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/pearl/commit/?id=41dd030cd6414f0acf60a32dcc4de415966601d0'/>
<id>urn:sha1:41dd030cd6414f0acf60a32dcc4de415966601d0</id>
<content type='text'>
The seed script reads the Linear key from the environment, but the README sources it from a gitignored `apikey.txt` that was landing at mode 644. `main` now warns on startup when that file is group- or other-accessible, so a loose key file gets flagged instead of sitting silently exposed. The warning points at `chmod 600`.
</content>
</entry>
<entry>
<title>fix(api): clear auth-source's negative cache on pearl-clear-cache</title>
<updated>2026-06-16T04:57:14+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-06-16T04:57:14+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/pearl/commit/?id=546bcf9bbe651eaaa0129346536c9e7e98748555'/>
<id>urn:sha1:546bcf9bbe651eaaa0129346536c9e7e98748555</id>
<content type='text'>
A key added to authinfo read as missing for up to 2h because auth-source caches the negative lookup and `pearl-clear-cache` only cleared pearl's own caches. It now also calls `auth-source-forget-all-cached`, and the auth-source miss tells the user to run `M-x pearl-clear-cache`. This is the 2026-06-01 live incident, where a freshly-synced Linear key kept erroring as unset.
</content>
</entry>
<entry>
<title>fix(api): signal missing-key as user-error with mode-aware advice</title>
<updated>2026-06-16T04:53:57+00:00</updated>
<author>
<name>Craig Jennings</name>
<email>c@cjennings.net</email>
</author>
<published>2026-06-16T04:53:57+00:00</published>
<link rel='alternate' type='text/html' href='https://git.cjennings.net/pearl/commit/?id=e749badfd974de42fe8d7cdbe2bfa4fa3e0771b2'/>
<id>urn:sha1:e749badfd974de42fe8d7cdbe2bfa4fa3e0771b2</id>
<content type='text'>
A missing API key raised a raw `error`, so it backtraced under `debug-on-error`, and the stale advice pointed at customizing `pearl-api-key`. Now `pearl--headers` signals a `user-error` and branches the advice by mode: accounts mode points at `pearl-accounts` and `pearl-switch-account`, legacy mode at `pearl-api-key` and `pearl-load-api-key-from-env`. The credential-source resolver's three failure paths become `user-error` too, since a bad credential is a config problem, not a bug.
</content>
</entry>
</feed>
