@kaitranntt/ccs 7.34.1-dev.5 → 7.34.1-dev.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ccs.js +11 -5
- package/dist/ccs.js.map +1 -1
- package/dist/cliproxy/cliproxy-executor.d.ts.map +1 -1
- package/dist/cliproxy/cliproxy-executor.js +0 -3
- package/dist/cliproxy/cliproxy-executor.js.map +1 -1
- package/dist/cliproxy/services/variant-settings.d.ts.map +1 -1
- package/dist/cliproxy/services/variant-settings.js +5 -0
- package/dist/cliproxy/services/variant-settings.js.map +1 -1
- package/dist/config/unified-config-types.d.ts.map +1 -1
- package/dist/config/unified-config-types.js +3 -0
- package/dist/config/unified-config-types.js.map +1 -1
- package/dist/utils/hooks/image-analyzer-profile-hook-injector.d.ts +1 -1
- package/dist/utils/hooks/image-analyzer-profile-hook-injector.d.ts.map +1 -1
- package/dist/utils/hooks/image-analyzer-profile-hook-injector.js +6 -5
- package/dist/utils/hooks/image-analyzer-profile-hook-injector.js.map +1 -1
- package/dist/utils/hooks/index.d.ts +0 -1
- package/dist/utils/hooks/index.d.ts.map +1 -1
- package/dist/utils/hooks/index.js +1 -4
- package/dist/utils/hooks/index.js.map +1 -1
- package/dist/utils/image-analysis/hook-installer.d.ts +1 -26
- package/dist/utils/image-analysis/hook-installer.d.ts.map +1 -1
- package/dist/utils/image-analysis/hook-installer.js +2 -97
- package/dist/utils/image-analysis/hook-installer.js.map +1 -1
- package/dist/utils/image-analysis/index.d.ts +2 -2
- package/dist/utils/image-analysis/index.d.ts.map +1 -1
- package/dist/utils/image-analysis/index.js +2 -6
- package/dist/utils/image-analysis/index.js.map +1 -1
- package/dist/utils/shell-executor.d.ts.map +1 -1
- package/dist/utils/shell-executor.js +2 -4
- package/dist/utils/shell-executor.js.map +1 -1
- package/lib/hooks/image-analyzer-transformer.cjs +131 -9
- package/package.json +1 -1
- package/dist/utils/hooks/image-read-block-hook-env.d.ts +0 -34
- package/dist/utils/hooks/image-read-block-hook-env.d.ts.map +0 -1
- package/dist/utils/hooks/image-read-block-hook-env.js +0 -52
- package/dist/utils/hooks/image-read-block-hook-env.js.map +0 -1
- package/lib/hooks/block-image-read.cjs +0 -170
|
@@ -1,170 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* CCS Image Read Blocking Hook
|
|
4
|
-
*
|
|
5
|
-
* Blocks Claude's Read tool from reading image files to prevent context overflow.
|
|
6
|
-
* Each image can consume 100K+ tokens, causing immediate context exhaustion.
|
|
7
|
-
*
|
|
8
|
-
* This is a PreToolUse hook that runs BEFORE the tool is executed.
|
|
9
|
-
*
|
|
10
|
-
* Behavior (matches WebSearch pattern):
|
|
11
|
-
* - ENABLED by default for third-party profiles (settings, cliproxy)
|
|
12
|
-
* - DISABLED for native Claude accounts (account, default profiles)
|
|
13
|
-
* - User can override via config: hooks.block_image_read.enabled: false
|
|
14
|
-
*
|
|
15
|
-
* Usage:
|
|
16
|
-
* Configured in ~/.claude/settings.json:
|
|
17
|
-
* {
|
|
18
|
-
* "hooks": {
|
|
19
|
-
* "PreToolUse": [{
|
|
20
|
-
* "matcher": "Read",
|
|
21
|
-
* "hooks": [{
|
|
22
|
-
* "type": "command",
|
|
23
|
-
* "command": "node ~/.ccs/hooks/block-image-read.cjs",
|
|
24
|
-
* "timeout": 5
|
|
25
|
-
* }]
|
|
26
|
-
* }]
|
|
27
|
-
* }
|
|
28
|
-
* }
|
|
29
|
-
*
|
|
30
|
-
* Environment Variables (set by CCS):
|
|
31
|
-
* CCS_BLOCK_IMAGE_READ=1 - Enable blocking (default for third-party)
|
|
32
|
-
* CCS_BLOCK_IMAGE_READ=0 - Disable blocking
|
|
33
|
-
* CCS_PROFILE_TYPE - Profile type (account, default, settings, cliproxy)
|
|
34
|
-
* CCS_DEBUG=1 - Enable debug output
|
|
35
|
-
*
|
|
36
|
-
* Exit codes:
|
|
37
|
-
* 0 - Allow tool (pass-through)
|
|
38
|
-
* 2 - Block tool (deny with message)
|
|
39
|
-
*
|
|
40
|
-
* @module hooks/block-image-read
|
|
41
|
-
*/
|
|
42
|
-
|
|
43
|
-
// Image file extensions to block
|
|
44
|
-
const IMAGE_EXTENSIONS = /\.(png|jpg|jpeg|webp|gif|bmp|tiff|tif|ico|svg|heic|heif|avif)$/i;
|
|
45
|
-
|
|
46
|
-
// Read input from stdin
|
|
47
|
-
let input = '';
|
|
48
|
-
process.stdin.setEncoding('utf8');
|
|
49
|
-
process.stdin.on('data', (chunk) => {
|
|
50
|
-
input += chunk;
|
|
51
|
-
});
|
|
52
|
-
process.stdin.on('end', () => {
|
|
53
|
-
processHook();
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
// Handle stdin not being available
|
|
57
|
-
process.stdin.on('error', () => {
|
|
58
|
-
process.exit(0);
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* Check if hook should skip (for native Claude accounts).
|
|
63
|
-
* Matches WebSearch hook pattern.
|
|
64
|
-
*/
|
|
65
|
-
function shouldSkipHook() {
|
|
66
|
-
// Account/default profiles use native Claude - don't block
|
|
67
|
-
const profileType = process.env.CCS_PROFILE_TYPE;
|
|
68
|
-
if (profileType === 'account' || profileType === 'default') {
|
|
69
|
-
if (process.env.CCS_DEBUG) {
|
|
70
|
-
console.error(`[CCS Hook] Skipping image block for profile type: ${profileType}`);
|
|
71
|
-
}
|
|
72
|
-
return true;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
// Explicit disable via config
|
|
76
|
-
if (process.env.CCS_BLOCK_IMAGE_READ === '0') {
|
|
77
|
-
if (process.env.CCS_DEBUG) {
|
|
78
|
-
console.error('[CCS Hook] Image read blocking disabled by config');
|
|
79
|
-
}
|
|
80
|
-
return true;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
return false;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* Main hook processing logic
|
|
88
|
-
*/
|
|
89
|
-
function processHook() {
|
|
90
|
-
try {
|
|
91
|
-
// Skip for native accounts or explicit disable
|
|
92
|
-
if (shouldSkipHook()) {
|
|
93
|
-
process.exit(0);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
const data = JSON.parse(input);
|
|
97
|
-
|
|
98
|
-
// Only handle Read tool
|
|
99
|
-
if (data.tool_name !== 'Read') {
|
|
100
|
-
process.exit(0);
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
const filePath = data.tool_input?.file_path || '';
|
|
104
|
-
|
|
105
|
-
if (process.env.CCS_DEBUG) {
|
|
106
|
-
console.error(`[CCS Hook] Read intercepted: ${filePath}`);
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
// Check if file is an image
|
|
110
|
-
if (IMAGE_EXTENSIONS.test(filePath)) {
|
|
111
|
-
if (process.env.CCS_DEBUG) {
|
|
112
|
-
console.error(`[CCS Hook] Blocking image read: ${filePath}`);
|
|
113
|
-
}
|
|
114
|
-
outputBlock(filePath);
|
|
115
|
-
return;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
// Allow non-image files
|
|
119
|
-
process.exit(0);
|
|
120
|
-
} catch (err) {
|
|
121
|
-
if (process.env.CCS_DEBUG) {
|
|
122
|
-
console.error('[CCS Hook] Parse error:', err.message);
|
|
123
|
-
}
|
|
124
|
-
// Don't block on parse errors
|
|
125
|
-
process.exit(0);
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
/**
|
|
130
|
-
* Output block response and exit
|
|
131
|
-
*/
|
|
132
|
-
function outputBlock(filePath) {
|
|
133
|
-
// Extract just the filename for cleaner display
|
|
134
|
-
const fileName = filePath.split(/[/\\]/).pop() || filePath;
|
|
135
|
-
|
|
136
|
-
const message = [
|
|
137
|
-
'[Image Read Blocked - Context Protection]',
|
|
138
|
-
'',
|
|
139
|
-
`File: ${fileName}`,
|
|
140
|
-
`Path: ${filePath}`,
|
|
141
|
-
'',
|
|
142
|
-
'Image files consume 100K+ tokens each and will exhaust context.',
|
|
143
|
-
'',
|
|
144
|
-
'The image was generated successfully. To view it:',
|
|
145
|
-
' - Open the file path above in your image viewer',
|
|
146
|
-
' - Use your file manager to navigate to the location',
|
|
147
|
-
' - On macOS: open "' + filePath + '"',
|
|
148
|
-
' - On Linux: xdg-open "' + filePath + '"',
|
|
149
|
-
' - On Windows: start "" "' + filePath + '"',
|
|
150
|
-
'',
|
|
151
|
-
'If you need to analyze the image, use the ai-multimodal skill',
|
|
152
|
-
'which processes images via Gemini API without loading into context.',
|
|
153
|
-
].join('\n');
|
|
154
|
-
|
|
155
|
-
const output = {
|
|
156
|
-
decision: 'block',
|
|
157
|
-
reason: 'Image file blocked to prevent context overflow',
|
|
158
|
-
// User-facing message (shows in CLI output)
|
|
159
|
-
systemMessage: `[Image Read Blocked] ${fileName} - Open file directly to view.`,
|
|
160
|
-
hookSpecificOutput: {
|
|
161
|
-
hookEventName: 'PreToolUse',
|
|
162
|
-
permissionDecision: 'deny',
|
|
163
|
-
// Claude reads this - explains what happened and alternatives
|
|
164
|
-
permissionDecisionReason: message,
|
|
165
|
-
},
|
|
166
|
-
};
|
|
167
|
-
|
|
168
|
-
console.log(JSON.stringify(output));
|
|
169
|
-
process.exit(2);
|
|
170
|
-
}
|