@orchagent/cli 0.3.1 → 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.
@@ -29,7 +29,8 @@ exports.agentsMdAdapter = {
29
29
  return { canConvert: true, warnings, errors };
30
30
  },
31
31
  convert(agent) {
32
- const agentRef = `${agent.org_slug}/${agent.name}`;
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,30 +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
- const normalized = name
25
- .toLowerCase()
26
- .replace(/[^a-z0-9-]/g, '-')
27
- .replace(/-+/g, '-')
28
- .replace(/^-|-$/g, '');
29
- return normalized || 'agent'; // Fallback if empty
30
- }
31
9
  exports.claudeCodeAdapter = {
32
10
  id: 'claude-code',
33
11
  name: 'Claude Code Sub-Agent',
@@ -69,7 +47,7 @@ exports.claudeCodeAdapter = {
69
47
  return { canConvert: true, warnings, errors };
70
48
  },
71
49
  convert(agent) {
72
- const normalizedName = normalizeAgentName(agent.name);
50
+ const normalizedName = (0, utils_1.normalizeAgentName)(agent.name);
73
51
  // Build frontmatter
74
52
  const frontmatter = {
75
53
  name: normalizedName,
@@ -78,7 +56,7 @@ exports.claudeCodeAdapter = {
78
56
  };
79
57
  // Map model if specified
80
58
  if (agent.default_models?.anthropic) {
81
- const modelAlias = mapModelToAlias(agent.default_models.anthropic);
59
+ const modelAlias = (0, utils_1.mapModelToAlias)(agent.default_models.anthropic);
82
60
  if (modelAlias !== 'inherit') {
83
61
  frontmatter.model = modelAlias;
84
62
  }
@@ -1,15 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.cursorAdapter = void 0;
4
- // Convert agent name to valid filename (lowercase + hyphens)
5
- function normalizeAgentName(name) {
6
- const normalized = name
7
- .toLowerCase()
8
- .replace(/[^a-z0-9-]/g, '-')
9
- .replace(/-+/g, '-')
10
- .replace(/^-|-$/g, '');
11
- return normalized || 'agent'; // Fallback if empty
12
- }
4
+ const utils_1 = require("./utils");
13
5
  exports.cursorAdapter = {
14
6
  id: 'cursor',
15
7
  name: 'Cursor Rules',
@@ -44,7 +36,7 @@ exports.cursorAdapter = {
44
36
  return { canConvert: true, warnings, errors };
45
37
  },
46
38
  convert(agent) {
47
- const normalizedName = normalizeAgentName(agent.name);
39
+ const normalizedName = (0, utils_1.normalizeAgentName)(agent.name);
48
40
  const description = agent.description || `Rules from ${agent.name}`;
49
41
  // Cursor .mdc format
50
42
  const content = `---
@@ -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
+ }
@@ -4,6 +4,12 @@ exports.registerConfigCommand = registerConfigCommand;
4
4
  const config_1 = require("../lib/config");
5
5
  const errors_1 = require("../lib/errors");
6
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
+ }
7
13
  const SUPPORTED_KEYS = ['default-format'];
8
14
  function isValidKey(key) {
9
15
  return SUPPORTED_KEYS.includes(key);
@@ -14,8 +20,8 @@ async function setConfigValue(key, value) {
14
20
  }
15
21
  if (key === 'default-format') {
16
22
  const formats = value.split(',').map((f) => f.trim()).filter(Boolean);
17
- // Validate all format IDs against adapter registry
18
- const validFormatIds = adapters_1.adapterRegistry.getIds();
23
+ // Validate format IDs against union of skill formats and agent adapters
24
+ const validFormatIds = getAllValidFormatIds();
19
25
  const invalidFormats = formats.filter((f) => !validFormatIds.includes(f));
20
26
  if (invalidFormats.length > 0) {
21
27
  throw new errors_1.CliError(`Invalid format ID(s): ${invalidFormats.join(', ')}. Valid formats: ${validFormatIds.join(', ')}`);
@@ -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
- const pathDisplay = installPath.scope === 'user'
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
  }
@@ -13,10 +13,8 @@ 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
- function escapeRegex(str) {
18
- return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
19
- }
20
18
  function parseAgentRef(value) {
21
19
  const [ref, versionPart] = value.split('@');
22
20
  const version = versionPart?.trim() || DEFAULT_VERSION;
@@ -127,18 +125,18 @@ function registerInstallCommand(program) {
127
125
  for (const warn of checkResult.warnings) {
128
126
  process.stdout.write(`Warning (${formatId}): ${warn}\n`);
129
127
  }
130
- // Check if adapter supports requested scope
128
+ // Determine scope for this adapter (use local variable to not affect other formats)
129
+ let effectiveScope = scope;
131
130
  const supportedScopes = adapter.installPaths.map(p => p.scope);
132
- if (!supportedScopes.includes(scope)) {
131
+ if (!supportedScopes.includes(effectiveScope)) {
133
132
  process.stderr.write(`Warning: ${adapter.name} doesn't support '${scope}' scope. ` +
134
133
  `Supported: ${supportedScopes.join(', ')}. Using '${supportedScopes[0]}' instead.\n`);
135
- // Use the first supported scope
136
- scope = supportedScopes[0];
134
+ effectiveScope = supportedScopes[0];
137
135
  }
138
136
  // Convert
139
137
  const files = adapter.convert(agent);
140
138
  // Determine base directory
141
- const baseDir = scope === 'user' ? os_1.default.homedir() : process.cwd();
139
+ const baseDir = effectiveScope === 'user' ? os_1.default.homedir() : process.cwd();
142
140
  // Install each file
143
141
  for (const file of files) {
144
142
  const fullDir = path_1.default.join(baseDir, file.installPath);
@@ -160,18 +158,7 @@ function registerInstallCommand(program) {
160
158
  // File doesn't exist, will create new
161
159
  }
162
160
  const agentRef = `${org}/${parsed.name}`;
163
- const markerStart = `<!-- orchagent:${agentRef} -->`;
164
- const markerEnd = `<!-- /orchagent:${agentRef} -->`;
165
- if (existingContent.includes(markerStart)) {
166
- // Replace existing section
167
- const regex = new RegExp(`${escapeRegex(markerStart)}[\\s\\S]*?${escapeRegex(markerEnd)}`, 'g');
168
- file.content = existingContent.replace(regex, file.content.trim());
169
- }
170
- else if (existingContent) {
171
- // Append to existing file
172
- file.content = existingContent.trimEnd() + '\n\n' + file.content;
173
- }
174
- // else: new file, use content as-is
161
+ file.content = (0, agents_md_utils_1.mergeAgentsMdContent)(existingContent, file.content, agentRef);
175
162
  }
176
163
  await promises_1.default.writeFile(fullPath, file.content);
177
164
  filesWritten++;
@@ -180,7 +167,7 @@ function registerInstallCommand(program) {
180
167
  agent: `${org}/${parsed.name}`,
181
168
  version: parsed.version,
182
169
  format: formatId,
183
- scope,
170
+ scope: effectiveScope,
184
171
  path: fullPath,
185
172
  installedAt: new Date().toISOString(),
186
173
  adapterVersion: adapter.version,
@@ -12,9 +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
- function escapeRegex(str) {
16
- return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
17
- }
15
+ const agents_md_utils_1 = require("../lib/agents-md-utils");
18
16
  async function fetchLatestAgent(config, agentRef) {
19
17
  const [org, name] = agentRef.split('/');
20
18
  if (!org || !name)
@@ -119,19 +117,7 @@ function registerUpdateCommand(program) {
119
117
  catch {
120
118
  // File doesn't exist, will create new
121
119
  }
122
- const agentRef = item.agent;
123
- const markerStart = `<!-- orchagent:${agentRef} -->`;
124
- const markerEnd = `<!-- /orchagent:${agentRef} -->`;
125
- if (existingContent.includes(markerStart)) {
126
- // Replace existing section
127
- const regex = new RegExp(`${escapeRegex(markerStart)}[\\s\\S]*?${escapeRegex(markerEnd)}`, 'g');
128
- file.content = existingContent.replace(regex, file.content.trim());
129
- }
130
- else if (existingContent) {
131
- // Append to existing file
132
- file.content = existingContent.trimEnd() + '\n\n' + file.content;
133
- }
134
- // else: new file, use content as-is
120
+ file.content = (0, agents_md_utils_1.mergeAgentsMdContent)(existingContent, file.content, item.agent);
135
121
  }
136
122
  await promises_1.default.writeFile(fullPath, file.content);
137
123
  // Update tracking
@@ -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
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@orchagent/cli",
3
- "version": "0.3.1",
3
+ "version": "0.3.2",
4
4
  "description": "Command-line interface for the orchagent AI agent marketplace",
5
5
  "license": "MIT",
6
6
  "author": "orchagent <hello@orchagent.io>",