Reorganize: Move all skills to skills/ folder

- Created skills/ directory
- Moved 272 skills to skills/ subfolder
- Kept agents/ at root level
- Kept installation scripts and docs at root level

Repository structure:
- skills/           - All 272 skills from skills.sh
- agents/           - Agent definitions
- *.sh, *.ps1       - Installation scripts
- README.md, etc.   - Documentation

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
admin
2026-01-23 18:05:17 +00:00
Unverified
parent 2b4e974878
commit b723e2bd7d
4083 changed files with 1056 additions and 1098063 deletions

View File

@@ -0,0 +1,428 @@
/**
* Claude Code Plugin API
*
* Developer-friendly API for creating Claude Code plugins
* Inspired by Conduit's component system
*/
import { HookSystem, HookEvent, HookContext } from './hook-system'
import { SecurityManager, Sandbox, Permission } from './security'
// ============================================================================
// TYPES AND INTERFACES
// ============================================================================
export interface PluginConfig {
name: string
version: string
description: string
author: string
license?: string
repository?: string
permissions?: Permission[]
enabled?: boolean
}
export interface CommandHandler {
description: string
parameters?: Record<string, any>
handler: (args: any, context: PluginContext) => Promise<any>
}
export interface ToolExtension {
name: string
description: string
parameters?: any
handler: (args: any, context: PluginContext) => Promise<any>
}
export interface PluginContext {
plugin: string
session: {
id?: string
messageId?: string
}
config: Map<string, any>
sandbox: Sandbox
}
export type HookHandler = (context: HookContext) => Promise<void | any>
// ============================================================================
// PLUGIN CLASS
// ============================================================================
export class Plugin {
public readonly name: string
public readonly version: string
public readonly description: string
public readonly author: string
public readonly license?: string
public readonly repository?: string
private permissions: Permission[]
private enabled: boolean
private commands: Map<string, CommandHandler> = new Map()
private tools: ToolExtension[] = []
private hooks: Map<HookEvent, HookHandler[]> = new Map()
private config: Map<string, any> = new Map()
private security: SecurityManager
private hookSystem: HookSystem
constructor(config: PluginConfig, security: SecurityManager, hookSystem: HookSystem) {
this.name = config.name
this.version = config.version
this.description = config.description
this.author = config.author
this.license = config.license
this.repository = config.repository
this.permissions = config.permissions || []
this.enabled = config.enabled !== false
this.security = security
this.hookSystem = hookSystem
// Create security context
this.security.createContext(this.name, this.permissions)
}
// ============================================================================
// LIFECYCLE HOOKS
// ============================================================================
async onLoad?(): Promise<void>
async onUnload?(): Promise<void>
async onEnable?(): Promise<void>
async onDisable?(): Promise<void>
// ============================================================================
// COMMAND REGISTRATION
// ============================================================================
registerCommand(name: string, handler: CommandHandler): void {
this.commands.set(name, handler)
}
getCommand(name: string): CommandHandler | undefined {
return this.commands.get(name)
}
listCommands(): string[] {
return Array.from(this.commands.keys())
}
async executeCommand(name: string, args: any, context: PluginContext): Promise<any> {
const command = this.commands.get(name)
if (!command) {
throw new Error(`Command "${name}" not found in plugin "${this.name}"`)
}
return await command.handler(args, context)
}
// ============================================================================
// TOOL EXTENSIONS
// ============================================================================
registerTool(tool: ToolExtension): void {
this.tools.push(tool)
}
getTools(): ToolExtension[] {
return [...this.tools]
}
// ============================================================================
// HOOK REGISTRATION
// ============================================================================
on(event: HookEvent, handler: HookHandler): void {
const existing = this.hooks.get(event) || []
existing.push(handler)
this.hooks.set(event, existing)
}
async executeHooks(event: HookEvent, context: HookContext): Promise<void> {
const handlers = this.hooks.get(event) || []
for (const handler of handlers) {
await handler(context)
}
}
// ============================================================================
// CONFIGURATION
// ============================================================================
setConfig(key: string, value: any): void {
this.config.set(key, value)
}
getConfig<T>(key: string): T | undefined {
return this.config.get(key) as T
}
getAllConfig(): Map<string, any> {
return new Map(this.config)
}
loadConfig(configObj: Record<string, any>): void {
for (const [key, value] of Object.entries(configObj)) {
this.config.set(key, value)
}
}
// ============================================================================
// STATE MANAGEMENT
// ============================================================================
enable(): void {
this.enabled = true
}
disable(): void {
this.enabled = false
}
isEnabled(): boolean {
return this.enabled
}
// ============================================================================
// SECURITY
// ============================================================================
hasPermission(permission: Permission): boolean {
return this.permissions.includes(permission)
}
createSandbox(): Sandbox {
const context = this.security.getContext(this.name)
if (!context) {
throw new Error(`Security context not found for plugin "${this.name}"`)
}
return new Sandbox(this.security, context)
}
// ============================================================================
// METADATA
// ============================================================================
getMetadata(): PluginConfig {
return {
name: this.name,
version: this.version,
description: this.description,
author: this.author,
license: this.license,
repository: this.repository,
permissions: this.permissions,
enabled: this.enabled,
}
}
toJSON(): Record<string, any> {
return {
name: this.name,
version: this.version,
description: this.description,
author: this.author,
license: this.license,
repository: this.repository,
permissions: this.permissions,
enabled: this.enabled,
commands: this.listCommands(),
tools: this.tools.length,
hooks: Array.from(this.hooks.keys()),
}
}
}
// ============================================================================
// PLUGIN BUILDER - Fluent API for Creating Plugins
// ============================================================================
export class PluginBuilder {
private config: Partial<PluginConfig> = {}
private commandHandlers: Map<string, CommandHandler> = new Map()
private toolExtensions: ToolExtension[] = []
private hookHandlers: Map<HookEvent, HookHandler[]> = new Map()
private configValues: Map<string, any> = new Map()
name(name: string): this {
this.config.name = name
return this
}
version(version: string): this {
this.config.version = version
return this
}
description(description: string): this {
this.config.description = description
return this
}
author(author: string): this {
this.config.author = author
return this
}
license(license: string): this {
this.config.license = license
return this
}
repository(repository: string): this {
this.config.repository = repository
return this
}
permissions(...permissions: Permission[]): this {
this.config.permissions = permissions
return this
}
enabled(enabled: boolean): this {
this.config.enabled = enabled
return this
}
command(name: string, handler: CommandHandler): this {
this.commandHandlers.set(name, handler)
return this
}
tool(tool: ToolExtension): this {
this.toolExtensions.push(tool)
return this
}
hook(event: HookEvent, handler: HookHandler): this {
const existing = this.hookHandlers.get(event) || []
existing.push(handler)
this.hookHandlers.set(event, existing)
return this
}
config(key: string, value: any): this {
this.configValues.set(key, value)
return this
}
onLoad(handler: () => Promise<void>): this {
return this.hook('PluginLoad', handler as HookHandler)
}
onUnload(handler: () => Promise<void>): this {
return this.hook('PluginUnload', handler as HookHandler)
}
onSessionStart(handler: HookHandler): this {
return this.hook('SessionStart', handler)
}
onSessionEnd(handler: HookHandler): this {
return this.hook('SessionEnd', handler)
}
onPreToolUse(handler: HookHandler): this {
return this.hook('PreToolUse', handler)
}
onPostToolUse(handler: HookHandler): this {
return this.hook('PostToolUse', handler)
}
onPreFileEdit(handler: HookHandler): this {
return this.hook('PreFileEdit', handler)
}
onPostFileEdit(handler: HookHandler): this {
return this.hook('PostFileEdit', handler)
}
build(security: SecurityManager, hookSystem: HookSystem): Plugin {
if (!this.config.name || !this.config.version || !this.config.author) {
throw new Error('Plugin must have name, version, and author')
}
const plugin = new Plugin(
this.config as PluginConfig,
security,
hookSystem
)
// Register commands
for (const [name, handler] of this.commandHandlers) {
plugin.registerCommand(name, handler)
}
// Register tools
for (const tool of this.toolExtensions) {
plugin.registerTool(tool)
}
// Register hooks
for (const [event, handlers] of this.hookHandlers) {
for (const handler of handlers) {
plugin.on(event, handler)
}
}
// Load config
plugin.loadConfig(Object.fromEntries(this.configValues))
return plugin
}
}
// ============================================================================
// HELPER FUNCTIONS
// ============================================================================
export function createPlugin(
config: PluginConfig,
builder?: (plugin: PluginBuilder) => PluginBuilder
): PluginBuilder {
const pb = new PluginBuilder()
if (config.name) pb.name(config.name)
if (config.version) pb.version(config.version)
if (config.description) pb.description(config.description)
if (config.author) pb.author(config.author)
if (config.license) pb.license(config.license)
if (config.repository) pb.repository(config.repository)
if (config.permissions) pb.permissions(...config.permissions)
if (config.enabled !== undefined) pb.enabled(config.enabled)
return builder ? builder(pb) : pb
}
export function definePlugin(
config: PluginConfig,
definition: (pb: PluginBuilder) => void
): PluginBuilder {
const builder = new PluginBuilder()
// Set basic config
if (config.name) builder.name(config.name)
if (config.version) builder.version(config.version)
if (config.description) builder.description(config.description)
if (config.author) builder.author(config.author)
if (config.license) builder.license(config.license)
if (config.repository) builder.repository(config.repository)
if (config.permissions) builder.permissions(...config.permissions)
if (config.enabled !== undefined) builder.enabled(config.enabled)
// Apply definition
definition(builder)
return builder
}
// ============================================================================
// EXPORTS
// ============================================================================
export default Plugin