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,48 @@
{
"name": "docker-helper",
"version": "1.0.0",
"description": "Docker container management without Docker Desktop",
"author": "Your Name",
"license": "MIT",
"repository": "https://github.com/yourusername/claude-docker-helper",
"claude": {
"permissions": [
"read:files",
"write:files",
"execute:commands"
],
"commands": [
{
"name": "docker:deploy",
"description": "Deploy containers with zero-downtime support",
"handler": "commands/deploy.ts",
"permissions": ["execute:commands"]
},
{
"name": "docker:logs",
"description": "View and filter container logs",
"handler": "commands/logs.ts",
"permissions": ["execute:commands"]
},
{
"name": "docker:cleanup",
"description": "Clean up unused containers, images, and volumes",
"handler": "commands/cleanup.ts",
"permissions": ["execute:commands"]
},
{
"name": "docker:env",
"description": "Manage environment variables for containers",
"handler": "commands/env.ts",
"permissions": ["read:files", "write:files"]
}
],
"hooks": [
{
"event": "SessionStart",
"handler": "hooks/check-docker.ts",
"priority": 100
}
]
}
}

View File

@@ -0,0 +1,63 @@
/**
* Docker Cleanup Command
* Clean up unused containers, images, and volumes
*/
import { exec } from 'child_process'
import { promisify } from 'util'
const execAsync = promisify(exec)
export interface CleanupOptions {
containers?: boolean
images?: boolean
volumes?: boolean
networks?: boolean
all?: boolean
}
export async function handle(args: CleanupOptions, context: any): Promise<string> {
const {
containers = true,
images = true,
volumes = false,
networks = false,
all = false
} = args
const results: string[] = []
try {
if (all || containers) {
results.push('Cleaning up stopped containers...')
const { stdout: containerOutput } = await execAsync('docker container prune -f')
results.push(containerOutput)
}
if (all || images) {
results.push('\nCleaning up dangling images...')
const { stdout: imageOutput } = await execAsync('docker image prune -a -f')
results.push(imageOutput)
}
if (all || volumes) {
results.push('\nCleaning up unused volumes...')
const { stdout: volumeOutput } = await execAsync('docker volume prune -f')
results.push(volumeOutput)
}
if (all || networks) {
results.push('\nCleaning up unused networks...')
const { stdout: networkOutput } = await execAsync('docker network prune -f')
results.push(networkOutput)
}
results.push('\n✓ Docker cleanup complete!')
return results.join('\n')
} catch (error: any) {
throw new Error(`Docker cleanup failed: ${error.message}`)
}
}
export default { handle }

View File

@@ -0,0 +1,74 @@
/**
* Docker Deploy Command
* Deploy containers with zero-downtime support
*/
import { exec } from 'child_process'
import { promisify } from 'util'
import { readFileSync, writeFileSync } from 'fs'
const execAsync = promisify(exec)
export interface DeployOptions {
env?: string
noDowntime?: boolean
force?: boolean
build?: boolean
scale?: number
}
export async function handle(args: DeployOptions, context: any): Promise<string> {
const { env = 'production', noDowntime = true, force = false, build = true, scale } = args
try {
const results: string[] = []
// Build if requested
if (build) {
results.push('Building Docker image...')
const { stdout: buildOutput } = await execAsync('docker-compose build')
results.push(buildOutput)
}
if (noDowntime && !force) {
// Zero-downtime deployment
results.push('Starting zero-downtime deployment...')
// Get current running containers
const { stdout: psOutput } = await execAsync('docker-compose ps -q')
const hasRunning = psOutput.trim().length > 0
if (hasRunning) {
// Start new containers alongside old ones
results.push('Starting new containers...')
await execAsync(`docker-compose up -d --scale app=${scale || 2} --no-recreate`)
// Wait for health checks
await new Promise(resolve => setTimeout(resolve, 5000))
// Stop old containers gracefully
results.push('Stopping old containers...')
await execAsync('docker-compose up -d --scale app=1 --no-recreate')
} else {
// First deployment
results.push('Initial deployment...')
await execAsync('docker-compose up -d')
}
} else {
// Standard deployment with potential downtime
results.push('Deploying with potential downtime...')
await execAsync('docker-compose up -d --force-recreate')
}
// Show status
const { stdout: statusOutput } = await execAsync('docker-compose ps')
results.push('\n✓ Deployment complete!\n')
results.push(statusOutput)
return results.join('\n')
} catch (error: any) {
throw new Error(`Docker deployment failed: ${error.message}`)
}
}
export default { handle }

View File

@@ -0,0 +1,107 @@
/**
* Docker Environment Command
* Manage environment variables for containers
*/
import { exec } from 'child_process'
import { promisify } from 'util'
import { readFileSync, writeFileSync, existsSync } from 'fs'
const execAsync = promisify(exec)
export interface EnvOptions {
action: 'list' | 'set' | 'unset' | 'export'
key?: string
value?: string
file?: string
}
export async function handle(args: EnvOptions, context: any): Promise<string> {
const { action, key, value, file = '.env' } = args
try {
switch (action) {
case 'list':
return listEnv(file)
case 'set':
if (!key || value === undefined) {
throw new Error('Key and value are required for set action')
}
return setEnv(file, key, value)
case 'unset':
if (!key) {
throw new Error('Key is required for unset action')
}
return unsetEnv(file, key)
case 'export':
return exportEnv(file)
default:
throw new Error(`Unknown action: ${action}`)
}
} catch (error: any) {
throw new Error(`Environment management failed: ${error.message}`)
}
}
function listEnv(file: string): string {
if (!existsSync(file)) {
return `# Environment file ${file} does not exist`
}
const content = readFileSync(file, 'utf-8')
return content
}
function setEnv(file: string, key: string, value: string): string {
let content = ''
if (existsSync(file)) {
content = readFileSync(file, 'utf-8')
}
// Check if key exists
const lines = content.split('\n')
const keyIndex = lines.findIndex(line => line.startsWith(`${key}=`))
if (keyIndex >= 0) {
// Update existing key
lines[keyIndex] = `${key}=${value}`
content = lines.join('\n')
} else {
// Add new key
content += `${key}=${value}\n`
}
writeFileSync(file, content, 'utf-8')
return `✓ Set ${key} in ${file}`
}
function unsetEnv(file: string, key: string): string {
if (!existsSync(file)) {
return `# Environment file ${file} does not exist`
}
const content = readFileSync(file, 'utf-8')
const lines = content.split('\n')
const filtered = lines.filter(line => !line.startsWith(`${key}=`))
writeFileSync(file, filtered.join('\n'), 'utf-8')
return `✓ Unset ${key} from ${file}`
}
function exportEnv(file: string): string {
if (!existsSync(file)) {
return `# Environment file ${file} does not exist`
}
const content = readFileSync(file, 'utf-8')
const exportCommands = content
.split('\n')
.filter(line => line.trim() && !line.startsWith('#'))
.map(line => `export ${line}`)
.join('\n')
return exportCommands
}
export default { handle }

View File

@@ -0,0 +1,58 @@
/**
* Docker Logs Command
* View and filter container logs
*/
import { exec } from 'child_process'
import { promisify } from 'util'
const execAsync = promisify(exec)
export interface LogsOptions {
service?: string
tail?: number
follow?: boolean
since?: string
grep?: string
}
export async function handle(args: LogsOptions, context: any): Promise<string> {
const { service, tail = 100, follow = false, since, grep } = args
try {
let command = 'docker-compose logs'
if (tail) {
command += ` --tail ${tail}`
}
if (follow) {
command += ' -f'
}
if (since) {
command += ` --since "${since}"`
}
if (service) {
command += ` ${service}`
}
const { stdout, stderr } = await execAsync(command)
let logs = stdout
// Filter by grep pattern if provided
if (grep) {
const lines = logs.split('\n')
const filtered = lines.filter(line => line.includes(grep))
logs = filtered.join('\n')
}
return logs || stderr || 'No logs found'
} catch (error: any) {
throw new Error(`Failed to fetch logs: ${error.message}`)
}
}
export default { handle }