aboutsummaryrefslogtreecommitdiff
path: root/todo.org
Commit message (Collapse)AuthorAgeFilesLines
...
* docs(todo): log the defensive restart/shutdown hardeningCraig Jennings13 days1-15/+3
|
* docs(todo): log the three video-audio-recording hardening fixesCraig Jennings13 days1-30/+6
| | | | Closed the X11/audio shell-quoting, the scoped wf-recorder stop signal, and the selected-directory creation as dated event-log entries under the recording hardening tree.
* docs(todo): close C-s isearch task — verified non-bug on Emacs 30.2Craig Jennings13 days1-10/+3
| | | | While isearch is active, overriding-terminal-local-map is isearch-mode-map, so C-s resolves to isearch-repeat-forward and the global cj/consult-line-or-repeat binding can't shadow it. isearch-mode-map already binds C-s to that default, so I left selection-framework.el unchanged.
* docs(ai-kb): fold in review 6 and resolve the build-time decisionsCraig Jennings13 days1-11/+17
| | | | | | The latest design review was a UX and performance pass, and I folded its findings into the spec and the implementation tasks. The important one: human Emacs edits now use the same write path as agent writes. An ai-kb minor mode runs index, full lint, and commit under flock on after-save, so a hand edit can't quietly skip the safety gate. The rest: the generated index.org is now invisible to backlink and orphan logic (excluded from the scan, referenced as plain text rather than id-links), a required :SUMMARY: property feeds the index and query without inference, query gains lexical ranking with recency only as a tie-break, the switch installs a full org-roam profile rather than a two-variable swap, and the browsing surface (dashboard, find, search, show, backlinks, map) is named. I also answered the six build-time decisions: concrete raw and curation limits, performance budgets for the perf fixtures, the lexical scoring weights, org-roam-graph as the first map implementation, the after-save failure UX (the save always lands, the commit is gated, and a failure shows without trapping the buffer), and the after-save recursion guard. The numeric limits and budgets are starting points to calibrate. The rest are firm. Step 1 stays buildable.
* docs(todo): split Implement ai-kb tasks into 1a/1b and fold in review-5 ↵Craig Jennings13 days1-0/+43
| | | | | | hardening I reorganized the Implement ai-kb children into the Step 1a / 1b phases from the spec: 1a is the safe write path (store, contract, the index/lint/remember/doctor CLI, the adapter, provisioning), and 1b is query/curate/sync, the push timer, and the curation workflow. The remember task now gates the commit on the full ai-kb lint rather than node org-lint, the test tasks target the org-lint fatal-check list and the query --json contract, the push task carries the failure-observability surfaces, and the pointer convention is ID-first throughout.
* chore(todo): archive resolved dashboard tasks to ResolvedCraig Jennings13 days1-98/+93
|
* docs(todo): close broad/misleading file-op clarificationCraig Jennings13 days1-14/+2
|
* docs(todo): close video-concat filelist rebuildCraig Jennings13 days1-8/+2
|
* docs(todo): close babel-confirm hardening, file keybinding follow-upCraig Jennings13 days1-11/+7
|
* docs(todo): close dwim-shell input-quoting, file concat-list follow-upCraig Jennings13 days1-20/+11
|
* docs(todo): close password temp-file fix, file 7z argv follow-upCraig Jennings13 days1-15/+11
|
* docs(todo): close SkyFi key-injection removalCraig Jennings13 days1-12/+2
|
* docs(todo): triage hardening backlog — close done, tag soloCraig Jennings14 days1-89/+40
| | | | I triaged the ~50 open hardening findings against the codebase. Closed five whose premise was stale because the work already shipped: the personal-calendar-config split, the shared cache helper, the cache idle-timer gating, and AI-conversation-persistence coverage. Tagged 31 findings :solo: — bounded work an agent can finish and verify without a decision from me. The rest carry a preference, policy, or design call and stay untagged.
* docs(todo): record kill-compose-buffers-on-exit decisionCraig Jennings14 days1-2/+2
|
* docs(todo): close mail compose lifecycle clarificationCraig Jennings14 days1-11/+2
|
* docs(todo): close org-babel structure-template fixCraig Jennings14 days1-11/+2
|
* docs(todo): close flyspell-and-abbrev coverageCraig Jennings14 days1-10/+2
|
* docs(todo): close external-open/media-utils coverageCraig Jennings14 days1-13/+2
|
* docs(todo): close title-case edge coverage and mail/system-commands coverageCraig Jennings14 days1-21/+4
|
* docs(todo): close host-env predicate cleanupCraig Jennings14 days1-16/+3
|
* docs(todo): close dirvish hardening and coverage tasksCraig Jennings14 days1-25/+4
|
* docs(todo): add :solo: tag and mark Claude-doable hardening tasksCraig Jennings14 days1-22/+19
| | | | I added a :solo: tag to the legend for tasks Claude can take end to end with no input from me: bounded scope, no design or preference call, verifiable locally. Tagged the nine hardening findings I've already assessed that way. Also closed the dirvish runtime-require task, shipped in b63c4f83.
* docs(todo): record TRAMP/dirvish "?" root cause, leave fix to verifyCraig Jennings14 days1-15/+15
| | | | | | I traced why remote dirvish shows "?" for dates: dirvish fetches remote attributes through an async `ls -1lahi` parser that only runs when the connection has direct-async and the remote has GNU ls. It falls back to skipping `file-attributes` (rendering "?") when either gate is shut. That's why the earlier dired-listing-switches attempts missed the real path, and why disabling direct-async made it worse. The config already enables direct-async, so the rest is per-host and needs a live remote. I left the three diagnostic evals and the likely fixes in the task body.
* docs(todo): close org-log-done reconcileCraig Jennings14 days1-2/+3
|
* docs(todo): close always-save-daily taskCraig Jennings14 days1-2/+3
|
* docs(todo): close auth-source consolidationCraig Jennings14 days1-1/+3
| | | | I closed the auth-source-idiom consolidation. The four copies now delegate to one system-lib helper.
* docs(todo): close dashboard navigator/keymap dedupCraig Jennings14 days1-1/+3
| | | | I closed the navigator and keymap duplication task. Both now derive from one launcher table.
* docs(todo): close dashboard subtitle and color bugs, file navigator-color ↵Craig Jennings14 days1-4/+11
| | | | | | follow-up I closed the subtitle-centering and the navigator/item color bugs, and filed a follow-up to give the navigator its own color separate from the list items, which is blocked by the shared dashboard-items-face overlay.
* docs(todo): close test-name abort bugCraig Jennings2026-05-221-1/+4
| | | | The real cause wasn't gptel: the gptel-tools tests already stub the constructors. test-name aborted because a test file leaked default-directory at load. Fixed with absolute load paths plus containment.
* docs(todo): close gptel backend-load bugCraig Jennings2026-05-221-1/+2
| | | | The fork's backend constructors load again, verified end-to-end.
* docs(todo): close finalize-task keybinding, file follow-upsCraig Jennings2026-05-221-29/+23
| | | | I closed the finalize-task keybinding work and recorded its design in the task body. Three follow-ups came out of it: reconcile the duplicate org-log-done setting, always save the daily after a journal task-copy, and manually verify the live journal copy that the unit tests mock out.
* docs(todo): review all tasks, re-grade gptel, expand Corfu subtasksCraig Jennings2026-05-221-3/+133
| | | | | | | | | | | | I walked all 24 unreviewed top-level tasks in one pass and stamped each with :LAST_REVIEWED: 2026-05-22. That dropped the threshold-7 staleness count from 24 to 0. I re-graded "gptel fork not loading: gptel-make-anthropic void" from [#C] to [#B]. It breaks gptel chat entirely and is the root cause of the test-name batch-load abort, so it shouldn't sit at the bottom of the pile. I reworded the sentence-shaped keybinding task to a terse topic and tagged it :quick:. Then I answered its embedded request with a cj/org-heading-to-dated-log sketch that drops the keyword and priority cookie and prepends a sortable timestamp, plus three mnemonic key candidates. I switched the org-noter task from VERIFY to TODO. It's in-progress implementation work, not an open question waiting on input. I expanded the Company-to-Corfu task with the migration spec's nine implementation steps as sub-tasks, so the work is ready to pick up without re-reading the design doc.
* docs(todo): log launch + dashboard bugs, tag quick tasks, close shipped workCraig Jennings2026-05-211-25/+50
| | | | I filed the gptel-fork-load error, the org-contacts launch error, and two dashboard polish bugs (off-center banner subtitle, uncolored navigator icons + titles). I tagged the genuinely quick tasks :quick:, dropped all gptel work to #C, and closed the two tasks shipped this session: the ai-vterm graceful close and the org-contacts launch fix.
* docs(todo): archive shipped tasks, file calendar and harness follow-upsCraig Jennings2026-05-211-8/+79
| | | | Moved the ai-vterm sizing and dashboard fixes to Resolved now that they've shipped. Filed two follow-ups: make test-name aborting on gptel-dependent test files, and consolidating the duplicated auth-source secret-funcall idiom.
* chore(todo): claim dashboard task + dated-log subtask rewritesCraig Jennings2026-05-181-57/+78
| | | | | | | | | | - Claim [#C] Dashboard buffer too long as DOING :bug: with expanded body. - File [#C] Collapse dashboard navigator + keymap duplication :refactor: surfaced by the audit of dashboard-config.el. - Mechanical: rewrote completed sub-tasks (level *** and deeper) from "DONE [#priority]" keyword form to "YYYY-MM-DD Day" dated-log form per the project's depth-based completion rule.
* chore(todo): shorten title to "Emacs Config"Craig Jennings2026-05-181-1/+1
|
* chore(todo): close Phase 1 ai-mcp foundationCraig Jennings2026-05-171-13/+2
|
* docs(design): MCP-into-gptel + gh-as-gptel-tool specs + MCP phasesCraig Jennings2026-05-171-1/+149
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Two new design docs in docs/design/ covering the next two GPTel work items, plus matching task scaffolding in todo.org. mcp-el-gptel-integration.org wires mcp.el into the config so GPTel gets access to the nine MCP servers Claude Code already uses (linear, notion, figma, slack-deepsat, drawio, google-calendar, google-docs-personal, google-docs-work, google-keep). The design covers async startup, the write-confirmation policy, a server-enablement defcustom, a doctor with live-auth-check, the audit buffer, and the mcp.el compatibility layer. The spec is at revision 3 after two code-review passes flagged a critical confirmation gap (gptel-confirm-tool-calls nil at ai-config.el:386 silently ignored per-tool :confirm slots) and several incorrect mcp.el API assumptions. Both are addressed. gptel-gh-tool.org wraps the gh CLI as a hybrid surface: 14 typed read wrappers plus one general write tool gated by :confirm t. Host/repo resolution is command-aware: --repo HOST/OWNER/REPO for repo commands, --hostname only for api and auth status. The runner enforces an irreversible-command blocklist, a 64KB in-flight output cap, and a debug-record plus last-error-buffer story. The spec is at revision 2 after a code-review pass corrected gh flag assumptions and reframed the safety story around per-tool confirm. todo.org gains a link to the MCP spec under the parent task plus nine TODO sub-tasks (one per implementation phase), and a new gh-tool TODO with the same spec-link shape.
* chore(todo): reorder GPTel Tool Work + add restclient API workspace taskCraig Jennings2026-05-161-69/+891
| | | | | | | | | | | | | Moves the Org Workflow Related Tools category up to sit directly after Git Related Tools in the GPTel Tool Work hierarchy. The previous ordering buried it after Messaging and File/Buffer. Adds a new task: Build an Org-native API workspace around restclient.el. Body carries a worked spec covering goals, primary user flows, proposed modules, Org workspace shape, secret handling, response handling, integration choices, testing strategy, and open questions. Captures three timestamped session log entries (original goals, ideas, spec) per the project's todo-format rules.
* docs(design): network tools brainstorm + GPTel Tool Work hierarchyCraig Jennings2026-05-161-299/+658
| | | | | | | | | | | | | | | | Adds docs/design/gptel-network-tools.org capturing the brainstorm output for the next gptel-tools batch -- net_diagnose, net_discover, net_services, network_status, dns_lookup -- with argv shapes, target-gating guardrails for nmap, and a ~47-test sketch. Restructures the GPTel Tool Work parent in todo.org with seven themed categories: Git, Org, messaging, file/buffer, filesystem, media / reading, and dev workflow. Each carries a body framing the design choice and stub child themes. Filesystem covers the pandoc / imagemagick / ffmpeg / ripgrep / fd / file+exiftool / jq+yq surface plus an eshell escape hatch. Per-theme spec lands in the task body once written. Implementation tasks join as siblings once the spec is approved.
* refactor(integrations): five hygiene fixes from the module-by-module re-reviewCraig Jennings2026-05-161-5/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | - markdown-config.el: two related fixes on `markdown-preview'. First, the URL was `https://localhost:8080/imp' but simple-httpd serves plaintext on port 8080 -- the browser hit a TLS handshake against a non-TLS listener and the preview never rendered. Changed to `http://' and switched from `browse-url-generic' to plain `browse-url' so the user's default protocol handler picks the browser. Second, the function used to start the network listener as a side effect of opening a preview; that's split into a separate `cj/markdown-preview-server-start' command and `markdown-preview' now signals a `user-error' (with the recovery command in the message) when the server isn't running. - slack-config.el: wrap the `which-key-add-keymap-based-replacements' call in `with-eval-after-load 'which-key'. Matches the pattern other config modules use and means a slow / missing which-key load won't block requiring slack-config. - ai-vterm.el: pass the inner shell-command-string through `shell-quote-argument' before wrapping in the tmux invocation. The default value with embedded double quotes was safe under the prior literal-single-quote wrap, but a user-customized `cj/ai-vterm-agent-command' containing a single quote silently broke the shell parse. Two existing tests updated to tolerate the post-quote escape shape; new regression test asserts a single-quote-bearing custom command survives. - eshell-config.el: scope the `TERM=xterm-256color' override to eshell-spawned processes only via an `eshell-mode' hook that prepends to a buffer-local `process-environment'. The previous global `setenv' at config-time changed `TERM' for every subsequent `start-process' across the Emacs session, so any subprocess (not just eshell pipelines) inherited `xterm-256color' regardless of whether the receiver could interpret the escapes.
* refactor(prog): six programming-track hygiene fixes from re-reviewCraig Jennings2026-05-161-6/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | - prog-lsp.el: rename `cj/lsp--remove-eldoc-provider' → `cj/lsp--remove-eldoc-provider-global' and call it once from the lsp-mode `:config' block instead of attaching it per-buffer via `lsp-managed-mode-hook'. The previous per-buffer remove with the buffer-local flag raced lsp-mode's own population of the local hook; removing the provider from the global default before any LSP buffer attaches makes the absence stick. Two existing tests updated to the new contract (remove-from-default + idempotent re-run). - prog-webdev.el / prog-python.el: warn at load time when `prettier' or `pyright' is missing on PATH via `cj/executable-find-or-warn'. Both modules now `(require 'system-lib)' to expose the helper. Missing dependencies surface up front instead of mid-edit at first format/LSP attach. - keyboard-compat.el: document existing idempotence. The hook install uses a named function so `add-hook' deduplicates, and the hook body only calls `define-key' (latest binding wins, same value) -- adding a comment so future readers don't re-question. - dev-fkeys.el: add a `typescript' clause to `cj/--f6-test-runner-cmd-for'. F6 now runs `npx --no-install vitest <path>' when vitest is on PATH, otherwise `npx --no-install jest <path>'. Updates the matching test from "returns nil" to cover both code paths; the impl-level test now asserts the routed command instead of expecting a user-error. - flycheck-config.el: build the LanguageTool wrapper path with `(expand-file-name "scripts/languagetool-flycheck" user-emacs-directory)' instead of a hardcoded `~/.emacs.d/...'. Survives a non-standard `user-emacs-directory'. - latex-config.el: replace the hardcoded Zathura viewer with `cj/--latex-select-pdf-viewer', which walks `cj/--latex-pdf-viewer-candidates' (zathura → evince → okular → SumatraPDF → xdg-open) and falls back to "PDF Tools" when nothing is on PATH. Each entry maps an executable to the matching TeX-view-program-list name so AUCTeX's defaults handle the actual viewer invocation.
* refactor(org-workflow): four hygiene fixes from the module-by-module re-reviewCraig Jennings2026-05-161-4/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | - org-roam-config.el: extract `cj/--org-roam-should-copy-completed-task-p' and gate the `org-after-todo-state-change-hook' on it. Skips fileless buffers (org-capture, indirect, temp Org) where `buffer-file-name' is nil and the downstream copy used to crash. Same gcal.org skip preserved. Five existing tests updated to bind `buffer-file-name' inside `run-hooks' so the positive-case hook still fires. - org-webclipper.el: drop the redundant `org-protocol-protocol-alist' registration inside `cj/webclipper-ensure-initialized'. The `with-eval-after-load 'org-protocol' block at the bottom of the module is the single registration site now; comment in the initializer explains why. Split the matching test into two: one for template registration (the initializer's actual job) and one for protocol registration (which now fires from the after-load block when `org-protocol' provides). - org-webclipper.el: validate `:url' and `:title' in `cj/org-protocol-webclip'. `:url' must be a non-empty string; `:title' must be a string when provided. Signals `user-error' with the unexpected value instead of silently setting the globals to nil and failing downstream in the capture handler. - mu4e-org-contacts-integration.el: declare `contacts-file' (via `eval-when-compile (defvar ...)') and `cj/get-all-contact-emails' (via `declare-function') near the top of the file. Byte-compile in isolation no longer warns about free variables / unknown functions; the cross-module dependency is explicit at the top.
* refactor(ui): four UI/navigation hygiene fixes from module-by-module re-reviewCraig Jennings2026-05-161-36/+44
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | - popper-config.el: move `(popper-mode +1)` and `(popper-echo-mode +1)` from the use-package `:init` block into `:config`. `:disabled t' on use-package skips `:config' but still runs `:init', so the previous shape enabled popper-mode on every load, including batch / test runs, despite the disabled marker. - modeline-config.el: make `cj/modeline-vc-fetch' fall back when the internal `vc-git--symbolic-ref' is missing. `require' uses `nil 'noerror', the call sits inside an `fboundp' guard, and `ignore-errors' wraps the call itself so an Emacs version that renames or removes the accessor leaves `branch' at `vc-working-revision''s output instead of crashing the modeline. - ui-config.el: guard the cursor-color `post-command-hook' behind `(display-graphic-p)' both at install time and inside the function body. Batch / TTY runs short-circuit cleanly with no per-command overhead. A `server-after-make-frame-hook' catches the daemon case where the first GUI frame is created after ui-config loads and installs the hook lazily. Updates test-ui-config--buffer-cursor-state and test-ui-cursor-color-integration to stub `display-graphic-p' so the work body still runs under batch. - nerd-icons-config.el: drop `:demand t' (`:defer t' now), keeping the `:config' advice install as the natural lazy-on-load path. Add a `with-eval-after-load 'nerd-icons' block as a safety net for the already-loaded case on re-eval; the block uses `advice-member-p' so the advice never stacks.
* refactor(custom-editing): five hygiene fixes from the module-by-module re-reviewCraig Jennings2026-05-161-43/+44
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | - Guard `cj/duplicate-line-or-region' when COMMENT is non-nil but the current mode has no `comment-start' (e.g. fundamental-mode). Previously the function silently produced malformed output via `comment-region'; now it signals a clear `user-error'. - Factor the `find-file' advice install in external-open.el into `cj/external-open-install-advice'. Same idempotent shape (remove-then-add) but the intent is named. - Add `cj/--validate-decoration-char' in custom-comments.el and wire it into all six divider / border / box helpers. Rejects multi-char strings, empty strings, and control characters like newline/tab that would corrupt subsequent `M-q' flows. Updated the five nil-decoration ERT tests from `:type 'wrong-type-argument' (the old crash signal from `string-to-char' on nil) to `:type 'user-error', since the validator produces a clear message instead of a deep crash. - Extract `cj/--require-spell-checker' in flyspell-and-abbrev.el. Both `cj/flyspell-toggle' and `cj/flyspell-then-abbrev' now call the shared helper; the checker list lives in `cj/--spell-checker-executables', so adding nuspell or any other checker is a one-line edit. - Preserve trailing newlines in custom-ordering output. Both `cj/--arrayify' and `cj/--unarrayify' now detect a trailing newline on the input region and re-append it to the result, matching the pattern custom-text-enclose.el already uses.
* refactor(foundation): hygiene pass across early-init, user-constants, ↵Craig Jennings2026-05-161-55/+57
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | system-defaults, chrono-tools Six small fixes the 2026-05-15 module-by-module re-review surfaced: - Consolidate `user-home-dir` -- canonical defconst stays in early-init.el (package-archive bootstrap needs it before normal modules load); user-constants.el switches to a `defvar` with the identical `(getenv "HOME")` expression so the module still loads / byte-compiles standalone, but at runtime early-init's defconst wins. - Drop the redundant `(autoload 'env-bsd-p ...)` line in system-defaults.el. The `(eval-when-compile (require 'host-environment))` already exposes the symbol to the byte compiler, and at runtime host-environment is loaded earlier in init.el. Added a comment documenting the boundary. - Convert `cj/debug-modules` and `cj/use-online-repos` from `defvar` to `defcustom`, with `:type`, `:group 'cj`, and a top-level `(defgroup cj ...)` so both show up in M-x customize. - Name the package-archive priorities in early-init.el. Nine new defconsts replace the magic numbers (200 / 125 / 120 / 115 / 100 / 25 / 20 / 15 / 5) with one constant each, plus a header comment explaining the local-first ordering and the gnu > nongnu > melpa > melpa-stable trust ranking within each tier. - Delete the 19-line commented-out `use-package time` world-clock block in chrono-tools.el. `time-zones` immediately above is the active replacement; git history preserves the old config if anyone needs it. - Add coverage for `cj/tmr-select-sound-file`. Collapsed the prefix-arg branch into a delegation to `cj/tmr-reset-sound-to-default` (single reset source) and extracted `cj/tmr--available-sound-files` as a pure helper that tests directly. 9 ERT tests across Normal / Boundary / Error cover the available-sounds helper, the reset path, the prefix-arg delegation (no prompt), the normal selection path, and the empty-dir / missing-dir / cancel boundaries.
* chore(todo): archive completed work to ResolvedCraig Jennings2026-05-161-281/+279
| | | | | Move the closed Gptel Work PROJECT and the flycheck modeline task from Open Work into Resolved. Both shipped this round.
* feat(modeline): surface flycheck status in the custom modelineCraig Jennings2026-05-161-8/+17
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The custom modeline builds `mode-line-format` from explicit segments and skips `minor-mode-alist`, so flycheck's lighter never appears. That hid error and warning counts even in buffers where flycheck was auto-enabling (every emacs-lisp and sh buffer). The fix is Option 4 from the design doc: customize the flycheck modeline variables, then add a single guarded `(:eval ...)` form to `mode-line-format`. Five new lines total, two-file change. `modules/flycheck-config.el` :custom block gets: (flycheck-mode-line-prefix "🐛") (flycheck-mode-success-indicator " ✓") `flycheck-mode-line-color` stays default-t so error / warning counts pick up their faces automatically. `modules/modeline-config.el` `mode-line-format` gets an `(:eval ...)` between the recording indicator and `cj/modeline-vc-branch`: (:eval (when (and (mode-line-window-selected-p) (bound-and-true-p flycheck-mode)) (flycheck-mode-line-status-text))) The `mode-line-window-selected-p` guard mirrors `cj/modeline-vc-branch` and `cj/modeline-misc-info` -- segments hide in inactive windows. The `bound-and-true-p flycheck-mode` guard keeps the form silent in buffers where flycheck hasn't loaded or isn't enabled, which is safer than referencing `flycheck-mode` directly. The `(:eval ...)` is inline rather than a named `defvar-local`, so no addition to the risky-local-variable list is needed. `tests/test-modeline-config-flycheck-segment.el` -- 3 smoke tests asserting the segment is present and both guards are in place. All existing tests stay green. Manual verification (per the design doc) is the user's call -- the emoji prefix and the colored count behavior need a running GUI Emacs to observe.
* docs(gptel): add shortlist design doc for additional gptel toolsCraig Jennings2026-05-161-16/+43
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The Gptel Work project asked for a survey of published gptel tools with adopt / skip / defer decisions per candidate. I can't do a live community-tool survey from this session, so the doc covers the candidates the task body called out plus a few obvious adjacents. Decisions: - ADOPT (7): `search_in_files`, `git_status` / `git_log` / `git_diff` (three tools), `web_fetch`, `search_emacs_help`, `find_file_by_name`, `take_screenshot`. Each gets a sketch in the doc -- args, validation posture, implementation outline. - DEFER (2): `run_shell_command` (huge surface, click-fatigue risk; the ADOPT-bucket tools cover most legit use cases), `org_capture` (needs UX design for template pre-fill and the round-trip). - SKIP (1): `eval_elisp` (code execution from a model is too dangerous even with confirm-each-call). The doc also lists three follow-ups: the live community survey that this session couldn't do, per-tool implementation sub-tasks to be filed under the next iteration of Gptel Work, and a sandboxing-convention decision for `web_fetch` (allowlist of outbound URLs vs description-only warning). Three open questions at the bottom of the doc for review: build-all-at-once vs paired stages, `fd` as a hard dep vs `find` fallback, Hyprland-only screenshot vs Wayland-generic via a portal. Closes the Gptel Work PROJECT for this iteration -- all 9 in-scope sub-tasks landed this session.
* feat(ai-conversations-browser): dired-style browser for saved GPTel ↵Craig Jennings2026-05-161-5/+35
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | conversations `cj/gptel-load-conversation` prompts via `completing-read`. A dedicated browser shows what each conversation is about at a glance and supports single-key load / delete / rename without having to scroll a minibuffer list. New module `modules/ai-conversations-browser.el` + `cj/gptel-browse-conversations` entry point bound to `C-; a b` ("browse conversations"). Opens `*GPTel-Conversations*` in `cj/gptel-browser-mode` (a `special-mode` derivative). Each row shows date, time, topic slug, and a preview of the most recent message (length configurable via `cj/gptel-browser-preview-length`, default 60 chars). Rows sort newest first. In the browser: - `RET` / `l`: load the conversation (delegates to `cj/gptel-load-conversation` with the file pre-selected via a `cl-letf` stub on `completing-read` so the user isn't prompted twice), then bury the window. - `d`: delete the file under point after `y-or-n-p` confirmation, re-render. - `r`: rename the file under point. Preserves the timestamp, slugifies the new topic, refuses unchanged input and existing targets. - `g`: refresh. - `n` / `p`: next / previous row. - `q`: quit-window. 21 tests cover the helpers (topic parsing, header stripping, preview shaping for truncate / short / empty cases, row-for-file with conversation + non-conversation filenames, rows enumeration, render output for empty + populated cases, newest-first sort, rename-target preservation of timestamp + slug, rename-target error on missing timestamp) and the file-touching actions (delete with y, cancel with n, rename, rename-on-empty-line error).