agentloom 0.1.5 → 0.1.6
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 -5
- package/dist/core/importer.d.ts +10 -0
- package/dist/core/importer.js +629 -13
- 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 +7 -1
- 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 +1 -0
- package/dist/core/skills.js +21 -2
- package/dist/core/sources.d.ts +2 -0
- package/dist/core/sources.js +34 -5
- package/dist/core/telemetry.d.ts +1 -1
- package/dist/core/telemetry.js +16 -0
- package/dist/sync/index.js +375 -17
- package/dist/types.d.ts +5 -1
- package/package.json +1 -1
package/dist/core/commands.js
CHANGED
|
@@ -1,16 +1,116 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
|
-
import
|
|
3
|
+
import TOML from "@iarna/toml";
|
|
4
|
+
import matter from "gray-matter";
|
|
5
|
+
import YAML from "yaml";
|
|
6
|
+
import { isObject, listMarkdownFiles, slugify } from "./fs.js";
|
|
7
|
+
import { ALL_PROVIDERS } from "../types.js";
|
|
4
8
|
export function parseCommandsDir(commandsDir) {
|
|
5
9
|
if (!fs.existsSync(commandsDir))
|
|
6
10
|
return [];
|
|
7
11
|
return listMarkdownFiles(commandsDir)
|
|
8
12
|
.sort((a, b) => a.localeCompare(b))
|
|
9
|
-
.map((sourcePath) =>
|
|
10
|
-
|
|
11
|
-
sourcePath
|
|
12
|
-
|
|
13
|
-
|
|
13
|
+
.map((sourcePath) => {
|
|
14
|
+
const content = fs.readFileSync(sourcePath, "utf8");
|
|
15
|
+
const fileName = path.basename(sourcePath);
|
|
16
|
+
const parsed = parseCommandContent(content);
|
|
17
|
+
return {
|
|
18
|
+
fileName,
|
|
19
|
+
sourcePath,
|
|
20
|
+
content,
|
|
21
|
+
body: parsed.body,
|
|
22
|
+
frontmatter: parsed.frontmatter,
|
|
23
|
+
};
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
export function parseCommandContent(content) {
|
|
27
|
+
const parsed = matter(content);
|
|
28
|
+
if (isObject(parsed.data) &&
|
|
29
|
+
Object.keys(parsed.data).length > 0) {
|
|
30
|
+
return {
|
|
31
|
+
body: parsed.content.trimStart(),
|
|
32
|
+
frontmatter: parsed.data,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
return {
|
|
36
|
+
body: content,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
export function getCommandProviderConfig(command, provider) {
|
|
40
|
+
if (!command.frontmatter)
|
|
41
|
+
return {};
|
|
42
|
+
const value = command.frontmatter[provider];
|
|
43
|
+
if (value === false)
|
|
44
|
+
return null;
|
|
45
|
+
if (isObject(value))
|
|
46
|
+
return value;
|
|
47
|
+
return {};
|
|
48
|
+
}
|
|
49
|
+
export function isCommandProviderEnabled(command, provider) {
|
|
50
|
+
return getCommandProviderConfig(command, provider) !== null;
|
|
51
|
+
}
|
|
52
|
+
export function renderCommandForProvider(command, provider) {
|
|
53
|
+
if (!isCommandProviderEnabled(command, provider)) {
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
const providerConfig = getCommandProviderConfig(command, provider);
|
|
57
|
+
if (providerConfig === null) {
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
const body = command.frontmatter ? command.body : command.content;
|
|
61
|
+
const normalizedBody = normalizeCommandArgumentsForProvider(body, provider);
|
|
62
|
+
const frontmatter = buildProviderCommandFrontmatter(command, providerConfig);
|
|
63
|
+
if (provider === "gemini") {
|
|
64
|
+
return buildGeminiCommandToml(frontmatter, normalizedBody);
|
|
65
|
+
}
|
|
66
|
+
if (Object.keys(frontmatter).length === 0) {
|
|
67
|
+
return normalizedBody;
|
|
68
|
+
}
|
|
69
|
+
const fm = YAML.stringify(frontmatter, { lineWidth: 0 }).trimEnd();
|
|
70
|
+
return `---\n${fm}\n---\n\n${normalizedBody.trimStart()}${normalizedBody.endsWith("\n") ? "" : "\n"}`;
|
|
71
|
+
}
|
|
72
|
+
function buildGeminiCommandToml(frontmatter, body) {
|
|
73
|
+
const payload = {
|
|
74
|
+
...frontmatter,
|
|
75
|
+
prompt: body.endsWith("\n") ? body : `${body}\n`,
|
|
76
|
+
};
|
|
77
|
+
return TOML.stringify(payload);
|
|
78
|
+
}
|
|
79
|
+
function buildProviderCommandFrontmatter(command, providerConfig) {
|
|
80
|
+
return {
|
|
81
|
+
...getSharedCommandMetadata(command.frontmatter),
|
|
82
|
+
...providerConfig,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
function getSharedCommandMetadata(frontmatter) {
|
|
86
|
+
if (!frontmatter)
|
|
87
|
+
return {};
|
|
88
|
+
const shared = {};
|
|
89
|
+
for (const [key, value] of Object.entries(frontmatter)) {
|
|
90
|
+
if (ALL_PROVIDERS.includes(key))
|
|
91
|
+
continue;
|
|
92
|
+
shared[key] = value;
|
|
93
|
+
}
|
|
94
|
+
return shared;
|
|
95
|
+
}
|
|
96
|
+
const COMMAND_ARGUMENT_PLACEHOLDER_BY_PROVIDER = {
|
|
97
|
+
copilot: "${input:args}",
|
|
98
|
+
gemini: "{{args}}",
|
|
99
|
+
};
|
|
100
|
+
export function normalizeCommandArgumentsForProvider(body, provider) {
|
|
101
|
+
const providerPlaceholder = COMMAND_ARGUMENT_PLACEHOLDER_BY_PROVIDER[provider];
|
|
102
|
+
if (!providerPlaceholder || providerPlaceholder === "$ARGUMENTS") {
|
|
103
|
+
return body;
|
|
104
|
+
}
|
|
105
|
+
return body.replace(/\$ARGUMENTS\b/g, providerPlaceholder);
|
|
106
|
+
}
|
|
107
|
+
export function normalizeCommandArgumentsForCanonical(body, provider) {
|
|
108
|
+
const providerPlaceholder = COMMAND_ARGUMENT_PLACEHOLDER_BY_PROVIDER[provider];
|
|
109
|
+
if (!providerPlaceholder || providerPlaceholder === "$ARGUMENTS") {
|
|
110
|
+
return body;
|
|
111
|
+
}
|
|
112
|
+
const escapedPlaceholder = providerPlaceholder.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
113
|
+
return body.replace(new RegExp(escapedPlaceholder, "g"), "$ARGUMENTS");
|
|
14
114
|
}
|
|
15
115
|
export function stripCommandFileExtension(fileName) {
|
|
16
116
|
const lower = fileName.toLowerCase();
|
package/dist/core/copy.js
CHANGED
|
@@ -8,7 +8,7 @@ Usage:
|
|
|
8
8
|
agentloom <entity> <verb> [options]
|
|
9
9
|
|
|
10
10
|
Aggregate commands:
|
|
11
|
-
add <source> Import agents/commands/mcp/skills from a source
|
|
11
|
+
add <source> Import agents/commands/mcp/rules/skills from a source
|
|
12
12
|
init Bootstrap canonical files, migrate providers, then sync
|
|
13
13
|
find <query> Search remote + local entities
|
|
14
14
|
update [source] Refresh lockfile-managed imports
|
|
@@ -20,6 +20,7 @@ Entity commands:
|
|
|
20
20
|
agent <add|list|delete|find|update|sync>
|
|
21
21
|
command <add|list|delete|find|update|sync>
|
|
22
22
|
mcp <add|list|delete|find|update|sync>
|
|
23
|
+
rule <add|list|delete|find|update|sync>
|
|
23
24
|
skill <add|list|delete|find|update|sync>
|
|
24
25
|
|
|
25
26
|
MCP manual server commands:
|
|
@@ -35,6 +36,8 @@ Common options:
|
|
|
35
36
|
--agents <csv> Agent selectors for add/delete
|
|
36
37
|
--commands <csv> Command selectors for add/delete
|
|
37
38
|
--mcps <csv> MCP selectors for add/delete
|
|
39
|
+
--rule <csv> Alias for --rules
|
|
40
|
+
--rules <csv> Rule selectors for add/delete
|
|
38
41
|
--skills <csv> Skill selectors for add/delete
|
|
39
42
|
--selection-mode <mode> Add mode: all (default) or custom
|
|
40
43
|
--source <value> Explicit source filter for update/delete
|
|
@@ -46,6 +49,7 @@ Examples:
|
|
|
46
49
|
agentloom agent add farnoodma/agents --agents issue-creator
|
|
47
50
|
agentloom command add farnoodma/agents --commands review
|
|
48
51
|
agentloom mcp add farnoodma/agents --mcps browser
|
|
52
|
+
agentloom rule add farnoodma/agents --rules always-test
|
|
49
53
|
agentloom skill add farnoodma/agents --skills pr-review
|
|
50
54
|
agentloom update
|
|
51
55
|
agentloom command update farnoodma/agents
|
|
@@ -58,7 +62,7 @@ export function getFindHelpText() {
|
|
|
58
62
|
|
|
59
63
|
Usage:
|
|
60
64
|
agentloom find <query>
|
|
61
|
-
agentloom <agent|command|mcp|skill> find <query>
|
|
65
|
+
agentloom <agent|command|mcp|rule|skill> find <query>
|
|
62
66
|
|
|
63
67
|
Examples:
|
|
64
68
|
agentloom find reviewer
|
|
@@ -70,7 +74,8 @@ export function getAddHelpText() {
|
|
|
70
74
|
|
|
71
75
|
Source discovery:
|
|
72
76
|
agents: .agents/agents -> agents
|
|
73
|
-
commands: .agents/commands -> commands -> prompts
|
|
77
|
+
commands: .agents/commands -> commands -> prompts -> (.github/prompts + .gemini/commands fallback)
|
|
78
|
+
rules: .agents/rules -> rules
|
|
74
79
|
skills: .agents/skills -> skills -> root SKILL.md
|
|
75
80
|
|
|
76
81
|
Usage:
|
|
@@ -82,6 +87,8 @@ Options:
|
|
|
82
87
|
--agents <name> Import selected agents (repeatable/csv)
|
|
83
88
|
--commands <name> Import selected commands (repeatable/csv)
|
|
84
89
|
--mcps <name> Import selected MCP servers (repeatable/csv)
|
|
90
|
+
--rule <name> Alias for --rules
|
|
91
|
+
--rules <name> Import selected rules (repeatable/csv)
|
|
85
92
|
--skills <name> Import selected skills (repeatable/csv)
|
|
86
93
|
--selection-mode <mode> all|sync-all (include future items) or custom (pin selection)
|
|
87
94
|
--rename <name> Rename imported item for single-item add flows
|
|
@@ -100,7 +107,7 @@ export function getUpdateHelpText() {
|
|
|
100
107
|
|
|
101
108
|
Usage:
|
|
102
109
|
agentloom update [source] [options]
|
|
103
|
-
agentloom <agent|command|mcp|skill> update [source] [options]
|
|
110
|
+
agentloom <agent|command|mcp|rule|skill> update [source] [options]
|
|
104
111
|
|
|
105
112
|
Options:
|
|
106
113
|
--source <value> Explicit source filter
|
|
@@ -131,7 +138,7 @@ export function getSyncHelpText() {
|
|
|
131
138
|
|
|
132
139
|
Usage:
|
|
133
140
|
agentloom sync [options]
|
|
134
|
-
agentloom <agent|command|mcp|skill> sync [options]
|
|
141
|
+
agentloom <agent|command|mcp|rule|skill> sync [options]
|
|
135
142
|
|
|
136
143
|
Options:
|
|
137
144
|
--local | --global Choose canonical scope (interactive prompts when omitted)
|
package/dist/core/importer.d.ts
CHANGED
|
@@ -20,6 +20,11 @@ export interface ImportOptions {
|
|
|
20
20
|
requireMcp?: boolean;
|
|
21
21
|
mcpSelectors?: string[];
|
|
22
22
|
promptForMcp?: boolean;
|
|
23
|
+
importRules?: boolean;
|
|
24
|
+
requireRules?: boolean;
|
|
25
|
+
ruleSelectors?: string[];
|
|
26
|
+
promptForRules?: boolean;
|
|
27
|
+
ruleRenameMap?: Record<string, string>;
|
|
23
28
|
importSkills?: boolean;
|
|
24
29
|
requireSkills?: boolean;
|
|
25
30
|
skillSelectors?: string[];
|
|
@@ -38,7 +43,12 @@ export interface ImportSummary {
|
|
|
38
43
|
importedAgents: string[];
|
|
39
44
|
importedCommands: string[];
|
|
40
45
|
importedMcpServers: string[];
|
|
46
|
+
importedRules: string[];
|
|
41
47
|
importedSkills: string[];
|
|
48
|
+
telemetryRules?: Array<{
|
|
49
|
+
name: string;
|
|
50
|
+
filePath: string;
|
|
51
|
+
}>;
|
|
42
52
|
telemetrySkills?: Array<{
|
|
43
53
|
name: string;
|
|
44
54
|
filePath: string;
|