aboutsummaryrefslogtreecommitdiff
Commit message (Collapse)AuthorAgeFilesLines
...
* feat(hugo): draft picker, preview toggle, publish commandCraig Jennings2026-04-223-2/+224
| | | | | | | | | | | | | Put the full Hugo workflow inside Emacs. All of it lives in modules/hugo-config.el. New functions: - cj/hugo-open-draft reads all .org files under content-org/log, finds those with #+hugo_draft: true, and offers a completing-read picker. - cj/hugo-preview toggles a local hugo server subprocess and opens the preview URL in the browser. A second press stops the server. - cj/hugo-publish opens magit-status on the website repo. The server-side post-receive hook on cjennings.net already rebuilds and deploys on push, so committing and pushing is the deploy. Two pure helpers support the picker: cj/hugo--post-metadata parses the front matter region of a post, and cj/hugo--collect-drafts walks a directory and filters to drafts. Seven ERT tests cover both helpers across normal, boundary, and error cases. Keybinding note: C-; h d and C-; h D have swapped roles. Lowercase d now opens the draft picker. Uppercase D toggles the draft flag in the current buffer. The previous lowercase-d binding was toggle.
* fix: load freshness, wttrin path, compile-time package initCraig Jennings2026-04-223-1/+10
| | | | | | | | Set load-prefer-newer in early-init.el. Emacs was loading the older .elc files even when the .el source was newer, warning on every load but still using the stale byte code. Point weather-config.el's wttrin :load-path at /home/cjennings/code/emacs-wttrin. The previous value was /home/cjennings/code/wttrin, which does not exist, so use-package could not load the package. Add (package-initialize) to the Makefile compile target. Without it, batch byte-compile cannot see ELPA packages like git-gutter, git-timemachine, forge, and difftastic, which produced "Cannot load" warnings on every run.
* docs: add README.orgCraig Jennings2026-04-201-0/+89
|
* style(font): set default and fallback font heights to 120Craig Jennings2026-04-201-2/+2
| | | | Default preset (BerkeleyMono) 140→120, fallback preset (FiraCode) 110→120.
* chore: rename /docs/ → /.ai/ in gitignore and CLAUDE.mdCraig Jennings2026-04-202-3/+4
| | | | | | .gitignore: rename the private-tooling entry from /docs/ to /.ai/. CLAUDE.md: expand Layout to list /.ai/ (gitignored) and docs/ (reserved for real project documentation, if/when created).
* chore: sync validate-el.sh JSON channel + pairwise rule from rulesetsCraig Jennings2026-04-192-9/+44
|
* chore: sync testing rules — pyramid, overmocking, ↵Craig Jennings2026-04-192-0/+130
| | | | refactor-for-testability, interactive/internal split
* chore: sync elisp-testing.md (testutil pattern generalized)Craig Jennings2026-04-191-3/+3
|
* chore: sync bundle — add commits.md rule, attribution suppressionCraig Jennings2026-04-193-1/+71
| | | | | | | | | Picks up upstream bundle changes: - New .claude/rules/commits.md: no AI attribution, conventional prefixes. - settings.json: attribution.commit and attribution.pr empty strings (suppresses Claude Code default attribution). - CLAUDE.md: Git Workflow references commits.md instead of the (gitignored) docs/protocols.org.
* chore: gitignore *.eln (native-compiled artifacts from validate-el.sh)Craig Jennings2026-04-191-0/+3
|
* chore: sync .claude/ bundle — package-initialize, flat-layout, generic testingCraig Jennings2026-04-193-4/+168
| | | | | | | | | | | | | | | | Re-installed the elisp ruleset from ~/code/rulesets, picking up three upstream bundle fixes: - validate-el.sh now calls (package-initialize) so byte-compile can resolve external packages (dash, etc.) via ~/.emacs.d/elpa/. - validate-el.sh Phase 2 (test runner) now matches any .el file outside tests/, not just modules/*.el. Supports flat-layout projects (Elisp package repos where sources live at project root). - .claude/rules/testing.md is now generic TDD principles (was Python/TS specific); language-specific testing rules live in elisp-testing.md, python-testing.md, etc. elisp-testing.md gained a line referencing testing.md as the base.
* chore: remove install-hooks target, rulesets install handles itCraig Jennings2026-04-191-10/+1
|
* chore: track CLAUDE.md and .claude/ bundle, narrow gitignoreCraig Jennings2026-04-197-3/+418
| | | | | | | | | | | | | | | | | | | | Swap blanket /CLAUDE.md + /.claude/ gitignore rules for personal-only overrides (.claude/settings.local.json, .claude/.cache/). Add the tracked bundle content from ~/code/rulesets install-elisp: - CLAUDE.md (project instructions) - .claude/rules/elisp.md - .claude/rules/elisp-testing.md - .claude/rules/verification.md - .claude/hooks/validate-el.sh (portable via $CLAUDE_PROJECT_DIR) - .claude/settings.json (allowlist + hook wiring) Hooks now use $CLAUDE_PROJECT_DIR with script-relative fallback, so a fresh clone of this repo works on any machine without path edits. Project-local skills under .claude/skills/ were stale DeepSat-flavored copies; deleted and replaced with symlinks into ~/.claude/skills/ via the rulesets repo's global install.
* chore(hooks): add tracked pre-commit hook via githooks/Craig Jennings2026-04-192-1/+60
| | | | | | | | | | | | | Portable setup: pre-commit lives in githooks/ (tracked), activated by `make install-hooks` which sets core.hooksPath. Survives fresh clones. The hook does two things on staged changes: - Scans added lines for common credential patterns (AWS keys, sk-* tokens, BEGIN PRIVATE KEY blocks, api_key/password literals) - Runs check-parens on staged .el files Bypass with `git commit --no-verify` for confirmed false positives.
* refactor(transcription): extract running-transcriptions and format-entryCraig Jennings2026-04-192-20/+91
| | | | | | | | | | | Two cleanups round out the transcription-config refactor: - cj/--running-transcriptions: the 'status = running' filter used by cleanup and count helpers is now one function. Existing counter tests cover both callers. - cj/--format-transcription-entry: the 13-line dolist body inside cj/transcriptions-buffer becomes a testable pure function. 6 tests cover status-face mapping, basename-only rendering, duration format, trailing newline.
* refactor(transcription): extract four sentinel side-effect helpersCraig Jennings2026-04-192-40/+180
| | | | | | | | | | | | | | | | Break cj/--transcription-sentinel's seven inline side-effects into named helpers: - cj/--write-transcript-on-success: writes process output to .txt on success - cj/--append-to-log: appends event marker + process output to log - cj/--update-transcription-status: marks tracking-list entry complete/error - cj/--notify-completion: sends success or critical notification Also: switch the tautological (cj/--should-keep-log t) to use the local success-p (equivalent but matches the function signature), and rename the unused audio-file sentinel arg to _audio-file. Sentinel shrinks from 48 lines with 7 inline blocks to 14 lines of straight-line helper calls. 10 tests cover the extracted helpers.
* refactor(transcription): extract init-log-file and track-transcriptionCraig Jennings2026-04-192-14/+132
| | | | | | | | | | | Pull two more helpers out of cj/--start-transcription-process: - cj/--init-log-file: writes the initial log header with timestamp, backend, audio file, script path - cj/--track-transcription: pushes a running-status entry and refreshes the modeline Start-process shrinks from 58 lines with 4 levels of nesting to ~25 lines mostly at depth 1-2. 10 tests cover the extracted helpers.
* refactor(transcription): extract cj/--build-process-environmentCraig Jennings2026-04-192-9/+109
| | | | | | Pull the per-backend env-var assembly out of cj/--start-transcription-process into a standalone pure function. 9 tests cover: the three backends, parent-env preservation, non-mutation, missing-key user-error, unknown-backend error.
* refactor(transcription): consolidate backends into descriptor alistCraig Jennings2026-04-192-90/+93
| | | | | | | | | | | | | | Introduce cj/--transcription-backends alist mapping each backend to (:script :auth-host :env-var). Replace: - two near-identical cj/--get-{openai,assemblyai}-api-key functions with a single parameterized cj/--auth-source-password helper - the pcase in cj/--transcription-script-path with an alist lookup - the pcase block in cj/--start-transcription-process that assembled the API-key env var with an alist-driven assembly Adding a new backend is now a single line in the alist. The existing tests plus retargeted API-key tests (now 10, covering the parameterized helper and the descriptor data) verify no behavior change.
* test(transcription): add characterization tests for API-key retrievalCraig Jennings2026-04-191-0/+90
| | | | | | | 8 tests pinning down current behavior of cj/--get-openai-api-key and cj/--get-assemblyai-api-key (host query, string vs function secret, missing-entry → nil). Baseline for upcoming consolidation into a single parameterized helper.
* refactor(org-contacts): remove dead boundp branchesCraig Jennings2026-04-191-16/+12
| | | | | | | | cj/org-contacts-template-name and cj/org-contacts-template-email each opened with (when (boundp 'cj/contact-name) ...) / (boundp 'cj/contact-email) to pick up a caller-supplied preset. Neither variable is ever defined, set, or let-bound anywhere in the config — the branches never ran. The (or ...) fallbacks always took over, so behavior is unchanged.
* fix(reconcile): restore repo iteration under projects-dir and code-dirCraig Jennings2026-04-192-1/+182
| | | | | | | | | | | The outer dolist in cj/check-for-open-work guarded its body with (boundp 'base-dir), which always returns nil under lexical-binding because base-dir is a lexical loop variable. Every repo under projects-dir and code-dir was silently skipped; only org-dir and user-emacs-directory (both top-level defvars) still got reconciled. Remove the bogus boundp check. Add regression tests covering the entry point itself — the existing suite only exercised the helpers.
* refactor(reconcile): extract helpers, add recursive repo discovery and 28 testsCraig Jennings2026-04-197-36/+549
| | | | | Extract should-skip-p, pull-clean, pull-dirty from 6-level nested reconcile-git-directory. Make find-git-repos recurse into sub-repos.
* fix: make this function recursiveCraig Jennings2026-04-181-4/+14
|
* fix: fix M-P by removing autoload cookie from keybindingCraig Jennings2026-04-181-1/+1
|
* feat(agenda): add project-filtered agenda view on C-f8Craig Jennings2026-04-092-6/+36
| | | | | | New cj/todo-list-single-project prompts for a project, then shows the daily agenda scoped to that project's todo.org plus calendars and inbox. Moved cj/todo-list-all-agenda-files from C-f8 to s-f8.
* feat(vterm): pass F8, F9, F10 through to EmacsCraig Jennings2026-04-073-3/+7
| | | | | | Add nil bindings for F8 (agenda), F9 (gptel), and F10 (music) in vterm-mode-map so these global keybindings aren't swallowed by vterm. Also disable wttrin-debug and update abbreviations.
* test(recording): add direct tests for device-sort-key, device-status-label, ↵Craig Jennings2026-04-053-0/+198
| | | | | | get-sink-index Previously tested only indirectly via label-devices and sink-has-active-audio-p.
* test(calendar-sync): add 32 tests for recurrence exceptions, helpers, unfoldingCraig Jennings2026-04-056-0/+313
| | | | | Cover occurrence-matches-exception-p (6), apply-single-exception (6), exdate-matches-p (6), extract-cn (5), extract-email (4), unfold-continuation (5).
* refactor(calendar-sync): extract require-calendars guard from 4 locationsCraig Jennings2026-04-051-8/+10
| | | | | Replaced 4 copies of "if null calendars, warn" with a shared calendar-sync--require-calendars predicate.
* refactor(calendar-sync): extract RFC 5545 continuation line unfoldingCraig Jennings2026-04-051-17/+17
| | | | | Deduplicated the folded-line handling loop from get-property and get-all-property-lines into calendar-sync--unfold-continuation.
* refactor(calendar-sync): extract CN and email parsing from duplicated codeCraig Jennings2026-04-051-25/+19
| | | | | Extracted calendar-sync--extract-cn and calendar-sync--extract-email from identical logic in parse-attendee-line and parse-organizer.
* refactor(calendar-sync): remove dead function calendar-sync--timezone-nameCraig Jennings2026-04-052-12/+1
| | | | Function was defined but never called anywhere in the codebase.
* test(calendar-sync): add 68 tests across 13 files for untested pure functionsCraig Jennings2026-04-0513-0/+647
| | | | | | | Covers core parsing (parse-ics-datetime, parse-timestamp, format-timestamp, split-events, parse-event), date utilities (add-months, add-days, weekday-to-number, date-weekday, event-start-time), and timezone (format-timezone-offset, convert-utc-to-local, localize-parsed-datetime).
* test(recording): add direct tests for extracted refactoring helpersCraig Jennings2026-04-053-0/+243
| | | | | | Cover build-video-command (9 tests), select-from-labeled (5 tests), and test-device (4 tests). All three were previously tested only indirectly through their callers.
* refactor(recording): extract select-from-labeled helper, flatten quick-setupCraig Jennings2026-04-051-33/+27
| | | | | | Extracted completing-read+cancel pattern into cj/recording--select-from-labeled. Reduces quick-setup nesting from 5 to 3 levels and eliminates duplicated completion table lambda.
* refactor(recording): extract video command builder from ffmpeg-record-videoCraig Jennings2026-04-051-42/+42
| | | | | Moved Wayland/X11 command string construction into cj/recording--build-video-command. Reduces ffmpeg-record-video from 70 to 25 lines, nesting from 4 to 2 levels.
* refactor(recording): extract shared test-device helper from ↵Craig Jennings2026-04-051-21/+16
| | | | | | | test-mic/test-monitor Both functions had identical record-5-seconds-and-playback logic. Extracted to cj/recording--test-device with device, prefix, and prompt-action parameters.
* refactor(recording): unify parse-pactl-sources/sinks-verbose into single ↵Craig Jennings2026-04-053-61/+28
| | | | | | | function Identical 31-line parser logic differed only in "Source #" vs "Sink #" header. Replaced with cj/recording--parse-pactl-verbose taking a record-type parameter.
* chore: gitignore and untrack data/ directoryCraig Jennings2026-04-053-230/+2
|
* chore: gitignore and untrack CLAUDE.mdv0.7.2Craig Jennings2026-04-052-28/+1
|
* chore: gitignore and untrack build artifacts, vendored assets, personal filesCraig Jennings2026-04-052043-30969/+15
| | | | | | Untrack .cask/, .localrepo/ (61M), emojis/ (7.2M), inbox/, todo.org, v2mom.org, .time-zones.el. Move test-reporter-spec.org to docs/ (already gitignored). Reduces tracked repo size significantly.
* feat(music): add random-aware next/previous; refactor music + calendar-syncCraig Jennings2026-04-036-174/+1050
| | | | | | | | | | Music: random mode now respected by next/previous keys. Previous navigates a 50-track play history ring buffer. Fixed playlist replacement bug. 24 new tests. Calendar-sync: consolidated duplicate parse functions, extracted timezone localization helper, unified expand-daily/monthly/yearly into parameterized function, removed dead code. 33 new characterization tests. -90 lines.
* feat(org): add <cj structure template for daily prep comment blocksCraig Jennings2026-04-021-1/+3
| | | | Add org-tempo template expanding <cj TAB to #+begin_src cj: comment blocks.
* feat(music): add test coverage for 7 functions, refactor with extracted helpersCraig Jennings2026-04-018-36/+975
| | | | | | | | | | | | Add 47 new unit tests across 7 test files covering playlist-modified-p, assert-valid-playlist-file, playlist-tracks, create-radio-station, ensure-playlist-buffer, after-playlist-clear, and header-text. Extract three helpers to reduce duplication: assert-m3u-files-exist (dedupes 2 identical guards), sync-playlist-file (dedupes 3 state-sync patterns), and select-m3u-file (reusable M3U selection with cancel). Simplify append-track-to-playlist nesting from 6 to 4 levels. Delete unused cj/music-keymap-prefix variable.
* fix(slack): disable emojify in lui buffers, add org cache reset commandCraig Jennings2026-03-162-1/+27
| | | | | | Disable slack-buffer-emojify to prevent wrong-type-argument listp errors on emoji characters during lui-scroll-post-command recenter. Add C-; O c to reset org-element cache across all org-mode buffers.
* fix(slack): add error visibility to notification handlerCraig Jennings2026-03-142-10/+23
| | | | | | Websocket library silently swallows callback errors via condition-case. Wrap cj/slack-notify in condition-case to surface errors in *Messages*. Add cj/slack-test-notify command for pipeline verification.
* fix(slack): fix notification bug, add close-all-buffers commandCraig Jennings2026-03-101-1/+17
| | | | | Pass missing team arg to slack-message-mentioned-p (was breaking all channel notifications). Add cj/slack-close-all-buffers on C-; S Q.
* fix(music): place point on first track after playlist load/reloadCraig Jennings2026-03-101-2/+4
|
* fix(calendar-sync): handle variable-length date lists in RRULE UNTILCraig Jennings2026-03-094-5/+133
| | | | | | | date-to-time used (reverse date) which broke when RRULE UNTIL values were parsed as 5-element lists (year month day hour minute) from UTC timestamps. This caused recurring events with UTC UNTIL dates to expand to 0 occurrences, producing stale calendar entries.