agentloom 0.1.5 → 0.1.7
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/README.md +92 -6
- package/dist/cli.js +11 -4
- package/dist/commands/add.js +14 -0
- package/dist/commands/delete.js +89 -3
- package/dist/commands/entity-utils.js +3 -0
- package/dist/commands/find.js +146 -12
- package/dist/commands/rule.d.ts +2 -0
- package/dist/commands/rule.js +86 -0
- package/dist/commands/sync.js +13 -4
- package/dist/commands/update.js +90 -7
- package/dist/core/argv.js +2 -0
- package/dist/core/commands.d.ts +12 -0
- package/dist/core/commands.js +106 -6
- package/dist/core/copy.js +12 -12
- package/dist/core/importer.d.ts +10 -0
- package/dist/core/importer.js +941 -46
- package/dist/core/lockfile.js +8 -0
- package/dist/core/manifest.js +1 -1
- package/dist/core/migration.js +650 -66
- package/dist/core/provider-entity-validation.d.ts +8 -0
- package/dist/core/provider-entity-validation.js +34 -0
- package/dist/core/provider-paths.d.ts +8 -1
- package/dist/core/provider-paths.js +69 -5
- package/dist/core/router.js +17 -3
- package/dist/core/rules.d.ts +34 -0
- package/dist/core/rules.js +149 -0
- package/dist/core/scope.js +1 -0
- package/dist/core/skills.d.ts +4 -0
- package/dist/core/skills.js +47 -12
- package/dist/core/sources.d.ts +7 -0
- package/dist/core/sources.js +146 -22
- package/dist/core/telemetry.d.ts +1 -1
- package/dist/core/telemetry.js +16 -0
- package/dist/sync/index.js +403 -17
- package/dist/types.d.ts +5 -1
- package/package.json +1 -1
package/dist/core/sources.js
CHANGED
|
@@ -56,55 +56,179 @@ export function prepareSource(options) {
|
|
|
56
56
|
},
|
|
57
57
|
};
|
|
58
58
|
}
|
|
59
|
+
export function discoverPluginSourceRoots(importRoot) {
|
|
60
|
+
const marketplacePath = path.join(importRoot, ".claude-plugin", "marketplace.json");
|
|
61
|
+
if (!fs.existsSync(marketplacePath) ||
|
|
62
|
+
!fs.statSync(marketplacePath).isFile()) {
|
|
63
|
+
return [];
|
|
64
|
+
}
|
|
65
|
+
let parsed;
|
|
66
|
+
try {
|
|
67
|
+
parsed = JSON.parse(fs.readFileSync(marketplacePath, "utf8"));
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
return [];
|
|
71
|
+
}
|
|
72
|
+
const plugins = Array.isArray(parsed?.plugins)
|
|
73
|
+
? parsed.plugins
|
|
74
|
+
: [];
|
|
75
|
+
const discoveredRoots = [];
|
|
76
|
+
for (const plugin of plugins) {
|
|
77
|
+
if (!plugin ||
|
|
78
|
+
typeof plugin !== "object" ||
|
|
79
|
+
Array.isArray(plugin) ||
|
|
80
|
+
typeof plugin.source !== "string") {
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
const source = plugin.source.trim();
|
|
84
|
+
if (!source)
|
|
85
|
+
continue;
|
|
86
|
+
const pluginRoot = path.resolve(importRoot, source);
|
|
87
|
+
if (!isPathWithinRoot(importRoot, pluginRoot)) {
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
if (!fs.existsSync(pluginRoot) || !fs.statSync(pluginRoot).isDirectory()) {
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
discoveredRoots.push(pluginRoot);
|
|
94
|
+
}
|
|
95
|
+
return dedupePaths(discoveredRoots);
|
|
96
|
+
}
|
|
59
97
|
export function discoverSourceAgentsDir(importRoot) {
|
|
60
|
-
|
|
61
|
-
|
|
98
|
+
return discoverSourceAgentsDirs(importRoot)[0] ?? null;
|
|
99
|
+
}
|
|
100
|
+
export function discoverSourceAgentsDirs(importRoot) {
|
|
101
|
+
const direct = discoverSourceAgentsDirsForRoot(importRoot);
|
|
102
|
+
if (direct.length > 0) {
|
|
62
103
|
return direct;
|
|
63
104
|
}
|
|
64
|
-
|
|
65
|
-
if (fs.existsSync(nested) && fs.statSync(nested).isDirectory()) {
|
|
66
|
-
return nested;
|
|
67
|
-
}
|
|
68
|
-
return null;
|
|
105
|
+
return dedupePaths(discoverPluginSourceRoots(importRoot).flatMap((pluginRoot) => discoverSourceAgentsDirsForRoot(pluginRoot)));
|
|
69
106
|
}
|
|
70
107
|
export function discoverSourceMcpPath(importRoot) {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
const direct =
|
|
75
|
-
if (
|
|
108
|
+
return discoverSourceMcpPaths(importRoot)[0] ?? null;
|
|
109
|
+
}
|
|
110
|
+
export function discoverSourceMcpPaths(importRoot) {
|
|
111
|
+
const direct = discoverSourceMcpPathsForRoot(importRoot);
|
|
112
|
+
if (direct.length > 0) {
|
|
76
113
|
return direct;
|
|
77
|
-
|
|
114
|
+
}
|
|
115
|
+
return dedupePaths(discoverPluginSourceRoots(importRoot).flatMap((pluginRoot) => discoverSourceMcpPathsForRoot(pluginRoot)));
|
|
78
116
|
}
|
|
79
|
-
export function
|
|
117
|
+
export function discoverSourceCommandsDirs(importRoot) {
|
|
118
|
+
const direct = discoverSourceCommandsDirsForRoot(importRoot);
|
|
119
|
+
if (direct.length > 0) {
|
|
120
|
+
return direct;
|
|
121
|
+
}
|
|
122
|
+
return dedupePaths(discoverPluginSourceRoots(importRoot).flatMap((pluginRoot) => discoverSourceCommandsDirsForRoot(pluginRoot)));
|
|
123
|
+
}
|
|
124
|
+
function discoverSourceCommandsDirsForRoot(importRoot) {
|
|
80
125
|
const nested = path.join(importRoot, ".agents", "commands");
|
|
81
126
|
if (fs.existsSync(nested) && fs.statSync(nested).isDirectory()) {
|
|
82
|
-
return nested;
|
|
127
|
+
return [nested];
|
|
83
128
|
}
|
|
84
129
|
const direct = path.join(importRoot, "commands");
|
|
85
130
|
if (fs.existsSync(direct) && fs.statSync(direct).isDirectory()) {
|
|
86
|
-
return direct;
|
|
131
|
+
return [direct];
|
|
87
132
|
}
|
|
88
133
|
const prompts = path.join(importRoot, "prompts");
|
|
89
134
|
if (fs.existsSync(prompts) && fs.statSync(prompts).isDirectory()) {
|
|
90
|
-
return prompts;
|
|
135
|
+
return [prompts];
|
|
136
|
+
}
|
|
137
|
+
const providerFallbacks = [];
|
|
138
|
+
const githubPrompts = path.join(importRoot, ".github", "prompts");
|
|
139
|
+
if (fs.existsSync(githubPrompts) &&
|
|
140
|
+
fs.statSync(githubPrompts).isDirectory()) {
|
|
141
|
+
providerFallbacks.push(githubPrompts);
|
|
142
|
+
}
|
|
143
|
+
const geminiCommands = path.join(importRoot, ".gemini", "commands");
|
|
144
|
+
if (fs.existsSync(geminiCommands) &&
|
|
145
|
+
fs.statSync(geminiCommands).isDirectory()) {
|
|
146
|
+
providerFallbacks.push(geminiCommands);
|
|
91
147
|
}
|
|
92
|
-
return
|
|
148
|
+
return providerFallbacks;
|
|
149
|
+
}
|
|
150
|
+
export function discoverSourceCommandsDir(importRoot) {
|
|
151
|
+
return discoverSourceCommandsDirs(importRoot)[0] ?? null;
|
|
93
152
|
}
|
|
94
153
|
export function discoverSourceSkillsDir(importRoot) {
|
|
154
|
+
return discoverSourceSkillsDirs(importRoot)[0] ?? null;
|
|
155
|
+
}
|
|
156
|
+
export function discoverSourceSkillsDirs(importRoot) {
|
|
157
|
+
const direct = discoverSourceSkillsDirsForRoot(importRoot);
|
|
158
|
+
if (direct.length > 0) {
|
|
159
|
+
return direct;
|
|
160
|
+
}
|
|
161
|
+
return dedupePaths(discoverPluginSourceRoots(importRoot).flatMap((pluginRoot) => discoverSourceSkillsDirsForRoot(pluginRoot)));
|
|
162
|
+
}
|
|
163
|
+
export function discoverSourceRulesDir(importRoot) {
|
|
164
|
+
return discoverSourceRulesDirs(importRoot)[0] ?? null;
|
|
165
|
+
}
|
|
166
|
+
export function discoverSourceRulesDirs(importRoot) {
|
|
167
|
+
const direct = discoverSourceRulesDirsForRoot(importRoot);
|
|
168
|
+
if (direct.length > 0) {
|
|
169
|
+
return direct;
|
|
170
|
+
}
|
|
171
|
+
return dedupePaths(discoverPluginSourceRoots(importRoot).flatMap((pluginRoot) => discoverSourceRulesDirsForRoot(pluginRoot)));
|
|
172
|
+
}
|
|
173
|
+
function discoverSourceAgentsDirsForRoot(importRoot) {
|
|
174
|
+
const direct = path.join(importRoot, "agents");
|
|
175
|
+
if (fs.existsSync(direct) && fs.statSync(direct).isDirectory()) {
|
|
176
|
+
return [direct];
|
|
177
|
+
}
|
|
178
|
+
const nested = path.join(importRoot, ".agents", "agents");
|
|
179
|
+
if (fs.existsSync(nested) && fs.statSync(nested).isDirectory()) {
|
|
180
|
+
return [nested];
|
|
181
|
+
}
|
|
182
|
+
const githubAgents = path.join(importRoot, ".github", "agents");
|
|
183
|
+
if (fs.existsSync(githubAgents) && fs.statSync(githubAgents).isDirectory()) {
|
|
184
|
+
return [githubAgents];
|
|
185
|
+
}
|
|
186
|
+
return [];
|
|
187
|
+
}
|
|
188
|
+
function discoverSourceMcpPathsForRoot(importRoot) {
|
|
189
|
+
const nested = path.join(importRoot, ".agents", "mcp.json");
|
|
190
|
+
if (fs.existsSync(nested) && fs.statSync(nested).isFile()) {
|
|
191
|
+
return [nested];
|
|
192
|
+
}
|
|
193
|
+
const direct = path.join(importRoot, "mcp.json");
|
|
194
|
+
if (fs.existsSync(direct) && fs.statSync(direct).isFile()) {
|
|
195
|
+
return [direct];
|
|
196
|
+
}
|
|
197
|
+
return [];
|
|
198
|
+
}
|
|
199
|
+
function discoverSourceSkillsDirsForRoot(importRoot) {
|
|
95
200
|
const nested = path.join(importRoot, ".agents", "skills");
|
|
96
201
|
if (fs.existsSync(nested) && fs.statSync(nested).isDirectory()) {
|
|
97
|
-
return nested;
|
|
202
|
+
return [nested];
|
|
98
203
|
}
|
|
99
204
|
const direct = path.join(importRoot, "skills");
|
|
100
205
|
if (fs.existsSync(direct) && fs.statSync(direct).isDirectory()) {
|
|
101
|
-
return direct;
|
|
206
|
+
return [direct];
|
|
102
207
|
}
|
|
103
208
|
const rootSkill = path.join(importRoot, "SKILL.md");
|
|
104
209
|
if (fs.existsSync(rootSkill) && fs.statSync(rootSkill).isFile()) {
|
|
105
|
-
return importRoot;
|
|
210
|
+
return [importRoot];
|
|
106
211
|
}
|
|
107
|
-
return
|
|
212
|
+
return [];
|
|
213
|
+
}
|
|
214
|
+
function discoverSourceRulesDirsForRoot(importRoot) {
|
|
215
|
+
const nested = path.join(importRoot, ".agents", "rules");
|
|
216
|
+
if (fs.existsSync(nested) && fs.statSync(nested).isDirectory()) {
|
|
217
|
+
return [nested];
|
|
218
|
+
}
|
|
219
|
+
const direct = path.join(importRoot, "rules");
|
|
220
|
+
if (fs.existsSync(direct) && fs.statSync(direct).isDirectory()) {
|
|
221
|
+
return [direct];
|
|
222
|
+
}
|
|
223
|
+
return [];
|
|
224
|
+
}
|
|
225
|
+
function dedupePaths(paths) {
|
|
226
|
+
return [...new Set(paths)];
|
|
227
|
+
}
|
|
228
|
+
function isPathWithinRoot(rootPath, targetPath) {
|
|
229
|
+
const relative = path.relative(rootPath, targetPath);
|
|
230
|
+
return (relative === "" ||
|
|
231
|
+
(!relative.startsWith("..") && !path.isAbsolute(relative)));
|
|
108
232
|
}
|
|
109
233
|
function resolveImportRoot(rootPath, subdir) {
|
|
110
234
|
if (!subdir)
|
package/dist/core/telemetry.d.ts
CHANGED
package/dist/core/telemetry.js
CHANGED
|
@@ -47,6 +47,7 @@ export function parseGitHubSource(input) {
|
|
|
47
47
|
}
|
|
48
48
|
export function buildTelemetryItems(summary) {
|
|
49
49
|
const items = [];
|
|
50
|
+
const importedRules = summary.importedRules ?? [];
|
|
50
51
|
for (const filePath of summary.importedAgents) {
|
|
51
52
|
const name = path.basename(filePath, path.extname(filePath));
|
|
52
53
|
items.push({ entityType: "agent", name, filePath });
|
|
@@ -58,6 +59,21 @@ export function buildTelemetryItems(summary) {
|
|
|
58
59
|
for (const serverName of summary.importedMcpServers) {
|
|
59
60
|
items.push({ entityType: "mcp", name: serverName, filePath: "mcp.json" });
|
|
60
61
|
}
|
|
62
|
+
if (summary.telemetryRules && summary.telemetryRules.length > 0) {
|
|
63
|
+
for (const rule of summary.telemetryRules) {
|
|
64
|
+
items.push({
|
|
65
|
+
entityType: "rule",
|
|
66
|
+
name: rule.name,
|
|
67
|
+
filePath: rule.filePath.replace(/^\/+/, ""),
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
for (const filePath of importedRules) {
|
|
73
|
+
const name = path.basename(filePath, path.extname(filePath));
|
|
74
|
+
items.push({ entityType: "rule", name, filePath });
|
|
75
|
+
}
|
|
76
|
+
}
|
|
61
77
|
if (summary.telemetrySkills && summary.telemetrySkills.length > 0) {
|
|
62
78
|
for (const skill of summary.telemetrySkills) {
|
|
63
79
|
items.push({
|