@kaitranntt/ccs 7.31.0 → 7.31.1-dev.2

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.
@@ -6,7 +6,7 @@
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
7
  exports.configureProviderModel = exports.getCurrentModel = exports.hasUserSettings = exports.findModel = exports.getProviderCatalog = exports.supportsModelConfig = exports.MODEL_CATALOG = exports.clearConfigCache = exports.getEnvVarsFromConfig = exports.getModelMappingFromConfig = exports.loadBaseConfig = exports.CLIPROXY_CONFIG_VERSION = exports.CLIPROXY_DEFAULT_PORT = exports.deleteConfig = exports.configExists = exports.getBinDir = exports.getCliproxyConfigPath = exports.getAuthDir = exports.getProviderAuthDir = exports.getCliproxyDir = exports.getModelMapping = exports.getProviderConfig = exports.ensureProviderSettings = exports.getProviderSettingsPath = exports.getEffectiveEnvVars = exports.getClaudeEnvVars = exports.parseUserApiKeys = exports.configNeedsRegeneration = exports.regenerateConfig = exports.generateConfig = exports.getVersionPinPath = exports.isVersionPinned = exports.clearPinnedVersion = exports.savePinnedVersion = exports.getPinnedVersion = exports.fetchLatestCliproxyVersion = exports.installCliproxyVersion = exports.getInstalledCliproxyVersion = exports.getCLIProxyPath = exports.isCLIProxyInstalled = exports.ensureCLIProxyBinary = exports.BinaryManager = exports.CLIPROXY_VERSION = exports.getPlatformDescription = exports.isPlatformSupported = exports.getArchiveBinaryName = exports.getExecutableName = exports.getChecksumsUrl = exports.getDownloadUrl = exports.detectPlatform = void 0;
8
8
  exports.ManagementApiClient = exports.THINKING_BUDGET_DEFAULT_MIN = exports.THINKING_BUDGET_MAX = exports.THINKING_BUDGET_MIN = exports.THINKING_AUTO_VALUE = exports.THINKING_OFF_VALUES = exports.VALID_THINKING_TIERS = exports.VALID_THINKING_LEVELS = exports.THINKING_LEVEL_BUDGETS = exports.validateThinking = exports.getAuthSummary = exports.resetAuthToDefaults = exports.setVariantApiKey = exports.setGlobalManagementSecret = exports.setGlobalApiKey = exports.getEffectiveManagementSecret = exports.getEffectiveApiKey = exports.maskToken = exports.generateSecureToken = exports.withStartupLock = exports.acquireStartupLock = exports.reclaimOrphanedProxy = exports.waitForProxyHealthy = exports.detectRunningProxy = exports.getServiceStatus = exports.stopCliproxyService = exports.ensureCliproxyService = exports.TOGETHER_TEMPLATE = exports.OPENROUTER_TEMPLATE = exports.removeOpenAICompatProvider = exports.updateOpenAICompatProvider = exports.addOpenAICompatProvider = exports.getOpenAICompatProvider = exports.listOpenAICompatProviders = exports.fetchAccountQuota = exports.isCliproxyRunning = exports.fetchCliproxyStats = exports.displayAuthStatus = exports.getProviderTokenDir = exports.getOAuthConfig = exports.ensureAuth = exports.triggerOAuth = exports.clearAuth = exports.getAllAuthStatus = exports.getAuthStatus = exports.isAuthenticated = exports.findAvailablePort = exports.isPortAvailable = exports.execClaudeWithCLIProxy = exports.showCurrentConfig = void 0;
9
- exports.isProfileSyncable = exports.getSyncableProfileCount = exports.generateSyncPreview = exports.generateSyncPayload = exports.mapProfileToClaudeKey = exports.loadSyncableProfiles = exports.createManagementClient = void 0;
9
+ exports.ToolSanitizationProxy = exports.ToolNameMapper = exports.GEMINI_MAX_TOOL_NAME_LENGTH = exports.smartTruncate = exports.removeDuplicateSegments = exports.isValidToolName = exports.sanitizeToolName = exports.isProfileSyncable = exports.getSyncableProfileCount = exports.generateSyncPreview = exports.generateSyncPayload = exports.mapProfileToClaudeKey = exports.loadSyncableProfiles = exports.createManagementClient = void 0;
10
10
  // Platform detection
11
11
  var platform_detector_1 = require("./platform-detector");
12
12
  Object.defineProperty(exports, "detectPlatform", { enumerable: true, get: function () { return platform_detector_1.detectPlatform; } });
@@ -138,4 +138,14 @@ Object.defineProperty(exports, "generateSyncPayload", { enumerable: true, get: f
138
138
  Object.defineProperty(exports, "generateSyncPreview", { enumerable: true, get: function () { return sync_1.generateSyncPreview; } });
139
139
  Object.defineProperty(exports, "getSyncableProfileCount", { enumerable: true, get: function () { return sync_1.getSyncableProfileCount; } });
140
140
  Object.defineProperty(exports, "isProfileSyncable", { enumerable: true, get: function () { return sync_1.isProfileSyncable; } });
141
+ var tool_name_sanitizer_1 = require("./tool-name-sanitizer");
142
+ Object.defineProperty(exports, "sanitizeToolName", { enumerable: true, get: function () { return tool_name_sanitizer_1.sanitizeToolName; } });
143
+ Object.defineProperty(exports, "isValidToolName", { enumerable: true, get: function () { return tool_name_sanitizer_1.isValidToolName; } });
144
+ Object.defineProperty(exports, "removeDuplicateSegments", { enumerable: true, get: function () { return tool_name_sanitizer_1.removeDuplicateSegments; } });
145
+ Object.defineProperty(exports, "smartTruncate", { enumerable: true, get: function () { return tool_name_sanitizer_1.smartTruncate; } });
146
+ Object.defineProperty(exports, "GEMINI_MAX_TOOL_NAME_LENGTH", { enumerable: true, get: function () { return tool_name_sanitizer_1.GEMINI_MAX_TOOL_NAME_LENGTH; } });
147
+ var tool_name_mapper_1 = require("./tool-name-mapper");
148
+ Object.defineProperty(exports, "ToolNameMapper", { enumerable: true, get: function () { return tool_name_mapper_1.ToolNameMapper; } });
149
+ var tool_sanitization_proxy_1 = require("./tool-sanitization-proxy");
150
+ Object.defineProperty(exports, "ToolSanitizationProxy", { enumerable: true, get: function () { return tool_sanitization_proxy_1.ToolSanitizationProxy; } });
141
151
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cliproxy/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cliproxy/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,103 @@
1
+ /**
2
+ * Tool Name Mapper
3
+ *
4
+ * Bidirectional mapping class to track original ↔ sanitized tool names.
5
+ * Used to restore original names in API responses after sanitization.
6
+ *
7
+ * Flow:
8
+ * 1. Request: registerTools() sanitizes names and stores mapping
9
+ * 2. Response: restoreToolUse() restores original names using mapping
10
+ */
11
+ /** MCP tool definition from Claude API */
12
+ export interface Tool {
13
+ name: string;
14
+ description?: string;
15
+ input_schema?: Record<string, unknown>;
16
+ [key: string]: unknown;
17
+ }
18
+ /** Tool use content block from Claude API response */
19
+ export interface ToolUseBlock {
20
+ type: 'tool_use';
21
+ id: string;
22
+ name: string;
23
+ input: Record<string, unknown>;
24
+ }
25
+ /** Content block from Claude API response (union type) */
26
+ export interface ContentBlock {
27
+ type: string;
28
+ [key: string]: unknown;
29
+ }
30
+ /** Record of a sanitization change */
31
+ export interface SanitizationChange {
32
+ original: string;
33
+ sanitized: string;
34
+ }
35
+ /** Record of a hash collision */
36
+ export interface HashCollision {
37
+ sanitized: string;
38
+ originals: string[];
39
+ }
40
+ /**
41
+ * Bidirectional mapper for tool name sanitization.
42
+ *
43
+ * Maintains a per-request mapping between sanitized and original tool names.
44
+ * Must be cleared between requests to avoid memory leaks.
45
+ */
46
+ export declare class ToolNameMapper {
47
+ /** Map from sanitized name → original name */
48
+ private mapping;
49
+ /** List of all changes made during registration */
50
+ private changes;
51
+ /** List of detected hash collisions */
52
+ private collisions;
53
+ /**
54
+ * Register tools and sanitize their names.
55
+ * Stores mapping for later restoration.
56
+ *
57
+ * @param tools Array of tool definitions
58
+ * @returns Array of tools with sanitized names
59
+ */
60
+ registerTools(tools: Tool[]): Tool[];
61
+ /**
62
+ * Restore original tool names in content blocks.
63
+ * Looks for tool_use blocks and restores their names.
64
+ *
65
+ * @param content Array of content blocks from API response
66
+ * @returns Array with restored tool names
67
+ */
68
+ restoreToolUse(content: ContentBlock[]): ContentBlock[];
69
+ /**
70
+ * Restore tool name in a single tool_use block.
71
+ * Useful for streaming responses.
72
+ *
73
+ * @param name The sanitized tool name
74
+ * @returns Original name if mapped, otherwise the input name
75
+ */
76
+ restoreName(name: string): string;
77
+ /**
78
+ * Check if any sanitization occurred during registration.
79
+ */
80
+ hasChanges(): boolean;
81
+ /**
82
+ * Get all sanitization changes for logging.
83
+ */
84
+ getChanges(): SanitizationChange[];
85
+ /**
86
+ * Get the number of tools that were sanitized.
87
+ */
88
+ getChangeCount(): number;
89
+ /**
90
+ * Check if any hash collisions were detected.
91
+ * Collisions occur when multiple original names map to the same sanitized name.
92
+ */
93
+ hasCollisions(): boolean;
94
+ /**
95
+ * Get all detected hash collisions for logging/warning.
96
+ */
97
+ getCollisions(): HashCollision[];
98
+ /**
99
+ * Clear all mappings. Call between requests.
100
+ */
101
+ clear(): void;
102
+ }
103
+ //# sourceMappingURL=tool-name-mapper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-name-mapper.d.ts","sourceRoot":"","sources":["../../src/cliproxy/tool-name-mapper.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,0CAA0C;AAC1C,MAAM,WAAW,IAAI;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACvC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,sDAAsD;AACtD,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,UAAU,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED,0DAA0D;AAC1D,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,sCAAsC;AACtC,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,iCAAiC;AACjC,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAED;;;;;GAKG;AACH,qBAAa,cAAc;IACzB,8CAA8C;IAC9C,OAAO,CAAC,OAAO,CAAkC;IAEjD,mDAAmD;IACnD,OAAO,CAAC,OAAO,CAA4B;IAE3C,uCAAuC;IACvC,OAAO,CAAC,UAAU,CAAuB;IAEzC;;;;;;OAMG;IACH,aAAa,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE;IAqCpC;;;;;;OAMG;IACH,cAAc,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,YAAY,EAAE;IAyBvD;;;;;;OAMG;IACH,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAIjC;;OAEG;IACH,UAAU,IAAI,OAAO;IAIrB;;OAEG;IACH,UAAU,IAAI,kBAAkB,EAAE;IAIlC;;OAEG;IACH,cAAc,IAAI,MAAM;IAIxB;;;OAGG;IACH,aAAa,IAAI,OAAO;IAIxB;;OAEG;IACH,aAAa,IAAI,aAAa,EAAE;IAIhC;;OAEG;IACH,KAAK,IAAI,IAAI;CAKd"}
@@ -0,0 +1,149 @@
1
+ "use strict";
2
+ /**
3
+ * Tool Name Mapper
4
+ *
5
+ * Bidirectional mapping class to track original ↔ sanitized tool names.
6
+ * Used to restore original names in API responses after sanitization.
7
+ *
8
+ * Flow:
9
+ * 1. Request: registerTools() sanitizes names and stores mapping
10
+ * 2. Response: restoreToolUse() restores original names using mapping
11
+ */
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.ToolNameMapper = void 0;
14
+ const tool_name_sanitizer_1 = require("./tool-name-sanitizer");
15
+ /**
16
+ * Bidirectional mapper for tool name sanitization.
17
+ *
18
+ * Maintains a per-request mapping between sanitized and original tool names.
19
+ * Must be cleared between requests to avoid memory leaks.
20
+ */
21
+ class ToolNameMapper {
22
+ constructor() {
23
+ /** Map from sanitized name → original name */
24
+ this.mapping = new Map();
25
+ /** List of all changes made during registration */
26
+ this.changes = [];
27
+ /** List of detected hash collisions */
28
+ this.collisions = [];
29
+ }
30
+ /**
31
+ * Register tools and sanitize their names.
32
+ * Stores mapping for later restoration.
33
+ *
34
+ * @param tools Array of tool definitions
35
+ * @returns Array of tools with sanitized names
36
+ */
37
+ registerTools(tools) {
38
+ return tools.map((tool) => {
39
+ const result = (0, tool_name_sanitizer_1.sanitizeToolName)(tool.name);
40
+ if (result.changed) {
41
+ // Check for collision: sanitized name already maps to different original
42
+ const existingOriginal = this.mapping.get(result.sanitized);
43
+ if (existingOriginal && existingOriginal !== tool.name) {
44
+ // Record collision
45
+ const existing = this.collisions.find((c) => c.sanitized === result.sanitized);
46
+ if (existing) {
47
+ if (!existing.originals.includes(tool.name)) {
48
+ existing.originals.push(tool.name);
49
+ }
50
+ }
51
+ else {
52
+ this.collisions.push({
53
+ sanitized: result.sanitized,
54
+ originals: [existingOriginal, tool.name],
55
+ });
56
+ }
57
+ }
58
+ // Store mapping: sanitized → original
59
+ this.mapping.set(result.sanitized, tool.name);
60
+ this.changes.push({
61
+ original: tool.name,
62
+ sanitized: result.sanitized,
63
+ });
64
+ }
65
+ return {
66
+ ...tool,
67
+ name: result.sanitized,
68
+ };
69
+ });
70
+ }
71
+ /**
72
+ * Restore original tool names in content blocks.
73
+ * Looks for tool_use blocks and restores their names.
74
+ *
75
+ * @param content Array of content blocks from API response
76
+ * @returns Array with restored tool names
77
+ */
78
+ restoreToolUse(content) {
79
+ return content.map((block) => {
80
+ if (block.type !== 'tool_use') {
81
+ return block;
82
+ }
83
+ // Type guard: we know this is a tool_use block
84
+ const toolUseName = block.name;
85
+ if (!toolUseName) {
86
+ return block;
87
+ }
88
+ const originalName = this.mapping.get(toolUseName);
89
+ if (originalName) {
90
+ return {
91
+ ...block,
92
+ name: originalName,
93
+ };
94
+ }
95
+ return block;
96
+ });
97
+ }
98
+ /**
99
+ * Restore tool name in a single tool_use block.
100
+ * Useful for streaming responses.
101
+ *
102
+ * @param name The sanitized tool name
103
+ * @returns Original name if mapped, otherwise the input name
104
+ */
105
+ restoreName(name) {
106
+ return this.mapping.get(name) ?? name;
107
+ }
108
+ /**
109
+ * Check if any sanitization occurred during registration.
110
+ */
111
+ hasChanges() {
112
+ return this.changes.length > 0;
113
+ }
114
+ /**
115
+ * Get all sanitization changes for logging.
116
+ */
117
+ getChanges() {
118
+ return [...this.changes];
119
+ }
120
+ /**
121
+ * Get the number of tools that were sanitized.
122
+ */
123
+ getChangeCount() {
124
+ return this.changes.length;
125
+ }
126
+ /**
127
+ * Check if any hash collisions were detected.
128
+ * Collisions occur when multiple original names map to the same sanitized name.
129
+ */
130
+ hasCollisions() {
131
+ return this.collisions.length > 0;
132
+ }
133
+ /**
134
+ * Get all detected hash collisions for logging/warning.
135
+ */
136
+ getCollisions() {
137
+ return [...this.collisions];
138
+ }
139
+ /**
140
+ * Clear all mappings. Call between requests.
141
+ */
142
+ clear() {
143
+ this.mapping.clear();
144
+ this.changes = [];
145
+ this.collisions = [];
146
+ }
147
+ }
148
+ exports.ToolNameMapper = ToolNameMapper;
149
+ //# sourceMappingURL=tool-name-mapper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-name-mapper.js","sourceRoot":"","sources":["../../src/cliproxy/tool-name-mapper.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Tool Name Sanitizer
3
+ *
4
+ * Sanitizes MCP tool names to comply with Gemini API constraints:
5
+ * - Max 64 characters
6
+ * - Must start with letter or underscore
7
+ * - Only a-z A-Z 0-9 _ . : - / allowed
8
+ *
9
+ * Strategies:
10
+ * 1. Remove duplicate segments (e.g., gitmcp__foo__foo → gitmcp__foo)
11
+ * 2. Smart truncate with hash suffix if still >64 chars
12
+ *
13
+ * Note: Hash collision risk is ~1 in 16M with 6-char MD5 prefix.
14
+ * Acceptable for typical MCP tool counts (<1000 tools).
15
+ */
16
+ /** Maximum tool name length allowed by Gemini API */
17
+ export declare const GEMINI_MAX_TOOL_NAME_LENGTH = 64;
18
+ /** Result of sanitization operation */
19
+ export interface SanitizeResult {
20
+ /** The sanitized tool name */
21
+ sanitized: string;
22
+ /** Whether the name was changed */
23
+ changed: boolean;
24
+ }
25
+ /**
26
+ * Check if a tool name is valid for Gemini API.
27
+ *
28
+ * Requirements:
29
+ * - Length <= 64 characters
30
+ * - Starts with letter or underscore
31
+ * - Contains only valid characters: a-z A-Z 0-9 _ . : -
32
+ */
33
+ export declare function isValidToolName(name: string): boolean;
34
+ /**
35
+ * Remove consecutive duplicate segments separated by '__'.
36
+ *
37
+ * Examples:
38
+ * - 'gitmcp__foo__foo' → 'gitmcp__foo'
39
+ * - 'a__b__c__b__c' → 'a__b__c'
40
+ * - 'no_dupes' → 'no_dupes'
41
+ */
42
+ export declare function removeDuplicateSegments(name: string): string;
43
+ /**
44
+ * Smart truncate a name to fit within maxLen.
45
+ * Preserves start of name and appends hash suffix for uniqueness.
46
+ *
47
+ * Format: <prefix>_<6-char-hash>
48
+ *
49
+ * @param name The name to truncate
50
+ * @param maxLen Maximum allowed length (default: 64)
51
+ */
52
+ export declare function smartTruncate(name: string, maxLen?: number): string;
53
+ /**
54
+ * Sanitize a tool name to comply with Gemini API constraints.
55
+ *
56
+ * Process:
57
+ * 1. Remove duplicate segments (always, as duplicates are likely unintentional)
58
+ * 2. Truncate with hash if >64 chars
59
+ * 3. Return result with changed flag
60
+ *
61
+ * @param name The original tool name
62
+ * @returns Sanitization result with sanitized name and changed flag
63
+ */
64
+ export declare function sanitizeToolName(name: string): SanitizeResult;
65
+ //# sourceMappingURL=tool-name-sanitizer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-name-sanitizer.d.ts","sourceRoot":"","sources":["../../src/cliproxy/tool-name-sanitizer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,qDAAqD;AACrD,eAAO,MAAM,2BAA2B,KAAK,CAAC;AAK9C,uCAAuC;AACvC,MAAM,WAAW,cAAc;IAC7B,8BAA8B;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,mCAAmC;IACnC,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAQrD;AAED;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAY5D;AAUD;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,GAAE,MAAoC,GAAG,MAAM,CAWhG;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,CAmB7D"}
@@ -0,0 +1,118 @@
1
+ "use strict";
2
+ /**
3
+ * Tool Name Sanitizer
4
+ *
5
+ * Sanitizes MCP tool names to comply with Gemini API constraints:
6
+ * - Max 64 characters
7
+ * - Must start with letter or underscore
8
+ * - Only a-z A-Z 0-9 _ . : - / allowed
9
+ *
10
+ * Strategies:
11
+ * 1. Remove duplicate segments (e.g., gitmcp__foo__foo → gitmcp__foo)
12
+ * 2. Smart truncate with hash suffix if still >64 chars
13
+ *
14
+ * Note: Hash collision risk is ~1 in 16M with 6-char MD5 prefix.
15
+ * Acceptable for typical MCP tool counts (<1000 tools).
16
+ */
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.sanitizeToolName = exports.smartTruncate = exports.removeDuplicateSegments = exports.isValidToolName = exports.GEMINI_MAX_TOOL_NAME_LENGTH = void 0;
19
+ const crypto_1 = require("crypto");
20
+ /** Maximum tool name length allowed by Gemini API */
21
+ exports.GEMINI_MAX_TOOL_NAME_LENGTH = 64;
22
+ /** Valid characters pattern for Gemini tool names */
23
+ const VALID_CHARS_REGEX = /^[a-zA-Z_][a-zA-Z0-9_.:/-]*$/;
24
+ /**
25
+ * Check if a tool name is valid for Gemini API.
26
+ *
27
+ * Requirements:
28
+ * - Length <= 64 characters
29
+ * - Starts with letter or underscore
30
+ * - Contains only valid characters: a-z A-Z 0-9 _ . : -
31
+ */
32
+ function isValidToolName(name) {
33
+ if (!name || name.length === 0) {
34
+ return false;
35
+ }
36
+ if (name.length > exports.GEMINI_MAX_TOOL_NAME_LENGTH) {
37
+ return false;
38
+ }
39
+ return VALID_CHARS_REGEX.test(name);
40
+ }
41
+ exports.isValidToolName = isValidToolName;
42
+ /**
43
+ * Remove consecutive duplicate segments separated by '__'.
44
+ *
45
+ * Examples:
46
+ * - 'gitmcp__foo__foo' → 'gitmcp__foo'
47
+ * - 'a__b__c__b__c' → 'a__b__c'
48
+ * - 'no_dupes' → 'no_dupes'
49
+ */
50
+ function removeDuplicateSegments(name) {
51
+ const segments = name.split('__');
52
+ const deduped = [];
53
+ for (const segment of segments) {
54
+ // Only add if different from previous segment
55
+ if (deduped.length === 0 || deduped[deduped.length - 1] !== segment) {
56
+ deduped.push(segment);
57
+ }
58
+ }
59
+ return deduped.join('__');
60
+ }
61
+ exports.removeDuplicateSegments = removeDuplicateSegments;
62
+ /**
63
+ * Generate a short hash from a string for truncation suffix.
64
+ * Uses first 6 characters of MD5 hash (16M combinations).
65
+ */
66
+ function generateShortHash(input) {
67
+ return (0, crypto_1.createHash)('md5').update(input).digest('hex').slice(0, 6);
68
+ }
69
+ /**
70
+ * Smart truncate a name to fit within maxLen.
71
+ * Preserves start of name and appends hash suffix for uniqueness.
72
+ *
73
+ * Format: <prefix>_<6-char-hash>
74
+ *
75
+ * @param name The name to truncate
76
+ * @param maxLen Maximum allowed length (default: 64)
77
+ */
78
+ function smartTruncate(name, maxLen = exports.GEMINI_MAX_TOOL_NAME_LENGTH) {
79
+ if (name.length <= maxLen) {
80
+ return name;
81
+ }
82
+ // Format: prefix + '_' + 6-char hash = 7 chars for suffix
83
+ const hash = generateShortHash(name);
84
+ const prefixLen = maxLen - 7; // 7 = '_' (1) + hash (6)
85
+ const prefix = name.slice(0, prefixLen);
86
+ return `${prefix}_${hash}`;
87
+ }
88
+ exports.smartTruncate = smartTruncate;
89
+ /**
90
+ * Sanitize a tool name to comply with Gemini API constraints.
91
+ *
92
+ * Process:
93
+ * 1. Remove duplicate segments (always, as duplicates are likely unintentional)
94
+ * 2. Truncate with hash if >64 chars
95
+ * 3. Return result with changed flag
96
+ *
97
+ * @param name The original tool name
98
+ * @returns Sanitization result with sanitized name and changed flag
99
+ */
100
+ function sanitizeToolName(name) {
101
+ // Step 1: Always try to remove duplicate segments
102
+ // Duplicates like gitmcp__foo__foo are likely unintentional from MCP naming
103
+ let sanitized = removeDuplicateSegments(name);
104
+ // Step 2: Truncate if still too long
105
+ if (sanitized.length > exports.GEMINI_MAX_TOOL_NAME_LENGTH) {
106
+ sanitized = smartTruncate(sanitized);
107
+ }
108
+ // Step 3: If still invalid after sanitization, apply truncation to original
109
+ if (!isValidToolName(sanitized)) {
110
+ sanitized = smartTruncate(name);
111
+ }
112
+ return {
113
+ sanitized,
114
+ changed: sanitized !== name,
115
+ };
116
+ }
117
+ exports.sanitizeToolName = sanitizeToolName;
118
+ //# sourceMappingURL=tool-name-sanitizer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-name-sanitizer.js","sourceRoot":"","sources":["../../src/cliproxy/tool-name-sanitizer.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;GAcG;;;AAEH,mCAAoC;AAEpC,qDAAqD;AACxC,QAAA,2BAA2B,GAAG,EAAE,CAAC;AAE9C,qDAAqD;AACrD,MAAM,iBAAiB,GAAG,8BAA8B,CAAC;AAUzD;;;;;;;GAOG;AACH,SAAgB,eAAe,CAAC,IAAY;IAC1C,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC/B,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,IAAI,CAAC,MAAM,GAAG,mCAA2B,EAAE,CAAC;QAC9C,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACtC,CAAC;AARD,0CAQC;AAED;;;;;;;GAOG;AACH,SAAgB,uBAAuB,CAAC,IAAY;IAClD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAClC,MAAM,OAAO,GAAa,EAAE,CAAC;IAE7B,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,8CAA8C;QAC9C,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,OAAO,EAAE,CAAC;YACpE,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACxB,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC5B,CAAC;AAZD,0DAYC;AAED;;;GAGG;AACH,SAAS,iBAAiB,CAAC,KAAa;IACtC,OAAO,IAAA,mBAAU,EAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AACnE,CAAC;AAED;;;;;;;;GAQG;AACH,SAAgB,aAAa,CAAC,IAAY,EAAE,SAAiB,mCAA2B;IACtF,IAAI,IAAI,CAAC,MAAM,IAAI,MAAM,EAAE,CAAC;QAC1B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,0DAA0D;IAC1D,MAAM,IAAI,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;IACrC,MAAM,SAAS,GAAG,MAAM,GAAG,CAAC,CAAC,CAAC,yBAAyB;IACvD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;IAExC,OAAO,GAAG,MAAM,IAAI,IAAI,EAAE,CAAC;AAC7B,CAAC;AAXD,sCAWC;AAED;;;;;;;;;;GAUG;AACH,SAAgB,gBAAgB,CAAC,IAAY;IAC3C,kDAAkD;IAClD,4EAA4E;IAC5E,IAAI,SAAS,GAAG,uBAAuB,CAAC,IAAI,CAAC,CAAC;IAE9C,qCAAqC;IACrC,IAAI,SAAS,CAAC,MAAM,GAAG,mCAA2B,EAAE,CAAC;QACnD,SAAS,GAAG,aAAa,CAAC,SAAS,CAAC,CAAC;IACvC,CAAC;IAED,4EAA4E;IAC5E,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,EAAE,CAAC;QAChC,SAAS,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;IAClC,CAAC;IAED,OAAO;QACL,SAAS;QACT,OAAO,EAAE,SAAS,KAAK,IAAI;KAC5B,CAAC;AACJ,CAAC;AAnBD,4CAmBC"}
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Tool Sanitization Proxy
3
+ *
4
+ * HTTP proxy that intercepts Claude CLI → CLIProxy requests to:
5
+ * 1. Sanitize MCP tool names exceeding Gemini's 64-char limit
6
+ * 2. Forward sanitized requests to upstream
7
+ * 3. Restore original names in responses
8
+ *
9
+ * Follows CodexReasoningProxy pattern for consistency.
10
+ */
11
+ export interface ToolSanitizationProxyConfig {
12
+ /** Upstream CLIProxy URL */
13
+ upstreamBaseUrl: string;
14
+ /** Enable verbose logging */
15
+ verbose?: boolean;
16
+ /** Log warnings when sanitization occurs */
17
+ warnOnSanitize?: boolean;
18
+ /** Request timeout in milliseconds */
19
+ timeoutMs?: number;
20
+ }
21
+ export declare class ToolSanitizationProxy {
22
+ private server;
23
+ private port;
24
+ private readonly config;
25
+ private readonly logFilePath;
26
+ private readonly debugMode;
27
+ constructor(config: ToolSanitizationProxyConfig);
28
+ /**
29
+ * Initialize log file path and ensure directory exists.
30
+ */
31
+ private initLogFile;
32
+ /**
33
+ * Write log entry to file (always) and console (if CCS_DEBUG=1).
34
+ */
35
+ private writeLog;
36
+ private log;
37
+ private warn;
38
+ /**
39
+ * Start the proxy server on an ephemeral port.
40
+ * @returns The assigned port number
41
+ */
42
+ start(): Promise<number>;
43
+ /**
44
+ * Stop the proxy server.
45
+ */
46
+ stop(): void;
47
+ /**
48
+ * Get the port the proxy is listening on.
49
+ */
50
+ getPort(): number | null;
51
+ private readBody;
52
+ private handleRequest;
53
+ private buildForwardHeaders;
54
+ private getRequestFn;
55
+ private forwardRaw;
56
+ /**
57
+ * Forward JSON request and buffer response for tool name restoration.
58
+ */
59
+ private forwardJsonBuffered;
60
+ /**
61
+ * Forward JSON request and stream response with tool name restoration.
62
+ * Handles SSE (Server-Sent Events) format.
63
+ */
64
+ private forwardJsonStreaming;
65
+ /**
66
+ * Process a single SSE event, restoring tool names if present.
67
+ */
68
+ private processSSEEvent;
69
+ }
70
+ //# sourceMappingURL=tool-sanitization-proxy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-sanitization-proxy.d.ts","sourceRoot":"","sources":["../../src/cliproxy/tool-sanitization-proxy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAWH,MAAM,WAAW,2BAA2B;IAC1C,4BAA4B;IAC5B,eAAe,EAAE,MAAM,CAAC;IACxB,6BAA6B;IAC7B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,4CAA4C;IAC5C,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,sCAAsC;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAUD,qBAAa,qBAAqB;IAChC,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,IAAI,CAAuB;IACnC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAwC;IAC/D,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAU;gBAExB,MAAM,EAAE,2BAA2B;IAW/C;;OAEG;IACH,OAAO,CAAC,WAAW;IAoBnB;;OAEG;IACH,OAAO,CAAC,QAAQ;IAkBhB,OAAO,CAAC,GAAG;IAMX,OAAO,CAAC,IAAI;IAMZ;;;OAGG;IACG,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC;IAmB9B;;OAEG;IACH,IAAI,IAAI,IAAI;IAOZ;;OAEG;IACH,OAAO,IAAI,MAAM,GAAG,IAAI;IAIxB,OAAO,CAAC,QAAQ;YAqBF,aAAa;IA6E3B,OAAO,CAAC,mBAAmB;IAmC3B,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,UAAU;IA+BlB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAsE3B;;;OAGG;IACH,OAAO,CAAC,oBAAoB;IAsE5B;;OAEG;IACH,OAAO,CAAC,eAAe;CAqDxB"}