@orchagent/cli 0.3.0 → 0.3.2
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/adapters/agents-md.js +2 -1
- package/dist/adapters/claude-code.js +3 -24
- package/dist/adapters/cursor.js +2 -9
- package/dist/adapters/index.js +5 -1
- package/dist/adapters/utils.js +35 -0
- package/dist/commands/config.js +11 -3
- package/dist/commands/formats.js +1 -4
- package/dist/commands/install.js +41 -12
- package/dist/commands/skill.js +6 -1
- package/dist/commands/update.js +16 -0
- package/dist/lib/agents-md-utils.js +34 -0
- package/dist/lib/string-utils.js +12 -0
- package/package.json +1 -1
|
@@ -29,7 +29,8 @@ exports.agentsMdAdapter = {
|
|
|
29
29
|
return { canConvert: true, warnings, errors };
|
|
30
30
|
},
|
|
31
31
|
convert(agent) {
|
|
32
|
-
const
|
|
32
|
+
const orgSlug = agent.org_slug || 'unknown';
|
|
33
|
+
const agentRef = `${orgSlug}/${agent.name}`;
|
|
33
34
|
const description = agent.description || '';
|
|
34
35
|
// Use orchagent markers for managed section
|
|
35
36
|
const content = `<!-- orchagent:${agentRef} -->
|
|
@@ -4,29 +4,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.claudeCodeAdapter = void 0;
|
|
7
|
+
const utils_1 = require("./utils");
|
|
7
8
|
const yaml_1 = __importDefault(require("yaml"));
|
|
8
|
-
// Map Anthropic model names to Claude Code aliases
|
|
9
|
-
function mapModelToAlias(model) {
|
|
10
|
-
if (!model)
|
|
11
|
-
return 'inherit';
|
|
12
|
-
const lower = model.toLowerCase();
|
|
13
|
-
if (lower.includes('opus'))
|
|
14
|
-
return 'opus';
|
|
15
|
-
if (lower.includes('haiku'))
|
|
16
|
-
return 'haiku';
|
|
17
|
-
// Default to sonnet for any Claude model
|
|
18
|
-
if (lower.includes('claude') || lower.includes('sonnet'))
|
|
19
|
-
return 'sonnet';
|
|
20
|
-
return 'inherit';
|
|
21
|
-
}
|
|
22
|
-
// Convert agent name to valid Claude Code name (lowercase + hyphens)
|
|
23
|
-
function normalizeAgentName(name) {
|
|
24
|
-
return name
|
|
25
|
-
.toLowerCase()
|
|
26
|
-
.replace(/[^a-z0-9-]/g, '-')
|
|
27
|
-
.replace(/-+/g, '-')
|
|
28
|
-
.replace(/^-|-$/g, '');
|
|
29
|
-
}
|
|
30
9
|
exports.claudeCodeAdapter = {
|
|
31
10
|
id: 'claude-code',
|
|
32
11
|
name: 'Claude Code Sub-Agent',
|
|
@@ -68,7 +47,7 @@ exports.claudeCodeAdapter = {
|
|
|
68
47
|
return { canConvert: true, warnings, errors };
|
|
69
48
|
},
|
|
70
49
|
convert(agent) {
|
|
71
|
-
const normalizedName = normalizeAgentName(agent.name);
|
|
50
|
+
const normalizedName = (0, utils_1.normalizeAgentName)(agent.name);
|
|
72
51
|
// Build frontmatter
|
|
73
52
|
const frontmatter = {
|
|
74
53
|
name: normalizedName,
|
|
@@ -77,7 +56,7 @@ exports.claudeCodeAdapter = {
|
|
|
77
56
|
};
|
|
78
57
|
// Map model if specified
|
|
79
58
|
if (agent.default_models?.anthropic) {
|
|
80
|
-
const modelAlias = mapModelToAlias(agent.default_models.anthropic);
|
|
59
|
+
const modelAlias = (0, utils_1.mapModelToAlias)(agent.default_models.anthropic);
|
|
81
60
|
if (modelAlias !== 'inherit') {
|
|
82
61
|
frontmatter.model = modelAlias;
|
|
83
62
|
}
|
package/dist/adapters/cursor.js
CHANGED
|
@@ -1,14 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.cursorAdapter = void 0;
|
|
4
|
-
|
|
5
|
-
function normalizeAgentName(name) {
|
|
6
|
-
return name
|
|
7
|
-
.toLowerCase()
|
|
8
|
-
.replace(/[^a-z0-9-]/g, '-')
|
|
9
|
-
.replace(/-+/g, '-')
|
|
10
|
-
.replace(/^-|-$/g, '');
|
|
11
|
-
}
|
|
4
|
+
const utils_1 = require("./utils");
|
|
12
5
|
exports.cursorAdapter = {
|
|
13
6
|
id: 'cursor',
|
|
14
7
|
name: 'Cursor Rules',
|
|
@@ -43,7 +36,7 @@ exports.cursorAdapter = {
|
|
|
43
36
|
return { canConvert: true, warnings, errors };
|
|
44
37
|
},
|
|
45
38
|
convert(agent) {
|
|
46
|
-
const normalizedName = normalizeAgentName(agent.name);
|
|
39
|
+
const normalizedName = (0, utils_1.normalizeAgentName)(agent.name);
|
|
47
40
|
const description = agent.description || `Rules from ${agent.name}`;
|
|
48
41
|
// Cursor .mdc format
|
|
49
42
|
const content = `---
|
package/dist/adapters/index.js
CHANGED
|
@@ -14,9 +14,13 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.agentsMdAdapter = exports.cursorAdapter = exports.claudeCodeAdapter = exports.adapterRegistry = exports.AdapterRegistry = void 0;
|
|
17
|
+
exports.agentsMdAdapter = exports.cursorAdapter = exports.claudeCodeAdapter = exports.adapterRegistry = exports.AdapterRegistry = exports.mapModelToAlias = exports.normalizeAgentName = void 0;
|
|
18
18
|
// Export types
|
|
19
19
|
__exportStar(require("./types"), exports);
|
|
20
|
+
// Export utilities
|
|
21
|
+
var utils_1 = require("./utils");
|
|
22
|
+
Object.defineProperty(exports, "normalizeAgentName", { enumerable: true, get: function () { return utils_1.normalizeAgentName; } });
|
|
23
|
+
Object.defineProperty(exports, "mapModelToAlias", { enumerable: true, get: function () { return utils_1.mapModelToAlias; } });
|
|
20
24
|
// Export registry
|
|
21
25
|
const registry_1 = require("./registry");
|
|
22
26
|
var registry_2 = require("./registry");
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Shared utilities for format adapters
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.normalizeAgentName = normalizeAgentName;
|
|
7
|
+
exports.mapModelToAlias = mapModelToAlias;
|
|
8
|
+
/**
|
|
9
|
+
* Convert agent name to valid format (lowercase + hyphens only).
|
|
10
|
+
* Used for filenames and identifiers across all adapters.
|
|
11
|
+
*/
|
|
12
|
+
function normalizeAgentName(name) {
|
|
13
|
+
const normalized = name
|
|
14
|
+
.toLowerCase()
|
|
15
|
+
.replace(/[^a-z0-9-]/g, '-')
|
|
16
|
+
.replace(/-+/g, '-')
|
|
17
|
+
.replace(/^-|-$/g, '');
|
|
18
|
+
return normalized || 'agent'; // Fallback if empty
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Map Anthropic model names to Claude Code aliases.
|
|
22
|
+
*/
|
|
23
|
+
function mapModelToAlias(model) {
|
|
24
|
+
if (!model)
|
|
25
|
+
return 'inherit';
|
|
26
|
+
const lower = model.toLowerCase();
|
|
27
|
+
if (lower.includes('opus'))
|
|
28
|
+
return 'opus';
|
|
29
|
+
if (lower.includes('haiku'))
|
|
30
|
+
return 'haiku';
|
|
31
|
+
// Default to sonnet for any Claude model
|
|
32
|
+
if (lower.includes('claude') || lower.includes('sonnet'))
|
|
33
|
+
return 'sonnet';
|
|
34
|
+
return 'inherit';
|
|
35
|
+
}
|
package/dist/commands/config.js
CHANGED
|
@@ -3,6 +3,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.registerConfigCommand = registerConfigCommand;
|
|
4
4
|
const config_1 = require("../lib/config");
|
|
5
5
|
const errors_1 = require("../lib/errors");
|
|
6
|
+
const adapters_1 = require("../adapters");
|
|
7
|
+
// Valid formats: union of skill directory formats and agent export adapters
|
|
8
|
+
function getAllValidFormatIds() {
|
|
9
|
+
const adapterIds = adapters_1.adapterRegistry.getIds();
|
|
10
|
+
const skillFormatIds = [...config_1.VALID_FORMAT_IDS];
|
|
11
|
+
return [...new Set([...adapterIds, ...skillFormatIds])];
|
|
12
|
+
}
|
|
6
13
|
const SUPPORTED_KEYS = ['default-format'];
|
|
7
14
|
function isValidKey(key) {
|
|
8
15
|
return SUPPORTED_KEYS.includes(key);
|
|
@@ -13,10 +20,11 @@ async function setConfigValue(key, value) {
|
|
|
13
20
|
}
|
|
14
21
|
if (key === 'default-format') {
|
|
15
22
|
const formats = value.split(',').map((f) => f.trim()).filter(Boolean);
|
|
16
|
-
// Validate
|
|
17
|
-
const
|
|
23
|
+
// Validate format IDs against union of skill formats and agent adapters
|
|
24
|
+
const validFormatIds = getAllValidFormatIds();
|
|
25
|
+
const invalidFormats = formats.filter((f) => !validFormatIds.includes(f));
|
|
18
26
|
if (invalidFormats.length > 0) {
|
|
19
|
-
throw new errors_1.CliError(`Invalid format ID(s): ${invalidFormats.join(', ')}. Valid formats: ${
|
|
27
|
+
throw new errors_1.CliError(`Invalid format ID(s): ${invalidFormats.join(', ')}. Valid formats: ${validFormatIds.join(', ')}`);
|
|
20
28
|
}
|
|
21
29
|
await (0, config_1.setDefaultFormats)(formats);
|
|
22
30
|
process.stdout.write(`Set default-format to: ${formats.join(',')}\n`);
|
package/dist/commands/formats.js
CHANGED
|
@@ -31,10 +31,7 @@ function registerFormatsCommand(program) {
|
|
|
31
31
|
process.stdout.write(` Supports: ${adapter.supportsAgentTypes.join(', ')} agents\n`);
|
|
32
32
|
process.stdout.write(` Format version: ${adapter.formatVersion}\n`);
|
|
33
33
|
for (const installPath of adapter.installPaths) {
|
|
34
|
-
|
|
35
|
-
? installPath.path
|
|
36
|
-
: installPath.path;
|
|
37
|
-
process.stdout.write(` ${installPath.scope}: ${pathDisplay}\n`);
|
|
34
|
+
process.stdout.write(` ${installPath.scope}: ${installPath.path}\n`);
|
|
38
35
|
}
|
|
39
36
|
process.stdout.write('\n');
|
|
40
37
|
}
|
package/dist/commands/install.js
CHANGED
|
@@ -13,6 +13,7 @@ const errors_1 = require("../lib/errors");
|
|
|
13
13
|
const analytics_1 = require("../lib/analytics");
|
|
14
14
|
const adapters_1 = require("../adapters");
|
|
15
15
|
const installed_1 = require("../lib/installed");
|
|
16
|
+
const agents_md_utils_1 = require("../lib/agents-md-utils");
|
|
16
17
|
const DEFAULT_VERSION = 'v1';
|
|
17
18
|
function parseAgentRef(value) {
|
|
18
19
|
const [ref, versionPart] = value.split('@');
|
|
@@ -96,7 +97,7 @@ function registerInstallCommand(program) {
|
|
|
96
97
|
}
|
|
97
98
|
}
|
|
98
99
|
// Validate scope
|
|
99
|
-
|
|
100
|
+
let scope = options.scope;
|
|
100
101
|
if (scope !== 'user' && scope !== 'project') {
|
|
101
102
|
throw new errors_1.CliError('Scope must be "user" or "project"');
|
|
102
103
|
}
|
|
@@ -104,6 +105,7 @@ function registerInstallCommand(program) {
|
|
|
104
105
|
process.stdout.write(`Fetching ${org}/${parsed.name}@${parsed.version}...\n`);
|
|
105
106
|
const agent = await downloadAgentWithFallback(resolved, org, parsed.name, parsed.version);
|
|
106
107
|
// Install for each format
|
|
108
|
+
let filesWritten = 0;
|
|
107
109
|
for (const formatId of targetFormats) {
|
|
108
110
|
const adapter = adapters_1.adapterRegistry.get(formatId);
|
|
109
111
|
if (!adapter) {
|
|
@@ -123,10 +125,18 @@ function registerInstallCommand(program) {
|
|
|
123
125
|
for (const warn of checkResult.warnings) {
|
|
124
126
|
process.stdout.write(`Warning (${formatId}): ${warn}\n`);
|
|
125
127
|
}
|
|
128
|
+
// Determine scope for this adapter (use local variable to not affect other formats)
|
|
129
|
+
let effectiveScope = scope;
|
|
130
|
+
const supportedScopes = adapter.installPaths.map(p => p.scope);
|
|
131
|
+
if (!supportedScopes.includes(effectiveScope)) {
|
|
132
|
+
process.stderr.write(`Warning: ${adapter.name} doesn't support '${scope}' scope. ` +
|
|
133
|
+
`Supported: ${supportedScopes.join(', ')}. Using '${supportedScopes[0]}' instead.\n`);
|
|
134
|
+
effectiveScope = supportedScopes[0];
|
|
135
|
+
}
|
|
126
136
|
// Convert
|
|
127
137
|
const files = adapter.convert(agent);
|
|
128
138
|
// Determine base directory
|
|
129
|
-
const baseDir =
|
|
139
|
+
const baseDir = effectiveScope === 'user' ? os_1.default.homedir() : process.cwd();
|
|
130
140
|
// Install each file
|
|
131
141
|
for (const file of files) {
|
|
132
142
|
const fullDir = path_1.default.join(baseDir, file.installPath);
|
|
@@ -138,13 +148,26 @@ function registerInstallCommand(program) {
|
|
|
138
148
|
}
|
|
139
149
|
// Create directory and write file
|
|
140
150
|
await promises_1.default.mkdir(fullDir, { recursive: true });
|
|
151
|
+
// Special handling for AGENTS.md - append/replace instead of overwrite
|
|
152
|
+
if (file.filename === 'AGENTS.md') {
|
|
153
|
+
let existingContent = '';
|
|
154
|
+
try {
|
|
155
|
+
existingContent = await promises_1.default.readFile(fullPath, 'utf-8');
|
|
156
|
+
}
|
|
157
|
+
catch {
|
|
158
|
+
// File doesn't exist, will create new
|
|
159
|
+
}
|
|
160
|
+
const agentRef = `${org}/${parsed.name}`;
|
|
161
|
+
file.content = (0, agents_md_utils_1.mergeAgentsMdContent)(existingContent, file.content, agentRef);
|
|
162
|
+
}
|
|
141
163
|
await promises_1.default.writeFile(fullPath, file.content);
|
|
164
|
+
filesWritten++;
|
|
142
165
|
// Track installation
|
|
143
166
|
const installedAgent = {
|
|
144
167
|
agent: `${org}/${parsed.name}`,
|
|
145
168
|
version: parsed.version,
|
|
146
169
|
format: formatId,
|
|
147
|
-
scope,
|
|
170
|
+
scope: effectiveScope,
|
|
148
171
|
path: fullPath,
|
|
149
172
|
installedAt: new Date().toISOString(),
|
|
150
173
|
adapterVersion: adapter.version,
|
|
@@ -155,17 +178,23 @@ function registerInstallCommand(program) {
|
|
|
155
178
|
}
|
|
156
179
|
}
|
|
157
180
|
if (!options.dryRun) {
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
181
|
+
if (filesWritten > 0) {
|
|
182
|
+
await (0, analytics_1.track)('cli_agent_install', {
|
|
183
|
+
agent: `${org}/${parsed.name}`,
|
|
184
|
+
formats: targetFormats,
|
|
185
|
+
scope,
|
|
186
|
+
});
|
|
187
|
+
process.stdout.write(`\nAgent installed successfully!\n`);
|
|
188
|
+
if (scope === 'user') {
|
|
189
|
+
process.stdout.write(`Available in all your projects.\n`);
|
|
190
|
+
}
|
|
191
|
+
else {
|
|
192
|
+
process.stdout.write(`Available in this project only.\n`);
|
|
193
|
+
}
|
|
166
194
|
}
|
|
167
195
|
else {
|
|
168
|
-
process.
|
|
196
|
+
process.stderr.write(`\nNo files were installed. Check warnings above.\n`);
|
|
197
|
+
process.exit(1);
|
|
169
198
|
}
|
|
170
199
|
}
|
|
171
200
|
});
|
package/dist/commands/skill.js
CHANGED
|
@@ -178,7 +178,12 @@ Instructions and guidance for AI agents...
|
|
|
178
178
|
else {
|
|
179
179
|
const defaults = await (0, config_1.getDefaultFormats)();
|
|
180
180
|
if (defaults.length > 0) {
|
|
181
|
-
|
|
181
|
+
// Filter to formats that have skill directories
|
|
182
|
+
targetFormats = defaults.filter(f => config_1.VALID_FORMAT_IDS.includes(f));
|
|
183
|
+
const skipped = defaults.filter(f => !config_1.VALID_FORMAT_IDS.includes(f));
|
|
184
|
+
if (skipped.length > 0) {
|
|
185
|
+
process.stderr.write(`Note: Skipping ${skipped.join(', ')} (no skill directory)\n`);
|
|
186
|
+
}
|
|
182
187
|
}
|
|
183
188
|
}
|
|
184
189
|
// Determine target directories
|
package/dist/commands/update.js
CHANGED
|
@@ -12,6 +12,7 @@ const api_1 = require("../lib/api");
|
|
|
12
12
|
const analytics_1 = require("../lib/analytics");
|
|
13
13
|
const adapters_1 = require("../adapters");
|
|
14
14
|
const installed_1 = require("../lib/installed");
|
|
15
|
+
const agents_md_utils_1 = require("../lib/agents-md-utils");
|
|
15
16
|
async function fetchLatestAgent(config, agentRef) {
|
|
16
17
|
const [org, name] = agentRef.split('/');
|
|
17
18
|
if (!org || !name)
|
|
@@ -97,12 +98,27 @@ function registerUpdateCommand(program) {
|
|
|
97
98
|
continue;
|
|
98
99
|
}
|
|
99
100
|
const files = adapter.convert(latest.agent);
|
|
101
|
+
if (files.length > 1) {
|
|
102
|
+
process.stderr.write(` Skipped: Multi-file adapters not supported for update. Reinstall instead.\n`);
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
100
105
|
for (const file of files) {
|
|
101
106
|
// Use the original path from tracking
|
|
102
107
|
const fullPath = item.path;
|
|
103
108
|
try {
|
|
104
109
|
const dir = path_1.default.dirname(fullPath);
|
|
105
110
|
await promises_1.default.mkdir(dir, { recursive: true });
|
|
111
|
+
// Special handling for AGENTS.md - append/replace instead of overwrite
|
|
112
|
+
if (file.filename === 'AGENTS.md') {
|
|
113
|
+
let existingContent = '';
|
|
114
|
+
try {
|
|
115
|
+
existingContent = await promises_1.default.readFile(fullPath, 'utf-8');
|
|
116
|
+
}
|
|
117
|
+
catch {
|
|
118
|
+
// File doesn't exist, will create new
|
|
119
|
+
}
|
|
120
|
+
file.content = (0, agents_md_utils_1.mergeAgentsMdContent)(existingContent, file.content, item.agent);
|
|
121
|
+
}
|
|
106
122
|
await promises_1.default.writeFile(fullPath, file.content);
|
|
107
123
|
// Update tracking
|
|
108
124
|
const updatedItem = {
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Utilities for handling AGENTS.md file updates
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.mergeAgentsMdContent = mergeAgentsMdContent;
|
|
7
|
+
const string_utils_1 = require("./string-utils");
|
|
8
|
+
/**
|
|
9
|
+
* Merge new content into an existing AGENTS.md file.
|
|
10
|
+
*
|
|
11
|
+
* - If the agent's section already exists (identified by markers), replace it
|
|
12
|
+
* - If the file has content but no section for this agent, append
|
|
13
|
+
* - If the file is empty/new, use the new content as-is
|
|
14
|
+
*
|
|
15
|
+
* @param existingContent - Current content of AGENTS.md (empty string if file doesn't exist)
|
|
16
|
+
* @param newContent - New content to merge (should include orchagent markers)
|
|
17
|
+
* @param agentRef - Agent reference like "org/agent-name" used in markers
|
|
18
|
+
* @returns Merged content
|
|
19
|
+
*/
|
|
20
|
+
function mergeAgentsMdContent(existingContent, newContent, agentRef) {
|
|
21
|
+
const markerStart = `<!-- orchagent:${agentRef} -->`;
|
|
22
|
+
const markerEnd = `<!-- /orchagent:${agentRef} -->`;
|
|
23
|
+
if (existingContent.includes(markerStart)) {
|
|
24
|
+
// Replace existing section
|
|
25
|
+
const regex = new RegExp(`${(0, string_utils_1.escapeRegex)(markerStart)}[\\s\\S]*?${(0, string_utils_1.escapeRegex)(markerEnd)}`, 'g');
|
|
26
|
+
return existingContent.replace(regex, newContent.trim());
|
|
27
|
+
}
|
|
28
|
+
else if (existingContent.trim()) {
|
|
29
|
+
// Append to existing file
|
|
30
|
+
return existingContent.trimEnd() + '\n\n' + newContent;
|
|
31
|
+
}
|
|
32
|
+
// New file, use content as-is
|
|
33
|
+
return newContent;
|
|
34
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Shared string utilities
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.escapeRegex = escapeRegex;
|
|
7
|
+
/**
|
|
8
|
+
* Escape special regex characters in a string
|
|
9
|
+
*/
|
|
10
|
+
function escapeRegex(str) {
|
|
11
|
+
return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
12
|
+
}
|