refactor(okf): migrate to skills-dir plugin - #897
Conversation
Consolidates okf-wiki-maintenance.sh, okf-wiki-review.txt, SKILL.md, and the SessionEnd hook registration from three separate locations into a single self-contained skills-dir plugin at ~/.claude/skills/okf/. Hook registration moves from settings.json to hooks/hooks.json, co-located with the script it references.
|
Warning Review limit reached
Next review available in: 49 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (6)
📝 WalkthroughWalkthroughAdds an OKF Claude skill with specification, templates, and a SessionEnd hook that distills memsearch journals into ChangesOKF Claude workflow
Estimated code review effort: 3 (Moderate) | ~25 minutes Possibly related PRs
Suggested labels: Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Code Review
This pull request introduces the Open Knowledge Format (OKF) skill for Claude Code, adding the OKF specification, skill instructions, templates, and a SessionEnd hook for wiki maintenance. Feedback on the changes highlights critical issues with the hook registration in hooks.json, specifically an incorrect nesting structure and an incorrect file location that would prevent Claude Code from properly loading the hook.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| "SessionEnd": [ | ||
| { | ||
| "hooks": [ | ||
| { | ||
| "type": "command", | ||
| "command": "~/.claude/skills/okf/scripts/okf-wiki-maintenance.sh", | ||
| "async": true, | ||
| "timeout": 300 | ||
| } | ||
| ] | ||
| } | ||
| ] |
There was a problem hiding this comment.
There are two issues with this hook registration:
- Incorrect Nesting Structure: The
SessionEndarray contains an object with a nestedhooksarray. Claude Code expects a flat array of hook objects directly under the event name (e.g.,SessionEnd). - Incorrect File Location: Claude Code typically looks for
hooks.jsonat the root of the plugin directory (i.e.,chezmoi/private_dot_claude/skills/okf/hooks.json) or inside the.claude-plugin/directory. Placing it in ahooks/subdirectory will likely cause Claude Code to ignore it.
We recommend flattening the structure and moving the file to the plugin root.
"SessionEnd": [
{
"type": "command",
"command": "~/.claude/skills/okf/scripts/okf-wiki-maintenance.sh",
"async": true,
"timeout": 300
}
]
✅MegaLinter analysis: Success
Notices📣 MegaLinter 9.5.0 is out! Discover the new features and security recommendations in the release announcement. (Skip this info by defining See detailed reports in MegaLinter artifacts Your project could benefit from a custom flavor, which would allow you to run only the linters you need, and thus improve runtime performances. (Skip this info by defining
|
✅MegaLinter analysis: Success
Notices📣 MegaLinter 9.5.0 is out! Discover the new features and security recommendations in the release announcement. (Skip this info by defining See detailed reports in MegaLinter artifacts Your project could benefit from a custom flavor, which would allow you to run only the linters you need, and thus improve runtime performances. (Skip this info by defining
|
✅
|
| Descriptor | Linter | Files | Fixed | Errors | Warnings | Elapsed time |
|---|---|---|---|---|---|---|
| ✅ ACTION | actionlint | 5 | 0 | 0 | 0.3s | |
| ✅ ACTION | zizmor | 5 | 0 | 0 | 0 | 0.6s |
| ✅ BASH | bash-exec | 5 | 0 | 0 | 0.02s | |
| ✅ BASH | shellcheck | 5 | 0 | 0 | 0.21s | |
| ✅ BASH | shfmt | 5 | 0 | 0 | 0 | 0.02s |
| ✅ COPYPASTE | jscpd | yes | no | no | 0.1s | |
| ✅ EDITORCONFIG | editorconfig-checker | 88 | 0 | 0 | 0.08s | |
| ✅ JSON | prettier | 7 | 0 | 0 | 0 | 0.48s |
| ✅ JSON | v8r | 11 | 0 | 0 | 3.9s | |
| ✅ MARKDOWN | markdownlint | 14 | 0 | 0 | 0 | 0.9s |
| ✅ MARKDOWN | markdown-table-formatter | 16 | 0 | 0 | 0 | 0.25s |
| ✅ REPOSITORY | betterleaks | yes | no | no | 2.81s | |
| ✅ REPOSITORY | checkov | yes | no | no | 22.68s | |
| ✅ REPOSITORY | gitleaks | yes | no | no | 1.3s | |
| ✅ REPOSITORY | git_diff | yes | no | no | 0.05s | |
| ✅ REPOSITORY | grype | yes | no | no | 52.09s | |
| ✅ REPOSITORY | osv-scanner | yes | no | no | 0.12s | |
| ✅ REPOSITORY | secretlint | yes | no | no | 1.04s | |
| ✅ REPOSITORY | syft | yes | no | no | 1.92s | |
| ✅ REPOSITORY | trivy | yes | no | no | 9.63s | |
| ✅ REPOSITORY | trivy-sbom | yes | no | no | 0.15s | |
| ✅ REPOSITORY | trufflehog | yes | no | no | 4.34s | |
| lychee | 39 | 16 | 0 | 1.02s | ||
| ✅ YAML | prettier | 11 | 0 | 0 | 0 | 0.51s |
| ✅ YAML | v8r | 11 | 0 | 0 | 7.46s | |
| ✅ YAML | yamllint | 11 | 0 | 0 | 0.41s |
Detailed Issues
⚠️ SPELL / lychee - 16 errors
📝 Summary
---------------------
🔍 Total...........45
🔗 Unique..........32
✅ Successful......29
⏳ Timeouts.........0
🔀 Redirected.......3
👻 Excluded.........0
❓ Unknown..........0
🚫 Errors..........16
⛔ Unsupported.....16
Errors in chezmoi/.chezmoitemplates/mcp_servers.json
[406] https://mcp.deepwiki.com/mcp (at 11:15) | Rejected status code: 406 Not Acceptable
Errors in chezmoi/.chezmoitemplates/opencode.json
[406] https://mcp.deepwiki.com/mcp (at 32:15) | Rejected status code: 406 Not Acceptable
Errors in chezmoi/private_dot_agents/skills/okf/templates/concept.md
[ERROR] file://chezmoi/private_dot_agents/skills/okf/templates/url (at 24:5) | File not found. Check if file exists and path is correct
Errors in chezmoi/private_dot_agents/skills/okf/templates/index.md
[ERROR] file://chezmoi/private_dot_agents/skills/okf/templates/relative-url (at 3:3) | File not found. Check if file exists and path is correct
[ERROR] file://chezmoi/private_dot_agents/skills/okf/templates/relative-url (at 4:3) | File not found. Check if file exists and path is correct
[ERROR] file://chezmoi/private_dot_agents/skills/okf/templates/subdir (at 8:3) | File not found. Check if file exists and path is correct
Errors in chezmoi/private_dot_agents/skills/okf/templates/log.md
[ERROR] file://chezmoi/private_dot_agents/skills/okf/templates/bundle-relative-path (at 5:36) | File not found. Check if file exists and path is correct
[ERROR] file://chezmoi/private_dot_agents/skills/okf/templates/bundle-relative-path (at 6:30) | File not found. Check if file exists and path is correct
[ERROR] file://chezmoi/private_dot_agents/skills/okf/templates/bundle-relative-path (at 7:39) | File not found. Check if file exists and path is correct
Errors in chezmoi/private_dot_claude/skills/okf/templates/concept.md
[ERROR] file://chezmoi/private_dot_claude/skills/okf/templates/url (at 24:5) | File not found. Check if file exists and path is correct
Errors in chezmoi/private_dot_claude/skills/okf/templates/index.md
[ERROR] file://chezmoi/private_dot_claude/skills/okf/templates/relative-url (at 3:3) | File not found. Check if file exists and path is correct
[ERROR] file://chezmoi/private_dot_claude/skills/okf/templates/relative-url (at 4:3) | File not found. Check if file exists and path is correct
[ERROR] file://chezmoi/private_dot_claude/skills/okf/templates/subdir (at 8:3) | File not found. Check if file exists and path is correct
Errors in chezmoi/private_dot_claude/skills/okf/templates/log.md
[ERROR] file://chezmoi/private_dot_claude/skills/okf/templates/bundle-relative-path (at 5:36) | File not found. Check if file exists and path is correct
[ERROR] file://chezmoi/private_dot_claude/skills/okf/templates/bundle-relative-path (at 6:30) | File not found. Check if file exists and path is correct
[ERROR] file://chezmoi/private_dot_claude/skills/okf/templates/bundle-relative-path (at 7:39) | File not found. Check if file exists and path is correct
Hint: Followed 3 redirects. You might want to consider replacing redirecting URLs with the resolved URLs. Use verbose mode (`-v`/`-vv`) to see redirection details.
Hint: You can configure accepted/rejected response codes with `-a` or `--accept`
Notices
📣 MegaLinter 9.5.0 is out! Discover the new features and security recommendations in the release announcement. (Skip this info by defining SECURITY_SUGGESTIONS: false)
See detailed reports in MegaLinter artifacts
Your project could benefit from a custom flavor, which would allow you to run only the linters you need, and thus improve runtime performances. (Skip this info by defining FLAVOR_SUGGESTIONS: false)
- Documentation: Custom Flavors
- Command:
npx mega-linter-runner@9.6.0 --custom-flavor-setup --custom-flavor-linters ACTION_ACTIONLINT,ACTION_ZIZMOR,BASH_EXEC,BASH_SHELLCHECK,BASH_SHFMT,COPYPASTE_JSCPD,EDITORCONFIG_EDITORCONFIG_CHECKER,JSON_V8R,JSON_PRETTIER,MARKDOWN_MARKDOWNLINT,MARKDOWN_MARKDOWN_TABLE_FORMATTER,REPOSITORY_CHECKOV,REPOSITORY_GIT_DIFF,REPOSITORY_GITLEAKS,REPOSITORY_BETTERLEAKS,REPOSITORY_GRYPE,REPOSITORY_OSV_SCANNER,REPOSITORY_SECRETLINT,REPOSITORY_SYFT,REPOSITORY_TRIVY,REPOSITORY_TRIVY_SBOM,REPOSITORY_TRUFFLEHOG,SPELL_LYCHEE,YAML_PRETTIER,YAML_YAMLLINT,YAML_V8R

Show us your support by starring ⭐ the repository
- Add mattpocock/skills marketplace and mattpocock-skills plugin to claude setup - Update mattpocock repo skills list with new skills (resolving-merge-conflicts, ask-matt, teach, grill-me) - Remove claude-code from ephemeral agent installs (handled by plugin now) - Enable 1m context variants for all bedrock model overrides and env vars Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
chezmoi/private_dot_claude/skills/okf/scripts/executable_okf-wiki-maintenance.sh (1)
24-28: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick winAdd a stale lock recovery mechanism.
The
mkdirlock is atomic and POSIX-portable, which is excellent. However, if the script is abruptly terminated (e.g., viaSIGKILLor a power loss), theEXITtrap will not execute. This leaves the lock directory behind, which will permanently block all future maintenance runs until the user manually intervenes.Consider checking the lock directory's modification time and forcefully removing it if it's older than a reasonable timeout (e.g., 2 hours).
♻️ Proposed fix to clear stale locks automatically
# Acquire exclusive lock via atomic mkdir — POSIX portable, no flock/shlock needed. +# Clear stale lock (older than 2 hours) to prevent permanent deadlocks +if [ -d "${LOCK_FILE}" ] && [ -n "$(find "${LOCK_FILE}" -maxdepth 0 -mmin +120 2>/dev/null)" ]; then + rmdir "${LOCK_FILE}" 2>/dev/null || true +fi + if ! mkdir "${LOCK_FILE}" 2>/dev/null; then🤖 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 `@chezmoi/private_dot_claude/skills/okf/scripts/executable_okf-wiki-maintenance.sh` around lines 24 - 28, Update the mkdir-based lock acquisition near LOCK_FILE to detect an existing lock directory older than the chosen stale-lock timeout (for example, two hours), remove it, and retry acquisition before exiting. Preserve atomic mkdir behavior for active locks and retain the EXIT trap cleanup for locks created by the current process.
🤖 Prompt for all review comments with 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.
Inline comments:
In `@chezmoi/private_dot_claude/skills/okf/hooks/hooks.json`:
- Around line 3-14: Flatten the SessionEnd configuration by removing the
intermediate object containing the nested hooks array, placing the command
action object directly in the SessionEnd array. Preserve the existing command,
async, and timeout values.
In `@README.md`:
- Around line 62-64: Update the “Current plugins” section in README.md to
accurately reflect all plugins installed by the setup script, or rename the
heading and wording to explicitly identify it as the personal OKF plugin only.
Keep the listed plugin description consistent with the chosen scope.
---
Nitpick comments:
In
`@chezmoi/private_dot_claude/skills/okf/scripts/executable_okf-wiki-maintenance.sh`:
- Around line 24-28: Update the mkdir-based lock acquisition near LOCK_FILE to
detect an existing lock directory older than the chosen stale-lock timeout (for
example, two hours), remove it, and retry acquisition before exiting. Preserve
atomic mkdir behavior for active locks and retain the EXIT trap cleanup for
locks created by the current process.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 9dfc535b-f148-4621-9ced-42e95c4c4653
📒 Files selected for processing (14)
README.mdchezmoi/.chezmoiscripts/run_onchange_after_agent_plugins.sh.tmplchezmoi/.chezmoiscripts/run_onchange_after_setup_claude.sh.tmplchezmoi/.chezmoitemplates/claude-settings.jsonchezmoi/private_dot_claude/skills/okf/SKILL.mdchezmoi/private_dot_claude/skills/okf/SPEC.mdchezmoi/private_dot_claude/skills/okf/dot_claude-plugin/plugin.jsonchezmoi/private_dot_claude/skills/okf/hooks/hooks.jsonchezmoi/private_dot_claude/skills/okf/scripts/executable_okf-wiki-maintenance.shchezmoi/private_dot_claude/skills/okf/scripts/okf-wiki-review.txtchezmoi/private_dot_claude/skills/okf/templates/concept.mdchezmoi/private_dot_claude/skills/okf/templates/index.mdchezmoi/private_dot_claude/skills/okf/templates/log.mdchezmoi/private_dot_claude/skills/symlink_okf
💤 Files with no reviewable changes (1)
- chezmoi/private_dot_claude/skills/symlink_okf
| "SessionEnd": [ | ||
| { | ||
| "hooks": [ | ||
| { | ||
| "type": "command", | ||
| "command": "${CLAUDE_PLUGIN_ROOT}/scripts/okf-wiki-maintenance.sh", | ||
| "async": true, | ||
| "timeout": 300 | ||
| } | ||
| ] | ||
| } | ||
| ] |
There was a problem hiding this comment.
🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win
Fix nested hooks array in hook configuration.
The SessionEnd array contains an object with another nested hooks array. Claude Code expects the action object (e.g., {"type": "command", ...}) to be directly inside the lifecycle event array. This nested structure is likely a copy-paste artifact and may cause the hook to silently fail to execute.
🐛 Proposed fix to flatten the hook structure
- "SessionEnd": [
- {
- "hooks": [
- {
- "type": "command",
- "command": "${CLAUDE_PLUGIN_ROOT}/scripts/okf-wiki-maintenance.sh",
- "async": true,
- "timeout": 300
- }
- ]
- }
- ]
+ "SessionEnd": [
+ {
+ "type": "command",
+ "command": "${CLAUDE_PLUGIN_ROOT}/scripts/okf-wiki-maintenance.sh",
+ "async": true,
+ "timeout": 300
+ }
+ ]📝 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.
| "SessionEnd": [ | |
| { | |
| "hooks": [ | |
| { | |
| "type": "command", | |
| "command": "${CLAUDE_PLUGIN_ROOT}/scripts/okf-wiki-maintenance.sh", | |
| "async": true, | |
| "timeout": 300 | |
| } | |
| ] | |
| } | |
| ] | |
| "SessionEnd": [ | |
| { | |
| "type": "command", | |
| "command": "${CLAUDE_PLUGIN_ROOT}/scripts/okf-wiki-maintenance.sh", | |
| "async": true, | |
| "timeout": 300 | |
| } | |
| ] |
🤖 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 `@chezmoi/private_dot_claude/skills/okf/hooks/hooks.json` around lines 3 - 14,
Flatten the SessionEnd configuration by removing the intermediate object
containing the nested hooks array, placing the command action object directly in
the SessionEnd array. Preserve the existing command, async, and timeout values.
| Current plugins: | ||
|
|
||
| - `okf-wiki` — SessionEnd hook that distills memsearch journals into the `~/wiki` OKF bundle | ||
|
|
||
| To install without cloning the repo: | ||
|
|
||
| ```bash | ||
| claude plugin marketplace add "https://github.com/yxtay/dotfiles" --sparse plugins | ||
| claude plugin install okf-wiki@yxtay | ||
| ``` | ||
| - `okf` — OKF skill + SessionEnd hook that distills memsearch journals into the `~/wiki` OKF bundle |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Keep the “Current plugins” list accurate.
The setup script still installs multiple plugins, but this section lists only okf. Either list the other installed plugins or rename the heading to clarify that this is only the personal OKF plugin.
🤖 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 `@README.md` around lines 62 - 64, Update the “Current plugins” section in
README.md to accurately reflect all plugins installed by the setup script, or
rename the heading and wording to explicitly identify it as the personal OKF
plugin only. Keep the listed plugin description consistent with the chosen
scope.
…ove skill - Move maintenance script and prompt from scripts/ to hooks/ - Update hooks.json command paths to hooks/ - Add SessionStart hook alongside existing SessionEnd - Add completion criterion to maintain mode - Remove redundant conformance check from "Before declaring done" - Replace duplicated Step 5 bullets in prompt with pointer to maintain mode - Clean up resource placeholder in concept template Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
|
The nested hooks structure is intentional and correct — it matches the Claude Code plugin hooks format used by other plugins (e.g. memsearch). The outer array element is a matcher object (can carry a |
Summary
okf-wiki-maintenance.sh,okf-wiki-review.txt,SKILL.md, and theSessionEndhook registration from three separate locations into a single self-contained skills-dir plugin at~/.claude/skills/okf/settings.jsontohooks/hooks.json, co-located with the script it referencessymlink_okf(Claude Code symlink to agents skill) — opencode copy inprivate_dot_agents/skills/okf/is preservedLayout
Loads automatically as
okf@skills-diron session start — no install step required.Summary by CodeRabbit