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