Skip to content

feat: add /reload-skills slash command (CLI + Web UI) - #1057

Merged
GCWing merged 1 commit into
GCWing:mainfrom
jarvis24young:feat/reload-skills-command
Jun 5, 2026
Merged

feat: add /reload-skills slash command (CLI + Web UI)#1057
GCWing merged 1 commit into
GCWing:mainfrom
jarvis24young:feat/reload-skills-command

Conversation

@jarvis24young

@jarvis24youngjarvis24young commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

对标

Claude Code 2.1.152 changelog:

Added /reload-skills command to re-scan skill directories without restarting the session

这个 PR 做什么

在 BitFun 的 CLI 和 Web UI 同时暴露 /reload-skills 命令,让用户改完 skill 文件后不必重启 BitFun 即可让改动生效。

现状

SkillRegistry::refresh()src/crates/core/src/agentic/tools/implementations/skills/registry.rs:729)和 Tauri RPC get_skill_configs(force_refresh: true)src/apps/desktop/src/api/skill_api.rs:467)以及 configAPI.getSkillConfigs({ forceRefresh: true })src/web-ui/src/infrastructure/api/service-api/ConfigAPI.ts:278全部已就绪——后端+IPC 链路已通。

只缺用户入口。 本 PR 仅加 UI 入口(一个 CommandSpec + 一个 match arm + 一个 action item + 一个 submit 函数 + i18n),0 后端改动。

行为

CLI(/reload-skills

$ /reload-skills
[状态栏] Skills reloaded (12 available)
[系统消息] Reloaded 12 skill(s) from disk.
  • 不需要 is_processing === false 守卫(cheap read,atomic cache swap)
  • 复用 SkillRegistry::global() 直接调用(CLI 跟 desktop 运行时共享同一 registry,不需要走 Tauri bridge)
  • 使用 rt_handle: &tokio::runtime::Handle 参数(与其他 async CLI helper 一致)

Web UI

  1. 聊天输入框输入 / → 命令 picker 多一项 Reload skills
  2. 选中 → 输入框填入 /reload-skills
  3. 按 Enter → 静默 refresh + 成功 toast (Reloaded skills (12 available))
  4. 失败时显示错误 toast (Failed to reload skills)
  5. 输入 /reload-skills foo → 警告 toast Use /reload-skills without extra arguments.

完全复用 /usage/init 的命令路由模式(pick → input → Enter → handleSendOrCancel matcher → submit 函数)。

改动文件

src/apps/cli/src/commands.rs (+1 entry in COMMAND_SPECS)
src/apps/cli/src/modes/chat.rs (+1 match arm + 1 method)
src/web-ui/src/flow_chat/components/ChatInput.tsx (+1 picker entry + 1 selectSlashCommandAction
branch + 1 submitReloadSkillsFromInput
+ 1 handleSendOrCancel matcher
+ 1 handleSendOrCancel startsWith warning
+ 1 deps list entry)
src/web-ui/src/locales/en-US/flow-chat.json (+4 keys)
src/web-ui/src/locales/zh-CN/flow-chat.json (+4 keys)
src/web-ui/src/locales/zh-TW/flow-chat.json (+4 keys)

总计 6 文件,+120 行单 commit fb7996c0,rebase 在最新 origin/main (e8755651) 之上。

验证

自动化

  • cargo check -p bitfun-cli → 0 错误
  • npx tsc --noEmit → 0 错误
  • npx eslint src/flow_chat/components/ChatInput.tsx → 0 错误(含 react-hooks/exhaustive-deps
  • npx vitest run921/921 测试通过
  • node scripts/i18n-contract.test.mjs37/37 通过(i18n 治理契约,含 literal-fallback-baseline 检查)

手动(PR 合入后)

  1. 在 BitFun 打开聊天框
  2. 输入 /reload-skills + Enter
  3. 期望:右下角 toast Reloaded skills (N available),N 包含 workspace-level skills
  4. 输入 /reload-skills foo + Enter
  5. 期望:警告 toast Use /reload-skills without extra arguments.发送消息
  6. (可选)在文件系统里新建/修改一个 skill 文件(~/.bitfun/skills/<workspace>/.bitfun/skills/
  7. 再次输入 /reload-skills + Enter
  8. 期望:toast 数字增加,新 skill 在 picker 中可用

CLI 验证

cargo run -p bitfun-cli
> /reload-skills
[状态栏] Skills reloaded (N available)
[系统消息] Reloaded N skill(s) from disk.

Review 历程(4 轮迭代全部合并为这 1 commit)

轮次触发修复
1独立 codex 静态审查HIGH × 2(workspacePath、startsWith 警告)+ MEDIUM × 3(defaultValue 措辞、CLI 措辞、rt_handle 参数)
2CI i18n 治理失败去掉 5 处字符串字面量 defaultValue(i18n-literal-fallback-baseline 治理)
3CI lint 失败workspacePath 到 useCallback deps 数组(react-hooks/exhaustive-deps
4rebase 到最新 main应用本地 main 新加的 localSlashCommandsEnabled 守卫(/usage/init 等也用这个守卫)

注意

  • PR feat(web-ui): precise slash-command matcher #1023 (feat/precise-slash-command-matcher) 仍 OPEN 等待维护者 review,与本 PR 无关
  • 本 PR 不含 SkillRegistry 任何后端改动
  • 已知问题(pre-existing, 不在 scope):refresh_for_workspace(workspace_root)workspace_root 参数被忽略——已在 PR 描述中提及

jarvis24young added a commit to jarvis24young/BitFun that referenced this pull request Jun 3, 2026
The CI run for PR GCWing#1057 failed on the i18n audit subtest
'i18n audit can emit a machine-readable governance report':
[i18n:audit] ERROR src/web-ui/src/flow_chat/components/ChatInput.tsx
has 5 literal i18next defaultValue fallback(s) but is missing
from scripts/i18n-literal-fallback-baseline.json.
BitFun's i18n governance treats literal defaultValue as a no-growth
guard (scripts/i18n-literal-fallback-baseline.json: "Add or repair
locale resources instead of raising this baseline"). A literal
defaultValue silently masks a missing translation — when the key is
absent, i18next returns the hardcoded English string from source
instead of failing the build. The fix is therefore never to use a
string literal as defaultValue when the key already exists in all
locales; the right pattern is plain `t('key')` (see siblings
`/usage`, `/init`, `/DeepReview` in the same array).
Strip the 5 defaultValue literals from the new /reload-skills calls.
The `count` interpolation in `reloadSkillsDone` is kept (it is a
real i18next interpolation, not a literal).
Verified:
- npx tsc --noEmit: 0 errors
- npx vitest run: 864/864 pass
- node scripts/i18n-contract.test.mjs: 37/37 pass (was 1/37 failing)
Mirrors Claude Code 2.1.152: a slash command that re-scans skill
directories from disk without requiring a session restart.
Both the CLI and the Web UI now expose the same command via a single
shared capability that was already in place end-to-end: the Tauri RPC
get_skill_configs(force_refresh: true) calls
SkillRegistry::global().refresh() and returns the new view, and
configAPI.getSkillConfigs({ forceRefresh: true }) wraps it on the
TS side. The only thing missing was a user-facing entry point on
both surfaces — this PR adds it.
Branch: feat/reload-skills-command, rebased on top of origin/main
(e875565). Single commit containing the full implementation.
---
CLI
- Register /reload-skills in COMMAND_SPECS.
- handle_command dispatches it to a new reload_skills_from_disk
method that calls SkillRegistry::global().refresh() directly
(no Tauri bridge needed in the CLI — it shares the same global
registry as the desktop runtime) and shows a status line with
the reloaded skill count. Not gated on is_processing: the cache
swap is atomic and a held SkillInfo reference is not kept
across the call.
- reload_skills_from_disk takes rt_handle as a parameter and uses
it via rt_handle.block_on, matching the convention used by every
other async CLI helper in this file.
Web UI
- New entry in getFilteredActions: id='reload-skills', command=
'/reload-skills'. Picker-routed.
- selectSlashCommandAction sets the input to the bare command (no
args); user presses Enter to dispatch.
- New submitReloadSkillsFromInput function modeled on
submitUsageFromInput: validates the bare command, clears the
input, calls configAPI.getSkillConfigs with both forceRefresh:
true AND workspacePath so project-level skills (in
.bitfun/skills/, .cursor/skills/, etc.) are included in the
count, and surfaces success / failure via the existing
notificationService toasts.
- New /reload-skills matcher in handleSendOrCancel wrapped in the
localSlashCommandsEnabled guard (matching the existing /usage,
/init, /DeepReview matcher pattern that landed on main while
this branch was in review).
- New 'startsWith' warning for the '/reload-skills foo' case so
the message does not fall through to the agent as a regular
user message.
- i18n defaultValue fallbacks are kept as plain t('key') calls
with no string-literal fallback — i18n audit governance
(scripts/i18n-literal-fallback-baseline.json) treats literal
defaultValue as anti-pattern because it silently masks
missing translations.
i18n (4 keys × 3 locales = 12 insertions):
- chatInput.reloadSkillsAction — picker label
- chatInput.reloadSkillsUsage — arg-validation warning
- chatInput.reloadSkillsDone — success toast (with {{count}})
- chatInput.reloadSkillsFailed — failure toast title
---
Verification:
- cargo check -p bitfun-cli: 0 errors
- npx tsc --noEmit: 0 errors
- npx eslint src/flow_chat/components/ChatInput.tsx: 0 errors
(incl. react-hooks/exhaustive-deps)
- npx vitest run: 921/921 pass
- node scripts/i18n-contract.test.mjs: 37/37 pass
(incl. literal-fallback-baseline check)
@jarvis24young
jarvis24youngforce-pushed the feat/reload-skills-command branch from 596c0de to fb7996cCompareJune 4, 2026 01:32
@GCWing
GCWing requested a review from wsp1911June 4, 2026 07:05
@GCWing
GCWing merged commit ca48283 into GCWing:mainJun 5, 2026
4 checks passed
Sign up for freeto 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.

3 participants

@jarvis24young@wsp1911@GCWing