@orchagent/cli 0.3.2 → 0.3.4

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.
@@ -6,7 +6,7 @@ exports.agentsMdAdapter = {
6
6
  name: 'AGENTS.md (Universal)',
7
7
  version: '1.0.0',
8
8
  formatVersion: '1.0',
9
- supportsAgentTypes: ['prompt', 'skill'],
9
+ supportedTypes: ['prompt', 'skill'],
10
10
  installPaths: [
11
11
  {
12
12
  scope: 'project',
@@ -11,7 +11,7 @@ exports.claudeCodeAdapter = {
11
11
  name: 'Claude Code Sub-Agent',
12
12
  version: '1.0.0',
13
13
  formatVersion: '2026-01',
14
- supportsAgentTypes: ['prompt', 'skill'],
14
+ supportedTypes: ['prompt', 'skill'],
15
15
  installPaths: [
16
16
  {
17
17
  scope: 'user',
@@ -7,7 +7,7 @@ exports.cursorAdapter = {
7
7
  name: 'Cursor Rules',
8
8
  version: '1.0.0',
9
9
  formatVersion: '2026-01',
10
- supportsAgentTypes: ['prompt', 'skill'],
10
+ supportedTypes: ['prompt', 'skill'],
11
11
  installPaths: [
12
12
  {
13
13
  scope: 'project',
@@ -35,7 +35,8 @@ async function getConfigValue(key) {
35
35
  throw new errors_1.CliError(`Unknown config key: ${key}. Supported keys: ${SUPPORTED_KEYS.join(', ')}`);
36
36
  }
37
37
  if (key === 'default-format') {
38
- const formats = await (0, config_1.getDefaultFormats)();
38
+ const resolved = await (0, config_1.getResolvedConfig)();
39
+ const formats = await (0, config_1.getDefaultFormats)(resolved);
39
40
  if (formats.length === 0) {
40
41
  process.stdout.write('(not set)\n');
41
42
  }
@@ -19,7 +19,7 @@ function registerFormatsCommand(program) {
19
19
  name: a.name,
20
20
  version: a.version,
21
21
  formatVersion: a.formatVersion,
22
- supportsAgentTypes: a.supportsAgentTypes,
22
+ supportedTypes: a.supportedTypes,
23
23
  installPaths: a.installPaths,
24
24
  }));
25
25
  process.stdout.write(JSON.stringify(data, null, 2) + '\n');
@@ -28,7 +28,8 @@ function registerFormatsCommand(program) {
28
28
  process.stdout.write('\nAvailable export formats:\n\n');
29
29
  for (const adapter of adapters) {
30
30
  process.stdout.write(` ${chalk_1.default.cyan(adapter.id)} ${adapter.name}\n`);
31
- process.stdout.write(` Supports: ${adapter.supportsAgentTypes.join(', ')} agents\n`);
31
+ const typeLabels = adapter.supportedTypes.map(t => t === 'skill' ? 'skills' : `${t} agents`);
32
+ process.stdout.write(` Supports: ${typeLabels.join(', ')}\n`);
32
33
  process.stdout.write(` Format version: ${adapter.formatVersion}\n`);
33
34
  for (const installPath of adapter.installPaths) {
34
35
  process.stdout.write(` ${installPath.scope}: ${installPath.path}\n`);
@@ -87,7 +87,7 @@ function registerInstallCommand(program) {
87
87
  }
88
88
  }
89
89
  else {
90
- const defaults = await (0, config_1.getDefaultFormats)();
90
+ const defaults = await (0, config_1.getDefaultFormats)(resolved);
91
91
  if (defaults.length > 0) {
92
92
  targetFormats = defaults;
93
93
  }
@@ -29,14 +29,14 @@ const DEFAULT_VERSION = 'v1';
29
29
  * - https://github.com/skillcreatorai/Ai-Agent-Skills
30
30
  */
31
31
  const AI_TOOL_SKILL_DIRS = [
32
- { name: 'Claude Code', path: '.claude/skills' },
33
- { name: 'Cursor', path: '.cursor/skills' },
34
- { name: 'Codex', path: '.codex/skills' },
35
- { name: 'Amp', path: '.agents/skills' },
36
- { name: 'OpenCode', path: '.opencode/skill' },
37
- { name: 'Antigravity', path: '.agent/skills' },
32
+ { name: 'Claude Code', projectPath: '.claude/skills', userPath: '.claude/skills' },
33
+ { name: 'Cursor', projectPath: '.cursor/skills', userPath: '.cursor/skills' },
34
+ { name: 'Codex', projectPath: '.codex/skills', userPath: '.codex/skills' },
35
+ { name: 'Amp', projectPath: '.agents/skills', userPath: '.agents/skills' },
36
+ { name: 'OpenCode', projectPath: '.opencode/skill', userPath: '.opencode/skill' },
37
+ { name: 'Antigravity', projectPath: '.agent/skills', userPath: '.agent/skills' },
38
38
  // TODO: Add more as we research them:
39
- // { name: 'Windsurf', path: '.windsurf/skills' },
39
+ // { name: 'Windsurf', projectPath: '.windsurf/skills', userPath: '.windsurf/skills' },
40
40
  ];
41
41
  function parseSkillRef(value) {
42
42
  const [ref, versionPart] = value.split('@');
@@ -161,6 +161,7 @@ Instructions and guidance for AI agents...
161
161
  .command('install <skill>')
162
162
  .description('Install skill to local AI tool directories (Claude Code, Cursor, etc.)')
163
163
  .option('--global', 'Install to home directory (default: current directory)')
164
+ .option('--scope <scope>', 'Install scope: user or project', 'project')
164
165
  .option('--dry-run', 'Show what would be installed without making changes')
165
166
  .option('--format <formats>', 'Comma-separated format IDs (e.g., claude-code,cursor)')
166
167
  .action(async (skillRef, options) => {
@@ -176,7 +177,7 @@ Instructions and guidance for AI agents...
176
177
  }
177
178
  }
178
179
  else {
179
- const defaults = await (0, config_1.getDefaultFormats)();
180
+ const defaults = await (0, config_1.getDefaultFormats)(resolved);
180
181
  if (defaults.length > 0) {
181
182
  // Filter to formats that have skill directories
182
183
  targetFormats = defaults.filter(f => config_1.VALID_FORMAT_IDS.includes(f));
@@ -202,8 +203,8 @@ Instructions and guidance for AI agents...
202
203
  'The skill exists but has an empty prompt. This may be a publishing issue.\n' +
203
204
  'Try re-publishing the skill or contact the skill author.');
204
205
  }
205
- // Determine base directory (home or current)
206
- const baseDir = options.global ? os_1.default.homedir() : process.cwd();
206
+ // Determine scope (--global is legacy alias for --scope user)
207
+ const scope = options.global ? 'user' : (options.scope || 'project');
207
208
  // Build skill content with header
208
209
  const skillContent = `# ${skillData.name}
209
210
 
@@ -216,9 +217,11 @@ ${skillData.prompt}
216
217
  // Dry run - show what would be installed
217
218
  if (options.dryRun) {
218
219
  process.stdout.write(`Would install ${org}/${parsed.skill}@${parsed.version}\n\n`);
219
- process.stdout.write(`Target directories:\n`);
220
+ process.stdout.write(`Target directories (scope: ${scope}):\n`);
220
221
  for (const tool of toolDirs) {
221
- const skillDir = path_1.default.join(baseDir, tool.path);
222
+ const baseDir = scope === 'user' ? os_1.default.homedir() : process.cwd();
223
+ const toolPath = scope === 'user' ? tool.userPath : tool.projectPath;
224
+ const skillDir = path_1.default.join(baseDir, toolPath);
222
225
  const skillFile = path_1.default.join(skillDir, `${parsed.skill}.md`);
223
226
  process.stdout.write(` - ${tool.name}: ${skillFile}\n`);
224
227
  }
@@ -228,7 +231,9 @@ ${skillData.prompt}
228
231
  // Install to target AI tool directories
229
232
  const installed = [];
230
233
  for (const tool of toolDirs) {
231
- const skillDir = path_1.default.join(baseDir, tool.path);
234
+ const baseDir = scope === 'user' ? os_1.default.homedir() : process.cwd();
235
+ const toolPath = scope === 'user' ? tool.userPath : tool.projectPath;
236
+ const skillDir = path_1.default.join(baseDir, toolPath);
232
237
  const skillFile = path_1.default.join(skillDir, `${parsed.skill}.md`);
233
238
  try {
234
239
  await promises_1.default.mkdir(skillDir, { recursive: true });
@@ -237,7 +242,7 @@ ${skillData.prompt}
237
242
  }
238
243
  catch (err) {
239
244
  // Skip if we can't write (e.g., permission issues)
240
- process.stderr.write(`Warning: Could not install to ${tool.path}: ${err.message}\n`);
245
+ process.stderr.write(`Warning: Could not install to ${toolPath}: ${err.message}\n`);
241
246
  }
242
247
  }
243
248
  if (installed.length === 0) {
@@ -245,7 +250,7 @@ ${skillData.prompt}
245
250
  }
246
251
  await (0, analytics_1.track)('cli_skill_install', {
247
252
  skill: `${org}/${parsed.skill}`,
248
- global: Boolean(options.global),
253
+ scope,
249
254
  });
250
255
  // Report authenticated install to backend (fire-and-forget)
251
256
  // This tracks unique installers for manipulation-resistant metrics
@@ -257,6 +262,6 @@ ${skillData.prompt}
257
262
  for (const tool of installed) {
258
263
  process.stdout.write(` - ${tool}\n`);
259
264
  }
260
- process.stdout.write(`\nLocation: ${options.global ? '~/' : './'}\n`);
265
+ process.stdout.write(`\nLocation: ${scope === 'user' ? '~/' : './'}\n`);
261
266
  });
262
267
  }
package/dist/lib/api.js CHANGED
@@ -57,6 +57,7 @@ exports.checkAgentDelete = checkAgentDelete;
57
57
  exports.deleteAgent = deleteAgent;
58
58
  exports.previewAgentVersion = previewAgentVersion;
59
59
  exports.reportInstall = reportInstall;
60
+ exports.fetchUserProfile = fetchUserProfile;
60
61
  const errors_1 = require("./errors");
61
62
  const DEFAULT_TIMEOUT_MS = 15000;
62
63
  const MAX_RETRIES = 3;
@@ -349,3 +350,10 @@ async function reportInstall(config, org, skill, version, cliVersion) {
349
350
  headers: { 'X-CLI-Version': cliVersion },
350
351
  });
351
352
  }
353
+ /**
354
+ * Fetch the current user's profile from the server.
355
+ */
356
+ async function fetchUserProfile(config) {
357
+ const result = await request(config, 'GET', '/users/me');
358
+ return result.user;
359
+ }
@@ -1,4 +1,37 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
2
35
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
36
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
37
  };
@@ -20,12 +53,12 @@ const DEFAULT_API_URL = 'https://api.orchagent.io';
20
53
  exports.VALID_FORMAT_IDS = ['claude-code', 'cursor', 'codex', 'amp', 'opencode', 'antigravity'];
21
54
  // Map format IDs to skill directories (used by skill install and agent install)
22
55
  exports.FORMAT_SKILL_DIRS = {
23
- 'claude-code': { name: 'Claude Code', path: '.claude/skills' },
24
- 'cursor': { name: 'Cursor', path: '.cursor/skills' },
25
- 'codex': { name: 'Codex', path: '.codex/skills' },
26
- 'amp': { name: 'Amp', path: '.agents/skills' },
27
- 'opencode': { name: 'OpenCode', path: '.opencode/skill' },
28
- 'antigravity': { name: 'Antigravity', path: '.agent/skills' },
56
+ 'claude-code': { name: 'Claude Code', projectPath: '.claude/skills', userPath: '.claude/skills' },
57
+ 'cursor': { name: 'Cursor', projectPath: '.cursor/skills', userPath: '.cursor/skills' },
58
+ 'codex': { name: 'Codex', projectPath: '.codex/skills', userPath: '.codex/skills' },
59
+ 'amp': { name: 'Amp', projectPath: '.agents/skills', userPath: '.agents/skills' },
60
+ 'opencode': { name: 'OpenCode', projectPath: '.opencode/skill', userPath: '.opencode/skill' },
61
+ 'antigravity': { name: 'Antigravity', projectPath: '.agent/skills', userPath: '.agent/skills' },
29
62
  };
30
63
  async function loadConfig() {
31
64
  try {
@@ -70,9 +103,27 @@ async function getResolvedConfig(overrides = {}, profile) {
70
103
  function getConfigPath() {
71
104
  return CONFIG_PATH;
72
105
  }
73
- async function getDefaultFormats() {
106
+ async function getDefaultFormats(resolvedConfig) {
107
+ // 1. Check local config first (explicit override)
74
108
  const config = await loadConfig();
75
- return config.default_formats ?? [];
109
+ if (config.default_formats?.length) {
110
+ return config.default_formats;
111
+ }
112
+ // 2. Try server preferences (if logged in)
113
+ if (resolvedConfig?.apiKey) {
114
+ try {
115
+ const { fetchUserProfile } = await Promise.resolve().then(() => __importStar(require('./api')));
116
+ const user = await fetchUserProfile(resolvedConfig);
117
+ if (user.preferences?.default_formats?.length) {
118
+ return user.preferences.default_formats;
119
+ }
120
+ }
121
+ catch {
122
+ // Offline or not logged in - use defaults
123
+ }
124
+ }
125
+ // 3. Return empty (no default = install to all)
126
+ return [];
76
127
  }
77
128
  async function setDefaultFormats(formats) {
78
129
  const config = await loadConfig();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@orchagent/cli",
3
- "version": "0.3.2",
3
+ "version": "0.3.4",
4
4
  "description": "Command-line interface for the orchagent AI agent marketplace",
5
5
  "license": "MIT",
6
6
  "author": "orchagent <hello@orchagent.io>",
@@ -50,7 +50,7 @@
50
50
  "commander": "^11.1.0",
51
51
  "open": "^10.0.0",
52
52
  "posthog-node": "^4.0.0",
53
- "update-notifier": "^7.3.1",
53
+ "update-notifier": "^6.0.2",
54
54
  "yaml": "^2.8.2"
55
55
  },
56
56
  "devDependencies": {