aboutsummaryrefslogtreecommitdiff
path: root/languages/elisp
Commit message (Collapse)AuthorAgeFilesLines
* fix(elisp): byte-compile cross-project .el edits against their own modulesCraig Jennings18 hours1-0/+5
| | | | | | The validate-el hook only put the current project's roots on the load path, so editing an .el file from another project failed Phase 1 byte-compile on free-variable warnings: the file's own sibling modules weren't reachable. I added the edited file's directory and its parent to the load path. For in-project edits both are redundant (already covered by PROJECT_ROOT and its modules dir). They only do work when the file sits outside the current project root. I left Phase 2's test runner alone. It discovers tests by stem under PROJECT_ROOT/tests, so a cross-project file's tests aren't found regardless of load path.
* docs(elisp): name eask as the build tool, not eldevCraig Jennings5 days1-1/+1
| | | | The real elisp packages drive eask in their Makefiles, but the bundle listed eldev as a build tool and left eask out, pointing a fresh session at the wrong tool.
* fix(elisp-hook): show a compact test summary in the terminal on failureCraig Jennings7 days1-3/+13
| | | | validate-el.sh dumped the full ERT batch output to the terminal on a red test, every backtrace frame, flooding the pane. It now prints a short summary there: the run tally plus the failing test names and their file:line. Claude still gets the full backtrace through additionalContext. fail_json takes an optional fourth argument for the terminal echo. Paren and byte-compile failures stay short, so they still print in full.
* feat(elisp): add coverage-summary to the Elisp bundle with missing-file ↵Craig Jennings14 days4-0/+407
| | | | | | | | | | | | | | detection A line-weighted coverage total has a blind spot: a module no test loads never shows up in the SimpleCov report, so it can't drag the number down. The suite looks healthier than it is. This adds a summary that counts every source file on disk against the report and treats an absent file as 0%, weighting the project number by file instead of by line so untested modules stay visible. The script ships at languages/elisp/claude/scripts/coverage-summary.el, self-contained on stock Emacs (just the built-in json). It parses the undercover SimpleCov shape directly rather than depending on the editor's coverage engine, so it runs anywhere the bundle lands. I proved it against a real 103-file report: 93 tracked, 27 untested modules surfaced, project number 66.4%. Delivery follows the bundle convention. The script lives under the gitignored .claude/ footprint and gets auto-fixed on drift by sync-language-bundle.sh, which I made generic for any claude/scripts/* rather than coverage-specific. The Makefile targets ship as a project-owned fragment (languages/elisp/coverage-makefile.txt) that install-lang.sh seeds at the project root and sync drops into .ai/inbox/ when that convention exists. The bundle never edits the project's own Makefile. Tests: 12 ERT for the kernel (Normal/Boundary/Error per function), wired into make test via a new languages/*/tests/ discovery path, plus bats for the sync auto-fix and the inbox-drop guards. This is the Elisp pilot. The pattern is proven, so fanning out to Python, Go, and TypeScript is now a follow-up. Each one needs only its own parser and fragment. The plumbing is already generic.
* fix(elisp): add themes/ to the validate-el.sh load pathCraig Jennings2026-05-251-0/+2
| | | | | | The PostToolUse hook byte-compiles each saved .el with -L for the project root, modules/, and tests/, but not themes/. A theme file that requires a sibling under themes/ then fails byte-compile with "Cannot open load file", a false VALIDATION FAILED even though the file loads fine at runtime. I added -L themes/ to both the byte-compile and test-runner blocks. Adding a load-path entry for a directory that doesn't exist is harmless to Emacs, so it stays unconditional, matching how modules/ and tests/ are already added without an existence guard.
* fix(elisp): gitignore the full Claude tooling footprintCraig Jennings2026-05-251-3/+4
| | | | | | The bundle tracked .claude/rules, CLAUDE.md, and githooks/, ignoring only the personal overrides. For a code project, especially a third-party package checkout, the whole Claude footprint should stay local: install and sync deliver it, so it shouldn't land in the project's history. gitignore-add.txt now ignores .claude/, CLAUDE.md, and githooks/ next to the elisp build artifacts. I also added install-lang.bats, which the bundle had no test for. It covers the landed footprint and the gitignore set.
* docs(languages): tighten elisp coding and testing rulesCraig Jennings2026-05-222-1/+45
| | | | Two audit fixes. elisp.md's "prefer Write over Edits" advice was tool-specific. It's now framed around intent: edit cohesively, then run paren and byte-compile checks immediately, whatever the editing mechanism. elisp-testing.md gains batch-mode reproducibility (emacs --batch as source of truth, no interactive state, no blocking prompts), state isolation (temp user-emacs-directory, explicit load-path, declared deps only), and byte-compile/native-comp warning handling, with native-comp gated on availability and kept opt-in.
* feat(hooks): add global hooks — PreCompact priorities + git/gh confirm modalsCraig Jennings2026-04-191-9/+24
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Three new machine-wide hooks installed via `make install-hooks`: - `precompact-priorities.sh` (PreCompact) — injects a priority block into the compaction prompt so the generated summary retains information most expensive to reconstruct: unanswered questions, root causes with file:line, subagent findings as primary evidence, exact numbers/IDs, A-vs-B decisions, open TODOs, classified-data handling. - `git-commit-confirm.py` (PreToolUse/Bash) — gates `git commit` behind a confirmation modal showing parsed message, staged files, diff stats, author. Parses both HEREDOC and `-m`/`--message` forms. - `gh-pr-create-confirm.py` (PreToolUse/Bash) — gates `gh pr create` behind a modal showing title, base ← head, reviewers, labels, assignees, milestone, draft flag, body (HEREDOC or quoted). Makefile: adds `install-hooks` / `uninstall-hooks` targets and extends `list` with a Hooks section. Install prints the settings.json snippet (in `hooks/settings-snippet.json`) to merge into `~/.claude/settings.json`. Also: `languages/elisp/claude/hooks/validate-el.sh` now emits JSON with `hookSpecificOutput.additionalContext` on failure (via new `fail_json()` helper) so Claude sees a structured error in context, in addition to the existing stderr output and exit 2. Patterns synthesized clean-room from fcakyon/claude-codex-settings (Apache-2.0). Each hook is original content.
* feat(rules): port key testing principles from quality-engineer promptCraig Jennings2026-04-191-0/+26
| | | | | | | | | | | | | | | | | | | | | | | Additions to claude-rules/testing.md: - Testing pyramid proportions (70-80% unit / 15-25% integration / 5-10% e2e) - Integration Tests section: docstring must name 'Components integrated:' and mark real vs mocked; when-to-write heuristics - Signs of Overmocking: 'would the test pass if the function body was NotImplementedError?' plus three more sharp questions - Testing Code That Uses Frameworks: test your integration, not the framework itself - Test Real Code, Not Copies: never inline prod code into tests - Error Behavior, Not Error Text: test type + key values, not exact prose - If Tests Are Hard to Write, Refactor the Code: hard-to-test is a code signal, not a test signal; extract focused helpers - Anti-patterns list extended Addition to languages/elisp/claude/rules/elisp-testing.md: - Interactive vs Internal split pattern: cj/foo wraps cj/--foo; test the internal directly, skip UI mocks Source: ~/.emacs.d/ai-prompts/quality-engineer.org (personal reference, kept as an extended prompt separate from these rules).
* chore: remove project-specific referencesCraig Jennings2026-04-191-3/+3
| | | | | | | | - elisp-testing.md: generalized testutil description. The specific files testutil-general.el / testutil-filesystem.el / testutil-org.el only exist in one project; bundle should describe the pattern, not name specific files. - README.org: install examples use ~/code/ path to match actual layout.
* feat: add commits.md rule — no AI attribution anywhereCraig Jennings2026-04-192-3/+9
| | | | | | | | | | | | | | New generic rule at claude-rules/commits.md covers author identity, absence of Claude/Anthropic/LLM/AI attribution (messages, PRs, comments, trailers, emojis), and conventional commit format. Applies to all repos. Bundle settings.json now sets attribution.commit: "" and attribution.pr: "" so Claude Code's default attribution is suppressed belt-and-suspenders with the written rule. Elisp CLAUDE.md template trimmed to reference commits.md instead of inlining the rules.
* chore(elisp): add *.elc and *.eln to gitignore templateCraig Jennings2026-04-191-0/+4
| | | | | | The validate-el.sh hook byte-compiles .el files, which produces .elc (and on Emacs 28+ with native-comp, .eln) artifacts. Projects using the bundle almost always want these ignored.
* fix(elisp): call package-initialize so byte-compile finds depsCraig Jennings2026-04-191-0/+2
| | | | | | | | | | | | | | | Byte-compile needs external packages on the load path to resolve (require ...) forms in project files. Without this, any project using MELPA/ELPA packages (dash, s, etc.) failed Phase 1 with "Cannot open load file". package-initialize reads package-user-dir (default ~/.emacs.d/elpa) and exposes installed package autoloads. Small latency cost (~100ms) but makes the hook work on real projects. Verified: - chime.el (requires dash) now byte-compiles cleanly; was failing. - emacs.d modules still pass; no regression.
* refactor(elisp): generalize validate-el.sh test-runner for flat layoutsCraig Jennings2026-04-191-4/+10
| | | | | | | | | | | | | | | | | | Phase 2 test lookup now triggers for any .el file outside tests/, not just modules/*.el. Stem-based test matching works the same way; this just broadens the case pattern. Before: only modules/foo.el → tests/test-foo*.el triggered Phase 2. After: foo.el, lib/foo.el, modules/foo.el all do. init.el and early-init.el are still Phase-1-only (byte-compile would load the full package graph). Verified on: - emacs.d (modules/-based): modules/browser-config.el still runs its matching test, exit 0 - flat layout (scratch /tmp): source.el at project root successfully finds and runs tests/test-source.el
* refactor: generalize testing.md, split Python specifics, DRY installCraig Jennings2026-04-192-42/+3
| | | | | | | | | | | | | | | | | | | claude-rules/testing.md is now language-agnostic (TDD principles, test categories, coverage targets, anti-patterns). Scope header widened to **/*. Python-specific content (pytest, fixtures, parametrize, anyio, Django DB testing) moved to languages/python/claude/rules/python-testing.md. Added languages/python/ bundle (rules only so far; no CLAUDE.md template or hooks yet — Python validation tooling differs from Elisp). Added install-python shortcut to the Makefile. Updated scripts/install-lang.sh to copy claude-rules/*.md into each target project's .claude/rules/. Bundles no longer need to carry their own verification.md copy — deleted languages/elisp/claude/rules/verification.md. Single source of truth in claude-rules/, fans out via install. Elisp-testing.md now references testing.md as its base (matches the python-testing.md pattern).
* feat: add per-project language bundles + elisp rulesetCraig Jennings2026-04-198-0/+463
Introduces a second install mode alongside the existing global symlinks: per-project language bundles that copy a language-specific Claude Code setup (rules, hooks, settings, pre-commit) into a target project. Layout additions: languages/elisp/ - Emacs Lisp bundle (rules, hooks, settings, CLAUDE.md) scripts/install-lang.sh - shared install logic Makefile additions: make help - unified help text make install-lang LANG=<lang> PROJECT=<path> [FORCE=1] make install-elisp PROJECT=<path> [FORCE=1] (shortcut) make list-languages - show available bundles Elisp bundle contents: - CLAUDE.md template (seed on first install, preserved on update) - .claude/rules/elisp.md, elisp-testing.md, verification.md - .claude/hooks/validate-el.sh (check-parens, byte-compile, run matching tests) - .claude/settings.json (permission allowlist, hook wiring) - githooks/pre-commit (secret scan + staged-file paren check) - gitignore-add.txt (append .claude/settings.local.json) Hooks use \$CLAUDE_PROJECT_DIR with a script-relative fallback, so the same bundle works on any machine or clone path. Install activates git hooks via core.hooksPath=githooks automatically. Re-running install is idempotent; CLAUDE.md is never overwritten without FORCE=1.