@kaitranntt/ccs 7.34.1-dev.3 → 7.34.1-dev.5

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.
Files changed (117) hide show
  1. package/dist/ccs.js +5 -0
  2. package/dist/ccs.js.map +1 -1
  3. package/dist/cliproxy/cliproxy-executor.d.ts.map +1 -1
  4. package/dist/cliproxy/cliproxy-executor.js +26 -0
  5. package/dist/cliproxy/cliproxy-executor.js.map +1 -1
  6. package/dist/commands/config-command.d.ts.map +1 -1
  7. package/dist/commands/config-command.js +14 -0
  8. package/dist/commands/config-command.js.map +1 -1
  9. package/dist/commands/config-image-analysis-command.d.ts +8 -0
  10. package/dist/commands/config-image-analysis-command.d.ts.map +1 -0
  11. package/dist/commands/config-image-analysis-command.js +175 -0
  12. package/dist/commands/config-image-analysis-command.js.map +1 -0
  13. package/dist/commands/help-command.d.ts.map +1 -1
  14. package/dist/commands/help-command.js +14 -0
  15. package/dist/commands/help-command.js.map +1 -1
  16. package/dist/commands/index.d.ts +1 -0
  17. package/dist/commands/index.d.ts.map +1 -1
  18. package/dist/commands/index.js +3 -1
  19. package/dist/commands/index.js.map +1 -1
  20. package/dist/commands/update-command.js +15 -5
  21. package/dist/commands/update-command.js.map +1 -1
  22. package/dist/config/unified-config-loader.d.ts +7 -1
  23. package/dist/config/unified-config-loader.d.ts.map +1 -1
  24. package/dist/config/unified-config-loader.js +157 -24
  25. package/dist/config/unified-config-loader.js.map +1 -1
  26. package/dist/config/unified-config-types.d.ts +19 -0
  27. package/dist/config/unified-config-types.d.ts.map +1 -1
  28. package/dist/config/unified-config-types.js +18 -1
  29. package/dist/config/unified-config-types.js.map +1 -1
  30. package/dist/management/checks/image-analysis-check.d.ts +16 -0
  31. package/dist/management/checks/image-analysis-check.d.ts.map +1 -0
  32. package/dist/management/checks/image-analysis-check.js +164 -0
  33. package/dist/management/checks/image-analysis-check.js.map +1 -0
  34. package/dist/management/checks/index.d.ts +1 -0
  35. package/dist/management/checks/index.d.ts.map +1 -1
  36. package/dist/management/checks/index.js +5 -1
  37. package/dist/management/checks/index.js.map +1 -1
  38. package/dist/management/doctor.d.ts.map +1 -1
  39. package/dist/management/doctor.js +4 -0
  40. package/dist/management/doctor.js.map +1 -1
  41. package/dist/management/repair/auto-repair.d.ts.map +1 -1
  42. package/dist/management/repair/auto-repair.js +16 -0
  43. package/dist/management/repair/auto-repair.js.map +1 -1
  44. package/dist/ui/assets/{accounts-BROl36rt.js → accounts-b2F3ZAU8.js} +1 -1
  45. package/dist/ui/assets/{alert-dialog-Bc0CRwpK.js → alert-dialog-L3d8GDXi.js} +1 -1
  46. package/dist/ui/assets/{api-BTvodZ9c.js → api-BuyRFWlp.js} +1 -1
  47. package/dist/ui/assets/auth-section-BpICzMKK.js +1 -0
  48. package/dist/ui/assets/backups-section-CAqSh_mu.js +1 -0
  49. package/dist/ui/assets/{cliproxy-CL-Lk791.js → cliproxy-CcLAW8bB.js} +2 -2
  50. package/dist/ui/assets/cliproxy-control-panel-K7xiAvok.js +1 -0
  51. package/dist/ui/assets/{confirm-dialog-B0UGiTIr.js → confirm-dialog-OG_57rDw.js} +1 -1
  52. package/dist/ui/assets/{copilot-DoojagGr.js → copilot-NIAKmbdW.js} +2 -2
  53. package/dist/ui/assets/globalenv-section-DdsS7yEO.js +1 -0
  54. package/dist/ui/assets/health--QCS2yIj.js +1 -0
  55. package/dist/ui/assets/{icons-B_4flurP.js → icons-D5eAI-GR.js} +1 -1
  56. package/dist/ui/assets/{index-8_6THoWM.css → index-BL8DS7Z0.css} +1 -1
  57. package/dist/ui/assets/{index-Dhj9QHKA.js → index-BcClU15l.js} +1 -1
  58. package/dist/ui/assets/index-C2Cx0QB3.js +1 -0
  59. package/dist/ui/assets/{index-C8D32oPF.js → index-CxBjoBIe.js} +16 -16
  60. package/dist/ui/assets/index-D4NhXgPa.js +1 -0
  61. package/dist/ui/assets/index-Dl9qz9yj.js +1 -0
  62. package/dist/ui/assets/proxy-status-widget-BvGTE0sc.js +1 -0
  63. package/dist/ui/assets/shared-CBqyGf1c.js +1 -0
  64. package/dist/ui/assets/{switch-l6toeZhu.js → switch-Cl6oSNjg.js} +1 -1
  65. package/dist/ui/index.html +3 -3
  66. package/dist/utils/hooks/get-image-analysis-hook-env.d.ts +17 -0
  67. package/dist/utils/hooks/get-image-analysis-hook-env.d.ts.map +1 -0
  68. package/dist/utils/hooks/get-image-analysis-hook-env.js +42 -0
  69. package/dist/utils/hooks/get-image-analysis-hook-env.js.map +1 -0
  70. package/dist/utils/hooks/image-analyzer-hook-configuration.d.ts +21 -0
  71. package/dist/utils/hooks/image-analyzer-hook-configuration.d.ts.map +1 -0
  72. package/dist/utils/hooks/image-analyzer-hook-configuration.js +78 -0
  73. package/dist/utils/hooks/image-analyzer-hook-configuration.js.map +1 -0
  74. package/dist/utils/hooks/image-analyzer-hook-installer.d.ts +31 -0
  75. package/dist/utils/hooks/image-analyzer-hook-installer.d.ts.map +1 -0
  76. package/dist/utils/hooks/image-analyzer-hook-installer.js +148 -0
  77. package/dist/utils/hooks/image-analyzer-hook-installer.js.map +1 -0
  78. package/dist/utils/hooks/image-analyzer-profile-hook-injector.d.ts +24 -0
  79. package/dist/utils/hooks/image-analyzer-profile-hook-injector.d.ts.map +1 -0
  80. package/dist/utils/hooks/image-analyzer-profile-hook-injector.js +250 -0
  81. package/dist/utils/hooks/image-analyzer-profile-hook-injector.js.map +1 -0
  82. package/dist/utils/hooks/image-read-block-hook-env.d.ts +34 -0
  83. package/dist/utils/hooks/image-read-block-hook-env.d.ts.map +1 -0
  84. package/dist/utils/hooks/image-read-block-hook-env.js +52 -0
  85. package/dist/utils/hooks/image-read-block-hook-env.js.map +1 -0
  86. package/dist/utils/hooks/index.d.ts +12 -0
  87. package/dist/utils/hooks/index.d.ts.map +1 -0
  88. package/dist/utils/hooks/index.js +24 -0
  89. package/dist/utils/hooks/index.js.map +1 -0
  90. package/dist/utils/image-analysis/hook-installer.d.ts +48 -0
  91. package/dist/utils/image-analysis/hook-installer.d.ts.map +1 -0
  92. package/dist/utils/image-analysis/hook-installer.js +214 -0
  93. package/dist/utils/image-analysis/hook-installer.js.map +1 -0
  94. package/dist/utils/image-analysis/index.d.ts +7 -0
  95. package/dist/utils/image-analysis/index.d.ts.map +1 -0
  96. package/dist/utils/image-analysis/index.js +17 -0
  97. package/dist/utils/image-analysis/index.js.map +1 -0
  98. package/dist/utils/shell-executor.d.ts +1 -0
  99. package/dist/utils/shell-executor.d.ts.map +1 -1
  100. package/dist/utils/shell-executor.js +28 -3
  101. package/dist/utils/shell-executor.js.map +1 -1
  102. package/lib/hooks/block-image-read.cjs +170 -0
  103. package/lib/hooks/image-analyzer-transformer.cjs +758 -0
  104. package/lib/prompts/image-analysis-default.txt +12 -0
  105. package/lib/prompts/image-analysis-document.txt +13 -0
  106. package/lib/prompts/image-analysis-screenshot.txt +13 -0
  107. package/package.json +3 -2
  108. package/dist/ui/assets/auth-section-CdJfwuku.js +0 -1
  109. package/dist/ui/assets/backups-section-C1QbR4iU.js +0 -1
  110. package/dist/ui/assets/cliproxy-control-panel-C67g3-lG.js +0 -1
  111. package/dist/ui/assets/globalenv-section-DWvTHsju.js +0 -1
  112. package/dist/ui/assets/health-kyBi8s6g.js +0 -1
  113. package/dist/ui/assets/index-Br2-kfvk.js +0 -1
  114. package/dist/ui/assets/index-CaHIXCeK.js +0 -1
  115. package/dist/ui/assets/index-DaeRFGpX.js +0 -1
  116. package/dist/ui/assets/proxy-status-widget-CRQnzDjM.js +0 -1
  117. package/dist/ui/assets/shared-CjMwFBIs.js +0 -1
@@ -0,0 +1,250 @@
1
+ "use strict";
2
+ /**
3
+ * Image Analyzer Profile Hook Injector
4
+ *
5
+ * Injects image analyzer hooks into per-profile settings files.
6
+ * This replaces the global ~/.claude/settings.json approach.
7
+ *
8
+ * Only injects for CLIProxy profiles (agy, gemini) that support vision analysis.
9
+ *
10
+ * @module utils/hooks/image-analyzer-profile-injector
11
+ */
12
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
13
+ if (k2 === undefined) k2 = k;
14
+ var desc = Object.getOwnPropertyDescriptor(m, k);
15
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
16
+ desc = { enumerable: true, get: function() { return m[k]; } };
17
+ }
18
+ Object.defineProperty(o, k2, desc);
19
+ }) : (function(o, m, k, k2) {
20
+ if (k2 === undefined) k2 = k;
21
+ o[k2] = m[k];
22
+ }));
23
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
24
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
25
+ }) : function(o, v) {
26
+ o["default"] = v;
27
+ });
28
+ var __importStar = (this && this.__importStar) || function (mod) {
29
+ if (mod && mod.__esModule) return mod;
30
+ var result = {};
31
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
32
+ __setModuleDefault(result, mod);
33
+ return result;
34
+ };
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.removeMigrationMarker = exports.ensureProfileHooks = void 0;
37
+ const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
39
+ const ui_1 = require("../ui");
40
+ const image_analyzer_hook_configuration_1 = require("./image-analyzer-hook-configuration");
41
+ const unified_config_loader_1 = require("../../config/unified-config-loader");
42
+ const config_manager_1 = require("../config-manager");
43
+ // Valid profile name pattern (alphanumeric, dash, underscore only)
44
+ const VALID_PROFILE_NAME = /^[a-zA-Z0-9_-]+$/;
45
+ /**
46
+ * Get migration marker path (respects CCS_HOME for test isolation)
47
+ */
48
+ function getMigrationMarkerPath() {
49
+ return path.join((0, config_manager_1.getCcsDir)(), '.image-analyzer-hook-migrated');
50
+ }
51
+ /**
52
+ * Check if CCS image analyzer hook exists in settings
53
+ */
54
+ function hasCcsHook(settings) {
55
+ const hooks = settings.hooks;
56
+ if (!hooks?.PreToolUse)
57
+ return false;
58
+ return hooks.PreToolUse.some((h) => {
59
+ const hook = h;
60
+ if (hook.matcher !== 'Read')
61
+ return false;
62
+ const hookArray = hook.hooks;
63
+ const command = hookArray?.[0]?.command;
64
+ if (typeof command !== 'string')
65
+ return false;
66
+ const normalized = command
67
+ .replace(/\\/g, '/') // Windows backslashes
68
+ .replace(/\/+/g, '/'); // Collapse multiple slashes
69
+ return normalized.includes('.ccs/hooks/image-analyzer-transformer');
70
+ });
71
+ }
72
+ /**
73
+ * One-time migration marker management
74
+ */
75
+ function migrateGlobalHook() {
76
+ const markerPath = getMigrationMarkerPath();
77
+ if (fs.existsSync(markerPath)) {
78
+ return; // Already migrated
79
+ }
80
+ try {
81
+ // No global hook to migrate (image analyzer is profile-only from the start)
82
+ // Just create marker to prevent future migration attempts
83
+ const ccsDir = (0, config_manager_1.getCcsDir)();
84
+ if (!fs.existsSync(ccsDir)) {
85
+ fs.mkdirSync(ccsDir, { recursive: true, mode: 0o700 });
86
+ }
87
+ // Create marker file atomically (wx = fail if exists, prevents race condition)
88
+ fs.writeFileSync(markerPath, new Date().toISOString(), { encoding: 'utf8', flag: 'wx' });
89
+ }
90
+ catch (error) {
91
+ if (process.env.CCS_DEBUG) {
92
+ console.error((0, ui_1.warn)(`Migration failed: ${error.message}`));
93
+ }
94
+ }
95
+ }
96
+ /**
97
+ * Ensure image analyzer hook is configured in profile's settings file
98
+ *
99
+ * Only injects for CLIProxy profiles with vision support (agy, gemini).
100
+ *
101
+ * @param profileName - Name of the profile (e.g., 'agy', 'gemini')
102
+ * @returns true if hook is configured (existing or newly added)
103
+ */
104
+ function ensureProfileHooks(profileName) {
105
+ try {
106
+ // Validate profile name to prevent path traversal
107
+ if (!VALID_PROFILE_NAME.test(profileName)) {
108
+ if (process.env.CCS_DEBUG) {
109
+ console.error((0, ui_1.warn)(`Invalid profile name: ${profileName}`));
110
+ }
111
+ return false;
112
+ }
113
+ // Only inject for CLIProxy profiles with vision support
114
+ const visionProfiles = ['agy', 'gemini'];
115
+ if (!visionProfiles.includes(profileName)) {
116
+ return false;
117
+ }
118
+ const imageConfig = (0, unified_config_loader_1.getImageAnalysisConfig)();
119
+ // Skip if image analysis is disabled
120
+ if (!imageConfig.enabled) {
121
+ return false;
122
+ }
123
+ // One-time migration marker
124
+ migrateGlobalHook();
125
+ // Get CCS directory (respects CCS_HOME for test isolation)
126
+ const ccsDir = (0, config_manager_1.getCcsDir)();
127
+ // Ensure CCS dir exists
128
+ if (!fs.existsSync(ccsDir)) {
129
+ fs.mkdirSync(ccsDir, { recursive: true, mode: 0o700 });
130
+ }
131
+ const settingsPath = path.join(ccsDir, `${profileName}.settings.json`);
132
+ // Read existing settings or create empty
133
+ let settings = {};
134
+ if (fs.existsSync(settingsPath)) {
135
+ try {
136
+ const content = fs.readFileSync(settingsPath, 'utf8');
137
+ settings = JSON.parse(content);
138
+ }
139
+ catch (parseError) {
140
+ if (process.env.CCS_DEBUG) {
141
+ console.error((0, ui_1.warn)(`Malformed ${profileName}.settings.json: ${parseError.message}`));
142
+ }
143
+ // Continue with empty settings, will add hooks
144
+ }
145
+ }
146
+ // Check if CCS hook already present
147
+ if (hasCcsHook(settings)) {
148
+ // Update timeout if needed
149
+ return updateHookTimeoutIfNeeded(settings, settingsPath);
150
+ }
151
+ // Get hook config
152
+ const hookConfig = (0, image_analyzer_hook_configuration_1.getImageAnalyzerHookConfig)();
153
+ // Ensure hooks structure exists
154
+ if (!settings.hooks) {
155
+ settings.hooks = {};
156
+ }
157
+ const settingsHooks = settings.hooks;
158
+ if (!settingsHooks.PreToolUse) {
159
+ settingsHooks.PreToolUse = [];
160
+ }
161
+ // Add CCS hook
162
+ const preToolUseHooks = hookConfig.PreToolUse;
163
+ settingsHooks.PreToolUse.push(...preToolUseHooks);
164
+ // Write updated settings
165
+ fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2), 'utf8');
166
+ if (process.env.CCS_DEBUG) {
167
+ console.error((0, ui_1.info)(`Added image analyzer hook to ${profileName}.settings.json`));
168
+ }
169
+ return true;
170
+ }
171
+ catch (error) {
172
+ if (process.env.CCS_DEBUG) {
173
+ console.error((0, ui_1.warn)(`Failed to inject hook: ${error.message}`));
174
+ }
175
+ return false;
176
+ }
177
+ }
178
+ exports.ensureProfileHooks = ensureProfileHooks;
179
+ /**
180
+ * Update hook timeout if it differs from current config
181
+ */
182
+ function updateHookTimeoutIfNeeded(settings, settingsPath) {
183
+ try {
184
+ const hooks = settings.hooks;
185
+ const hookConfig = (0, image_analyzer_hook_configuration_1.getImageAnalyzerHookConfig)();
186
+ const expectedHookPath = (0, image_analyzer_hook_configuration_1.getImageAnalyzerHookPath)();
187
+ const expectedCommand = `node "${expectedHookPath}"`;
188
+ const expectedHooks = hookConfig.PreToolUse[0]
189
+ .hooks;
190
+ const expectedTimeout = expectedHooks[0].timeout;
191
+ let needsUpdate = false;
192
+ for (const h of hooks.PreToolUse) {
193
+ const hook = h;
194
+ if (hook.matcher !== 'Read')
195
+ continue;
196
+ const hookArray = hook.hooks;
197
+ if (!hookArray?.[0]?.command)
198
+ continue;
199
+ const command = hookArray[0].command;
200
+ if (typeof command !== 'string')
201
+ continue;
202
+ // Normalize path separators for cross-platform matching (Windows uses backslashes)
203
+ const normalizedCommand = command
204
+ .replace(/\\/g, '/') // Windows backslashes
205
+ .replace(/\/+/g, '/'); // Collapse multiple slashes
206
+ if (!normalizedCommand.includes('.ccs/hooks/image-analyzer-transformer'))
207
+ continue;
208
+ // Found CCS hook - check if needs update
209
+ if (hookArray[0].command !== expectedCommand) {
210
+ hookArray[0].command = expectedCommand;
211
+ needsUpdate = true;
212
+ }
213
+ if (hookArray[0].timeout !== expectedTimeout) {
214
+ hookArray[0].timeout = expectedTimeout;
215
+ needsUpdate = true;
216
+ }
217
+ }
218
+ if (needsUpdate) {
219
+ fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2), 'utf8');
220
+ if (process.env.CCS_DEBUG) {
221
+ console.error((0, ui_1.info)('Updated image analyzer hook timeout in profile settings'));
222
+ }
223
+ }
224
+ return true;
225
+ }
226
+ catch (error) {
227
+ if (process.env.CCS_DEBUG) {
228
+ console.error((0, ui_1.warn)(`updateHookTimeoutIfNeeded failed: ${error.message}`));
229
+ }
230
+ return false;
231
+ }
232
+ }
233
+ /**
234
+ * Remove migration marker (called during uninstall)
235
+ */
236
+ function removeMigrationMarker() {
237
+ try {
238
+ const markerPath = getMigrationMarkerPath();
239
+ if (fs.existsSync(markerPath)) {
240
+ fs.unlinkSync(markerPath);
241
+ }
242
+ }
243
+ catch (error) {
244
+ if (process.env.CCS_DEBUG) {
245
+ console.error((0, ui_1.warn)(`removeMigrationMarker failed: ${error.message}`));
246
+ }
247
+ }
248
+ }
249
+ exports.removeMigrationMarker = removeMigrationMarker;
250
+ //# sourceMappingURL=image-analyzer-profile-hook-injector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image-analyzer-profile-hook-injector.js","sourceRoot":"","sources":["../../../src/utils/hooks/image-analyzer-profile-hook-injector.ts"],"names":[],"mappings":";AAAA;;;;;;;;;GASG;;;;;;;;;;;;;;;;;;;;;;;;;;AAEH,uCAAyB;AACzB,2CAA6B;AAC7B,8BAAmC;AACnC,2FAG6C;AAC7C,8EAA4E;AAC5E,sDAA8C;AAE9C,mEAAmE;AACnE,MAAM,kBAAkB,GAAG,kBAAkB,CAAC;AAE9C;;GAEG;AACH,SAAS,sBAAsB;IAC7B,OAAO,IAAI,CAAC,IAAI,CAAC,IAAA,0BAAS,GAAE,EAAE,+BAA+B,CAAC,CAAC;AACjE,CAAC;AAED;;GAEG;AACH,SAAS,UAAU,CAAC,QAAiC;IACnD,MAAM,KAAK,GAAG,QAAQ,CAAC,KAA8C,CAAC;IACtE,IAAI,CAAC,KAAK,EAAE,UAAU;QAAE,OAAO,KAAK,CAAC;IAErC,OAAO,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAU,EAAE,EAAE;QAC1C,MAAM,IAAI,GAAG,CAA4B,CAAC;QAC1C,IAAI,IAAI,CAAC,OAAO,KAAK,MAAM;YAAE,OAAO,KAAK,CAAC;QAE1C,MAAM,SAAS,GAAG,IAAI,CAAC,KAAmD,CAAC;QAC3E,MAAM,OAAO,GAAG,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC;QACxC,IAAI,OAAO,OAAO,KAAK,QAAQ;YAAE,OAAO,KAAK,CAAC;QAE9C,MAAM,UAAU,GAAG,OAAO;aACvB,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,sBAAsB;aAC1C,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,4BAA4B;QACrD,OAAO,UAAU,CAAC,QAAQ,CAAC,uCAAuC,CAAC,CAAC;IACtE,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,SAAS,iBAAiB;IACxB,MAAM,UAAU,GAAG,sBAAsB,EAAE,CAAC;IAC5C,IAAI,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC9B,OAAO,CAAC,mBAAmB;IAC7B,CAAC;IAED,IAAI,CAAC;QACH,4EAA4E;QAC5E,0DAA0D;QAC1D,MAAM,MAAM,GAAG,IAAA,0BAAS,GAAE,CAAC;QAC3B,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YAC3B,EAAE,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QACzD,CAAC;QACD,+EAA+E;QAC/E,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3F,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC;YAC1B,OAAO,CAAC,KAAK,CAAC,IAAA,SAAI,EAAC,qBAAsB,KAAe,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QACvE,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,SAAgB,kBAAkB,CAAC,WAAmB;IACpD,IAAI,CAAC;QACH,kDAAkD;QAClD,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;YAC1C,IAAI,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC;gBAC1B,OAAO,CAAC,KAAK,CAAC,IAAA,SAAI,EAAC,yBAAyB,WAAW,EAAE,CAAC,CAAC,CAAC;YAC9D,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC;QAED,wDAAwD;QACxD,MAAM,cAAc,GAAG,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;QACzC,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;YAC1C,OAAO,KAAK,CAAC;QACf,CAAC;QAED,MAAM,WAAW,GAAG,IAAA,8CAAsB,GAAE,CAAC;QAE7C,qCAAqC;QACrC,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC;YACzB,OAAO,KAAK,CAAC;QACf,CAAC;QAED,4BAA4B;QAC5B,iBAAiB,EAAE,CAAC;QAEpB,2DAA2D;QAC3D,MAAM,MAAM,GAAG,IAAA,0BAAS,GAAE,CAAC;QAE3B,wBAAwB;QACxB,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YAC3B,EAAE,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QACzD,CAAC;QAED,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,WAAW,gBAAgB,CAAC,CAAC;QAEvE,yCAAyC;QACzC,IAAI,QAAQ,GAA4B,EAAE,CAAC;QAC3C,IAAI,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;YAChC,IAAI,CAAC;gBACH,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;gBACtD,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YACjC,CAAC;YAAC,OAAO,UAAU,EAAE,CAAC;gBACpB,IAAI,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC;oBAC1B,OAAO,CAAC,KAAK,CACX,IAAA,SAAI,EAAC,aAAa,WAAW,mBAAoB,UAAoB,CAAC,OAAO,EAAE,CAAC,CACjF,CAAC;gBACJ,CAAC;gBACD,+CAA+C;YACjD,CAAC;QACH,CAAC;QAED,oCAAoC;QACpC,IAAI,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YACzB,2BAA2B;YAC3B,OAAO,yBAAyB,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;QAC3D,CAAC;QAED,kBAAkB;QAClB,MAAM,UAAU,GAAG,IAAA,8DAA0B,GAAE,CAAC;QAEhD,gCAAgC;QAChC,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;YACpB,QAAQ,CAAC,KAAK,GAAG,EAAE,CAAC;QACtB,CAAC;QAED,MAAM,aAAa,GAAG,QAAQ,CAAC,KAAkC,CAAC;QAClE,IAAI,CAAC,aAAa,CAAC,UAAU,EAAE,CAAC;YAC9B,aAAa,CAAC,UAAU,GAAG,EAAE,CAAC;QAChC,CAAC;QAED,eAAe;QACf,MAAM,eAAe,GAAG,UAAU,CAAC,UAAuB,CAAC;QAC3D,aAAa,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,eAAe,CAAC,CAAC;QAElD,yBAAyB;QACzB,EAAE,CAAC,aAAa,CAAC,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;QAE1E,IAAI,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC;YAC1B,OAAO,CAAC,KAAK,CAAC,IAAA,SAAI,EAAC,gCAAgC,WAAW,gBAAgB,CAAC,CAAC,CAAC;QACnF,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC;YAC1B,OAAO,CAAC,KAAK,CAAC,IAAA,SAAI,EAAC,0BAA2B,KAAe,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QAC5E,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAzFD,gDAyFC;AAED;;GAEG;AACH,SAAS,yBAAyB,CAChC,QAAiC,EACjC,YAAoB;IAEpB,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAkC,CAAC;QAC1D,MAAM,UAAU,GAAG,IAAA,8DAA0B,GAAE,CAAC;QAChD,MAAM,gBAAgB,GAAG,IAAA,4DAAwB,GAAE,CAAC;QACpD,MAAM,eAAe,GAAG,SAAS,gBAAgB,GAAG,CAAC;QACrD,MAAM,aAAa,GAAI,UAAU,CAAC,UAA6C,CAAC,CAAC,CAAC;aAC/E,KAAuC,CAAC;QAC3C,MAAM,eAAe,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC,OAAiB,CAAC;QAE3D,IAAI,WAAW,GAAG,KAAK,CAAC;QAExB,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;YACjC,MAAM,IAAI,GAAG,CAA4B,CAAC;YAC1C,IAAI,IAAI,CAAC,OAAO,KAAK,MAAM;gBAAE,SAAS;YAEtC,MAAM,SAAS,GAAG,IAAI,CAAC,KAAuC,CAAC;YAC/D,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO;gBAAE,SAAS;YAEvC,MAAM,OAAO,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;YACrC,IAAI,OAAO,OAAO,KAAK,QAAQ;gBAAE,SAAS;YAC1C,mFAAmF;YACnF,MAAM,iBAAiB,GAAG,OAAO;iBAC9B,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,sBAAsB;iBAC1C,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,4BAA4B;YACrD,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,uCAAuC,CAAC;gBAAE,SAAS;YAEnF,yCAAyC;YACzC,IAAI,SAAS,CAAC,CAAC,CAAC,CAAC,OAAO,KAAK,eAAe,EAAE,CAAC;gBAC7C,SAAS,CAAC,CAAC,CAAC,CAAC,OAAO,GAAG,eAAe,CAAC;gBACvC,WAAW,GAAG,IAAI,CAAC;YACrB,CAAC;YAED,IAAI,SAAS,CAAC,CAAC,CAAC,CAAC,OAAO,KAAK,eAAe,EAAE,CAAC;gBAC7C,SAAS,CAAC,CAAC,CAAC,CAAC,OAAO,GAAG,eAAe,CAAC;gBACvC,WAAW,GAAG,IAAI,CAAC;YACrB,CAAC;QACH,CAAC;QAED,IAAI,WAAW,EAAE,CAAC;YAChB,EAAE,CAAC,aAAa,CAAC,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;YAC1E,IAAI,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC;gBAC1B,OAAO,CAAC,KAAK,CAAC,IAAA,SAAI,EAAC,yDAAyD,CAAC,CAAC,CAAC;YACjF,CAAC;QACH,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC;YAC1B,OAAO,CAAC,KAAK,CAAC,IAAA,SAAI,EAAC,qCAAsC,KAAe,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QACvF,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAgB,qBAAqB;IACnC,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,sBAAsB,EAAE,CAAC;QAC5C,IAAI,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC9B,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC;YAC1B,OAAO,CAAC,KAAK,CAAC,IAAA,SAAI,EAAC,iCAAkC,KAAe,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QACnF,CAAC;IACH,CAAC;AACH,CAAC;AAXD,sDAWC"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Image Read Block Hook Environment Variables
3
+ *
4
+ * Provides environment variables for image read blocking hook configuration.
5
+ * Prevents context overflow when skills generate images and agent tries to read them.
6
+ *
7
+ * Enabled by default for third-party profiles (settings, cliproxy).
8
+ * Disabled for native Claude accounts where context is managed server-side.
9
+ *
10
+ * @module utils/hooks/image-read-block-hook-env
11
+ */
12
+ /**
13
+ * Configuration for image read blocking.
14
+ */
15
+ export interface ImageReadBlockConfig {
16
+ /** Whether blocking is enabled (default: true) */
17
+ enabled: boolean;
18
+ }
19
+ /**
20
+ * Get image read block configuration from unified config.
21
+ * Defaults to ENABLED (opt-out feature) - matches WebSearch pattern.
22
+ */
23
+ export declare function getImageReadBlockConfig(): ImageReadBlockConfig;
24
+ /**
25
+ * Get environment variables for image read block hook configuration.
26
+ *
27
+ * Like WebSearch, this respects CCS_PROFILE_TYPE:
28
+ * - 'account' or 'default' profiles: Skip blocking (native Claude)
29
+ * - 'settings' or 'cliproxy' profiles: Apply blocking
30
+ *
31
+ * @returns Record of environment variables to set before spawning Claude
32
+ */
33
+ export declare function getImageReadBlockHookEnv(): Record<string, string>;
34
+ //# sourceMappingURL=image-read-block-hook-env.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image-read-block-hook-env.d.ts","sourceRoot":"","sources":["../../../src/utils/hooks/image-read-block-hook-env.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,kDAAkD;IAClD,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,IAAI,oBAAoB,CAU9D;AAED;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAYjE"}
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ /**
3
+ * Image Read Block Hook Environment Variables
4
+ *
5
+ * Provides environment variables for image read blocking hook configuration.
6
+ * Prevents context overflow when skills generate images and agent tries to read them.
7
+ *
8
+ * Enabled by default for third-party profiles (settings, cliproxy).
9
+ * Disabled for native Claude accounts where context is managed server-side.
10
+ *
11
+ * @module utils/hooks/image-read-block-hook-env
12
+ */
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ exports.getImageReadBlockHookEnv = exports.getImageReadBlockConfig = void 0;
15
+ const unified_config_loader_1 = require("../../config/unified-config-loader");
16
+ /**
17
+ * Get image read block configuration from unified config.
18
+ * Defaults to ENABLED (opt-out feature) - matches WebSearch pattern.
19
+ */
20
+ function getImageReadBlockConfig() {
21
+ const config = (0, unified_config_loader_1.loadOrCreateUnifiedConfig)();
22
+ // Access hooks config via type assertion since it's a new field not yet in UnifiedConfig type
23
+ const hooksConfig = config.hooks;
24
+ return {
25
+ // Default to TRUE - enabled by default, user can opt-out
26
+ enabled: hooksConfig?.block_image_read?.enabled ?? true,
27
+ };
28
+ }
29
+ exports.getImageReadBlockConfig = getImageReadBlockConfig;
30
+ /**
31
+ * Get environment variables for image read block hook configuration.
32
+ *
33
+ * Like WebSearch, this respects CCS_PROFILE_TYPE:
34
+ * - 'account' or 'default' profiles: Skip blocking (native Claude)
35
+ * - 'settings' or 'cliproxy' profiles: Apply blocking
36
+ *
37
+ * @returns Record of environment variables to set before spawning Claude
38
+ */
39
+ function getImageReadBlockHookEnv() {
40
+ const config = getImageReadBlockConfig();
41
+ const env = {};
42
+ if (config.enabled) {
43
+ env.CCS_BLOCK_IMAGE_READ = '1';
44
+ }
45
+ else {
46
+ // Explicit disable signal
47
+ env.CCS_BLOCK_IMAGE_READ = '0';
48
+ }
49
+ return env;
50
+ }
51
+ exports.getImageReadBlockHookEnv = getImageReadBlockHookEnv;
52
+ //# sourceMappingURL=image-read-block-hook-env.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image-read-block-hook-env.js","sourceRoot":"","sources":["../../../src/utils/hooks/image-read-block-hook-env.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;GAUG;;;AAEH,8EAA+E;AAU/E;;;GAGG;AACH,SAAgB,uBAAuB;IACrC,MAAM,MAAM,GAAG,IAAA,iDAAyB,GAAE,CAAC;IAC3C,8FAA8F;IAC9F,MAAM,WAAW,GACf,MACD,CAAC,KAAK,CAAC;IACR,OAAO;QACL,yDAAyD;QACzD,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,OAAO,IAAI,IAAI;KACxD,CAAC;AACJ,CAAC;AAVD,0DAUC;AAED;;;;;;;;GAQG;AACH,SAAgB,wBAAwB;IACtC,MAAM,MAAM,GAAG,uBAAuB,EAAE,CAAC;IACzC,MAAM,GAAG,GAA2B,EAAE,CAAC;IAEvC,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACnB,GAAG,CAAC,oBAAoB,GAAG,GAAG,CAAC;IACjC,CAAC;SAAM,CAAC;QACN,0BAA0B;QAC1B,GAAG,CAAC,oBAAoB,GAAG,GAAG,CAAC;IACjC,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC;AAZD,4DAYC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Hooks Utilities Index
3
+ *
4
+ * Centralized exports for all hook-related utilities.
5
+ *
6
+ * @module utils/hooks
7
+ */
8
+ export { getImageReadBlockHookEnv, getImageReadBlockConfig } from './image-read-block-hook-env';
9
+ export { getImageAnalysisHookEnv } from './get-image-analysis-hook-env';
10
+ export { getImageAnalyzerHookPath, getImageAnalyzerHookConfig, hasImageAnalyzerHook, installImageAnalyzerHook, uninstallImageAnalyzerHook, } from './image-analyzer-hook-installer';
11
+ export { ensureProfileHooks as ensureImageAnalyzerProfileHooks } from './image-analyzer-profile-hook-injector';
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utils/hooks/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,wBAAwB,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AAChG,OAAO,EAAE,uBAAuB,EAAE,MAAM,+BAA+B,CAAC;AACxE,OAAO,EACL,wBAAwB,EACxB,0BAA0B,EAC1B,oBAAoB,EACpB,wBAAwB,EACxB,0BAA0B,GAC3B,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,kBAAkB,IAAI,+BAA+B,EAAE,MAAM,wCAAwC,CAAC"}
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ /**
3
+ * Hooks Utilities Index
4
+ *
5
+ * Centralized exports for all hook-related utilities.
6
+ *
7
+ * @module utils/hooks
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.ensureImageAnalyzerProfileHooks = exports.uninstallImageAnalyzerHook = exports.installImageAnalyzerHook = exports.hasImageAnalyzerHook = exports.getImageAnalyzerHookConfig = exports.getImageAnalyzerHookPath = exports.getImageAnalysisHookEnv = exports.getImageReadBlockConfig = exports.getImageReadBlockHookEnv = void 0;
11
+ var image_read_block_hook_env_1 = require("./image-read-block-hook-env");
12
+ Object.defineProperty(exports, "getImageReadBlockHookEnv", { enumerable: true, get: function () { return image_read_block_hook_env_1.getImageReadBlockHookEnv; } });
13
+ Object.defineProperty(exports, "getImageReadBlockConfig", { enumerable: true, get: function () { return image_read_block_hook_env_1.getImageReadBlockConfig; } });
14
+ var get_image_analysis_hook_env_1 = require("./get-image-analysis-hook-env");
15
+ Object.defineProperty(exports, "getImageAnalysisHookEnv", { enumerable: true, get: function () { return get_image_analysis_hook_env_1.getImageAnalysisHookEnv; } });
16
+ var image_analyzer_hook_installer_1 = require("./image-analyzer-hook-installer");
17
+ Object.defineProperty(exports, "getImageAnalyzerHookPath", { enumerable: true, get: function () { return image_analyzer_hook_installer_1.getImageAnalyzerHookPath; } });
18
+ Object.defineProperty(exports, "getImageAnalyzerHookConfig", { enumerable: true, get: function () { return image_analyzer_hook_installer_1.getImageAnalyzerHookConfig; } });
19
+ Object.defineProperty(exports, "hasImageAnalyzerHook", { enumerable: true, get: function () { return image_analyzer_hook_installer_1.hasImageAnalyzerHook; } });
20
+ Object.defineProperty(exports, "installImageAnalyzerHook", { enumerable: true, get: function () { return image_analyzer_hook_installer_1.installImageAnalyzerHook; } });
21
+ Object.defineProperty(exports, "uninstallImageAnalyzerHook", { enumerable: true, get: function () { return image_analyzer_hook_installer_1.uninstallImageAnalyzerHook; } });
22
+ var image_analyzer_profile_hook_injector_1 = require("./image-analyzer-profile-hook-injector");
23
+ Object.defineProperty(exports, "ensureImageAnalyzerProfileHooks", { enumerable: true, get: function () { return image_analyzer_profile_hook_injector_1.ensureProfileHooks; } });
24
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/utils/hooks/index.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;AAEH,yEAAgG;AAAvF,qIAAA,wBAAwB,OAAA;AAAE,oIAAA,uBAAuB,OAAA;AAC1D,6EAAwE;AAA/D,sIAAA,uBAAuB,OAAA;AAChC,iFAMyC;AALvC,yIAAA,wBAAwB,OAAA;AACxB,2IAAA,0BAA0B,OAAA;AAC1B,qIAAA,oBAAoB,OAAA;AACpB,yIAAA,wBAAwB,OAAA;AACxB,2IAAA,0BAA0B,OAAA;AAE5B,+FAA+G;AAAtG,uJAAA,kBAAkB,OAAmC"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Image Analysis Hook Installer
3
+ *
4
+ * Manages installation of:
5
+ * 1. block-image-read.cjs hook (blocks image reads to prevent context overflow)
6
+ * 2. Prompt templates for image analysis (user-customizable)
7
+ *
8
+ * @module utils/image-analysis/hook-installer
9
+ */
10
+ /**
11
+ * Get path to installed hook script
12
+ */
13
+ export declare function getHookPath(): string;
14
+ /**
15
+ * Get CCS hooks directory
16
+ */
17
+ export declare function getCcsHooksDir(): string;
18
+ /**
19
+ * Get prompts directory for image analysis
20
+ */
21
+ export declare function getPromptsDir(): string;
22
+ /**
23
+ * Check if image block hook is installed
24
+ */
25
+ export declare function hasImageBlockHook(): boolean;
26
+ /**
27
+ * Install image block hook to ~/.ccs/hooks/
28
+ *
29
+ * This hook intercepts Read tool calls for image files and blocks them
30
+ * to prevent context overflow (images consume 100K+ tokens each).
31
+ *
32
+ * @returns true if hook installed successfully
33
+ */
34
+ export declare function installImageBlockHook(): boolean;
35
+ /**
36
+ * Install prompt templates to ~/.ccs/prompts/image-analysis/
37
+ * Only installs if directory doesn't exist (doesn't overwrite user edits)
38
+ *
39
+ * @returns true if prompts installed or already exist
40
+ */
41
+ export declare function installImageAnalysisPrompts(): boolean;
42
+ /**
43
+ * Uninstall image block hook from ~/.ccs/hooks/
44
+ *
45
+ * @returns true if hook uninstalled successfully
46
+ */
47
+ export declare function uninstallImageBlockHook(): boolean;
48
+ //# sourceMappingURL=hook-installer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hook-installer.d.ts","sourceRoot":"","sources":["../../../src/utils/image-analysis/hook-installer.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAUH;;GAEG;AACH,wBAAgB,WAAW,IAAI,MAAM,CAEpC;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,CAE3C;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,IAAI,OAAO,CAiD/C;AAED;;;;;GAKG;AACH,wBAAgB,2BAA2B,IAAI,OAAO,CAqErD;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,IAAI,OAAO,CAkBjD"}
@@ -0,0 +1,214 @@
1
+ "use strict";
2
+ /**
3
+ * Image Analysis Hook Installer
4
+ *
5
+ * Manages installation of:
6
+ * 1. block-image-read.cjs hook (blocks image reads to prevent context overflow)
7
+ * 2. Prompt templates for image analysis (user-customizable)
8
+ *
9
+ * @module utils/image-analysis/hook-installer
10
+ */
11
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
12
+ if (k2 === undefined) k2 = k;
13
+ var desc = Object.getOwnPropertyDescriptor(m, k);
14
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
15
+ desc = { enumerable: true, get: function() { return m[k]; } };
16
+ }
17
+ Object.defineProperty(o, k2, desc);
18
+ }) : (function(o, m, k, k2) {
19
+ if (k2 === undefined) k2 = k;
20
+ o[k2] = m[k];
21
+ }));
22
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
23
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
24
+ }) : function(o, v) {
25
+ o["default"] = v;
26
+ });
27
+ var __importStar = (this && this.__importStar) || function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ Object.defineProperty(exports, "__esModule", { value: true });
35
+ exports.uninstallImageBlockHook = exports.installImageAnalysisPrompts = exports.installImageBlockHook = exports.hasImageBlockHook = exports.getPromptsDir = exports.getCcsHooksDir = exports.getHookPath = void 0;
36
+ const fs = __importStar(require("fs"));
37
+ const path = __importStar(require("path"));
38
+ const ui_1 = require("../ui");
39
+ const config_manager_1 = require("../config-manager");
40
+ // Hook file name
41
+ const IMAGE_BLOCK_HOOK = 'block-image-read.cjs';
42
+ /**
43
+ * Get path to installed hook script
44
+ */
45
+ function getHookPath() {
46
+ return path.join((0, config_manager_1.getCcsDir)(), 'hooks', IMAGE_BLOCK_HOOK);
47
+ }
48
+ exports.getHookPath = getHookPath;
49
+ /**
50
+ * Get CCS hooks directory
51
+ */
52
+ function getCcsHooksDir() {
53
+ return path.join((0, config_manager_1.getCcsDir)(), 'hooks');
54
+ }
55
+ exports.getCcsHooksDir = getCcsHooksDir;
56
+ /**
57
+ * Get prompts directory for image analysis
58
+ */
59
+ function getPromptsDir() {
60
+ return path.join((0, config_manager_1.getCcsDir)(), 'prompts', 'image-analysis');
61
+ }
62
+ exports.getPromptsDir = getPromptsDir;
63
+ /**
64
+ * Check if image block hook is installed
65
+ */
66
+ function hasImageBlockHook() {
67
+ return fs.existsSync(getHookPath());
68
+ }
69
+ exports.hasImageBlockHook = hasImageBlockHook;
70
+ /**
71
+ * Install image block hook to ~/.ccs/hooks/
72
+ *
73
+ * This hook intercepts Read tool calls for image files and blocks them
74
+ * to prevent context overflow (images consume 100K+ tokens each).
75
+ *
76
+ * @returns true if hook installed successfully
77
+ */
78
+ function installImageBlockHook() {
79
+ try {
80
+ // Ensure hooks directory exists
81
+ const hooksDir = getCcsHooksDir();
82
+ if (!fs.existsSync(hooksDir)) {
83
+ fs.mkdirSync(hooksDir, { recursive: true, mode: 0o700 });
84
+ }
85
+ const hookPath = getHookPath();
86
+ // Find the bundled hook script
87
+ // In npm package: node_modules/ccs/lib/hooks/
88
+ // In development: lib/hooks/
89
+ const possiblePaths = [
90
+ path.join(__dirname, '..', '..', '..', 'lib', 'hooks', IMAGE_BLOCK_HOOK),
91
+ path.join(__dirname, '..', '..', 'lib', 'hooks', IMAGE_BLOCK_HOOK),
92
+ path.join(__dirname, '..', 'lib', 'hooks', IMAGE_BLOCK_HOOK),
93
+ ];
94
+ let sourcePath = null;
95
+ for (const p of possiblePaths) {
96
+ if (fs.existsSync(p)) {
97
+ sourcePath = p;
98
+ break;
99
+ }
100
+ }
101
+ if (!sourcePath) {
102
+ if (process.env.CCS_DEBUG) {
103
+ console.error((0, ui_1.warn)(`Image block hook source not found: ${IMAGE_BLOCK_HOOK}`));
104
+ }
105
+ return false;
106
+ }
107
+ // Copy hook to ~/.ccs/hooks/
108
+ fs.copyFileSync(sourcePath, hookPath);
109
+ fs.chmodSync(hookPath, 0o755);
110
+ if (process.env.CCS_DEBUG) {
111
+ console.error((0, ui_1.info)(`Installed image block hook: ${hookPath}`));
112
+ }
113
+ return true;
114
+ }
115
+ catch (error) {
116
+ if (process.env.CCS_DEBUG) {
117
+ console.error((0, ui_1.warn)(`Failed to install image block hook: ${error.message}`));
118
+ }
119
+ return false;
120
+ }
121
+ }
122
+ exports.installImageBlockHook = installImageBlockHook;
123
+ /**
124
+ * Install prompt templates to ~/.ccs/prompts/image-analysis/
125
+ * Only installs if directory doesn't exist (doesn't overwrite user edits)
126
+ *
127
+ * @returns true if prompts installed or already exist
128
+ */
129
+ function installImageAnalysisPrompts() {
130
+ try {
131
+ const promptsDir = getPromptsDir();
132
+ // Skip if already exists (preserve user customizations)
133
+ if (fs.existsSync(promptsDir)) {
134
+ if (process.env.CCS_DEBUG) {
135
+ console.error((0, ui_1.info)('Image analysis prompts already installed - preserving user customizations'));
136
+ }
137
+ return true;
138
+ }
139
+ // Create directory
140
+ fs.mkdirSync(promptsDir, { recursive: true, mode: 0o755 });
141
+ // Find bundled prompts
142
+ const possibleBasePaths = [
143
+ path.join(__dirname, '..', '..', '..', 'lib', 'prompts'),
144
+ path.join(__dirname, '..', '..', 'lib', 'prompts'),
145
+ path.join(__dirname, '..', 'lib', 'prompts'),
146
+ ];
147
+ let promptsBasePath = null;
148
+ for (const p of possibleBasePaths) {
149
+ if (fs.existsSync(p)) {
150
+ promptsBasePath = p;
151
+ break;
152
+ }
153
+ }
154
+ if (!promptsBasePath) {
155
+ if (process.env.CCS_DEBUG) {
156
+ console.error((0, ui_1.warn)('Image analysis prompts source not found'));
157
+ }
158
+ return false;
159
+ }
160
+ // Copy prompt files
161
+ const promptFiles = [
162
+ 'image-analysis-default.txt',
163
+ 'image-analysis-screenshot.txt',
164
+ 'image-analysis-document.txt',
165
+ ];
166
+ for (const file of promptFiles) {
167
+ const sourcePath = path.join(promptsBasePath, file);
168
+ const destPath = path.join(promptsDir, file.replace('image-analysis-', ''));
169
+ if (fs.existsSync(sourcePath)) {
170
+ fs.copyFileSync(sourcePath, destPath);
171
+ fs.chmodSync(destPath, 0o644);
172
+ }
173
+ else if (process.env.CCS_DEBUG) {
174
+ console.error((0, ui_1.warn)(`Prompt template not found: ${file}`));
175
+ }
176
+ }
177
+ if (process.env.CCS_DEBUG) {
178
+ console.error((0, ui_1.info)(`Installed image analysis prompts: ${promptsDir}`));
179
+ }
180
+ return true;
181
+ }
182
+ catch (error) {
183
+ if (process.env.CCS_DEBUG) {
184
+ console.error((0, ui_1.warn)(`Failed to install image analysis prompts: ${error.message}`));
185
+ }
186
+ return false;
187
+ }
188
+ }
189
+ exports.installImageAnalysisPrompts = installImageAnalysisPrompts;
190
+ /**
191
+ * Uninstall image block hook from ~/.ccs/hooks/
192
+ *
193
+ * @returns true if hook uninstalled successfully
194
+ */
195
+ function uninstallImageBlockHook() {
196
+ try {
197
+ const hookPath = getHookPath();
198
+ if (fs.existsSync(hookPath)) {
199
+ fs.unlinkSync(hookPath);
200
+ if (process.env.CCS_DEBUG) {
201
+ console.error((0, ui_1.info)(`Uninstalled image block hook: ${hookPath}`));
202
+ }
203
+ }
204
+ return true;
205
+ }
206
+ catch (error) {
207
+ if (process.env.CCS_DEBUG) {
208
+ console.error((0, ui_1.warn)(`Failed to uninstall image block hook: ${error.message}`));
209
+ }
210
+ return false;
211
+ }
212
+ }
213
+ exports.uninstallImageBlockHook = uninstallImageBlockHook;
214
+ //# sourceMappingURL=hook-installer.js.map