aboutsummaryrefslogtreecommitdiff
Commit message (Collapse)AuthorAgeFilesLines
* fix(calendar-sync): re-derive status from a declined occurrence overrideCraig Jennings14 hours2-1/+46
| | | | A recurring event declined for one occurrence still synced with :STATUS: accepted, because apply-single-exception merged the override attendees but never re-derived the user's status from them, so filter-declined never dropped it. Re-derive :status via find-user-status when the exception overrides :attendees, leaving the inherited status when the override doesn't name the user. Four new tests cover declined, accepted, no-attendee, and user-absent overrides.
* chore(todo): file calendar-sync declined-occurrence bug (from chime handoff)Craig Jennings15 hours1-0/+2
|
* fix(dirvish): point the bg wallpaper command at set-wallpaper on WaylandCraig Jennings15 hours2-6/+7
| | | | The Wayland branch of cj/--wallpaper-program-for returned swww, but this system's wallpaper daemon is awww, so dirvish "bg" silently no-opped. Point it at the set-wallpaper script (on PATH via dotfiles), which wraps awww img and persists the choice to waypaper's config. X11 still uses feh. Updated the wallpaper-program test to match.
* docs(spec): google-keep in-editor integration spec (draft, 5 open decisions)Craig Jennings15 hours2-1/+155
|
* chore(todo): close converter/face-list/tier-2 items, reframe google-keep as ↵Craig Jennings16 hours1-8/+8
| | | | build-it-here
* feat(ledger): un-orphan ledger-config and rewrite clean-on-saveCraig Jennings16 hours2-14/+27
| | | | ledger-config.el was never required in init.el, so the whole module was dead code. I added the require (which installs ledger-mode, flycheck-ledger, and company-ledger via the global ensure) and rewrote the clean-on-save: instead of rebinding C-x C-s to a clean-then-save command, a buffer-local before-save-hook tidies the buffer on every save path, gated by cj/ledger-clean-on-save. The reports shell out to the ledger CLI, so a load-time check now warns when it isn't on PATH. Added ledger-highlight-xact-under-point.
* chore(todo): inbox-zero — file 5 emacs roam items as tasksCraig Jennings19 hours1-0/+10
|
* chore(todo): log controls.js extraction (tier 2)Craig Jennings19 hours1-1/+3
|
* refactor(theme-studio): extract control factories to controls.js, drop dead ↵Craig Jennings19 hours6-234/+221
| | | | | | | | previewFaceAttrs I split the custom dropdown, detail-editor, and expander factories out of app.js into controls.js (205 lines), spliced back at a CONTROLS_J token by generate.py. The token sits at the exact extraction point, so the assembled page is byte-identical and every gate passes unchanged. app.js drops from 927 to 721 lines. I also removed previewFaceAttrs (function, export, and test). It was test-only dead code whose docstring stalely claimed the gate calls it. The gate uses assertPreviewFaces instead.
* chore(todo): log theme-studio tier-1 simplification completionCraig Jennings20 hours1-0/+4
|
* refactor(theme-studio): tier-1 simplification passCraig Jennings20 hours8-82/+81
| | | | | | | | These are behavior-preserving cleanups from the refactor/simplify assessment, all test-verified. I merged syncMockHeight and syncPkgHeight into one syncPaneHeight(tableId, paneId), inlined the two single-use displayHex/displayName closures, dropped a pkgbody guard that buildPkgTable already does, and had paintUI call worstCellHtml instead of rebuilding the covered-contrast cell. I deleted the dead generatorHues "manual" branch (a copy of the fallback) and locateInfoLine (orphaned when I removed the preview info line earlier today). The two nerd-icons loaders now share _load_nerd_icons_artifact, with a sentinel so a null-file edge keeps its exact behavior. face_coverage.classify reads through named locals now, guarded by a new characterization test. Two assessment findings were wrong and skipped after I checked them against the code: LOCATE_REG is live (read by previewSpan), and normalizePaletteEntryCore doesn't exist.
* fix(theme-studio): gold nav arrows for the language and preview dropdownsCraig Jennings21 hours2-4/+10
| | | | The gold viewnav style was scoped to .pkgbar, so the arrows on the .langbar selectors (language and preview) fell back to default gray. I broadened the rule to .langbar and added a dimmed-gold disabled state for the single-pane preview.
* style(theme-studio): unify nav dropdowns to gold-on-darkCraig Jennings21 hours3-6/+12
| | | | The view, language, and preview selects share a navsel class matching their flanking arrow buttons (dark bg, gold bold-mono text), so each select and its arrows read as one control.
* feat(theme-studio): visible size-nav buttons + 48 pt gallery scaleCraig Jennings21 hours5-53/+83
| | | | | | | | | | The preview dropdown gets flanking nav buttons, matching the view selector, so the size steps with a click. Left/Right arrows do the same when the dropdown is focused. Both clamp at the ends and disable on a single-pane app. I extended the size scale to 32 and 48 pt for inspecting a glyph's detail. The cell width scales with the size, so beyond about 48 pt the grid is mostly scrolling. I removed the separate hover info line beside the dropdown. Each glyph's own title tooltip already shows its face and color, so the line was redundant. A new computed-style gate confirms the point size renders to the right pixels (24 pt is 32 px), so the pt label isn't lying.
* chore(todo): reorganize the Emacs task listCraig Jennings22 hours1-847/+884
|
* chore: refresh synced agent rules and hooksCraig Jennings22 hours8-9/+116
|
* chore(theme-studio): update WIP theme snapshotCraig Jennings22 hours2-107/+141
|
* feat(theme-studio): nerd-icons gallery as a hue-ordered icon gridCraig Jennings22 hours13-187/+2366
| | | | | | | | | | The nerd-icons pane is now a grid: one row per color face, the rows ordered by hue so families cluster, distinct icons (deduped within a color) drawn in their color with the icon's nerd-font name beneath. A "preview:" dropdown above the grid picks the glyph size in points, with Left/Right arrows to step it. Single-pane apps show it disabled, naming the preview. This replaces the v1 legend in the pane, whose data is still captured for round-trip. build-nerd-icons-legend.el is now a library. A cj/nerd-icons-write-legend entry point requires nerd-icons only at write time, so the capture logic loads and unit-tests without it. It dedupes icons by name within a face, computes each face's native hue, and orders the groups by hue. Writing the test surfaced a latent bug: face-hsl used (cadr (assoc t spec)), which grabs the first keyword instead of the plist. It only worked because the real faces fall through to the face-foreground branch. I fixed it to a correct t-clause parse. Coverage: 7 ERT capture tests (dedupe, hue order, lightness tiebreak, name sort, skip rules), 4 Python validator edges, and browser gates for the grid and the size dropdown. Locate stays color-level: clicking a color flashes its icons, and clicking an icon flashes its color row. Icons aren't individually editable, so there's nothing per-icon to select.
* fix(theme-studio): render nerd-icon glyphs in previews instead of tofuCraig Jennings24 hours7-12/+151
| | | | | | | | The legend, dashboard, and package previews drew nerd-icon glyphs as empty boxes. The font-family never reached them: PREVIEW_FONT was spliced into inline style="..." attributes with a double-quoted family name, so the inner quote closed the attribute early and the font was silently dropped. Dropping the quotes fixes it. A no-space family name needs none. I embedded the glyph font directly: Symbols Nerd Font Mono, encoded with fontTools (woff2_compress output is rejected by headed Chrome and Firefox), inlined as a data: URI under the unique family name ThemeStudioNerd so it resolves to the embed rather than a system-installed copy of the same name. The page is self-contained and renders on any clone. I added a #fonttest gate that parses previewLines output and asserts the resolved font-family plus glyph coverage, plus a make font target that re-encodes the woff2 with fontTools.
* chore(todo): wrap-up cleanup — archive resolved tasks, sync child prioritiesCraig Jennings28 hours1-199/+189
| | | | | | Move completed level-2 tasks (latexmk, theme-studio preview-split, tramp dates) into Resolved, and bump two AI-Open-Work child cookies to match their parent. Claude-Session: https://claude.ai/code/session_01BqrdWUo9GcznYX2pZr76gZ
* chore(elisp): clear byte-compile warnings (18 more modules)Craig Jennings28 hours18-23/+102
| | | | | | Add declare-function/defvar declarations for lazily-loaded package symbols, reflow over-long docstrings, swap pdf-view-*-command interactive-only calls for their non-interactive twins, fix a malformed with-demoted-errors in ledger-config (the clean-buffer body was being read as the format string), and rename the unprefixed global wwwdir to cj/httpd-wwwdir (no external refs). No behavior change. Claude-Session: https://claude.ai/code/session_01BqrdWUo9GcznYX2pZr76gZ
* chore(elisp): clear byte-compile warnings (calibredb, config-utilities, ↵Craig Jennings28 hours6-2/+53
| | | | | | | | tramp, diff, chrono, auth) Add declare-function/defvar declarations for lazily-loaded package functions and variables so each module compiles cleanly standalone; config-utilities wraps two lazy EmacSQL oref slot reads in with-no-warnings. No behavior change. Claude-Session: https://claude.ai/code/session_01BqrdWUo9GcznYX2pZr76gZ
* chore(elisp): clear byte-compile warnings (org, music, org-roam)Craig Jennings28 hours4-152/+283
| | | | | | Move own-command bindings out of use-package :bind to keymap-global-set / with-eval-after-load (C-c C-a org-appear-toggle, R music radio-station, C-c n r/t roam recipe/topic) — same keys, verified live. Pull music-config helper defuns out of :config/with-eval-after-load to top level (their proper home; emms referenced only at call time via declare-function). Swap obsolete org-show-all for org-fold-show-all (9.6). Plus declare-function/defvar for lazy symbols. No behavior change; full suite + launch smoke green. Claude-Session: https://claude.ai/code/session_01BqrdWUo9GcznYX2pZr76gZ
* chore(elisp): clear byte-compile warnings (elfeed, markdown, prog-general)Craig Jennings28 hours3-13/+45
| | | | | | The use-package :bind autoload stubs for own same-file commands collided with their defuns ("defined multiple times"). Move those bindings out of :bind to keymap-global-set / with-eval-after-load after the defun — same key, command, and map, verified live in the daemon. prog-general's case was instead a redundant same-file declare-function (removed). Plus declare-function/defvar for lazy package symbols, and mark-whole-buffer swapped for goto-char+push-mark in the elfeed tag helpers. No behavior change. Claude-Session: https://claude.ai/code/session_01BqrdWUo9GcznYX2pZr76gZ
* chore(elisp): clear byte-compile warnings (org-noter, calendar-sync, vc, ↵Craig Jennings29 hours5-24/+133
| | | | | | | | dirvish, org-contacts) Add declare-function/defvar declarations for lazily-loaded package symbols and reflow over-long docstrings so these modules compile cleanly standalone. org-contacts keeps the diary special vars (date/entry/original-date) declared function-locally rather than file-wide, so the lexical `entry` parameter is unaffected. No behavior change. Claude-Session: https://claude.ai/code/session_01BqrdWUo9GcznYX2pZr76gZ
* chore(elisp): clear byte-compile warnings (mail, dashboard, eshell, erc)Craig Jennings29 hours5-29/+175
| | | | | | Add declare-function/defvar declarations for lazily-loaded package functions and variables so each module compiles cleanly standalone, reflow over-long docstrings, and swap the obsolete erc-server-buffer-p for its named replacement erc-server-or-unjoined-channel-buffer-p (obsolete since 30.1). No behavior change. Two erc setq targets (erc-unique-buffers, erc-generate-buffer-name-function) appear not to be real ERC variables — declared to silence the warning with a NOTE flagging that the intended buffer-naming may not be taking effect. Claude-Session: https://claude.ai/code/session_01BqrdWUo9GcznYX2pZr76gZ
* style(elisp): clear defcustom-group and dead-local byte-compile warningsCraig Jennings31 hours3-5/+15
| | | | | | Add :type and a containing :group to the three localrepo defcustoms (new localrepo defgroup) and to cj/org-agenda-window-height. Drop the unused `initial` local in the org-contacts completion-at-point function. Claude-Session: https://claude.ai/code/session_01BqrdWUo9GcznYX2pZr76gZ
* fix(elisp): make dead let-bindings of foreign special vars take effectCraig Jennings31 hours2-0/+11
| | | | | | Byte-compile flagged three let-bindings of package vars as unused lexical variables — under lexical-binding they compiled to dead locals the package never saw, so the intended behavior silently never happened. Declare each var special so the binding is dynamic: music-config now actually suppresses the emms overwrite prompt on playlist save (emms-source-playlist-ask-before-overwrite) and turns off orderless smart-case for the music picker; org-roam copy-todo-to-today now actually applies its custom dailies capture template. Same class as the coverage-core json fix. Claude-Session: https://claude.ai/code/session_01BqrdWUo9GcznYX2pZr76gZ
* chore(theme-studio): commit WIP theme locked-face reorderingCraig Jennings31 hours1-223/+229
| | | | Claude-Session: https://claude.ai/code/session_01BqrdWUo9GcznYX2pZr76gZ
* refactor(org-refile): drop roam Project notes as refile targetsCraig Jennings31 hours2-11/+11
| | | | | | Stop scanning org-roam notes tagged "Project" for refile targets; keep the "Topic" scan. Behavior change by decision: roam Projects are no longer pulled in anywhere (the agenda never scanned them either — that was a stale doc claim, corrected separately). Refiling into Topic notes and into per-project todo.org files is unchanged. Test reworked to assert Topic is included and Project is not. Claude-Session: https://claude.ai/code/session_01BqrdWUo9GcznYX2pZr76gZ
* chore(todo): close agenda-sources bug (docs fix + existence filtering)Craig Jennings31 hours1-2/+3
| | | | Claude-Session: https://claude.ai/code/session_01BqrdWUo9GcznYX2pZr76gZ
* fix(org-agenda): filter missing base files; drop the roam-source doc claimCraig Jennings31 hours2-29/+62
| | | | | | cj/--org-agenda-base-files now drops files that do not exist (a fresh machine may lack the synced calendars or the inbox), and org-agenda-skip-unavailable-files is set as a backstop, so org-agenda never prompts to create a missing path — the interactive-prompt class that once hung the chime daemon. The filter lives in the one shared helper, so the agenda builders, single-project view, and the chime initializer all get the existence check. Also correct the docs: the commentary and docstrings claimed org-roam nodes tagged "Project" are agenda sources, but they were never scanned; roam Project/Topic notes are refile targets (org-refile-config.el), not agenda sources. Claude-Session: https://claude.ai/code/session_01BqrdWUo9GcznYX2pZr76gZ
* chore(todo): close ai-term wrap-teardown task, file end-to-end VERIFYCraig Jennings31 hours1-1/+18
| | | | | | Close the task with the three functions shipped and unit-verified, and file the tmux/shutdown side effects and both-sides workflow run as a VERIFY under Manual testing and validation. Claude-Session: https://claude.ai/code/session_01BqrdWUo9GcznYX2pZr76gZ
* feat(ai-term): wrap-teardown + shutdown entry points for rulesetsCraig Jennings31 hours4-0/+287
| | | | | | Add the three headless functions the rulesets wrap-it-up workflow calls via emacsclient -e, since this module owns the aiv- session naming, the agent buffer, and the geometry restore. cj/ai-term-quit kills a project's tmux session and agent buffer and restores the layout, idempotent and safe when already gone. cj/ai-term-live-count returns the integer count of live aiv- sessions for the shutdown safety gate. cj/ai-term-shutdown-countdown re-checks that gate, then runs an abort-able run-at-time countdown in the echo area and, uncancelled, runs the shutdown command (a defcustom so tests stub it). Reuses the existing kill/close helpers. 13 ERT tests cover the live-count parsing, the quit kill-and-idempotency, and the gate-abort/cancel/tick logic; the tmux and shutdown side effects are manual. Claude-Session: https://claude.ai/code/session_01BqrdWUo9GcznYX2pZr76gZ
* chore(todo): close README holistic-pass taskCraig Jennings32 hours1-2/+3
| | | | Claude-Session: https://claude.ai/code/session_01BqrdWUo9GcznYX2pZr76gZ
* docs: holistic README pass — version floor, layout, features, targetsCraig Jennings32 hours1-3/+15
| | | | | | Bump the Emacs floor to 30 (developed on 30.2). Fix the module count (~100 to ~120), add docs/ to the layout, and reword scripts/ now that it also holds theme-studio. Add Theme Studio, the ghostel native terminal, and ai-term to Features, and make coverage-summary to the dev targets. Claude-Session: https://claude.ai/code/session_01BqrdWUo9GcznYX2pZr76gZ
* chore(todo): file README holistic-pass task from roam inboxCraig Jennings32 hours1-0/+2
| | | | Claude-Session: https://claude.ai/code/session_01BqrdWUo9GcznYX2pZr76gZ
* chore(todo): close the nerd-icons colors PROJECT (phases 1-4 shipped)Craig Jennings32 hours1-21/+25
| | | | | | Mark the nerd-icons colors PROJECT DONE with its four phases as dated event-log entries, promote the vNext follow-ups to a standalone [#D] task, and file the live-visual check as a VERIFY under Manual testing and validation. Claude-Session: https://claude.ai/code/session_01BqrdWUo9GcznYX2pZr76gZ
* test(nerd-icons): dir-precedence probe + legend round-trip (phase 4)Craig Jennings32 hours3-0/+33
| | | | | | Lock the dir-precedence decision with an ERT probe: when a dir icon already carries nerd-icons-completion-dir-face, the advice's prepended nerd-icons-yellow is first in the face list and wins. Extend the #nerdiconstest browser gate with an export/import round-trip over an assigned nerd-icons color, asserting it re-imports to the same state and that the separate nerd-icons-completion dir-face stays out of the nerd-icons app. Claude-Session: https://claude.ai/code/session_01BqrdWUo9GcznYX2pZr76gZ
* feat(nerd-icons): drop the runtime tint so the theme drives icon color (phase 3)Craig Jennings32 hours2-102/+7
| | | | | | Remove cj/nerd-icons-tint-color, cj/--nerd-icons-color-faces, cj/nerd-icons-apply-tint and its two call sites, so the 34 nerd-icons color faces are no longer force-set to one darkgoldenrod foreground at load time. The WIP theme already owns those faces (theme-studio auto-discovered them), so with the tint gone their per-filetype colors come from the theme and are editable in theme-studio's new nerd-icons pane. The dir-icon advice (cj/--nerd-icons-color-dir) stays — it points at a theme-owned face now. Delete the apply-tint test, which covered removed code. Claude-Session: https://claude.ai/code/session_01BqrdWUo9GcznYX2pZr76gZ
* feat(theme-studio): bespoke nerd-icons filetype-legend preview (phase 2)Craig Jennings32 hours7-5/+127
| | | | | | Register nerd-icons as a bespoke app whenever its captured legend is valid: the 34 color faces stay editable rows, and the legend rides APPS['nerd-icons'].legend. A new renderNerdIconsPreview draws each curated filetype's glyph in its mapped face's effective color, read through the same registry the other previews use, so recoloring a face repaints every row mapped to it. When the legend is absent the generic inventory app stands in. The #nerdiconstest browser gate covers the wiring, the dir-row owner, and the recolor-repaint. Claude-Session: https://claude.ai/code/session_01BqrdWUo9GcznYX2pZr76gZ
* feat(theme-studio): capture the nerd-icons filetype legend (phase 1)Craig Jennings33 hours4-0/+266
| | | | | | Add build-nerd-icons-legend.el, which resolves the curated v1 legend rows (glyph + owner color face per filetype) from the live nerd-icons alists and dumps them to nerd-icons-legend.json, a committed artifact like package-inventory.json. generate.py gains load_nerd_icons_legend, which validates the artifact and returns None — with a warning — when it is absent, malformed, empty, or missing a field, so the page can fall back to the generic nerd-icons app rather than error. Data only; the bespoke preview that renders it lands next. Claude-Session: https://claude.ai/code/session_01BqrdWUo9GcznYX2pZr76gZ
* chore(todo): break nerd-icons colors spec into Phase 1-4 tasksCraig Jennings33 hours1-3/+13
| | | | | | Ready confirmed; run the spec-response Phase 6 breakdown. Convert the spec task to a PROJECT and file the four implementation phases (legend capture, bespoke preview, atomic theme-assignment + tint removal, verification) as solo children. Claude-Session: https://claude.ai/code/session_01BqrdWUo9GcznYX2pZr76gZ
* chore(todo): close stale mu4e trash/refile task, file its live VERIFYCraig Jennings33 hours1-1/+9
| | | | | | The mu4e cmail trash-folder + per-message refile fix shipped 2026-06-13 but the task stayed DOING; close it DONE and file the live-mail check as a VERIFY under Manual testing and validation. Claude-Session: https://claude.ai/code/session_01BqrdWUo9GcznYX2pZr76gZ
* chore(todo): reopen face-button and latexmk VERIFYsCraig Jennings38 hours1-4/+11
| | | | | | Only the copy-mode scroll check was confirmed; restore the face-name button and latexmk manual VERIFYs to pending. Claude-Session: https://claude.ai/code/session_01BqrdWUo9GcznYX2pZr76gZ
* chore(todo): close the three verified manual checks from this sessionCraig Jennings38 hours1-18/+6
| | | | | | Craig confirmed the copy-mode scroll, face-name buttons, and latexmk compile all work in a live frame; rewrite each VERIFY to a dated event-log entry. Claude-Session: https://claude.ai/code/session_01BqrdWUo9GcznYX2pZr76gZ
* chore(todo): close C-arrow copy-mode bug, restore ai-term headingCraig Jennings38 hours1-7/+10
| | | | | | Close the copy-mode regression task with its resolution, and restore the ai-term wrap-teardown heading that was dropped when the bug task was filed. Update the copy-mode manual VERIFY for the C-<up>-only behavior. Claude-Session: https://claude.ai/code/session_01BqrdWUo9GcznYX2pZr76gZ
* fix(term): scope copy-mode to C-<up> and don't re-enter mid-copyCraig Jennings38 hours2-134/+121
| | | | | | Today's modified-arrow work bound every C-arrow and M-arrow to copy-mode, which swallowed C-<left>/C-<right> — readline word-motion at the shell prompt. Bind only C-<up> (enter copy-mode and scroll up); the other arrows pass through to the terminal again. C-<up> pressed while already in copy-mode now just moves up: cj/term-copy-mode-up checks tmux pane_in_mode (and ghostel--input-mode without tmux) and skips re-entry, which would otherwise reset the cursor to the start of the line. Claude-Session: https://claude.ai/code/session_01BqrdWUo9GcznYX2pZr76gZ
* chore(todo): file C-arrow copy-mode regression from roam inboxCraig Jennings38 hours1-1/+2
| | | | Claude-Session: https://claude.ai/code/session_01BqrdWUo9GcznYX2pZr76gZ
* docs: codify the lexical-binding foreign-special-var compile trapCraig Jennings38 hours1-0/+2
| | | | | | Record the coverage-core failure: let-binding json.el's reader vars in a lexical-binding file without a compile-time defvar makes the compiled code bind them lexically, so they never reach json-read-file. Same compiled-vs-interpreted class as the existing make-test and native-comp insights. Claude-Session: https://claude.ai/code/session_01BqrdWUo9GcznYX2pZr76gZ