guolei-agents 1.0.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/bin/agents.js +19 -0
- package/build.mjs +47 -0
- package/dist/agents.js +19 -0
- package/dist/index.js +577 -0
- package/dist/index.js.map +7 -0
- package/dist/templates/default-agent.md +35 -0
- package/package.json +38 -0
- package/src/commands/add.ts +44 -0
- package/src/commands/check.ts +11 -0
- package/src/commands/find.ts +25 -0
- package/src/commands/init.ts +84 -0
- package/src/commands/list.ts +42 -0
- package/src/commands/remove.ts +42 -0
- package/src/commands/update.ts +12 -0
- package/src/core/discover.ts +129 -0
- package/src/core/installer.ts +169 -0
- package/src/core/parser.ts +55 -0
- package/src/index.ts +64 -0
- package/src/types/index.ts +78 -0
- package/src/utils/filesystem.ts +177 -0
- package/src/utils/logger.ts +13 -0
- package/templates/default-agent.md +35 -0
- package/tsconfig.json +20 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/index.ts", "../src/commands/add.ts", "../src/core/installer.ts", "../src/core/parser.ts", "../src/core/discover.ts", "../src/utils/filesystem.ts", "../src/utils/logger.ts", "../src/commands/list.ts", "../src/commands/remove.ts", "../src/commands/init.ts", "../src/commands/find.ts", "../src/commands/check.ts", "../src/commands/update.ts"],
|
|
4
|
+
"sourcesContent": ["#!/usr/bin/env node\n\nimport { Command } from 'commander';\nimport chalk from 'chalk';\nimport { addCommand } from './commands/add.js';\nimport { listCommand } from './commands/list.js';\nimport { removeCommand } from './commands/remove.js';\nimport { initCommand } from './commands/init.js';\nimport { findCommand } from './commands/find.js';\nimport { checkCommand } from './commands/check.js';\nimport { updateCommand } from './commands/update.js';\n\nconst program = new Command();\n\nprogram\n .name('agents')\n .description('CLI for managing AI coding agents')\n .version('1.0.0');\n\nprogram\n .command('add <source>')\n .description('Install one or more agents from a GitHub repository or local path')\n .option('-g, --global', 'Install to global directory', false)\n .option('-a, --agent <agents...>', 'Target agent platform(s)')\n .option('--agent-name <name>', 'Name for the installed agent')\n .option('-y, --yes', 'Skip confirmation', false)\n .option('--copy', 'Copy instead of symlink', false)\n .action(addCommand);\n\nprogram\n .command('list')\n .description('List installed agents')\n .option('-g, --global', 'List only global agents')\n .option('-a, --agent <agent>', 'Filter by platform')\n .action(listCommand);\n\nprogram\n .command('remove <name>')\n .description('Remove an installed agent')\n .option('-g, --global', 'Remove from global directory')\n .option('-a, --agent <agent>', 'Remove from specific platform')\n .action(removeCommand);\n\nprogram\n .command('init [name]')\n .description('Create a new agent definition template')\n .action(initCommand);\n\nprogram\n .command('find [query]')\n .description('Search for available agents')\n .action(findCommand);\n\nprogram\n .command('check')\n .description('Check for updates to installed agents')\n .action(checkCommand);\n\nprogram\n .command('update')\n .description('Update all installed agents to the latest version')\n .action(updateCommand);\n\nprogram.parse();\n", "import ora from 'ora';\nimport { installAgent } from '../core/installer.js';\nimport { detectPlatforms } from '../utils/filesystem.js';\nimport { logger } from '../utils/logger.js';\nimport type { AgentPlatform, InstallOptions } from '../types/index.js';\n\ninterface AddCommandOptions {\n global: boolean;\n agent: string[] | undefined;\n agentName: string | undefined;\n yes: boolean;\n copy: boolean;\n}\n\nexport async function addCommand(source: string, options: AddCommandOptions): Promise<void> {\n const spinner = ora('Installing agent...').start();\n\n try {\n let platforms: AgentPlatform[];\n \n if (options.agent && options.agent.length > 0) {\n platforms = options.agent as AgentPlatform[];\n } else {\n platforms = detectPlatforms();\n }\n\n const installOptions: InstallOptions = {\n source,\n global: options.global,\n platforms,\n agentName: options.agentName,\n copy: options.copy,\n yes: options.yes,\n };\n\n await installAgent(installOptions);\n \n spinner.succeed(`Successfully installed agent from ${source}`);\n } catch (err) {\n spinner.fail(`Failed to install agent: ${err instanceof Error ? err.message : String(err)}`);\n logger.error(String(err));\n process.exit(1);\n }\n}\n", "import { join, basename } from 'path';\nimport { existsSync, readdirSync, readFileSync, mkdirSync, copyFileSync, symlinkSync, rmSync } from 'fs';\nimport { tmpdir, homedir } from 'os';\nimport { mkdtempSync, rmSync as rmSyncFs } from 'fs';\nimport { parseAgentFile } from './parser.js';\nimport { discoverFromDirectory } from './discover.js';\nimport { ensureDir, getPlatformPaths, isDirectory, findFiles } from '../utils/filesystem.js';\nimport { logger } from '../utils/logger.js';\nimport type { AgentPlatform, AgentFile, InstallOptions } from '../types/index.js';\n\nexport async function installAgent(options: InstallOptions): Promise<void> {\n const { source, global, platforms, agentName, copy } = options;\n \n logger.info(`Installing agent from: ${source}`);\n\n const tempDir = await fetchSource(source);\n \n try {\n const agents = await discoverFromDirectory(tempDir);\n \n if (agents.length === 0) {\n throw new Error('No agents found in the source');\n }\n\n for (const platform of platforms) {\n const targetPaths = getPlatformPaths(platform, global);\n \n for (const targetPath of targetPaths) {\n ensureDir(targetPath);\n \n for (const agentFile of agents) {\n const name = agentName || agentFile.agent.name || basename(agentFile.path, '.md');\n const finalPath = join(targetPath, `${name}.md`);\n \n if (existsSync(finalPath) && !options.yes) {\n logger.warn(`Agent \"${name}\" already exists at ${finalPath}`);\n continue;\n }\n\n if (copy) {\n const sourcePath = agentFile.path;\n if (isDirectory(sourcePath)) {\n copyDirectory(sourcePath, join(targetPath, name));\n } else {\n copyFileSync(sourcePath, finalPath);\n }\n logger.success(`Copied agent \"${name}\" to ${finalPath}`);\n } else {\n const sourceDir = tempDir;\n try {\n symlinkSync(sourceDir, finalPath, 'dir');\n logger.success(`Symlinked agent \"${name}\" to ${finalPath}`);\n } catch (err) {\n logger.warn(`Failed to create symlink, copying instead: ${err}`);\n copyDirectory(sourceDir, join(targetPath, name));\n logger.success(`Copied agent \"${name}\" to ${targetPath}`);\n }\n }\n }\n }\n }\n } finally {\n if (existsSync(tempDir) && tempDir.startsWith(tmpdir())) {\n rmSync(tempDir, { recursive: true, force: true });\n }\n }\n}\n\nasync function fetchSource(source: string): Promise<string> {\n if (source.startsWith('.') || source.startsWith('/') || /^[a-zA-Z]:\\\\/.test(source)) {\n return source;\n }\n\n const degit = await import('degit');\n const tempDir = mkdtempSync(join(tmpdir(), 'npx-agents-'));\n \n const parts = source.split('/');\n let owner = parts[0];\n let repo = parts[1]?.replace(/#.+$/, '') || '';\n let ref = '';\n \n if (source.includes('#')) {\n const [repoPart, refPart] = source.split('#');\n repo = repoPart.split('/')[1];\n ref = refPart;\n }\n\n try {\n const target = ref ? `${owner}/${repo}#${ref}` : `${owner}/${repo}`;\n await degit.default(target).clone(tempDir);\n return tempDir;\n } catch (err) {\n rmSync(tempDir, { recursive: true, force: true });\n throw new Error(`Failed to fetch from ${source}: ${err}`);\n }\n}\n\nfunction copyDirectory(source: string, target: string): void {\n ensureDir(target);\n const files = readdirSync(source);\n for (const file of files) {\n const srcPath = join(source, file);\n const destPath = join(target, file);\n if (isDirectory(srcPath)) {\n copyDirectory(srcPath, destPath);\n } else {\n copyFileSync(srcPath, destPath);\n }\n }\n}\n\nexport function listInstalledAgents(platform: AgentPlatform, global: boolean): AgentFile[] {\n const agents: AgentFile[] = [];\n const paths = getPlatformPaths(platform, global);\n \n for (const path of paths) {\n if (!existsSync(path)) continue;\n \n const mdFiles = findFiles(path, /\\.md$/);\n for (const file of mdFiles) {\n try {\n const content = readFileSync(file, 'utf-8');\n const agentFile = parseAgentFile(content, file);\n agents.push(agentFile);\n } catch (err) {\n continue;\n }\n }\n }\n \n return agents;\n}\n\nexport function removeAgent(name: string, platform: AgentPlatform, global: boolean): boolean {\n const paths = getPlatformPaths(platform, global);\n \n for (const path of paths) {\n const agentPath = join(path, `${name}.md`);\n if (existsSync(agentPath)) {\n rmSync(agentPath, { recursive: true, force: true });\n logger.success(`Removed agent \"${name}\" from ${path}`);\n return true;\n }\n \n if (existsSync(path)) {\n const entries = readdirSync(path);\n for (const entry of entries) {\n const entryPath = join(path, entry);\n const linkTarget = existsSync(entryPath) ? entryPath : null;\n if (linkTarget && readlinkCheck(entryPath, name)) {\n rmSync(entryPath, { recursive: true, force: true });\n logger.success(`Removed agent \"${name}\" from ${path}`);\n return true;\n }\n }\n }\n }\n \n return false;\n}\n\nfunction readlinkCheck(path: string, name: string): boolean {\n try {\n const stat = require('fs').lstatSync(path);\n return stat.isSymbolicLink() && path.includes(name);\n } catch {\n return false;\n }\n}\n", "import matter from 'gray-matter';\nimport type { Agent, AgentFile } from '../types/index.js';\n\nexport function parseAgentFile(content: string, path: string): AgentFile {\n const { data, content: body } = matter(content);\n \n if (!data.description) {\n throw new Error(`Agent at ${path} is missing required \"description\" field in frontmatter`);\n }\n\n const agent: Agent = {\n description: data.description,\n name: data.name,\n mode: data.mode,\n model: data.model,\n temperature: data.temperature,\n maxSteps: data.maxSteps,\n color: data.color,\n trigger: data.trigger,\n hidden: data.hidden,\n tools: data.tools,\n permission: data.permission,\n mcp: data.mcp,\n version: data.version,\n };\n\n return {\n path,\n agent,\n content: body.trim(),\n };\n}\n\nexport function parseAgentFromString(content: string, filename: string): AgentFile {\n const baseName = filename.replace(/\\.md$/, '');\n return parseAgentFile(content, baseName);\n}\n\nexport function validateAgent(agent: Agent): string[] {\n const errors: string[] = [];\n \n if (!agent.description) {\n errors.push('Missing required \"description\" field');\n }\n \n if (agent.temperature !== undefined && (agent.temperature < 0 || agent.temperature > 1)) {\n errors.push('Temperature must be between 0 and 1');\n }\n \n if (agent.mode && !['primary', 'subagent', 'all'].includes(agent.mode)) {\n errors.push('Mode must be \"primary\", \"subagent\", or \"all\"');\n }\n \n return errors;\n}\n", "import { join, basename } from 'path';\nimport { existsSync, readdirSync, readFileSync } from 'fs';\nimport { parseAgentFile } from './parser.js';\nimport { findFiles, isDirectory } from '../utils/filesystem.js';\nimport type { AgentFile, Agent } from '../types/index.js';\n\nconst SEARCH_DIRECTORIES = [\n '',\n 'agents',\n '.agents',\n '.opencode/agents',\n 'src/agents',\n];\n\nconst PRIORITY_FILES = [\n 'AGENTS.md',\n 'SKILL.md',\n 'AGENT.md',\n];\n\nexport async function discoverFromDirectory(dir: string): Promise<AgentFile[]> {\n const agents: AgentFile[] = [];\n\n for (const subDir of SEARCH_DIRECTORIES) {\n const searchDir = subDir ? join(dir, subDir) : dir;\n if (!existsSync(searchDir)) continue;\n\n const mdFiles = findFiles(searchDir, /\\.md$/);\n \n for (const file of mdFiles) {\n const fileName = basename(file);\n if (fileName.startsWith('.')) continue;\n if (fileName === 'README.md') continue;\n\n try {\n const content = readFileSync(file, 'utf-8');\n const agentFile = parseAgentFile(content, file);\n agents.push(agentFile);\n } catch (err) {\n continue;\n }\n }\n }\n\n for (const fileName of PRIORITY_FILES) {\n const priorityFile = join(dir, fileName);\n if (existsSync(priorityFile)) {\n try {\n const content = readFileSync(priorityFile, 'utf-8');\n const agentFile = parseAgentFile(content, priorityFile);\n const exists = agents.some(a => a.path === agentFile.path);\n if (!exists) {\n agents.unshift(agentFile);\n }\n } catch (err) {\n continue;\n }\n }\n }\n\n return agents;\n}\n\nexport async function discoverFromRepo(owner: string, repo: string, ref?: string): Promise<AgentFile[]> {\n const degit = await import('degit');\n const tempDir = await createTempDir();\n \n try {\n const source = ref ? `${owner}/${repo}#${ref}` : `${owner}/${repo}`;\n await degit.default(source).clone(tempDir);\n \n return discoverFromDirectory(tempDir);\n } finally {\n // Cleanup temp directory would happen here in production\n }\n}\n\nasync function createTempDir(): Promise<string> {\n const { mkdtempSync } = await import('fs');\n const { tmpdir } = await import('os');\n return mkdtempSync(join(tmpdir(), 'npx-agents-'));\n}\n\nexport function discoverLocal(dir: string): AgentFile[] {\n const agents: AgentFile[] = [];\n \n if (!existsSync(dir)) {\n return agents;\n }\n\n const mdFiles = findFiles(dir, /\\.md$/);\n \n for (const file of mdFiles) {\n const fileName = basename(file);\n if (fileName.startsWith('.') || fileName === 'README.md') continue;\n\n try {\n const content = readFileSync(file, 'utf-8');\n const agentFile = parseAgentFile(content, file);\n agents.push(agentFile);\n } catch (err) {\n continue;\n }\n }\n\n return agents;\n}\n\nexport function parseSource(source: string): { type: 'github' | 'local'; owner?: string; repo?: string; path: string } {\n if (source.startsWith('.') || source.startsWith('/') || /^[a-zA-Z]:\\\\/.test(source)) {\n return { type: 'local', path: source };\n }\n\n if (source.includes('/') && !source.startsWith('http')) {\n const parts = source.split('/');\n if (parts.length >= 2) {\n return { type: 'github', owner: parts[0], repo: parts[1].replace(/#.+$/, '') };\n }\n }\n\n if (source.startsWith('http://') || source.startsWith('https://')) {\n const urlMatch = source.match(/github\\.com[/:]([^/]+)\\/([^/]+)/);\n if (urlMatch) {\n return { type: 'github', owner: urlMatch[1], repo: urlMatch[2].replace(/#.+$/, '') };\n }\n }\n\n return { type: 'local', path: source };\n}\n", "import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync, symlinkSync, copyFileSync, rmSync, statSync } from 'fs';\nimport { join, dirname, basename } from 'path';\nimport { homedir } from 'os';\nimport type { AgentPlatform } from '../types/index.js';\n\nexport function ensureDir(dir: string): void {\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n}\n\nexport function readDir(dir: string): string[] {\n if (!existsSync(dir)) {\n return [];\n }\n return readdirSync(dir);\n}\n\nexport function readFile(path: string): string {\n return readFileSync(path, 'utf-8');\n}\n\nexport function writeFile(path: string, content: string): void {\n ensureDir(dirname(path));\n writeFileSync(path, content, 'utf-8');\n}\n\nexport function isDirectory(path: string): boolean {\n return existsSync(path) && statSync(path).isDirectory();\n}\n\nexport function isFile(path: string): boolean {\n return existsSync(path) && statSync(path).isFile();\n}\n\nexport function getPlatformPaths(platform: AgentPlatform, global: boolean): string[] {\n const home = homedir();\n \n const paths: Record<AgentPlatform, { project: string[]; global: string[] }> = {\n 'opencode': {\n project: ['.opencode/agents/'],\n global: [join(home, '.config', 'opencode', 'agents')],\n },\n 'claude-code': {\n project: ['.claude/agents/'],\n global: [join(home, '.claude', 'agents')],\n },\n 'cursor': {\n project: ['.cursor/agents/'],\n global: [join(home, '.cursor', 'agents')],\n },\n 'windsurf': {\n project: ['.windsurf/agents/'],\n global: [join(home, '.codeium', 'windsurf', 'agents')],\n },\n 'cline': {\n project: ['.cline/agents/'],\n global: [join(home, '.cline', 'agents')],\n },\n 'roo': {\n project: ['.roo/agents/'],\n global: [join(home, '.roo', 'agents')],\n },\n 'codex': {\n project: ['.codex/agents/'],\n global: [join(home, '.codex', 'agents')],\n },\n 'continue': {\n project: ['.continue/agents/'],\n global: [join(home, '.continue', 'agents')],\n },\n };\n\n return global ? paths[platform].global : paths[platform].project;\n}\n\nexport function getGlobalAgentsDir(): string {\n return process.env.NPX_AGENTS_DIR || join(homedir(), '.config', 'npx-agents');\n}\n\nexport function createSymlink(source: string, target: string): void {\n ensureDir(dirname(target));\n symlinkSync(source, target, 'dir');\n}\n\nexport function copyDir(source: string, target: string): void {\n ensureDir(target);\n const files = readdirSync(source);\n for (const file of files) {\n const srcPath = join(source, file);\n const destPath = join(target, file);\n if (isDirectory(srcPath)) {\n copyDir(srcPath, destPath);\n } else {\n copyFileSync(srcPath, destPath);\n }\n }\n}\n\nexport function removePath(path: string): void {\n if (existsSync(path)) {\n rmSync(path, { recursive: true, force: true });\n }\n}\n\nexport function findFiles(dir: string, pattern: RegExp): string[] {\n const results: string[] = [];\n \n if (!existsSync(dir)) {\n return results;\n }\n \n const files = readdirSync(dir);\n for (const file of files) {\n const fullPath = join(dir, file);\n if (isDirectory(fullPath)) {\n results.push(...findFiles(fullPath, pattern));\n } else if (pattern.test(file)) {\n results.push(fullPath);\n }\n }\n \n return results;\n}\n\nexport function detectPlatforms(): AgentPlatform[] {\n const platforms: AgentPlatform[] = [];\n const home = homedir();\n const cwd = process.cwd();\n \n const checks: Array<{ platform: AgentPlatform; check: () => boolean }> = [\n {\n platform: 'opencode',\n check: () => existsSync(join(home, '.config', 'opencode')) || existsSync(join(cwd, '.opencode')),\n },\n {\n platform: 'claude-code',\n check: () => existsSync(join(home, '.claude')) || existsSync(join(cwd, '.claude')),\n },\n {\n platform: 'cursor',\n check: () => existsSync(join(home, '.cursor')) || existsSync(join(cwd, '.cursor')),\n },\n {\n platform: 'windsurf',\n check: () => existsSync(join(home, '.codeium', 'windsurf')) || existsSync(join(cwd, '.windsurf')),\n },\n {\n platform: 'cline',\n check: () => existsSync(join(home, '.cline')) || existsSync(join(cwd, '.cline')),\n },\n {\n platform: 'roo',\n check: () => existsSync(join(home, '.roo')) || existsSync(join(cwd, '.roo')),\n },\n {\n platform: 'codex',\n check: () => existsSync(join(home, '.codex')) || existsSync(join(cwd, '.codex')),\n },\n {\n platform: 'continue',\n check: () => existsSync(join(home, '.continue')) || existsSync(join(cwd, '.continue')),\n },\n ];\n\n for (const check of checks) {\n if (check.check()) {\n platforms.push(check.platform);\n }\n }\n\n if (platforms.length === 0) {\n platforms.push('opencode');\n }\n\n return platforms;\n}\n", "import chalk from 'chalk';\n\nexport const logger = {\n info: (msg: string) => console.log(chalk.blue('\u2139'), msg),\n success: (msg: string) => console.log(chalk.green('\u2713'), msg),\n warn: (msg: string) => console.log(chalk.yellow('\u26A0'), msg),\n error: (msg: string) => console.error(chalk.red('\u2717'), msg),\n debug: (msg: string) => {\n if (process.env.DEBUG === 'npx-agents') {\n console.log(chalk.gray('[debug]'), msg);\n }\n },\n};\n", "import chalk from 'chalk';\nimport { listInstalledAgents } from '../core/installer.js';\nimport { detectPlatforms } from '../utils/filesystem.js';\nimport { logger } from '../utils/logger.js';\nimport type { AgentPlatform } from '../types/index.js';\n\ninterface ListCommandOptions {\n global: boolean;\n agent: string | undefined;\n}\n\nexport async function listCommand(options: ListCommandOptions): Promise<void> {\n let platforms: AgentPlatform[];\n \n if (options.agent) {\n platforms = [options.agent as AgentPlatform];\n } else {\n platforms = detectPlatforms();\n }\n\n const scope = options.global ? 'global' : 'project';\n \n for (const platform of platforms) {\n const agents = listInstalledAgents(platform, options.global);\n \n if (agents.length === 0) {\n logger.info(`No agents found for ${platform} (${scope})`);\n continue;\n }\n\n console.log(chalk.bold(`\\n${platform} agents (${scope}):\\n`));\n \n for (const agent of agents) {\n const name = agent.agent.name || agent.path.split(/[/\\\\]/).pop()?.replace('.md', '') || 'unknown';\n const mode = agent.agent.mode || 'subagent';\n const description = agent.agent.description || 'No description';\n \n console.log(` ${chalk.cyan(name)} ${chalk.gray(`[${mode}]`)}`);\n console.log(` ${chalk.dim(description)}\\n`);\n }\n }\n}\n", "import ora from 'ora';\nimport { removeAgent } from '../core/installer.js';\nimport { detectPlatforms } from '../utils/filesystem.js';\nimport { logger } from '../utils/logger.js';\nimport type { AgentPlatform } from '../types/index.js';\n\ninterface RemoveCommandOptions {\n global: boolean;\n agent: string | undefined;\n}\n\nexport async function removeCommand(name: string, options: RemoveCommandOptions): Promise<void> {\n const spinner = ora(`Removing agent \"${name}\"...`).start();\n\n try {\n let platforms: AgentPlatform[];\n \n if (options.agent) {\n platforms = [options.agent as AgentPlatform];\n } else {\n platforms = detectPlatforms();\n }\n\n let removed = false;\n \n for (const platform of platforms) {\n const result = removeAgent(name, platform, options.global);\n if (result) {\n removed = true;\n }\n }\n\n if (removed) {\n spinner.succeed(`Removed agent \"${name}\"`);\n } else {\n spinner.warn(`Agent \"${name}\" not found`);\n }\n } catch (err) {\n spinner.fail(`Failed to remove agent: ${err instanceof Error ? err.message : String(err)}`);\n process.exit(1);\n }\n}\n", "import { join } from 'path';\nimport { existsSync, readFileSync } from 'fs';\nimport { ensureDir, detectPlatforms } from '../utils/filesystem.js';\nimport { logger } from '../utils/logger.js';\nimport { fileURLToPath } from 'url';\nimport { dirname } from 'path';\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\ninterface InitCommandOptions {\n global?: boolean;\n}\n\nexport async function initCommand(name?: string, _options?: InitCommandOptions): Promise<void> {\n try {\n const targetName = name || 'my-agent';\n const targetDir = name ? join(process.cwd(), name) : process.cwd();\n const targetPath = join(targetDir, `${targetName}.md`);\n\n if (existsSync(targetPath)) {\n logger.error(`Agent file already exists at ${targetPath}`);\n process.exit(1);\n }\n\n ensureDir(targetDir);\n\n let template: string;\n const templatePath = join(__dirname, '..', '..', 'templates', 'default-agent.md');\n \n if (existsSync(templatePath)) {\n template = readFileSync(templatePath, 'utf-8');\n } else {\n template = getDefaultTemplate(targetName);\n }\n\n const fs = await import('fs');\n fs.writeFileSync(targetPath, template, 'utf-8');\n\n logger.success(`Created agent template at ${targetPath}`);\n console.log(`\\nYou can now edit ${targetPath} to customize your agent.`);\n } catch (err) {\n logger.error(`Failed to create agent: ${err instanceof Error ? err.message : String(err)}`);\n process.exit(1);\n }\n}\n\nfunction getDefaultTemplate(name: string): string {\n return `---\ndescription: ${name} - Add your agent description here\nmode: subagent\nmodel: anthropic/claude-3-5-sonnet-20241022\ntemperature: 0.7\ntools:\n read: true\n write: true\n edit: true\n bash: false\n glob: true\n grep: true\n task: false\n skill: false\nhidden: false\n---\n\n# ${name}\n\nYou are a custom AI agent. Describe your purpose and behavior here.\n\n## When to Use\n\nDescribe when this agent should be invoked.\n\n## Workflow\n\n1. First step...\n2. Second step...\n3. Third step...\n\n## Guidelines\n\n- Add your specific guidelines here\n- Be clear and concise\n`;\n}\n", "import chalk from 'chalk';\nimport { logger } from '../utils/logger.js';\n\ninterface FindCommandOptions {\n}\n\nexport async function findCommand(query?: string, _options?: FindCommandOptions): Promise<void> {\n if (!query) {\n console.log(chalk.bold('\\nSearch for agents\\n'));\n console.log('Usage: npx agents find <query>');\n console.log('\\nExample:');\n console.log(' npx agents find code-review');\n console.log(' npx agents find testing');\n return;\n }\n\n logger.info(`Searching for agents matching \"${query}\"...`);\n\n console.log(chalk.yellow('\\nNote: Agent search functionality requires integration with skills.sh API.'));\n console.log('For now, you can browse agents at: https://skills.sh\\n');\n \n console.log(chalk.dim('Alternatively, you can:'));\n console.log(chalk.dim(' 1. Check GitHub for agent repositories'));\n console.log(chalk.dim(' 2. Use \"npx agents add <owner/repo>\" to install directly'));\n}\n", "import chalk from 'chalk';\nimport { logger } from '../utils/logger.js';\n\nexport async function checkCommand(): Promise<void> {\n logger.info('Checking for agent updates...');\n \n console.log(chalk.yellow('\\nNote: Update checking requires version tracking.'));\n console.log('To update agents, use: npx agents add <source> --force\\n');\n \n console.log(chalk.dim('Add version info to your agents to enable update checking.'));\n}\n", "import chalk from 'chalk';\nimport { logger } from '../utils/logger.js';\n\nexport async function updateCommand(): Promise<void> {\n logger.info('Updating agents...');\n \n console.log(chalk.yellow('\\nNote: Auto-update functionality coming soon.\\n'));\n \n console.log(chalk.dim('To update an agent, remove it and reinstall:'));\n console.log(chalk.dim(' npx agents remove <agent-name>'));\n console.log(chalk.dim(' npx agents add <source>'));\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["join", "basename", "existsSync", "readdirSync", "readFileSync", "copyFileSync", "symlinkSync", "rmSync", "join", "basename", "existsSync", "readFileSync", "join", "existsSync", "basename", "readFileSync", "basename", "join", "existsSync", "copyFileSync", "symlinkSync", "rmSync", "readdirSync", "readFileSync", "chalk", "chalk", "ora", "ora", "join", "existsSync", "readFileSync", "dirname", "join", "existsSync", "readFileSync", "chalk", "chalk", "chalk", "chalk", "chalk", "chalk"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: my-agent - Add your agent description here
|
|
3
|
+
mode: subagent
|
|
4
|
+
model: anthropic/claude-3-5-sonnet-20241022
|
|
5
|
+
temperature: 0.7
|
|
6
|
+
tools:
|
|
7
|
+
read: true
|
|
8
|
+
write: true
|
|
9
|
+
edit: true
|
|
10
|
+
bash: false
|
|
11
|
+
glob: true
|
|
12
|
+
grep: true
|
|
13
|
+
task: false
|
|
14
|
+
skill: false
|
|
15
|
+
hidden: false
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
# my-agent
|
|
19
|
+
|
|
20
|
+
You are a custom AI agent. Describe your purpose and behavior here.
|
|
21
|
+
|
|
22
|
+
## When to Use
|
|
23
|
+
|
|
24
|
+
Describe when this agent should be invoked.
|
|
25
|
+
|
|
26
|
+
## Workflow
|
|
27
|
+
|
|
28
|
+
1. First step...
|
|
29
|
+
2. Second step...
|
|
30
|
+
3. Third step...
|
|
31
|
+
|
|
32
|
+
## Guidelines
|
|
33
|
+
|
|
34
|
+
- Add your specific guidelines here
|
|
35
|
+
- Be clear and concise
|
package/package.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "guolei-agents",
|
|
3
|
+
"version": "1.0.2",
|
|
4
|
+
"description": "CLI for managing AI coding agents",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"agents": "./bin/agents.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"build": "node build.mjs",
|
|
11
|
+
"dev": "node --watch src/index.ts",
|
|
12
|
+
"test": "vitest",
|
|
13
|
+
"prepublishOnly": "npm run build"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"opencode",
|
|
17
|
+
"claude",
|
|
18
|
+
"agent",
|
|
19
|
+
"cli",
|
|
20
|
+
"skills"
|
|
21
|
+
],
|
|
22
|
+
"author": "",
|
|
23
|
+
"license": "MIT",
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"commander": "^12.1.0",
|
|
26
|
+
"degit": "^2.8.4",
|
|
27
|
+
"gray-matter": "^4.0.3",
|
|
28
|
+
"ora": "^5.4.1",
|
|
29
|
+
"chalk": "^5.3.0",
|
|
30
|
+
"yaml": "^2.3.4"
|
|
31
|
+
},
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"@types/node": "^20.10.0",
|
|
34
|
+
"typescript": "^5.3.0",
|
|
35
|
+
"esbuild": "^0.24.0",
|
|
36
|
+
"vitest": "^1.0.0"
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import ora from 'ora';
|
|
2
|
+
import { installAgent } from '../core/installer.js';
|
|
3
|
+
import { detectPlatforms } from '../utils/filesystem.js';
|
|
4
|
+
import { logger } from '../utils/logger.js';
|
|
5
|
+
import type { AgentPlatform, InstallOptions } from '../types/index.js';
|
|
6
|
+
|
|
7
|
+
interface AddCommandOptions {
|
|
8
|
+
global: boolean;
|
|
9
|
+
agent: string[] | undefined;
|
|
10
|
+
agentName: string | undefined;
|
|
11
|
+
yes: boolean;
|
|
12
|
+
copy: boolean;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export async function addCommand(source: string, options: AddCommandOptions): Promise<void> {
|
|
16
|
+
const spinner = ora('Installing agent...').start();
|
|
17
|
+
|
|
18
|
+
try {
|
|
19
|
+
let platforms: AgentPlatform[];
|
|
20
|
+
|
|
21
|
+
if (options.agent && options.agent.length > 0) {
|
|
22
|
+
platforms = options.agent as AgentPlatform[];
|
|
23
|
+
} else {
|
|
24
|
+
platforms = detectPlatforms();
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const installOptions: InstallOptions = {
|
|
28
|
+
source,
|
|
29
|
+
global: options.global,
|
|
30
|
+
platforms,
|
|
31
|
+
agentName: options.agentName,
|
|
32
|
+
copy: options.copy,
|
|
33
|
+
yes: options.yes,
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
await installAgent(installOptions);
|
|
37
|
+
|
|
38
|
+
spinner.succeed(`Successfully installed agent from ${source}`);
|
|
39
|
+
} catch (err) {
|
|
40
|
+
spinner.fail(`Failed to install agent: ${err instanceof Error ? err.message : String(err)}`);
|
|
41
|
+
logger.error(String(err));
|
|
42
|
+
process.exit(1);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { logger } from '../utils/logger.js';
|
|
3
|
+
|
|
4
|
+
export async function checkCommand(): Promise<void> {
|
|
5
|
+
logger.info('Checking for agent updates...');
|
|
6
|
+
|
|
7
|
+
console.log(chalk.yellow('\nNote: Update checking requires version tracking.'));
|
|
8
|
+
console.log('To update agents, use: npx agents add <source> --force\n');
|
|
9
|
+
|
|
10
|
+
console.log(chalk.dim('Add version info to your agents to enable update checking.'));
|
|
11
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { logger } from '../utils/logger.js';
|
|
3
|
+
|
|
4
|
+
interface FindCommandOptions {
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export async function findCommand(query?: string, _options?: FindCommandOptions): Promise<void> {
|
|
8
|
+
if (!query) {
|
|
9
|
+
console.log(chalk.bold('\nSearch for agents\n'));
|
|
10
|
+
console.log('Usage: npx agents find <query>');
|
|
11
|
+
console.log('\nExample:');
|
|
12
|
+
console.log(' npx agents find code-review');
|
|
13
|
+
console.log(' npx agents find testing');
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
logger.info(`Searching for agents matching "${query}"...`);
|
|
18
|
+
|
|
19
|
+
console.log(chalk.yellow('\nNote: Agent search functionality requires integration with skills.sh API.'));
|
|
20
|
+
console.log('For now, you can browse agents at: https://skills.sh\n');
|
|
21
|
+
|
|
22
|
+
console.log(chalk.dim('Alternatively, you can:'));
|
|
23
|
+
console.log(chalk.dim(' 1. Check GitHub for agent repositories'));
|
|
24
|
+
console.log(chalk.dim(' 2. Use "npx agents add <owner/repo>" to install directly'));
|
|
25
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { join } from 'path';
|
|
2
|
+
import { existsSync, readFileSync } from 'fs';
|
|
3
|
+
import { ensureDir, detectPlatforms } from '../utils/filesystem.js';
|
|
4
|
+
import { logger } from '../utils/logger.js';
|
|
5
|
+
import { fileURLToPath } from 'url';
|
|
6
|
+
import { dirname } from 'path';
|
|
7
|
+
|
|
8
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
9
|
+
|
|
10
|
+
interface InitCommandOptions {
|
|
11
|
+
global?: boolean;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export async function initCommand(name?: string, _options?: InitCommandOptions): Promise<void> {
|
|
15
|
+
try {
|
|
16
|
+
const targetName = name || 'my-agent';
|
|
17
|
+
const targetDir = name ? join(process.cwd(), name) : process.cwd();
|
|
18
|
+
const targetPath = join(targetDir, `${targetName}.md`);
|
|
19
|
+
|
|
20
|
+
if (existsSync(targetPath)) {
|
|
21
|
+
logger.error(`Agent file already exists at ${targetPath}`);
|
|
22
|
+
process.exit(1);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
ensureDir(targetDir);
|
|
26
|
+
|
|
27
|
+
let template: string;
|
|
28
|
+
const templatePath = join(__dirname, '..', '..', 'templates', 'default-agent.md');
|
|
29
|
+
|
|
30
|
+
if (existsSync(templatePath)) {
|
|
31
|
+
template = readFileSync(templatePath, 'utf-8');
|
|
32
|
+
} else {
|
|
33
|
+
template = getDefaultTemplate(targetName);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const fs = await import('fs');
|
|
37
|
+
fs.writeFileSync(targetPath, template, 'utf-8');
|
|
38
|
+
|
|
39
|
+
logger.success(`Created agent template at ${targetPath}`);
|
|
40
|
+
console.log(`\nYou can now edit ${targetPath} to customize your agent.`);
|
|
41
|
+
} catch (err) {
|
|
42
|
+
logger.error(`Failed to create agent: ${err instanceof Error ? err.message : String(err)}`);
|
|
43
|
+
process.exit(1);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function getDefaultTemplate(name: string): string {
|
|
48
|
+
return `---
|
|
49
|
+
description: ${name} - Add your agent description here
|
|
50
|
+
mode: subagent
|
|
51
|
+
model: anthropic/claude-3-5-sonnet-20241022
|
|
52
|
+
temperature: 0.7
|
|
53
|
+
tools:
|
|
54
|
+
read: true
|
|
55
|
+
write: true
|
|
56
|
+
edit: true
|
|
57
|
+
bash: false
|
|
58
|
+
glob: true
|
|
59
|
+
grep: true
|
|
60
|
+
task: false
|
|
61
|
+
skill: false
|
|
62
|
+
hidden: false
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
# ${name}
|
|
66
|
+
|
|
67
|
+
You are a custom AI agent. Describe your purpose and behavior here.
|
|
68
|
+
|
|
69
|
+
## When to Use
|
|
70
|
+
|
|
71
|
+
Describe when this agent should be invoked.
|
|
72
|
+
|
|
73
|
+
## Workflow
|
|
74
|
+
|
|
75
|
+
1. First step...
|
|
76
|
+
2. Second step...
|
|
77
|
+
3. Third step...
|
|
78
|
+
|
|
79
|
+
## Guidelines
|
|
80
|
+
|
|
81
|
+
- Add your specific guidelines here
|
|
82
|
+
- Be clear and concise
|
|
83
|
+
`;
|
|
84
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { listInstalledAgents } from '../core/installer.js';
|
|
3
|
+
import { detectPlatforms } from '../utils/filesystem.js';
|
|
4
|
+
import { logger } from '../utils/logger.js';
|
|
5
|
+
import type { AgentPlatform } from '../types/index.js';
|
|
6
|
+
|
|
7
|
+
interface ListCommandOptions {
|
|
8
|
+
global: boolean;
|
|
9
|
+
agent: string | undefined;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export async function listCommand(options: ListCommandOptions): Promise<void> {
|
|
13
|
+
let platforms: AgentPlatform[];
|
|
14
|
+
|
|
15
|
+
if (options.agent) {
|
|
16
|
+
platforms = [options.agent as AgentPlatform];
|
|
17
|
+
} else {
|
|
18
|
+
platforms = detectPlatforms();
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const scope = options.global ? 'global' : 'project';
|
|
22
|
+
|
|
23
|
+
for (const platform of platforms) {
|
|
24
|
+
const agents = listInstalledAgents(platform, options.global);
|
|
25
|
+
|
|
26
|
+
if (agents.length === 0) {
|
|
27
|
+
logger.info(`No agents found for ${platform} (${scope})`);
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
console.log(chalk.bold(`\n${platform} agents (${scope}):\n`));
|
|
32
|
+
|
|
33
|
+
for (const agent of agents) {
|
|
34
|
+
const name = agent.agent.name || agent.path.split(/[/\\]/).pop()?.replace('.md', '') || 'unknown';
|
|
35
|
+
const mode = agent.agent.mode || 'subagent';
|
|
36
|
+
const description = agent.agent.description || 'No description';
|
|
37
|
+
|
|
38
|
+
console.log(` ${chalk.cyan(name)} ${chalk.gray(`[${mode}]`)}`);
|
|
39
|
+
console.log(` ${chalk.dim(description)}\n`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import ora from 'ora';
|
|
2
|
+
import { removeAgent } from '../core/installer.js';
|
|
3
|
+
import { detectPlatforms } from '../utils/filesystem.js';
|
|
4
|
+
import { logger } from '../utils/logger.js';
|
|
5
|
+
import type { AgentPlatform } from '../types/index.js';
|
|
6
|
+
|
|
7
|
+
interface RemoveCommandOptions {
|
|
8
|
+
global: boolean;
|
|
9
|
+
agent: string | undefined;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export async function removeCommand(name: string, options: RemoveCommandOptions): Promise<void> {
|
|
13
|
+
const spinner = ora(`Removing agent "${name}"...`).start();
|
|
14
|
+
|
|
15
|
+
try {
|
|
16
|
+
let platforms: AgentPlatform[];
|
|
17
|
+
|
|
18
|
+
if (options.agent) {
|
|
19
|
+
platforms = [options.agent as AgentPlatform];
|
|
20
|
+
} else {
|
|
21
|
+
platforms = detectPlatforms();
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
let removed = false;
|
|
25
|
+
|
|
26
|
+
for (const platform of platforms) {
|
|
27
|
+
const result = removeAgent(name, platform, options.global);
|
|
28
|
+
if (result) {
|
|
29
|
+
removed = true;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (removed) {
|
|
34
|
+
spinner.succeed(`Removed agent "${name}"`);
|
|
35
|
+
} else {
|
|
36
|
+
spinner.warn(`Agent "${name}" not found`);
|
|
37
|
+
}
|
|
38
|
+
} catch (err) {
|
|
39
|
+
spinner.fail(`Failed to remove agent: ${err instanceof Error ? err.message : String(err)}`);
|
|
40
|
+
process.exit(1);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { logger } from '../utils/logger.js';
|
|
3
|
+
|
|
4
|
+
export async function updateCommand(): Promise<void> {
|
|
5
|
+
logger.info('Updating agents...');
|
|
6
|
+
|
|
7
|
+
console.log(chalk.yellow('\nNote: Auto-update functionality coming soon.\n'));
|
|
8
|
+
|
|
9
|
+
console.log(chalk.dim('To update an agent, remove it and reinstall:'));
|
|
10
|
+
console.log(chalk.dim(' npx agents remove <agent-name>'));
|
|
11
|
+
console.log(chalk.dim(' npx agents add <source>'));
|
|
12
|
+
}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { join, basename } from 'path';
|
|
2
|
+
import { existsSync, readdirSync, readFileSync } from 'fs';
|
|
3
|
+
import { parseAgentFile } from './parser.js';
|
|
4
|
+
import { findFiles, isDirectory } from '../utils/filesystem.js';
|
|
5
|
+
import type { AgentFile, Agent } from '../types/index.js';
|
|
6
|
+
|
|
7
|
+
const SEARCH_DIRECTORIES = [
|
|
8
|
+
'',
|
|
9
|
+
'agents',
|
|
10
|
+
'.agents',
|
|
11
|
+
'.opencode/agents',
|
|
12
|
+
'src/agents',
|
|
13
|
+
];
|
|
14
|
+
|
|
15
|
+
const PRIORITY_FILES = [
|
|
16
|
+
'AGENTS.md',
|
|
17
|
+
'SKILL.md',
|
|
18
|
+
'AGENT.md',
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
export async function discoverFromDirectory(dir: string): Promise<AgentFile[]> {
|
|
22
|
+
const agents: AgentFile[] = [];
|
|
23
|
+
|
|
24
|
+
for (const subDir of SEARCH_DIRECTORIES) {
|
|
25
|
+
const searchDir = subDir ? join(dir, subDir) : dir;
|
|
26
|
+
if (!existsSync(searchDir)) continue;
|
|
27
|
+
|
|
28
|
+
const mdFiles = findFiles(searchDir, /\.md$/);
|
|
29
|
+
|
|
30
|
+
for (const file of mdFiles) {
|
|
31
|
+
const fileName = basename(file);
|
|
32
|
+
if (fileName.startsWith('.')) continue;
|
|
33
|
+
if (fileName === 'README.md') continue;
|
|
34
|
+
|
|
35
|
+
try {
|
|
36
|
+
const content = readFileSync(file, 'utf-8');
|
|
37
|
+
const agentFile = parseAgentFile(content, file);
|
|
38
|
+
agents.push(agentFile);
|
|
39
|
+
} catch (err) {
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
for (const fileName of PRIORITY_FILES) {
|
|
46
|
+
const priorityFile = join(dir, fileName);
|
|
47
|
+
if (existsSync(priorityFile)) {
|
|
48
|
+
try {
|
|
49
|
+
const content = readFileSync(priorityFile, 'utf-8');
|
|
50
|
+
const agentFile = parseAgentFile(content, priorityFile);
|
|
51
|
+
const exists = agents.some(a => a.path === agentFile.path);
|
|
52
|
+
if (!exists) {
|
|
53
|
+
agents.unshift(agentFile);
|
|
54
|
+
}
|
|
55
|
+
} catch (err) {
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return agents;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export async function discoverFromRepo(owner: string, repo: string, ref?: string): Promise<AgentFile[]> {
|
|
65
|
+
const degit = await import('degit');
|
|
66
|
+
const tempDir = await createTempDir();
|
|
67
|
+
|
|
68
|
+
try {
|
|
69
|
+
const source = ref ? `${owner}/${repo}#${ref}` : `${owner}/${repo}`;
|
|
70
|
+
await degit.default(source).clone(tempDir);
|
|
71
|
+
|
|
72
|
+
return discoverFromDirectory(tempDir);
|
|
73
|
+
} finally {
|
|
74
|
+
// Cleanup temp directory would happen here in production
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
async function createTempDir(): Promise<string> {
|
|
79
|
+
const { mkdtempSync } = await import('fs');
|
|
80
|
+
const { tmpdir } = await import('os');
|
|
81
|
+
return mkdtempSync(join(tmpdir(), 'npx-agents-'));
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export function discoverLocal(dir: string): AgentFile[] {
|
|
85
|
+
const agents: AgentFile[] = [];
|
|
86
|
+
|
|
87
|
+
if (!existsSync(dir)) {
|
|
88
|
+
return agents;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const mdFiles = findFiles(dir, /\.md$/);
|
|
92
|
+
|
|
93
|
+
for (const file of mdFiles) {
|
|
94
|
+
const fileName = basename(file);
|
|
95
|
+
if (fileName.startsWith('.') || fileName === 'README.md') continue;
|
|
96
|
+
|
|
97
|
+
try {
|
|
98
|
+
const content = readFileSync(file, 'utf-8');
|
|
99
|
+
const agentFile = parseAgentFile(content, file);
|
|
100
|
+
agents.push(agentFile);
|
|
101
|
+
} catch (err) {
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return agents;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export function parseSource(source: string): { type: 'github' | 'local'; owner?: string; repo?: string; path: string } {
|
|
110
|
+
if (source.startsWith('.') || source.startsWith('/') || /^[a-zA-Z]:\\/.test(source)) {
|
|
111
|
+
return { type: 'local', path: source };
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if (source.includes('/') && !source.startsWith('http')) {
|
|
115
|
+
const parts = source.split('/');
|
|
116
|
+
if (parts.length >= 2) {
|
|
117
|
+
return { type: 'github', owner: parts[0], repo: parts[1].replace(/#.+$/, '') };
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (source.startsWith('http://') || source.startsWith('https://')) {
|
|
122
|
+
const urlMatch = source.match(/github\.com[/:]([^/]+)\/([^/]+)/);
|
|
123
|
+
if (urlMatch) {
|
|
124
|
+
return { type: 'github', owner: urlMatch[1], repo: urlMatch[2].replace(/#.+$/, '') };
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return { type: 'local', path: source };
|
|
129
|
+
}
|