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
2 changes: 1 addition & 1 deletion .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
{
"name": "ragkit",
"source": "./plugins/ragkit",
"version": "0.1.4",
"version": "0.1.5",
"description": "Standalone knowledge-base RAG plugin (vector/lexical/metadata multi-channel recall).",
"category": "database",
"homepage": "https://github.com/qxbyte/pluginhub",
Expand Down
2 changes: 1 addition & 1 deletion plugins/ragkit/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ragkit",
"version": "0.1.4",
"version": "0.1.5",
"description": "Standalone knowledge-base RAG: chunk + embed + multi-channel recall (vector/lexical/metadata, RRF-fused) over distill-style knowledge-base/ directories.",
"author": {
"name": "xueqiang",
Expand Down
6 changes: 6 additions & 0 deletions plugins/ragkit/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

## Unreleased

## 0.1.5 (2026-07-08) — 加 session-start bootstrap hook(无 command 也能在 CodeBuddy 出命令)

- **新增 `hooks/`(session-start bootstrap)**——这是 superpowers 无 command 却能触发/显示 skill 的关键,ragkit 之前缺这块。0.1.4 去掉 commands 后:**Claude Code 原生发现插件 skill、仍出 `/ragkit:*`;但 CodeBuddy 上没有 bootstrap 的插件 skill 是"死的"**(不出命令、模型也不主动调)——对上 superpowers porting 指南那句"bootstrap 就是整个集成,没有它 skill 文件是死的"。
- 新增文件:`hooks/hooks.json`(SessionStart)+ `hooks/run-hook.sh`(复用 specode 的纯 Python 探测启动器,不走 uv,已在同环境验证)+ `scripts/ragkit_hooks.py`(注入 bootstrap,镜像 spec_hooks.py 的 emit 格式)。
- bootstrap 内容:声明四个 skill(query/embed/status/eval)+ **防脱轨硬护栏**——只按名调 skill、绝不在文件系统搜 skill/脚本文件(插件在缓存目录不在项目里)、检索只准调 ragkit 脚本、严禁自己读 `.ragkit` 向量/装 numpy/手搓相似度、脚本失败即停报错。直接堵死执行记录-2 那种"绕开插件手搓检索"。

## 0.1.4 (2026-07-08) — 去 commands,skill 直接出斜杠(修记录 2 脱轨元凶)

- **删掉 `commands/` 目录**(4 个薄壳命令),并从 4 个 skill 去掉 `user-invocable: false`。Claude Code 里 command 已并入 skill——默认(不写 `user-invocable`)的 skill 自动就有 `/ragkit:*` 斜杠入口 + 模型自动调,两样都占。`/ragkit:query` 等入口不变,只是现在**直接由 skill 提供**。
Expand Down
14 changes: 14 additions & 0 deletions plugins/ragkit/hooks/hooks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"hooks": {
"SessionStart": [
{
"hooks": [
{
"type": "command",
"command": "sh \"${CLAUDE_PLUGIN_ROOT:-${CODEBUDDY_PLUGIN_ROOT}}/hooks/run-hook.sh\" \"${CLAUDE_PLUGIN_ROOT:-${CODEBUDDY_PLUGIN_ROOT}}/scripts/ragkit_hooks.py\" session-start"
}
]
}
]
}
}
40 changes: 40 additions & 0 deletions plugins/ragkit/hooks/run-hook.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#!/bin/sh
# ragkit plugin python launcher (POSIX / Git Bash / MSYS).
# 依次探测 python3 / python / py,找到就 exec 并透传所有参数。
#
# Windows 注意:PATH 上的 python.exe / python3.exe 可能是 Microsoft Store 的
# App Execution Alias stub(路径形如 .../WindowsApps/python3.exe,跑起来只会
# 打印 "Python was not found" 并 exit 49)。这里通过路径模式跳过这种 stub,
# 继续探测真实解释器(通常落在 py launcher 上)。

set -u

_specode_is_alias_stub() {
case "$1" in
*/WindowsApps/python.exe|*/WindowsApps/python3.exe) return 0 ;;
*/WindowsApps/python|*/WindowsApps/python3) return 0 ;;
esac
return 1
}

p3="$(command -v python3 2>/dev/null || true)"
if [ -n "$p3" ] && ! _specode_is_alias_stub "$p3"; then
exec "$p3" "$@"
fi

p="$(command -v python 2>/dev/null || true)"
if [ -n "$p" ] && ! _specode_is_alias_stub "$p"; then
exec "$p" "$@"
fi

if command -v py >/dev/null 2>&1; then
exec py -3 "$@"
fi

printf '%s\n' "ragkit: 未找到可用的 Python 解释器(已尝试 python3 / python / py)。" >&2
printf '%s\n' " 请安装 Python 3.8+ 并确保其位于 PATH 中后再次重试。" >&2
printf '%s\n' " Windows 用户:若提示 \"Python was not found\",多半是命中了 Microsoft" >&2
printf '%s\n' " Store 的 python.exe 别名 stub。请从 python.org 安装真 Python,或在" >&2
printf '%s\n' " 「设置 > 应用 > 高级应用设置 > 应用执行别名」中关闭 python.exe /" >&2
printf '%s\n' " python3.exe 的 Microsoft Store 别名。" >&2
exit 127
53 changes: 53 additions & 0 deletions plugins/ragkit/scripts/ragkit_hooks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#!/usr/bin/env python3
"""ragkit_hooks.py — RagKit's only hook: SessionStart bootstrap injection.

Reads stdin (tolerates non-TTY / empty), emits an additionalContext JSON to
stdout, exit 0. Swallows any exception and exits 0 (advisory, never blocks).

Why this exists: on harnesses like CodeBuddy a plugin's skills stay INERT
without a session-start bootstrap — they don't surface as commands and the
model won't reach for them (superpowers' porting guide: "the bootstrap is the
entire integration; without it the skill files are inert"). Claude Code
natively discovers plugin skills, so RagKit worked there without a hook; other
harnesses need this. Mirrors specode's spec_hooks.py emit shape (proven on the
same setup). The bootstrap also carries the hard guardrail that stops a weak
model from bypassing the plugin and hand-rolling retrieval.
"""
from __future__ import annotations

import json
import sys

BOOTSTRAP = (
"RagKit 可用:对项目 `knowledge-base/` 做多路检索(向量+词汇+元数据,RRF 融合)。"
"四个 skill —— `ragkit:query`(检索,返回定位卡片)/ `ragkit:embed`(构建/更新向量索引)"
"/ `ragkit:status`(索引健康)/ `ragkit:eval`(检索精度评估)。用户要检索 / 建索引 / 查健康时,"
"用 `Skill` 工具**按名调用**对应 skill(`/ragkit:*` 或直接按名,无需去找命令文件)。"
"硬约束(防脱轨):① 只按名调 skill,**绝不在文件系统里搜 skill / 脚本文件**——"
"插件文件在插件缓存目录、不在你的项目里,skill 内部会自己定位脚本;"
"② 检索**只能**调 RagKit 的脚本,**严禁**自己读 `.ragkit` 向量文件、装 numpy、"
"或用 embedding API 手搓相似度(结果会错且不可复现);"
"③ 脚本定位 / 运行失败 → 停下报确切错误,不要绕过、不要自己实现。"
)


def main() -> int:
try:
try:
sys.stdin.read()
except Exception:
pass
out = {
"hookSpecificOutput": {
"hookEventName": "SessionStart",
"additionalContext": BOOTSTRAP,
}
}
sys.stdout.write(json.dumps(out, ensure_ascii=False))
except Exception:
pass
return 0


if __name__ == "__main__":
sys.exit(main())
Loading