feat: list eligible hooks in onboarding

This commit is contained in:
Peter Steinberger
2026-01-18 16:07:53 +00:00
parent ffcf3263c1
commit 96ee027371
3 changed files with 43 additions and 4 deletions

View File

@@ -26,6 +26,7 @@ Docs: https://docs.clawd.bot
- Nodes: add headless node host (`clawdbot node start`) for `system.run`/`system.which`. - Nodes: add headless node host (`clawdbot node start`) for `system.run`/`system.which`.
- Nodes: add node daemon service install/status/start/stop/restart. - Nodes: add node daemon service install/status/start/stop/restart.
- Hooks: run `BOOT.md` on gateway startup with the boot-md hook. (#1164) — thanks @ngutman. - Hooks: run `BOOT.md` on gateway startup with the boot-md hook. (#1164) — thanks @ngutman.
- Onboarding: list all eligible hooks with one-line descriptions in the enable step.
- Bridge: add `skills.bins` RPC to support node host auto-allow skill bins. - Bridge: add `skills.bins` RPC to support node host auto-allow skill bins.
- Slash commands: replace `/cost` with `/usage off|tokens|full` to control per-response usage footer; `/usage` no longer aliases `/status`. (Supersedes #1140) — thanks @Nachx639. - Slash commands: replace `/cost` with `/usage off|tokens|full` to control per-response usage footer; `/usage` no longer aliases `/status`. (Supersedes #1140) — thanks @Nachx639.
- Sessions: add daily reset policy with per-type overrides and idle windows (default 4am local), preserving legacy idle-only configs. (#1146) — thanks @austinm911. - Sessions: add daily reset policy with per-type overrides and idle windows (default 4am local), preserving legacy idle-only configs. (#1146) — thanks @austinm911.

View File

@@ -77,6 +77,39 @@ describe("onboard-hooks", () => {
configChecks: [], configChecks: [],
install: [], install: [],
}, },
{
name: "command-logger",
description: "Log all command events to a centralized audit file",
source: "clawdbot-bundled",
pluginId: undefined,
filePath: "/mock/workspace/hooks/command-logger/HOOK.md",
baseDir: "/mock/workspace/hooks/command-logger",
handlerPath: "/mock/workspace/hooks/command-logger/handler.js",
hookKey: "command-logger",
emoji: "📝",
events: ["command"],
homepage: undefined,
always: false,
disabled: false,
eligible,
managedByPlugin: false,
requirements: {
bins: [],
anyBins: [],
env: [],
config: ["workspace.dir"],
os: [],
},
missing: {
bins: [],
anyBins: [],
env: [],
config: eligible ? [] : ["workspace.dir"],
os: [],
},
configChecks: [],
install: [],
},
], ],
}); });
@@ -105,6 +138,11 @@ describe("onboard-hooks", () => {
label: "💾 session-memory", label: "💾 session-memory",
hint: "Save session context to memory when /new command is issued", hint: "Save session context to memory when /new command is issued",
}, },
{
value: "command-logger",
label: "📝 command-logger",
hint: "Log all command events to a centralized audit file",
},
], ],
}); });
}); });

View File

@@ -23,10 +23,10 @@ export async function setupInternalHooks(
const workspaceDir = resolveAgentWorkspaceDir(cfg, resolveDefaultAgentId(cfg)); const workspaceDir = resolveAgentWorkspaceDir(cfg, resolveDefaultAgentId(cfg));
const report = buildWorkspaceHookStatus(workspaceDir, { config: cfg }); const report = buildWorkspaceHookStatus(workspaceDir, { config: cfg });
// Filter for eligible and recommended hooks (session-memory is recommended) // Show every eligible hook so users can opt in during onboarding.
const recommendedHooks = report.hooks.filter((h) => h.eligible && h.name === "session-memory"); const eligibleHooks = report.hooks.filter((h) => h.eligible);
if (recommendedHooks.length === 0) { if (eligibleHooks.length === 0) {
await prompter.note( await prompter.note(
"No eligible hooks found. You can configure hooks later in your config.", "No eligible hooks found. You can configure hooks later in your config.",
"No Hooks Available", "No Hooks Available",
@@ -38,7 +38,7 @@ export async function setupInternalHooks(
message: "Enable hooks?", message: "Enable hooks?",
options: [ options: [
{ value: "__skip__", label: "Skip for now" }, { value: "__skip__", label: "Skip for now" },
...recommendedHooks.map((hook) => ({ ...eligibleHooks.map((hook) => ({
value: hook.name, value: hook.name,
label: `${hook.emoji ?? "🔗"} ${hook.name}`, label: `${hook.emoji ?? "🔗"} ${hook.name}`,
hint: hook.description, hint: hook.description,