spacehub

surshar / claude-code

Claude Code is an agentic coding tool that lives in your terminal, understands your codebase, and helps you code faster by executing routine tasks, explaining complex code, and handling git workflows - all through natural language commands.

Built by Anthropic · github.com/anthropics

claude-code / mods / sec-default / hooks / register.ts
74 lines · 2.5 KBRaw
1import type { On } from 'claude-code'
2
3import { admissionFailure } from './admission-failure'
4import { managedModsOnlyRefusal } from './managed-mods-only-refusal'
5import { pastUsers } from './past-users'
6import Policy from './policy'
7import { TOOL_REGISTER_REFUSAL } from './tool-register-refusal'
8
9/**
10 * The built-in's hooks, seated outermost: each keeps one control an
11 * organization has today out of reach of the plugins a person installs.
12 *
13 * Three moves: continue past the user tier (`next.to(e, "append")`), refuse
14 * a user-tier caller or module by name, or pass. Provenance is the event's
15 * pinned `provider` or `tier`; policy is `$.settings.read`; fail closed.
16 *
17 * @param on the engine's registrar
18 */
19export function register(on: On) {
20 const readPolicy = Policy.createPolicyMemo(Policy.POLICY_MEMO_MS)
21
22 on('classic.*', ($, e, next) => next.to(e, 'append'))
23
24 on('prompt.section', ($, e, next) => next.to(e, 'append'))
25 on('prompt.context', ($, e, next) => next.to(e, 'append'))
26 on('prompt.compose', ($, e, next) => next.to(e, 'append'))
27 on('skill.prompt', ($, e, next) => next.to(e, 'append'))
28 on('attribution.text', ($, e, next) => next.to(e, 'append'))
29
30 on('settings.read', ($, e, next) => next.to(e, 'append'))
31
32 on('tool.describe', ($, e, next) => pastUsers(e, next))
33 on('command.describe', ($, e, next) => pastUsers(e, next))
34 on('agent.offer', ($, e, next) => pastUsers(e, next))
35 on('agent.spawn', ($, e, next) => pastUsers(e, next))
36
37 on('tool.register', async ($, e, next) => {
38 const isOrgs =
39 next.origin.tier === 'prepend' || next.origin.tier === 'append'
40
41 if (isOrgs) {
42 return next.to(e, 'append')
43 }
44
45 const isRefused =
46 next.origin.tier === 'user' &&
47 (await Policy.decidedByPolicy(
48 readPolicy(() => $.settings.read(Policy.SOURCE)),
49 Policy.hasMcpAllowlist,
50 ))
51
52 return isRefused ? { deny: TOOL_REGISTER_REFUSAL } : next(e)
53 })
54
55 on('tool.list', async ($, e, next) =>
56 Policy.managedToolsRestored(
57 await readPolicy(() => $.settings.read(Policy.SOURCE)).catch(
58 () => undefined,
59 ),
60 await next.to(e, 'append'),
61 await next(e),
62 ),
63 )
64
65 on('plugin.register', { tier: 'user' }, async ($, e, next) =>
66 Policy.isManagedModsOnly(await $.settings.read(Policy.SOURCE))
67 ? { refuse: managedModsOnlyRefusal(e.name) }
68 : next(e),
69 ).catch(($, e, next) => {
70 $.ui.log(admissionFailure(e.name, next.error), { to: 'debug' })
71
72 return next.called ? next(e) : { refuse: managedModsOnlyRefusal(e.name) }
73 })
74}