ccjk 7.0.0 → 7.0.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.
@@ -1,135 +0,0 @@
1
- # Agent: Router
2
-
3
- > **Purpose**: Route research queries to appropriate information agents
4
- > **Key Feature**: Query classification + dispatch
5
-
6
- ## 🎯 What This Agent Does
7
-
8
- Analyzes the user's information needs and routes to the most appropriate specialized research agent (doc-researcher, mcp-researcher, version-checker, or npm-researcher).
9
-
10
- ## 📋 Query Classification
11
-
12
- ```typescript
13
- type ResearchQuery = {
14
- category: 'documentation' | 'mcp' | 'version' | 'package' | 'comparison'
15
- keywords: string[]
16
- agent: AgentType
17
- }
18
- ```
19
-
20
- ### Classification Rules
21
-
22
- **Documentation queries** → `doc-researcher`
23
- - "Latest Claude Code features"
24
- - "MCP specification"
25
- - "Claude Code API docs"
26
-
27
- **MCP server queries** → `mcp-researcher`
28
- - "@modelcontextprotocol/server-filesystem config"
29
- - "MCP servers for databases"
30
- - "How to install MCP server"
31
-
32
- **Version queries** → `version-checker`
33
- - "Latest ccjk version"
34
- - "CCR updates"
35
- - "CCUsage release notes"
36
-
37
- **NPM package queries** → `npm-researcher`
38
- - "vite package size"
39
- - "webpack vs vite"
40
- - "express dependencies"
41
-
42
- ## 🔍 Query Examples
43
-
44
- ```
45
- User: "How to configure filesystem MCP server"
46
-
47
- Router: Detect keywords ["MCP", "server", "filesystem", "config"]
48
-
49
- Classify: category = "mcp", agent = "mcp-researcher"
50
-
51
- Dispatch: mcp-researcher with query "filesystem MCP server configuration"
52
-
53
- Return: Server info + config template
54
- ```
55
-
56
- ## 🎯 Smart Routing
57
-
58
- ### Single Agent Routing
59
- ```typescript
60
- const routingMap = {
61
- 'documentation|Claude Code|MCP|docs': 'doc-researcher',
62
- 'MCP|server|@modelcontextprotocol|registry': 'mcp-researcher',
63
- 'version|update|release': 'version-checker',
64
- 'npm|package|bundle|bundlephobia': 'npm-researcher'
65
- }
66
-
67
- function routeQuery(query: string): string {
68
- for (const [pattern, agent] of Object.entries(routingMap)) {
69
- const regex = new RegExp(pattern, 'i')
70
- if (regex.test(query)) {
71
- return agent
72
- }
73
- }
74
- return 'npm-researcher' // Default
75
- }
76
- ```
77
-
78
- ### Multi-Agent Routing
79
- ```typescript
80
- // For complex queries, consult multiple agents
81
- const multiAgentQueries = [
82
- "How to use MCP server with express",
83
- "Vite vs webpack with latest features"
84
- ]
85
-
86
- function routeMultiAgent(query: string): AgentType[] {
87
- const agents: AgentType[] = []
88
-
89
- if (query.includes('MCP')) agents.push('mcp-researcher')
90
- if (query.includes('express')) agents.push('npm-researcher')
91
- if (query.includes('vite') || query.includes('webpack')) agents.push('npm-researcher')
92
-
93
- return agents
94
- }
95
- ```
96
-
97
- ## 📊 Agent Coordination
98
-
99
- ```typescript
100
- // Single agent query
101
- async function routeToAgent(query: string): Promise<Result> {
102
- const agent = routeQuery(query)
103
- return await executeAgent(agent, query)
104
- }
105
-
106
- // Multi-agent query (combine results)
107
- async function routeToAgents(query: string): Promise<CombinedResult> {
108
- const agents = routeMultiAgent(query)
109
- const results = await Promise.all(
110
- agents.map(agent => executeAgent(agent, query))
111
- )
112
-
113
- return combineResults(results)
114
- }
115
-
116
- function combineResults(results: AgentResult[]): CombinedResult {
117
- return {
118
- sources: results.map(r => r.source).join(', '),
119
- information: results.map(r => r.data).join('\n---\n'),
120
- confidence: Math.min(...results.map(r => r.confidence))
121
- }
122
- }
123
- ```
124
-
125
- ## 🔗 Related Agents
126
-
127
- - **doc-researcher**: Documentation queries
128
- - **mcp-researcher**: MCP server queries
129
- - **version-checker**: Version queries
130
- - **npm-researcher**: NPM package queries
131
-
132
- ## 📚 References
133
-
134
- - Agent implementation guide
135
- - Query classification patterns
@@ -1,6 +0,0 @@
1
- {
2
- "name": "ccjk-info-agents",
3
- "version": "1.0.0",
4
- "description": "Background agents for fetching real-time CCJK information",
5
- "agents": "./agents/"
6
- }
@@ -1,265 +0,0 @@
1
- /**
2
- * Cache Manager for CCJK Information Agents
3
- * Provides intelligent caching for doc-researcher, mcp-researcher, version-checker, npm-researcher
4
- */
5
-
6
- import { existsSync, mkdirSync, readdirSync, readFileSync, rmSync, statSync, writeFileSync } from 'node:fs'
7
- import { join } from 'node:path'
8
- import process from 'node:process'
9
-
10
- export interface CacheConfig {
11
- ttl: number
12
- maxSize?: number
13
- }
14
-
15
- export interface CacheEntry<T> {
16
- data: T
17
- timestamp: number
18
- source: string
19
- cached: boolean
20
- }
21
-
22
- export class CacheManager {
23
- private cacheDir: string
24
- private defaultTtl: number
25
- private maxSize: number
26
-
27
- constructor(options: {
28
- cacheDir: string
29
- defaultTtl?: number
30
- maxSize?: number
31
- } = {}) {
32
- this.cacheDir = options.cacheDir || join(process.env.HOME || '~', '.ccjk', 'cache')
33
- this.defaultTtl = options.defaultTtl || 24 * 60 * 60 * 1000 // 24 hours
34
- this.maxSize = options.maxSize || 100 * 1024 * 1024 // 100MB default
35
-
36
- this.ensureCacheDir()
37
- }
38
-
39
- /**
40
- * Ensure cache directory exists
41
- */
42
- private ensureCacheDir(): void {
43
- if (!existsSync(this.cacheDir)) {
44
- mkdirSync(this.cacheDir, { recursive: true })
45
- }
46
- }
47
-
48
- /**
49
- * Get cache path for key
50
- */
51
- private getCachePath(key: string): string {
52
- const sanitizedKey = key.replace(/[^\w-]/g, '_')
53
- return join(this.cacheDir, `${sanitizedKey}.json`)
54
- }
55
-
56
- /**
57
- * Get cache size
58
- */
59
- getCacheSize(): number {
60
- try {
61
- const files = this.getCacheFiles()
62
- return files.reduce((total, file) => {
63
- const path = join(this.cacheDir, file)
64
- const stats = statSync(path)
65
- return total + stats.size
66
- }, 0)
67
- }
68
- catch {
69
- return 0
70
- }
71
- }
72
-
73
- /**
74
- * Clean old cache entries
75
- */
76
- clean(): void {
77
- const files = this.getCacheFiles()
78
- let totalCleaned = 0
79
-
80
- for (const file of files) {
81
- try {
82
- const cachePath = join(this.cacheDir, file)
83
- const content = JSON.parse(readFileSync(cachePath, 'utf8'))
84
-
85
- const age = Date.now() - content.timestamp
86
- if (age > this.defaultTtl) {
87
- rmSync(cachePath)
88
- totalCleaned++
89
- }
90
- }
91
- catch {
92
- // Skip invalid cache files
93
- console.warn(`Invalid cache file: ${file}`)
94
- }
95
- }
96
-
97
- console.log(`✅ Cleaned ${totalCleaned} expired cache entries`)
98
- }
99
-
100
- /**
101
- * Get all cache files
102
- */
103
- private getCacheFiles(): string[] {
104
- try {
105
- return readdirSync(this.cacheDir).filter(f => f.endsWith('.json'))
106
- }
107
- catch {
108
- return []
109
- }
110
- }
111
-
112
- /**
113
- * Clear entire cache
114
- */
115
- clear(): void {
116
- const files = this.getCacheFiles()
117
- for (const file of files) {
118
- rmSync(join(this.cacheDir, file))
119
- }
120
- console.log(`✅ Cleared ${files.length} cache files`)
121
- }
122
-
123
- /**
124
- * Check if cache entry is valid (not expired)
125
- */
126
- private isValid(entry: { timestamp: number }, ttl?: number): boolean {
127
- const age = Date.now() - entry.timestamp
128
- return age < (ttl || this.defaultTtl)
129
- }
130
-
131
- /**
132
- * Get value from cache
133
- */
134
- get<T>(key: string, config?: { ttl?: number }): CacheEntry<T> | null {
135
- const cachePath = this.getCachePath(key)
136
-
137
- if (!existsSync(cachePath)) {
138
- return null
139
- }
140
-
141
- try {
142
- const content = readFileSync(cachePath, 'utf8')
143
- const entry = JSON.parse(content) as CacheEntry<T>
144
-
145
- if (this.isValid(entry, config?.ttl)) {
146
- return { ...entry, cached: true }
147
- }
148
- else {
149
- // Cache expired
150
- rmSync(cachePath)
151
- return null
152
- }
153
- }
154
- catch {
155
- // Invalid cache
156
- rmSync(cachePath)
157
- return null
158
- }
159
- }
160
-
161
- /**
162
- * Set value in cache
163
- */
164
- set<T>(key: string, data: T, options?: {
165
- ttl?: number
166
- source?: string
167
- }): void {
168
- const cachePath = this.getCachePath(key)
169
-
170
- const entry: CacheEntry<T> = {
171
- data,
172
- timestamp: Date.now(),
173
- source: options?.source || 'unknown',
174
- cached: false,
175
- }
176
-
177
- writeFileSync(cachePath, JSON.stringify(entry, null, 2))
178
- }
179
-
180
- /**
181
- * Get or fetch (with fallback)
182
- */
183
- async getOrFetch<T>(
184
- key: string,
185
- fetchFn: () => Promise<T>,
186
- options?: {
187
- ttl?: number
188
- source?: string
189
- },
190
- ): Promise<CacheEntry<T>> {
191
- // Try cache first
192
- const cached = this.get<T>(key, options)
193
- if (cached) {
194
- return cached
195
- }
196
-
197
- // Cache miss or expired - fetch fresh data
198
- try {
199
- const data = await fetchFn()
200
- this.set(key, data, options)
201
- return {
202
- data,
203
- timestamp: Date.now(),
204
- source: options?.source || 'fresh',
205
- cached: false,
206
- }
207
- }
208
- catch (error) {
209
- throw new Error(`Failed to fetch and cache data: ${error.message}`)
210
- }
211
- }
212
-
213
- /**
214
- * Get cache statistics
215
- */
216
- stats(): {
217
- totalEntries: number
218
- cacheSize: string
219
- latest: CacheEntry<any> | null
220
- oldest: CacheEntry<any> | null
221
- } {
222
- const files = this.getCacheFiles()
223
- const entries = files.map((file) => {
224
- try {
225
- const content = readFileSync(join(this.cacheDir, file), 'utf8')
226
- return JSON.parse(content)
227
- }
228
- catch {
229
- return null
230
- }
231
- }).filter(Boolean)
232
-
233
- const size = this.getCacheSize()
234
- const sorted = entries.sort((a, b) => a.timestamp - b.timestamp)
235
-
236
- return {
237
- totalEntries: entries.length,
238
- cacheSize: `${(size / 1024 / 1024).toFixed(2)} MB`,
239
- latest: sorted[sorted.length - 1] || null,
240
- oldest: sorted[0] || null,
241
- }
242
- }
243
- }
244
-
245
- // Agent-specific cache configurations
246
- export const AGENT_CACHE_CONFIG = {
247
- 'doc-researcher': {
248
- ttl: 72 * 60 * 60 * 1000, // 72 hours
249
- description: 'Documentation (stable, 3 days)',
250
- },
251
- 'mcp-researcher': {
252
- ttl: 24 * 60 * 60 * 1000, // 24 hours
253
- description: 'MCP servers (frequent updates, 1 day)',
254
- },
255
- 'version-checker': {
256
- ttl: 168 * 60 * 60 * 1000, // 168 hours (7 days)
257
- description: 'Versions (stable, 1 week)',
258
- },
259
- 'npm-researcher': {
260
- ttl: 24 * 60 * 60 * 1000, // 24 hours
261
- description: 'NPM packages (daily updates, 1 day)',
262
- },
263
- }
264
-
265
- export default CacheManager
@@ -1,202 +0,0 @@
1
- # Agent: Doc Researcher
2
-
3
- > **Purpose**: Fetch latest Claude Code documentation
4
- > **Data Source**: https://docs.anthropic.com
5
- > **Cache TTL**: 72 hours (3 days)
6
- > **Run Mode**: Background
7
-
8
- ## 🎯 What This Agent Does
9
-
10
- Researches and retrieves the latest Claude Code documentation to ensure CCJK skills and recommendations are based on current information.
11
-
12
- ## 📚 Data Sources
13
-
14
- ### Primary Sources
15
- - **Claude Code Docs**: https://docs.anthropic.com/claude/docs
16
- - **Claude API Docs**: https://docs.anthropic.com/claude/reference
17
- - **MCP Documentation**: https://modelcontextprotocol.io/
18
- - **Release Notes**: https://docs.anthropic.com/claude/docs/releases
19
-
20
- ## 🔍 Research Queries
21
-
22
- ### Common Queries
23
- ```typescript
24
- // Latest Claude Code features
25
- "Claude Code latest features 2025"
26
-
27
- // MCP documentation
28
- "Model Context Protocol specification"
29
-
30
- // Skills documentation
31
- "Claude Code skills documentation"
32
-
33
- // API reference
34
- "Claude API messages parameters"
35
- ```
36
-
37
- ## 📊 Cache Strategy
38
-
39
- ```typescript
40
- const CACHE_CONFIG = {
41
- docs: {
42
- ttl: 72 * 60 * 60 * 1000, // 72 hours
43
- key: (query) => `docs:${query}`
44
- }
45
- }
46
- ```
47
-
48
- **Rationale**: Documentation is relatively stable but updates occasionally. 72-hour balance ensures freshness without excessive API calls.
49
-
50
- ## 🔄 Workflow
51
-
52
- ```
53
- User Query: "Latest Claude Code features"
54
-
55
- 1. Check Cache
56
-
57
- 2. If Cache Hit (< 72h old)
58
- → Return cached docs
59
-
60
- 3. If Cache Miss or Expired
61
- → Fetch from docs.anthropic.com
62
- → Parse and extract relevant sections
63
- → Store in cache
64
- → Return to user
65
- ```
66
-
67
- ## 📋 Output Format
68
-
69
- ```typescript
70
- interface DocResearchResult {
71
- query: string
72
- source: string
73
- url: string
74
- title: string
75
- content: string
76
- lastUpdated: Date
77
- cacheHit: boolean
78
- }
79
- ```
80
-
81
- ## 🎯 Key Features
82
-
83
- ### 1. Smart Caching
84
- - Check cache age before fetching
85
- - Return cached if fresh (< 72h)
86
- - Fetch and update if stale
87
-
88
- ### 2. Relevant Extraction
89
- - Parse documentation HTML/Markdown
90
- - Extract relevant sections only
91
- - Format for easy reading
92
-
93
- ### 3. Source Attribution
94
- - Always include source URL
95
- - Provide timestamp
96
- - Indicate if data is from cache
97
-
98
- ## 🔗 Related Skills
99
-
100
- - **layer1-mcp**: Uses latest MCP docs
101
- - **layer2-best-practices**: Updated with latest standards
102
- - **All skills**: Benefit from current documentation
103
-
104
- ## 📝 Usage Examples
105
-
106
- ### Example 1: Fetch Latest MCP Docs
107
- ```
108
- User: "What's the latest MCP specification?"
109
-
110
- Agent: doc-researcher
111
-
112
- Query: "Model Context Protocol specification 2025"
113
-
114
- Output:
115
- - Latest MCP version
116
- - New transport types
117
- - Updated API format
118
- - Source: modelcontextprotocol.io
119
- ```
120
-
121
- ### Example 2: Claude Code Features
122
- ```
123
- User: "What's new in Claude Code?"
124
-
125
- Agent: doc-researcher
126
-
127
- Query: "Claude Code latest features"
128
-
129
- Output:
130
- - New features list
131
- - Updated workflows
132
- - New skill formats
133
- - Source: docs.anthropic.com
134
- ```
135
-
136
- ## ⚙️ Configuration
137
-
138
- ```json
139
- {
140
- "agent": "doc-researcher",
141
- "runMode": "background",
142
- "cache": {
143
- "enabled": true,
144
- "ttl": 259200000
145
- },
146
- "sources": [
147
- "https://docs.anthropic.com",
148
- "https://modelcontextprotocol.io"
149
- ]
150
- }
151
- ```
152
-
153
- ## 🚫 Error Handling
154
-
155
- ```typescript
156
- try {
157
- const docs = await fetchDocs(query)
158
- return docs
159
- } catch (error) {
160
- // Fallback to cached data if available
161
- const cached = await getFromCache(query)
162
- if (cached) {
163
- console.warn('Using cached docs (fetch failed)')
164
- return { ...cached, source: 'cache (offline)' }
165
- }
166
-
167
- // If no cache, return error
168
- throw new Error(`Failed to fetch docs: ${error.message}`)
169
- }
170
- ```
171
-
172
- ## 📈 Performance Metrics
173
-
174
- - **Average Fetch Time**: ~2 seconds
175
- - **Cache Hit Rate**: Target > 80%
176
- - **Success Rate**: Target > 95%
177
-
178
- ## 🔐 Security & Privacy
179
-
180
- - ✅ No personal data sent
181
- - ✅ Only public documentation accessed
182
- - ✅ Cache stored locally
183
- - ✅ No tracking or analytics
184
-
185
- ## 🔄 Update Strategy
186
-
187
- **When to Update Cache**:
188
- - Manual trigger: `/fetch-docs`
189
- - Automatic: If cache > 72h old
190
- - Before: Using docs in critical decisions
191
-
192
- ## 📚 References
193
-
194
- - [Claude Code Documentation](https://docs.anthropic.com/claude/docs)
195
- - [MCP Specification](https://modelcontextprotocol.io/)
196
- - [Agent Implementation Guide](./AGENT-IMPLEMENTATION.md)
197
-
198
- ---
199
-
200
- **Status**: ✅ Ready for implementation
201
- **Priority**: 🔴 High
202
- **Dependencies**: None (can run independently)