MCPcopy Create free account
hub / github.com/Noumena-Network/code / initialize

Function initialize

src/utils/skills/skillChangeDetector.ts:88–144  ·  view source on GitHub ↗
()

Source from the content-addressed store, hash-verified

86 * Initialize file watching for skill directories
87 */
88export async function initialize(): Promise<void> {
89 if (initialized || disposed) return
90 initialized = true
91
92 // Register callback for when dynamic skills are loaded (only once)
93 if (!dynamicSkillsCallbackRegistered) {
94 dynamicSkillsCallbackRegistered = true
95 onDynamicSkillsLoaded(() => {
96 // Clear memoization caches so new skills are picked up
97 // Note: we use clearCommandMemoizationCaches (not clearCommandsCache)
98 // because clearCommandsCache would call clearSkillCaches which
99 // wipes out the dynamic skills we just loaded
100 clearCommandMemoizationCaches()
101 // Notify listeners that skills changed
102 skillsChanged.emit()
103 })
104 }
105
106 const paths = await getWatchablePaths()
107 if (paths.length === 0) return
108
109 logForDebugging(
110 `Watching for changes in skill/command directories: ${paths.join(', ')}...`,
111 )
112
113 watcher = chokidar.watch(paths, {
114 persistent: true,
115 ignoreInitial: true,
116 depth: 2, // Skills use skill-name/SKILL.md format
117 awaitWriteFinish: {
118 stabilityThreshold:
119 testOverrides?.stabilityThreshold ?? FILE_STABILITY_THRESHOLD_MS,
120 pollInterval:
121 testOverrides?.pollInterval ?? FILE_STABILITY_POLL_INTERVAL_MS,
122 },
123 // Ignore special file types (sockets, FIFOs, devices) - they cannot be watched
124 // and will error with EOPNOTSUPP on macOS. Only allow regular files and directories.
125 ignored: (path, stats) => {
126 if (stats && !stats.isFile() && !stats.isDirectory()) return true
127 // Ignore .git directories
128 return path.split(platformPath.sep).some(dir => dir === '.git')
129 },
130 ignorePermissionErrors: true,
131 usePolling: USE_POLLING,
132 interval: testOverrides?.chokidarInterval ?? POLLING_INTERVAL_MS,
133 atomic: true,
134 })
135
136 watcher.on('add', handleChange)
137 watcher.on('change', handleChange)
138 watcher.on('unlink', handleChange)
139
140 // Register cleanup to properly dispose of the file watcher during graceful shutdown
141 unregisterCleanup = registerCleanup(async () => {
142 await dispose()
143 })
144}
145

Callers

nothing calls this directly

Calls 7

onDynamicSkillsLoadedFunction · 0.85
getWatchablePathsFunction · 0.85
registerCleanupFunction · 0.85
emitMethod · 0.80
disposeFunction · 0.70
logForDebuggingFunction · 0.50

Tested by

no test coverage detected