wave-agent-sdk 0.0.6 → 0.0.8
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/agent.d.ts +32 -20
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +209 -24
- package/dist/constants/events.d.ts +28 -0
- package/dist/constants/events.d.ts.map +1 -0
- package/dist/constants/events.js +27 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/managers/aiManager.d.ts +34 -1
- package/dist/managers/aiManager.d.ts.map +1 -1
- package/dist/managers/aiManager.js +248 -132
- package/dist/managers/backgroundBashManager.d.ts.map +1 -1
- package/dist/managers/backgroundBashManager.js +7 -6
- package/dist/managers/hookManager.d.ts +13 -16
- package/dist/managers/hookManager.d.ts.map +1 -1
- package/dist/managers/hookManager.js +81 -44
- package/dist/managers/liveConfigManager.d.ts +58 -0
- package/dist/managers/liveConfigManager.d.ts.map +1 -0
- package/dist/managers/liveConfigManager.js +160 -0
- package/dist/managers/messageManager.d.ts +41 -24
- package/dist/managers/messageManager.d.ts.map +1 -1
- package/dist/managers/messageManager.js +168 -49
- package/dist/managers/slashCommandManager.d.ts.map +1 -1
- package/dist/managers/slashCommandManager.js +9 -3
- package/dist/managers/subagentManager.d.ts +51 -0
- package/dist/managers/subagentManager.d.ts.map +1 -1
- package/dist/managers/subagentManager.js +190 -19
- package/dist/services/aiService.d.ts +13 -5
- package/dist/services/aiService.d.ts.map +1 -1
- package/dist/services/aiService.js +350 -74
- package/dist/services/configurationWatcher.d.ts +120 -0
- package/dist/services/configurationWatcher.d.ts.map +1 -0
- package/dist/services/configurationWatcher.js +439 -0
- package/dist/services/fileWatcher.d.ts +69 -0
- package/dist/services/fileWatcher.d.ts.map +1 -0
- package/dist/services/fileWatcher.js +213 -0
- package/dist/services/hook.d.ts +91 -9
- package/dist/services/hook.d.ts.map +1 -1
- package/dist/services/hook.js +393 -43
- package/dist/services/jsonlHandler.d.ts +62 -0
- package/dist/services/jsonlHandler.d.ts.map +1 -0
- package/dist/services/jsonlHandler.js +257 -0
- package/dist/services/memory.d.ts +9 -0
- package/dist/services/memory.d.ts.map +1 -1
- package/dist/services/memory.js +81 -12
- package/dist/services/memoryStore.d.ts +81 -0
- package/dist/services/memoryStore.d.ts.map +1 -0
- package/dist/services/memoryStore.js +200 -0
- package/dist/services/session.d.ts +64 -49
- package/dist/services/session.d.ts.map +1 -1
- package/dist/services/session.js +310 -132
- package/dist/tools/bashTool.d.ts.map +1 -1
- package/dist/tools/bashTool.js +5 -4
- package/dist/tools/deleteFileTool.d.ts.map +1 -1
- package/dist/tools/deleteFileTool.js +2 -1
- package/dist/tools/editTool.d.ts.map +1 -1
- package/dist/tools/editTool.js +3 -2
- package/dist/tools/multiEditTool.d.ts.map +1 -1
- package/dist/tools/multiEditTool.js +4 -3
- package/dist/tools/readTool.d.ts.map +1 -1
- package/dist/tools/readTool.js +2 -1
- package/dist/tools/todoWriteTool.d.ts.map +1 -1
- package/dist/tools/todoWriteTool.js +3 -10
- package/dist/tools/writeTool.d.ts.map +1 -1
- package/dist/tools/writeTool.js +5 -6
- package/dist/types/commands.d.ts +4 -0
- package/dist/types/commands.d.ts.map +1 -1
- package/dist/types/core.d.ts +35 -0
- package/dist/types/core.d.ts.map +1 -1
- package/dist/types/environment.d.ts +42 -0
- package/dist/types/environment.d.ts.map +1 -0
- package/dist/types/environment.js +21 -0
- package/dist/types/hooks.d.ts +8 -2
- package/dist/types/hooks.d.ts.map +1 -1
- package/dist/types/hooks.js +8 -2
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +2 -0
- package/dist/types/memoryStore.d.ts +82 -0
- package/dist/types/memoryStore.d.ts.map +1 -0
- package/dist/types/memoryStore.js +7 -0
- package/dist/types/messaging.d.ts +21 -9
- package/dist/types/messaging.d.ts.map +1 -1
- package/dist/types/messaging.js +5 -1
- package/dist/types/session.d.ts +20 -0
- package/dist/types/session.d.ts.map +1 -0
- package/dist/types/session.js +7 -0
- package/dist/utils/bashHistory.d.ts.map +1 -1
- package/dist/utils/bashHistory.js +27 -26
- package/dist/utils/cacheControlUtils.d.ts +121 -0
- package/dist/utils/cacheControlUtils.d.ts.map +1 -0
- package/dist/utils/cacheControlUtils.js +367 -0
- package/dist/utils/commandPathResolver.d.ts +52 -0
- package/dist/utils/commandPathResolver.d.ts.map +1 -0
- package/dist/utils/commandPathResolver.js +145 -0
- package/dist/utils/configPaths.d.ts +85 -0
- package/dist/utils/configPaths.d.ts.map +1 -0
- package/dist/utils/configPaths.js +121 -0
- package/dist/utils/configResolver.d.ts +37 -10
- package/dist/utils/configResolver.d.ts.map +1 -1
- package/dist/utils/configResolver.js +127 -23
- package/dist/utils/constants.d.ts +1 -1
- package/dist/utils/constants.js +1 -1
- package/dist/utils/convertMessagesForAPI.d.ts.map +1 -1
- package/dist/utils/convertMessagesForAPI.js +8 -13
- package/dist/utils/customCommands.d.ts.map +1 -1
- package/dist/utils/customCommands.js +66 -21
- package/dist/utils/fileUtils.d.ts +15 -0
- package/dist/utils/fileUtils.d.ts.map +1 -0
- package/dist/utils/fileUtils.js +61 -0
- package/dist/utils/globalLogger.d.ts +102 -0
- package/dist/utils/globalLogger.d.ts.map +1 -0
- package/dist/utils/globalLogger.js +136 -0
- package/dist/utils/hookMatcher.d.ts +1 -6
- package/dist/utils/hookMatcher.d.ts.map +1 -1
- package/dist/utils/mcpUtils.d.ts.map +1 -1
- package/dist/utils/mcpUtils.js +25 -3
- package/dist/utils/messageOperations.d.ts +27 -27
- package/dist/utils/messageOperations.d.ts.map +1 -1
- package/dist/utils/messageOperations.js +46 -36
- package/dist/utils/pathEncoder.d.ts +104 -0
- package/dist/utils/pathEncoder.d.ts.map +1 -0
- package/dist/utils/pathEncoder.js +272 -0
- package/dist/utils/subagentParser.d.ts.map +1 -1
- package/dist/utils/subagentParser.js +2 -1
- package/dist/utils/tokenCalculation.d.ts +26 -0
- package/dist/utils/tokenCalculation.d.ts.map +1 -0
- package/dist/utils/tokenCalculation.js +36 -0
- package/package.json +6 -3
- package/src/agent.ts +301 -37
- package/src/constants/events.ts +38 -0
- package/src/index.ts +2 -0
- package/src/managers/aiManager.ts +325 -173
- package/src/managers/backgroundBashManager.ts +7 -6
- package/src/managers/hookManager.ts +106 -84
- package/src/managers/liveConfigManager.ts +248 -0
- package/src/managers/messageManager.ts +237 -100
- package/src/managers/slashCommandManager.ts +9 -7
- package/src/managers/subagentManager.ts +284 -22
- package/src/services/aiService.ts +474 -83
- package/src/services/configurationWatcher.ts +622 -0
- package/src/services/fileWatcher.ts +301 -0
- package/src/services/hook.ts +538 -47
- package/src/services/jsonlHandler.ts +319 -0
- package/src/services/memory.ts +92 -12
- package/src/services/memoryStore.ts +279 -0
- package/src/services/session.ts +381 -157
- package/src/tools/bashTool.ts +5 -4
- package/src/tools/deleteFileTool.ts +2 -1
- package/src/tools/editTool.ts +3 -2
- package/src/tools/multiEditTool.ts +4 -3
- package/src/tools/readTool.ts +2 -1
- package/src/tools/todoWriteTool.ts +3 -11
- package/src/tools/writeTool.ts +7 -6
- package/src/types/commands.ts +6 -0
- package/src/types/core.ts +44 -0
- package/src/types/environment.ts +60 -0
- package/src/types/hooks.ts +21 -8
- package/src/types/index.ts +2 -0
- package/src/types/memoryStore.ts +94 -0
- package/src/types/messaging.ts +21 -10
- package/src/types/session.ts +25 -0
- package/src/utils/bashHistory.ts +27 -27
- package/src/utils/cacheControlUtils.ts +540 -0
- package/src/utils/commandPathResolver.ts +189 -0
- package/src/utils/configPaths.ts +163 -0
- package/src/utils/configResolver.ts +182 -22
- package/src/utils/constants.ts +1 -1
- package/src/utils/convertMessagesForAPI.ts +8 -14
- package/src/utils/customCommands.ts +90 -22
- package/src/utils/fileUtils.ts +65 -0
- package/src/utils/globalLogger.ts +145 -0
- package/src/utils/hookMatcher.ts +1 -12
- package/src/utils/mcpUtils.ts +34 -3
- package/src/utils/messageOperations.ts +77 -60
- package/src/utils/pathEncoder.ts +379 -0
- package/src/utils/subagentParser.ts +2 -1
- package/src/utils/tokenCalculation.ts +43 -0
- package/src/types/index.ts.backup +0 -357
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import fs from "fs";
|
|
6
6
|
import { BASH_HISTORY_FILE, DATA_DIRECTORY } from "./constants.js";
|
|
7
|
+
import { logger } from "./globalLogger.js";
|
|
7
8
|
const HISTORY_VERSION = 1;
|
|
8
9
|
const MAX_HISTORY_SIZE = 1000;
|
|
9
10
|
/**
|
|
@@ -15,8 +16,8 @@ const ensureDataDirectory = () => {
|
|
|
15
16
|
fs.mkdirSync(DATA_DIRECTORY, { recursive: true });
|
|
16
17
|
}
|
|
17
18
|
}
|
|
18
|
-
catch {
|
|
19
|
-
|
|
19
|
+
catch (error) {
|
|
20
|
+
logger.debug("Failed to create data directory:", error);
|
|
20
21
|
}
|
|
21
22
|
};
|
|
22
23
|
/**
|
|
@@ -35,7 +36,7 @@ export const loadBashHistory = () => {
|
|
|
35
36
|
const history = JSON.parse(data);
|
|
36
37
|
// Version compatibility check
|
|
37
38
|
if (history.version !== HISTORY_VERSION) {
|
|
38
|
-
|
|
39
|
+
logger.debug("Bash history version mismatch, resetting history");
|
|
39
40
|
return {
|
|
40
41
|
commands: [],
|
|
41
42
|
version: HISTORY_VERSION,
|
|
@@ -43,8 +44,8 @@ export const loadBashHistory = () => {
|
|
|
43
44
|
}
|
|
44
45
|
return history;
|
|
45
46
|
}
|
|
46
|
-
catch {
|
|
47
|
-
|
|
47
|
+
catch (error) {
|
|
48
|
+
logger.debug("Failed to load bash history:", error);
|
|
48
49
|
return {
|
|
49
50
|
commands: [],
|
|
50
51
|
version: HISTORY_VERSION,
|
|
@@ -58,7 +59,7 @@ export const saveBashHistory = (history) => {
|
|
|
58
59
|
try {
|
|
59
60
|
// Skip saving to file when in test environment
|
|
60
61
|
if (process.env.NODE_ENV === "test") {
|
|
61
|
-
|
|
62
|
+
logger.debug("Skipping bash history save in test environment");
|
|
62
63
|
return;
|
|
63
64
|
}
|
|
64
65
|
ensureDataDirectory();
|
|
@@ -69,8 +70,8 @@ export const saveBashHistory = (history) => {
|
|
|
69
70
|
const data = JSON.stringify(history, null, 2);
|
|
70
71
|
fs.writeFileSync(BASH_HISTORY_FILE, data, "utf-8");
|
|
71
72
|
}
|
|
72
|
-
catch {
|
|
73
|
-
|
|
73
|
+
catch (error) {
|
|
74
|
+
logger.debug("Failed to save bash history:", error);
|
|
74
75
|
}
|
|
75
76
|
};
|
|
76
77
|
/**
|
|
@@ -78,11 +79,6 @@ export const saveBashHistory = (history) => {
|
|
|
78
79
|
*/
|
|
79
80
|
export const addBashCommandToHistory = (command, workdir) => {
|
|
80
81
|
try {
|
|
81
|
-
// Filter system-generated commands, do not add to history
|
|
82
|
-
if (command.startsWith("git add . && git commit -m")) {
|
|
83
|
-
// logger.debug("Skipping system-generated command:", { command, workdir });
|
|
84
|
-
return;
|
|
85
|
-
}
|
|
86
82
|
const history = loadBashHistory();
|
|
87
83
|
const timestamp = Date.now();
|
|
88
84
|
// Check if it's a duplicate consecutive command to avoid duplicate recording
|
|
@@ -102,10 +98,10 @@ export const addBashCommandToHistory = (command, workdir) => {
|
|
|
102
98
|
});
|
|
103
99
|
}
|
|
104
100
|
saveBashHistory(history);
|
|
105
|
-
|
|
101
|
+
logger.debug("Added bash command to history:", { command, workdir });
|
|
106
102
|
}
|
|
107
|
-
catch {
|
|
108
|
-
|
|
103
|
+
catch (error) {
|
|
104
|
+
logger.debug("Failed to add bash command to history:", error);
|
|
109
105
|
}
|
|
110
106
|
};
|
|
111
107
|
/**
|
|
@@ -156,11 +152,16 @@ export const searchBashHistory = (query, limit = 10, workdir) => {
|
|
|
156
152
|
// Deduplicate search results, keep latest record
|
|
157
153
|
const dedupedMatches = deduplicateCommands(matches);
|
|
158
154
|
const result = dedupedMatches.slice(0, limit);
|
|
159
|
-
|
|
155
|
+
logger.debug("Bash history search results:", {
|
|
156
|
+
query,
|
|
157
|
+
workdir: process.cwd(),
|
|
158
|
+
originalCount: matches.length,
|
|
159
|
+
dedupedCount: result.length,
|
|
160
|
+
});
|
|
160
161
|
return result;
|
|
161
162
|
}
|
|
162
|
-
catch {
|
|
163
|
-
|
|
163
|
+
catch (error) {
|
|
164
|
+
logger.debug("Failed to search bash history:", error);
|
|
164
165
|
return [];
|
|
165
166
|
}
|
|
166
167
|
};
|
|
@@ -190,8 +191,8 @@ export const getRecentBashCommands = (workdir, limit = 10) => {
|
|
|
190
191
|
const deduped = deduplicateCommands(filtered);
|
|
191
192
|
return deduped.slice(-limit).reverse(); // Latest first
|
|
192
193
|
}
|
|
193
|
-
catch {
|
|
194
|
-
|
|
194
|
+
catch (error) {
|
|
195
|
+
logger.debug("Failed to get recent bash commands:", error);
|
|
195
196
|
return [];
|
|
196
197
|
}
|
|
197
198
|
};
|
|
@@ -205,10 +206,10 @@ export const clearBashHistory = () => {
|
|
|
205
206
|
version: HISTORY_VERSION,
|
|
206
207
|
};
|
|
207
208
|
saveBashHistory(history);
|
|
208
|
-
|
|
209
|
+
logger.debug("Bash history cleared");
|
|
209
210
|
}
|
|
210
|
-
catch {
|
|
211
|
-
|
|
211
|
+
catch (error) {
|
|
212
|
+
logger.debug("Failed to clear bash history:", error);
|
|
212
213
|
}
|
|
213
214
|
};
|
|
214
215
|
/**
|
|
@@ -225,8 +226,8 @@ export const getBashCommandStats = () => {
|
|
|
225
226
|
workdirs,
|
|
226
227
|
};
|
|
227
228
|
}
|
|
228
|
-
catch {
|
|
229
|
-
|
|
229
|
+
catch (error) {
|
|
230
|
+
logger.debug("Failed to get bash command stats:", error);
|
|
230
231
|
return {
|
|
231
232
|
totalCommands: 0,
|
|
232
233
|
uniqueCommands: 0,
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cache Control Utilities for Claude Models
|
|
3
|
+
*
|
|
4
|
+
* This module provides utilities for adding cache_control markers to Claude models
|
|
5
|
+
* to optimize token usage and reduce costs. Cache control is only applied to Claude
|
|
6
|
+
* models and preserves backward compatibility with existing message formats.
|
|
7
|
+
*/
|
|
8
|
+
import type { ChatCompletionMessageParam, ChatCompletionContentPart, ChatCompletionContentPartText, ChatCompletionFunctionTool, CompletionUsage } from "openai/resources";
|
|
9
|
+
/**
|
|
10
|
+
* Cache control directive for Claude models
|
|
11
|
+
*/
|
|
12
|
+
export interface CacheControl {
|
|
13
|
+
type: "ephemeral";
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Extended text content part with cache control support
|
|
17
|
+
*/
|
|
18
|
+
export interface ClaudeChatCompletionContentPartText extends ChatCompletionContentPartText {
|
|
19
|
+
type: "text";
|
|
20
|
+
text: string;
|
|
21
|
+
cache_control?: CacheControl;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Extended tool definition with cache control support
|
|
25
|
+
*/
|
|
26
|
+
export interface ClaudeChatCompletionFunctionTool extends ChatCompletionFunctionTool {
|
|
27
|
+
type: "function";
|
|
28
|
+
function: ChatCompletionFunctionTool["function"];
|
|
29
|
+
cache_control?: CacheControl;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Enhanced usage metrics including Claude cache information
|
|
33
|
+
*/
|
|
34
|
+
export interface ClaudeUsage extends CompletionUsage {
|
|
35
|
+
prompt_tokens: number;
|
|
36
|
+
completion_tokens: number;
|
|
37
|
+
total_tokens: number;
|
|
38
|
+
cache_read_input_tokens?: number;
|
|
39
|
+
cache_creation_input_tokens?: number;
|
|
40
|
+
cache_creation?: {
|
|
41
|
+
ephemeral_5m_input_tokens: number;
|
|
42
|
+
ephemeral_1h_input_tokens: number;
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Configuration for cache control application
|
|
47
|
+
*/
|
|
48
|
+
export interface CacheControlConfig {
|
|
49
|
+
cacheSystemMessage: boolean;
|
|
50
|
+
cacheUserMessageCount: number;
|
|
51
|
+
cacheLastTool: boolean;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Default cache control configuration
|
|
55
|
+
*/
|
|
56
|
+
export declare const DEFAULT_CACHE_CONTROL_CONFIG: CacheControlConfig;
|
|
57
|
+
/**
|
|
58
|
+
* Determines if a model supports cache control
|
|
59
|
+
* @param modelName - Model identifier
|
|
60
|
+
* @returns True if model name contains 'claude' (case-insensitive)
|
|
61
|
+
*/
|
|
62
|
+
export declare function isClaudeModel(modelName: string): boolean;
|
|
63
|
+
/**
|
|
64
|
+
* Validates cache control structure
|
|
65
|
+
* @param control - Object to validate
|
|
66
|
+
* @returns True if valid cache control object
|
|
67
|
+
*/
|
|
68
|
+
export declare function isValidCacheControl(control: unknown): control is CacheControl;
|
|
69
|
+
/**
|
|
70
|
+
* Adds cache control markers to message content
|
|
71
|
+
* @param content - Original content (string or structured)
|
|
72
|
+
* @param shouldCache - Whether to add cache control
|
|
73
|
+
* @returns Structured content with cache control markers
|
|
74
|
+
*/
|
|
75
|
+
export declare function addCacheControlToContent(content: string | ChatCompletionContentPart[], shouldCache: boolean): ClaudeChatCompletionContentPartText[];
|
|
76
|
+
/**
|
|
77
|
+
* Adds cache control to the last tool in tools array
|
|
78
|
+
* @param tools - Array of tool definitions
|
|
79
|
+
* @returns Tools array with cache control on last tool
|
|
80
|
+
*/
|
|
81
|
+
export declare function addCacheControlToLastTool(tools: ChatCompletionFunctionTool[]): ClaudeChatCompletionFunctionTool[];
|
|
82
|
+
/**
|
|
83
|
+
* Transforms messages for Claude cache control
|
|
84
|
+
* @param messages - Original OpenAI message array
|
|
85
|
+
* @param modelName - Model name for cache detection
|
|
86
|
+
* @param config - Cache control configuration
|
|
87
|
+
* @returns Messages with cache control markers applied
|
|
88
|
+
*/
|
|
89
|
+
export declare function transformMessagesForClaudeCache(messages: ChatCompletionMessageParam[], modelName: string, config?: CacheControlConfig): ChatCompletionMessageParam[];
|
|
90
|
+
/**
|
|
91
|
+
* Extends standard usage with cache metrics
|
|
92
|
+
* @param standardUsage - OpenAI usage response
|
|
93
|
+
* @param cacheMetrics - Additional cache metrics from Claude
|
|
94
|
+
* @returns Extended usage with cache information
|
|
95
|
+
*/
|
|
96
|
+
export declare function extendUsageWithCacheMetrics(standardUsage: CompletionUsage, cacheMetrics?: Partial<ClaudeUsage>): ClaudeUsage;
|
|
97
|
+
/**
|
|
98
|
+
* Validates Claude usage structure
|
|
99
|
+
* @param usage - Usage object to validate
|
|
100
|
+
* @returns True if usage structure is valid
|
|
101
|
+
*/
|
|
102
|
+
export declare function isValidClaudeUsage(usage: unknown): usage is ClaudeUsage;
|
|
103
|
+
/**
|
|
104
|
+
* Adds cache control to the last N user messages in a conversation
|
|
105
|
+
* This optimizes multi-turn conversations by caching recent user context
|
|
106
|
+
*
|
|
107
|
+
* @param messages - Array of chat completion messages
|
|
108
|
+
* @param maxUserMessagesToCache - Maximum number of recent user messages to cache (default: 2)
|
|
109
|
+
* @returns Modified messages array with cache control on recent user messages
|
|
110
|
+
*/
|
|
111
|
+
export declare function addCacheControlToRecentUserMessages(messages: ChatCompletionMessageParam[], maxUserMessagesToCache?: number): ChatCompletionMessageParam[];
|
|
112
|
+
/**
|
|
113
|
+
* Helper function to identify user message indices that should be cached
|
|
114
|
+
* Used for testing and validation purposes
|
|
115
|
+
*
|
|
116
|
+
* @param messages - Array of chat completion messages
|
|
117
|
+
* @param maxUserMessagesToCache - Maximum number of recent user messages to identify
|
|
118
|
+
* @returns Array of indices for user messages that should be cached
|
|
119
|
+
*/
|
|
120
|
+
export declare function findRecentUserMessageIndices(messages: ChatCompletionMessageParam[], maxUserMessagesToCache?: number): number[];
|
|
121
|
+
//# sourceMappingURL=cacheControlUtils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cacheControlUtils.d.ts","sourceRoot":"","sources":["../../src/utils/cacheControlUtils.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EACV,0BAA0B,EAC1B,yBAAyB,EACzB,6BAA6B,EAC7B,0BAA0B,EAC1B,eAAe,EAChB,MAAM,kBAAkB,CAAC;AAM1B;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,WAAW,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,mCACf,SAAQ,6BAA6B;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,CAAC,EAAE,YAAY,CAAC;CAC9B;AAED;;GAEG;AACH,MAAM,WAAW,gCACf,SAAQ,0BAA0B;IAClC,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE,0BAA0B,CAAC,UAAU,CAAC,CAAC;IACjD,aAAa,CAAC,EAAE,YAAY,CAAC;CAC9B;AAED;;GAEG;AACH,MAAM,WAAW,WAAY,SAAQ,eAAe;IAClD,aAAa,EAAE,MAAM,CAAC;IACtB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;IAGrB,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,2BAA2B,CAAC,EAAE,MAAM,CAAC;IACrC,cAAc,CAAC,EAAE;QACf,yBAAyB,EAAE,MAAM,CAAC;QAClC,yBAAyB,EAAE,MAAM,CAAC;KACnC,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,kBAAkB,EAAE,OAAO,CAAC;IAC5B,qBAAqB,EAAE,MAAM,CAAC;IAC9B,aAAa,EAAE,OAAO,CAAC;CACxB;AAMD;;GAEG;AACH,eAAO,MAAM,4BAA4B,EAAE,kBAIjC,CAAC;AAMX;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAaxD;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,IAAI,YAAY,CAQ7E;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,MAAM,GAAG,yBAAyB,EAAE,EAC7C,WAAW,EAAE,OAAO,GACnB,mCAAmC,EAAE,CAkEvC;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,0BAA0B,EAAE,GAClC,gCAAgC,EAAE,CAwCpC;AAED;;;;;;GAMG;AACH,wBAAgB,+BAA+B,CAC7C,QAAQ,EAAE,0BAA0B,EAAE,EACtC,SAAS,EAAE,MAAM,EACjB,MAAM,GAAE,kBAAiD,GACxD,0BAA0B,EAAE,CAkE9B;AAED;;;;;GAKG;AACH,wBAAgB,2BAA2B,CACzC,aAAa,EAAE,eAAe,EAC9B,YAAY,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,GAClC,WAAW,CAkCb;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,WAAW,CAyCvE;AAED;;;;;;;GAOG;AACH,wBAAgB,mCAAmC,CACjD,QAAQ,EAAE,0BAA0B,EAAE,EACtC,sBAAsB,GAAE,MAAU,GACjC,0BAA0B,EAAE,CAuE9B;AAED;;;;;;;GAOG;AACH,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,0BAA0B,EAAE,EACtC,sBAAsB,GAAE,MAAU,GACjC,MAAM,EAAE,CAqBV"}
|
|
@@ -0,0 +1,367 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cache Control Utilities for Claude Models
|
|
3
|
+
*
|
|
4
|
+
* This module provides utilities for adding cache_control markers to Claude models
|
|
5
|
+
* to optimize token usage and reduce costs. Cache control is only applied to Claude
|
|
6
|
+
* models and preserves backward compatibility with existing message formats.
|
|
7
|
+
*/
|
|
8
|
+
// ============================================================================
|
|
9
|
+
// Default Configuration
|
|
10
|
+
// ============================================================================
|
|
11
|
+
/**
|
|
12
|
+
* Default cache control configuration
|
|
13
|
+
*/
|
|
14
|
+
export const DEFAULT_CACHE_CONTROL_CONFIG = {
|
|
15
|
+
cacheSystemMessage: true,
|
|
16
|
+
cacheUserMessageCount: 2,
|
|
17
|
+
cacheLastTool: true,
|
|
18
|
+
};
|
|
19
|
+
// ============================================================================
|
|
20
|
+
// Utility Functions (Basic Structure - to be implemented)
|
|
21
|
+
// ============================================================================
|
|
22
|
+
/**
|
|
23
|
+
* Determines if a model supports cache control
|
|
24
|
+
* @param modelName - Model identifier
|
|
25
|
+
* @returns True if model name contains 'claude' (case-insensitive)
|
|
26
|
+
*/
|
|
27
|
+
export function isClaudeModel(modelName) {
|
|
28
|
+
// Handle null, undefined, and non-string inputs
|
|
29
|
+
if (!modelName || typeof modelName !== "string") {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
// Handle empty strings and whitespace-only strings
|
|
33
|
+
const trimmed = modelName.trim();
|
|
34
|
+
if (trimmed.length === 0) {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
return trimmed.toLowerCase().includes("claude");
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Validates cache control structure
|
|
41
|
+
* @param control - Object to validate
|
|
42
|
+
* @returns True if valid cache control object
|
|
43
|
+
*/
|
|
44
|
+
export function isValidCacheControl(control) {
|
|
45
|
+
return (control !== null &&
|
|
46
|
+
typeof control === "object" &&
|
|
47
|
+
control !== undefined &&
|
|
48
|
+
"type" in control &&
|
|
49
|
+
control.type === "ephemeral");
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Adds cache control markers to message content
|
|
53
|
+
* @param content - Original content (string or structured)
|
|
54
|
+
* @param shouldCache - Whether to add cache control
|
|
55
|
+
* @returns Structured content with cache control markers
|
|
56
|
+
*/
|
|
57
|
+
export function addCacheControlToContent(content, shouldCache) {
|
|
58
|
+
// Handle null/undefined content
|
|
59
|
+
if (content == null) {
|
|
60
|
+
return [];
|
|
61
|
+
}
|
|
62
|
+
// If shouldCache is false, return content as text parts without cache control
|
|
63
|
+
if (!shouldCache) {
|
|
64
|
+
if (typeof content === "string") {
|
|
65
|
+
return [{ type: "text", text: content }];
|
|
66
|
+
}
|
|
67
|
+
// Validate array input
|
|
68
|
+
if (!Array.isArray(content)) {
|
|
69
|
+
console.warn("Invalid content type for cache control transformation:", typeof content);
|
|
70
|
+
return [];
|
|
71
|
+
}
|
|
72
|
+
// Filter and convert only text parts with validation
|
|
73
|
+
return content
|
|
74
|
+
.filter((part) => {
|
|
75
|
+
if (!part || typeof part !== "object") {
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
return part.type === "text" && typeof part.text === "string";
|
|
79
|
+
})
|
|
80
|
+
.map((part) => ({ type: "text", text: part.text }));
|
|
81
|
+
}
|
|
82
|
+
// shouldCache is true - add cache control markers
|
|
83
|
+
if (typeof content === "string") {
|
|
84
|
+
// Transform string content to structured array with cache control
|
|
85
|
+
return [
|
|
86
|
+
{
|
|
87
|
+
type: "text",
|
|
88
|
+
text: content,
|
|
89
|
+
cache_control: { type: "ephemeral" },
|
|
90
|
+
},
|
|
91
|
+
];
|
|
92
|
+
}
|
|
93
|
+
// Validate array input
|
|
94
|
+
if (!Array.isArray(content)) {
|
|
95
|
+
console.warn("Invalid content type for cache control transformation:", typeof content);
|
|
96
|
+
return [];
|
|
97
|
+
}
|
|
98
|
+
// Handle structured content - preserve existing structure, add cache control to text parts
|
|
99
|
+
return content
|
|
100
|
+
.filter((part) => {
|
|
101
|
+
if (!part || typeof part !== "object") {
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
return part.type === "text" && typeof part.text === "string";
|
|
105
|
+
})
|
|
106
|
+
.map((part) => ({
|
|
107
|
+
type: "text",
|
|
108
|
+
text: part.text,
|
|
109
|
+
cache_control: { type: "ephemeral" },
|
|
110
|
+
}));
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Adds cache control to the last tool in tools array
|
|
114
|
+
* @param tools - Array of tool definitions
|
|
115
|
+
* @returns Tools array with cache control on last tool
|
|
116
|
+
*/
|
|
117
|
+
export function addCacheControlToLastTool(tools) {
|
|
118
|
+
// Handle null, undefined, or empty arrays
|
|
119
|
+
if (!tools || !Array.isArray(tools) || tools.length === 0) {
|
|
120
|
+
return [];
|
|
121
|
+
}
|
|
122
|
+
// Validate tools structure
|
|
123
|
+
const validTools = tools.filter((tool) => {
|
|
124
|
+
if (!tool || typeof tool !== "object") {
|
|
125
|
+
console.warn("Invalid tool structure detected, skipping:", tool);
|
|
126
|
+
return false;
|
|
127
|
+
}
|
|
128
|
+
if (tool.type !== "function" || !tool.function) {
|
|
129
|
+
console.warn("Tool is not a function type or missing function property:", tool);
|
|
130
|
+
return false;
|
|
131
|
+
}
|
|
132
|
+
return true;
|
|
133
|
+
});
|
|
134
|
+
if (validTools.length === 0) {
|
|
135
|
+
console.warn("No valid tools found for cache control");
|
|
136
|
+
return [];
|
|
137
|
+
}
|
|
138
|
+
// Create a copy of the valid tools array
|
|
139
|
+
const result = validTools.map((tool) => ({
|
|
140
|
+
...tool,
|
|
141
|
+
}));
|
|
142
|
+
// Add cache control to the last tool only
|
|
143
|
+
const lastIndex = result.length - 1;
|
|
144
|
+
result[lastIndex] = {
|
|
145
|
+
...result[lastIndex],
|
|
146
|
+
cache_control: { type: "ephemeral" },
|
|
147
|
+
};
|
|
148
|
+
return result;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Transforms messages for Claude cache control
|
|
152
|
+
* @param messages - Original OpenAI message array
|
|
153
|
+
* @param modelName - Model name for cache detection
|
|
154
|
+
* @param config - Cache control configuration
|
|
155
|
+
* @returns Messages with cache control markers applied
|
|
156
|
+
*/
|
|
157
|
+
export function transformMessagesForClaudeCache(messages, modelName, config = DEFAULT_CACHE_CONTROL_CONFIG) {
|
|
158
|
+
// Validate inputs
|
|
159
|
+
if (!messages || !Array.isArray(messages)) {
|
|
160
|
+
console.warn("Invalid messages array provided to transformMessagesForClaudeCache");
|
|
161
|
+
return [];
|
|
162
|
+
}
|
|
163
|
+
if (messages.length === 0) {
|
|
164
|
+
return [];
|
|
165
|
+
}
|
|
166
|
+
// Only apply cache control for Claude models
|
|
167
|
+
if (!isClaudeModel(modelName)) {
|
|
168
|
+
return messages;
|
|
169
|
+
}
|
|
170
|
+
// Validate config
|
|
171
|
+
if (!config || typeof config !== "object") {
|
|
172
|
+
console.warn("Invalid cache control config, using defaults");
|
|
173
|
+
config = DEFAULT_CACHE_CONTROL_CONFIG;
|
|
174
|
+
}
|
|
175
|
+
const result = messages.map((message, index) => {
|
|
176
|
+
// Validate message structure
|
|
177
|
+
if (!message || typeof message !== "object" || !message.role) {
|
|
178
|
+
console.warn("Invalid message structure at index", index, ":", message);
|
|
179
|
+
return message; // Return as-is to avoid breaking the flow
|
|
180
|
+
}
|
|
181
|
+
// System message: cache if enabled in config
|
|
182
|
+
if (message.role === "system" && config.cacheSystemMessage) {
|
|
183
|
+
return {
|
|
184
|
+
...message,
|
|
185
|
+
content: addCacheControlToContent(message.content, true),
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
// User messages: cache last N messages based on config
|
|
189
|
+
if (message.role === "user" && config.cacheUserMessageCount > 0) {
|
|
190
|
+
const userMessageIndices = [];
|
|
191
|
+
messages.forEach((msg, idx) => {
|
|
192
|
+
if (msg.role === "user") {
|
|
193
|
+
userMessageIndices.push(idx);
|
|
194
|
+
}
|
|
195
|
+
});
|
|
196
|
+
// Check if this user message is among the last N
|
|
197
|
+
const isRecentUser = userMessageIndices
|
|
198
|
+
.slice(-config.cacheUserMessageCount)
|
|
199
|
+
.includes(index);
|
|
200
|
+
if (isRecentUser) {
|
|
201
|
+
return {
|
|
202
|
+
...message,
|
|
203
|
+
content: addCacheControlToContent(message.content, true),
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
// Return message unchanged
|
|
208
|
+
return message;
|
|
209
|
+
});
|
|
210
|
+
return result;
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Extends standard usage with cache metrics
|
|
214
|
+
* @param standardUsage - OpenAI usage response
|
|
215
|
+
* @param cacheMetrics - Additional cache metrics from Claude
|
|
216
|
+
* @returns Extended usage with cache information
|
|
217
|
+
*/
|
|
218
|
+
export function extendUsageWithCacheMetrics(standardUsage, cacheMetrics) {
|
|
219
|
+
const baseUsage = {
|
|
220
|
+
prompt_tokens: standardUsage.prompt_tokens,
|
|
221
|
+
completion_tokens: standardUsage.completion_tokens,
|
|
222
|
+
total_tokens: standardUsage.total_tokens,
|
|
223
|
+
};
|
|
224
|
+
// Add cache metrics if provided
|
|
225
|
+
if (cacheMetrics) {
|
|
226
|
+
if (typeof cacheMetrics.cache_read_input_tokens === "number") {
|
|
227
|
+
baseUsage.cache_read_input_tokens = cacheMetrics.cache_read_input_tokens;
|
|
228
|
+
}
|
|
229
|
+
if (typeof cacheMetrics.cache_creation_input_tokens === "number") {
|
|
230
|
+
baseUsage.cache_creation_input_tokens =
|
|
231
|
+
cacheMetrics.cache_creation_input_tokens;
|
|
232
|
+
}
|
|
233
|
+
if (cacheMetrics.cache_creation &&
|
|
234
|
+
typeof cacheMetrics.cache_creation.ephemeral_5m_input_tokens ===
|
|
235
|
+
"number" &&
|
|
236
|
+
typeof cacheMetrics.cache_creation.ephemeral_1h_input_tokens === "number") {
|
|
237
|
+
baseUsage.cache_creation = {
|
|
238
|
+
ephemeral_5m_input_tokens: cacheMetrics.cache_creation.ephemeral_5m_input_tokens,
|
|
239
|
+
ephemeral_1h_input_tokens: cacheMetrics.cache_creation.ephemeral_1h_input_tokens,
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
return baseUsage;
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Validates Claude usage structure
|
|
247
|
+
* @param usage - Usage object to validate
|
|
248
|
+
* @returns True if usage structure is valid
|
|
249
|
+
*/
|
|
250
|
+
export function isValidClaudeUsage(usage) {
|
|
251
|
+
if (!usage || typeof usage !== "object") {
|
|
252
|
+
return false;
|
|
253
|
+
}
|
|
254
|
+
const usageObj = usage;
|
|
255
|
+
// Check required standard fields
|
|
256
|
+
const hasStandardFields = typeof usageObj.prompt_tokens === "number" &&
|
|
257
|
+
typeof usageObj.completion_tokens === "number" &&
|
|
258
|
+
typeof usageObj.total_tokens === "number";
|
|
259
|
+
if (!hasStandardFields) {
|
|
260
|
+
return false;
|
|
261
|
+
}
|
|
262
|
+
// Check optional cache fields
|
|
263
|
+
const hasCacheFields = (usageObj.cache_read_input_tokens === undefined ||
|
|
264
|
+
typeof usageObj.cache_read_input_tokens === "number") &&
|
|
265
|
+
(usageObj.cache_creation_input_tokens === undefined ||
|
|
266
|
+
typeof usageObj.cache_creation_input_tokens === "number");
|
|
267
|
+
if (!hasCacheFields) {
|
|
268
|
+
return false;
|
|
269
|
+
}
|
|
270
|
+
// Check cache_creation object if present
|
|
271
|
+
if (usageObj.cache_creation !== undefined) {
|
|
272
|
+
const cacheCreation = usageObj.cache_creation;
|
|
273
|
+
if (typeof cacheCreation !== "object" ||
|
|
274
|
+
typeof cacheCreation.ephemeral_5m_input_tokens !== "number" ||
|
|
275
|
+
typeof cacheCreation.ephemeral_1h_input_tokens !== "number") {
|
|
276
|
+
return false;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
return true;
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Adds cache control to the last N user messages in a conversation
|
|
283
|
+
* This optimizes multi-turn conversations by caching recent user context
|
|
284
|
+
*
|
|
285
|
+
* @param messages - Array of chat completion messages
|
|
286
|
+
* @param maxUserMessagesToCache - Maximum number of recent user messages to cache (default: 2)
|
|
287
|
+
* @returns Modified messages array with cache control on recent user messages
|
|
288
|
+
*/
|
|
289
|
+
export function addCacheControlToRecentUserMessages(messages, maxUserMessagesToCache = 2) {
|
|
290
|
+
// Validate inputs
|
|
291
|
+
if (!messages || !Array.isArray(messages)) {
|
|
292
|
+
console.warn("Invalid messages array provided to addCacheControlToRecentUserMessages");
|
|
293
|
+
return [];
|
|
294
|
+
}
|
|
295
|
+
if (messages.length === 0 || maxUserMessagesToCache <= 0) {
|
|
296
|
+
return messages;
|
|
297
|
+
}
|
|
298
|
+
// Validate maxUserMessagesToCache is a reasonable number
|
|
299
|
+
if (maxUserMessagesToCache > 100) {
|
|
300
|
+
console.warn("maxUserMessagesToCache is unusually high:", maxUserMessagesToCache, "limiting to 100");
|
|
301
|
+
maxUserMessagesToCache = 100;
|
|
302
|
+
}
|
|
303
|
+
// Find all user message indices in reverse order (most recent first)
|
|
304
|
+
const userMessageIndices = [];
|
|
305
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
306
|
+
const message = messages[i];
|
|
307
|
+
// Validate message structure
|
|
308
|
+
if (!message || typeof message !== "object" || !message.role) {
|
|
309
|
+
console.warn("Invalid message at index", i, ", skipping");
|
|
310
|
+
continue;
|
|
311
|
+
}
|
|
312
|
+
if (message.role === "user") {
|
|
313
|
+
userMessageIndices.push(i);
|
|
314
|
+
if (userMessageIndices.length >= maxUserMessagesToCache) {
|
|
315
|
+
break;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
// If no user messages found, return unchanged
|
|
320
|
+
if (userMessageIndices.length === 0) {
|
|
321
|
+
return messages;
|
|
322
|
+
}
|
|
323
|
+
// Create a copy of messages and modify the identified user messages
|
|
324
|
+
const modifiedMessages = [...messages];
|
|
325
|
+
for (const index of userMessageIndices) {
|
|
326
|
+
const message = modifiedMessages[index];
|
|
327
|
+
if (message.role === "user" && message.content != null) {
|
|
328
|
+
try {
|
|
329
|
+
modifiedMessages[index] = {
|
|
330
|
+
...message,
|
|
331
|
+
content: addCacheControlToContent(message.content, true),
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
catch (error) {
|
|
335
|
+
console.warn("Failed to add cache control to user message at index", index, ":", error);
|
|
336
|
+
// Continue with original message if transformation fails
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
return modifiedMessages;
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Helper function to identify user message indices that should be cached
|
|
344
|
+
* Used for testing and validation purposes
|
|
345
|
+
*
|
|
346
|
+
* @param messages - Array of chat completion messages
|
|
347
|
+
* @param maxUserMessagesToCache - Maximum number of recent user messages to identify
|
|
348
|
+
* @returns Array of indices for user messages that should be cached
|
|
349
|
+
*/
|
|
350
|
+
export function findRecentUserMessageIndices(messages, maxUserMessagesToCache = 2) {
|
|
351
|
+
if (!Array.isArray(messages) ||
|
|
352
|
+
messages.length === 0 ||
|
|
353
|
+
maxUserMessagesToCache <= 0) {
|
|
354
|
+
return [];
|
|
355
|
+
}
|
|
356
|
+
const userMessageIndices = [];
|
|
357
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
358
|
+
if (messages[i].role === "user") {
|
|
359
|
+
userMessageIndices.push(i);
|
|
360
|
+
if (userMessageIndices.length >= maxUserMessagesToCache) {
|
|
361
|
+
break;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
// Return indices in original order (not reversed)
|
|
366
|
+
return userMessageIndices.reverse();
|
|
367
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Command path resolver utilities for nested command discovery
|
|
3
|
+
* Handles conversion between file paths and command IDs with colon syntax
|
|
4
|
+
*/
|
|
5
|
+
export interface CommandIdParts {
|
|
6
|
+
namespace?: string;
|
|
7
|
+
commandName: string;
|
|
8
|
+
isNested: boolean;
|
|
9
|
+
depth: number;
|
|
10
|
+
segments: string[];
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Generate command ID from file path
|
|
14
|
+
* @param filePath - Absolute path to markdown file
|
|
15
|
+
* @param rootDir - Root commands directory path
|
|
16
|
+
* @returns Command identifier string (e.g., "openspec:apply")
|
|
17
|
+
* @throws Error on invalid path structure
|
|
18
|
+
*/
|
|
19
|
+
export declare function generateCommandId(filePath: string, rootDir: string): string;
|
|
20
|
+
/**
|
|
21
|
+
* Parse command ID into components
|
|
22
|
+
* @param commandId - Command identifier (e.g., "openspec:apply")
|
|
23
|
+
* @returns Object with namespace and command name
|
|
24
|
+
* @throws Error on malformed command ID
|
|
25
|
+
*/
|
|
26
|
+
export declare function parseCommandId(commandId: string): CommandIdParts;
|
|
27
|
+
/**
|
|
28
|
+
* Validate command ID format
|
|
29
|
+
* @param commandId - Command identifier to validate
|
|
30
|
+
* @returns Boolean indicating validity
|
|
31
|
+
*/
|
|
32
|
+
export declare function validateCommandId(commandId: string): boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Convert file path to command segments array
|
|
35
|
+
* @param filePath - Absolute path to markdown file
|
|
36
|
+
* @param rootDir - Root commands directory path
|
|
37
|
+
* @returns Array of path segments
|
|
38
|
+
*/
|
|
39
|
+
export declare function getCommandSegments(filePath: string, rootDir: string): string[];
|
|
40
|
+
/**
|
|
41
|
+
* Get namespace from command segments
|
|
42
|
+
* @param segments - Command path segments
|
|
43
|
+
* @returns Namespace string or undefined for flat commands
|
|
44
|
+
*/
|
|
45
|
+
export declare function getNamespace(segments: string[]): string | undefined;
|
|
46
|
+
/**
|
|
47
|
+
* Get command depth from segments
|
|
48
|
+
* @param segments - Command path segments
|
|
49
|
+
* @returns Depth number (0 for root, 1 for nested)
|
|
50
|
+
*/
|
|
51
|
+
export declare function getDepth(segments: string[]): number;
|
|
52
|
+
//# sourceMappingURL=commandPathResolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commandPathResolver.d.ts","sourceRoot":"","sources":["../../src/utils/commandPathResolver.ts"],"names":[],"mappings":"AAEA;;;GAGG;AAEH,MAAM,WAAW,cAAc;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAmD3E;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc,CAyChE;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAU5D;AAaD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,GACd,MAAM,EAAE,CASV;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,SAAS,CAEnE;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,CAEnD"}
|