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.
- package/dist/chunks/package.mjs +1 -1
- package/package.json +61 -68
- package/.claude/hooks/ccjk-diagnose-hook.sh +0 -106
- package/.claude/hooks/eslint-hook.ts +0 -122
- package/.claude-plugin/plugin.json +0 -9
- package/README-INTERNAL.md +0 -305
- package/agents/agent-router.md +0 -135
- package/agents/agents.json +0 -6
- package/agents/cache-manager.ts +0 -265
- package/agents/doc-researcher.md +0 -202
- package/agents/mcp-researcher.md +0 -285
- package/agents/npm-researcher.md +0 -383
- package/agents/version-checker.md +0 -332
- package/hooks/hooks.json +0 -15
- package/skills/ccjk/SKILL.md +0 -224
- package/skills/ccjk/references/ccjk-defaults.md +0 -265
- package/skills/ccjk/references/coding-standards.md +0 -198
- package/skills/ccjk/references/error-patterns.md +0 -353
- package/skills/ccjk/references/platform-conventions.md +0 -307
- package/skills/ccjk-config/SKILL.md +0 -301
- package/skills/ccjk-init/SKILL.md +0 -201
- package/skills/ccjk-mcp/SKILL.md +0 -249
- package/skills/ccjk-sync/SKILL.md +0 -328
- package/skills/coding-guidelines.md +0 -262
- package/skills/config-router/SKILL.md +0 -233
- package/skills/domain-cli.md +0 -228
- package/skills/domain-cloud.md +0 -246
- package/skills/domain-desktop.md +0 -272
- package/skills/domain-web.md +0 -229
- package/skills/layer1-api.md +0 -160
- package/skills/layer1-mcp.md +0 -305
- package/skills/layer1-workflow.md +0 -144
- package/skills/layer2-best-practices.md +0 -155
- package/skills/layer2-design-patterns.md +0 -107
package/agents/agent-router.md
DELETED
|
@@ -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
|
package/agents/agents.json
DELETED
package/agents/cache-manager.ts
DELETED
|
@@ -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
|
package/agents/doc-researcher.md
DELETED
|
@@ -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)
|