All notable changes to Numen are documented here.
AI Pipeline Templates & Preset Library (Issue #36)
Reusable AI pipeline templates for accelerated content creation workflows, featuring 8 built-in templates, community library, space-scoped templates, one-click install wizard, template versioning, and plugin registration hooks.
Features:
- 8 built-in templates: Blog Post Pipeline, Social Media Campaign, Product Description, Email Newsletter, Press Release, Landing Page, Technical Documentation, Video Script
- Template library API: Discover, rate, and install templates with metadata
- Space-scoped templates: Custom templates per content space with full RBAC support
- Install wizard: Auto-configures personas, stages, and input variables from template schema
- Template versioning: Track changes, publish/unpublish versions, rollback support
- Template packs: Plugin system for registering template collections
- Community ratings: Rate and provide feedback on templates
- Metadata support: Categories, icons, author info, and schema versioning
- Security: Space-scoped installs, RBAC permission gates, audit logging
Endpoints:
GET /api/v1/spaces/{space}/pipeline-templates— List templates (paginated)POST /api/v1/spaces/{space}/pipeline-templates— Create custom templateGET /api/v1/spaces/{space}/pipeline-templates/{template}— Get template detailsPATCH /api/v1/spaces/{space}/pipeline-templates/{template}— Update templateDELETE /api/v1/spaces/{space}/pipeline-templates/{template}— Delete templatePOST /api/v1/spaces/{space}/pipeline-templates/{template}/publish— Publish templatePOST /api/v1/spaces/{space}/pipeline-templates/{template}/unpublish— Unpublish templateGET /api/v1/spaces/{space}/pipeline-templates/{template}/versions— List versionsPOST /api/v1/spaces/{space}/pipeline-templates/{template}/versions— Create versionGET /api/v1/spaces/{space}/pipeline-templates/{template}/versions/{version}— Get versionPOST /api/v1/spaces/{space}/pipeline-templates/installs/{version}— Install template (rate-limited 5/min)PATCH /api/v1/spaces/{space}/pipeline-templates/installs/{install}— Update installDELETE /api/v1/spaces/{space}/pipeline-templates/installs/{install}— Remove installGET /api/v1/spaces/{space}/pipeline-templates/{template}/ratings— List ratingsPOST /api/v1/spaces/{space}/pipeline-templates/{template}/ratings— Rate template
Plugin Hooks:
registerTemplateCategory(array $category)— Register custom template categoriesregisterTemplatePack(array $pack)— Register template collections from plugins
Models:
PipelineTemplate— Template metadata (name, slug, category, icon, author)PipelineTemplateVersion— Versioned template definitions with JSON schemaPipelineTemplateInstall— Track template usage per spacePipelineTemplateRating— Community feedback (1-5 stars)
New environment variables:
TEMPLATE_LIBRARY_ENABLED=trueTEMPLATE_INSTALL_RATE_LIMIT=5(per minute)
See docs/pipeline-templates.md for complete documentation.
- Webhooks admin UI — manage webhook endpoints, event subscriptions, delivery logs, and secret rotation directly from the admin panel (Settings → Webhooks)
- 6 new database tables with ULID PKs and idempotent migrations:
competitor_sources— crawlable competitor feeds (RSS, sitemap, scrape, API)competitor_content_items— crawled articles with dedup by content hashcontent_fingerprints— morphic TF-IDF/keyword fingerprints for similaritydifferentiation_analyses— LLM-assisted differentiation scoringcompetitor_alerts— configurable alert rulescompetitor_alert_events— fired alert history with notification log
CrawlerService— orchestrates RSS, sitemap, scrape, and API crawlersRssCrawler,SitemapCrawler,ScrapeCrawler,ApiCrawler— pluggable crawlersCrawlCompetitorSourceJob— queued job with retries + stale-check
ContentFingerprintService— TF-IDF vectorization over content bodySimilarityCalculator— cosine similarity between fingerprint vectorsSimilarContentFinder— finds the top-N most similar competitor items
DifferentiationAnalysisService— LLM-powered angle/gap/recommendation extractionDifferentiationResult— typed value object for analysis output- Pipeline stage
CompetitorAnalysisStage— integrates into the content pipeline
CompetitorAnalysisStagewired intoStageRegistry- Automatic enrichment of
ContentBriefwith competitor insights on pipeline run
CompetitorAlertService— evaluates active alerts against new competitor contentCheckCompetitorAlertsJob— queued job dispatched post-crawlCompetitorAlertNotification— Laravel notification (email channel)SlackChannel— Block Kit Slack webhook notificationsWebhookChannel— generic HTTP webhook with structured JSON payload- Alert types:
new_content,keyword,high_similarity
CompetitorGraphIndexer— creates virtual nodes +competitor_similarityedges- Reuses existing
content_graph_nodes/content_graph_edgestables from #14 - Competitor items indexed with deterministic node IDs (SHA-1 prefix)
CompetitorSourceController— CRUD for competitor sourcesCompetitorController— content listing, crawl trigger, alert CRUDDifferentiationController— analysis listing + summary endpoint- Form requests with full validation
- JSON:API-style resources
- Input validation on all competitor source URLs (must match protocol/domain whitelist)
- Rate limiting on crawlers (500 req/day per source)
- Auth: All endpoints require
manage-competitorspermission - CORS disabled for competitor data (internal only)
- All components use Composition API + TypeScript
CrawlerHealthMonitor— detects stale/high-error sources, logs warningsRetentionPolicyService— prunes old content/analyses/events on configurable schedule- Scheduler entries: health check (hourly), retention prune (weekly Sun 02:00)
- OpenAPI 3.1 spec:
docs/competitor-differentiation-api.yaml - Blog post:
docs/blog-competitor-differentiation.md
COMPETITOR_ANALYSIS_ENABLED=true
COMPETITOR_SIMILARITY_THRESHOLD=0.25
COMPETITOR_MAX_ANALYZE=5
COMPETITOR_AUTO_ENRICH_BRIEFS=true
COMPETITOR_CONTENT_RETENTION_DAYS=90
COMPETITOR_ANALYSIS_RETENTION_DAYS=180
COMPETITOR_ALERT_EVENT_RETENTION_DAYS=30Media Library & Digital Asset Management (Discussion #4)
A complete digital asset management (DAM) system for organizing, tagging, editing, and serving media assets. Built for multi-format content delivery and CDN integration.
Features:
- Folders & Collections — Organize assets hierarchically using adjacency-list folders. Create smart collections with powerful filtering and bulk operations.
- Drag-and-drop Upload — Metadata extraction (MIME type, dimensions, file size, duration) on ingest. Progress tracking and batch upload support.
- AI Auto-tagging (opt-in) — Enable
MEDIA_AI_TAGGINGenvironment variable to automatically tag images using Claude vision. Powered by Anthropic API; all costs logged toAIGenerationLog. - Image Editing — Crop, rotate, and resize images via
MediaEditController. Changes create new variants; originals are preserved. - Automatic Variant Generation — On upload, generate
thumb(150×150),medium(600×600), andlarge(1600×1600) variants. WebP format with configurable quality. Stored locally or on S3 (viaFILESYSTEM_DISK). - Usage Tracking — Query which content items reference a specific asset. Prevents accidental deletion of in-use media.
- Public Headless API —
/v1/public/mediaendpoints (no auth required) with throttle protection (120 req/min). Perfect for headless frontends and CDN edge caching. - Full REST API — Complete CRUD operations on assets, folders, and collections. Bearer token auth via Sanctum.
- MediaPicker Vue Component — Integrates with content editor for seamless asset selection during content creation.
Environment Variables (new):
MEDIA_AI_TAGGING— Enable automatic AI-based image tagging (default:false)CDN_ENABLED— Enable public CDN delivery endpoints (default:true)
API Endpoints:
Authenticated (requires Bearer token):
GET /v1/media— List all assetsPOST /v1/media— Upload asset (20 req/min throttle)GET /v1/media/{asset}— Fetch asset detailsPATCH /v1/media/{asset}— Update asset metadataDELETE /v1/media/{asset}— Delete assetPATCH /v1/media/{asset}/move— Move to folderGET /v1/media/{asset}/usage— Show usage in contentPOST /v1/media/{asset}/edit— Edit (crop/rotate/resize)GET /v1/media/{asset}/variants— List generated variantsGET|POST /v1/media/folders— CRUD foldersPATCH /v1/media/folders/{folder}/move— Move folderGET|POST|PATCH|DELETE /v1/media/collections— CRUD collectionsPOST|DELETE /v1/media/collections/{collection}/items— Manage collection items
Public (no auth):
GET /v1/public/media— List public assets (120 req/min throttle)GET /v1/public/media/{asset}— Fetch public assetGET /v1/public/media/collections/{collection}— Fetch collection
- Remove legacy
numen.anthropicconfig block (duplicatesnumen.providers.anthropic) AgentContractinterface extracted fromAgentabstract class
Multi-Language & i18n Support (Discussion #7)
Full content localization with AI-powered translation, space-level locale management, and intelligent fallback chains.
Locale Management:
- Space-level locale configuration: add/remove/reorder locales, set default locale
- Intelligent 5-step fallback chain (exact match → language prefix → fallback config → space default →
"en") - Prevents invalid locale codes with
Localevalidation class (BCP 47 compliant)
AI-Powered Translation:
- Tone-aware translation using existing Persona system — respects content creator's voice
- Async job queue (
TranslateContentJobonai-pipelinequeue) for background processing - Translation status tracking: pending → completed/failed with error logging
- Job retry support with configurable backoff
Translation Workflow:
- Translation matrix view showing per-content, per-locale coverage and status
- Side-by-side translation editor for reviewing AI-generated translations
- Manual translation support via API
- Batch translation operations with progress reporting
REST API Endpoints:
- Locale Management:
GET/POST/PATCH/DELETE /api/v1/locales(space-scoped) - Translation Workflow:
POST /api/v1/content/{content}/translate,GET /api/v1/content/{content}/translations - Translation Matrix:
GET /api/v1/translations/matrixwith pagination and status filters - Supported Locales:
GET /api/v1/locales/supportedfor available BCP 47 codes
Locale Awareness:
- Middleware:
SetLocaleFromRequestrespectsAccept-Languageheader,?locale=query param, andX-Localeheader - API responses include current locale context; content delivery selects best-match locale automatically