claude-flow-novice 2.16.0 → 2.16.1
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/.claude/cfn-extras/skills/GOOGLE_SHEETS_SKILLS_README.md +1 -1
- package/.claude/cfn-extras/skills/google-sheets-api-coordinator/SKILL.md +1 -1
- package/.claude/cfn-extras/skills/google-sheets-formula-builder/SKILL.md +1 -1
- package/.claude/cfn-extras/skills/google-sheets-progress/SKILL.md +1 -1
- package/.claude/commands/CFN_LOOP_FRONTEND.md +1 -1
- package/.claude/commands/cfn-loop-cli.md +124 -46
- package/.claude/commands/cfn-loop-frontend.md +1 -1
- package/.claude/commands/cfn-loop-task.md +2 -2
- package/.claude/commands/deprecated/cfn-loop.md +2 -2
- package/.claude/hooks/cfn-invoke-post-edit.sh +31 -5
- package/.claude/hooks/cfn-post-edit.config.json +9 -2
- package/.claude/root-claude-distribute/CFN-CLAUDE.md +1 -1
- package/.claude/skills/cfn-backlog-management/SKILL.md +1 -1
- package/.claude/skills/cfn-loop-orchestration/NORTH_STAR_INDEX.md +1 -1
- package/claude-assets/agents/cfn-dev-team/analysts/root-cause-analyst.md +2 -2
- package/claude-assets/agents/cfn-dev-team/architecture/base-template-generator.md +1 -1
- package/claude-assets/agents/cfn-dev-team/coordinators/cfn-frontend-coordinator.md +2 -2
- package/claude-assets/agents/cfn-dev-team/coordinators/handoff-coordinator.md +1 -1
- package/claude-assets/agents/cfn-dev-team/dev-ops/devops-engineer.md +1 -1
- package/claude-assets/agents/cfn-dev-team/dev-ops/docker-specialist.md +2 -2
- package/claude-assets/agents/cfn-dev-team/dev-ops/github-commit-agent.md +2 -2
- package/claude-assets/agents/cfn-dev-team/dev-ops/kubernetes-specialist.md +1 -1
- package/claude-assets/agents/cfn-dev-team/developers/api-gateway-specialist.md +1 -1
- package/claude-assets/agents/cfn-dev-team/developers/data/data-engineer.md +1 -1
- package/claude-assets/agents/cfn-dev-team/developers/database/database-architect.md +1 -1
- package/claude-assets/agents/cfn-dev-team/developers/frontend/typescript-specialist.md +1 -1
- package/claude-assets/agents/cfn-dev-team/developers/frontend/ui-designer.md +1 -1
- package/claude-assets/agents/cfn-dev-team/developers/graphql-specialist.md +1 -1
- package/claude-assets/agents/cfn-dev-team/documentation/pseudocode.md +1 -1
- package/claude-assets/agents/cfn-dev-team/product-owners/accessibility-advocate-persona.md +1 -1
- package/claude-assets/agents/cfn-dev-team/product-owners/cto-agent.md +1 -1
- package/claude-assets/agents/cfn-dev-team/product-owners/power-user-persona.md +1 -1
- package/claude-assets/agents/cfn-dev-team/reviewers/quality/security-specialist.md +1 -1
- package/claude-assets/agents/cfn-dev-team/testers/api-testing-specialist.md +1 -1
- package/claude-assets/agents/cfn-dev-team/testers/chaos-engineering-specialist.md +1 -1
- package/claude-assets/agents/cfn-dev-team/testers/contract-tester.md +1 -1
- package/claude-assets/agents/cfn-dev-team/testers/e2e/playwright-tester.md +1 -1
- package/claude-assets/agents/cfn-dev-team/testers/integration-tester.md +1 -1
- package/claude-assets/agents/cfn-dev-team/testers/load-testing-specialist.md +1 -1
- package/claude-assets/agents/cfn-dev-team/testers/mutation-testing-specialist.md +1 -1
- package/claude-assets/agents/cfn-dev-team/testers/unit/tdd-london-unit-swarm.md +1 -1
- package/claude-assets/agents/cfn-dev-team/utility/agent-builder.md +11 -0
- package/claude-assets/agents/cfn-dev-team/utility/analyst.md +1 -1
- package/claude-assets/agents/cfn-dev-team/utility/claude-code-expert.md +1 -1
- package/claude-assets/agents/cfn-dev-team/utility/epic-creator.md +1 -1
- package/claude-assets/agents/cfn-dev-team/utility/memory-leak-specialist.md +1 -1
- package/claude-assets/agents/cfn-dev-team/utility/researcher.md +1 -1
- package/claude-assets/agents/cfn-dev-team/utility/z-ai-specialist.md +1 -1
- package/claude-assets/agents/custom/cfn-docker-expert.md +1 -0
- package/claude-assets/agents/custom/cfn-loops-cli-expert.md +326 -17
- package/claude-assets/agents/custom/cfn-redis-operations.md +529 -529
- package/claude-assets/agents/custom/cfn-system-expert.md +1 -1
- package/claude-assets/agents/custom/trigger-dev-expert.md +369 -0
- package/claude-assets/agents/docker-team/micro-sprint-planner.md +747 -747
- package/claude-assets/agents/project-only-agents/npm-package-specialist.md +1 -1
- package/claude-assets/cfn-extras/skills/GOOGLE_SHEETS_SKILLS_README.md +1 -1
- package/claude-assets/cfn-extras/skills/google-sheets-api-coordinator/SKILL.md +1 -1
- package/claude-assets/cfn-extras/skills/google-sheets-formula-builder/SKILL.md +1 -1
- package/claude-assets/cfn-extras/skills/google-sheets-progress/SKILL.md +1 -1
- package/claude-assets/commands/CFN_LOOP_FRONTEND.md +1 -1
- package/claude-assets/commands/cfn-loop-cli.md +124 -46
- package/claude-assets/commands/cfn-loop-frontend.md +1 -1
- package/claude-assets/commands/cfn-loop-task.md +2 -2
- package/claude-assets/commands/deprecated/cfn-loop.md +2 -2
- package/claude-assets/hooks/GIT-HOOKS-USAGE-EXAMPLES.md +116 -0
- package/claude-assets/hooks/README-GIT-HOOKS.md +443 -0
- package/claude-assets/hooks/cfn-invoke-post-edit.sh +31 -5
- package/claude-assets/hooks/cfn-post-edit.config.json +9 -2
- package/claude-assets/hooks/install-git-hooks.sh +243 -0
- package/claude-assets/hooks/subagent-start.sh +98 -0
- package/claude-assets/hooks/subagent-stop.sh +93 -0
- package/claude-assets/hooks/validators/credential-scanner.sh +172 -0
- package/claude-assets/root-claude-distribute/CFN-CLAUDE.md +1 -1
- package/claude-assets/skills/cfn-backlog-management/SKILL.md +1 -1
- package/claude-assets/skills/cfn-dependency-ingestion/SKILL.md +41 -13
- package/claude-assets/skills/cfn-dependency-ingestion/ingest.sh +237 -0
- package/claude-assets/skills/cfn-dependency-ingestion/manifests/cli-mode-dependencies.txt +73 -0
- package/claude-assets/skills/cfn-dependency-ingestion/manifests/shared-dependencies.txt +57 -0
- package/claude-assets/skills/cfn-dependency-ingestion/manifests/trigger-dev-dependencies.txt +82 -0
- package/claude-assets/skills/cfn-dependency-ingestion/manifests/trigger-mode-dependencies.txt +80 -0
- package/claude-assets/skills/cfn-environment-sanitization/sanitize-environment.sh +14 -4
- package/claude-assets/skills/cfn-loop-orchestration/NORTH_STAR_INDEX.md +1 -1
- package/claude-assets/skills/cfn-provider-routing/SKILL.md +23 -0
- package/claude-assets/skills/docker-build/build.sh +1 -1
- package/dist/agent/skill-mcp-selector.js +2 -1
- package/dist/agent/skill-mcp-selector.js.map +1 -1
- package/dist/agents/agent-loader.js +165 -146
- package/dist/agents/agent-loader.js.map +1 -1
- package/dist/cli/agent-executor.js +470 -26
- package/dist/cli/agent-executor.js.map +1 -1
- package/dist/cli/agent-prompt-builder.js +2 -2
- package/dist/cli/agent-prompt-builder.js.map +1 -1
- package/dist/cli/agent-spawn.js +7 -4
- package/dist/cli/agent-spawn.js.map +1 -1
- package/dist/cli/agent-spawner.js +51 -4
- package/dist/cli/agent-spawner.js.map +1 -1
- package/dist/cli/agent-token-manager.js +2 -1
- package/dist/cli/agent-token-manager.js.map +1 -1
- package/dist/cli/anthropic-client.js +117 -11
- package/dist/cli/anthropic-client.js.map +1 -1
- package/dist/cli/cfn-context.js +2 -1
- package/dist/cli/cfn-context.js.map +1 -1
- package/dist/cli/cfn-metrics.js +2 -1
- package/dist/cli/cfn-metrics.js.map +1 -1
- package/dist/cli/cfn-redis.js +2 -1
- package/dist/cli/cfn-redis.js.map +1 -1
- package/dist/cli/cli-agent-context.js +2 -0
- package/dist/cli/cli-agent-context.js.map +1 -1
- package/dist/cli/config-manager.js +4 -252
- package/dist/cli/config-manager.js.map +1 -1
- package/dist/cli/conversation-fork-cleanup.js +2 -1
- package/dist/cli/conversation-fork-cleanup.js.map +1 -1
- package/dist/cli/conversation-fork.js +2 -1
- package/dist/cli/conversation-fork.js.map +1 -1
- package/dist/cli/coordination/agent-messaging.js +415 -0
- package/dist/cli/coordination/agent-messaging.js.map +1 -0
- package/dist/cli/coordination/wait-for-threshold.js +232 -0
- package/dist/cli/coordination/wait-for-threshold.js.map +1 -0
- package/dist/cli/iteration-history.js +2 -1
- package/dist/cli/iteration-history.js.map +1 -1
- package/dist/cli/process-lifecycle.js +5 -1
- package/dist/cli/process-lifecycle.js.map +1 -1
- package/dist/cli/spawn-agent-cli.js +41 -6
- package/dist/cli/spawn-agent-cli.js.map +1 -1
- package/dist/coordination/redis-waiting-mode.js +4 -0
- package/dist/coordination/redis-waiting-mode.js.map +1 -1
- package/dist/lib/artifact-registry.js +4 -0
- package/dist/lib/artifact-registry.js.map +1 -1
- package/dist/lib/connection-pool.js +390 -0
- package/dist/lib/connection-pool.js.map +1 -0
- package/dist/lib/environment-contract.js +258 -0
- package/dist/lib/environment-contract.js.map +1 -0
- package/dist/lib/query-optimizer.js +388 -0
- package/dist/lib/query-optimizer.js.map +1 -0
- package/dist/lib/result-cache.js +285 -0
- package/dist/lib/result-cache.js.map +1 -0
- package/dist/mcp/auth-middleware.js +2 -1
- package/dist/mcp/auth-middleware.js.map +1 -1
- package/dist/mcp/playwright-mcp-server-auth.js +2 -1
- package/dist/mcp/playwright-mcp-server-auth.js.map +1 -1
- package/package.json +3 -1
- package/scripts/build-agent-image.sh +1 -1
- package/scripts/cost-allocation-tracker.sh +632 -0
- package/scripts/docker-rebuild-all-agents.sh +2 -2
- package/scripts/reorganize-tests.sh +280 -0
- package/scripts/trigger-dev-setup.sh +12 -0
- package/tests/README.md +45 -0
- package/.claude/commands/cost-savings-status.md +0 -34
- package/.claude/commands/metrics-summary.md +0 -58
- package/claude-assets/agents/cfn-dev-team/dev-ops/monitoring-specialist.md +0 -768
- package/claude-assets/agents/custom/test-mcp-access.md +0 -24
- package/claude-assets/commands/cost-savings-status.md +0 -34
- package/claude-assets/commands/metrics-summary.md +0 -58
- package/tests/test-memory-leak-task-mode.sh +0 -435
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/cli/spawn-agent-cli.ts"],"sourcesContent":["#!/usr/bin/env node\r\n/**\r\n * Agent Spawning CLI Entry Point\r\n *\r\n * Provides command-line interface for spawning agents.\r\n * Fully backward compatible with bash version.\r\n *\r\n * Usage:\r\n * spawn-agent-cli <agent-type> --task-id <id> [--iteration N] [--mode mode]\r\n * spawn-agent-cli --help\r\n * spawn-agent-cli --version\r\n */\r\n\r\nimport { AgentSpawner } from './agent-spawner';\r\nimport { writeFileSync, readFileSync } from 'fs';\r\nimport { resolve } from 'path';\r\n\r\ninterface CLIArgs {\r\n agentType?: string;\r\n taskId?: string;\r\n iteration?: number;\r\n mode?: 'mvp' | 'standard' | 'enterprise';\r\n provider?: string;\r\n model?: string;\r\n background?: boolean;\r\n help?: boolean;\r\n version?: boolean;\r\n json?: boolean;\r\n [key: string]: unknown;\r\n}\r\n\r\n/**\r\n * Parse command-line arguments\r\n */\r\nfunction parseArgs(args: string[]): CLIArgs {\r\n const parsed: CLIArgs = {\r\n background: true\r\n };\r\n\r\n for (let i = 0; i < args.length; i++) {\r\n const arg = args[i];\r\n\r\n if (arg === '--help') {\r\n parsed.help = true;\r\n } else if (arg === '--version') {\r\n parsed.version = true;\r\n } else if (arg === '--json') {\r\n parsed.json = true;\r\n } else if (arg === '--foreground') {\r\n parsed.background = false;\r\n } else if (arg === '--background') {\r\n parsed.background = true;\r\n } else if (arg === '--task-id' || arg === '-t') {\r\n parsed.taskId = args[++i];\r\n } else if (arg === '--iteration' || arg === '-i') {\r\n parsed.iteration = parseInt(args[++i], 10);\r\n } else if (arg === '--mode' || arg === '-m') {\r\n parsed.mode = args[++i] as 'mvp' | 'standard' | 'enterprise';\r\n } else if (arg === '--provider' || arg === '-p') {\r\n parsed.provider = args[++i];\r\n } else if (arg === '--model') {\r\n parsed.model = args[++i];\r\n } else if (!arg.startsWith('-')) {\r\n if (!parsed.agentType) {\r\n parsed.agentType = arg;\r\n }\r\n }\r\n }\r\n\r\n return parsed;\r\n}\r\n\r\n/**\r\n * Print help message\r\n */\r\nfunction printHelp(): void {\r\n console.log(`\r\nAgent Spawning CLI\r\n\r\nUSAGE:\r\n spawn-agent-cli <agent-type> [OPTIONS]\r\n\r\nARGUMENTS:\r\n <agent-type> Type of agent to spawn (e.g., backend-dev, tester)\r\n\r\nOPTIONS:\r\n -t, --task-id <id> Task ID for coordination (required for CLI mode)\r\n -i, --iteration <n> Iteration number (default: 1)\r\n -m, --mode <mode> Mode: mvp, standard, enterprise (default: standard)\r\n -p, --provider <p> Provider: zai, anthropic, etc. (default: auto-detect)\r\n --model <model> Explicit model name (default: auto-detect)\r\n --foreground Run in foreground (default: background)\r\n --background Run in background (default)\r\n --json Output result as JSON\r\n -h, --help Show this help message\r\n -v, --version Show version information\r\n\r\nEXAMPLES:\r\n # Basic agent spawn\r\n spawn-agent-cli backend-dev --task-id task-123\r\n\r\n # With explicit iteration\r\n spawn-agent-cli tester --task-id task-123 --iteration 2\r\n\r\n # With custom provider\r\n spawn-agent-cli reviewer --task-id task-123 --provider anthropic\r\n\r\n # JSON output for integration\r\n spawn-agent-cli coder --task-id task-123 --json\r\n\r\nENVIRONMENT VARIABLES:\r\n TASK_ID Task ID (can be set instead of --task-id)\r\n PROJECT_ROOT Project root directory (default: cwd)\r\n AGENT_ID Custom agent ID (default: generated)\r\n`);\r\n}\r\n\r\n/**\r\n * Print version information\r\n */\r\nfunction printVersion(): void {\r\n try {\r\n const packageJson = JSON.parse(\r\n readFileSync(resolve(__dirname, '../../package.json'), 'utf-8')\r\n );\r\n console.log(`spawn-agent-cli v${packageJson.version}`);\r\n } catch {\r\n console.log('spawn-agent-cli v1.0.0');\r\n }\r\n}\r\n\r\n/**\r\n * Validate CLI arguments\r\n */\r\nfunction validateArgs(args: CLIArgs): { valid: boolean; errors: string[] } {\r\n const errors: string[] = [];\r\n\r\n if (!args.agentType) {\r\n errors.push('Agent type is required');\r\n }\r\n\r\n const taskId = args.taskId || process.env.TASK_ID;\r\n if (!taskId) {\r\n errors.push('Task ID is required (--task-id or TASK_ID env var)');\r\n }\r\n\r\n if (args.taskId && !/^[a-zA-Z0-9_.-]{1,64}$/.test(args.taskId)) {\r\n errors.push('Invalid task ID format');\r\n }\r\n\r\n if (args.iteration && (args.iteration < 1 || !Number.isInteger(args.iteration))) {\r\n errors.push('Iteration must be a positive integer');\r\n }\r\n\r\n if (args.mode && !['mvp', 'standard', 'enterprise'].includes(args.mode)) {\r\n errors.push('Mode must be mvp, standard, or enterprise');\r\n }\r\n\r\n return {\r\n valid: errors.length === 0,\r\n errors\r\n };\r\n}\r\n\r\n/**\r\n * Format output based on options\r\n */\r\nfunction formatOutput(result: unknown, json: boolean = false): string {\r\n if (json) {\r\n return JSON.stringify(result, null, 2);\r\n }\r\n\r\n if (typeof result === 'object' && result !== null) {\r\n const obj = result as Record<string, unknown>;\r\n if (obj.status === 'failed') {\r\n return `ERROR: ${obj.error || 'Failed to spawn agent'}`;\r\n }\r\n return `Agent spawned: ${obj.agentId} (PID: ${obj.pid})`;\r\n }\r\n\r\n return String(result);\r\n}\r\n\r\n/**\r\n * Main CLI function\r\n */\r\nasync function main(): Promise<void> {\r\n const args = parseArgs(process.argv.slice(2));\r\n\r\n // Handle flags\r\n if (args.help) {\r\n printHelp();\r\n process.exit(0);\r\n }\r\n\r\n if (args.version) {\r\n printVersion();\r\n process.exit(0);\r\n }\r\n\r\n // Validate arguments\r\n const taskId = args.taskId || process.env.TASK_ID;\r\n const validation = validateArgs({ ...args, taskId });\r\n\r\n if (!validation.valid) {\r\n console.error('Argument validation failed:');\r\n validation.errors.forEach(err => console.error(` - ${err}`));\r\n console.error('Use --help for usage information');\r\n process.exit(1);\r\n }\r\n\r\n // Create spawner\r\n const projectRoot = process.env.PROJECT_ROOT || process.cwd();\r\n const spawner = new AgentSpawner(projectRoot);\r\n\r\n // Build config\r\n const config = {\r\n agentType: args.agentType!,\r\n taskId: taskId!,\r\n iteration: args.iteration || 1,\r\n mode: args.mode || 'standard' as const,\r\n provider: args.provider,\r\n model: args.model,\r\n background: args.background !== false,\r\n env: {\r\n TASK_ID: taskId!\r\n }\r\n };\r\n\r\n try {\r\n // Spawn agent\r\n const result = await spawner.spawnAgent(config);\r\n\r\n // Output result\r\n console.log(formatOutput(result, args.json));\r\n\r\n // Exit with appropriate code\r\n process.exit(result.status === 'spawned' ? 0 : 1);\r\n } catch (error) {\r\n const errorMsg = error instanceof Error ? error.message : String(error);\r\n console.error(`ERROR: ${errorMsg}`);\r\n process.exit(2);\r\n }\r\n}\r\n\r\n// Run main function\r\nmain().catch((error) => {\r\n console.error('Unexpected error:', error);\r\n process.exit(2);\r\n});\r\n\r\nexport { parseArgs, validateArgs, formatOutput };\r\n"],"names":["AgentSpawner","readFileSync","resolve","parseArgs","args","parsed","background","i","length","arg","help","version","json","taskId","iteration","parseInt","mode","provider","model","startsWith","agentType","printHelp","console","log","printVersion","packageJson","JSON","parse","__dirname","validateArgs","errors","push","process","env","TASK_ID","test","Number","isInteger","includes","valid","formatOutput","result","stringify","obj","status","error","agentId","pid","String","main","argv","slice","exit","validation","forEach","err","projectRoot","PROJECT_ROOT","cwd","spawner","config","spawnAgent","errorMsg","Error","message","catch"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/cli/spawn-agent-cli.ts"],"sourcesContent":["#!/usr/bin/env node\r\n/**\r\n * Agent Spawning CLI Entry Point\r\n *\r\n * Provides command-line interface for spawning agents.\r\n * Fully backward compatible with bash version.\r\n *\r\n * Usage:\r\n * spawn-agent-cli <agent-type> --task-id <id> [--iteration N] [--mode mode]\r\n * spawn-agent-cli --help\r\n * spawn-agent-cli --version\r\n */\r\n\r\nimport { AgentSpawner } from './agent-spawner';\r\nimport { writeFileSync, readFileSync } from 'fs';\r\nimport { resolve, dirname } from 'path';\r\nimport { fileURLToPath } from 'url';\r\n\r\n// ESM-compatible __dirname\r\nconst __filename = fileURLToPath(import.meta.url);\r\nconst __dirname = dirname(__filename);\r\n\r\ninterface CLIArgs {\r\n agentType?: string;\r\n taskId?: string;\r\n iteration?: number;\r\n mode?: 'mvp' | 'standard' | 'enterprise';\r\n provider?: string;\r\n model?: string;\r\n prompt?: string;\r\n background?: boolean;\r\n help?: boolean;\r\n version?: boolean;\r\n json?: boolean;\r\n [key: string]: unknown;\r\n}\r\n\r\n/**\r\n * Parse command-line arguments\r\n */\r\nfunction parseArgs(args: string[]): CLIArgs {\r\n const parsed: CLIArgs = {\r\n background: true\r\n };\r\n\r\n for (let i = 0; i < args.length; i++) {\r\n const arg = args[i];\r\n\r\n if (arg === '--help') {\r\n parsed.help = true;\r\n } else if (arg === '--version') {\r\n parsed.version = true;\r\n } else if (arg === '--json') {\r\n parsed.json = true;\r\n } else if (arg === '--foreground') {\r\n parsed.background = false;\r\n } else if (arg === '--background') {\r\n parsed.background = true;\r\n } else if (arg === '--task-id' || arg === '-t') {\r\n parsed.taskId = args[++i];\r\n } else if (arg === '--iteration' || arg === '-i') {\r\n parsed.iteration = parseInt(args[++i], 10);\r\n } else if (arg === '--mode' || arg === '-m') {\r\n parsed.mode = args[++i] as 'mvp' | 'standard' | 'enterprise';\r\n } else if (arg === '--provider' || arg === '-p') {\r\n parsed.provider = args[++i];\r\n } else if (arg === '--model') {\r\n parsed.model = args[++i];\r\n } else if (arg === '--prompt') {\r\n parsed.prompt = args[++i];\r\n } else if (!arg.startsWith('-')) {\r\n if (!parsed.agentType) {\r\n parsed.agentType = arg;\r\n }\r\n }\r\n }\r\n\r\n return parsed;\r\n}\r\n\r\n/**\r\n * Print help message\r\n */\r\nfunction printHelp(): void {\r\n console.log(`\r\nAgent Spawning CLI\r\n\r\nUSAGE:\r\n spawn-agent-cli <agent-type> [OPTIONS]\r\n\r\nARGUMENTS:\r\n <agent-type> Type of agent to spawn (e.g., backend-dev, tester)\r\n\r\nOPTIONS:\r\n -t, --task-id <id> Task ID for coordination (required for CLI mode)\r\n -i, --iteration <n> Iteration number (default: 1)\r\n -m, --mode <mode> Mode: mvp, standard, enterprise (default: standard)\r\n -p, --provider <p> Provider: zai, anthropic, etc. (default: auto-detect)\r\n --model <model> Explicit model name (default: auto-detect)\r\n --prompt <text> Task prompt/description to pass to agent\r\n --foreground Run in foreground (default: background)\r\n --background Run in background (default)\r\n --json Output result as JSON\r\n -h, --help Show this help message\r\n -v, --version Show version information\r\n\r\nEXAMPLES:\r\n # Basic agent spawn\r\n spawn-agent-cli backend-dev --task-id task-123\r\n\r\n # With explicit iteration\r\n spawn-agent-cli tester --task-id task-123 --iteration 2\r\n\r\n # With custom provider\r\n spawn-agent-cli reviewer --task-id task-123 --provider anthropic\r\n\r\n # JSON output for integration\r\n spawn-agent-cli coder --task-id task-123 --json\r\n\r\nENVIRONMENT VARIABLES:\r\n TASK_ID Task ID (can be set instead of --task-id)\r\n PROJECT_ROOT Project root directory (default: cwd)\r\n AGENT_ID Custom agent ID (default: generated)\r\n`);\r\n}\r\n\r\n/**\r\n * Print version information\r\n */\r\nfunction printVersion(): void {\r\n try {\r\n const packageJson = JSON.parse(\r\n readFileSync(resolve(__dirname, '../../package.json'), 'utf-8')\r\n );\r\n console.log(`spawn-agent-cli v${packageJson.version}`);\r\n } catch {\r\n console.log('spawn-agent-cli v1.0.0');\r\n }\r\n}\r\n\r\n/**\r\n * Phase 1: Mode Prefix Function for CLI/Trigger.dev Collision Mitigation\r\n *\r\n * Generates task ID with mode prefix to prevent Redis key collisions between\r\n * CLI mode and Trigger.dev Docker mode. Both modes share identical Redis coordination\r\n * patterns and must use isolated namespaces.\r\n *\r\n * @param rawTaskId - Original task ID without prefix\r\n * @param mode - Execution mode: 'cli' for CLI mode, 'trigger' for Trigger.dev\r\n * @returns Prefixed task ID in format \"MODE:rawTaskId\"\r\n *\r\n * Example:\r\n * generateTaskId('task-123', 'cli') => 'cli:task-123'\r\n * generateTaskId('task-123', 'trigger') => 'trigger:task-123'\r\n *\r\n * Redis Key Isolation (After):\r\n * CLI: cfn:task:cli:task-123:status\r\n * Trigger: cfn:task:trigger:task-123:status\r\n */\r\nfunction generateTaskId(rawTaskId: string, mode: 'cli' | 'trigger'): string {\r\n // Don't add prefix if task ID already has a namespace prefix\r\n if (/^[a-z]+:/.test(rawTaskId)) {\r\n return rawTaskId;\r\n }\r\n return `${mode}:${rawTaskId}`;\r\n}\r\n\r\n/**\r\n * Validate CLI arguments\r\n */\r\nfunction validateArgs(args: CLIArgs): { valid: boolean; errors: string[] } {\r\n const errors: string[] = [];\r\n\r\n if (!args.agentType) {\r\n errors.push('Agent type is required');\r\n }\r\n\r\n const taskId = args.taskId || process.env.TASK_ID;\r\n if (!taskId) {\r\n errors.push('Task ID is required (--task-id or TASK_ID env var)');\r\n }\r\n\r\n // Allow optional namespace prefix (e.g., \"cli:\", \"task:\") for coordination routing\r\n if (taskId && !/^([a-z]+:)?[a-zA-Z0-9_.-]{1,64}$/.test(taskId)) {\r\n errors.push('Invalid task ID format');\r\n }\r\n\r\n if (args.iteration && (args.iteration < 1 || !Number.isInteger(args.iteration))) {\r\n errors.push('Iteration must be a positive integer');\r\n }\r\n\r\n if (args.mode && !['mvp', 'standard', 'enterprise'].includes(args.mode)) {\r\n errors.push('Mode must be mvp, standard, or enterprise');\r\n }\r\n\r\n return {\r\n valid: errors.length === 0,\r\n errors\r\n };\r\n}\r\n\r\n/**\r\n * Format output based on options\r\n */\r\nfunction formatOutput(result: unknown, json: boolean = false): string {\r\n if (json) {\r\n return JSON.stringify(result, null, 2);\r\n }\r\n\r\n if (typeof result === 'object' && result !== null) {\r\n const obj = result as Record<string, unknown>;\r\n if (obj.status === 'failed') {\r\n return `ERROR: ${obj.error || 'Failed to spawn agent'}`;\r\n }\r\n return `Agent spawned: ${obj.agentId} (PID: ${obj.pid})`;\r\n }\r\n\r\n return String(result);\r\n}\r\n\r\n/**\r\n * Main CLI function\r\n */\r\nasync function main(): Promise<void> {\r\n const args = parseArgs(process.argv.slice(2));\r\n\r\n // Handle flags\r\n if (args.help) {\r\n printHelp();\r\n process.exit(0);\r\n }\r\n\r\n if (args.version) {\r\n printVersion();\r\n process.exit(0);\r\n }\r\n\r\n // Validate arguments\r\n const taskId = args.taskId || process.env.TASK_ID;\r\n const validation = validateArgs({ ...args, taskId });\r\n\r\n if (!validation.valid) {\r\n console.error('Argument validation failed:');\r\n validation.errors.forEach(err => console.error(` - ${err}`));\r\n console.error('Use --help for usage information');\r\n process.exit(1);\r\n }\r\n\r\n // Create spawner\r\n const projectRoot = process.env.PROJECT_ROOT || process.cwd();\r\n const spawner = new AgentSpawner(projectRoot);\r\n\r\n // Build config with CLI mode prefix for Redis key isolation (Phase 1)\r\n const prefixedTaskId = generateTaskId(taskId!, 'cli');\r\n const config = {\r\n agentType: args.agentType!,\r\n taskId: prefixedTaskId,\r\n iteration: args.iteration || 1,\r\n mode: args.mode || 'standard' as const,\r\n provider: args.provider,\r\n model: args.model,\r\n prompt: args.prompt,\r\n background: args.background !== false,\r\n env: {\r\n TASK_ID: prefixedTaskId\r\n }\r\n };\r\n\r\n try {\r\n // Spawn agent\r\n const result = await spawner.spawnAgent(config);\r\n\r\n // Output result\r\n console.log(formatOutput(result, args.json));\r\n\r\n // Exit with appropriate code\r\n process.exit(result.status === 'spawned' ? 0 : 1);\r\n } catch (error) {\r\n const errorMsg = error instanceof Error ? error.message : String(error);\r\n console.error(`ERROR: ${errorMsg}`);\r\n process.exit(2);\r\n }\r\n}\r\n\r\n// Run main function\r\nmain().catch((error) => {\r\n console.error('Unexpected error:', error);\r\n process.exit(2);\r\n});\r\n\r\nexport { parseArgs, validateArgs, formatOutput, generateTaskId };\r\n"],"names":["AgentSpawner","readFileSync","resolve","dirname","fileURLToPath","__filename","url","__dirname","parseArgs","args","parsed","background","i","length","arg","help","version","json","taskId","iteration","parseInt","mode","provider","model","prompt","startsWith","agentType","printHelp","console","log","printVersion","packageJson","JSON","parse","generateTaskId","rawTaskId","test","validateArgs","errors","push","process","env","TASK_ID","Number","isInteger","includes","valid","formatOutput","result","stringify","obj","status","error","agentId","pid","String","main","argv","slice","exit","validation","forEach","err","projectRoot","PROJECT_ROOT","cwd","spawner","prefixedTaskId","config","spawnAgent","errorMsg","Error","message","catch"],"mappings":"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"}
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import Redis from 'ioredis';
|
|
2
2
|
import { readFileSync } from 'fs';
|
|
3
3
|
import path from 'path';
|
|
4
|
+
import { fileURLToPath } from 'url';
|
|
5
|
+
// ESM-compatible __dirname
|
|
6
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
7
|
+
const __dirname = path.dirname(__filename);
|
|
4
8
|
export class RedisWaitingMode {
|
|
5
9
|
redis;
|
|
6
10
|
config;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/coordination/redis-waiting-mode.ts"],"sourcesContent":["import Redis from 'ioredis';\nimport { readFileSync } from 'fs';\nimport path from 'path';\n\ninterface RedisConfig {\n host: string;\n port: number;\n db: number;\n}\n\ninterface WaitingModeConfig {\n defaultTimeout: number;\n wakeChannelPattern: string;\n resultKeyPattern: string;\n consensusThreshold: number;\n}\n\nexport class RedisWaitingMode {\n private redis: Redis;\n private config: RedisConfig & { waitingMode: WaitingModeConfig };\n\n constructor() {\n const configPath = path.resolve(__dirname, '../../.claude/skills/redis-coordination/config.json');\n const configFile = readFileSync(configPath, 'utf-8');\n this.config = JSON.parse(configFile);\n\n this.redis = new Redis({\n host: this.config.host,\n port: this.config.port,\n db: this.config.db\n });\n }\n\n async enterWaitingMode(taskId: string, agentId: string, context: string): Promise<any> {\n try {\n const wakeChannel = this.config.waitingMode.wakeChannelPattern\n .replace('{taskId}', taskId)\n .replace('{agentId}', agentId);\n\n const result = await this.redis.blpop(\n wakeChannel,\n this.config.waitingMode.defaultTimeout / 1000\n );\n\n return {\n status: result ? 'woken' : 'timeout',\n payload: result ? JSON.parse(result[1]) : null,\n context\n };\n } catch (error) {\n return {\n status: 'error',\n message: error instanceof Error ? error.message : 'Unknown error',\n context\n };\n }\n }\n\n async wakeAgent(taskId: string, agentId: string, payload: any): Promise<any> {\n try {\n const wakeChannel = this.config.waitingMode.wakeChannelPattern\n .replace('{taskId}', taskId)\n .replace('{agentId}', agentId);\n\n await this.redis.lpush(wakeChannel, JSON.stringify(payload));\n\n return {\n status: 'success',\n taskId,\n agentId,\n payload\n };\n } catch (error) {\n return {\n status: 'error',\n message: error instanceof Error ? error.message : 'Unknown error',\n taskId,\n agentId\n };\n }\n }\n\n async reportResult(taskId: string, agentId: string, result: any, confidence: number): Promise<any> {\n try {\n const resultKey = this.config.waitingMode.resultKeyPattern\n .replace('{taskId}', taskId)\n .replace('{agentId}', agentId);\n\n await this.redis.set(resultKey, JSON.stringify({\n result,\n confidence,\n timestamp: Date.now()\n }));\n\n return {\n status: 'success',\n taskId,\n agentId,\n confidence\n };\n } catch (error) {\n return {\n status: 'error',\n message: error instanceof Error ? error.message : 'Unknown error',\n taskId,\n agentId\n };\n }\n }\n\n async collectConsensus(taskId: string, agentIds: string[]): Promise<any> {\n try {\n const results = await Promise.all(\n agentIds.map(async (agentId) => {\n const resultKey = this.config.waitingMode.resultKeyPattern\n .replace('{taskId}', taskId)\n .replace('{agentId}', agentId);\n\n const resultStr = await this.redis.get(resultKey);\n return resultStr ? JSON.parse(resultStr) : null;\n })\n );\n\n const validResults = results.filter(r => r && r.confidence);\n const avgConfidence = validResults.length\n ? validResults.reduce((sum, r) => sum + r.confidence, 0) / validResults.length\n : 0;\n\n const consensusReached = avgConfidence >= this.config.waitingMode.consensusThreshold;\n\n return {\n status: consensusReached ? 'consensus' : 'insufficient_consensus',\n taskId,\n results: validResults,\n avgConfidence,\n consensusThreshold: this.config.waitingMode.consensusThreshold\n };\n } catch (error) {\n return {\n status: 'error',\n message: error instanceof Error ? error.message : 'Unknown error',\n taskId\n };\n }\n }\n}\n\n// Export a singleton instance for easier use\nexport const redisWaitingMode = new RedisWaitingMode();\n"],"names":["Redis","readFileSync","path","RedisWaitingMode","redis","config","configPath","resolve","
|
|
1
|
+
{"version":3,"sources":["../../src/coordination/redis-waiting-mode.ts"],"sourcesContent":["import Redis from 'ioredis';\nimport { readFileSync } from 'fs';\nimport path from 'path';\nimport { fileURLToPath } from 'url';\n\n// ESM-compatible __dirname\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\ninterface RedisConfig {\n host: string;\n port: number;\n db: number;\n}\n\ninterface WaitingModeConfig {\n defaultTimeout: number;\n wakeChannelPattern: string;\n resultKeyPattern: string;\n consensusThreshold: number;\n}\n\nexport class RedisWaitingMode {\n private redis: Redis;\n private config: RedisConfig & { waitingMode: WaitingModeConfig };\n\n constructor() {\n const configPath = path.resolve(__dirname, '../../.claude/skills/redis-coordination/config.json');\n const configFile = readFileSync(configPath, 'utf-8');\n this.config = JSON.parse(configFile);\n\n this.redis = new Redis({\n host: this.config.host,\n port: this.config.port,\n db: this.config.db\n });\n }\n\n async enterWaitingMode(taskId: string, agentId: string, context: string): Promise<any> {\n try {\n const wakeChannel = this.config.waitingMode.wakeChannelPattern\n .replace('{taskId}', taskId)\n .replace('{agentId}', agentId);\n\n const result = await this.redis.blpop(\n wakeChannel,\n this.config.waitingMode.defaultTimeout / 1000\n );\n\n return {\n status: result ? 'woken' : 'timeout',\n payload: result ? JSON.parse(result[1]) : null,\n context\n };\n } catch (error) {\n return {\n status: 'error',\n message: error instanceof Error ? error.message : 'Unknown error',\n context\n };\n }\n }\n\n async wakeAgent(taskId: string, agentId: string, payload: any): Promise<any> {\n try {\n const wakeChannel = this.config.waitingMode.wakeChannelPattern\n .replace('{taskId}', taskId)\n .replace('{agentId}', agentId);\n\n await this.redis.lpush(wakeChannel, JSON.stringify(payload));\n\n return {\n status: 'success',\n taskId,\n agentId,\n payload\n };\n } catch (error) {\n return {\n status: 'error',\n message: error instanceof Error ? error.message : 'Unknown error',\n taskId,\n agentId\n };\n }\n }\n\n async reportResult(taskId: string, agentId: string, result: any, confidence: number): Promise<any> {\n try {\n const resultKey = this.config.waitingMode.resultKeyPattern\n .replace('{taskId}', taskId)\n .replace('{agentId}', agentId);\n\n await this.redis.set(resultKey, JSON.stringify({\n result,\n confidence,\n timestamp: Date.now()\n }));\n\n return {\n status: 'success',\n taskId,\n agentId,\n confidence\n };\n } catch (error) {\n return {\n status: 'error',\n message: error instanceof Error ? error.message : 'Unknown error',\n taskId,\n agentId\n };\n }\n }\n\n async collectConsensus(taskId: string, agentIds: string[]): Promise<any> {\n try {\n const results = await Promise.all(\n agentIds.map(async (agentId) => {\n const resultKey = this.config.waitingMode.resultKeyPattern\n .replace('{taskId}', taskId)\n .replace('{agentId}', agentId);\n\n const resultStr = await this.redis.get(resultKey);\n return resultStr ? JSON.parse(resultStr) : null;\n })\n );\n\n const validResults = results.filter(r => r && r.confidence);\n const avgConfidence = validResults.length\n ? validResults.reduce((sum, r) => sum + r.confidence, 0) / validResults.length\n : 0;\n\n const consensusReached = avgConfidence >= this.config.waitingMode.consensusThreshold;\n\n return {\n status: consensusReached ? 'consensus' : 'insufficient_consensus',\n taskId,\n results: validResults,\n avgConfidence,\n consensusThreshold: this.config.waitingMode.consensusThreshold\n };\n } catch (error) {\n return {\n status: 'error',\n message: error instanceof Error ? error.message : 'Unknown error',\n taskId\n };\n }\n }\n}\n\n// Export a singleton instance for easier use\nexport const redisWaitingMode = new RedisWaitingMode();\n"],"names":["Redis","readFileSync","path","fileURLToPath","__filename","url","__dirname","dirname","RedisWaitingMode","redis","config","configPath","resolve","configFile","JSON","parse","host","port","db","enterWaitingMode","taskId","agentId","context","wakeChannel","waitingMode","wakeChannelPattern","replace","result","blpop","defaultTimeout","status","payload","error","message","Error","wakeAgent","lpush","stringify","reportResult","confidence","resultKey","resultKeyPattern","set","timestamp","Date","now","collectConsensus","agentIds","results","Promise","all","map","resultStr","get","validResults","filter","r","avgConfidence","length","reduce","sum","consensusReached","consensusThreshold","redisWaitingMode"],"mappings":"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"}
|
|
@@ -6,6 +6,10 @@
|
|
|
6
6
|
import { createHash } from 'crypto';
|
|
7
7
|
import { readFileSync, existsSync, mkdirSync, statSync } from 'fs';
|
|
8
8
|
import { join, dirname } from 'path';
|
|
9
|
+
import { fileURLToPath } from 'url';
|
|
10
|
+
// ESM-compatible __dirname
|
|
11
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
12
|
+
const __dirname = dirname(__filename);
|
|
9
13
|
// ============================================================================
|
|
10
14
|
// Error Classes
|
|
11
15
|
// ============================================================================
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/lib/artifact-registry.ts"],"sourcesContent":["/**\r\n * Artifact Registry TypeScript API\r\n * Provides centralized artifact management with TTL-based cleanup\r\n * Version: 1.0.0\r\n */\r\n\r\nimport Database from 'better-sqlite3';\r\nimport { createHash } from 'crypto';\r\nimport { readFileSync, existsSync, mkdirSync, statSync } from 'fs';\r\nimport { join, dirname } from 'path';\r\n\r\n// ============================================================================\r\n// Types and Interfaces\r\n// ============================================================================\r\n\r\nexport type ArtifactType = 'code' | 'documentation' | 'test' | 'config' | 'binary' | 'data' | 'model' | 'report' | 'other';\r\nexport type ArtifactStatus = 'active' | 'archived' | 'deleted';\r\nexport type RetentionPolicy = 'ephemeral' | 'standard' | 'permanent' | 'custom';\r\n\r\nexport interface ArtifactMetadata {\r\n name: string;\r\n type: ArtifactType;\r\n format?: string;\r\n content?: string;\r\n storage_location: string;\r\n swarm_id?: string;\r\n agent_id?: string;\r\n task_id?: string;\r\n version?: number;\r\n parent_artifact_id?: string;\r\n artifact_chain?: string[];\r\n tags?: string[];\r\n metadata?: Record<string, any>;\r\n acl_level?: number;\r\n is_compressed?: boolean;\r\n compression_type?: string;\r\n retention_days?: number;\r\n retention_policy?: RetentionPolicy;\r\n}\r\n\r\nexport interface Artifact {\r\n id: string;\r\n name: string;\r\n type: ArtifactType;\r\n format?: string;\r\n content?: string;\r\n content_hash?: string;\r\n size_bytes?: number;\r\n storage_location: string;\r\n checksum?: string;\r\n is_compressed: boolean;\r\n compression_type?: string;\r\n swarm_id?: string;\r\n agent_id?: string;\r\n task_id?: string;\r\n version: number;\r\n parent_artifact_id?: string;\r\n artifact_chain?: string;\r\n tags?: string;\r\n metadata?: string;\r\n acl_level: number;\r\n retention_days: number;\r\n retention_policy: RetentionPolicy;\r\n expires_at?: string;\r\n status: ArtifactStatus;\r\n cleanup_eligible: boolean;\r\n created_at: string;\r\n updated_at: string;\r\n archived_at?: string;\r\n deleted_at?: string;\r\n}\r\n\r\nexport interface ArtifactFilters {\r\n type?: ArtifactType;\r\n status?: ArtifactStatus;\r\n retention_policy?: RetentionPolicy;\r\n swarm_id?: string;\r\n agent_id?: string;\r\n task_id?: string;\r\n tags?: string[];\r\n cleanup_eligible?: boolean;\r\n created_after?: Date;\r\n created_before?: Date;\r\n expires_before?: Date;\r\n limit?: number;\r\n offset?: number;\r\n}\r\n\r\nexport interface ArtifactStats {\r\n total: number;\r\n active: number;\r\n archived: number;\r\n deleted: number;\r\n cleanup_eligible: number;\r\n total_size_bytes: number;\r\n}\r\n\r\n// ============================================================================\r\n// Error Classes\r\n// ============================================================================\r\n\r\nexport class ArtifactRegistryError extends Error {\r\n constructor(message: string, public code: string, public details?: any) {\r\n super(message);\r\n this.name = 'ArtifactRegistryError';\r\n }\r\n}\r\n\r\nexport class ArtifactNotFoundError extends ArtifactRegistryError {\r\n constructor(id: string) {\r\n super(`Artifact not found: ${id}`, 'ARTIFACT_NOT_FOUND', { id });\r\n this.name = 'ArtifactNotFoundError';\r\n }\r\n}\r\n\r\nexport class ArtifactValidationError extends ArtifactRegistryError {\r\n constructor(message: string, details?: any) {\r\n super(message, 'VALIDATION_ERROR', details);\r\n this.name = 'ArtifactValidationError';\r\n }\r\n}\r\n\r\nexport class ArtifactDatabaseError extends ArtifactRegistryError {\r\n constructor(message: string, details?: any) {\r\n super(message, 'DATABASE_ERROR', details);\r\n this.name = 'ArtifactDatabaseError';\r\n }\r\n}\r\n\r\n// ============================================================================\r\n// Artifact Registry Class\r\n// ============================================================================\r\n\r\nexport class ArtifactRegistry {\r\n private db: Database.Database;\r\n private static instance: ArtifactRegistry | null = null;\r\n\r\n constructor(dbPath: string) {\r\n try {\r\n // Ensure database directory exists\r\n const dbDir = dirname(dbPath);\r\n if (!existsSync(dbDir)) {\r\n mkdirSync(dbDir, { recursive: true });\r\n }\r\n\r\n this.db = new Database(dbPath);\r\n this.db.pragma('journal_mode = WAL'); // Write-Ahead Logging for concurrency\r\n this.db.pragma('foreign_keys = ON');\r\n this.db.pragma('synchronous = NORMAL');\r\n\r\n this.initializeSchema();\r\n } catch (error) {\r\n throw new ArtifactDatabaseError(\r\n `Failed to initialize database: ${error instanceof Error ? error.message : String(error)}`,\r\n { dbPath, error }\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Get singleton instance (optional pattern)\r\n */\r\n static getInstance(dbPath?: string): ArtifactRegistry {\r\n if (!ArtifactRegistry.instance) {\r\n if (!dbPath) {\r\n throw new ArtifactDatabaseError('Database path required for first initialization', {});\r\n }\r\n ArtifactRegistry.instance = new ArtifactRegistry(dbPath);\r\n }\r\n return ArtifactRegistry.instance;\r\n }\r\n\r\n /**\r\n * Initialize database schema\r\n */\r\n private initializeSchema(): void {\r\n try {\r\n const schemaPath = join(__dirname, '../database/artifact-registry-schema.sql');\r\n if (!existsSync(schemaPath)) {\r\n throw new Error(`Schema file not found: ${schemaPath}`);\r\n }\r\n\r\n const schema = readFileSync(schemaPath, 'utf-8');\r\n\r\n // Step 1: Remove multi-line comments FIRST (they can contain semicolons)\r\n const withoutMultiLineComments = schema.replace(/\\/\\*[\\s\\S]*?\\*\\//g, '');\r\n\r\n // Step 2: Remove single-line comments\r\n const cleanedSchema = withoutMultiLineComments\r\n .split('\\n')\r\n .filter(line => {\r\n const trimmed = line.trim();\r\n return trimmed.length > 0 && !trimmed.startsWith('--');\r\n })\r\n .join('\\n');\r\n\r\n // Step 3: Execute entire schema as one block\r\n // SQLite's exec() can handle multiple statements including triggers with internal semicolons\r\n this.db.exec(cleanedSchema);\r\n } catch (error) {\r\n throw new ArtifactDatabaseError(\r\n `Failed to initialize schema: ${error instanceof Error ? error.message : String(error)}`,\r\n { error }\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Generate unique artifact ID\r\n */\r\n private generateId(): string {\r\n const timestamp = Date.now();\r\n const random = Math.random().toString(36).substring(2, 15);\r\n return `artifact-${timestamp}-${random}`;\r\n }\r\n\r\n /**\r\n * Calculate checksum for file\r\n */\r\n private calculateChecksum(filePath: string): string {\r\n try {\r\n const content = readFileSync(filePath);\r\n return createHash('sha256').update(content).digest('hex');\r\n } catch (error) {\r\n throw new ArtifactValidationError(\r\n `Failed to calculate checksum: ${error instanceof Error ? error.message : String(error)}`,\r\n { filePath, error }\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Validate artifact metadata\r\n */\r\n private validateMetadata(metadata: ArtifactMetadata): void {\r\n if (!metadata.name || metadata.name.trim().length === 0) {\r\n throw new ArtifactValidationError('Artifact name is required');\r\n }\r\n\r\n if (!metadata.type) {\r\n throw new ArtifactValidationError('Artifact type is required');\r\n }\r\n\r\n const validTypes: ArtifactType[] = ['code', 'documentation', 'test', 'config', 'binary', 'data', 'model', 'report', 'other'];\r\n if (!validTypes.includes(metadata.type)) {\r\n throw new ArtifactValidationError(`Invalid artifact type: ${metadata.type}`, { validTypes });\r\n }\r\n\r\n if (!metadata.storage_location || metadata.storage_location.trim().length === 0) {\r\n throw new ArtifactValidationError('Storage location is required');\r\n }\r\n\r\n if (metadata.acl_level !== undefined && (metadata.acl_level < 1 || metadata.acl_level > 5)) {\r\n throw new ArtifactValidationError('ACL level must be between 1 and 5', { acl_level: metadata.acl_level });\r\n }\r\n\r\n if (metadata.retention_policy) {\r\n const validPolicies: RetentionPolicy[] = ['ephemeral', 'standard', 'permanent', 'custom'];\r\n if (!validPolicies.includes(metadata.retention_policy)) {\r\n throw new ArtifactValidationError(`Invalid retention policy: ${metadata.retention_policy}`, { validPolicies });\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Create new artifact\r\n */\r\n createArtifact(metadata: ArtifactMetadata): Artifact {\r\n try {\r\n // Validate metadata\r\n this.validateMetadata(metadata);\r\n\r\n // Generate ID\r\n const id = this.generateId();\r\n\r\n // Calculate file-based metadata if storage location exists\r\n let size_bytes: number | undefined;\r\n let checksum: string | undefined;\r\n let content_hash: string | undefined;\r\n\r\n if (existsSync(metadata.storage_location)) {\r\n const stats = statSync(metadata.storage_location);\r\n size_bytes = stats.size;\r\n checksum = this.calculateChecksum(metadata.storage_location);\r\n\r\n if (metadata.content) {\r\n content_hash = createHash('sha256').update(metadata.content).digest('hex');\r\n }\r\n }\r\n\r\n // Set defaults\r\n const retention_days = metadata.retention_days ?? (\r\n metadata.retention_policy === 'ephemeral' ? 7 :\r\n metadata.retention_policy === 'permanent' ? 0 :\r\n 30 // standard\r\n );\r\n\r\n const retention_policy = metadata.retention_policy ?? 'standard';\r\n\r\n // Prepare insert statement\r\n const stmt = this.db.prepare(`\r\n INSERT INTO artifacts (\r\n id, name, type, format, content, content_hash, size_bytes,\r\n storage_location, checksum, is_compressed, compression_type,\r\n swarm_id, agent_id, task_id, version, parent_artifact_id,\r\n artifact_chain, tags, metadata, acl_level,\r\n retention_days, retention_policy, status\r\n ) VALUES (\r\n ?, ?, ?, ?, ?, ?, ?,\r\n ?, ?, ?, ?,\r\n ?, ?, ?, ?, ?,\r\n ?, ?, ?, ?,\r\n ?, ?, ?\r\n )\r\n `);\r\n\r\n // Execute insert\r\n stmt.run(\r\n id,\r\n metadata.name,\r\n metadata.type,\r\n metadata.format ?? null,\r\n metadata.content ?? null,\r\n content_hash ?? null,\r\n size_bytes ?? null,\r\n metadata.storage_location,\r\n checksum ?? null,\r\n metadata.is_compressed ? 1 : 0,\r\n metadata.compression_type ?? null,\r\n metadata.swarm_id ?? null,\r\n metadata.agent_id ?? null,\r\n metadata.task_id ?? null,\r\n metadata.version ?? 1,\r\n metadata.parent_artifact_id ?? null,\r\n metadata.artifact_chain ? JSON.stringify(metadata.artifact_chain) : null,\r\n metadata.tags ? JSON.stringify(metadata.tags) : null,\r\n metadata.metadata ? JSON.stringify(metadata.metadata) : null,\r\n metadata.acl_level ?? 2,\r\n retention_days,\r\n retention_policy,\r\n 'active'\r\n );\r\n\r\n // Retrieve and return created artifact\r\n const artifact = this.getArtifact(id);\r\n if (!artifact) {\r\n throw new ArtifactDatabaseError('Failed to retrieve created artifact', { id });\r\n }\r\n\r\n return artifact;\r\n } catch (error) {\r\n if (error instanceof ArtifactRegistryError) {\r\n throw error;\r\n }\r\n throw new ArtifactDatabaseError(\r\n `Failed to create artifact: ${error instanceof Error ? error.message : String(error)}`,\r\n { metadata, error }\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Get artifact by ID\r\n */\r\n getArtifact(id: string): Artifact | null {\r\n try {\r\n const stmt = this.db.prepare('SELECT * FROM artifacts WHERE id = ?');\r\n const row = stmt.get(id) as Artifact | undefined;\r\n return row ?? null;\r\n } catch (error) {\r\n throw new ArtifactDatabaseError(\r\n `Failed to get artifact: ${error instanceof Error ? error.message : String(error)}`,\r\n { id, error }\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * List artifacts with optional filters\r\n */\r\n listArtifacts(filters?: ArtifactFilters): Artifact[] {\r\n try {\r\n let query = 'SELECT * FROM artifacts WHERE 1=1';\r\n const params: any[] = [];\r\n\r\n if (filters) {\r\n if (filters.type) {\r\n query += ' AND type = ?';\r\n params.push(filters.type);\r\n }\r\n\r\n if (filters.status) {\r\n query += ' AND status = ?';\r\n params.push(filters.status);\r\n }\r\n\r\n if (filters.retention_policy) {\r\n query += ' AND retention_policy = ?';\r\n params.push(filters.retention_policy);\r\n }\r\n\r\n if (filters.swarm_id) {\r\n query += ' AND swarm_id = ?';\r\n params.push(filters.swarm_id);\r\n }\r\n\r\n if (filters.agent_id) {\r\n query += ' AND agent_id = ?';\r\n params.push(filters.agent_id);\r\n }\r\n\r\n if (filters.task_id) {\r\n query += ' AND task_id = ?';\r\n params.push(filters.task_id);\r\n }\r\n\r\n if (filters.cleanup_eligible !== undefined) {\r\n query += ' AND cleanup_eligible = ?';\r\n params.push(filters.cleanup_eligible ? 1 : 0);\r\n }\r\n\r\n if (filters.created_after) {\r\n query += ' AND created_at >= ?';\r\n params.push(filters.created_after.toISOString());\r\n }\r\n\r\n if (filters.created_before) {\r\n query += ' AND created_at <= ?';\r\n params.push(filters.created_before.toISOString());\r\n }\r\n\r\n if (filters.expires_before) {\r\n query += ' AND expires_at IS NOT NULL AND expires_at <= ?';\r\n params.push(filters.expires_before.toISOString());\r\n }\r\n\r\n if (filters.tags && filters.tags.length > 0) {\r\n // JSON search for tags (SQLite JSON support)\r\n for (const tag of filters.tags) {\r\n query += ` AND tags LIKE ?`;\r\n params.push(`%\"${tag}\"%`);\r\n }\r\n }\r\n }\r\n\r\n query += ' ORDER BY created_at DESC';\r\n\r\n if (filters?.limit) {\r\n query += ' LIMIT ?';\r\n params.push(filters.limit);\r\n }\r\n\r\n if (filters?.offset) {\r\n query += ' OFFSET ?';\r\n params.push(filters.offset);\r\n }\r\n\r\n const stmt = this.db.prepare(query);\r\n return stmt.all(...params) as Artifact[];\r\n } catch (error) {\r\n throw new ArtifactDatabaseError(\r\n `Failed to list artifacts: ${error instanceof Error ? error.message : String(error)}`,\r\n { filters, error }\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Archive artifact (mark as archived)\r\n */\r\n archiveArtifact(id: string): Artifact {\r\n try {\r\n const artifact = this.getArtifact(id);\r\n if (!artifact) {\r\n throw new ArtifactNotFoundError(id);\r\n }\r\n\r\n if (artifact.status === 'deleted') {\r\n throw new ArtifactValidationError('Cannot archive deleted artifact', { id, status: artifact.status });\r\n }\r\n\r\n const stmt = this.db.prepare(`\r\n UPDATE artifacts\r\n SET status = 'archived',\r\n archived_at = CURRENT_TIMESTAMP,\r\n updated_at = CURRENT_TIMESTAMP\r\n WHERE id = ?\r\n `);\r\n\r\n stmt.run(id);\r\n\r\n const updated = this.getArtifact(id);\r\n if (!updated) {\r\n throw new ArtifactDatabaseError('Failed to retrieve archived artifact', { id });\r\n }\r\n\r\n return updated;\r\n } catch (error) {\r\n if (error instanceof ArtifactRegistryError) {\r\n throw error;\r\n }\r\n throw new ArtifactDatabaseError(\r\n `Failed to archive artifact: ${error instanceof Error ? error.message : String(error)}`,\r\n { id, error }\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Delete artifact (soft delete - mark as deleted)\r\n */\r\n deleteArtifact(id: string): Artifact {\r\n try {\r\n const artifact = this.getArtifact(id);\r\n if (!artifact) {\r\n throw new ArtifactNotFoundError(id);\r\n }\r\n\r\n const stmt = this.db.prepare(`\r\n UPDATE artifacts\r\n SET status = 'deleted',\r\n deleted_at = CURRENT_TIMESTAMP,\r\n updated_at = CURRENT_TIMESTAMP\r\n WHERE id = ?\r\n `);\r\n\r\n stmt.run(id);\r\n\r\n const updated = this.getArtifact(id);\r\n if (!updated) {\r\n throw new ArtifactDatabaseError('Failed to retrieve deleted artifact', { id });\r\n }\r\n\r\n return updated;\r\n } catch (error) {\r\n if (error instanceof ArtifactRegistryError) {\r\n throw error;\r\n }\r\n throw new ArtifactDatabaseError(\r\n `Failed to delete artifact: ${error instanceof Error ? error.message : String(error)}`,\r\n { id, error }\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Get artifact statistics by retention policy\r\n */\r\n getStatsByRetentionPolicy(): Record<RetentionPolicy, ArtifactStats> {\r\n try {\r\n const stmt = this.db.prepare(`\r\n SELECT\r\n retention_policy,\r\n COUNT(*) as total,\r\n SUM(CASE WHEN status = 'active' THEN 1 ELSE 0 END) as active,\r\n SUM(CASE WHEN status = 'archived' THEN 1 ELSE 0 END) as archived,\r\n SUM(CASE WHEN status = 'deleted' THEN 1 ELSE 0 END) as deleted,\r\n SUM(CASE WHEN cleanup_eligible = 1 THEN 1 ELSE 0 END) as cleanup_eligible,\r\n COALESCE(SUM(size_bytes), 0) as total_size_bytes\r\n FROM artifacts\r\n GROUP BY retention_policy\r\n `);\r\n\r\n const rows = stmt.all() as Array<{ retention_policy: RetentionPolicy } & ArtifactStats>;\r\n const stats: Record<string, ArtifactStats> = {};\r\n\r\n for (const row of rows) {\r\n const { retention_policy, ...statsData } = row;\r\n stats[retention_policy] = statsData;\r\n }\r\n\r\n return stats as Record<RetentionPolicy, ArtifactStats>;\r\n } catch (error) {\r\n throw new ArtifactDatabaseError(\r\n `Failed to get statistics: ${error instanceof Error ? error.message : String(error)}`,\r\n { error }\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Find expired artifacts eligible for cleanup\r\n */\r\n findExpiredArtifacts(): Artifact[] {\r\n try {\r\n const stmt = this.db.prepare(`\r\n SELECT * FROM artifacts\r\n WHERE status = 'active'\r\n AND expires_at IS NOT NULL\r\n AND datetime('now') >= expires_at\r\n ORDER BY created_at ASC\r\n `);\r\n\r\n return stmt.all() as Artifact[];\r\n } catch (error) {\r\n throw new ArtifactDatabaseError(\r\n `Failed to find expired artifacts: ${error instanceof Error ? error.message : String(error)}`,\r\n { error }\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Close database connection\r\n */\r\n close(): void {\r\n this.db.close();\r\n }\r\n}\r\n"],"names":["Database","createHash","readFileSync","existsSync","mkdirSync","statSync","join","dirname","ArtifactRegistryError","Error","message","code","details","name","ArtifactNotFoundError","id","ArtifactValidationError","ArtifactDatabaseError","ArtifactRegistry","db","instance","dbPath","dbDir","recursive","pragma","initializeSchema","error","String","getInstance","schemaPath","__dirname","schema","withoutMultiLineComments","replace","cleanedSchema","split","filter","line","trimmed","trim","length","startsWith","exec","generateId","timestamp","Date","now","random","Math","toString","substring","calculateChecksum","filePath","content","update","digest","validateMetadata","metadata","type","validTypes","includes","storage_location","acl_level","undefined","retention_policy","validPolicies","createArtifact","size_bytes","checksum","content_hash","stats","size","retention_days","stmt","prepare","run","format","is_compressed","compression_type","swarm_id","agent_id","task_id","version","parent_artifact_id","artifact_chain","JSON","stringify","tags","artifact","getArtifact","row","get","listArtifacts","filters","query","params","push","status","cleanup_eligible","created_after","toISOString","created_before","expires_before","tag","limit","offset","all","archiveArtifact","updated","deleteArtifact","getStatsByRetentionPolicy","rows","statsData","findExpiredArtifacts","close"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/lib/artifact-registry.ts"],"sourcesContent":["/**\r\n * Artifact Registry TypeScript API\r\n * Provides centralized artifact management with TTL-based cleanup\r\n * Version: 1.0.0\r\n */\r\n\r\nimport Database from 'better-sqlite3';\r\nimport { createHash } from 'crypto';\r\nimport { readFileSync, existsSync, mkdirSync, statSync } from 'fs';\r\nimport { join, dirname } from 'path';\r\nimport { fileURLToPath } from 'url';\r\n\r\n// ESM-compatible __dirname\r\nconst __filename = fileURLToPath(import.meta.url);\r\nconst __dirname = dirname(__filename);\r\n\r\n// ============================================================================\r\n// Types and Interfaces\r\n// ============================================================================\r\n\r\nexport type ArtifactType = 'code' | 'documentation' | 'test' | 'config' | 'binary' | 'data' | 'model' | 'report' | 'other';\r\nexport type ArtifactStatus = 'active' | 'archived' | 'deleted';\r\nexport type RetentionPolicy = 'ephemeral' | 'standard' | 'permanent' | 'custom';\r\n\r\nexport interface ArtifactMetadata {\r\n name: string;\r\n type: ArtifactType;\r\n format?: string;\r\n content?: string;\r\n storage_location: string;\r\n swarm_id?: string;\r\n agent_id?: string;\r\n task_id?: string;\r\n version?: number;\r\n parent_artifact_id?: string;\r\n artifact_chain?: string[];\r\n tags?: string[];\r\n metadata?: Record<string, any>;\r\n acl_level?: number;\r\n is_compressed?: boolean;\r\n compression_type?: string;\r\n retention_days?: number;\r\n retention_policy?: RetentionPolicy;\r\n}\r\n\r\nexport interface Artifact {\r\n id: string;\r\n name: string;\r\n type: ArtifactType;\r\n format?: string;\r\n content?: string;\r\n content_hash?: string;\r\n size_bytes?: number;\r\n storage_location: string;\r\n checksum?: string;\r\n is_compressed: boolean;\r\n compression_type?: string;\r\n swarm_id?: string;\r\n agent_id?: string;\r\n task_id?: string;\r\n version: number;\r\n parent_artifact_id?: string;\r\n artifact_chain?: string;\r\n tags?: string;\r\n metadata?: string;\r\n acl_level: number;\r\n retention_days: number;\r\n retention_policy: RetentionPolicy;\r\n expires_at?: string;\r\n status: ArtifactStatus;\r\n cleanup_eligible: boolean;\r\n created_at: string;\r\n updated_at: string;\r\n archived_at?: string;\r\n deleted_at?: string;\r\n}\r\n\r\nexport interface ArtifactFilters {\r\n type?: ArtifactType;\r\n status?: ArtifactStatus;\r\n retention_policy?: RetentionPolicy;\r\n swarm_id?: string;\r\n agent_id?: string;\r\n task_id?: string;\r\n tags?: string[];\r\n cleanup_eligible?: boolean;\r\n created_after?: Date;\r\n created_before?: Date;\r\n expires_before?: Date;\r\n limit?: number;\r\n offset?: number;\r\n}\r\n\r\nexport interface ArtifactStats {\r\n total: number;\r\n active: number;\r\n archived: number;\r\n deleted: number;\r\n cleanup_eligible: number;\r\n total_size_bytes: number;\r\n}\r\n\r\n// ============================================================================\r\n// Error Classes\r\n// ============================================================================\r\n\r\nexport class ArtifactRegistryError extends Error {\r\n constructor(message: string, public code: string, public details?: any) {\r\n super(message);\r\n this.name = 'ArtifactRegistryError';\r\n }\r\n}\r\n\r\nexport class ArtifactNotFoundError extends ArtifactRegistryError {\r\n constructor(id: string) {\r\n super(`Artifact not found: ${id}`, 'ARTIFACT_NOT_FOUND', { id });\r\n this.name = 'ArtifactNotFoundError';\r\n }\r\n}\r\n\r\nexport class ArtifactValidationError extends ArtifactRegistryError {\r\n constructor(message: string, details?: any) {\r\n super(message, 'VALIDATION_ERROR', details);\r\n this.name = 'ArtifactValidationError';\r\n }\r\n}\r\n\r\nexport class ArtifactDatabaseError extends ArtifactRegistryError {\r\n constructor(message: string, details?: any) {\r\n super(message, 'DATABASE_ERROR', details);\r\n this.name = 'ArtifactDatabaseError';\r\n }\r\n}\r\n\r\n// ============================================================================\r\n// Artifact Registry Class\r\n// ============================================================================\r\n\r\nexport class ArtifactRegistry {\r\n private db: Database.Database;\r\n private static instance: ArtifactRegistry | null = null;\r\n\r\n constructor(dbPath: string) {\r\n try {\r\n // Ensure database directory exists\r\n const dbDir = dirname(dbPath);\r\n if (!existsSync(dbDir)) {\r\n mkdirSync(dbDir, { recursive: true });\r\n }\r\n\r\n this.db = new Database(dbPath);\r\n this.db.pragma('journal_mode = WAL'); // Write-Ahead Logging for concurrency\r\n this.db.pragma('foreign_keys = ON');\r\n this.db.pragma('synchronous = NORMAL');\r\n\r\n this.initializeSchema();\r\n } catch (error) {\r\n throw new ArtifactDatabaseError(\r\n `Failed to initialize database: ${error instanceof Error ? error.message : String(error)}`,\r\n { dbPath, error }\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Get singleton instance (optional pattern)\r\n */\r\n static getInstance(dbPath?: string): ArtifactRegistry {\r\n if (!ArtifactRegistry.instance) {\r\n if (!dbPath) {\r\n throw new ArtifactDatabaseError('Database path required for first initialization', {});\r\n }\r\n ArtifactRegistry.instance = new ArtifactRegistry(dbPath);\r\n }\r\n return ArtifactRegistry.instance;\r\n }\r\n\r\n /**\r\n * Initialize database schema\r\n */\r\n private initializeSchema(): void {\r\n try {\r\n const schemaPath = join(__dirname, '../database/artifact-registry-schema.sql');\r\n if (!existsSync(schemaPath)) {\r\n throw new Error(`Schema file not found: ${schemaPath}`);\r\n }\r\n\r\n const schema = readFileSync(schemaPath, 'utf-8');\r\n\r\n // Step 1: Remove multi-line comments FIRST (they can contain semicolons)\r\n const withoutMultiLineComments = schema.replace(/\\/\\*[\\s\\S]*?\\*\\//g, '');\r\n\r\n // Step 2: Remove single-line comments\r\n const cleanedSchema = withoutMultiLineComments\r\n .split('\\n')\r\n .filter(line => {\r\n const trimmed = line.trim();\r\n return trimmed.length > 0 && !trimmed.startsWith('--');\r\n })\r\n .join('\\n');\r\n\r\n // Step 3: Execute entire schema as one block\r\n // SQLite's exec() can handle multiple statements including triggers with internal semicolons\r\n this.db.exec(cleanedSchema);\r\n } catch (error) {\r\n throw new ArtifactDatabaseError(\r\n `Failed to initialize schema: ${error instanceof Error ? error.message : String(error)}`,\r\n { error }\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Generate unique artifact ID\r\n */\r\n private generateId(): string {\r\n const timestamp = Date.now();\r\n const random = Math.random().toString(36).substring(2, 15);\r\n return `artifact-${timestamp}-${random}`;\r\n }\r\n\r\n /**\r\n * Calculate checksum for file\r\n */\r\n private calculateChecksum(filePath: string): string {\r\n try {\r\n const content = readFileSync(filePath);\r\n return createHash('sha256').update(content).digest('hex');\r\n } catch (error) {\r\n throw new ArtifactValidationError(\r\n `Failed to calculate checksum: ${error instanceof Error ? error.message : String(error)}`,\r\n { filePath, error }\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Validate artifact metadata\r\n */\r\n private validateMetadata(metadata: ArtifactMetadata): void {\r\n if (!metadata.name || metadata.name.trim().length === 0) {\r\n throw new ArtifactValidationError('Artifact name is required');\r\n }\r\n\r\n if (!metadata.type) {\r\n throw new ArtifactValidationError('Artifact type is required');\r\n }\r\n\r\n const validTypes: ArtifactType[] = ['code', 'documentation', 'test', 'config', 'binary', 'data', 'model', 'report', 'other'];\r\n if (!validTypes.includes(metadata.type)) {\r\n throw new ArtifactValidationError(`Invalid artifact type: ${metadata.type}`, { validTypes });\r\n }\r\n\r\n if (!metadata.storage_location || metadata.storage_location.trim().length === 0) {\r\n throw new ArtifactValidationError('Storage location is required');\r\n }\r\n\r\n if (metadata.acl_level !== undefined && (metadata.acl_level < 1 || metadata.acl_level > 5)) {\r\n throw new ArtifactValidationError('ACL level must be between 1 and 5', { acl_level: metadata.acl_level });\r\n }\r\n\r\n if (metadata.retention_policy) {\r\n const validPolicies: RetentionPolicy[] = ['ephemeral', 'standard', 'permanent', 'custom'];\r\n if (!validPolicies.includes(metadata.retention_policy)) {\r\n throw new ArtifactValidationError(`Invalid retention policy: ${metadata.retention_policy}`, { validPolicies });\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Create new artifact\r\n */\r\n createArtifact(metadata: ArtifactMetadata): Artifact {\r\n try {\r\n // Validate metadata\r\n this.validateMetadata(metadata);\r\n\r\n // Generate ID\r\n const id = this.generateId();\r\n\r\n // Calculate file-based metadata if storage location exists\r\n let size_bytes: number | undefined;\r\n let checksum: string | undefined;\r\n let content_hash: string | undefined;\r\n\r\n if (existsSync(metadata.storage_location)) {\r\n const stats = statSync(metadata.storage_location);\r\n size_bytes = stats.size;\r\n checksum = this.calculateChecksum(metadata.storage_location);\r\n\r\n if (metadata.content) {\r\n content_hash = createHash('sha256').update(metadata.content).digest('hex');\r\n }\r\n }\r\n\r\n // Set defaults\r\n const retention_days = metadata.retention_days ?? (\r\n metadata.retention_policy === 'ephemeral' ? 7 :\r\n metadata.retention_policy === 'permanent' ? 0 :\r\n 30 // standard\r\n );\r\n\r\n const retention_policy = metadata.retention_policy ?? 'standard';\r\n\r\n // Prepare insert statement\r\n const stmt = this.db.prepare(`\r\n INSERT INTO artifacts (\r\n id, name, type, format, content, content_hash, size_bytes,\r\n storage_location, checksum, is_compressed, compression_type,\r\n swarm_id, agent_id, task_id, version, parent_artifact_id,\r\n artifact_chain, tags, metadata, acl_level,\r\n retention_days, retention_policy, status\r\n ) VALUES (\r\n ?, ?, ?, ?, ?, ?, ?,\r\n ?, ?, ?, ?,\r\n ?, ?, ?, ?, ?,\r\n ?, ?, ?, ?,\r\n ?, ?, ?\r\n )\r\n `);\r\n\r\n // Execute insert\r\n stmt.run(\r\n id,\r\n metadata.name,\r\n metadata.type,\r\n metadata.format ?? null,\r\n metadata.content ?? null,\r\n content_hash ?? null,\r\n size_bytes ?? null,\r\n metadata.storage_location,\r\n checksum ?? null,\r\n metadata.is_compressed ? 1 : 0,\r\n metadata.compression_type ?? null,\r\n metadata.swarm_id ?? null,\r\n metadata.agent_id ?? null,\r\n metadata.task_id ?? null,\r\n metadata.version ?? 1,\r\n metadata.parent_artifact_id ?? null,\r\n metadata.artifact_chain ? JSON.stringify(metadata.artifact_chain) : null,\r\n metadata.tags ? JSON.stringify(metadata.tags) : null,\r\n metadata.metadata ? JSON.stringify(metadata.metadata) : null,\r\n metadata.acl_level ?? 2,\r\n retention_days,\r\n retention_policy,\r\n 'active'\r\n );\r\n\r\n // Retrieve and return created artifact\r\n const artifact = this.getArtifact(id);\r\n if (!artifact) {\r\n throw new ArtifactDatabaseError('Failed to retrieve created artifact', { id });\r\n }\r\n\r\n return artifact;\r\n } catch (error) {\r\n if (error instanceof ArtifactRegistryError) {\r\n throw error;\r\n }\r\n throw new ArtifactDatabaseError(\r\n `Failed to create artifact: ${error instanceof Error ? error.message : String(error)}`,\r\n { metadata, error }\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Get artifact by ID\r\n */\r\n getArtifact(id: string): Artifact | null {\r\n try {\r\n const stmt = this.db.prepare('SELECT * FROM artifacts WHERE id = ?');\r\n const row = stmt.get(id) as Artifact | undefined;\r\n return row ?? null;\r\n } catch (error) {\r\n throw new ArtifactDatabaseError(\r\n `Failed to get artifact: ${error instanceof Error ? error.message : String(error)}`,\r\n { id, error }\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * List artifacts with optional filters\r\n */\r\n listArtifacts(filters?: ArtifactFilters): Artifact[] {\r\n try {\r\n let query = 'SELECT * FROM artifacts WHERE 1=1';\r\n const params: any[] = [];\r\n\r\n if (filters) {\r\n if (filters.type) {\r\n query += ' AND type = ?';\r\n params.push(filters.type);\r\n }\r\n\r\n if (filters.status) {\r\n query += ' AND status = ?';\r\n params.push(filters.status);\r\n }\r\n\r\n if (filters.retention_policy) {\r\n query += ' AND retention_policy = ?';\r\n params.push(filters.retention_policy);\r\n }\r\n\r\n if (filters.swarm_id) {\r\n query += ' AND swarm_id = ?';\r\n params.push(filters.swarm_id);\r\n }\r\n\r\n if (filters.agent_id) {\r\n query += ' AND agent_id = ?';\r\n params.push(filters.agent_id);\r\n }\r\n\r\n if (filters.task_id) {\r\n query += ' AND task_id = ?';\r\n params.push(filters.task_id);\r\n }\r\n\r\n if (filters.cleanup_eligible !== undefined) {\r\n query += ' AND cleanup_eligible = ?';\r\n params.push(filters.cleanup_eligible ? 1 : 0);\r\n }\r\n\r\n if (filters.created_after) {\r\n query += ' AND created_at >= ?';\r\n params.push(filters.created_after.toISOString());\r\n }\r\n\r\n if (filters.created_before) {\r\n query += ' AND created_at <= ?';\r\n params.push(filters.created_before.toISOString());\r\n }\r\n\r\n if (filters.expires_before) {\r\n query += ' AND expires_at IS NOT NULL AND expires_at <= ?';\r\n params.push(filters.expires_before.toISOString());\r\n }\r\n\r\n if (filters.tags && filters.tags.length > 0) {\r\n // JSON search for tags (SQLite JSON support)\r\n for (const tag of filters.tags) {\r\n query += ` AND tags LIKE ?`;\r\n params.push(`%\"${tag}\"%`);\r\n }\r\n }\r\n }\r\n\r\n query += ' ORDER BY created_at DESC';\r\n\r\n if (filters?.limit) {\r\n query += ' LIMIT ?';\r\n params.push(filters.limit);\r\n }\r\n\r\n if (filters?.offset) {\r\n query += ' OFFSET ?';\r\n params.push(filters.offset);\r\n }\r\n\r\n const stmt = this.db.prepare(query);\r\n return stmt.all(...params) as Artifact[];\r\n } catch (error) {\r\n throw new ArtifactDatabaseError(\r\n `Failed to list artifacts: ${error instanceof Error ? error.message : String(error)}`,\r\n { filters, error }\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Archive artifact (mark as archived)\r\n */\r\n archiveArtifact(id: string): Artifact {\r\n try {\r\n const artifact = this.getArtifact(id);\r\n if (!artifact) {\r\n throw new ArtifactNotFoundError(id);\r\n }\r\n\r\n if (artifact.status === 'deleted') {\r\n throw new ArtifactValidationError('Cannot archive deleted artifact', { id, status: artifact.status });\r\n }\r\n\r\n const stmt = this.db.prepare(`\r\n UPDATE artifacts\r\n SET status = 'archived',\r\n archived_at = CURRENT_TIMESTAMP,\r\n updated_at = CURRENT_TIMESTAMP\r\n WHERE id = ?\r\n `);\r\n\r\n stmt.run(id);\r\n\r\n const updated = this.getArtifact(id);\r\n if (!updated) {\r\n throw new ArtifactDatabaseError('Failed to retrieve archived artifact', { id });\r\n }\r\n\r\n return updated;\r\n } catch (error) {\r\n if (error instanceof ArtifactRegistryError) {\r\n throw error;\r\n }\r\n throw new ArtifactDatabaseError(\r\n `Failed to archive artifact: ${error instanceof Error ? error.message : String(error)}`,\r\n { id, error }\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Delete artifact (soft delete - mark as deleted)\r\n */\r\n deleteArtifact(id: string): Artifact {\r\n try {\r\n const artifact = this.getArtifact(id);\r\n if (!artifact) {\r\n throw new ArtifactNotFoundError(id);\r\n }\r\n\r\n const stmt = this.db.prepare(`\r\n UPDATE artifacts\r\n SET status = 'deleted',\r\n deleted_at = CURRENT_TIMESTAMP,\r\n updated_at = CURRENT_TIMESTAMP\r\n WHERE id = ?\r\n `);\r\n\r\n stmt.run(id);\r\n\r\n const updated = this.getArtifact(id);\r\n if (!updated) {\r\n throw new ArtifactDatabaseError('Failed to retrieve deleted artifact', { id });\r\n }\r\n\r\n return updated;\r\n } catch (error) {\r\n if (error instanceof ArtifactRegistryError) {\r\n throw error;\r\n }\r\n throw new ArtifactDatabaseError(\r\n `Failed to delete artifact: ${error instanceof Error ? error.message : String(error)}`,\r\n { id, error }\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Get artifact statistics by retention policy\r\n */\r\n getStatsByRetentionPolicy(): Record<RetentionPolicy, ArtifactStats> {\r\n try {\r\n const stmt = this.db.prepare(`\r\n SELECT\r\n retention_policy,\r\n COUNT(*) as total,\r\n SUM(CASE WHEN status = 'active' THEN 1 ELSE 0 END) as active,\r\n SUM(CASE WHEN status = 'archived' THEN 1 ELSE 0 END) as archived,\r\n SUM(CASE WHEN status = 'deleted' THEN 1 ELSE 0 END) as deleted,\r\n SUM(CASE WHEN cleanup_eligible = 1 THEN 1 ELSE 0 END) as cleanup_eligible,\r\n COALESCE(SUM(size_bytes), 0) as total_size_bytes\r\n FROM artifacts\r\n GROUP BY retention_policy\r\n `);\r\n\r\n const rows = stmt.all() as Array<{ retention_policy: RetentionPolicy } & ArtifactStats>;\r\n const stats: Record<string, ArtifactStats> = {};\r\n\r\n for (const row of rows) {\r\n const { retention_policy, ...statsData } = row;\r\n stats[retention_policy] = statsData;\r\n }\r\n\r\n return stats as Record<RetentionPolicy, ArtifactStats>;\r\n } catch (error) {\r\n throw new ArtifactDatabaseError(\r\n `Failed to get statistics: ${error instanceof Error ? error.message : String(error)}`,\r\n { error }\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Find expired artifacts eligible for cleanup\r\n */\r\n findExpiredArtifacts(): Artifact[] {\r\n try {\r\n const stmt = this.db.prepare(`\r\n SELECT * FROM artifacts\r\n WHERE status = 'active'\r\n AND expires_at IS NOT NULL\r\n AND datetime('now') >= expires_at\r\n ORDER BY created_at ASC\r\n `);\r\n\r\n return stmt.all() as Artifact[];\r\n } catch (error) {\r\n throw new ArtifactDatabaseError(\r\n `Failed to find expired artifacts: ${error instanceof Error ? error.message : String(error)}`,\r\n { error }\r\n );\r\n }\r\n }\r\n\r\n /**\r\n * Close database connection\r\n */\r\n close(): void {\r\n this.db.close();\r\n }\r\n}\r\n"],"names":["Database","createHash","readFileSync","existsSync","mkdirSync","statSync","join","dirname","fileURLToPath","__filename","url","__dirname","ArtifactRegistryError","Error","message","code","details","name","ArtifactNotFoundError","id","ArtifactValidationError","ArtifactDatabaseError","ArtifactRegistry","db","instance","dbPath","dbDir","recursive","pragma","initializeSchema","error","String","getInstance","schemaPath","schema","withoutMultiLineComments","replace","cleanedSchema","split","filter","line","trimmed","trim","length","startsWith","exec","generateId","timestamp","Date","now","random","Math","toString","substring","calculateChecksum","filePath","content","update","digest","validateMetadata","metadata","type","validTypes","includes","storage_location","acl_level","undefined","retention_policy","validPolicies","createArtifact","size_bytes","checksum","content_hash","stats","size","retention_days","stmt","prepare","run","format","is_compressed","compression_type","swarm_id","agent_id","task_id","version","parent_artifact_id","artifact_chain","JSON","stringify","tags","artifact","getArtifact","row","get","listArtifacts","filters","query","params","push","status","cleanup_eligible","created_after","toISOString","created_before","expires_before","tag","limit","offset","all","archiveArtifact","updated","deleteArtifact","getStatsByRetentionPolicy","rows","statsData","findExpiredArtifacts","close"],"mappings":"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"}
|