| Commit message (Collapse) | Author | Age | Files | Lines |
| | |
|
| | |
|
| | |
|
| | |
|
| |
|
|
| |
The seeding engine turns the color guide's seed table into executable defaults: a role-to-treatment table, a face-to-role map per tier (syntax, UI, org), and a pure seed() that opens the tool guide-correct and reseeds dupre-revised to the compact mapping. v1 generates the shades with OKLCH, reusing the perceptual-metrics colormath.js core, so it sequences after that feature's Phase 1. todo.org carries the two implementation phases.
|
| | |
|
| |
|
|
| |
The spec adds OKLCH editing, perceptual-lightness and APCA readouts, and a pairwise ΔE distinguishability check to the theme-studio, so it can build deliberately low-contrast themes by metric instead of by eye. The testing strategy extracts the color math into a Node-unit-tested colormath.js core, with the browser hash tests reduced to UI wiring and coverage measured on that core. todo.org carries the five implementation phases and the manual-validation checklist.
|
| | |
|
| |
|
|
| |
F8 is bound globally to cj/main-agenda-display, but ghostel's semi-char mode forwarded it to the terminal program, so it did nothing inside a ghostel buffer. I added F8 to ghostel-keymap-exceptions and rebuilt the semi-char map, which lets it fall through to the global map, the path F10 and the F9 family already take.
|
| |
|
|
| |
The tool authors themes from scratch -- palette, faces across every tier, live preview, export to a loadable deftheme. It never selects among existing themes, so "selector" mis-described it. Renamed the directory, the generated HTML and its title, the design spec, and every reference in the code, README, tests, and todo. No behavior change.
|
| | |
|
| |
|
|
| |
These three no longer fall to the generic face-name list. ghostel renders a mock terminal covering all 19 faces (the 16 ANSI colors, default, and the fake cursor). mu4e renders a headers list, message view, and compose stub covering all 37 of the faces the dupre theme themes; mu4e is absent from the generated inventory, so its face list is curated. dashboard covers all 8. Every face has a real preview element, so the click-to-flash linking works both directions with no fallback.
|
| |
|
|
| |
Clicking a face row now flashes that face in the live-buffer and package previews, and clicking an element in either preview flashes its table row. The syntax tier already did this. UI faces had only preview-to-row, and package faces had neither. The package preview spans and table rows now carry data-face, reusing the same delegated-click handler the mock frame uses. When a face isn't shown in a bespoke preview, the row falls back to flashing its own cell. A fuller org preview that gives every org row a real target is filed as a separate task.
|
| |
|
|
|
|
|
|
|
|
| |
build-theme.el is the last link in the theme-selector pipeline: a theme.json export becomes a single self-contained themes/<name>-theme.el. All four tiers convert: default from assignments.bg/.p, the syntax categories to their font-lock/tree-sitter faces with the bold/italic sets applied, UI passthrough, and package faces with :inherit/:height/weight/slant.
The output is a flat generated deftheme, not the palette/faces/theme trio the hand-authored dupre ships. A theme.json carries resolved per-face hex, not dupre's semantic-mapping layer, so a flat deftheme is the faithful output and never clobbers the curated dupre files.
I omitted the dec (decorator) key: Emacs has no dedicated decorator face and renders decorators with font-lock-type-face, which the type key already owns, so coloring dec independently would clobber types. Decorators follow the type color, as they do in stock Emacs.
20 ERT tests cover the attribute builder, each tier, the dec omission, and an end-to-end convert-and-load with a WCAG-AA assertion on the round-tripped default.
|
| |
|
|
| |
The last link in the tier-3 pipeline, with pointers to the theme.json contract, the existing dupre theme files, and the Elisp/testing conventions so a fresh session can start from the task alone.
|
| |
|
|
|
|
| |
I extended the hash-guarded self-test harness to assert the tier-3 acceptance criteria against the real emitted code, run in headless Chrome: old-JSON import with no packages key, the full package round-trip (fg, bg, bold, italic, inherit, height, source), cleared-state export, unknown-package preservation, and inheritance-cycle termination. All pass. The two DOM-coupled regressions are handled structurally rather than in the harness: updateColor remaps PKGMAP when a palette color is edited, and PKGMAP stores hexes so a deleted palette color leaves package references in the recoverable "(gone)" state.
This closes the tier-3 package-faces milestone: all seven phases plus the test surface have landed.
|
| |
|
|
| |
I rewrote the README to cover what the tool actually is now: the three face tiers (syntax, UI, package) plus the palette, the in-page color picker with its AA/AAA legibility mask, the package-faces section with bespoke org/magit/elfeed previews and the generic fallback, modeled inheritance and relative height (with the note that the font family stays in font-config.el), the theme.json packages schema with inherit/height/source, export-versus-save, and the inventory-refresh command with its loaded-config dependency. It also documents that theme-selector.html is generated.
|
| |
|
|
|
|
| |
I added the hybrid inventory. build-inventory.el, loaded into a running Emacs, queries every installed package's faces grouped by the package that defines them and writes package-inventory.json. generate.py embeds that file and merges each package into the app dropdown as an editable generic app, leaving the bespoke org, magit, and elfeed untouched.
The dropdown now reaches 40 apps: the three bespoke plus 37 inventory packages (643 faces), so any installed package can be themed against the palette with the generic preview. The inventory is a committed data artifact refreshed by reloading the .el, never browser-side discovery, matching the spec's hybrid-and-split decision.
|
| |
|
|
| |
I added renderMagitPreview and renderElfeedPreview. The magit one is a status buffer: head and branch lines, an untracked section, a diff hunk with context, removed, and added lines, and recent commits with hashes, authors, and a keyword and tag. The elfeed one is a search list: the filter line, dated entries with feed, unread and read titles, and tags, plus log lines colored by level. The preview pane dispatches to each app's bespoke renderer, the generic fallback covers everything else, and the pane label now names the app and says whether the preview is bespoke or generic.
|
| |
|
|
| |
I added renderOrgPreview, a mock org document painted live from the org package faces. It exercises the prominent ones in context: document title, headings with their heights, a TODO and a DONE, tags, a scheduled timestamp, a property drawer, inline code and verbatim, a link, a checkbox, a quote, a src block with begin and end lines, and a header-row table. The preview pane now dispatches on the app's preview key, so org-mode gets this bespoke document and every other app keeps the generic face-name list until its own preview lands. It rebuilds on any package-face or palette edit.
|
| |
|
|
|
|
| |
I added the package faces section: an application selector for org-mode, magit, and elfeed, and a face table for the chosen app with a foreground and background dropdown, bold and italic toggles, an inherit dropdown (base faces plus the app's own faces), a relative-height stepper, a live contrast readout on the effective inherit-resolved color, and a per-face reset, plus a per-app reset and a text filter for the large sets.
The right pane shows a generic preview, each face name in its own resolved colors, which the bespoke org/magit/elfeed previews replace in the next phases. The fg/bg dropdown is now a shared colorDropdown helper that the ui-faces table also uses, so there's no forked control. Palette edits propagate to package faces, and import and export carry them through.
|
| |
|
|
|
|
| |
I filled the APPS registry with the complete own-defface sets: 88 org faces including org-agenda, 98 magit, and 13 elfeed, built from embedded face-name lists plus a curated seed-color map. Prominent faces are seeded with palette colors, heading heights, and the fixed-pitch inherits that keep code and tables monospace under variable-pitch prose. The long tail seeds to the default foreground for the user to tune.
Org headings carry their heights, agenda dates and deadlines are colored by role, and magit's diff, branch, and section faces map to the palette's greens, reds, and blues. No UI yet. That's phase 3, and the schema self-test still passes while seeding all 199 faces.
|
| |
|
|
|
|
| |
I folded a relative height field into the tier-3 spec and brought Phase 1's schema in line. A face's height is a float multiplier off the base font (1.3 is 1.3x the running font, never a point size), so it stays portable across fonts and machines, and it's omitted from export at 1.0. The font family itself stays in font-config.el, where it belongs; the theme owns only relative size.
Height is read straight off the face and does not cascade through inherit, because Emacs multiplies float heights along an inherit chain and headings should each size off the body, not compound off the level above. The org starter now seeds heading heights and the fixed-pitch inherits that keep code and tables monospace under variable-pitch prose. The self-test gained a height assertion and still reports PASS.
|
| |
|
|
|
|
| |
I laid the tier-3 foundation: an APPS registry (org starter for now) and a PKGMAP holding {fg,bg,bold,italic,inherit,source} per face. Pure helpers seed PKGMAP from APPS defaults, build the export per the state policy, and merge an import back in. Export gains a packages key when any package face is present, and import reads it while old JSON with no packages key still loads cleanly onto the seeded defaults. No UI yet — that's phase 3.
A #selftest harness, guarded by the URL hash so it never shows in normal use, runs seed to export to import and checks the round-trip, old-JSON merge, and inherit/source survival. Headless Chrome reports PASS, which is how I verified the schema end-to-end against the real emitted code rather than a copy.
|
| |
|
|
|
|
| |
Craig resolved the last two opens: hybrid-and-split inventory (org/magit/elfeed bespoke first, the generated all-package inventory as a later phase) and the custom color picker built after tier 3. With inheritance already settled, the rubric moves to Ready.
I emitted the phase breakdown into todo.org under Emacs Open Work: one task per implementation phase plus a test-surface task, all marked solo since each builds and self-verifies through node, headless screenshots, and import/export round-trips. A Manual testing task collects the two human judgments that aren't solo: whether the seeded package defaults look right and whether the large org and magit tables stay usable.
|
| |
|
|
| |
A plan for a contrast-first AAA sibling of the dupre theme. It keeps dupre's hues but builds them Prot's way, with contrast as the founding constraint, where the in-progress dupre revision is mood-first and lands at AA. The spec records the modus methodology analysis, the AA-to-AAA starting palette, the hard blue-keyword decision, and enough context to resume cold months from now. The task in Emacs Open Work links to it.
|
| |
|
|
| |
A full make test run is green except four tests in test-dupre-theme.el. Logged with the two root causes (a stale #151311 background assertion across three tests, and an org-todo color mismatch) so the red baseline is tracked instead of tolerated.
|
| |
|
|
| |
dupre's diff-refine-changed is bright gold under near-white text (WCAG ~1.35), unreadable as a plain background. Filed with the side-by-side comparison render from the pearl session that surfaced it.
|
| |
|
|
| |
Reorder the Emacs Open Work section: Calibre pulled to the top, the message-client and localrepo tasks regrouped. Stamp 7 task-review tasks with today's date and regrade the dashboard-keybinding task to B. Mark the M-F9 close-removes-split bug DONE now that the fix shipped in 1a097b7e.
|
| |
|
|
| |
Created a Calibre parent grouping the bookmark-title, keybindings, and metadata-embed children. Relocated the project-aware capture and Calibre-keybindings items out of the global capture inbox. Added tasks for project-aware capture, the "? = curated help menu" convention survey, and embedding Calibre's DB metadata into the book files. Flipped the in-progress tasks to DOING and added manual-verify checklist items for the shipped features.
|
| | |
|
| |
|
|
|
|
|
|
| |
The C-; M Signal prefix didn't take effect on a fresh Emacs launch. signal-config.el was the only feature module that bound into cj/custom-keymap directly, wrapped in (with-eval-after-load 'keybindings (when (boundp 'cj/custom-keymap) ...)). The boundp guard turned a load-order miss into a silent no-op, so the binding never landed at startup. A later live-reload always papered over it because keybindings was loaded by then.
I switched to the documented cj/register-prefix-map helper and added (require 'keybindings) at the top, matching every other prefix map. The require guarantees keybindings loads before registration, so the guard is gone.
I verified at a full emacs --batch init.el launch, the actual failing scenario, that C-; M resolves to the signel prefix. I added a contract test asserting the registration, since the boundp guard was robust under unit timings and only failed at full launch.
|
| |
|
|
| |
The Duet design work graduated into a standalone package, so its task moved out of this todo. modules/duet-config.el is a use-package stub for it, inert until wired into init.el. Daily task-review also synced three ghostel follow-up priorities to their parent.
|
| |
|
|
| |
The shipped no-dim behavior works fine, which is the measured decision the task asked for, so the revisit is unneeded. Rewrote it to a dated cancellation log entry per the sub-task close rule.
|
| |
|
|
| |
Daily task-review pass over the seven oldest-unreviewed tasks: all kept as-is and re-stamped to 2026-06-05. Tagged the TTY C-; keymap task :solo:quick: and the Slack popup task :quick:.
|
| | |
|
| |
|
|
|
|
|
|
| |
I swapped the terminal engine from vterm to ghostel (libghostty-vt) everywhere. term-config replaces vterm-config (the F12 terminal, the C-; x menu, tmux history capture), and ai-term replaces ai-vterm (the F9 Claude-agent launcher). ghostel renders the agent TUI without vterm's flicker under heavy streaming, and one engine now covers every terminal workflow.
Two behavior changes fall out of the swap. F9 launches in a terminal frame now: ghostel renders in TTY frames, so the old GUI-only guard is gone. Terminal windows no longer dim when unfocused: ghostel resolves its palette into the native module per-terminal, so there's no per-window color hook to dim through the way vterm had.
auto-dim drops its vterm color-advice path, the dashboard Terminal button launches ghostel, and the vterm and vterm-toggle packages are removed. The tmux pane-history and copy-mode machinery carried over unchanged. It keys on the pty tty, which ghostel exposes.
|
| |
|
|
|
|
| |
I restored the heading "Color dashboard navigator independently of list items" above its PROPERTIES drawer. The 2026-06-02 archive cleanup dropped the heading, which orphaned the drawer and body into the preceding DONE task and tripped org-lint's obsolete-properties-drawer check. org-lint is clean again.
I also filed "TTY-accessible personal C-; keymap" [#B]: C-; is GUI-only, so the whole custom prefix family is unreachable in a terminal. The task records the single-point fix in keybindings.el and the candidate TTY-safe mirror prefixes.
|
| | |
|
| |
|
|
| |
Move the f9 toggle, completing-read prompts, and GPG pinentry subtrees into Resolved, and file the pearl vanilla-config dogfooding follow-ups surfaced by the cross-project handoff.
|
| |
|
|
|
|
|
|
| |
A picker prompt is the last thing shown before a command commits, so a bare noun leaves a mis-keyed command ambiguous. Hitting C-f8 (project agenda) instead of C-f9 (AI-vterm picker) gave the same "Project:" prompt with no signal which one was about to run.
Reworded 17 prompts across 8 modules so each names the operation rather than just the thing being chosen: "Project:" becomes "Show agenda for project:", "F6:" becomes "Run tests:", the dwim-shell sub-prompts gain their context (checksum algorithm, PDF compression quality, text-to-speech voice, run dwim-shell command), the two contact pickers split into "Find contact:" and "Insert contact email:", and the dirvish ediff, org finalize, and custom-comments length/box-style prompts get the same treatment.
I audited all ~124 completing-read / read-* call sites; the rest already named their operation and were left alone. These are prompt-string changes only, no logic touched.
|
| |
|
|
|
|
|
|
|
|
| |
Audit reconciliation:
- EAT consolidation: moved DOING back to TODO — the eval matrix has no recorded run since the 2026-05-26 direction note, so it isn't active work.
- Finish terminal GPG pinentry: CANCELLED as a duplicate. The "Terminal GPG pinentry Completion" task is canonical; its audit already found the terminal-pinentry branch gone, so the work restarts from main and is tracked there.
- M-F9 close: added a note that it's still a bug, distinct from the F9 toggle collapse — close should leave the surrounding layout intact, and cj/--ai-vterm-close-buffer still deletes the window.
- De-linked the coverage-v1 cross-reference, which pointed at a session file that was never archived.
Review: re-stamped LAST_REVIEWED on the seven oldest-unreviewed tasks (debug-profiling, org-noter, API workspace, Company-to-Corfu, F2 preview, TRAMP/dirvish, F-key Completion), all kept as-is.
|
| |
|
|
|
|
|
|
|
|
|
|
| |
F9 toggle-off used quit-restore-window to dismiss the agent. With several agents alive sharing one slot, switching among them (C-F9) reuses the window via set-window-buffer, which leaves the window's quit-restore parameter pointing at the first agent shown. Once stale, quit-restore-window falls back to switch-to-prev-buffer and surfaces a different agent instead of removing the window, so F9 appeared to "show another agent" rather than hide the split.
Toggle-off now collapses the split with delete-window, which is independent of the slot's buffer history, so the working buffer reclaims the frame. Geometry is captured first so the next toggle-on re-splits at the same width.
Toggle-on reopens the exact agent that was hidden (new cj/--ai-vterm-last-hidden-buffer), falling back to the most-recent agent only when that buffer has been killed. Hide-then-show is now a faithful round trip, not a jump to whichever agent is most-recent in buffer-list.
Sole-window toggle-off returns to the most-recent non-agent buffer instead of other-buffer, which could land on another agent.
I updated the two reuse-edge-window tests that asserted the old restore-displaced-into-a-kept-slot behavior to match the new always-collapse behavior.
|
| |
|
|
| |
I stamped LAST_REVIEWED on the seven oldest-unreviewed tasks and tagged the gptel-magit velox bug and the Signal dashboard task as quick.
|
| |
|
|
|
|
| |
AI-vterm launches a graphical vterm side window, so F9 / C-F9 / M-F9 now decline with a message in a terminal frame instead of opening a vterm. The guard checks the current frame at command time rather than at load. That matters under the daemon, which serves GUI and terminal frames both with display-graphic-p nil at load, so a load-time gate would have disabled the launcher in its GUI frames too.
Routed the three window-behavior tests through a GUI-frame stub, since a batch run is itself a terminal frame.
|
| |
|
|
|
| |
velox's gptel is below the 0.9.8 that gptel-magit requires, so the package
fails to activate at startup. Captures the repro and the version-check fix.
|
| | |
|
| |
|
|
| |
I folded the "Chat buffer placement + exit keys" task into a dated event-log entry under the DOING Signal parent. The work landed in dotemacs 998e9c7a (bottom-30 docking via display-buffer-alist plus tests) and signel-fork df02d79 (pop-to-buffer + signel--cancel-input + C-c C-k binding).
|
| |
|
|
|
|
|
|
|
|
|
|
| |
Walked the open-task backlog twice tonight. The first pass was a content audit (is each task still factually accurate?). The second was a relevance/priority review. Together they surfaced enough drift to be worth landing as one batch rather than dribbling into the next session.
The audit filed three new completion-task parents, each with an audit-finding body and child-task recommendations: F-key Completion (roughly 75% shipped per evidence), Terminal GPG pinentry Completion (no trace of the prior branch on this machine, treat as fresh), and Localrepo Documentation (build is shipped, docs land in three artifacts, four gap-fix tasks spin out as siblings). Headline-indicators-wrap and Buttercup closed DONE, Rework-dev-F-keys cancelled as superseded.
Manual Testing and Validation became its own top-level task with the 10 misfiled verify children moved in. Walk started tonight (tests 1 and 2 verified, two signel bugs surfaced and fixed in the same session), deferred to 2026-05-29 for the message-sending tests.
The Buttercup eval doc captures the rubric I came to during the brainstorm: adopt the moment a project crosses the "test reader is no longer the test author at write-time" threshold. ERT stays the right default until then. None of my projects have crossed yet.
Lint pass resolved all 21 org-lint follow-ups inline rather than letting them accumulate in a hidden inbox: 5 wrong-prefix design-doc links (../docs/design/X.org should have been docs/design/X.org), 4 file:line bare references wrapped in code formatting, 1 timestamp moved out of org-link brackets, 1 nested src block converted to begin_example, the wttrin diagnostic's stale link replaced with a note about where the surviving record lives, 8 markdown-bold patterns converted to org italics, 2 verbatim ** TODO references trimmed so the linter stops misreading them as headings.
|
| |
|
|
| |
The wrap-up's sync-child-priority pass bumped two intentionally-deprioritized children of the Signal parent: the [#C] handle-error leak and the [#D] groups vNext. Both are deliberate. The leak is bounded by the stop/start clrhash and the groups task is explicitly post-1:1-stability, so I tagged them :no-sync: to stick at their chosen priorities across future wrap-ups.
|