@cleocode/caamp 1.8.1 → 1.9.0
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/chunk-ER3FIOTM.js +244 -0
- package/dist/chunk-ER3FIOTM.js.map +1 -0
- package/dist/{chunk-CPHF5IM4.js → chunk-MFWBR2NY.js} +20 -290
- package/dist/chunk-MFWBR2NY.js.map +1 -0
- package/dist/{chunk-LDTYDQGR.js → chunk-OLJZ23W3.js} +7 -5
- package/dist/{chunk-LDTYDQGR.js.map → chunk-OLJZ23W3.js.map} +1 -1
- package/dist/chunk-TRIXT4T7.js +276 -0
- package/dist/chunk-TRIXT4T7.js.map +1 -0
- package/dist/cli.js +199 -87
- package/dist/cli.js.map +1 -1
- package/dist/hooks-LV6VU7QJ.js +56 -0
- package/dist/index.d.ts +207 -2
- package/dist/index.js +71 -19
- package/dist/index.js.map +1 -1
- package/dist/{injector-TIUEM4X2.js → injector-P2OL6RK3.js} +3 -2
- package/dist/injector-P2OL6RK3.js.map +1 -0
- package/package.json +1 -1
- package/providers/hook-mappings.json +302 -0
- package/providers/registry.json +599 -156
- package/dist/chunk-CPHF5IM4.js.map +0 -1
- /package/dist/{injector-TIUEM4X2.js.map → hooks-LV6VU7QJ.js.map} +0 -0
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
import {
|
|
2
|
+
resolveRegistryTemplatePath
|
|
3
|
+
} from "./chunk-TRIXT4T7.js";
|
|
4
|
+
|
|
5
|
+
// src/core/hooks/types.ts
|
|
6
|
+
var HOOK_CATEGORIES = ["session", "prompt", "tool", "agent", "context"];
|
|
7
|
+
var CANONICAL_HOOK_EVENTS = [
|
|
8
|
+
"SessionStart",
|
|
9
|
+
"SessionEnd",
|
|
10
|
+
"PromptSubmit",
|
|
11
|
+
"ResponseComplete",
|
|
12
|
+
"PreToolUse",
|
|
13
|
+
"PostToolUse",
|
|
14
|
+
"PostToolUseFailure",
|
|
15
|
+
"PermissionRequest",
|
|
16
|
+
"SubagentStart",
|
|
17
|
+
"SubagentStop",
|
|
18
|
+
"PreModel",
|
|
19
|
+
"PostModel",
|
|
20
|
+
"PreCompact",
|
|
21
|
+
"PostCompact",
|
|
22
|
+
"Notification",
|
|
23
|
+
"ConfigChange"
|
|
24
|
+
];
|
|
25
|
+
|
|
26
|
+
// src/core/hooks/normalizer.ts
|
|
27
|
+
import { readFileSync } from "fs";
|
|
28
|
+
import { dirname, join } from "path";
|
|
29
|
+
import { fileURLToPath } from "url";
|
|
30
|
+
var _mappings = null;
|
|
31
|
+
function findMappingsPath() {
|
|
32
|
+
const thisDir = dirname(fileURLToPath(import.meta.url));
|
|
33
|
+
return join(thisDir, "..", "..", "..", "providers", "hook-mappings.json");
|
|
34
|
+
}
|
|
35
|
+
function loadMappings() {
|
|
36
|
+
if (_mappings) return _mappings;
|
|
37
|
+
const raw = readFileSync(findMappingsPath(), "utf-8");
|
|
38
|
+
_mappings = JSON.parse(raw);
|
|
39
|
+
return _mappings;
|
|
40
|
+
}
|
|
41
|
+
function resetHookMappings() {
|
|
42
|
+
_mappings = null;
|
|
43
|
+
}
|
|
44
|
+
function getCanonicalEvent(event) {
|
|
45
|
+
const data = loadMappings();
|
|
46
|
+
return data.canonicalEvents[event];
|
|
47
|
+
}
|
|
48
|
+
function getAllCanonicalEvents() {
|
|
49
|
+
return loadMappings().canonicalEvents;
|
|
50
|
+
}
|
|
51
|
+
function getCanonicalEventsByCategory(category) {
|
|
52
|
+
const data = loadMappings();
|
|
53
|
+
return CANONICAL_HOOK_EVENTS.filter(
|
|
54
|
+
(event) => data.canonicalEvents[event].category === category
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
function getProviderHookProfile(providerId) {
|
|
58
|
+
const data = loadMappings();
|
|
59
|
+
return data.providerMappings[providerId];
|
|
60
|
+
}
|
|
61
|
+
function getMappedProviderIds() {
|
|
62
|
+
return Object.keys(loadMappings().providerMappings);
|
|
63
|
+
}
|
|
64
|
+
function toNative(canonical, providerId) {
|
|
65
|
+
const profile = getProviderHookProfile(providerId);
|
|
66
|
+
if (!profile) return null;
|
|
67
|
+
const mapping = profile.mappings[canonical];
|
|
68
|
+
return mapping?.supported ? mapping.nativeName : null;
|
|
69
|
+
}
|
|
70
|
+
function toCanonical(nativeName, providerId) {
|
|
71
|
+
const profile = getProviderHookProfile(providerId);
|
|
72
|
+
if (!profile) return null;
|
|
73
|
+
for (const [canonical, mapping] of Object.entries(profile.mappings)) {
|
|
74
|
+
if (mapping.supported && mapping.nativeName === nativeName) {
|
|
75
|
+
return canonical;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
function toNativeBatch(canonicals, providerId) {
|
|
81
|
+
const data = loadMappings();
|
|
82
|
+
const profile = data.providerMappings[providerId];
|
|
83
|
+
if (!profile) return [];
|
|
84
|
+
const results = [];
|
|
85
|
+
for (const canonical of canonicals) {
|
|
86
|
+
const mapping = profile.mappings[canonical];
|
|
87
|
+
if (mapping?.supported && mapping.nativeName) {
|
|
88
|
+
results.push({
|
|
89
|
+
canonical,
|
|
90
|
+
native: mapping.nativeName,
|
|
91
|
+
providerId,
|
|
92
|
+
category: data.canonicalEvents[canonical].category,
|
|
93
|
+
canBlock: data.canonicalEvents[canonical].canBlock
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return results;
|
|
98
|
+
}
|
|
99
|
+
function supportsHook(canonical, providerId) {
|
|
100
|
+
const profile = getProviderHookProfile(providerId);
|
|
101
|
+
if (!profile) return false;
|
|
102
|
+
return profile.mappings[canonical]?.supported ?? false;
|
|
103
|
+
}
|
|
104
|
+
function getHookSupport(canonical, providerId) {
|
|
105
|
+
const profile = getProviderHookProfile(providerId);
|
|
106
|
+
if (!profile) {
|
|
107
|
+
return { canonical, supported: false, native: null };
|
|
108
|
+
}
|
|
109
|
+
const mapping = profile.mappings[canonical];
|
|
110
|
+
return {
|
|
111
|
+
canonical,
|
|
112
|
+
supported: mapping?.supported ?? false,
|
|
113
|
+
native: mapping?.nativeName ?? null,
|
|
114
|
+
notes: mapping?.notes
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
function getSupportedEvents(providerId) {
|
|
118
|
+
const profile = getProviderHookProfile(providerId);
|
|
119
|
+
if (!profile) return [];
|
|
120
|
+
return CANONICAL_HOOK_EVENTS.filter(
|
|
121
|
+
(event) => profile.mappings[event]?.supported
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
function getUnsupportedEvents(providerId) {
|
|
125
|
+
const profile = getProviderHookProfile(providerId);
|
|
126
|
+
if (!profile) return [...CANONICAL_HOOK_EVENTS];
|
|
127
|
+
return CANONICAL_HOOK_EVENTS.filter(
|
|
128
|
+
(event) => !profile.mappings[event]?.supported
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
function getProvidersForEvent(canonical) {
|
|
132
|
+
const data = loadMappings();
|
|
133
|
+
return Object.entries(data.providerMappings).filter(([, profile]) => profile.mappings[canonical]?.supported).map(([id]) => id);
|
|
134
|
+
}
|
|
135
|
+
function getCommonEvents(providerIds) {
|
|
136
|
+
if (providerIds.length === 0) return [];
|
|
137
|
+
return CANONICAL_HOOK_EVENTS.filter(
|
|
138
|
+
(event) => providerIds.every((id) => supportsHook(event, id))
|
|
139
|
+
);
|
|
140
|
+
}
|
|
141
|
+
function getProviderSummary(providerId) {
|
|
142
|
+
const profile = getProviderHookProfile(providerId);
|
|
143
|
+
if (!profile) return void 0;
|
|
144
|
+
const supported = getSupportedEvents(providerId);
|
|
145
|
+
const unsupported = getUnsupportedEvents(providerId);
|
|
146
|
+
return {
|
|
147
|
+
providerId,
|
|
148
|
+
hookSystem: profile.hookSystem,
|
|
149
|
+
experimental: profile.experimental,
|
|
150
|
+
supportedCount: supported.length,
|
|
151
|
+
totalCanonical: CANONICAL_HOOK_EVENTS.length,
|
|
152
|
+
supported,
|
|
153
|
+
unsupported,
|
|
154
|
+
providerOnly: profile.providerOnlyEvents,
|
|
155
|
+
coverage: Math.round(supported.length / CANONICAL_HOOK_EVENTS.length * 100)
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
function buildHookMatrix(providerIds) {
|
|
159
|
+
const data = loadMappings();
|
|
160
|
+
const ids = providerIds ?? Object.keys(data.providerMappings);
|
|
161
|
+
const matrix = {};
|
|
162
|
+
for (const event of CANONICAL_HOOK_EVENTS) {
|
|
163
|
+
matrix[event] = {};
|
|
164
|
+
for (const id of ids) {
|
|
165
|
+
const profile = data.providerMappings[id];
|
|
166
|
+
matrix[event][id] = profile?.mappings[event] ?? {
|
|
167
|
+
nativeName: null,
|
|
168
|
+
supported: false
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
return {
|
|
173
|
+
events: [...CANONICAL_HOOK_EVENTS],
|
|
174
|
+
providers: ids,
|
|
175
|
+
matrix
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
function getHookSystemType(providerId) {
|
|
179
|
+
const profile = getProviderHookProfile(providerId);
|
|
180
|
+
return profile?.hookSystem ?? "none";
|
|
181
|
+
}
|
|
182
|
+
function getHookConfigPath(providerId) {
|
|
183
|
+
const profile = getProviderHookProfile(providerId);
|
|
184
|
+
if (!profile?.hookConfigPath) return null;
|
|
185
|
+
return resolveRegistryTemplatePath(profile.hookConfigPath);
|
|
186
|
+
}
|
|
187
|
+
function getProviderOnlyEvents(providerId) {
|
|
188
|
+
const profile = getProviderHookProfile(providerId);
|
|
189
|
+
return profile?.providerOnlyEvents ?? [];
|
|
190
|
+
}
|
|
191
|
+
function translateToAll(canonical, providerIds) {
|
|
192
|
+
const result = {};
|
|
193
|
+
for (const id of providerIds) {
|
|
194
|
+
const native = toNative(canonical, id);
|
|
195
|
+
if (native) {
|
|
196
|
+
result[id] = native;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
return result;
|
|
200
|
+
}
|
|
201
|
+
function resolveNativeEvent(nativeName) {
|
|
202
|
+
const data = loadMappings();
|
|
203
|
+
const results = [];
|
|
204
|
+
for (const [providerId, profile] of Object.entries(data.providerMappings)) {
|
|
205
|
+
for (const [canonical, mapping] of Object.entries(profile.mappings)) {
|
|
206
|
+
if (mapping.supported && mapping.nativeName === nativeName) {
|
|
207
|
+
results.push({ providerId, canonical });
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
return results;
|
|
212
|
+
}
|
|
213
|
+
function getHookMappingsVersion() {
|
|
214
|
+
return loadMappings().version;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
export {
|
|
218
|
+
HOOK_CATEGORIES,
|
|
219
|
+
CANONICAL_HOOK_EVENTS,
|
|
220
|
+
resetHookMappings,
|
|
221
|
+
getCanonicalEvent,
|
|
222
|
+
getAllCanonicalEvents,
|
|
223
|
+
getCanonicalEventsByCategory,
|
|
224
|
+
getProviderHookProfile,
|
|
225
|
+
getMappedProviderIds,
|
|
226
|
+
toNative,
|
|
227
|
+
toCanonical,
|
|
228
|
+
toNativeBatch,
|
|
229
|
+
supportsHook,
|
|
230
|
+
getHookSupport,
|
|
231
|
+
getSupportedEvents,
|
|
232
|
+
getUnsupportedEvents,
|
|
233
|
+
getProvidersForEvent,
|
|
234
|
+
getCommonEvents,
|
|
235
|
+
getProviderSummary,
|
|
236
|
+
buildHookMatrix,
|
|
237
|
+
getHookSystemType,
|
|
238
|
+
getHookConfigPath,
|
|
239
|
+
getProviderOnlyEvents,
|
|
240
|
+
translateToAll,
|
|
241
|
+
resolveNativeEvent,
|
|
242
|
+
getHookMappingsVersion
|
|
243
|
+
};
|
|
244
|
+
//# sourceMappingURL=chunk-ER3FIOTM.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/hooks/types.ts","../src/core/hooks/normalizer.ts"],"sourcesContent":["/**\n * CAAMP Hooks Normalizer - Type Definitions\n *\n * Defines the canonical CAAMP hook event taxonomy and provider mapping types.\n * CAAMP provides a unified hook interface across all providers — consumers\n * use canonical event names, and the normalizer translates to/from\n * provider-native names.\n */\n\n// ── Canonical Hook Events ───────────────────────────────────────────\n\nexport const HOOK_CATEGORIES = [\"session\", \"prompt\", \"tool\", \"agent\", \"context\"] as const;\nexport type HookCategory = (typeof HOOK_CATEGORIES)[number];\n\nexport const CANONICAL_HOOK_EVENTS = [\n \"SessionStart\",\n \"SessionEnd\",\n \"PromptSubmit\",\n \"ResponseComplete\",\n \"PreToolUse\",\n \"PostToolUse\",\n \"PostToolUseFailure\",\n \"PermissionRequest\",\n \"SubagentStart\",\n \"SubagentStop\",\n \"PreModel\",\n \"PostModel\",\n \"PreCompact\",\n \"PostCompact\",\n \"Notification\",\n \"ConfigChange\",\n] as const;\n\nexport type CanonicalHookEvent = (typeof CANONICAL_HOOK_EVENTS)[number];\n\nexport interface CanonicalEventDefinition {\n category: HookCategory;\n description: string;\n canBlock: boolean;\n}\n\n// ── Provider Hook System Types ──────────────────────────────────────\n\nexport type HookSystemType = \"config\" | \"plugin\" | \"none\";\nexport type HookHandlerType = \"command\" | \"http\" | \"prompt\" | \"agent\" | \"plugin\";\n\nexport interface HookMapping {\n nativeName: string | null;\n supported: boolean;\n notes?: string;\n}\n\nexport interface ProviderHookProfile {\n hookSystem: HookSystemType;\n hookConfigPath: string | null;\n hookFormat: string | null;\n handlerTypes: HookHandlerType[];\n experimental: boolean;\n mappings: Record<CanonicalHookEvent, HookMapping>;\n providerOnlyEvents: string[];\n}\n\n// ── Normalization Result Types ──────────────────────────────────────\n\nexport interface NormalizedHookEvent {\n canonical: CanonicalHookEvent;\n native: string;\n providerId: string;\n category: HookCategory;\n canBlock: boolean;\n}\n\nexport interface HookSupportResult {\n canonical: CanonicalHookEvent;\n supported: boolean;\n native: string | null;\n notes?: string;\n}\n\nexport interface ProviderHookSummary {\n providerId: string;\n hookSystem: HookSystemType;\n experimental: boolean;\n supportedCount: number;\n totalCanonical: number;\n supported: CanonicalHookEvent[];\n unsupported: CanonicalHookEvent[];\n providerOnly: string[];\n coverage: number;\n}\n\nexport interface CrossProviderMatrix {\n events: CanonicalHookEvent[];\n providers: string[];\n matrix: Record<CanonicalHookEvent, Record<string, HookMapping>>;\n}\n\n// ── Hook Mappings Data File Types ───────────────────────────────────\n\nexport interface HookMappingsFile {\n version: string;\n lastUpdated: string;\n description: string;\n canonicalEvents: Record<CanonicalHookEvent, CanonicalEventDefinition>;\n providerMappings: Record<string, ProviderHookProfile>;\n}\n","/**\n * CAAMP Hooks Normalizer\n *\n * Translates between CAAMP canonical hook events and provider-native\n * event names. Provides query functions for hook support, cross-provider\n * comparison, and event normalization.\n *\n * This module follows the same pattern as `src/core/mcp/transforms.ts` —\n * a translation layer that lets consumers use one canonical interface\n * while CAAMP handles provider-specific differences.\n */\n\nimport { readFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { resolveRegistryTemplatePath } from \"../paths/standard.js\";\nimport type {\n CanonicalEventDefinition,\n CanonicalHookEvent,\n CrossProviderMatrix,\n HookCategory,\n HookMapping,\n HookMappingsFile,\n HookSupportResult,\n HookSystemType,\n NormalizedHookEvent,\n ProviderHookProfile,\n ProviderHookSummary,\n} from \"./types.js\";\nimport { CANONICAL_HOOK_EVENTS, HOOK_CATEGORIES } from \"./types.js\";\n\n// ── Data Loading ────────────────────────────────────────────────────\n\nlet _mappings: HookMappingsFile | null = null;\n\nfunction findMappingsPath(): string {\n const thisDir = dirname(fileURLToPath(import.meta.url));\n // src/core/hooks/ -> providers/hook-mappings.json\n return join(thisDir, \"..\", \"..\", \"..\", \"providers\", \"hook-mappings.json\");\n}\n\nfunction loadMappings(): HookMappingsFile {\n if (_mappings) return _mappings;\n const raw = readFileSync(findMappingsPath(), \"utf-8\");\n _mappings = JSON.parse(raw) as HookMappingsFile;\n return _mappings;\n}\n\n/** Reset cached data (for testing). */\nexport function resetHookMappings(): void {\n _mappings = null;\n}\n\n// ── Core Query Functions ────────────────────────────────────────────\n\n/**\n * Get the canonical event definition (category, description, canBlock).\n */\nexport function getCanonicalEvent(event: CanonicalHookEvent): CanonicalEventDefinition {\n const data = loadMappings();\n return data.canonicalEvents[event];\n}\n\n/**\n * Get all canonical event definitions.\n */\nexport function getAllCanonicalEvents(): Record<CanonicalHookEvent, CanonicalEventDefinition> {\n return loadMappings().canonicalEvents;\n}\n\n/**\n * Get canonical events filtered by category.\n */\nexport function getCanonicalEventsByCategory(category: HookCategory): CanonicalHookEvent[] {\n const data = loadMappings();\n return CANONICAL_HOOK_EVENTS.filter(\n (event) => data.canonicalEvents[event].category === category,\n );\n}\n\n/**\n * Get the full hook profile for a provider.\n */\nexport function getProviderHookProfile(providerId: string): ProviderHookProfile | undefined {\n const data = loadMappings();\n return data.providerMappings[providerId];\n}\n\n/**\n * Get all provider IDs that have hook mappings.\n */\nexport function getMappedProviderIds(): string[] {\n return Object.keys(loadMappings().providerMappings);\n}\n\n// ── Normalization: Canonical → Native ───────────────────────────────\n\n/**\n * Translate a CAAMP canonical event name to the provider's native name.\n *\n * @returns The native event name, or `null` if unsupported\n *\n * @example\n * ```typescript\n * toNative(\"PreToolUse\", \"claude-code\"); // \"PreToolUse\"\n * toNative(\"PreToolUse\", \"gemini-cli\"); // \"BeforeTool\"\n * toNative(\"PreToolUse\", \"cursor\"); // \"preToolUse\"\n * toNative(\"PreToolUse\", \"kimi\"); // null\n * ```\n */\nexport function toNative(\n canonical: CanonicalHookEvent,\n providerId: string,\n): string | null {\n const profile = getProviderHookProfile(providerId);\n if (!profile) return null;\n const mapping = profile.mappings[canonical];\n return mapping?.supported ? mapping.nativeName : null;\n}\n\n/**\n * Translate a provider-native event name to the CAAMP canonical name.\n *\n * @returns The canonical event name, or `null` if no mapping exists\n *\n * @example\n * ```typescript\n * toCanonical(\"BeforeTool\", \"gemini-cli\"); // \"PreToolUse\"\n * toCanonical(\"stop\", \"cursor\"); // \"ResponseComplete\"\n * toCanonical(\"UserPromptSubmit\", \"claude-code\"); // \"PromptSubmit\"\n * ```\n */\nexport function toCanonical(\n nativeName: string,\n providerId: string,\n): CanonicalHookEvent | null {\n const profile = getProviderHookProfile(providerId);\n if (!profile) return null;\n\n for (const [canonical, mapping] of Object.entries(profile.mappings)) {\n if (mapping.supported && mapping.nativeName === nativeName) {\n return canonical as CanonicalHookEvent;\n }\n }\n return null;\n}\n\n/**\n * Batch-translate multiple canonical events to native names for a provider.\n *\n * @returns Array of normalized events (only supported ones included)\n */\nexport function toNativeBatch(\n canonicals: CanonicalHookEvent[],\n providerId: string,\n): NormalizedHookEvent[] {\n const data = loadMappings();\n const profile = data.providerMappings[providerId];\n if (!profile) return [];\n\n const results: NormalizedHookEvent[] = [];\n for (const canonical of canonicals) {\n const mapping = profile.mappings[canonical];\n if (mapping?.supported && mapping.nativeName) {\n results.push({\n canonical,\n native: mapping.nativeName,\n providerId,\n category: data.canonicalEvents[canonical].category,\n canBlock: data.canonicalEvents[canonical].canBlock,\n });\n }\n }\n return results;\n}\n\n// ── Support Queries ─────────────────────────────────────────────────\n\n/**\n * Check if a provider supports a specific canonical hook event.\n */\nexport function supportsHook(\n canonical: CanonicalHookEvent,\n providerId: string,\n): boolean {\n const profile = getProviderHookProfile(providerId);\n if (!profile) return false;\n return profile.mappings[canonical]?.supported ?? false;\n}\n\n/**\n * Get full hook support details for a canonical event on a provider.\n */\nexport function getHookSupport(\n canonical: CanonicalHookEvent,\n providerId: string,\n): HookSupportResult {\n const profile = getProviderHookProfile(providerId);\n if (!profile) {\n return { canonical, supported: false, native: null };\n }\n const mapping = profile.mappings[canonical];\n return {\n canonical,\n supported: mapping?.supported ?? false,\n native: mapping?.nativeName ?? null,\n notes: mapping?.notes,\n };\n}\n\n/**\n * Get all supported canonical events for a provider.\n */\nexport function getSupportedEvents(providerId: string): CanonicalHookEvent[] {\n const profile = getProviderHookProfile(providerId);\n if (!profile) return [];\n return CANONICAL_HOOK_EVENTS.filter(\n (event) => profile.mappings[event]?.supported,\n );\n}\n\n/**\n * Get all unsupported canonical events for a provider.\n */\nexport function getUnsupportedEvents(providerId: string): CanonicalHookEvent[] {\n const profile = getProviderHookProfile(providerId);\n if (!profile) return [...CANONICAL_HOOK_EVENTS];\n return CANONICAL_HOOK_EVENTS.filter(\n (event) => !profile.mappings[event]?.supported,\n );\n}\n\n/**\n * Get providers that support a specific canonical event.\n */\nexport function getProvidersForEvent(canonical: CanonicalHookEvent): string[] {\n const data = loadMappings();\n return Object.entries(data.providerMappings)\n .filter(([, profile]) => profile.mappings[canonical]?.supported)\n .map(([id]) => id);\n}\n\n/**\n * Get canonical events common to all specified providers.\n */\nexport function getCommonEvents(providerIds: string[]): CanonicalHookEvent[] {\n if (providerIds.length === 0) return [];\n return CANONICAL_HOOK_EVENTS.filter(\n (event) => providerIds.every((id) => supportsHook(event, id)),\n );\n}\n\n// ── Summary & Matrix Functions ──────────────────────────────────────\n\n/**\n * Get a summary of hook support for a provider.\n */\nexport function getProviderSummary(providerId: string): ProviderHookSummary | undefined {\n const profile = getProviderHookProfile(providerId);\n if (!profile) return undefined;\n\n const supported = getSupportedEvents(providerId);\n const unsupported = getUnsupportedEvents(providerId);\n\n return {\n providerId,\n hookSystem: profile.hookSystem,\n experimental: profile.experimental,\n supportedCount: supported.length,\n totalCanonical: CANONICAL_HOOK_EVENTS.length,\n supported,\n unsupported,\n providerOnly: profile.providerOnlyEvents,\n coverage: Math.round((supported.length / CANONICAL_HOOK_EVENTS.length) * 100),\n };\n}\n\n/**\n * Build a cross-provider hook support matrix.\n *\n * Shows which canonical events are supported by which providers,\n * with native name translations.\n */\nexport function buildHookMatrix(providerIds?: string[]): CrossProviderMatrix {\n const data = loadMappings();\n const ids = providerIds ?? Object.keys(data.providerMappings);\n\n const matrix: Record<string, Record<string, HookMapping>> = {};\n for (const event of CANONICAL_HOOK_EVENTS) {\n matrix[event] = {};\n for (const id of ids) {\n const profile = data.providerMappings[id];\n matrix[event][id] = profile?.mappings[event] ?? {\n nativeName: null,\n supported: false,\n };\n }\n }\n\n return {\n events: [...CANONICAL_HOOK_EVENTS],\n providers: ids,\n matrix: matrix as CrossProviderMatrix[\"matrix\"],\n };\n}\n\n/**\n * Get the hook system type for a provider.\n */\nexport function getHookSystemType(providerId: string): HookSystemType {\n const profile = getProviderHookProfile(providerId);\n return profile?.hookSystem ?? \"none\";\n}\n\n/**\n * Get the resolved hook config path for a provider.\n */\nexport function getHookConfigPath(providerId: string): string | null {\n const profile = getProviderHookProfile(providerId);\n if (!profile?.hookConfigPath) return null;\n return resolveRegistryTemplatePath(profile.hookConfigPath);\n}\n\n/**\n * Get provider-only events (native events with no canonical mapping).\n */\nexport function getProviderOnlyEvents(providerId: string): string[] {\n const profile = getProviderHookProfile(providerId);\n return profile?.providerOnlyEvents ?? [];\n}\n\n// ── Multi-Provider Translation ──────────────────────────────────────\n\n/**\n * Translate a canonical event to native names across multiple providers.\n * Returns only providers that support the event.\n *\n * @example\n * ```typescript\n * const result = translateToAll(\"PreToolUse\", [\"claude-code\", \"gemini-cli\", \"kimi\"]);\n * // { \"claude-code\": \"PreToolUse\", \"gemini-cli\": \"BeforeTool\" }\n * // (kimi excluded — unsupported)\n * ```\n */\nexport function translateToAll(\n canonical: CanonicalHookEvent,\n providerIds: string[],\n): Record<string, string> {\n const result: Record<string, string> = {};\n for (const id of providerIds) {\n const native = toNative(canonical, id);\n if (native) {\n result[id] = native;\n }\n }\n return result;\n}\n\n/**\n * Find the best canonical match for a native event name across all providers.\n * Useful when you have a native name but don't know which provider it's from.\n */\nexport function resolveNativeEvent(nativeName: string): Array<{\n providerId: string;\n canonical: CanonicalHookEvent;\n}> {\n const data = loadMappings();\n const results: Array<{ providerId: string; canonical: CanonicalHookEvent }> = [];\n\n for (const [providerId, profile] of Object.entries(data.providerMappings)) {\n for (const [canonical, mapping] of Object.entries(profile.mappings)) {\n if (mapping.supported && mapping.nativeName === nativeName) {\n results.push({ providerId, canonical: canonical as CanonicalHookEvent });\n }\n }\n }\n\n return results;\n}\n\n/**\n * Get the version of the hook mappings data.\n */\nexport function getHookMappingsVersion(): string {\n return loadMappings().version;\n}\n"],"mappings":";;;;;AAWO,IAAM,kBAAkB,CAAC,WAAW,UAAU,QAAQ,SAAS,SAAS;AAGxE,IAAM,wBAAwB;AAAA,EACnC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;;;ACnBA,SAAS,oBAAoB;AAC7B,SAAS,SAAS,YAAY;AAC9B,SAAS,qBAAqB;AAmB9B,IAAI,YAAqC;AAEzC,SAAS,mBAA2B;AAClC,QAAM,UAAU,QAAQ,cAAc,YAAY,GAAG,CAAC;AAEtD,SAAO,KAAK,SAAS,MAAM,MAAM,MAAM,aAAa,oBAAoB;AAC1E;AAEA,SAAS,eAAiC;AACxC,MAAI,UAAW,QAAO;AACtB,QAAM,MAAM,aAAa,iBAAiB,GAAG,OAAO;AACpD,cAAY,KAAK,MAAM,GAAG;AAC1B,SAAO;AACT;AAGO,SAAS,oBAA0B;AACxC,cAAY;AACd;AAOO,SAAS,kBAAkB,OAAqD;AACrF,QAAM,OAAO,aAAa;AAC1B,SAAO,KAAK,gBAAgB,KAAK;AACnC;AAKO,SAAS,wBAA8E;AAC5F,SAAO,aAAa,EAAE;AACxB;AAKO,SAAS,6BAA6B,UAA8C;AACzF,QAAM,OAAO,aAAa;AAC1B,SAAO,sBAAsB;AAAA,IAC3B,CAAC,UAAU,KAAK,gBAAgB,KAAK,EAAE,aAAa;AAAA,EACtD;AACF;AAKO,SAAS,uBAAuB,YAAqD;AAC1F,QAAM,OAAO,aAAa;AAC1B,SAAO,KAAK,iBAAiB,UAAU;AACzC;AAKO,SAAS,uBAAiC;AAC/C,SAAO,OAAO,KAAK,aAAa,EAAE,gBAAgB;AACpD;AAiBO,SAAS,SACd,WACA,YACe;AACf,QAAM,UAAU,uBAAuB,UAAU;AACjD,MAAI,CAAC,QAAS,QAAO;AACrB,QAAM,UAAU,QAAQ,SAAS,SAAS;AAC1C,SAAO,SAAS,YAAY,QAAQ,aAAa;AACnD;AAcO,SAAS,YACd,YACA,YAC2B;AAC3B,QAAM,UAAU,uBAAuB,UAAU;AACjD,MAAI,CAAC,QAAS,QAAO;AAErB,aAAW,CAAC,WAAW,OAAO,KAAK,OAAO,QAAQ,QAAQ,QAAQ,GAAG;AACnE,QAAI,QAAQ,aAAa,QAAQ,eAAe,YAAY;AAC1D,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;AAOO,SAAS,cACd,YACA,YACuB;AACvB,QAAM,OAAO,aAAa;AAC1B,QAAM,UAAU,KAAK,iBAAiB,UAAU;AAChD,MAAI,CAAC,QAAS,QAAO,CAAC;AAEtB,QAAM,UAAiC,CAAC;AACxC,aAAW,aAAa,YAAY;AAClC,UAAM,UAAU,QAAQ,SAAS,SAAS;AAC1C,QAAI,SAAS,aAAa,QAAQ,YAAY;AAC5C,cAAQ,KAAK;AAAA,QACX;AAAA,QACA,QAAQ,QAAQ;AAAA,QAChB;AAAA,QACA,UAAU,KAAK,gBAAgB,SAAS,EAAE;AAAA,QAC1C,UAAU,KAAK,gBAAgB,SAAS,EAAE;AAAA,MAC5C,CAAC;AAAA,IACH;AAAA,EACF;AACA,SAAO;AACT;AAOO,SAAS,aACd,WACA,YACS;AACT,QAAM,UAAU,uBAAuB,UAAU;AACjD,MAAI,CAAC,QAAS,QAAO;AACrB,SAAO,QAAQ,SAAS,SAAS,GAAG,aAAa;AACnD;AAKO,SAAS,eACd,WACA,YACmB;AACnB,QAAM,UAAU,uBAAuB,UAAU;AACjD,MAAI,CAAC,SAAS;AACZ,WAAO,EAAE,WAAW,WAAW,OAAO,QAAQ,KAAK;AAAA,EACrD;AACA,QAAM,UAAU,QAAQ,SAAS,SAAS;AAC1C,SAAO;AAAA,IACL;AAAA,IACA,WAAW,SAAS,aAAa;AAAA,IACjC,QAAQ,SAAS,cAAc;AAAA,IAC/B,OAAO,SAAS;AAAA,EAClB;AACF;AAKO,SAAS,mBAAmB,YAA0C;AAC3E,QAAM,UAAU,uBAAuB,UAAU;AACjD,MAAI,CAAC,QAAS,QAAO,CAAC;AACtB,SAAO,sBAAsB;AAAA,IAC3B,CAAC,UAAU,QAAQ,SAAS,KAAK,GAAG;AAAA,EACtC;AACF;AAKO,SAAS,qBAAqB,YAA0C;AAC7E,QAAM,UAAU,uBAAuB,UAAU;AACjD,MAAI,CAAC,QAAS,QAAO,CAAC,GAAG,qBAAqB;AAC9C,SAAO,sBAAsB;AAAA,IAC3B,CAAC,UAAU,CAAC,QAAQ,SAAS,KAAK,GAAG;AAAA,EACvC;AACF;AAKO,SAAS,qBAAqB,WAAyC;AAC5E,QAAM,OAAO,aAAa;AAC1B,SAAO,OAAO,QAAQ,KAAK,gBAAgB,EACxC,OAAO,CAAC,CAAC,EAAE,OAAO,MAAM,QAAQ,SAAS,SAAS,GAAG,SAAS,EAC9D,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE;AACrB;AAKO,SAAS,gBAAgB,aAA6C;AAC3E,MAAI,YAAY,WAAW,EAAG,QAAO,CAAC;AACtC,SAAO,sBAAsB;AAAA,IAC3B,CAAC,UAAU,YAAY,MAAM,CAAC,OAAO,aAAa,OAAO,EAAE,CAAC;AAAA,EAC9D;AACF;AAOO,SAAS,mBAAmB,YAAqD;AACtF,QAAM,UAAU,uBAAuB,UAAU;AACjD,MAAI,CAAC,QAAS,QAAO;AAErB,QAAM,YAAY,mBAAmB,UAAU;AAC/C,QAAM,cAAc,qBAAqB,UAAU;AAEnD,SAAO;AAAA,IACL;AAAA,IACA,YAAY,QAAQ;AAAA,IACpB,cAAc,QAAQ;AAAA,IACtB,gBAAgB,UAAU;AAAA,IAC1B,gBAAgB,sBAAsB;AAAA,IACtC;AAAA,IACA;AAAA,IACA,cAAc,QAAQ;AAAA,IACtB,UAAU,KAAK,MAAO,UAAU,SAAS,sBAAsB,SAAU,GAAG;AAAA,EAC9E;AACF;AAQO,SAAS,gBAAgB,aAA6C;AAC3E,QAAM,OAAO,aAAa;AAC1B,QAAM,MAAM,eAAe,OAAO,KAAK,KAAK,gBAAgB;AAE5D,QAAM,SAAsD,CAAC;AAC7D,aAAW,SAAS,uBAAuB;AACzC,WAAO,KAAK,IAAI,CAAC;AACjB,eAAW,MAAM,KAAK;AACpB,YAAM,UAAU,KAAK,iBAAiB,EAAE;AACxC,aAAO,KAAK,EAAE,EAAE,IAAI,SAAS,SAAS,KAAK,KAAK;AAAA,QAC9C,YAAY;AAAA,QACZ,WAAW;AAAA,MACb;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,QAAQ,CAAC,GAAG,qBAAqB;AAAA,IACjC,WAAW;AAAA,IACX;AAAA,EACF;AACF;AAKO,SAAS,kBAAkB,YAAoC;AACpE,QAAM,UAAU,uBAAuB,UAAU;AACjD,SAAO,SAAS,cAAc;AAChC;AAKO,SAAS,kBAAkB,YAAmC;AACnE,QAAM,UAAU,uBAAuB,UAAU;AACjD,MAAI,CAAC,SAAS,eAAgB,QAAO;AACrC,SAAO,4BAA4B,QAAQ,cAAc;AAC3D;AAKO,SAAS,sBAAsB,YAA8B;AAClE,QAAM,UAAU,uBAAuB,UAAU;AACjD,SAAO,SAAS,sBAAsB,CAAC;AACzC;AAeO,SAAS,eACd,WACA,aACwB;AACxB,QAAM,SAAiC,CAAC;AACxC,aAAW,MAAM,aAAa;AAC5B,UAAM,SAAS,SAAS,WAAW,EAAE;AACrC,QAAI,QAAQ;AACV,aAAO,EAAE,IAAI;AAAA,IACf;AAAA,EACF;AACA,SAAO;AACT;AAMO,SAAS,mBAAmB,YAGhC;AACD,QAAM,OAAO,aAAa;AAC1B,QAAM,UAAwE,CAAC;AAE/E,aAAW,CAAC,YAAY,OAAO,KAAK,OAAO,QAAQ,KAAK,gBAAgB,GAAG;AACzE,eAAW,CAAC,WAAW,OAAO,KAAK,OAAO,QAAQ,QAAQ,QAAQ,GAAG;AACnE,UAAI,QAAQ,aAAa,QAAQ,eAAe,YAAY;AAC1D,gBAAQ,KAAK,EAAE,YAAY,UAA2C,CAAC;AAAA,MACzE;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAKO,SAAS,yBAAiC;AAC/C,SAAO,aAAa,EAAE;AACxB;","names":[]}
|
|
@@ -1,265 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
};
|
|
1
|
+
import {
|
|
2
|
+
resolveProviderSkillsDir,
|
|
3
|
+
resolveProvidersRegistryPath,
|
|
4
|
+
resolveRegistryTemplatePath
|
|
5
|
+
} from "./chunk-TRIXT4T7.js";
|
|
6
6
|
|
|
7
7
|
// src/core/instructions/injector.ts
|
|
8
|
-
import { existsSync
|
|
8
|
+
import { existsSync } from "fs";
|
|
9
9
|
import { mkdir, readFile, writeFile } from "fs/promises";
|
|
10
|
-
import { dirname as
|
|
10
|
+
import { dirname as dirname2, join as join2 } from "path";
|
|
11
11
|
|
|
12
12
|
// src/core/registry/providers.ts
|
|
13
13
|
import { readFileSync } from "fs";
|
|
14
|
-
import { dirname
|
|
14
|
+
import { dirname, join } from "path";
|
|
15
15
|
import { fileURLToPath } from "url";
|
|
16
|
-
|
|
17
|
-
// src/core/paths/standard.ts
|
|
18
|
-
import { existsSync } from "fs";
|
|
19
|
-
import { homedir as homedir2 } from "os";
|
|
20
|
-
import { dirname, join as join2 } from "path";
|
|
21
|
-
|
|
22
|
-
// src/core/platform-paths.ts
|
|
23
|
-
import envPaths from "env-paths";
|
|
24
|
-
import { arch, homedir, hostname, platform, release } from "os";
|
|
25
|
-
import { isAbsolute, join, resolve } from "path";
|
|
26
|
-
var APP_NAME = "agents";
|
|
27
|
-
function resolveAgentsHomeOverride(value) {
|
|
28
|
-
if (value === void 0) return void 0;
|
|
29
|
-
const trimmed = value.trim();
|
|
30
|
-
if (trimmed.length === 0) return void 0;
|
|
31
|
-
if (trimmed === "~") return homedir();
|
|
32
|
-
if (trimmed.startsWith("~/")) return join(homedir(), trimmed.slice(2));
|
|
33
|
-
if (isAbsolute(trimmed)) return resolve(trimmed);
|
|
34
|
-
return resolve(homedir(), trimmed);
|
|
35
|
-
}
|
|
36
|
-
var _paths = null;
|
|
37
|
-
var _sysInfo = null;
|
|
38
|
-
var _lastAgentsHome = void 0;
|
|
39
|
-
function getPlatformPaths() {
|
|
40
|
-
const currentAgentsHome = process.env["AGENTS_HOME"];
|
|
41
|
-
if (_paths && currentAgentsHome !== _lastAgentsHome) {
|
|
42
|
-
_paths = null;
|
|
43
|
-
_sysInfo = null;
|
|
44
|
-
}
|
|
45
|
-
if (_paths) return _paths;
|
|
46
|
-
const ep = envPaths(APP_NAME, { suffix: "" });
|
|
47
|
-
_lastAgentsHome = currentAgentsHome;
|
|
48
|
-
_paths = {
|
|
49
|
-
data: resolveAgentsHomeOverride(currentAgentsHome) ?? ep.data,
|
|
50
|
-
config: ep.config,
|
|
51
|
-
cache: ep.cache,
|
|
52
|
-
log: ep.log,
|
|
53
|
-
temp: ep.temp
|
|
54
|
-
};
|
|
55
|
-
return _paths;
|
|
56
|
-
}
|
|
57
|
-
function getSystemInfo() {
|
|
58
|
-
if (_sysInfo) return _sysInfo;
|
|
59
|
-
const paths = getPlatformPaths();
|
|
60
|
-
_sysInfo = {
|
|
61
|
-
platform: platform(),
|
|
62
|
-
arch: arch(),
|
|
63
|
-
release: release(),
|
|
64
|
-
hostname: hostname(),
|
|
65
|
-
nodeVersion: process.version,
|
|
66
|
-
paths
|
|
67
|
-
};
|
|
68
|
-
return _sysInfo;
|
|
69
|
-
}
|
|
70
|
-
function _resetPlatformPathsCache() {
|
|
71
|
-
_paths = null;
|
|
72
|
-
_sysInfo = null;
|
|
73
|
-
_lastAgentsHome = void 0;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
// src/core/paths/standard.ts
|
|
77
|
-
function getPlatformLocations() {
|
|
78
|
-
const home = homedir2();
|
|
79
|
-
const platform2 = process.platform;
|
|
80
|
-
if (platform2 === "win32") {
|
|
81
|
-
const appData = process.env["APPDATA"] ?? join2(home, "AppData", "Roaming");
|
|
82
|
-
return {
|
|
83
|
-
home,
|
|
84
|
-
config: appData,
|
|
85
|
-
vscodeConfig: join2(appData, "Code", "User"),
|
|
86
|
-
zedConfig: join2(appData, "Zed"),
|
|
87
|
-
claudeDesktopConfig: join2(appData, "Claude"),
|
|
88
|
-
applications: []
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
|
-
if (platform2 === "darwin") {
|
|
92
|
-
const config2 = process.env["XDG_CONFIG_HOME"] ?? join2(home, ".config");
|
|
93
|
-
return {
|
|
94
|
-
home,
|
|
95
|
-
config: config2,
|
|
96
|
-
vscodeConfig: join2(home, "Library", "Application Support", "Code", "User"),
|
|
97
|
-
zedConfig: join2(home, "Library", "Application Support", "Zed"),
|
|
98
|
-
claudeDesktopConfig: join2(home, "Library", "Application Support", "Claude"),
|
|
99
|
-
applications: ["/Applications", join2(home, "Applications")]
|
|
100
|
-
};
|
|
101
|
-
}
|
|
102
|
-
const config = process.env["XDG_CONFIG_HOME"] ?? join2(home, ".config");
|
|
103
|
-
return {
|
|
104
|
-
home,
|
|
105
|
-
config,
|
|
106
|
-
vscodeConfig: join2(config, "Code", "User"),
|
|
107
|
-
zedConfig: join2(config, "zed"),
|
|
108
|
-
claudeDesktopConfig: join2(config, "Claude"),
|
|
109
|
-
applications: []
|
|
110
|
-
};
|
|
111
|
-
}
|
|
112
|
-
function getAgentsHome() {
|
|
113
|
-
return getPlatformPaths().data;
|
|
114
|
-
}
|
|
115
|
-
function getProjectAgentsDir(projectRoot = process.cwd()) {
|
|
116
|
-
return join2(projectRoot, ".agents");
|
|
117
|
-
}
|
|
118
|
-
function resolveProjectPath(relativePath, projectDir = process.cwd()) {
|
|
119
|
-
return join2(projectDir, relativePath);
|
|
120
|
-
}
|
|
121
|
-
function getCanonicalSkillsDir() {
|
|
122
|
-
return join2(getAgentsHome(), "skills");
|
|
123
|
-
}
|
|
124
|
-
function getLockFilePath() {
|
|
125
|
-
return join2(getAgentsHome(), ".caamp-lock.json");
|
|
126
|
-
}
|
|
127
|
-
function getAgentsMcpDir(scope = "global", projectDir) {
|
|
128
|
-
if (scope === "global") return join2(getAgentsHome(), "mcp");
|
|
129
|
-
return join2(projectDir ?? process.cwd(), ".agents", "mcp");
|
|
130
|
-
}
|
|
131
|
-
function getAgentsMcpServersPath(scope = "global", projectDir) {
|
|
132
|
-
return join2(getAgentsMcpDir(scope, projectDir), "servers.json");
|
|
133
|
-
}
|
|
134
|
-
function getAgentsInstructFile(scope = "global", projectDir) {
|
|
135
|
-
if (scope === "global") return join2(getAgentsHome(), "AGENTS.md");
|
|
136
|
-
return join2(projectDir ?? process.cwd(), ".agents", "AGENTS.md");
|
|
137
|
-
}
|
|
138
|
-
function getAgentsConfigPath(scope = "global", projectDir) {
|
|
139
|
-
if (scope === "global") return join2(getAgentsHome(), "config.toml");
|
|
140
|
-
return join2(projectDir ?? process.cwd(), ".agents", "config.toml");
|
|
141
|
-
}
|
|
142
|
-
function getAgentsWikiDir(scope = "global", projectDir) {
|
|
143
|
-
if (scope === "global") return join2(getAgentsHome(), "wiki");
|
|
144
|
-
return join2(projectDir ?? process.cwd(), ".agents", "wiki");
|
|
145
|
-
}
|
|
146
|
-
function getAgentsSpecDir(scope = "global", projectDir) {
|
|
147
|
-
if (scope === "global") return join2(getAgentsHome(), "spec");
|
|
148
|
-
return join2(projectDir ?? process.cwd(), ".agents", "spec");
|
|
149
|
-
}
|
|
150
|
-
function getAgentsLinksDir(scope = "global", projectDir) {
|
|
151
|
-
if (scope === "global") return join2(getAgentsHome(), "links");
|
|
152
|
-
return join2(projectDir ?? process.cwd(), ".agents", "links");
|
|
153
|
-
}
|
|
154
|
-
function resolveRegistryTemplatePath(template) {
|
|
155
|
-
const locations = getPlatformLocations();
|
|
156
|
-
return template.replace(/\$HOME/g, locations.home).replace(/\$CONFIG/g, locations.config).replace(/\$VSCODE_CONFIG/g, locations.vscodeConfig).replace(/\$ZED_CONFIG/g, locations.zedConfig).replace(/\$CLAUDE_DESKTOP_CONFIG/g, locations.claudeDesktopConfig).replace(/\$AGENTS_HOME/g, getAgentsHome());
|
|
157
|
-
}
|
|
158
|
-
function resolveProviderConfigPath(provider, scope, projectDir = process.cwd()) {
|
|
159
|
-
if (scope === "global") {
|
|
160
|
-
return provider.configPathGlobal;
|
|
161
|
-
}
|
|
162
|
-
if (!provider.configPathProject) {
|
|
163
|
-
return null;
|
|
164
|
-
}
|
|
165
|
-
return resolveProjectPath(provider.configPathProject, projectDir);
|
|
166
|
-
}
|
|
167
|
-
function resolvePreferredConfigScope(provider, useGlobalFlag) {
|
|
168
|
-
if (useGlobalFlag) {
|
|
169
|
-
return "global";
|
|
170
|
-
}
|
|
171
|
-
return provider.configPathProject ? "project" : "global";
|
|
172
|
-
}
|
|
173
|
-
function resolveProviderSkillsDir(provider, scope, projectDir = process.cwd()) {
|
|
174
|
-
if (scope === "global") {
|
|
175
|
-
return provider.pathSkills;
|
|
176
|
-
}
|
|
177
|
-
return resolveProjectPath(provider.pathProjectSkills, projectDir);
|
|
178
|
-
}
|
|
179
|
-
function resolveProviderSkillsDirs(provider, scope, projectDir = process.cwd()) {
|
|
180
|
-
const vendorPath = resolveProviderSkillsDir(provider, scope, projectDir);
|
|
181
|
-
const precedence = provider.capabilities?.skills?.precedence ?? "vendor-only";
|
|
182
|
-
const resolveAgentsPath = () => {
|
|
183
|
-
if (scope === "global") {
|
|
184
|
-
return provider.capabilities?.skills?.agentsGlobalPath ?? null;
|
|
185
|
-
}
|
|
186
|
-
const projectRelative = provider.capabilities?.skills?.agentsProjectPath ?? null;
|
|
187
|
-
return projectRelative ? join2(projectDir, projectRelative) : null;
|
|
188
|
-
};
|
|
189
|
-
switch (precedence) {
|
|
190
|
-
case "vendor-only":
|
|
191
|
-
return [vendorPath];
|
|
192
|
-
case "agents-canonical": {
|
|
193
|
-
const agentsPath = resolveAgentsPath();
|
|
194
|
-
return agentsPath ? [agentsPath] : [vendorPath];
|
|
195
|
-
}
|
|
196
|
-
case "agents-first": {
|
|
197
|
-
const agentsPath = resolveAgentsPath();
|
|
198
|
-
return agentsPath ? [agentsPath, vendorPath] : [vendorPath];
|
|
199
|
-
}
|
|
200
|
-
case "agents-supported": {
|
|
201
|
-
const agentsPath = resolveAgentsPath();
|
|
202
|
-
return agentsPath ? [vendorPath, agentsPath] : [vendorPath];
|
|
203
|
-
}
|
|
204
|
-
case "vendor-global-agents-project": {
|
|
205
|
-
if (scope === "global") {
|
|
206
|
-
return [vendorPath];
|
|
207
|
-
}
|
|
208
|
-
const agentsPath = resolveAgentsPath();
|
|
209
|
-
return agentsPath ? [agentsPath, vendorPath] : [vendorPath];
|
|
210
|
-
}
|
|
211
|
-
default:
|
|
212
|
-
return [vendorPath];
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
function resolveProviderProjectPath(provider, projectDir = process.cwd()) {
|
|
216
|
-
return resolveProjectPath(provider.pathProject, projectDir);
|
|
217
|
-
}
|
|
218
|
-
function resolveProvidersRegistryPath(startDir) {
|
|
219
|
-
const candidates = [
|
|
220
|
-
join2(startDir, "..", "..", "..", "providers", "registry.json"),
|
|
221
|
-
join2(startDir, "..", "providers", "registry.json")
|
|
222
|
-
];
|
|
223
|
-
for (const candidate of candidates) {
|
|
224
|
-
if (existsSync(candidate)) {
|
|
225
|
-
return candidate;
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
let current = startDir;
|
|
229
|
-
for (let i = 0; i < 8; i += 1) {
|
|
230
|
-
const candidate = join2(current, "providers", "registry.json");
|
|
231
|
-
if (existsSync(candidate)) {
|
|
232
|
-
return candidate;
|
|
233
|
-
}
|
|
234
|
-
current = dirname(current);
|
|
235
|
-
}
|
|
236
|
-
throw new Error(`Cannot find providers/registry.json (searched from ${startDir})`);
|
|
237
|
-
}
|
|
238
|
-
function normalizeSkillSubPath(path) {
|
|
239
|
-
if (!path) return void 0;
|
|
240
|
-
const normalized = path.replace(/\\/g, "/").replace(/^\/+/, "").replace(/\/SKILL\.md$/i, "").trim();
|
|
241
|
-
return normalized.length > 0 ? normalized : void 0;
|
|
242
|
-
}
|
|
243
|
-
function buildSkillSubPathCandidates(marketplacePath, parsedPath) {
|
|
244
|
-
const candidates = [];
|
|
245
|
-
const base = normalizeSkillSubPath(marketplacePath);
|
|
246
|
-
const parsed = normalizeSkillSubPath(parsedPath);
|
|
247
|
-
if (base) candidates.push(base);
|
|
248
|
-
if (parsed) candidates.push(parsed);
|
|
249
|
-
const knownPrefixes = [".agents", ".claude"];
|
|
250
|
-
for (const value of [base, parsed]) {
|
|
251
|
-
if (!value || !value.startsWith("skills/")) continue;
|
|
252
|
-
for (const prefix of knownPrefixes) {
|
|
253
|
-
candidates.push(`${prefix}/${value}`);
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
if (candidates.length === 0) {
|
|
257
|
-
candidates.push(void 0);
|
|
258
|
-
}
|
|
259
|
-
return Array.from(new Set(candidates));
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
// src/core/registry/providers.ts
|
|
263
16
|
var DEFAULT_SKILLS_CAPABILITY = {
|
|
264
17
|
agentsGlobalPath: null,
|
|
265
18
|
agentsProjectPath: null,
|
|
@@ -298,7 +51,7 @@ function resolveCapabilities(raw) {
|
|
|
298
51
|
return { skills, hooks, spawn };
|
|
299
52
|
}
|
|
300
53
|
function findRegistryPath() {
|
|
301
|
-
const thisDir =
|
|
54
|
+
const thisDir = dirname(fileURLToPath(import.meta.url));
|
|
302
55
|
return resolveProvidersRegistryPath(thisDir);
|
|
303
56
|
}
|
|
304
57
|
var _registry = null;
|
|
@@ -429,7 +182,7 @@ function getEffectiveSkillsPaths(provider, scope, projectDir) {
|
|
|
429
182
|
const resolveAgentsPath = () => {
|
|
430
183
|
if (scope === "global" && agentsGlobalPath) return agentsGlobalPath;
|
|
431
184
|
if (scope === "project" && agentsProjectPath && projectDir) {
|
|
432
|
-
return
|
|
185
|
+
return join(projectDir, agentsProjectPath);
|
|
433
186
|
}
|
|
434
187
|
return null;
|
|
435
188
|
};
|
|
@@ -560,7 +313,7 @@ var MARKER_END = "<!-- CAAMP:END -->";
|
|
|
560
313
|
var MARKER_PATTERN = /<!-- CAAMP:START -->[\s\S]*?<!-- CAAMP:END -->/g;
|
|
561
314
|
var MARKER_PATTERN_SINGLE = /<!-- CAAMP:START -->[\s\S]*?<!-- CAAMP:END -->/;
|
|
562
315
|
async function checkInjection(filePath, expectedContent) {
|
|
563
|
-
if (!
|
|
316
|
+
if (!existsSync(filePath)) return "missing";
|
|
564
317
|
const content = await readFile(filePath, "utf-8");
|
|
565
318
|
if (!MARKER_PATTERN_SINGLE.test(content)) return "none";
|
|
566
319
|
if (expectedContent) {
|
|
@@ -584,8 +337,8 @@ ${MARKER_END}`;
|
|
|
584
337
|
}
|
|
585
338
|
async function inject(filePath, content) {
|
|
586
339
|
const block = buildBlock(content);
|
|
587
|
-
await mkdir(
|
|
588
|
-
if (!
|
|
340
|
+
await mkdir(dirname2(filePath), { recursive: true });
|
|
341
|
+
if (!existsSync(filePath)) {
|
|
589
342
|
await writeFile(filePath, `${block}
|
|
590
343
|
`, "utf-8");
|
|
591
344
|
return "created";
|
|
@@ -617,7 +370,7 @@ ${existing}`;
|
|
|
617
370
|
return "added";
|
|
618
371
|
}
|
|
619
372
|
async function removeInjection(filePath) {
|
|
620
|
-
if (!
|
|
373
|
+
if (!existsSync(filePath)) return false;
|
|
621
374
|
const content = await readFile(filePath, "utf-8");
|
|
622
375
|
if (!MARKER_PATTERN.test(content)) return false;
|
|
623
376
|
const cleaned = content.replace(MARKER_PATTERN, "").replace(/^\n{2,}/, "\n").trim();
|
|
@@ -634,7 +387,7 @@ async function checkAllInjections(providers, projectDir, scope, expectedContent)
|
|
|
634
387
|
const results = [];
|
|
635
388
|
const checked = /* @__PURE__ */ new Set();
|
|
636
389
|
for (const provider of providers) {
|
|
637
|
-
const filePath = scope === "global" ?
|
|
390
|
+
const filePath = scope === "global" ? join2(provider.pathGlobal, provider.instructFile) : join2(projectDir, provider.instructFile);
|
|
638
391
|
if (checked.has(filePath)) continue;
|
|
639
392
|
checked.add(filePath);
|
|
640
393
|
const status = await checkInjection(filePath, expectedContent);
|
|
@@ -642,7 +395,7 @@ async function checkAllInjections(providers, projectDir, scope, expectedContent)
|
|
|
642
395
|
file: filePath,
|
|
643
396
|
provider: provider.id,
|
|
644
397
|
status,
|
|
645
|
-
fileExists:
|
|
398
|
+
fileExists: existsSync(filePath)
|
|
646
399
|
});
|
|
647
400
|
}
|
|
648
401
|
return results;
|
|
@@ -651,7 +404,7 @@ async function injectAll(providers, projectDir, scope, content) {
|
|
|
651
404
|
const results = /* @__PURE__ */ new Map();
|
|
652
405
|
const injected = /* @__PURE__ */ new Set();
|
|
653
406
|
for (const provider of providers) {
|
|
654
|
-
const filePath = scope === "global" ?
|
|
407
|
+
const filePath = scope === "global" ? join2(provider.pathGlobal, provider.instructFile) : join2(projectDir, provider.instructFile);
|
|
655
408
|
if (injected.has(filePath)) continue;
|
|
656
409
|
injected.add(filePath);
|
|
657
410
|
const action = await inject(filePath, content);
|
|
@@ -665,7 +418,7 @@ async function ensureProviderInstructionFile(providerId, projectDir, options) {
|
|
|
665
418
|
throw new Error(`Unknown provider: "${providerId}". Check CAAMP provider registry.`);
|
|
666
419
|
}
|
|
667
420
|
const scope = options.scope ?? "project";
|
|
668
|
-
const filePath = scope === "global" ?
|
|
421
|
+
const filePath = scope === "global" ? join2(provider.pathGlobal, provider.instructFile) : join2(projectDir, provider.instructFile);
|
|
669
422
|
const template = {
|
|
670
423
|
references: options.references,
|
|
671
424
|
content: options.content
|
|
@@ -688,7 +441,7 @@ async function ensureAllProviderInstructionFiles(providerIds, projectDir, option
|
|
|
688
441
|
throw new Error(`Unknown provider: "${providerId}". Check CAAMP provider registry.`);
|
|
689
442
|
}
|
|
690
443
|
const scope = options.scope ?? "project";
|
|
691
|
-
const filePath = scope === "global" ?
|
|
444
|
+
const filePath = scope === "global" ? join2(provider.pathGlobal, provider.instructFile) : join2(projectDir, provider.instructFile);
|
|
692
445
|
if (processed.has(filePath)) continue;
|
|
693
446
|
processed.add(filePath);
|
|
694
447
|
const template = {
|
|
@@ -708,29 +461,6 @@ async function ensureAllProviderInstructionFiles(providerIds, projectDir, option
|
|
|
708
461
|
}
|
|
709
462
|
|
|
710
463
|
export {
|
|
711
|
-
__export,
|
|
712
|
-
getPlatformPaths,
|
|
713
|
-
getSystemInfo,
|
|
714
|
-
_resetPlatformPathsCache,
|
|
715
|
-
getPlatformLocations,
|
|
716
|
-
getAgentsHome,
|
|
717
|
-
getProjectAgentsDir,
|
|
718
|
-
getCanonicalSkillsDir,
|
|
719
|
-
getLockFilePath,
|
|
720
|
-
getAgentsMcpDir,
|
|
721
|
-
getAgentsMcpServersPath,
|
|
722
|
-
getAgentsInstructFile,
|
|
723
|
-
getAgentsConfigPath,
|
|
724
|
-
getAgentsWikiDir,
|
|
725
|
-
getAgentsSpecDir,
|
|
726
|
-
getAgentsLinksDir,
|
|
727
|
-
resolveRegistryTemplatePath,
|
|
728
|
-
resolveProviderConfigPath,
|
|
729
|
-
resolvePreferredConfigScope,
|
|
730
|
-
resolveProviderSkillsDir,
|
|
731
|
-
resolveProviderSkillsDirs,
|
|
732
|
-
resolveProviderProjectPath,
|
|
733
|
-
buildSkillSubPathCandidates,
|
|
734
464
|
getAllProviders,
|
|
735
465
|
getProvider,
|
|
736
466
|
resolveAlias,
|
|
@@ -763,4 +493,4 @@ export {
|
|
|
763
493
|
ensureProviderInstructionFile,
|
|
764
494
|
ensureAllProviderInstructionFiles
|
|
765
495
|
};
|
|
766
|
-
//# sourceMappingURL=chunk-
|
|
496
|
+
//# sourceMappingURL=chunk-MFWBR2NY.js.map
|