Skip to content

feat: add semantic-anchors Claude Code plugin with onboarding skill and pre-commit sync#203

Open
cpoepke wants to merge 2 commits intoLLM-Coding:mainfrom
cpoepke:main
Open

feat: add semantic-anchors Claude Code plugin with onboarding skill and pre-commit sync#203
cpoepke wants to merge 2 commits intoLLM-Coding:mainfrom
cpoepke:main

Conversation

@cpoepke
Copy link

@cpoepke cpoepke commented Mar 17, 2026

Adds a Skill and Claude Code plugin that installs semantic anchor context into coding agents (Claude Code, Codex, Gemini CLI, Copilot, Cursor) at session start, plus a translator skill for recognising established methodologies in prompts.

What is included

Plugin infrastructure (plugins/semantic-anchors/)

  • plugin.json, tile.json: plugin manifest and marketplace tile (Claude only)
  • hooks/hooks.json + scripts/prompt-onboarding.sh: SessionStart hook that fires once per 24 h when no semantic-anchor block is present, prompting the user to run onboarding. Cooldown and project state tracked in ~/.claude/semantic-anchor-onboarding/state.json. Hardened against malformed state files (JSONDecodeError, ValueError on fromisoformat).
  • .claude-plugin/marketplace.json: marketplace registration

Semantic anchor onboarding skill (skill/semantic-anchor-onboarding/) 6-step workflow for installing a small, stable set of semantic anchors into AGENTS.md / CLAUDE.md / GEMINI.md / copilot-instructions.md:

  1. Decide scope (project vs. home directory)
  2. Select anchors — conflict groups, always-on defaults, task-local list
  3. Render the anchor block from assets/templates/anchor-block.md
  4. Run scripts/install.sh (idempotent marker-based injection, pure sh)
  5. Add native agent behaviour (Claude hook, Gemini mirror, Copilot instructions)
  6. Validate on a fresh session

Supports: Claude Code, Codex/OpenAI, Gemini CLI, GitHub Copilot, Cursor. Platform: Unix/macOS and Windows (Git Bash). No dependencies beyond sh and python3 (already required for JSON manipulation in hooks).

  • scripts/install.sh: injects/replaces the anchor block in the best available markdown file; installs a Claude SessionStart hook when --claude-hook is passed; backs up settings.json with plain cp before overwriting
  • references/anchor-selection.md: category guide, conflict groups, safe always-on defaults, task-local list
  • references/agent-support.md: per-agent loading rules and portability notes
  • assets/templates/: starter templates for AGENTS.md, CLAUDE.md, GEMINI.md, copilot-instructions.md, anchor-block.md

Semantic anchor translator skill (skill/semantic-anchor-translator/) Updated catalog.md with:

  • New entries: ATAM, LASR by Toth/Zörner, OWASP Top 10 (were referenced but undefined)
  • Missing Proponents added: Testing Pyramid (Mike Cohn), Property-Based Testing (Claessen/Hughes), Clean Architecture (Robert C. Martin), Hexagonal Architecture (Alistair Cockburn)
  • Missing Also-known-as added: Clean Architecture, Hexagonal Architecture

Pre-commit sync hook (.githooks/pre-commit)

Overwrites plugins/semantic-anchors/skills/ from skill/ on every commit so the two never diverge. Pure sh — no extra dependencies, works on Unix/macOS and Windows Git Bash. Activate once after cloning:
git config core.hooksPath .githooks

scripts/sync-claude-plugin.sh changed from bash to POSIX sh (set -eu, no pipefail). plugins/semantic-anchors/skills/README.md added with do-not-edit notice. CLAUDE.md updated with first-time setup instruction.

Summary by CodeRabbit

Release Notes

  • New Features

    • Neues Semantic Anchors Plugin für persistente Coding-Agent-Kontexte und Prompting
    • Onboarding-Workflow mit automatischer SessionStart-Integration
    • Unterstützung für Claude, Codex, Gemini CLI, GitHub Copilot, Cursor und Windsurf
  • Documentation

    • Installationsanleitungen und Agent-Konfigurationsvorlagen hinzugefügt
    • Semantic-Anchor-Katalog und Auswahlhilfen für Entwickler
  • Chores

    • Git Hook Setup für automatische Plugin-Synchronisierung
    • First-Time Setup Dokumentation hinzugefügt

@coderabbitai
Copy link

coderabbitai bot commented Mar 17, 2026

Walkthrough

Dieser Pull Request führt ein umfassendes Semantic-Anchors-Plugin-System ein, das es Coding-Agenten (Claude, Codex, Gemini, Cursor, GitHub Copilot, Windsurf) ermöglicht, persistente kontextuelle Anker zu installieren und zu verwalten. Das System umfasst Plugin-Manifeste, Git Hooks für Synchronisierung, Installationsskripte und umfangreiche Dokumentation sowie Vorlagen für verschiedene Agenten.

Changes

Cohort / File(s) Summary
Plugin-Manifeste und Konfiguration
.claude-plugin/marketplace.json, plugins/semantic-anchors/plugin.json, plugins/semantic-anchors/tile.json, plugins/semantic-anchors/hooks/hooks.json
Neue Manifest-Dateien für die Registrierung des Semantic-Anchors-Plugins im Claude Marketplace und für lokale Plugin-Konfiguration mit Onboarding-Hooks.
Git Hooks und Synchronisationsskripte
.githooks/pre-commit, scripts/sync-claude-plugin.sh
Pre-Commit-Hook zur automatischen Synchronisierung von Skill-Dateien aus dem kanonischen skill/-Verzeichnis in das Plugin-Verzeichnis; Synchronisierungsskript zur rekursiven Kopie von Skill-Verzeichnissen.
Dokumentation und Setup-Anleitung
CLAUDE.md, README.md, README.adoc
Neue Abschnitte zur Dokumentation des First-Time-Setup für Git Hooks und Installationsleitfäden für verschiedene Coding-Agenten (Codex, Claude Code, Gemini CLI, Cursor, GitHub Copilot, Windsurf).
Onboarding-Skills und Assets
skill/semantic-anchor-onboarding/SKILL.md, plugins/semantic-anchors/skills/semantic-anchor-onboarding/SKILL.md, skill/semantic-anchor-onboarding/assets/templates/*, plugins/semantic-anchors/skills/semantic-anchor-onboarding/assets/templates/*
Umfassende Dokumentation und Markdown-Vorlagen (AGENTS.md, CLAUDE.md, GEMINI.md, anchor-block.md, copilot-instructions.md) für die Konfiguration von Semantic Anchors auf Projekt- und Home-Ebene.
Onboarding-Referenzen
skill/semantic-anchor-onboarding/references/agent-support.md, skill/semantic-anchor-onboarding/references/anchor-selection.md, plugins/semantic-anchors/skills/semantic-anchor-onboarding/references/*
Referenzdokumente mit Agent-Support-Matrix, Onboarding-Interview-Flow, Konfliktauflösungsregeln und kategoriegesteuerte Anker-Selektionsleitfäden für verschiedene Domänen.
Onboarding-Agent-Konfiguration
skill/semantic-anchor-onboarding/agents/openai.yaml, plugins/semantic-anchors/skills/semantic-anchor-onboarding/agents/openai.yaml
OpenAI-Agent-Schnittstellenkonfiguration mit Anzeigename, Kurzbeschreibung und Standard-Prompt für die Semantic-Anchor-Installation.
Onboarding-Skripte
plugins/semantic-anchors/scripts/prompt-onboarding.sh, skill/semantic-anchor-onboarding/scripts/claude-session-start.sh, skill/semantic-anchor-onboarding/scripts/install.sh, plugins/semantic-anchors/skills/semantic-anchor-onboarding/scripts/claude-session-start.sh
Bash-Skripte für Onboarding-Abläufe: Prompt mit Abkühlzeit-Verwaltung, SessionStart-Hook zum Extrahieren von Anker-Blöcken, und umfassendes Installationsskript zur Injizierung und Hook-Integration.
Translator-Skills
plugins/semantic-anchors/skills/semantic-anchor-translator/SKILL.md, plugins/semantic-anchors/skills/semantic-anchor-translator/references/catalog.md
Dokumentation und umfangreicher Katalog für den Semantic-Anchor-Translator mit Recognition- und Guidance-Modi sowie kategorisiertem Anker-Katalog über Testing, Architecture, Design, Problem-Solving und weitere Domänen.
Skills-Verzeichnis-Verwaltung
plugins/semantic-anchors/skills/README.md
Hinweisdatei zur automatischen Generierung und Pre-Commit-Synchronisierung von Skill-Dateien mit Anleitung zur Bearbeitung von Quellen im skill/-Verzeichnis.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Die Änderungen umfassen heterogene Inhalte: mehrere Shell-Skripte mit Logik (Installationsskript mit 263 Zeilen, Prompt-Onboarding mit Kühlzeit-Verwaltung), verschiedene Manifest-Formate, umfangreiche Dokumentation und Vorlagen. Während viele Dateien reine Dokumentation sind, erfordern die Skripte (insbesondere install.sh mit JSON-Manipulation und Pfadberechnung) sorgfältige Überprüfung. Die Vielzahl unterschiedlicher Dateitypen und Zwecke erfordert separate Überprüfung für jede Kategorie.

Possibly related PRs

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed Der PR-Titel beschreibt präzise die Hauptänderungen: Hinzufügung eines semantischen Ankern-Plugins für Claude Code mit Onboarding-Skill und Pre-Commit-Synchronisierung.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@cpoepke cpoepke force-pushed the main branch 5 times, most recently from b6e4b90 to 331e199 Compare March 17, 2026 18:48
…nd pre-commit sync

Contributed by Conrad Pöpke (github.com/cpoepke) — plugin and skill author.
This commit adds tooling for coding agents; it does not change the semantic
anchor catalog maintained by the LLM-Coding/Semantic-Anchors community.

Adds a complete Claude Code plugin that installs semantic anchor context into
coding agents (Claude Code, Codex, Gemini CLI, Copilot, Cursor) at session start,
plus a translator skill for recognising established methodologies in prompts.

## What is included

### Plugin infrastructure (plugins/semantic-anchors/)
- plugin.json, tile.json: plugin manifest and marketplace tile
- hooks/hooks.json + scripts/prompt-onboarding.sh: SessionStart hook that fires
  once per 24 h when no semantic-anchor block is present, prompting the user to
  run onboarding. Cooldown and project state tracked in ~/.claude/semantic-anchor-onboarding/state.json.
  Hardened against malformed state files (JSONDecodeError, ValueError on fromisoformat).
- .claude-plugin/marketplace.json: marketplace registration

### Semantic anchor onboarding skill (skill/semantic-anchor-onboarding/)
6-step workflow for installing a small, stable set of semantic anchors into
AGENTS.md / CLAUDE.md / GEMINI.md / copilot-instructions.md:
1. Decide scope (project vs. home directory)
2. Select anchors — conflict groups, always-on defaults, task-local list
3. Render the anchor block from assets/templates/anchor-block.md
4. Run scripts/install.sh (idempotent marker-based injection, pure sh)
5. Add native agent behaviour (Claude hook, Gemini mirror, Copilot instructions)
6. Validate on a fresh session

Supports: Claude Code, Codex/OpenAI, Gemini CLI, GitHub Copilot, Cursor.
Platform: Unix/macOS and Windows (Git Bash). No dependencies beyond sh and python3
(already required for JSON manipulation in hooks).

- scripts/install.sh: injects/replaces the anchor block in the best available
  markdown file; installs a Claude SessionStart hook when --claude-hook is passed;
  backs up settings.json with plain cp before overwriting
- references/anchor-selection.md: category guide, conflict groups, safe always-on
  defaults, task-local list
- references/agent-support.md: per-agent loading rules and portability notes
- assets/templates/: starter templates for AGENTS.md, CLAUDE.md, GEMINI.md,
  copilot-instructions.md, anchor-block.md

### Semantic anchor translator skill (skill/semantic-anchor-translator/)
Updated catalog.md with:
- New entries: ATAM, LASR by Toth/Zörner, OWASP Top 10 (were referenced but undefined)
- Missing Proponents added: Testing Pyramid (Mike Cohn), Property-Based Testing
  (Claessen/Hughes), Clean Architecture (Robert C. Martin), Hexagonal Architecture
  (Alistair Cockburn)
- Missing Also-known-as added: Clean Architecture, Hexagonal Architecture

### Pre-commit sync hook (.githooks/pre-commit)
Overwrites plugins/semantic-anchors/skills/ from skill/ on every commit so the
two never diverge. Pure sh — no extra dependencies, works on Unix/macOS and
Windows Git Bash. Activate once after cloning:
  git config core.hooksPath .githooks

scripts/sync-claude-plugin.sh changed from bash to POSIX sh (set -eu, no pipefail).
plugins/semantic-anchors/skills/README.md added with do-not-edit notice.
CLAUDE.md updated with first-time setup instruction.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@rdmueller
Copy link
Member

this sounds like a great idea. You marked this as Draft, so I will wait until it is ready for review!

- Add setup guides for Gemini CLI, Claude Code, Cursor, and Copilot
- Include link to automated install.sh for broad agent coverage
- Standardize on AGENTS.md as portable baseline across environments
@cpoepke cpoepke marked this pull request as ready for review March 17, 2026 22:01
@cpoepke
Copy link
Author

cpoepke commented Mar 17, 2026

this sounds like a great idea. You marked this as Draft, so I will wait until it is ready for review!

@rdmueller there you go. Hope this works as intended for all coding agents 😅

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 12

🧹 Nitpick comments (1)
plugins/semantic-anchors/skills/README.md (1)

3-4: Sync-Beschreibung präzisieren (betrifft nur Skill-Unterordner).

Die Aussage ist aktuell zu allgemein. Der Sync-Job überschreibt nur Unterverzeichnisse aus skill/*, nicht zwingend jede Datei im Verzeichnis (z. B. Root-README-Dateien).

💡 Präziser Formulierungsvorschlag
-The files in this directory are copied from `skill/` by `scripts/sync-claude-plugin.sh`
-and overwritten automatically on every commit via `.githooks/pre-commit`.
+Skill subdirectories in this directory are copied from `skill/` by
+`scripts/sync-claude-plugin.sh` and overwritten on every commit via
+`.githooks/pre-commit`.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@plugins/semantic-anchors/skills/README.md` around lines 3 - 4, Die aktuelle
Formulierung ist zu allgemein; ändere die README-Zeile so sie erklärt, dass das
Skript scripts/sync-claude-plugin.sh nur Unterverzeichnisse aus skill/* in
dieses Verzeichnis kopiert und diese Unterverzeichnisse bei jedem Commit durch
.githooks/pre-commit überschrieben werden, aber nicht zwingend einzelne Dateien
im Plugin-Root (z. B. globale README-Dateien). Erwähne explizit
"Unterverzeichnisse aus skill/*" und nenne scripts/sync-claude-plugin.sh sowie
.githooks/pre-commit als die verantwortlichen Mechanismen, damit die Aussage
präzise und nicht irreführend ist.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.claude-plugin/marketplace.json:
- Around line 6-16: The top-level "name" value ("LLM Coding") and the plugin
author.name ("LLM-Coding") are inconsistent; pick the canonical publisher name
and make both occurrences identical (update the top-level "name" and the
plugins[...].author.name to the chosen value). Ensure the same exact string is
used for any other publisher name occurrences in this file (e.g., plugin
metadata) so marketplace surfaces a single unified publisher name.

In @.githooks/pre-commit:
- Around line 10-16: Der Hook ruft das Sync-Script mit sh
"$REPO_ROOT/scripts/sync-claude-plugin.sh" auf, prüft das Ergebnis aber nicht,
sodass ein Fehlschlag stillschweigend ignoriert wird; ändere die Hook-Logik im
.githooks/pre-commit so dass der Hook beim Fehler des Sync-Scripts sofort
abbricht (z.B. set -e ganz oben oder unmittelbar nach dem Aufruf den Exit-Status
prüfen und mit exit 1 beenden), damit der nachfolgende git -C "$REPO_ROOT" add
-- plugins/semantic-anchors/skills/ nie ausgeführt wird wenn das Sync-Script
fehlschlägt.

In `@plugins/semantic-anchors/scripts/prompt-onboarding.sh`:
- Around line 47-69: The state write is not atomic and I/O errors can abort the
hook; update the block that writes state (around state_path, json.dump and
entry["last_prompt"]) to perform an atomic write: write JSON to a temporary file
in the same directory (e.g., using tempfile.NamedTemporaryFile), flush and
os.fsync the file, then os.replace the temp file onto state_path to ensure
atomic swap; wrap the entire write/replace in an OSError/IOError except that
logs the error (or prints) and continues (fail-open) instead of letting the
process crash so the hook won’t abort on write failures. Ensure you keep the
existing read handling (open state_path) and that entry["last_prompt"] is still
set before attempting the atomic write.

In
`@plugins/semantic-anchors/skills/semantic-anchor-onboarding/scripts/claude-session-start.sh`:
- Around line 1-5: The three onboarding scripts currently require Bash because
they use a bash-only shebang and pipefail: change each script's interpreter line
from "#!/bin/bash" to "#!/bin/sh" and replace "set -euo pipefail" with "set -eu"
so they run under POSIX sh; update this in all copies for install.sh,
claude-session-start.sh, and prompt-onboarding.sh both in the skill/ originals
and the synced copies under plugins/semantic-anchors/skills/... to ensure
consistent behavior across sync-claude-plugin.sh and avoid bash-only
assumptions.

In
`@plugins/semantic-anchors/skills/semantic-anchor-translator/references/catalog.md`:
- Around line 167-170: Update the text under the "Feynman Technique" heading
where the line currently reads "Explain concept simply" to a grammatically
correct phrasing such as "Explain concepts simply" or "Explain a concept
simply"; locate and edit the exact string "Explain concept simply" in the
catalog entry to apply the change.

In `@README.md`:
- Around line 43-50: The README example uses the raw template (anchor-block.md)
as the --source for the install.sh installer, which copies placeholders like
{{PRIMARY_ANCHOR_*}} into the target; update the example to demonstrate
preprocessing or using a resolved temporary file instead (e.g., create
/tmp/semantic-anchor-block.md with the concrete anchors) and then call
install.sh with that file as --source, or add a short note instructing to run
the template-render step before calling install.sh; refer to the template file
name anchor-block.md and the installer invocation (install.sh with --source,
--target-dir, --scope) so readers replace the raw template with a
concrete/filled file or perform template rendering first.

In `@scripts/sync-claude-plugin.sh`:
- Around line 13-18: Der Sync lässt verwaiste Zielordner in $PLUGIN_SKILLS_DIR
zurück; erweitere das Skript (im Bereich der bestehenden for-loop über
"$SOURCE_DIR"/*) so dass es zuerst alle Ziel-Skill-Ordner listet und für jeden
Zielnamen prüft, ob ein entsprechender Quellordner "$SOURCE_DIR/$skill_name"
existiert, andernfalls den Zielordner entfernt; zusätzlich härte das Entfernen
ab, indem du vor dem rm -rf sicherstellst, dass die zu löschende Variable nicht
leer ist und einen sicheren Pfad innerhalb $PLUGIN_SKILLS_DIR enthält (z.B. nur
löschen, wenn der Path mit "$PLUGIN_SKILLS_DIR/" beginnt), und dann die
Kopier-Logik (cp -R "$skill_dir" ...) wie jetzt beibehältst.

In `@skill/semantic-anchor-onboarding/references/anchor-selection.md`:
- Around line 34-40: Die Liste in anchor-selection.md ist nicht synchron mit dem
Katalog; überprüfe die referenzierten Anker (ATAM; Docs-as-Code according to
Ralf D. Müller; Domain-Driven Design according to Evans; LASR by Toth/Zörner;
Mental Model according to Naur; OWASP Top 10; Pyramid Principle according to
Barbara Minto; The Spectrum of Semantic Anchors) gegen
skill/semantic-anchor-translator/references/catalog.md and either add the
missing/renamed entries to the catalog or update the names in
skill/semantic-anchor-onboarding/references/anchor-selection.md to exactly match
the canonical identifiers used in the catalog so the catalog remains the single
source of truth.

In `@skill/semantic-anchor-onboarding/scripts/install.sh`:
- Around line 142-154: The script currently only checks for MARKER_START and
then runs an awk block that sets in_block until MARKER_END, which will drop the
rest of target_file if MARKER_END is missing; before performing the awk replace
(the block that reads MARKER_START/MARKER_END, INJECTED_FILE, writes
REPLACED_FILE and mv's it over target_file), add a pre-check that both
MARKER_START and MARKER_END exist and that the end marker comes after the start
marker (e.g., inspect target_file for both markers and their relative
positions), and bail out with a non-zero return if the pair is not found in
correct order to keep the installer idempotent and portable.
- Around line 28-40: Die case-Armles in install.sh lesen $2 direkt (für
SOURCE_FILE, TARGET_DIR, SCOPE) und schlagen bei fehlenden Optionswerten mit
"unbound variable" fehl; vor dem Zugriff auf $2 prüfe jeweils, dass ein weiteres
Argument existiert (z.B. mittels Prüfung auf "${2-}" oder "$#" >= 2) und dass es
kein weiteres Flag ist, und falls nicht, gib eine Usage-Fehlermeldung und exit;
aktualisiere die case-Branches für --source, --target-dir und --scope
entsprechend, so dass fehlende Werte abgefangen und sprechende Fehler ausgegeben
werden.
- Around line 222-244: The current loop only checks for exact equality of
hook.get("command") to decide deduplication, so if the managed command target
changes a new hook is appended; instead, when iterating session_start -> entry
-> hooks, detect existing managed semantic-anchor hooks by a stable identifier
(e.g., hook.get("type") == "command" and the hook command contains the known
tool prefix or matches the command basename) and update that hook's "command"
value to the new command variable rather than appending a duplicate; use the
existing variables session_start, entry, hooks and command to find and replace
hook["command"]=command and then break, otherwise append the new matcher/hooks
block as before.

In `@skill/semantic-anchor-onboarding/SKILL.md`:
- Around line 29-33: Die Dokumentation in SKILL.md muss präzisiert werden:
ersetzen Sie die ungenaue Formulierung "inject into the first suitable existing
markdown file" durch eine explizite Aufzählung der tatsächlich verwendeten
Kandidaten und verweisen Sie auf die Auswahl-Logik in select_target_file();
nennen Sie dort die feste Liste (AGENTS.md, CLAUDE.md, GEMINI.md,
.github/copilot-instructions.md, .claude/AGENTS.md) und ergänzen Sie einen
kurzen Hinweis, dass dieselbe Liste vom Prompt-Hook überprüft wird, damit
zukünftige Wartende und Implementierer die Einschränkung sofort erkennen.

---

Nitpick comments:
In `@plugins/semantic-anchors/skills/README.md`:
- Around line 3-4: Die aktuelle Formulierung ist zu allgemein; ändere die
README-Zeile so sie erklärt, dass das Skript scripts/sync-claude-plugin.sh nur
Unterverzeichnisse aus skill/* in dieses Verzeichnis kopiert und diese
Unterverzeichnisse bei jedem Commit durch .githooks/pre-commit überschrieben
werden, aber nicht zwingend einzelne Dateien im Plugin-Root (z. B. globale
README-Dateien). Erwähne explizit "Unterverzeichnisse aus skill/*" und nenne
scripts/sync-claude-plugin.sh sowie .githooks/pre-commit als die
verantwortlichen Mechanismen, damit die Aussage präzise und nicht irreführend
ist.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: 94cab3c4-f585-4899-a4f3-8a3ceb991e20

📥 Commits

Reviewing files that changed from the base of the PR and between f8029c0 and aaa3e28.

📒 Files selected for processing (35)
  • .claude-plugin/marketplace.json
  • .githooks/pre-commit
  • CLAUDE.md
  • README.adoc
  • README.md
  • plugins/semantic-anchors/hooks/hooks.json
  • plugins/semantic-anchors/plugin.json
  • plugins/semantic-anchors/scripts/prompt-onboarding.sh
  • plugins/semantic-anchors/skills/README.md
  • plugins/semantic-anchors/skills/semantic-anchor-onboarding/SKILL.md
  • plugins/semantic-anchors/skills/semantic-anchor-onboarding/agents/openai.yaml
  • plugins/semantic-anchors/skills/semantic-anchor-onboarding/assets/templates/AGENTS.md
  • plugins/semantic-anchors/skills/semantic-anchor-onboarding/assets/templates/CLAUDE.md
  • plugins/semantic-anchors/skills/semantic-anchor-onboarding/assets/templates/GEMINI.md
  • plugins/semantic-anchors/skills/semantic-anchor-onboarding/assets/templates/anchor-block.md
  • plugins/semantic-anchors/skills/semantic-anchor-onboarding/assets/templates/copilot-instructions.md
  • plugins/semantic-anchors/skills/semantic-anchor-onboarding/references/agent-support.md
  • plugins/semantic-anchors/skills/semantic-anchor-onboarding/references/anchor-selection.md
  • plugins/semantic-anchors/skills/semantic-anchor-onboarding/scripts/claude-session-start.sh
  • plugins/semantic-anchors/skills/semantic-anchor-onboarding/scripts/install.sh
  • plugins/semantic-anchors/skills/semantic-anchor-translator/SKILL.md
  • plugins/semantic-anchors/skills/semantic-anchor-translator/references/catalog.md
  • plugins/semantic-anchors/tile.json
  • scripts/sync-claude-plugin.sh
  • skill/semantic-anchor-onboarding/SKILL.md
  • skill/semantic-anchor-onboarding/agents/openai.yaml
  • skill/semantic-anchor-onboarding/assets/templates/AGENTS.md
  • skill/semantic-anchor-onboarding/assets/templates/CLAUDE.md
  • skill/semantic-anchor-onboarding/assets/templates/GEMINI.md
  • skill/semantic-anchor-onboarding/assets/templates/anchor-block.md
  • skill/semantic-anchor-onboarding/assets/templates/copilot-instructions.md
  • skill/semantic-anchor-onboarding/references/agent-support.md
  • skill/semantic-anchor-onboarding/references/anchor-selection.md
  • skill/semantic-anchor-onboarding/scripts/claude-session-start.sh
  • skill/semantic-anchor-onboarding/scripts/install.sh

Comment on lines +6 to +16
"name": "LLM Coding",
"url": "https://github.com/LLM-Coding"
},
"plugins": [
{
"name": "semantic-anchors",
"description": "Semantic anchor skills for translating established methodologies, prompting first-run Claude onboarding, and installing persistent coding-agent context.",
"version": "0.1.0",
"author": {
"name": "LLM-Coding",
"url": "https://github.com/LLM-Coding"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Uneinheitlicher Publisher-Name in den Metadaten

Der Anzeigename ist innerhalb derselben Datei einmal LLM Coding und einmal LLM-Coding. Das erschwert konsistente Zuordnung in Marketplace-Oberflächen.

🔧 Vorschlag
       "author": {
-        "name": "LLM-Coding",
+        "name": "LLM Coding",
         "url": "https://github.com/LLM-Coding"
       },
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.claude-plugin/marketplace.json around lines 6 - 16, The top-level "name"
value ("LLM Coding") and the plugin author.name ("LLM-Coding") are inconsistent;
pick the canonical publisher name and make both occurrences identical (update
the top-level "name" and the plugins[...].author.name to the chosen value).
Ensure the same exact string is used for any other publisher name occurrences in
this file (e.g., plugin metadata) so marketplace surfaces a single unified
publisher name.

Comment on lines +10 to +16
REPO_ROOT="$(git rev-parse --show-toplevel)"

# Run the sync (rm -rf + cp -R each skill directory)
sh "$REPO_ROOT/scripts/sync-claude-plugin.sh"

# Stage the result so the overwritten files are included in this commit
git -C "$REPO_ROOT" add -- plugins/semantic-anchors/skills/
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Sichtprüfung: hat der Hook fail-fast gesetzt?
nl -ba .githooks/pre-commit | sed -n '1,30p'
rg -n '^\s*set\s+-' .githooks/pre-commit || true

Repository: LLM-Coding/Semantic-Anchors

Length of output: 113


🏁 Script executed:

#!/bin/bash
# Read the pre-commit hook file
cat -n .githooks/pre-commit

# Search for any set directives
echo "---"
grep -n "set " .githooks/pre-commit || echo "No 'set' directives found"

Repository: LLM-Coding/Semantic-Anchors

Length of output: 813


Pre-Commit-Hook muss bei Fehlern des Sync-Scripts sofort abbrechen.

Der Hook fehlt ein Fail-Fast-Mechanismus. Wenn das Sync-Script in Zeile 13 fehlschlägt, wird die Ausführung nicht unterbrochen. Das git add in Zeile 16 läuft dann dennoch und kann erfolgreich sein, wodurch der Hook mit Exit-Code 0 endet – obwohl das Sync-Script fehlgeschlagen ist. Dies ermöglicht inkonsistente Commits.

🛠️ Vorschlag: Fail-Fast aktivieren
 #!/bin/sh
 # Pre-commit hook: sync skill/ -> plugins/semantic-anchors/skills/
+set -eu
+
 #
 # Overwrites the plugin skills directory from the canonical skill/ source so
 # the two never diverge in a commit.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.githooks/pre-commit around lines 10 - 16, Der Hook ruft das Sync-Script mit
sh "$REPO_ROOT/scripts/sync-claude-plugin.sh" auf, prüft das Ergebnis aber
nicht, sodass ein Fehlschlag stillschweigend ignoriert wird; ändere die
Hook-Logik im .githooks/pre-commit so dass der Hook beim Fehler des Sync-Scripts
sofort abbricht (z.B. set -e ganz oben oder unmittelbar nach dem Aufruf den
Exit-Status prüfen und mit exit 1 beenden), damit der nachfolgende git -C
"$REPO_ROOT" add -- plugins/semantic-anchors/skills/ nie ausgeführt wird wenn
das Sync-Script fehlschlägt.

Comment on lines +47 to +69
try:
with open(state_path, "r", encoding="utf-8") as handle:
state = json.load(handle)
except (FileNotFoundError, json.JSONDecodeError):
state = {}

projects = state.setdefault("projects", {})
entry = projects.setdefault(project_dir, {})
last_prompt_raw = entry.get("last_prompt")

if last_prompt_raw:
try:
last_prompt = datetime.fromisoformat(last_prompt_raw.replace("Z", "+00:00"))
except (ValueError, TypeError):
last_prompt = None
if last_prompt and now - last_prompt < timedelta(hours=cooldown_hours):
raise SystemExit(0)

entry["last_prompt"] = now.isoformat().replace("+00:00", "Z")

with open(state_path, "w", encoding="utf-8") as handle:
json.dump(state, handle, indent=2)
handle.write("\n")
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

State-Handling ist nicht robust (nicht atomar + fail-closed bei I/O-Fehlern)

Direktes Überschreiben von state.json kann bei Parallelität/Abbruch beschädigte Zustände erzeugen. Zusätzlich brechen ungefangene OSError-Fälle den Hook unnötig hart ab.

🛠️ Vorschlag (atomarer Write + fail-open)
 try:
     with open(state_path, "r", encoding="utf-8") as handle:
         state = json.load(handle)
 except (FileNotFoundError, json.JSONDecodeError):
     state = {}
+except OSError:
+    raise SystemExit(0)
@@
-with open(state_path, "w", encoding="utf-8") as handle:
-    json.dump(state, handle, indent=2)
-    handle.write("\n")
+try:
+    tmp_path = f"{state_path}.tmp"
+    with open(tmp_path, "w", encoding="utf-8") as handle:
+        json.dump(state, handle, indent=2)
+        handle.write("\n")
+    os.replace(tmp_path, state_path)
+except OSError:
+    raise SystemExit(0)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@plugins/semantic-anchors/scripts/prompt-onboarding.sh` around lines 47 - 69,
The state write is not atomic and I/O errors can abort the hook; update the
block that writes state (around state_path, json.dump and entry["last_prompt"])
to perform an atomic write: write JSON to a temporary file in the same directory
(e.g., using tempfile.NamedTemporaryFile), flush and os.fsync the file, then
os.replace the temp file onto state_path to ensure atomic swap; wrap the entire
write/replace in an OSError/IOError except that logs the error (or prints) and
continues (fail-open) instead of letting the process crash so the hook won’t
abort on write failures. Ensure you keep the existing read handling (open
state_path) and that entry["last_prompt"] is still set before attempting the
atomic write.

Comment on lines +1 to +5
#!/bin/bash
# Claude SessionStart hook for semantic-anchor onboarding.
# Usage: ./claude-session-start.sh /path/to/markdown-file

set -euo pipefail
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/sh
set -eu

for f in \
  "plugins/semantic-anchors/skills/semantic-anchor-onboarding/scripts/claude-session-start.sh" \
  "plugins/semantic-anchors/skills/semantic-anchor-onboarding/scripts/install.sh" \
  "plugins/semantic-anchors/scripts/prompt-onboarding.sh" \
  "scripts/sync-claude-plugin.sh"
do
  [ -f "$f" ] || continue
  printf '\n== %s ==\n' "$f"
  sed -n '1,12p' "$f"
  rg -n 'pipefail|#!/bin/bash|#!/bin/sh' "$f" || true
done

Repository: LLM-Coding/Semantic-Anchors

Length of output: 1812


Bash-Abhängigkeit in Onboarding-Skripten ohne Not eingeführt.

Die Logik in claude-session-start.sh benötigt Bash nicht – set -euo pipefail wird aber verwendet, wobei pipefail eine Bash-Erweiterung ist. Auf Systemen ohne Bash oder mit reinem POSIX-Shell schlägt der installierte Hook sofort fehl. Besonders problematisch: Der Sync-Skript selbst (scripts/sync-claude-plugin.sh) nutzt korrekt #!/bin/sh und set -eu, während die synced Scripts Bash verlangen.

Bitte alle drei Onboarding-Skripte (install.sh, claude-session-start.sh, prompt-onboarding.sh) auf POSIX sh umstellen: #!/bin/sh und set -eu statt #!/bin/bash und set -euo pipefail. Dies betrifft beide Quellen: die Originale unter skill/ und die synced Kopien unter plugins/.

♻️ Vorschlag
-#!/bin/bash
+#!/bin/sh
 # Claude SessionStart hook for semantic-anchor onboarding.
 # Usage: ./claude-session-start.sh /path/to/markdown-file
 
-set -euo pipefail
+set -eu
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
#!/bin/bash
# Claude SessionStart hook for semantic-anchor onboarding.
# Usage: ./claude-session-start.sh /path/to/markdown-file
set -euo pipefail
#!/bin/sh
# Claude SessionStart hook for semantic-anchor onboarding.
# Usage: ./claude-session-start.sh /path/to/markdown-file
set -eu
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@plugins/semantic-anchors/skills/semantic-anchor-onboarding/scripts/claude-session-start.sh`
around lines 1 - 5, The three onboarding scripts currently require Bash because
they use a bash-only shebang and pipefail: change each script's interpreter line
from "#!/bin/bash" to "#!/bin/sh" and replace "set -euo pipefail" with "set -eu"
so they run under POSIX sh; update this in all copies for install.sh,
claude-session-start.sh, and prompt-onboarding.sh both in the skill/ originals
and the synced copies under plugins/semantic-anchors/skills/... to ensure
consistent behavior across sync-claude-plugin.sh and avoid bash-only
assumptions.

Comment on lines +167 to +170
### Feynman Technique
- **Proponents:** Richard Feynman
- **Core:** Explain concept simply, identify gaps, refine understanding

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Kleiner Grammatikfehler in der Feynman-Beschreibung.

Auf Line 169 klingt „Explain concept simply“ unnatürlich. Vorschlag: „Explain concepts simply“ oder „Explain a concept simply“.

✏️ Formulierungsvorschlag
-- **Core:** Explain concept simply, identify gaps, refine understanding
+- **Core:** Explain concepts simply, identify gaps, refine understanding
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
### Feynman Technique
- **Proponents:** Richard Feynman
- **Core:** Explain concept simply, identify gaps, refine understanding
### Feynman Technique
- **Proponents:** Richard Feynman
- **Core:** Explain concepts simply, identify gaps, refine understanding
🧰 Tools
🪛 LanguageTool

[grammar] ~169-~169: This construction requires the preposition ‘to’.
Context: ...oponents:** Richard Feynman - Core: Explain concept simply, identify gaps, refine understan...

(L2_EXPLAIN)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@plugins/semantic-anchors/skills/semantic-anchor-translator/references/catalog.md`
around lines 167 - 170, Update the text under the "Feynman Technique" heading
where the line currently reads "Explain concept simply" to a grammatically
correct phrasing such as "Explain concepts simply" or "Explain a concept
simply"; locate and edit the exact string "Explain concept simply" in the
catalog entry to apply the change.

Comment on lines +34 to +40
- `Testing Pyramid`
- `SOLID Principles`
- `Hexagonal Architecture` or `Clean Architecture`
- `Domain-Driven Design`
- `ADR according to Nygard` or `MADR`
- `Diataxis Framework`
- `Docs-as-Code`
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/sh
set -eu

python3 - <<'PY'
from pathlib import Path
import re
import unicodedata

anchor_file = Path("skill/semantic-anchor-onboarding/references/anchor-selection.md")
catalog_file = Path("skill/semantic-anchor-translator/references/catalog.md")

anchor_text = anchor_file.read_text(encoding="utf-8")
catalog_text = catalog_file.read_text(encoding="utf-8")

anchors = sorted(set(re.findall(r'`([^`]+)`', anchor_text)))

def norm(value: str) -> str:
    value = unicodedata.normalize("NFKD", value).encode("ascii", "ignore").decode("ascii")
    value = value.lower()
    value = re.sub(r'[^a-z0-9]+', ' ', value).strip()
    return value

catalog_norm = norm(catalog_text)
missing = [anchor for anchor in anchors if norm(anchor) not in catalog_norm]

print(f"Anzahl referenzierter Anchors: {len(anchors)}")
print("Potenziell fehlend oder anders benannt im Katalog:")
for anchor in missing:
    print(f" - {anchor}")
PY

Repository: LLM-Coding/Semantic-Anchors

Length of output: 407


Fehlerhafte Synchronisation zwischen Ankerliste und Katalog: 8 Ankernamen fehlen oder unterscheiden sich im Katalog.

Die Überprüfung gegen skill/semantic-anchor-translator/references/catalog.md zeigt, dass folgende in anchor-selection.md referenzierte Anker nicht oder unter abweichender Bezeichnung im Katalog vorhanden sind:

  • ATAM
  • Docs-as-Code according to Ralf D. Müller
  • Domain-Driven Design according to Evans
  • LASR by Toth/Zörner
  • Mental Model according to Naur
  • OWASP Top 10
  • Pyramid Principle according to Barbara Minto
  • The Spectrum of Semantic Anchors

Entweder diese Anker zum Katalog hinzufügen oder die Referenzen in anchor-selection.md korrigieren, um die Synchronisation sicherzustellen. Der Katalog muss als Single Source of Truth für alle aktiv referenzierten Anker fungieren.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@skill/semantic-anchor-onboarding/references/anchor-selection.md` around lines
34 - 40, Die Liste in anchor-selection.md ist nicht synchron mit dem Katalog;
überprüfe die referenzierten Anker (ATAM; Docs-as-Code according to Ralf D.
Müller; Domain-Driven Design according to Evans; LASR by Toth/Zörner; Mental
Model according to Naur; OWASP Top 10; Pyramid Principle according to Barbara
Minto; The Spectrum of Semantic Anchors) gegen
skill/semantic-anchor-translator/references/catalog.md and either add the
missing/renamed entries to the catalog or update the names in
skill/semantic-anchor-onboarding/references/anchor-selection.md to exactly match
the canonical identifiers used in the catalog so the catalog remains the single
source of truth.

Comment on lines +28 to +40
while [ "$#" -gt 0 ]; do
case "$1" in
--source)
SOURCE_FILE="$2"
shift 2
;;
--target-dir)
TARGET_DIR="$2"
shift 2
;;
--scope)
SCOPE="$2"
shift 2
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fehlende Optionswerte vor dem Zugriff validieren.

Line 31, Line 35 und Line 39 lesen $2 ohne Vorprüfung. Mit set -u endet ./install.sh --source dadurch in einem unbound variable statt mit einer brauchbaren Usage-Fehlermeldung.

Diff-Vorschlag
 while [ "$#" -gt 0 ]; do
   case "$1" in
     --source)
+      [ "$#" -ge 2 ] || { echo "Missing value for $1" >&2; usage >&2; exit 1; }
       SOURCE_FILE="$2"
       shift 2
       ;;
     --target-dir)
+      [ "$#" -ge 2 ] || { echo "Missing value for $1" >&2; usage >&2; exit 1; }
       TARGET_DIR="$2"
       shift 2
       ;;
     --scope)
+      [ "$#" -ge 2 ] || { echo "Missing value for $1" >&2; usage >&2; exit 1; }
       SCOPE="$2"
       shift 2
       ;;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
while [ "$#" -gt 0 ]; do
case "$1" in
--source)
SOURCE_FILE="$2"
shift 2
;;
--target-dir)
TARGET_DIR="$2"
shift 2
;;
--scope)
SCOPE="$2"
shift 2
while [ "$#" -gt 0 ]; do
case "$1" in
--source)
[ "$#" -ge 2 ] || { echo "Missing value for $1" >&2; usage >&2; exit 1; }
SOURCE_FILE="$2"
shift 2
;;
--target-dir)
[ "$#" -ge 2 ] || { echo "Missing value for $1" >&2; usage >&2; exit 1; }
TARGET_DIR="$2"
shift 2
;;
--scope)
[ "$#" -ge 2 ] || { echo "Missing value for $1" >&2; usage >&2; exit 1; }
SCOPE="$2"
shift 2
;;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@skill/semantic-anchor-onboarding/scripts/install.sh` around lines 28 - 40,
Die case-Armles in install.sh lesen $2 direkt (für SOURCE_FILE, TARGET_DIR,
SCOPE) und schlagen bei fehlenden Optionswerten mit "unbound variable" fehl; vor
dem Zugriff auf $2 prüfe jeweils, dass ein weiteres Argument existiert (z.B.
mittels Prüfung auf "${2-}" oder "$#" >= 2) und dass es kein weiteres Flag ist,
und falls nicht, gib eine Usage-Fehlermeldung und exit; aktualisiere die
case-Branches für --source, --target-dir und --scope entsprechend, so dass
fehlende Werte abgefangen und sprechende Fehler ausgegeben werden.

Comment on lines +142 to +154
if grep -qF "$MARKER_START" "$target_file"; then
awk -v start="$MARKER_START" -v end="$MARKER_END" -v repl="$INJECTED_FILE" '
BEGIN {
while ((getline line < repl) > 0) replacement = replacement line "\n"
close(repl)
in_block = 0
}
index($0, start) { if (!in_block) printf "%s", replacement; in_block = 1; next }
index($0, end) { in_block = 0; next }
!in_block { print }
' "$target_file" > "$REPLACED_FILE"
mv "$REPLACED_FILE" "$target_file"
return 0
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Ein unvollständiger Markerblock kann den Rest der Datei abschneiden.

Line 142 prüft nur den Startmarker. Wenn der Endmarker fehlt, bleibt in_block ab Line 149 bis EOF aktiv und alles danach wird beim Rewrite verworfen. Vor dem Ersetzen sollte die Datei mindestens auf ein vollständiges, geordnetes Marker-Paar geprüft werden.

Diff-Vorschlag
   if grep -qF "$MARKER_START" "$target_file"; then
+    if ! awk -v start="$MARKER_START" -v end="$MARKER_END" '
+      index($0, start) { seen_start = 1 }
+      seen_start && index($0, end) { found_pair = 1; exit }
+      END { exit found_pair ? 0 : 1 }
+    ' "$target_file"; then
+      echo "Existing semantic-anchors block is malformed" >&2
+      exit 1
+    fi
+
     awk -v start="$MARKER_START" -v end="$MARKER_END" -v repl="$INJECTED_FILE" '
       BEGIN {
         while ((getline line < repl) > 0) replacement = replacement line "\n"
As per coding guidelines, "follow portable, idempotent installer flow".
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@skill/semantic-anchor-onboarding/scripts/install.sh` around lines 142 - 154,
The script currently only checks for MARKER_START and then runs an awk block
that sets in_block until MARKER_END, which will drop the rest of target_file if
MARKER_END is missing; before performing the awk replace (the block that reads
MARKER_START/MARKER_END, INJECTED_FILE, writes REPLACED_FILE and mv's it over
target_file), add a pre-check that both MARKER_START and MARKER_END exist and
that the end marker comes after the start marker (e.g., inspect target_file for
both markers and their relative positions), and bail out with a non-zero return
if the pair is not found in correct order to keep the installer idempotent and
portable.

Comment on lines +222 to +244
already_present = False
for entry in session_start:
if not isinstance(entry, dict):
continue
for hook in entry.get("hooks", []):
if isinstance(hook, dict) and hook.get("command") == command:
already_present = True
break
if already_present:
break

if not already_present:
session_start.append(
{
"matcher": "startup|resume",
"hooks": [
{
"type": "command",
"command": command,
}
],
}
)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Der SessionStart-Hook wird nur angehängt, nicht wirklich aktualisiert.

Die Deduplizierung auf Line 227 vergleicht nur die exakte command-Zeichenkette. Wenn sich die Ziel-Datei später ändert, bleibt der alte semantic-anchor-Hook stehen und ein zweiter Eintrag wird ergänzt. Dann laufen bei startup|resume mehrere verwaltete Hooks parallel.

Diff-Vorschlag
 already_present = False
 for entry in session_start:
     if not isinstance(entry, dict):
         continue
-    for hook in entry.get("hooks", []):
-        if isinstance(hook, dict) and hook.get("command") == command:
+    hooks_list = entry.get("hooks", [])
+    for hook in hooks_list:
+        existing_command = hook.get("command") if isinstance(hook, dict) else None
+        if isinstance(existing_command, str) and "semantic-anchor-onboarding/session-start.sh" in existing_command:
+            entry["matcher"] = "startup|resume"
+            hook["type"] = "command"
+            hook["command"] = command
             already_present = True
             break
     if already_present:
         break
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
already_present = False
for entry in session_start:
if not isinstance(entry, dict):
continue
for hook in entry.get("hooks", []):
if isinstance(hook, dict) and hook.get("command") == command:
already_present = True
break
if already_present:
break
if not already_present:
session_start.append(
{
"matcher": "startup|resume",
"hooks": [
{
"type": "command",
"command": command,
}
],
}
)
already_present = False
for entry in session_start:
if not isinstance(entry, dict):
continue
hooks_list = entry.get("hooks", [])
for hook in hooks_list:
existing_command = hook.get("command") if isinstance(hook, dict) else None
if isinstance(existing_command, str) and "semantic-anchor-onboarding/session-start.sh" in existing_command:
entry["matcher"] = "startup|resume"
hook["type"] = "command"
hook["command"] = command
already_present = True
break
if already_present:
break
if not already_present:
session_start.append(
{
"matcher": "startup|resume",
"hooks": [
{
"type": "command",
"command": command,
}
],
}
)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@skill/semantic-anchor-onboarding/scripts/install.sh` around lines 222 - 244,
The current loop only checks for exact equality of hook.get("command") to decide
deduplication, so if the managed command target changes a new hook is appended;
instead, when iterating session_start -> entry -> hooks, detect existing managed
semantic-anchor hooks by a stable identifier (e.g., hook.get("type") ==
"command" and the hook command contains the known tool prefix or matches the
command basename) and update that hook's "command" value to the new command
variable rather than appending a duplicate; use the existing variables
session_start, entry, hooks and command to find and replace
hook["command"]=command and then break, otherwise append the new matcher/hooks
block as before.

Comment on lines +29 to +33
4. Run the installer instead of editing by hand.
- Use `scripts/install.sh --source /path/to/anchor-block.md --target-dir <repo> --scope project` for repository onboarding.
- Use `scripts/install.sh --source /path/to/anchor-block.md --scope home` for personal onboarding.
- The installer follows the same pattern as ToonDex: inject into the first suitable existing markdown file, otherwise create a minimal `AGENTS.md`.
- The installer writes an idempotent marker block so future updates replace the old anchor section instead of appending duplicates.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/sh
set -eu

prompt_file="plugins/semantic-anchors/scripts/prompt-onboarding.sh"
install_file="plugins/semantic-anchors/skills/semantic-anchor-onboarding/scripts/install.sh"

printf '== Vom Prompt-Hook geprüfte Marker-Dateien ==\n'
sed -n '1,160p' "$prompt_file" | rg -n 'has_marker|AGENTS\.md|CLAUDE\.md|GEMINI\.md|copilot-instructions\.md'

printf '\n== Installer-Kandidaten und Auswahl ==\n'
sed -n '1,260p' "$install_file" | rg -n -C2 'AGENTS\.md|CLAUDE\.md|GEMINI\.md|copilot-instructions\.md|README\.md|markdown|candidate|suitable|target'

Repository: LLM-Coding/Semantic-Anchors

Length of output: 4106


Dokumentation in SKILL.md unklar: Kandidaten-Liste sollte spezifiziert werden.

Die Zeilen 29–33 beschreiben den Installer als „inject into the first suitable existing markdown file", was vermuten lässt, dass beliebige Markdown-Dateien gewählt werden können. Tatsächlich begrenzt select_target_file() die Auswahl auf eine feste Kandidaten-Liste (AGENTS.md, CLAUDE.md, GEMINI.md, .github/copilot-instructions.md, .claude/AGENTS.md), die mit den vom Prompt-Hook geprüften Dateien identisch ist.

Bitte präzisieren Sie die Formulierung: Die feste Liste sollte explizit genannt werden, um künftige Wartende und Implementierer nicht zu verwirren.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@skill/semantic-anchor-onboarding/SKILL.md` around lines 29 - 33, Die
Dokumentation in SKILL.md muss präzisiert werden: ersetzen Sie die ungenaue
Formulierung "inject into the first suitable existing markdown file" durch eine
explizite Aufzählung der tatsächlich verwendeten Kandidaten und verweisen Sie
auf die Auswahl-Logik in select_target_file(); nennen Sie dort die feste Liste
(AGENTS.md, CLAUDE.md, GEMINI.md, .github/copilot-instructions.md,
.claude/AGENTS.md) und ergänzen Sie einen kurzen Hinweis, dass dieselbe Liste
vom Prompt-Hook überprüft wird, damit zukünftige Wartende und Implementierer die
Einschränkung sofort erkennen.

Copy link

@Nantero1 Nantero1 Mar 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure if translation skill is actually needed, LLMs are generally good at translation, instructing them to translate from natural language to nearest discvered semantic anchor word shoudl be enough. Addtionally add something like, if the match is below 90% then additionally explain the difference and nuances to explain the actually used pattern even closer.
What do you think? Would reduce complexity and naturally become better as LLMs become better.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @Nantero1 ! I added a pre-commit script which copies and syncs the skills for Claude Code support. The translator skill did exist beforehand and was introduced in #132

@rdmueller
Copy link
Member

@Nantero1 - thanx for the review!
@cpoepke have you studied the CodeRabbit feedback?

@JThoennes
Copy link
Contributor

@cpoepke: To me, this looks like a rather huge PR. Perhaps it could be split into several steps?

The shells script will not run on Windows. Is there anything missing?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants