MCPcopy
hub / github.com/codeaashu/claude-code / usePermissionRequestLogging

Function usePermissionRequestLogging

src/components/permissions/hooks.ts:101–209  ·  view source on GitHub ↗
(
  toolUseConfirm: ToolUseConfirm,
  unaryEvent: UnaryEvent,
)

Source from the content-addressed store, hash-verified

99 * Handles both the analytics event and the unary event logging.
100 */
101export function usePermissionRequestLogging(
102 toolUseConfirm: ToolUseConfirm,
103 unaryEvent: UnaryEvent,
104): void {
105 const setAppState = useSetAppState()
106 // Guard against effect re-firing if toolUseConfirm's object reference
107 // changes during a single dialog's lifetime (e.g., parent re-renders with a
108 // fresh object). Without this, the unconditional setAppState below can
109 // cascade into an infinite microtask loop — each re-fire does another
110 // setAppState spread + (ant builds) splitCommand → shell-quote regex,
111 // pegging CPU at 100% and leaking ~500MB/min in JSRopeString/RegExp allocs.
112 // The component is keyed by toolUseID, so this ref resets on remount —
113 // we only need to dedupe re-fires WITHIN one dialog instance.
114 const loggedToolUseID = useRef<string | null>(null)
115
116 useEffect(() => {
117 if (loggedToolUseID.current === toolUseConfirm.toolUseID) {
118 return
119 }
120 loggedToolUseID.current = toolUseConfirm.toolUseID
121
122 // Increment permission prompt count for attribution tracking
123 setAppState(prev => ({
124 ...prev,
125 attribution: {
126 ...prev.attribution,
127 permissionPromptCount: prev.attribution.permissionPromptCount + 1,
128 },
129 }))
130
131 // Log analytics event
132 logEvent('tengu_tool_use_show_permission_request', {
133 messageID: toolUseConfirm.assistantMessage.message
134 .id as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
135 toolName: sanitizeToolNameForAnalytics(toolUseConfirm.tool.name),
136 isMcp: toolUseConfirm.tool.isMcp ?? false,
137 decisionReasonType: toolUseConfirm.permissionResult.decisionReason
138 ?.type as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
139 sandboxEnabled: SandboxManager.isSandboxingEnabled(),
140 })
141
142 if (process.env.USER_TYPE === 'ant') {
143 const permissionResult = toolUseConfirm.permissionResult
144 if (
145 toolUseConfirm.tool.name === BashTool.name &&
146 permissionResult.behavior === 'ask' &&
147 !hasRules(permissionResult.suggestions)
148 ) {
149 // Log if no rule suggestions ("always allow") are provided
150 logEvent('tengu_internal_tool_use_permission_request_no_always_allow', {
151 messageID: toolUseConfirm.assistantMessage.message
152 .id as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
153 toolName: sanitizeToolNameForAnalytics(toolUseConfirm.tool.name),
154 isMcp: toolUseConfirm.tool.isMcp ?? false,
155 decisionReasonType: (permissionResult.decisionReason?.type ??
156 'unknown') as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
157 sandboxEnabled: SandboxManager.isSandboxingEnabled(),
158

Callers 6

SkillPermissionRequestFunction · 0.85
FilePermissionDialogFunction · 0.85

Calls 9

useSetAppStateFunction · 0.85
logEventFunction · 0.85
hasRulesFunction · 0.85
decisionReasonToStringFunction · 0.85
splitCommand_DEPRECATEDFunction · 0.85
jsonStringifyFunction · 0.85
logUnaryEventFunction · 0.85
isSandboxingEnabledMethod · 0.80

Tested by

no test coverage detected