cache-manager
Manage analysis cache for incremental FSD validation
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Manage analysis cache for incremental FSD validation
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Check and install OpenAPI Sync MCP server dependency
Best practice templates for API layer scaffolding
Detect and analyze FSD layer structure in a project
Generate FSD-compliant slice boilerplate with pattern matching
Check FSD import boundary rules and detect violations
Manage OpenAPI spec cache and implementation state for efficient diff-based sync
| name | cache-manager |
| description | Manage analysis cache for incremental FSD validation |
분석 결과를 캐시하여 증분 검증을 지원합니다.
This skill is invoked by:
/fsdarch:analyze - To enable incremental analysis/fsdarch:validate - To speed up validationAction: Check if cache file exists
1. Use Glob to check for .fsd-architect.cache.json
2. If not found → return { valid: false, reason: 'no-cache' }
3. If found → proceed to Step 2
Glob command:
Glob: ".fsd-architect.cache.json"
Action: Read and validate cache integrity
1. Read .fsd-architect.cache.json using Read tool
2. Parse JSON (handle parse errors → E501)
3. Check version field matches current plugin version
4. Compute hash of .fsd-architect.json
5. Compare with cached configHash
Read commands:
Read: .fsd-architect.cache.json
Read: .fsd-architect.json # For hash comparison
Hash Function Implementation:
/**
* Simple string hash function for config comparison.
* Produces a consistent hash for cache invalidation detection.
*/
function simpleHash(content: string): string {
let hash = 0;
for (let i = 0; i < content.length; i++) {
const char = content.charCodeAt(i);
hash = ((hash << 5) - hash) + char;
hash = hash & hash; // Convert to 32bit integer
}
// Convert to base-36 for compact representation
return Math.abs(hash).toString(36);
}
Validation checks:
// Version check
if (cache.version !== '1.0.0') {
return { valid: false, reason: 'version-mismatch' }; // E503
}
// Config hash check using simpleHash()
const currentConfig = await read('.fsd-architect.json');
const currentHash = simpleHash(currentConfig);
if (cache.configHash !== currentHash) {
return { valid: false, reason: 'config-changed' };
}
// Age check (24 hours = 86400000 ms)
if (Date.now() - cache.timestamp > 86400000) {
return { valid: false, reason: 'expired' };
}
interface CacheFile {
version: string;
configHash: string;
timestamp: number;
layers: LayerCache;
files: FileCache;
}
interface LayerCache {
[layerName: string]: {
path: string;
slices: string[];
lastModified: number;
};
}
interface FileCache {
[filePath: string]: {
mtime: number;
imports: string[];
violations: Violation[];
};
}
interface ChangeSet {
added: string[]; // New files
modified: string[]; // Changed files
removed: string[]; // Deleted files
unchanged: string[];
}
interface CacheStatus {
valid: boolean;
reason?: 'no-cache' | 'version-mismatch' | 'config-changed' | 'expired';
changes?: ChangeSet;
cached?: {
layers: LayerCache;
files: FileCache;
};
}
{
"version": "0.1.0",
"configHash": "abc123...",
"timestamp": 1699999999999,
"layers": {
"features": {
"path": "src/features",
"slices": ["auth", "cart", "checkout"],
"lastModified": 1699999999000
}
},
"files": {
"src/features/auth/model/session.ts": {
"mtime": 1699999998000,
"imports": ["@entities/user", "@features/cart"],
"violations": [
{
"code": "E201",
"target": "@features/cart"
}
]
}
}
}
Check if .fsd-architect.cache.json is in .gitignore.
If not, suggest adding it:
# FSD Architect cache
.fsd-architect.cache.json
--force flag.fsd-architect.cache.json{ valid: false } to trigger full rescanfunction checkCache():
cachePath = '.fsd-architect.cache.json'
if not exists(cachePath):
return { valid: false, reason: 'no-cache' }
cache = read(cachePath)
// Version check
if cache.version != PLUGIN_VERSION:
return { valid: false, reason: 'version-mismatch' }
// Config check
currentConfigHash = hash(read('.fsd-architect.json'))
if cache.configHash != currentConfigHash:
return { valid: false, reason: 'config-changed' }
// Age check (24 hours)
if now() - cache.timestamp > 86400000:
return { valid: false, reason: 'expired' }
// Detect changes
currentFiles = glob('**/*.{ts,tsx,js,jsx}')
changes = detectChanges(cache.files, currentFiles)
return {
valid: true,
changes: changes,
cached: cache
}
function writeCache(analysisResult):
cache = {
version: PLUGIN_VERSION,
configHash: hash(read('.fsd-architect.json')),
timestamp: now(),
layers: analysisResult.layers,
files: {}
}
for file in analysisResult.files:
cache.files[file.path] = {
mtime: getMtime(file.path),
imports: file.imports,
violations: file.violations
}
write('.fsd-architect.cache.json', cache)
ensureGitignore('.fsd-architect.cache.json')
When cache is valid with changes:
changes.added and changes.modifiedchanges.removed from cachechanges.unchanged from cache| Scenario | Full Scan | Incremental |
|---|---|---|
| 100 files | ~5s | ~0.5s |
| 500 files | ~20s | ~1s |
| 1000 files | ~45s | ~2s |
If cache file is invalid JSON:
{ valid: false, reason: 'corrupted' }If cannot write cache: