aboutsummaryrefslogtreecommitdiff
Commit message (Collapse)AuthorAgeFilesLines
* 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.
* refactor(gptel): extract model-list and selection logic for testabilityCraig Jennings2026-03-063-20/+217
| | | | | | | - Extract cj/gptel--build-model-list from cj/gptel-change-model - Extract cj/gptel--current-model-selection from cj/gptel-change-model - Add test-ai-config-build-model-list.el (9 tests) - Add test-ai-config-current-model-selection.el (8 tests)
* refactor(gptel): lazy-load gptel-magit, rebind rewrite/context keysCraig Jennings2026-03-064-35/+181
| | | | | | | | | | - Replace use-package gptel-magit hook with autoloads via with-eval-after-load 'magit (loads gptel only on key press) - Move org header defuns above use-package to fix load order - Set gptel-include-reasoning to "*AI-Reasoning*" buffer - Rebind rewrite to C-; a r, clear context to C-; a c - Add test-ai-config-gptel-magit-lazy-loading.el (8 tests) - Mark all ai-config cleanup items DONE in todo.org
* refactor(gptel): move config defuns to top level, rebind keys, set reasoningCraig Jennings2026-03-062-52/+44
| | | | | | | | | - Move cj/gptel--fresh-org-prefix, cj/gptel--refresh-org-prefix, cj/gptel-backend-and-model, cj/gptel-insert-model-heading out of use-package :config to top level (fixes byte-compile warnings) - Set gptel-include-reasoning to "*AI-Reasoning*" buffer - Rebind rewrite to C-; a r, clear context to C-; a c - Update todo.org with completed cleanup items
* test(gptel): add unit tests for ai-config, remove dead cj/gptel-backendsCraig Jennings2026-03-065-6/+277
| | | | | | | | - Add testutil-ai-config.el with gptel stubs for batch testing - Add tests for cj/gptel--model-to-string (9 tests) - Add tests for cj/gptel--fresh-org-prefix (8 tests) - Add tests for cj/gptel-backend-and-model (8 tests) - Remove dead cj/gptel-backends defvar (duplicates cj/gptel--available-backends)
* fix(gptel): fix docstring warnings, rename model->string to model-to-stringCraig Jennings2026-03-062-16/+11
| | | | | | | | - Escape single quote in cj/ensure-gptel-backends docstring - Wrap cj/gptel--available-backends docstring to 80 chars - Add missing docstring to cj/gptel--model-to-string - Rename cj/gptel--model->string to cj/gptel--model-to-string - Mark stale model list task as DONE in todo.org
* fix(gptel): remove duplicate backend setter, fix commentary keybindingsCraig Jennings2026-03-061-10/+9
| | | | | | Remove redundant gptel-backend setq and orphaned section header. Fix commentary keybinding references: M-a → C-; a, correct buffer add (.) and rewrite (&) bindings.
* feat(gptel): update Claude models, fix default system promptCraig Jennings2026-03-062-5/+104
| | | | | | | | Update Anthropic model list to current: claude-opus-4-6, claude-sonnet-4-6, claude-haiku-4-5-20251001. Fix gptel--system-message not picking up the custom default.org directive (defvar set at load time before gptel-prompts replaces the default entry). Add cleanup tasks for ai-config, calibredb, and slack reaction workflow to todo.org.
* fix(slack): fix notification and mark-as-read bugsCraig Jennings2026-03-062-3/+55
| | | | | | Notifications silently failed: slack-room-im-p (nonexistent) replaced with slack-im-p; slack-message-to-string replaced with slack-message-body. Mark-as-read bound to nonexistent function; added cj/slack-mark-read-and-bury.
* feat: add Slack client module with dashboard integrationCraig Jennings2026-03-063-0/+150
| | | | | | Add emacs-slack config with auth-source credentials, DM/mention-only notifications via notify script, compose buffer workflow, and dashboard icon. Keybindings under C-; S prefix.
* session: switch Python LSP to pyright, add Django web-mode configCraig Jennings2026-03-043-120/+124
| | | | | | Replaced pylsp with lsp-pyright in prog-python.el for better type inference, especially for Django ORM. Added Django engine and indent settings to web-mode in prog-webdev.el. Pyright already installed via pacman.
* feat(json,yaml): add tree-sitter modes, formatting, and jq integrationCraig Jennings2026-03-028-21/+292
| | | | | | | New prog-json module: json-ts-mode with jq formatting (C-; f) and jq-interactively (C-c C-q). Upgraded prog-yaml to yaml-ts-mode with prettier formatting. Both use treesit-auto for grammar management. Includes 18 new tests (10 JSON, 8 YAML), 185/185 passing.