139
}
140
}
142
>
// carry no `IParsed*` wrapper, so attribute them to scope via their source
143
>
// settings-file uri.
144
>
for (const hook of hooks) {
145
buckets.get(scopeOf(URI.parse(hook.uri), workingDirectory))!.hooks.push(hook);
146
}
148
>
const result: Customization[] = [];
149
>
// Workspace containers first (precedence), then user. `base` is the scope
150
>
// root the container `.claude/<sub>` uri is built from.
151
>
const orderedScopes: readonly (readonly [ClaudeCustomizationScope, URI | undefined])[] = [
152
>
[ClaudeCustomizationScope.Workspace, workingDirectory],
153
>
[ClaudeCustomizationScope.User, userHome],
154
>
];
155
>
for (const [scope, base] of orderedScopes) {
156
>
if (!base) {
157
continue;
158
}
160
>
if (bucket.agents.length > 0) {
161
result.push(makeDirectory(base, 'agents', CustomizationType.Agent, bucket.agents));
162
}
164
result.push(makeDirectory(base, 'skills', CustomizationType.Skill, bucket.skills));
165
}
167
result.push(makeDirectory(base, 'rules', CustomizationType.Rule, bucket.rules));
168
}
170
result.push(makeDirectory(base, 'hooks', CustomizationType.Hook, bucket.hooks));
171
}
173
>
174
>
// Native plugins are top-level entries (like MCP servers), each carrying
175
>
// its bundled components as children.
176
>
for (const plugin of nativePlugins) {
177
result.push(makePlugin(plugin));
178
}
180
>
result.push(...mcpServers);
181
>
return result;
182
>
}
183
184
/**