claude-code-workflow 6.2.7 → 6.3.0
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/.claude/CLAUDE.md +16 -1
- package/.claude/workflows/cli-templates/protocols/analysis-protocol.md +11 -4
- package/.claude/workflows/cli-templates/protocols/write-protocol.md +10 -75
- package/.claude/workflows/cli-tools-usage.md +14 -24
- package/.codex/AGENTS.md +51 -1
- package/.codex/prompts/compact.md +378 -0
- package/.gemini/GEMINI.md +57 -20
- package/ccw/dist/cli.d.ts.map +1 -1
- package/ccw/dist/cli.js +21 -8
- package/ccw/dist/cli.js.map +1 -1
- package/ccw/dist/commands/cli.d.ts +2 -0
- package/ccw/dist/commands/cli.d.ts.map +1 -1
- package/ccw/dist/commands/cli.js +129 -8
- package/ccw/dist/commands/cli.js.map +1 -1
- package/ccw/dist/commands/hook.d.ts.map +1 -1
- package/ccw/dist/commands/hook.js +3 -2
- package/ccw/dist/commands/hook.js.map +1 -1
- package/ccw/dist/config/litellm-api-config-manager.d.ts +180 -0
- package/ccw/dist/config/litellm-api-config-manager.d.ts.map +1 -0
- package/ccw/dist/config/litellm-api-config-manager.js +770 -0
- package/ccw/dist/config/litellm-api-config-manager.js.map +1 -0
- package/ccw/dist/config/provider-models.d.ts +73 -0
- package/ccw/dist/config/provider-models.d.ts.map +1 -0
- package/ccw/dist/config/provider-models.js +172 -0
- package/ccw/dist/config/provider-models.js.map +1 -0
- package/ccw/dist/core/cache-manager.d.ts.map +1 -1
- package/ccw/dist/core/cache-manager.js +3 -5
- package/ccw/dist/core/cache-manager.js.map +1 -1
- package/ccw/dist/core/dashboard-generator.d.ts.map +1 -1
- package/ccw/dist/core/dashboard-generator.js +3 -1
- package/ccw/dist/core/dashboard-generator.js.map +1 -1
- package/ccw/dist/core/routes/cli-routes.d.ts.map +1 -1
- package/ccw/dist/core/routes/cli-routes.js +169 -0
- package/ccw/dist/core/routes/cli-routes.js.map +1 -1
- package/ccw/dist/core/routes/codexlens-routes.d.ts.map +1 -1
- package/ccw/dist/core/routes/codexlens-routes.js +234 -18
- package/ccw/dist/core/routes/codexlens-routes.js.map +1 -1
- package/ccw/dist/core/routes/hooks-routes.d.ts.map +1 -1
- package/ccw/dist/core/routes/hooks-routes.js +30 -32
- package/ccw/dist/core/routes/hooks-routes.js.map +1 -1
- package/ccw/dist/core/routes/litellm-api-routes.d.ts +21 -0
- package/ccw/dist/core/routes/litellm-api-routes.d.ts.map +1 -0
- package/ccw/dist/core/routes/litellm-api-routes.js +780 -0
- package/ccw/dist/core/routes/litellm-api-routes.js.map +1 -0
- package/ccw/dist/core/routes/litellm-routes.d.ts +20 -0
- package/ccw/dist/core/routes/litellm-routes.d.ts.map +1 -0
- package/ccw/dist/core/routes/litellm-routes.js +85 -0
- package/ccw/dist/core/routes/litellm-routes.js.map +1 -0
- package/ccw/dist/core/routes/mcp-routes.js +2 -2
- package/ccw/dist/core/routes/mcp-routes.js.map +1 -1
- package/ccw/dist/core/routes/status-routes.d.ts.map +1 -1
- package/ccw/dist/core/routes/status-routes.js +39 -0
- package/ccw/dist/core/routes/status-routes.js.map +1 -1
- package/ccw/dist/core/routes/system-routes.js +1 -1
- package/ccw/dist/core/routes/system-routes.js.map +1 -1
- package/ccw/dist/core/server.d.ts.map +1 -1
- package/ccw/dist/core/server.js +15 -1
- package/ccw/dist/core/server.js.map +1 -1
- package/ccw/dist/mcp-server/index.js +1 -1
- package/ccw/dist/mcp-server/index.js.map +1 -1
- package/ccw/dist/tools/claude-cli-tools.d.ts +82 -0
- package/ccw/dist/tools/claude-cli-tools.d.ts.map +1 -0
- package/ccw/dist/tools/claude-cli-tools.js +216 -0
- package/ccw/dist/tools/claude-cli-tools.js.map +1 -0
- package/ccw/dist/tools/cli-executor.d.ts.map +1 -1
- package/ccw/dist/tools/cli-executor.js +76 -14
- package/ccw/dist/tools/cli-executor.js.map +1 -1
- package/ccw/dist/tools/codex-lens.d.ts +9 -2
- package/ccw/dist/tools/codex-lens.d.ts.map +1 -1
- package/ccw/dist/tools/codex-lens.js +114 -9
- package/ccw/dist/tools/codex-lens.js.map +1 -1
- package/ccw/dist/tools/context-cache-store.d.ts +136 -0
- package/ccw/dist/tools/context-cache-store.d.ts.map +1 -0
- package/ccw/dist/tools/context-cache-store.js +256 -0
- package/ccw/dist/tools/context-cache-store.js.map +1 -0
- package/ccw/dist/tools/context-cache.d.ts +56 -0
- package/ccw/dist/tools/context-cache.d.ts.map +1 -0
- package/ccw/dist/tools/context-cache.js +294 -0
- package/ccw/dist/tools/context-cache.js.map +1 -0
- package/ccw/dist/tools/core-memory.d.ts.map +1 -1
- package/ccw/dist/tools/core-memory.js +33 -19
- package/ccw/dist/tools/core-memory.js.map +1 -1
- package/ccw/dist/tools/index.d.ts.map +1 -1
- package/ccw/dist/tools/index.js +2 -0
- package/ccw/dist/tools/index.js.map +1 -1
- package/ccw/dist/tools/litellm-client.d.ts +85 -0
- package/ccw/dist/tools/litellm-client.d.ts.map +1 -0
- package/ccw/dist/tools/litellm-client.js +188 -0
- package/ccw/dist/tools/litellm-client.js.map +1 -0
- package/ccw/dist/tools/litellm-executor.d.ts +34 -0
- package/ccw/dist/tools/litellm-executor.d.ts.map +1 -0
- package/ccw/dist/tools/litellm-executor.js +192 -0
- package/ccw/dist/tools/litellm-executor.js.map +1 -0
- package/ccw/dist/tools/pattern-parser.d.ts +55 -0
- package/ccw/dist/tools/pattern-parser.d.ts.map +1 -0
- package/ccw/dist/tools/pattern-parser.js +237 -0
- package/ccw/dist/tools/pattern-parser.js.map +1 -0
- package/ccw/dist/tools/smart-search.d.ts +1 -0
- package/ccw/dist/tools/smart-search.d.ts.map +1 -1
- package/ccw/dist/tools/smart-search.js +117 -41
- package/ccw/dist/tools/smart-search.js.map +1 -1
- package/ccw/dist/types/litellm-api-config.d.ts +294 -0
- package/ccw/dist/types/litellm-api-config.d.ts.map +1 -0
- package/ccw/dist/types/litellm-api-config.js +8 -0
- package/ccw/dist/types/litellm-api-config.js.map +1 -0
- package/ccw/src/cli.ts +258 -244
- package/ccw/src/commands/cli.ts +153 -9
- package/ccw/src/commands/hook.ts +3 -2
- package/ccw/src/config/.litellm-api-config-manager.ts.2025-12-23T11-57-43-727Z.bak +441 -0
- package/ccw/src/config/litellm-api-config-manager.ts +1012 -0
- package/ccw/src/config/provider-models.ts +222 -0
- package/ccw/src/core/cache-manager.ts +292 -294
- package/ccw/src/core/dashboard-generator.ts +3 -1
- package/ccw/src/core/routes/cli-routes.ts +192 -0
- package/ccw/src/core/routes/codexlens-routes.ts +241 -19
- package/ccw/src/core/routes/hooks-routes.ts +399 -405
- package/ccw/src/core/routes/litellm-api-routes.ts +930 -0
- package/ccw/src/core/routes/litellm-routes.ts +107 -0
- package/ccw/src/core/routes/mcp-routes.ts +1271 -1271
- package/ccw/src/core/routes/status-routes.ts +51 -0
- package/ccw/src/core/routes/system-routes.ts +1 -1
- package/ccw/src/core/server.ts +15 -1
- package/ccw/src/mcp-server/index.ts +1 -1
- package/ccw/src/templates/dashboard-css/12-cli-legacy.css +44 -0
- package/ccw/src/templates/dashboard-css/31-api-settings.css +2265 -0
- package/ccw/src/templates/dashboard-js/components/cli-history.js +15 -8
- package/ccw/src/templates/dashboard-js/components/cli-status.js +323 -9
- package/ccw/src/templates/dashboard-js/components/navigation.js +329 -313
- package/ccw/src/templates/dashboard-js/i18n.js +583 -1
- package/ccw/src/templates/dashboard-js/views/api-settings.js +3362 -0
- package/ccw/src/templates/dashboard-js/views/cli-manager.js +199 -24
- package/ccw/src/templates/dashboard-js/views/codexlens-manager.js +1265 -27
- package/ccw/src/templates/dashboard.html +840 -831
- package/ccw/src/tools/claude-cli-tools.ts +300 -0
- package/ccw/src/tools/cli-executor.ts +83 -14
- package/ccw/src/tools/codex-lens.ts +146 -9
- package/ccw/src/tools/context-cache-store.ts +368 -0
- package/ccw/src/tools/context-cache.ts +393 -0
- package/ccw/src/tools/core-memory.ts +33 -19
- package/ccw/src/tools/index.ts +2 -0
- package/ccw/src/tools/litellm-client.ts +246 -0
- package/ccw/src/tools/litellm-executor.ts +241 -0
- package/ccw/src/tools/pattern-parser.ts +329 -0
- package/ccw/src/tools/smart-search.ts +142 -41
- package/ccw/src/types/litellm-api-config.ts +402 -0
- package/ccw-litellm/README.md +180 -0
- package/ccw-litellm/pyproject.toml +35 -0
- package/ccw-litellm/src/ccw_litellm/__init__.py +47 -0
- package/ccw-litellm/src/ccw_litellm/__pycache__/__init__.cpython-313.pyc +0 -0
- package/ccw-litellm/src/ccw_litellm/__pycache__/cli.cpython-313.pyc +0 -0
- package/ccw-litellm/src/ccw_litellm/cli.py +108 -0
- package/ccw-litellm/src/ccw_litellm/clients/__init__.py +12 -0
- package/ccw-litellm/src/ccw_litellm/clients/__pycache__/__init__.cpython-313.pyc +0 -0
- package/ccw-litellm/src/ccw_litellm/clients/__pycache__/litellm_embedder.cpython-313.pyc +0 -0
- package/ccw-litellm/src/ccw_litellm/clients/__pycache__/litellm_llm.cpython-313.pyc +0 -0
- package/ccw-litellm/src/ccw_litellm/clients/litellm_embedder.py +251 -0
- package/ccw-litellm/src/ccw_litellm/clients/litellm_llm.py +165 -0
- package/ccw-litellm/src/ccw_litellm/config/__init__.py +22 -0
- package/ccw-litellm/src/ccw_litellm/config/__pycache__/__init__.cpython-313.pyc +0 -0
- package/ccw-litellm/src/ccw_litellm/config/__pycache__/loader.cpython-313.pyc +0 -0
- package/ccw-litellm/src/ccw_litellm/config/__pycache__/models.cpython-313.pyc +0 -0
- package/ccw-litellm/src/ccw_litellm/config/loader.py +316 -0
- package/ccw-litellm/src/ccw_litellm/config/models.py +130 -0
- package/ccw-litellm/src/ccw_litellm/interfaces/__init__.py +14 -0
- package/ccw-litellm/src/ccw_litellm/interfaces/__pycache__/__init__.cpython-313.pyc +0 -0
- package/ccw-litellm/src/ccw_litellm/interfaces/__pycache__/embedder.cpython-313.pyc +0 -0
- package/ccw-litellm/src/ccw_litellm/interfaces/__pycache__/llm.cpython-313.pyc +0 -0
- package/ccw-litellm/src/ccw_litellm/interfaces/embedder.py +52 -0
- package/ccw-litellm/src/ccw_litellm/interfaces/llm.py +45 -0
- package/codex-lens/src/codexlens/__pycache__/config.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/cli/__pycache__/commands.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/cli/__pycache__/embedding_manager.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/cli/__pycache__/model_manager.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/cli/__pycache__/output.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/cli/commands.py +378 -23
- package/codex-lens/src/codexlens/cli/embedding_manager.py +660 -56
- package/codex-lens/src/codexlens/cli/model_manager.py +31 -18
- package/codex-lens/src/codexlens/cli/output.py +12 -1
- package/codex-lens/src/codexlens/config.py +93 -0
- package/codex-lens/src/codexlens/search/__pycache__/chain_search.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/search/__pycache__/hybrid_search.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/search/__pycache__/ranking.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/search/chain_search.py +6 -2
- package/codex-lens/src/codexlens/search/hybrid_search.py +44 -21
- package/codex-lens/src/codexlens/search/ranking.py +1 -1
- package/codex-lens/src/codexlens/semantic/__init__.py +42 -0
- package/codex-lens/src/codexlens/semantic/__pycache__/__init__.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/__pycache__/base.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/__pycache__/chunker.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/__pycache__/embedder.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/__pycache__/factory.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/__pycache__/gpu_support.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/__pycache__/litellm_embedder.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/__pycache__/vector_store.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/semantic/base.py +61 -0
- package/codex-lens/src/codexlens/semantic/chunker.py +43 -20
- package/codex-lens/src/codexlens/semantic/embedder.py +60 -13
- package/codex-lens/src/codexlens/semantic/factory.py +98 -0
- package/codex-lens/src/codexlens/semantic/gpu_support.py +225 -3
- package/codex-lens/src/codexlens/semantic/litellm_embedder.py +144 -0
- package/codex-lens/src/codexlens/semantic/rotational_embedder.py +434 -0
- package/codex-lens/src/codexlens/semantic/vector_store.py +33 -8
- package/codex-lens/src/codexlens/storage/__pycache__/path_mapper.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/storage/migrations/__pycache__/migration_004_dual_fts.cpython-313.pyc +0 -0
- package/codex-lens/src/codexlens/storage/path_mapper.py +27 -1
- package/package.json +15 -5
- package/.codex/prompts.zip +0 -0
- package/ccw/package.json +0 -65
|
@@ -0,0 +1,393 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Context Cache MCP Tool
|
|
3
|
+
* Pack files by @patterns, cache in memory, paginated read by session ID
|
|
4
|
+
*
|
|
5
|
+
* Operations:
|
|
6
|
+
* - pack: Parse @patterns and cache file contents
|
|
7
|
+
* - read: Paginated read from cache by session ID
|
|
8
|
+
* - status: Get cache/session status
|
|
9
|
+
* - release: Release session cache
|
|
10
|
+
* - cleanup: Cleanup expired caches
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { z } from 'zod';
|
|
14
|
+
import type { ToolSchema, ToolResult } from '../types/tool.js';
|
|
15
|
+
import { parseAndPack } from './pattern-parser.js';
|
|
16
|
+
import {
|
|
17
|
+
getContextCacheStore,
|
|
18
|
+
type CacheMetadata,
|
|
19
|
+
type PagedReadResult,
|
|
20
|
+
type CacheStatus,
|
|
21
|
+
type SessionStatus,
|
|
22
|
+
} from './context-cache-store.js';
|
|
23
|
+
|
|
24
|
+
// Zod schema for parameter validation
|
|
25
|
+
const OperationEnum = z.enum(['pack', 'read', 'status', 'release', 'cleanup']);
|
|
26
|
+
|
|
27
|
+
const ParamsSchema = z.object({
|
|
28
|
+
operation: OperationEnum,
|
|
29
|
+
// Pack parameters
|
|
30
|
+
patterns: z.array(z.string()).optional(),
|
|
31
|
+
content: z.string().optional(), // Direct text content to cache
|
|
32
|
+
session_id: z.string().optional(),
|
|
33
|
+
cwd: z.string().optional(),
|
|
34
|
+
include_dirs: z.array(z.string()).optional(),
|
|
35
|
+
ttl: z.number().optional(),
|
|
36
|
+
include_metadata: z.boolean().optional().default(true),
|
|
37
|
+
max_file_size: z.number().optional(),
|
|
38
|
+
// Read parameters
|
|
39
|
+
offset: z.number().optional().default(0),
|
|
40
|
+
limit: z.number().optional().default(65536), // 64KB default
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
type Params = z.infer<typeof ParamsSchema>;
|
|
44
|
+
|
|
45
|
+
// Result types
|
|
46
|
+
interface PackResult {
|
|
47
|
+
operation: 'pack';
|
|
48
|
+
session_id: string;
|
|
49
|
+
files_packed: number;
|
|
50
|
+
files_skipped: number;
|
|
51
|
+
total_bytes: number;
|
|
52
|
+
patterns_matched: number;
|
|
53
|
+
patterns_failed: number;
|
|
54
|
+
expires_at: string;
|
|
55
|
+
errors?: string[];
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
interface ReadResult {
|
|
59
|
+
operation: 'read';
|
|
60
|
+
session_id: string;
|
|
61
|
+
content: string;
|
|
62
|
+
offset: number;
|
|
63
|
+
limit: number;
|
|
64
|
+
total_bytes: number;
|
|
65
|
+
has_more: boolean;
|
|
66
|
+
next_offset: number | null;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
interface StatusResult {
|
|
70
|
+
operation: 'status';
|
|
71
|
+
session_id?: string;
|
|
72
|
+
session?: SessionStatus;
|
|
73
|
+
cache?: CacheStatus;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
interface ReleaseResult {
|
|
77
|
+
operation: 'release';
|
|
78
|
+
session_id: string;
|
|
79
|
+
released: boolean;
|
|
80
|
+
freed_bytes: number;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
interface CleanupResult {
|
|
84
|
+
operation: 'cleanup';
|
|
85
|
+
removed: number;
|
|
86
|
+
remaining: number;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
type OperationResult = PackResult | ReadResult | StatusResult | ReleaseResult | CleanupResult;
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Generate session ID if not provided
|
|
93
|
+
*/
|
|
94
|
+
function generateSessionId(): string {
|
|
95
|
+
return `ctx-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Operation: pack
|
|
100
|
+
* Parse @patterns and/or cache text content directly
|
|
101
|
+
*/
|
|
102
|
+
async function executePack(params: Params): Promise<PackResult> {
|
|
103
|
+
const {
|
|
104
|
+
patterns,
|
|
105
|
+
content,
|
|
106
|
+
session_id,
|
|
107
|
+
cwd,
|
|
108
|
+
include_dirs,
|
|
109
|
+
ttl,
|
|
110
|
+
include_metadata,
|
|
111
|
+
max_file_size,
|
|
112
|
+
} = params;
|
|
113
|
+
|
|
114
|
+
// Require at least patterns or content
|
|
115
|
+
if ((!patterns || patterns.length === 0) && !content) {
|
|
116
|
+
throw new Error('Either "patterns" or "content" is required for pack operation');
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const sessionId = session_id || generateSessionId();
|
|
120
|
+
const store = getContextCacheStore();
|
|
121
|
+
|
|
122
|
+
let finalContent = '';
|
|
123
|
+
let filesPacked = 0;
|
|
124
|
+
let filesSkipped = 0;
|
|
125
|
+
let totalBytes = 0;
|
|
126
|
+
let patternsMatched = 0;
|
|
127
|
+
let patternsFailed = 0;
|
|
128
|
+
let errors: string[] = [];
|
|
129
|
+
let files: string[] = [];
|
|
130
|
+
let parsedPatterns: string[] = [];
|
|
131
|
+
|
|
132
|
+
// Pack files from patterns if provided
|
|
133
|
+
if (patterns && patterns.length > 0) {
|
|
134
|
+
const result = await parseAndPack(patterns, {
|
|
135
|
+
cwd: cwd || process.cwd(),
|
|
136
|
+
includeDirs: include_dirs,
|
|
137
|
+
includeMetadata: include_metadata,
|
|
138
|
+
maxFileSize: max_file_size,
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
finalContent = result.content;
|
|
142
|
+
filesPacked = result.packedFiles.length;
|
|
143
|
+
filesSkipped = result.skippedFiles.length;
|
|
144
|
+
totalBytes = result.totalBytes;
|
|
145
|
+
patternsMatched = result.parseResult.stats.matched_patterns;
|
|
146
|
+
patternsFailed = result.parseResult.stats.total_patterns - patternsMatched;
|
|
147
|
+
errors = result.parseResult.errors;
|
|
148
|
+
files = result.packedFiles;
|
|
149
|
+
parsedPatterns = result.parseResult.patterns;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Append direct content if provided
|
|
153
|
+
if (content) {
|
|
154
|
+
if (finalContent) {
|
|
155
|
+
finalContent += '\n\n=== ADDITIONAL CONTENT ===\n' + content;
|
|
156
|
+
} else {
|
|
157
|
+
finalContent = content;
|
|
158
|
+
}
|
|
159
|
+
totalBytes += Buffer.byteLength(content, 'utf-8');
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// Store in cache
|
|
163
|
+
const metadata: CacheMetadata = {
|
|
164
|
+
files,
|
|
165
|
+
patterns: parsedPatterns,
|
|
166
|
+
total_bytes: totalBytes,
|
|
167
|
+
file_count: filesPacked,
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
const entry = store.set(sessionId, finalContent, metadata, ttl);
|
|
171
|
+
const expiresAt = new Date(entry.created_at + entry.ttl).toISOString();
|
|
172
|
+
|
|
173
|
+
return {
|
|
174
|
+
operation: 'pack',
|
|
175
|
+
session_id: sessionId,
|
|
176
|
+
files_packed: filesPacked,
|
|
177
|
+
files_skipped: filesSkipped,
|
|
178
|
+
total_bytes: totalBytes,
|
|
179
|
+
patterns_matched: patternsMatched,
|
|
180
|
+
patterns_failed: patternsFailed,
|
|
181
|
+
expires_at: expiresAt,
|
|
182
|
+
errors: errors.length > 0 ? errors : undefined,
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Operation: read
|
|
188
|
+
* Paginated read from cache
|
|
189
|
+
*/
|
|
190
|
+
function executeRead(params: Params): ReadResult {
|
|
191
|
+
const { session_id, offset, limit } = params;
|
|
192
|
+
|
|
193
|
+
if (!session_id) {
|
|
194
|
+
throw new Error('Parameter "session_id" is required for read operation');
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
const store = getContextCacheStore();
|
|
198
|
+
const result = store.read(session_id, offset, limit);
|
|
199
|
+
|
|
200
|
+
if (!result) {
|
|
201
|
+
throw new Error(`Session "${session_id}" not found or expired`);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
return {
|
|
205
|
+
operation: 'read',
|
|
206
|
+
session_id,
|
|
207
|
+
content: result.content,
|
|
208
|
+
offset: result.offset,
|
|
209
|
+
limit: result.limit,
|
|
210
|
+
total_bytes: result.total_bytes,
|
|
211
|
+
has_more: result.has_more,
|
|
212
|
+
next_offset: result.next_offset,
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Operation: status
|
|
218
|
+
* Get session or overall cache status
|
|
219
|
+
*/
|
|
220
|
+
function executeStatus(params: Params): StatusResult {
|
|
221
|
+
const { session_id } = params;
|
|
222
|
+
const store = getContextCacheStore();
|
|
223
|
+
|
|
224
|
+
if (session_id) {
|
|
225
|
+
// Session-specific status
|
|
226
|
+
const sessionStatus = store.getSessionStatus(session_id);
|
|
227
|
+
return {
|
|
228
|
+
operation: 'status',
|
|
229
|
+
session_id,
|
|
230
|
+
session: sessionStatus,
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// Overall cache status
|
|
235
|
+
const cacheStatus = store.getStatus();
|
|
236
|
+
return {
|
|
237
|
+
operation: 'status',
|
|
238
|
+
cache: cacheStatus,
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Operation: release
|
|
244
|
+
* Release session cache
|
|
245
|
+
*/
|
|
246
|
+
function executeRelease(params: Params): ReleaseResult {
|
|
247
|
+
const { session_id } = params;
|
|
248
|
+
|
|
249
|
+
if (!session_id) {
|
|
250
|
+
throw new Error('Parameter "session_id" is required for release operation');
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
const store = getContextCacheStore();
|
|
254
|
+
const result = store.release(session_id);
|
|
255
|
+
|
|
256
|
+
return {
|
|
257
|
+
operation: 'release',
|
|
258
|
+
session_id,
|
|
259
|
+
released: result.released,
|
|
260
|
+
freed_bytes: result.freed_bytes,
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* Operation: cleanup
|
|
266
|
+
* Cleanup expired caches
|
|
267
|
+
*/
|
|
268
|
+
function executeCleanup(): CleanupResult {
|
|
269
|
+
const store = getContextCacheStore();
|
|
270
|
+
const result = store.cleanupExpired();
|
|
271
|
+
const status = store.getStatus();
|
|
272
|
+
|
|
273
|
+
return {
|
|
274
|
+
operation: 'cleanup',
|
|
275
|
+
removed: result.removed,
|
|
276
|
+
remaining: status.entries,
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* Route to operation handler
|
|
282
|
+
*/
|
|
283
|
+
async function execute(params: Params): Promise<OperationResult> {
|
|
284
|
+
const { operation } = params;
|
|
285
|
+
|
|
286
|
+
switch (operation) {
|
|
287
|
+
case 'pack':
|
|
288
|
+
return executePack(params);
|
|
289
|
+
case 'read':
|
|
290
|
+
return executeRead(params);
|
|
291
|
+
case 'status':
|
|
292
|
+
return executeStatus(params);
|
|
293
|
+
case 'release':
|
|
294
|
+
return executeRelease(params);
|
|
295
|
+
case 'cleanup':
|
|
296
|
+
return executeCleanup();
|
|
297
|
+
default:
|
|
298
|
+
throw new Error(
|
|
299
|
+
`Unknown operation: ${operation}. Valid operations: pack, read, status, release, cleanup`
|
|
300
|
+
);
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
// MCP Tool Schema
|
|
305
|
+
export const schema: ToolSchema = {
|
|
306
|
+
name: 'context_cache',
|
|
307
|
+
description: `Context file cache with @pattern and text content support, paginated reading.
|
|
308
|
+
|
|
309
|
+
Usage:
|
|
310
|
+
context_cache(operation="pack", patterns=["@src/**/*.ts"], session_id="...")
|
|
311
|
+
context_cache(operation="pack", content="text to cache", session_id="...")
|
|
312
|
+
context_cache(operation="pack", patterns=["@src/**/*.ts"], content="extra text")
|
|
313
|
+
context_cache(operation="read", session_id="...", offset=0, limit=65536)
|
|
314
|
+
context_cache(operation="status", session_id="...")
|
|
315
|
+
context_cache(operation="release", session_id="...")
|
|
316
|
+
context_cache(operation="cleanup")
|
|
317
|
+
|
|
318
|
+
Pattern syntax:
|
|
319
|
+
@src/**/*.ts - All TypeScript files in src
|
|
320
|
+
@CLAUDE.md - Specific file
|
|
321
|
+
@../shared/**/* - Sibling directory (needs include_dirs)`,
|
|
322
|
+
inputSchema: {
|
|
323
|
+
type: 'object',
|
|
324
|
+
properties: {
|
|
325
|
+
operation: {
|
|
326
|
+
type: 'string',
|
|
327
|
+
enum: ['pack', 'read', 'status', 'release', 'cleanup'],
|
|
328
|
+
description: 'Operation to perform',
|
|
329
|
+
},
|
|
330
|
+
patterns: {
|
|
331
|
+
type: 'array',
|
|
332
|
+
items: { type: 'string' },
|
|
333
|
+
description: '@patterns to pack (e.g., ["@src/**/*.ts"]). Either patterns or content required for pack.',
|
|
334
|
+
},
|
|
335
|
+
content: {
|
|
336
|
+
type: 'string',
|
|
337
|
+
description: 'Direct text content to cache. Either patterns or content required for pack.',
|
|
338
|
+
},
|
|
339
|
+
session_id: {
|
|
340
|
+
type: 'string',
|
|
341
|
+
description: 'Cache session ID. Auto-generated for pack if not provided.',
|
|
342
|
+
},
|
|
343
|
+
cwd: {
|
|
344
|
+
type: 'string',
|
|
345
|
+
description: 'Working directory for pattern resolution (default: process.cwd())',
|
|
346
|
+
},
|
|
347
|
+
include_dirs: {
|
|
348
|
+
type: 'array',
|
|
349
|
+
items: { type: 'string' },
|
|
350
|
+
description: 'Additional directories to include for pattern matching',
|
|
351
|
+
},
|
|
352
|
+
ttl: {
|
|
353
|
+
type: 'number',
|
|
354
|
+
description: 'Cache TTL in milliseconds (default: 1800000 = 30min)',
|
|
355
|
+
},
|
|
356
|
+
include_metadata: {
|
|
357
|
+
type: 'boolean',
|
|
358
|
+
description: 'Include file metadata headers in packed content (default: true)',
|
|
359
|
+
},
|
|
360
|
+
max_file_size: {
|
|
361
|
+
type: 'number',
|
|
362
|
+
description: 'Max file size in bytes to include (default: 1MB). Larger files are skipped.',
|
|
363
|
+
},
|
|
364
|
+
offset: {
|
|
365
|
+
type: 'number',
|
|
366
|
+
description: 'Byte offset for paginated read (default: 0)',
|
|
367
|
+
},
|
|
368
|
+
limit: {
|
|
369
|
+
type: 'number',
|
|
370
|
+
description: 'Max bytes to read (default: 65536 = 64KB)',
|
|
371
|
+
},
|
|
372
|
+
},
|
|
373
|
+
required: ['operation'],
|
|
374
|
+
},
|
|
375
|
+
};
|
|
376
|
+
|
|
377
|
+
// Handler function
|
|
378
|
+
export async function handler(
|
|
379
|
+
params: Record<string, unknown>
|
|
380
|
+
): Promise<ToolResult<OperationResult>> {
|
|
381
|
+
const parsed = ParamsSchema.safeParse(params);
|
|
382
|
+
|
|
383
|
+
if (!parsed.success) {
|
|
384
|
+
return { success: false, error: `Invalid params: ${parsed.error.message}` };
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
try {
|
|
388
|
+
const result = await execute(parsed.data);
|
|
389
|
+
return { success: true, result };
|
|
390
|
+
} catch (error) {
|
|
391
|
+
return { success: false, error: (error as Error).message };
|
|
392
|
+
}
|
|
393
|
+
}
|
|
@@ -16,6 +16,8 @@ const OperationEnum = z.enum(['list', 'import', 'export', 'summary', 'embed', 's
|
|
|
16
16
|
|
|
17
17
|
const ParamsSchema = z.object({
|
|
18
18
|
operation: OperationEnum,
|
|
19
|
+
// Path parameter - highest priority for project resolution
|
|
20
|
+
path: z.string().optional(),
|
|
19
21
|
text: z.string().optional(),
|
|
20
22
|
id: z.string().optional(),
|
|
21
23
|
tool: z.enum(['gemini', 'qwen']).optional().default('gemini'),
|
|
@@ -106,17 +108,21 @@ interface EmbedStatusResult {
|
|
|
106
108
|
type OperationResult = ListResult | ImportResult | ExportResult | SummaryResult | EmbedResult | SearchResult | EmbedStatusResult;
|
|
107
109
|
|
|
108
110
|
/**
|
|
109
|
-
* Get project path
|
|
111
|
+
* Get project path - uses explicit path if provided, otherwise falls back to current working directory
|
|
112
|
+
* Priority: path parameter > getProjectRoot()
|
|
110
113
|
*/
|
|
111
|
-
function getProjectPath(): string {
|
|
114
|
+
function getProjectPath(explicitPath?: string): string {
|
|
115
|
+
if (explicitPath) {
|
|
116
|
+
return explicitPath;
|
|
117
|
+
}
|
|
112
118
|
return getProjectRoot();
|
|
113
119
|
}
|
|
114
120
|
|
|
115
121
|
/**
|
|
116
|
-
* Get database path for
|
|
122
|
+
* Get database path for project
|
|
117
123
|
*/
|
|
118
|
-
function getDatabasePath(): string {
|
|
119
|
-
const projectPath = getProjectPath();
|
|
124
|
+
function getDatabasePath(explicitPath?: string): string {
|
|
125
|
+
const projectPath = getProjectPath(explicitPath);
|
|
120
126
|
const paths = StoragePaths.project(projectPath);
|
|
121
127
|
return join(paths.root, 'core-memory', 'core_memory.db');
|
|
122
128
|
}
|
|
@@ -129,8 +135,8 @@ const PREVIEW_MAX_LENGTH = 100;
|
|
|
129
135
|
* List all memories with compact output
|
|
130
136
|
*/
|
|
131
137
|
function executeList(params: Params): ListResult {
|
|
132
|
-
const { limit } = params;
|
|
133
|
-
const store = getCoreMemoryStore(getProjectPath());
|
|
138
|
+
const { limit, path } = params;
|
|
139
|
+
const store = getCoreMemoryStore(getProjectPath(path));
|
|
134
140
|
const memories = store.getMemories({ limit }) as CoreMemory[];
|
|
135
141
|
|
|
136
142
|
// Convert to compact format with truncated preview
|
|
@@ -160,13 +166,13 @@ function executeList(params: Params): ListResult {
|
|
|
160
166
|
* Import text as a new memory
|
|
161
167
|
*/
|
|
162
168
|
function executeImport(params: Params): ImportResult {
|
|
163
|
-
const { text } = params;
|
|
169
|
+
const { text, path } = params;
|
|
164
170
|
|
|
165
171
|
if (!text || text.trim() === '') {
|
|
166
172
|
throw new Error('Parameter "text" is required for import operation');
|
|
167
173
|
}
|
|
168
174
|
|
|
169
|
-
const store = getCoreMemoryStore(getProjectPath());
|
|
175
|
+
const store = getCoreMemoryStore(getProjectPath(path));
|
|
170
176
|
const memory = store.upsertMemory({
|
|
171
177
|
content: text.trim(),
|
|
172
178
|
});
|
|
@@ -184,14 +190,14 @@ function executeImport(params: Params): ImportResult {
|
|
|
184
190
|
* Searches current project first, then all projects if not found
|
|
185
191
|
*/
|
|
186
192
|
function executeExport(params: Params): ExportResult {
|
|
187
|
-
const { id } = params;
|
|
193
|
+
const { id, path } = params;
|
|
188
194
|
|
|
189
195
|
if (!id) {
|
|
190
196
|
throw new Error('Parameter "id" is required for export operation');
|
|
191
197
|
}
|
|
192
198
|
|
|
193
|
-
// Try current project first
|
|
194
|
-
const store = getCoreMemoryStore(getProjectPath());
|
|
199
|
+
// Try current project first (or explicit path if provided)
|
|
200
|
+
const store = getCoreMemoryStore(getProjectPath(path));
|
|
195
201
|
let memory = store.getMemory(id);
|
|
196
202
|
|
|
197
203
|
// If not found, search across all projects
|
|
@@ -218,13 +224,13 @@ function executeExport(params: Params): ExportResult {
|
|
|
218
224
|
* Generate AI summary for a memory
|
|
219
225
|
*/
|
|
220
226
|
async function executeSummary(params: Params): Promise<SummaryResult> {
|
|
221
|
-
const { id, tool = 'gemini' } = params;
|
|
227
|
+
const { id, tool = 'gemini', path } = params;
|
|
222
228
|
|
|
223
229
|
if (!id) {
|
|
224
230
|
throw new Error('Parameter "id" is required for summary operation');
|
|
225
231
|
}
|
|
226
232
|
|
|
227
|
-
const store = getCoreMemoryStore(getProjectPath());
|
|
233
|
+
const store = getCoreMemoryStore(getProjectPath(path));
|
|
228
234
|
const memory = store.getMemory(id);
|
|
229
235
|
|
|
230
236
|
if (!memory) {
|
|
@@ -245,8 +251,8 @@ async function executeSummary(params: Params): Promise<SummaryResult> {
|
|
|
245
251
|
* Generate embeddings for memory chunks
|
|
246
252
|
*/
|
|
247
253
|
async function executeEmbed(params: Params): Promise<EmbedResult> {
|
|
248
|
-
const { source_id, batch_size = 8, force = false } = params;
|
|
249
|
-
const dbPath = getDatabasePath();
|
|
254
|
+
const { source_id, batch_size = 8, force = false, path } = params;
|
|
255
|
+
const dbPath = getDatabasePath(path);
|
|
250
256
|
|
|
251
257
|
const result = await MemoryEmbedder.generateEmbeddings(dbPath, {
|
|
252
258
|
sourceId: source_id,
|
|
@@ -272,13 +278,13 @@ async function executeEmbed(params: Params): Promise<EmbedResult> {
|
|
|
272
278
|
* Search memory chunks using semantic search
|
|
273
279
|
*/
|
|
274
280
|
async function executeSearch(params: Params): Promise<SearchResult> {
|
|
275
|
-
const { query, top_k = 10, min_score = 0.3, source_type } = params;
|
|
281
|
+
const { query, top_k = 10, min_score = 0.3, source_type, path } = params;
|
|
276
282
|
|
|
277
283
|
if (!query) {
|
|
278
284
|
throw new Error('Parameter "query" is required for search operation');
|
|
279
285
|
}
|
|
280
286
|
|
|
281
|
-
const dbPath = getDatabasePath();
|
|
287
|
+
const dbPath = getDatabasePath(path);
|
|
282
288
|
|
|
283
289
|
const result = await MemoryEmbedder.searchMemories(dbPath, query, {
|
|
284
290
|
topK: top_k,
|
|
@@ -309,7 +315,8 @@ async function executeSearch(params: Params): Promise<SearchResult> {
|
|
|
309
315
|
* Get embedding status statistics
|
|
310
316
|
*/
|
|
311
317
|
async function executeEmbedStatus(params: Params): Promise<EmbedStatusResult> {
|
|
312
|
-
const
|
|
318
|
+
const { path } = params;
|
|
319
|
+
const dbPath = getDatabasePath(path);
|
|
313
320
|
|
|
314
321
|
const result = await MemoryEmbedder.getEmbeddingStatus(dbPath);
|
|
315
322
|
|
|
@@ -368,6 +375,9 @@ Usage:
|
|
|
368
375
|
core_memory(operation="search", query="authentication") # Search memories semantically
|
|
369
376
|
core_memory(operation="embed_status") # Check embedding status
|
|
370
377
|
|
|
378
|
+
Path parameter (highest priority):
|
|
379
|
+
core_memory(operation="list", path="/path/to/project") # Use specific project path
|
|
380
|
+
|
|
371
381
|
Memory IDs use format: CMEM-YYYYMMDD-HHMMSS`,
|
|
372
382
|
inputSchema: {
|
|
373
383
|
type: 'object',
|
|
@@ -377,6 +387,10 @@ Memory IDs use format: CMEM-YYYYMMDD-HHMMSS`,
|
|
|
377
387
|
enum: ['list', 'import', 'export', 'summary', 'embed', 'search', 'embed_status'],
|
|
378
388
|
description: 'Operation to perform',
|
|
379
389
|
},
|
|
390
|
+
path: {
|
|
391
|
+
type: 'string',
|
|
392
|
+
description: 'Project path (highest priority - overrides auto-detected project root)',
|
|
393
|
+
},
|
|
380
394
|
text: {
|
|
381
395
|
type: 'string',
|
|
382
396
|
description: 'Text content to import (required for import operation)',
|
package/ccw/src/tools/index.ts
CHANGED
|
@@ -22,6 +22,7 @@ import { executeInitWithProgress } from './smart-search.js';
|
|
|
22
22
|
// codex_lens removed - functionality integrated into smart_search
|
|
23
23
|
import * as readFileMod from './read-file.js';
|
|
24
24
|
import * as coreMemoryMod from './core-memory.js';
|
|
25
|
+
import * as contextCacheMod from './context-cache.js';
|
|
25
26
|
import type { ProgressInfo } from './codex-lens.js';
|
|
26
27
|
|
|
27
28
|
// Import legacy JS tools
|
|
@@ -357,6 +358,7 @@ registerTool(toLegacyTool(smartSearchMod));
|
|
|
357
358
|
// codex_lens removed - functionality integrated into smart_search
|
|
358
359
|
registerTool(toLegacyTool(readFileMod));
|
|
359
360
|
registerTool(toLegacyTool(coreMemoryMod));
|
|
361
|
+
registerTool(toLegacyTool(contextCacheMod));
|
|
360
362
|
|
|
361
363
|
// Register legacy JS tools
|
|
362
364
|
registerTool(uiGeneratePreviewTool);
|