Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,6 @@ for entry in "${marketplaces[@]}"; do
claude plugin marketplace add "${entry}"
done

# Local marketplace — personal plugins in this repo, installed directly.
claude plugin marketplace add "{{ .chezmoi.sourceDir }}/../plugins"

plugins=(
claude-code-setup@claude-plugins-official
claude-md-management@claude-plugins-official
Expand All @@ -28,7 +25,6 @@ plugins=(
typescript-lsp@claude-plugins-official
caveman@caveman
memsearch@memsearch-plugins
okf-wiki@yxtay
)
for entry in "${plugins[@]}"; do
claude plugin install "${entry}"
Expand Down
Empty file modified chezmoi/private_dot_claude/executable_statusline-command.sh
100644 → 100755
Empty file.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/usr/bin/env bash
# SessionEnd / PreCompact hook: periodically distill memsearch journals into the ~/wiki OKF bundle.
# Independent of the memsearch plugin's own SessionEnd hook — reads its journal output
# SessionEnd hook: periodically distill memsearch memories into the ~/wiki OKF bundle.
# Independent of the memsearch plugin's own SessionEnd hook — reads its memory output
# as a data source only, no changes to memsearch itself.
set -euo pipefail

Expand All @@ -14,17 +14,18 @@ JOURNAL_DIR="${MEMSEARCH_DIR}/memory"
WIKI_DIR="${OKF_WIKI_DIR:-${HOME}/wiki}"
STATE_FILE="${WIKI_DIR}/.okf-wiki-last-run"
LOCK_FILE="${WIKI_DIR}/.okf-wiki-maintenance.lock"
PROMPT_FILE="${CLAUDE_PLUGIN_ROOT:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)}/prompts/okf-wiki-review.txt"
PROMPT_FILE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/okf-wiki-review.txt"

[ -d "${JOURNAL_DIR}" ] || exit 0
[ -f "${PROMPT_FILE}" ] || exit 0
mkdir -p "${WIKI_DIR}"
command -v claude &>/dev/null || exit 0

# Acquire exclusive lock — prevents concurrent SessionEnd + PreCompact runs.
# fd 9 is opened on LOCK_FILE; flock holds it for this process's lifetime.
exec 9>"${LOCK_FILE}"
flock -n 9 || exit 0 # -n = non-blocking: exit immediately if already locked
# Acquire exclusive lock via atomic mkdir — POSIX portable, no flock/shlock needed.
if ! mkdir "${LOCK_FILE}" 2>/dev/null; then
exit 0
fi
trap 'rmdir "${LOCK_FILE}"' EXIT
Comment on lines +24 to +28

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

set -euo pipefail
printf 'FILES\n'
git ls-files 'plugins/okf-wiki/hooks/okf-wiki-maintenance.sh' 'plugins/okf-wiki/**' | sed -n '1,120p'

printf '\nSCRIPT\n'
wc -l plugins/okf-wiki/hooks/okf-wiki-maintenance.sh
cat -n plugins/okf-wiki/hooks/okf-wiki-maintenance.sh

printf '\nSEARCH LOCK/TIMEOUT\n'
rg -n 'LOCK_FILE|timeout|SessionEnd|flock|mkdir' plugins/okf-wiki -S

Repository: yxtay/dotfiles

Length of output: 244


🏁 Script executed:

set -euo pipefail
printf 'HOOK CONFIG\n'
fd -a 'hooks.json' plugins/okf-wiki -t f -g 'hooks.json' -g '*.json' | sed -n '1,20p'
rg -n '"timeout"|SessionEnd|okf-wiki-maintenance|LOCK_FILE' plugins/okf-wiki -S

Repository: yxtay/dotfiles

Length of output: 378


🏁 Script executed:

set -euo pipefail
python3 - <<'PY'
from pathlib import Path
p = Path('plugins/okf-wiki/hooks/okf-wiki-maintenance.sh')
print(p.exists(), p)
if p.exists():
    txt = p.read_text()
    print('contains stale recovery:', any(k in txt for k in ['mmin', 'stale', 'timeout', 'find']))
PY

Repository: yxtay/dotfiles

Length of output: 205


🏁 Script executed:

set -euo pipefail
printf 'TOP-LEVEL FILES\n'
git ls-files | sed -n '1,200p'

printf '\nPOSSIBLE OKF WIKI FILES\n'
git ls-files | rg -n 'okf-wiki|maintenance|hooks\.json|\.sh$' -n -S

printf '\nDIRECTORY SNAPSHOT\n'
find . -maxdepth 3 -type d | sed -n '1,200p'

Repository: yxtay/dotfiles

Length of output: 4416


🏁 Script executed:

set -euo pipefail

printf 'FILE: chezmoi/private_dot_claude/okf/executable_okf-wiki-maintenance.sh\n'
wc -l chezmoi/private_dot_claude/okf/executable_okf-wiki-maintenance.sh
cat -n chezmoi/private_dot_claude/okf/executable_okf-wiki-maintenance.sh

printf '\nRELATED REFERENCES\n'
rg -n 'okf-wiki-maintenance|LOCK_FILE|flock|mkdir|timeout|SessionEnd|hook' chezmoi -S

Repository: yxtay/dotfiles

Length of output: 5420


🏁 Script executed:

set -euo pipefail

printf 'NEARBY FILES\n'
git ls-files 'chezmoi/private_dot_claude/okf/*' | sed -n '1,120p'

printf '\nHOOK/WRAPPER CONTENT\n'
for f in \
  chezmoi/private_dot_claude/okf/executable_okf-wiki-maintenance.sh \
  chezmoi/private_dot_claude/okf/okf-wiki-review.txt
do
  echo "--- $f"
  wc -l "$f"
  cat -n "$f"
done

Repository: yxtay/dotfiles

Length of output: 6083


mkdir lock can leave the hook disabled forever. If the process is killed before the EXIT trap runs, .okf-wiki-maintenance.lock remains and every later invocation immediately exits 0 with no logging. Add stale-lock recovery or another expiry path.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@plugins/okf-wiki/hooks/okf-wiki-maintenance.sh` around lines 24 - 28, Update
the lock acquisition flow around LOCK_FILE and the EXIT trap to recover from
stale lock directories when the owning process is no longer running, or
otherwise provide an expiry path. Preserve atomic exclusive locking for active
maintenance runs, and ensure later invocations do not exit silently forever
because of a lock left by a killed process.


# Skip if already ran today (same calendar date).
if [ -f "${STATE_FILE}" ]; then
Expand All @@ -35,43 +36,39 @@ if [ -f "${STATE_FILE}" ]; then
fi
fi

# Only look at journals touched since the last run (falls back to last 3 days on first run).
# Memories since last run, or last 3 days on first run. Always include yesterday (-mtime -1 = <24h).
if [ -f "${STATE_FILE}" ]; then
recent_journals="$(find "${JOURNAL_DIR}" -maxdepth 1 -name '*.md' -newer "${STATE_FILE}" 2>/dev/null)"
recent_memories="$(find "${JOURNAL_DIR}" -maxdepth 1 -name '*.md' \( -newer "${STATE_FILE}" -o -mtime -1 \) 2>/dev/null)"
else
recent_journals="$(find "${JOURNAL_DIR}" -maxdepth 1 -name '*.md' -mtime -3 2>/dev/null)"
recent_memories="$(find "${JOURNAL_DIR}" -maxdepth 1 -name '*.md' -mtime -3 2>/dev/null)"
fi

[ -n "${recent_journals}" ] || exit 0

# Include memsearch-synthesized summaries if present (higher-signal than raw journals).
extra_context=""
[ -f "${MEMSEARCH_DIR}/PROJECT.md" ] && extra_context="${extra_context}
Project summary: ${MEMSEARCH_DIR}/PROJECT.md"
[ -f "${MEMSEARCH_DIR}/USER.md" ] && extra_context="${extra_context}
User profile: ${MEMSEARCH_DIR}/USER.md"
[ -n "${recent_memories}" ] || exit 0

export MEMSEARCH_DISABLE=1
export MEMSEARCH_NO_WATCH=1
export OKF_WIKI_DISABLE=1
unset CLAUDECODE # clear CLAUDECODE so the child session doesn't inherit hook context

# hook runs with async:true — Claude Code does not block on this script.
# Run claude -p synchronously so flock holds for the full duration, preventing
# a concurrent PreCompact trigger from starting a second run.
# Run claude -p synchronously so mkdir lock holds for the full duration,
# preventing a concurrent trigger from starting a second run.
# Write state file only on success so a failed run does not suppress the next.
Comment on lines 53 to 56

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Stale "shlock" reference — the lock is now mkdir-based.

This comment (line 54) still refers to "shlock," but the actual lock implemented at line 24-28 is an atomic mkdir. Leftover terminology from an earlier implementation iteration; misleading for future readers.

📝 Proposed fix
-# Run claude -p synchronously so shlock holds for the full duration, preventing
+# Run claude -p synchronously so the mkdir lock holds for the full duration, preventing
 # a concurrent trigger from starting a second run.
📝 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
# hook runs with async:true — Claude Code does not block on this script.
# Run claude -p synchronously so flock holds for the full duration, preventing
# a concurrent PreCompact trigger from starting a second run.
# Run claude -p synchronously so shlock holds for the full duration, preventing
# a concurrent trigger from starting a second run.
# Write state file only on success so a failed run does not suppress the next.
# hook runs with async:true — Claude Code does not block on this script.
# Run claude -p synchronously so the mkdir lock holds for the full duration, preventing
# a concurrent trigger from starting a second run.
# Write state file only on success so a failed run does not suppress the next.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@plugins/okf-wiki/hooks/okf-wiki-maintenance.sh` around lines 53 - 56, Update
the maintenance hook comment describing synchronous execution to replace the
stale “shlock” terminology with the current atomic mkdir-based lock terminology,
while preserving the explanation that the lock must remain held for the full run
to prevent concurrent triggers.

if claude -p \
prompt="$(
printf 'Wiki directory: %s\n' "${WIKI_DIR}"
[ -f "${MEMSEARCH_DIR}/USER.md" ] && printf 'User profile: %s\n' "${MEMSEARCH_DIR}/USER.md"
[ -f "${MEMSEARCH_DIR}/PROJECT.md" ] && printf 'Project review: %s\n' "${MEMSEARCH_DIR}/PROJECT.md"
printf 'Recent memory:\n%s\n' "${recent_memories}"
)"
if printf '%s' "${prompt}" | claude -p \
--strict-mcp-config \
--no-session-persistence \
--model haiku \
--effort low \
--allowed-tools "Skill,Read,Write,Edit,Glob,Grep" \
--allowed-tools "Read,Write,Edit,Glob,Grep" \
--append-system-prompt-file "${PROMPT_FILE}" \
--add-dir "${WIKI_DIR}" \
--add-dir "${MEMSEARCH_DIR}" \
"Wiki directory: ${WIKI_DIR}
Recently changed journal files:
${recent_journals}${extra_context}" \
>/dev/null 2>&1; then
date +%Y-%m-%d >"${STATE_FILE}"
fi
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
You are maintaining a personal OKF (Open Knowledge Format) wiki.

You will receive recently-changed memsearch journal files (daily markdown logs of past coding
sessions) and, when listed, memsearch-synthesized PROJECT.md and USER.md summaries as additional
context. Prefer the synthesized summaries as higher-signal; use raw journals for detail not
captured there.
You will receive recently-changed memsearch memory files (daily markdown logs of past coding
sessions) and, when listed, memsearch-synthesized PROJECT.md (project review) and USER.md (user
profile) as additional context. Prefer the synthesized summaries as higher-signal; use raw memory
files for detail not captured there.

Step 1 — invoke the `okf` skill. It defines the bundle layout, frontmatter rules, and the exact
steps for adding, updating, and linking concepts. Follow it exactly for any edits you make.

Step 2 — read `<wiki>/index.md` to understand the bundle's current structure.

Step 3 — read the input files listed in the user message.
Step 3 — read the files listed under "Recent memory:" in the user message, plus any user profile and project review files listed.

Step 4 — decide: is there anything durable worth adding to the wiki?
A piece of knowledge is durable if it is likely to recur across future sessions and is not already
Expand All @@ -28,5 +28,5 @@ Step 5 — if there is durable knowledge, apply the skill's "Maintaining a bundl
- If a bundle-level `log.md` exists in the directory you are editing, add one line to it.

Constraints:
- Do not touch memsearch-owned files (PROJECT.md, USER.md, journal .md files) — read-only to you.
- Do not touch memsearch-owned files (PROJECT.md, USER.md, memory .md files) — read-only to you.
- Do not ask questions. This runs unattended.
16 changes: 0 additions & 16 deletions plugins/.claude-plugin/marketplace.json

This file was deleted.

5 changes: 0 additions & 5 deletions plugins/okf-wiki/.claude-plugin/plugin.json

This file was deleted.

17 changes: 0 additions & 17 deletions plugins/okf-wiki/hooks/hooks.json

This file was deleted.

Loading