UNPKG

@agentled/cli

Version:

CLI for Agentled — manage workflows, apps, and knowledge from the command line. Zero context-window cost for AI agents.

159 lines 7.96 kB
/* eslint-disable no-console */ import { describeSkillsInstall, getSkillsTargetDir, getCodexSkillsDir, getOpenClawSkillsDir, getHermesSkillsDir, installSkills, resolveBundledSkillsDir, exportSkillToTarget, buildCodexPlugin, listSkillModules, NON_NATIVE_TARGETS, } from '../utils/skills.js'; import { existsSync, readdirSync, readFileSync } from 'node:fs'; import { join } from 'node:path'; function parseSkillVersion(skillMdPath) { try { const content = readFileSync(skillMdPath, 'utf-8'); const fmMatch = content.match(/^---\n([\s\S]*?)\n---/); if (!fmMatch) return null; const versionMatch = fmMatch[1].match(/^version:\s*(.+)$/m); return versionMatch ? versionMatch[1].trim() : null; } catch { return null; } } export function registerSkillsCommands(program) { const skills = program .command('skills') .description('Manage Claude Code skills bundled with the CLI'); skills .command('install') .description('Install the bundled Agentled skill (Claude Code by default; also Codex, OpenClaw, Hermes, Cursor, Gemini, AGENTS.md, codex-plugin)') .option('--project', 'Install into the current project\'s .claude/skills/ instead of the user-global location') .option('--force', 'Overwrite existing skill files even if they contain local edits') .option('--target <target>', 'Where to install: claude | codex | openclaw | hermes | cursor | agents | gemini | codex-plugin', 'claude') .action((opts) => { try { const target = String(opts.target).toLowerCase(); // Codex plugin package — scaffold a directory with a manifest + skill bundle. if (target === 'codex-plugin') { const skillDir = join(resolveBundledSkillsDir(), 'agentled'); const { pluginDir, manifestPath } = buildCodexPlugin(skillDir, process.cwd()); console.log(` ✓ agentled Codex plugin scaffolded → ${pluginDir}`); console.log(` manifest: ${manifestPath}`); console.log(` Install it in Codex via "Install plugin" → local path, or add it to a local marketplace.`); return; } // Single-file exports for agents that read one markdown context file // (Cursor / Gemini / AGENTS.md). if (NON_NATIVE_TARGETS.includes(target)) { const sourceDir = resolveBundledSkillsDir(); const skillDir = join(sourceDir, 'agentled'); const result = exportSkillToTarget(target, skillDir, process.cwd(), { force: opts.force }); if (result.action === 'written-sidecar') { const conventional = target === 'agents' ? 'AGENTS.md' : 'GEMINI.md'; console.log(` ✓ agentled exported → ${result.path}`); console.log(` • ${conventional} already exists — wrote a sidecar instead of overwriting. Include it, or re-run with --force to replace.`); } else { console.log(` ✓ agentled exported → ${result.path}`); } return; } // Native skill-directory installs (Claude Code, Codex, OpenClaw, Hermes). // These all read `<dir>/<skill>/SKILL.md`, so we copy the full bundle. const skillDirTargets = { codex: getCodexSkillsDir(), openclaw: getOpenClawSkillsDir(), hermes: getHermesSkillsDir(), }; const explicitDir = skillDirTargets[target]; if (explicitDir) { const results = installSkills({ targetDir: explicitDir, force: opts.force }); console.log(describeSkillsInstall(results, explicitDir)); return; } if (target !== 'claude') { console.error(`Error: unknown --target "${opts.target}". Use one of: claude, codex, openclaw, hermes, cursor, agents, gemini, codex-plugin.`); process.exit(1); } const isGlobal = !opts.project; const targetDir = getSkillsTargetDir(isGlobal); const results = installSkills({ global: isGlobal, force: opts.force }); console.log(describeSkillsInstall(results, targetDir)); } catch (e) { console.error(`Error: ${e.message}`); process.exit(1); } }); skills .command('list') .description('List the composable reference modules inside the Agentled skill') .action(() => { const skillDir = join(resolveBundledSkillsDir(), 'agentled'); const modules = listSkillModules(skillDir); if (modules.length === 0) { console.log('No reference modules bundled with this CLI version.'); return; } console.log('Agentled skill — composable reference modules (loaded on demand):\n'); for (const m of modules) { console.log(` ${m.file}`); console.log(` ${m.title}`); if (m.loadWhen) console.log(` ↳ ${m.loadWhen}`); console.log(''); } console.log('The router (SKILL.md) points the agent at these by task. Export all of them'); console.log('as one file for other agents with: agentled skills install --target cursor|agents|gemini'); }); skills .command('update') .description('Refresh the installed skill to the version bundled with this CLI') .option('--project', 'Update the project-level skill (default: user-global)') .option('--force', 'Overwrite even if the installed skill has local edits') .action((opts) => { try { const isGlobal = !opts.project; const targetDir = getSkillsTargetDir(isGlobal); const results = installSkills({ global: isGlobal, force: opts.force }); console.log(describeSkillsInstall(results, targetDir)); } catch (e) { console.error(`Error: ${e.message}`); process.exit(1); } }); skills .command('status') .description('Show bundled vs installed skill versions') .option('--project', 'Check the project-level skills (default: user-global)') .action((opts) => { const isGlobal = !opts.project; const targetDir = getSkillsTargetDir(isGlobal); const sourceDir = resolveBundledSkillsDir(); if (!existsSync(sourceDir)) { console.log(`No bundled skills found (${sourceDir}). Reinstall @agentled/cli.`); return; } const bundled = readdirSync(sourceDir, { withFileTypes: true }) .filter(d => d.isDirectory()) .map(d => d.name); if (bundled.length === 0) { console.log('No skills bundled with this CLI version.'); return; } for (const name of bundled) { const bundledVersion = parseSkillVersion(join(sourceDir, name, 'SKILL.md')) ?? '?'; const installedSkillMd = join(targetDir, name, 'SKILL.md'); const installedVersion = existsSync(installedSkillMd) ? (parseSkillVersion(installedSkillMd) ?? 'unknown') : null; if (installedVersion === null) { console.log(` ${name}: bundled v${bundledVersion}, not installed`); } else if (installedVersion === bundledVersion) { console.log(` ${name}: bundled v${bundledVersion}, installed v${installedVersion} (up to date)`); } else { console.log(` ${name}: bundled v${bundledVersion}, installed v${installedVersion}`); } } console.log(`\nSkills directory: ${targetDir}`); }); } //# sourceMappingURL=skills.js.map