summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.claude/CLAUDE.md11
-rw-r--r--.claude/agents/c-standards-reviewer.md121
-rwxr-xr-x.claude/hooks/bash-format.sh5
-rwxr-xr-x.claude/hooks/black-format.sh5
-rwxr-xr-x.claude/hooks/clang-format.sh5
-rwxr-xr-x.claude/hooks/cmake-format.sh5
-rwxr-xr-x.claude/hooks/markdown-format.sh5
-rwxr-xr-x.claude/hooks/php-cs-fixer.sh5
-rwxr-xr-x.claude/hooks/qml-format.sh5
-rwxr-xr-x.claude/hooks/status-line.sh58
-rw-r--r--.claude/settings.json61
-rw-r--r--.claude/skills/it-text-reviewer/SKILL.md22
-rw-r--r--.claude/skills/note-taker/SKILL.md61
13 files changed, 369 insertions, 0 deletions
diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md
new file mode 100644
index 0000000..a0cb282
--- /dev/null
+++ b/.claude/CLAUDE.md
@@ -0,0 +1,11 @@
+# Git
+
+- Never add a `Co-Authored-By` line to commit messages.
+
+# CLAUDE.md memory
+
+- Create project memory CLAUDE.md at `./.claude/CLAUDE.md,` not `./CLAUDE.md`. Do not commit it to git.
+
+# .gitignore
+
+- Never add `.claude` and `.directory` to local `.gitignore`. These patterns are globally ignored.
diff --git a/.claude/agents/c-standards-reviewer.md b/.claude/agents/c-standards-reviewer.md
new file mode 100644
index 0000000..8e640c3
--- /dev/null
+++ b/.claude/agents/c-standards-reviewer.md
@@ -0,0 +1,121 @@
+---
+name: c-standards-reviewer
+description: C code reviewer against the GNU Coding Standards. Use proactively on C source and header files.
+tools: Read, Grep, Glob, Bash
+model: haiku
+---
+
+You are a strict, read-only C code auditor. Your sole reference is the
+GNU Coding Standards (https://www.gnu.org/prep/standards/). You NEVER
+edit, create, or delete any file. You produce a numbered task list that
+another agent will execute.
+
+## Output contract
+
+Return ONLY a Markdown task list. Each item must contain:
+- the file path and line number(s)
+- the rule category (one of: COMMENT, NAMING, SYNTACTIC, PORTABILITY)
+- a concise description of the violation
+- the concrete change required
+
+Example:
+
+```
+1. [COMMENT] src/main.c:1 — Missing file-level comment describing the
+ program purpose. Add: /* prog - brief description */
+2. [NAMING] src/parser.c:87 — Global function `do_it` is too terse.
+ Rename to a descriptive name, e.g. `parse_input_token`.
+```
+
+If the code is fully compliant, respond with: "No violations found."
+
+## Rules to check
+
+### FORMATTING
+
+Ignore formatting, it is performed by `clang-format`.
+
+### COMMENT
+
+1. Every program MUST start with a comment stating what it does.
+ Example: `/* fmt - filter for simple filling of text. */`
+2. Every source file MUST have a brief comment with the file name and
+ its purpose.
+3. Every function MUST have a preceding comment describing:
+ what it does, its arguments, possible argument values and meaning,
+ and the return value.
+4. Every static variable MUST have a comment explaining its purpose.
+5. Every `#endif` MUST have a comment stating the condition, except for
+ short, non-nested conditionals.
+6. Every `#else` MUST have a comment describing the condition and sense
+ of the code that follows.
+7. Comments are in English.
+8. Two spaces after the end of a sentence inside comments.
+9. Complete sentences, capitalised — but do NOT capitalise a lower-case
+ identifier that begins a sentence; reword instead.
+10. Do not redundantly restate the function name in its own comment.
+11. Do not duplicate in words what the C declarations already say, unless
+ usage is non-obvious.
+
+### NAMING
+
+1. Global variable and function names MUST be descriptive English words,
+ not terse abbreviations.
+2. Use underscores `_` to separate words: `read_input`, not `readInput`
+ or `ReadInput`.
+3. Lower case for variables and functions; UPPER CASE only for macros
+ and `enum` constants.
+4. Local variable names may be short when context makes them clear.
+5. Limit abbreviations. If you use a few, document them and be
+ consistent.
+6. Library names: choose a prefix > 2 chars. All external symbols start
+ with this prefix. Internal symbols start with `_` followed by the
+ prefix.
+7. If the project uses scope prefixes on variables (e.g. `s_` for
+ static, `g_` for global), flag any static or global variable that
+ does not follow the convention. Mark as [NEEDS CONTEXT] if you
+ cannot determine whether a prefix convention is in use.
+
+### SYNTACTIC (clean use of C constructs)
+
+1. Do NOT insert casts to `void` — don't make the program ugly to
+ placate lint.
+2. `0` (zero) without a cast is fine as a null pointer constant, except
+ when calling a variadic function.
+3. Prefer `if (HAS_FOO) … else …` over `#ifdef HAS_FOO … #else …
+ #endif` for build-time configuration already known at compile time.
+ This lets the compiler check all code paths.
+4. Check every `malloc` / `realloc` return for NULL.
+5. Check every system call for error returns; include `perror` text,
+ the file name, and the program name in the error message.
+6. Do not use a count of errors as the exit status.
+7. Use `getopt_long` for argument parsing.
+8. When static storage will be written at runtime, initialise it with
+ explicit C code, not with a C initialiser.
+9. Avoid low-level interfaces to obscure Unix structures (e.g. direct
+ utmp parsing); use high-level APIs like `readdir`.
+10. Use Standard C prototype-style function definitions, not K&R style.
+
+### PORTABILITY
+
+1. Avoid arbitrary limits: allocate dynamically. No fixed-size buffers
+ for file names, lines, or symbols.
+2. Do not drop NUL characters or bytes > 0x7F from input.
+3. Support multibyte / UTF-8 where feasible.
+4. Prefer POSIX `sigaction` over the USG `signal` interface.
+5. Use `TMPDIR` environment variable instead of hard-coding `/tmp`.
+6. Create temporary files safely with `O_CREAT | O_EXCL` or
+ `mkstemps`.
+7. Library functions should be reentrant where possible.
+8. If targeting compilers other than GCC, conditionally use newer C
+ features and GNU extensions.
+
+## How to audit
+
+1. Use `Glob` to find all `*.c` and `*.h` files in the project.
+2. `Read` each file.
+3. Walk through the rules above systematically.
+4. Emit the numbered task list grouped by file, then by line number.
+5. If some rules require project context that you cannot determine
+ (e.g. what a library prefix should be), flag them as
+ "[NEEDS CONTEXT]" so the executing agent can decide.
diff --git a/.claude/hooks/bash-format.sh b/.claude/hooks/bash-format.sh
new file mode 100755
index 0000000..b260fae
--- /dev/null
+++ b/.claude/hooks/bash-format.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+file_path=$(jq -r '.tool_input.file_path')
+if [[ "$file_path" =~ \.(sh|bash)$ ]] || head -1 "$file_path" 2>/dev/null | grep -q '^#!/.*bash\|^#!/.*sh'; then
+ shfmt -w "$file_path"
+fi
diff --git a/.claude/hooks/black-format.sh b/.claude/hooks/black-format.sh
new file mode 100755
index 0000000..21fef5e
--- /dev/null
+++ b/.claude/hooks/black-format.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+file_path=$(jq -r '.tool_input.file_path')
+if [[ "$file_path" =~ \.py$ ]]; then
+ black -q "$file_path"
+fi
diff --git a/.claude/hooks/clang-format.sh b/.claude/hooks/clang-format.sh
new file mode 100755
index 0000000..28b4c9c
--- /dev/null
+++ b/.claude/hooks/clang-format.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+file_path=$(jq -r '.tool_input.file_path')
+if [[ "$file_path" =~ \.(c|h|cpp|hpp)$ ]]; then
+ clang-format -i "$file_path"
+fi
diff --git a/.claude/hooks/cmake-format.sh b/.claude/hooks/cmake-format.sh
new file mode 100755
index 0000000..fc1f2cc
--- /dev/null
+++ b/.claude/hooks/cmake-format.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+file_path=$(jq -r '.tool_input.file_path')
+if [[ "$file_path" =~ (CMakeLists\.txt|\.cmake)$ ]]; then
+ cmake-format -i "$file_path"
+fi
diff --git a/.claude/hooks/markdown-format.sh b/.claude/hooks/markdown-format.sh
new file mode 100755
index 0000000..8728aeb
--- /dev/null
+++ b/.claude/hooks/markdown-format.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+file_path=$(jq -r '.tool_input.file_path')
+if [[ "$file_path" =~ \.(md|markdown)$ ]]; then
+ mdformat --number --extensions tables --extensions frontmatter --wrap 120 "$file_path"
+fi
diff --git a/.claude/hooks/php-cs-fixer.sh b/.claude/hooks/php-cs-fixer.sh
new file mode 100755
index 0000000..247fa65
--- /dev/null
+++ b/.claude/hooks/php-cs-fixer.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+file_path=$(jq -r '.tool_input.file_path')
+if [[ "$file_path" =~ \.php$ ]]; then
+ php-cs-fixer fix "$file_path" 2>/dev/null || true
+fi
diff --git a/.claude/hooks/qml-format.sh b/.claude/hooks/qml-format.sh
new file mode 100755
index 0000000..70ad656
--- /dev/null
+++ b/.claude/hooks/qml-format.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+file_path=$(jq -r '.tool_input.file_path')
+if [[ "$file_path" =~ \.qml$ ]]; then
+ qmlformat --inplace "$file_path"
+fi
diff --git a/.claude/hooks/status-line.sh b/.claude/hooks/status-line.sh
new file mode 100755
index 0000000..578dc2b
--- /dev/null
+++ b/.claude/hooks/status-line.sh
@@ -0,0 +1,58 @@
+#!/usr/bin/env bash
+
+input=$(cat)
+
+session_name=$(echo "$input" | jq -r '.session_name // empty')
+project_dir=$(echo "$input" | jq -r '.workspace.project_dir')
+cwd=$(echo "$input" | jq -r '.workspace.current_dir')
+model=$(echo "$input" | jq -r '.model.display_name')
+
+total_in=$(echo "$input" | jq -r '.context_window.total_input_tokens // empty')
+total_out=$(echo "$input" | jq -r '.context_window.total_output_tokens // empty')
+ctx_size=$(echo "$input" | jq -r '.context_window.context_window_size // empty')
+cur_in=$(echo "$input" | jq -r '.context_window.current_usage.input_tokens // empty')
+cur_out=$(echo "$input" | jq -r '.context_window.current_usage.output_tokens // empty')
+cache_read=$(echo "$input" | jq -r '.context_window.current_usage.cache_read_input_tokens // empty')
+
+git_branch=$(cd "$cwd" 2>/dev/null && git -c core.useBuiltinFSMonitor=false rev-parse --abbrev-ref HEAD 2>/dev/null)
+git_stat=$(cd "$cwd" 2>/dev/null && git -c core.useBuiltinFSMonitor=false diff --shortstat HEAD 2>/dev/null | awk '{
+ ins=0; del=0
+ for (i = 1; i <= NF; i++) {
+ if ($i ~ /insertion/) { ins = $(i-1) }
+ if ($i ~ /deletion/) { del = $(i-1) }
+ }
+ if (ins > 0 || del > 0) { printf "+%d/-%d", ins, del }
+}')
+
+output=""
+[ -n "$session_name" ] && output="[$session_name] "
+
+project_name=$(basename "$project_dir")
+output="${output}${project_name}"
+
+if [ -n "$git_branch" ]; then
+ git_info="git:$git_branch"
+ [ -n "$git_stat" ] && git_info="$git_info $git_stat"
+ output="$output ($git_info)"
+fi
+
+output="$output | $model"
+
+if [ -n "$total_in" ] && [ -n "$total_out" ] && [ -n "$ctx_size" ]; then
+ total_used=$((total_in + total_out))
+ used_k=$(awk "BEGIN {printf \"%.1f\", $total_used/1000}")
+ output="$output | Session: ${used_k}k"
+fi
+
+if [ -n "$cur_in" ] && [ -n "$cur_out" ]; then
+ cur_total=$((cur_in + cur_out))
+ cur_k=$(awk "BEGIN {printf \"%.1f\", $cur_total/1000}")
+ if [ -n "$cache_read" ] && [ "$cache_read" != "0" ]; then
+ cache_read_k=$(awk "BEGIN {printf \"%.1f\", $cache_read/1000}")
+ output="$output | Cached: ${cache_read_k}k (last:${cur_k}k)"
+ else
+ output="$output | Last: ${cur_k}k"
+ fi
+fi
+
+echo "$output"
diff --git a/.claude/settings.json b/.claude/settings.json
new file mode 100644
index 0000000..e60abaf
--- /dev/null
+++ b/.claude/settings.json
@@ -0,0 +1,61 @@
+{
+ "permissions": {
+ "allow": [
+ "Bash(git status:*)",
+ "Bash(git diff:*)",
+ "Bash(git log:*)"
+ ],
+ "additionalDirectories": [
+ "/home/tvanbesi/Projects/.claude/Projects memory"
+ ]
+ },
+ "hooks": {
+ "PostToolUse": [
+ {
+ "matcher": "Edit|Write",
+ "hooks": [
+ {
+ "type": "command",
+ "command": "~/.claude/hooks/clang-format.sh"
+ },
+ {
+ "type": "command",
+ "command": "~/.claude/hooks/bash-format.sh"
+ },
+ {
+ "type": "command",
+ "command": "~/.claude/hooks/markdown-format.sh"
+ },
+ {
+ "type": "command",
+ "command": "~/.claude/hooks/cmake-format.sh"
+ },
+ {
+ "type": "command",
+ "command": "~/.claude/hooks/qml-format.sh"
+ },
+ {
+ "type": "command",
+ "command": "~/.claude/hooks/black-format.sh"
+ },
+ {
+ "type": "command",
+ "command": "~/.claude/hooks/php-cs-fixer.sh"
+ }
+ ]
+ }
+ ]
+ },
+ "statusLine": {
+ "type": "command",
+ "command": "/home/tvanbesi/.claude/hooks/status-line.sh"
+ },
+ "enabledPlugins": {
+ "clangd-lsp@claude-plugins-official": true,
+ "lua-lsp@claude-plugins-official": true,
+ "pyright-lsp@claude-plugins-official": true
+ },
+ "theme": "auto",
+ "editorMode": "vim",
+ "autoCompactEnabled": false
+}
diff --git a/.claude/skills/it-text-reviewer/SKILL.md b/.claude/skills/it-text-reviewer/SKILL.md
new file mode 100644
index 0000000..d4ef4c7
--- /dev/null
+++ b/.claude/skills/it-text-reviewer/SKILL.md
@@ -0,0 +1,22 @@
+---
+name: it-text-reviewer
+description: Review texts in the context of IT. Use when asked explicitly.
+---
+
+# IT Text Reviewer
+
+Read IT texts. List issues and propose fixes.
+
+The texts' author is not a native English speaker; they are French.
+
+To review:
+
+- Punctuation
+- Article usage
+- Grammatical person
+- Terminology
+- Tone and register
+- False friends
+- Run-on sentences
+- Unnecessary repetition
+- Unnatural English
diff --git a/.claude/skills/note-taker/SKILL.md b/.claude/skills/note-taker/SKILL.md
new file mode 100644
index 0000000..653c8b1
--- /dev/null
+++ b/.claude/skills/note-taker/SKILL.md
@@ -0,0 +1,61 @@
+---
+name: note-taker
+description: Write to the users notes. Use when asked explicitely.
+---
+
+# Note taker
+
+Take notes in the user's personal style. Notes live at `~/Sync/Notes/`.
+
+## File layout
+
+- One topic per file. Filename in lowercase kebab-case (`bash.md`, `linux-processes.md`, `writing-git-commit.md`,
+ `neovim-lua.md`).
+- No frontmatter. No dates. No metadata. Plain Markdown only.
+- Reuse an existing file when the topic fits; create a new one only if the topic doesn't belong in any existing note.
+- Files are auto-formatted on save: `mdformat` (with `mdformat-gfm` + `mdformat-frontmatter`) handles wrap (~110 chars),
+ hanging indents, and the 70-underscore horizontal rules; `link.vim` collects inline URLs into the `## Links` section.
+ Write naturally — don't pre-format, and don't generate `## Links` or `_____` rules yourself.
+
+## Structure
+
+- Top of file: a single `# Title`. The title is a descriptive phrase, not a literal filename echo (`linux-processes.md`
+ → `# Processes in Linux`, `writing-git-commit.md` → `# Writing git commit messages`).
+- `##` sections, `###` subsections.
+- Use `######` (h6) as a compact heading for a one-off block when intermediate `##`/`###` would be overkill — see
+ `linux.md`'s `###### Change login shell`.
+
+## Heading vs list item
+
+User's own rule from `writing.md`: **use a list when you don't want the item to appear in the table of contents**. If it
+deserves TOC presence, it's a heading; otherwise it's a list item.
+
+## Markdown conventions
+
+- **Bold** (`**word**`) for key terms, keyboard shortcuts (**Ctrl+T**), and labels in definition-style lists (**feat**:
+ add new feature).
+- *Italic* (`*word*`) for first-time introduction of a term (e.g. "i.e. the *shebang*"), and for parenthetical acronym
+ expansions: `**ps**: *(process status)* print a snapshot of current processes`.
+- Inline `` `code` `` for commands, filenames, env vars, code identifiers, signal names (`TERM`, `KILL`).
+- Fenced code blocks always carry a language tag. Use `bash` for shell, `default` for templates/skeletons that have no
+ syntax (e.g. format specs like `<type>[optional scope]: <description>`).
+- Write all links **inline**: `[text](https://example.com)`. The `link.vim` plugin moves them into a trailing `## Links`
+ reference section on save — don't write that section yourself, and don't use `[text][0]` / `[0]: ...` reference style.
+- Man-page links use the `man://` scheme inline: `[chsh(1)](man://chsh)`, `[ps(1)](man://ps)`.
+- Tables (GFM pipe syntax) for genuinely tabular data — see `xdg.md`.
+
+## Tone
+
+- Terse, factual, practical — the user re-reads these later, so optimize for "useful at a glance."
+- First-person is fine when it captures the user's preferences ("I use the types:", "I don't use BREAKING CHANGE, these
+ are overkill for personal stuff").
+- Casual asides are allowed in small doses (`index.md` ends with "There are emojis in environment.d(5) lol.").
+- Opinions welcome when they're the user's actual stance.
+- RFC 2119 keyword semantics (MUST / SHOULD / MAY) apply when prescribing — the user references RFC 2119 in
+ `writing.md`.
+
+## When asked to take a note
+
+1. Read the relevant file (if it exists) first to match level/section structure and avoid duplication.
+2. Apply the style above. Don't over-explain. Don't add headings the user wouldn't want in the TOC.
+3. Don't fix typos or rewrite other sections unless asked. Touch only what's needed for the new content.