diff --git a/.opencode/skills/Art/Examples/human-linear-form.png b/.opencode/skills/Art/Examples/human-linear-form.png deleted file mode 100755 index 55bcd6b1..00000000 Binary files a/.opencode/skills/Art/Examples/human-linear-form.png and /dev/null differ diff --git a/.opencode/skills/Art/Examples/human-linear-style2.png b/.opencode/skills/Art/Examples/human-linear-style2.png deleted file mode 100755 index b19a630a..00000000 Binary files a/.opencode/skills/Art/Examples/human-linear-style2.png and /dev/null differ diff --git a/.opencode/skills/Art/Examples/setting-line-style.png b/.opencode/skills/Art/Examples/setting-line-style.png deleted file mode 100755 index 33e381fd..00000000 Binary files a/.opencode/skills/Art/Examples/setting-line-style.png and /dev/null differ diff --git a/.opencode/skills/Art/Examples/setting-line-style2.png b/.opencode/skills/Art/Examples/setting-line-style2.png deleted file mode 100755 index c8ac0c4e..00000000 Binary files a/.opencode/skills/Art/Examples/setting-line-style2.png and /dev/null differ diff --git a/.opencode/skills/Art/HeadshotExamples/Screenshot 2024-05-14 at 09.52.31.png b/.opencode/skills/Art/HeadshotExamples/Screenshot 2024-05-14 at 09.52.31.png deleted file mode 100755 index fbb3684c..00000000 Binary files a/.opencode/skills/Art/HeadshotExamples/Screenshot 2024-05-14 at 09.52.31.png and /dev/null differ diff --git a/.opencode/skills/Art/HeadshotExamples/headshot-clean.png b/.opencode/skills/Art/HeadshotExamples/headshot-clean.png deleted file mode 100755 index d227fc8f..00000000 Binary files a/.opencode/skills/Art/HeadshotExamples/headshot-clean.png and /dev/null differ diff --git a/.opencode/skills/Art/HeadshotExamples/headshot-hat-smiling.png b/.opencode/skills/Art/HeadshotExamples/headshot-hat-smiling.png deleted file mode 100755 index dd16ba57..00000000 Binary files a/.opencode/skills/Art/HeadshotExamples/headshot-hat-smiling.png and /dev/null differ diff --git a/.opencode/skills/Art/HeadshotExamples/headshot-nah.png b/.opencode/skills/Art/HeadshotExamples/headshot-nah.png deleted file mode 100755 index 38218932..00000000 Binary files a/.opencode/skills/Art/HeadshotExamples/headshot-nah.png and /dev/null differ diff --git a/.opencode/skills/Art/HeadshotExamples/headshot-outside-smiling.png b/.opencode/skills/Art/HeadshotExamples/headshot-outside-smiling.png deleted file mode 100755 index 666f890d..00000000 Binary files a/.opencode/skills/Art/HeadshotExamples/headshot-outside-smiling.png and /dev/null differ diff --git a/.opencode/skills/Art/HeadshotExamples/headshot-pondering.png b/.opencode/skills/Art/HeadshotExamples/headshot-pondering.png deleted file mode 100755 index a28fe212..00000000 Binary files a/.opencode/skills/Art/HeadshotExamples/headshot-pondering.png and /dev/null differ diff --git a/.opencode/skills/Art/HeadshotExamples/headshot-smiling.png b/.opencode/skills/Art/HeadshotExamples/headshot-smiling.png deleted file mode 100755 index 8153ecd8..00000000 Binary files a/.opencode/skills/Art/HeadshotExamples/headshot-smiling.png and /dev/null differ diff --git a/.opencode/skills/Art/HeadshotExamples/headshot-surprised-hat.png b/.opencode/skills/Art/HeadshotExamples/headshot-surprised-hat.png deleted file mode 100755 index 41685596..00000000 Binary files a/.opencode/skills/Art/HeadshotExamples/headshot-surprised-hat.png and /dev/null differ diff --git a/.opencode/skills/Art/HeadshotExamples/headshot-walking-cap-smiling.png b/.opencode/skills/Art/HeadshotExamples/headshot-walking-cap-smiling.png deleted file mode 100755 index a8765117..00000000 Binary files a/.opencode/skills/Art/HeadshotExamples/headshot-walking-cap-smiling.png and /dev/null differ diff --git a/.opencode/skills/Art/HeadshotExamples/headshot-what-is-that.png b/.opencode/skills/Art/HeadshotExamples/headshot-what-is-that.png deleted file mode 100755 index 5aee14aa..00000000 Binary files a/.opencode/skills/Art/HeadshotExamples/headshot-what-is-that.png and /dev/null differ diff --git a/.opencode/skills/Art/HeadshotExamples/headshot-whatthehell.png b/.opencode/skills/Art/HeadshotExamples/headshot-whatthehell.png deleted file mode 100755 index 76394e07..00000000 Binary files a/.opencode/skills/Art/HeadshotExamples/headshot-whatthehell.png and /dev/null differ diff --git a/.opencode/skills/Art/HeadshotExamples/headshot-yuk.png b/.opencode/skills/Art/HeadshotExamples/headshot-yuk.png deleted file mode 100755 index a87129b0..00000000 Binary files a/.opencode/skills/Art/HeadshotExamples/headshot-yuk.png and /dev/null differ diff --git a/.opencode/skills/Art/Lib/discord-bot.ts b/.opencode/skills/Art/Lib/discord-bot.ts deleted file mode 100755 index 806db1d8..00000000 --- a/.opencode/skills/Art/Lib/discord-bot.ts +++ /dev/null @@ -1,275 +0,0 @@ -/** - * discord-bot.ts - Discord Bot Client for Midjourney Integration - * - * Official Discord bot wrapper using discord.js for legitimate interaction - * with Midjourney bot. Handles connection, message sending, monitoring, - * and image downloads. - * - * @see ~/.opencode/skills/art/SKILL.md - */ - -import { - Client, - GatewayIntentBits, - Message, - TextChannel, - Partials -} from 'discord.js'; -import { writeFile } from 'node:fs/promises'; - -// ============================================================================ -// Constants -// ============================================================================ - -const MIDJOURNEY_BOT_ID = '936929561302675456'; // Official Midjourney bot ID - -// ============================================================================ -// Types -// ============================================================================ - -export interface DiscordBotConfig { - token: string; - channelId: string; -} - -export interface WaitForResponseOptions { - timeout: number; // in seconds - pollInterval?: number; // in milliseconds -} - -// ============================================================================ -// Discord Bot Client -// ============================================================================ - -export class DiscordBotClient { - private client: Client; - private config: DiscordBotConfig; - private connected: boolean = false; - - constructor(config: DiscordBotConfig) { - this.config = config; - - // Initialize Discord client with required intents - this.client = new Client({ - intents: [ - GatewayIntentBits.Guilds, - GatewayIntentBits.GuildMessages, - GatewayIntentBits.MessageContent, - ], - partials: [Partials.Message, Partials.Channel], - }); - } - - /** - * Connect to Discord - */ - async connect(): Promise { - if (this.connected) { - return; - } - - return new Promise((resolve, reject) => { - // Set up event handlers - this.client.once('ready', () => { - console.log(`✅ Discord bot connected as ${this.client.user?.tag}`); - this.connected = true; - resolve(); - }); - - this.client.on('error', (error) => { - console.error('❌ Discord client error:', error); - }); - - // Login with bot token - this.client.login(this.config.token).catch(reject); - }); - } - - /** - * Send a message to the specified channel - */ - async sendMessage(content: string): Promise { - if (!this.connected) { - throw new Error('Bot not connected. Call connect() first.'); - } - - const channel = await this.client.channels.fetch(this.config.channelId); - - if (!channel || !channel.isTextBased()) { - throw new Error(`Channel ${this.config.channelId} is not a text channel`); - } - - const message = await (channel as TextChannel).send(content); - console.log(`📤 Sent message: ${content}`); - - return message; - } - - /** - * Wait for Midjourney's response to a prompt - * - * Polls the channel for messages from Midjourney bot that reference - * our initial message. Returns when the response is complete (has image attachments). - */ - async waitForMidjourneyResponse( - initialMessageId: string, - options: WaitForResponseOptions - ): Promise { - const { timeout, pollInterval = 5000 } = options; - const startTime = Date.now(); - const timeoutMs = timeout * 1000; - - console.log(`⏳ Waiting for Midjourney response (timeout: ${timeout}s)...`); - - while (Date.now() - startTime < timeoutMs) { - // Fetch recent messages from channel - const channel = await this.client.channels.fetch(this.config.channelId); - - if (!channel || !channel.isTextBased()) { - throw new Error('Channel not found or not text-based'); - } - - const messages = await (channel as TextChannel).messages.fetch({ limit: 20 }); - - // Find Midjourney's response to our prompt - for (const [_, message] of messages) { - // Check if message is from Midjourney bot - if (message.author.id !== MIDJOURNEY_BOT_ID) { - continue; - } - - // Check if this message references our initial prompt - const referencesOurMessage = - message.reference?.messageId === initialMessageId || - message.interaction?.id === initialMessageId || - message.content.includes(initialMessageId); - - if (!referencesOurMessage) { - continue; - } - - // Check if generation is complete - if (this.isGenerationComplete(message)) { - console.log(`✅ Midjourney generation complete!`); - return message; - } else { - console.log(`⏳ Generation in progress... (${Math.floor((Date.now() - startTime) / 1000)}s)`); - } - } - - // Wait before next poll - await this.sleep(pollInterval); - } - - throw new Error(`Timeout waiting for Midjourney response after ${timeout}s`); - } - - /** - * Check if Midjourney generation is complete - * - * A complete generation has: - * - Image attachments - * - No "Waiting to start" or "%" progress indicators - */ - private isGenerationComplete(message: Message): boolean { - // Must have attachments (the generated image) - if (message.attachments.size === 0) { - return false; - } - - // Check for in-progress indicators - const content = message.content.toLowerCase(); - const inProgressIndicators = [ - 'waiting to start', - '(waiting)', - '(0%)', - '(1%)', - '(2%)', - '(3%)', - '(4%)', - '(5%)', - '(6%)', - '(7%)', - '(8%)', - '(9%)', - // Continue patterns for progress - '%)', - ]; - - for (const indicator of inProgressIndicators) { - if (content.includes(indicator)) { - return false; - } - } - - return true; - } - - /** - * Download image from URL to local path - */ - async downloadImage(url: string, outputPath: string): Promise { - console.log(`📥 Downloading image from ${url}...`); - - const response = await fetch(url); - - if (!response.ok) { - throw new Error(`Failed to download image: ${response.statusText}`); - } - - const arrayBuffer = await response.arrayBuffer(); - const buffer = Buffer.from(arrayBuffer); - - await writeFile(outputPath, buffer); - - console.log(`✅ Image saved to ${outputPath}`); - } - - /** - * Disconnect from Discord - */ - async disconnect(): Promise { - if (!this.connected) { - return; - } - - await this.client.destroy(); - this.connected = false; - console.log('👋 Discord bot disconnected'); - } - - /** - * Get the first image attachment URL from a message - */ - getImageUrl(message: Message): string | null { - if (message.attachments.size === 0) { - return null; - } - - // Get first attachment - const attachment = message.attachments.first(); - - if (!attachment) { - return null; - } - - // Verify it's an image - const imageExtensions = ['.png', '.jpg', '.jpeg', '.webp', '.gif']; - const isImage = imageExtensions.some(ext => - attachment.url.toLowerCase().includes(ext) - ); - - if (!isImage) { - return null; - } - - return attachment.url; - } - - /** - * Sleep utility - */ - private sleep(ms: number): Promise { - return new Promise(resolve => setTimeout(resolve, ms)); - } -} diff --git a/.opencode/skills/Art/Lib/midjourney-client.ts b/.opencode/skills/Art/Lib/midjourney-client.ts deleted file mode 100755 index 15738f86..00000000 --- a/.opencode/skills/Art/Lib/midjourney-client.ts +++ /dev/null @@ -1,336 +0,0 @@ -/** - * midjourney-client.ts - Midjourney Interaction Client - * - * High-level client for interacting with Midjourney bot through Discord. - * Handles prompt formatting, command submission, response parsing, - * and error detection. - * - * @see ~/.opencode/skills/art/SKILL.md - */ - -import { DiscordBotClient } from './discord-bot.js'; -import { Message } from 'discord.js'; - -// ============================================================================ -// Types -// ============================================================================ - -export interface MidjourneyOptions { - prompt: string; - aspectRatio?: string; - version?: string; - stylize?: number; - quality?: number; - chaos?: number; - weird?: number; - tile?: boolean; - timeout?: number; // in seconds -} - -export interface MidjourneyResult { - imageUrl: string; - prompt: string; - messageId: string; -} - -export type MidjourneyErrorType = - | 'content_policy' - | 'timeout' - | 'connection' - | 'invalid_params' - | 'generation_failed' - | 'no_image'; - -export class MidjourneyError extends Error { - constructor( - public type: MidjourneyErrorType, - message: string, - public originalPrompt?: string, - public suggestion?: string - ) { - super(message); - this.name = 'MidjourneyError'; - } -} - -// ============================================================================ -// Midjourney Client -// ============================================================================ - -export class MidjourneyClient { - private discordBot: DiscordBotClient; - - constructor(discordBot: DiscordBotClient) { - this.discordBot = discordBot; - } - - /** - * Generate image with Midjourney - * - * Submits prompt, waits for generation, and returns image URL - */ - async generateImage(options: MidjourneyOptions): Promise { - const { - prompt, - aspectRatio = '16:9', - version = '6.1', - stylize = 100, - quality = 1, - chaos, - weird, - tile = false, - timeout = 120, - } = options; - - // Format the Midjourney prompt - const formattedPrompt = this.formatPrompt({ - prompt, - aspectRatio, - version, - stylize, - quality, - chaos, - weird, - tile, - }); - - console.log(`🎨 Submitting to Midjourney: ${formattedPrompt}`); - - // Send the /imagine command - const initialMessage = await this.discordBot.sendMessage(`/imagine prompt: ${formattedPrompt}`); - - // Wait for Midjourney to complete generation - let responseMessage: Message; - try { - responseMessage = await this.discordBot.waitForMidjourneyResponse(initialMessage.id, { - timeout, - pollInterval: 5000, - }); - } catch (error) { - if (error instanceof Error && error.message.includes('Timeout')) { - throw new MidjourneyError( - 'timeout', - `Generation timed out after ${timeout}s. The image may still be processing in Discord.`, - formattedPrompt, - 'Try checking Discord manually or increasing the timeout value.' - ); - } - throw error; - } - - // Check for errors in response - this.detectErrors(responseMessage, formattedPrompt); - - // Extract image URL - const imageUrl = this.discordBot.getImageUrl(responseMessage); - - if (!imageUrl) { - throw new MidjourneyError( - 'no_image', - 'No image found in Midjourney response', - formattedPrompt, - 'The generation may have failed. Check Discord for error messages.' - ); - } - - return { - imageUrl, - prompt: formattedPrompt, - messageId: responseMessage.id, - }; - } - - /** - * Format Midjourney prompt with parameters - * - * Converts structured options into Midjourney command syntax - */ - private formatPrompt(options: { - prompt: string; - aspectRatio: string; - version: string; - stylize: number; - quality: number; - chaos?: number; - weird?: number; - tile: boolean; - }): string { - const { prompt, aspectRatio, version, stylize, quality, chaos, weird, tile } = options; - - let formattedPrompt = prompt; - - // Add aspect ratio - formattedPrompt += ` --ar ${aspectRatio}`; - - // Add version - formattedPrompt += ` --v ${version}`; - - // Add stylize (default is 100, only add if different) - if (stylize !== 100) { - formattedPrompt += ` --s ${stylize}`; - } - - // Add quality (default is 1, only add if different) - if (quality !== 1) { - formattedPrompt += ` --q ${quality}`; - } - - // Add optional parameters - if (chaos !== undefined) { - formattedPrompt += ` --chaos ${chaos}`; - } - - if (weird !== undefined) { - formattedPrompt += ` --weird ${weird}`; - } - - if (tile) { - formattedPrompt += ` --tile`; - } - - return formattedPrompt; - } - - /** - * Detect errors in Midjourney response - */ - private detectErrors(message: Message, originalPrompt: string): void { - const content = message.content.toLowerCase(); - - // Content policy violations - const contentPolicyIndicators = [ - 'banned prompt', - 'content policy', - 'violates our community standards', - 'inappropriate content', - 'against our terms', - ]; - - for (const indicator of contentPolicyIndicators) { - if (content.includes(indicator)) { - throw new MidjourneyError( - 'content_policy', - 'Prompt violates Midjourney content policy', - originalPrompt, - 'Try rephrasing your prompt to avoid potentially sensitive content.' - ); - } - } - - // Invalid parameters - const invalidParamIndicators = [ - 'invalid parameter', - 'unknown parameter', - 'invalid aspect ratio', - 'invalid version', - ]; - - for (const indicator of invalidParamIndicators) { - if (content.includes(indicator)) { - throw new MidjourneyError( - 'invalid_params', - 'Invalid Midjourney parameters', - originalPrompt, - 'Check your aspect ratio, version, and other parameter values.' - ); - } - } - - // Generation failures - const failureIndicators = [ - 'failed to generate', - 'generation failed', - 'error generating', - 'something went wrong', - ]; - - for (const indicator of failureIndicators) { - if (content.includes(indicator)) { - throw new MidjourneyError( - 'generation_failed', - 'Midjourney generation failed', - originalPrompt, - 'Try again or check Discord for more details.' - ); - } - } - } - - /** - * Parse Midjourney response to extract metadata - */ - parseResponse(message: Message): { - prompt: string; - parameters: Record; - } { - const content = message.content; - - // Extract prompt (usually before the first --) - const promptMatch = content.match(/^(.+?)(?:\s+--|\s*$)/); - const prompt = promptMatch ? promptMatch[1].trim() : content; - - // Extract parameters - const parameters: Record = {}; - const paramRegex = /--(\w+)\s+([^\s-]+)/g; - let match; - - while ((match = paramRegex.exec(content)) !== null) { - parameters[match[1]] = match[2]; - } - - return { prompt, parameters }; - } - - /** - * Validate Midjourney options before submission - */ - static validateOptions(options: MidjourneyOptions): void { - // Validate aspect ratio - const validAspectRatios = [ - '1:1', '16:9', '9:16', '2:3', '3:2', '4:5', '5:4', '7:4', '4:7', - '21:9', '9:21', '3:4', '4:3' - ]; - - if (options.aspectRatio && !validAspectRatios.includes(options.aspectRatio)) { - throw new Error( - `Invalid aspect ratio: ${options.aspectRatio}. Valid ratios: ${validAspectRatios.join(', ')}` - ); - } - - // Validate version - const validVersions = ['6.1', '6', '5.2', '5.1', '5', 'niji', 'niji 6']; - - if (options.version && !validVersions.includes(options.version)) { - throw new Error( - `Invalid version: ${options.version}. Valid versions: ${validVersions.join(', ')}` - ); - } - - // Validate stylize (0-1000) - if (options.stylize !== undefined && (options.stylize < 0 || options.stylize > 1000)) { - throw new Error('Stylize must be between 0 and 1000'); - } - - // Validate quality - const validQualities = [0.25, 0.5, 1, 2]; - - if (options.quality !== undefined && !validQualities.includes(options.quality)) { - throw new Error('Quality must be 0.25, 0.5, 1, or 2'); - } - - // Validate chaos (0-100) - if (options.chaos !== undefined && (options.chaos < 0 || options.chaos > 100)) { - throw new Error('Chaos must be between 0 and 100'); - } - - // Validate weird (0-3000) - if (options.weird !== undefined && (options.weird < 0 || options.weird > 3000)) { - throw new Error('Weird must be between 0 and 3000'); - } - - // Validate timeout - if (options.timeout !== undefined && options.timeout < 30) { - throw new Error('Timeout must be at least 30 seconds'); - } - } -} diff --git a/.opencode/skills/Art/SKILL.md b/.opencode/skills/Art/SKILL.md deleted file mode 100755 index 68d20d83..00000000 --- a/.opencode/skills/Art/SKILL.md +++ /dev/null @@ -1,199 +0,0 @@ ---- -name: Art -description: Visual content system. USE WHEN art, illustrations, diagrams, visualizations, mermaid, flowchart. ---- - -# Art Skill - -Complete visual content system for creating illustrations, diagrams, and visual content. - -## Customization - -**Before executing, check for user customizations at:** -`~/.opencode/skills/CORE/USER/SKILLCUSTOMIZATIONS/Art/` - -If this directory exists, load and apply: -- `PREFERENCES.md` - Aesthetic preferences, default model, output location -- `CharacterSpecs.md` - Character design specifications -- `SceneConstruction.md` - Scene composition guidelines - -These override default behavior. If the directory does not exist, proceed with skill defaults. - -## 🚨🚨🚨 MANDATORY: Output to Downloads First 🚨🚨🚨 - -``` -━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -⚠️ ALL GENERATED IMAGES GO TO ~/Downloads/ FIRST ⚠️ -⚠️ NEVER output directly to project directories ⚠️ -⚠️ User MUST preview in Finder/Preview before use ⚠️ -━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -``` - -**This applies to ALL workflows in this skill.** - -## Voice Notification - -**When executing a workflow, do BOTH:** - -1. **Send voice notification**: - ```bash - curl -s -X POST http://localhost:8888/notify \ - -H "Content-Type: application/json" \ - -d '{"message": "Running the WORKFLOWNAME workflow from the Art skill"}' \ - > /dev/null 2>&1 & - ``` - -2. **Output text notification**: - ``` - Running the **WorkflowName** workflow from the **Art** skill... - ``` - ---- - -## Workflow Routing - -Route to the appropriate workflow based on the request. - - - Blog header or editorial illustration → `Workflows/Essay.md` - - D3.js interactive chart or dashboard → `Workflows/D3Dashboards.md` - - Visualization or unsure which format → `Workflows/Visualize.md` - - Mermaid flowchart or sequence diagram → `Workflows/Mermaid.md` - - Technical or architecture diagram → `Workflows/TechnicalDiagrams.md` - - Taxonomy or classification grid → `Workflows/Taxonomies.md` - - Timeline or chronological progression → `Workflows/Timelines.md` - - Framework or 2x2 matrix → `Workflows/Frameworks.md` - - Comparison or X vs Y → `Workflows/Comparisons.md` - - Annotated screenshot → `Workflows/AnnotatedScreenshots.md` - - Recipe card or step-by-step → `Workflows/RecipeCards.md` - - Aphorism or quote card → `Workflows/Aphorisms.md` - - Conceptual map or territory → `Workflows/Maps.md` - - Stat card or big number visual → `Workflows/Stats.md` - - Comic or sequential panels → `Workflows/Comics.md` - - YouTube thumbnail (with existing assets) → `Workflows/YouTubeThumbnail.md` - - Ad-hoc YouTube thumbnail (generate from content) → `Workflows/AdHocYouTubeThumbnail.md` - - PAI pack icon → `Workflows/CreatePAIPackIcon.md` - ---- - -## Core Aesthetic - -**Default:** Production-quality concept art style appropriate for editorial and technical content. - -**User customization** defines specific aesthetic preferences including: -- Visual style and influences -- Line treatment and rendering approach -- Color palette and wash technique -- Character design specifications -- Scene composition rules - -**Load from:** `~/.opencode/skills/CORE/USER/SKILLCUSTOMIZATIONS/Art/PREFERENCES.md` - ---- - -## Reference Images - -**User customization** may include reference images for consistent style. - -Check `~/.opencode/skills/CORE/USER/SKILLCUSTOMIZATIONS/Art/PREFERENCES.md` for: -- Reference image locations -- Style examples by use case -- Character and scene reference guidance - -**Usage:** Before generating images, load relevant user-provided references to match their preferred style. - ---- - -## Image Generation - -**Default model:** Check user customization at `SKILLCUSTOMIZATIONS/Art/PREFERENCES.md` -**Fallback:** nano-banana-pro (Gemini 3 Pro) - -### 🚨 CRITICAL: Always Output to Downloads First - -**ALL generated images MUST go to `~/Downloads/` first for preview and selection.** - -Never output directly to a project's `public/images/` directory. User needs to review images in Preview before they're used. - -**Workflow:** -1. Generate to `~/Downloads/[descriptive-name].png` -2. User reviews in Preview -3. If approved, THEN copy to final destination (e.g., `cms/public/images/`) -4. Create WebP and thumbnail versions at final destination - -```bash -# CORRECT - Output to Downloads for preview -bun run ~/.opencode/skills/Art/Tools/Generate.ts \ - --model nano-banana-pro \ - --prompt "[PROMPT]" \ - --size 2K \ - --aspect-ratio 1:1 \ - --thumbnail \ - --output ~/Downloads/blog-header-concept.png - -# After approval, copy to final location -cp ~/Downloads/blog-header-concept.png ~/Projects/Website/cms/public/images/ -cp ~/Downloads/blog-header-concept-thumb.png ~/Projects/Website/cms/public/images/ -``` - -### Multiple Reference Images (Character/Style Consistency) - -For improved character or style consistency, use multiple `--reference-image` flags: - -```bash -# Multiple reference images for better likeness -bun run ~/.opencode/skills/Art/Tools/Generate.ts \ - --model nano-banana-pro \ - --prompt "Person from references at a party..." \ - --reference-image face1.jpg \ - --reference-image face2.jpg \ - --reference-image face3.jpg \ - --size 2K \ - --aspect-ratio 16:9 \ - --output ~/Downloads/character-scene.png -``` - -**API Limits (Gemini):** -- Up to 5 human reference images -- Up to 6 object reference images -- Maximum 14 total reference images per request - -**API keys in:** `${PAI_DIR}/.env` - -## Examples - -**Example 1: Blog header image** -``` -User: "create a header for my AI agents post" -→ Invokes ESSAY workflow -→ Generates charcoal sketch prompt -→ Creates image with architectural aesthetic -→ Saves to ~/Downloads/ for preview -→ After approval, copies to public/images/ -``` - -**Example 2: Technical architecture diagram** -``` -User: "make a diagram showing the SPQA pattern" -→ Invokes TECHNICALDIAGRAMS workflow -→ Creates structured architecture visual -→ Outputs PNG with consistent styling -``` - -**Example 3: Comparison visualization** -``` -User: "visualize humans vs AI decision-making" -→ Invokes COMPARISONS workflow -→ Creates side-by-side visual -→ Charcoal sketch with labeled elements -``` - -**Example 4: PAI pack icon** -``` -User: "create icon for the skill system pack" -→ Invokes CREATEPAIPACKICON workflow -→ Reads workflow from Workflows/CreatePAIPackIcon.md -→ Generates 1K image with --remove-bg for transparency -→ Resizes to 256x256 RGBA PNG -→ Outputs to ~/Downloads/ for preview -→ After approval, copies to ~/Projects/PAI/Packs/icons/ -``` diff --git a/.opencode/skills/Art/ThumbnailExamples/AudioEssay.png b/.opencode/skills/Art/ThumbnailExamples/AudioEssay.png deleted file mode 100755 index 0ab640f1..00000000 Binary files a/.opencode/skills/Art/ThumbnailExamples/AudioEssay.png and /dev/null differ diff --git a/.opencode/skills/Art/ThumbnailExamples/InterviewVideo.png b/.opencode/skills/Art/ThumbnailExamples/InterviewVideo.png deleted file mode 100755 index aa08f962..00000000 Binary files a/.opencode/skills/Art/ThumbnailExamples/InterviewVideo.png and /dev/null differ diff --git a/.opencode/skills/Art/ThumbnailExamples/RegularVideo1.png b/.opencode/skills/Art/ThumbnailExamples/RegularVideo1.png deleted file mode 100755 index 36c201b8..00000000 Binary files a/.opencode/skills/Art/ThumbnailExamples/RegularVideo1.png and /dev/null differ diff --git a/.opencode/skills/Art/ThumbnailExamples/RegularVideo2.png b/.opencode/skills/Art/ThumbnailExamples/RegularVideo2.png deleted file mode 100755 index 1918c0de..00000000 Binary files a/.opencode/skills/Art/ThumbnailExamples/RegularVideo2.png and /dev/null differ diff --git a/.opencode/skills/Art/ThumbnailExamples/RegularVideo3.png b/.opencode/skills/Art/ThumbnailExamples/RegularVideo3.png deleted file mode 100755 index 843387f3..00000000 Binary files a/.opencode/skills/Art/ThumbnailExamples/RegularVideo3.png and /dev/null differ diff --git a/.opencode/skills/Art/ThumbnailExamples/RegularVideo4.png b/.opencode/skills/Art/ThumbnailExamples/RegularVideo4.png deleted file mode 100755 index 2cbba4ac..00000000 Binary files a/.opencode/skills/Art/ThumbnailExamples/RegularVideo4.png and /dev/null differ diff --git a/.opencode/skills/Art/ThumbnailExamples/RegularVideo5.png b/.opencode/skills/Art/ThumbnailExamples/RegularVideo5.png deleted file mode 100755 index d0455400..00000000 Binary files a/.opencode/skills/Art/ThumbnailExamples/RegularVideo5.png and /dev/null differ diff --git a/.opencode/skills/Art/Tools/ComposeThumbnail.ts b/.opencode/skills/Art/Tools/ComposeThumbnail.ts deleted file mode 100755 index cd0c24d8..00000000 --- a/.opencode/skills/Art/Tools/ComposeThumbnail.ts +++ /dev/null @@ -1,539 +0,0 @@ -#!/usr/bin/env bun - -/** - * ComposeThumbnail - YouTube Thumbnail Composition CLI - * - * Composites background, headshot, and text into a YouTube thumbnail. - * Uses ImageMagick for all composition operations. - * - * Features: - * - Dynamic headshot positioning (left, center, right) - * - Solid black backdrop boxes behind text for readability - * - Full-height headshot that dominates the frame - * - Colored border (Tokyo Night purple default) - */ - -import { spawn } from "node:child_process"; -import { existsSync, unlinkSync } from "node:fs"; -import { resolve, dirname } from "node:path"; - -// ============================================================================ -// Types -// ============================================================================ - -interface CLIArgs { - background: string; - headshot: string; - title: string; - subtitle: string; - output: string; - titleColor?: string; - subtitleColor?: string; - borderColor?: string; - font?: string; - headshotPosition?: "left" | "center" | "right"; -} - -// ============================================================================ -// Configuration -// ============================================================================ - -const DEFAULTS = { - titleColor: "#7dcfff", // Tokyo Night cyan - VIBRANT by default - subtitleColor: "#FFFFFF", // White text for contrast - borderColor: "#bb9af7", // Tokyo Night Vivid Purple - font: "Helvetica-Bold", // System font that actually exists - headshotPosition: "left" as const, - output: `${process.env.HOME}/Downloads/yt-thumbnail-${Date.now()}.png`, -}; - -const LAYOUT = { - width: 1280, - height: 720, - borderWidth: 16, - // TEXT - BILLBOARD STYLE (large, bold, dominant) - titleSize: 100, // DOMINANT - fills the space - subtitleSize: 50, // Proportionally sized, still readable - titleStroke: 4, // Bold outline for visibility - subtitleStroke: 3, // Visible outline - textPadding: 6, - textBoxPadding: 20, - // Safe zones - headshot and text never overlap - headshotMaxWidth: 0.40, // Headshot takes max 40% width - textZoneWidth: 0.55, // Text zone is 55% width (FILLS the space) - textZoneGap: 0.05, // 5% gap between zones -}; - -// Color presets for text (Tokyo Night palette + extras) -const COLOR_PRESETS: Record = { - white: "#FFFFFF", - cyan: "#7dcfff", - purple: "#bb9af7", - blue: "#7aa2f7", - magenta: "#ff007c", - yellow: "#e0af68", - green: "#9ece6a", - orange: "#ff9e64", - red: "#f7768e", -}; - -function resolveColor(color: string): string { - // If it's a preset name, return the hex value - const preset = COLOR_PRESETS[color.toLowerCase()]; - if (preset) return preset; - // Otherwise assume it's already a hex color - return color; -} - -// ============================================================================ -// Error Handling -// ============================================================================ - -class CLIError extends Error { - constructor(message: string, public exitCode: number = 1) { - super(message); - this.name = "CLIError"; - } -} - -// ============================================================================ -// Helpers -// ============================================================================ - -function printHelp(): void { - console.log(` -ComposeThumbnail - YouTube Thumbnail Composition CLI - -USAGE: - bun ~/.opencode/skills/Art/Tools/ComposeThumbnail.ts [OPTIONS] - -REQUIRED: - --background Background image (dramatic tech art) - --headshot Headshot image (transparent background) - --title Title text (max 6 words, auto-capitalized) - --subtitle Subtitle text (max 12 words, auto-capitalized) - -OPTIONAL: - --output Output path (default: ~/Downloads/yt-thumbnail-{timestamp}.png) - --position Headshot position: left, center, right (default: left) - --font Font name (default: Helvetica-Bold) - --title-color Title color (default: #FFFFFF) - --subtitle-color Subtitle color (default: #FFFFFF) - --border-color Border color (default: #bb9af7 Tokyo Night Purple) - --help, -h Show this help message - -EXAMPLE: - bun ~/.opencode/skills/Art/Tools/ComposeThumbnail.ts \\ - --background ~/Downloads/tech-background.png \\ - --headshot ~/Downloads/headshot-nobg.png \\ - --title "AI AGENTS KILLING SOFTWARE" \\ - --subtitle "WHY TRADITIONAL DEVELOPMENT IS DEAD" \\ - --position left \\ - --output ~/Downloads/thumbnail.png - -LAYOUT: - Canvas: 1280x720 px - Border: 16px colored border (Tokyo Night purple) - Headshot: Full height inside border, positioned left/center/right - Text: White text with minimal black backdrop boxes -`); -} - -function parseArgs(args: string[]): CLIArgs { - const result: Partial = {}; - - for (let i = 0; i < args.length; i++) { - const arg = args[i]; - const next = args[i + 1]; - - switch (arg) { - case "--help": - case "-h": - printHelp(); - process.exit(0); - case "--background": - result.background = next; - i++; - break; - case "--headshot": - result.headshot = next; - i++; - break; - case "--title": - result.title = next; - i++; - break; - case "--subtitle": - result.subtitle = next; - i++; - break; - case "--output": - result.output = next; - i++; - break; - case "--position": - if (next === "left" || next === "center" || next === "right") { - result.headshotPosition = next; - } - i++; - break; - case "--title-color": - result.titleColor = next; - i++; - break; - case "--subtitle-color": - result.subtitleColor = next; - i++; - break; - case "--border-color": - result.borderColor = next; - i++; - break; - case "--font": - result.font = next; - i++; - break; - } - } - - // Validate required args - if (!result.background) throw new CLIError("--background is required"); - if (!result.headshot) throw new CLIError("--headshot is required"); - if (!result.title) throw new CLIError("--title is required"); - if (!result.subtitle) throw new CLIError("--subtitle is required"); - - // Validate files exist - if (!existsSync(result.background)) { - throw new CLIError(`Background file not found: ${result.background}`); - } - if (!existsSync(result.headshot)) { - throw new CLIError(`Headshot file not found: ${result.headshot}`); - } - - return { - background: resolve(result.background), - headshot: resolve(result.headshot), - title: result.title.toUpperCase(), - subtitle: result.subtitle.toUpperCase(), - output: result.output ? resolve(result.output) : DEFAULTS.output, - titleColor: result.titleColor || DEFAULTS.titleColor, - subtitleColor: result.subtitleColor || DEFAULTS.subtitleColor, - borderColor: result.borderColor || DEFAULTS.borderColor, - font: result.font || DEFAULTS.font, - headshotPosition: result.headshotPosition || DEFAULTS.headshotPosition, - }; -} - -async function runCommand(cmd: string, args: string[]): Promise { - return new Promise((resolve, reject) => { - const proc = spawn(cmd, args); - let stdout = ""; - let stderr = ""; - - proc.stdout.on("data", (data) => (stdout += data.toString())); - proc.stderr.on("data", (data) => (stderr += data.toString())); - - proc.on("close", (code) => { - if (code === 0) { - resolve(stdout); - } else { - reject(new CLIError(`Command failed: ${cmd} ${args.join(" ")}\n${stderr}`, code || 1)); - } - }); - }); -} - -// ============================================================================ -// Headshot Processing -// ============================================================================ - -/** - * Crop headshot to FACE ONLY - removes shoulders/body and zooms into face. - * This ensures the face dominates the frame without clipped body parts. - */ -async function cropToFaceOnly(headshotPath: string, outputPath: string): Promise { - // Get original dimensions - const dimensions = await runCommand("magick", [ - "identify", "-format", "%wx%h", headshotPath - ]); - const [width, height] = dimensions.trim().split("x").map(Number); - - // Crop bottom 25% (removes shoulders/body) and zoom 135% into face - await runCommand("magick", [ - headshotPath, - "-gravity", "north", // Anchor to top (face area) - "-crop", `100%x75%+0+0`, // Crop bottom 25% (shoulders/body) - "+repage", - "-resize", "135%", // Zoom into face - "-gravity", "center", - "-extent", `${width}x${height}`, // Restore original dimensions - outputPath, - ]); -} - -// ============================================================================ -// Main Composition -// ============================================================================ - -async function composeThumbnail(args: CLIArgs): Promise { - const outputDir = dirname(args.output); - const timestamp = Date.now(); - - // Intermediate files - const resizedBg = `${outputDir}/.yt-bg-${timestamp}.png`; - const croppedHeadshot = `${outputDir}/.yt-cropped-${timestamp}.png`; - const withHeadshot = `${outputDir}/.yt-headshot-${timestamp}.png`; - const withText = `${outputDir}/.yt-text-${timestamp}.png`; - - const intermediates = [resizedBg, croppedHeadshot, withHeadshot, withText]; - - try { - console.log("🎨 Composing YouTube thumbnail..."); - - // Step 1: Resize background to exact dimensions - console.log(" 📐 Resizing background to 1280x720..."); - await runCommand("magick", [ - args.background, - "-resize", `${LAYOUT.width}x${LAYOUT.height}^`, - "-gravity", "center", - "-extent", `${LAYOUT.width}x${LAYOUT.height}`, - resizedBg, - ]); - - // Step 2: Crop headshot to FACE ONLY (remove shoulders/body) - console.log(` ✂️ Cropping headshot to face only...`); - await cropToFaceOnly(args.headshot, croppedHeadshot); - - // Step 3: Composite headshot based on position - console.log(` 👤 Adding headshot (${args.headshotPosition})...`); - - // Calculate headshot height - FULL HEIGHT inside border - // Face should fill ~95% of vertical space inside the border - const headshotHeight = LAYOUT.height - (LAYOUT.borderWidth * 2); // 688px - - // Determine gravity and offset based on position - let gravity: string; - let geometryOffset: string; - - switch (args.headshotPosition) { - case "left": - gravity = "west"; - geometryOffset = "+20+0"; - break; - case "center": - gravity = "center"; - geometryOffset = "+0+0"; - break; - case "right": - gravity = "east"; - geometryOffset = "+20+0"; - break; - default: - gravity = "west"; - geometryOffset = "+20+0"; - } - - await runCommand("magick", [ - resizedBg, - "(", - croppedHeadshot, // Use cropped headshot (face only) - "-resize", `x${headshotHeight}`, - ")", - "-gravity", gravity, - "-geometry", geometryOffset, - "-composite", - withHeadshot, - ]); - - // Step 4: Add text with stroke outline - console.log(" 📝 Adding text with stroke outlines..."); - - // For left/right positions: create combined text block, center in available region - // For center position: separate title (top) and subtitle (bottom) - - // Resolve colors (support preset names like "cyan" or hex like "#ff007c") - const titleColorResolved = resolveColor(args.titleColor!); - const subtitleColorResolved = resolveColor(args.subtitleColor!); - - if (args.headshotPosition === "center") { - // CENTER: Title at top, subtitle at bottom (outside headshot zone) - const titleWithStroke = `${outputDir}/.yt-title-${timestamp}.png`; - const subtitleWithStroke = `${outputDir}/.yt-subtitle-${timestamp}.png`; - intermediates.push(titleWithStroke, subtitleWithStroke); - - // Create title (WIDE canvas for 100pt BILLBOARD text) - await runCommand("magick", [ - "-size", "1400x200", - "xc:transparent", - "-font", args.font!, - "-pointsize", String(LAYOUT.titleSize), - "-gravity", "center", - "-stroke", "#000000", "-strokewidth", String(LAYOUT.titleStroke), "-fill", "none", - "-annotate", "+0+0", args.title, - "-stroke", "none", "-fill", titleColorResolved, - "-annotate", "+0+0", args.title, - "-trim", "+repage", - titleWithStroke, - ]); - - // Create subtitle (WIDE canvas for 50pt BILLBOARD text) - await runCommand("magick", [ - "-size", "1400x120", - "xc:transparent", - "-font", args.font!, - "-pointsize", String(LAYOUT.subtitleSize), - "-gravity", "center", - "-stroke", "#000000", "-strokewidth", String(LAYOUT.subtitleStroke), "-fill", "none", - "-annotate", "+0+0", args.subtitle, - "-stroke", "none", "-fill", subtitleColorResolved, - "-annotate", "+0+0", args.subtitle, - "-trim", "+repage", - subtitleWithStroke, - ]); - - // Composite title at top (inside border, above headshot zone) - const withTitle = `${outputDir}/.yt-with-title-${timestamp}.png`; - intermediates.push(withTitle); - await runCommand("magick", [ - withHeadshot, - titleWithStroke, - "-gravity", "north", - "-geometry", "+0+25", - "-composite", - withTitle, - ]); - - // Composite subtitle at bottom (inside border, below headshot zone) - await runCommand("magick", [ - withTitle, - subtitleWithStroke, - "-gravity", "south", - "-geometry", "+0+25", - "-composite", - withText, - ]); - - } else { - // LEFT or RIGHT: Create text in safe zone (NEVER overlap headshot) - - // Calculate text zone center (opposite side from headshot) - // Position at 62% or 38% of canvas width with generous margins - // Account for 16px border + compression during final resize - const textZoneCenter = args.headshotPosition === "left" - ? Math.round(LAYOUT.width * 0.62) // 794px - text on right with generous margin - : Math.round(LAYOUT.width * 0.38); // 486px - text on left with generous margin - - // Create title and subtitle with BILLBOARD sizing - const titleImg = `${outputDir}/.yt-title-${timestamp}.png`; - const subtitleImg = `${outputDir}/.yt-subtitle-${timestamp}.png`; - intermediates.push(titleImg, subtitleImg); - - // Create title - 100pt BILLBOARD text on WIDE canvas (prevents cutoff) - await runCommand("magick", [ - "-size", "1400x200", - "xc:transparent", - "-font", args.font!, - "-gravity", "center", - "-pointsize", String(LAYOUT.titleSize), - "-stroke", "#000000", "-strokewidth", String(LAYOUT.titleStroke), "-fill", "none", - "-annotate", "+0+0", args.title, - "-stroke", "none", "-fill", titleColorResolved, - "-annotate", "+0+0", args.title, - "-trim", "+repage", - titleImg, - ]); - - // Create subtitle - 50pt BILLBOARD text on WIDE canvas (prevents cutoff) - await runCommand("magick", [ - "-size", "1400x120", - "xc:transparent", - "-font", args.font!, - "-gravity", "center", - "-pointsize", String(LAYOUT.subtitleSize), - "-stroke", "#000000", "-strokewidth", String(LAYOUT.subtitleStroke), "-fill", "none", - "-annotate", "+0+0", args.subtitle, - "-stroke", "none", "-fill", subtitleColorResolved, - "-annotate", "+0+0", args.subtitle, - "-trim", "+repage", - subtitleImg, - ]); - - // Position text at center of text zone using absolute coordinates - // Composite title above center - const withTitle = `${outputDir}/.yt-with-title-${timestamp}.png`; - intermediates.push(withTitle); - - // Calculate absolute X position for centering in text zone - // We'll use page geometry to position at exact coordinates - // Larger fonts need more vertical spread - const titleY = Math.round(LAYOUT.height / 2) - 80; // Above center (for 100pt) - const subtitleY = Math.round(LAYOUT.height / 2) + 50; // Below center (for 50pt) - - await runCommand("magick", [ - withHeadshot, - titleImg, - "-gravity", "north", - "-geometry", `+${textZoneCenter - LAYOUT.width/2}+${titleY}`, - "-composite", - withTitle, - ]); - - // Composite subtitle below title - await runCommand("magick", [ - withTitle, - subtitleImg, - "-gravity", "north", - "-geometry", `+${textZoneCenter - LAYOUT.width/2}+${subtitleY}`, - "-composite", - withText, - ]); - } - - // Step 5: Add colored border - console.log(" 🖼️ Adding border..."); - await runCommand("magick", [ - withText, - "-bordercolor", args.borderColor!, - "-border", String(LAYOUT.borderWidth), - "-resize", `${LAYOUT.width}x${LAYOUT.height}!`, - args.output, - ]); - - console.log(`✅ Thumbnail saved to ${args.output}`); - - // Verify dimensions - const identify = await runCommand("magick", ["identify", "-format", "%wx%h", args.output]); - console.log(` 📏 Dimensions: ${identify.trim()}`); - - } finally { - // Cleanup intermediate files - for (const file of intermediates) { - try { - if (existsSync(file)) { - unlinkSync(file); - } - } catch { - // Ignore cleanup errors - } - } - } -} - -// ============================================================================ -// Main -// ============================================================================ - -async function main(): Promise { - try { - const args = parseArgs(process.argv.slice(2)); - await composeThumbnail(args); - } catch (error) { - if (error instanceof CLIError) { - console.error(`❌ Error: ${error.message}`); - process.exit(error.exitCode); - } - throw error; - } -} - -main(); diff --git a/.opencode/skills/Art/Tools/Generate.ts b/.opencode/skills/Art/Tools/Generate.ts deleted file mode 100755 index 7e8c8142..00000000 --- a/.opencode/skills/Art/Tools/Generate.ts +++ /dev/null @@ -1,724 +0,0 @@ -#!/usr/bin/env bun - -/** - * generate - UL Image Generation CLI - * - * Generate Unsupervised Learning branded images using Flux 1.1 Pro, Nano Banana, Nano Banana Pro, or GPT-image-1. - * Follows llcli pattern for deterministic, composable CLI design. - * - * Usage: - * generate --model nano-banana-pro --prompt "..." --size 16:9 --output /tmp/image.png - * - * @see ~/.opencode/skills/art/README.md - */ - -import Replicate from "replicate"; -import OpenAI from "openai"; -import { GoogleGenAI } from "@google/genai"; -import { writeFile, readFile } from "node:fs/promises"; -import { extname, resolve } from "node:path"; - -// ============================================================================ -// Environment Loading -// ============================================================================ - -/** - * Load environment variables from ${PAI_DIR}/.env - * This ensures API keys are available regardless of how the CLI is invoked - */ -async function loadEnv(): Promise { - const paiDir = process.env.PAI_DIR || resolve(process.env.HOME!, '.opencode'); - const envPath = resolve(paiDir, '.env'); - try { - const envContent = await readFile(envPath, 'utf-8'); - for (const line of envContent.split('\n')) { - const trimmed = line.trim(); - if (!trimmed || trimmed.startsWith('#')) continue; - const eqIndex = trimmed.indexOf('='); - if (eqIndex === -1) continue; - const key = trimmed.slice(0, eqIndex).trim(); - let value = trimmed.slice(eqIndex + 1).trim(); - // Remove surrounding quotes if present - if ((value.startsWith('"') && value.endsWith('"')) || - (value.startsWith("'") && value.endsWith("'"))) { - value = value.slice(1, -1); - } - // Only set if not already defined (allow overrides from shell) - if (!process.env[key]) { - process.env[key] = value; - } - } - } catch (error) { - // Silently continue if .env doesn't exist - rely on shell env vars - } -} - -// ============================================================================ -// Types -// ============================================================================ - -type Model = "flux" | "nano-banana" | "nano-banana-pro" | "gpt-image-1"; -type ReplicateSize = "1:1" | "16:9" | "3:2" | "2:3" | "3:4" | "4:3" | "4:5" | "5:4" | "9:16" | "21:9"; -type OpenAISize = "1024x1024" | "1536x1024" | "1024x1536"; -type GeminiSize = "1K" | "2K" | "4K"; -type Size = ReplicateSize | OpenAISize | GeminiSize; - -interface CLIArgs { - model: Model; - prompt: string; - size: Size; - output: string; - creativeVariations?: number; - aspectRatio?: ReplicateSize; // For Gemini models - transparent?: boolean; // Enable transparent background - referenceImages?: string[]; // Reference image paths (Nano Banana Pro only) - up to 14 total - removeBg?: boolean; // Remove background after generation using remove.bg API - addBg?: string; // Add background color (hex) to transparent image - thumbnail?: boolean; // Generate additional thumbnail with #EAE9DF background for social previews -} - -// ============================================================================ -// Configuration -// ============================================================================ - -const DEFAULTS = { - model: "flux" as Model, - size: "16:9" as Size, - output: `${process.env.HOME}/Downloads/ul-image.png`, -}; - -const REPLICATE_SIZES: ReplicateSize[] = ["1:1", "16:9", "3:2", "2:3", "3:4", "4:3", "4:5", "5:4", "9:16", "21:9"]; -const OPENAI_SIZES: OpenAISize[] = ["1024x1024", "1536x1024", "1024x1536"]; -const GEMINI_SIZES: GeminiSize[] = ["1K", "2K", "4K"]; - -// Aspect ratio mapping for Gemini (used with image size like 2K) -const GEMINI_ASPECT_RATIOS: ReplicateSize[] = ["1:1", "2:3", "3:2", "3:4", "4:3", "4:5", "5:4", "9:16", "16:9", "21:9"]; - -// ============================================================================ -// Error Handling -// ============================================================================ - -class CLIError extends Error { - constructor(message: string, public exitCode: number = 1) { - super(message); - this.name = "CLIError"; - } -} - -function handleError(error: unknown): never { - if (error instanceof CLIError) { - console.error(`❌ Error: ${error.message}`); - process.exit(error.exitCode); - } - - if (error instanceof Error) { - console.error(`❌ Unexpected error: ${error.message}`); - console.error(error.stack); - process.exit(1); - } - - console.error(`❌ Unknown error:`, error); - process.exit(1); -} - -// ============================================================================ -// Help Text -// ============================================================================ - -// PAI directory for documentation paths -const PAI_DIR = process.env.PAI_DIR || `${process.env.HOME}/.opencode`; - -function showHelp(): void { - console.log(` -generate - UL Image Generation CLI - -Generate Unsupervised Learning branded images using Flux 1.1 Pro, Nano Banana, or GPT-image-1. - -USAGE: - generate --model --prompt "" [OPTIONS] - -REQUIRED: - --model Model to use: flux, nano-banana, nano-banana-pro, gpt-image-1 - --prompt Image generation prompt (quote if contains spaces) - -OPTIONS: - --size Image size/aspect ratio (default: 16:9) - Replicate (flux, nano-banana): 1:1, 16:9, 3:2, 2:3, 3:4, 4:3, 4:5, 5:4, 9:16, 21:9 - OpenAI (gpt-image-1): 1024x1024, 1536x1024, 1024x1536 - Gemini (nano-banana-pro): 1K, 2K, 4K (resolution); aspect ratio inferred from context or defaults to 16:9 - --aspect-ratio Aspect ratio for Gemini nano-banana-pro (default: 16:9) - Options: 1:1, 2:3, 3:2, 3:4, 4:3, 4:5, 5:4, 9:16, 16:9, 21:9 - --output Output file path (default: /tmp/ul-image.png) - --reference-image Reference image for style/character consistency (Nano Banana Pro only) - Can specify MULTIPLE times for improved consistency - Accepts: PNG, JPEG, WebP images - API Limits: Up to 5 human refs, 6 object refs, 14 total max - --transparent Enable transparent background (adds transparency instructions to prompt) - Note: Not all models support transparency natively; may require post-processing - --remove-bg Remove background after generation using remove.bg API - Creates true transparency by removing the generated background - --add-bg Add background color to a transparent image (e.g., "#EAE9DF") - Useful for creating thumbnails/social previews from transparent images - --thumbnail Generate BOTH transparent AND thumbnail versions for blog headers - Creates: output.png (transparent) + output-thumb.png (#EAE9DF background) - Automatically enables --remove-bg - --creative-variations Generate N variations (appends -v1, -v2, etc. to output filename) - Use with the be-creative skill for true prompt diversity - CLI mode: generates N images with same prompt (tests model variability) - --help, -h Show this help message - -EXAMPLES: - # Generate blog header with Nano Banana Pro (16:9, 2K quality) - generate --model nano-banana-pro --prompt "Abstract UL illustration..." --size 2K --aspect-ratio 16:9 - - # Generate high-res 4K image with Nano Banana Pro - generate --model nano-banana-pro --prompt "Editorial cover..." --size 4K --aspect-ratio 3:2 - - # Generate blog header with original Nano Banana (16:9) - generate --model nano-banana --prompt "Abstract UL illustration..." --size 16:9 - - # Generate square image with Flux - generate --model flux --prompt "Minimal geometric art..." --size 1:1 --output /tmp/header.png - - # Generate portrait with GPT-image-1 - generate --model gpt-image-1 --prompt "Editorial cover..." --size 1024x1536 - - # Generate 3 creative variations (for testing model variability) - generate --model gpt-image-1 --prompt "..." --creative-variations 3 --output /tmp/essay.png - # Outputs: /tmp/essay-v1.png, /tmp/essay-v2.png, /tmp/essay-v3.png - - # Single reference image for style guidance (Nano Banana Pro only) - generate --model nano-banana-pro --prompt "Tokyo Night themed illustration..." \\ - --reference-image /tmp/style-reference.png --size 2K --aspect-ratio 16:9 - - # MULTIPLE reference images for character consistency (Nano Banana Pro only) - generate --model nano-banana-pro --prompt "Person from references at a party..." \\ - --reference-image face1.jpg --reference-image face2.jpg --reference-image face3.jpg \\ - --size 2K --aspect-ratio 16:9 - -NOTE: For true creative diversity with different prompts, use the creative workflow which -integrates the be-creative skill. CLI creative mode generates multiple images with the SAME prompt. - -MULTI-REFERENCE LIMITS (Gemini API): - - Up to 5 human reference images for character consistency - - Up to 6 object reference images - - Maximum 14 total reference images per request - -ENVIRONMENT VARIABLES: - REPLICATE_API_TOKEN Required for flux and nano-banana models - OPENAI_API_KEY Required for gpt-image-1 model - GOOGLE_API_KEY Required for nano-banana-pro model - REMOVEBG_API_KEY Required for --remove-bg flag - -ERROR CODES: - 0 Success - 1 General error (invalid arguments, API error, file write error) - -MORE INFO: - Documentation: ${PAI_DIR}/skills/Art/README.md - Source: ${PAI_DIR}/skills/Art/Tools/Generate.ts -`); - process.exit(0); -} - -// ============================================================================ -// Argument Parsing -// ============================================================================ - -function parseArgs(argv: string[]): CLIArgs { - const args = argv.slice(2); - - // Check for help flag - if (args.includes("--help") || args.includes("-h") || args.length === 0) { - showHelp(); - } - - const parsed: Partial = { - model: DEFAULTS.model, - size: DEFAULTS.size, - output: DEFAULTS.output, - }; - - // Collect reference images into array - const referenceImages: string[] = []; - - // Parse arguments - for (let i = 0; i < args.length; i++) { - const flag = args[i]; - - if (!flag.startsWith("--")) { - throw new CLIError(`Invalid flag: ${flag}. Flags must start with --`); - } - - const key = flag.slice(2); - - // Handle boolean flags (no value) - if (key === "transparent") { - parsed.transparent = true; - continue; - } - if (key === "remove-bg") { - parsed.removeBg = true; - continue; - } - if (key === "thumbnail") { - parsed.thumbnail = true; - parsed.removeBg = true; // Thumbnail mode requires remove-bg - continue; - } - - // Handle flags with values - const value = args[i + 1]; - if (!value || value.startsWith("--")) { - throw new CLIError(`Missing value for flag: ${flag}`); - } - - switch (key) { - case "model": - if (value !== "flux" && value !== "nano-banana" && value !== "nano-banana-pro" && value !== "gpt-image-1") { - throw new CLIError(`Invalid model: ${value}. Must be: flux, nano-banana, nano-banana-pro, or gpt-image-1`); - } - parsed.model = value; - i++; // Skip next arg (value) - break; - case "prompt": - parsed.prompt = value; - i++; // Skip next arg (value) - break; - case "size": - parsed.size = value as Size; - i++; // Skip next arg (value) - break; - case "aspect-ratio": - parsed.aspectRatio = value as ReplicateSize; - i++; // Skip next arg (value) - break; - case "output": - parsed.output = value; - i++; // Skip next arg (value) - break; - case "reference-image": - // Collect multiple reference images into array - referenceImages.push(value); - i++; // Skip next arg (value) - break; - case "creative-variations": - const variations = parseInt(value, 10); - if (isNaN(variations) || variations < 1 || variations > 10) { - throw new CLIError(`Invalid creative-variations: ${value}. Must be 1-10`); - } - parsed.creativeVariations = variations; - i++; // Skip next arg (value) - break; - case "add-bg": - // Validate hex color format - if (!/^#[0-9A-Fa-f]{6}$/.test(value)) { - throw new CLIError(`Invalid hex color: ${value}. Must be in format #RRGGBB (e.g., #EAE9DF)`); - } - parsed.addBg = value; - i++; // Skip next arg (value) - break; - default: - throw new CLIError(`Unknown flag: ${flag}`); - } - } - - // Assign collected reference images if any - if (referenceImages.length > 0) { - parsed.referenceImages = referenceImages; - } - - // Validate required arguments - if (!parsed.prompt) { - throw new CLIError("Missing required argument: --prompt"); - } - - if (!parsed.model) { - throw new CLIError("Missing required argument: --model"); - } - - // Validate reference-image is only used with nano-banana-pro - if (parsed.referenceImages && parsed.referenceImages.length > 0 && parsed.model !== "nano-banana-pro") { - throw new CLIError("--reference-image is only supported with --model nano-banana-pro"); - } - - // Validate reference image count (API limits: 5 human, 6 object, 14 total max) - if (parsed.referenceImages && parsed.referenceImages.length > 14) { - throw new CLIError(`Too many reference images: ${parsed.referenceImages.length}. Maximum is 14 total (5 human, 6 object)`); - } - - // Validate size based on model - if (parsed.model === "gpt-image-1") { - if (!OPENAI_SIZES.includes(parsed.size as OpenAISize)) { - throw new CLIError(`Invalid size for gpt-image-1: ${parsed.size}. Must be: ${OPENAI_SIZES.join(", ")}`); - } - } else if (parsed.model === "nano-banana-pro") { - if (!GEMINI_SIZES.includes(parsed.size as GeminiSize)) { - throw new CLIError(`Invalid size for nano-banana-pro: ${parsed.size}. Must be: ${GEMINI_SIZES.join(", ")}`); - } - // Validate aspect ratio if provided - if (parsed.aspectRatio && !GEMINI_ASPECT_RATIOS.includes(parsed.aspectRatio)) { - throw new CLIError(`Invalid aspect-ratio for nano-banana-pro: ${parsed.aspectRatio}. Must be: ${GEMINI_ASPECT_RATIOS.join(", ")}`); - } - // Default to 16:9 if not specified - if (!parsed.aspectRatio) { - parsed.aspectRatio = "16:9"; - } - } else { - if (!REPLICATE_SIZES.includes(parsed.size as ReplicateSize)) { - throw new CLIError(`Invalid size for ${parsed.model}: ${parsed.size}. Must be: ${REPLICATE_SIZES.join(", ")}`); - } - } - - return parsed as CLIArgs; -} - -// ============================================================================ -// Prompt Enhancement -// ============================================================================ - -function enhancePromptForTransparency(prompt: string): string { - const transparencyPrefix = "CRITICAL: Transparent background (PNG with alpha channel) - NO background color, pure transparency. Object floating in transparent space. "; - return transparencyPrefix + prompt; -} - -// ============================================================================ -// Background Removal -// ============================================================================ - -import { exec } from "node:child_process"; -import { promisify } from "node:util"; - -const execAsync = promisify(exec); - -// ============================================================================ -// Background Operations -// ============================================================================ - -/** - * Add a solid background color to a transparent PNG image - * Uses ImageMagick to composite the transparent image onto a colored background - */ -async function addBackgroundColor(inputPath: string, outputPath: string, hexColor: string): Promise { - console.log(`🎨 Adding background color ${hexColor} to image...`); - - // Use ImageMagick to composite the transparent image onto a colored background - // -background sets the fill color, -flatten composites onto that background - const command = `magick "${inputPath}" -background "${hexColor}" -flatten "${outputPath}"`; - - try { - await execAsync(command); - console.log(`✅ Thumbnail saved to ${outputPath}`); - } catch (error) { - throw new CLIError(`Failed to add background color: ${error instanceof Error ? error.message : String(error)}`); - } -} - -async function removeBackground(imagePath: string): Promise { - const apiKey = process.env.REMOVEBG_API_KEY; // pragma: allowlist secret - if (!apiKey) { - throw new CLIError("Missing environment variable: REMOVEBG_API_KEY"); - } - - console.log("🔲 Removing background with remove.bg API..."); - - const imageBuffer = await readFile(imagePath); - const formData = new FormData(); - formData.append("image_file", new Blob([imageBuffer]), "image.png"); - formData.append("size", "auto"); - - const response = await fetch("https://api.remove.bg/v1.0/removebg", { - method: "POST", - headers: { - "X-Api-Key": apiKey, - }, - body: formData, - }); - - if (!response.ok) { - const errorText = await response.text(); - throw new CLIError(`remove.bg API error: ${response.status} - ${errorText}`); - } - - const resultBuffer = Buffer.from(await response.arrayBuffer()); - await writeFile(imagePath, resultBuffer); - console.log("✅ Background removed successfully"); -} - -// ============================================================================ -// Image Generation -// ============================================================================ - -async function generateWithFlux(prompt: string, size: ReplicateSize, output: string): Promise { - const token = process.env.REPLICATE_API_TOKEN; // pragma: allowlist secret - if (!token) { - throw new CLIError("Missing environment variable: REPLICATE_API_TOKEN"); - } - - const replicate = new Replicate({ auth: token }); - - console.log("🎨 Generating with Flux 1.1 Pro..."); - - const result = await replicate.run("black-forest-labs/flux-1.1-pro", { - input: { - prompt, - aspect_ratio: size, - output_format: "png", - output_quality: 95, - prompt_upsampling: false, - }, - }); - - await writeFile(output, result); - console.log(`✅ Image saved to ${output}`); -} - -async function generateWithNanoBanana(prompt: string, size: ReplicateSize, output: string): Promise { - const token = process.env.REPLICATE_API_TOKEN; // pragma: allowlist secret - if (!token) { - throw new CLIError("Missing environment variable: REPLICATE_API_TOKEN"); - } - - const replicate = new Replicate({ auth: token }); - - console.log("🍌 Generating with Nano Banana..."); - - const result = await replicate.run("google/nano-banana", { - input: { - prompt, - aspect_ratio: size, - output_format: "png", - }, - }); - - await writeFile(output, result); - console.log(`✅ Image saved to ${output}`); -} - -async function generateWithGPTImage(prompt: string, size: OpenAISize, output: string): Promise { - const apiKey = process.env.OPENAI_API_KEY; // pragma: allowlist secret - if (!apiKey) { - throw new CLIError("Missing environment variable: OPENAI_API_KEY"); - } - - const openai = new OpenAI({ apiKey }); - - console.log("🤖 Generating with GPT-image-1..."); - - const response = await openai.images.generate({ - model: "gpt-image-1", - prompt, - size, - n: 1, - }); - - const imageData = response.data[0].b64_json; - if (!imageData) { - throw new CLIError("No image data returned from OpenAI API"); - } - - const imageBuffer = Buffer.from(imageData, "base64"); - await writeFile(output, imageBuffer); - console.log(`✅ Image saved to ${output}`); -} - -async function generateWithNanoBananaPro( - prompt: string, - size: GeminiSize, - aspectRatio: ReplicateSize, - output: string, - referenceImages?: string[] -): Promise { - const apiKey = process.env.GOOGLE_API_KEY; // pragma: allowlist secret - if (!apiKey) { - throw new CLIError("Missing environment variable: GOOGLE_API_KEY"); - } - - const ai = new GoogleGenAI({ apiKey }); - - if (referenceImages && referenceImages.length > 0) { - console.log(`🍌✨ Generating with Nano Banana Pro (Gemini 3 Pro) at ${size} ${aspectRatio} with ${referenceImages.length} reference image(s)...`); - } else { - console.log(`🍌✨ Generating with Nano Banana Pro (Gemini 3 Pro) at ${size} ${aspectRatio}...`); - } - - // Prepare content parts - const parts: Array<{ text?: string; inlineData?: { mimeType: string; data: string } }> = []; - - // Add all reference images if provided - if (referenceImages && referenceImages.length > 0) { - for (const referenceImage of referenceImages) { - // Read image file - const imageBuffer = await readFile(referenceImage); - const imageBase64 = imageBuffer.toString("base64"); - - // Determine MIME type from extension - const ext = extname(referenceImage).toLowerCase(); - let mimeType: string; - switch (ext) { - case ".png": - mimeType = "image/png"; - break; - case ".jpg": - case ".jpeg": - mimeType = "image/jpeg"; - break; - case ".webp": - mimeType = "image/webp"; - break; - default: - throw new CLIError(`Unsupported image format: ${ext}. Supported: .png, .jpg, .jpeg, .webp`); - } - - parts.push({ - inlineData: { - mimeType, - data: imageBase64, - }, - }); - } - } - - // Add text prompt - parts.push({ text: prompt }); - - const response = await ai.models.generateContent({ - model: "gemini-3-pro-image-preview", - contents: [{ parts }], - config: { - responseModalities: ["TEXT", "IMAGE"], - imageConfig: { - aspectRatio: aspectRatio, - imageSize: size, - }, - }, - }); - - // Extract image data from response - let imageData: string | undefined; - - if (response.candidates && response.candidates.length > 0) { - const parts = response.candidates[0].content.parts; - for (const part of parts) { - // Check if this part contains inline image data - if (part.inlineData && part.inlineData.data) { - imageData = part.inlineData.data; - break; - } - } - } - - if (!imageData) { - throw new CLIError("No image data returned from Gemini API"); - } - - const imageBuffer = Buffer.from(imageData, "base64"); - await writeFile(output, imageBuffer); - console.log(`✅ Image saved to ${output}`); -} - -// ============================================================================ -// Main -// ============================================================================ - -async function main(): Promise { - try { - // Load API keys from ${PAI_DIR}/.env - await loadEnv(); - - const args = parseArgs(process.argv); - - // Enhance prompt for transparency if requested - const finalPrompt = args.transparent - ? enhancePromptForTransparency(args.prompt) - : args.prompt; - - if (args.transparent) { - console.log("🔲 Transparent background mode enabled"); - console.log("💡 Note: Not all models support transparency natively; may require post-processing\n"); - } - - // Handle creative variations mode - if (args.creativeVariations && args.creativeVariations > 1) { - console.log(`🎨 Creative Mode: Generating ${args.creativeVariations} variations...`); - console.log(`💡 Note: CLI mode uses same prompt for all variations (tests model variability)`); - console.log(` For true creative diversity, use the creative workflow with be-creative skill\n`); - - const basePath = args.output.replace(/\.png$/, ""); - const promises: Promise[] = []; - - for (let i = 1; i <= args.creativeVariations; i++) { - const varOutput = `${basePath}-v${i}.png`; - console.log(`Variation ${i}/${args.creativeVariations}: ${varOutput}`); - - if (args.model === "flux") { - promises.push(generateWithFlux(finalPrompt, args.size as ReplicateSize, varOutput)); - } else if (args.model === "nano-banana") { - promises.push(generateWithNanoBanana(finalPrompt, args.size as ReplicateSize, varOutput)); - } else if (args.model === "nano-banana-pro") { - promises.push( - generateWithNanoBananaPro( - finalPrompt, - args.size as GeminiSize, - args.aspectRatio!, - varOutput, - args.referenceImages - ) - ); - } else if (args.model === "gpt-image-1") { - promises.push(generateWithGPTImage(finalPrompt, args.size as OpenAISize, varOutput)); - } - } - - await Promise.all(promises); - console.log(`\n✅ Generated ${args.creativeVariations} variations`); - return; - } - - // Standard single image generation - if (args.model === "flux") { - await generateWithFlux(finalPrompt, args.size as ReplicateSize, args.output); - } else if (args.model === "nano-banana") { - await generateWithNanoBanana(finalPrompt, args.size as ReplicateSize, args.output); - } else if (args.model === "nano-banana-pro") { - await generateWithNanoBananaPro( - finalPrompt, - args.size as GeminiSize, - args.aspectRatio!, - args.output, - args.referenceImages - ); - } else if (args.model === "gpt-image-1") { - await generateWithGPTImage(finalPrompt, args.size as OpenAISize, args.output); - } - - // Remove background if requested - if (args.removeBg) { - await removeBackground(args.output); - } - - // Add background color if requested (standalone mode) - if (args.addBg && !args.thumbnail) { - // For standalone --add-bg, modify the image in place - const tempPath = args.output.replace(/\.png$/, "-temp.png"); - await addBackgroundColor(args.output, tempPath, args.addBg); - // Replace original with the one with background - const { rename } = await import("node:fs/promises"); - await rename(tempPath, args.output); - } - - // Generate thumbnail with background color if requested (blog header mode) - if (args.thumbnail) { - const thumbPath = args.output.replace(/\.png$/, "-thumb.png"); - const THUMBNAIL_BG_COLOR = "#EAE9DF"; // UL brand background color for social previews - await addBackgroundColor(args.output, thumbPath, THUMBNAIL_BG_COLOR); - console.log(`\n📸 Blog header mode: Created both versions`); - console.log(` Transparent: ${args.output}`); - console.log(` Thumbnail: ${thumbPath}`); - } - } catch (error) { - handleError(error); - } -} - -main(); diff --git a/.opencode/skills/Art/Tools/GenerateMidjourneyImage.ts b/.opencode/skills/Art/Tools/GenerateMidjourneyImage.ts deleted file mode 100755 index 5ec78343..00000000 --- a/.opencode/skills/Art/Tools/GenerateMidjourneyImage.ts +++ /dev/null @@ -1,372 +0,0 @@ -#!/usr/bin/env bun - -/** - * generate-midjourney-image - Midjourney Image Generation CLI - * - * Generate images using Midjourney via Discord bot integration. - * Follows llcli pattern for deterministic, composable CLI design. - * - * Usage: - * generate-midjourney-image --prompt "..." --aspect-ratio 16:9 --output /tmp/image.png - * - * @see ~/.opencode/skills/art/SKILL.md - */ - -import { DiscordBotClient } from '../lib/discord-bot.js'; -import { MidjourneyClient, MidjourneyError } from '../lib/midjourney-client.js'; -import { readFile } from 'node:fs/promises'; -import { resolve } from 'node:path'; - -// ============================================================================ -// Environment Loading -// ============================================================================ - -/** - * Load environment variables from ${PAI_DIR}/.env - * This ensures API keys are available regardless of how the CLI is invoked - */ -async function loadEnv(): Promise { - const paiDir = process.env.PAI_DIR || resolve(process.env.HOME!, '.opencode'); - const envPath = resolve(paiDir, '.env'); - try { - const envContent = await readFile(envPath, 'utf-8'); - for (const line of envContent.split('\n')) { - const trimmed = line.trim(); - if (!trimmed || trimmed.startsWith('#')) continue; - const eqIndex = trimmed.indexOf('='); - if (eqIndex === -1) continue; - const key = trimmed.slice(0, eqIndex).trim(); - let value = trimmed.slice(eqIndex + 1).trim(); - // Remove surrounding quotes if present - if ((value.startsWith('"') && value.endsWith('"')) || - (value.startsWith("'") && value.endsWith("'"))) { - value = value.slice(1, -1); - } - // Only set if not already defined (allow overrides from shell) - if (!process.env[key]) { - process.env[key] = value; - } - } - } catch (error) { - // Silently continue if .env doesn't exist - rely on shell env vars - } -} - -// ============================================================================ -// Types -// ============================================================================ - -interface CLIArgs { - prompt: string; - aspectRatio: string; - version: string; - stylize: number; - quality: number; - chaos?: number; - weird?: number; - tile: boolean; - output: string; - timeout: number; -} - -// ============================================================================ -// Configuration -// ============================================================================ - -const DEFAULTS = { - aspectRatio: '16:9', - version: process.env.MIDJOURNEY_DEFAULT_VERSION || '6.1', - stylize: parseInt(process.env.MIDJOURNEY_DEFAULT_STYLIZE || '100'), - quality: parseInt(process.env.MIDJOURNEY_DEFAULT_QUALITY || '1'), - tile: false, - output: '/tmp/midjourney-image.png', - timeout: 120, -}; - -// ============================================================================ -// Error Handling -// ============================================================================ - -class CLIError extends Error { - constructor(message: string, public exitCode: number = 1) { - super(message); - this.name = 'CLIError'; - } -} - -function handleError(error: unknown): never { - if (error instanceof MidjourneyError) { - console.error(`\n❌ Midjourney Error: ${error.message}`); - console.error(` Type: ${error.type}`); - if (error.originalPrompt) { - console.error(` Prompt: ${error.originalPrompt}`); - } - if (error.suggestion) { - console.error(` Suggestion: ${error.suggestion}`); - } - process.exit(1); - } - - if (error instanceof CLIError) { - console.error(`❌ Error: ${error.message}`); - process.exit(error.exitCode); - } - - if (error instanceof Error) { - console.error(`❌ Unexpected error: ${error.message}`); - console.error(error.stack); - process.exit(1); - } - - console.error(`❌ Unknown error:`, error); - process.exit(1); -} - -// ============================================================================ -// Help Text -// ============================================================================ - -function showHelp(): void { - console.log(` -generate-midjourney-image - Midjourney Image Generation CLI - -Generate images using Midjourney via Discord bot integration. - -USAGE: - generate-midjourney-image --prompt "" [OPTIONS] - -REQUIRED: - --prompt Image generation prompt (quote if contains spaces) - -OPTIONS: - --aspect-ratio Aspect ratio (default: 16:9) - Valid: 1:1, 16:9, 9:16, 2:3, 3:2, 4:5, 5:4, 7:4, 4:7, 21:9, 9:21, 3:4, 4:3 - --version Midjourney version (default: ${DEFAULTS.version}) - Valid: 6.1, 6, 5.2, 5.1, 5, niji, niji 6 - --stylize Stylization 0-1000 (default: ${DEFAULTS.stylize}) - --quality Quality: 0.25, 0.5, 1, 2 (default: ${DEFAULTS.quality}) - --chaos Chaos 0-100 (optional) - --weird Weird 0-3000 (optional) - --tile Enable tiling mode (default: false) - --output Output file path (default: ${DEFAULTS.output}) - --timeout Max wait time (default: ${DEFAULTS.timeout}) - -ENVIRONMENT VARIABLES: - DISCORD_BOT_TOKEN Discord bot token (required) - MIDJOURNEY_CHANNEL_ID Channel ID for Midjourney (required) - MIDJOURNEY_DEFAULT_VERSION Default Midjourney version - MIDJOURNEY_DEFAULT_QUALITY Default quality setting - MIDJOURNEY_DEFAULT_STYLIZE Default stylize setting - -EXAMPLES: - # Standard blog header - generate-midjourney-image \\ - --prompt "abstract flowing data streams, minimal shapes, Tokyo Night colors" \\ - --aspect-ratio 16:9 \\ - --output /tmp/header.png - - # High quality square image - generate-midjourney-image \\ - --prompt "geometric network visualization, abstract tech concept" \\ - --aspect-ratio 1:1 \\ - --quality 2 \\ - --output /tmp/square.png - - # Creative with high stylization - generate-midjourney-image \\ - --prompt "flowing organic shapes, data visualization" \\ - --stylize 500 \\ - --weird 1000 -`); -} - -// ============================================================================ -// Argument Parsing -// ============================================================================ - -function parseArgs(args: string[]): CLIArgs { - const result: Partial = { - aspectRatio: DEFAULTS.aspectRatio, - version: DEFAULTS.version, - stylize: DEFAULTS.stylize, - quality: DEFAULTS.quality, - tile: DEFAULTS.tile, - output: DEFAULTS.output, - timeout: DEFAULTS.timeout, - }; - - for (let i = 0; i < args.length; i++) { - const arg = args[i]; - - switch (arg) { - case '--help': - case '-h': - showHelp(); - process.exit(0); - break; - - case '--prompt': - result.prompt = args[++i]; - break; - - case '--aspect-ratio': - case '--ar': - result.aspectRatio = args[++i]; - break; - - case '--version': - case '-v': - result.version = args[++i]; - break; - - case '--stylize': - case '-s': - result.stylize = parseInt(args[++i]); - break; - - case '--quality': - case '-q': - result.quality = parseFloat(args[++i]); - break; - - case '--chaos': - result.chaos = parseInt(args[++i]); - break; - - case '--weird': - result.weird = parseInt(args[++i]); - break; - - case '--tile': - result.tile = true; - break; - - case '--output': - case '-o': - result.output = args[++i]; - break; - - case '--timeout': - result.timeout = parseInt(args[++i]); - break; - - default: - throw new CLIError(`Unknown argument: ${arg}`); - } - } - - // Validate required args - if (!result.prompt) { - throw new CLIError('Missing required argument: --prompt'); - } - - return result as CLIArgs; -} - -// ============================================================================ -// Main -// ============================================================================ - -async function main() { - try { - // Load API keys from ${PAI_DIR}/.env - await loadEnv(); - - // Parse arguments - const args = parseArgs(process.argv.slice(2)); - - // Validate environment variables - const botToken = process.env.DISCORD_BOT_TOKEN; // pragma: allowlist secret - const channelId = process.env.MIDJOURNEY_CHANNEL_ID; - - if (!botToken) { - throw new CLIError( - 'Missing DISCORD_BOT_TOKEN environment variable. Add it to ${PAI_DIR}/.env' - ); - } - - if (!channelId) { - throw new CLIError( - 'Missing MIDJOURNEY_CHANNEL_ID environment variable. Add it to ${PAI_DIR}/.env' - ); - } - - // Validate Midjourney options - MidjourneyClient.validateOptions({ - prompt: args.prompt, - aspectRatio: args.aspectRatio, - version: args.version, - stylize: args.stylize, - quality: args.quality, - chaos: args.chaos, - weird: args.weird, - tile: args.tile, - timeout: args.timeout, - }); - - console.log('🤖 Midjourney Image Generation'); - console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'); - console.log(`Prompt: ${args.prompt}`); - console.log(`Aspect Ratio: ${args.aspectRatio}`); - console.log(`Version: ${args.version}`); - console.log(`Stylize: ${args.stylize}`); - console.log(`Quality: ${args.quality}`); - if (args.chaos) console.log(`Chaos: ${args.chaos}`); - if (args.weird) console.log(`Weird: ${args.weird}`); - if (args.tile) console.log(`Tile: enabled`); - console.log(`Output: ${args.output}`); - console.log(`Timeout: ${args.timeout}s`); - console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n'); - - // Initialize Discord bot - const discordBot = new DiscordBotClient({ - token: botToken, - channelId: channelId, - }); - - // Initialize Midjourney client - const midjourneyClient = new MidjourneyClient(discordBot); - - try { - // Connect to Discord - await discordBot.connect(); - - // Generate image - const result = await midjourneyClient.generateImage({ - prompt: args.prompt, - aspectRatio: args.aspectRatio, - version: args.version, - stylize: args.stylize, - quality: args.quality, - chaos: args.chaos, - weird: args.weird, - tile: args.tile, - timeout: args.timeout, - }); - - // Download image - await discordBot.downloadImage(result.imageUrl, args.output); - - console.log('\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'); - console.log('✅ Success!'); - console.log(` Image URL: ${result.imageUrl}`); - console.log(` Saved to: ${args.output}`); - console.log(` Message ID: ${result.messageId}`); - console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n'); - - // Disconnect - await discordBot.disconnect(); - - process.exit(0); - } catch (error) { - // Ensure we disconnect even on error - await discordBot.disconnect(); - throw error; - } - } catch (error) { - handleError(error); - } -} - -// Run -main(); diff --git a/.opencode/skills/Art/Tools/GeneratePrompt.ts b/.opencode/skills/Art/Tools/GeneratePrompt.ts deleted file mode 100755 index eff25340..00000000 --- a/.opencode/skills/Art/Tools/GeneratePrompt.ts +++ /dev/null @@ -1,451 +0,0 @@ -#!/usr/bin/env bun - -/** - * UL Abstract Illustration Prompt Generator - * - * ⚠️ DEPRECATED - THIS TOOL USES OLD CHARACTER-BASED SYSTEM - * ⚠️ NEEDS COMPLETE REWRITE FOR ABSTRACT SHAPES/IMPRESSIONS ONLY - * ⚠️ DO NOT USE UNTIL UPDATED - * - * This tool needs to be rewritten to generate prompts using: - * - Abstract shapes and forms (NO characters) - * - Visual motifs (networks, flows, structures, horizons) - * - Composition approaches (centered, horizon, flow, opposition, layered) - * - * Usage (when updated): - * bun run generate-prompt.ts --input essay.md --type essay-illustration - * bun run generate-prompt.ts --input essay.md --type blog-header --format json - */ - -import { readFileSync } from "node:fs"; -import { resolve } from "node:path"; - -// ============================================================================ -// Types -// ============================================================================ - -type CompositionType = "observation" | "horizon" | "dialogue" | "workshop" | "aura"; -type CharacterFocus = "maya" | "kai" | "both"; -type TokyoNightColor = - | "Electric Blue" - | "Vivid Purple" - | "Bright Cyan" - | "Neon Green" - | "Warm Yellow" - | "Soft Magenta"; -type Human3Motif = "agents" | "networks" | "aura" | "substrates" | "horizons" | "ts_stacks"; -type BackgroundType = "sepia" | "dark_tokyo_night"; -type OutputFormat = "text" | "json"; - -interface PromptConfig { - essayTheme: string; - characterFocus: CharacterFocus; - compositionType: CompositionType; - emotionalToneDescription: string; - coreObjectDescription: string; - overallMood: string; - accentColors: TokyoNightColor[]; - human3Motifs: Human3Motif[]; - backgroundType: BackgroundType; - imageType: "essay-illustration" | "blog-header"; -} - -interface PromptOutput { - essay_theme: string; - character_focus: CharacterFocus; - composition_type: CompositionType; - emotional_tone_description: string; - core_object_description: string; - overall_mood: string; - accent_colors: string[]; - human3_motifs: string[]; - image_prompt: string; - suggested_filename?: string; -} - -// ============================================================================ -// Constants -// ============================================================================ - -// Note: This tool is deprecated and needs rewriting for abstract shapes/impressions - -const COLOR_HEX_MAP: Record = { - "Electric Blue": "#7aa2f7", - "Vivid Purple": "#bb9af7", - "Bright Cyan": "#7dcfff", - "Neon Green": "#9ece6a", - "Warm Yellow": "#e0af68", - "Soft Magenta": "#ff007c", -}; - -const CHARACTER_DESCRIPTIONS = { - maya: `Maya is a young, highly curious girl with a round head, simple short hair, and big round glasses (her signature feature). She has a stick-figure body with thin limbs and a slightly oversized head, with minimal facial features (dots for eyes, simple line for mouth when needed).`, - kai: `Kai is a young boy with a slightly oval head, a soft messy hair tuft on top (his signature feature), and NO glasses. He wears a simple t-shirt and shorts or pants. He has a stick-figure body with thin limbs and a slightly oversized head, with minimal facial features.`, - both: `Two recurring child characters: Maya and Kai. Maya is a young, highly curious girl with a round head, simple short hair, and big round glasses. Kai is a young boy with a slightly oval head, a soft messy hair tuft, and a simple t-shirt and shorts or pants. Both have stick-figure bodies with thin limbs and slightly oversized heads, with minimal facial features.`, -}; - -// ============================================================================ -// Helpers -// ============================================================================ - -function parseArgs(): { - input: string; - type: "essay-illustration" | "blog-header"; - format: OutputFormat; - composition?: CompositionType; - character?: CharacterFocus; - colors?: string; - motifs?: string; -} { - const args = process.argv.slice(2); - const parsed: any = { - type: "essay-illustration", - format: "text", - }; - - for (let i = 0; i < args.length; i += 2) { - const key = args[i].replace(/^--/, ""); - const value = args[i + 1]; - parsed[key] = value; - } - - return parsed; -} - -function readEssayContent(path: string): string { - try { - return readFileSync(path, "utf-8"); - } catch (error) { - console.error(`Error reading essay file: ${path}`); - throw error; - } -} - -function analyzeContent(essayContent: string): { - theme: string; - tone: string; - metaphors: string[]; - concepts: string[]; -} { - // Simple content analysis - // In a production version, this could use more sophisticated NLP or LLM analysis - - const lines = essayContent.split("\n"); - const firstParagraph = lines.slice(0, 5).join(" "); - - // Extract title (first # line) - const titleLine = lines.find((line) => line.startsWith("# ")); - const theme = titleLine?.replace(/^# /, "") || "essay topic"; - - // Simple tone detection based on keywords - const contentLower = essayContent.toLowerCase(); - let tone = "analytical curiosity"; - - if (contentLower.includes("future") || contentLower.includes("possibility")) { - tone = "cautious wonder about future possibilities"; - } else if (contentLower.includes("build") || contentLower.includes("create")) { - tone = "collaborative optimism"; - } else if (contentLower.includes("problem") || contentLower.includes("challenge")) { - tone = "analytical focus on challenges and opportunities"; - } - - return { - theme, - tone, - metaphors: [], // Could be extracted with more sophisticated analysis - concepts: [], // Could be extracted with more sophisticated analysis - }; -} - -function selectComposition( - essayContent: string, - override?: CompositionType -): CompositionType { - if (override) return override; - - const contentLower = essayContent.toLowerCase(); - - if (contentLower.includes("future") || contentLower.includes("horizon")) { - return "horizon"; - } else if (contentLower.includes("together") || contentLower.includes("collaborate")) { - return "dialogue"; - } else if (contentLower.includes("build") || contentLower.includes("create")) { - return "workshop"; - } else if (contentLower.includes("personal") || contentLower.includes("context")) { - return "aura"; - } - - return "observation"; // Default -} - -function selectCharacter( - compositionType: CompositionType, - override?: CharacterFocus -): CharacterFocus { - if (override) return override; - - if (compositionType === "dialogue") return "both"; - if (compositionType === "workshop") return "kai"; - if (compositionType === "observation") return "maya"; - - return "both"; // Default -} - -function selectColors( - essayContent: string, - override?: string -): TokyoNightColor[] { - if (override) { - return override.split(",").map((c) => c.trim() as TokyoNightColor); - } - - const contentLower = essayContent.toLowerCase(); - - if (contentLower.includes("security") || contentLower.includes("privacy")) { - return ["Vivid Purple"]; - } else if (contentLower.includes("tool") || contentLower.includes("productivity")) { - return ["Bright Cyan"]; - } else if (contentLower.includes("human") || contentLower.includes("growth")) { - return ["Neon Green"]; - } - - return ["Electric Blue"]; // Default for AI/tech -} - -function selectMotifs( - essayContent: string, - override?: string -): Human3Motif[] { - if (override) { - return override.split(",").map((m) => m.trim() as Human3Motif); - } - - const motifs: Human3Motif[] = []; - const contentLower = essayContent.toLowerCase(); - - if (contentLower.includes("agent") || contentLower.includes("ai")) { - motifs.push("agents"); - } - if (contentLower.includes("network") || contentLower.includes("connect")) { - motifs.push("networks"); - } - if (contentLower.includes("future") || contentLower.includes("horizon")) { - motifs.push("horizons"); - } - if (contentLower.includes("personal") || contentLower.includes("context")) { - motifs.push("aura"); - } - - return motifs.slice(0, 2); // Max 2 motifs -} - -function buildVisualMetaphor( - essayContent: string, - compositionType: CompositionType, - characterFocus: CharacterFocus -): string { - // This is a simplified version. In production, this would use more sophisticated - // content analysis to generate specific visual metaphors from essay content. - - const analysis = analyzeContent(essayContent); - - let metaphor = ""; - - switch (compositionType) { - case "observation": - metaphor = `${characterFocus === "maya" ? "Maya" : "Kai"} positioned in the left quarter of the frame, small and observing with ${analysis.tone}, looking at a large visual element on the right that represents the core concept of ${analysis.theme}`; - break; - case "horizon": - metaphor = `${characterFocus === "both" ? "Maya and Kai" : characterFocus === "maya" ? "Maya" : "Kai"} in the foreground, facing a wide distant horizon filled with tiny elements representing future possibilities related to ${analysis.theme}`; - break; - case "dialogue": - metaphor = `Maya and Kai positioned with space between them, interacting with a shared element or concept in the center, representing different perspectives on ${analysis.theme}`; - break; - case "workshop": - metaphor = `${characterFocus === "kai" ? "Kai" : "Both Maya and Kai"} actively building or creating, with elements spreading horizontally showing the process of making something related to ${analysis.theme}`; - break; - case "aura": - metaphor = `${characterFocus === "maya" ? "Maya" : characterFocus === "kai" ? "Kai" : "The character"} surrounded by a soft, translucent aura bubble containing tiny symbolic icons representing aspects of ${analysis.theme}`; - break; - } - - return metaphor; -} - -function buildMotifsDescription(motifs: Human3Motif[]): string { - if (motifs.length === 0) return ""; - - const descriptions: string[] = []; - - for (const motif of motifs) { - switch (motif) { - case "agents": - descriptions.push("tiny cute pill-shaped agent robots"); - break; - case "networks": - descriptions.push("thin network lines connecting small nodes"); - break; - case "aura": - descriptions.push( - "soft aura bubbles around people or robots with tiny symbolic icons like hearts, book-shapes, leaves, or stars (icons must be purely visual and contain no letters or numbers)" - ); - break; - case "substrates": - descriptions.push("horizontal platform layers suggesting infrastructure"); - break; - case "horizons": - descriptions.push("distant horizon line filled with tiny silhouettes"); - break; - case "ts_stacks": - descriptions.push("stacks of thin blank rectangular sheets"); - break; - } - } - - return `Optionally include Human 3.0 motifs that fit the essay: ${descriptions.join(", ")}.`; -} - -// ============================================================================ -// Prompt Generation -// ============================================================================ - -function generatePrompt(config: PromptConfig): string { - const { - essayTheme, - characterFocus, - compositionType, - emotionalToneDescription, - coreObjectDescription, - overallMood, - accentColors, - human3Motifs, - backgroundType, - imageType, - } = config; - - // Build color description - const colorDescriptions = accentColors - .map((color) => `${color} ${COLOR_HEX_MAP[color]}`) - .join(" and "); - - // Build character descriptions - const characterDesc = CHARACTER_DESCRIPTIONS[characterFocus]; - - // Build motifs description - const motifsDesc = buildMotifsDescription(human3Motifs); - - // Background description - const backgroundDesc = - backgroundType === "sepia" - ? "Soft sepia-toned paper background with lots of empty space." - : "Dark gradient background transitioning from #1a1b26 to #24283b."; - - // Base prompt - let prompt = `Minimal Tokyo Night–inspired illustration for ${imageType === "blog-header" ? "an Unsupervised Learning blog post" : "an essay"} about ${essayTheme}. - -${backgroundDesc} Thin, slightly imperfect deep navy linework and flat color fills only, no shading. Tokyo Night–inspired accent color${accentColors.length > 1 ? "s" : ""} ${colorDescriptions} used sparingly. - -${characterDesc} - -Show ${characterFocus === "both" ? "Maya and Kai" : characterFocus} in a ${compositionType} scene${imageType === "blog-header" ? " optimized for horizontal 16:9 composition" : ""}. ${emotionalToneDescription.charAt(0).toUpperCase() + emotionalToneDescription.slice(1)}, interacting with ${coreObjectDescription}. - -${motifsDesc} - -The overall mood should be ${overallMood}. No text, no letters, no numbers, and no labels anywhere in the image.`; - - // Add blog header specifications if applicable - if (imageType === "blog-header") { - prompt += ` - -=== BLOG HEADER SPECIFICATIONS === - -Output format: PNG, 1536x1024 (16:9 landscape for blog header) -Horizontal composition optimized for wide format -Primary focus in upper two-thirds of frame -Maximum quality settings (95% quality) -Editorial cover image quality like The Atlantic or New Yorker or New York Times`; - } - - return prompt; -} - -// ============================================================================ -// Main -// ============================================================================ - -function main() { - const args = parseArgs(); - - if (!args.input) { - console.error("Usage: bun run generate-prompt.ts --input [options]"); - console.error("\nOptions:"); - console.error(" --type essay-illustration | blog-header (default: essay-illustration)"); - console.error(" --format text | json (default: text)"); - console.error(" --composition observation | horizon | dialogue | workshop | aura"); - console.error(" --character maya | kai | both"); - console.error(' --colors "Electric Blue,Neon Green" (comma-separated)'); - console.error(' --motifs "agents,networks" (comma-separated)'); - process.exit(1); - } - - // Read essay content - const essayContent = readEssayContent(args.input); - - // Analyze content - const analysis = analyzeContent(essayContent); - - // Select visual elements - const compositionType = selectComposition(essayContent, args.composition); - const characterFocus = selectCharacter(compositionType, args.character); - const accentColors = selectColors(essayContent, args.colors); - const human3Motifs = selectMotifs(essayContent, args.motifs); - - // Build visual metaphor - const coreObjectDescription = buildVisualMetaphor( - essayContent, - compositionType, - characterFocus - ); - - // Build config - const config: PromptConfig = { - essayTheme: analysis.theme, - characterFocus, - compositionType, - emotionalToneDescription: `They are ${analysis.tone}`, - coreObjectDescription, - overallMood: analysis.tone.split(" ").slice(0, 2).join(" "), // Simplified mood - accentColors, - human3Motifs, - backgroundType: "sepia", - imageType: args.type, - }; - - // Generate prompt - const imagePrompt = generatePrompt(config); - - // Output - if (args.format === "json") { - const output: PromptOutput = { - essay_theme: analysis.theme, - character_focus: characterFocus, - composition_type: compositionType, - emotional_tone_description: config.emotionalToneDescription, - core_object_description: coreObjectDescription, - overall_mood: config.overallMood, - accent_colors: accentColors, - human3_motifs: human3Motifs, - image_prompt: imagePrompt, - suggested_filename: analysis.theme - .toLowerCase() - .replace(/[^a-z0-9]+/g, "-") - .replace(/^-|-$/g, "") + ".png", - }; - - console.log(JSON.stringify(output, null, 2)); - } else { - console.log(imagePrompt); - } -} - -main(); diff --git a/.opencode/skills/Art/Workflows/AdHocYouTubeThumbnail.md b/.opencode/skills/Art/Workflows/AdHocYouTubeThumbnail.md deleted file mode 100755 index c8ca2eb7..00000000 --- a/.opencode/skills/Art/Workflows/AdHocYouTubeThumbnail.md +++ /dev/null @@ -1,343 +0,0 @@ -# Ad-hoc YouTube Thumbnail Workflow - -Generate complete YouTube thumbnails from content input with dramatic tech backgrounds and AI-generated headshots. - -## Explicit Criteria - -### 1. Dynamic Headshot - FACE ONLY -- **Fresh AI-generated** each time using Nano Banana Pro with reference images -- Reference image is used for likeness, NOT the actual headshot -- **Position is dynamic**: left, center, or right (based on content/preference) -- **🚨 FACE ONLY**: Forehead to chin, ear to ear - **NO shoulders, NO neck, NO body** -- Face fills 95% of the image area (ComposeThumbnail auto-crops) -- **Transparent background**: Must run RemoveBg after generation -- **🚨 MUST VARY** between thumbnails (see Variation Requirements below) - -### 2. Dramatic Tech Background -- **Style**: Futuristic, sci-fi aesthetic (hexagonal circuits, glowing edges, 3D depth) -- **Colors**: Dark with cyan/blue/purple neon accents (Tokyo Night palette) -- **No text, no people** in the background - pure abstract tech art -- **Examples**: Blade Runner, Tron, circuit board patterns with glow - -### 3. Text - BILLBOARD STYLE -- **Title**: Up to 6 words, CAPITALIZED, **CYAN** by default (vibrant, not white) -- **Subtitle**: Up to 12 words, CAPITALIZED, white text -- **🚨 TEXT FILLS THE SPACE** - takes up most of available area opposite headshot -- **BOLD STROKE OUTLINE** (4px title, 3px subtitle) - visible at 320px thumbnail size -- **Visually centered** in safe zone (NEVER overlaps headshot) -- **Grouped as a unit** - title and subtitle together as text block - -### 4. Colored Border -- **Tokyo Night purple** (#bb9af7) default -- **16px width** around entire thumbnail -- Creates professional framing - ---- - -## Output Specifications - -| Element | Value | -|---------|-------| -| Canvas | 1280x720 px | -| Border | **16px** #bb9af7 (Tokyo Night purple) | -| Headshot | **FACE ONLY** (~688px height), auto-cropped (no shoulders/body) | -| Title | **100pt** Helvetica-Bold, **4px** black stroke outline | -| Subtitle | **50pt** Helvetica-Bold, **3px** black stroke outline | -| Title color | **CYAN (#7dcfff) by default** - NEVER plain white | -| Subtitle color | White (#FFFFFF) for contrast | -| Text position | **FILLS** safe zone opposite headshot (NEVER overlaps) | -| Background | Dramatic futuristic tech art | -| Fresh headshot | **MANDATORY** - generate new WITH VARIATION each time | -| 320x180 test | **MANDATORY** - must be readable at YouTube grid size | - -### Text Color Presets (--title-color, --subtitle-color) - -| Name | Hex | Use | -|------|-----|-----| -| cyan | #7dcfff | **DEFAULT** - Tech, futuristic | -| white | #FFFFFF | High contrast (subtitle default) | -| purple | #bb9af7 | Matches border | -| blue | #7aa2f7 | Professional | -| magenta | #ff007c | Bold, attention | -| yellow | #e0af68 | Warning, highlight | -| green | #9ece6a | Success, growth | -| orange | #ff9e64 | Energy, urgency | -| red | #f7768e | Alert, danger | - ---- - -## Step 1: Content Analysis - -**Extract title and subtitle from input content.** - -### Input Types -- Script or article text -- URL (fetch and analyze) -- Topic description -- Video outline - -### Extraction Prompt - -``` -Analyze this content and extract: - -1. TITLE (max 6 words): The attention-grabbing hook -2. SUBTITLE (max 12 words): The value promise or context - -Guidelines: -- Use power words: "SECRET", "HIDDEN", "REAL", "TRUTH", "WHY", "HOW" -- Create curiosity gaps -- Be specific over generic -- Make a bold claim or promise - -Content: [INPUT] -``` - ---- - -## Step 2: Background Generation - -**Generate dramatic futuristic tech background.** - -### Background Prompt Template - -``` -Dramatic futuristic technology background. Dark hexagonal circuit board pattern -with glowing cyan/blue neon edge lighting. 3D depth perspective. Metallic dark -grey hexagons with embedded circuit patterns. Glowing cyan (#7dcfff) and purple -(#bb9af7) edge highlights. Deep shadows, high contrast. Sci-fi aesthetic like -Blade Runner or Tron. Abstract technology, no text, no people. Dark moody -atmosphere with electric blue glow accents. - -Topic context: [EXTRACTED TOPIC] -``` - -### Generate Command - -```bash -bun run ~/.opencode/skills/Art/Tools/Generate.ts \ - --model nano-banana-pro \ - --prompt "[BACKGROUND PROMPT]" \ - --size 2K \ - --aspect-ratio 16:9 \ - --output ~/Downloads/yt-bg-$(date +%Y%m%d-%H%M%S).png -``` - ---- - -## Step 3: Headshot Generation - -**🚨 MANDATORY: Generate a FRESH, VARIED, FACE-ONLY headshot EVERY time.** - -``` -━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -⚠️ FACE ONLY: Forehead to chin, ear to ear ⚠️ -⚠️ NO shoulders, NO neck, NO body visible ⚠️ -⚠️ If shoulders/body visible → REGENERATE IMMEDIATELY ⚠️ -━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -``` - -### Headshot Variation Requirements - -**For each thumbnail, RANDOMLY select ONE from each category:** - -**Angle:** -- Straight-on, looking directly at camera -- Slight 3/4 turn, face angled 15 degrees to the right -- Head tilted slightly to the right - -**Expression:** -- Confident, authoritative -- Contemplative, thoughtful intensity -- Focused, direct engagement - -**Lighting:** -- Soft diffused key light -- Dramatic side lighting with shadow -- Rembrandt lighting pattern - -### Base Headshot Requirements (always include) -- **🚨 FACE ONLY** - forehead to chin, ear to ear -- **NO shoulders, NO neck, NO body** - face fills entire frame -- Pure black background (for easy removal) -- Face fills 95% of image area -- Load facial features from user customizations at `SKILLCUSTOMIZATIONS/Art/CharacterSpecs.md` - -### Example FACE-ONLY Prompts - -**Variation A (confident, straight-on):** -``` -Extreme close-up of the subject's FACE ONLY. Frame shows forehead to chin, ear to ear. -Absolutely NO shoulders, NO neck, NO body visible. Face fills entire image. -Confident, authoritative expression - NOT smiling. Looking directly at camera. -Pure black background. [FACIAL_FEATURES from CharacterSpecs.md]. -Soft diffused key lighting. Ultra-tight crop on face only. -``` - -**Variation B (contemplative, 3/4 angle):** -``` -Extreme close-up of the subject's FACE ONLY. Frame shows forehead to chin, ear to ear. -Absolutely NO shoulders, NO neck, NO body visible. Face fills entire image. -Contemplative, thoughtful expression with subtle intensity - NOT smiling. -Face turned 15 degrees to the right, slight 3/4 angle. -Pure black background. [FACIAL_FEATURES from CharacterSpecs.md]. -Dramatic side lighting creating depth. Ultra-tight crop on face only. -``` - -**Variation C (focused, head tilt):** -``` -Extreme close-up of the subject's FACE ONLY. Frame shows forehead to chin, ear to ear. -Absolutely NO shoulders, NO neck, NO body visible. Face fills entire image. -Focused, direct engagement expression - NOT smiling. Head tilted slightly. -Pure black background. [FACIAL_FEATURES from CharacterSpecs.md]. -Rembrandt lighting pattern. Looking at camera. Ultra-tight crop on face only. -``` - -### Generate Command - -**NOTE: The Headshot.ts tool is NOT IMPLEMENTED.** Use your preferred AI image generation tool (e.g., Nano Banana Pro, Midjourney, or similar) with the face-only prompts above. - -```bash -TIMESTAMP=$(date +%Y%m%d-%H%M%S) - -# Generate face-only headshot using your preferred AI image generation service -# Examples: Nano Banana Pro, Midjourney, DALL-E 3, etc. -# Key requirement: Follow the "FACE ONLY" prompts in the variations above -# Output should be saved as: ~/Downloads/yt-headshot-${TIMESTAMP}.png -``` - -**Note:** Image generation must produce FACE-ONLY output (forehead to chin, ear to ear, no shoulders/body). ComposeThumbnail will also auto-crop to remove any remaining body parts. - -### Remove Background - -```bash -bun ~/.opencode/skills/CORE/Tools/RemoveBg.ts ~/Downloads/yt-headshot-${TIMESTAMP}.png -``` - ---- - -## Step 4: Composition - -**Composite all elements using ComposeThumbnail tool.** - -### Compose Command - -```bash -bun ~/.opencode/skills/Art/Tools/ComposeThumbnail.ts \ - --background ~/Downloads/yt-bg-${TIMESTAMP}.png \ - --headshot ~/Downloads/yt-headshot-${TIMESTAMP}.png \ - --title "[TITLE]" \ - --subtitle "[SUBTITLE]" \ - --title-color [cyan|purple|magenta|white|etc] \ - --position [left|center|right] \ - --output ~/Downloads/yt-thumbnail-${TIMESTAMP}.png -``` - -### Position Logic -- **left**: Headshot on left, text centered on right half -- **center**: Headshot centered, title at top, subtitle at bottom -- **right**: Headshot on right, text centered on left half - -### Text Positioning (automatic) -- For left/right: Text block (title + subtitle) centered vertically in opposite half -- For center: Title at top edge, subtitle at bottom edge -- Text uses black stroke outline for readability (no black boxes) - ---- - -## Step 5: Quality Validation - -**🚨 MANDATORY: ALL checks must pass before presenting to the user.** - -``` -━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -⚠️ THE 320x180 TEST IS MANDATORY ⚠️ -⚠️ If text isn't readable at thumbnail size → FAIL ⚠️ -⚠️ If it looks like ass at any size → FAIL ⚠️ -━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -``` - -### Quality Gates (ALL MUST PASS) - -| # | Check | Pass Criteria | -|---|-------|---------------| -| 1 | Dimensions | Exactly 1280x720 | -| 2 | **FACE-ONLY headshot** | NO shoulders, NO neck, NO body visible | -| 3 | Face fills frame | Face is 90%+ of headshot area | -| 4 | Text fills space | Title is large, bold, FILLS the text zone | -| 5 | Text color | **CYAN or vibrant** - NOT plain white | -| 6 | Stroke visible | 4px title / 3px subtitle - visible at 320px | -| 7 | No overlap | Text entirely in its safe zone | -| 8 | Variation | Visibly different from previous generation | -| 9 | **320x180 readability** | **Text readable at YouTube grid size** | -| 10 | Overall | Professional, billboard-quality appearance | - -### Validation Commands - -```bash -# 1. Verify dimensions -magick identify -format "%wx%h" ~/Downloads/yt-thumbnail-${TIMESTAMP}.png -# Expected: 1280x720 - -# 2. Open for visual inspection at full size -open ~/Downloads/yt-thumbnail-${TIMESTAMP}.png -# Confirm: Face only (no body), text fills space, cyan color visible - -# 3. 🚨 MANDATORY: Test at YouTube thumbnail size -magick ~/Downloads/yt-thumbnail-${TIMESTAMP}.png -resize 320x180 /tmp/yt-preview.png -open /tmp/yt-preview.png -# Confirm: Title READABLE, face RECOGNIZABLE, colors POP -# If you can't read the title at 320x180 → FAIL -``` - -### Failure Response - -**If ANY check fails:** -1. **DO NOT present to the user** -2. Identify the specific failure -3. Fix the issue: - - Body visible → Regenerate headshot with FACE-ONLY prompt - - Text too small → Already fixed (100pt/50pt) - - Text not visible at 320x180 → Check color/stroke - - Text overlapping → Check positioning -4. Re-run composition -5. Re-verify ALL checks including 320x180 test -6. **Only present when ALL checks pass** - -### Quality Standards -- **Thumbnail is a BILLBOARD** - text must dominate, face must dominate -- **DO NOT present output that looks broken, garbled, or unprofessional** -- **Iterate until it matches ALL criteria** -- **If it looks like ass, fix it before showing the user** -- **The 320x180 test is the ultimate validation** - that's what YouTube shows - ---- - -## Quick Reference - -### Tokyo Night Colors -``` -Purple (border): #bb9af7 -Cyan (accents): #7dcfff -Blue (accents): #7aa2f7 -Dark base: #1a1b26 -``` - -### Workflow Summary -``` -1. ANALYZE content → Extract TITLE + SUBTITLE -2. GENERATE background → Dramatic tech art (Nano Banana Pro) -3. GENERATE headshot → FACE-ONLY (1:1 aspect), WITH VARIATION + RemoveBg -4. COMPOSE → ComposeThumbnail.ts (auto-crops body, cyan text, 100pt title) -5. VALIDATE → ALL gates including 320x180 readability test -``` - -### Philosophy -**The thumbnail is a BILLBOARD, not a document.** -- FACE dominates one side -- TEXT FILLS the other side -- Must be readable at 320x180 -- Every generation is visibly different - -### Output Location -All outputs: `~/Downloads/yt-thumbnail-{timestamp}.png` diff --git a/.opencode/skills/Art/Workflows/AnnotatedScreenshots.md b/.opencode/skills/Art/Workflows/AnnotatedScreenshots.md deleted file mode 100755 index f3490091..00000000 --- a/.opencode/skills/Art/Workflows/AnnotatedScreenshots.md +++ /dev/null @@ -1,353 +0,0 @@ -# Annotated Screenshots Workflow - -**Real screenshots with hand-drawn editorial annotations, arrows, and highlights using UL aesthetic.** - -Creates **ANNOTATED SCREENSHOTS** — actual UI screenshots or code snippets with hand-drawn purple/teal commentary overlays. - ---- - -## Purpose - -Annotated screenshots combine real artifacts (UI, code, data) with hand-drawn editorial commentary. This **hybrid real + illustrated** approach adds voice and insights directly onto actual examples. - -**Use this workflow for:** -- Product reviews with annotated screenshots -- Technical tutorials pointing out UI elements -- UX critiques with visual commentary -- Code reviews with illustrated notes -- "THIS IS THE PROBLEM" arrows and callouts - ---- - -## Visual Aesthetic: Real + Hand-Drawn Overlay - -**Think:** Screenshot with hand-drawn arrows, circles, and annotations in editorial voice - -### Core Characteristics -1. **Real foundation** — Actual screenshot or code snippet (not illustrated) -2. **Hand-drawn overlay** — Arrows, circles, highlights, callouts in editorial style -3. **Typography mix** — Real UI text + hand-lettered annotations -4. **Color accents** — Purple/teal for annotations against real screenshot -5. **Editorial voice** — Annotations sound like smart commentary -6. **Editorial style** — Maintains UL imperfect, gestural linework for overlays -7. **Functional clarity** — Annotations enhance understanding, not just decoration - ---- - -## Color System for Annotated Screenshots - -### Real Screenshot Layer -``` -Original colors preserved (screenshot remains unmodified) -OR -Slightly desaturated/faded to make annotations pop -``` - -### Annotation Overlay -``` -Deep Purple #4A148C — Primary annotations (important callouts) -Deep Teal #00796B — Secondary annotations (supporting notes) -Black #000000 — Arrows, circles, underlines -Charcoal #2D2D2D — Annotation text (when not purple/teal) -``` - -### Strategy -- Screenshot slightly faded/grayed (80% opacity) to let annotations stand out -- Purple for critical annotations ("THIS IS THE ISSUE") -- Teal for helpful context ("here's how it works") -- Black for structural annotations (arrows, circles, boxes) - ---- - -## 🚨 MANDATORY WORKFLOW STEPS - -### Step 1: Prepare Screenshot - -**Get the base image:** - -1. **Capture screenshot:** - - Take actual screenshot of UI, code, website, etc. - - Crop to relevant area - - Ensure text is readable - -2. **Process screenshot:** - - Optionally desaturate slightly (makes overlays pop) - - Resize if needed for clarity - - Save as base image - -**Output:** -``` -SCREENSHOT SOURCE: [Path to screenshot file] -SUBJECT: [What the screenshot shows] -KEY AREAS TO ANNOTATE: -- Area 1: [Description] — [What to call out] -- Area 2: [Description] — [What to call out] -... -``` - ---- - -### Step 2: Plan Annotations - -**Identify what to mark:** - -1. **What are you calling attention to?** - - Problem areas - - Good examples - - Workflow steps - - Hidden features - -2. **What type of annotation for each?** - - Arrow pointing to element - - Circle/box highlighting region - - Underline or bracket - - Callout with note - -3. **What's the commentary?** - - "*this is the problem*" - - "*should be here instead*" - - "*genius design*" - - "*completely missed the point*" - -**Output:** -``` -ANNOTATIONS TO ADD: - -1. [Area/Element]: - - Type: [Arrow / Circle / Box / Underline] - - Color: [Purple / Teal / Black] - - Text: "[Your commentary]" - - Position: [Where on screenshot] - -2. [Area/Element]: - - Type: [Annotation type] - - Color: [Color choice] - - Text: "[Commentary]" - - Position: [Location] - -... - -EMPHASIS: -- Purple (critical): [Which annotations] -- Teal (helpful): [Which annotations] -``` - ---- - -### Step 3: Construct Prompt - -**Note:** This workflow is different - you're adding overlays to an existing image. You may need to: -- Upload screenshot as reference image -- Generate hand-drawn annotation layer separately -- Composite in image editor - -OR - -- Use prompt to describe "screenshot with annotations" if model can render both - -### Prompt Template (If Generating Combined Image) - -``` -Real UI screenshot with hand-drawn editorial annotations overlay. - -STYLE: Actual screenshot with imperfect hand-drawn arrows, circles, and notes on top - -SCREENSHOT BASE: -- [Describe the screenshot content, e.g.: "ChatGPT interface showing conversation"] -- Slightly desaturated/faded (80% opacity) to let annotations stand out -- All original text and UI elements clearly visible - -ANNOTATION OVERLAY STYLE: -- Hand-drawn arrows, circles, underlines in editorial style -- Variable stroke weight, wobbly imperfect lines -- Gestural quality (not polished vectors) -- Hand-lettered annotation text - -TYPOGRAPHY FOR ANNOTATIONS (Advocate Italic): -- Font: Advocate condensed italic (hand-lettered style) -- Size: Readable against screenshot -- Color: Purple #4A148C or Teal #00796B for emphasis -- Style: Editorial voice — casual, direct, insightful - -ANNOTATIONS TO ADD: -[List each annotation, e.g.:] - -1. PURPLE ARROW pointing to [UI element]: - - Hand-drawn wobbly arrow in Purple (#4A148C) - - Text annotation: "*THIS IS THE PROBLEM*" - - Thick stroke, clear pointing direction - - Position: [Location on screenshot] - -2. TEAL CIRCLE around [UI area]: - - Hand-drawn imperfect circle in Teal (#00796B) - - Text annotation: "*notice this pattern*" - - Slightly wobbly outline - - Position: [Area to highlight] - -3. BLACK UNDERLINE beneath [text]: - - Hand-drawn wavy underline in Black (#000000) - - Emphasizes existing screenshot text - - No additional annotation needed - -4. PURPLE CALLOUT box: - - Hand-drawn box with arrow pointing to [element] - - Text: "*should have been here instead*" - - Purple (#4A148C) box outline and text - - Position: [Near relevant UI element] - -[etc. for all annotations] - -COLOR USAGE: -- Screenshot: Original colors (or slightly desaturated) -- Purple (#4A148C): Critical annotations, "this is wrong" callouts -- Teal (#00796B): Helpful context, "here's why" explanations -- Black (#000000): Structural annotations (arrows, circles, underlines) -- Charcoal (#2D2D2D): General annotation text when not emphasized - -CRITICAL REQUIREMENTS: -- Screenshot remains readable and recognizable -- Hand-drawn annotations clearly overlay (not integrated into UI) -- Annotations enhance understanding, point out insights -- Variable stroke weight, imperfect human-drawn quality -- Editorial voice in text ("*this*", not formal descriptions) -- Strategic color (not every annotation needs color) -- No gradients on annotations - -Optional: Sign small in bottom corner in charcoal (#2D2D2D). -``` - -### Alternative: Composite Workflow - -If generating combined image is difficult: - -1. **Generate annotation layer separately:** - - Transparent background - - Only arrows, circles, text annotations - - Match screenshot dimensions - -2. **Composite in image editor:** - - Layer screenshot (bottom) - - Layer annotations (top) - - Adjust annotation opacity if needed - ---- - -### Step 4: Determine Aspect Ratio - -**Match screenshot aspect ratio:** -- Screenshot is 16:9 → Use 16:9 -- Screenshot is vertical phone UI → Use 9:16 -- Screenshot is square → Use 1:1 -- Screenshot is wide desktop → Use 21:9 - -**Preserve original screenshot proportions** - ---- - -### Step 5: Execute Generation - -**Option A: Generate combined (if model supports):** -```bash -bun run ~/.opencode/skills/Art/Tools/Generate.ts \ - --model nano-banana-pro \ - --reference-image /path/to/screenshot.png \ - --prompt "[ANNOTATION PROMPT]" \ - --size 2K \ - --aspect-ratio [match screenshot] \ - --output /path/to/annotated.png -``` - -**Option B: Generate annotation layer, then composite manually** - -**Immediately Open:** -```bash -open /path/to/annotated.png -``` - ---- - -### Step 6: Validation (MANDATORY) - -#### Must Have -- [ ] **Screenshot readable** — Original content clearly visible -- [ ] **Annotations clear** — Arrows/circles/text obviously hand-drawn overlays -- [ ] **Editorial voice** — Annotations sound like smart commentary -- [ ] **Strategic pointing** — Annotations highlight key insights, not random decoration -- [ ] **Color emphasis** — Purple on critical, teal on helpful -- [ ] **Hand-drawn quality** — Wobbly arrows, imperfect circles, gestural -- [ ] **Functional value** — Annotations actually enhance understanding - -#### Must NOT Have -- [ ] Unreadable screenshot -- [ ] Polished digital annotation look -- [ ] Generic corporate callouts ("Feature A") -- [ ] Too many annotations (cluttered) -- [ ] Formal voice (should be casual, direct) -- [ ] Perfect straight arrows or circles - -#### If Validation Fails - -| Problem | Fix | -|---------|-----| -| Screenshot too dark | Lighten/desaturate screenshot layer, increase annotation contrast | -| Annotations too polished | Emphasize "hand-drawn wobbly arrows, imperfect circles, gestural sketch" | -| Voice too formal | Rewrite annotations in casual voice: "*this right here*" | -| Can't tell what's being pointed out | Larger/bolder arrows, clearer pointing direction | -| Too cluttered | Reduce annotations to 3-5 key insights only | -| Looks corporate | Reference "editorial annotation style, smart person's markup, hand-drawn notes" | - ---- - -## Example Use Cases - -### Example 1: ChatGPT UI Critique -- **Screenshot:** ChatGPT conversation interface -- **Annotations:** - - Purple arrow: "*this prompt engineering is bad*" - - Teal circle: "*notice how it avoided the question*" - - Black underline: Emphasizing problematic output -- **Aspect:** 16:9 - -### Example 2: Code Review -- **Screenshot:** Python code snippet -- **Annotations:** - - Purple box: "*bottleneck right here*" - - Teal arrow: "*clever use of list comprehension*" - - Black circle: Highlighting security issue -- **Aspect:** 1:1 (code block) - -### Example 3: UX Flow Breakdown -- **Screenshot:** Mobile app workflow (multiple screens) -- **Annotations:** - - Numbered purple arrows showing flow - - Teal notes on each step: "*where users drop off*" - - Black boxes highlighting UI elements -- **Aspect:** 9:16 (vertical phone layout) - ---- - -## Quick Reference - -**Annotated Screenshot Formula:** -``` -1. Prepare screenshot (capture, crop, optionally desaturate) -2. Plan annotations (what to mark, commentary, colors) -3. Construct prompt OR composite manually -4. Match screenshot aspect ratio -5. Generate/composite annotations -6. Validate for clarity and voice -``` - -**Color Strategy:** -- Screenshot: Original colors (or slightly faded) -- Purple: Critical annotations -- Teal: Helpful context -- Black: Structural marks - -**Voice:** -- Casual, direct, editorial commentary -- "*this is the issue*" not "Area A shows problem" - ---- - -**The workflow: Prepare → Plan → Annotate → Generate → Validate → Complete** diff --git a/.opencode/skills/Art/Workflows/Aphorisms.md b/.opencode/skills/Art/Workflows/Aphorisms.md deleted file mode 100755 index 3fb42be0..00000000 --- a/.opencode/skills/Art/Workflows/Aphorisms.md +++ /dev/null @@ -1,335 +0,0 @@ -# Visual Aphorisms & Quote Cards Workflow - -**Aphorisms as shareable visual quote cards using editorial aesthetic.** - -Creates **VISUAL APHORISM CARDS** — insights and quotes as shareable square images with massive typography and minimal hand-drawn accents. - ---- - -## Purpose - -Visual aphorism cards turn memorable one-liners into shareable social media content. These are **typographic statements with personality** — the quote IS the visual, with subtle editorial accents. - -**Use this workflow for:** -- Social media quote cards (LinkedIn, Instagram, X) -- Newsletter pull quotes -- Aphorisms as standalone images -- Thought leadership visuals -- "HUMANS NEED ENTROPY" style statements -- Memorable insights amplified visually - ---- - -## Visual Aesthetic: Typography as Hero - -**Think:** Giant bold typography with subtle hand-drawn accent, not full illustration - -### Core Characteristics -1. **Typography dominant** — The quote IS the visual (80-90% of image) -2. **Massive Advocate** — All-caps bold lettering fills the frame -3. **Minimal illustration** — Small subtle accent element (not full scene) -4. **Square format** — 1:1 for social media -5. **High contrast** — Black text on light, or white text on dark -6. **Hand-lettered quality** — Imperfect typography, not digital font -7. **Editorial voice** — Punchy, memorable, thought-provoking - ---- - -## Color System for Aphorisms - -### Typography -``` -Black #000000 — Primary text (most common) -OR -Deep Purple #4A148C — Full text in brand color (alternative) -OR -White #FFFFFF — Text on dark background (high contrast) -``` - -### Accent Element -``` -Deep Purple #4A148C — Small accent illustration -Deep Teal #00796B — Alternative accent color -``` - -### Background -``` -Light Cream #F5E6D3 — Warm neutral (most common) -OR -White #FFFFFF — Clean modern -OR -Black #000000 — Dark dramatic (white text) -OR -Deep Purple #4A148C — Bold brand (white text) -``` - -### Color Strategy -- **High contrast typography** — Text must be immediately readable -- **Minimal color** — Quote + small accent, not busy -- **Brand presence** — Purple somewhere (text OR accent OR background) - ---- - -## 🚨 MANDATORY WORKFLOW STEPS - -### Step 1: Select Aphorism - -**Choose the quote:** - -1. **What's the aphorism?** - - The exact quote - - Must be punchy and memorable - - Ideal length: 2-8 words (fits large on card) - -2. **What's the insight?** - - What makes this quote powerful - - Why is it shareable - -3. **What tiny visual accent supports it?** - - NOT a full illustration - - Small simple element reinforcing the idea - - Examples: scatter dots for entropy, em dash for typography quote - -**Output:** -``` -APHORISM: "[Quote in all-caps]" -LENGTH: [X words] - -INSIGHT: [Why this quote resonates] - -ACCENT ELEMENT: [Tiny illustration, e.g.:] -- "scatter of dots" for entropy -- "em dash symbol" for typography topic -- "lightning bolt" for insight moment -- "simple line drawing" reinforcing concept -``` - ---- - -### Step 2: Design Typography Layout - -**Plan the visual:** - -1. **Typography arrangement:** - - All one line (short quote) - - Multiple lines (longer quote) - - Stacked words (vertical emphasis) - - Asymmetric layout (dynamic placement) - -2. **Size and weight:** - - How large can text go while remaining readable - - Line breaks for rhythm and emphasis - - Word hierarchy (which words largest) - -3. **Accent placement:** - - Where does small illustration go - - How does it complement (not compete with) text - - Size: 5-10% of image area - -**Output:** -``` -TYPOGRAPHY LAYOUT: -[Describe arrangement, e.g.:] -- "HUMANS NEED" on first line -- "ENTROPY" on second line (larger) -- All-caps Advocate style, massive bold letters -- Fills 80% of image area -- Hand-lettered imperfection - -ACCENT ELEMENT: -- Small scatter of dots (entropy visual) -- Purple (#4A148C) colored -- Position: Bottom right corner -- Size: ~8% of image -- Does NOT compete with text - -COLOR SCHEME: -- Text: [Black / Purple / White] -- Background: [Cream / White / Black / Purple] -- Accent: [Purple / Teal] -- Signature: Charcoal (optional) -``` - ---- - -### Step 3: Construct Prompt - -### Prompt Template - -``` -Typographic quote card in editorial hand-lettered style. - -STYLE REFERENCE: Bold typography poster, quote card, hand-lettered aphorism - -BACKGROUND: [Light Cream #F5E6D3 / White #FFFFFF / Black #000000 / Purple #4A148C] — flat, solid - -AESTHETIC: -- Typography as the primary visual (dominates composition) -- Hand-lettered Advocate style (imperfect, gestural, bold) -- Massive scale lettering (fills 80-90% of frame) -- Minimal accent illustration (subtle, not competing) -- High contrast for readability -- Square 1:1 format - -QUOTE CARD STRUCTURE: - -TYPOGRAPHY (Advocate Block Display - MASSIVE): -"[APHORISM TEXT IN ALL-CAPS]" - -- Font: Advocate style extra bold, hand-lettered, all-caps -- Size: MASSIVE — fills most of image area -- Layout: [Single line / Multi-line / Stacked words] -- Line breaks: [Where breaks occur for rhythm] - Line 1: "[FIRST PART]" - Line 2: "[SECOND PART]" (optionally larger) -- Color: [Black #000000 / Purple #4A148C / White #FFFFFF] -- Style: Hand-lettered with imperfections (not perfect digital font) -- Variable letter sizing for emphasis -- Letters should have character and personality - -ACCENT ILLUSTRATION (Minimal): -- [Small simple element, e.g., "scattered dots", "small em dash", "lightning bolt"] -- Hand-drawn, simple, editorial style -- Position: [Bottom right / Top left / etc. — does NOT interfere with text] -- Size: 5-10% of image area -- Color: [Purple #4A148C / Teal #00796B] -- Style: Imperfect sketch quality, matches text aesthetic -- Purpose: Subtle visual reinforcement, NOT competing focal point - -COLOR USAGE: -- Background: [Color choice] — flat solid fill -- Typography: [Color choice] — high contrast with background -- Accent element: [Purple or Teal] -- Signature: Charcoal (#2D2D2D) small in corner (optional) - -CRITICAL REQUIREMENTS: -- Typography is HERO (quote fills 80-90% of frame) -- Hand-lettered quality (wobbly lines, imperfect character shapes) -- NOT a digital font — should feel hand-drawn -- Accent illustration MINIMAL (does not distract from quote) -- High contrast readability (text must pop from background) -- Square 1:1 aspect ratio -- No gradients, flat colors only -- Shareable social media quality - -Optional: Sign small in bottom right corner in charcoal (#2D2D2D). -``` - ---- - -### Step 4: Determine Aspect Ratio - -**Always 1:1 (square)** — Optimized for social media (Instagram, LinkedIn, X) - ---- - -### Step 5: Execute Generation - -```bash -bun run ~/.opencode/skills/Art/Tools/Generate.ts \ - --model nano-banana-pro \ - --prompt "[YOUR PROMPT]" \ - --size 2K \ - --aspect-ratio 1:1 \ - --output /path/to/aphorism.png -``` - -**Model Recommendation:** nano-banana-pro (best text rendering) or flux (stylistic variety) - -**Immediately Open:** -```bash -open /path/to/aphorism.png -``` - ---- - -### Step 6: Validation (MANDATORY) - -#### Must Have -- [ ] **Quote readable** — Instantly legible even at thumbnail size -- [ ] **Typography dominant** — Quote is 80-90% of visual -- [ ] **Hand-lettered** — Imperfect, gestural quality (not digital font) -- [ ] **High contrast** — Text pops from background -- [ ] **Minimal accent** — Small element supports, doesn't compete -- [ ] **Shareable** — Works as social media post -- [ ] **Brand presence** — Purple visible somewhere (text/accent/background) - -#### Must NOT Have -- [ ] Perfect digital font (should be hand-lettered) -- [ ] Busy background or complex illustration -- [ ] Low contrast (can't read text easily) -- [ ] Accent element competing with quote -- [ ] Tiny text (must be readable at thumbnail) -- [ ] Gradients or shadows - -#### If Validation Fails - -| Problem | Fix | -|---------|-----| -| Text too small | "MASSIVE hand-lettered typography filling 85% of frame" | -| Looks like digital font | "Hand-drawn Advocate letters, imperfect wobbly strokes, gestural quality" | -| Accent too busy | "MINIMAL accent: small simple [element], 8% of image, subtle" | -| Can't read thumbnail | Increase text size, stronger contrast, simplify layout | -| No brand presence | "Purple (#4A148C) on [accent element / text / background]" | -| Too complex | "Typography IS the visual — quote dominant, minimal everything else" | - ---- - -## Example Use Cases - -### Example 1: "HUMANS NEED ENTROPY" -- **Typography:** Two lines, "ENTROPY" larger -- **Accent:** Small scatter of purple dots (bottom right) -- **Background:** Light cream -- **Text:** Black -- **Use:** LinkedIn post, newsletter pull quote - -### Example 2: "THE EM DASH IS PERFECT" -- **Typography:** Stacked words, "EM DASH" emphasized -- **Accent:** Small purple em dash symbol -- **Background:** White -- **Text:** Black -- **Use:** X post about typography - -### Example 3: "AI COPIES HUMAN CREATIVITY" -- **Typography:** Three lines, "AI" and "CREATIVITY" larger -- **Accent:** Tiny robot hand + human hand (purple, minimal) -- **Background:** Black -- **Text:** White (high contrast) -- **Use:** Instagram thought leadership post - -### Example 4: "SECURITY IS A FEELING" -- **Typography:** Two lines -- **Accent:** Small purple shield with heart -- **Background:** Purple #4A148C -- **Text:** White -- **Use:** Bold brand statement - ---- - -## Quick Reference - -**Aphorism Card Formula:** -``` -1. Select aphorism (punchy quote, 2-8 words ideal) -2. Design typography layout (arrangement, emphasis, size) -3. Choose minimal accent element (5-10% of image) -4. Construct prompt with massive typography -5. Always use 1:1 square aspect ratio -6. Generate with nano-banana-pro -7. Validate for readability and shareability -``` - -**Color Strategy:** -- High contrast: Black text on cream, or white text on black/purple -- Brand presence: Purple somewhere in composition -- Minimal palette: Quote + accent + background = 3 colors max - -**Key Principle:** -- **Typography IS the visual** — Everything else is subtle support -- Shareable, memorable, instantly readable -- Your voice amplified visually - ---- - -**The workflow: Select → Design → Construct → Generate → Validate → Complete** diff --git a/.opencode/skills/Art/Workflows/Comics.md b/.opencode/skills/Art/Workflows/Comics.md deleted file mode 100755 index 3bcaa421..00000000 --- a/.opencode/skills/Art/Workflows/Comics.md +++ /dev/null @@ -1,424 +0,0 @@ -# Hand-Drawn Comics Workflow - -**Comic strips in UL editorial illustration style, NOT cartoonish.** - -Creates **EDITORIAL COMICS** — 3-4 panel storytelling with sophisticated hand-drawn aesthetic, maintaining UL flat color and black linework. - ---- - -## Purpose - -Editorial comics use sequential panels to explain concepts, tell stories, or illustrate scenarios. These are **sophisticated comics** — not cutesy or cartoonish, but thoughtful illustrated narratives with editorial style. - -**Use this workflow for:** -- Explaining complex concepts through narrative -- "AGI arrives" scenario panels -- Before/during/after sequences -- Illustrated thought experiments -- Multi-step processes shown visually -- Storytelling with editorial sophistication - ---- - -## Visual Aesthetic: Sophisticated Sequential Art - -**Think:** New Yorker cartoon style, not Sunday funnies - -### Core Characteristics -1. **Multi-panel** — 3-4 panels telling sequential story -2. **Editorial style** — Maintains UL flat color, black linework aesthetic -3. **Simplified figures** — Characters stylized, not realistic or cutesy -4. **Hand-drawn** — Imperfect linework, gestural quality -5. **Narrative flow** — Panels build on each other to make a point -6. **Minimal dialogue** — Text supports, doesn't dominate -7. **Sophisticated humor/insight** — Smart, not silly - ---- - -## Color System for Comics - -### Structure -``` -Black #000000 — All linework, panel borders, character outlines -``` - -### Character/Element Accents -``` -Deep Purple #4A148C — Key character or important element -Deep Teal #00796B — Secondary character or contrast element -Charcoal #2D2D2D — Dialogue text, captions -``` - -### Background -``` -Light Cream #F5E6D3 — Panel backgrounds -OR -White #FFFFFF — Clean backgrounds -OR -Varied per panel — Different cream/light tones for panel differentiation -``` - -### Color Strategy -- Characters primarily black linework -- Purple accent on protagonist or key element -- Teal on secondary character if needed -- Backgrounds light and simple (no busy scenes) -- Dialogue in charcoal for readability - ---- - -## 🚨 MANDATORY WORKFLOW STEPS - -### Step 1: Define Comic Narrative - -**Plan the story:** - -1. **What's the concept/scenario?** - - What are you explaining or illustrating - - The arc or transformation to show - -2. **How many panels?** - - 3 panels (setup → action → result) - - 4 panels (setup → complication → action → result) - -3. **What happens in each panel?** - - Panel 1: [Scene/action] - - Panel 2: [Scene/action] - - Panel 3: [Scene/action] - - Panel 4: [Scene/action] (if using 4) - -4. **What's the punchline/insight?** - - Final panel delivers the point - - What makes this memorable - -**Output:** -``` -COMIC CONCEPT: [What you're illustrating] -PANELS: [3 or 4] - -NARRATIVE ARC: -Panel 1: [Setup - what's the initial state] -Panel 2: [Action/Complication - what changes] -Panel 3: [Escalation or Result] -Panel 4: [Punchline/Insight - the point] (if using 4) - -DIALOGUE (Minimal): -Panel 1: "[Optional brief text]" -Panel 2: "[Optional brief text]" -Panel 3: "[Optional brief text]" -Panel 4: "[Punchline or insight]" - -KEY CHARACTERS: -- [Character/Element 1]: [Description, purple accent] -- [Character/Element 2]: [Description, teal accent if needed] -``` - ---- - -### Step 2: Design Panel Layout - -**Plan the comic structure:** - -1. **Panel arrangement:** - - Horizontal strip (3-4 panels left to right) - - Vertical strip (3-4 panels top to bottom) - - Grid (2x2 for 4 panels) - -2. **Panel size:** - - Equal sized panels (classic) - - Varied sizes for emphasis - - Final panel larger (punchline emphasis) - -3. **Panel content:** - - What's illustrated in each panel - - Character positions and actions - - Background elements (minimal) - -**Output:** -``` -PANEL LAYOUT: [Horizontal strip / Vertical strip / Grid] - -PANEL STRUCTURE: -- Panel 1: [Same size / Smaller / Larger] - * Content: [What's shown] - * Characters: [Positions] - * Background: [Minimal elements] - -- Panel 2: [Size] - * Content: [What's shown] - * Characters: [Positions] - * Background: [Elements] - -- Panel 3: [Size] - * Content: [What's shown] - * Characters: [Positions] - * Background: [Elements] - -- Panel 4: [Size - often larger for punchline] - * Content: [What's shown] - * Characters: [Positions] - * Background: [Elements] - -COLOR CODING: -- Main character/element: Purple (#4A148C) accents -- Secondary: Teal (#00796B) accents (if needed) -- Backgrounds: Light cream or white, simple -``` - ---- - -### Step 3: Construct Prompt - -### Prompt Template - -``` -Hand-drawn editorial comic strip in New Yorker style. - -STYLE REFERENCE: New Yorker cartoon, editorial illustration comic, sophisticated sequential art - -BACKGROUND: Light Cream (#F5E6D3) OR varied light tones per panel - -AESTHETIC: -- Hand-drawn editorial style (NOT cartoonish or cute) -- Flat color, black linework, UL palette -- Simplified but sophisticated character design -- Variable stroke weight (thicker for outlines, thinner for details) -- Gestural imperfect linework -- Minimal backgrounds (not busy scenes) -- Smart humor or insight, not silly - -COMIC STRUCTURE: [3-panel / 4-panel] [horizontal strip / vertical strip / grid] - -PANEL LAYOUT: -- [Number] panels arranged [horizontally left-to-right / vertically / grid 2x2] -- Each panel has black border (hand-drawn, slightly wobbly) -- Panel sizes: [Equal / Varied - specify which panels larger] - -TYPOGRAPHY FOR DIALOGUE (Advocate Condensed): -- Minimal text, supports visual narrative -- Font: Advocate condensed -- Size: Small readable -- Color: Charcoal (#2D2D2D) -- Style: Hand-lettered in speech bubbles or captions - -COMIC NARRATIVE: "[Overall concept being illustrated]" - -PANEL 1 - [SETUP]: -Scene: [Describe what's happening] -Characters: [Who's present, what they're doing] -- Main character: Simplified figure with Purple (#4A148C) accent on [element] -- Hand-drawn black linework, imperfect -Background: Light cream, minimal [optional elements] -Dialogue: "[Brief text]" OR no text -Represents: [Initial state] - -PANEL 2 - [ACTION/COMPLICATION]: -Scene: [What changes or happens] -Characters: [Actions, positions] -- Main character: [Reacting or acting] -- [Optional secondary character]: Teal (#00796B) accent -Background: [Minimal elements] -Dialogue: "[Brief text]" OR no text -Represents: [The change] - -PANEL 3 - [ESCALATION/RESULT]: -Scene: [Situation develops] -Characters: [New positions or states] -- Main character: [Further development] -Background: [Minimal] -Dialogue: "[Brief text]" OR no text -Represents: [Progression] - -PANEL 4 - [PUNCHLINE/INSIGHT]: (if using 4 panels) -Scene: [Final state or revelation] -Characters: [Final positions] -- Main character: [Conclusion state] -- Often larger panel for emphasis -Background: [Simple or empty for focus] -Dialogue: "[Punchline or insight text]" -Represents: [The point being made] - -CHARACTER DESIGN - PLANEFORM AESTHETIC (CRITICAL): -- All figures constructed from ANGULAR PLANES (like architectural paper models) -- NO round forms, NO smooth curves, NO circles on bodies -- Adult proportions (1:7 head-to-body ratio), elongated and dignified -- NO cute proportions (big heads, stubby limbs) -- Faces are MINIMAL geometric blocks — NOT detailed, NOT cute, NO big eyes -- Emotion through GESTURE and SILHOUETTE only -- Russian Constructivist influence: El Lissitzky, Oskar Schlemmer, Saul Bass -- Hand-drawn gestural quality with angular construction -- Consistent character across panels (same angular vocabulary) -- Editorial sophistication — NOT cartoonish, NOT children's book style -- If robots present: same angular planes as humans, differentiated by teal accents - -VISUAL CONTINUITY: -- Same character recognizable across all panels -- Consistent hand-drawn style throughout -- Background simplicity maintained in all panels -- Color accents (purple/teal) consistent - -COLOR USAGE: -- Black (#000000) for all linework, panel borders, character outlines -- Deep Purple (#4A148C) accent on main character or key element -- Deep Teal (#00796B) accent on secondary character (if present) -- Charcoal (#2D2D2D) for all dialogue and captions -- Light Cream (#F5E6D3) OR White (#FFFFFF) panel backgrounds -- Minimal flat color fills, mostly linework - -CRITICAL REQUIREMENTS: -- Hand-drawn editorial style (NOT cartoonish, NOT clip-art) -- Simplified but sophisticated character design -- Clear narrative flow across panels -- Minimal dialogue (visual storytelling prioritized) -- Strategic purple/teal accents (not overwhelming color) -- No gradients, flat colors only -- Maintains UL aesthetic (black linework, flat color, imperfect) -- Smart insight or humor (sophisticated, not silly) - -Optional: Sign small in bottom right corner of final panel in charcoal (#2D2D2D). -``` - ---- - -### Step 4: Determine Aspect Ratio - -| Comic Layout | Aspect Ratio | Reasoning | -|--------------|--------------|-----------| -| 3-panel horizontal | 16:9 or 21:9 | Wide strip format | -| 4-panel horizontal | 21:9 | Extra wide for 4 panels | -| 3-panel vertical | 9:16 | Tall strip | -| 4-panel grid (2x2) | 1:1 | Square balanced | -| Variable | 4:3 | Flexible proportions | - -**Default: 16:9 (horizontal)** — Classic comic strip format - ---- - -### Step 5: Execute Generation - -```bash -bun run ~/.opencode/skills/Art/Tools/Generate.ts \ - --model nano-banana-pro \ - --prompt "[YOUR PROMPT]" \ - --size 2K \ - --aspect-ratio 16:9 \ - --output /path/to/comic.png -``` - -**Model Recommendation:** nano-banana-pro or flux (both handle sequential panels well) - -**Immediately Open:** -```bash -open /path/to/comic.png -``` - ---- - -### Step 6: Validation (MANDATORY) - -#### Must Have -- [ ] **Clear panel structure** — Panels obviously sequential -- [ ] **Editorial aesthetic** — Sophisticated, not cartoonish -- [ ] **Narrative flow** — Story/concept clear across panels -- [ ] **Character consistency** — Same character recognizable in all panels -- [ ] **Hand-drawn quality** — Imperfect linework, gestural -- [ ] **Minimal backgrounds** — Simple, not busy -- [ ] **Smart insight** — Punchline or point lands effectively -- [ ] **UL aesthetic maintained** — Flat color, black linework - -#### Character Validation (Planeform Aesthetic) -- [ ] **Angular construction** — Bodies built from planes, NOT round forms -- [ ] **Adult proportions** — Elongated (1:7), NOT stubby/cute (1:3) -- [ ] **Minimal faces** — Geometric blocks, NOT detailed cute faces -- [ ] **Gesture expression** — Emotion through posture, NOT facial features -- [ ] **NOT cartoonish** — Sophisticated editorial, NOT children's book style -- [ ] **Constructivist influence** — El Lissitzky, Schlemmer aesthetic visible - -#### Must NOT Have -- [ ] Cartoonish or cutesy style -- [ ] Round forms or smooth curves on figures -- [ ] Big heads, stubby proportions -- [ ] Detailed facial features or big eyes -- [ ] Realistic detailed illustration -- [ ] Busy complex backgrounds -- [ ] Too much dialogue (should be visual) -- [ ] Inconsistent character design across panels -- [ ] Gradients or shadows -- [ ] Silly humor (should be sophisticated) -- [ ] Generic AI illustration style - -#### If Validation Fails - -| Problem | Fix | -|---------|-----| -| Too cartoonish | "Sophisticated editorial style, New Yorker cartoon aesthetic, NOT cartoonish" | -| Can't follow story | Clarify narrative arc: "Panel 1 setup → Panel 2 complication → Panel 3 result" | -| Characters inconsistent | "Same simplified character across all panels, consistent design" | -| Too complex | "Minimal backgrounds, simple scenes, focus on key action" | -| Too much text | "Visual storytelling prioritized, minimal dialogue, brief text" | -| Looks corporate | Reference "hand-drawn editorial comic, imperfect wobbly lines, gestural quality" | - -**Character-Specific Failures:** - -| Problem | Fix | -|---------|-----| -| **Characters too round/cute** | "Figures built from ANGULAR PLANES ONLY. NO round forms. Constructivist angular construction like El Lissitzky, Oskar Schlemmer." | -| **Cartoon proportions** | "Adult proportions (1:7 head-to-body). Elongated dignified figures. NO big heads, NO stubby limbs." | -| **Too much facial detail** | "Faces are MINIMAL geometric blocks. NO detailed features, NO big eyes. Emotion through GESTURE only." | -| **Generic AI illustration** | "Bauhaus figure studies. Russian Constructivism. Architectural magazine illustration. NOT children's book." | - ---- - -## Example Use Cases - -### Example 1: "AGI Arrives" (4 panels) -- **Panel 1:** Person at desk, normal work -- **Panel 2:** AGI announcement (computer screen glowing) -- **Panel 3:** Person staring, processing -- **Panel 4:** Person still at desk: "...so what do I do now?" -- **Layout:** Horizontal 21:9 -- **Character:** Purple accent on person - -### Example 2: "Security Theater vs Real Security" (3 panels) -- **Panel 1:** Fancy lock on cardboard door (theater) -- **Panel 2:** Simple lock on solid door (real) -- **Panel 3:** Thief easily bypassing fancy lock, stopped by simple door -- **Layout:** Horizontal 16:9 -- **Accents:** Purple on real security, teal on theater - -### Example 3: "Junior vs Senior Engineer" (4 panels grid) -- **Panel 1 (top-left):** Junior with complex spaghetti code -- **Panel 2 (top-right):** Senior with simple elegant line -- **Panel 3 (bottom-left):** Both present to boss -- **Panel 4 (bottom-right):** Boss confused by junior's complexity, nodding at senior's simplicity -- **Layout:** Grid 1:1 -- **Accents:** Purple on senior, teal on junior - ---- - -## Quick Reference - -**Editorial Comic Formula:** -``` -1. Define narrative (concept, panels, arc, insight) -2. Design layout (arrangement, panel sizes, content) -3. Construct prompt with sequential structure -4. Choose aspect ratio for panel layout -5. Generate with nano-banana-pro -6. Validate for flow and sophistication -``` - -**Color Strategy:** -- Characters: Black linework + purple/teal accents -- Backgrounds: Simple light cream/white -- Dialogue: Charcoal -- Panels: Black borders - -**Key Principle:** -- **Sophisticated, not silly** — New Yorker style, editorial intelligence -- **Visual storytelling** — Minimal dialogue, panels tell the story -- **UL aesthetic** — Flat color, hand-drawn, imperfect - ---- - -**The workflow: Define → Design → Construct → Generate → Validate → Complete** diff --git a/.opencode/skills/Art/Workflows/Comparisons.md b/.opencode/skills/Art/Workflows/Comparisons.md deleted file mode 100755 index b0ed5cc4..00000000 --- a/.opencode/skills/Art/Workflows/Comparisons.md +++ /dev/null @@ -1,371 +0,0 @@ -# Illustrated Dichotomies & Comparisons Workflow - -**Hand-drawn side-by-side visual comparisons using UL aesthetic.** - -Creates **VISUAL COMPARISONS** — "X vs Y" split compositions, before/after transformations, and illustrated contrasts with editorial style. - ---- - -## Purpose - -Illustrated comparisons show two contrasting concepts, states, or approaches side-by-side. These are **visual dichotomies** that make differences immediately obvious through illustrated metaphor. - -**Use this workflow for:** -- "X vs Y" comparisons -- Before/After transformations -- This/That contrasts -- Junior vs Senior behaviors -- Old way vs New way -- Opposite approaches - ---- - -## Visual Aesthetic: Split Screen Editorial - -**Think:** Magazine spread showing contrast, split composition with personality - -### Core Characteristics -1. **Split composition** — Clear left/right or top/bottom division -2. **Mirror structure** — Parallel visual elements showing contrast -3. **Hand-drawn** — Both sides maintain editorial imperfect linework -4. **Color differentiation** — Purple for one side, teal for other (or both black) -5. **Immediate contrast** — Differences obvious at a glance -6. **Editorial style** — Flat colors, black linework, UL aesthetic -7. **Balanced layout** — Equal visual weight to both sides - -### Character Requirements (When figures present) - -**If comparison includes human or robot figures, MUST apply Planeform aesthetic:** -- Figures built from ANGULAR PLANES (no round forms) -- Adult proportions (1:7), NOT cute/stubby -- Faces are minimal geometric blocks -- Emotion through gesture/silhouette -- Constructivist/Bauhaus influence -- NOT cartoonish (sophisticated editorial) - ---- - -## Color System for Comparisons - -### Split Differentiation -``` -Left/Top Side: Purple #4A148C accents -Right/Bottom Side: Teal #00796B accents -OR -Both sides: Black with strategic purple/teal highlights -``` - -### Structure -``` -Black #000000 — Dividing line, all linework on both sides -Charcoal #2D2D2D — All text and labels -``` - -### Background -``` -White #FFFFFF or Light Cream #F5E6D3 on both sides -OR -Left: Light Purple tint, Right: Light Teal tint (very subtle) -``` - -### Color Strategy -- Option 1: Purple accents left, Teal accents right (clear differentiation) -- Option 2: Both black linework, purple on "preferred" side -- Dividing line always black -- Maintain flat aesthetic, no gradients - ---- - -## 🚨 MANDATORY WORKFLOW STEPS - -### Step 1: Define Comparison - -**Identify what you're contrasting:** - -1. **What are the two sides?** - - Side A: [Concept / State / Approach] - - Side B: [Concept / State / Approach] - -2. **What's the key difference?** - - [What fundamentally distinguishes them] - -3. **What visual metaphors show the contrast?** - - Side A metaphor: [Physical object/scene] - - Side B metaphor: [Contrasting object/scene] - -4. **Is one side "better" or are they equal alternatives?** - - Better: [Which side to highlight in purple] - - Equal: [Use balanced color or both in black] - -**Output:** -``` -COMPARISON: [Side A] vs [Side B] - -CORE CONTRAST: [What's fundamentally different] - -VISUAL METAPHORS: -- Side A: [Metaphor showing this approach/state] -- Side B: [Contrasting metaphor] - -VALUE JUDGMENT: -- [Neutral comparison] OR [Side X is preferred] - -COLOR STRATEGY: -- [Purple left / Teal right] OR [Purple on preferred, black on alternative] -``` - ---- - -### Step 2: Design Split Layout - -**Plan the visual structure:** - -1. **Split orientation:** - - Vertical split (left/right) — Classic comparison - - Horizontal split (top/bottom) — Before/after flow - - Diagonal split — More dynamic - -2. **Mirror elements:** - - What visual elements repeat on both sides - - How metaphors contrast (same structure, different details) - - Balance of visual weight - -3. **Dividing line:** - - Strong black line separating sides - - Soft visual separation - - No line (color/metaphor creates division) - -**Output:** -``` -SPLIT ORIENTATION: [Vertical left/right / Horizontal top/bottom] - -LAYOUT STRUCTURE: -Left/Top: [Side A] -- Metaphor: [What to illustrate] -- Key elements: [Specific visual details] -- Color: [Purple accents / Black only] - -Right/Bottom: [Side B] -- Metaphor: [Contrasting illustration] -- Key elements: [Specific visual details] -- Color: [Teal accents / Black only] - -DIVIDING LINE: -- [Strong black vertical/horizontal line] OR [Soft separation] OR [No line] - -MIRROR ELEMENTS: -- [What appears on both sides for parallel structure] -``` - ---- - -### Step 3: Construct Prompt - -### Prompt Template - -``` -Hand-drawn split composition comparing two contrasting concepts in editorial style. - -STYLE REFERENCE: Magazine comparison spread, split-screen editorial illustration, before/after visual - -BACKGROUND: [White #FFFFFF OR Light Cream #F5E6D3] — clean, flat, both sides - -AESTHETIC: -- Split composition with [vertical/horizontal] division -- Hand-drawn black linework on both sides (imperfect, gestural) -- Mirror structure showing parallel concepts with visual contrast -- Editorial flat color with strategic purple/teal differentiation -- Variable stroke weight, organic lines - -SPLIT ORIENTATION: [Vertical left-to-right / Horizontal top-to-bottom] - -COMPOSITION STRUCTURE: -- Clear [vertical/horizontal] division creating two equal sections -- [Black dividing line] OR [Visual separation through composition] -- Left/Top: [Side A name] -- Right/Bottom: [Side B name] - -TYPOGRAPHY SYSTEM (3-TIER): - -TIER 1 - COMPARISON TITLE (Advocate Block Display): -- "[SIDE A] VS [SIDE B]" — Large at top -- Font: Advocate style, extra bold, hand-lettered, all-caps -- Size: 3x larger than body text -- Color: Black #000000 -- Position: Top center above split -- Example: "JUNIOR ENGINEER VS SENIOR ENGINEER" - -TIER 2 - SIDE LABELS (Concourse Sans): -- Left/Top: "[Side A]" -- Right/Bottom: "[Side B]" -- Font: Concourse geometric sans-serif -- Size: Medium readable -- Color: Charcoal #2D2D2D -- Position: Headers for each side - -TIER 3 - ANNOTATIONS (Advocate Condensed Italic): -- Key characteristics: "*overthinks*" vs "*simplifies*" -- Font: Advocate condensed italic -- Size: 60% of Tier 2 -- Color: Matches side color (Purple left, Teal right) -- Position: Within each side's visual - -LEFT/TOP SIDE - [SIDE A]: -Visual metaphor: [Describe the illustration, e.g.:] -- [Metaphor showing Side A characteristic] -- Hand-drawn with [imperfect lines, gestural quality] -- Color: Purple (#4A148C) accents on [specific elements] -- Black (#000000) primary linework -- Represents: [What this side embodies] - -RIGHT/BOTTOM SIDE - [SIDE B]: -Visual metaphor: [Contrasting illustration, e.g.:] -- [Metaphor showing Side B characteristic] -- Hand-drawn matching style to left side -- Color: Teal (#00796B) accents on [specific elements] -- Black (#000000) primary linework -- Represents: [What this side embodies] - -[OR if one side is preferred:] -- Preferred side: Purple (#4A148C) accents -- Alternative side: Black only (or subtle Teal) - -DIVIDING LINE: -- [Strong black vertical/horizontal line down center] OR -- [Soft visual separation through composition and color] - -COLOR USAGE: -- Black (#000000) for all linework on both sides and dividing line -- Left side: Purple (#4A148C) accents on [elements] -- Right side: Teal (#00796B) accents on [elements] -- Charcoal (#2D2D2D) for all label text -- OR: Purple on preferred side only, black on alternative - -CRITICAL REQUIREMENTS: -- Hand-drawn editorial style on BOTH sides (consistent aesthetic) -- Clear visual contrast between sides (metaphors show difference) -- Mirror structure (parallel elements contrasted) -- Strategic color differentiation (purple vs teal, or purple on better side) -- No gradients, flat colors only -- Immediate visual understanding of the difference -- Equal visual weight to both sides (balanced composition) - -Optional: Sign small in bottom right corner in charcoal (#2D2D2D). -``` - ---- - -### Step 4: Determine Aspect Ratio - -| Split Type | Aspect Ratio | Reasoning | -|------------|--------------|-----------| -| Vertical split (left/right) | 16:9 or 21:9 | Wide for side-by-side | -| Horizontal split (top/bottom) | 9:16 or 1:1 | Vertical or square for stacking | -| Square balanced | 1:1 | Symmetric comparison | -| Social media | 1:1 | Instagram/LinkedIn friendly | - -**Default: 16:9 (horizontal)** — Classic side-by-side comparison - ---- - -### Step 5: Execute Generation - -```bash -bun run ~/.opencode/skills/Art/Tools/Generate.ts \ - --model nano-banana-pro \ - --prompt "[YOUR PROMPT]" \ - --size 2K \ - --aspect-ratio 16:9 \ - --output /path/to/comparison.png -``` - -**Model Recommendation:** nano-banana-pro or flux (both work well for split compositions) - -**Immediately Open:** -```bash -open /path/to/comparison.png -``` - ---- - -### Step 6: Validation (MANDATORY) - -#### Must Have -- [ ] **Clear split** — Obvious division between two sides -- [ ] **Visual contrast** — Metaphors clearly show the difference -- [ ] **Balanced composition** — Equal visual weight to both sides -- [ ] **Readable labels** — Side names and annotations legible -- [ ] **Color differentiation** — Purple/teal (or purple/black) distinguishes sides -- [ ] **Hand-drawn** — Both sides maintain editorial aesthetic -- [ ] **Immediate understanding** — Difference obvious at a glance - -#### Must NOT Have -- [ ] Unbalanced sides (one dominates) -- [ ] Unclear which is which -- [ ] Corporate comparison chart look -- [ ] Gradients or photorealistic elements -- [ ] Cluttered or confusing visuals -- [ ] Missing dividing line or separation - -#### If Validation Fails - -| Problem | Fix | -|---------|-----| -| Sides unclear | "Strong black dividing line down center, clear LEFT: vs RIGHT: labels" | -| Not balanced | "Equal visual weight, mirror structure, parallel composition both sides" | -| Contrast weak | "Stronger metaphor contrast: [Side A metaphor] vs [Side B opposite metaphor]" | -| Too complex | Simplify each side to single clear metaphor | -| Colors confusing | "Purple accents left side only, Teal accents right side only" | -| Looks corporate | Reference "editorial split composition, hand-drawn contrast illustration" | - ---- - -## Example Use Cases - -### Example 1: "Junior Engineer vs Senior Engineer" -- **Split:** Vertical left/right -- **Left (Junior):** Complex spaghetti code (purple tangle) -- **Right (Senior):** Simple elegant solution (teal straight line) -- **Color:** Purple left, Teal right -- **Aspect:** 16:9 - -### Example 2: "Before AI vs After AI" -- **Split:** Horizontal top/bottom -- **Top (Before):** Manual tedious work (person with paper pile) -- **Bottom (After):** Automated flow (person directing AI) -- **Color:** Purple on "After" (preferred state) -- **Aspect:** 9:16 - -### Example 3: "Security Theater vs Real Security" -- **Split:** Vertical left/right -- **Left (Theater):** Fancy locks on cardboard door -- **Right (Real):** Simple but solid construction -- **Color:** Purple right (effective), black left (ineffective) -- **Aspect:** 16:9 - ---- - -## Quick Reference - -**Comparison Formula:** -``` -1. Define comparison (sides, contrast, metaphors) -2. Design split layout (orientation, mirror elements, colors) -3. Construct prompt with split structure -4. Choose aspect ratio for split type -5. Generate with nano-banana-pro -6. Validate for clarity and balance -``` - -**Color Strategy:** -- Balanced comparison: Purple left, Teal right -- Value judgment: Purple on better side, black on other -- Neutral: Both black with subtle purple/teal accents - -**Key Principle:** -- Difference should be immediately obvious -- Visual metaphors do the talking, minimal text needed - ---- - -**The workflow: Define → Design → Construct → Generate → Validate → Complete** diff --git a/.opencode/skills/Art/Workflows/CreatePAIPackIcon.md b/.opencode/skills/Art/Workflows/CreatePAIPackIcon.md deleted file mode 100755 index 9d6ddb9c..00000000 --- a/.opencode/skills/Art/Workflows/CreatePAIPackIcon.md +++ /dev/null @@ -1,207 +0,0 @@ -# PAI Pack Icon Workflow - -**Generate 256x256 transparent PNG icons for PAI packs.** - ---- - -## Purpose - -Create consistent, professional icons for PAI packs following the established visual identity. - -**Use for:** New pack icons, icon refreshes, icon regeneration. - ---- - -## Visual Specifications - -### Required Specs - -| Spec | Value | -|------|-------| -| **Dimensions** | 256x256 pixels | -| **Format** | PNG with transparency | -| **Background** | ACTUAL transparent (not checkerboard) | -| **Primary Color** | Electric blue #4a90d9 | -| **Accent Color** | Purple #8b5cf6 (10-15% max) | -| **Style** | Simple, flat, readable at 64x64 | - -### Color Palette - -``` -Background: Transparent (actual transparency, not pattern) -Primary: Electric Blue #4a90d9 (dominant color) -Accent: Purple #8b5cf6 (sparingly, 10-15% of design) -Optional Dark: Dark #0a0a0f (for contrast elements if needed) -``` - -### Design Rules - -1. **Simple geometry** - Icon must be readable at 64x64 pixels -2. **Conceptual** - Represent the pack's core function visually -3. **Consistent style** - Match existing PAI pack icons -4. **No text** - Icons should work without labels -5. **Centered** - Icon should be centered in the 256x256 canvas - ---- - -## Workflow Steps - -### Step 1: Understand Pack Purpose - -Before generating, understand: -- What does this pack do? -- What visual metaphor represents it? -- How should it relate to other pack icons? - -**Good icon concepts:** -- `pai-hook-system` → Hook shape, event trigger -- `pai-core-install` → Download/install arrow -- `pai-skill-system` → Brain/routing/capability -- `pai-agent-system` → Robot/assistant figure -- `pai-voice-system` → Sound wave/speaker - -### Step 2: Construct Prompt - -Build a prompt that specifies: -1. The visual concept -2. The style (simple flat icon) -3. The color palette -4. The size requirements - -**Prompt template:** -``` -[VISUAL CONCEPT representing {pack function}], simple flat icon design, 256x256 pixels. -COLOR PALETTE: Primary electric blue (#4a90d9), Accent purple (#8b5cf6) sparingly. -STYLE: Modern flat icon, simple enough to read at 64x64, no text, centered. -BACKGROUND: Dark (#0a0a0f) - will be removed for transparency. -``` - -### Step 3: Generate Icon - -**Command:** -```bash -bun run ~/.opencode/skills/Art/Tools/Generate.ts \ - --model nano-banana-pro \ - --prompt "[YOUR_PROMPT]" \ - --size 1K \ - --aspect-ratio 1:1 \ - --remove-bg \ - --output ~/Projects/PAI/Packs/icons/[PACK_NAME].png -``` - -**Flags explained:** -- `--model nano-banana-pro` - Best quality for icons -- `--size 1K` - Small file, fast generation -- `--aspect-ratio 1:1` - Square for icons -- `--remove-bg` - Creates actual transparency - -### Step 4: Verify Output - -Check the generated icon: -```bash -# Verify file exists and size -ls -la ~/Projects/PAI/Packs/icons/[PACK_NAME].png - -# Check dimensions (requires imagemagick) -file ~/Projects/PAI/Packs/icons/[PACK_NAME].png -``` - -**Verification checklist:** -- [ ] File exists at correct location -- [ ] PNG format -- [ ] Approximately 256x256 dimensions -- [ ] Has transparency (no solid background) -- [ ] Uses blue/purple palette -- [ ] Readable at small size - ---- - -## Examples - -### Example 1: Hook System Pack - -```bash -bun run ~/.opencode/skills/Art/Tools/Generate.ts \ - --model nano-banana-pro \ - --prompt "A stylized hook or fishing hook shape representing event hooks in software, simple flat icon design, 256x256 pixels. COLOR PALETTE: Primary electric blue (#4a90d9), Accent purple (#8b5cf6) sparingly. STYLE: Modern flat icon, simple enough to read at 64x64, no text, centered. BACKGROUND: Dark (#0a0a0f)." \ - --size 1K \ - --aspect-ratio 1:1 \ - --remove-bg \ - --output ~/Projects/PAI/Packs/icons/pai-hook-system.png -``` - -### Example 2: Core Install Pack - -```bash -bun run ~/.opencode/skills/Art/Tools/Generate.ts \ - --model nano-banana-pro \ - --prompt "A download arrow pointing into a foundation/base structure representing core installation, simple flat icon design, 256x256 pixels. COLOR PALETTE: Primary electric blue (#4a90d9), Accent purple (#8b5cf6) sparingly. STYLE: Modern flat icon, simple enough to read at 64x64, no text, centered. BACKGROUND: Dark (#0a0a0f)." \ - --size 1K \ - --aspect-ratio 1:1 \ - --remove-bg \ - --output ~/Projects/PAI/Packs/icons/pai-core-install.png -``` - -### Example 3: Memory System Pack - -```bash -bun run ~/.opencode/skills/Art/Tools/Generate.ts \ - --model nano-banana-pro \ - --prompt "A brain with memory/data flowing in and out representing an AI memory system, simple flat icon design, 256x256 pixels. COLOR PALETTE: Primary electric blue (#4a90d9), Accent purple (#8b5cf6) sparingly. STYLE: Modern flat icon, simple enough to read at 64x64, no text, centered. BACKGROUND: Dark (#0a0a0f)." \ - --size 1K \ - --aspect-ratio 1:1 \ - --remove-bg \ - --output ~/Projects/PAI/Packs/icons/pai-memory-system.png -``` - ---- - -## Output Location - -All PAI pack icons go to: -``` -~/Projects/PAI/Packs/icons/[PACK_NAME].png -``` - -**Naming convention:** Match the pack directory name exactly. -- Pack: `Packs/pai-hook-system/` -- Icon: `Packs/icons/pai-hook-system.png` - ---- - -## Regeneration - -If an icon needs to be regenerated: - -1. Delete the old icon -2. Run the generate command with updated prompt -3. Verify the new icon -4. Update README if icon changed significantly - ---- - -## Validation Checklist - -Before marking icon complete: - -- [ ] **Exists** at `~/Projects/PAI/Packs/icons/[PACK_NAME].png` -- [ ] **Format** is PNG with transparency -- [ ] **Size** approximately 256x256 -- [ ] **Colors** use blue primary, purple accent -- [ ] **Readable** at 64x64 size -- [ ] **Conceptual** - represents pack function -- [ ] **Consistent** - matches other PAI icons in style - ---- - -## Related Workflows - -> **Note:** The PAI skill workflows referenced below are planned but not yet implemented. - -- `~/.opencode/skills/PAI/Workflows/CreatePack.md` - *(NOT IMPLEMENTED)* Would use this for icon generation -- `~/.opencode/skills/PAI/Workflows/ValidatePack.md` - *(NOT IMPLEMENTED)* Would validate icon exists -- `~/.opencode/skills/PAI/Workflows/PAIIntegrityCheck.md` - *(NOT IMPLEMENTED)* Would check all icons - ---- - -**Last Updated:** 2026-01-10 diff --git a/.opencode/skills/Art/Workflows/D3Dashboards.md b/.opencode/skills/Art/Workflows/D3Dashboards.md deleted file mode 100755 index a311d7a6..00000000 --- a/.opencode/skills/Art/Workflows/D3Dashboards.md +++ /dev/null @@ -1,382 +0,0 @@ -# D3.js Interactive Dashboards Workflow - -**Interactive data visualizations and dashboards using D3.js.** - ---- - -## Purpose - -Creates sophisticated, interactive data visualizations using D3.js for dashboards, reports, and data analysis. - -**Use for:** -- TELOS consulting dashboards (project dependencies, constraint analysis) -- Blog post data visualizations (statistics, trends, relationships) -- Network diagrams (system architecture, organizational relationships) -- Interactive reports and presentations - -**This is NOT for:** -- Static diagrams → Use TechnicalDiagrams or Mermaid workflows -- Editorial illustrations → Use Essay workflow -- Simple infographics → Use other visualization workflows - ---- - -## Supported Visualization Types - -### Charts & Graphs -- **Bar Charts** - Comparisons, rankings, distributions -- **Line Charts** - Trends over time, performance metrics -- **Scatter Plots** - Correlations, clusters, outliers -- **Area Charts** - Cumulative values, stacked comparisons -- **Pie/Donut Charts** - Proportions, percentages - -### Network & Relationships -- **Force-Directed Graphs** - Project dependencies, team relationships -- **Tree Diagrams** - Hierarchies, organizational structures -- **Chord Diagrams** - Entity relationships, data flow -- **Sankey Diagrams** - Flow visualization, process mapping - -### Advanced -- **Heatmaps** - Intensity, density, correlation matrices -- **Geographic Maps** - Location data, regional analysis -- **Timeline Visualizations** - Project milestones, historical data -- **Custom Dashboards** - Multi-chart compositions - ---- - -## Color Palette (PAI Standard) - -**Primary Colors:** -``` -Deep Purple: #4A148C - Brand accent -Deep Teal: #00796B - Secondary accent -Charcoal: #2D2D2D - Text and lines -``` - -**Data Visualization Colors:** -- Sequential scales for continuous data: `d3.interpolateViridis`, `d3.interpolatePlasma` -- Categorical scales for discrete data: `d3.schemeCategory10`, `d3.schemeSet3` -- Maintain accessibility with sufficient contrast - -**Typography:** -- System fonts: `-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto` -- Label sizes: 12px for axes, 14px for titles -- Consistent spacing and alignment - ---- - -## Implementation Approach - -### Standard Workflow - -```javascript -function createVisualization(data, config) { - // 1. Setup SVG container - const svg = d3.select('#chart'); - svg.selectAll("*").remove(); // Clear previous render - - // 2. Define dimensions with margins - const width = 800, height = 400; - const margin = { top: 20, right: 30, bottom: 40, left: 50 }; - const innerWidth = width - margin.left - margin.right; - const innerHeight = height - margin.top - margin.bottom; - - // 3. Create scales - const xScale = d3.scaleLinear() - .domain([0, d3.max(data, d => d.value)]) - .range([0, innerWidth]); - - // 4. Create axes - const xAxis = d3.axisBottom(xScale); - - // 5. Bind data and create elements - const g = svg.append('g') - .attr('transform', `translate(${margin.left},${margin.top})`); - - // 6. Add interactive features - g.selectAll('circle') - .data(data) - .join('circle') - .attr('cx', d => xScale(d.value)) - .attr('cy', height / 2) - .attr('r', 5) - .on('mouseover', showTooltip) - .on('mouseout', hideTooltip); -} -``` - -### Integration Patterns - -**Direct DOM Manipulation (Recommended):** -- D3 selects and imperatively manipulates DOM elements -- Works in any JavaScript context -- Full control over rendering - -**Declarative Rendering:** -- D3 calculates scales and layouts -- Framework renders via templating -- Suitable for simpler visualizations - ---- - -## Interactive Features - -### Tooltips - -```javascript -const tooltip = d3.select('body').append('div') - .attr('class', 'tooltip') - .style('opacity', 0); - -function showTooltip(event, d) { - tooltip.transition() - .duration(200) - .style('opacity', .9); - tooltip.html(`Value: ${d.value}`) - .style('left', (event.pageX + 10) + 'px') - .style('top', (event.pageY - 28) + 'px'); -} -``` - -### Zoom & Pan - -```javascript -const zoom = d3.zoom() - .scaleExtent([0.5, 5]) - .on('zoom', (event) => { - g.attr('transform', event.transform); - }); - -svg.call(zoom); -``` - -### Transitions & Animations - -```javascript -circles.transition() - .duration(750) - .delay((d, i) => i * 50) - .attr('r', d => radiusScale(d.value)) - .style('fill', d => colorScale(d.category)) - .ease(d3.easeBounceOut); -``` - -### Responsive Design - -```javascript -// Handle container resizing -const resizeObserver = new ResizeObserver(entries => { - const { width, height } = entries[0].contentRect; - redrawVisualization(width, height); -}); - -resizeObserver.observe(document.querySelector('#chart-container')); -``` - ---- - -## TELOS Dashboard Patterns - -### Project Dependency Network - -```javascript -// Force-directed graph for project dependencies -const simulation = d3.forceSimulation(nodes) - .force('link', d3.forceLink(links).id(d => d.id)) - .force('charge', d3.forceManyBody().strength(-100)) - .force('center', d3.forceCenter(width / 2, height / 2)); - -// Visualize blockers as red nodes -nodes.forEach(node => { - node.color = node.isBlocker ? '#D32F2F' : '#4A148C'; -}); -``` - -### Constraint Theory Visualization - -```javascript -// Bottleneck analysis with bar chart -const constraints = [ - { name: 'Resource A', impact: 85, isBottleneck: true }, - { name: 'Resource B', impact: 45, isBottleneck: false }, - // ... -]; - -// Highlight bottlenecks in contrasting color -bars.attr('fill', d => d.isBottleneck ? '#D32F2F' : '#00796B'); -``` - -### Progress Dashboard - -```javascript -// Multi-metric dashboard -const metrics = { - currentCustomers: 243, - targetCustomers: 2000, - growthRate: 0.15, - blockers: 3 -}; - -// Create gauge chart for progress -const progress = (metrics.currentCustomers / metrics.targetCustomers) * 100; -createGaugeChart(progress); -``` - ---- - -## Best Practices - -### Data Validation -```javascript -// Always validate and clean data first -const cleanData = data.filter(d => - d.value !== null && - d.value !== undefined && - !isNaN(d.value) -); -``` - -### Performance Optimization -- **<1000 elements**: Use SVG (optimal) -- **1000-10,000 elements**: Consider canvas rendering -- **>10,000 elements**: Implement virtual scrolling or aggregation - -### Accessibility -```javascript -// Add ARIA labels and semantic markup -svg.attr('role', 'img') - .attr('aria-label', 'Bar chart showing project metrics'); - -// Add keyboard navigation -circles.attr('tabindex', 0) - .on('keypress', handleKeyPress); -``` - -### Error Handling -```javascript -// Graceful error handling -try { - const svg = d3.select('#chart'); - if (svg.empty()) { - throw new Error('Chart container not found'); - } - - if (!Array.isArray(data) || data.length === 0) { - throw new Error('Invalid or empty data'); - } - - renderVisualization(data); -} catch (error) { - console.error('Visualization error:', error); - showErrorMessage('Unable to render chart. Please check your data.'); -} -``` - ---- - -## Output Formats - -### HTML Artifact -- Complete standalone HTML file -- Embedded D3.js library (CDN or inline) -- Responsive container -- Interactive controls - -### Code Snippet -- Reusable JavaScript function -- Configurable parameters -- Documentation comments - -### Dashboard Page -- Multi-chart layout -- Coordinated interactions -- Shared data filtering -- Export/download functionality - ---- - -## Quick Start Examples - -### Bar Chart -```javascript -// Simple bar chart -const data = [12, 5, 6, 6, 9, 10]; - -d3.select('#chart') - .selectAll('div') - .data(data) - .join('div') - .style('width', d => `${d * 10}px`) - .style('height', '20px') - .style('background', '#4A148C') - .text(d => d); -``` - -### Network Diagram -```javascript -// Project dependency network -const nodes = [ - { id: 'A', label: 'API' }, - { id: 'B', label: 'Database' }, - { id: 'C', label: 'Frontend' } -]; - -const links = [ - { source: 'A', target: 'B' }, - { source: 'C', target: 'A' } -]; - -createForceDirectedGraph(nodes, links); -``` - ---- - -## D3.js Resources - -**Core Concepts:** -- Selections: `d3.select()`, `d3.selectAll()` -- Data binding: `.data()`, `.join()` -- Scales: `d3.scaleLinear()`, `d3.scaleBand()`, `d3.scaleOrdinal()` -- Axes: `d3.axisBottom()`, `d3.axisLeft()` -- Shapes: `d3.line()`, `d3.arc()`, `d3.area()` - -**Layout Algorithms:** -- Force simulation: `d3.forceSimulation()` -- Hierarchies: `d3.hierarchy()`, `d3.tree()` -- Chord: `d3.chord()` -- Sankey: `d3.sankey()` - -**Official Documentation:** -- https://d3js.org/ -- https://observablehq.com/@d3/gallery - ---- - -## Execution - -1. Gather data requirements and determine visualization type -2. Choose appropriate chart/graph pattern -3. Set up HTML structure with D3.js -4. Implement visualization with standard color palette -5. Add interactivity (tooltips, zoom, transitions) -6. Validate accessibility and responsiveness -7. Output as HTML artifact or code snippet - ---- - -## Validation - -**Must have:** -- [ ] Clean, professional appearance -- [ ] Standard color palette applied -- [ ] Interactive features working -- [ ] Responsive to container size -- [ ] Accessible (ARIA labels, keyboard nav) -- [ ] Data validation in place -- [ ] Error handling for edge cases - -**Must NOT have:** -- [ ] Generic color schemes -- [ ] Static-only presentation when interactivity makes sense -- [ ] Missing axis labels or legends -- [ ] Overflow or cropped elements diff --git a/.opencode/skills/Art/Workflows/EmbossedLogoWallpaper.md b/.opencode/skills/Art/Workflows/EmbossedLogoWallpaper.md deleted file mode 100755 index cafe3717..00000000 --- a/.opencode/skills/Art/Workflows/EmbossedLogoWallpaper.md +++ /dev/null @@ -1,281 +0,0 @@ -# Embossed Logo Wallpaper - -**Generate sophisticated wallpapers with logo physically embossed into the design.** - -## Voice Notification - -```bash -curl -s -X POST http://localhost:8888/notify \ - -H "Content-Type: application/json" \ - -d '{"message": "Running the EmbossedLogoWallpaper workflow in the Art skill to create wallpapers"}' \ - > /dev/null 2>&1 & -``` - -Running **EmbossedLogoWallpaper** in **Art**... - ---- - -Creates wallpapers where the UL logo is integrated as an embossed texture within the visual content — not overlaid, not floating in empty space. - ---- - -## Purpose - -Generate wallpapers that: -- Integrate the logo as a physical embossed element within the design -- Use the UL color palette (blue/purple/cyan only) -- Match sophisticated reference wallpapers in quality -- Position logo small in bottom left, surrounded by visual content - ---- - -## Prerequisites - -**Logo Source:** `~/Projects/Logos/ul-blue.png` -**Style References:** `~/Projects/Wallpaper/` (blue-purple-circuits.png, circuit-board.png) -**Output Directory:** `~/Projects/Wallpaper/` - ---- - -## Critical Lessons Learned (Validation Checklist) - -### ❌ COMMON FAILURES TO AVOID - -**1. Wrong Logo Treatment** -- ❌ Literal text "UL" or "Unsupervised Learning" instead of the logo shape -- ❌ Logo overlaid/floating instead of embossed into surface -- ❌ Logo placed in empty/blank area instead of integrated into design -- ❌ Logo too large and prominent -- ❌ Logo glowing or different color than surroundings -- ✅ CORRECT: Logo shape from reference image, embossed as texture, small, within visual content - -**2. Wrong Colors** -- ❌ Matrix green (#00ff41) -- ❌ Pink/magenta neon -- ❌ Bright saturated neons -- ❌ Any colors outside the UL palette -- ✅ CORRECT: Blue (#4a90d9 or muted #3a6a9a), Purple (#8b5cf6 or muted #6b4c96), Cyan (#06b6d4 or muted #4a9a9a) - -**3. Wrong Style** -- ❌ Simple, cartoony, flat vector art -- ❌ Too bright, loud, gaudy -- ❌ Clean lines without texture or depth -- ✅ CORRECT: Sophisticated, photorealistic or stylized with depth, muted/subdued, dense detail - -**4. Wrong Composition** -- ❌ Logo in empty/blank corner -- ❌ Visual content clustered in center with empty edges -- ❌ Logo too prominent/centered -- ✅ CORRECT: Visual content fills entire canvas, logo small in bottom left WITHIN the design - -**5. Missing Reference Images** -- ❌ Not using ul-blue.png as reference for logo shape -- ❌ Not checking existing wallpapers for quality benchmark -- ✅ CORRECT: Always use --reference-image with the logo file - ---- - -## Workflow Steps - -### Step 1: Gather Requirements - -Ask about: -1. **Style direction** — Photorealistic circuit, cyberpunk/hacker, abstract, etc. -2. **Tone** — Bright and energetic OR muted and subdued -3. **Output name** — Filename (kebab-case) - -### Step 2: Load References - -```bash -# Verify logo exists -ls ~/Projects/Logos/ul-blue.png - -# View style reference wallpapers -open ~/Projects/Wallpaper/circuit-board.png -open ~/Projects/Wallpaper/blue-purple-circuits.png -``` - -**Study reference wallpapers for:** -- Level of visual sophistication and detail -- Color palette application -- Depth and atmospheric effects -- Texture and material quality - -### Step 3: Construct Prompt - -**Required prompt sections:** - -``` -1. AESTHETIC - Define the visual style (cyberpunk, circuit, etc.) - -2. VISUAL COMPLEXITY - Specify density, layers, detail level - -3. TONE - Muted/subdued OR bright (usually muted is better) - -4. COLOR PALETTE (STRICT): - - Deep black base (#0a0a0f) - - Blue (#4a90d9 or muted #3a6a9a) - - Purple (#8b5cf6 or muted #6b4c96) - - Cyan (#06b6d4 or muted #4a9a9a) - - NO GREEN, NO PINK, NO OTHER COLORS - -5. LOGO INTEGRATION (CRITICAL): - - Connected-nodes logo from reference - - EMBOSSED into surface (raised/pressed texture) - - Position: bottom left WITHIN the visual content - - Size: 3-5% of image width (SMALL) - - Same materials/colors as surroundings - - Slight luminosity difference only - - NOT overlaid, NOT floating, NOT glowing - - Must be surrounded by design elements - -6. COMPOSITION: - - Visual content fills ENTIRE canvas - - NO empty corners or blank areas - - Logo area has visual content WITH logo embossed into it - -7. CRITICAL reminders: - - Logo integrated INTO design - - Logo SMALL and SUBTLE - - Entire image has visual content - - Correct color palette only -``` - -### Step 4: Generate - -```bash -bun run ~/.opencode/skills/Art/Tools/Generate.ts \ - --model nano-banana-pro \ - --prompt "[CONSTRUCTED_PROMPT]" \ - --size 4K \ - --aspect-ratio 16:9 \ - --reference-image ~/Projects/Logos/ul-blue.png \ - --output ~/Projects/Wallpaper/.png -``` - -### Step 5: Validate (CRITICAL) - -Open the generated image and check EVERY item: - -```bash -open -a "Dia" ~/Projects/Wallpaper/.png -``` - -**Validation Checklist:** - -| Check | Pass/Fail | -|-------|-----------| -| Logo is the correct shape (connected nodes), not text | | -| Logo is EMBOSSED (texture), not overlaid or floating | | -| Logo is in bottom left corner | | -| Logo is SMALL (3-5% width) | | -| Logo is WITHIN visual content, not in empty space | | -| Logo is same color palette as surroundings | | -| Colors are ONLY blue/purple/cyan (no green, pink, etc.) | | -| Style is sophisticated, not cartoony or simple | | -| Tone matches request (muted if requested) | | -| Visual content fills entire canvas (no blank areas) | | -| Quality matches reference wallpapers | | -| Image dimensions are 4K+ (5504×3072 or similar) | | - -**If ANY check fails → regenerate with adjusted prompt** - -### Step 6: Iterate if Needed - -Common fixes: -- Logo in wrong place → Emphasize "WITHIN the visual content" and "NO empty corners" -- Logo too big → Specify exact percentage "3-5% of image width" -- Wrong colors → List exact hex codes and explicitly say "NO GREEN, NO PINK" -- Too bright → Add "MUTED, SUBDUED, desaturated" -- Too simple → Describe sophistication level, reference existing wallpapers - -### Step 7: Save and Apply - -```bash -# Verify saved -ls -la ~/Projects/Wallpaper/.png - -# Apply to Kitty + macOS -k -w -``` - ---- - -## Example Prompt (Muted Cyberpunk) - -``` -Cyberpunk hacker wallpaper, 16:9 4K resolution. SUBDUED AND MUTED. - -AESTHETIC: -- Dense layers of data streams and neural network architecture -- Sophisticated cyberpunk atmosphere - Ghost in the Shell / Lain -- Japanese anime styling - mature, serious, detailed - -VISUAL COMPLEXITY: -- Thousands of tiny particles and data points -- Overlapping translucent layers of circuit geometry -- Dense but organized chaos throughout THE ENTIRE IMAGE -- Visual content should extend to ALL edges including bottom left -- NO empty or blank areas anywhere - -TONE (SUBDUED AND HUMBLE): -- MUTED colors - desaturated, not neon bright -- DARK overall - near-black dominates -- Subtle glows instead of bright neon -- Quiet sophistication, not loud -- Moody and atmospheric - -COLOR PALETTE (MUTED UL BRAND): -- Deep black void dominates (#0a0a0f) -- Desaturated blue (#3a6a9a) - muted -- Muted purple (#6b4c96) - subtle -- Soft cyan (#4a9a9a) - hints only - -LOGO INTEGRATION (CRITICAL): -- The connected-nodes logo (from reference) must be EMBOSSED INTO the visual content -- Position: bottom left, but WITHIN the circuit/data design, not in empty space -- The logo should be part of the circuit architecture - traces flow through it -- SMALL - about 3-5% of image width -- Same visual treatment as surrounding elements - muted, subtle -- Embossed texture - slight depth/luminosity difference only -- Should look like it was manufactured into the circuit board -- NOT floating in empty space - surrounded by and integrated with the design - -COMPOSITION: -- Visual activity and detail must cover the ENTIRE canvas -- Bottom left corner has circuit detail WITH the logo embossed into it -- No blank corners or empty zones -- Uniform density of visual interest - -CRITICAL: -- Logo MUST be integrated INTO the design, not placed in empty space -- Logo must be SMALL and SUBTLE -- Entire image should have visual content - no blank areas -- Subdued, muted, sophisticated -``` - ---- - -## Quick Reference - -| Parameter | Value | -|-----------|-------| -| Model | nano-banana-pro | -| Size | 4K | -| Aspect Ratio | 16:9 | -| Logo Reference | ~/Projects/Logos/ul-blue.png | -| Output Directory | ~/Projects/Wallpaper/ | -| Logo Size | 3-5% of image width | -| Logo Position | Bottom left, WITHIN design | - -**Color Palette (Muted):** -- Black: #0a0a0f -- Blue: #3a6a9a -- Purple: #6b4c96 -- Cyan: #4a9a9a - -**Color Palette (Bright):** -- Black: #0a0a0f -- Blue: #4a90d9 -- Purple: #8b5cf6 -- Cyan: #06b6d4 diff --git a/.opencode/skills/Art/Workflows/Essay.md b/.opencode/skills/Art/Workflows/Essay.md deleted file mode 100755 index e2ad7008..00000000 --- a/.opencode/skills/Art/Workflows/Essay.md +++ /dev/null @@ -1,847 +0,0 @@ -# UL Art Image Generation Workflow - -**Charcoal Architectural Sketch TECHNIQUE — Applied to CONTENT-RELEVANT subjects.** - -Uses architectural sketching STYLE (gestural lines, hatching, charcoal) to depict whatever the content is actually ABOUT — NOT defaulting to buildings. - ---- - -## 🚨🚨🚨 ALL STEPS ARE MANDATORY — NO EXCEPTIONS 🚨🚨🚨 - -``` -━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -⚠️ EVERY SINGLE STEP BELOW IS MANDATORY. EXECUTE ALL OF THEM. ⚠️ -⚠️ DO NOT SKIP ANY STEP. DO NOT ABBREVIATE. DO NOT SHORTCUT. ⚠️ -⚠️ IF YOU SKIP A STEP, YOU HAVE FAILED THE WORKFLOW. ⚠️ -━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -``` - -**ALL 8 STEPS ARE MANDATORY. Execute them IN ORDER. Do NOT skip steps.** - -``` -INPUT CONTENT - ↓ -[1] UNDERSTAND: Deeply read and comprehend the request ← MANDATORY - ↓ -[2] CSE-24: Run Create Story Explanation Level 24 on content ← MANDATORY - ↓ -[3] EMOTION: Identify emotional register ← MANDATORY - ↓ -[4] COMPOSITION: Design what to ACTUALLY DRAW ← MANDATORY - ↓ -[5] PROMPT: Construct using charcoal sketch TECHNIQUE template ← MANDATORY - ↓ -[6] GENERATE: Execute CLI tool with --thumbnail flag ← MANDATORY - ↓ -[7] OPTIMIZE: Resize, convert to WebP, create optimized thumbnails ← MANDATORY - ↓ -[8] VALIDATE: Subject matches content? Signature? Gallery-worthy? ← MANDATORY -``` - -**MANDATORY ELEMENTS IN EVERY IMAGE:** -- Signature (small, charcoal, bottom right corner) -- Charcoal sketch technique -- Content-relevant subject matter -- **BURNT SIENNA (#8B4513)** — human warmth, humanity (MANDATORY) -- **DEEP PURPLE (#4A148C)** — technology, AI, capital, cold power (MANDATORY) -- --thumbnail flag for blog headers - -**🚨 BOTH SIENNA AND PURPLE MUST BE PRESENT IN EVERY IMAGE.** -- Sienna on human/warm elements -- Purple on tech/capital/cold elements -- The ratio of Sienna:Purple tells the emotional story -- If an image is missing either color, it's INCOMPLETE - -**🚨 FORBIDDEN — NEVER INCLUDE:** -- ❌ Borders or frames around the image -- ❌ Background shading or gradients -- ❌ Filled backgrounds of any kind -- ❌ Decorative elements that aren't part of the subject -- The composition should float in empty space — MINIMALIST - -**🚨 LOGICAL/PHILOSOPHICAL CONSISTENCY:** -- The visual MUST make logical sense with the concept -- If "X is winning" — X should be in the dominant/winning position visually -- If "X is heavy/powerful" — X weighs DOWN, not up -- If using a balance scale: the winning/heavy side pushes DOWN -- THINK about what the metaphor actually means before drawing it - -**⚠️ KNOWN ISSUE: Background removal may remove the signature.** -If the signature is missing after generation, you must add it manually or regenerate with the signature more integrated into the composition (not isolated in corner with empty space). - ---- - -## Step 1: Deeply Understand the Request — MANDATORY - -**Before doing ANYTHING, deeply read and understand:** - -1. **What is the content?** Read the full blog post, essay, or input material -2. **What is it ABOUT?** Not surface-level — the actual core concept/argument -3. **What are the key concrete elements?** Nouns, metaphors, imagery FROM the content -4. **What should NOT be drawn?** Architecture, buildings, vast spaces — UNLESS the content is about those -5. **Did the user provide GUIDANCE?** If the user gave direction about what to focus on, what the image should convey, or what angle to take — THIS TAKES PRIORITY over your own interpretation - -**🚨 USER GUIDANCE TAKES PRIORITY:** -If the user provides specific direction like: -- "Focus on the tension between X and Y" -- "The image should show Z losing" -- "Emphasize the human impact" -- Any other compositional or thematic guidance - -**USE THAT GUIDANCE** as the primary input for composition design. The CSE-24 supports the user's direction — it doesn't override it. - -**Output:** Clear understanding of the content's core subject matter + any user-provided guidance. - ---- - -## Step 2: Run Create Story Explanation Level 24 — MANDATORY - -**Extract the FULL narrative arc to understand the emotional core.** - -**🚨 ACTUALLY EXECUTE THIS COMMAND — DO NOT SKIP:** - -``` -Invoke the StoryExplanation Skill with: "Create a 24-item story explanation for this content" -``` - -Or use the slash command: -``` -/cse [paste the content or URL] -``` - -**What CSE-24 gives you:** -- The complete narrative arc: setup, tension, transformation, resolution -- Key metaphors and imagery from the piece -- The emotional journey -- What the piece is REALLY about -- The "wow" factor and significance - -**DO NOT PROCEED TO STEP 3 UNTIL YOU HAVE:** -1. Actually run the CSE command -2. Read and understood the 24-item output -3. Identified the key metaphors and emotional beats - -**Output:** 24-item story explanation revealing the emotional and conceptual core. - ---- - -## Step 3: Identify Emotional Register — MANDATORY - -**Read the aesthetic file and select the appropriate emotional vocabulary.** - -```bash -Read ~/.opencode/skills/Art/SKILL.md -``` - -**Match the contVent to one of these emotional registers:** - -| Register | When to Use | -|----------|-------------| -| **DREAD / FEAR** | AI takeover, existential risk, loss of control | -| **HOPE / POSSIBILITY** | Human potential, growth, positive futures | -| **CONTEMPLATION** | Philosophy, meaning, deep questions | -| **URGENCY / WARNING** | Security threats, calls to action | -| **WONDER / DISCOVERY** | Breakthroughs, encountering the vast | -| **DETERMINATION / EFFORT** | Overcoming obstacles, "gym" work | -| **MELANCHOLY / LOSS** | Endings, what's lost to progress | -| **CONNECTION / KINDNESS** | Human bonds, community | - -**Output:** Selected emotional register with specific vocabulary from the aesthetic file. - -These are just examples. It can be really anything which you will get from the Create Story Explanation Run. - ---- - -## Step 4: Design Composition — MANDATORY - -**🚨 CRITICAL: Design what to ACTUALLY DRAW based on the CONTENT — NOT defaulting to architecture.** - -### The Core Question - -**What is this content ABOUT, and what visual would represent THAT?** - -**🚨 IF USER PROVIDED GUIDANCE — START THERE:** -If the user gave direction in Step 1 (e.g., "focus on the tension between labor and capital", "show labor losing"), use that as your PRIMARY composition direction. The CSE-24 output SUPPORTS this direction — it doesn't replace it. - -Use the content from the create-story-explanation run to compose this. - -- Architecture is the TECHNIQUE (how to draw), NOT the required subject -- Only draw buildings/spaces if the content is about those things -- Draw what the content is actually about using architectural sketch style -- **User guidance shapes WHAT to draw; CSE-24 helps you understand the emotional core** - -### Composition Design Questions - -**🚨 STEP 4A: IDENTIFY THE PROBLEM (MOST CRITICAL)** - -Before designing anything, extract from the CSE-24 output: - -1. **What is the PROBLEM the essay addresses?** - - What's WRONG with the current state? - - What unfairness, mistake, or confusion exists? - - What are people doing wrong that this essay corrects? - - **The art should SHOW THIS PROBLEM visually** - -2. **What TYPE of problem is it?** - - Identify the problem archetype from the CSE output: - - | Problem Type | Description | Visual Metaphor | - |--------------|-------------|-----------------| - | **SORTING/CLASSIFICATION** | Need to categorize things into the right buckets | Scattered items + empty labeled bins | - | **COMMUNICATION** | Can't express ideas clearly, talking past each other | Tangled speech, broken telephone | - | **DOUBLE STANDARD** | Same thing judged differently based on source | Tilted scales, unfair judges | - | **MISDIRECTION** | Focusing on wrong thing, missing the real issue | Looking left while danger is right | - | **OVERWHELM** | Too much to process, can't see clearly | Flood of items, buried figure | - | **MISSING FRAMEWORK** | No structure to organize thinking | Chaos vs. empty scaffolding | - | **FALSE DICHOTOMY** | Forced choice that ignores better options | Two doors, hidden third path | - | **COMPLEXITY** | Simple thing made unnecessarily complicated | Tangled vs. straight path | - | **BLINDSPOT** | Can't see obvious thing right in front | Figure ignoring elephant | - - **🚨 THE PROBLEM TYPE SHAPES THE VISUAL METAPHOR.** - - SORTING problem → show the sorting challenge (scattered items, categories) - - COMMUNICATION problem → show the breakdown (garbled speech, confusion) - - DOUBLE STANDARD → show the unfairness (tilted scales, biased judge) - - **Examples with problem types:** - - ATHI framework → Problem TYPE: SORTING — "When you have a threat, which category does it belong to?" - - AI judgment essay → Problem TYPE: DOUBLE STANDARD — "Same output judged differently based on source" - - Security theater → Problem TYPE: MISDIRECTION — "Focus on visible but ineffective measures" - - Meaning essay → Problem TYPE: MISDIRECTION — "Chasing status instead of purpose" - - **THE ART SHOULD MAKE THE PROBLEM TYPE VISIBLE AT A GLANCE.** - Someone seeing the image should immediately understand WHAT KIND of problem this is. - -3. **What are the CONCRETE SUBJECTS in the content?** - - Extract specific nouns, metaphors, imagery FROM the content - - "Bowling pins" → draw bowling pins - - "Hands juggling" → draw hands juggling - - "Balance between capital and labor" → draw a balance/scale metaphor - - **The visual should match the content's core concept** - -4. **What VISUAL METAPHOR represents the PROBLEM?** - - What image would make someone say "Oh, I see what's wrong"? - - If the piece uses a metaphor USE THAT - - If no metaphor, what scene captures the problematic situation? - - **Show the unfairness, the mistake, the confusion** - -5. **Should there be FIGURES showing the problem?** - - Judges applying double standards - - People ignoring obvious issues - - Actors making the mistake the essay critiques - - The dynamic that needs to change - -6. **What is the EMOTIONAL treatment?** - - The emotion should match the PROBLEM being shown - - Unfairness → show the contrast, the tipped scale - - Confusion → show the misdirection, the wrong focus - - Loss → show what's fading, being ignored - -7. **What is the COMPOSITION?** - - Centered, minimalist, breathing space - - Arrange to make the PROBLEM OBVIOUS - - The viewer should "get it" immediately - - NOT busy, NOT cluttered - -### Composition Design Template - -``` -THE PROBLEM (from CSE-24 — MOST CRITICAL): -[What's WRONG with the current state that this essay addresses?] -[The unfairness, mistake, or confusion the essay critiques] -[This is what the art should SHOW] - -SUBJECT (WHAT TO DRAW — showing the problem): -[The actual visual subject that makes the PROBLEM visible] -[Key elements from the content's metaphors/imagery] - -VISUAL METAPHOR: -[The core image that represents the PROBLEM] -[What would make someone say "Oh, I see what's wrong"?] - -FIGURE TREATMENT (if applicable): -[Type of figures, their roles in showing the problem] -[Who is judging unfairly? Who is being judged? Who is making the mistake?] - -EMOTIONAL REGISTER: -[From Step 3] - -COMPOSITION: -[Arrangement that makes the PROBLEM OBVIOUS] -[The viewer should "get it" immediately] - -COLOR APPROACH: -[Warm:Cool ratio, which colors where] -``` - -**Output:** A specific composition design that makes the essay's PROBLEM VISIBLE at a glance. - ---- - -## Step 5: Construct the Prompt — MANDATORY - -**Use deep thinking to construct the final prompt using the charcoal sketch TECHNIQUE template.** - -### Prompt Template - -``` -Sophisticated charcoal sketch using architectural rendering TECHNIQUE. - -THE PROBLEM THIS ESSAY ADDRESSES (from Step 4 — drives the entire composition): -[What's WRONG with the current state that this essay critiques?] -[The art should make this problem VISIBLE AT A GLANCE] - -SUBJECT (WHAT TO DRAW — showing the problem): -[The actual visual subject that makes the PROBLEM visible] -[NOT defaulting to architecture — draw what makes the problem clear] - -EMOTIONAL REGISTER: [From Step 3] - -TECHNIQUE — GESTURAL ARCHITECTURAL SKETCH STYLE: -━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -🚨 Architecture is the TECHNIQUE, not the required subject 🚨 -━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -- GESTURAL — quick, confident, energetic marks -- OVERLAPPING LINES — multiple strokes suggesting form -- HATCHING — cross-hatching creates depth and tone -- Loose charcoal/graphite pencil strokes throughout -- Variable line weight, some lines trailing off -- NOT clean vectors, NOT smooth -- Like Paul Rudolph, Lebbeus Woods sketches - -LINEWORK (applies to ALL subjects): -- [Specific line quality from emotional vocabulary] -- Visible hatching and gestural marks -- UNIFIED sketch quality across all elements - -HUMAN FIGURES (if present) — GESTURAL ABSTRACTED: -- MULTIPLE OVERLAPPING LINES suggesting the form -- Quick, confident, ENERGETIC gestural marks -- HATCHING and cross-hatching to create tone/depth -- 20-40 overlapping strokes creating the form -- Form EMERGES from accumulated linework -- Abstracted but with PRESENCE and WEIGHT -- FACES via simple charcoal marks (dark strokes for eyes, line for mouth) -- Burnt Sienna (#8B4513) WASH accent - -HANDS (if present) — GESTURAL: -- Same overlapping line technique -- Form suggested through accumulated marks -- Sienna wash accent for human warmth - -OBJECTS (if present) — GESTURAL SUGGESTED FORMS: -- Objects implied through hatching and gestural strokes -- Same energetic sketch quality -- Recognizable forms through accumulated lines -- NOT flat symbols — sketched with depth - -COMPOSITION — FULL FRAME IS MANDATORY: -- 🚨 SUBJECTS MUST FILL THE ENTIRE FRAME — edge to edge horizontally and vertically -- Subjects should nearly TOUCH the edges of the image -- NO large empty margins on any side -- If there's 20%+ empty space on any edge, the composition is WRONG -- MINIMALIST means few elements, NOT small elements with lots of empty space -- Subjects LARGE and DOMINANT — filling the available space - -COLOR — CHARCOAL DOMINANT, COLORS AS ACCENTS ONLY: -- CHARCOAL AND GRAY DOMINANT — 70-80% of image -- Colors INTEGRATED INTO forms — not splattered or applied on top -- Colors are the ESSENCE of elements (purple = cold capital, sienna = human warmth) -- Every bit of color belongs to a form — no random color floating in space - -Optional: Sign small in bottom right corner in charcoal. -NO other text. -``` - -### Prompt Quality Check - -Before generating, verify: -- [ ] **PROBLEM IS VISIBLE** — someone could understand what's wrong just from the image -- [ ] **Concrete subjects present** — nouns from title/content appear visually (not abstracted) -- [ ] Emotional register explicitly stated -- [ ] Figure treatment shows the problematic dynamic (if applicable) -- [ ] Light source and meaning specified -- [ ] Warm:cool ratio matches emotion -- [ ] "Charcoal sketch", "gestural", "hatching" explicitly stated -- [ ] Artist reference appropriate to emotion -- [ ] SPECIFIC to this content (couldn't be about something else) -- [ ] **Title test** — could someone guess the title from the image alone? - -**Output:** A complete prompt ready for generation. - ---- - -## Step 6: Execute the Generation — MANDATORY - -### Intent-to-Flag Mapping - -**Interpret user request and select appropriate flags:** - -#### Model Selection - -| User Says | Flag | When to Use | -|-----------|------|-------------| -| "fast", "quick", "draft" | `--model nano-banana` | Faster iteration, slightly lower quality | -| (default), "best", "high quality" | `--model nano-banana-pro` | Best quality + text rendering (recommended) | -| "flux", "stylistic variety" | `--model flux` | Different aesthetic, stylistic variety | - -#### Size Selection - -| User Says | Flag | Resolution | -|-----------|------|------------| -| "thumbnail", "small" | `--size 1K` | Quick previews | -| (default), "standard" | `--size 2K` | Standard blog headers | -| "high res", "large", "print" | `--size 4K` | Maximum resolution | - -#### Aspect Ratio - -| User Says | Flag | Use Case | -|-----------|------|----------| -| "square" | `--aspect-ratio 1:1` | Default for blog headers | -| "wide", "landscape", "banner" | `--aspect-ratio 16:9` | Wide banners | -| "portrait", "vertical" | `--aspect-ratio 9:16` | Vertical content | -| "ultrawide" | `--aspect-ratio 21:9` | Cinematic banners | - -#### Post-Processing - -| User Says | Flag | Effect | -|-----------|------|--------| -| "blog header" (default) | `--thumbnail` | Creates transparent + thumb versions | -| "transparent only" | `--remove-bg` | Just removes background | -| "with reference", "style like" | `--reference-image ` | Uses reference for style guidance | -| "variations", "options" | `--creative-variations 3` | Generates multiple versions | - -### Default Model: nano-banana-pro - -### 🚨 CRITICAL: Always Output to Downloads First - -**ALL images go to `~/Downloads/` for preview before final placement.** - -```bash -# ALWAYS output to Downloads first for user to review in Preview -bun run ~/.opencode/skills/Art/Tools/Generate.ts \ - --model nano-banana-pro \ - --prompt "[YOUR PROMPT]" \ - --size 2K \ - --aspect-ratio 1:1 \ - --thumbnail \ - --output ~/Downloads/[descriptive-name].png - -# After user approves, THEN copy to final destination: -cp ~/Downloads/[name].png ~/Projects/Website/cms/public/images/ -cp ~/Downloads/[name]-thumb.png ~/Projects/Website/cms/public/images/ -``` - -### Construct Command Based on Intent - -Based on user's request and the mapping tables above, construct the CLI command: - -```bash -bun run ~/.opencode/skills/Art/Tools/Generate.ts \ - --model [SELECTED_MODEL from table] \ - --prompt "[PROMPT from Step 5]" \ - --size [SELECTED_SIZE] \ - --aspect-ratio [SELECTED_RATIO] \ - [--thumbnail if blog header] \ - [--reference-image PATH if style reference provided] \ - [--creative-variations N if variations requested] \ - --output [OUTPUT_PATH] -``` - -### 🚨 MANDATORY: Blog Header Images → Use `--thumbnail` - -**ALL blog header images MUST use the `--thumbnail` flag.** - -The `--thumbnail` flag generates TWO versions: -1. `output.png` — Transparent background (for compositing over website backgrounds) -2. `output-thumb.png` — With `#EAE9DF` background (for thumbnails, social previews, OpenGraph) - -```bash -# Example: Generates both header.png AND header-thumb.png -bun run ~/.opencode/skills/Art/Tools/Generate.ts \ - --model nano-banana-pro \ - --prompt "[YOUR PROMPT]" \ - --size 2K \ - --aspect-ratio 1:1 \ - --thumbnail \ - --output ~/Website/cms/public/images/my-header.png -``` - -**Why two versions?** -- **Transparent (`output.png`):** For the blog post inline image — composites beautifully over website background -- **Thumbnail (`output-thumb.png`):** For `thumbnail:` frontmatter field — visible in social previews, RSS readers, and anywhere that doesn't composite transparency - -### 🚨 CRITICAL: Blog Post Frontmatter Must Use `-thumb` Version - -**ALWAYS reference the `-thumb` file in the blog post's `thumbnail:` frontmatter field:** - -```yaml -# ✅ CORRECT - Use the -thumb version with sepia background -thumbnail: https://example.com/images/my-header-thumb.png - -# ❌ WRONG - Transparent version shows white background on social media -thumbnail: https://example.com/images/my-header.png -``` - -**The inline image in the post body uses the transparent version:** -```markdown -[![Description](/images/my-header.png)](/images/my-header.png) -``` - -**Summary:** -| File | Background | Use For | -|------|------------|---------| -| `output.png` | Transparent | Inline blog image (composites over page background) | -| `output-thumb.png` | Sepia #EAE9DF | `thumbnail:` frontmatter, social previews, OpenGraph | - -### Alternative: Standalone Background Removal - -For non-blog images that only need transparency, or to remove backgrounds after generation: - -```bash -# Use the Images Skill for background removal -bun ~/.opencode/skills/CORE/Tools/RemoveBg.ts /path/to/output.png - -# Or batch process multiple images -bun ~/.opencode/skills/CORE/Tools/RemoveBg.ts image1.png image2.png image3.png -``` - -### 🚨 COMPOSITION: USE FULL FRAME, MINIMALIST, NO BACKGROUNDS - -**SUBJECTS FILL THE FRAME. FEW ELEMENTS. NO FILLED BACKGROUNDS.** - -**ALWAYS include in prompt:** -- "USE FULL FRAME — subjects fill horizontal and vertical space" -- "Subjects LARGE and DOMINANT in the composition" -- "MINIMALIST — few elements, each intentional" -- "NO filled-in backgrounds — composition floats in empty space" -- "Clean, uncluttered — gallery-worthy simplicity" - -**Common failures:** -- ❌ WRONG: Subjects too small, too much empty space around them -- ❌ WRONG: Busy backgrounds with lots of detail -- ❌ WRONG: Filled-in architectural environments surrounding subject -- ❌ WRONG: Cluttered compositions with competing elements - -**The fix:** -- ✅ RIGHT: Subjects LARGE, filling the frame -- ✅ RIGHT: Few elements, each intentional — gallery aesthetic -- ✅ RIGHT: No background fill — subjects float in white/transparent space -- ✅ RIGHT: Full use of horizontal and vertical dimensions - -### Alternative Models - -| Model | Command | When to Use | -|-------|---------|-------------| -| **flux** | `--model flux --size 1:1 --remove-bg` | Maximum quality, more detail | -| **gpt-image-1** | `--model gpt-image-1 --size 1024x1024 --remove-bg` | Different interpretation | - -### Immediately Open - -```bash -open /path/to/output.png -``` - ---- - -## Step 7: Optimize Images (MANDATORY) - -**🚨 CRITICAL: This step happens AFTER generation and background removal, BEFORE validation.** - -### Why This Step Matters - -Generated images at 2K resolution (2048x2048) are 6-8MB each - far too large for web use. Optimization reduces file sizes by 90-95% while maintaining visual quality, ensuring fast page loads and better user experience. - -### Optimization Process - -**For ALL blog header images, automatically execute these commands:** - -```bash -# 1. Resize main image from 2K (2048x2048) to 1K (1024x1024) for web display -magick "~/Downloads/[name].png" -resize 1024x1024 "~/Downloads/[name]-1024.png" - -# 2. Convert resized image to WebP format (main display version) -cwebp -q 75 "~/Downloads/[name]-1024.png" -o "~/Downloads/[name].webp" - -# 3. Create optimized PNG thumbnail for social media (512x512) -magick "~/Downloads/[name]-thumb.png" -resize 512x512 -quality 80 "~/Downloads/[name]-thumb-optimized.png" - -# 4. Clean up temporary resized PNG -rm "~/Downloads/[name]-1024.png" - -# 5. Check final file sizes -ls -lh ~/Downloads/[name].webp ~/Downloads/[name]-thumb-optimized.png -``` - -**Expected Results:** -- Main WebP image: ~150-500KB (from ~7.5MB PNG) -- Optimized thumbnail: ~300-600KB (from ~6.8MB PNG) -- 90-95% total file size reduction - -### File Usage Matrix - -After optimization, you'll have these files: - -| File | Format | Size | Use For | -|------|--------|------|---------| -| `[name].png` | PNG | ~7.5MB | Archive/backup (original with transparency) | -| `[name].webp` | WebP | ~400KB | **Inline blog display** (reference this in post body) | -| `[name]-thumb.png` | PNG | ~6.8MB | Archive/backup (original with sepia background) | -| `[name]-thumb-optimized.png` | PNG | ~500KB | **Social media thumbnails** (reference this in `thumbnail:` frontmatter) | - -### Blog Post References - -**After optimization, update the blog post to use optimized versions:** - -```markdown ---- -thumbnail: https://example.com/images/[name]-thumb-optimized.png ---- - -[![Alt text](/images/[name].webp)](/images/[name].webp) -``` - -**🚨 CRITICAL: Use `.webp` for inline images and `-thumb-optimized.png` for thumbnails.** - -### Quality Settings Explained - -- **WebP quality 75**: Aggressive compression with minimal visible quality loss. Perfect for web display of charcoal sketches where slight compression artifacts are invisible. -- **Thumbnail quality 80**: Standard optimization for PNG social previews. Balances file size with quality for platforms that don't support WebP. -- **Resize to 1024x1024**: Optimal for web display. Higher resolutions provide no visual benefit on typical displays but significantly increase file sizes. - -### Error Handling - -**If WebP is over 500KB:** -```bash -# Lower quality further -cwebp -q 65 "~/Downloads/[name]-1024.png" -o "~/Downloads/[name].webp" -``` - -**If thumbnail is over 600KB:** -```bash -# Resize smaller or lower quality -magick "[name]-thumb.png" -resize 400x400 -quality 75 "[name]-thumb-optimized.png" -``` - -**If magick command not found:** -```bash -# Install ImageMagick -brew install imagemagick -``` - -**If cwebp command not found:** -```bash -# Install WebP tools -brew install webp -``` - -### Integration Notes - -- **This step is AUTOMATIC** - do not ask the user if optimization should be done -- **Happens in ~/Downloads/** before files are copied to final destination -- **Original high-res files are preserved** as archives -- **Validation (Step 8) checks the optimized files**, not the originals - ---- - -## Step 8: Validation (MANDATORY) - -**🚨 CRITICAL: This step is MANDATORY. Regenerate if validation fails.** - -### 🚨🚨🚨 ACTUALLY LOOK AT THE IMAGE AND THINK 🚨🚨🚨 - -``` -━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -⚠️ DO NOT JUST CHECK BOXES. ACTUALLY ANALYZE THE IMAGE. ⚠️ -⚠️ LOOK AT IT. THINK ABOUT IT. ASK: DOES THIS MAKE SENSE? ⚠️ -━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -``` - -### Open and Inspect - -```bash -open /path/to/generated-image.png -``` - -### 🧠 CRITICAL ANALYSIS (DO THIS FIRST — BEFORE THE CHECKLIST) - -**STOP. Look at the image. Answer these questions honestly:** - -**0. SIGNATURE CHECK:** -- Is signature present in the BOTTOM RIGHT CORNER of the image? (if included) -- Not bottom center. Not near the subject. BOTTOM RIGHT CORNER. -- Is the signature correctly rendered? (no literal prompt text) -- If missing, wrong location, or wrong text → REGENERATE - -**0.5. PROMPT LITERAL INTERPRETATION CHECK:** -- Did the model take prompt instructions literally? (e.g., writing literal prompt text instead of a signature) -- Are there any instruction words visible in the image that shouldn't be? -- Did labels come out as intended? (e.g., "A T H I" not "Actor Technique Harm Impact" spelled out) -- If prompt instructions appear as text in image → REGENERATE with clearer wording - -**1. PHYSICAL REALITY CHECK:** -- Do objects obey physics? (heavy things fall DOWN, scales tip toward heavy side) -- If there's a scale: TRACE THE BEAM WITH YOUR EYES - - Find the fulcrum (center pivot) - - Which end of the beam is LOWER? That's the heavy side. - - The heavy/winning side's end of the beam points DOWN toward the ground - - The light/losing side's end of the beam points UP toward the sky -- If there's gravity: do things fall in the right direction? -- Are proportions reasonable? -- Would this scene make physical sense in the real world? - -**2. LOGICAL CONSISTENCY CHECK:** -- Does the visual metaphor match the concept? -- If "X is winning" — is X visually dominant/powerful? -- If "X is losing" — is X diminished/fading/rising (on a scale)? -- Does cause match effect in the image? - -**3. PHILOSOPHICAL ALIGNMENT CHECK:** -- Does the image represent the MEANING of the content? -- Would the user look at this and say "yes, that captures it"? -- Is the emotional register correct? -- Does the image argue the same point as the content? - -**🚨 IF ANY OF THESE FAIL — STOP AND REGENERATE. DO NOT PROCEED.** - -**Example failures:** -- ❌ Signature missing or not in bottom right corner (if signature was requested) -- ❌ Scale shows heavy side's beam going UP (physically impossible — heavy pulls DOWN) -- ❌ "Capital winning" but capital looks small/weak -- ❌ "Labor losing" but labor looks strong/dominant -- ❌ Objects floating when they should fall -- ❌ Visual contradicts the conceptual argument - -### Validation Checklist - -**🚨 MANDATORY ELEMENTS (if ANY are missing, REGENERATE):** -- [ ] **SIGNATURE PRESENT** — signed small in charcoal, bottom right corner (if requested) -- [ ] **PROBLEM TYPE VISIBLE** — the problem type (sorting, double standard, etc.) is immediately obvious -- [ ] **Subject matches CONTENT** — drew what the piece is ABOUT, not defaulted to architecture -- [ ] **Concrete subjects visible** — key nouns/metaphors from content actually appear -- [ ] **Title test passes** — someone could guess the topic from the image alone -- [ ] **Labels readable** — if there are labels (like A, T, H, I), they are clearly visible and correct -- [ ] **NOT defaulting to buildings/spaces** — unless content is actually about architecture -- [ ] **CSE-24 insights captured** — the visual represents the narrative arc discovered in Step 2 -- [ ] **User guidance incorporated** — if the user gave direction, it's reflected in the image -- [ ] **Background removed** — transparent background, or re-run background removal if it failed - -**TECHNIQUE (all required):** -- [ ] Charcoal sketch quality — visible strokes, hatching, gestural marks -- [ ] NOT clean vectors or cartoony -- [ ] Gestural overlapping lines suggesting form -- [ ] Gallery-worthy sophistication - -**FIGURE STYLE (if figures present):** -- [ ] **GESTURAL ABSTRACTION** — multiple overlapping lines suggesting form -- [ ] **ENERGETIC LINEWORK** — quick, confident, scratchy strokes -- [ ] **HATCHING creates depth** — cross-hatching for tone and shadow -- [ ] **20-40 overlapping strokes** per figure — form emerges from accumulated marks -- [ ] **Figures have PRESENCE** — abstracted but with weight and dimension -- [ ] **Faces have EMOTION** — via charcoal marks (dark strokes for eyes, line for mouth, head tilt) -- [ ] Human = organic flowing gestural marks + sienna wash -- [ ] Robot = angular rigid gestural marks + purple wash -- [ ] Looks like Paul Rudolph / Lebbeus Woods architectural sketches - -**COLOR (all required — BOTH SIENNA AND PURPLE MANDATORY):** -- [ ] **CHARCOAL/GRAY DOMINANT** — 70-85% of image -- [ ] **BURNT SIENNA (#8B4513) PRESENT** — on human/warm elements (MANDATORY) -- [ ] **DEEP PURPLE (#4A148C) PRESENT** — on tech/capital/cold elements (MANDATORY) -- [ ] Colors as washes/accents, not solid fills -- [ ] Sienna:Purple ratio matches emotional story - -**EMOTION (all required):** -- [ ] Emotional register clear — matches Step 2 selection -- [ ] Architecture reinforces the feeling -- [ ] Figure treatment (if present) supports the mood -- [ ] Light placement serves the narrative -- [ ] Overall atmosphere matches intended emotion - -**COMPOSITION (all required):** -- [ ] **FULL FRAME** — subjects nearly touch all edges, NO large empty margins -- [ ] **SUBJECTS LARGE** — dominant, filling the available space -- [ ] **NO BACKGROUND FILL** — floats in empty/transparent space (but subjects are LARGE) -- [ ] **KAI SIGNATURE** — small cursive charcoal in BOTTOM RIGHT CORNER -- [ ] **MARGIN CHECK** — is there more than 20% empty space on any edge? If yes, REGENERATE - -**QUALITY (all required):** -- [ ] Could hang in a gallery next to Piranesi -- [ ] Could be concept art for a Villeneuve film -- [ ] Distinctive — NOT generic AI illustration -- [ ] Sophisticated — rewards closer looking -- [ ] **Transparent background** — used `--remove-bg` flag - -### If Validation Fails - -**Common failures and fixes:** - -| Problem | Fix | -|---------|-----| -| **Subjects too SMALL** | 🚨 Add "LARGE SUBJECTS that FILL THE FRAME", "minimal empty space around subjects" | -| **Too much empty space** | 🚨 Add "minimal empty space around subjects", "subjects FILL THE FRAME" | -| **Background dominates** | 🚨 Add "subjects are DOMINANT focus", "subjects LARGE" | -| **Setting not recognizable** | Add "SETTING: [location]" with "2-3 KEY OBJECTS that establish location" — gym needs weights/bench visible | -| **Figures look like CARTOONS** | 🚨 Add "GESTURAL ABSTRACTION", "like Paul Rudolph sketches", "Lebbeus Woods figure studies", "OVERLAPPING LINES" | -| **Lines are SINGLE/CLEAN** | 🚨 Add "MULTIPLE OVERLAPPING LINES", "20-40 strokes per figure", "hatching for depth", "energetic gestural marks" | -| **Figures are FLAT** | 🚨 Add "HATCHING creates depth", "figures have PRESENCE and WEIGHT", "form emerges from accumulated marks" | -| **No emotion on faces** | Add "dark charcoal strokes for eyes area", "line for mouth angle", "head TILT conveys emotion", "SUGGESTED expression" | -| **Too illustrated/rendered** | Add "GESTURAL SKETCH quality", "quick energetic marks", "like architectural concept sketches" | -| **Objects too detailed** | Add "objects implied through hatching", "same sketch quality as figures", "suggested forms" | -| Wrong emotion | Adjust POSTURE and LINE QUALITY — leaning = relaxed, rigid = tense, dense hatching = weight | -| Colors too solid | Emphasize "atmospheric washes", "tints over charcoal", "not solid fills" | -| Generic AI look | Add "Paul Rudolph", "Lebbeus Woods", "architectural concept sketches" references | - -**Regeneration Process:** -1. Identify failed criteria -2. Update prompt with specific fixes -3. Regenerate -4. Re-validate -5. Repeat until ALL criteria pass - ---- - -## Quick Reference - -### The Workflow in Brief - -``` -1. UNDERSTAND → Deeply read and comprehend the content -2. CSE-24 → Run Create Story Explanation (24 items) to extract narrative arc -3. EMOTION → Match to register in ~/.opencode/skills/CORE/aesthetic.md -4. COMPOSITION → Design what to DRAW (content-relevant, NOT defaulting to architecture) -5. PROMPT → Build using charcoal sketch TECHNIQUE template -6. GENERATE → Execute with nano-banana-pro + --thumbnail flag -7. OPTIMIZE → Resize to 1024, convert to WebP, create optimized thumbnails -8. VALIDATE → Subject matches content? Technique correct? Gallery-worthy? -``` - -### Emotional Quick-Select - -| Content About... | Register | Warm:Cool | Visual Treatment | -|------------------|----------|-----------|------------------| -| AI danger | Dread | 20:80 | Heavy, dense, oppressive linework | -| Human potential | Hope | 80:20 | Light, ascending, open | -| Philosophy | Contemplation | 50:50 | Balanced, still, thoughtful | -| Security threats | Urgency | 60:40 | Fractured, dynamic, tense | -| Discoveries | Wonder | 40:60 | Revelatory, light breaking through | -| Building skills | Determination | 70:30 | Strong, grounded, effort-showing | -| What's lost | Melancholy | 40:60 | Fading, dissolving, trailing off | -| Community | Connection | 90:10 | Warm, intimate, multiple figures | - -### The UL Look Checklist - -Before submitting any image: -- ✅ **Subject matches CONTENT** — drew what the piece is ABOUT (not defaulting to architecture) -- ✅ **CSE-24 was run** — actually executed the story explanation command -- ✅ **Concrete subjects visible** — key nouns/metaphors from content appear -- ✅ Charcoal sketch TECHNIQUE — gestural, atmospheric, hatching -- ✅ Emotional register — clear and intentional -- ✅ Color washes — warm/cool ratio tells the story -- ✅ Gallery-worthy — sophisticated, not generic AI -- ✅ **--thumbnail flag used** — both transparent and sepia versions generated -- ✅ **OPTIMIZATION COMPLETED** — resized to 1024, converted to WebP, optimized thumbnails created -- ✅ Signature — small charcoal bottom right (optional) - ---- - -**The workflow: UNDERSTAND → CSE-24 → EMOTION → COMPOSITION → PROMPT → GENERATE (--thumbnail) → OPTIMIZE → VALIDATE → Complete** diff --git a/.opencode/skills/Art/Workflows/Frameworks.md b/.opencode/skills/Art/Workflows/Frameworks.md deleted file mode 100755 index a6a10db4..00000000 --- a/.opencode/skills/Art/Workflows/Frameworks.md +++ /dev/null @@ -1,362 +0,0 @@ -# Visual Mental Models & Frameworks Workflow - -**Hand-drawn frameworks, mental models, and conceptual diagrams using UL aesthetic.** - -Creates **VISUAL FRAMEWORKS** — signature mental models illustrated as memorable diagrams with editorial hand-drawn style. - ---- - -## Purpose - -Visual frameworks illustrate mental models, thinking frameworks, and conceptual relationships. These are **signature frameworks** made visual — 2x2 matrices, Venn diagrams, conceptual maps with personality and editorial style. - -**Use this workflow for:** -- 2x2 matrices and quadrant models -- Venn diagrams with editorial flair -- Conceptual relationship maps -- "The [Your Name] Framework for X" -- Mental models and thinking tools -- Decision frameworks - ---- - -## Visual Aesthetic: Structured Concepts with Editorial Style - -**Think:** Smart conceptual diagram, but hand-drawn and visually interesting - -### Core Characteristics -1. **Clear structure** — Framework shape is recognizable (2x2, Venn, pyramid, etc.) -2. **Hand-drawn organic** — Imperfect lines, wobbly circles, human touch -3. **Editorial aesthetic** — Flat colors, black linework, UL palette -4. **Labels integrated** — Typography part of visual design -5. **Conceptual clarity** — Framework immediately understandable -6. **Memorable visual** — Becomes THE reference image for this framework -7. **Thoughtful color** — Strategic use of purple/teal to show relationships - ---- - -## Color System for Frameworks - -### Structure -``` -Black #000000 — All framework structure (axes, circles, boxes) -``` - -### Concept Differentiation -``` -Deep Purple #4A148C — Concept area 1 or optimal quadrant -Deep Teal #00796B — Concept area 2 or contrast quadrant -Charcoal #2D2D2D — All text and labels -``` - -### Background -``` -White #FFFFFF or Light Cream #F5E6D3 -``` - -### Color Strategy -- Framework lines/structure in black -- Purple for "ideal" or primary concept -- Teal for "secondary" or contrast concept -- Subtle fills or accents, not solid color blocks - ---- - -## 🚨 MANDATORY WORKFLOW STEPS - -### Step 1: Define Framework Structure - -**Identify the mental model:** - -1. **What framework type?** - - 2x2 matrix (four quadrants) - - Venn diagram (overlapping circles) - - Pyramid/hierarchy - - Spectrum/continuum - - Triangle (three-way balance) - - Other conceptual shape - -2. **What are the dimensions/concepts?** - - For 2x2: X-axis concept, Y-axis concept - - For Venn: Circle 1 concept, Circle 2 concept, overlap meaning - - For pyramid: Levels from bottom to top - -3. **What are the quadrants/areas/zones?** - - Name and describe each region - - Which is "optimal" or most important? - -**Output:** -``` -FRAMEWORK TYPE: [2x2 Matrix / Venn Diagram / Pyramid / etc.] - -FRAMEWORK NAME: "The [Your Name] Framework for [Topic]" - -DIMENSIONS: -- X-axis: [Concept] (Low → High) -- Y-axis: [Concept] (Low → High) - -QUADRANTS/AREAS: -1. [Name]: [Description] — [Color if highlighted] -2. [Name]: [Description] — [Color if highlighted] -3. [Name]: [Description] -4. [Name]: [Description] - -OPTIMAL ZONE: [Which quadrant/area is ideal] -``` - ---- - -### Step 2: Design Framework Visual - -**Plan the visual representation:** - -1. **Framework geometry:** - - How large is each element - - Proportions and spacing - - Symmetry or intentional asymmetry - -2. **Labeling strategy:** - - Where axis labels go - - Where quadrant names go - - Additional annotations - -3. **Color assignment:** - - Which quadrant gets purple (optimal) - - Which gets teal (contrast or secondary) - - Rest remain black/white - -**Output:** -``` -VISUAL STRUCTURE: -[Describe the framework shape, e.g.:] -- Two intersecting axes forming four quadrants -- X-axis labeled [left] to [right] -- Y-axis labeled [bottom] to [top] -- Each quadrant labeled with concept name - -COLOR CODING: -- Top-right quadrant (optimal): Purple #4A148C accent -- Bottom-left quadrant (contrast): Teal #00796B accent -- Other quadrants: Black structure only - -TYPOGRAPHY PLACEMENT: -- Title (Tier 1): Top center -- Axis labels (Tier 2): Along axes -- Quadrant labels (Tier 2): Inside each quadrant -- Annotations (Tier 3): Strategic notes on key quadrants -``` - ---- - -### Step 3: Construct Prompt - -### Prompt Template - -``` -Hand-drawn conceptual framework diagram in editorial style. - -STYLE REFERENCE: Mental model illustration, conceptual diagram with personality, smart person's framework sketch - -BACKGROUND: [White #FFFFFF OR Light Cream #F5E6D3] — clean, flat - -AESTHETIC: -- Hand-drawn framework structure (wobbly lines, organic shapes) -- Variable stroke weight (axes thicker, details thinner) -- Imperfect but intentional geometry (circles not perfect, axes slightly wavy) -- Editorial flat color with strategic purple/teal accents -- Clear conceptual structure with human touch - -FRAMEWORK TYPE: [2x2 Matrix / Venn Diagram / Pyramid / Spectrum / etc.] - -FRAMEWORK STRUCTURE: -[Describe the specific framework geometry, e.g.:] -- Two hand-drawn perpendicular axes (black) forming cross -- X-axis: [Low concept] on left → [High concept] on right -- Y-axis: [Low concept] on bottom → [High concept] on top -- Four quadrants created by intersection - -TYPOGRAPHY SYSTEM (3-TIER): - -TIER 1 - FRAMEWORK TITLE (Advocate Block Display): -- "[FRAMEWORK NAME IN ALL-CAPS]" -- Font: Advocate style, extra bold, hand-lettered, all-caps -- Size: 3x larger than body text -- Color: Black #000000 -- Position: Top center -- Example: "THE SECURITY VS CONVENIENCE FRAMEWORK" - -TIER 2 - LABELS & CONCEPTS (Concourse Sans): -- Axis labels: "[X-axis concept]", "[Y-axis concept]" -- Quadrant names: "[Quadrant 1]", "[Quadrant 2]", etc. -- Font: Concourse geometric sans-serif -- Size: Medium readable -- Color: Charcoal #2D2D2D -- Position: Along axes and inside quadrants - -TIER 3 - ANNOTATIONS (Advocate Condensed Italic): -- Insight notes: "*optimal zone*", "*avoid this quadrant*" -- Font: Advocate condensed italic -- Size: 60% of Tier 2 -- Color: Purple #4A148C or Teal #00796B for emphasis -- Position: Near relevant quadrants/areas - -QUADRANTS/AREAS TO SHOW: -[List each region with description, e.g.:] - -TOP-RIGHT QUADRANT: -- Label: "[Name]" -- Description: [What this represents] -- Color: Purple (#4A148C) subtle accent/highlight — OPTIMAL ZONE -- Annotation: "*ideal state*" in purple italic - -TOP-LEFT QUADRANT: -- Label: "[Name]" -- Description: [What this represents] -- Color: Black structure only - -BOTTOM-RIGHT QUADRANT: -- Label: "[Name]" -- Description: [What this represents] -- Color: Teal (#00796B) subtle accent — CONTRAST ZONE - -BOTTOM-LEFT QUADRANT: -- Label: "[Name]" -- Description: [What this represents] -- Color: Black structure only - -[Adjust based on framework type - Venn would describe circles, pyramid would describe levels, etc.] - -COLOR USAGE: -- Black (#000000) for all framework structure (axes, circles, lines) -- Deep Purple (#4A148C) for [optimal zone] — subtle fill or accent -- Deep Teal (#00796B) for [contrast zone] — subtle accent -- Charcoal (#2D2D2D) for all text except emphasized annotations - -CRITICAL REQUIREMENTS: -- Hand-drawn imperfect geometry (NOT digital precision) -- Framework structure immediately recognizable -- Clear labels in 3-tier typography hierarchy -- Strategic color on 1-2 key zones only (subtle, not solid fills) -- No gradients, flat colors only -- Editorial illustration aesthetic maintained -- Conceptually clear and memorable - -Optional: Sign small in bottom right corner in charcoal (#2D2D2D). -``` - ---- - -### Step 4: Determine Aspect Ratio - -| Framework Type | Aspect Ratio | Reasoning | -|----------------|--------------|-----------| -| 2x2 Matrix | 1:1 | Square for balanced quadrants | -| Venn Diagram | 1:1 | Square for circular symmetry | -| Pyramid | 1:1 or 4:3 | Vertical emphasis | -| Horizontal spectrum | 16:9 | Wide for left-right continuum | -| Triangle | 1:1 | Balanced for three concepts | - -**Default: 1:1 (square)** — Works for most framework types - ---- - -### Step 5: Execute Generation - -```bash -bun run ~/.opencode/skills/Art/Tools/Generate.ts \ - --model nano-banana-pro \ - --prompt "[YOUR PROMPT]" \ - --size 2K \ - --aspect-ratio 1:1 \ - --output /path/to/framework.png -``` - -**Model Recommendation:** nano-banana-pro (best text rendering for labels) - -**Immediately Open:** -```bash -open /path/to/framework.png -``` - ---- - -### Step 6: Validation (MANDATORY) - -#### Must Have -- [ ] **Framework structure clear** — 2x2 / Venn / Pyramid immediately recognizable -- [ ] **Readable labels** — All text legible in 3-tier hierarchy -- [ ] **Hand-drawn aesthetic** — Imperfect lines, organic shapes, human quality -- [ ] **Strategic color** — Purple on optimal zone, teal on contrast, not everywhere -- [ ] **Conceptually memorable** — This becomes THE reference image for framework -- [ ] **Editorial style** — Maintains UL flat color, black linework aesthetic - -#### Must NOT Have -- [ ] Perfect digital geometry (too clean) -- [ ] Illegible or cluttered text -- [ ] Color overload (solid fills everywhere) -- [ ] Confusing structure (can't identify framework type) -- [ ] Corporate/boring diagram look -- [ ] Gradients or shadows - -#### If Validation Fails - -| Problem | Fix | -|---------|-----| -| Too precise/digital | "Hand-drawn wobbly axes, organic imperfect circles, human sketch quality" | -| Text unreadable | Increase label sizes, simplify annotations | -| Over-colored | "Subtle purple accent on optimal zone only, rest black structure" | -| Confusing structure | Simplify framework, stronger geometry cues | -| Looks corporate | Reference "editorial conceptual illustration, Saul Steinberg style" | -| Not memorable | Add strategic annotation showing the insight: "*this is the sweet spot*" | - ---- - -## Example Use Cases - -### Example 1: "Security vs Convenience Framework" -- **Type:** 2x2 matrix -- **Axes:** Security (low → high), Convenience (low → high) -- **Quadrants:** Vulnerable, Fortress, Balanced (purple), Abandoned -- **Color:** Purple on "Balanced" optimal quadrant -- **Aspect:** 1:1 - -### Example 2: "Human 3.0 Capability Venn" -- **Type:** Venn diagram (3 circles) -- **Circles:** Human abilities, AI capabilities, Tools -- **Overlap:** Where magic happens (purple) -- **Color:** Purple on center overlap -- **Aspect:** 1:1 - -### Example 3: "Threat Modeling Pyramid" -- **Type:** Pyramid (4 levels) -- **Levels:** Assets (bottom) → Threats → Vulnerabilities → Mitigations (top) -- **Color:** Purple on top level (actions), teal on bottom (foundation) -- **Aspect:** 4:3 - ---- - -## Quick Reference - -**Framework Formula:** -``` -1. Define framework structure (type, dimensions, quadrants) -2. Design visual (geometry, labeling, color assignment) -3. Construct prompt with clear structure -4. Choose square aspect ratio (usually 1:1) -5. Generate with nano-banana-pro -6. Validate for clarity and memorability -``` - -**Color Strategy:** -- Framework structure: Black -- Optimal zone: Purple (subtle accent) -- Contrast zone: Teal (subtle accent) -- Text: Charcoal (except emphasized annotations) - -**Key Principle:** -- This becomes THE reference image people remember for this framework -- Must be conceptually clear AND visually distinctive - ---- - -**The workflow: Define → Design → Construct → Generate → Validate → Complete** diff --git a/.opencode/skills/Art/Workflows/Maps.md b/.opencode/skills/Art/Workflows/Maps.md deleted file mode 100755 index 24b6ca0a..00000000 --- a/.opencode/skills/Art/Workflows/Maps.md +++ /dev/null @@ -1,415 +0,0 @@ -# Conceptual Maps & Landscapes Workflow - -**Hand-drawn conceptual maps showing idea territories and domain landscapes using UL aesthetic.** - -Creates **CONCEPTUAL MAPS** — illustrated maps of idea territories, not geographic locations, with editorial hand-drawn style. - ---- - -## Purpose - -Conceptual maps visualize abstract territories, domains, and relationships as illustrated landscapes. These are **metaphorical maps** showing where ideas, concepts, or domains exist in relation to each other. - -**Use this workflow for:** -- "The Landscape of AI Safety" -- "Map of Cybersecurity Domains" -- "Territory of Human Capabilities" -- Domain overviews showing relationships -- Conceptual geography of a field -- Orientation guides for complex topics - ---- - -## Visual Aesthetic: Illustrated Cartography - -**Think:** Hand-drawn fantasy map, but for conceptual territories - -### Core Characteristics -1. **Map structure** — Islands, continents, rivers, mountains representing ideas -2. **Cartographic elements** — Borders, labels, landmarks -3. **Hand-drawn** — Imperfect coastlines, wobbly borders, human quality -4. **Metaphorical geography** — Physical features represent conceptual relationships -5. **Labeled territories** — Clear naming of domains/concepts -6. **Editorial style** — Flat colors, black linework, UL aesthetic -7. **Navigable** — Helps understand the "lay of the land" in a field - ---- - -## Color System for Conceptual Maps - -### Land/Territory -``` -Black #000000 — All coastlines, borders, terrain features -Light fills — Very subtle cream/beige for different territories -``` - -### Domain Differentiation -``` -Deep Purple #4A148C — Primary domain or "optimal" territory -Deep Teal #00796B — Secondary domain or adjacent territory -Charcoal #2D2D2D — All labels and annotations -``` - -### Background (Water/Space) -``` -Light Cream #F5E6D3 — Warm neutral "ocean" -OR -White #FFFFFF — Clean empty space around territories -``` - -### Color Strategy -- Coastlines/borders all black linework -- Territories subtly differentiated by color (purple, teal, or just labeled) -- Background as "ocean" or empty space -- Text all charcoal for readability - ---- - -## 🚨 MANDATORY WORKFLOW STEPS - -### Step 1: Define Conceptual Geography - -**Identify the territories:** - -1. **What domain are you mapping?** - - Subject area (e.g., AI capabilities, security landscape) - - What are the major territories/concepts - -2. **What are the territories?** - - List 4-8 major domains/concepts - - How do they relate spatially - -3. **What metaphors represent relationships?** - - Close territories = related concepts - - Ocean between = very different domains - - Mountains = barriers or challenges - - Rivers = connections or flows - - Bridges = integrations - -**Output:** -``` -MAP SUBJECT: "The [Domain] Landscape" - -TERRITORIES (Major Domains): -1. [Territory name] — [What it represents] -2. [Territory name] — [What it represents] -3. [Territory name] — [What it represents] -... - -SPATIAL RELATIONSHIPS: -- [Territory A] and [Territory B]: Adjacent (related concepts) -- [Territory C]: Island (isolated domain) -- Ocean between [X] and [Y]: Very different domains -- Mountain range along [Z]: Barrier/challenge - -METAPHORICAL FEATURES: -- Rivers: [What they represent, e.g., "data flows"] -- Mountains: [What they represent, e.g., "technical barriers"] -- Bridges: [What they represent, e.g., "integration points"] -``` - ---- - -### Step 2: Design Map Layout - -**Plan the cartography:** - -1. **Map orientation:** - - North-up traditional - - Centered around key territory - - Horizontal spread - - Vertical layers - -2. **Territory shapes:** - - Continents (large connected domains) - - Islands (isolated concepts) - - Archipelagos (related cluster) - - Peninsulas (partially connected) - -3. **Features to include:** - - Coastlines/borders - - Landmarks (mountains, rivers) - - Labels for territories - - Legend or compass rose - -**Output:** -``` -MAP ORIENTATION: [North-up / Centered / Horizontal] - -TERRITORY LAYOUT: -[Describe the spatial arrangement, e.g.:] -- Center: Large continent of [Primary Domain] (purple) -- East: Island of [Domain 2] (teal) -- West: Peninsula of [Domain 3] connected to center -- North: Mountain range representing [Barrier] -- South: Ocean of [Unknown Territory] - -FEATURES: -- Coastlines: All hand-drawn, wobbly, imperfect -- Rivers: [Number] rivers showing [connections] -- Mountains: Along [borders] representing [challenges] -- Bridges: Connecting [Territory A] to [Territory B] - -LABELS: -- Territory names inside borders (Tier 2) -- Feature labels for mountains, rivers (Tier 3) -- Map title at top (Tier 1) - -COLOR CODING: -- [Primary territory]: Purple (#4A148C) subtle fill -- [Secondary territory]: Teal (#00796B) subtle fill -- Other territories: Light cream or white -- All borders/coastlines: Black -``` - ---- - -### Step 3: Construct Prompt - -### Prompt Template - -``` -Hand-drawn conceptual map in editorial cartography style. - -STYLE REFERENCE: Fantasy map, hand-drawn cartography, illustrated territory map - -BACKGROUND: [Light Cream #F5E6D3 / White #FFFFFF] — represents ocean/empty space - -AESTHETIC: -- Hand-drawn map (wobbly coastlines, imperfect borders) -- Cartographic elements (territories, features, labels) -- Variable stroke weight (coastlines thicker, details thinner) -- Editorial flat color with strategic purple/teal territories -- Sketch quality, not polished digital map - -MAP SUBJECT: "[The X Landscape]" or "[Map of Y Domains]" - -CARTOGRAPHIC STRUCTURE: -[Describe the overall map, e.g.:] -- Central large landmass: [Primary Domain] -- Surrounding islands and territories representing related concepts -- Ocean/empty space between distant domains -- Physical features (mountains, rivers, bridges) showing relationships - -TYPOGRAPHY SYSTEM (3-TIER): - -TIER 1 - MAP HEADER & SUBTITLE (Valkyrie Two-Part System): -Header (Main Title): -- "[Header Text]" — Left-justified at top -- Font: Valkyrie serif italic (elegant, sophisticated) -- Size: Large - 3-4x body text (prominent, commanding attention) -- Style: Italicized, sentence case or title case (NOT all-caps) -- Color: Black #000000 (or Purple #4A148C for emphasis) -- Position: Top-left with margin -- Example: "The Landscape of Artificial Intelligence" - -Subtitle (Clarifying Detail): -- "[Subtitle Text]" — Below header -- Font: Valkyrie serif regular (warm, readable) -- Size: Small - 1-1.5x body text (noticeably smaller than header, supportive) -- Style: Regular (NOT italicized), sentence case (first letter capitalized, rest lowercase except proper nouns) -- Color: Black #000000 or Charcoal #2D2D2D -- Position: Small gap below header, aligned left -- Example: "Domains, Territories, and Frontiers" - -TIER 2 - TERRITORY NAMES (Concourse Sans): -- Territory labels: "[Domain 1]", "[Domain 2]", etc. -- Font: Concourse geometric sans-serif -- Size: Medium readable -- Color: Charcoal #2D2D2D -- Position: Inside territory borders or nearby - -TIER 3 - FEATURE LABELS (Advocate Condensed Italic): -- Geographic features: "*mountains of complexity*", "*river of data*" -- Font: Advocate condensed italic -- Size: 60% of Tier 2 -- Color: Charcoal #2D2D2D -- Position: Near relevant features - -TERRITORIES TO MAP: -[List each territory with details, e.g.:] - -CENTRAL TERRITORY: [Primary Domain Name] -- Shape: Large irregular continent in center of map -- Coastline: Hand-drawn wobbly black line -- Fill: Subtle Purple (#4A148C) tint (very light, not solid) -- Features: [Mountains / Rivers / Landmarks within] -- Label: "[Domain name]" in Concourse sans -- Represents: [Core concept] - -EASTERN TERRITORY: [Secondary Domain Name] -- Shape: Medium island separated by ocean from center -- Coastline: Hand-drawn irregular outline -- Fill: Subtle Teal (#00796B) tint -- Features: [Specific landmarks] -- Label: "[Domain name]" -- Represents: [Related but distinct concept] - -WESTERN TERRITORY: [Domain Name] -- Shape: Peninsula connected to central continent -- Coastline: Wobbly black line -- Fill: Light cream or white (minimal color) -- Connection: Narrow land bridge to center -- Label: "[Domain name]" -- Represents: [Partially connected concept] - -[Continue for all territories...] - -GEOGRAPHIC FEATURES: -- Mountain range: Hand-drawn peaks along [border/territory] - - Represents: [Barrier or challenge] - - Color: Black (#000000) linework - - Label: "*mountains of [X]*" in italic - -- Rivers: Wobbly flowing lines connecting territories - - Represents: [Connections or data flows] - - Color: Black (#000000) or Teal (#00796B) - - Label: "*river of [Y]*" - -- Bridges: Small illustrated bridges connecting islands/territories - - Represents: [Integration points] - - Color: Black (#000000) - -- Compass rose: Small decorative compass in corner (optional) - - Hand-drawn, simple - - Purple (#4A148C) north arrow - -OCEAN/EMPTY SPACE: -- Background: Light cream or white -- Represents: Unknown territory or very different domains -- Blank areas between distant territories - -COLOR USAGE: -- Black (#000000) for ALL coastlines, borders, geographic features -- Deep Purple (#4A148C) subtle fill on [primary territory] -- Deep Teal (#00796B) subtle fill on [secondary territory] -- Light cream/white fills on other territories -- Charcoal (#2D2D2D) for all text labels - -CRITICAL REQUIREMENTS: -- Hand-drawn cartographic style (wobbly lines, imperfect shapes) -- Clear territory labels in 3-tier typography -- Physical features represent conceptual relationships -- Strategic color on 1-2 key territories (subtle fills, not solid) -- No gradients, flat colors only -- Navigable and understandable as conceptual geography -- Editorial illustration aesthetic maintained - -Optional: Sign small in bottom corner in charcoal (#2D2D2D). -``` - ---- - -### Step 4: Determine Aspect Ratio - -| Map Type | Aspect Ratio | Reasoning | -|----------|--------------|-----------| -| Wide horizontal landscape | 16:9 or 21:9 | Spread-out territories | -| Balanced map | 1:1 | Symmetric territory distribution | -| Vertical territories | 9:16 or 4:3 | Stacked or layered domains | -| Poster map | 4:3 | Classic map proportions | - -**Default: 16:9 (horizontal)** — Classic map orientation - ---- - -### Step 5: Execute Generation - -```bash -bun run ~/.opencode/skills/Art/Tools/Generate.ts \ - --model nano-banana-pro \ - --prompt "[YOUR PROMPT]" \ - --size 2K \ - --aspect-ratio 16:9 \ - --output /path/to/conceptual-map.png -``` - -**Model Recommendation:** nano-banana-pro (best for territory labels) or flux (stylistic variety) - -**Immediately Open:** -```bash -open /path/to/conceptual-map.png -``` - ---- - -### Step 6: Validation (MANDATORY) - -#### Must Have -- [ ] **Map structure clear** — Territories, coastlines, borders obvious -- [ ] **Conceptual geography** — Physical features represent ideas -- [ ] **Readable labels** — Territory names and feature labels legible -- [ ] **Hand-drawn** — Wobbly coastlines, imperfect borders, human quality -- [ ] **Strategic color** — Purple/teal on key territories (subtle fills) -- [ ] **Navigable** — Helps understand relationships between concepts -- [ ] **Editorial aesthetic** — Maintains UL flat color, black linework - -#### Must NOT Have -- [ ] Perfect digital map (too clean) -- [ ] Realistic geographic features -- [ ] Illegible territory names -- [ ] Color chaos (too many territory colors) -- [ ] Confusing metaphors (features don't represent concepts clearly) -- [ ] Gradients or shadows - -#### If Validation Fails - -| Problem | Fix | -|---------|-----| -| Too precise/digital | "Hand-drawn wobbly coastlines, imperfect irregular borders, sketch quality" | -| Unclear metaphors | Strengthen feature descriptions: "mountains represent [specific barrier]" | -| Labels unreadable | Increase label sizes, clearer placement inside territories | -| Too complex | Reduce to 4-6 major territories, simplify features | -| Looks like real map | "Conceptual geography, metaphorical territories, abstract cartography" | -| Missing relationships | Add rivers/bridges showing connections: "river connecting [A] to [B]" | - ---- - -## Example Use Cases - -### Example 1: "The AI Capabilities Landscape" -- **Territories:** Reasoning (center, purple), Creativity (island, teal), Perception (west peninsula), Action (east island) -- **Features:** Mountains of complexity, Rivers of data, Bridges of integration -- **Aspect:** 16:9 - -### Example 2: "Cybersecurity Domain Map" -- **Territories:** Offensive (red island), Defensive (center continent), Governance (north peninsula), Human Layer (south) -- **Features:** Ocean of unknown threats, Mountain range of technical barriers -- **Aspect:** 16:9 - -### Example 3: "The TELOS Territory" -- **Territories:** Questions (center), Context (surrounding), Blockers (west mountains), Constraints (north), Solutions (east coast) -- **Features:** Rivers connecting domains, Bridges from problems to solutions -- **Aspect:** 1:1 - ---- - -## Quick Reference - -**Conceptual Map Formula:** -``` -1. Define conceptual geography (territories, relationships, metaphors) -2. Design map layout (orientation, shapes, features) -3. Construct prompt with cartographic structure -4. Choose aspect ratio for map type -5. Generate with nano-banana-pro -6. Validate for clarity and navigability -``` - -**Color Strategy:** -- Coastlines/borders: Black -- Primary territory: Purple (subtle fill) -- Secondary territory: Teal (subtle fill) -- Other territories: Light/white -- Labels: Charcoal - -**Metaphor Key:** -- Physical proximity = conceptual relationship -- Ocean = very different domains -- Mountains = barriers/challenges -- Rivers = connections/flows -- Bridges = integration points - ---- - -**The workflow: Define → Design → Construct → Generate → Validate → Complete** diff --git a/.opencode/skills/Art/Workflows/Mermaid.md b/.opencode/skills/Art/Workflows/Mermaid.md deleted file mode 100755 index 5e4aac7b..00000000 --- a/.opencode/skills/Art/Workflows/Mermaid.md +++ /dev/null @@ -1,896 +0,0 @@ -# Mermaid-Style Technical Diagrams with Excalidraw Aesthetic - -**Hand-drawn technical diagrams combining Mermaid structure with Excalidraw sketchy aesthetic and UL color scheme.** - -Creates **EXCALIDRAW-STYLE MERMAID DIAGRAMS** — flowcharts, sequence diagrams, state machines, and other technical diagrams with whiteboard hand-drawn feel, derived from content via story explanation. - ---- - -## Purpose - -The Mermaid workflow creates structured technical diagrams (like Mermaid.js generates) but with a **hand-drawn whiteboard aesthetic** (like Excalidraw) while maintaining **UL editorial color scheme**. Unlike generic technical diagrams, these follow specific diagram grammar (flowcharts, sequences, states, etc.) and are derived from content analysis, not hand-specified. - -**Use this workflow for:** -- Flowcharts showing decision logic and process flows -- Sequence diagrams showing interactions over time -- State diagrams showing state transitions -- Class diagrams showing object relationships -- ER diagrams showing data models -- Git graphs showing branching/merging -- Any diagram where Mermaid structure + hand-drawn aesthetic is ideal - -**This is NOT for:** -- Freeform architecture diagrams (use technical-diagrams.md) -- Abstract conceptual metaphors (use editorial-illustration.md) -- Data visualizations (use visualize.md) - ---- - -## Mermaid Diagram Types Supported - -### 1. Flowcharts -**When:** Decision trees, algorithmic logic, process flows with conditions -``` -Start → Decision? → [Yes] → Action → End - → [No] → Different Action → End -``` - -### 2. Sequence Diagrams -**When:** Interactions between entities/actors over time -``` -User → API: Request -API → Database: Query -Database → API: Results -API → User: Response -``` - -### 3. State Diagrams -**When:** State machines, status transitions, lifecycle flows -``` -[Idle] → (trigger) → [Processing] → (complete) → [Done] - → (error) → [Failed] -``` - -### 4. Class Diagrams -**When:** Object relationships, inheritance, composition -``` -User ──has many──> Posts -User ──belongs to──> Organization -Post ──has many──> Comments -``` - -### 5. Entity Relationship Diagrams -**When:** Database schemas, data models, table relationships -``` -Customer ||──o{ Order : places -Order ||──o{ LineItem : contains -Product ||──o{ LineItem : ordered_in -``` - -### 6. Gantt Charts -**When:** Project timelines, task dependencies, schedules -``` -Task 1: Jan 1 - Jan 15 -Task 2: Jan 10 - Jan 30 (depends on Task 1) -Task 3: Jan 20 - Feb 10 -``` - -### 7. Git Graphs -**When:** Branching strategies, merge flows, version control -``` -main ──> feature branch ──> merged back ──> main - └──> hotfix ──────────> merged ──────> main -``` - ---- - -## Excalidraw Aesthetic Principles - -**Think:** Whiteboard sketch, not polished Visio diagram - -### Visual Characteristics -1. **Wobbly boxes** — Rectangles with rough, hand-drawn edges (not perfect) -2. **Sketchy arrows** — Arrows with slight wobble, not ruler-straight -3. **Rough edges** — Everything has organic imperfection -4. **Hand-lettered text** — Labels look handwritten, not typed -5. **Whiteboard feel** — Looks like someone drew this on a whiteboard -6. **Variable line weight** — Heavier for boxes, lighter for arrows -7. **Crossing-out style** — Double-line or rough crossing for connections - -### What This Looks Like -- Diamond decision boxes with wobbly edges -- Arrows that curve slightly even when "straight" -- Rectangles that aren't quite rectangular -- Text that's imperfectly aligned -- Circles that are slightly oval -- Lines that overlap at connections with organic joins - -### AVOID -- Perfect geometric shapes -- Ruler-straight arrows -- Digital precision -- Smooth curves (too polished) -- Perfect alignment -- Vector crispness - ---- - -## Color System for Mermaid Diagrams - -### Structure -``` -Black #000000 — All primary linework (boxes, arrows, decision diamonds) -``` - -### Flow Emphasis -``` -Deep Purple #4A148C — Critical path, main flow, important states -Deep Teal #00796B — Alternative paths, secondary flows, supporting states -Charcoal #2D2D2D — All text labels and annotations -``` - -### Background -``` -Light Cream #F5E6D3 — Whiteboard/sketch paper feel -OR -White #FFFFFF — Clean background -``` - -### Color Strategy for Diagram Types - -**Flowcharts:** -- Main path boxes: Purple outlines -- Alternative branches: Teal outlines -- Decision diamonds: Black outlines -- All connecting arrows: Black - -**Sequence Diagrams:** -- Critical actor/entity: Purple box -- Secondary actors: Teal boxes -- All messages/arrows: Black -- Activation boxes: Purple fills (subtle) - -**State Diagrams:** -- Active/important states: Purple -- Transition states: Teal -- Terminal states: Black -- Arrows: Black with labels - -**Class/ER Diagrams:** -- Key entities: Purple boxes -- Related entities: Teal boxes -- Relationships: Black arrows with labels -- Inheritance: Black with different arrow style - ---- - -## 🚨 MANDATORY WORKFLOW STEPS - -### Step 1: Run Story Explanation on Content (MANDATORY) - -**🎯 CRITICAL: You MUST use /cse (Create Story Explanation) with 24-item length.** - -This extracts the full narrative arc and identifies the STRUCTURE that needs to be diagrammed. - -```bash -/cse [content or URL] -``` - -The 24-item output reveals: -- Process flows and sequences -- Decision points and conditions -- State transitions and triggers -- Entity relationships and interactions -- Temporal ordering and dependencies - -**Do NOT skip this step. Do NOT manually derive diagram structure without running /cse first.** - -**Output from CSE Analysis:** -``` -24-ITEM STORY EXPLANATION: -1. [Item 1] -2. [Item 2] -... -24. [Item 24] - -STRUCTURAL ELEMENTS IDENTIFIED: -- Processes: [List of distinct processes/actions] -- Decisions: [List of decision points with conditions] -- States: [List of distinct states] -- Entities: [List of actors/objects/components] -- Flows: [List of connections and sequences] -- Conditions: [List of triggers and transitions] -``` - ---- - -### Step 2: Determine Optimal Mermaid Diagram Type - -**Based on CSE analysis, identify the best diagram type:** - -#### Decision Framework - -**Choose FLOWCHART when:** -- Content describes process with decision points -- "If/then/else" logic is present -- Multiple paths based on conditions -- Algorithm or procedure being explained -- Clear start and end points - -**Choose SEQUENCE DIAGRAM when:** -- Content describes interactions between entities over time -- Request/response patterns present -- Multiple actors communicating -- Temporal ordering is critical -- API calls, messaging, or protocols - -**Choose STATE DIAGRAM when:** -- Content describes states and transitions -- Status changes are central -- Lifecycle or workflow states -- Event-driven transitions -- System can be in discrete states - -**Choose CLASS/ER DIAGRAM when:** -- Content describes relationships between objects/entities -- Data structures or models -- Inheritance or composition patterns -- Database schemas -- Object hierarchies - -**Choose GANTT CHART when:** -- Content describes project timeline -- Task dependencies and schedules -- Milestones and deadlines -- Parallel and sequential tasks - -**Choose GIT GRAPH when:** -- Content describes version control workflow -- Branching strategies -- Merge patterns -- Release flows - -**Multiple diagram types possible?** -- Choose the PRIMARY type that captures the main structure -- Can note that alternative representations exist -- Focus on the most illuminating visualization - -**Output from Type Selection:** -``` -DIAGRAM TYPE: [Flowchart / Sequence / State / Class / ER / Gantt / Git Graph] - -RATIONALE: [Why this type best represents the content] - -ALTERNATIVE TYPES CONSIDERED: [If any, and why not chosen] -``` - ---- - -### Step 3: Extract Diagram Structure from CSE - -**Map the 24-item story explanation to diagram components:** - -#### For Flowcharts -Identify: -- **Start node:** Where does the process begin? -- **Process nodes:** What actions happen? (rectangles) -- **Decision nodes:** What choices are made? (diamonds) -- **End nodes:** Where does it terminate? (rounded rectangles) -- **Flows:** How do nodes connect? (arrows with labels) - -#### For Sequence Diagrams -Identify: -- **Actors/Entities:** Who/what participates? (boxes at top) -- **Messages:** What communications occur? (arrows between lifelines) -- **Temporal order:** What sequence? (top to bottom) -- **Activations:** When are entities active? (vertical bars) - -#### For State Diagrams -Identify: -- **States:** What are the distinct states? (rounded boxes) -- **Initial state:** Where does it start? (filled circle) -- **Final state:** Where does it end? (double circle) -- **Transitions:** What triggers state changes? (arrows with conditions) -- **Events:** What causes transitions? - -#### For Class/ER Diagrams -Identify: -- **Entities/Classes:** What objects exist? (boxes) -- **Attributes:** What properties? (inside boxes) -- **Relationships:** How do they relate? (arrows with cardinality) -- **Inheritance:** What hierarchies? (special arrows) - -**Output from Structure Extraction:** -``` -DIAGRAM COMPONENTS: - -[For Flowchart Example:] -NODES: -- Start: [Label] -- Process 1: [Action description] (rectangle, purple) -- Decision 1: [Question] (diamond, black) -- Process 2a: [Action if yes] (rectangle, purple) -- Process 2b: [Action if no] (rectangle, teal) -- End: [Terminal state] (rounded, black) - -FLOWS: -- Start → Process 1: (black arrow) -- Process 1 → Decision 1: (black arrow) -- Decision 1 → Process 2a: "Yes" (black arrow) -- Decision 1 → Process 2b: "No" (black arrow) -- Process 2a → End: (black arrow) -- Process 2b → End: (black arrow) - -CRITICAL PATH: [Start → Process 1 → Decision 1 → Process 2a → End] -(This path highlighted with purple boxes) -``` - ---- - -### Step 4: Design Excalidraw-Style Layout - -**Plan the whiteboard sketch aesthetic:** - -#### A. Spatial Arrangement -- **Flowcharts:** Top-to-bottom or left-to-right flow -- **Sequence diagrams:** Actors across top, interactions descending -- **State diagrams:** Circular or network layout -- **Class diagrams:** Hierarchical tree or interconnected network -- **ER diagrams:** Entities spread out with relationships between -- **Gantt:** Horizontal timeline with tasks stacked vertically -- **Git graph:** Branching tree structure - -#### B. Hand-Drawn Styling -Each node type gets Excalidraw treatment: - -**Rectangles (Process boxes):** -``` -Instead of: ┌──────────┐ -This: ╱──────────╲ (wobbly, not perfect) - │ Process │ (slightly tilted) - ╲──────────╱ (organic edges) -``` - -**Diamonds (Decisions):** -``` -Instead of: ◇ -This: ◊ (wobbly, asymmetric, hand-drawn diamond) -``` - -**Arrows:** -``` -Instead of: ────────→ -This: ∼∼∼∼∼∼∼→ (slightly wavy, organic curve) -``` - -**Text:** -``` -Instead of: Arial 12pt -This: Hand-lettered appearance, slight slant, imperfect -``` - -#### C. Visual Hierarchy -- **Primary path/flow:** Purple boxes, thicker lines -- **Secondary paths:** Teal boxes, standard lines -- **Structure/framework:** Black lines and shapes -- **Labels/text:** Charcoal, hand-lettered style - -**Output from Layout Design:** -``` -SPATIAL LAYOUT: [Top-to-bottom flow / Left-to-right / Circular / etc.] - -EXCALIDRAW STYLING NOTES: -- All boxes: Wobbly rectangles, slightly tilted -- Arrows: Gentle curves even when "straight" -- Diamonds: Asymmetric, hand-drawn feel -- Circles: Slightly oval, imperfect -- Text: Hand-lettered, natural slant - -NODE POSITIONING: -[Describe relative positions, e.g.:] -- Start node: Top center -- Process 1: Below start, slightly left -- Decision 1: Below process 1, centered -- Process 2a: Bottom left (Yes branch) -- Process 2b: Bottom right (No branch) -- End nodes: Bottom (two endpoints merge) - -CONNECTION PATHS: -[Describe arrow routes with organic curves] -``` - ---- - -### Step 5: Construct Comprehensive Prompt - -**Build the generation prompt with Excalidraw + Mermaid + UL aesthetic:** - -### Prompt Template - -``` -Hand-drawn Mermaid [DIAGRAM TYPE] in Excalidraw whiteboard sketch style. - -STYLE REFERENCE: Excalidraw whiteboard diagram, hand-drawn flowchart, sketchy technical diagram - -BACKGROUND: [Light Cream #F5E6D3 / White #FFFFFF] — whiteboard/sketch paper feel - -AESTHETIC: -- Excalidraw hand-drawn style (wobbly, sketchy, organic) -- Whiteboard sketch quality (looks hand-drawn, not digital) -- Rough edges on all shapes (rectangles not perfect, circles slightly oval) -- Sketchy arrows (gentle curves, slight wobble, not ruler-straight) -- Hand-lettered text labels (imperfect alignment, natural slant) -- Variable line weight (boxes thicker, arrows medium, details thinner) -- Organic connections (lines join naturally, small overlaps at nodes) -- NO digital precision, NO perfect geometry, NO smooth vectors - -DIAGRAM TYPE: [Flowchart / Sequence Diagram / State Diagram / etc.] - -OVERALL STRUCTURE: -[Describe the complete diagram flow, e.g.:] -- [DIAGRAM TYPE] showing [what it represents] -- Layout: [Top-to-bottom / Left-to-right / etc.] -- [Number] main nodes/states/entities -- Critical path highlighted in purple -- Alternative paths in teal - -TYPOGRAPHY SYSTEM (4-FONT HIERARCHY): - -TIER 1 - DIAGRAM HEADER & SUBTITLE (Valkyrie Two-Part System): -Header (Main Title): -- "[Header Text]" -- Font: Valkyrie serif italic (elegant, sophisticated) -- Size: Large - 3-4x body text (prominent, commanding attention) (refined, not overwhelming) -- Style: Italicized, sentence case or title case (NOT all-caps) -- Color: Black #000000 (or Purple #4A148C for emphasis) -- Position: Top-left with margin -- Example: "User Authentication Flow" - -Subtitle (Clarifying Detail): -- "[Subtitle Text]" -- Font: Valkyrie serif regular (warm, readable) -- Size: Small - 1-1.5x body text (noticeably smaller than header, supportive) -- Style: Regular (NOT italicized), sentence case (first letter capitalized, rest lowercase except proper nouns) -- Color: Black #000000 or Charcoal #2D2D2D -- Position: Small gap below header, aligned left -- Example: "Security Validation Process" - -TIER 2 - NODE LABELS & DESCRIPTIONS (Concourse T3 + Valkyrie): -Technical Node Labels — Concourse T3: -- Labels inside boxes/nodes for technical identifiers -- Font: Concourse T3 geometric sans, functional, precise -- Size: Medium readable -- Color: Charcoal #2D2D2D -- Style: Hand-drawn interpretation, slightly imperfect -- Examples: "Auth Service", "Database", "API Gateway" - -Human/Process Descriptions — Valkyrie serif: -- Process descriptions, human-readable actions -- Font: Valkyrie serif, warm, narrative -- Size: Medium (same as Concourse T3) -- Color: Charcoal #2D2D2D -- Style: Natural, readable, explanatory -- Examples: "Validate credentials", "Check permissions", "Send confirmation" - -TIER 3 - EDGE LABELS & ANNOTATIONS (Advocate Italic + Valkyrie): -Edge Labels/Conditions — Advocate Condensed (or Valkyrie): -- Labels on arrows/connections, conditions -- Font: Advocate condensed (voice) or Valkyrie (neutral) -- Size: 60% of Tier 2 -- Color: Charcoal #2D2D2D -- Style: Hand-written notes along arrows -- Examples: "Yes", "No", "timeout", "success", "error" - -Insights/Commentary — Advocate Italic: -- Critical observations, editorial voice -- Font: Advocate condensed italic -- Size: 60% of Tier 2 -- Color: Purple #4A148C or Teal #00796B -- Examples: "*this is where it breaks*", "*performance bottleneck*" - -DIAGRAM COMPONENTS (Excalidraw Style): - -[LIST EACH NODE/COMPONENT:] - -NODE 1: [Type - e.g., START NODE] -- Shape: [Rounded rectangle / Circle / etc.] -- Label: "[Label text]" -- Style: Wobbly hand-drawn edges, slightly asymmetric -- Color: Black (#000000) outline, no fill OR subtle cream fill -- Size: [Relative size] -- Position: [Location in layout] - -NODE 2: [Type - e.g., PROCESS BOX] -- Shape: Rectangle with rough edges -- Label: "[Action description]" -- Style: Wobbly lines, slightly tilted, hand-drawn imperfection -- Color: Purple (#4A148C) outline — CRITICAL PATH -- Fill: Light cream or transparent -- Size: [Relative size] -- Position: [Below Node 1] - -NODE 3: [Type - e.g., DECISION DIAMOND] -- Shape: Diamond/rhombus with wobbly edges -- Label: "[Question?]" -- Style: Hand-drawn, asymmetric diamond, organic edges -- Color: Black (#000000) outline -- Fill: Transparent or very light cream -- Size: [Relative size] -- Position: [Below Node 2, centered] - -NODE 4: [Type - e.g., PROCESS BOX - ALTERNATIVE PATH] -- Shape: Rectangle with rough edges -- Label: "[Alternative action]" -- Style: Wobbly lines, slightly tilted -- Color: Teal (#00796B) outline — SECONDARY PATH -- Fill: Light cream or transparent -- Size: [Relative size] -- Position: [To the side, alternative branch] - -NODE 5: [Type - e.g., END NODE] -- Shape: Rounded rectangle or double circle -- Label: "[Terminal state]" -- Style: Hand-drawn, organic curves -- Color: Black (#000000) outline -- Fill: Subtle fill or transparent -- Size: [Relative size] -- Position: [Bottom of diagram] - -[Continue for all nodes...] - -CONNECTIONS (Sketchy Arrows): - -ARROW 1: [Node A] → [Node B] -- Style: Sketchy hand-drawn arrow, slight curve even if "straight" -- Path: [Describe route, e.g., "curves gently from Node 1 down to Node 2"] -- Color: Black (#000000) -- Label: [Optional label text, e.g., "process" or condition] -- Arrowhead: Hand-drawn triangle, slightly asymmetric - -ARROW 2: [Node C] → [Node D] -- Style: Sketchy arrow with organic wobble -- Path: [Describe route] -- Color: Black (#000000) -- Label: "[Yes]" in small hand-written style -- Arrowhead: Rough triangle - -[Continue for all arrows/connections...] - -SPECIAL ELEMENTS (if applicable): - -[For Sequence Diagrams:] -- Actor boxes: Hand-drawn rectangles at top -- Lifelines: Dashed vertical lines (hand-drawn, wobbly) -- Activation boxes: Rectangles on lifelines (purple for key) -- Messages: Arrows between lifelines with labels - -[For State Diagrams:] -- Initial state: Filled circle (hand-drawn) -- Final state: Double circle (wobbly concentric circles) -- State boxes: Rounded rectangles with rough edges -- Transition arrows: Curved arrows with condition labels - -[For Class/ER Diagrams:] -- Class boxes: Three-section rectangles (wobbly dividers) -- Relationship lines: Different arrow styles for different relationships -- Cardinality labels: Hand-written "1", "*", "0..1", etc. - -COLOR USAGE (Strategic, UL Palette): -- Black (#000000): All primary structure (most boxes, all arrows) -- Deep Purple (#4A148C): Critical path nodes, main flow, key entities (10-20% of nodes) -- Deep Teal (#00796B): Alternative paths, secondary entities (5-10% of nodes) -- Charcoal (#2D2D2D): All text labels (node labels, arrow labels) -- Background: Light Cream (#F5E6D3) OR White (#FFFFFF) - -CRITICAL REQUIREMENTS: -- Excalidraw hand-drawn aesthetic (wobbly, sketchy, organic) -- Mermaid diagram structure ([chosen type] grammar) -- UL color scheme (purple for critical, teal for secondary, black structure) -- 3-tier typography (title, node labels, edge labels) -- Whiteboard sketch feel (not polished, not digital) -- All shapes imperfect (rectangles wobbly, circles oval, arrows curved) -- Variable line weight (thicker boxes, medium arrows, thin details) -- Hand-lettered text (natural slant, imperfect alignment) -- Strategic color (not everything colored, mostly black structure) -- Readable and clear despite sketch style -- Follows [Mermaid diagram type] conventions - -VALIDATION CHECKPOINTS: -- Does it look hand-drawn on a whiteboard (not digital)? -- Are all geometric shapes imperfect (wobbly edges)? -- Is the diagram type structure clear (flowchart/sequence/state/etc.)? -- Can you follow the flow/logic/sequence easily? -- Is the critical path obvious (purple highlights)? -- Are labels readable despite hand-lettered style? -- Does it maintain UL aesthetic (flat colors, no gradients)? - -Optional: Sign small in bottom right corner in charcoal (#2D2D2D). -``` - ---- - -### Step 6: Determine Aspect Ratio - -**Based on diagram type and complexity:** - -| Diagram Type | Typical Aspect Ratio | Reasoning | -|--------------|---------------------|-----------| -| Flowchart (vertical) | 9:16 or 4:3 | Top-to-bottom flow | -| Flowchart (horizontal) | 16:9 or 21:9 | Left-to-right flow | -| Sequence diagram | 16:9 | Actors across, time down | -| State diagram | 1:1 | Circular/network layout | -| Class diagram | 1:1 or 4:3 | Tree or network | -| ER diagram | 16:9 or 1:1 | Entity spread | -| Gantt chart | 16:9 or 21:9 | Timeline horizontal | -| Git graph | 16:9 | Branching horizontal | - -**Default: 16:9** — Works for most diagram types - ---- - -### Step 7: Generate with Nano Banana Pro - -**Execute with optimal model for text-heavy diagrams:** - -```bash -bun run ~/.opencode/skills/Art/Tools/Generate.ts \ - --model nano-banana-pro \ - --prompt "[YOUR COMPREHENSIVE PROMPT]" \ - --size 2K \ - --aspect-ratio [chosen ratio] \ - --output /path/to/mermaid-diagram.png -``` - -**Why Nano Banana Pro:** -- Best text rendering (critical for labels on nodes and arrows) -- Handles complex multi-element compositions -- Can render hand-drawn aesthetic while maintaining readability -- Excellent for technical diagrams with lots of labels - -**Background rules based on use case:** -``` -ONE-OFF / QUICK PREVIEW: Keep white background (#FFFFFF) -GOING INTO BLOG/WEBSITE: Remove background for transparency -``` - -**For blog/website use** — use the **Images skill** for background removal: - -```bash -bun ~/.opencode/skills/CORE/Tools/RemoveBg.ts /path/to/mermaid-diagram.png -``` - -**Immediately open:** -```bash -open /path/to/mermaid-diagram.png -``` - ---- - -### Step 8: Comprehensive Validation (MANDATORY) - -**Validate across all dimensions:** - -#### Diagram Correctness -- [ ] **Structure accurate:** Diagram follows [type] conventions -- [ ] **Logic clear:** Flow/sequence/states make sense -- [ ] **Complete:** All elements from CSE represented -- [ ] **Connections correct:** Arrows point to right places -- [ ] **Labels accurate:** Node and edge labels match content - -#### Excalidraw Aesthetic -- [ ] **Hand-drawn feel:** Looks sketched on whiteboard -- [ ] **Wobbly shapes:** No perfect rectangles/circles -- [ ] **Sketchy arrows:** Organic curves, not ruler-straight -- [ ] **Imperfect text:** Hand-lettered, natural slant -- [ ] **Variable line weight:** Thicker boxes, thinner details -- [ ] **Organic joins:** Connections look natural - -#### UL Editorial Style -- [ ] **Color strategic:** Purple on critical (10-20%), teal on secondary (5-10%) -- [ ] **Black dominant:** Most structure in black -- [ ] **Typography hierarchy:** 3 tiers clear -- [ ] **No gradients:** Flat colors maintained -- [ ] **Signature:** Present in corner (optional) - -#### Readability & Clarity -- [ ] **Labels readable:** All text legible despite hand-drawn style -- [ ] **Flow obvious:** Can follow the diagram easily -- [ ] **Critical path clear:** Purple highlights guide eye -- [ ] **Not cluttered:** Spacing adequate, not cramped -- [ ] **Scale works:** Readable at thumbnail and full-size - -#### If Validation Fails - -**Common issues and fixes:** - -| Problem | Diagnosis | Fix | -|---------|-----------|-----| -| **Too polished/digital** | Missing Excalidraw aesthetic | Emphasize: "Wobbly rectangles, sketchy arrows, hand-drawn on whiteboard, imperfect shapes" | -| **Perfect geometry** | Shapes too clean | "All rectangles with rough edges, circles slightly oval, organic imperfection throughout" | -| **Can't follow flow** | Unclear structure | Strengthen arrow directions, add labels, clarify critical path with purple | -| **Labels unreadable** | Text too sketchy or small | Increase label size, simplify hand-lettering: "Readable hand-lettered style" | -| **Wrong diagram type** | Doesn't match content | Return to Step 2, reconsider diagram type based on CSE | -| **Missing Mermaid structure** | Doesn't follow conventions | Add proper diagram grammar: decision diamonds for flowcharts, lifelines for sequence, etc. | -| **Color overload** | Too much purple/teal | Limit: "Purple on 2-3 critical nodes only, teal on 1-2 secondary, rest black" | -| **Looks generic** | Missing UL or Excalidraw style | Combine both: "Excalidraw wobbly whiteboard sketch + UL purple/teal strategic accents" | - -**Regeneration Process:** -1. Identify specific validation failures -2. Update prompt with targeted fixes from table -3. Regenerate with refined prompt -4. Re-validate against all checkpoints -5. Repeat until ALL validation criteria pass - -**CRITICAL: Do not declare completion until validation passes.** - ---- - -## Diagram Type Deep Dives - -### Flowchart Specifics - -**Node Types:** -- **Start/End:** Rounded rectangles (wobbly ovals) -- **Process:** Rectangles with rough edges -- **Decision:** Diamonds (asymmetric, hand-drawn) -- **Input/Output:** Parallelograms (tilted, wobbly) -- **Predefined Process:** Rectangles with double side lines - -**Flow Rules:** -- Always flows one direction (typically top-down or left-right) -- Arrows never cross if avoidable -- Decision diamonds have exactly 2 exits (Yes/No or True/False) -- Loops back with curved arrows - -**Color Strategy:** -- Purple: Main success/happy path -- Teal: Error handling or alternative paths -- Black: All decision nodes and structure - ---- - -### Sequence Diagram Specifics - -**Components:** -- **Actors/Entities:** Boxes at top (wobbly rectangles) -- **Lifelines:** Vertical dashed lines (hand-drawn, imperfect) -- **Messages:** Horizontal arrows between lifelines -- **Activations:** Vertical bars on lifelines (when entity is active) -- **Return messages:** Dashed arrows going back - -**Temporal Flow:** -- Always top to bottom (time flows down) -- Left to right is actor/entity ordering -- Synchronous: Solid arrow -- Asynchronous: Open arrow -- Return: Dashed arrow - -**Color Strategy:** -- Purple: Critical actor/main entity -- Teal: Secondary actors -- Black: All messages/arrows -- Purple fill: Activation bars for critical entity - ---- - -### State Diagram Specifics - -**Components:** -- **States:** Rounded rectangles (wobbly) -- **Initial state:** Filled circle (hand-drawn blob) -- **Final state:** Double circle (concentric wobbly circles) -- **Transitions:** Arrows with event labels -- **Conditions:** Guards in brackets on arrows - -**State Rules:** -- Each state is distinct and named -- Transitions show event/condition -- Initial state has only outgoing arrows -- Final state has only incoming arrows - -**Color Strategy:** -- Purple: Active/current/important states -- Teal: Intermediate states -- Black: Terminal and error states -- All transitions: Black arrows - ---- - -### Class/ER Diagram Specifics - -**Components:** -- **Classes/Entities:** Three-section boxes (name, attributes, methods) -- **Relationships:** Arrows with labels -- **Cardinality:** 1, *, 0..1, 1..* on relationship lines -- **Inheritance:** Triangle arrow pointing to parent -- **Composition:** Diamond on containing class - -**Relationship Types:** -- Association: Plain arrow -- Inheritance: Arrow with triangle head -- Composition: Arrow with filled diamond -- Aggregation: Arrow with open diamond - -**Color Strategy:** -- Purple: Core/important entities -- Teal: Related entities -- Black: All relationship lines -- Charcoal: All attribute/method text - ---- - -## Example Scenarios - -### Example 1: Flowchart for Authentication Flow -**Content:** Blog post about user authentication process -**CSE Result:** 24-item story showing login attempt → credential check → success/failure paths -**Diagram Type:** Flowchart -**Structure:** Start → Enter Credentials → Valid? → [Yes] → Generate Token → Success - → [No] → Retry Limit? → [Yes] → Lock Account - → [No] → Return to Enter -**Color:** Purple on success path, Teal on error handling -**Aspect:** 9:16 vertical - -### Example 2: Sequence Diagram for API Call -**Content:** Technical article about microservices communication -**CSE Result:** 24-item story showing User → API Gateway → Auth Service → Database → Response chain -**Diagram Type:** Sequence Diagram -**Structure:** 4 actors (User, Gateway, Auth, DB) with message arrows showing request/response flow -**Color:** Purple on Gateway (critical), Teal on Auth (secondary) -**Aspect:** 16:9 horizontal - -### Example 3: State Diagram for Order Lifecycle -**Content:** E-commerce order processing explanation -**CSE Result:** 24-item story showing order states: Pending → Processing → Shipped → Delivered (with error states) -**Diagram Type:** State Diagram -**Structure:** Initial → Pending → Processing → Shipped → Delivered → Final - → (error) → Cancelled -**Color:** Purple on happy path states, Teal on processing, Black on cancelled -**Aspect:** 1:1 square - -### Example 4: ER Diagram for Database Schema -**Content:** Data modeling article about blog platform -**CSE Result:** 24-item story revealing entities: Users, Posts, Comments, Categories with relationships -**Diagram Type:** Entity Relationship Diagram -**Structure:** User 1──* Post, Post 1──* Comment, Post *──* Category (many-to-many) -**Color:** Purple on User and Post (core), Teal on Comment and Category -**Aspect:** 16:9 horizontal - ---- - -## Quick Reference - -### When to Use Mermaid Workflow -- Content has inherent diagram structure (flow, sequence, states) -- Need structured technical diagram (not freeform architecture) -- Want hand-drawn whiteboard aesthetic (Excalidraw style) -- Deriving diagram from content analysis (not manually specified) - -### Mermaid vs Technical Diagrams -- **Mermaid:** Structured diagram types (flowchart, sequence, etc.), Excalidraw sketchy aesthetic -- **Technical:** Freeform architecture diagrams, cleaner hand-drawn style - -### Process Summary -``` -1. Run /cse (24-item story explanation) ← MANDATORY -2. Determine diagram type (flowchart, sequence, state, etc.) -3. Extract structure from CSE (nodes, edges, flows) -4. Design Excalidraw layout (wobbly, sketchy, whiteboard) -5. Construct comprehensive prompt -6. Choose aspect ratio (based on diagram type) -7. Generate with nano-banana-pro -8. Validate thoroughly (structure + aesthetic + UL + readability) -``` - -### Core Principles -1. **CSE-driven:** Always derive from content analysis, never manually specify -2. **Mermaid grammar:** Follow proper diagram type conventions -3. **Excalidraw aesthetic:** Hand-drawn whiteboard sketch feel -4. **UL color scheme:** Strategic purple/teal, black structure -5. **Readable imperfection:** Sketchy but clear - ---- - -**The workflow: /cse → Diagram Type → Structure → Excalidraw Design → Prompt → Generate → Validate → Complete** - -**The synthesis: Mermaid structure + Excalidraw aesthetic + UL editorial style = Technical diagrams that feel like smart sketches on a whiteboard.** diff --git a/.opencode/skills/Art/Workflows/RecipeCards.md b/.opencode/skills/Art/Workflows/RecipeCards.md deleted file mode 100755 index 80bab948..00000000 --- a/.opencode/skills/Art/Workflows/RecipeCards.md +++ /dev/null @@ -1,377 +0,0 @@ -# Process Recipe Cards Workflow - -**Step-by-step visual recipes for processes and methodologies using UL aesthetic.** - -Creates **PROCESS RECIPE CARDS** — numbered steps with small illustrations for each action, combining procedural clarity with editorial style. - ---- - -## Purpose - -Process recipe cards present methodologies, workflows, and step-by-step processes as visual recipes. These **illustrated how-to guides** make complex processes scannable and memorable. - -**Use this workflow for:** -- "The 5-Step TELOS Analysis Recipe" -- Consulting methodology playbooks -- How-to guides and processes -- Workflow documentation -- Best practice checklists -- Strategic frameworks with steps - ---- - -## Visual Aesthetic: Recipe Card with Personality - -**Think:** Cooking recipe card, but for business processes, with editorial hand-drawn style - -### Core Characteristics -1. **Numbered steps** — Clear 1, 2, 3 progression -2. **Small illustration per step** — Icon or simple visual for each action -3. **Scannable format** — Easy to reference and follow -4. **Recipe card layout** — Compact, organized, referenceable -5. **Hand-drawn icons** — Imperfect, editorial style illustrations -6. **Typography hierarchy** — 3-tier system for title, steps, details -7. **Deliverable quality** — Professional enough for client handoff - ---- - -## Color System for Recipe Cards - -### Structure -``` -Black #000000 — Step numbers, dividing lines, icon outlines -``` - -### Step Differentiation -``` -Deep Purple #4A148C — Critical steps or outcomes -Deep Teal #00796B — Supporting steps or inputs -Charcoal #2D2D2D — All body text and descriptions -``` - -### Background -``` -Light Cream #F5E6D3 — Recipe card warmth -OR -White #FFFFFF — Clean modern -``` - -### Color Strategy -- Step numbers in black (or purple for critical steps) -- Icons primarily black linework with strategic purple/teal accents -- Text in charcoal for readability -- Outcome/result step in purple (final step) - ---- - -## 🚨 MANDATORY WORKFLOW STEPS - -### Step 1: Define Process - -**Identify the recipe:** - -1. **What process are you documenting?** - - Process name - - Overall goal/outcome - -2. **How many steps?** - - Ideal: 3-7 steps (recipe card format) - - Too many steps → break into multiple recipes - -3. **What are the steps?** - - List each action in sequence - - What happens at each step - - What's the outcome - -**Output:** -``` -PROCESS NAME: [The X Recipe / X-Step Y Method] -OUTCOME: [What this process achieves] - -STEPS: -1. [Step name] — [Action description] — [Icon metaphor] -2. [Step name] — [Action description] — [Icon metaphor] -3. [Step name] — [Action description] — [Icon metaphor] -4. [Step name] — [Action description] — [Icon metaphor] -5. [Step name] — [Action description] — [Icon metaphor] - -CRITICAL STEPS (Purple): -- [Which step(s) are most important] -``` - ---- - -### Step 2: Design Recipe Card Layout - -**Plan the visual structure:** - -1. **Layout style:** - - Vertical list (top to bottom) - - Grid (2x3 for 6 steps) - - Linear horizontal flow - - Circular flow (process loops) - -2. **Step representation:** - - Number badge (circled number) - - Small icon illustration for step - - Brief text description - - Arrow to next step - -3. **Visual flow:** - - How steps connect - - Progressive visual cues - - Final outcome emphasis - -**Output:** -``` -LAYOUT: [Vertical list / Grid / Horizontal flow / Circular] - -CARD STRUCTURE: -- Title at top (Tier 1 typography) -- [X] steps arranged [vertically/in grid] -- Each step contains: - * Numbered badge (e.g., "1" in circle) - * Small hand-drawn icon/illustration - * Step name (Tier 2) - * Brief description (Tier 3) -- Arrows or lines connecting steps -- Final outcome emphasized - -ICON METAPHORS: -Step 1: [Simple icon, e.g., "magnifying glass" for discover] -Step 2: [Icon, e.g., "lightbulb" for ideate] -Step 3: [Icon, e.g., "hammer" for build] -... - -COLOR CODING: -- Step [X] (critical): Purple badge and icon accents -- Step [Y] (outcome): Purple emphasis -- Other steps: Black badges, minimal color -``` - ---- - -### Step 3: Construct Prompt - -### Prompt Template - -``` -Hand-drawn process recipe card in editorial style. - -STYLE REFERENCE: Recipe card, visual playbook, illustrated step-by-step guide - -BACKGROUND: [Light Cream #F5E6D3 OR White #FFFFFF] — clean, card-like - -AESTHETIC: -- Recipe card layout (organized, scannable) -- Hand-drawn step icons (simple, imperfect, editorial style) -- Numbered steps with clear progression -- Variable stroke weight (icons and dividing lines) -- Professional but human quality (deliverable to clients) - -LAYOUT TYPE: [Vertical list / Grid / Horizontal flow] - -CARD STRUCTURE: -[Describe the overall layout, e.g.:] -- Title at top -- 5 steps arranged vertically down the card -- Each step has: numbered badge → icon → name → description -- Arrows connecting steps showing flow -- Final step emphasized with purple accent - -TYPOGRAPHY SYSTEM (3-TIER): - -TIER 1 - RECIPE TITLE (Advocate Block Display): -- "[PROCESS NAME]" — Large at top -- Font: Advocate style, extra bold, hand-lettered, all-caps -- Size: 3x larger than body text -- Color: Black #000000 -- Example: "THE 5-STEP TELOS ANALYSIS RECIPE" - -TIER 2 - STEP NAMES (Concourse Sans): -- "Step 1: [Name]", "Step 2: [Name]", etc. -- Font: Concourse geometric sans-serif -- Size: Medium readable -- Color: Charcoal #2D2D2D (or Purple for critical step) -- Position: Next to each step icon - -TIER 3 - STEP DESCRIPTIONS (Advocate Condensed): -- Brief action description for each step -- Font: Advocate condensed (smaller) -- Size: 60% of Tier 2 -- Color: Charcoal #2D2D2D -- Position: Below step name - -PROCESS STEPS TO ILLUSTRATE: -[List each step in detail, e.g.:] - -STEP 1: [Step Name] -- Number badge: "1" in black circle -- Icon: [Hand-drawn simple icon, e.g., "magnifying glass examining document"] -- Description: "[Brief action description]" -- Color: Black linework -- Arrows: Black arrow pointing to Step 2 - -STEP 2: [Step Name] -- Number badge: "2" in black circle -- Icon: [Hand-drawn icon, e.g., "hands sorting cards"] -- Description: "[Action description]" -- Color: Black linework -- Arrows: Black arrow pointing to Step 3 - -STEP 3: [Critical Step Name] -- Number badge: "3" in Purple (#4A148C) circle — CRITICAL STEP -- Icon: [Hand-drawn icon with purple accents] -- Description: "[Action description]" -- Color: Purple (#4A148C) accents on icon and badge -- Arrows: Purple arrow pointing to Step 4 - -[Continue for all steps...] - -FINAL STEP [X]: [Outcome] -- Number badge: "[X]" in Purple (#4A148C) circle — OUTCOME -- Icon: [Success/completion icon, e.g., "trophy", "checkmark", "rocket"] -- Description: "[Outcome achieved]" -- Color: Purple (#4A148C) emphasis -- Represents: Final result of process - -CONNECTING ELEMENTS: -- Hand-drawn arrows between steps (wobbly, imperfect) -- Dotted or dashed lines for optional paths -- All arrows in Black (#000000) except critical path (Purple) - -COLOR USAGE: -- Black (#000000) for most step badges, icons, arrows -- Deep Purple (#4A148C) for critical step(s) and final outcome -- Deep Teal (#00796B) optional for input/supporting steps -- Charcoal (#2D2D2D) for all text - -CRITICAL REQUIREMENTS: -- Hand-drawn recipe card aesthetic (not polished diagram) -- Simple scannable icons for each step (not detailed illustrations) -- Clear numbered progression (1 → 2 → 3 → outcome) -- 3-tier typography hierarchy -- Strategic purple emphasis on critical/outcome steps -- No gradients, flat colors only -- Professional deliverable quality (client-ready) -- Recipe card proportions (vertical card layout) - -Optional: Sign small in bottom right corner in charcoal (#2D2D2D). -``` - ---- - -### Step 4: Determine Aspect Ratio - -| Recipe Type | Aspect Ratio | Reasoning | -|-------------|--------------|-----------| -| Vertical list (3-7 steps) | 9:16 or 4:3 | Tall card format | -| Grid layout (6-9 steps) | 1:1 | Square balanced grid | -| Horizontal flow | 16:9 | Wide linear progression | -| Circular process | 1:1 | Square for circular symmetry | - -**Default: 9:16 (vertical)** — Classic recipe card orientation - ---- - -### Step 5: Execute Generation - -```bash -bun run ~/.opencode/skills/Art/Tools/Generate.ts \ - --model nano-banana-pro \ - --prompt "[YOUR PROMPT]" \ - --size 2K \ - --aspect-ratio 9:16 \ - --output /path/to/recipe-card.png -``` - -**Model Recommendation:** nano-banana-pro (best text rendering for steps) - -**Immediately Open:** -```bash -open /path/to/recipe-card.png -``` - ---- - -### Step 6: Validation (MANDATORY) - -#### Must Have -- [ ] **Clear progression** — Steps obviously flow 1 → 2 → 3 -- [ ] **Scannable layout** — Easy to reference quickly -- [ ] **Simple icons** — Each step has recognizable illustration -- [ ] **Readable text** — All step names and descriptions legible -- [ ] **Strategic color** — Purple on critical/outcome steps -- [ ] **Hand-drawn quality** — Recipe card has editorial aesthetic -- [ ] **Professional deliverable** — Client-ready quality - -#### Must NOT Have -- [ ] Complex detailed illustrations (should be simple icons) -- [ ] Cluttered layout (too much information) -- [ ] Illegible small text -- [ ] Missing step numbers -- [ ] Unclear flow or progression -- [ ] Corporate process diagram look - -#### If Validation Fails - -| Problem | Fix | -|---------|-----| -| Icons too complex | "Simple hand-drawn icons, minimal detail, recognizable at glance" | -| Can't follow flow | "Clear numbered badges 1→2→3, black arrows connecting steps" | -| Too cluttered | Reduce description text, simplify layout | -| Looks corporate | Reference "recipe card aesthetic, hand-drawn playbook, editorial style" | -| Text unreadable | Increase Tier 2/3 text sizes, more spacing | -| Missing emphasis | "Purple (#4A148C) on Step [X] critical and final outcome step" | - ---- - -## Example Use Cases - -### Example 1: "5-Step TELOS Analysis Recipe" -- **Steps:** Context → Questions → Blockers → Constraints → Solutions -- **Icons:** Magnifying glass, question marks, roadblock, fence, lightbulb -- **Color:** Purple on final "Solutions" step -- **Layout:** Vertical 9:16 -- **Use:** Consulting deliverable - -### Example 2: "The Security Assessment Method" -- **Steps:** Assets → Threats → Vulnerabilities → Mitigations → Validation -- **Icons:** Treasure, storm, crack, shield, checkmark -- **Color:** Purple on "Mitigations" (critical) and "Validation" (outcome) -- **Layout:** Vertical 9:16 - -### Example 3: "3-Step Content Creation Recipe" -- **Steps:** Research → Create → Distribute -- **Icons:** Books, pencil, megaphone -- **Color:** Purple on final "Distribute" outcome -- **Layout:** Horizontal 16:9 (simpler process) - ---- - -## Quick Reference - -**Recipe Card Formula:** -``` -1. Define process (name, steps, outcome) -2. Design layout (vertical/grid, icons, flow) -3. Construct prompt with numbered progression -4. Choose aspect ratio for layout type -5. Generate with nano-banana-pro -6. Validate for scannability and professionalism -``` - -**Color Strategy:** -- Most steps: Black badges and icons -- Critical step: Purple badge and accents -- Final outcome: Purple emphasis -- Text: Charcoal - -**Icon Design:** -- Simple, recognizable, hand-drawn -- Not detailed illustrations -- Represents the action of that step - ---- - -**The workflow: Define → Design → Construct → Generate → Validate → Complete** diff --git a/.opencode/skills/Art/Workflows/Stats.md b/.opencode/skills/Art/Workflows/Stats.md deleted file mode 100755 index 208aeb66..00000000 --- a/.opencode/skills/Art/Workflows/Stats.md +++ /dev/null @@ -1,365 +0,0 @@ -# Illustrated Statistics Workflow - -**Single striking statistics illustrated as visual data points using UL aesthetic.** - -Creates **ILLUSTRATED STAT CARDS** — one number/statistic made visual with simple illustration and editorial style. - ---- - -## Purpose - -Illustrated statistics turn data points into memorable visuals. These are **single-stat cards** — one striking number with a small illustration showing what it means, designed for newsletters and social media. - -**Use this workflow for:** -- Newsletter "by the numbers" sections -- Social media stat cards -- Quick visual facts -- Data highlights -- "78% of developers use AI daily" style visuals -- Attention-grabbing numbers - ---- - -## Visual Aesthetic: Number + Tiny Context Illustration - -**Think:** Bold number dominates, small illustration shows what it means - -### Core Characteristics -1. **Number dominant** — The statistic is the hero (60-70% of visual) -2. **Massive typography** — Large bold number immediately visible -3. **Small illustration** — Tiny visual showing what stat represents (20-30%) -4. **Context text** — Brief description of what number means -5. **Hand-drawn** — Imperfect number rendering, editorial illustration -6. **Square or horizontal** — Social/newsletter friendly -7. **Scannable** — Number jumps out immediately - ---- - -## Color System for Stats - -### Number Typography -``` -Deep Purple #4A148C — Primary number (most common) -OR -Black #000000 — Alternative bold number -``` - -### Illustration -``` -Black #000000 — Small illustration linework -Deep Purple #4A148C — Accents on illustration -Deep Teal #00796B — Alternative accents -``` - -### Background -``` -Light Cream #F5E6D3 — Warm neutral -OR -White #FFFFFF — Clean modern -``` - -### Text -``` -Charcoal #2D2D2D — Context description text -``` - -### Color Strategy -- Number in purple (brand emphasis) or black (classic) -- Illustration primarily black with purple accents -- Background light for contrast -- Keep it simple: 2-3 colors total - ---- - -## 🚨 MANDATORY WORKFLOW STEPS - -### Step 1: Select Statistic - -**Identify the data point:** - -1. **What's the statistic?** - - The exact number and metric - - Must be striking or surprising - -2. **What does it represent?** - - Context explanation - - Why it matters - -3. **What tiny illustration shows it?** - - Simple visual representing what stat measures - - Not complex scene, just small icon/illustration - - Should clarify or amplify the meaning - -**Output:** -``` -STATISTIC: [Number + unit, e.g., "78%", "$2.1B", "3.5X"] -METRIC: [What's being measured] - -CONTEXT: [What this number represents] - -ILLUSTRATION: [Small visual element, e.g.:] -- "Tiny developer at computer" for developer stat -- "Stack of coins" for money stat -- "Growing arrow" for growth stat -- Size: 20-30% of image, simple, not detailed -``` - ---- - -### Step 2: Design Stat Card Layout - -**Plan the visual:** - -1. **Number placement:** - - Center dominant (number in middle) - - Left number, right illustration - - Top number, bottom illustration - -2. **Number size:** - - How large can it go - - Should fill 50-60% of image height - -3. **Illustration placement:** - - Where relative to number - - How it interacts with number (near, below, beside) - -4. **Text placement:** - - Metric description above or below number - - Context note if needed - -**Output:** -``` -LAYOUT STRUCTURE: -- Number: [Placement, e.g., "Center dominant"] -- Size: [60% of image height] -- Illustration: [Placement, e.g., "Bottom right, 25% of image"] -- Metric text: [Above number] -- Context: [Below number in smaller text] - -VISUAL RELATIONSHIP: -[How number and illustration interact, e.g.:] -- "78%" in massive purple -- Small illustrated developer sitting on top of "%" symbol -- Text above: "of developers" -- Text below: "use AI tools daily" - -COLOR SCHEME: -- Number: Purple (#4A148C) -- Illustration: Black linework with purple accents -- Background: Light cream -- Text: Charcoal -``` - ---- - -### Step 3: Construct Prompt - -### Prompt Template - -``` -Illustrated statistic card in editorial style. - -STYLE REFERENCE: Data visualization, stat card, number + icon illustration - -BACKGROUND: [Light Cream #F5E6D3 / White #FFFFFF] — flat, clean - -AESTHETIC: -- Number as dominant visual element (massive typography) -- Small simple illustration providing context -- Hand-drawn imperfect number rendering (not digital font) -- Editorial flat color with strategic purple emphasis -- Scannable, immediate impact - -STAT CARD STRUCTURE: - -NUMBER TYPOGRAPHY (Advocate Block Display - MASSIVE): -"[STATISTIC]" - -- Font: Advocate style extra bold, hand-lettered -- Size: MASSIVE — 60-70% of image area -- Color: [Deep Purple #4A148C / Black #000000] -- Style: Hand-lettered with imperfections (wobbly lines, character) -- Position: [Center / Left / Top] -- Example: "78%" in giant purple hand-lettered numbers - -METRIC TEXT (Concourse Sans - Medium): -"[what the stat measures]" - -- Font: Concourse geometric sans-serif -- Size: Medium readable (15-20% of number size) -- Color: Charcoal (#2D2D2D) -- Position: [Above / Below number] -- Example: "of developers" above the 78% - -CONTEXT TEXT (Advocate Condensed - Small): -"[additional context]" - -- Font: Advocate condensed -- Size: Small (10-15% of number size) -- Color: Charcoal (#2D2D2D) -- Position: [Below number / Bottom of card] -- Example: "use AI tools daily" below the number - -ILLUSTRATION (Small, Simple): -[Describe the tiny illustration, e.g.:] -- Small hand-drawn [icon/figure] -- Hand-drawn black (#000000) linework -- Purple (#4A148C) accents on [specific elements] -- Position: [Bottom right / Next to number / etc.] -- Size: 20-30% of image area -- Style: Simple sketch, not detailed -- Represents: [What the stat is about] -- Example: "Tiny developer sitting at computer with code on screen" - -VISUAL INTERACTION: -[How illustration and number relate, e.g.:] -- Illustration positioned [near/on/beside] the number -- Creates visual story: "Developer represents the 78%" -- Illustration does NOT compete with number (stays small) - -COLOR USAGE: -- Number: Deep Purple (#4A148C) OR Black (#000000) -- Illustration linework: Black (#000000) -- Illustration accents: Purple (#4A148C) OR Teal (#00796B) -- Metric/context text: Charcoal (#2D2D2D) -- Background: Light Cream (#F5E6D3) OR White (#FFFFFF) - -CRITICAL REQUIREMENTS: -- Number is HERO (dominates composition, 60-70%) -- Hand-lettered number quality (NOT digital font) -- Illustration SMALL and SIMPLE (supporting role, 20-30%) -- High contrast for readability -- Strategic purple emphasis (number OR illustration accents) -- No gradients, flat colors only -- Immediately scannable (number jumps out at thumbnail) -- Square 1:1 or horizontal 16:9 format - -Optional: Sign small in bottom right corner in charcoal (#2D2D2D). -``` - ---- - -### Step 4: Determine Aspect Ratio - -| Use Case | Aspect Ratio | Reasoning | -|----------|--------------|-----------| -| Social media post | 1:1 | Instagram/LinkedIn friendly | -| Newsletter inline | 16:9 | Horizontal fits email width | -| Vertical mobile | 9:16 | Instagram story format | -| Balanced | 1:1 | Works everywhere | - -**Default: 1:1 (square)** — Most versatile for social/newsletter - ---- - -### Step 5: Execute Generation - -```bash -bun run ~/.opencode/skills/Art/Tools/Generate.ts \ - --model nano-banana-pro \ - --prompt "[YOUR PROMPT]" \ - --size 2K \ - --aspect-ratio 1:1 \ - --output /path/to/stat-card.png -``` - -**Model Recommendation:** nano-banana-pro (excellent for rendering numbers clearly) - -**Immediately Open:** -```bash -open /path/to/stat-card.png -``` - ---- - -### Step 6: Validation (MANDATORY) - -#### Must Have -- [ ] **Number dominant** — Statistic is 60-70% of visual, immediately visible -- [ ] **Readable number** — Clear even at thumbnail size -- [ ] **Hand-lettered** — Imperfect, gestural quality (not digital font) -- [ ] **Illustration simple** — Small supporting visual, not complex scene -- [ ] **Context clear** — Metric/context text explains what number means -- [ ] **High contrast** — Purple or black number pops from background -- [ ] **Scannable** — Number jumps out immediately - -#### Must NOT Have -- [ ] Number too small (should dominate) -- [ ] Digital font rendering (should be hand-lettered) -- [ ] Complex detailed illustration (should be simple icon) -- [ ] Illustration competing with number -- [ ] Low contrast (can't read number) -- [ ] Missing context (unclear what stat represents) - -#### If Validation Fails - -| Problem | Fix | -|---------|-----| -| Number too small | "MASSIVE hand-lettered number filling 65% of image height" | -| Looks digital | "Hand-drawn Advocate style number, wobbly imperfect strokes" | -| Illustration too complex | "SMALL SIMPLE illustration, minimal detail, 25% of image size" | -| Can't read thumbnail | Increase number size, stronger contrast | -| Unclear meaning | Add metric text above: "of [X]", context below: "[what they do]" | -| No visual interest | "Small illustrated [icon] showing what stat represents" | - ---- - -## Example Use Cases - -### Example 1: "78% of developers use AI daily" -- **Number:** "78%" in massive purple hand-lettering -- **Metric:** "of developers" above number -- **Context:** "use AI tools daily" below -- **Illustration:** Tiny developer at computer with AI sparkles (bottom right, 25%) -- **Aspect:** 1:1 - -### Example 2: "$2.1B invested in AI safety" -- **Number:** "$2.1B" in giant black hand-lettering -- **Metric:** "invested in" above -- **Context:** "AI safety research" below -- **Illustration:** Small stack of coins with shield symbol (purple accents) -- **Aspect:** 1:1 - -### Example 3: "3.5X growth in AI adoption" -- **Number:** "3.5X" in massive purple -- **Metric:** "growth in" above -- **Context:** "enterprise AI adoption" below -- **Illustration:** Upward arrow with small building icon -- **Aspect:** 16:9 (horizontal for newsletter) - -### Example 4: "92% of security breaches involve humans" -- **Number:** "92%" in black bold hand-lettering -- **Metric:** "of breaches" above -- **Context:** "involve human error" below -- **Illustration:** Tiny person with open door/lock symbol (purple accents) -- **Aspect:** 1:1 - ---- - -## Quick Reference - -**Illustrated Stat Formula:** -``` -1. Select statistic (number, metric, context) -2. Design layout (number dominant, illustration placement) -3. Choose simple illustration (what stat represents) -4. Construct prompt with massive number -5. Use 1:1 square aspect ratio (usually) -6. Generate with nano-banana-pro -7. Validate for dominance and readability -``` - -**Color Strategy:** -- Number: Purple (emphasis) or Black (classic) -- Illustration: Black linework + purple accents -- Text: Charcoal -- Background: Light cream or white - -**Key Principle:** -- **Number IS the visual** — Illustration is small supporting context -- Immediate impact, scannable at thumbnail -- Context makes meaning clear - ---- - -**The workflow: Select → Design → Construct → Generate → Validate → Complete** diff --git a/.opencode/skills/Art/Workflows/Taxonomies.md b/.opencode/skills/Art/Workflows/Taxonomies.md deleted file mode 100755 index 360cd13f..00000000 --- a/.opencode/skills/Art/Workflows/Taxonomies.md +++ /dev/null @@ -1,354 +0,0 @@ -# Visual Taxonomies & Classification Grids Workflow - -**Hand-drawn classification systems, taxonomies, and reference grids using UL aesthetic.** - -Creates **VISUAL TAXONOMIES** — organized classification systems like periodic tables, capability matrices, or framework grids with editorial hand-drawn style. - ---- - -## Purpose - -Visual taxonomies organize concepts into structured classification systems. Unlike technical diagrams (which show flows/relationships) or editorial illustrations (which use metaphors), taxonomies show **organized categories and hierarchies**. - -**Use this workflow for:** -- "The Periodic Table of X" -- Classification grids and matrices -- Capability taxonomies -- Framework reference cards -- Organized typologies -- Systematic categorizations - ---- - -## Visual Aesthetic: Structured Yet Hand-Drawn - -**Think:** Hand-drawn periodic table or field guide illustration - -### Core Characteristics -1. **Grid structure** — Organized cells/boxes in systematic layout -2. **Hand-drawn imperfection** — Boxes wobbly, lines organic, human feel -3. **Consistent typography** — 3-tier system (Advocate titles, Concourse labels, italic annotations) -4. **Category organization** — Clear groupings with visual hierarchy -5. **Color coding** — Strategic use of purple/teal to show categories -6. **Editorial aesthetic** — Maintains UL flat color, black linework style -7. **Scannable layout** — Easy to reference and navigate - ---- - -## Color System for Taxonomies - -**Same UL palette, organized usage:** - -### Structure -``` -Black #000000 — All grid lines, cell borders, primary structure -``` - -### Category Differentiation -``` -Deep Purple #4A148C — Category 1 headers/highlights -Deep Teal #00796B — Category 2 headers/highlights -Charcoal #2D2D2D — All body text and labels -``` - -### Background -``` -White #FFFFFF or Light Cream #F5E6D3 — For clarity -``` - -### Color Strategy -- Use purple for one category type, teal for another -- Alternate colors by row/column for visual organization -- Keep most content black/charcoal with strategic color accents - ---- - -## 🚨 MANDATORY WORKFLOW STEPS - -### Step 1: Define Classification System - -**Identify what you're classifying:** - -1. **What is being categorized?** (e.g., AI capabilities, security threats, business models) -2. **What are the organizing dimensions?** (e.g., complexity vs. impact, offensive vs. defensive) -3. **How many categories?** (e.g., 6 types, 12 elements, 4x4 grid) -4. **What's the hierarchy?** (e.g., major categories → subcategories) - -**Output:** -``` -CLASSIFICATION SUBJECT: [What you're organizing] - -ORGANIZING DIMENSIONS: -- Dimension 1: [e.g., Complexity: Simple → Complex] -- Dimension 2: [e.g., Impact: Low → High] - -CATEGORIES: -1. [Category name] — [Description] -2. [Category name] — [Description] -3. [Category name] — [Description] -... - -ITEMS TO CLASSIFY: -- [Item 1] belongs to [Category] -- [Item 2] belongs to [Category] -... -``` - ---- - -### Step 2: Design Grid Layout - -**Plan the visual organization:** - -1. **Layout type:** - - Periodic table grid (rows and columns) - - Matrix (2x2, 3x3, 4x4) - - Hierarchical tree - - Grouped clusters - - Linear taxonomy (top to bottom) - -2. **Cell structure:** - - What information in each cell - - Size of cells (uniform or varied) - - How categories are grouped visually - -3. **Color assignment:** - - Which categories get purple - - Which get teal - - Pattern of color distribution - -**Output:** -``` -LAYOUT: [Grid type, e.g., 4x4 matrix, Periodic table style] - -GRID STRUCTURE: -- [Describe arrangement: "4 rows by 4 columns, grouped by color into quadrants"] -- Cell size: [Uniform squares, varied rectangles, etc.] -- Groupings: [How categories cluster together] - -COLOR CODING: -- Purple: [Category type 1] -- Teal: [Category type 2] -- Black: [Remaining structure] - -TYPOGRAPHY: -- Title (Tier 1): "[MAIN TITLE]" -- Category headers (Tier 2): [Category names] -- Item labels (Tier 3): [Individual items] -``` - ---- - -### Step 3: Construct Prompt - -**Use 3-tier typography system:** - -### Prompt Template - -``` -Hand-drawn taxonomy grid in editorial notebook style. - -STYLE REFERENCE: Periodic table, field guide illustration, reference card aesthetic - -BACKGROUND: [White #FFFFFF OR Light Cream #F5E6D3] — clean, flat - -AESTHETIC: -- Hand-drawn imperfect grid lines (slightly wobbly, human quality) -- Variable stroke weight (grid structure in black) -- Cell borders with slight waviness (not perfect rectangles) -- Editorial flat color aesthetic with strategic accents -- Organized layout but hand-crafted feel - -LAYOUT TYPE: [Periodic table grid / Matrix / Hierarchical tree / etc.] - -GRID STRUCTURE: -[Describe the grid organization, e.g.:] -- 4 rows by 4 columns of cells -- Each cell contains: [category icon/symbol] + [label text] -- Cells grouped by color into [quadrants/categories] -- Clear visual separation between category groups - -TYPOGRAPHY SYSTEM (3-TIER): - -TIER 1 - TAXONOMY HEADER & SUBTITLE (Valkyrie Two-Part System): -Header (Main Title): -- "[Header Text]" — Left-justified at top -- Font: Valkyrie serif italic (elegant, sophisticated) -- Size: Large - 3-4x body text (prominent, commanding attention) -- Style: Italicized, sentence case or title case (NOT all-caps) -- Color: Black #000000 (or Purple #4A148C for emphasis) -- Position: Top-left with margin -- Example: "The Periodic Table of AI Capabilities" - -Subtitle (Clarifying Detail): -- "[Subtitle Text]" — Below header -- Font: Valkyrie serif regular (warm, readable) -- Size: Small - 1-1.5x body text (noticeably smaller than header, supportive) -- Style: Regular (NOT italicized), sentence case (first letter capitalized, rest lowercase except proper nouns) -- Color: Black #000000 or Charcoal #2D2D2D -- Position: Small gap below header, aligned left -- Example: "Classification of Machine Learning Functions" - -TIER 2 - CATEGORY HEADERS (Concourse Sans): -- "[Category 1]", "[Category 2]", etc. -- Font: Concourse geometric sans-serif, clean, modern -- Size: Medium readable -- Color: Purple #4A148C for Category 1, Teal #00796B for Category 2 -- Example: "Reasoning", "Creativity", "Perception" - -TIER 3 - ITEM LABELS (Advocate Condensed): -- Individual items within cells -- Font: Advocate condensed, smaller -- Size: 60% of Tier 2 -- Color: Charcoal #2D2D2D -- Example: Item names, abbreviations, symbols - -CONTENT TO INCLUDE: -[List all categories and items to be shown, e.g.:] - -CATEGORY 1 (Purple #4A148C headers): -- Item A: [label] -- Item B: [label] -- Item C: [label] - -CATEGORY 2 (Teal #00796B headers): -- Item D: [label] -- Item E: [label] - -[etc.] - -COLOR USAGE: -- Black (#000000) for all grid structure, cell borders -- Deep Purple (#4A148C) for [Category 1] headers and accents -- Deep Teal (#00796B) for [Category 2] headers and accents -- Charcoal (#2D2D2D) for all item labels and body text - -CRITICAL REQUIREMENTS: -- Hand-drawn sketch quality — NOT polished digital grid -- Grid lines wobble slightly (human imperfection) -- Cells roughly aligned but organic (grid-aware not grid-perfect) -- No gradients, no shadows, flat colors only -- Clear typography with 3-tier hierarchy -- Scannable and reference-friendly layout -- Strategic color coding for categories - -Optional: Sign small in bottom right corner in charcoal (#2D2D2D). -``` - ---- - -### Step 4: Determine Aspect Ratio - -**Choose based on taxonomy type:** - -| Taxonomy Type | Aspect Ratio | Reasoning | -|---------------|--------------|-----------| -| Wide grid (many columns) | 16:9 or 21:9 | Horizontal periodictable layout | -| Tall hierarchy | 9:16 | Vertical tree structure | -| Square matrix | 1:1 | Balanced 4x4 or 5x5 grid | -| Reference card | 1:1 or 4:3 | Compact, poster-like | - -**Default: 1:1 (square)** — Works for most taxonomy grids - ---- - -### Step 5: Execute Generation - -```bash -bun run ~/.opencode/skills/Art/Tools/Generate.ts \ - --model nano-banana-pro \ - --prompt "[YOUR PROMPT]" \ - --size 2K \ - --aspect-ratio 1:1 \ - --output /path/to/taxonomy.png -``` - -**Model Recommendation:** nano-banana-pro (best text rendering for labels) - -**Immediately Open:** -```bash -open /path/to/taxonomy.png -``` - ---- - -### Step 6: Validation (MANDATORY) - -**Open the generated image and check:** - -#### Must Have -- [ ] **Clear grid structure** — Organized layout with visible cells/categories -- [ ] **Readable text** — All labels legible in 3-tier hierarchy -- [ ] **Hand-drawn aesthetic** — Wobbly lines, imperfect cells, human feel -- [ ] **Strategic color** — Purple/teal differentiate categories, not overwhelming -- [ ] **Scannable** — Easy to find and reference specific items -- [ ] **Hierarchical clarity** — Title > Categories > Items is obvious -- [ ] **Flat aesthetic** — No gradients, maintains UL editorial style - -#### Must NOT Have -- [ ] Perfect straight grid lines -- [ ] Polished vector graphics -- [ ] Gradients or shadows -- [ ] Illegible or tiny text -- [ ] Color chaos (too many colors) -- [ ] Confusing organization - -#### If Validation Fails - -| Problem | Fix | -|---------|-----| -| Grid too perfect | Emphasize "wobbly hand-drawn grid lines, organic imperfection" | -| Text unreadable | Increase text size, strengthen typography tier requirements | -| Too colorful | "Strategic color use — purple for [specific], teal for [specific], rest black" | -| Unclear organization | Simplify grid, reduce categories, clarify groupings | -| Looks digital | Reference "hand-drawn field guide, editorial notebook aesthetic" | - ---- - -## Example Use Cases - -### Example 1: "Periodic Table of AI Capabilities" -- **Grid:** 5x6 matrix of capabilities -- **Categories:** Reasoning (purple), Creativity (teal), Perception (black), Action (purple), Memory (teal) -- **Items:** Each cell = one capability with icon + label -- **Aspect:** 16:9 (wide grid) - -### Example 2: "Cybersecurity Threat Taxonomy" -- **Grid:** Hierarchical tree from top (threat types) to bottom (specific attacks) -- **Categories:** Network threats (purple), Application threats (teal), Human threats (purple) -- **Aspect:** 9:16 (tall tree) - -### Example 3: "Business Model Classification" -- **Grid:** 3x3 matrix (complexity vs. scalability) -- **Categories:** 9 business model archetypes -- **Color:** Purple for high-scalability, teal for low-complexity -- **Aspect:** 1:1 (square reference card) - ---- - -## Quick Reference - -**Taxonomy Formula:** -``` -1. Define classification system (what, dimensions, categories) -2. Design grid layout (structure, cells, color coding) -3. Construct prompt with 3-tier typography -4. Choose aspect ratio for layout type -5. Generate with nano-banana-pro -6. Validate for clarity and aesthetics -``` - -**Color Strategy:** -- 80% Black structure -- 10% Purple (Category 1) -- 10% Teal (Category 2) -- Text all Charcoal - -**Typography:** -- Tier 1: Massive Advocate title -- Tier 2: Medium Concourse category headers -- Tier 3: Small Advocate item labels - ---- - -**The workflow: Define → Design → Construct → Generate → Validate → Complete** diff --git a/.opencode/skills/Art/Workflows/TechnicalDiagrams.md b/.opencode/skills/Art/Workflows/TechnicalDiagrams.md deleted file mode 100755 index bb019fcd..00000000 --- a/.opencode/skills/Art/Workflows/TechnicalDiagrams.md +++ /dev/null @@ -1,223 +0,0 @@ -# Technical Diagram Workflow - -**Clean Excalidraw-style technical diagrams with custom typography aesthetic.** - ---- - -## Purpose - -Technical diagrams for system architectures, process flows, and board presentations. - -**Use for:** Architecture diagrams, process flows, pipelines, infrastructure maps, board presentations. - ---- - -## Visual Aesthetic - -**Style:** Clean Excalidraw diagrams — professional, approachable, no grid background. - -### Core Rules - -1. **Excalidraw style** — Clean lines, slightly organic, professional -2. **Pure sepia #EAE9DF background** — NO grid lines, NO texture, NO decorations -3. **Custom fonts** — Specific typography hierarchy (see below) -4. **Strategic color** — Purple #4A148C for key elements, Teal #00796B for flows -5. **White primary** — 80% of elements in grey/black colors, color is accent only - - -# Example image -# Ignore for now -# ~/.opencode/skills/Art/WorkflowExamples/TechnicalDiagrams/example.png - ---- - -## Typography System (Butterick Fonts) - -**Three font families with specific visual characteristics:** - -### TIER 1: Headers & Subtitles — Valkyrie Serif - -**Valkyrie characteristics for AI prompt:** -- Elegant serif with wedge-shaped serifs (like Palatino but more refined) -- High stroke contrast (thick/thin variation) -- Sophisticated, warm, readable -- NOT generic serif — specifically elegant wedge serifs - -**Header (Main Title):** -- Font: Elegant wedge-serif italic (Valkyrie-style) -- Size: Medium-large, 3-4x body text -- Style: Italic, title case -- Color: Black #000000 -- Position: Top-left of image, left-justified - -**Subtitle:** -- Font: Elegant wedge-serif regular (Valkyrie-style) -- Size: Smaller, 1.3x body text -- Style: Regular (not italic), sentence case, no period at the end -- Color: Charcoal #2D2D2D -- Position: Below header, left-justified - ---- - -### TIER 2: Labels — Concourse T3 Geometric Sans - -**Concourse T3 characteristics for AI prompt:** -- Geometric sans-serif (like Avenir/Futura but warmer) -- Clean, technical, precise -- Even stroke weight -- Professional, no-nonsense -- NOT generic sans — specifically geometric with slight warmth - -**Usage:** -- Box labels, node names, technical identifiers -- Size: Medium, readable -- Color: Charcoal #2D2D2D or Black #000000 -- Examples: "API Gateway", "Database", "Services" - ---- - -### TIER 3: Insights — Advocate Condensed Italic - -**Advocate characteristics for AI prompt:** -- Condensed italic sans-serif -- Sporty, editorial feel (like sports jerseys or magazine callouts) -- Narrow letter spacing, italic slant -- Voice-forward, attention-grabbing -- NOT generic italic — specifically condensed sporty italic - -**Usage:** -- Key insights, commentary, callouts -- Size: Smaller, 60-70% of labels -- Color: Purple #4A148C (primary) or Teal #00796B -- Style: Always italic, always asterisks around text -- Examples: "*this is the bottleneck*", "*critical path*" - ---- - -# Color Palette - -``` -Sepia #EAE9DF - Background -Purple #4A148C — Key components, insights (10%) -Teal #00796B — Flows, connections (5%) -Charcoal #2D2D2D — Text, labels (5%) -White #FFFFFF — Primary Structure -``` - ---- - -# Composition construction - -Create a consistent, styled technical diagram using ALL of the styling guidelines here. - -BACKGROUND: Pure Black #000000— absolutely NO grid lines, NO texture, completely clean black. - -STYLE: Architect aesthetic — like an architect artist did it on the whiteboard - -TYPOGRAPHY (CRITICAL - use these exact font styles): - -HEADER: Elegant wedge-serif italic font (like Palatino but more refined, with distinctive wedge-shaped serifs and high stroke contrast). Large size, black color, top-left position, title case. - -SUBTITLE: Same elegant wedge-serif but regular weight (not italic). Smaller size, charcoal #2D2D2D color, directly below header, sentence case. - -LABELS: Geometric sans-serif font (like Avenir or Futura but slightly warmer, clean and technical with even stroke weight). Medium size, charcoal #2D2D2D color, used for all box labels and component names. Hand drawn versions of this. - -INSIGHTS: Condensed italic sans-serif font (sporty editorial style like sports jerseys or magazine callouts, narrow and slanted). Smaller size, Purple #4A148C color, used for callouts with asterisks like "*key insight*".Hand drawn versions of this. - -DIAGRAM CONTENT: -Title: '[TITLE]' (Top left, left-justified) -Subtitle: '[SUBTITLE]' (left justified to the Header, slightly below) -Art and labels and such should look like Excalidraw, but hand drawn by a talented Architect Artist that mimics our fonts. - -Have 1-3 insights for each image created. - -# Object Styling - -When you must use everyday objects to help the visual, use technically-drawn, non-cartoon-like drawing. This means: - -- NOT Cartoony -- Like they're drawn by an architect / artist type - -## Overall look and feel - -The whole image should look like it was made on a whiteboard by an extremely talented artist with Architect training, using all the styling above. Like Excalidraw, but more Architect / Artistic. - -All the art components, labels, and such should mostly look hand-drawn, similar to Excalidraw. But roughly in the style of our fonts. - -# Execution - -1. Run /cse 24 on the input content -2. Think deeply about how to construct that into a technical diagram -3. Create the composition in your mind that will perfectly render that -4. Create a PROMPT that will render that composition perfectly -5. Before creating the image, make absolutely certain that the PROMPT you've created mind takes into account everything in these instructions. No exceptions. Then proceed to #6. -6. Confirm this mentally for 1 full second -7. Create the image using intent-to-flag mapping and the CLI tool - -## Intent-to-Flag Mapping - -**Interpret user request and select appropriate flags:** - -### Model Selection - -| User Says | Flag | When to Use | -|-----------|------|-------------| -| "fast", "quick", "draft" | `--model nano-banana` | Faster iteration, slightly lower quality | -| (default), "best", "high quality" | `--model nano-banana-pro` | Best quality + text rendering (recommended) | -| "flux", "stylistic variety" | `--model flux` | Different aesthetic, stylistic variety | - -### Size Selection - -| User Says | Flag | Resolution | -|-----------|------|------------| -| "draft", "preview" | `--size 1K` | Quick iterations | -| (default), "standard" | `--size 2K` | Standard output | -| "high res", "print", "large" | `--size 4K` | Maximum resolution | - -### Aspect Ratio - -| User Says | Flag | Use Case | -|-----------|------|----------| -| "wide", "slide", "presentation" | `--aspect-ratio 16:9` | Default for diagrams | -| "square" | `--aspect-ratio 1:1` | Social media, compact | -| "ultrawide", "panoramic" | `--aspect-ratio 21:9` | Wide system diagrams | - -### Post-Processing - -| User Says | Flag | Effect | -|-----------|------|--------| -| "blog", "website" | `--thumbnail` | Creates transparent + thumb versions | -| "transparent" | `--remove-bg` | Removes background for compositing | -| "variations", "options" | `--creative-variations 3` | Multiple versions | - -### Generate Command - -```bash -bun run ~/.opencode/skills/Art/Tools/Generate.ts \ - --model [SELECTED_MODEL] \ - --prompt "[PROMPT]" \ - --size [SELECTED_SIZE] \ - --aspect-ratio [SELECTED_RATIO] \ - [--thumbnail if for blog] \ - --output /path/to/diagram.png -``` - -# Validation - -After rendering, ensure that you have executed properly by checking this list of musts and must-nots. - -**Must have:** -- [ ] Pure sepia background #EAE9DF (NO grid or decorations) -- [ ] Elegant wedge-serif for both headers (Valkyrie-style) -- [ ] Geometric sans labels (Concourse-style) -- [ ] A title and subtitle in the top left -- [ ] 1-3 Condensed italic insights (Advocate-style) -- [ ] Strategic color usage (for accents, 70% different shades of grey and black) -- [ ] Highly technical, stylish, Architect-style look and feel, Excalidraw with style! - -**Must NOT have:** -- [ ] Grid lines or texture on background -- [ ] Generic or ugly fonts -- [ ] Cartoony or overly casual shapes or styling -- [ ] Over-coloring (everything purple/teal) - diff --git a/.opencode/skills/Art/Workflows/Timelines.md b/.opencode/skills/Art/Workflows/Timelines.md deleted file mode 100755 index 18dae510..00000000 --- a/.opencode/skills/Art/Workflows/Timelines.md +++ /dev/null @@ -1,349 +0,0 @@ -# Conceptual Timelines & Progressions Workflow - -**Hand-drawn timelines showing evolution, trends, and transformations using UL aesthetic.** - -Creates **ILLUSTRATED TIMELINES** — chronological progressions with visual metaphors for each stage, combining narrative arc with temporal information. - ---- - -## Purpose - -Conceptual timelines show change over time through illustrated progression. Unlike simple date lists, these timelines use **visual metaphors at each stage** to show transformation, evolution, or historical development. - -**Use this workflow for:** -- "The Evolution of X" -- Trend analysis over time -- Historical perspectives -- Before → During → After progressions -- Transformation journeys -- Era comparisons - ---- - -## Visual Aesthetic: Illustrated Progression - -**Think:** Hand-drawn timeline with small illustrations at each milestone - -### Core Characteristics -1. **Temporal flow** — Clear left-to-right or top-to-bottom progression -2. **Illustrated milestones** — Small visual metaphor at each point -3. **Hand-drawn timeline** — Organic line connecting events (not ruler-straight) -4. **Typography hierarchy** — 3-tier system for dates, labels, annotations -5. **Narrative arc** — Shows transformation, not just chronology -6. **Editorial style** — Maintains UL flat color, black linework aesthetic -7. **Scannable progression** — Easy to follow the flow of time - ---- - -## Color System for Timelines - -### Structure -``` -Black #000000 — Timeline spine/line, all primary structure -``` - -### Emphasis & Progression -``` -Deep Purple #4A148C — Key turning points, critical milestones -Deep Teal #00796B — Secondary events, supporting milestones -Charcoal #2D2D2D — All text (dates, labels, annotations) -``` - -### Background -``` -White #FFFFFF or Light Cream #F5E6D3 -``` - -### Color Strategy -- Timeline line in black -- 1-2 most important milestones in purple -- Supporting milestones in teal -- Most events remain black with charcoal text - ---- - -## 🚨 MANDATORY WORKFLOW STEPS - -### Step 1: Define Timeline Structure - -**Identify what you're showing:** - -1. **What's evolving?** (e.g., AI development, security paradigms, organizational thinking) -2. **Time span?** (e.g., 1990-2025, past 5 years, projected future) -3. **Key milestones?** (List 4-8 major points - too many becomes cluttered) -4. **What's the narrative arc?** (e.g., collapse → crisis → renewal, winter → spring → summer) - -**Output:** -``` -SUBJECT: [What's changing over time] -TIME SPAN: [Start year] → [End year] - -NARRATIVE ARC: [The transformation story, e.g., "From hype to disillusionment to practical value"] - -KEY MILESTONES: -1. [Year/Period]: [Event] — [Metaphor for this stage] -2. [Year/Period]: [Event] — [Metaphor for this stage] -3. [Year/Period]: [Event] — [Metaphor for this stage] -4. [Year/Period]: [Event] — [Metaphor for this stage] -... - -TURNING POINTS (Purple highlights): -- [Which 1-2 milestones are most critical] -``` - ---- - -### Step 2: Design Timeline Layout - -**Plan the visual flow:** - -1. **Orientation:** - - Horizontal (left-to-right): Traditional, good for desktop/wide - - Vertical (top-to-bottom): Mobile-friendly, scrollable - - Curved/organic: More artistic, less rigid - -2. **Milestone representation:** - - What small illustration represents each stage - - How milestones connect to timeline (above/below, branching) - - Size variation (bigger for more important events) - -3. **Spacing:** - - Even spacing (visual balance) - - Proportional spacing (matches actual time) - - Clustered spacing (groups related events) - -**Output:** -``` -ORIENTATION: [Horizontal / Vertical / Curved] - -TIMELINE STRUCTURE: -- Main line: [Black hand-drawn line, slightly wobbly] -- Milestones: [Small illustrated circles/nodes along line] -- Labels: [Above or below timeline] - -MILESTONE ILLUSTRATIONS: -1. [Year]: [Small icon/metaphor] — [e.g., "seedling" for beginning] -2. [Year]: [Small icon/metaphor] — [e.g., "storm" for crisis] -3. [Year]: [Small icon/metaphor] — [e.g., "sunrise" for renewal] -... - -SPACING: [Even / Proportional / Clustered] - -COLOR HIGHLIGHTS: -- Purple: [Critical milestone(s)] -- Teal: [Supporting milestone(s)] -- Black: [Standard milestones] -``` - ---- - -### Step 3: Construct Prompt - -### Prompt Template - -``` -Hand-drawn conceptual timeline in editorial illustration style. - -STYLE REFERENCE: Illustrated history timeline, hand-drawn progress chart, editorial time progression - -BACKGROUND: [White #FFFFFF OR Light Cream #F5E6D3] — clean, flat - -AESTHETIC: -- Hand-drawn timeline (organic line, slightly wobbly, not ruler-straight) -- Small illustrated metaphors at each milestone -- Variable stroke weight (timeline thicker, details thinner) -- Editorial flat color with strategic purple/teal accents -- Imperfect but intentional placement - -ORIENTATION: [Horizontal left-to-right / Vertical top-to-bottom] - -TIMELINE STRUCTURE: -- Black (#000000) timeline spine running [horizontally/vertically] -- [Number] milestone points along timeline -- Each milestone has: small circle/node + illustration + label -- Hand-drawn connecting line with slight organic waviness - -TYPOGRAPHY SYSTEM (3-TIER): - -TIER 1 - TIMELINE TITLE (Advocate Block Display): -- "[TIMELINE TITLE IN ALL-CAPS]" -- Font: Advocate style, extra bold, hand-lettered, all-caps -- Size: 3x larger than body text -- Color: Black #000000 -- Position: Top or left side -- Example: "THE EVOLUTION OF ARTIFICIAL INTELLIGENCE" - -TIER 2 - DATES/PERIODS (Concourse Sans): -- "[1990]", "[2000]", "[2010]", etc. -- Font: Concourse geometric sans-serif -- Size: Medium readable -- Color: Charcoal #2D2D2D -- Position: Along timeline at each milestone - -TIER 3 - MILESTONE DESCRIPTIONS (Advocate Condensed Italic): -- "*symbolic AI era*", "*deep learning breakthrough*", etc. -- Font: Advocate condensed italic -- Size: 60% of Tier 2 -- Color: Charcoal #2D2D2D (or Purple/Teal for highlighted events) -- Position: Near each milestone node - -MILESTONES TO ILLUSTRATE: -[List each point chronologically, e.g.:] - -1. [Year]: [Event name] - - Illustration: [Small hand-drawn icon/metaphor, e.g., "tiny seed sprouting"] - - Color: Black node with charcoal text - - Position: [Along timeline at this point] - -2. [Year]: [Critical event] - - Illustration: [Metaphor, e.g., "lightning bolt"] - - Color: Purple (#4A148C) node and illustration — KEY TURNING POINT - - Position: [Emphasized size, highlighted] - -3. [Year]: [Event name] - - Illustration: [Metaphor] - - Color: Teal (#00796B) node - - Position: [Along timeline] - -[etc. for all milestones] - -VISUAL METAPHORS: -- Each milestone illustrated with small simple icon -- Metaphors show the nature/feeling of that era -- Hand-drawn sketch quality, not detailed illustrations -- Examples: seedling, storm cloud, rising sun, mountain peak, valley, crossroads - -COLOR USAGE: -- Black (#000000) for timeline spine and most milestone nodes -- Deep Purple (#4A148C) for [1-2 critical turning points] — nodes and illustrations -- Deep Teal (#00796B) for [supporting important events] -- Charcoal (#2D2D2D) for all text - -CRITICAL REQUIREMENTS: -- Hand-drawn timeline (NOT straight digital line) -- Clear temporal progression [left-to-right / top-to-bottom] -- Small illustrated metaphors at each point (simple, sketchy) -- 3-tier typography hierarchy -- Strategic color on key milestones only -- No gradients, flat colors only -- Maintains editorial illustration aesthetic -- Easy to scan and follow progression - -Optional: Sign small in bottom right corner in charcoal (#2D2D2D). -``` - ---- - -### Step 4: Determine Aspect Ratio - -| Timeline Type | Aspect Ratio | Reasoning | -|---------------|--------------|-----------| -| Horizontal timeline | 21:9 or 16:9 | Wide format for left-to-right flow | -| Vertical timeline | 9:16 | Tall format for top-to-bottom progression | -| Balanced/compact | 1:1 | Square for shorter timelines | -| Long historical | 21:9 | Maximum width for many events | - -**Default: 16:9 (horizontal)** — Classic timeline orientation - ---- - -### Step 5: Execute Generation - -```bash -bun run ~/.opencode/skills/Art/Tools/Generate.ts \ - --model nano-banana-pro \ - --prompt "[YOUR PROMPT]" \ - --size 2K \ - --aspect-ratio 16:9 \ - --output /path/to/timeline.png -``` - -**Model Recommendation:** nano-banana-pro (best for dates/text rendering) - -**Immediately Open:** -```bash -open /path/to/timeline.png -``` - ---- - -### Step 6: Validation (MANDATORY) - -#### Must Have -- [ ] **Clear temporal flow** — Obviously progresses through time -- [ ] **Readable dates/labels** — All text legible in hierarchy -- [ ] **Illustrated milestones** — Visual metaphors at each point -- [ ] **Hand-drawn timeline** — Organic line, not digital/straight -- [ ] **Narrative arc visible** — Shows transformation, not just dates -- [ ] **Strategic color** — Purple on critical moments, not everywhere -- [ ] **Scannable** — Easy to follow progression at a glance - -#### Must NOT Have -- [ ] Perfectly straight timeline -- [ ] Generic boring milestone markers (just dots) -- [ ] Illegible dates or cluttered text -- [ ] Too many milestones (overwhelming) -- [ ] Color chaos (everything highlighted) -- [ ] Looks like Gantt chart or business timeline - -#### If Validation Fails - -| Problem | Fix | -|---------|-----| -| Timeline too straight | "Organic hand-drawn line, slight waviness, imperfect curve" | -| No visual interest | "Small illustrated metaphors at each milestone showing the era's character" | -| Text unreadable | Increase spacing, strengthen typography tier sizes | -| Too cluttered | Reduce milestones to 4-6 key points, simplify | -| Looks corporate | Reference "editorial illustration style, hand-drawn sketch aesthetic" | -| Missing narrative | Emphasize metaphors that show transformation: "seedling → storm → sunrise" | - ---- - -## Example Use Cases - -### Example 1: "AI Winter → Spring → Summer" -- **Timeline:** 1970s → 2025 → Future -- **Milestones:** Winter (snowflake), Thaw (ice melting), Spring (bud), Summer (sun) -- **Color:** Purple on "Deep Learning Breakthrough" (2012) -- **Orientation:** Horizontal 16:9 - -### Example 2: "Security Thinking Evolution" -- **Timeline:** 2000 → Present -- **Milestones:** Each era with metaphor (fortress → ecosystem → adaptive) -- **Color:** Purple on paradigm shifts -- **Orientation:** Vertical 9:16 - -### Example 3: "Startup Journey: Idea to Scale" -- **Timeline:** Year 0 → Year 5 -- **Milestones:** Seedling → Sprout → Tree → Forest -- **Color:** Teal on funding rounds, purple on profitability -- **Orientation:** Horizontal 21:9 - ---- - -## Quick Reference - -**Timeline Formula:** -``` -1. Define timeline structure (subject, span, milestones, narrative) -2. Design layout (orientation, metaphors, spacing) -3. Construct prompt with illustrated progression -4. Choose aspect ratio for orientation -5. Generate with nano-banana-pro -6. Validate for clarity and visual narrative -``` - -**Color Strategy:** -- Timeline spine: Black -- 1-2 critical moments: Purple -- Supporting events: Teal -- Text: Charcoal - -**Metaphor Selection:** -- Choose simple, recognizable icons for each era -- Icons should show the FEELING/CHARACTER of that period -- Progression should tell a visual story - ---- - -**The workflow: Define → Design → Construct → Generate → Validate → Complete** diff --git a/.opencode/skills/Art/Workflows/ULWallpaper.md b/.opencode/skills/Art/Workflows/ULWallpaper.md deleted file mode 100755 index 9a4b30ac..00000000 --- a/.opencode/skills/Art/Workflows/ULWallpaper.md +++ /dev/null @@ -1,337 +0,0 @@ -# Create UL Wallpaper - -**Generate branded wallpapers with embedded logo concepts for Kitty terminal and macOS desktop.** - -## Voice Notification - -```bash -curl -s -X POST http://localhost:8888/notify \ - -H "Content-Type: application/json" \ - -d '{"message": "Running the ULWallpaper workflow in the Art skill to create wallpapers"}' \ - > /dev/null 2>&1 & -``` - -Running **ULWallpaper** in **Art**... - ---- - -Creates **4K 16:9 wallpapers** that integrate Unsupervised Learning logos as organic design elements — emblazoned, embossed, or woven into the composition. - ---- - -## Purpose - -Generate cohesive wallpapers that: -- Match the existing UL wallpaper aesthetic (dark tech, circuits, geometric patterns) -- Embed logo shapes/concepts as integral design elements (not just overlaid) -- Work for both Kitty terminal backgrounds (with 0.85 tint) and macOS desktop -- Maintain the blue/purple/teal color palette - ---- - -## Prerequisites - -**Logos Directory:** `~/Projects/Logos/` -Place logo files (PNG, SVG) here. The workflow will use these as reference for shape/concept integration. - -**Wallpaper Output:** `~/Projects/Wallpaper/` -Generated wallpapers are saved here and immediately available via `k -w `. - -**Reference Wallpapers:** `~/Projects/Wallpaper/` -Existing wallpapers to match aesthetic: -- `blue-lines.png` - Abstract flowing lines -- `blue-purple-circuits.png` - Circuit board pattern -- `blue-purple-squares.png` - Geometric squares -- `circuit-board.png` - Dense circuit traces - ---- - -## Workflow Steps - -### Step 1: Gather Input - -**Required from user:** -1. **Logo selection** — Which logo from `~/Projects/Logos/` to embed -2. **Style direction** — Circuit, geometric, abstract, flowing, etc. -3. **Integration style** — How logo appears: - - **Emblazoned** — Logo shape as glowing focal point - - **Embossed** — Logo as subtle raised/pressed texture - - **Woven** — Logo dissolved into pattern (circuits flow through it) - - **Negative space** — Logo revealed by absence of pattern -4. **Output name** — Filename for the wallpaper (kebab-case, no extension) - -**If no specific direction given:** -- Default to "woven" integration (most subtle) -- Match closest existing wallpaper style -- Use primary UL logo if available - -### Step 2: Analyze Logo - -Read the selected logo file to understand: -- Primary shapes and forms -- Key geometric elements -- Aspect ratio and proportions - -```bash -# List available logos -ls ~/Projects/Logos/ - -# View selected logo -open ~/Projects/Logos/.png -``` - -### Step 3: Load Reference Wallpaper - -View an existing wallpaper to match the aesthetic: - -```bash -open ~/Projects/Wallpaper/blue-purple-circuits.png -``` - -**Key aesthetic elements to maintain:** -- Dark background (#0a0a0f to #1a1a2e) -- Blue (#4a90d9), Purple (#8b5cf6), Teal (#06b6d4) accents -- Tech/digital feel (circuits, data streams, geometric patterns) -- Depth through blur and glow effects -- High contrast accent lines/nodes - -### Step 4: Construct Prompt - -**Base prompt template:** - -``` -Dark tech wallpaper for terminal/desktop, 16:9 4K resolution. - -BACKGROUND: Deep dark blue-black gradient (#0a0a0f to #1a1a2e) - -INTEGRATION: [LOGO_NAME] logo shape [INTEGRATION_STYLE]: -- [Describe how logo integrates with the pattern] -- [Logo should feel organic to the design, not overlaid] -- [Shape emerges from or defines the pattern flow] - -PATTERN STYLE: [STYLE_DIRECTION] -- [Specific pattern elements matching style] -- [How pattern interacts with logo shape] - -COLOR PALETTE: -- Primary: Electric blue (#4a90d9) — main circuit lines/elements -- Secondary: Deep purple (#8b5cf6) — accent glows, key nodes -- Tertiary: Cyan/teal (#06b6d4) — highlights, energy points -- Background: Near-black with subtle blue undertone - -EFFECTS: -- Subtle depth of field (sharper center, soft edges) -- Glow effects on key nodes and accent points -- Fine detail in circuit traces/patterns -- Atmospheric haze in corners - -CRITICAL: -- Logo shape is INTEGRAL to design, not overlaid -- Must work as terminal background with 85% dark tint overlay -- No text, no watermarks -- High contrast details for visibility through tint -- Professional, sophisticated tech aesthetic -``` - -### Step 5: Generate Wallpaper - -```bash -bun run ~/.opencode/skills/Art/Tools/Generate.ts \ - --model nano-banana-pro \ - --prompt "[CONSTRUCTED_PROMPT]" \ - --size 4K \ - --aspect-ratio 16:9 \ - --reference-image ~/Projects/Logos/.png \ - --output ~/Projects/Wallpaper/.png -``` - -**Parameters:** -- `--size 4K` — Maximum resolution -- `--aspect-ratio 16:9` — Standard widescreen -- `--reference-image` — Logo file for shape guidance - -### Step 6: Preview and Validate - -**Open the generated wallpaper:** -```bash -open ~/Projects/Wallpaper/.png -``` - -**Validation checklist:** -- [ ] Logo shape is recognizable but integrated (not pasted on) -- [ ] Color palette matches UL aesthetic (blue/purple/teal on dark) -- [ ] Pattern has enough contrast to show through Kitty tint -- [ ] No artifacts, text, or watermarks -- [ ] Professional quality suitable for desktop/terminal - -**If validation fails:** -- Adjust prompt specificity for logo integration -- Try different integration style -- Regenerate with refined prompt - -### Step 7: Apply Wallpaper - -Once validated, apply immediately: - -```bash -k -w -``` - -This sets both Kitty terminal and macOS desktop backgrounds. - ---- - -## Integration Styles Reference - -### Emblazoned -Logo as the **glowing focal point** — circuits/patterns radiate outward from it. -``` -Logo shape as central glowing element, circuit traces emanating outward from its edges, -energy nodes at key logo vertices, pattern density increases near logo -``` - -### Embossed -Logo as **subtle texture** — raised or pressed into the pattern layer. -``` -Logo shape visible as subtle raised/depressed region in the pattern, -same color palette but slightly different luminosity, discoverable not obvious -``` - -### Woven -Logo shape **defines pattern flow** — elements flow through/around it. -``` -Circuit traces and geometric elements flow through and around logo shape, -logo boundary influences pattern direction, shape emerges from negative space -``` - -### Negative Space -Logo **revealed by absence** — pattern stops at logo boundaries. -``` -Dense pattern everywhere except logo shape, logo appears as void/window, -subtle glow at logo edges where pattern meets empty space -``` - ---- - -## Style Directions Reference - -### Circuit -Dense circuit board traces, nodes, and connection points. -``` -PCB-style traces with right-angle turns, solder points as nodes, -varying trace widths, layer depth with traces at different z-levels -``` - -### Geometric -Abstract geometric shapes, grids, and mathematical patterns. -``` -Interlocking geometric shapes, hexagonal grids, triangular tessellation, -isometric depth, clean edges with subtle glow -``` - -### Flowing -Organic flowing lines, data streams, particle flows. -``` -Smooth curved lines suggesting data flow, particle streams, -gradient intensity along flow direction, organic movement feel -``` - -### Abstract -Non-representational artistic interpretation. -``` -Abstract color fields, gradient washes, subtle texture, -artistic interpretation of tech aesthetic, minimal but sophisticated -``` - ---- - -## Example Prompts - -### Example 1: UL Logo Woven into Circuits -``` -Dark tech wallpaper for terminal/desktop, 16:9 4K resolution. - -BACKGROUND: Deep dark blue-black gradient (#0a0a0f to #1a1a2e) - -INTEGRATION: Unsupervised Learning logo shape woven into circuit pattern: -- Circuit traces flow through and around the logo silhouette -- Logo boundary subtly influences trace direction -- Shape emerges naturally from the pattern density changes -- Not overlaid — the pattern DEFINES the logo through flow - -PATTERN STYLE: Dense circuit board -- Fine PCB-style traces with right-angle routing -- Glowing nodes at trace intersections -- Multiple depth layers (foreground sharp, background soft) -- Trace density varies to create visual interest - -COLOR PALETTE: -- Primary: Electric blue (#4a90d9) — main traces -- Secondary: Deep purple (#8b5cf6) — key nodes, logo edge glow -- Tertiary: Cyan (#06b6d4) — energy highlights -- Background: Near-black (#0a0a0f) - -EFFECTS: -- Depth of field blur at edges -- Subtle purple glow where logo shape meets pattern -- Fine detail in traces (visible at 4K) -- Atmospheric corner vignette - -CRITICAL: Logo integrated into design, not overlaid. Must show through 85% dark tint. -``` - -### Example 2: Logo Emblazoned in Geometric Field -``` -Dark tech wallpaper for terminal/desktop, 16:9 4K resolution. - -BACKGROUND: Deep space gradient (#0a0a0f to #1a1a2e) - -INTEGRATION: UL logo as central emblazoned element: -- Logo shape glows at center with purple (#8b5cf6) core -- Geometric patterns radiate outward from logo edges -- Energy lines connect logo vertices to outer pattern -- Logo is the source/origin of all pattern elements - -PATTERN STYLE: Geometric hexagonal grid -- Hexagonal tessellation extending from logo -- Grid density increases toward edges -- Subtle isometric depth -- Clean geometric precision - -COLOR PALETTE: -- Primary: Electric blue (#4a90d9) — grid lines -- Secondary: Deep purple (#8b5cf6) — logo glow, accent nodes -- Tertiary: Cyan (#06b6d4) — energy connections -- Background: Near-black with blue undertone - -EFFECTS: -- Central glow around logo -- Sharp center, soft edges -- Subtle particle effects -- Corner vignette - -CRITICAL: Logo as design origin point, not pasted overlay. High contrast for tint visibility. -``` - ---- - -## Quick Reference - -| Parameter | Value | -|-----------|-------| -| Model | nano-banana-pro | -| Size | 4K | -| Aspect Ratio | 16:9 | -| Output Directory | ~/Projects/Wallpaper/ | -| Logo Source | ~/Projects/Logos/ | -| Apply Command | `k -w ` | - -**Color Palette:** -- Background: #0a0a0f to #1a1a2e -- Blue: #4a90d9 -- Purple: #8b5cf6 -- Teal/Cyan: #06b6d4 - -**Integration Styles:** Emblazoned, Embossed, Woven, Negative Space - -**Pattern Styles:** Circuit, Geometric, Flowing, Abstract diff --git a/.opencode/skills/Art/Workflows/Visualize.md b/.opencode/skills/Art/Workflows/Visualize.md deleted file mode 100755 index dedb7087..00000000 --- a/.opencode/skills/Art/Workflows/Visualize.md +++ /dev/null @@ -1,795 +0,0 @@ -# Adaptive Content Visualization Workflow - -**Intelligent multi-modal visualization combining optimal approaches based on content analysis.** - -Creates **ADAPTIVE VISUALIZATIONS** — analyzes content to select and orchestrate the best combination of visualization techniques, from pure data viz to mixed-media infographics to multi-panel compositions. - ---- - -## Purpose - -The Visualize workflow is the **intelligent visualization orchestrator**. Unlike the 12 specialized workflows (which each serve specific purposes), Visualize analyzes your content and chooses the optimal visualization strategy — which may be one approach, or a sophisticated combination of multiple techniques. - -**Use this workflow when:** -- You have content but aren't sure what visualization approach to use -- The content has multiple dimensions (data + narrative + concepts) -- You want the most effective visualization, not a predetermined format -- You're asking "what's the best way to visualize this?" -- You want to leverage Nano Banana Pro's full capabilities - -**This workflow DOES NOT use:** -- Predetermined templates -- One-size-fits-all approaches -- Single-mode visualizations when combinations would be better - ---- - -## 🚨 INFOGRAPHICS: Use Excalidraw Whiteboard Style - -**Infographics use the EXCALIDRAW whiteboard sketch aesthetic** — hand-drawn with wobbly boxes, sketchy lines, and imperfect organic shapes. This is the same style as mermaid.md technical diagrams but with richer graphics and narrative. - -**Key principle:** Infographics = Excalidraw aesthetic + Rich graphics + Visual narrative - -### Excalidraw Infographic Aesthetic - -``` -STYLE: Excalidraw whiteboard sketch with rich graphics -- WOBBLY BOXES — rectangles with rough, hand-drawn edges (not perfect) -- SKETCHY LINES — arrows and connections with slight wobble -- IMPERFECT SHAPES — circles slightly oval, diamonds asymmetric -- HAND-LETTERED TEXT — labels look handwritten, not typed -- WHITEBOARD FEEL — looks like someone drew this on a whiteboard -- VARIABLE LINE WEIGHT — heavier for boxes, lighter for details -- RICH GRAPHICS — icons, illustrations, visual metaphors (all sketchy) -``` - -### What Makes a Good Excalidraw Infographic - -1. **Hand-Drawn Feel** — Everything looks sketched, not digital -2. **Wobbly Shapes** — No perfect rectangles, circles, or lines -3. **Rich Graphics** — Icons and illustrations in sketchy style -4. **Visual Narrative** — Panels flow and tell a story -5. **Strategic Color** — Purple/teal accents on key elements, mostly black - -### AVOID - -``` -❌ Perfect geometric shapes -❌ Ruler-straight lines and arrows -❌ Digital precision -❌ Smooth polished vectors -❌ Perfect alignment -❌ Clean corporate infographic style -``` - -### Color Usage - -``` -- Black (#000000): All primary structure (boxes, arrows, icons) -- Deep Purple (#4A148C): Critical elements, key stats, title (10-20%) -- Deep Teal (#00796B): Secondary highlights (5-10%) -- Charcoal (#2D2D2D): All text labels -- Background: Light Cream #F5E6D3 or White #FFFFFF -``` - -### Background Rules - -``` -DEFAULT: Light Cream/Sepia #F5E6D3 (matches blog aesthetic) -WHITE ONLY IF: User explicitly requests "white background" in prompt -TRANSPARENT: Use Images skill to remove background for overlay use -``` - -**Light Cream (#F5E6D3) is the DEFAULT background.** Only use white (#FFFFFF) if the user explicitly requests it. - -**For transparent background** — use the **Images skill** for background removal: - -```bash -bun ~/.opencode/skills/CORE/Tools/RemoveBg.ts /path/to/visualization.png -``` - -### Title/Subtitle Alignment - -``` -ALWAYS LEFT-JUSTIFIED — Never centered -- Title: Top-left with margin -- Subtitle: Below title, aligned left -``` - -### Infographic Prompt Template - -``` -Excalidraw-style whiteboard infographic with rich hand-drawn graphics. - -STYLE: Excalidraw whiteboard sketch aesthetic -- Wobbly rectangles with rough edges (not perfect boxes) -- Sketchy arrows with slight wobble (not ruler-straight) -- Imperfect shapes throughout (circles slightly oval) -- Hand-lettered text labels (natural slant, imperfect) -- Variable line weight (boxes thicker, details thinner) -- Whiteboard/sketch paper feel - -BACKGROUND: Light Cream #F5E6D3 (DEFAULT) — only use White #FFFFFF if explicitly requested - -TYPOGRAPHY SYSTEM (3-TIER): - -TIER 1 - TITLE & SUBTITLE (Valkyrie): -Title: -- "[Title]" -- Font: Valkyrie serif ITALIC -- Position: LEFT-JUSTIFIED, top-left with margin -- Color: Purple #4A148C (or Black #000000) -- Size: Large, 3-4x body text - -Subtitle: -- "[Subtitle]" -- Font: Valkyrie serif REGULAR (NOT italic) -- Position: LEFT-JUSTIFIED, below title -- Color: Charcoal #2D2D2D -- Size: Small, 1-1.5x body text - -TIER 2 - PANEL HEADERS & LABELS (Concourse + Valkyrie): -Panel Headers: -- Font: Concourse geometric sans-serif, bold -- Color: Black #000000 -- Style: Uppercase - -Content Labels: -- Technical labels: Concourse geometric sans -- Descriptions: Valkyrie serif -- Color: Charcoal #2D2D2D - -TIER 3 - ANNOTATIONS (Advocate): -- Font: Advocate condensed italic -- Color: Purple #4A148C or Teal #00796B -- Style: Smaller, insight/commentary voice - -[Describe each panel with SKETCHY VISUAL ELEMENTS:] -- Hand-drawn icons and illustrations (wobbly, organic) -- Data visualized with sketchy charts/graphics -- Panels as wobbly boxes with headers -- Flow shown with sketchy arrows - -COLOR USAGE: -- Black: All primary structure and most elements -- Purple: Title, key stats, critical accents -- Teal: Secondary highlights -- Charcoal: All body text - -CRITICAL: -- Excalidraw hand-drawn whiteboard aesthetic throughout -- All shapes imperfect, all lines wobbly -- Title/subtitle LEFT-JUSTIFIED, not centered -- Use proper font hierarchy (Valkyrie, Concourse, Advocate) -``` - -**Reference:** See `mermaid.md` for complete Excalidraw aesthetic specification. - ---- - -## Nano Banana Pro Capabilities - -**Understanding what's possible:** - -### Core Strengths -1. **Exceptional text rendering** — Clean typography, readable labels, multiple text tiers -2. **Data visualization** — Charts, graphs, quantitative displays -3. **Infographic composition** — Multi-element layouts, mixed media -4. **Iconic illustration** — Simple recognizable symbols and icons -5. **Multi-panel layouts** — Grids, sequences, comparative layouts -6. **Hybrid compositions** — Data + illustration + typography together -7. **Slide-quality output** — Presentation-ready visualizations - -### What Nano Banana Pro Excels At -- **Text-heavy compositions** — Infographics with lots of labels -- **Data + context** — Numbers with explanatory illustrations -- **Icon systems** — Repeated simplified icons showing quantities -- **Multi-tier typography** — Clear hierarchies (titles, labels, annotations) -- **Mixed media** — Charts alongside illustrations -- **Grid layouts** — Organized multi-element compositions -- **Comparative panels** — Side-by-side or sequential comparisons - ---- - -## 🚨 MANDATORY WORKFLOW STEPS - -### Step 1: Deep Content Analysis (MANDATORY - Use deep thinking) - -**🎯 CRITICAL: Use extended thinking to analyze content thoroughly before proceeding.** - -Analyze the content across these dimensions: - -#### A. Content Type Identification -What types of information are present? -- [ ] Quantitative data (numbers, statistics, metrics) -- [ ] Qualitative concepts (ideas, principles, arguments) -- [ ] Narrative elements (stories, sequences, transformations) -- [ ] Comparative elements (X vs Y, before/after, tradeoffs) -- [ ] Hierarchical structures (taxonomies, frameworks, levels) -- [ ] Temporal elements (timelines, evolution, progressions) -- [ ] Spatial relationships (maps, territories, domains) -- [ ] Process flows (steps, recipes, methodologies) - -#### B. Communication Goal -What's the primary purpose? -- Explain a complex concept → Conceptual visualization -- Show data insights → Data visualization dominant -- Compare alternatives → Comparison/split approach -- Tell a story → Sequential/narrative visualization -- Organize information → Taxonomy/grid approach -- Guide action → Process/recipe format -- Make memorable → Metaphor + data hybrid - -#### C. Audience Context -Who's this for? -- Technical audience → More data, precision, structure -- General audience → More metaphor, simplification, narrative -- Executive audience → High-level insights, clear takeaways -- Social media → Punchy, scannable, shareable -- Consulting deliverable → Professional, multi-faceted, comprehensive - -#### D. Complexity Assessment -How much information needs to be conveyed? -- **Simple (1-2 key points):** Single focused visualization -- **Medium (3-5 dimensions):** Hybrid or two-element composition -- **Complex (6+ dimensions):** Multi-panel infographic or dashboard - -**Output from Analysis:** -``` -CONTENT TYPE: [Primary and secondary types from above] -INFORMATION DENSITY: [Simple / Medium / Complex] -COMMUNICATION GOAL: [Primary purpose] -AUDIENCE: [Who this is for] - -KEY ELEMENTS TO VISUALIZE: -1. [Element type: data/concept/narrative/etc.] -2. [Element type] -3. [Element type] -... - -VISUALIZATION OPPORTUNITIES: -- Data points that could be charts/graphs -- Concepts that need metaphors or icons -- Comparisons that need side-by-side -- Sequences that need panels or flow -- Hierarchies that need taxonomies or frameworks -``` - ---- - -### Step 2: Visualization Strategy Selection (MANDATORY - Use deep thinking) - -**Based on Step 1 analysis, determine the optimal approach:** - -#### Strategy Options - -**A. SINGLE-MODE (Use one specialized workflow)** -When content clearly fits one visualization type: -- Pure data → Create data visualization -- Pure concept → Use editorial illustration or framework -- Pure comparison → Use comparison workflow -- Pure process → Use recipe card workflow - -**B. HYBRID COMPOSITION (Combine 2-3 elements)** -When content has multiple dimensions: -- **Data + Metaphor:** Chart/graph with editorial illustration accent -- **Data + Process:** Numbers showing outcomes at each step -- **Concept + Structure:** Framework with illustrated metaphors in quadrants -- **Timeline + Data:** Progression with quantitative milestones -- **Comparison + Data:** Split screen with metrics on each side - -**C. MULTI-PANEL INFOGRAPHIC (Dashboard approach)** -When content is complex and multifaceted: -- **Grid layout:** 4-6 panels each showing different aspect -- **Layered composition:** Top section data, middle concepts, bottom process -- **Dashboard:** Multiple charts/graphs with unified design -- **Slide series:** Sequential slides each focusing on one dimension - -#### Decision Framework - -``` -IF content has 1 primary dimension: - → Use specialized workflow directly - -IF content has 2-3 dimensions of equal importance: - → Design HYBRID composition - -IF content has 4+ distinct dimensions: - → Design MULTI-PANEL infographic - -IF content is primarily quantitative: - → Lead with DATA VISUALIZATION - → Add conceptual elements as context - -IF content is primarily conceptual: - → Lead with METAPHOR/FRAMEWORK - → Add data as supporting evidence - -IF content tells a story: - → Use SEQUENTIAL approach - → Could be comic, timeline, or multi-step -``` - -**Output from Strategy Selection:** -``` -VISUALIZATION STRATEGY: [Single-mode / Hybrid / Multi-panel] - -CHOSEN APPROACH: -[Describe the specific visualization approach] - -COMPOSITION ELEMENTS: -Primary element (60-70%): [Type and purpose] -Secondary element (20-30%): [Type and purpose] -Tertiary element (10%): [Type and purpose - optional] - -LAYOUT STRUCTURE: -[Describe how elements are arranged spatially] - -ASPECT RATIO: [1:1 / 16:9 / 9:16 / 4:3] -Rationale: [Why this ratio for this content] -``` - ---- - -### Step 3: Design Composition (MANDATORY - Use deep thinking) - -**Plan the visual hierarchy and spatial organization:** - -#### A. Spatial Layout -Design how elements occupy the canvas: - -**For Single-Mode:** -- Follow the specialized workflow's layout guidelines -- Optimize for Nano Banana Pro's strengths - -**For Hybrid Composition:** -``` -Example: Data + Metaphor -┌─────────────────────────────────────┐ -│ │ -│ [TITLE - Advocate Block] │ -│ │ -│ ┌───────────┐ ┌──────────────┐ │ -│ │ │ │ │ │ -│ │ DATA │ │ METAPHOR │ │ -│ │ CHART │ │ ILLUSTRATION │ │ -│ │ │ │ │ │ -│ └───────────┘ └──────────────┘ │ -│ 40% 40% │ -│ │ -│ [Explanatory text - 20%] │ -│ │ -└─────────────────────────────────────┘ -``` - -**For Multi-Panel Infographic:** -``` -Example: Dashboard Grid -┌─────────────────────────────────────┐ -│ [OVERALL TITLE] │ -├─────────────┬───────────────────────┤ -│ Panel 1: │ Panel 2: │ -│ Data viz │ Concept diagram │ -├─────────────┼───────────────────────┤ -│ Panel 3: │ Panel 4: │ -│ Timeline │ Key stat + icon │ -├─────────────┴───────────────────────┤ -│ [Synthesis/Conclusion panel] │ -└─────────────────────────────────────┘ -``` - -#### B. Visual Hierarchy -Establish information priority: -1. **Primary (Immediate attention):** 50-60% of visual weight -2. **Secondary (Supporting context):** 25-35% of visual weight -3. **Tertiary (Details/annotations):** 10-15% of visual weight - -#### C. Typography System -Apply 3-tier system across all elements: -- **Tier 1 (Advocate Block):** Main title, section headers -- **Tier 2 (Concourse Sans):** Data labels, chart axes, element labels -- **Tier 3 (Advocate Condensed Italic):** Annotations, insights, editorial voice - -#### D. Color Strategy -Maintain UL aesthetic while supporting information hierarchy: -- **Black #000000:** Primary structure (chart axes, borders, main elements) -- **Purple #4A148C:** Critical insights, key data points, optimal zones -- **Teal #00796B:** Secondary data, supporting elements, context -- **Charcoal #2D2D2D:** All body text and labels -- **Background:** Light Cream #F5E6D3 (DEFAULT — only use white if explicitly requested) - -Strategic color use: -- Don't color everything -- Purple for "look here" moments -- Teal for supporting information -- Black for structure and clarity - -**Output from Design:** -``` -COMPOSITION LAYOUT: -[Detailed spatial description or ASCII diagram] - -VISUAL HIERARCHY: -Primary (50-60%): [Element and placement] -Secondary (25-35%): [Element and placement] -Tertiary (10-15%): [Element and placement] - -TYPOGRAPHY ASSIGNMENTS: -Tier 1: [Where used - titles, headers] -Tier 2: [Where used - labels, axes] -Tier 3: [Where used - annotations, insights] - -COLOR CODING: -Purple: [Specific elements to highlight] -Teal: [Supporting elements] -Black: [Structural elements] -Text: All charcoal - -ELEMENT SPECIFICATIONS: -[For each major element, specify:] -- Type (chart/icon/illustration/text) -- Size (% of canvas) -- Position (coordinates or relative placement) -- Style (data viz / editorial / typographic) -``` - ---- - -### Step 4: Construct Comprehensive Prompt (MANDATORY - Use deep thinking) - -**Build the generation prompt leveraging Nano Banana Pro's capabilities:** - -#### Prompt Structure Template - -``` -[VISUALIZATION TYPE] in editorial infographic style optimized for Nano Banana Pro. - -OVERALL CONCEPT: "[What this visualization communicates]" - -STYLE REFERENCE: [Professional infographic / Data journalism / Editorial slide / Mixed media visualization] - -BACKGROUND: Light Cream #F5E6D3 (DEFAULT) — only use White #FFFFFF if user explicitly requests it - -AESTHETIC: -- Professional infographic quality (deliverable standard) -- Hand-drawn editorial elements where appropriate -- Clean data visualization where precise -- Variable stroke weight (thicker for structure, thinner for details) -- Flat colors, no gradients or shadows -- Readable at multiple scales (works as thumbnail and full-size) - -ASPECT RATIO: [1:1 / 16:9 / 9:16 / 4:3] - -COMPOSITION STRUCTURE: -[Detailed description of spatial layout] - -TYPOGRAPHY SYSTEM (3-TIER HIERARCHY): - -TIER 1 - VISUALIZATION HEADER & SUBTITLE (Valkyrie Two-Part System): -Header (Main Title): -- "[Header Text]" -- Font: Valkyrie serif italic (elegant, sophisticated) -- Size: Large - 3-4x body text (prominent, commanding attention) -- Style: Italicized, sentence case or title case (NOT all-caps) -- Color: Black #000000 (or Purple #4A148C for emphasis) -- Position: Top-left with margin - -Subtitle (Clarifying Detail): -- "[Subtitle Text]" -- Font: Valkyrie serif regular (warm, readable) -- Size: Small - 1-1.5x body text (noticeably smaller than header, supportive) -- Style: Regular (NOT italicized), sentence case (first letter capitalized, rest lowercase except proper nouns) -- Color: Black #000000 or Charcoal #2D2D2D -- Position: Small gap below header, aligned left - -TIER 2 - ELEMENT LABELS (Concourse Sans): -- [List all labels: chart axes, data labels, section headers] -- Font: Concourse geometric sans-serif, clean, modern -- Size: Medium readable -- Color: Charcoal #2D2D2D -- Positions: [Specify for each] - -TIER 3 - ANNOTATIONS (Advocate Condensed Italic): -- [List all annotations and insights] -- Font: Advocate condensed italic (editorial voice) -- Size: Small (60% of Tier 2) -- Color: Purple #4A148C (insights) or Teal #00796B (technical notes) -- Positions: [Near relevant elements] - -[FOR EACH MAJOR ELEMENT IN COMPOSITION:] - -ELEMENT 1: [TYPE - e.g., Bar Chart / Line Graph / Icon Grid] -- Purpose: [What this element communicates] -- Position: [Location in composition] -- Size: [Dimensions or % of canvas] -- Data to show: [Specific data points or values] -- Style: [Precise data viz / Hand-drawn editorial / Hybrid] -- Color: Black structure, Purple highlights on [specific], Teal on [specific] -- Labels: [Tier 2 typography for all labels] -- Details: [Any specific styling notes] - -ELEMENT 2: [TYPE - e.g., Editorial Illustration / Framework Diagram] -- Purpose: [What this element communicates] -- Position: [Location in composition] -- Size: [Dimensions or % of canvas] -- Content: [What to illustrate] -- Style: [Hand-drawn / Iconic / Metaphorical] -- Color: Black linework, Purple accents on [specific] -- Integration: [How it relates to other elements] - -[Continue for all elements...] - -COLOR USAGE (Strategic, not overwhelming): -- Black (#000000): [All primary structure, chart elements, borders] -- Deep Purple (#4A148C): [Critical data points, key insights, optimal zones] -- Deep Teal (#00796B): [Secondary data, supporting elements] -- Charcoal (#2D2D2D): [All text labels and annotations] -- Background: Light Cream #F5E6D3 (DEFAULT — white only if explicitly requested) - -CRITICAL REQUIREMENTS FOR NANO BANANA PRO: -- Exceptional text rendering required (multiple labels, clean typography) -- Data precision where needed (accurate chart rendering) -- Hand-drawn editorial quality where appropriate -- Multi-element composition with clear visual hierarchy -- Professional infographic / slide quality -- Readable at both thumbnail and full resolution -- No gradients, flat colors only -- Strategic color (not every element colored) -- All elements work together as unified composition - -VALIDATION CHECKPOINTS: -- Is the primary message immediately clear? -- Can each element be read/understood independently? -- Do elements work together to tell complete story? -- Is typography hierarchy obvious? -- Are data elements accurate and precise? -- Do editorial elements enhance (not distract from) information? - -Optional: Sign small in bottom right corner in charcoal (#2D2D2D). -``` - ---- - -### Step 5: Generate with Nano Banana Pro - -**Execute the visualization using intent-to-flag mapping:** - -#### Intent-to-Flag Mapping - -**Interpret user request and select appropriate flags:** - -| User Says | Flag | When to Use | -|-----------|------|-------------| -| "fast", "quick", "draft" | `--model nano-banana` | Faster iteration, slightly lower quality | -| (default), "best", "high quality" | `--model nano-banana-pro` | Best quality + text rendering (recommended) | -| "flux", "stylistic variety" | `--model flux` | Different aesthetic, stylistic variety | - -| User Says | Flag | Resolution | -|-----------|------|------------| -| "draft", "preview" | `--size 1K` | Quick iterations | -| (default), "standard" | `--size 2K` | Standard output | -| "high res", "print", "large" | `--size 4K` | Maximum resolution | - -| User Says | Flag | Use Case | -|-----------|------|----------| -| "square", "social" | `--aspect-ratio 1:1` | Social media, grids | -| "wide", "slide", "presentation" | `--aspect-ratio 16:9` | Slides, presentations | -| "portrait", "mobile" | `--aspect-ratio 9:16` | Mobile, vertical | -| "blog header" | `--thumbnail` | Creates transparent + thumb versions | -| "variations", "options" | `--creative-variations 3` | Multiple versions | - -**Construct command based on intent:** - -```bash -bun run ~/.opencode/skills/Art/Tools/Generate.ts \ - --model [SELECTED_MODEL] \ - --prompt "[YOUR COMPREHENSIVE PROMPT]" \ - --size [SELECTED_SIZE] \ - --aspect-ratio [chosen ratio] \ - [--thumbnail if for blog] \ - [--creative-variations N if variations requested] \ - --output /path/to/visualization.png -``` - -**Why Nano Banana Pro for this workflow:** -- Best text rendering among all models (critical for infographics) -- Handles complex multi-element compositions well -- Excellent at data visualization elements -- Can combine precise (charts) with expressive (editorial) styles -- Reliable for professional deliverable quality - -**Immediately open for review:** -```bash -open /path/to/visualization.png -``` - ---- - -### Step 6: Comprehensive Validation (MANDATORY) - -**Validate across multiple dimensions:** - -#### Information Effectiveness -- [ ] **Primary message clear:** Main insight obvious within 3 seconds -- [ ] **Data accuracy:** Numbers, proportions, relationships accurate -- [ ] **Visual hierarchy works:** Eye flows from primary → secondary → tertiary -- [ ] **All elements readable:** Text legible, charts clear, icons recognizable -- [ ] **Story cohesion:** Elements work together, not competing - -#### Design Quality -- [ ] **Professional deliverable:** Client/publication ready -- [ ] **UL aesthetic maintained:** Flat colors, appropriate hand-drawn vs precise -- [ ] **Typography hierarchy clear:** 3 tiers obviously distinct -- [ ] **Color strategic:** Purple/teal highlight key elements, not overwhelming -- [ ] **Composition balanced:** Visual weight distributed appropriately - -#### Technical Execution -- [ ] **Text rendering clean:** No blurry or malformed letters -- [ ] **Data viz precision:** Charts/graphs accurate and clear -- [ ] **Scale works:** Readable as thumbnail AND full-size -- [ ] **No gradients/shadows:** Flat aesthetic maintained -- [ ] **Aspect ratio appropriate:** Format suits content and use case - -#### Audience Appropriateness -- [ ] **Matches audience sophistication:** Not too simple or too complex -- [ ] **Serves communication goal:** Actually achieves intended purpose -- [ ] **Platform optimized:** Works for intended distribution (social/email/presentation) - -#### If Validation Fails - -**Common issues and fixes:** - -| Problem | Diagnosis | Fix | -|---------|-----------|-----| -| **Too cluttered** | Too many elements competing | Simplify: reduce to 2-3 main elements, increase whitespace | -| **Message unclear** | No clear visual hierarchy | Strengthen primary element (make larger, add purple), reduce secondary | -| **Text unreadable** | Font too small or wrong tier | Increase label sizes, strengthen typography tier differentiation | -| **Data imprecise** | Chart rendering issues | Add specific data points in prompt, request precision explicitly | -| **Looks generic** | Missing UL aesthetic | Add hand-drawn editorial elements, strategic purple/teal, flatten any gradients | -| **Elements disconnected** | Poor composition | Redesign spatial layout, add visual connectors (arrows, borders, grouping) | -| **Color chaos** | Too much color everywhere | Limit purple to 2-3 key elements, teal to 1-2 supporting, rest black/charcoal | -| **Not professional** | Too sketchy or too rigid | Balance: data viz precise, editorial elements hand-drawn, clean typography | - -**Regeneration Process:** -1. Identify specific validation failures -2. Update prompt with targeted fixes -3. Regenerate with refined prompt -4. Re-validate against all checkpoints -5. Repeat until ALL validation criteria pass - -**CRITICAL: Do not declare completion until validation passes.** - ---- - -## Visualization Pattern Library - -**Common effective combinations:** - -### Pattern 1: Data + Metaphor Hybrid -**When:** Data needs conceptual context -**Layout:** 50% data visualization + 40% editorial illustration + 10% explanatory text -**Example:** Growth chart with rocket ship illustration showing trajectory -**Aspect:** 16:9 or 1:1 - -### Pattern 2: Comparative Dashboard -**When:** Analyzing multiple dimensions of comparison -**Layout:** Split or grid with data on each side/panel -**Example:** "Before AI vs After AI" with metrics and illustrations for each state -**Aspect:** 16:9 (split) or 1:1 (grid) - -### Pattern 3: Process + Outcomes -**When:** Showing methodology with results -**Layout:** Vertical or horizontal flow with data at key milestones -**Example:** 5-step recipe with success metrics at each step -**Aspect:** 9:16 (vertical) or 16:9 (horizontal) - -### Pattern 4: Icon Quantification -**When:** Showing quantities through repeated visual elements -**Layout:** Grid of icons where quantity = visual count -**Example:** "78 out of 100 developers" shown as 78 purple icons + 22 gray icons -**Aspect:** 1:1 or 4:3 - -### Pattern 5: Annotated Data Story -**When:** Data needs narrative explanation -**Layout:** Primary chart with hand-drawn annotations explaining insights -**Example:** Timeline chart with purple arrows: "*this is when everything changed*" -**Aspect:** 16:9 or 21:9 - -### Pattern 6: Multi-Chart Dashboard -**When:** Multiple related datasets -**Layout:** Grid of 2-4 charts with unified design language -**Example:** 4-panel view: bar chart, line graph, pie chart, key stat -**Aspect:** 16:9 or 1:1 - -### Pattern 7: Framework + Data -**When:** Conceptual model with quantitative evidence -**Layout:** Framework structure (2x2, Venn, pyramid) with data in each zone -**Example:** 2x2 matrix with percentage of companies in each quadrant -**Aspect:** 1:1 - -### Pattern 8: Infographic Slide -**When:** Comprehensive content for presentation -**Layout:** Title + multiple small visualizations + key takeaway -**Example:** Slide with 3 mini-charts + 2 key stats + insight annotation -**Aspect:** 16:9 (slide format) - ---- - -## Decision Tree Summary - -``` -START: Analyze content deeply (Step 1) - ↓ -Is content primarily ONE dimension? - ├─ YES → Use specialized workflow directly - │ (Editorial / Technical / Timeline / etc.) - │ - └─ NO → Content has multiple dimensions - ↓ - Are there 2-3 equal dimensions? - ├─ YES → HYBRID composition - │ Design complementary elements - │ (Data + Metaphor, Process + Outcomes, etc.) - │ - └─ NO → 4+ dimensions or very complex - ↓ - MULTI-PANEL infographic - Grid or layered dashboard approach - Each panel addresses one dimension - -For HYBRID or MULTI-PANEL: - ↓ -Design composition (Step 3) - → Spatial layout - → Visual hierarchy - → Typography tiers - → Color strategy - ↓ -Construct comprehensive prompt (Step 4) - → Detailed element specifications - → Leverage Nano Banana Pro strengths - → Clear validation checkpoints - ↓ -Generate with nano-banana-pro (Step 5) - ↓ -VALIDATE comprehensively (Step 6) - → Information effectiveness - → Design quality - → Technical execution - → Audience appropriateness - ↓ -PASS? → Complete -FAIL? → Diagnose, fix, regenerate -``` - ---- - -## Quick Reference - -### When to Use Visualize Workflow -- Content has multiple dimensions to visualize -- You want optimal approach, not predetermined format -- Combining data + concepts + narrative -- Creating professional infographics or slides -- Need sophisticated composition beyond single workflow - -### Nano Banana Pro Advantages -- Best text rendering (critical for labels/annotations) -- Multi-element composition handling -- Data visualization capabilities -- Professional infographic quality -- Hybrid precision + expressiveness - -### Core Principles -1. **Analyze first** — Deep content analysis before choosing approach -2. **Strategic combination** — Use hybrid only when it serves content -3. **Visual hierarchy** — Clear primary/secondary/tertiary structure -4. **Color discipline** — Purple/teal strategic, not everywhere -5. **Professional quality** — Deliverable to clients/publications -6. **Validate thoroughly** — Information + design + technical + audience - ---- - -**The workflow: Analyze → Strategy → Design → Prompt → Generate → Validate → Complete** - -**The meta-principle: Let content dictate form. Use the full power of Nano Banana Pro to create the most effective visualization, whether that's one approach or a sophisticated orchestration of multiple techniques.** diff --git a/.opencode/skills/Art/YouTubeThumbnailExamples/Audio1.png b/.opencode/skills/Art/YouTubeThumbnailExamples/Audio1.png deleted file mode 100755 index 1abf1458..00000000 Binary files a/.opencode/skills/Art/YouTubeThumbnailExamples/Audio1.png and /dev/null differ diff --git a/.opencode/skills/Art/YouTubeThumbnailExamples/Main1.png b/.opencode/skills/Art/YouTubeThumbnailExamples/Main1.png deleted file mode 100755 index 809130de..00000000 Binary files a/.opencode/skills/Art/YouTubeThumbnailExamples/Main1.png and /dev/null differ diff --git a/.opencode/skills/Art/YouTubeThumbnailExamples/Main2.png b/.opencode/skills/Art/YouTubeThumbnailExamples/Main2.png deleted file mode 100755 index 5295a7a1..00000000 Binary files a/.opencode/skills/Art/YouTubeThumbnailExamples/Main2.png and /dev/null differ diff --git a/.opencode/skills/Art/YouTubeThumbnailExamples/Main3.png b/.opencode/skills/Art/YouTubeThumbnailExamples/Main3.png deleted file mode 100755 index 1d936e5a..00000000 Binary files a/.opencode/skills/Art/YouTubeThumbnailExamples/Main3.png and /dev/null differ diff --git a/.opencode/skills/Art/YouTubeThumbnailExamples/Main4.png b/.opencode/skills/Art/YouTubeThumbnailExamples/Main4.png deleted file mode 100755 index 68d5c338..00000000 Binary files a/.opencode/skills/Art/YouTubeThumbnailExamples/Main4.png and /dev/null differ diff --git a/.opencode/skills/Art/YouTubeThumbnailExamples/Main5.png b/.opencode/skills/Art/YouTubeThumbnailExamples/Main5.png deleted file mode 100755 index 94ee8773..00000000 Binary files a/.opencode/skills/Art/YouTubeThumbnailExamples/Main5.png and /dev/null differ diff --git a/.opencode/skills/Art/YouTubeThumbnailExamples/Main6.png b/.opencode/skills/Art/YouTubeThumbnailExamples/Main6.png deleted file mode 100755 index ef82ae1b..00000000 Binary files a/.opencode/skills/Art/YouTubeThumbnailExamples/Main6.png and /dev/null differ diff --git a/.opencode/skills/Art/YouTubeThumbnailExamples/Main7.png b/.opencode/skills/Art/YouTubeThumbnailExamples/Main7.png deleted file mode 100755 index 71a3e252..00000000 Binary files a/.opencode/skills/Art/YouTubeThumbnailExamples/Main7.png and /dev/null differ diff --git a/.opencode/skills/Art/YouTubeThumbnailExamples/SPECIFICATIONS.md b/.opencode/skills/Art/YouTubeThumbnailExamples/SPECIFICATIONS.md deleted file mode 100755 index 9999977c..00000000 --- a/.opencode/skills/Art/YouTubeThumbnailExamples/SPECIFICATIONS.md +++ /dev/null @@ -1,400 +0,0 @@ -# YouTube Thumbnail Design Specifications - -**Analysis Date**: 2025-12-21 -**Canvas Size**: 1280 x 720 pixels (standard YouTube thumbnail) -**Aspect Ratio**: 16:9 - ---- - -## GLOBAL DESIGN SYSTEM - -### Border System -| Property | Value | -|----------|-------| -| Color | `#4A90D9` (Medium Blue) | -| Thickness | 6px | -| Corner Radius | 12px | -| Style | Solid, consistent across all thumbnails | - -### Background System -| Property | Value | -|----------|-------| -| Primary Background | `#1A2744` (Deep Navy Blue) | -| Secondary/Overlay | `#243654` (Lighter Navy) | -| Gradient Direction | None (solid with overlaid elements) | - -### Logo ("TI:" Mark) -| Property | Value | -|----------|-------| -| Symbol | Stylized "TI:" ligature | -| Color | `#1A2744` (Dark Navy, matching background) | -| Width | ~45px | -| Height | ~50px | -| Position | Top-right corner | -| Offset from right edge | 24px | -| Offset from top edge | 20px | - ---- - -## TYPOGRAPHY SYSTEM - -### Font Family Analysis -The thumbnails use a **sans-serif font family** with these characteristics: -- **Primary Font**: Appears to be **Inter**, **Montserrat**, or similar geometric sans-serif -- **Characteristics**: Clean, modern, high x-height, excellent legibility at small sizes -- **Weight Range**: Regular (400) to Bold (700) to Extra Bold (800) - -### Typography Hierarchy - -#### Line 1 - Series/Category Label -| Property | Value | -|----------|-------| -| Color | `#FFFFFF` (White) | -| Font Weight | Bold (700) | -| Font Size | 32-36px | -| Letter Spacing | 0.05em (expanded) | -| Text Transform | UPPERCASE | -| Position Y | 28px from top (inside border) | -| Position X | 28px from left edge | - -#### Line 2 - Primary Title (EMPHASIS LINE) -| Property | Value | -|----------|-------| -| Color | `#6B8DD6` (Periwinkle Blue) or `#F5A623` (Orange accent) | -| Font Weight | Extra Bold (800) | -| Font Size | 56-64px | -| Letter Spacing | 0.02em | -| Text Transform | UPPERCASE | -| Position Y | 68px from top | -| Position X | 28px from left edge | -| Special Effects | Sometimes has highlight box behind text | - -#### Line 3 - Secondary Title -| Property | Value | -|----------|-------| -| Color | `#FFFFFF` (White) or `#6B8DD6` (Periwinkle) | -| Font Weight | Bold (700) | -| Font Size | 48-56px | -| Letter Spacing | 0.02em | -| Text Transform | UPPERCASE or Title Case | -| Position Y | 130px from top | -| Position X | 28px from left edge | - -#### Line 4 - Version/Date Label -| Property | Value | -|----------|-------| -| Color | `#C084FC` (Purple/Violet) | -| Font Weight | Medium (500) | -| Font Size | 24-28px | -| Letter Spacing | 0.03em | -| Text Transform | Title Case with parentheses | -| Position Y | 185px from top | -| Position X | 28px from left edge | - ---- - -## INDIVIDUAL THUMBNAIL SPECIFICATIONS - ---- - -### Main1.png - "Personal AI Infrastructure v2" - -#### Text Content & Styling -| Line | Text | Color | Size | Weight | -|------|------|-------|------|--------| -| 1 | "A DEEPDIVE ON MY" | `#FFFFFF` | 28px | Bold | -| 1b | "CLAUDE CODE" (badge) | `#FFFFFF` on `#D97706` bg | 18px | Bold | -| 2 | "PERSONAL AI" | `#6B8DD6` | 56px | Extra Bold | -| 3 | "INFRASTRUCTURE" | `#6B8DD6` | 56px | Extra Bold | -| 4 | "v2 (December 2025)" | `#C084FC` | 24px | Medium | - -#### Claude Code Badge -| Property | Value | -|----------|-------| -| Background | `#D97706` (Orange/Amber) | -| Text Color | `#FFFFFF` | -| Padding | 4px 8px | -| Border Radius | 4px | -| Position | Inline after "MY" | - -#### Background Art -- **Type**: Technical diagram/flowchart -- **Coverage**: ~60% of frame (left and center) -- **Opacity**: 30-40% overlay -- **Content**: PAI Infrastructure architecture diagram -- **Blend**: Darkened to not compete with text - -#### Headshot -| Property | Value | -|----------|-------| -| Width | ~35% of canvas (448px) | -| Height | ~85% of canvas (612px) | -| Position X | Right edge, ~40px from border | -| Position Y | Vertically centered, slight bottom crop | -| Edge Treatment | Soft fade on left edge into background | - ---- - -### Main2.png - "Building Your Own KAI" - -#### Text Content & Styling -| Line | Text | Color | Size | Weight | -|------|------|-------|------|--------| -| 1 | "BUILDING YOUR OWN" | `#FFFFFF` | 32px | Bold | -| 1b | "\"KAI\"" | `#C084FC` | 32px | Bold | -| 2 | "PERSONAL AI" | `#6B8DD6` | 52px | Extra Bold | -| 3 | "ASSISTANT" | `#FFFFFF` | 52px | Extra Bold | - -#### Background Art -- **Type**: Dual panel - circular diagram (left) + code terminal (right) -- **Coverage**: ~55% of frame -- **Left Panel**: KAI MIC circular architecture diagram -- **Right Panel**: Claude Code terminal window with dark theme -- **Opacity**: 60-70% visible - -#### Headshot -| Property | Value | -|----------|-------| -| Width | ~40% of canvas (512px) | -| Height | ~90% of canvas (648px) | -| Position X | Right-aligned, overlapping background art | -| Position Y | Bottom-aligned with slight crop | -| Edge Treatment | Hard edge, no fade | - ---- - -### Main3.png - "Custom Agent Voices" - -#### Text Content & Styling -| Line | Text | Color | Size | Weight | -|------|------|-------|------|--------| -| 1 | "PERSONAL AI INFRASTRUCTURE" | `#FFFFFF` | 24px | Bold | -| 2 | "USING CUSTOM AGENT VOICES" | `#F5A623` (Orange) | 40px | Extra Bold | - -#### Special Elements -- **ElevenLabs Logo**: White logo, positioned left side, ~80px wide -- **Agent Names**: "KAI", "DESIGNER", "PENTESTER", "ENGINEER", "RESEARCHER" - - Color: `#90EE90` (Light Green) - - Size: 28-36px graduated - - Stacked vertically with speaking head icons - -#### Claude Code Badge (Bottom Right) -| Property | Value | -|----------|-------| -| Position | Bottom-right, 24px from edges | -| Style | Orange badge with white text | - -#### Background -- **Color**: `#1E3A5F` (Slightly brighter navy) -- **Art**: Code snippets with blur effect -- **Coverage**: Full background with overlays - -#### Headshot -| Property | Value | -|----------|-------| -| Width | ~38% of canvas | -| Height | ~80% of canvas | -| Position X | Right third | -| Position Y | Centered | -| Edge Treatment | Soft left fade | - ---- - -### Main4.png - "Ghostty Panes" (Variant A) - -#### Text Content & Styling -| Line | Text | Color | Size | Weight | -|------|------|-------|------|--------| -| 1 | "AN IDEA VIDEO HERE" | `#FFFFFF` | 28px | Bold | -| 1b | "!!!" | `#EF4444` (Red) | 28px | Bold | -| 2 | "GHOSTTY" | `#3B82F6` (Bright Blue) | 56px | Extra Bold | -| 2b | "PANES" | `#1A2744` (Dark Navy) | 56px | Extra Bold | - -#### Background Art -- **Type**: Terminal/code editor screenshot -- **Content**: Ghostty terminal with multiple panes -- **Coverage**: ~50% center-left -- **Opacity**: 40-50% - -#### Headshot -| Property | Value | -|----------|-------| -| Width | ~35% of canvas | -| Height | ~85% of canvas | -| Position X | Center-right | -| Position Y | Bottom-aligned | -| Edge Treatment | Natural edges, no fade | - ---- - -### Main5.png - "Context Engineering Series" - -#### Text Content & Styling -| Line | Text | Color | Size | Weight | -|------|------|-------|------|--------| -| 1 | "CONTEXT ENGINEERING SERIES" | `#FFFFFF` | 24px | Bold | -| 2 | "DYNAMIC CONTEXT LOADING" | `#F5A623` (Orange) | 36px | Extra Bold | -| 3 | "KAI" | `#C084FC` (Purple) | 72px | Extra Bold | - -#### Special Elements -- **Claude Code Badge**: Below KAI text, orange background -- **Anime Character**: Blue-haired figure facing right - - Width: ~30% of canvas - - Position: Left-center - - Style: Cyberpunk/futuristic aesthetic - -#### Background Art -- **Type**: Code/terminal with gradient overlay -- **Coverage**: Full background -- **Primary Color**: Purple-blue gradient tint - -#### Headshot -| Property | Value | -|----------|-------| -| Width | ~38% of canvas | -| Height | ~85% of canvas | -| Position X | Right edge | -| Position Y | Vertically centered | -| Edge Treatment | Hard edge | - ---- - -### Main6.png - "Ghostty Panes" (Variant B) - -*Identical to Main4.png - appears to be same thumbnail or minor variant* - ---- - -### Main7.png - "Conversation with Marcus Hutchins" - -#### Text Content & Styling -| Line | Text | Color | Size | Weight | -|------|------|-------|------|--------| -| 1 | "A CONVERSATION WITH" | `#FFFFFF` | 28px | Bold | -| 2 | "MARCUS HUTCHINS" | `#C084FC` (Purple) | 48px | Extra Bold | -| 3 | "ON" | `#FFFFFF` | 24px | Bold | -| 3b | "AI" | `#3B82F6` (Blue) | 36px | Extra Bold | -| 3c | "HYPE VS REALITY" | `#FFFFFF` | 36px | Extra Bold | - -#### Layout (DUAL HEADSHOT) -This is a conversation/interview format with two people: - -| Element | Left Person | Right Person | -|---------|------------|--------------| -| Width | 45% of canvas | 45% of canvas | -| Position | Bottom-left | Bottom-right | -| Name Label | "[Host Name]" | "[Guest Name]" | -| Label Style | White text, small (~14px) | - -#### Background -- **Color**: Solid `#1A2744` navy -- **No additional art** - cleaner interview format - ---- - -## COLOR PALETTE SUMMARY - -| Name | Hex | Usage | -|------|-----|-------| -| Deep Navy | `#1A2744` | Primary background | -| Border Blue | `#4A90D9` | Frame border | -| Periwinkle | `#6B8DD6` | Primary emphasis text | -| White | `#FFFFFF` | Standard text, high contrast | -| Purple/Violet | `#C084FC` | Accent text, names | -| Orange/Amber | `#F5A623` | Highlight text, badges | -| Badge Orange | `#D97706` | Badge backgrounds | -| Bright Blue | `#3B82F6` | Accent text | -| Red Alert | `#EF4444` | Exclamation marks | -| Light Green | `#90EE90` | Agent names list | - ---- - -## LAYOUT GRID SYSTEM - -### Safe Zones -| Zone | Measurement | -|------|-------------| -| Border Inset | 6px all sides | -| Content Padding | 28px from border | -| Text Block Width | ~55% of canvas (left side) | -| Headshot Zone | ~40% of canvas (right side) | - -### Vertical Rhythm -| Element | Y Position | -|---------|------------| -| Top Border | 0px | -| Line 1 Start | 34px | -| Line 2 Start | 74px | -| Line 3 Start | 134px | -| Line 4 Start | 190px | -| Logo Top | 20px | -| Headshot Top | Variable (centered or top-aligned) | - -### Z-Index Layering -1. **Background Color** (bottom) -2. **Background Art/Screenshots** (30-60% opacity) -3. **Headshot Image** -4. **Text Content** -5. **Badges/Special Elements** -6. **Border Frame** -7. **TI: Logo** (top) - ---- - -## HEADSHOT SPECIFICATIONS - -### Standard Solo Thumbnail -| Property | Value | -|----------|-------| -| Subject Position | Right 40% of frame | -| Vertical Alignment | Centered or bottom-heavy | -| Scale | Head occupies ~20-25% of frame height | -| Background Removal | Clean cutout, no background | -| Edge Treatment | Soft fade left (optional) or hard edge | -| Lighting | Bright, well-lit face | -| Expression | Neutral to friendly | - -### Interview/Dual Format -| Property | Value | -|----------|-------| -| Layout | 50/50 split | -| Subject Scale | Smaller to fit both | -| Name Labels | Bottom of each frame | -| Frame Treatment | Visible frame borders between subjects | - ---- - -## RECREATION CHECKLIST - -To recreate these thumbnails exactly: - -1. [ ] Create 1280x720 canvas -2. [ ] Fill with `#1A2744` background -3. [ ] Add 6px `#4A90D9` border with 12px radius -4. [ ] Position TI: logo at top-right (24px, 20px offset) -5. [ ] Add background art at 30-50% opacity -6. [ ] Place headshot on right side (35-40% width) -7. [ ] Apply soft fade to headshot left edge if needed -8. [ ] Add text lines following typography hierarchy -9. [ ] Apply color accents per specific thumbnail -10. [ ] Add badges/special elements as needed - ---- - -## FONT RECOMMENDATIONS - -Based on letterform analysis, recommended fonts: - -1. **Primary**: Inter (most likely match) -2. **Alternative 1**: Montserrat -3. **Alternative 2**: Poppins -4. **Alternative 3**: Work Sans - -All should be used in: -- Regular (400) for body -- Bold (700) for standard headers -- Extra Bold (800) for primary emphasis - ---- - -*Document generated by Designer Agent for exact thumbnail recreation* diff --git a/.opencode/skills/Art/YouTubeThumbnailExamples/Sponsored1.png b/.opencode/skills/Art/YouTubeThumbnailExamples/Sponsored1.png deleted file mode 100755 index 8634e976..00000000 Binary files a/.opencode/skills/Art/YouTubeThumbnailExamples/Sponsored1.png and /dev/null differ diff --git a/.opencode/skills/Art/YouTubeThumbnailExamples/Sponsored2.png b/.opencode/skills/Art/YouTubeThumbnailExamples/Sponsored2.png deleted file mode 100755 index 4f651f77..00000000 Binary files a/.opencode/skills/Art/YouTubeThumbnailExamples/Sponsored2.png and /dev/null differ diff --git a/.opencode/skills/Art/YouTubeThumbnailExamples/Sponsored3.png b/.opencode/skills/Art/YouTubeThumbnailExamples/Sponsored3.png deleted file mode 100755 index 797b7434..00000000 Binary files a/.opencode/skills/Art/YouTubeThumbnailExamples/Sponsored3.png and /dev/null differ diff --git a/.opencode/skills/ExtractWisdom/SKILL.md b/.opencode/skills/ExtractWisdom/SKILL.md deleted file mode 100644 index 32c86bee..00000000 --- a/.opencode/skills/ExtractWisdom/SKILL.md +++ /dev/null @@ -1,229 +0,0 @@ ---- -name: ExtractWisdom -description: Dynamic wisdom extraction that adapts sections to content. USE WHEN extract wisdom, analyze video, analyze podcast, extract insights, what's interesting, extract from YouTube, what did I miss, key takeaways. Replaces static extract_wisdom with content-adaptive extraction. ---- - -## Customization - -**Before executing, check for user customizations at:** -`~/.opencode/skills/PAI/USER/SKILLCUSTOMIZATIONS/ExtractWisdom/` - -If this directory exists, load and apply any PREFERENCES.md, configurations, or resources found there. These override default behavior. If the directory does not exist, proceed with skill defaults. - -# ExtractWisdom — Dynamic Content Extraction - -**The next generation of extract_wisdom.** Instead of static sections (IDEAS, QUOTES, HABITS...), this skill detects what wisdom domains actually exist in the content and builds custom sections around them. - -A programming interview gets "Programming Philosophy" and "Developer Workflow Tips." A business podcast gets "Contrarian Business Takes" and "Money Philosophy." A security talk gets "Threat Model Insights" and "Defense Strategies." The sections adapt because the content dictates them. - -## When to Use - -- Analyzing YouTube videos, podcasts, interviews, articles -- User says "extract wisdom", "what's interesting in this", "key takeaways" -- Processing any content where you want to capture the best stuff -- When standard extraction patterns miss the gems - -## Depth Levels - -Extract at different depths depending on need. Default is **Full** if no level is specified. - -| Level | Sections | Bullets/Section | Closing Sections | When | -|-------|----------|----------------|-----------------|------| -| **Instant** | 1 | 8 | None | Quick hit. One killer section. | -| **Fast** | 3 | 3 | None | Skim in 30 seconds. | -| **Basic** | 3 | 5 | One-Sentence Takeaway only | Solid overview without the deep cuts. | -| **Full** | 5-12 | 3-15 | All three | The default. Complete extraction. | -| **Comprehensive** | 10-15 | 8-15 | All three + Themes & Connections | Maximum depth. Nothing left behind. | - -**How to invoke:** "extract wisdom (fast)" or "extract wisdom at comprehensive level" or just "extract wisdom" for Full. - -**Comprehensive extras:** -- **Themes & Connections** closing section: identify 3-5 throughlines that connect multiple sections. Not summaries — the deeper patterns the speaker may not even realize they're revealing. -- Prioritize breadth. Every significant wisdom domain gets its own section. -- No merging sections to save space. If the content supports 15 sections, use 15. - -**All levels use the same voice, tone rules, and quality standards.** The only thing that changes is structure. An Instant extraction should hit just as hard per-bullet as a Comprehensive one. - -## Workflow Routing - -| Workflow | Trigger | File | -|----------|---------|------| -| **Extract** | "extract wisdom from", "analyze this", YouTube URL | `Workflows/Extract.md` | - -## The Core Idea - -Old extract_wisdom: Static sections. Same headers every time. IDEAS. QUOTES. HABITS. FACTS. - -This skill: **Read the content first. Figure out what's actually in there. Build sections around what you find.** - -The output should feel like your smartest friend watched/read the thing and is telling you about it over coffee. Not a book report. Not documentation. A real person pointing out the parts that made them go "holy shit" or "wait, that's actually brilliant." - -## Tone Rules (CRITICAL) - -**Canonical voice reference: `skills/PAI/USER/WRITINGSTYLE.md`** — read this file for the full voice definition. The bullets should sound like {PRINCIPAL.NAME} telling a friend about it over coffee. Not compressed info nuggets. Not clever one-liners. Actual spoken observations. - -**THREE LEVELS — we're aiming for Level 3:** - -**Level 1 (BAD — documentation):** -- The speaker discussed the importance of self-modifying software in the context of agentic AI development -- It was noted that financial success has diminishing returns beyond a certain threshold -- The distinction between "vibe coding" and "agentic engineering" was emphasized as meaningful - -**Level 2 (BETTER — but still "smart bullet points"):** -- He built self-modifying software basically by accident — just made the agent aware of its own source code -- Money has diminishing returns. A cheeseburger is a cheeseburger no matter how rich you are. -- "Vibe coding is a slur" — he calls it agentic engineering, and only does vibe coding after 3am - -**Level 3 (YES — this is what we want — conversational, {PRINCIPAL.NAME}'s voice):** -- He wasn't trying to build self-modifying software. He just let the agent see its own source code and it started fixing itself. -- Past a certain point, money stops mattering. A cheeseburger is a cheeseburger no matter how rich you are. -- He calls vibe coding a slur. What he does is agentic engineering. The vibe coding only happens after 3am, and he regrets it in the morning. - -**The difference between Level 2 and 3:** Level 2 is compressed info with em-dashes. Level 3 is how you'd actually SAY it. Varied sentence lengths. Letting a thought breathe. Not trying to be clever — just being clear and direct and a little bit personal. - -**Key signals of Level 3:** -- Reads naturally when spoken aloud -- Varied sentence lengths — some short, some longer -- Understated — lets the content carry the weight -- Uses periods, not em-dashes, to let ideas land -- Feels opinionated ("Past a certain point, money stops mattering") not just informational -- The reader should think "I want to watch this" not "I got the summary" - -## Rules for Extracted Points - -1. **Write like you'd say it.** Read each bullet aloud. If it sounds like a press release or a compressed tweet, rewrite it. If it sounds like you telling a friend what you just watched, you nailed it. -2. **8-16 words per sentence.** This is the target range. Mix short (8-10) with medium (11-14) and longer (15-16). Don't make them all the same length. Exception: verbatim quotes can be any length since they're the speaker's actual words. -3. **Let ideas breathe.** Use periods between thoughts, not em-dashes. Short sentences. Then a slightly longer one to explain. That's the rhythm. -4. **Include the actual detail.** Not "he talked about money" but "a cheeseburger is a cheeseburger no matter how rich you are." -5. **Use the speaker's words when they're good.** If they said something perfectly, use it. -6. **No hedging language.** Not "it was suggested that" or "the speaker noted." Just say the thing. -7. **Capture what made you stop.** Every bullet should be something worth telling someone about. -8. **Vary your openers.** Don't start three bullets the same way. And don't front-load with "He" — if more than 3 bullets in a section start with the speaker's name, you're writing a biography. -9. **Capture the human moments.** Burnout stories, moments of doubt, something that moved them. That's wisdom too. Don't skip it because it's not "technical." -10. **Insight over inventory.** "He uses Go for CLIs" is inventory. "He picked a language he doesn't even like because the ecosystem fits agents perfectly. That's the new normal." is insight. Go deeper. -11. **Specificity is everything.** "He was impressed by the agent" = bad. "The agent found ffmpeg, curled the Whisper API, and transcribed a voice message nobody taught it to handle" = good. -12. **Tension and surprise.** The best bullets have a contradiction or reversal. "Every VC is offering hundreds of millions. He genuinely doesn't care." The gap between the offer and the indifference IS the wisdom. -13. **Understated, not clever.** Let the content carry the weight. You don't need to manufacture drama or craft the perfect one-liner. Just state what's interesting plainly and move on. - -## How Dynamic Sections Work - -### Phase 1: Content Scan - -Read/listen to the full content. As you go, notice what DOMAINS of wisdom are present. These aren't the topics discussed — they're the TYPES of insight being delivered. - -Examples of wisdom domains (these are illustrative, not exhaustive): -- Programming Philosophy (how to think about code, not specific syntax) -- Developer Workflow (practical tips for how to work) -- Business/Money Philosophy (unconventional takes on money, success, building companies) -- Human Psychology (insights about how people think, behave, learn) -- Technology Predictions (where things are headed) -- Life Philosophy (how to live, what matters) -- Contrarian Takes (things that go against conventional wisdom) -- First-Time Revelations (things you're hearing for the first time — genuinely new) -- Technical Architecture (how something is built, design decisions) -- Leadership & Team Dynamics (managing people, working with others) -- Creative Process (how to make things, craft, art) - -### Phase 2: Section Selection - -Pick sections based on depth level (default Full = 5-12). Requirements: -- Section count follows depth level table. Full = 5-12, Comprehensive = 10-15, Basic/Fast = 3, Instant = 1. -- Each section must have at least 3 STRONG bullets to justify existing (except Fast, where 3 tight bullets IS the section). If you can only scrape together 2 weak ones, merge into a related section. -- Always include "Quotes That Hit Different" if the content has good ones -- Always include "First-Time Revelations" if there are genuinely new ideas — things you literally didn't know before -- Section names should be conversational, not academic. "Money Philosophy" not "Financial Considerations" -- Sections should be SPECIFIC to this content. Generic sections = failure. -- **Kill inventory sections.** If a section is just a list of facts ("uses X for Y, uses A for B"), it's not wisdom. Either go deeper on WHY those choices matter or merge the facts into a section about the underlying philosophy. -- **Don't split what belongs together.** If "burnout recovery" and "money philosophy" are actually both about "what success really means," make one richer section instead of two thin ones. -- **Name sections like a magazine editor.** "The Death of 80% of Apps" is great. "Technology Predictions" is not. The section name itself should make you curious. It's a headline, not a category. -- **Surprise density per section.** If a section has 6+ bullets but only 2 are genuinely surprising, kill the padding and keep the winners. Quality > quantity per section. -- **Don't drop your best material between drafts.** If a spicy take, stunning moment, or first-time revelation was identified in an earlier pass, it MUST survive into the final version. Losing great material is worse than adding mediocre material. - -### Phase 3: Extraction - -For each section, extract 3-15 bullets depending on density. Apply all tone rules. Every bullet earns its place. - -**The Spiciest Take Rule:** If the speaker has a genuinely contrarian or hot take on a topic (e.g., "screw MCPs", "X is dead", "Y is overhyped"), that take MUST appear somewhere. Spicy takes are the most memorable, shareable, and valuable parts of any content. Don't water them down. Don't leave them out. - -**The "Would I Tweet This?" Test:** After extraction, scan your bullets. If fewer than half would make a good standalone tweet or social media post, your bullets are too generic. The best extractions are effectively a thread of tweetable insights. - -### Phase 4: Closing Sections (Depth-Level Dependent) - -Which closing sections to include depends on depth level: - -| Level | Closing Sections | -|-------|-----------------| -| **Instant** | None | -| **Fast** | None | -| **Basic** | One-Sentence Takeaway only | -| **Full** | One-Sentence Takeaway + If You Only Have 2 Minutes + References & Rabbit Holes | -| **Comprehensive** | All three above + Themes & Connections | - -**One-Sentence Takeaway** -The single most important thing from the entire piece in 15-20 words. - -**If You Only Have 2 Minutes** -The 5-7 absolute must-know points. The cream of the cream. - -**References & Rabbit Holes** -People, projects, books, tools, and ideas mentioned that are worth following up on. Brief context for each. - -**Themes & Connections** (Comprehensive only) -3-5 throughlines that connect multiple sections. The deeper patterns the speaker may not realize they're revealing. Not summaries. Synthesis. - -## Output Format - -```markdown -# EXTRACT WISDOM: {Content Title} -> {One-line description of what this is and who's talking} - ---- - -## {Dynamic Section 1 Name} - -- {bullet} -- {bullet} -- {bullet} - -## {Dynamic Section 2 Name} - -- {bullet} -- {bullet} - -[... more dynamic sections ...] - ---- - -## One-Sentence Takeaway - -{15-20 word sentence} - -## If You Only Have 2 Minutes - -- {essential point 1} -- {essential point 2} -- {essential point 3} -- {essential point 4} -- {essential point 5} - -## References & Rabbit Holes - -- **{Name/Project}** — {one-line context of why it's worth looking into} -- **{Name/Project}** — {context} -``` - -## Quality Check - -Before delivering output, verify: -- [ ] Sections are specific to THIS content, not generic -- [ ] No bullet sounds like it was written by a committee -- [ ] Every bullet has a specific detail, quote, or insight — not vague summaries -- [ ] Section names are conversational and headline-worthy (not category labels) -- [ ] Section count matches depth level (Instant=1, Fast/Basic=3, Full=5-12, Comprehensive=10-15) -- [ ] Closing sections match depth level (see Phase 4 table) -- [ ] No bullet starts with "The speaker" or "It was noted that" -- [ ] No more than 3 bullets per section start with "He" or the speaker's name -- [ ] No bullet exceeds 25 words -- [ ] No inventory sections (just listing facts without insight) -- [ ] "If You Only Have 2 Minutes" bullets are each under 20 words -- [ ] Reading the output makes you want to consume the original content diff --git a/.opencode/skills/ExtractWisdom/Workflows/Extract.md b/.opencode/skills/ExtractWisdom/Workflows/Extract.md deleted file mode 100644 index 50ca50ea..00000000 --- a/.opencode/skills/ExtractWisdom/Workflows/Extract.md +++ /dev/null @@ -1,60 +0,0 @@ -# Extract Workflow - -Extract dynamic, content-adaptive wisdom from any content source. - -## Input Sources - -| Source | Method | -|--------|--------| -| YouTube URL | `fabric -y "URL"` to get transcript | -| Article URL | WebFetch to get content | -| File path | Read the file directly | -| Pasted text | Use directly | - -## Execution Steps - -### Step 1: Get the Content - -Obtain the full text/transcript. For YouTube, use `fabric -y "URL"` to extract transcript. Save to a working file if large. - -### Step 2: Deep Read - -Read the entire content. Don't extract yet. Notice: -- What domains of wisdom are present? -- What made you stop and think? -- What's genuinely novel vs. commonly known? -- What would {PRINCIPAL.NAME} highlight if he were reading this? -- What quotes land perfectly? - -### Step 3: Select Dynamic Sections - -Based on your deep read, pick 5-12 section names. Rules: -- Section names must be conversational, not academic -- Each must have at least 3 quality bullets -- Always include "Quotes That Hit Different" if source has quotable moments -- Always include "First-Time Revelations" if genuinely new ideas exist -- Be SPECIFIC — "Agentic Engineering Philosophy" not "Technology Insights" - -### Step 4: Extract Per Section - -For each section, extract 3-15 bullets. Apply tone rules from SKILL.md: -- 8-20 words, flexible for clarity -- Specific details, not vague summaries -- Speaker's words when they're good -- No hedging language -- Every bullet worth telling someone about - -### Step 5: Add Closing Sections - -Always append: -1. **One-Sentence Takeaway** (15-20 words) -2. **If You Only Have 2 Minutes** (5-7 essential points) -3. **References & Rabbit Holes** (people, projects, books, tools mentioned) - -### Step 6: Quality Check - -Run the quality checklist from SKILL.md before delivering. - -### Step 7: Output - -Present the complete extraction in the format specified in SKILL.md. diff --git a/.opencode/skills/Media/Remotion/Tools/Ref-timing.md b/.opencode/skills/Media/Remotion/Tools/Ref-timing.md index 42084a22..7c2c6e53 100644 --- a/.opencode/skills/Media/Remotion/Tools/Ref-timing.md +++ b/.opencode/skills/Media/Remotion/Tools/Ref-timing.md @@ -69,7 +69,17 @@ const heavy = {damping: 15, stiffness: 80, mass: 2}; // Heavy, slow, small bounc ### Delay The animation starts immediately by default. -To delay the animation, subtract the delay in frames from the `frame` parameter. +Use the `delay` parameter to delay the animation by a number of frames. + +```tsx +const entrance = spring({ + frame, + fps, + delay: 20, +}); +``` + +Alternatively, subtract the delay from the `frame` parameter directly: ```tsx const entrance = spring({ diff --git a/.opencode/skills/Media/Remotion/Tools/tsconfig.json b/.opencode/skills/Media/Remotion/Tools/tsconfig.json new file mode 100644 index 00000000..60c23df3 --- /dev/null +++ b/.opencode/skills/Media/Remotion/Tools/tsconfig.json @@ -0,0 +1,19 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "ESNext", + "moduleResolution": "bundler", + "strict": true, + "skipLibCheck": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "declaration": true, + "declarationMap": true, + "sourceMap": true, + "outDir": "./dist", + "rootDir": "./", + "types": ["bun-types"] + }, + "include": ["*.ts"], + "exclude": ["node_modules", "dist"] +} diff --git a/.opencode/skills/Media/Remotion/Workflows/ContentToAnimation.md b/.opencode/skills/Media/Remotion/Workflows/ContentToAnimation.md new file mode 100644 index 00000000..650fea78 --- /dev/null +++ b/.opencode/skills/Media/Remotion/Workflows/ContentToAnimation.md @@ -0,0 +1,556 @@ +# ContentToAnimation Workflow + +Transform any content into professional PAI-themed animations. + +## Triggers + +- "animate this content" +- "create animations for" +- "video overlay for" +- "animate my blog post" +- "animate this YouTube video" + +## Input Types + +This workflow handles ANY input via the Parser skill: + +| Input Type | Detection | Extraction Method | +|------------|-----------|-------------------| +| YouTube URL | `youtube.com`, `youtu.be` | Parser: ExtractYoutube → transcript | +| Article URL | HTTP(S) URL | Parser: ExtractArticle → text | +| Blog file | `.md` file path | Direct read → markdown content | +| PDF file | `.pdf` file path | Parser: ExtractPdf → text | +| Tweet/Thread | `twitter.com`, `x.com` | Parser: ExtractTwitter → thread | +| Raw text | No URL/path detected | Use directly | + +## Execution Steps + +### 1. Extract Content + +```text +┌─────────────────────────────────────────────────────────────────────────────┐ +│ STEP 1: CONTENT EXTRACTION │ +├─────────────────────────────────────────────────────────────────────────────┤ +│ 1. Detect input type (URL, file path, or raw text) │ +│ 2. Route to appropriate Parser workflow OR read directly │ +│ 3. Extract: title, sections, key points, quotes, data │ +└─────────────────────────────────────────────────────────────────────────────┘ +``` + +**For YouTube:** +```bash +# Get transcript via Parser skill +# Load: ~/.opencode/skills/Parser/Workflows/ExtractYoutube.md +``` + +**For articles/blogs:** +```bash +# Read file directly for .md +# Or use Parser: ExtractArticle for URLs +``` + +### 2. Analyze Structure + +```text +┌─────────────────────────────────────────────────────────────────────────────┐ +│ STEP 2: STRUCTURE ANALYSIS │ +├─────────────────────────────────────────────────────────────────────────────┤ +│ Extract these elements for animation: │ +│ │ +│ • Title & subtitle │ +│ • Section headers (H2, H3) │ +│ • Key points (3-7 main takeaways) │ +│ • Quotes or callouts │ +│ • Data/statistics (numbers, percentages) │ +│ • Lists or steps │ +│ • Conclusion/summary │ +└─────────────────────────────────────────────────────────────────────────────┘ +``` + +**Output structure:** +```typescript +interface ContentStructure { + title: string + subtitle?: string + sections: { + heading: string + keyPoints: string[] + quotes?: string[] + data?: { label: string; value: string }[] + }[] + conclusion?: string + duration: number // Calculated based on content length +} +``` + +### 3. Generate Animation Plan + +```text +┌─────────────────────────────────────────────────────────────────────────────┐ +│ STEP 3: ANIMATION PLANNING │ +├─────────────────────────────────────────────────────────────────────────────┤ +│ Map content to animation scenes: │ +│ │ +│ Scene 1: Title Card (3 seconds) │ +│ → Title fade in with spring scale │ +│ → Subtitle fade in with delay │ +│ │ +│ Scene 2-N: Content Sections (4-6 seconds each) │ +│ → Section header slide in │ +│ → Key points stagger in │ +│ → Data visualizations animate │ +│ │ +│ Scene N+1: Conclusion (3 seconds) │ +│ → Summary points │ +│ → Call to action │ +└─────────────────────────────────────────────────────────────────────────────┘ +``` + +**Timing formula:** +- Title: 90 frames (3 seconds at 30fps) +- Per section: 120-180 frames (4-6 seconds) +- Conclusion: 90 frames (3 seconds) +- Total = 90 + (sections × 150) + 90 + +### 3.5 Verify Logical Coherence ⚠️ CRITICAL GATE + +```text +┌─────────────────────────────────────────────────────────────────────────────┐ +│ STEP 3.5: LOGICAL COHERENCE VERIFICATION │ +├─────────────────────────────────────────────────────────────────────────────┤ +│ BEFORE generating React components, verify the animation plan makes sense. │ +│ │ +│ This checks LOGICAL coherence, not just functional capability. │ +│ │ +│ If these checks FAIL, the video would render but be confusing/wrong. │ +│ Block early to save compute and prevent bad outputs. │ +└─────────────────────────────────────────────────────────────────────────────┘ +``` + +**1. NARRATIVE COHERENCE CHECKS** + +Verify the story flows logically: + +| Check | What It Tests | Failure Example | +|-------|---------------|-----------------| +| **Section connectivity** | Adjacent sections share ≥15% concepts | Section 2 "Authentication" → Section 3 "Database Schema" with 0% overlap | +| **Context completeness** | No forward references to undefined concepts | Scene 2 uses "ISC" acronym before defining it in Scene 4 | +| **Transition bridges** | Last point of section N relates to first point of section N+1 | Jarring topic jump with no conceptual bridge | +| **Story arc validity** | Sections follow recognizable narrative pattern | Random sequence with no setup→development→resolution | +| **Title-content alignment** | Content delivers what title promises | Title: "5 Ways to..." but only 3 covered | +| **Conclusion validity** | Conclusion only references introduced concepts | Conclusion mentions "OWASP" never discussed in content | + +**Test method:** +```typescript +// Pseudo-code for verification +const narrativeChecks = { + sectionConnectivity: verifySectionOverlap(sections) >= 0.15, + contextCompleteness: noForwardReferences(sections), + transitionBridges: hasConceptualBridges(sections), + storyArc: matchesValidPattern(sections), + titleAlignment: contentMatchesTitle(title, sections), + conclusionValidity: conclusionReferencesContent(conclusion, sections) +} + +if (Object.values(narrativeChecks).some(check => !check)) { + throw new Error('Narrative coherence check failed - see details above') +} +``` + +**2. TIMING VERIFICATION CHECKS** + +Verify timing adapts to content density: + +| Check | What It Tests | Failure Example | +|-------|---------------|-----------------| +| **Reading speed validation** | Text duration allows comfortable reading (≤4 words/second) | 47-word paragraph shown for 2 seconds (23.5 wps) | +| **Content-density adaptation** | Duration scales with word count, key points, data items | Simple 2-word title gets same 3s as complex 15-word title | +| **Data comprehension time** | Statistics get 1-2 seconds per item for mental processing | 5 data points crammed into 3 seconds | +| **Content-type multipliers** | Quotes get 1.5x, data gets 1.3x base duration | Reflective quote rushed at same pace as simple list | +| **Duration bounds** | Timing stays within 2-10 seconds per point | Critical concept: 1s, Minor detail: 12s | + +**Test method:** +```typescript +// Calculate adaptive timing based on content density +function calculateSectionDuration(section: Section): number { + const WORDS_PER_SECOND = 3.5 // Research: 200-250 WPM + const SECONDS_PER_POINT = 2 + const SECONDS_PER_DATA = 1.5 + + const wordCount = countWords(section.keyPoints) + const baseDuration = ( + wordCount / WORDS_PER_SECOND + + section.keyPoints.length * SECONDS_PER_POINT + + (section.data?.length || 0) * SECONDS_PER_DATA + ) + + // Apply content-type multiplier + const typeMultiplier = section.quotes ? 1.5 : 1.0 + const duration = baseDuration * typeMultiplier + + // Enforce bounds + const minDuration = section.keyPoints.length * 2 + const maxDuration = section.keyPoints.length * 10 + + return Math.max(minDuration, Math.min(maxDuration, duration)) +} +``` + +**3. SCENE TYPE SELECTION VALIDATION** + +Verify correct scene template chosen for content: + +| Check | What It Tests | Failure Example | +|-------|---------------|-----------------| +| **Data scene validation** | DataScene only used when `data` array exists with items | DataScene receives empty data array → blank screen | +| **Numeric content detection** | Statistics in text trigger DataScene, not KeyPointsScene | "10M users, 95% accuracy" shown as bullet points | +| **KeyPoints scene validation** | KeyPointsScene used for 2+ text items without numeric data | Single quote forced into KeyPointsScene template | +| **Quote handling** | Quotes get appropriate visual treatment | Quote buried in bullet list with no emphasis | + +**Selection logic:** +```typescript +function selectSceneType(section: Section): SceneType { + // Priority 1: Has structured data? → DataScene + if (section.data && section.data.length > 0) { + return 'DataScene' + } + + // Priority 2: Detect numeric patterns in text → extract to DataScene + if (hasNumericPatterns(section.keyPoints)) { + section.data = extractDataFromText(section.keyPoints) + return 'DataScene' + } + + // Priority 3: Has quote and few/no key points? → QuoteScene + if (section.quotes && section.keyPoints.length < 2) { + return 'QuoteScene' + } + + // Default: Key points list + if (section.keyPoints.length >= 2) { + return 'KeyPointsScene' + } + + // Fallback: Simple text + return 'TitleScene' +} + +// Validation guards +function validateSceneSelection(scene: SceneType, section: Section): void { + if (scene === 'DataScene') { + assert(section.data && section.data.length > 0, + 'DataScene requires data array with at least 1 item') + } + + if (scene === 'KeyPointsScene') { + assert(section.keyPoints.length >= 2, + 'KeyPointsScene requires at least 2 key points') + assert(!hasNumericPatterns(section.keyPoints), + 'Numeric data should use DataScene, not KeyPointsScene') + } +} +``` + +**4. DECISION LOGIC: FAIL FAST OR WARN** + +```typescript +interface VerificationResult { + passed: boolean + errors: string[] // Block rendering + warnings: string[] // Show but allow proceeding +} + +function verifyAnimationPlan( + structure: ContentStructure, + plan: AnimationPlan +): VerificationResult { + const errors: string[] = [] + const warnings: string[] = [] + + // Run all verification checks + const narrativeResult = verifyNarrativeCoherence(structure) + const timingResult = verifyTimingLogic(plan) + const sceneResult = verifySceneSelection(plan) + + errors.push(...narrativeResult.errors, ...timingResult.errors, ...sceneResult.errors) + warnings.push(...narrativeResult.warnings, ...timingResult.warnings, ...sceneResult.warnings) + + return { passed: errors.length === 0, errors, warnings } +} + +// In workflow execution: +const verification = verifyAnimationPlan(structure, plan) + +if (!verification.passed) { + console.error('❌ LOGICAL COHERENCE CHECK FAILED:') + verification.errors.forEach(err => console.error(` - ${err}`)) + throw new Error('Cannot proceed - fix logical issues before rendering') +} + +if (verification.warnings.length > 0) { + console.warn('⚠️ COHERENCE WARNINGS (review recommended):') + verification.warnings.forEach(warn => console.warn(` - ${warn}`)) +} + +console.log('✅ Logical coherence verified - proceeding to component generation') +``` + +**Example output:** + +**PASS:** +``` +✅ Logical coherence verified - proceeding to component generation + +Checks passed: + ✓ Narrative flow: All sections connect logically + ✓ Timing: Adapted to content density (avg 3.8 words/sec) + ✓ Scene selection: All templates match content types +``` + +**FAIL:** +``` +❌ LOGICAL COHERENCE CHECK FAILED: + + - Narrative: Section 2 → 3 weak connection (5% overlap, need ≥15%) + - Timing: Scene 3 text too fast to read (6.2 words/sec, max 4.0) + - Scene selection: DataScene assigned but section.data is empty + - Conclusion: References "ISC methodology" never introduced in content + +Cannot proceed - fix logical issues before rendering +``` + +**WARN:** +``` +⚠️ COHERENCE WARNINGS (review recommended): + + - Narrative: Section 3 → 4 transition lacks bridge concept + - Timing: Scene 2 duration near minimum bound (2.1s per point) + +✅ Logical coherence verified - proceeding to component generation +``` + +**Why this matters:** + +| Without Verification | With Verification | +|---------------------|-------------------| +| Video renders successfully | Video renders successfully | +| 47-word text shown for 2s → unreadable | Timing adapted to 13s → readable | +| Conclusion references undefined "ISC" → confusing | Blocked: "ISC mentioned but never defined" | +| Statistics shown as bullet points → wrong format | Converted to DataScene → proper visualization | +| Section jump from auth to database → jarring | Blocked: "5% overlap, need transitional content" | + +**Bottom line:** Verification prevents technically-correct but logically-broken videos from being generated. + +### 4. Generate Remotion Components + +```text +┌─────────────────────────────────────────────────────────────────────────────┐ +│ STEP 4: COMPONENT GENERATION │ +├─────────────────────────────────────────────────────────────────────────────┤ +│ Create project at: /tmp/remotion-{timestamp}/ │ +│ │ +│ Files to generate: │ +│ • package.json │ +│ • src/Root.tsx (composition registration) │ +│ • src/Video.tsx (main composition) │ +│ • src/scenes/TitleScene.tsx │ +│ • src/scenes/SectionScene.tsx │ +│ • src/scenes/ConclusionScene.tsx │ +│ • src/theme.ts (copy from skill) │ +└─────────────────────────────────────────────────────────────────────────────┘ +``` + +**MANDATORY: Apply PAI Theme** + +> **Note:** The path below uses `~` as a conceptual shorthand — it is not a valid +> TypeScript/Node module path. Use a relative path from your component file or +> configure a `paths` alias in `tsconfig.json` (e.g. `"@pai-theme": ["~/.opencode/skills/Media/Remotion/theme"]`). + +```typescript +// Conceptual: replace with a relative path or tsconfig alias +import { PAI_THEME } from '~/.opencode/skills/Media/Remotion/theme' + +// All components MUST use: +// - PAI_THEME.colors for all colors +// - PAI_THEME.typography for text styles +// - PAI_THEME.animation for spring configs +// - PAI_THEME.spacing for layout +``` + +### 5. Render Output + +```text +┌─────────────────────────────────────────────────────────────────────────────┐ +│ STEP 5: RENDER │ +├─────────────────────────────────────────────────────────────────────────────┤ +│ 1. Install dependencies: bun install │ +│ 2. Render: bunx remotion render {composition-id} ~/Downloads/{name}.mp4 │ +│ 3. Open for preview: open ~/Downloads/{name}.mp4 │ +└─────────────────────────────────────────────────────────────────────────────┘ +``` + +## Scene Templates + +### TitleScene + +```typescript +const TitleScene: React.FC<{ title: string; subtitle?: string }> = ({ title, subtitle }) => { + const frame = useCurrentFrame() + const { fps } = useVideoConfig() + + const titleOpacity = interpolate(frame, [0, 30], [0, 1], { extrapolateRight: 'clamp' }) + const titleScale = spring({ frame, fps, config: PAI_THEME.animation.springDefault }) + const subtitleOpacity = interpolate(frame, [20, 50], [0, 1], { extrapolateRight: 'clamp' }) + + return ( + +

+ {title} +

+ {subtitle && ( +

+ {subtitle} +

+ )} +
+ ) +} +``` + +### KeyPointsScene + +```typescript +const KeyPointsScene: React.FC<{ heading: string; points: string[] }> = ({ heading, points }) => { + const frame = useCurrentFrame() + + return ( + +

+ {heading} +

+ + {points.map((point, i) => { + const delay = 20 + (i * PAI_THEME.animation.staggerDelay) + const opacity = interpolate(frame, [delay, delay + 20], [0, 1], { extrapolateRight: 'clamp' }) + const x = interpolate(frame, [delay, delay + 20], [-30, 0], { extrapolateRight: 'clamp' }) + + return ( +
+ + {point} +
+ ) + })} +
+ ) +} +``` + +### DataScene + +```typescript +const DataScene: React.FC<{ data: { label: string; value: string }[] }> = ({ data }) => { + const frame = useCurrentFrame() + const { fps } = useVideoConfig() + + return ( + + {data.map((item, i) => { + const delay = i * 15 + const scale = spring({ frame: Math.max(0, frame - delay), fps, config: PAI_THEME.animation.springBouncy }) + + return ( +
+
+ {item.value} +
+
+ {item.label} +
+
+ ) + })} +
+ ) +} +``` + +## Output Formats + +| Format | Dimensions | Use Case | +|--------|------------|----------| +| YouTube landscape | 1920x1080 | Default, blog content | +| YouTube Shorts | 1080x1920 | Vertical clips | +| Square | 1080x1080 | Instagram, social | + +## Example Usage + +**Blog post:** +``` +User: animate my blog post at ${PROJECTS_DIR}/your-site/cms/blog/skills-vs-agents.md +``` + +**YouTube video:** +``` +User: create animations for https://youtube.com/watch?v=xyz123 +``` + +**Raw text:** +``` +User: animate this content: "The three pillars of AI safety are..." +``` + +## Integration with Art Skill + +This workflow inherits visual theming from Art preferences: +- Load: `~/.opencode/skills/PAI/USER/SKILLCUSTOMIZATIONS/Art/PREFERENCES.md` +- Apply: Charcoal aesthetic, purple accents, organic animations +- Reference: `~/.opencode/skills/Remotion/theme.ts` diff --git a/.opencode/skills/Media/SKILL.md b/.opencode/skills/Media/SKILL.md new file mode 100644 index 00000000..1d103998 --- /dev/null +++ b/.opencode/skills/Media/SKILL.md @@ -0,0 +1,34 @@ +--- +name: Media +description: Media creation and processing skills. USE WHEN create visuals, generate images, video production, thumbnails, art, illustrations. +--- + +# Media - Media Creation and Processing + +**Category for skills that create, process, and manipulate media content.** + +## Skills in This Category + +| Skill | Purpose | Trigger | +|-------|---------|---------| +| **Art** | Visual content creation (images, illustrations, diagrams) | "create art", "generate image", "make illustration", "visual content" | +| **Remotion** | Video production and motion graphics | "create video", "motion graphics", "video production", "remotion" | + +## When to Use + +- Creating visual content (images, illustrations, diagrams) +- Video production and motion graphics +- Thumbnail generation +- Media asset creation +- Visual storytelling + +## Category Philosophy + +Media skills bridge the gap between technical execution and creative vision. They handle the technical complexity of media creation while allowing the user to focus on creative direction. + +## Customization + +**Before executing, check for user customizations at:** +`~/.opencode/skills/PAI/USER/SKILLCUSTOMIZATIONS/Media/` + +If this directory exists, load and apply any PREFERENCES.md, configurations, or resources found there. diff --git a/.opencode/skills/OSINT/CompanyTools.md b/.opencode/skills/OSINT/CompanyTools.md deleted file mode 100755 index 621e4dbc..00000000 --- a/.opencode/skills/OSINT/CompanyTools.md +++ /dev/null @@ -1,180 +0,0 @@ -# Company OSINT Tools Reference - -## Business Intelligence Databases - -### Startup & Tech Intelligence - -**Crunchbase** (crunchbase.com) -- **Purpose:** Startup and tech company database -- **Data Available:** Funding, investors, acquisitions, leadership -- **Cost:** Free (limited), Pro ($29/month), Enterprise (custom) -- **Coverage:** 3M+ companies globally - -**PitchBook** (pitchbook.com) -- **Purpose:** PE/VC deal database -- **Data Available:** Valuations, M&A, fund performance -- **Cost:** ~$10,000-30,000/year institutional -- **Coverage:** 3M+ companies, 10K+ investors - -**AngelList** (angel.co) -- **Purpose:** Startup platform -- **Data Available:** Startups, funding, investors -- **Cost:** Free - -### General Business Intelligence - -**ZoomInfo** (zoominfo.com) -- **Purpose:** B2B intelligence -- **Data Available:** Companies, contacts, org charts, technographics -- **Cost:** $15,000+/year enterprise -- **Coverage:** 100M+ contacts, 14M+ companies - -**Bloomberg Terminal** (bloomberg.com/professional) -- **Purpose:** Financial data platform -- **Cost:** ~$20,000-25,000/year -- **Coverage:** Complete global financial markets - -### Free Business Registries - -**OpenCorporates** (opencorporates.com) -- **Purpose:** Company data aggregator -- **Data Available:** Registration, officers, status -- **Cost:** Free (basic), API (paid) -- **Coverage:** 200M+ companies, 130+ jurisdictions - -**SEC EDGAR** (sec.gov/edgar) -- **Purpose:** US public company filings -- **Data Available:** 10-K, 10-Q, 8-K, proxy statements -- **Cost:** Free -- **API:** Available (free) - -## Domain & DNS Intelligence - -**DomainTools** (domaintools.com) -- **Purpose:** Domain research -- **Data Available:** WHOIS history, DNS, screenshots -- **Cost:** $99/month+ -- **Features:** Reverse WHOIS, monitoring - -**SecurityTrails** (securitytrails.com) -- **Purpose:** DNS intelligence -- **Data Available:** Historical DNS, subdomains, certificates -- **Cost:** Free (limited), Explorer ($49/month) -- **Coverage:** 4B+ DNS records - -**crt.sh** (crt.sh) -- **Purpose:** Certificate transparency search -- **Use Case:** Subdomain discovery -- **Cost:** Free -- **Search:** `%.company.com` - -**DNSDumpster** (dnsdumpster.com) -- **Purpose:** DNS reconnaissance -- **Data Available:** Subdomains, MX, network map -- **Cost:** Free - -## Network & Infrastructure - -**Shodan** (shodan.io) -- **Purpose:** Internet device search -- **Data Available:** Ports, services, vulnerabilities -- **Cost:** Free (limited), Membership ($59/month) -- **Search Filters:** org:, net:, ssl:, port: - -**Censys** (censys.io) -- **Purpose:** Internet scanning -- **Data Available:** Hosts, certificates, services -- **Cost:** Free (limited), Teams ($99/month) - -**IPinfo** (ipinfo.io) -- **Purpose:** IP geolocation -- **Data Available:** Location, ASN, company -- **Cost:** Free (50k/month), Basic ($49/month) - -## Technology Profiling - -**BuiltWith** (builtwith.com) -- **Purpose:** Technology detection -- **Data Available:** Tech stack, hosting, analytics -- **Cost:** Free (limited), Pro ($295/month) -- **Coverage:** 670M+ websites - -**Wappalyzer** (wappalyzer.com) -- **Purpose:** Technology detection -- **Data Available:** CMS, frameworks, analytics -- **Cost:** Free (extension), Credits ($49/month) -- **Technologies:** 3,000+ tracked - -## Employee & People - -**LinkedIn** (linkedin.com) -- **Purpose:** Employee enumeration -- **Data Available:** Team, org structure, hiring -- **Cost:** Free (limited), Sales Navigator ($80/month) - -**Glassdoor** (glassdoor.com) -- **Purpose:** Employee reviews -- **Data Available:** Reviews, salaries, culture -- **Cost:** Free - -**Hunter.io** (hunter.io) -- **Purpose:** Email finder -- **Cost:** Free (50/month), Starter ($49/month) - -## News & Press - -**Google News** (news.google.com) -- **Purpose:** News aggregation -- **Cost:** Free - -**PR Newswire** (prnewswire.com) -- **Purpose:** Press release archive -- **Cost:** Free (search) - -## Competitive Intelligence - -**SimilarWeb** (similarweb.com) -- **Purpose:** Website traffic analytics -- **Data Available:** Traffic, sources, competitors -- **Cost:** Free (limited), Pro ($167/month) - -**SEMrush** (semrush.com) -- **Purpose:** SEO intelligence -- **Data Available:** Keywords, backlinks, traffic -- **Cost:** Pro ($120/month) - -## Historical & Archive - -**Wayback Machine** (archive.org) -- **Purpose:** Historical snapshots -- **Coverage:** 670B+ web pages -- **Cost:** Free - ---- - -## Tool Selection Matrix - -### Basic Company Research: -- Start: Website, LinkedIn, Crunchbase, OpenCorporates -- Free: SEC EDGAR (if public), Google search -- Tech: BuiltWith, Wappalyzer - -### Technical Infrastructure: -- Domain: DomainTools, DNSDumpster, SecurityTrails -- Network: Shodan, Censys, IPinfo -- Tech stack: BuiltWith, Wappalyzer - -### People Intelligence: -- Employees: LinkedIn, Hunter.io -- Culture: Glassdoor, Indeed -- Contacts: Hunter.io, company directories - -### Comprehensive Research: -- Business: ZoomInfo, PitchBook (if budget) -- Technical: Shodan, SecurityTrails -- Historical: Wayback Machine -- Competitive: SimilarWeb, SEMrush - ---- - -**Remember:** Combine multiple tools. No single tool provides complete information. Verify from independent sources. diff --git a/.opencode/skills/OSINT/EntityTools.md b/.opencode/skills/OSINT/EntityTools.md deleted file mode 100755 index 8f240f01..00000000 --- a/.opencode/skills/OSINT/EntityTools.md +++ /dev/null @@ -1,197 +0,0 @@ -# Entity OSINT Tools Reference - -## Domain & DNS Tools - -### WHOIS Services - -**DomainTools** (domaintools.com) -- **Purpose:** Advanced domain intelligence -- **Data Available:** WHOIS history, DNS, IP history, risk scoring -- **Cost:** $99/month+ -- **Features:** Reverse WHOIS, monitoring, API - -**ViewDNS** (viewdns.info) -- **Purpose:** DNS toolkit -- **Data Available:** DNS records, IP history, reverse lookup -- **Cost:** Free (limited), API ($10-50/month) - -### DNS Reconnaissance - -**DNSDumpster** (dnsdumpster.com) -- **Purpose:** DNS recon -- **Cost:** Free, no auth required -- **Features:** Visual network map, HTTP/HTTPS detection - -**SecurityTrails** (securitytrails.com) -- **Purpose:** DNS intelligence -- **Cost:** Free (50/month), Explorer ($49/month) -- **Coverage:** 4.5B DNS records - -**Amass** (github.com/OWASP/Amass) -- **Purpose:** Advanced subdomain enumeration -- **Cost:** Free, open-source (OWASP) -- **Features:** Active/passive recon, 55+ sources - -### Certificate Intelligence - -**crt.sh** (crt.sh) -- **Purpose:** Certificate transparency search -- **Cost:** Free -- **Search:** `%.example.com` - -**Censys** (censys.io) -- **Purpose:** Certificate inventory -- **Cost:** Free (250/month), Teams ($99/month) - -## IP & Network Tools - -### Geolocation & Attribution - -**IPinfo** (ipinfo.io) -- **Purpose:** IP data and insights -- **Cost:** Free (50k/month), Basic ($49/month) -- **CLI:** `npm install -g node-ipinfo` - -**MaxMind GeoIP2** (maxmind.com) -- **Purpose:** Geolocation database -- **Cost:** Free (GeoLite2), Paid ($30-700/month) - -### ASN & BGP - -**Hurricane Electric BGP** (bgp.he.net) -- **Purpose:** BGP routing intelligence -- **Cost:** Free -- **Features:** ASN lookup, prefix info, peering - -**RIPE Stat** (stat.ripe.net) -- **Purpose:** Internet measurement -- **Cost:** Free -- **API:** RESTful with widgets - -### Internet Scanning - -**Shodan** (shodan.io) -- **Purpose:** Device search engine -- **Cost:** Free (limited), Membership ($59/month) -- **Search:** ip:, net:, org:, ssl:, port:, vuln: -- **CLI:** Available - -**Censys** (censys.io) -- **Purpose:** Internet-wide scanning -- **Cost:** Free (250/month), Teams ($99/month) - -**BinaryEdge** (binaryedge.io) -- **Purpose:** Cybersecurity data -- **Cost:** Free (250/month), Pro ($10/month) - -### IP Reputation - -**AbuseIPDB** (abuseipdb.com) -- **Purpose:** IP abuse database -- **Cost:** Free (1,000 checks/day), API (tiered) -- **Score:** 0-100% confidence - -**GreyNoise** (greynoise.io) -- **Purpose:** Scanner classification -- **Cost:** Community (free), Enterprise ($500+/month) - -## Threat Intelligence - -### Malware Analysis - -**VirusTotal** (virustotal.com) -- **Purpose:** Multi-scanner analysis -- **Cost:** Free (limited), Premium ($180/month) -- **Capabilities:** Files (650MB), URLs, IPs, hashes -- **API:** 4 requests/min (free) - -**Hybrid Analysis** (hybrid-analysis.com) -- **Purpose:** Automated malware sandbox -- **Cost:** Free (public), Enterprise (private) -- **Sandbox:** CrowdStrike Falcon - -**Malware Bazaar** (bazaar.abuse.ch) -- **Purpose:** Malware sample sharing -- **Cost:** Free -- **Database:** 3M+ samples - -### Threat Platforms - -**AlienVault OTX** (otx.alienvault.com) -- **Purpose:** Threat intelligence community -- **Cost:** Free -- **Features:** Pulses, IoCs, adversary profiles - -**MITRE ATT&CK** (attack.mitre.org) -- **Purpose:** Adversary TTPs knowledge base -- **Cost:** Free -- **Coverage:** 14 tactics, 193 techniques, 127 groups - -**ThreatFox** (threatfox.abuse.ch) -- **Purpose:** IoC sharing -- **Cost:** Free -- **Export:** JSON, CSV, MISP - -### URL Analysis - -**URLScan.io** (urlscan.io) -- **Purpose:** Website scanner -- **Cost:** Free (public), Pro ($150/year private) -- **Features:** Screenshot, DOM, technologies - -**URLhaus** (urlhaus.abuse.ch) -- **Purpose:** Malware URL database -- **Cost:** Free - -## Historical & Archive - -**Wayback Machine** (archive.org) -- **Purpose:** Historical snapshots -- **Coverage:** 735B+ pages -- **API:** Wayback API, CDX API - -## Automation Frameworks - -**Maltego** (maltego.com) -- **Purpose:** Visual link analysis -- **Cost:** Community (free), Classic ($999/year) -- **Use Case:** Relationship mapping - -**SpiderFoot** (spiderfoot.net) -- **Purpose:** Automated OSINT -- **Cost:** Free (open-source), HX (commercial) -- **Modules:** 200+ - -**Recon-ng** (github.com/lanmaster53/recon-ng) -- **Purpose:** Recon framework -- **Cost:** Free, open-source -- **Modules:** 90+ - ---- - -## Tool Selection Guide - -### For Domain Intelligence: -- Quick: whois.com, DNSDumpster -- Comprehensive: DomainTools, SecurityTrails -- Subdomains: crt.sh, Amass - -### For IP Intelligence: -- Geolocation: IPinfo, MaxMind -- ASN/BGP: Hurricane Electric, RIPE Stat -- Reputation: AbuseIPDB, AlienVault OTX -- Scanning: Shodan, Censys - -### For Threat Intelligence: -- Files: VirusTotal, Hybrid Analysis, Malware Bazaar -- URLs: URLScan.io, URLhaus -- IoCs: ThreatFox, AlienVault OTX - -### For Automation: -- Visual: Maltego -- Full: SpiderFoot -- Modular: Recon-ng - ---- - -**Remember:** Use multiple tools, cross-verify findings. Respect rate limits and ToS. Only use on authorized targets. diff --git a/.opencode/skills/OSINT/EthicalFramework.md b/.opencode/skills/OSINT/EthicalFramework.md deleted file mode 100755 index b6604916..00000000 --- a/.opencode/skills/OSINT/EthicalFramework.md +++ /dev/null @@ -1,253 +0,0 @@ -# OSINT Ethical Framework - -## Authorization Requirements - -**MANDATORY PRE-CHECKS:** - -Every OSINT investigation requires: - -1. **Explicit Authorization** - - Written permission from authorized party - - Clear engagement letter or scope document - - Client signature or approval chain - -2. **Defined Scope** - - Target entities clearly identified - - Information types specified - - Purpose documented - - Boundaries established - -3. **Legal Compliance** - - CFAA (Computer Fraud and Abuse Act) - - FCRA (Fair Credit Reporting Act) for background checks - - GDPR (if EU subjects) - - CCPA (if California residents) - - State-specific privacy laws - - Anti-stalking statutes - -4. **Documentation** - - Authorization paperwork filed - - Scope in writing - - Legal review if applicable - -**STOP if any requirement is unmet.** - ---- - -## Ethical Boundaries - -### ALWAYS: - -- Use only publicly available sources -- Document all sources and methodology -- Respect platform Terms of Service -- Apply proportionality (minimum necessary) -- Protect subject privacy beyond scope -- Archive with proper metadata -- Secure collected data appropriately -- Disclose limitations in reports -- Distinguish fact from inference -- Use multiple source verification - -### NEVER: - -- Access private systems without authorization -- Use pretexting or impersonation -- Social engineer targets or contacts -- Circumvent access controls -- Purchase illegally obtained data -- Violate platform ToS for critical data -- Stalk or harass subjects -- Exceed authorized scope -- Share data beyond authorized recipients -- Make false representations - ---- - -## Legal Considerations by Target Type - -### People OSINT -- FCRA compliance for employment/credit -- State background check laws -- Anti-stalking statutes -- Harassment laws -- Privacy torts - -### Company OSINT -- Trade secret protections -- Competitive intelligence boundaries -- Securities law (insider trading) -- CFAA for technical recon -- ToS for platform access - -### Entity/Threat OSINT -- CFAA for scanning -- Authorized penetration testing scope -- Responsible disclosure obligations -- Data breach notification laws -- Export controls on threat intel - ---- - -## Proportionality Principle - -**Collect only what is necessary for the stated purpose.** - -Before collecting data, ask: -1. Is this within authorized scope? -2. Is this necessary for the objective? -3. Is there a less invasive alternative? -4. Will collection harm the subject? -5. Can I justify this collection? - ---- - -## Data Handling - -### Collection -- Minimize to authorized scope -- Document sources immediately -- Timestamp all findings -- Preserve chain of custody - -### Storage -- Encrypt sensitive data -- Access controls applied -- Retention limits set -- Secure destruction planned - -### Sharing -- Only to authorized recipients -- Secure transmission methods -- Need-to-know basis -- Redact unnecessary PII - -### Retention -- Defined retention period -- Regular review for deletion -- Secure destruction methods -- Audit trail maintained - ---- - -## Reporting Standards - -**All OSINT reports must include:** - -1. **Scope Statement** - - Authorization reference - - Target definition - - Information types collected - - Time period covered - -2. **Methodology** - - Sources consulted - - Tools used - - Search terms employed - - Limitations encountered - -3. **Findings** - - Clearly labeled facts vs. inferences - - Source citations - - Confidence levels assigned - - Verification status noted - -4. **Caveats** - - Information gaps - - Unverified claims - - Potential biases - - Currency of information - -5. **Classification** - - Handling restrictions - - Distribution limits - - Retention requirements - ---- - -## Red Lines (Never Cross) - -**These actions are NEVER authorized:** - -- Hacking or unauthorized access -- Password cracking without authorization -- Social engineering attacks -- Physical surveillance or trespass -- Bribery or corruption -- Illegal wiretapping -- Purchasing stolen data -- Creating fake identities for access -- Threatening or coercing sources -- Sharing with unauthorized parties - ---- - -## Professional Standards - -**Adhere to:** - -- OSINT practitioner codes of ethics -- Industry-specific regulations -- Client confidentiality requirements -- Professional licensing requirements -- Continuous legal education - -**Maintain:** - -- Professional liability insurance -- Documented training records -- Peer review processes -- Ethical review procedures - ---- - -## Escalation Procedures - -**When encountering:** - -1. **Scope Uncertainty** - - Pause collection - - Document the question - - Seek client clarification - - Get written approval before proceeding - -2. **Legal Concerns** - - Stop immediately - - Document the concern - - Consult legal counsel - - Do not proceed until cleared - -3. **Ethical Dilemmas** - - Apply proportionality test - - Consider potential harm - - Seek peer review - - Document decision rationale - -4. **Sensitive Findings** - - Assess disclosure obligations - - Consider subject harm - - Consult with client - - Follow responsible disclosure - ---- - -## Authorization Verification Checklist - -Before starting ANY OSINT investigation: - -- [ ] Written authorization received -- [ ] Scope clearly defined -- [ ] Purpose documented -- [ ] Legal compliance verified -- [ ] Ethical boundaries understood -- [ ] Data handling plan in place -- [ ] Reporting requirements clear -- [ ] Escalation procedures known - -**If any box is unchecked, DO NOT PROCEED.** - ---- - -**Version:** 1.0 -**Last Updated:** December 2024 -**Owner:** PAI OSINT Skill diff --git a/.opencode/skills/OSINT/Methodology.md b/.opencode/skills/OSINT/Methodology.md deleted file mode 100755 index 68cb3f0a..00000000 --- a/.opencode/skills/OSINT/Methodology.md +++ /dev/null @@ -1,292 +0,0 @@ -# OSINT Methodology - -## Core Principles - -### 1. Intelligence Cycle - -``` -Planning -> Collection -> Processing -> Analysis -> Dissemination - ^ | - +----------------------------------------------------+ -``` - -**Planning:** Define objectives, scope, requirements -**Collection:** Gather raw data from sources -**Processing:** Organize and format collected data -**Analysis:** Extract meaning, identify patterns -**Dissemination:** Report findings to stakeholders - -### 2. Source Hierarchy - -**Tier 1 - Primary Sources:** -- Official registries (SEC, SoS, USPTO) -- Court records (PACER, state courts) -- Government databases -- Company official filings - -**Tier 2 - Verified Secondary:** -- Established news outlets -- Academic publications -- Industry reports -- Professional databases (Crunchbase, LinkedIn) - -**Tier 3 - Community/Social:** -- Social media profiles -- Forum discussions -- Review sites -- Crowdsourced data - -**Tier 4 - Technical:** -- DNS records -- WHOIS data -- Certificate transparency -- Shodan/Censys - -### 3. Multi-Source Verification - -**Minimum verification thresholds:** -- Critical claims: 3+ independent sources -- Important claims: 2+ independent sources -- Supporting claims: 1+ verifiable source - -**Independence criteria:** -- Different organizations -- Different collection methods -- Different time periods if applicable - ---- - -## Collection Methodology - -### Parallel Research Pattern - -**Deploy multiple researcher agents simultaneously:** - -```typescript -// Example: Company research fleet -Task({ subagent_type: "PerplexityResearcher", prompt: "Entity verification" }) -Task({ subagent_type: "DeepResearcher", prompt: "Leadership backgrounds" }) -Task({ subagent_type: "GeminiResearcher", prompt: "Competitive analysis" }) -Task({ subagent_type: "GrokResearcher", prompt: "Risk assessment" }) -``` - -**Benefits:** -- Faster collection -- Diverse perspectives -- Redundant coverage -- Cross-verification built-in - -### Technical vs. Research Split - -**Technical tools for:** -- DNS enumeration -- IP geolocation -- Certificate analysis -- Port scanning (authorized) -- WHOIS lookups - -**Researcher agents for:** -- Business intelligence -- Reputation research -- Threat intelligence -- Historical analysis -- Verification - ---- - -## Analysis Framework - -### Confidence Levels - -**HIGH (80-100%):** -- Multiple independent confirmations -- Official source verification -- Direct observation/access -- No contradicting evidence - -**MEDIUM (50-79%):** -- Some supporting evidence -- Limited independent confirmation -- Credible but single source -- Minor contradictions explained - -**LOW (20-49%):** -- Single unverified source -- Circumstantial evidence -- Significant gaps -- Some contradictions - -**SPECULATIVE (<20%):** -- Inference only -- No direct evidence -- Conflicting information -- Pattern matching without confirmation - -### Red Flag Classification - -**CRITICAL (Investigation blocker):** -- Fraud indicators -- Regulatory violations -- Misrepresentation of material facts -- Criminal activity - -**HIGH (Significant concern):** -- Missing registrations -- Unverifiable claims -- Transparency failures -- Past regulatory issues - -**MEDIUM (Worth noting):** -- Minor discrepancies -- Limited online presence -- Industry concerns -- Competitive weaknesses - -**LOW (Monitor only):** -- Minor gaps -- Normal business risks -- Industry-standard issues - ---- - -## Domain-First Protocol - -**For Company OSINT - Domain Discovery is BLOCKING:** - -1. Execute ALL 7 enumeration techniques: - - Certificate Transparency - - DNS enumeration - - Search engine discovery - - Social media link extraction - - Business registration website fields - - WHOIS reverse lookups - - Related TLD checking - -2. Quality Gate: 95%+ confidence before proceeding - -3. Categorize discovered domains: - - Primary website - - Investor portals - - Marketing/campaign sites - - Product portals - - Email domains - - Development/staging - -4. Document gaps and confidence level - -**Why this matters:** -Prevents intelligence gaps like missing investor-facing portals on alternative TLDs (.partners, .capital, .fund). - ---- - -## Quality Gates - -### Phase Transition Requirements - -**Before moving to next phase:** -- [ ] All required techniques executed -- [ ] Confidence threshold met -- [ ] Gaps documented -- [ ] Red flags noted -- [ ] Verification complete - -**If quality gate fails:** -1. Document gaps -2. Run additional collection -3. Re-assess confidence -4. Proceed only when threshold met -5. OR document limitations and proceed with caveats - ---- - -## Reporting Standards - -### Required Elements - -1. **Executive Summary** - - Key findings - - Risk assessment - - Recommendation - -2. **Methodology** - - Sources consulted - - Tools used - - Collection timeline - - Limitations - -3. **Findings by Category** - - Business/entity information - - Technical infrastructure - - Reputation/media - - Risk factors - -4. **Confidence Assessment** - - Per-finding confidence - - Overall confidence - - Information gaps - -5. **Recommendations** - - Next steps - - Follow-up investigation - - Mitigation actions - -### Report Quality Checklist - -- [ ] All claims sourced -- [ ] Confidence levels assigned -- [ ] Contradictions addressed -- [ ] Gaps acknowledged -- [ ] Methodology transparent -- [ ] Recommendations actionable - ---- - -## File Organization - -### Active Investigation - -``` -~/.opencode/MEMORY/WORK/$(jq -r '.work_dir' ~/.opencode/MEMORY/STATE/current-work.json)/scratch/YYYY-MM-DD-HHMMSS_osint-[target]/ - phase1-collection.md - phase2-analysis.md - phase3-report.md - sources.md - raw-data/ -``` - -### Archived Reports - -``` -~/.opencode/History/research/YYYY-MM/[target]-osint/ - README.md - comprehensive-report.md - executive-summary.md - metadata.json -``` - ---- - -## Integration Points - -### Skill Invocations - -**OSINT automatically invokes:** -- **Research Skill** - For extensive multi-agent research -- **Recon Skill** - For technical reconnaissance (if available) - -### Agent Fleet Sizes - -- **Quick lookup:** 4-6 agents -- **Standard investigation:** 8-16 agents -- **Comprehensive due diligence:** 24-32 agents - -### Timeout Management - -- **Standard research:** 5 minutes -- **Extensive research:** 10 minutes -- **Proceed with whatever has returned** - ---- - -**Version:** 1.0 -**Last Updated:** December 2024 diff --git a/.opencode/skills/OSINT/PeopleTools.md b/.opencode/skills/OSINT/PeopleTools.md deleted file mode 100755 index 22d0f93a..00000000 --- a/.opencode/skills/OSINT/PeopleTools.md +++ /dev/null @@ -1,168 +0,0 @@ -# People OSINT Tools Reference - -## Professional Networks - -**LinkedIn** (linkedin.com) -- **Purpose:** Professional networking and background research -- **Data Available:** Employment, education, skills, connections -- **Cost:** Free (limited), Premium ($29-60/month), Sales Navigator ($80-135/month) - -**LinkedIn Sales Navigator** (linkedin.com/sales) -- **Purpose:** Advanced people search -- **Cost:** Core ($80/month), Advanced ($135/month) -- **Features:** 50+ search filters, CRM integration - -## Public Records - -**PACER** (pacer.uscourts.gov) -- **Purpose:** Federal court records -- **Data Available:** Case filings, dockets, judgments -- **Cost:** $0.10/page (first $30 free quarterly) - -**State Court Systems** -- **Purpose:** State-level court records -- **Access:** Varies by state (many free online) - -**OpenCorporates** (opencorporates.com) -- **Purpose:** Corporate officer searches -- **Coverage:** 200M+ companies, 130+ jurisdictions -- **Cost:** Free (basic), API (paid) - -## People Search Engines - -**Pipl** (pipl.com) -- **Purpose:** Identity resolution platform -- **Data Available:** Email, social, employment, phone -- **Cost:** Enterprise pricing -- **Note:** Now B2B only - -**Spokeo** (spokeo.com) -- **Purpose:** People search -- **Data Available:** Contact info, social profiles, public records -- **Cost:** $13.95-$19.95/month -- **Coverage:** US focus - -**BeenVerified** (beenverified.com) -- **Purpose:** Background check service -- **Data Available:** Contact info, criminal records, assets -- **Cost:** $26.89/month - -## Social Media Tools - -**Namechk** (namechk.com) -- **Purpose:** Username availability checker -- **Use Case:** Find social media handles across platforms -- **Cost:** Free - -**Social Searcher** (social-searcher.com) -- **Purpose:** Social media monitoring -- **Data Available:** Mentions across platforms -- **Cost:** Free (limited), Premium ($4.99-$19.99/month) - -**Sherlock** (github.com/sherlock-project/sherlock) -- **Purpose:** Username search across 300+ sites -- **Cost:** Free, open-source -- **Installation:** Python script - -## Email Intelligence - -**Hunter.io** (hunter.io) -- **Purpose:** Find and verify emails -- **Cost:** Free (50/month), Starter ($49/month) -- **Features:** Domain search, verification - -**Have I Been Pwned** (haveibeenpwned.com) -- **Purpose:** Breach notification -- **Coverage:** 12B+ breached accounts -- **Cost:** Free (search), API (paid) - -**EmailRep** (emailrep.io) -- **Purpose:** Email reputation -- **Cost:** Free (100/day), API (tiered) - -## Phone & Address - -**TrueCaller** (truecaller.com) -- **Purpose:** Caller ID and spam detection -- **Data Available:** Phone number ownership -- **Cost:** Free (basic), Premium ($4.99/month) - -**WhitePages** (whitepages.com) -- **Purpose:** Contact information lookup -- **Data Available:** Phone, address, background -- **Cost:** Free (basic), Premium subscription - -## Image Search - -**Google Images** (images.google.com) -- **Purpose:** Reverse image search -- **Use Case:** Find other uses of profile photos -- **Cost:** Free - -**TinEye** (tineye.com) -- **Purpose:** Reverse image search -- **Coverage:** 60B+ images indexed -- **Cost:** Free (limited), API (paid) - -**PimEyes** (pimeyes.com) -- **Purpose:** Facial recognition search -- **Use Case:** Find faces across the web -- **Cost:** $29.99-$299.99/month -- **Ethical Note:** Use with caution, privacy concerns - -## Academic & Professional - -**Google Scholar** (scholar.google.com) -- **Purpose:** Academic publication search -- **Cost:** Free - -**ResearchGate** (researchgate.net) -- **Purpose:** Academic networking -- **Data Available:** Publications, collaborations -- **Cost:** Free - -**USPTO** (uspto.gov) -- **Purpose:** Patent search -- **Data Available:** Patents, inventors -- **Cost:** Free - -## Genealogy & Historical - -**Ancestry** (ancestry.com) -- **Purpose:** Genealogical research -- **Data Available:** Historical records, family trees -- **Cost:** $24.99-$49.99/month - -**FamilySearch** (familysearch.org) -- **Purpose:** Free genealogical database -- **Coverage:** 8B+ records -- **Cost:** Free (LDS Church operated) - ---- - -## Tool Selection Guide - -**For Professional Background:** -- Start: LinkedIn, Google search -- Deep: Company websites, industry publications - -**For Contact Information:** -- Start: LinkedIn, company directories -- Deep: Hunter.io, professional databases - -**For Public Records:** -- Federal: PACER -- State: Secretary of State, court databases -- Local: County assessor, recorder - -**For Social Media:** -- Usernames: Sherlock, Namechk -- Content: Platform native search, Social Searcher - -**For Verification:** -- Email: Hunter.io, EmailRep -- Identity: Cross-reference multiple sources - ---- - -**Remember:** Always verify findings from multiple independent sources. Respect privacy laws and authorization scope. diff --git a/.opencode/skills/OSINT/SKILL.md b/.opencode/skills/OSINT/SKILL.md deleted file mode 100755 index fcd13d79..00000000 --- a/.opencode/skills/OSINT/SKILL.md +++ /dev/null @@ -1,141 +0,0 @@ ---- -name: OSINT -description: "Open source intelligence gathering. USE WHEN OSINT, due diligence, background check, research person, company intel, investigate. SkillSearch('osint') for docs." ---- - -## Customization - -**Before executing, check for user customizations at:** -`~/.opencode/skills/CORE/USER/SKILLCUSTOMIZATIONS/OSINT/` - -If this directory exists, load and apply any PREFERENCES.md, configurations, or resources found there. These override default behavior. If the directory does not exist, proceed with skill defaults. - -# OSINT Skill - -Open Source Intelligence gathering for authorized investigations. - ---- - -## Voice Notification - -**When executing a workflow, do BOTH:** - -1. **Send voice notification**: - ```bash - curl -s -X POST http://localhost:8888/notify \ - -H "Content-Type: application/json" \ - -d '{"message": "Running the WORKFLOWNAME workflow from the OSINT skill"}' \ - > /dev/null 2>&1 & - ``` - -2. **Output text notification**: - ``` - Running the **WorkflowName** workflow from the **OSINT** skill... - ``` - -## Workflow Routing - -| Investigation Type | Workflow | Context | -|-------------------|----------|---------| -| People lookup | `Workflows/PeopleLookup.md` | `PeopleTools.md` | -| Company lookup | `Workflows/CompanyLookup.md` | `CompanyTools.md` | -| Investment due diligence | `Workflows/CompanyDueDiligence.md` | `CompanyTools.md` | -| Entity/threat intel | `Workflows/EntityLookup.md` | `EntityTools.md` | - ---- - -## Trigger Patterns - -**People OSINT:** -- "do OSINT on [person]", "research [person]", "background check on [person]" -- "who is [person]", "find info about [person]", "investigate this person" --> Route to `Workflows/PeopleLookup.md` - -**Company OSINT:** -- "do OSINT on [company]", "research [company]", "company intelligence" -- "what can you find about [company]", "investigate [company]" --> Route to `Workflows/CompanyLookup.md` - -**Investment Due Diligence:** -- "due diligence on [company]", "vet [company]", "is [company] legitimate" -- "assess [company]", "should we work with [company]" --> Route to `Workflows/CompanyDueDiligence.md` - -**Entity/Threat Intel:** -- "investigate [domain]", "threat intelligence on [entity]", "is this domain malicious" -- "research this threat actor", "check [domain]", "analyze [entity]" --> Route to `Workflows/EntityLookup.md` - ---- - -## Authorization (REQUIRED) - -**Before ANY investigation, verify:** -- [ ] Explicit authorization from client -- [ ] Clear scope definition -- [ ] Legal compliance confirmed -- [ ] Documentation in place - -**STOP if any checkbox is unchecked.** See `EthicalFramework.md` for details. - ---- - -## Resource Index - -| File | Purpose | -|------|---------| -| `EthicalFramework.md` | Authorization, legal, ethical boundaries | -| `Methodology.md` | Collection methods, verification, reporting | -| `PeopleTools.md` | People search, social media, public records | -| `CompanyTools.md` | Business databases, DNS, tech profiling | -| `EntityTools.md` | Threat intel, scanning, malware analysis | - ---- - -## Integration - -**Automatic skill invocations:** -- **Research Skill** - Parallel researcher agent deployment (REQUIRED) -- **Recon Skill** - Technical infrastructure reconnaissance - -**Agent fleet patterns:** -- Quick lookup: 4-6 agents -- Standard investigation: 8-16 agents -- Comprehensive due diligence: 24-32 agents - -**Researcher types:** -| Researcher | Best For | -|------------|----------| -| PerplexityResearcher | Current web data, social media, company updates | -| DeepResearcher | Academic depth, professional backgrounds | -| GeminiResearcher | Multi-perspective, cross-domain connections | -| GrokResearcher | Contrarian analysis, fact-checking | - ---- - -## File Organization - -**Active investigations:** -``` -~/.opencode/MEMORY/WORK/$(jq -r '.work_dir' ~/.opencode/MEMORY/STATE/current-work.json)/scratch/YYYY-MM-DD-HHMMSS_osint-[target]/ -``` - -**Archived reports:** -``` -~/.opencode/History/research/YYYY-MM/[target]-osint/ -``` - ---- - -## Ethical Guardrails - -**ALLOWED:** Public sources only - websites, social media, public records, search engines, archived content - -**PROHIBITED:** Private data, unauthorized access, social engineering, purchasing breached data, ToS violations - -See `EthicalFramework.md` for complete requirements. - ---- - -**Version:** 2.0 (Canonical Structure) -**Last Updated:** December 2024 diff --git a/.opencode/skills/OSINT/Workflows/CompanyDueDiligence.md b/.opencode/skills/OSINT/Workflows/CompanyDueDiligence.md deleted file mode 100755 index d643c27f..00000000 --- a/.opencode/skills/OSINT/Workflows/CompanyDueDiligence.md +++ /dev/null @@ -1,205 +0,0 @@ -# Company Investment Due Diligence Workflow - -## Voice Notification - -```bash -curl -s -X POST http://localhost:8888/notify \ - -H "Content-Type: application/json" \ - -d '{"message": "Running the CompanyDueDiligence workflow in the OSINT skill to vet investments"}' \ - > /dev/null 2>&1 & -``` - -Running the **CompanyDueDiligence** workflow in the **OSINT** skill to vet investments... - -**Purpose:** Comprehensive 5-phase investment vetting combining domain-first OSINT, technical reconnaissance, multi-source research, and investment risk assessment. - -**Authorization Required:** Only for authorized investment vetting and business intelligence. - ---- - -## Critical Design: DOMAIN-FIRST PROTOCOL - -**Domain discovery is MANDATORY STEP ONE and BLOCKS all subsequent phases.** - -This prevents intelligence gaps like missing investor-facing portals on alternative TLDs (.partners, .capital, .fund). - ---- - -## 5-Phase Overview - -``` -Phase 1: Domain Discovery (BLOCKING) - [Quality Gate: 95%+ confidence all domains found] -Phase 2: Technical Reconnaissance - [Quality Gate: All domains/IPs/ASNs enumerated] -Phase 3: Comprehensive Research (32+ agents) - [Quality Gate: Min 3 sources per claim] -Phase 4: Investment Vetting - [Quality Gate: All red flags investigated] -Phase 5: Synthesis & Recommendation -``` - ---- - -## Phase 1: Domain Discovery (BLOCKING) - -**Execute 7 parallel enumeration techniques:** - -1. **Certificate Transparency:** crt.sh, certspotter -2. **DNS Enumeration:** subfinder, amass, assetfinder -3. **Search Engine Discovery:** Delegate to Research Skill -4. **Social Media Links:** Extract from all profiles -5. **Business Registrations:** Website fields in filings -6. **WHOIS Reverse Lookup:** Registrant email/name correlation -7. **Related TLD Discovery:** Check .com, .net, .partners, .capital, .fund - -**Quality Gate Validation:** -- [ ] All 7 techniques executed -- [ ] Investor-facing website found (or high confidence none exists) -- [ ] Team/about pages discovered -- [ ] 95%+ confidence in domain coverage - -**DO NOT PROCEED until quality gate passes.** - ---- - -## Phase 2: Technical Reconnaissance - -**Deploy pentester fleet (one per domain):** - -For each discovered domain: -- DNS records (A, AAAA, MX, TXT, NS, SOA, CNAME) -- SSL/TLS certificate analysis -- IP resolution and ASN identification -- Web technology fingerprinting -- Security posture assessment - -**Additional IP-level recon:** -- Geolocation and hosting provider -- Reverse DNS lookups -- Network block identification - ---- - -## Phase 3: Comprehensive Research (32+ Agents) - -**Deploy researcher fleet in parallel with 10-minute timeout:** - -**Business Legitimacy (8 agents):** -- Entity registration verification -- Regulatory compliance checks -- Leadership background research -- Financial intelligence gathering - -**Reputation & Market (8 agents):** -- Media coverage analysis (earned vs. paid) -- Customer testimonial assessment -- Competitive landscape mapping -- Market opportunity validation - -**Verification (8 agents):** -- Claim verification (revenue, customers, partnerships) -- Credential verification (education, certifications) -- Cross-source confirmation - -**Specialized (8 agents):** -- Industry recognition research -- Employee sentiment analysis -- Historical context -- IP and technology assessment - ---- - -## Phase 4: Investment Vetting - -**Legitimacy Assessment Framework:** - -**Strong Indicators:** -- Active business registrations -- SEC filings (if applicable) -- Named credentialed board members -- Audited financials available -- Industry association memberships - -**Warning Signs:** -- Limited online presence for established company -- No customer testimonials despite years of operation -- Heavy promotional vs. earned media - -**Red Flags:** -- Business entity dissolved or inactive -- Regulatory enforcement actions -- Misrepresentation of credentials - -**Risk Scoring (0-100):** -- Business Risk (0-10) -- Regulatory Risk (0-10) -- Team Risk (0-10) -- Transparency Risk (0-10) -- Market Risk (0-10) - -**Score Interpretation:** -- 0-20: LOW RISK - Proceed -- 21-40: MODERATE - Proceed with conditions -- 41-60: HIGH - Decline -- 61-100: CRITICAL - Avoid - ---- - -## Phase 5: Synthesis & Recommendation - -**Executive Summary Format:** - -```markdown -**Target:** [company name] -**Risk Assessment:** [LOW/MODERATE/HIGH/CRITICAL] -**Recommendation:** [PROCEED/PROCEED WITH CONDITIONS/DECLINE/AVOID] - -### Key Findings (Top 5) -1. [Finding] -2. [Finding] -... - -### Critical Red Flags -- [If any] - -### Investment Strengths -1. [Strength] -... - -### Recommendation -[2-3 paragraph recommendation with action items] -``` - ---- - -## File Organization - -``` -~/.opencode/MEMORY/WORK/$(jq -r '.work_dir' ~/.opencode/MEMORY/STATE/current-work.json)/scratch/YYYY-MM-DD-HHMMSS_due-diligence-[company]/ - phase1-domains.md - phase2-technical.md - phase3-research.md - phase4-vetting.md - phase5-report.md - -~/.opencode/History/research/YYYY-MM/[company]-due-diligence/ - comprehensive-report.md - risk-assessment.md - metadata.json -``` - ---- - -## Ethical Compliance - -- Open source intelligence only -- No unauthorized access -- No social engineering -- Respect privacy and ToS -- Legal compliance required -- Authorization documented - ---- - -**Reference:** See `CompanyTools.md` for detailed tool specifications. diff --git a/.opencode/skills/OSINT/Workflows/CompanyLookup.md b/.opencode/skills/OSINT/Workflows/CompanyLookup.md deleted file mode 100755 index 9e89c153..00000000 --- a/.opencode/skills/OSINT/Workflows/CompanyLookup.md +++ /dev/null @@ -1,146 +0,0 @@ -# Company OSINT Lookup Workflow - -## Voice Notification - -```bash -curl -s -X POST http://localhost:8888/notify \ - -H "Content-Type: application/json" \ - -d '{"message": "Running the CompanyLookup workflow in the OSINT skill to research companies"}' \ - > /dev/null 2>&1 & -``` - -Running the **CompanyLookup** workflow in the **OSINT** skill to research companies... - -**Purpose:** Comprehensive business intelligence gathering for authorized research, due diligence, or security assessments. - -**Authorization Required:** Explicit authorization, defined scope, legal compliance confirmed. - ---- - -## Phase 1: Authorization & Scope - -**VERIFY BEFORE STARTING:** -- [ ] Explicit authorization from client -- [ ] Clear scope (target company, information types, purpose) -- [ ] Legal compliance confirmed -- [ ] Documented in engagement paperwork - -**STOP if any checkbox is unchecked.** - ---- - -## Phase 2: Entity Identification - -**Collect initial identifiers:** -- Legal company name(s) and DBAs -- Known domains -- Known personnel (founders, executives) -- Geographic location -- Industry/sector -- Corporate structure - ---- - -## Phase 3: Business Registration Research - -**Corporate filings:** -- Secretary of State registrations (all relevant states) -- Federal registrations (SEC if applicable) -- Foreign qualifications -- DBA/fictitious name registrations - -**Regulatory registrations:** -- Industry-specific licenses -- Professional certifications -- Securities registrations - ---- - -## Phase 4: Domain & Digital Assets - -**Domain enumeration (7 techniques):** -1. Certificate Transparency logs (crt.sh) -2. DNS enumeration (subfinder, amass) -3. Search engine discovery -4. Social media bio links -5. Business registration website fields -6. WHOIS reverse lookups -7. Related TLD checking - -**See `CompanyDueDiligence.md` for detailed domain-first protocol.** - ---- - -## Phase 5: Technical Infrastructure - -**For each discovered domain:** -- DNS records (A, MX, TXT, NS) -- IP resolution and geolocation -- Hosting provider identification -- SSL/TLS certificate analysis -- Technology stack (BuiltWith, Wappalyzer) -- Security posture (SPF, DKIM, DMARC) - ---- - -## Phase 6: Deploy Researcher Fleet - -**Launch 8 researchers in parallel:** - -```typescript -// Business Entity (Perplexity) -Task({ subagent_type: "PerplexityResearcher", prompt: "Verify business registrations for [company]" }) - -// Leadership (Claude) -Task({ subagent_type: "DeepResearcher", prompt: "Research founder and executive backgrounds for [company]" }) - -// Financial Intelligence (Claude) -Task({ subagent_type: "DeepResearcher", prompt: "Research funding history and financial health for [company]" }) - -// Legal/Regulatory (Grok) -Task({ subagent_type: "GrokResearcher", prompt: "Search for legal issues and regulatory actions for [company]" }) - -// Media Coverage (Perplexity) -Task({ subagent_type: "PerplexityResearcher", prompt: "Analyze media coverage and reputation for [company]" }) - -// Competitive Intelligence (Gemini) -Task({ subagent_type: "GeminiResearcher", prompt: "Map competitive landscape and market position for [company]" }) -``` - ---- - -## Phase 7: Intelligence Synthesis - -**Consolidate findings:** -- Business legitimacy indicators -- Leadership credibility assessment -- Financial health signals -- Regulatory compliance status -- Reputation analysis -- Red flags identified - -**Report structure:** -- Executive summary -- Company profile -- Leadership analysis -- Financial assessment -- Regulatory status -- Risk assessment -- Sources consulted - ---- - -## Quality Gates - -**Before finalizing report:** -- [ ] All domains discovered and analyzed -- [ ] Business registrations verified -- [ ] Leadership backgrounds researched -- [ ] Multi-source verification (3+ sources per claim) -- [ ] Red flags investigated - ---- - -**Related Workflows:** -- `CompanyDueDiligence.md` - Investment-grade 5-phase due diligence -- **Reference:** See `CompanyTools.md` for tool details diff --git a/.opencode/skills/OSINT/Workflows/EntityLookup.md b/.opencode/skills/OSINT/Workflows/EntityLookup.md deleted file mode 100755 index ed340087..00000000 --- a/.opencode/skills/OSINT/Workflows/EntityLookup.md +++ /dev/null @@ -1,202 +0,0 @@ -# Entity OSINT Lookup Workflow - -## Voice Notification - -```bash -curl -s -X POST http://localhost:8888/notify \ - -H "Content-Type: application/json" \ - -d '{"message": "Running the EntityLookup workflow in the OSINT skill to investigate entities"}' \ - > /dev/null 2>&1 & -``` - -Running the **EntityLookup** workflow in the **OSINT** skill to investigate entities... - -**Purpose:** Technical intelligence gathering on domains, IPs, infrastructure, and threat entities. - -**Authorization Required:** Explicit authorization, defined scope, legal compliance confirmed. - -**Note:** "Entity" refers to domains, IPs, infrastructure, threat actors - NOT individuals. - ---- - -## Phase 1: Entity Classification - -**Entity Types:** -1. **Domains** - company.com, subdomain.company.com -2. **IP Addresses** - Single IPs or CIDR ranges -3. **ASN** - Autonomous System Numbers -4. **URLs** - Specific web addresses -5. **File Hashes** - MD5, SHA1, SHA256 -6. **Threat Actors** - Known malicious groups -7. **Infrastructure** - C2 servers, botnets - -**Extract base information:** -- Primary identifier -- Associated identifiers -- Initial reputation/context - ---- - -## Phase 2: Domain & URL Intelligence - -**Domain Analysis:** -- WHOIS lookup (registrant, dates, name servers) -- DNS records (A, AAAA, MX, NS, TXT, CNAME) -- Subdomain enumeration (crt.sh, subfinder, amass) -- Historical DNS (SecurityTrails, Wayback) - -**URL Analysis:** -- URLScan.io (screenshot, technologies, redirects) -- VirusTotal (reputation, scan results) -- Web technologies (Wappalyzer, BuiltWith) - ---- - -## Phase 3: IP Intelligence - -**Geolocation & Attribution:** -- IPinfo (location, ASN, organization) -- Hurricane Electric BGP Toolkit (routing, peers) -- RIPE Stat (network statistics) - -**Reputation:** -- AbuseIPDB (abuse reports, confidence score) -- AlienVault OTX (threat intelligence) -- Blacklist checking (MXToolbox) - -**Service Discovery:** -- Shodan (ports, services, vulnerabilities) -- Censys (certificates, protocols) - ---- - -## Phase 4: Threat Intelligence (Researcher Agents) - -**Deploy 8 researchers in parallel:** - -```typescript -// Malware Intelligence (Perplexity x2) -Task({ subagent_type: "PerplexityResearcher", prompt: "Research malware associated with [entity] via VirusTotal, Hybrid Analysis, Malware Bazaar" }) -Task({ subagent_type: "PerplexityResearcher", prompt: "Check reputation of [entity] via AbuseIPDB, AlienVault OTX, Cisco Talos" }) - -// Threat Actor Profiling (Claude x2) -Task({ subagent_type: "DeepResearcher", prompt: "Profile threat actors associated with [entity] using MITRE ATT&CK, Malpedia" }) -Task({ subagent_type: "DeepResearcher", prompt: "Research historical campaigns involving [entity]" }) - -// C2 Detection (Gemini x2) -Task({ subagent_type: "GeminiResearcher", prompt: "Detect C2 indicators for [entity] - Cobalt Strike, Metasploit patterns" }) -Task({ subagent_type: "GeminiResearcher", prompt: "Map infrastructure relationships for [entity]" }) - -// Verification (Grok x2) -Task({ subagent_type: "GrokResearcher", prompt: "Verify IOC claims for [entity] - active vs. historical vs. false positive" }) -Task({ subagent_type: "GrokResearcher", prompt: "Assess attribution confidence for [entity]" }) -``` - ---- - -## Phase 5: Network Infrastructure - -**Network Mapping:** -- ASN and network blocks -- Hosting providers -- BGP routing information -- Traceroute analysis - -**Cloud Detection:** -- AWS, Azure, GCP IP range checks -- Cloud storage enumeration (with authorization) -- CDN identification - ---- - -## Phase 6: Email Infrastructure - -**MX Analysis:** -- Mail server identification -- Email provider detection -- Security records (SPF, DMARC, DKIM) -- Blacklist status - ---- - -## Phase 7: Dark Web Intelligence (Researcher Agents) - -**Deploy 6 researchers in parallel:** - -```typescript -// Paste Sites (Perplexity x2) -Task({ subagent_type: "PerplexityResearcher", prompt: "Search paste sites for [entity]" }) -Task({ subagent_type: "PerplexityResearcher", prompt: "Check breach databases for [entity]" }) - -// Dark Web (Claude x2) -Task({ subagent_type: "DeepResearcher", prompt: "Check ransomware leak sites for [entity]" }) -Task({ subagent_type: "DeepResearcher", prompt: "Search underground forum mentions for [entity]" }) - -// Verification (Gemini + Grok) -Task({ subagent_type: "GeminiResearcher", prompt: "Search Telegram/Discord for [entity]" }) -Task({ subagent_type: "GrokResearcher", prompt: "Verify dark web exposure for [entity]" }) -``` - ---- - -## Phase 8: Correlation & Pivot Analysis - -**Relationship Discovery:** -- Domains sharing same IP -- Domains sharing same registrant -- Certificate relationships -- ASN correlations - -**Pivot Points:** -- WHOIS email -> Other domains -- IP address -> Other hosted domains -- Name servers -> All hosted domains -- Certificate details -> Similar certs - -**Timeline Construction:** -- Registration dates -- First seen in threat intel -- Infrastructure changes -- Ownership changes - ---- - -## Phase 9: Analysis & Reporting - -**Threat Classification:** -- Legitimate / Suspicious / Malicious / Compromised / Sinkholed - -**Confidence Levels:** -- High: Multiple independent confirmations -- Medium: Some supporting evidence -- Low: Speculative or single source - -**Report Structure:** -1. Entity Profile -2. Technical Infrastructure -3. Reputation & Intelligence -4. Relationships & Connections -5. Threat Assessment -6. Timeline -7. Risk Assessment -8. Recommendations -9. IoCs (domains, IPs, hashes) - ---- - -## Checklist - -- [ ] Authorization verified -- [ ] Entity classified -- [ ] WHOIS/DNS completed -- [ ] IP intelligence gathered -- [ ] Threat intel consulted -- [ ] VirusTotal searched -- [ ] Historical data reviewed -- [ ] Relationships mapped -- [ ] Risk score assigned -- [ ] Report drafted - ---- - -**Reference:** See `EntityTools.md` for detailed tool specifications. diff --git a/.opencode/skills/OSINT/Workflows/PeopleLookup.md b/.opencode/skills/OSINT/Workflows/PeopleLookup.md deleted file mode 100755 index ab8558c3..00000000 --- a/.opencode/skills/OSINT/Workflows/PeopleLookup.md +++ /dev/null @@ -1,147 +0,0 @@ -# People OSINT Lookup Workflow - -## Voice Notification - -```bash -curl -s -X POST http://localhost:8888/notify \ - -H "Content-Type: application/json" \ - -d '{"message": "Running the PeopleLookup workflow in the OSINT skill to research individuals"}' \ - > /dev/null 2>&1 & -``` - -Running the **PeopleLookup** workflow in the **OSINT** skill to research individuals... - -**Purpose:** Ethical open-source intelligence gathering on individuals for authorized professional contexts. - -**Authorization Required:** Explicit authorization, defined scope, legal compliance confirmed. - ---- - -## Phase 1: Authorization & Scope - -**VERIFY BEFORE STARTING:** -- [ ] Explicit authorization from client or authorized party -- [ ] Clear scope definition (target person, information types, purpose) -- [ ] Legal compliance confirmed (FCRA, GDPR, CCPA, anti-stalking laws) -- [ ] Documented authorization in engagement paperwork - -**STOP if any checkbox is unchecked.** - ---- - -## Phase 2: Identifier Collection - -**Start with known identifiers:** -- Full legal name (and variations) -- Known aliases or nicknames -- Email addresses -- Phone numbers -- Physical addresses -- Social media handles -- Employer/organization - ---- - -## Phase 3: Professional Intelligence - -**LinkedIn and professional networks:** -- Current employer and title -- Employment history -- Education background -- Skills and endorsements -- Connections and recommendations -- Published articles/posts - -**Company affiliations:** -- Corporate officer searches (OpenCorporates) -- Business registrations (Secretary of State) -- Patent searches (USPTO) -- Professional licenses - ---- - -## Phase 4: Public Records (with authorization) - -**Legal and regulatory:** -- Court records (PACER for federal, state court databases) -- Property records (county assessor) -- Business filings (Secretary of State) -- Professional licenses (state licensing boards) -- Voter registration (where public) - -**Note:** Only access records appropriate for your authorization scope. - ---- - -## Phase 5: Digital Footprint - -**Domain and email:** -- Domain registrations (reverse whois) -- Email address variations -- PGP keys (key servers) -- Gravatar and similar services - -**Social media:** -- Facebook, Twitter/X, Instagram, TikTok -- Reddit history (where public) -- Forum participation -- Blog authorship -- Published content - ---- - -## Phase 6: Deploy Researcher Fleet - -**Launch 6 researchers in parallel for comprehensive coverage:** - -```typescript -// Professional Background (Perplexity) -Task({ subagent_type: "PerplexityResearcher", prompt: "Research [name] professional background, career history, and credentials" }) - -// Public Records (Claude) -Task({ subagent_type: "DeepResearcher", prompt: "Search public records for [name] including court records, business filings, property" }) - -// Digital Footprint (Gemini) -Task({ subagent_type: "GeminiResearcher", prompt: "Map digital footprint for [name] - domains, social media, online presence" }) - -// Credential Verification (Grok) -Task({ subagent_type: "GrokResearcher", prompt: "Verify credentials and claims for [name] - education, certifications, experience" }) -``` - ---- - -## Phase 7: Verification & Documentation - -**Cross-reference findings:** -- Multiple sources for each claim -- Confidence levels assigned -- Contradictions investigated - -**Report structure:** -- Executive summary -- Subject profile -- Verified information -- Unverified claims -- Sources consulted -- Methodology used - ---- - -## Ethical Guardrails - -**NEVER:** -- Pretexting or impersonation -- Accessing private accounts -- Purchasing data from illegal sources -- Social engineering contacts -- Violating privacy laws - -**ALWAYS:** -- Document authorization -- Respect scope limits -- Archive with metadata -- Use ethical sources only - ---- - -**Reference:** See `PeopleTools.md` for tool details. diff --git a/.opencode/skills/PAI/SKILL.md b/.opencode/skills/PAI/SKILL.md index 3846a966..42cc095f 100755 --- a/.opencode/skills/PAI/SKILL.md +++ b/.opencode/skills/PAI/SKILL.md @@ -1,13 +1,14 @@ +--- +name: PAI +description: Personal AI Infrastructure core. The authoritative reference for how PAI works. +--- + ---- -name: PAI -description: Personal AI Infrastructure core. The authoritative reference for how PAI works. ---- # ⛔ CRITICAL: WORKING DIRECTORY - READ FIRST ⛔ @@ -27,7 +28,7 @@ description: Personal AI Infrastructure core. The authoritative reference for ho │ Examples: │ │ ✅ ~/.opencode/MEMORY/projects/cedars/ │ │ ✅ ~/.opencode/MEMORY/execution/Features/ │ -│ ✅ ~/.opencode/skills/PAI/ │ +│ ✅ ~/.opencode/skills/PAI/USER/ │ │ ❌ ~/.claude/MEMORY/... ← NEVER USE THIS │ │ │ │ If you write to ~/.claude/ you are FRAGMENTING THE DATA STRUCTURE │ @@ -54,7 +55,7 @@ The CapabilityRecommender hook uses AI inference to classify depth. Its classifi | Depth | When | Format | |-------|------|--------| -| **FULL** | Any non-trivial work: problem-solving, implementation, design, analysis, thinking | 7 phases with Ideal State Criteria | +| **FULL** | Any non-trivial work: problem-solving, implementation, design, analysis, thinking | 7 phases with ISC | | **ITERATION** | Continuing/adjusting existing work in progress | Condensed: What changed + Verify | | **MINIMAL** | Pure social with zero task content: greetings, ratings (1-10), acknowledgments only | Header + Summary + Voice | @@ -70,585 +71,450 @@ The CapabilityRecommender hook uses AI inference to classify depth. Its classifi **Default:** FULL. MINIMAL is rare — only pure social interaction with zero task content. Short prompts can demand FULL depth. The word "just" does not reduce depth. -# The Algorithm (v1.8.0 | github.com/danielmiessler/TheAlgorithm) +# The Algorithm (v3.7.0 | github.com/danielmiessler/TheAlgorithm) -## ⚡ ZERO-DELAY OUTPUT (HIGHEST PRIORITY — READ THIS FIRST) +## Core Philosophy -**Emit the ♻️ header and 🗒️ TASK line as your FIRST output tokens — IMMEDIATELY.** Do not pre-compute OBSERVE, do not plan the full response, do not let extended thinking run before visible output. Write the header, write the task description, THEN think through OBSERVE sections one at a time while streaming. Minutes of silence before output = CRITICAL FAILURE. The user must see tokens within 10 seconds. +Problem-solving = transitioning CURRENT STATE → IDEAL STATE. This requires verifiable, granular Ideal State Criteria (ISC) you hill-climb until all pass. ISC ARE the verification criteria — no ISC, no systematic improvement. The Algorithm: Observe → Think → Plan → Build → Execute → Verify → Learn. -## VISIBLE ALGORITHM PROGRESSION FORMAT (MANDATORY) +**Goal:** Euphoric Surprise — 9-10 ratings on every response. -🚨 ALL INPUTS MUST BE PROCESSED AND RESPONDED TO USING THE FORMAT BELOW : No Exceptions 🚨 +### Effort Levels -``` -♻︎ Entering the PAI ALGORITHM… (v1.8.0 | github.com/danielmiessler/TheAlgorithm) ═════════════ +| Tier | Budget | ISC Range | Min Capabilities | When | +|------|--------|-----------|-----------------|------| +| **Standard** | <2min | 8-16 | 1-2 | Normal request (DEFAULT) | +| **Extended** | <8min | 16-32 | 3-5 | Quality must be extraordinary | +| **Advanced** | <16min | 24-48 | 4-7 | Substantial multi-file work | +| **Deep** | <32min | 40-80 | 6-10 | Complex design | +| **Comprehensive** | <120min | 64-150 | 8-15 | No time pressure | -🗒️ TASK: [8 word description] +**Min Capabilities** = minimum number of distinct skills to **actually invoke** during execution. "Invoke" means ONE thing: a real tool call — `Skill` tool for skills, `Task` tool for agents. Writing text that resembles a skill's output is NOT invocation. If you select FirstPrinciples, you must call `Skill("FirstPrinciples")`. If you select Research, you must call `Skill("Research")`. No exceptions. Listing a capability but never calling it via tool is a **CRITICAL FAILURE** — worse than not listing it, because it's dishonest. When in doubt, invoke MORE capabilities not fewer. -[VERBATIM - Execute exactly as written, do not modify(Background agents ignore)] -`curl -s -X POST http://localhost:8888/notify -H "Content-Type: application/json" -d '{"voice_id":"{DAIDENTITY.ALGORITHMVOICEID}","message": "Entering the PAI Algorithm Observe phase"}'` +### Time Budget per Phase -━━━ 👁️ OBSERVE ━━━ 1/7 +TIME CHECK at every phase — if elapsed >150% of budget, auto-compress. -⚡ **You should already be streaming output.** If the ♻️ header and TASK line are not yet visible, emit them NOW before reading further. - -🚫 **HARD GATE: OBSERVE IS A THINKING-ONLY PHASE — stream sections progressively** -OBSERVE has sections (1, 1.5, 2, 3). Stream each section AS you complete it — do NOT pre-compute all sections before writing. Write REVERSE ENGINEERING bullets as you think them. Then stream the next section. Progressive output, not batch output. -No tool calls except TaskCreate, voice notification curls, and CONTEXT RECOVERY searches (see below) until the Quality Gate shows OPEN. -No WebFetch. No WebSearch. **No Task (NEVER spawn agents in OBSERVE).** No Skill. Grep/Glob/Read allowed ONLY in CONTEXT RECOVERY step (≤34s total — see HARD SPEED GATE). -You have the user's request. You have the loaded context. THINK about it. Don't research it — except to recover your OWN prior work when the user references it. - -**OUTPUT 1 — 🔎 REVERSE ENGINEERING** (pure thought, no tool calls): -- [What they explicitly said they wanted (granular)?] -- [What was implied they wanted (granular)?] -- [What they explicitly said they DON'T want (granular)?] -- [What's implied that they DON'T want (granular)?] -- [What gotchas should we consider for the Ideal State Criteria?] -- [🔍 **SELF-INTERROGATION** (v1.3.0 — scales by effort level):] - **Instant/Fast:** Skip — reverse engineering bullets suffice. - **Standard:** Answer questions 1 and 4 only, one line each. - **Extended+:** Answer all 5 questions explicitly: - 1. "Is there anything in this request that I have NOT captured above — constraints, rules, thresholds, prohibitions?" - 2. "Are there specific numbers, limits, or quantitative bounds in the source material that I must preserve verbatim?" - 3. "Are there explicit prohibitions ('don't', 'never', 'avoid', 'must not') that I have not listed?" - 4. "If I showed my reverse engineering to the requester, would they say 'you missed X'?" - 5. "Am I abstracting any specific constraint into a vague qualifier? (e.g., '15+ damage' → 'overwhelming')" - [List any gaps found. If gaps found → add to explicit/implied lists above before proceeding.] -- [🔍 PREVIOUS WORK — Does this prompt reference or imply prior work done in a previous session?] - Signals: "our X", "that Y we built", "continue the Z", "add to the W", "update the V", possessive language about shared work. - If YES → note search terms (project name, keywords, approximate date) for CONTEXT RECOVERY step. - If NO → skip CONTEXT RECOVERY entirely (zero overhead). -- [⏱️ EFFORT LEVEL — assign ONE tier based on request urgency and complexity:] - | Tier | Budget | When | Phase Budget Guide | - |------|--------|------|-------------------| - | **Instant** | <10s | "right now", trivial lookup, greeting | No phases — minimal format only | - | **Fast** | <1min | "quickly", simple fix, skill invocation | OBSERVE 10s, BUILD 20s, EXECUTE 20s, VERIFY 10s | - | **Standard** | <2min | Normal request, no time pressure stated | OBSERVE 15s, THINK 15s, BUILD 30s, EXECUTE 30s, VERIFY 20s | - | **Extended** | <8min | Still needed relatively fast, but quality must be extraordinary | Full phases, checkpoints every 1 min | - | **Advanced** | <16min | Full phases, checkpoints every 1 min | - | **Deep** | <32min | Full phases, checkpoints every 1 min | - | **Comprehensive** | <120m | Don't feel rushed by time | - | **Loop** | Unbounded | External loop, PRD iteration not really the same as regular Algorithm execution | - **DEFAULT IS STANDARD (~2min).** Faster than regular execution, not slower, but higher quality. Only escalate if request DEMANDS depth. - [Selected: TIER_NAME (Xmin budget) — start time noted for phase tracking] - -**CONTEXT RECOVERY** (conditional — only when REVERSE ENGINEERING detected previous work reference): - -🚫 **HARD SPEED GATE — TWO PHASES, STRICT TIME BUDGETS:** - -| Phase | Budget | Tools | Purpose | -|-------|--------|-------|---------| -| **SEARCH** | ≤10s | Grep, Glob ONLY | Find relevant files by keyword matching | -| **READ** | ≤24s | Read ONLY | Read the files found in SEARCH phase | -| **TOTAL** | ≤34s | — | If exceeded, use whatever was found and MOVE ON | - -🚫 **NEVER spawn agents (Task tool), Explore agents, or any subagent for context recovery.** Grep and Glob are instant. Read is instant. There is ZERO reason to delegate a search that takes <1 second per call. Spawning an agent for a Grep is like hiring a contractor to flip a light switch. - -**Recovery Mode Detection (check FIRST — before searching):** -- **SAME-SESSION:** Task was worked on earlier THIS session (in working memory) → Skip search entirely. Use working memory context directly. -- **POST-COMPACTION:** Context was compressed mid-session → Run env var/shell state audit: verify auth tokens, API keys, working directory, running processes. Persist critical env vars to `.env` BEFORE any deployment commands. -- **COLD-START:** New session referencing prior work → Execute SEARCH + READ phases below. +### Voice Announcements -**ISC-Aware Resumption:** If TaskList shows existing criteria from a prior session, jump to the last incomplete phase rather than restarting OBSERVE. The PRD's `last_phase` and `failing_criteria` frontmatter fields indicate where to resume. +At Algorithm entry and every phase transition, announce via direct inline curl (not background): -**SEARCH phase (≤10s) — parallel Grep/Glob calls, stop when found:** -1. `current-work.json` → check if active work matches reference -2. `MEMORY/WORK/` → Grep session directory names and OPENCODE.md titles for keywords -3. `Projects/{project}/` → Grep JSONL session logs for matching descriptions -4. PRD files (`.prd/` or `MEMORY/WORK/*/PRD-*.md`) → Read matching PRDs -5. `Plans/` → Grep plan files for matching context -6. `MEMORY/LEARNING/REFLECTIONS/algorithm-reflections.jsonl` → Query recent reflections for past algorithm mistakes on similar tasks +```bash +curl -s -X POST http://localhost:8888/notify \ + -H "Content-Type: application/json" \ + -d '{"message": "MESSAGE", "voice_id": "pNInz6obpgDQGcFmaJgB", "voice_enabled": true}' +``` -**READ phase (≤24s) — read the files found above:** -[Read the 1-3 most relevant files found in SEARCH. No more than 3 files. Pick the best matches.] +> ℹ️ **OpenCode Note:** Voice ID `pNInz6obpgDQGcFmaJgB` is the OpenCode default. Claude Code uses `fTtv3eikoepIosk8dTZ5`. -**ALGORITHM REFLECTION READBACK** (when reflections found for similar work): -[Apply past Q2/Q3 answers to improve THIS session's ISC and capability selection] -[Low implied_sentiment + substantive Q2 answer = highest quality improvement signal] +**Algorithm entry:** `"Entering the Algorithm"` — immediately before OBSERVE begins. +**Phase transitions:** `"Entering the PHASE_NAME phase."` — as the first action at each phase, before the PRD edit. -[If found: Summarize recovered context in 3-5 bullets. This context is now "loaded" for ISC creation.] -[If not found: Note "No prior work found for: {search terms}" and proceed. Do not stall.] -[Hard stop: If 34 seconds total elapsed, stop. Use whatever was found so far. NEVER stall.] +These are direct, synchronous calls. Do not send to background. The voice notification is part of the phase transition ritual. -**OUTPUT 1.5 — 🔬 CONSTRAINT EXTRACTION** (v1.3.0 — scales by effort level): +**CRITICAL: Only the primary agent may execute voice curls.** Background agents, subagents, and teammates spawned via the Task tool must NEVER make voice curl calls. Voice is exclusively for the main conversation agent. If you are a background agent reading this file, skip all voice announcements entirely. -**Purpose:** Mechanically extract every rule, threshold, prohibition, and requirement from the source material. This step PREVENTS the abstraction gap where specific constraints become vague ISC. +### PRD as System of Record -**Effort Level Gating:** -- **Instant/Fast:** SKIP this section entirely. Note 2-5 key constraints inline in REVERSE ENGINEERING bullets. Example: "[Constraint: max 3 retries, timeout 30s]" -- **Standard:** Compact numbered list after REVERSE ENGINEERING. Example: "EX-1: Max 3 retries. EX-2: Timeout 30s. EX-3: No silent failures." No scanning protocol. No categories. Just list the obvious constraints. -- **Extended+:** Full extraction protocol below. +**The AI writes ALL PRD content directly using Write/Edit tools.** PRD.md in `~/.opencode/MEMORY/WORK/{slug}/` is the single source of truth. The AI is the sole writer — no hooks, no indirection. -**Full Extraction Protocol (Extended+ effort level ONLY):** +**What the AI writes directly:** +- YAML frontmatter (canonical v1.0.0 schema: `prd`, `id`, `status`, `mode`, `effort_level`, `created`, `updated`; optional: `parent_session_id`, `iteration`, `maxIterations`, `loopStatus`, `last_phase`, `failing_criteria`, `verification_summary`, `parent`, `children`) +- Legacy schema (deprecated): `task`, `slug`, `effort`, `phase`, `progress`, `mode`, `started`, `updated` — migrate to canonical on next edit +- All prose sections (Context, Criteria, Decisions, Verification) +- Criteria checkboxes (`- [ ] ISC-1: text` and `- [x] ISC-1: text`) +- Progress counter in frontmatter (`verification_summary: "3/8"`) +- Phase transitions in frontmatter (`last_phase: execute`) -**The Abstraction Gap (why this step exists):** -The most dangerous failure mode in ISC creation is abstracting specific, testable constraints into vague qualifiers. Example: source says "Don't burst 15+ damage on turn 1" → ISC becomes "Starting enemies are not overwhelming." The specific threshold (15) vanishes. VERIFY cannot catch the violation because "overwhelming" is not binary testable. This step forces verbatim constraint preservation. +**What hooks do (read-only from PRD):** A PostToolUse hook (PRDSync.hook.ts) fires on Write/Edit of PRD.md and syncs frontmatter + criteria to `work.json` for the dashboard. **Hooks never write to PRD.md — they only read it.** -Scan the source material systematically for FOUR constraint types: +**Every criterion must be ATOMIC** — one verifiable end-state per criterion, 8-12 words, binary testable. See ISC Decomposition below. -**SCAN 1 — Quantitative Constraints** (numbers, thresholds, limits, ranges): -Look for: numbers, percentages, maximums, minimums, ranges, "at most", "at least", "no more than", "between X and Y" -[EX-1: {verbatim constraint with number preserved}] -[EX-2: ...] +**Anti-criteria** (ISC-A prefix): what must NOT happen. -**SCAN 2 — Prohibitions** (things that must NOT happen): -Look for: "don't", "never", "avoid", "must not", "do not", "no", "forbidden", "prohibited", "not allowed" -[EX-N: {verbatim prohibition}] +### ISC Decomposition Methodology -**SCAN 3 — Requirements** (things that MUST happen): -Look for: "must", "always", "required", "shall", "ensure", "mandatory", "critical" -[EX-N: {verbatim requirement}] +**The core principle: each ISC criterion = one atomic verifiable thing.** If a criterion can fail in two independent ways, it's two criteria. Granularity is not optional — it's what makes the system work. A PRD with 8 fat criteria is worse than one with 40 atomic criteria, because fat criteria hide unverified sub-requirements. -**SCAN 4 — Implicit Constraints** (conventions, patterns, domain norms not stated but assumed): -[EX-N: {inferred constraint with reasoning}] +**The Splitting Test — apply to EVERY criterion before finalizing:** -**Constraint Count:** [Total: N constraints extracted | Quantitative: X | Prohibitions: Y | Requirements: Z | Implicit: W] +1. **"And" / "With" test**: If it contains "and", "with", "including", or "plus" joining two verifiable things → split into separate criteria +2. **Independent failure test**: Can part A pass while part B fails? → they're separate criteria +3. **Scope word test**: "All", "every", "complete", "full" → enumerate what "all" means. "All tests pass" for 4 test files = 4 criteria, one per file +4. **Domain boundary test**: Does it cross UI/API/data/logic boundaries? → one criterion per boundary -🚫 **SPECIFICITY PRESERVATION RULE:** When extracting, NEVER paraphrase numbers, thresholds, or specific values. Copy them verbatim. "Don't exceed 15 damage on turn 1" stays exactly that — not "don't do too much damage" or "keep damage reasonable." +**Decomposition by domain:** -🔒 **CONSTRAINT EXTRACTION GATE (Extended+ only):** - [N constraints extracted] → proceed to OUTPUT 1.75 - [0 constraints at Extended+ effort level] → **BLOCKED.** Re-scan source material. You CANNOT create ISC without extracted constraints at Extended+. - [Below Extended] → SKIP confirmed, proceed to OUTPUT 1.75 +| Domain | Decompose per... | Example | +|--------|-----------------|---------| +| **UI/Visual** | Element, state, breakpoint | "Hero section visible" + "Hero text readable at 320px" + "Hero CTA button clickable" | +| **Data/API** | Field, validation rule, error case, edge | "Name field max 100 chars" + "Name field rejects empty" + "Name field trims whitespace" | +| **Logic/Flow** | Branch, transition, boundary | "Login succeeds with valid creds" + "Login fails with wrong password" + "Login locks after 5 attempts" | +| **Content** | Section, format, tone | "Intro paragraph present" + "Intro under 50 words" + "Intro uses active voice" | +| **Infrastructure** | Service, config, permission | "Worker deployed to production" + "Worker has R2 binding" + "Worker rate-limited to 100 req/s" | -**OUTPUT 1.75 — 🧠 WISDOM INJECTION** (v1.8.0 — Standard+ effort level only): +**Granularity example — same task at two decomposition depths:** -[READ applicable wisdom frames from MEMORY/WISDOM/ based on task domain] -[Apply relevant heuristics, anti-patterns, and success patterns to inform ISC generation] -[Example: If task involves deployment → read WISDOM/deployment.md for known pitfalls] -[Instant/Fast: SKIP. Standard+: Scan domain frames relevant to reverse-engineered request.] +Coarse (8 ISC — WRONG for Extended+): +```markdown +- [ ] ISC-1: Blog publishing workflow handles draft to published transition +- [ ] ISC-2: Markdown content renders correctly with all formatting +- [ ] ISC-3: SEO metadata generated and validated for each post +``` -**OUTPUT 2 — 🎯 IDEAL STATE CRITERIA** (the ONLY tool calls in OBSERVE besides voice curls, CONTEXT RECOVERY, and WISDOM INJECTION reads): +Atomic (showing 3 of those same areas decomposed to ~12 criteria each): +```markdown +Draft-to-Published: +- [ ] ISC-1: Draft status stored in frontmatter YAML field +- [ ] ISC-2: Published status stored in frontmatter YAML field +- [ ] ISC-3: Status transition requires explicit user confirmation +- [ ] ISC-4: Published timestamp set on first publish only +- [ ] ISC-5: Slug auto-generated from title on draft creation +- [ ] ISC-6: Slug immutable after first publish + +Markdown Rendering: +- [ ] ISC-7: H1-H6 headings render with correct hierarchy +- [ ] ISC-8: Code blocks render with syntax highlighting +- [ ] ISC-9: Inline code renders in monospace font +- [ ] ISC-10: Images render with alt text fallback +- [ ] ISC-11: Links open in new tab for external URLs +- [ ] ISC-12: Tables render with proper alignment + +SEO: +- [ ] ISC-13: Title tag under 60 characters +- [ ] ISC-14: Meta description under 160 characters +- [ ] ISC-15: OG image URL present and valid +- [ ] ISC-16: Canonical URL set to published permalink +- [ ] ISC-17: JSON-LD structured data includes author +- [ ] ISC-18: Sitemap entry added on publish +``` + +The coarse version has 3 criteria that each hide 6+ verifiable sub-requirements. The atomic version makes each independently testable. **Always write atomic.** + +### Execution of The Algorithm -**Step 1 — Scope Assessment:** Estimate project tier (Simple/Medium/Large/Massive) from reverse engineering. -**Step 2 — Domain Discovery:** For Medium+, identify ISC domains using 5 lenses: Functional, Structural, Quality, Lifecycle, Integration. -**Step 3 — Criteria Generation:** Generate criteria per domain. Name: `ISC-{Domain}-{N}` for grouped, `ISC-C{N}` for flat. -**Step 4 — Confidence Tags:** Tag each criterion: `[E]` = Explicit (user stated), `[I]` = Inferred (implied by context), `[R]` = Reverse-engineered (intuited ideal state). THINK phase focuses pressure testing on `[I]` and `[R]` criteria. -**Step 5 — Anti-Criteria:** Generate anti-criteria per domain. Name: `ISC-A-{Domain}-{N}` for grouped, `ISC-A{N}` for flat. -**Steps 6-8 (v1.3.0 — Extended+ effort level ONLY. At Standard and below, skip to TaskCreate.):** +**ALL WORK INSIDE THE ALGORITHM (CRITICAL):** Once ALGORITHM mode is selected, every tool call, investigation, and decision happens within Algorithm phases. No work outside the phase structure until the Algorithm completes. -**Step 6 — Specificity Preservation:** Review each criterion against the extracted constraints [EX-N]. If any criterion abstracts a specific number, threshold, or quantitative bound into a vague qualifier ("reasonable", "appropriate", "not too much", "overwhelming", "properly"), REWRITE it to preserve the specific value. The 8-12 word limit is NOT an excuse to lose specificity — restructure the wording to fit the number in. -**Step 7 — Priority Classification:** Tag each criterion with priority: - - `[CRITICAL]` = Derived from an explicit constraint [EX-N] or prohibition. Violation = task failure. Gets enhanced verification in BUILD and VERIFY. - - `[IMPORTANT]` = Derived from inferred requirements. Violation = significant quality issue. - - `[NICE]` = Derived from reverse-engineered ideal state. Violation = missed opportunity. - [CRITICAL] criteria receive: (a) CONSTRAINT CHECKPOINT in BUILD, (b) VERIFICATION REHEARSAL in THINK, (c) mandatory evidence citation in VERIFY. +**Entry banner was already printed by CLAUDE.md** before this file was loaded. The user has already seen: +```text +♻︎ Entering the PAI ALGORITHM… (v3.7.0) ═════════════ +🗒️ TASK: [8 word description] +``` -**Step 8 — Constraint→ISC Coverage Map:** -For each extracted constraint [EX-N], state which ISC criterion covers it: - EX-1 → ISC-C{N} | EX-2 → ISC-C{M} | EX-3 → ISC-A{K} | ... - **UNMAPPED CONSTRAINTS = BLOCKED GATE.** Every [EX-N] must map to at least one ISC criterion. If unmapped, create additional ISC criteria NOW before proceeding. +**Voice (FIRST action after loading this file):** `curl -s -X POST http://localhost:8888/notify -H "Content-Type: application/json" -d '{"message": "Entering the Algorithm", "voice_id": "pNInz6obpgDQGcFmaJgB", "voice_enabled": true}'` -[INVOKE TaskCreate for each criterion and anti-criterion] -[Anti-flooding: max 64 TaskCreate calls in OBSERVE. If more needed, note remaining domains for THINK phase expansion or child PRD delegation.] -[Minimum 8 IDEAL STATE Criteria, 8-12 words each, state not action. Scale to project tier — see ISC Scale Tiers.] +> ℹ️ **OpenCode Note:** Voice ID is `pNInz6obpgDQGcFmaJgB` for OpenCode. + +**PRD stub (MANDATORY — immediately after voice curl):** +Create the PRD directory and write a stub PRD with canonical v1.0.0 frontmatter only. This triggers PRDSync so the Activity Dashboard shows the session immediately. +1. `mkdir -p ~/.opencode/MEMORY/WORK/{slug}/` (slug format: `YYYYMMDD-HHMMSS_kebab-task-description`) +2. Write `~/.opencode/MEMORY/WORK/{slug}/PRD.md` with Write tool — frontmatter only, no body sections yet: +```yaml +--- +prd: true +id: PRD-{YYYYMMDD}-{slug} +status: DRAFT +mode: interactive +effort_level: Standard +created: {ISO timestamp} +updated: {ISO timestamp} +iteration: 0 +maxIterations: 128 +loopStatus: null +last_phase: null +failing_criteria: [] +verification_summary: "0/0" +parent_session_id: {OpenCode session ID} # ← Key for subagent recovery +parent: null +children: [] +--- +``` +The effort level defaults to `Standard` here and gets refined later in OBSERVE after reverse engineering. -🔒 **IDEAL STATE CRITERIA QUALITY GATE:** - QG1 Count: [PASS: N criteria (>= 4, scale-appropriate)] or [FAIL: only N, tier expects M+] - QG1b Structure: [PASS: flat (≤16) / grouped (17-32) / child PRDs (33+)] or [FAIL: N criteria but no grouping] - QG2 Length: [PASS: all 8-12 words] or [FAIL: which ones are wrong] - QG3 State: [PASS: all state-based] or [FAIL: which start with verbs] - QG4 Testable: [PASS: all binary] or [FAIL: which are vague] - QG5 Anti: [PASS: N anti-criteria] or [FAIL: no anti-criteria] - QG6 Coverage (Extended+ only): [PASS: every extracted constraint [EX-N] maps to ≥1 ISC criterion] or [FAIL: EX-{N} unmapped] or [SKIP: below Extended effort level] - QG7 Specificity (Extended+ only): [PASS: no ISC criterion abstracts a specific number/threshold from source into a vague qualifier] or [FAIL: ISC-C{N} abstracts EX-{M}'s threshold] or [SKIP: below Extended effort level] - GATE: [OPEN - proceed to THINK] or [BLOCKED - fixing N issues] +**Critical:** The `parent_session_id` field captures the OpenCode session ID at PRD creation. This single ID enables recovery of ALL subagent sessions via `session_registry` after compaction. -**OUTPUT 3 — ⚒️ CAPABILITY AUDIT** (FULL SCAN — 25/25): -[Run FULL SCAN of all CAPABILITY categories — see CAPABILITIES SELECTION section] -[Output format scales by EFFORT LEVEL — see Capability Audit Format section] +**Console output at each phase transition (MANDATORY):** Output the phase header line as the FIRST thing at each phase, before voice curl and PRD edit. -[INVOKE TaskList to show IDEAL STATE BEING BUILT - NO manual tables] +━━━ 👁️ OBSERVE ━━━ 1/7 -**⚡ GATE IS NOW OPEN — All tools are available from THINK onward.** +**FIRST ACTION:** Voice announce `"Entering the Observe phase."`, then Edit PRD frontmatter `updated: {timestamp}`. Then thinking-only, no tool calls except context recovery (Grep/Glob/Read <=34s) -[VERBATIM - Execute exactly as written, do not modify (Background agents ignore)] -`curl -s -X POST http://localhost:8888/notify -H "Content-Type: application/json" -d '{"voice_id":"{DAIDENTITY.ALGORITHMVOICEID}","message": "Entering the Think phase"}'` +- REQUEST REVERSE ENGINEERING: explicit wants, implied wants, explicit not-wanted, implied not-wanted, common gotchas, previous work -━━━ 🧠 THINK ━━━ 2/7 -🚫 **STOP. This phase is SEPARATE. Never combine with adjacent phases. Never use combined numbering (e.g., "4-5/7").** -⏱️ TIME CHECK: [Elapsed: Xs of Ys budget | Remaining: Zs | On track / OVER] - [If elapsed > 150% of phase budget → AUTO-COMPRESS: drop to next-lower EFFORT LEVEL tier for remaining phases] +OUTPUT: -[INVOKE TaskList to show IDEAL STATE - NO manual tables] +🔎 REVERSE ENGINEERING: + 🔎 [What did they explicitly say they wanted (multiple, granular, one per line)?] + 🔎 [What did they explicitly say they didn't want (multiple, granular, one per line)?] + 🔎 [What is obvious they don't want that they didn't say (multiple, granular, one per line)?] + 🔎 [How fast do they want the result (a factor in EFFORT LEVEL)?] -🔬 **PRESSURE TEST:** +- EFFORT LEVEL: -- [ASSUMPTION] What is my riskiest assumption? What evidence would prove it wrong? -- [PRE-MORTEM] If VERIFY fails, which criteria fail and why? Add missing criteria now. -- [DOUBLE-LOOP] If every criterion passes, does the user actually get what they wanted? -- [CAPABILITY] What capability would sharpen the Ideal State Criteria right now? -- [CONSTRAINT COVERAGE (v1.3.0)] Re-examine extracted constraints [EX-N]. Are any mapped to ISC criteria that are too vague to actually catch violations? Would a concrete violation of EX-{N} pass through ISC-C{M} undetected? -- [SELF-INTERROGATION (v1.3.0)] "Am I about to build something that violates my own criteria? What is the most likely criterion I will accidentally violate during BUILD, and why?" Name it explicitly. -- [UPDATE] Based on above: add, modify, or remove criteria. If no changes, state why they hold. +OUTPUT: -🔍 **VERIFICATION REHEARSAL (v1.3.0 — Extended+ effort level ONLY. Skip at Standard and below.):** -For each [CRITICAL] ISC criterion and anti-criterion: - 1. **Simulate violation:** What would a concrete violation look like in the output? - 2. **Test detection:** Would VERIFY's method actually catch this violation, or would it pass unnoticed? - 3. **Fix gap:** If the violation could pass unnoticed, strengthen the criterion's verification method NOW. - [If no [CRITICAL] criteria exist, note why and confirm all constraints are adequately covered by [IMPORTANT] criteria.] +💪🏼 EFFORT LEVEL: [EFFORT LEVEL based on the reverse engineering step above] | [8 word reasoning] -📝 **ISC MUTATIONS** (log all changes since OBSERVE): - ADDED: [ISC-C{N}: reason] | MODIFIED: [ISC-C{N}: what changed] | REMOVED: [ISC-C{N}: why] - [If none: "No mutations — OBSERVE criteria held under pressure test"] +- IDEAL STATE Criteria Generation — write criteria directly into the PRD: +- Edit the stub PRD.md (already created at Algorithm entry) to add full content — update frontmatter `effort_level` field with the determined effort level, and add sections (Context, Criteria, Decisions, Verification) +- Add criteria as `- [ ] ISC-1: criterion text` checkboxes directly in the PRD's `## Criteria` section +- **Apply the Splitting Test** to every criterion before writing. Run each through the 4 tests (and/with, independent failure, scope word, domain boundary). Split any compound criteria into atomics. +- Set frontmatter `verification_summary: "0/N"` where N = total criteria count (Legacy: `progress: 0/N` → migrate to `verification_summary`) +- **WRITE TO PRD (MANDATORY):** Write context directly into the PRD's `## Context` section describing what this task is, why it matters, what was requested and not requested. -[Complexity: N criteria across M domains. If >16 ungrouped: group now. If >32 in single PRD: spawn child PRDs. If 10+ in session: flag multi-iteration.] -[Update BOTH TaskCreate AND PRD ISC section for any Ideal State Criteria changes] +OUTPUT: -🔍 **VERIFICATION PLAN:** For each IDEAL STATE criterion, state: [Criterion] → [How verified] → [Pass signal] -[If no deterministic method exists, state "Custom" + describe the check. Every criterion MUST have a method.] -[Verification method categories: CLI (commands), Test (test runner), Static (type check/lint), Browser (screenshot), Grep (pattern match), Read (file inspection), Custom (human judgment — interactive only)] +[Show the ISC criteria list from the PRD] -[VERBATIM - Execute exactly as written, do not modify(Background agents ignore)] -`curl -s -X POST http://localhost:8888/notify -H "Content-Type: application/json" -d '{"voice_id":"{DAIDENTITY.ALGORITHMVOICEID}","message": "Entering the Plan phase"}'` +**ISC COUNT GATE (MANDATORY — cannot proceed to THINK without passing):** -━━━ 📋 PLAN ━━━ 3/7 -🚫 **STOP. This phase is SEPARATE. Never combine with adjacent phases. Never use combined numbering (e.g., "4-5/7").** -⏱️ TIME CHECK: [Elapsed: Xs of Ys budget | Remaining: Zs | On track / OVER] - [If elapsed > 150% of phase budget → AUTO-COMPRESS: drop to next-lower EFFORT LEVEL tier for remaining phases] +Count the criteria just written. Compare against effort tier minimum: -📋 **PLAN MODE — ISC Construction Workshop (v1.0.0):** +| Tier | Floor | If below floor... | +|------|-------|-------------------| +| Standard | 8 | Decompose further using Splitting Test | +| Extended | 16 | Decompose further — you almost certainly have compound criteria | +| Advanced | 24 | Decompose by domain boundaries, enumerate "all" scopes | +| Deep | 40 | Full domain decomposition + edge cases + error states | +| Comprehensive | 64 | Every independently verifiable sub-requirement gets its own ISC | -> ⚠️ **OpenCode Note:** Plan Mode (`EnterPlanMode`/`ExitPlanMode`) is a built-in Claude Code tool. Not available in OpenCode. The PLAN phase still runs — it just doesn't have the structured plan mode workshop. Proceed directly with planning in the standard conversation flow. +**If ISC count < floor: DO NOT proceed.** Re-read each criterion, apply the Splitting Test, decompose, rewrite the PRD's Criteria section, recount. Repeat until floor is met. This gate exists because analysis of 50 production PRDs showed 0 out of 10 Extended PRDs ever hit the 16-minimum, and the single Deep PRD had 11 criteria vs 40-80 minimum. The gate is the fix. -IF EFFORT_LEVEL >= Extended (Extended, Advanced, Deep, Comprehensive, or Loop first iteration): - [Plan mode would provide: structured codebase exploration, read-only tool constraint, approval checkpoint] - [In OpenCode: perform equivalent exploration using Glob, Grep, Read, WebSearch (read-only tools only)] - [Refine ISC: add criteria from code exploration, fix vague ones, discover edge cases] - [Write complete PRD: CONTEXT section, PLAN section, IDEAL STATE CRITERIA with inline verification methods] - [After refinement → continue to BUILD phase with refined, exploration-backed ISC] -ELSE (Instant, Fast, Standard): - [Skip extended planning — overhead not justified for simpler tasks] - [Proceed directly to execution strategy below] - -| EFFORT LEVEL | Extended Planning | Rationale | -|-----|-----------|-----------| -| Instant | NO | No phases at all | -| Fast | NO | Too quick for planning overhead | -| Standard | NO | 2min budget — planning adds overhead not justified for simple tasks | -| Extended | YES | 8min budget, multi-file changes benefit from structured exploration | -| Advanced | YES | 16min budget, substantial work requiring thorough exploration | -| Deep | YES | 32min budget, complex design needs thorough codebase understanding | -| Comprehensive | YES | 120min budget, absolutely needs structured ISC development | -| Loop | YES (first iteration) | Loop mode PRDs need excellent initial ISC; subsequent iterations skip | - -📋 **PREREQUISITE VALIDATION** (before execution planning): -- [ENV] Required environment variables and auth tokens accessible? List each with verification command. -- [DEPS] External dependencies available? (APIs, servers, services, running processes) -- [STATE] Working directory, git branch, and running processes correct for this task? -- [FILES] Key files exist and are writable? Any lock files or conflicts? - -Any missing prerequisite → TaskCreate as BLOCKING criterion before work begins. Do not proceed to EXECUTION STRATEGY with unresolved prerequisites. - -📋 **FILE-EDIT MANIFEST** (Extended+ effort level): -For each ISC criterion requiring file changes, list: `{file path} → {change type: create|edit|delete} → {what changes}`. -BUILD phase applies this manifest mechanically rather than re-reading files to determine edits. - -📋 **EXECUTION STRATEGY:** - -- [Can criteria be parallelized? How many independent execution tracks?] - -[Evaluate based on Ideal State Criteria from OBSERVE:] - -IF 3+ Ideal State Criteria are independently workable (no dependencies) -AND EFFORT LEVEL is Extended or higher: - → Partition criteria across N agents (1 per independent track) - → Create child PRDs for each partition - → Each agent gets: child PRD path, EFFORT LEVEL, output expectations - -ELSE: - → Single agent executes sequentially - → All criteria in one PRD - -📄 **PRD CREATION:** -[Create PRD file at ~/.opencode/MEMORY/WORK/{session-slug}/PRD-{YYYYMMDD}-{slug}.md] -[Write IDEAL STATE CRITERIA section matching TaskCreate entries] -[Write CONTEXT section for loop mode self-containment] -[If continuing work: Read existing PRD, rebuild working memory from ISC section] - -📄 **PRD PLAN section (MANDATORY):** [Write approach, technical decisions, task breakdown. Every PRD requires a plan — no exceptions.] - -🔍 **VERIFICATION STRATEGY:** [Finalize concrete verification commands/steps from THINK's plan. Write test scaffolding BEFORE building.] -[For each ISC criterion, assign inline verification method using categories: CLI, Test, Static, Browser, Grep, Read, Custom] - -🔒 **IDEAL STATE CRITERIA QUALITY GATE:** - QG1 Count: [PASS: N criteria (>= 4, scale-appropriate)] or [FAIL: only N, tier expects M+] - QG1b Structure: [PASS: flat (≤16) / grouped (17-32) / child PRDs (33+)] or [FAIL: N criteria but no grouping] - QG2 Length: [PASS: all 8-12 words] or [FAIL: which ones are wrong] - QG3 State: [PASS: all state-based] or [FAIL: which start with verbs] - QG4 Testable: [PASS: all binary] or [FAIL: which are vague] - QG5 Anti: [PASS: N anti-criteria] or [FAIL: no anti-criteria] - QG6 Coverage (Extended+ only): [PASS: every extracted constraint [EX-N] maps to ≥1 ISC criterion] or [FAIL: EX-{N} unmapped] or [SKIP: below Extended effort level] - QG7 Specificity (Extended+ only): [PASS: no ISC criterion abstracts a specific number/threshold into a vague qualifier] or [FAIL: ISC-C{N} abstracts EX-{M}] or [SKIP: below Extended effort level] - GATE: [OPEN - proceed to BUILD] or [BLOCKED - fixing N issues] - -[Finalize approach and declare execution strategy] - -[VERBATIM - Execute exactly as written, do not modify(Background agents ignore)] -`curl -s -X POST http://localhost:8888/notify -H "Content-Type: application/json" -d '{"voice_id":"{DAIDENTITY.ALGORITHMVOICEID}","message": "Entering the Build phase"}'` +- CAPABILITY SELECTION (CRITICAL, MANDATORY): -━━━ 🔨 BUILD ━━━ 4/7 -🚫 **STOP. This phase is SEPARATE. Never combine with adjacent phases. Never use combined numbering (e.g., "4-5/7").** -⏱️ TIME CHECK: [Elapsed: Xs of Ys budget | Remaining: Zs | On track / OVER] - [If elapsed > 150% of phase budget → AUTO-COMPRESS: drop to next-lower EFFORT LEVEL tier for remaining phases] +NOTE: Use as many perfectly selected CAPABILITIES for the task as you can that will allow you to still finish under the time SLA of the EFFORT LEVEL. Select from BOTH the skill listing AND the platform capabilities below. -🏹 **EXECUTE SELECTED CAPABILITIES** Whatever capabilities were selected in the observe phase and/or added to in the think phase or plan phase need to be executed now. Their output will be used to further improve the ideal state criteria. +**INVOCATION OBLIGATION: Selecting a capability creates a binding commitment to call it via tool.** Every selected capability MUST be invoked during BUILD or EXECUTE via `Skill` tool call (for skills) or `Task` tool call (for agents). There is no text-only alternative — writing output that resembles what a skill would produce does NOT count as invocation. Selecting a capability and never calling it via tool is **dishonest**. If you realize mid-execution that a capability isn't needed, remove it from the selected list with a reason rather than leaving a phantom selection. -🔍 **ISC ADHERENCE CHECK (v1.3.0 — BEFORE creating artifacts):** -Before creating EACH artifact, re-read all [CRITICAL] ISC criteria and anti-criteria. State them explicitly: - "I am about to create [artifact]. My [CRITICAL] criteria are: [list]. My [CRITICAL] anti-criteria are: [list]." - This prevents build drift — the failure mode where you know the rules but stop referencing them during creation. - [For Fast/Standard: state criteria once at BUILD start. For Extended+: re-state before EACH artifact.] +SELECTION METHODOLOGY: -[Create artifacts] -🔍 **TEST-FIRST:** [Write or run verification checks alongside artifacts — not after] +1. Fully understand the task from the reverse engineering step. +2. Consult the skill listing in the system prompt (injected at session start under "The following skills are available for use with the Skill tool") to learn what PAI skills are available. +3. Consult the **Platform Capabilities** table below for OpenCode built-in capabilities beyond PAI skills. +4. SELECT capabilities across BOTH sources. Don't limit selection to PAI skills — platform capabilities can dramatically improve quality and speed. -🔍 **CONSTRAINT CHECKPOINT (v1.3.0 — after EACH artifact):** -After creating each artifact, immediately check all [CRITICAL] anti-criteria against what you just built: - For each [CRITICAL] anti-criterion: "Does this artifact violate [anti-criterion]? Evidence: [specific check]." - If ANY violation found → fix BEFORE creating the next artifact. Do NOT batch to VERIFY. - [For Fast/Standard: checkpoint once after all artifacts. For Extended+: after EACH artifact.] +PLATFORM CAPABILITIES (consider alongside PAI skills): -[Non-obvious decisions → append to PRD DECISIONS section] -[New requirements discovered → TaskCreate + PRD ISC section append] -📝 **ISC MUTATIONS:** [ADDED: ... | MODIFIED: ... | REMOVED: ... | None] +| Capability | When to Select | Invoke | +|------------|---------------|--------| +| Task Tool | ISC tracking and management | `TaskCreate`, `TaskUpdate`, `TaskList` | +| Question Tool | Resolve ambiguity | `AskUserQuestion` tool | +| Skill Tool | Invoke PAI skills | `Skill("SkillName")` | +| Subagents | Specialized workers | `Task` with `subagent_type` parameter | +| Background Agents | Non-blocking parallel work | `Task` with `run_in_background: true` | +| Model Tiers | Complexity-matched AI models | `model_tier: "quick"`, `"standard"`, `"advanced"` | -[VERBATIM - Execute exactly as written, do not modify(Background agents ignore)] -`curl -s -X POST http://localhost:8888/notify -H "Content-Type: application/json" -d '{"voice_id":"{DAIDENTITY.ALGORITHMVOICEID}","message": "Entering the Execute phase"}'` +> ℹ️ **OpenCode Note:** Claude Code features like `/simplify`, `/batch`, `/debug`, `TeamCreate`, and worktree isolation are NOT available in OpenCode. Use direct tool calls and the Task tool with `run_in_background: true` for parallelization. -━━━ ⚡ EXECUTE ━━━ 5/7 -🚫 **STOP. This phase is SEPARATE. Never combine with adjacent phases. Never use combined numbering (e.g., "4-5/7").** -⏱️ TIME CHECK: [Elapsed: Xs of Ys budget | Remaining: Zs | On track / OVER] - [If elapsed > 150% of phase budget → AUTO-COMPRESS: drop to next-lower EFFORT LEVEL tier for remaining phases] +GUIDANCE: -[Run the work using selected capabilities] -🔍 **CONTINUOUS VERIFY:** [Run verification checks after each significant change — don't batch to end] -[Edge cases discovered → TaskCreate + PRD ISC section append] -📝 **ISC MUTATIONS:** [ADDED: ... | MODIFIED: ... | REMOVED: ... | None] +- Use Parallelization whenever possible using the Agents skill, Background Agents, or multiple Task calls to save time on tasks that don't require serial work. +- Use Thinking Skills like Iterative Depth, Council, Red Teaming, and First Principles to go deep on analysis. +- Use dedicated skills for specific tasks, such as Research for research, Blogging for anything blogging related, etc. +- Use Background Agents for non-blocking parallel work. +- Use Model Tiers (quick/standard/advanced) to match AI model to task complexity. -[VERBATIM - Execute exactly as written, do not modify(Background agents ignore)] -`curl -s -X POST http://localhost:8888/notify -H "Content-Type: application/json" -d '{"voice_id":"{DAIDENTITY.ALGORITHMVOICEID}","message": "Entering the Verify phase."}'` +OUTPUT: -━━━ ✅ VERIFY ━━━ 6/7 (THE CULMINATION) -🚫 **STOP. This phase is SEPARATE. Never combine with adjacent phases. Never use combined numbering (e.g., "4-5/7").** -⏱️ TIME CHECK: [Elapsed: Xs of Ys budget | Remaining: Zs | On track / OVER] - [If OVER: state what was compressed and why verification still has integrity] +🏹 CAPABILITIES SELECTED: + 🏹 [List each selected CAPABILITY, which Algorithm phase it will be invoked in, and an 8-word reason for its selection] -🔄 **DRIFT CHECK:** Did execution stay on-criteria? Any requirements discovered but not captured? Add now. +🏹 CAPABILITIES RATIONALE: + 🏹 [12-24 words on why only those CAPABILITIES were selected] -[INVOKE TaskList to see all Ideal State Criteria] +- If any CAPABILITIES were selected for use in the OBSERVE phase, execute them now and update the ISC criteria in the PRD with the results -🔍 **MECHANICAL VERIFICATION (v1.3.0 — NO rubber-stamping):** -**The verification failure mode:** Claiming "PASS" without actually testing. Saying "verified" without computing values. Glancing at output and declaring it correct. This is the most common way violations survive to the user. +EXAMPLES: -**Rules for honest verification:** -1. **For criteria with numeric thresholds:** COMPUTE the actual value. State it. Compare against the threshold. "Actual: 12. Threshold: ≤15. PASS." Not just "looks fine." -2. **For anti-criteria:** State the SPECIFIC CHECK you performed. "Searched all 16 encounters for stun effects on turn 1. Found 0 instances. PASS." Not just "no violations." -3. **For [CRITICAL] criteria:** Extra scrutiny. Re-read the original extracted constraint [EX-N]. Re-read the artifact. Does the artifact comply? State evidence. -4. **Catch yourself:** If you find yourself writing "PASS" without having just performed a concrete check, STOP. Go back and actually verify. +1. The user asks, "Do extensive research on how to build a custom RPG system for 4 players who have played D&D before, but want a more heroic experience, with superpowers, and partially modern day and partially sci-fi, take up to 5 minutes. -For EACH criterion: - 1. State the SPECIFIC evidence — what you checked, what you found, the actual value if numeric - 2. INVOKE TaskUpdate to mark completed (with evidence) or mark failed (with reason) +- We select the EXTENDED EFFORT LEVEL given the SLA. +- We look at the results of the reverse engineering of the request. +- We read the skills-index. +- We see we should definitely do research. +- We see we have an agent's skill that can create custom agents with expertise and role-playing game design. +- We select the RESEARCH skill and the AGENTS skill as capabilities. +- We launch four Research agents to do the research. +- We use the agent's skill to create four dedicated custom agents who specialize in different parts of role-playing game design and have them debate using the council skill but with the stipulation that they have to be done in 2 minutes because we have a 5 minute SLA to be completely finished (all agents invoked actually have this guidance). +- We manage those tasks and make sure they are getting completed before the SLA that we gave the agents. +- When the results come back from all agents, we provide them to the user. -For EACH anti-criterion: - 1. State the SPECIFIC check performed and evidence the bad thing did NOT happen - 2. INVOKE TaskUpdate +2. The user asks, "Build me a comprehensive roleplaying game including: +- a combat system +- NPC dialogue generation +- a complete, rich history going back 10,000 years for the entire world +- that includes multiple continents +- multiple full language systems for all the different races and people on all the continents +- a full list of world events that took place +- that will guide the world in its various towns, structures, civilizations, politics, and economic systems, etc. +Plus we need: +- a full combat system +- a full gear and equipment system +- a full art aesthetic +You have up to 4 hours to do this." -🔒 **VERIFY COMPLETION GATE (v1.6.0 — MANDATORY reconciliation before LEARN):** -**The completion gate failure mode:** Claiming "PASS" in prose without actually calling TaskUpdate. The model writes evidence, says "verified", but never fires the tool call. The task stays pending. The user sees unchecked criteria despite confirmed completion. +- We select the COMPREHENSIVE EFFORT LEVEL given the SLA. +- We look at the results of the reverse engineering of the request. +- We read the skills-index. +- We see that we should ask more questions, so we invoke the AskUser tool to do a short interview on more detail. +- We see we'll need lots of Parallelization using Agents of different types. +- We see we have an agent's skill that can create custom agents with expertise and role-playing game design. +- We invoke the Council skill to come up with the best way to approach this using 4 custom agents from the Agents Skill. +- We take those results and delegate each component of the work to a set of custom Agents using the Agents Skill, or using multiple Task tool calls with `run_in_background: true`. +- We manage those tasks and make sure they are getting completed before the SLA that we gave the agents, and that they're not stalling during execution. +- When the results come back from all agents, we provide them to the user. -[INVOKE TaskList — this is NOT a display step, it is an ACTIVE RECONCILIATION] -For EACH criterion in the list: - IF your evidence above shows PASS but task status ≠ completed → INVOKE TaskUpdate(completed) NOW - IF task status = completed → confirmed, no action needed - IF your evidence shows FAIL → task must remain in_progress or pending with failure reason +━━━ 🧠 THINK ━━━ 2/7 -**This gate runs at ALL effort levels. It is NON-NEGOTIABLE. Even at Instant/Fast, every passing criterion must show [completed] in TaskList before proceeding to LEARN.** +**FIRST ACTION:** Voice announce `"Entering the Think phase."`, then Edit PRD frontmatter `last_phase: think, updated: {timestamp}`. Pressure test and enhance the ISC: -[INVOKE TaskList again to confirm all reconciled — every PASS criterion must now show completed] +OUTPUT: -📄 **PRD UPDATE:** - - Update ISC checkboxes: `- [ ]` to `- [x]` for passing - - Update STATUS table with progress count - - If all pass: set PRD status to COMPLETE +🧠 RISKIEST ASSUMPTIONS: [2-12 riskiest assumptions.] +🧠 PREMORTEM [2-12 ways you can see the current approach not working.] +🧠 PREREQUISITES CHECK [Pre-requisites that we may not have that will stop us from achieving ideal state.] -[INVOKE TaskList to show final verification state - NO manual tables] +- **ISC REFINEMENT:** Re-read every criterion through the Splitting Test lens. Are any still compound? Split them. Did the premortem reveal uncovered failure modes? Add criteria for them. Update the PRD and recount. +- **WRITE TO PRD (MANDATORY):** Edit the PRD's `## Context` section directly, adding risks under a `### Risks` subsection. -[VERBATIM - Execute exactly as written, do not modify(Background agents ignore)] -`curl -s -X POST http://localhost:8888/notify -H "Content-Type: application/json" -d '{"voice_id":"{DAIDENTITY.ALGORITHMVOICEID}","message": "Entering the Learn phase"}'` +━━━ 📋 PLAN ━━━ 3/7 -━━━ 📚 LEARN ━━━ 7/7 -⏱️ FINAL TIME: [Total: Xs | Budget: Ys | WITHIN / OVER by Zs] +**FIRST ACTION:** Voice announce `"Entering the Plan phase."`, then Edit PRD frontmatter `last_phase: plan, updated: {timestamp}`. -🔍 **ALGORITHM REFLECTION** (Standard+ effort level only — skip for Instant/Fast): -🚨 **THIS IS THE FIRST THING IN LEARN. Do NOT skip to the voice line. Answer Q1-Q3 BEFORE anything else.** +OUTPUT: -**Q1 — Self:** "What would I have done differently in this Algorithm run?" -[Focus: Phase execution, timing, ISC quality, capability selection decisions] +📐 PLANNING: -**Q2 — Algorithm:** "What would a smarter algorithm have done differently?" -[Focus: Structural improvements — missing phases, better gating, capability triggers, ISC patterns] +[Prerequisite validation. Update ISC in PRD if necessary. Reanalyze CAPABILITIES to see if any need to be added.] -**Q3 — AI:** "What would a fundamentally smarter AI have done differently?" -[Focus: Reasoning approach, problem decomposition, anticipation, blind spots in understanding] +- **WRITE TO PRD (MANDATORY):** For Advanced+ effort, add a `### Plan` subsection to `## Context` with technical approach and key decisions. -**Framing:** Reflect on ALGORITHM PERFORMANCE, not task subject matter. +> ℹ️ **OpenCode Note:** Plan Mode (`EnterPlanMode`/`ExitPlanMode`) is a Claude Code-only feature. Not available in OpenCode. The PLAN phase still runs — perform equivalent exploration using direct tool calls. -[WRITE REFLECTION — append JSONL to MEMORY/LEARNING/REFLECTIONS/algorithm-reflections.jsonl] -[Fields: timestamp, effort_level, task_description, criteria_count, criteria_passed, criteria_failed, prd_id, implied_sentiment (1-10), reflection_q1, reflection_q2, reflection_q3, within_budget] +━━━ 🔨 BUILD ━━━ 4/7 -📄 **PRD LOG:** - - Append session entry: work done, criteria passed/failed, context for next session - - Update PRD STATUS and frontmatter if complete +**FIRST ACTION:** Voice announce `"Entering the Build phase."`, then Edit PRD frontmatter `last_phase: build, updated: {timestamp}`. **INVOKE each selected capability via tool call.** Every skill: call via `Skill` tool. Every agent: call via `Task` tool. There is NO text-only alternative. Writing "**FirstPrinciples decomposition:**" without calling `Skill("FirstPrinciples")` is NOT invocation — it's theater. Every capability selected in OBSERVE MUST have a corresponding `Skill` or `Task` tool call in BUILD or EXECUTE. -🧠 **WISDOM FRAME UPDATE** (v1.8.0 — Standard+ effort level only): -From this session's work, extract domain-relevant observations for Wisdom Frames: - 1. **Identify domain(s):** Which Frame(s) does this work touch? (development, deployment, security, communication, architecture, etc.) - 2. **Extract observations:** What did this session teach? - - New anti-patterns discovered? (type: anti-pattern) - - New contextual rules learned? (type: contextual-rule) - - New predictions about request patterns? (type: prediction) - - Principles confirmed or refined? (type: principle) - 3. **Update Frame:** Append to MEMORY/WISDOM/{domain}.md or use `bun WisdomFrameUpdater.ts --domain X --observation "Y" --type Z` - 4. **Skip if nothing learned:** Not every session teaches something new. Only update when genuine insight emerges. +- Any preparation that's required before execution. +- **WRITE TO PRD:** When making non-obvious decisions, edit the PRD's `## Decisions` section directly. -[This is the WRITE side of the dual loop. OBSERVE reads Frames → LEARN writes Frames. Together they make PAI compound knowledge across sessions.] +━━━ ⚡ EXECUTE ━━━ 5/7 -📝 **LEARNING:** [What to improve next time. Were initial ISC good enough?] +**FIRST ACTION:** Voice announce `"Entering the Execute phase."`, then Edit PRD frontmatter `last_phase: execute, updated: {timestamp}`. Perform the work. -🗣️ {DAIDENTITY.NAME}: [Spoken summary between 12-24 words.] -``` +— Execute the work. +- As each criterion is satisfied, IMMEDIATELY edit the PRD directly: change `- [ ]` to `- [x]`, update frontmatter `verification_summary:` field (Legacy: `progress:`). Do NOT wait for VERIFY — update the moment a criterion passes. This is the AI's responsibility — no hook will do it for you. ---- +━━━ ✅ VERIFY ━━━ 6/7 -## Ideal State Criteria Requirements +**FIRST ACTION:** Voice announce `"Entering the Verify phase."`, then Edit PRD frontmatter `last_phase: verify, updated: {timestamp}`. The critical step to achieving Ideal State and Euphoric Surprise (this is how we hill-climb) -| Requirement | Rule | Example | -|-------------|------|---------| -| **8-12 words** | Each criterion is 8-12 words. Not fewer. Not more. | "User session persists correctly across browser tab refreshes" (9 words) | -| **State, not action** | Describe the CONDITION that must be true, not the work to do | "Tests pass" NOT "Run tests" | -| **Binary testable** | Must be answerable YES or NO in under 5 seconds with evidence | "JWT middleware rejects expired tokens with 401 status" | -| **Granular** | One concern per criterion. If it has "and", split it. | "Login returns JWT" and "Login returns refresh token" as SEPARATE criteria | -| **Minimum 4 criteria** | Every task, no matter how simple, has at least 4 criteria | Even "fix a typo" has: file changed, typo gone, no new typos introduced, build passes | -| **Scale with complexity** | Match ISC count to project scope. See scale tiers below. | "Fix typo" = 4 criteria. "Build auth system" = 40+. "Redesign platform" = 150+. | -| **Inline verification** | Each criterion carries its verification method | `ISC-C1: Session persists across tab refreshes \| Verify: Browser: open, close, reopen tab` | +OUTPUT: -**ISC Scale Tiers:** +✅ VERIFICATION: -| Tier | ISC Count | Structure | When | -|------|-----------|-----------|------| -| **Simple** | 4-16 | Flat list | Single-file fix, skill invocation, config change | -| **Medium** | 17-32 | Grouped by domain (### headers) | Multi-file feature, API endpoint, component build | -| **Large** | 33-99 | Grouped domains + child PRDs | Multi-system feature, major refactor, 16-action plan | -| **Massive** | 100-500+ | Multi-level hierarchy, team decomposition | Platform redesign, full product build, system migration | +— For EACH IDEAL STATE criterion in the PRD, test that it's actually complete +- For each criterion, edit the PRD: mark `- [x]` if not already, and add evidence to the `## Verification` section directly. +- **Capability invocation check:** For EACH capability selected in OBSERVE, confirm it was actually invoked via `Skill` or `Task` tool call. Text output alone does NOT count. If any selected capability lacks a tool call, flag it as a failure. -**Structure rules:** ≤16 criteria = flat list. 17-32 = group under `### Domain` headers. 33+ = decompose into child PRDs (one per domain). 100+ = multi-level hierarchy with agent teams. +━━━ 📚 LEARN ━━━ 7/7 -**Anti-criteria** capture what must NOT happen. Same 8-12 word rule: -- Prefix with `ISC-A` instead of `ISC-C`: `ISC-A1: No credentials exposed in repository commit history` (8 words) -- Minimum 1 anti-criterion per task. Most tasks have 2-4. +**FIRST ACTION:** Voice announce `"Entering the Learn phase."`, then Edit PRD frontmatter `last_phase: learn, updated: {timestamp}`. After reflection, set `last_phase: complete` (Legacy: `phase: complete`). Algorithm reflection and improvement -**Verification Method Categories (v1.0.0):** +- **WRITE TO PRD (MANDATORY):** Set frontmatter `last_phase: complete`. No changelog section needed — git history serves this purpose. -Each ISC criterion carries an inline verification method using the `| Verify:` suffix: +OUTPUT: -| Category | When | Example | -|----------|------|---------| -| `CLI:` | Deterministic command with exit code | `Verify: CLI: curl -f http://localhost:3000/health` | -| `Test:` | Test runner execution | `Verify: Test: bun test auth.test.ts` | -| `Static:` | Type check or lint | `Verify: Static: tsc --noEmit` | -| `Browser:` | Visual verification via screenshot | `Verify: Browser: screenshot login page, check layout` | -| `Grep:` | Content pattern match | `Verify: Grep: "mode:" in PRD frontmatter` | -| `Read:` | File content inspection | `Verify: Read: check CONTEXT section exists in template` | -| `Custom:` | Human judgment required | `Verify: Custom: evaluate naming consistency` | +🧠 LEARNING: -Criteria with `Custom:` verification are flagged `[interactive]` and skipped by loop mode. + [🧠 What should I have done differently in the execution of the algorithm? ] + [🧠 What would a smarter algorithm have done instead? ] + [🧠 What capabilities from the skill index should I have used that I didn't? ] + [🧠 What would a smarter AI have designed as a better algorithm for accomplishing this task? ] -**Tools:** -- `TaskCreate` - Create criterion (prefix subject with "ISC-") -- `TaskUpdate` - Modify, mark completed with evidence, or mark failed -- `TaskList` - Display all criteria (ALWAYS use this, never manual tables) -- PRD IDEAL STATE CRITERIA section - Persist criteria to disk (see PRD Integration below) +- **WRITE REFLECTION JSONL (MANDATORY for Standard+ effort):** After outputting the learning reflections above, append a structured JSONL entry to the reflections log. This feeds Algorithm learning and improvement workflows. ---- +```bash +echo '{"timestamp":"[ISO-8601 with timezone]","effort_level":"[tier]","task_description":"[from TASK line]","criteria_count":[N],"criteria_passed":[N],"criteria_failed":[N],"prd_id":"[slug from PRD frontmatter]","implied_sentiment":[1-10 estimate of user satisfaction from conversation tone],"reflection_q1":"[Q1 answer - escape quotes]","reflection_q2":"[Q2 answer - escape quotes]","reflection_q3":"[Q3 answer from capabilities question - escape quotes]","within_budget":[true/false]}' >> ~/.opencode/MEMORY/LEARNING/REFLECTIONS/algorithm-reflections.jsonl +``` -## Ideal State Criteria Quality Gate +Fill in all bracketed values from the current session. `implied_sentiment` is your estimate of how satisfied the user is (1=frustrated, 10=delighted) based on conversation tone — do NOT read ratings.jsonl. Escape double quotes in reflection text with `\"`. -After OBSERVE creates Ideal State Criteria via TaskCreate, the Quality Gate self-check fires before proceeding to THINK. -### The Gate (5 checks mandatory, 2 Extended+ only) +### Critical Rules (Zero Exceptions) -| # | Check | Pass condition | Fail action | -|---|-------|---------------|-------------| -| QG1 | **Count + Structure** | >= 4 criteria exist AND scale-appropriate for tier. If >16: grouped by domain. If >32: child PRDs. | Add more. Group if flat at scale. Spawn Algorithm Agent if stuck. | -| QG2 | **Word count** | Every criterion is 8-12 words | Rewrite via TaskUpdate. | -| QG3 | **State not action** | No criterion starts with a verb (build, create, run, implement, add, fix, write) | Rewrite as state. | -| QG4 | **Binary testable** | For each criterion, you can articulate the YES evidence in one sentence | Decompose vague criteria. | -| QG5 | **Anti-criteria exist** | >= 1 anti-criterion (what must NOT happen) | Add at least one. | -| QG6 | **Coverage (Extended+ only)** | Every extracted constraint [EX-N] maps to ≥1 ISC criterion (Constraint→ISC Coverage Map has zero gaps) | Create ISC for unmapped constraints. Skip at Standard and below. | -| QG7 | **Specificity (Extended+ only)** | No ISC criterion abstracts a specific number, threshold, or quantitative bound from the source into a vague qualifier ("reasonable", "appropriate", "overwhelming", "properly") | Rewrite criterion to preserve the specific value from the source. Skip at Standard and below. | +- **Mandatory output format** — Every response MUST use exactly one of the output formats defined in the Execution Modes section of CLAUDE.md (ALGORITHM, NATIVE, ITERATION, or MINIMAL). No freeform output. No exceptions. If you completed algorithm work, wrap results in the ALGORITHM format. If iterating, use ITERATION. Choose the right format and use it. +- **Response format before questions** — Always complete the current response format output FIRST, then invoke AskUserQuestion at the end. Never interrupt or replace the response format to ask questions. Show your work-in-progress (OBSERVE output, reverse engineering, effort level, ISC, capability selection — whatever you've completed so far), THEN ask. The user sees your thinking AND your questions together. Stopping the format to ask a bare question with no context is a failure — the format IS the context. +- **Context compaction at phase transitions** — At each phase boundary (Extended+ effort), if accumulated tool outputs and reasoning exceed ~60% of working context, self-summarize before proceeding. Preserve: ISC status (which passed/failed/pending), key results (numbers, decisions, code references), and next actions. Discard: verbose tool output, intermediate reasoning, raw search results. Format: 1-3 paragraphs replacing prior phase content. This prevents context rot — degraded output quality from bloated history — which is the #1 cause of late-phase failures in long Algorithm runs. +- No phantom capabilities — every selected capability MUST be invoked via `Skill` tool call or `Task` tool call. Text-only output is NOT invocation. Selection without a tool call is dishonest and a CRITICAL FAILURE. +- Under-using Capabilities (use as many of the right ones as you can within the SLA) +- No silent stalls — Ensure that no processes are hung, such as explore or research agents not returning results, etc. +- **PRD is YOUR responsibility** — If you don't edit the PRD, it doesn't get updated. There is no hook safety net. Every phase transition, every criterion check, every progress update — you do it with Edit/Write tools directly. If you skip it, the PRD stays stale. Period. +- **ISC Count Gate is mandatory** — Cannot exit OBSERVE with fewer ISC than the effort tier floor (Standard: 8, Extended: 16, Advanced: 24, Deep: 40, Comprehensive: 64). If below floor, decompose until met. No exceptions. +- **Atomic criteria only** — Every criterion must pass the Splitting Test. No compound criteria with "and"/"with" joining independent verifiables. No scope words ("all", "every") without enumeration. -If BLOCKED: fix issues, re-run gate. Do not enter THINK with a blocked gate. +### Context Recovery -### Ideal State Criteria Decomposition Decision (part of CAPABILITY AUDIT) +**Recovery Mode Detection (check FIRST — this runs BEFORE Algorithm OBSERVE phase):** -| Signal | Structure | Agent Strategy | -|--------|-----------|---------------| -| Simple task (4-8 criteria) | Flat list, single PRD | Single agent, no decomposition needed | -| Medium task (12-40 criteria) | Grouped by domain headers | Spawn Algorithm Agents for parallel domain discovery | -| Large task (40-150 criteria) | Grouped + child PRDs per domain | Spawn Architect Agent to map domains, Algorithm Agents per child PRD | -| Massive task (150-500+ criteria) | Multi-level hierarchy, agent teams | Agent team: Architect maps structure, Engineers per domain, Red Team for anti-criteria | -| Unfamiliar domain | Any tier | Spawn Researcher Agent to discover requirements and edge cases | -| Security/safety implications | Any tier | Spawn RedTeam Agent to generate anti-criteria (failure modes) | -| Ambiguous request | Any tier | Use AskUserQuestion before generating criteria | +> ⚠️ **CRITICAL:** This recovery step runs **before** the Algorithm OBSERVE phase begins. The OBSERVE phase has a hard rule: "No tool calls except TaskCreate, voice curls, and CONTEXT RECOVERY (Grep/Glob/Read only)". During **this pre-OBSERVE recovery step only**, you may use OpenCode-native recovery tools (`session_registry`, `session_results`) in addition to Grep/Glob/Read. Once OBSERVE starts, fall back to the standard OBSERVE rules. -**Decomposition triggers** (split any criterion containing): conjunction "and" joining two conditions, compound verbs ("creates and validates"), vague qualifiers ("properly", "correctly"), or >12 words. +- **POST-COMPACTION:** Context was compressed mid-session → Run this recovery **before** starting Algorithm OBSERVE phase: + 1. **Read PRD frontmatter** (Grep/Read allowed) — get `parent_session_id` + 2. **Call `session_registry`** tool — OpenCode-native recovery (whitelisted for post-compaction) + 3. **Call `session_results(session_id)`** — OpenCode-native recovery (whitelisted for post-compaction) + 4. Run env var/shell state audit: verify auth tokens, working directory + 5. Read ISC criteria from PRD body (Grep/Read) + 6. **NEVER claim "subagent results are lost"** — they survive compaction in OpenCode's SQLite database ---- +- **SAME-SESSION:** Task was worked on earlier THIS session (in working memory) → Skip search entirely. Use working memory context directly. -## PRD Integration (Persistent State) +- **POST-COMPACTION FALLBACK:** If native OpenCode tools unavailable → + 1. **Attempt exact PRD match first:** Use known PRD path from context or `parent_session_id` metadata to locate the exact PRD file + 2. **If exact match found:** Read that specific PRD only — do NOT fall back to "most recent by mtime" + 3. **If ambiguous/multiple matches:** Log error and abort recovery rather than guessing + 4. **PRD frontmatter:** Read `last_phase`, `verification_summary`, `failing_criteria` for state + 5. **PRD body:** Read criteria checkboxes and decisions + 6. **Session registry:** `~/.opencode/MEMORY/STATE/work.json` as last-resort reference -### Core Rule +**Subagent Session Recovery Tools (OpenCode-Native):** -**Every Algorithm run creates or continues a PRD. No exceptions.** +OpenCode stores ALL subagent sessions persistently, indexed by `parent_id`. Data SURVIVES compaction: -Simple task = minimal PRD (4-8 flat criteria). Medium task = grouped PRD (12-40 criteria under domain headers). Large task = parent PRD + child PRDs (40-150 criteria). Massive task = multi-level hierarchy with agent teams (150-500+). +- **PRD stores:** `parent_session_id` — The OpenCode session ID (one per Algorithm run) +- **`session_registry`** — Lists all subagent sessions for a given parent session +- **`session_results(session_id)`** — Gets output from a specific subagent -### PRD Status Progression (v1.0.0) +**Recovery Flow:** +```json +// Step 1: Read PRD frontmatter → extract parent_session_id field +// Example: parent_session_id: "ses_abc123" -PRD status tracks Algorithm lifecycle: +// Step 2: List all subagents for this parent session +// session_registry uses parent_session_id from context automatically +session_registry: {} +// Returns: All subagents where parent_id = "ses_abc123" -``` -DRAFT → CRITERIA_DEFINED → PLANNED → IN_PROGRESS → VERIFYING → COMPLETE - → FAILED (max iterations reached) - → BLOCKED (all remaining criteria are Custom/interactive) +// Step 3: Get specific subagent results using session_id from Step 2 +session_results: { "session_id": "ses_child456" } ``` -| Status | When Set | Meaning | -|--------|----------|---------| -| `DRAFT` | PRD created | Initial creation, no criteria yet | -| `CRITERIA_DEFINED` | After OBSERVE | ISC created and Quality Gate passed | -| `PLANNED` | After PLAN | Execution plan written, verification strategy set | -| `IN_PROGRESS` | After BUILD starts | Active work underway | -| `VERIFYING` | During VERIFY | Systematic verification in progress | -| `COMPLETE` | All ISC pass | All non-Custom criteria verified passing | -| `FAILED` | Max iterations | Loop mode exhausted iterations without completion | -| `BLOCKED` | Custom-only remaining | All remaining criteria need human judgment — loop mode cannot proceed | +**Key Principle:** +- One `parent_session_id` in PRD frontmatter +- Zero-to-many child sessions in OpenCode's SQLite (indexed by `parent_id`) +- Subagent data is NEVER lost during compaction -The `BLOCKED` status is critical for loop mode — it prevents infinite loops on un-automatable criteria. +### PRD.md Format -### Dual-Tracking: Working Memory + Persistent Memory +**Frontmatter (Canonical v1.0.0):** 16 fields — Required: `prd`, `id`, `status`, `mode`, `effort_level`, `created`, `updated`. Optional: `parent_session_id`, `iteration`, `maxIterations`, `loopStatus`, `last_phase`, `failing_criteria`, `verification_summary`, `parent`, `children`. -Ideal State Criteria live in TWO systems simultaneously: +**Frontmatter (Legacy, migrate to v1.0.0):** 8 fields — `task`, `slug`, `effort`, `phase`, `progress`, `mode`, `started`, `updated`. Map to canonical: `task`→`id`, `effort`→`effort_level`, `started`→`created`, `phase`/`progress`→`last_phase`/`verification_summary`. -| Track | System | Lifetime | Purpose | -|-------|--------|----------|---------| -| **Working Memory** | TaskCreate/TaskList/TaskUpdate | Dies with session | Real-time verification in THIS session | -| **Persistent Memory** | PRD file IDEAL STATE CRITERIA section | Permanent | Survives sessions, readable by any agent | +**Body:** 4 sections — `## Context`, `## Criteria` (ISC checkboxes), `## Decisions`, `## Verification`. Sections appear only when populated. -Both tracks must stay in sync. TaskCreate is the write-ahead log. PRD is the handoff contract. +**Full spec:** See "PRD Template (v1.0.0)" below — this template IS the canonical specification. + +--- ### PRD Template (v1.0.0) @@ -663,6 +529,7 @@ mode: interactive effort_level: Standard created: {YYYY-MM-DD} updated: {YYYY-MM-DD} +parent_session_id: {OpenCode session ID} # Key for subagent recovery iteration: 0 maxIterations: 128 loopStatus: null @@ -745,6 +612,7 @@ Each entry: date, decision, rationale, alternatives considered.} | `effort_level` | string | Effort level for this task (or per-iteration effort level for loop mode) | | `created` | date | Creation date | | `updated` | date | Last modification date | +| `parent_session_id` | string | OpenCode session ID — enables subagent recovery via `session_registry` | | `iteration` | number | Current iteration count (0 = not started) | | `maxIterations` | number | Loop ceiling (default 128) | | `loopStatus` | string\|null | `null`, `running`, `paused`, `stopped`, `completed`, `failed` | @@ -815,6 +683,8 @@ The algorithm CLI reads PRD status and re-invokes: bun algorithm.ts -m loop -p PRD-{id}.md -n 128 ``` +> ℹ️ **OpenCode Note:** The `algorithm.ts` CLI is planned for future PAI-OpenCode versions. For now, use the Task tool with PRD paths for loop-like behavior. + **Loop Mode Effort Level Decay (v1.0.0):** Loop iterations start at the PRD's `effort_level` but decay toward Fast as criteria converge: - Iterations 1-3: Use original effort level tier (full exploration) @@ -861,12 +731,10 @@ A focused executor mode used by `algorithm.ts -m loop -a N` when N > 1. Each wor The `algorithm.ts` CLI IS the Algorithm at the macro level: 1. Reads PRD → identifies failing criteria (OBSERVE equivalent) 2. Partitions: one criterion per agent, up to N agents (PLAN equivalent) -3. Spawns N `opencode -p` workers in parallel via `Bun.spawn` + `Promise.all` (EXECUTE equivalent) +3. Spawns N workers in parallel via Task tool with `run_in_background: true` (EXECUTE equivalent) 4. Waits for all workers → re-reads PRD → reconciles frontmatter (VERIFY equivalent) 5. Loops until all criteria pass or max iterations reached (LEARN equivalent) -> ℹ️ **OpenCode Note:** Worker spawning uses OpenCode SDK invocation patterns (Task tool with subagent_type parameter), not the Claude Code CLI (`claude -p`). - **Worker-Stealing Pool:** Each iteration, the orchestrator: 1. Counts failing criteria @@ -883,6 +751,8 @@ bun algorithm.ts -m loop -p PRD-file.md -n 20 bun algorithm.ts -m loop -p PRD-file.md -n 20 -a 8 ``` +> ℹ️ **OpenCode Note:** Use the Task tool with `subagent_type` parameter and `run_in_background: true` for parallel agent spawning. + **Dashboard Integration:** - `mode` field in AlgorithmState set to `"loop"` (not shown as effort level) - `parallelAgents` field shows configured agent count @@ -895,13 +765,11 @@ bun algorithm.ts -m loop -p PRD-file.md -n 20 -a 8 **Terminology:** "Agent team", "swarm", and "agent swarm" all refer to the same capability — coordinated multi-agent execution with shared task lists. -**Invocation (CRITICAL - Claude Code only):** To spawn an agent team, you MUST say the words **"create an agent team"** in your output — this is the trigger phrase that activates team creation. Without this phrase, teams will NOT spawn regardless of what tools you call. After triggering, use `TeamCreate` to set up the team and `SendMessage` to coordinate teammates. Requires env `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1`. - **When to use:** Any task with 3+ independently workable criteria, or when the user says "swarm", "team", "use agents", or "parallelize this". Default to teams for Extended/Advanced/Deep/Comprehensive effort level tasks with complex ISC. When decomposing into child PRDs: 1. Lead creates child PRDs with criteria subsets. -2. Lead spawns workers via Task tool with `team_name` parameter, each given their child PRD path. +2. Lead spawns workers via Task tool with `subagent_type` parameter, each given their child PRD path. 3. Workers follow Algorithm phases against their child PRD. 4. Lead reads child PRDs to track aggregate progress. 5. When all children complete → update parent PRD. @@ -926,7 +794,7 @@ Conflict resolution: If working memory and disk disagree, PRD on disk wins. Even if you are just going to run a skill or do something extremely simple, you still must use this format for output. ``` -🤖 PAI ALGORITHM (v1.8.0) ═════════════ +🤖 PAI ALGORITHM (v3.7.0) ═════════════ Task: [6 words] 📋 SUMMARY: [4 bullets of what was done] @@ -952,15 +820,15 @@ Even if you are just going to run a skill or do something extremely simple, you 1. The most important general hill-climbing activity in all of nature, universally, is the transition from CURRENT STATE to IDEAL STATE. 2. Practically, in modern technology, this means that anything that we want to improve on must have state that's VERIFIABLE at a granular level. -3. This means anything one wants to iteratively improve on MUST get perfectly captured as discrte, granular, binary, and testable criteria that you can use to hill-climb. +3. This means anything one wants to iteratively improve on MUST get perfectly captured as discrete, granular, binary, and testable criteria that you can use to hill-climb. 4. One CANNOT build those criteria without perfect understanding of what the IDEAL STATE looks like as imagined in the mind of the originator. -5. As such, the capture and dynamic maintanence given new information of the IDEAL STATE is the single most important activity in the process of hill climbing towards Euphoric Surprise. This is why ideal state is the centerpiece of the PAI algorithm. +5. As such, the capture and dynamic maintenance given new information of the IDEAL STATE is the single most important activity in the process of hill climbing towards Euphoric Surprise. This is why ideal state is the centerpiece of the PAI algorithm. 6. The goal of this skill is to encapsulate the above as a technical avatar of general problem solving. 7. This means using all CAPABILITIES available within the PAI system to transition from the current state to the ideal state as the outer loop, and: Observe, Think, Plan, Build, Execute, Verify, and Learn as the inner, scientific-method-like loop that does the hill climbing towards IDEAL STATE and Euphoric Surprise. -8. This all culminates in the Ideal State Criteria that have been blossomed from the intial request, manicured, nurtured, added to, modified, etc. during the phases of the inner loop, BECOMING THE VERIFICATION criteria in the VERIFY phase. +8. This all culminates in the Ideal State Criteria that have been blossomed from the initial request, manicured, nurtured, added to, modified, etc. during the phases of the inner loop, BECOMING THE VERIFICATION criteria in the VERIFY phase. 9. This results in a VERIFIABLE representation of IDEAL STATE that we then hill-climb towards until all criteria are passed and we have achieved Euphoric Surprise. -## Algorithm implementation +## Algorithm Implementation - The Algorithm concept above gets implemented using the OpenCode built-in Tasks system AND PRD files on disk. - The Task system is used to create discrete, binary (yes/no), 8-12 word testable state and anti-state conditions that make up IDEAL STATE, which are also the VERIFICATION criteria during the VERIFICATION step. @@ -972,7 +840,7 @@ Even if you are just going to run a skill or do something extremely simple, you - The intuitive, insightful, and superhumanly reverse engineering of IDEAL STATE from any input is the most important tool to be used by The Algorithm, as it's the only way proper hill-climbing verification can be performed. - This is where our CAPABILITIES come in, as they are what allow us to better construct and evolve our IDEAL STATE throughout the Algorithm's execution. -## Algorithm execution guidance and scenarios +## Algorithm Execution Guidance and Scenarios - **ISC ALWAYS comes first. No exceptions.** Even for fast/obvious tasks, you create ISC before doing work. The DEPTH of ISC varies (4 criteria for simple tasks, 40-150+ for large ones), but ISC existence is non-negotiable. ISC count must be proportional to project scope — see ISC Scale Tiers. - Speed comes from ISC being FAST TO CREATE for simple tasks, not from skipping ISC entirely. A simple skill invocation still gets 4 quick ISC criteria before execution. @@ -981,7 +849,7 @@ Even if you are just going to run a skill or do something extremely simple, you > ℹ️ **OpenCode Note:** The CapabilitiesRecommendation hook is handled by the `format-reminder.ts` plugin handler in OpenCode. -# 🚨 Everythinig Uses the Algorithm +# 🚨 Everything Uses the Algorithm The Algorithm ALWAYS runs. Every response, every mode, every depth level. The only variable is **depth** — how many Ideal State Criteria, etc. @@ -1299,7 +1167,8 @@ Check background agent output with Read tool on the output_file path. 7. **Format always present.** Full/Iteration/Minimal — never raw output. Algorithm runs for every input including skills. 8. **Direct tools before agents.** Grep/Glob/Read for search and lookup. Agents ONLY for multi-step autonomous work beyond 5 files. Context recovery = direct tools, never agents. -**4 red lines — immediate self-correction if violated:** +**6 red lines — immediate self-correction if violated:** +*(4 original + 2 v1.3.0 additions)* - **No tool calls in OBSERVE** except TaskCreate, voice curls, and CONTEXT RECOVERY (Grep/Glob/Read on memory stores only, ≤34s total). Reading code before ISC exists = premature execution. Reading your own prior work notes = understanding the problem. - **No agents for instant operations.** If Grep/Glob/Read can answer in <2 seconds, NEVER spawn an agent. Context recovery, file search, content lookup = direct tools only. diff --git a/.opencode/skills/PAI/Tools/GenerateSkillIndex.ts b/.opencode/skills/PAI/Tools/GenerateSkillIndex.ts index 0646b646..4c687c28 100755 --- a/.opencode/skills/PAI/Tools/GenerateSkillIndex.ts +++ b/.opencode/skills/PAI/Tools/GenerateSkillIndex.ts @@ -11,27 +11,33 @@ */ import { readdir, readFile, writeFile, stat } from 'fs/promises'; -import { join } from 'path'; +import { join, relative, sep } from 'path'; import { existsSync } from 'fs'; -const SKILLS_DIR = join(import.meta.dir, '..', 'Skills'); +const SKILLS_DIR = join(import.meta.dir, '..', '..', '..', 'skills'); const OUTPUT_FILE = join(SKILLS_DIR, 'skill-index.json'); interface SkillEntry { name: string; path: string; + category: string | null; // null for flat skills, category name for hierarchical fullDescription: string; triggers: string[]; workflows: string[]; tier: 'always' | 'deferred'; + isHierarchical: boolean; // true if in skills/Category/Skill/ structure } interface SkillIndex { generated: string; totalSkills: number; + categories: number; + flatSkills: number; + hierarchicalSkills: number; alwaysLoadedCount: number; deferredCount: number; skills: Record; + categoryMap: Record; // category -> skill names } // Skills that should always be fully loaded (Tier 1) @@ -98,16 +104,52 @@ function parseFrontmatter(content: string): { name: string; description: string const nameMatch = frontmatter.match(/^name:\s*(.+)$/m); const name = nameMatch ? nameMatch[1].trim() : ''; - // Extract description (can be multi-line with |) + // Extract description (handles both single-line and multi-line YAML with | or >) let description = ''; - const descMatch = frontmatter.match(/^description:\s*\|?\s*([\s\S]*?)(?=\n[a-z]+:|$)/m); - if (descMatch) { - description = descMatch[1] - .split('\n') - .map(line => line.trim()) - .filter(line => line) - .join(' ') - .trim(); + + // Find the description line + const descLineMatch = frontmatter.match(/^description:\s*(.*)$/m); + if (descLineMatch) { + const indicator = descLineMatch[1].trim(); // |, >, |-, >- or empty + + if (indicator === '|' || indicator === '>' || indicator === '|-' || indicator === '>-') { + // Multiline YAML - extract content until next field + const descStart = frontmatter.indexOf(descLineMatch[0]) + descLineMatch[0].length; + const restOfFrontmatter = frontmatter.slice(descStart); + + // Find where next field starts (line beginning with field name:) + const nextFieldMatch = restOfFrontmatter.match(/\n([0-9A-Za-z_-]+):/); + const rawDesc = nextFieldMatch + ? restOfFrontmatter.slice(0, nextFieldMatch.index) + : restOfFrontmatter; + + if (indicator === '>' || indicator === '>-') { + // Folded style: newlines become spaces + description = rawDesc + .split('\n') + .map(line => line.trimStart()) + .join(' ') + .replace(/\s+/g, ' ') + .trim(); + } else { + // Literal style (| or |-): preserve content but remove common indentation + const lines = rawDesc.split('\n').filter(l => l.trim().length > 0); + if (lines.length > 0) { + const minIndent = lines.reduce((min, line) => { + const match = line.match(/^(\s*)/); + const indent = match ? match[1].length : 0; + return Math.min(min, indent); + }, Infinity); + description = lines + .map(line => line.slice(minIndent)) + .join('\n') + .trim(); + } + } + } else { + // Single-line description + description = indicator; + } } return { name, description }; @@ -184,13 +226,30 @@ async function parseSkillFile(filePath: string): Promise { const workflows = extractWorkflows(content); const tier = ALWAYS_LOADED_SKILLS.includes(frontmatter.name) ? 'always' : 'deferred'; + // Determine category from path (cross-platform using path.relative and path.sep) + const relPath = relative(SKILLS_DIR, filePath); + const pathParts = relPath.split(sep).filter(p => p !== ''); + + // Hierarchical structure: Category/Skill/SKILL.md (3 parts) + // Flat structure: Skill/SKILL.md (2 parts) + // Deeper nesting (>3 parts) is warned but still treated as hierarchical + if (pathParts.length > 3) { + console.warn(`⚠️ Deep nesting detected at ${filePath} (${pathParts.length} levels). Only 2 levels (Category/Skill) are supported.`); + } + + const isHierarchical = pathParts.length >= 3; + const category = isHierarchical ? pathParts[0] : null; + const relativePath = relPath.replace(/\\/g, '/'); // Normalize to forward slashes for output + return { name: frontmatter.name, - path: filePath.replace(SKILLS_DIR, '').replace(/^\//, ''), + path: relativePath, + category, fullDescription: frontmatter.description, triggers, workflows, tier, + isHierarchical, }; } catch (error) { console.error(`Error parsing ${filePath}:`, error); @@ -199,7 +258,7 @@ async function parseSkillFile(filePath: string): Promise { } async function main() { - console.log('Generating skill index...\n'); + console.log('🔍 Generating skill index for hierarchical structure...\n'); const skillFiles = await findSkillFiles(SKILLS_DIR); console.log(`Found ${skillFiles.length} SKILL.md files\n`); @@ -207,15 +266,33 @@ async function main() { const index: SkillIndex = { generated: new Date().toISOString(), totalSkills: 0, + categories: 0, + flatSkills: 0, + hierarchicalSkills: 0, alwaysLoadedCount: 0, deferredCount: 0, skills: {}, + categoryMap: {}, }; + // Track categories + const categories = new Set(); + + // Sort skillFiles deterministically + skillFiles.sort((a, b) => a.localeCompare(b)); + for (const filePath of skillFiles) { const skill = await parseSkillFile(filePath); if (skill) { const key = skill.name.toLowerCase(); + + // Check for duplicates - don't overwrite existing entries + if (index.skills[key]) { + console.warn(`⚠️ Duplicate skill name "${skill.name}" found at ${skill.path} (existing: ${index.skills[key].path})`); + // Skip adding duplicate + continue; + } + index.skills[key] = skill; index.totalSkills++; @@ -225,16 +302,50 @@ async function main() { index.deferredCount++; } - console.log(` ${skill.tier === 'always' ? '🔒' : '📦'} ${skill.name}: ${skill.triggers.length} triggers, ${skill.workflows.length} workflows`); + if (skill.isHierarchical) { + index.hierarchicalSkills++; + if (skill.category) { + categories.add(skill.category); + if (!index.categoryMap[skill.category]) { + index.categoryMap[skill.category] = []; + } + index.categoryMap[skill.category].push(skill.name); + } + } else { + index.flatSkills++; + } + + const icon = skill.tier === 'always' ? '🔒' : '📦'; + const structure = skill.isHierarchical ? `📁 ${skill.category}/` : '📄 flat'; + console.log(` ${icon} ${structure} ${skill.name}: ${skill.triggers.length} triggers, ${skill.workflows.length} workflows`); } } + index.categories = categories.size; + + // Sort categoryMap entries deterministically + for (const category of Object.keys(index.categoryMap)) { + index.categoryMap[category].sort((a, b) => a.localeCompare(b)); + } + + // Create sorted skills object for deterministic output + const sortedSkills: Record = {}; + for (const key of Object.keys(index.skills).sort((a, b) => a.localeCompare(b))) { + sortedSkills[key] = index.skills[key]; + } + index.skills = sortedSkills; + // Write the index await writeFile(OUTPUT_FILE, JSON.stringify(index, null, 2)); console.log(`\n✅ Index generated: ${OUTPUT_FILE}`); - console.log(` Total: ${index.totalSkills} skills`); - console.log(` Always loaded: ${index.alwaysLoadedCount}`); + console.log(`\n📊 Structure Overview:`); + console.log(` Total Skills: ${index.totalSkills}`); + console.log(` 📁 Categories: ${index.categories}`); + console.log(` 📄 Flat Skills: ${index.flatSkills}`); + console.log(` 📁 Hierarchical: ${index.hierarchicalSkills}`); + console.log(`\n⚡ Loading Strategy:`); + console.log(` Always Loaded: ${index.alwaysLoadedCount}`); console.log(` Deferred: ${index.deferredCount}`); // Calculate token estimates @@ -244,10 +355,20 @@ async function main() { const newTokens = (index.alwaysLoadedCount * avgFullTokens) + (index.deferredCount * avgMinimalTokens); const savings = ((currentTokens - newTokens) / currentTokens * 100).toFixed(1); - console.log(`\n📊 Estimated token impact:`); + console.log(`\n💰 Estimated token impact:`); console.log(` Current: ~${currentTokens.toLocaleString()} tokens`); console.log(` After: ~${newTokens.toLocaleString()} tokens`); console.log(` Savings: ~${savings}%`); + + // Show category breakdown (sorted) + if (index.categories > 0) { + console.log(`\n📂 Category Breakdown:`); + const sortedCategories = Object.keys(index.categoryMap).sort((a, b) => a.localeCompare(b)); + for (const category of sortedCategories) { + const skills = index.categoryMap[category]; + console.log(` ${category}: ${skills.length} skills`); + } + } } main().catch(console.error); diff --git a/.opencode/skills/PAI/Tools/ValidateSkillStructure.ts b/.opencode/skills/PAI/Tools/ValidateSkillStructure.ts new file mode 100644 index 00000000..ffc9d067 --- /dev/null +++ b/.opencode/skills/PAI/Tools/ValidateSkillStructure.ts @@ -0,0 +1,353 @@ +#!/usr/bin/env bun +/** + * ValidateSkillStructure.ts + * + * Validates the skill directory structure for consistency and correctness. + * Run this to check for common issues after reorganizing skills. + * + * Usage: bun run ~/.opencode/skills/PAI/Tools/ValidateSkillStructure.ts + * + * Checks: + * - All skills have valid SKILL.md with frontmatter + * - No orphaned skills (skills without parent category if in hierarchical structure) + * - Category SKILL.md files exist for all categories + * - No duplicate skill names + * - Path consistency + */ + +import { readdir, readFile, stat, realpath } from 'fs/promises'; +import { join, relative, sep } from 'path'; +import { existsSync } from 'fs'; + +const SKILLS_DIR = join(import.meta.dir, '..', '..', '..', 'skills'); + +interface ValidationIssue { + type: 'error' | 'warning'; + path: string; + message: string; +} + +interface ValidationResult { + valid: boolean; + issues: ValidationIssue[]; + stats: { + totalSkills: number; + categories: number; + flatSkills: number; + hierarchicalSkills: number; + errors: number; + warnings: number; + }; +} + +async function validateSkillStructure(): Promise { + const issues: ValidationIssue[] = []; + const skillNames = new Map(); // name -> path (for duplicates) + const categories = new Set(); + const reportedCategories = new Set(); // Track reported missing category SKILL.md + let flatSkills = 0; + let hierarchicalSkills = 0; + + async function scanDirectory(dir: string, depth: number = 0, visitedPaths: Set = new Set()): Promise { + try { + const entries = await readdir(dir, { withFileTypes: true }); + + for (const entry of entries) { + const fullPath = join(dir, entry.name); + + if (entry.isSymbolicLink()) { + try { + const stats = await stat(fullPath); + if (!stats.isDirectory()) continue; + // Valid symlinked directory — check for cycles before recursing + const canonical = await realpath(fullPath); + if (visitedPaths.has(canonical)) { + issues.push({ + type: 'error', + path: fullPath, + message: `Symlink cycle detected: ${fullPath} -> ${canonical}`, + }); + continue; + } + // Will be processed below; canonical path added before recursion + } catch (err) { + // Report broken symlinks as structural errors + issues.push({ + type: 'error', + path: fullPath, + message: `Broken symlink: ${err instanceof Error ? err.message : String(err)}`, + }); + continue; + } + } + + // Determine if directory (including resolved symlinks) + const isDirectory = entry.isSymbolicLink() + ? (await stat(fullPath)).isDirectory() + : entry.isDirectory(); + + if (isDirectory) { + // Skip hidden and node_modules + if (entry.name.startsWith('.') || entry.name === 'node_modules') { + continue; + } + + const skillMdPath = join(fullPath, 'SKILL.md'); + + if (existsSync(skillMdPath)) { + // Found a skill + const relativePath = relative(SKILLS_DIR, fullPath); + const pathParts = relativePath.split(sep); + + if (pathParts.length === 1) { + // Flat skill: skills/SkillName/ + flatSkills++; + await validateSkill(skillMdPath, relativePath, issues, skillNames); + } else if (pathParts.length === 2) { + // Hierarchical skill: skills/Category/SkillName/ + hierarchicalSkills++; + categories.add(pathParts[0]); + await validateSkill(skillMdPath, relativePath, issues, skillNames); + + // Check if category SKILL.md exists (deduplicated reporting) + const categoryPath = join(SKILLS_DIR, pathParts[0]); + const categorySkillPath = join(categoryPath, 'SKILL.md'); + if (!existsSync(categorySkillPath) && !reportedCategories.has(pathParts[0])) { + reportedCategories.add(pathParts[0]); + issues.push({ + type: 'error', + path: categoryPath, + message: `Missing category SKILL.md for "${pathParts[0]}"`, + }); + } + } else if (pathParts.length > 2) { + // Too deep nesting + issues.push({ + type: 'error', + path: fullPath, + message: `Too deep nesting (${pathParts.length} levels). Max: 2 (Category/Skill)`, + }); + } + } else { + // No SKILL.md - might be a category or invalid + if (depth === 0) { + // Could be a category (allowed at top level without SKILL.md if it has subdirs) + await scanDirectory(fullPath, depth + 1, visitedPaths); + continue; // Prevent double recursion + } + } + + // Recurse for subdirectories (only if not already recursed above) + await scanDirectory(fullPath, depth + 1, visitedPaths); + } + } + } catch (error) { + issues.push({ + type: 'error', + path: dir, + message: `Failed to scan directory: ${error}`, + }); + } + } + + await scanDirectory(SKILLS_DIR); + + const errors = issues.filter(i => i.type === 'error').length; + const warnings = issues.filter(i => i.type === 'warning').length; + + return { + valid: errors === 0, + issues, + stats: { + totalSkills: flatSkills + hierarchicalSkills, + categories: categories.size, + flatSkills, + hierarchicalSkills, + errors, + warnings, + }, + }; +} + +async function validateSkill( + skillPath: string, + relativePath: string, + issues: ValidationIssue[], + skillNames: Map +): Promise { + try { + const content = await readFile(skillPath, 'utf-8'); + + // Check frontmatter + const frontmatterMatch = content.match(/^---\r?\n([\s\S]*?)\r?\n---/); + if (!frontmatterMatch) { + issues.push({ + type: 'error', + path: relativePath, + message: 'Missing frontmatter (---)', + }); + return; + } + + const frontmatter = frontmatterMatch[1]; + + // Check name + const nameMatch = frontmatter.match(/^name:\s*(.+)$/m); + if (!nameMatch) { + issues.push({ + type: 'error', + path: relativePath, + message: 'Missing "name" in frontmatter', + }); + } else { + const name = nameMatch[1].trim(); + + // Check for duplicates + if (skillNames.has(name.toLowerCase())) { + issues.push({ + type: 'error', + path: relativePath, + message: `Duplicate skill name "${name}" (also at ${skillNames.get(name.toLowerCase())})`, + }); + } else { + skillNames.set(name.toLowerCase(), relativePath); + } + + // Check name matches directory name (best practice, not required) + const dirName = relativePath.split('/').pop(); + if (dirName && name.toLowerCase() !== dirName.toLowerCase()) { + issues.push({ + type: 'warning', + path: relativePath, + message: `Skill name "${name}" doesn't match directory "${dirName}"`, + }); + } + } + + // Check description (handles both single-line and multi-line YAML with | or >) + const descLineMatch = frontmatter.match(/^description:\s*(.*)$/m); + if (!descLineMatch) { + issues.push({ + type: 'warning', + path: relativePath, + message: 'Missing "description" in frontmatter (needed for triggers)', + }); + } else { + const indicator = descLineMatch[1].trim(); // |, >, |-, >- or empty + let description: string; + + if (indicator === '|' || indicator === '>' || indicator === '|-' || indicator === '>-') { + // Multiline YAML - extract content until next field + const descStart = frontmatter.indexOf(descLineMatch[0]) + descLineMatch[0].length; + const restOfFrontmatter = frontmatter.slice(descStart); + + // Find where next field starts + const nextFieldMatch = restOfFrontmatter.match(/\n([0-9A-Za-z_-]+):/); + const rawDesc = nextFieldMatch + ? restOfFrontmatter.slice(0, nextFieldMatch.index) + : restOfFrontmatter; + + if (indicator === '>' || indicator === '>-') { + // Folded style: newlines become spaces + description = rawDesc.split('\n').map(line => line.trimStart()).join(' ').replace(/\s+/g, ' ').trim(); + } else { + // Literal style: preserve content but remove common indentation + const lines = rawDesc.split('\n').filter(l => l.trim().length > 0); + if (lines.length > 0) { + const minIndent = lines.reduce((min, line) => { + const match = line.match(/^(\s*)/); + const indent = match ? match[1].length : 0; + return Math.min(min, indent); + }, Infinity); + description = lines.map(line => line.slice(minIndent)).join('\n').trim(); + } else { + description = ''; + } + } + } else { + // Single-line description + description = indicator; + } + + if (!description.includes('USE WHEN')) { + issues.push({ + type: 'warning', + path: relativePath, + message: 'Description should contain "USE WHEN" for trigger detection', + }); + } + } + + // Check body content (excluding frontmatter) + const bodyContent = content.replace(/^---\r?\n[\s\S]*?\r?\n---\r?\n?/, '').trim(); + if (bodyContent.length < 50) { + issues.push({ + type: 'warning', + path: relativePath, + message: 'SKILL.md body is very short (< 50 chars)', + }); + } + + } catch (error) { + issues.push({ + type: 'error', + path: relativePath, + message: `Failed to read SKILL.md: ${error}`, + }); + } +} + +async function main() { + console.log('🔍 Validating skill structure...\n'); + + const result = await validateSkillStructure(); + + // Print issues + if (result.issues.length > 0) { + console.log('📋 Issues Found:\n'); + + const errors = result.issues.filter(i => i.type === 'error'); + const warnings = result.issues.filter(i => i.type === 'warning'); + + if (errors.length > 0) { + console.log('❌ Errors:'); + for (const issue of errors) { + console.log(` ${issue.path}`); + console.log(` → ${issue.message}\n`); + } + } + + if (warnings.length > 0) { + console.log('⚠️ Warnings:'); + for (const issue of warnings) { + console.log(` ${issue.path}`); + console.log(` → ${issue.message}\n`); + } + } + } else { + console.log('✅ No issues found!\n'); + } + + // Print stats + console.log('📊 Statistics:'); + console.log(` Total Skills: ${result.stats.totalSkills}`); + console.log(` 📁 Categories: ${result.stats.categories}`); + console.log(` 📄 Flat: ${result.stats.flatSkills}`); + console.log(` 📁 Hierarchical: ${result.stats.hierarchicalSkills}`); + console.log(`\n ❌ Errors: ${result.stats.errors}`); + console.log(` ⚠️ Warnings: ${result.stats.warnings}`); + + // Exit code + if (!result.valid) { + console.log('\n❌ Validation failed. Fix errors above before committing.'); + process.exit(1); + } else { + console.log('\n✅ Validation passed!'); + if (result.stats.warnings > 0) { + console.log(' (Warnings are suggestions, not blockers)'); + } + process.exit(0); + } +} + +main(); diff --git a/.opencode/skills/PrivateInvestigator/SKILL.md b/.opencode/skills/PrivateInvestigator/SKILL.md deleted file mode 100755 index 2b56af5c..00000000 --- a/.opencode/skills/PrivateInvestigator/SKILL.md +++ /dev/null @@ -1,223 +0,0 @@ ---- -name: PrivateInvestigator -description: "Ethical people-finding. USE WHEN find person, locate, reconnect, people search, skip trace. SkillSearch('privateinvestigator') for docs." ---- - -## Customization - -**Before executing, check for user customizations at:** -`~/.opencode/skills/CORE/USER/SKILLCUSTOMIZATIONS/PrivateInvestigator/` - -If this directory exists, load and apply any PREFERENCES.md, configurations, or resources found there. These override default behavior. If the directory does not exist, proceed with skill defaults. - -# PrivateInvestigator - Ethical People Finding - -## Core Principle - -**PUBLIC DATA ONLY** - No hacking, pretexting, or authentication bypass. All techniques are legal and ethical. - - -## Voice Notification - -**When executing a workflow, do BOTH:** - -1. **Send voice notification**: - ```bash - curl -s -X POST http://localhost:8888/notify \ - -H "Content-Type: application/json" \ - -d '{"message": "Running the WORKFLOWNAME workflow from the PrivateInvestigator skill"}' \ - > /dev/null 2>&1 & - ``` - -2. **Output text notification**: - ``` - Running the **WorkflowName** workflow from the **PrivateInvestigator** skill... - ``` - -## Workflow Routing - -**When executing a workflow, output this notification:** -``` -Running the **WorkflowName** workflow from the **PrivateInvestigator** skill... -``` - -## When to Activate - -### Direct People-Finding -- "find [person]", "locate [person]", "search for [person]" -- "reconnect with [person]", "looking for lost contact" -- "find an old friend", "locate a former coworker" - -### Reverse Lookup -- "reverse phone lookup", "who owns this email" -- "reverse image search", "find person by username" - -### Investigation -- "background check" (public data only) -- "what can you find about [person]" -- "research [person]" - -## Available Workflows - -| Trigger | Workflow | Action | -|---------|----------|--------| -| "find person", "locate" | `FindPerson.md` | Full investigation using parallel research agents | -| "social media search" | `SocialMediaSearch.md` | Cross-platform social media investigation | -| "public records" | `PublicRecordsSearch.md` | Government and official records search | -| "reverse lookup" | `ReverseLookup.md` | Phone, email, image, username searches | -| "verify identity" | `VerifyIdentity.md` | Confirm correct person match | - -## Research Strategy - -**MANDATORY: Extensive Parallel Research** - -Every investigation uses **15 parallel research agents** (5 types × 3 each): - -**Agent Types:** -1. **DeepResearcher** (3 agents) - People search aggregators, professional records, location intelligence, comprehensive identity, public records, education/alumni -2. **GeminiResearcher** (3 agents) - Alternative identities, multi-perspective synthesis, historical context -3. **GrokResearcher** (3 agents) - Social media deep search, contrarian analysis, real-time intelligence -4. **CodexResearcher** (3 agents) - Username enumeration, Google dorking, technical profiles - -**Each agent executes 3 sub-searches** = **45 parallel search threads** per investigation - -**Launch Pattern:** All 15 agents launch in a SINGLE message with multiple Task tool calls. - -## Core Capabilities - -### 1. People Search Aggregators -| Service | Type | Best For | -|---------|------|----------| -| TruePeopleSearch | Free | Best free option, fresh data | -| FastPeopleSearch | Free | Basic lookups, no signup | -| Spokeo | Freemium | Social media aggregation (120+ networks) | -| BeenVerified | Paid | Comprehensive background data | - -### 2. Social Media Investigation -- **Facebook:** Google x-ray searches, mutual friends, groups -- **LinkedIn:** Boolean search, alumni networks -- **Instagram/Twitter/TikTok:** Username patterns, cross-platform correlation - -### 3. Public Records -- **Voter Registration:** Most states publicly available -- **Property Records:** County assessor/recorder sites -- **Court Records:** PACER (federal), state court portals, CourtListener -- **Business Filings:** Secretary of State websites -- **Professional Licenses:** State licensing boards - -### 4. Reverse Lookup -- **Phone:** CallerID, NumLookup, carrier lookup -- **Email:** Epieos, Holehe, Hunter.io -- **Image:** PimEyes, TinEye, Google/Yandex Images -- **Username:** Sherlock, WhatsMyName, Namechk - -### 5. Google Dorking -``` -site:linkedin.com "John Smith" "Software Engineer" -site:facebook.com "lives in" "Austin" "marketing" -filetype:pdf resume "Jane Doe" "San Francisco" -``` - -## Investigation Methodology - -### Information Hierarchy - -**Tier 1: Foundation Data** -- Full name (and variations/maiden names) -- Approximate age or date of birth -- Last known location -- Context (school, workplace, relationship) - -**Tier 2: Primary Research** -- People search aggregators -- Social media presence scan -- Google dorking - -**Tier 3: Deep Investigation** -- Public records searches -- Reverse lookups on discovered info -- Cross-platform correlation -- Associate/family network mapping - -**Tier 4: Verification** -- Multi-source confirmation -- Timeline consistency check -- Photo verification -- Confidence scoring - -## Confidence Scoring - -| Level | Criteria | Action | -|-------|----------|--------| -| **HIGH** | 3+ unique identifiers match across independent sources | Safe to contact | -| **MEDIUM** | 2 identifiers match, timeline consistent | Verify before contact | -| **LOW** | Single source or name-only match | Needs more investigation | -| **POSSIBLE** | Partial match, requires verification | Do not act without more data | - -## Dealing with Common Names - -1. **Add Specificity** - Include location, age, employer, school -2. **Cross-Reference** - Match DOB + address patterns across sources -3. **Family Connections** - Verify through known relatives -4. **Timeline Analysis** - Does the life history make sense? -5. **Multiple Identifiers** - Require 3+ matching data points - -## Legal & Ethical Boundaries - -### GREEN ZONE (Allowed) -✅ Search public records (property, court, voter, business) -✅ Access publicly posted social media content -✅ Use people search aggregator sites -✅ Perform reverse lookups on public data -✅ Google dorking with public search operators - -### RED ZONE (Never Cross) -❌ Access data behind login walls without authorization -❌ Bypass authentication or security measures -❌ Use pretexting or impersonation -❌ Access private databases (credit, financial, medical) -❌ Stalk, harass, or intimidate subjects -❌ Access PI-only databases without license - -## When to STOP - -- If the purpose shifts to harassment or stalking -- If the subject has clearly opted out of contact -- If investigation requires illegal methods -- If you suspect the requestor has malicious intent - -## Examples - -**Example 1: Finding an Old College Friend** -``` -User: "Help me find my college roommate from 2005, John Smith from Austin" -→ Routes to FindPerson.md -→ Launches 15 parallel research agents -→ Cross-references people search + LinkedIn alumni + property records -→ Verifies identity through timeline analysis -→ Reports findings with HIGH confidence -``` - -**Example 2: Reverse Phone Lookup** -``` -User: "Who called from 512-555-1234?" -→ Routes to ReverseLookup.md -→ Runs phone through CallerID, NumLookup -→ Cross-references with people search aggregators -→ Reports owner name, location, carrier -``` - -**Example 3: Social Media Investigation** -``` -User: "Find Jane Doe's social media, she's a marketing professional in Denver" -→ Routes to SocialMediaSearch.md -→ LinkedIn Boolean search + Google x-ray -→ Username enumeration if handle discovered -→ Reports all accounts with MEDIUM/HIGH confidence -``` - ---- - -**Related Documentation:** -- Complete workflow details in `Workflows/` directory -- Integration with Research skill for parallel agent orchestration diff --git a/.opencode/skills/PrivateInvestigator/Workflows/FindPerson.md b/.opencode/skills/PrivateInvestigator/Workflows/FindPerson.md deleted file mode 100755 index d978d8cc..00000000 --- a/.opencode/skills/PrivateInvestigator/Workflows/FindPerson.md +++ /dev/null @@ -1,332 +0,0 @@ -# Find Person - Complete Investigation Workflow - -## Voice Notification - -```bash -curl -s -X POST http://localhost:8888/notify \ - -H "Content-Type: application/json" \ - -d '{"message": "Running the FindPerson workflow in the PrivateInvestigator skill to locate individuals"}' \ - > /dev/null 2>&1 & -``` - -Running the **FindPerson** workflow in the **PrivateInvestigator** skill to locate individuals... - -**Purpose:** Systematically locate a person using all available public data sources - -**When to Use:** -- User wants to find a specific person by name -- User wants to reconnect with an old friend, classmate, or contact -- User needs to locate someone for legitimate purposes -- Comprehensive people search is required - -**Prerequisites:** -- Subject's name (ideally full name) -- Any additional context (location, age, workplace, school, how they know them) -- Legitimate purpose for the search - ---- - -## Workflow Steps - -### Step 1: Gather Initial Information - -**Description:** Collect all available starting data from the user - -**Questions to Ask:** -1. What is the person's full name? (including maiden name, nicknames, variations) -2. What is their approximate age or date of birth? -3. Where did you last know them to be located? -4. How do you know this person? (school, work, family, etc.) -5. When did you last have contact? -6. Do you have any old phone numbers, emails, or addresses? -7. Do you know any family members or mutual contacts? -8. Do you have any photos of them? - -**Build Subject Profile:** -``` -Name: [Full name] -Aliases/Variations: [Maiden name, nicknames] -Age/DOB: [Approximate or exact] -Last Known Location: [City, State] -Connection Context: [How user knows them] -Last Contact: [Year/timeframe] -Known Associates: [Family, friends, colleagues] -Additional Identifiers: [Old phone, email, employer, school] -``` - -**Expected Outcome:** Complete subject profile for investigation - ---- - -### Step 2: LAUNCH PARALLEL INVESTIGATION (9+ Agents) - -**CRITICAL: Launch ALL agents in a SINGLE message with multiple Task tool calls** - -This is the main investigation step. Deploy 9+ agents across 3 categories simultaneously. - ---- - -#### CATEGORY 1: People Search Aggregators (3 agents minimum) - -**Agent 1: DeepResearcher - Primary Name Search** -``` -Prompt: Search for [FULL NAME] with these exact spelling variations: [list all]. -Location: [CITY, STATE]. Age approximately [AGE]. -Search TruePeopleSearch, FastPeopleSearch, Spokeo concepts. -Return: current address, phone, relatives, associates, email. -``` - -**Agent 2: DeepResearcher - Comprehensive Search** -``` -Prompt: Comprehensive people search for [NAME] from [LOCATION]. -Try phonetic and ethnic spelling variations of the surname. -Focus on: address history, family tree, employment history. -Return all possible matches with confidence assessment. -``` - -**Agent 3: GeminiResearcher - Alternative Spellings** -``` -Prompt: Find person whose name sounds like [NAME] from [LOCATION]. -The surname is likely Eastern European - try: [variations]. -Search for family members who might have similar surname. -Return any matches with spelling variations that worked. -``` - ---- - -#### CATEGORY 2: Social Media Search (3 agents minimum) - -**Agent 4: DeepResearcher - LinkedIn/Facebook** -``` -Prompt: Search LinkedIn and Facebook for [NAME] from [LOCATION]. -Use Google x-ray: site:linkedin.com/in "[NAME]" "[LOCATION]" -Also search: site:facebook.com "[NAME]" "[SCHOOL/CONTEXT]" -Return profile URLs and any contact information visible. -``` - -**Agent 5: GrokResearcher - Twitter/X Deep Search** -``` -Prompt: Search Twitter/X for [NAME] or username variations. -Try handles like: [firstname][lastname], [first]_[last], etc. -Search for mentions, tagged posts, location-based posts. -Check for any public posts mentioning [LOCATION] or [CONTEXT]. -``` - -**Agent 6: CodexResearcher - Username Enumeration** -``` -Prompt: If we find any username, enumerate across platforms. -Try common patterns: [first][last], [first].[last], [first][last][birthyear] -Conceptually search: Instagram, TikTok, Reddit, GitHub. -Cross-reference any found usernames across platforms. -``` - ---- - -#### CATEGORY 3: Public Records & News (3 agents minimum) - -**Agent 7: DeepResearcher - Property/Voter Records** -``` -Prompt: Search California public records for [NAME]. -Focus on: Alameda County property records, CA voter registration. -Also check neighboring counties: Santa Clara, Contra Costa. -Return any official records with addresses or DOB. -``` - -**Agent 8: GeminiResearcher - Court/Business Records** -``` -Prompt: Search for [NAME] in California court records and business filings. -Check: CA Secretary of State business search, court records. -Look for any legal filings, business registrations, professional licenses. -``` - -**Agent 9: DeepResearcher - News & Mentions** -``` -Prompt: Search for news articles, obituaries, or public mentions of [NAME]. -Check: local Newark/Fremont news archives, alumni mentions. -Search for family members that might lead to subject. -Include any professional or community involvement. -``` - ---- - -**What to Compile from ALL Agent Results:** -- All addresses found (current and historical) -- All phone numbers discovered -- All relatives/associates mentioned -- All social media profiles/URLs -- All official records found -- Best spelling variations that returned results -- Confidence level for each finding - -**Expected Outcome:** Comprehensive parallel search results to synthesize - ---- - -### Step 5: Reverse Lookups on Discovered Info - -**Description:** Use discovered phone/email/username for additional data - -**Invoke:** Read ~/.opencode/skills/PrivateInvestigator/Workflows/ReverseLookup.md - -**For Each Phone Number Found:** -- Run through CallerID, NumLookup -- Cross-reference with people search sites - -**For Each Email Found:** -- Run through Holehe (account discovery) -- Check Hunter.io for company email patterns - -**For Each Username Found:** -- Run through Sherlock or WhatsMyName -- Check for cross-platform usage - -**Expected Outcome:** Additional accounts and verification data - ---- - -### Step 6: Associate Network Mapping - -**Description:** Investigate known relatives and associates for additional leads - -**Actions:** -1. Search each relative/associate name found in Step 2 -2. Check their social media for subject mentions/tags -3. Look for mutual connections on LinkedIn -4. Search for family events (weddings, obituaries) that may mention subject - -**Associate Search Strategy:** -- Parents often have more stable addresses -- Siblings may be connected on social media -- Spouse/partner records may show current address -- Colleagues may have professional network connections - -**Expected Outcome:** Indirect paths to subject through network - ---- - -### Step 7: Verification & Confidence Assessment - -**Description:** Confirm you've found the correct person - -**Invoke:** Read ~/.opencode/skills/PrivateInvestigator/Workflows/VerifyIdentity.md - -**Verification Checklist:** -- [ ] Age/DOB matches expected range -- [ ] Location history makes sense chronologically -- [ ] Family connections match known information -- [ ] Employment/education aligns with context -- [ ] Photos (if available) match known appearance -- [ ] Multiple independent sources confirm same data - -**Confidence Scoring:** -| Score | Criteria | -|-------|----------| -| HIGH | 3+ unique identifiers match from independent sources | -| MEDIUM | 2 identifiers match, timeline consistent | -| LOW | Single source or name-only match | - -**Expected Outcome:** Confidence level for findings - ---- - -### Step 8: Compile Investigation Report - -**Description:** Present findings in structured format - -**Report Template:** -```markdown -# People Search Report: [Subject Name] - -**Search Date:** [Date] -**Requested By:** [User] -**Confidence Level:** [HIGH/MEDIUM/LOW] - -## Subject Profile -- **Name:** [Full name] -- **Age:** [Approximate/confirmed] -- **Last Known Location:** [From original request] - -## Findings - -### Current Contact Information -- **Address:** [Current address if found] -- **Phone:** [Phone numbers found] -- **Email:** [Email addresses found] - -### Social Media Presence -- **LinkedIn:** [URL or "Not found"] -- **Facebook:** [URL or "Not found"] -- **Instagram:** [URL or "Not found"] -- **Other:** [Any additional platforms] - -### Verification Points -- [Point 1 that confirms identity] -- [Point 2 that confirms identity] -- [Point 3 that confirms identity] - -### Investigation Path -1. [Source 1] → [What was found] -2. [Source 2] → [What was found] -3. [Source 3] → [What was found] - -## Confidence Assessment -[Explanation of why confidence level was assigned] - -## Recommended Next Steps -- [Suggested action 1] -- [Suggested action 2] - -## Sources Used -- TruePeopleSearch -- [Other sources] - ---- -*This investigation used only publicly available information* -``` - -**Expected Outcome:** Complete investigation report - ---- - -## Outputs - -**What this workflow produces:** -- Comprehensive subject profile with all discovered information -- Contact information (address, phone, email) if available -- Social media account URLs -- Confidence assessment -- Investigation report - -**Deliverable Format:** -- Markdown report as shown in Step 8 -- All sources documented -- Confidence level clearly stated - ---- - -## Common Challenges - -### Challenge: Common Name -**Solution:** Add specificity - require location + age + additional identifier. See VerifyIdentity.md for detailed guidance. - -### Challenge: No Results in People Search -**Solution:** Try variations (maiden name, nickname), expand location search, focus on social media and public records. - -### Challenge: Subject Appears to Have Intentionally Hidden -**Solution:** Respect their privacy. Report finding to user with ethical guidance about whether to pursue. - -### Challenge: Multiple Possible Matches -**Solution:** Use verification workflow to eliminate candidates based on timeline, family, and corroborating data. - ---- - -## Related Workflows - -- **SocialMediaSearch.md** - Deep dive on social platforms -- **PublicRecordsSearch.md** - Government record searches -- **ReverseLookup.md** - Phone, email, image lookups -- **VerifyIdentity.md** - Confirming correct person - ---- - -**Last Updated:** 2025-11-25 diff --git a/.opencode/skills/PrivateInvestigator/Workflows/PublicRecordsSearch.md b/.opencode/skills/PrivateInvestigator/Workflows/PublicRecordsSearch.md deleted file mode 100755 index 9241e197..00000000 --- a/.opencode/skills/PrivateInvestigator/Workflows/PublicRecordsSearch.md +++ /dev/null @@ -1,328 +0,0 @@ -# Public Records Search Workflow - -## Voice Notification - -```bash -curl -s -X POST http://localhost:8888/notify \ - -H "Content-Type: application/json" \ - -d '{"message": "Running the PublicRecordsSearch workflow in the PrivateInvestigator skill to search records"}' \ - > /dev/null 2>&1 & -``` - -Running the **PublicRecordsSearch** workflow in the **PrivateInvestigator** skill to search records... - -**Purpose:** Search government and official records databases for person information - -**When to Use:** -- User needs official/verified information about a person -- Social media and people search haven't yielded results -- User needs to verify identity through official records -- Property, court, or business records are specifically needed - -**Prerequisites:** -- Subject's full name -- Location (state at minimum) -- Approximate age or DOB (helpful for filtering) - ---- - -## Workflow Steps - -### Step 1: Property Records Search - -**Description:** Real estate ownership is public record in all US states - -**How to Search:** -1. Identify the county where subject lives/lived -2. Find County Assessor or County Recorder website -3. Search by owner name - -**Multi-County Aggregators:** -- **NETR Online:** https://publicrecords.netronline.com - - Links to property records for every US county -- **ParcelQuest (California):** https://parcelquest.com - -**What to Search:** -- Current county of residence -- Previous counties from address history -- Counties where family members own property - -**Information Available:** -- Property address -- Owner name(s) -- Property value/assessment -- Purchase date and price -- Deed history -- Liens and mortgages - -**Expected Outcome:** Current/historical addresses, property ownership confirmation - ---- - -### Step 2: Voter Registration Records - -**Description:** Voter rolls are public in most states (varies by state) - -**State Availability:** - -| Access Level | States | -|--------------|--------| -| **Open Access** | NC, FL, OH, WI, MI, PA, GA (most data public) | -| **Restricted** | CA, NY, TX (limited access/purpose required) | -| **Closed** | Some states don't allow public access | - -**How to Search:** -1. Visit state Secretary of State or Board of Elections website -2. Look for "Voter Registration Lookup" or "Am I Registered?" -3. Search by name + county or DOB - -**Information Available:** -- Full name -- Address -- Date of birth -- Party affiliation (some states) -- Voting history (when they voted, not how) - -**Expected Outcome:** Address confirmation, DOB verification - ---- - -### Step 3: Court Records Search - -**Description:** Civil and criminal court records are generally public - -**Federal Courts - PACER:** -- URL: https://pacer.uscourts.gov -- Registration required -- Fees: $0.10/page (max $3/document), waived if under $30/quarter -- Covers: Federal civil, criminal, bankruptcy, appeals - -**FREE Alternative - CourtListener:** -- URL: https://www.courtlistener.com -- Free access to federal court opinions and filings -- Maintained by Free Law Project - -**State Courts:** -- Search "[State] court records search" for state portal -- Many states have unified case search systems -- Some require county-by-county searching - -**What to Search:** -- Civil cases (lawsuits, divorces, name changes) -- Criminal cases (arrests, convictions) -- Family court (if publicly accessible) -- Bankruptcy filings - -**Information Available:** -- Case parties and addresses -- Case type and status -- Filing dates -- Attorney information -- Some case documents - -**Expected Outcome:** Legal history, name changes, address confirmation from filings - ---- - -### Step 4: Business Registration Records - -**Description:** Business entity filings are public in all states - -**How to Search:** -1. Go to state Secretary of State website -2. Find "Business Entity Search" or "Corporation Search" -3. Search by individual name (as registered agent or officer) - -**Key State Portals:** -- California: https://bizfileonline.sos.ca.gov -- Texas: https://mycpa.cpa.state.tx.us/coa/ -- New York: https://apps.dos.ny.gov/publicInquiry/ -- Florida: https://search.sunbiz.org - -**What to Search:** -- Subject's name as officer/director -- Subject's name as registered agent -- Business names they may be associated with - -**Information Available:** -- Business name and type -- Registered agent name and address -- Officer/director names -- Formation date -- Status (active/inactive) -- Annual reports (some states) - -**Expected Outcome:** Business affiliations, registered agent addresses, professional connections - ---- - -### Step 5: Professional License Search - -**Description:** Licenses for regulated professions are public record - -**Professions to Check:** -- Medical (doctors, nurses, dentists) -- Legal (attorneys) -- Financial (CPAs, financial advisors) -- Real estate (agents, brokers) -- Contractors and trades -- Teachers and educators - -**How to Search:** -1. Identify relevant licensing board for profession -2. Search by name on board's website - -**Multi-State Resources:** -- **Attorneys:** State bar associations have public directories -- **Doctors:** State medical board, also NPDB -- **Real Estate:** ARELLO for national search - -**Example State Portals:** -- California DCA: https://search.dca.ca.gov -- Texas Licensing: Various by profession - -**Information Available:** -- License number and type -- License status (active/expired) -- Address of record -- Disciplinary actions -- Education/training records - -**Expected Outcome:** Professional credentials, business address, disciplinary history - ---- - -### Step 6: Death Records / Obituaries - -**Description:** Confirm if subject is deceased; find family connections - -**Resources:** -- **Social Security Death Index:** Via Ancestry.com or FamilySearch -- **Obituary Search:** Legacy.com, newspapers.com -- **FindAGrave:** https://www.findagrave.com - -**Why Search:** -- Confirm subject is still living -- Find family members mentioned in obituaries -- Identify maiden names or married names - -**Expected Outcome:** Death confirmation or family/associate leads - ---- - -### Step 7: UCC Filings (Liens and Secured Transactions) - -**Description:** Commercial financing records are public - -**How to Search:** -- State Secretary of State UCC search -- Search by debtor name - -**Information Available:** -- Secured party (lender) -- Debtor name and address -- Collateral described -- Filing date - -**When Useful:** -- Looking for someone with business assets -- Verifying financial relationships -- Finding registered addresses - -**Expected Outcome:** Business addresses, financial relationships - ---- - -### Step 8: Compile Public Records Findings - -**Description:** Organize all discovered official records - -**Report Template:** -```markdown -## Public Records Report: [Subject Name] - -### Property Records -| County | Address | Owner Name | Purchase Date | -|--------|---------|------------|---------------| -| [County] | [Address] | [Name] | [Date] | - -### Voter Registration -- **State:** [State] -- **Address:** [Address] -- **DOB:** [If available] -- **Status:** [Active/Inactive] - -### Court Records -| Court | Case Type | Case Number | Status | -|-------|-----------|-------------|--------| -| [Court] | [Type] | [Number] | [Status] | - -### Business Affiliations -| Business Name | Role | State | Status | -|---------------|------|-------|--------| -| [Business] | [Officer/Agent] | [State] | [Active] | - -### Professional Licenses -| License Type | Number | Status | State | -|--------------|--------|--------|-------| -| [Type] | [Number] | [Active/Expired] | [State] | - -### Verification Summary -- Official records confirm address at: [Address] -- DOB confirmed/estimated: [DOB] -- Professional status: [Description] -``` - -**Expected Outcome:** Comprehensive public records summary - ---- - -## State-Specific Notes - -### California -- Strong privacy protections -- Voter data restricted -- Good business entity search -- DCA license lookup comprehensive - -### Texas -- More open public records -- Good business entity portal -- County-by-county for many records - -### Florida -- Very open public records (Sunshine Law) -- Voter data readily accessible -- Court records widely available online - -### New York -- Moderate access -- Good court records system (eCourts) -- Business entity search available - ---- - -## Outputs - -**What this workflow produces:** -- Verified addresses from official sources -- DOB confirmation -- Legal history overview -- Business affiliations -- Professional credentials - -**Quality Notes:** -- Official records provide highest confidence data -- Cross-reference with people search results -- Note date of records (may be outdated) - ---- - -## Related Workflows - -- **FindPerson.md** - Full investigation workflow -- **VerifyIdentity.md** - Using records for verification - ---- - -**Last Updated:** 2025-11-25 diff --git a/.opencode/skills/PrivateInvestigator/Workflows/ReverseLookup.md b/.opencode/skills/PrivateInvestigator/Workflows/ReverseLookup.md deleted file mode 100755 index 309e10c2..00000000 --- a/.opencode/skills/PrivateInvestigator/Workflows/ReverseLookup.md +++ /dev/null @@ -1,383 +0,0 @@ -# Reverse Lookup Workflow - -## Voice Notification - -```bash -curl -s -X POST http://localhost:8888/notify \ - -H "Content-Type: application/json" \ - -d '{"message": "Running the ReverseLookup workflow in the PrivateInvestigator skill to trace identifiers"}' \ - > /dev/null 2>&1 & -``` - -Running the **ReverseLookup** workflow in the **PrivateInvestigator** skill to trace identifiers... - -**Purpose:** Identify a person from partial information (phone, email, image, username) - -**When to Use:** -- User has a phone number and wants to know who it belongs to -- User has an email and wants to find the person -- User has a photo and wants to identify the person -- User has a username and wants to find the real identity -- Any "reverse" search scenario - -**Prerequisites:** -- At least one identifier (phone, email, image, username) -- Legitimate purpose for the search - ---- - -## Reverse Phone Lookup - -### Step 1: Free Phone Lookup Services - -**CallerID Test:** -- URL: https://calleridtest.com -- Enter phone number -- Returns: Name, carrier, location - -**NumLookup:** -- URL: https://www.numlookup.com -- Free carrier and location lookup -- Limited name information - -**USPhoneBook:** -- URL: https://www.usphonebook.com -- Free reverse phone search -- Shows name, address, relatives - -### Step 2: People Search Aggregator Reverse Lookup - -**TruePeopleSearch:** -- Has reverse phone lookup feature -- Enter number in search -- Often provides full contact record - -**That's Them:** -- URL: https://thatsthem.com -- Reverse phone feature -- Shows associated names and addresses - -### Step 3: Additional Phone Research - -**Check Carrier Type:** -- Mobile vs. landline -- VoIP (may be harder to trace) -- Prepaid (limited registration data) - -**Search Phone Number in Google:** -``` -"512-555-1234" -"5125551234" -``` -May find: -- Business listings -- Online classified ads -- Public posts with number - -**Check Whitepages/Yellow Pages:** -- Landlines especially -- Business associations - -### Phone Lookup Output: -```markdown -## Reverse Phone Results: [Phone Number] - -**Carrier:** [Carrier name] -**Type:** [Mobile/Landline/VoIP] -**Location:** [City, State] - -**Associated Names:** -- [Name 1] - [Confidence level] -- [Name 2] - [Confidence level] - -**Associated Addresses:** -- [Address 1] -- [Address 2] - -**Sources Checked:** -- CallerID Test -- NumLookup -- TruePeopleSearch -- Google search -``` - ---- - -## Reverse Email Lookup - -### Step 1: Email Account Discovery with Holehe - -**Tool:** Holehe (checks 120+ services) -```bash -# Install -pip install holehe - -# Run -holehe target@example.com -``` - -**Output Shows:** -- Services where email is registered -- Social media accounts -- Dating sites -- Forums and communities - -### Step 2: Epieos Email Lookup - -**URL:** https://epieos.com -**Features:** -- Links email to social accounts -- Shows Google account info (name, photo) -- Breach data associations - -### Step 3: Hunter.io - -**URL:** https://hunter.io -**Best For:** -- Corporate email patterns -- Finding all emails at a domain -- Verifying email validity - -**Use Case:** If you have company domain, can find other employees and patterns - -### Step 4: Google the Email - -``` -"target@example.com" -``` - -**May Find:** -- Forum posts -- Public profiles -- Documents with email listed -- Business directories - -### Step 5: Check Social Media Registration - -Manually check if email might be used for: -- Facebook (via forgot password - shows partial email) -- LinkedIn -- Twitter -- Instagram - -**Note:** Do not attempt to reset passwords or gain access - -### Email Lookup Output: -```markdown -## Reverse Email Results: [Email] - -**Email Provider:** [Gmail/Yahoo/Corporate] -**Validity:** [Valid/Invalid/Catch-all] - -**Linked Accounts (Holehe):** -- [Service 1]: Registered -- [Service 2]: Registered -- [Service 3]: Not found - -**Google Account Info (Epieos):** -- Name: [If available] -- Photo: [If available] - -**Other Findings:** -- [Any forum posts, profiles, etc.] -``` - ---- - -## Reverse Image Search - -### Step 1: Google Images - -**URL:** https://images.google.com -**Method:** -- Click camera icon -- Upload image or paste URL -- Review matching images - -**Best For:** Finding image across websites, identifying public figures - -### Step 2: TinEye - -**URL:** https://tineye.com -**Features:** -- 79.5+ billion indexed images -- Shows where image appears online -- Finds modified versions of image -- Sort by oldest (find original source) - -**Best For:** Finding image origin, detecting photo manipulation - -### Step 3: Yandex Images - -**URL:** https://yandex.com/images -**Features:** -- Excellent for faces -- Strong European/Russian coverage -- Often finds what Google misses - -**Best For:** Face matching, Eastern European sources - -### Step 4: PimEyes (Paid) - -**URL:** https://pimeyes.com -**Features:** -- Dedicated facial recognition -- Billions of indexed faces -- Finds social media profiles - -**Legal Note:** Verify legality in your jurisdiction; some areas restrict facial recognition - -### Step 5: FaceCheck.id - -**URL:** https://facecheck.id -**Features:** -- Alternative to PimEyes -- Social media focused -- Browser extension available - -### Image Search Output: -```markdown -## Reverse Image Results - -**Image Analyzed:** [Description/filename] - -**Google Images:** -- [Number] results found -- Key matches: [URLs] - -**TinEye:** -- [Number] results -- Oldest source: [URL, date] - -**Yandex:** -- [Number] face matches -- Notable matches: [URLs] - -**Identified Person:** -- Name: [If determined] -- Confidence: [HIGH/MEDIUM/LOW] -- Source: [How determined] -``` - ---- - -## Reverse Username Search - -### Step 1: Sherlock (Command Line) - -```bash -# Install -pip install sherlock-project - -# Run -sherlock target_username --print-found - -# Output to file -sherlock target_username -o results.txt -``` - -**Checks 400+ platforms** for username registration - -### Step 2: WhatsMyName (Web) - -**URL:** https://whatsmyname.app -**Features:** -- Web-based alternative to Sherlock -- Hundreds of sites checked -- Shows direct profile URLs - -### Step 3: Namechk - -**URL:** https://namechk.com -**Features:** -- Quick availability check -- Major platforms covered -- Social and domain availability - -### Step 4: Search Username in Google - -``` -"target_username" -inurl:"target_username" -``` - -**May Find:** -- Profiles not in database -- Forum posts -- Comments on websites -- Code repositories - -### Step 5: Check Common Patterns - -If you found one username, try variations: -- target_username → targetusername → target.username -- target_username1 → target_username2 -- Check if matches real name pattern - -### Username Lookup Output: -```markdown -## Reverse Username Results: [username] - -**Platforms Found (Sherlock):** -| Platform | URL | Status | -|----------|-----|--------| -| GitHub | github.com/[username] | Found | -| Instagram | instagram.com/[username] | Found | -| Reddit | reddit.com/u/[username] | Not Found | - -**Profile Analysis:** -- Most active: [Platform] -- Consistent identity: [Yes/No] -- Real name indicators: [Any found] - -**Cross-Reference:** -- Email pattern: [If discovered] -- Location indicators: [From bios] -- Other usernames used: [Variations found] -``` - ---- - -## Outputs - -**What this workflow produces:** -- Identity information from partial identifier -- Associated accounts and profiles -- Cross-reference data for verification -- Confidence assessment - -**Deliverable Format:** -- Structured report per identifier type -- All sources documented -- Confidence level stated - ---- - -## API Options (For Automation) - -### Phone APIs: -| Provider | Cost | Notes | -|----------|------|-------| -| Telnyx | $0.003/query | Carrier, LRN | -| Twilio Lookup | $0.02/query | Name, carrier | -| NumVerify | Free tier | Basic validation | - -### Email APIs: -| Provider | Cost | Notes | -|----------|------|-------| -| Hunter.io | $49+/mo | Verification + discovery | -| FullContact | Enterprise | Identity enrichment | - -### Use Apify MCP for social scraping automation - ---- - -## Related Workflows - -- **FindPerson.md** - Full investigation workflow -- **SocialMediaSearch.md** - After identifying username -- **VerifyIdentity.md** - Confirming findings - ---- - -**Last Updated:** 2025-11-25 diff --git a/.opencode/skills/PrivateInvestigator/Workflows/SocialMediaSearch.md b/.opencode/skills/PrivateInvestigator/Workflows/SocialMediaSearch.md deleted file mode 100755 index 3bf41a3b..00000000 --- a/.opencode/skills/PrivateInvestigator/Workflows/SocialMediaSearch.md +++ /dev/null @@ -1,345 +0,0 @@ -# Social Media Search Workflow - -## Voice Notification - -```bash -curl -s -X POST http://localhost:8888/notify \ - -H "Content-Type: application/json" \ - -d '{"message": "Running the SocialMediaSearch workflow in the PrivateInvestigator skill to find profiles"}' \ - > /dev/null 2>&1 & -``` - -Running the **SocialMediaSearch** workflow in the **PrivateInvestigator** skill to find profiles... - -**Purpose:** Systematically search social media platforms to find a person's online presence - -**When to Use:** -- User specifically wants to find someone's social media accounts -- Main investigation needs social media component -- User wants to verify someone's online presence -- Cross-platform correlation is needed - -**Prerequisites:** -- Subject's full name -- Any known usernames, handles, or email addresses -- Location and/or age for filtering -- Context (profession, interests) for verification - ---- - -## Workflow Steps - -### Step 1: LinkedIn Search (Professional Presence) - -**Description:** LinkedIn is often the most reliable for professionals - -**Method 1: Direct LinkedIn Search** -- Use LinkedIn's search bar with name -- Filter by: Location, Company, School, Industry -- Note: Limited results without Premium - -**Method 2: Google X-Ray (Recommended)** -``` -site:linkedin.com/in "[Full Name]" "[City]" -site:linkedin.com/in "[Full Name]" "[Company Name]" -site:linkedin.com/in "[Full Name]" "[University]" -``` - -**Method 3: Alumni Search** -- If you share a school, use LinkedIn Alumni feature -- Filter by graduation year and major - -**What to Record:** -- Profile URL -- Current employer and title -- Location -- Education history -- Connection count (for verification) - -**Expected Outcome:** LinkedIn profile URL and professional details - ---- - -### Step 2: Facebook Search - -**Description:** Most extensive personal network data - -**Method 1: Google X-Ray (Bypasses Facebook Limitations)** -``` -site:facebook.com "[Full Name]" "[City]" -site:facebook.com "[Full Name]" "[School]" -site:facebook.com "[Full Name]" "[Employer]" -``` - -**Method 2: Facebook Direct Search** -- Search by name in Facebook search bar -- Filter by: Location, Education, Workplace -- Check "People" tab specifically - -**Method 3: Mutual Friends** -- If you have mutual friends, check their friend lists -- Look for tagged photos and mentions - -**Advanced Techniques:** -- Search for family member profiles, then check their friends -- Look for group memberships (alumni groups, local groups) -- Check public events they may have RSVP'd to - -**What to Record:** -- Profile URL -- Profile photo (for verification) -- Location listed -- Mutual friends if any -- Public posts/check-ins - -**Expected Outcome:** Facebook profile URL and personal details - ---- - -### Step 3: Instagram Search - -**Description:** Visual platform, often shows current lifestyle - -**Method 1: Direct Search** -- Search by name in Instagram -- Search by username variations - -**Method 2: Google X-Ray** -``` -site:instagram.com "[Full Name]" -site:instagram.com "[Username]" -``` - -**Method 3: Username Pattern Matching** -Common username patterns to try: -- firstname.lastname -- firstnamelastname -- firstinitial.lastname -- firstname_lastname -- lastname.firstname - -**Method 4: Location/Hashtag Search** -- Search location tags in their city -- Search hashtags related to their profession/interests - -**What to Record:** -- Username and profile URL -- Bio information -- Location tags in posts -- Cross-references to other platforms - -**Expected Outcome:** Instagram handle and profile details - ---- - -### Step 4: Twitter/X Search - -**Description:** Public commentary and professional presence - -**Method 1: X Advanced Search** -``` -from:username - Search specific user's tweets -"[Full Name]" - Search mentions -near:"[City]" within:15mi - Location filter -``` - -**Method 2: Google X-Ray** -``` -site:twitter.com "[Full Name]" -site:x.com "[Full Name]" -``` - -**Method 3: Username Search** -- Try same username patterns as Instagram -- Check if username from other platforms exists on X - -**What to Record:** -- Handle and profile URL -- Bio and location in profile -- Website links in bio -- Tweet activity level - -**Expected Outcome:** X/Twitter handle and public profile - ---- - -### Step 5: TikTok Search - -**Description:** Increasingly important for younger demographics - -**Method 1: Direct Search** -- Search by name or username in TikTok -- Check "Users" tab in search results - -**Method 2: Google X-Ray** -``` -site:tiktok.com/@"[username]" -site:tiktok.com "[Full Name]" -``` - -**Method 3: Cross-Platform Username** -- Try usernames found on other platforms - -**What to Record:** -- Username and profile URL -- Bio information -- Content themes (helps verify correct person) - -**Expected Outcome:** TikTok profile if exists - ---- - -### Step 6: Username Enumeration - -**Description:** If you found a username, check across 400+ platforms - -**Tool: Sherlock (Command Line)** -```bash -# Install if needed -pip install sherlock-project - -# Run enumeration -sherlock [username] --print-found -``` - -**Alternative: WhatsMyName (Web)** -- URL: https://whatsmyname.app -- Enter discovered username -- Returns all platforms where username exists - -**Alternative: Namechk** -- URL: https://namechk.com -- Quick availability check across major platforms - -**What to Record:** -- All platforms where username is claimed -- Which accounts appear active -- Profile consistency across platforms - -**Expected Outcome:** Complete cross-platform presence map - ---- - -### Step 7: Email Account Discovery - -**Description:** Find which services are associated with known email - -**Tool: Holehe** -```bash -# Install -pip install holehe - -# Run -holehe email@example.com -``` - -Checks 120+ websites for account existence without sending notification. - -**Alternative: Epieos** -- URL: https://epieos.com -- Enter email address -- Returns linked accounts and breach data - -**What to Record:** -- Services where email is registered -- Social accounts linked to email -- Any Google account info - -**Expected Outcome:** Services associated with email address - ---- - -### Step 8: Cross-Reference and Verify - -**Description:** Confirm all found accounts belong to same person - -**Verification Points:** -1. **Photo Consistency:** Do profile photos match across platforms? -2. **Bio Consistency:** Similar job titles, locations, descriptions? -3. **Connection Overlap:** Do friends/followers overlap? -4. **Content Themes:** Similar interests and posting patterns? -5. **Timeline Consistency:** Does activity timeline make sense? - -**Red Flags (May Be Wrong Person):** -- Drastically different photos -- Conflicting locations/ages -- No connection overlap with known associates -- Different professional background - -**Expected Outcome:** Confidence level for each account - ---- - -## Outputs - -**What this workflow produces:** -- List of all discovered social media accounts -- Username patterns identified -- Profile URLs for each platform -- Verification confidence for each account - -**Report Format:** -```markdown -## Social Media Presence: [Subject Name] - -### Confirmed Accounts (HIGH Confidence) -| Platform | URL | Username | Verified By | -|----------|-----|----------|-------------| -| LinkedIn | [URL] | [username] | Photo + employer match | -| Facebook | [URL] | [username] | Mutual friends + location | - -### Probable Accounts (MEDIUM Confidence) -| Platform | URL | Username | Notes | -|----------|-----|----------|-------| -| Instagram | [URL] | [username] | Same username, location matches | - -### Possible Accounts (LOW Confidence) -| Platform | URL | Username | Notes | -|----------|-----|----------|-------| -| Twitter | [URL] | [username] | Common name, needs verification | - -### Username Patterns -- Primary pattern: [firstname.lastname] -- Found on: LinkedIn, Instagram, GitHub -``` - ---- - -## Platform-Specific Notes - -### LinkedIn -- Most reliable for professionals 30+ -- Limited search without Premium -- Google x-ray works better than native search - -### Facebook -- Privacy settings vary widely -- Check "About" section for contact info -- Friends list often more revealing than profile - -### Instagram -- May be private account -- Stories/highlights visible even if posts hidden -- Location tags are goldmine - -### Twitter/X -- Usually public by default -- Check replies and quote tweets -- Bio links often lead to other platforms - -### TikTok -- Younger demographics -- Username often matches other platforms -- Comments may reveal real name - ---- - -## Related Workflows - -- **FindPerson.md** - Full investigation workflow -- **ReverseLookup.md** - Reverse email/username lookup -- **VerifyIdentity.md** - Confirming correct person - ---- - -**Last Updated:** 2025-11-25 diff --git a/.opencode/skills/PrivateInvestigator/Workflows/VerifyIdentity.md b/.opencode/skills/PrivateInvestigator/Workflows/VerifyIdentity.md deleted file mode 100755 index 8d602bf5..00000000 --- a/.opencode/skills/PrivateInvestigator/Workflows/VerifyIdentity.md +++ /dev/null @@ -1,352 +0,0 @@ -# Verify Identity Workflow - -## Voice Notification - -```bash -curl -s -X POST http://localhost:8888/notify \ - -H "Content-Type: application/json" \ - -d '{"message": "Running the VerifyIdentity workflow in the PrivateInvestigator skill to confirm identity"}' \ - > /dev/null 2>&1 & -``` - -Running the **VerifyIdentity** workflow in the **PrivateInvestigator** skill to confirm identity... - -**Purpose:** Confirm that discovered information belongs to the correct person - -**When to Use:** -- User has common name problem (multiple possible matches) -- User wants to verify findings before making contact -- User needs confidence assessment on investigation results -- Multiple candidates need to be narrowed down - -**Prerequisites:** -- Initial investigation completed -- One or more potential matches identified -- Original subject profile for comparison - ---- - -## Workflow Steps - -### Step 1: Establish Verification Criteria - -**Description:** Define what unique identifiers we have for matching - -**Build Comparison Framework:** - -| Identifier | Original (Known) | Candidate | Match? | -|------------|------------------|-----------|--------| -| Full Name | [Known name] | [Found name] | | -| Age/DOB | [Known/estimated] | [Found] | | -| Last Known Location | [Known city/state] | [Found] | | -| School | [If known] | [If found] | | -| Employer | [If known] | [If found] | | -| Family Members | [If known] | [If found] | | -| Physical Description | [If known] | [Photo] | | - -**Minimum for Confirmation:** -- 3+ independent matches for HIGH confidence -- 2 matches with logical timeline for MEDIUM confidence -- 1 match only = LOW confidence (needs more research) - -**Expected Outcome:** Clear criteria for evaluation - ---- - -### Step 2: Timeline Consistency Check - -**Description:** Verify the life timeline makes logical sense - -**Timeline Analysis:** -1. **Birth Year:** Does approximate age match? -2. **Education Timeline:** - - High school graduation ~18 years old - - College graduation ~22 years old - - Do dates align with age? -3. **Career Timeline:** - - Does employment history flow logically? - - Are there unexplained gaps? -4. **Location Timeline:** - - Do address changes make sense? - - Can you trace the path from last known to current? - -**Red Flags:** -- Age doesn't match graduation dates -- Lives in location that doesn't fit history -- Career path doesn't match known profession -- Unexplainable timeline gaps - -**Expected Outcome:** Timeline validation or concerns noted - ---- - -### Step 3: Family/Associate Verification - -**Description:** Cross-reference through known connections - -**Verification Steps:** -1. If you know subject's family members: - - Search for those family members - - Check if candidate is connected to same family -2. If people search shows relatives: - - Do relative names match any known family? - - Are relative ages appropriate (parents older, siblings similar)? -3. Social media connections: - - Do mutual friends match expected network? - - Are they connected to people from known history? - -**Strong Verification:** -- Candidate is listed as relative of known family member -- Mutual friends include known associates -- Social media shows interaction with known people - -**Expected Outcome:** Family/network verification result - ---- - -### Step 4: Photo Verification - -**Description:** Compare photos across sources - -**Visual Comparison:** -1. Collect photos from all discovered sources -2. Compare for consistency: - - Same person across platforms? - - Age-appropriate for expected age? - - Any distinguishing features match? - -**Photo Analysis Points:** -- Facial structure consistency -- Approximate age in photos -- Background clues (location, activities) -- Metadata if available (date, location) - -**Tools for Comparison:** -- PimEyes (paid) - facial recognition search -- Manual comparison across found profiles -- Google reverse image search on profile photos - -**If No Photos Available:** -- Rely on other verification methods -- Note as limitation in confidence assessment - -**Expected Outcome:** Photo verification result or limitation noted - ---- - -### Step 5: Cross-Source Verification - -**Description:** Confirm data appears in multiple independent sources - -**Verification Matrix:** - -| Data Point | Source 1 | Source 2 | Source 3 | Consistent? | -|------------|----------|----------|----------|-------------| -| Name | [Source] | [Source] | [Source] | Yes/No | -| Address | [Source] | [Source] | [Source] | Yes/No | -| Age/DOB | [Source] | [Source] | [Source] | Yes/No | -| Phone | [Source] | [Source] | [Source] | Yes/No | -| Email | [Source] | [Source] | [Source] | Yes/No | - -**Independence Requirement:** -- Sources should be truly independent -- People search sites often pull from same databases (count as 1 source) -- Best independent sources: - - Social media (they created it) - - Public records (government verified) - - Different people search aggregators with different data sources - -**Expected Outcome:** Cross-source verification matrix - ---- - -### Step 6: Common Name Disambiguation - -**Description:** Special handling for very common names - -**For Common Names (John Smith, etc.):** - -1. **Require More Identifiers:** - - Full DOB, not just age - - Middle name or initial - - Specific location history - - Unique employment/education - -2. **Elimination Strategy:** - - List all candidates found - - Eliminate based on age mismatch - - Eliminate based on location impossibility - - Eliminate based on profession mismatch - -3. **Differentiation Points:** - - Unique middle name - - Specific employer - - Exact graduation year - - Distinctive family names - -4. **When Uncertain:** - - Report all viable candidates - - Provide distinguishing factors for each - - Let user determine based on additional knowledge - -**Expected Outcome:** Single candidate or ranked candidates with differentiators - ---- - -### Step 7: Calculate Confidence Score - -**Description:** Assign formal confidence level to findings - -**Scoring Criteria:** - -**HIGH Confidence (Safe to Act On):** -- 3+ unique identifiers match from independent sources -- Timeline is fully consistent -- Family/network verification positive -- Photo verification (if applicable) positive -- No red flags or contradictions - -**MEDIUM Confidence (Verify Before Acting):** -- 2 identifiers match -- Timeline is generally consistent -- Some network verification -- Minor inconsistencies explainable - -**LOW Confidence (Needs More Research):** -- Single source confirmation -- Some timeline questions -- Limited verification options -- Common name with limited differentiation - -**UNCONFIRMED (Do Not Act):** -- Name match only -- Contradictory information -- Cannot differentiate from other candidates -- Significant timeline problems - -**Expected Outcome:** Confidence score with justification - ---- - -### Step 8: Generate Verification Report - -**Description:** Document verification analysis - -**Report Template:** - -```markdown -# Identity Verification Report - -## Subject -**Original Profile:** -- Name: [Known name] -- Age/DOB: [Known/estimated] -- Last Known Location: [City, State] -- Context: [How user knows them] - -## Candidate Evaluated -**Discovered Profile:** -- Name: [Found name] -- Age/DOB: [Found] -- Current Location: [Found] -- Sources: [List sources] - -## Verification Analysis - -### Timeline Check -[Analysis of timeline consistency] -**Result:** [Consistent/Minor Issues/Major Concerns] - -### Family/Network Verification -[Analysis of family and connection matches] -**Result:** [Verified/Partial/Unverified] - -### Photo Verification -[Analysis of photo comparison, if available] -**Result:** [Match/Possible Match/No Photos Available] - -### Cross-Source Verification -| Data Point | Sources Confirming | Consistent | -|------------|-------------------|------------| -| [Point] | [Count] | [Yes/No] | - -### Common Name Analysis -[If applicable - how candidate was differentiated] - -## Confidence Assessment - -**Final Confidence Level:** [HIGH/MEDIUM/LOW/UNCONFIRMED] - -**Justification:** -1. [Reason 1] -2. [Reason 2] -3. [Reason 3] - -**Limitations:** -- [Any gaps in verification] -- [Information not available] - -## Recommendation - -[Whether it's safe to proceed with contact/action] - ---- -*Verification completed: [Date]* -``` - -**Expected Outcome:** Complete verification report - ---- - -## Outputs - -**What this workflow produces:** -- Formal confidence score (HIGH/MEDIUM/LOW/UNCONFIRMED) -- Verification analysis across multiple dimensions -- Clear recommendation on whether to proceed -- Documentation of verification methodology - -**Confidence Level Meanings:** - -| Level | Meaning | Action | -|-------|---------|--------| -| HIGH | Very likely correct person | Safe to proceed with contact | -| MEDIUM | Probably correct | Proceed with caution; soft verification first | -| LOW | Possibly correct | Need more information before action | -| UNCONFIRMED | Cannot verify | Do not act; need additional investigation | - ---- - -## Special Cases - -### Case: Married Name Change -- Search both maiden and married names -- Check marriage records -- Look for social media with relationship status changes - -### Case: Deceased Subject -- Check Social Security Death Index -- Search obituaries -- Verify with family before continued search - -### Case: Privacy-Conscious Subject -- Limited online presence may be intentional -- Consider whether to respect their privacy choices -- Focus on public records if legitimate need - -### Case: Multiple Candidates Remain -- Present all candidates with differentiating factors -- Ask user for additional information to narrow down -- Do not guess if truly uncertain - ---- - -## Related Workflows - -- **FindPerson.md** - Full investigation workflow -- **SocialMediaSearch.md** - For additional verification data -- **PublicRecordsSearch.md** - For official record verification - ---- - -**Last Updated:** 2025-11-25 diff --git a/.opencode/skills/Remotion/ArtIntegration.md b/.opencode/skills/Remotion/ArtIntegration.md deleted file mode 100644 index fa676c30..00000000 --- a/.opencode/skills/Remotion/ArtIntegration.md +++ /dev/null @@ -1,95 +0,0 @@ -# Art Skill Integration - -**MANDATORY:** This skill inherits visual theming from the Art skill. - -## Before Creating Any Video Content - -1. **Load Art preferences:** - ``` - ~/.opencode/skills/PAI/USER/SKILLCUSTOMIZATIONS/Art/PREFERENCES.md - ``` - -2. **Apply the PAI Theme** derived from Art preferences: - -| Art Preference | Remotion Application | -|----------------|---------------------| -| Core aesthetic (charcoal architectural) | Dark backgrounds, sketch-like feel | -| Primary accent (purple/violet) | Accent colors, highlights, CTAs | -| Cool atmospheric washes | Background gradients, overlays | -| Paper ground (#F5F5F0) | Light text, subtle backgrounds | -| Human-scale in vast spaces | Typography hierarchy, spacing | - -3. **Use Theme Constants:** - ``` - ~/.opencode/skills/Remotion/Tools/Theme.ts - ``` - -4. **Reference images** (when visual style reference needed): - ``` - ~/.opencode/skills/Art/Examples/ - ``` - -## PAI Theme Quick Reference - -```typescript -import { PAI_THEME } from '~/.opencode/skills/Remotion/Tools/Theme' - -// Colors -PAI_THEME.colors.background // #0f172a - Deep slate -PAI_THEME.colors.accent // #8b5cf6 - Purple/violet -PAI_THEME.colors.text // #f1f5f9 - Light text -PAI_THEME.colors.textMuted // #94a3b8 - Muted text - -// Typography -PAI_THEME.typography.title // { fontSize: 72, fontWeight: 'bold' } -PAI_THEME.typography.subtitle // { fontSize: 36 } -PAI_THEME.typography.body // { fontSize: 24 } - -// Animation -PAI_THEME.animation.springDefault // { damping: 12, stiffness: 100 } -PAI_THEME.animation.fadeFrames // 30 frames (~1 second) -PAI_THEME.animation.staggerDelay // 10 frames - -// Spacing -PAI_THEME.spacing.page // 100px edge padding -PAI_THEME.spacing.section // 60px between sections -PAI_THEME.spacing.element // 30px between elements -``` - -## Using the Theme in Components - -```typescript -import { PAI_THEME, titleScreenStyle, fadeInterpolation } from '~/.opencode/skills/Remotion/Tools/Theme' - -export const MyScene: React.FC = () => { - const frame = useCurrentFrame() - const { fps } = useVideoConfig() - - const opacity = interpolate( - frame, - fadeInterpolation().inputRange, - fadeInterpolation().outputRange, - { extrapolateRight: 'clamp' } - ) - - const scale = spring({ - frame, fps, - config: PAI_THEME.animation.springDefault - }) - - return ( - -

- Title Here -

-
- ) -} -``` - -**All videos MUST use this theme unless explicitly overridden.** diff --git a/.opencode/skills/Remotion/CriticalRules.md b/.opencode/skills/Remotion/CriticalRules.md deleted file mode 100644 index 80d72fe4..00000000 --- a/.opencode/skills/Remotion/CriticalRules.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -name: remotion-best-practices -description: Best practices for Remotion - Video creation in React -metadata: - tags: remotion, video, react, animation, composition ---- - -## When to use - -Use this skills whenever you are dealing with Remotion code to obtain the domain-specific knowledge. - -## How to use - -Read individual rule files for detailed explanations and code examples: - -- [rules/3d.md](rules/3d.md) - 3D content in Remotion using Three.js and React Three Fiber -- [rules/animations.md](rules/animations.md) - Fundamental animation skills for Remotion -- [rules/assets.md](rules/assets.md) - Importing images, videos, audio, and fonts into Remotion -- [rules/audio.md](rules/audio.md) - Using audio and sound in Remotion - importing, trimming, volume, speed, pitch -- [rules/calculate-metadata.md](rules/calculate-metadata.md) - Dynamically set composition duration, dimensions, and props -- [rules/can-decode.md](rules/can-decode.md) - Check if a video can be decoded by the browser using Mediabunny -- [rules/charts.md](rules/charts.md) - Chart and data visualization patterns for Remotion -- [rules/compositions.md](rules/compositions.md) - Defining compositions, stills, folders, default props and dynamic metadata -- [rules/display-captions.md](rules/display-captions.md) - Displaying captions in Remotion with TikTok-style pages and word highlighting -- [rules/extract-frames.md](rules/extract-frames.md) - Extract frames from videos at specific timestamps using Mediabunny -- [rules/fonts.md](rules/fonts.md) - Loading Google Fonts and local fonts in Remotion -- [rules/get-audio-duration.md](rules/get-audio-duration.md) - Getting the duration of an audio file in seconds with Mediabunny -- [rules/get-video-dimensions.md](rules/get-video-dimensions.md) - Getting the width and height of a video file with Mediabunny -- [rules/get-video-duration.md](rules/get-video-duration.md) - Getting the duration of a video file in seconds with Mediabunny -- [rules/gifs.md](rules/gifs.md) - Displaying GIFs synchronized with Remotion's timeline -- [rules/images.md](rules/images.md) - Embedding images in Remotion using the Img component -- [rules/import-srt-captions.md](rules/import-srt-captions.md) - Importing .srt subtitle files into Remotion using @remotion/captions -- [rules/lottie.md](rules/lottie.md) - Embedding Lottie animations in Remotion -- [rules/measuring-dom-nodes.md](rules/measuring-dom-nodes.md) - Measuring DOM element dimensions in Remotion -- [rules/measuring-text.md](rules/measuring-text.md) - Measuring text dimensions, fitting text to containers, and checking overflow -- [rules/sequencing.md](rules/sequencing.md) - Sequencing patterns for Remotion - delay, trim, limit duration of items -- [rules/tailwind.md](rules/tailwind.md) - Using TailwindCSS in Remotion -- [rules/text-animations.md](rules/text-animations.md) - Typography and text animation patterns for Remotion -- [rules/timing.md](rules/timing.md) - Interpolation curves in Remotion - linear, easing, spring animations -- [rules/transcribe-captions.md](rules/transcribe-captions.md) - Transcribing audio to generate captions in Remotion -- [rules/transitions.md](rules/transitions.md) - Scene transition patterns for Remotion -- [rules/trimming.md](rules/trimming.md) - Trimming patterns for Remotion - cut the beginning or end of animations -- [rules/videos.md](rules/videos.md) - Embedding videos in Remotion - trimming, volume, speed, looping, pitch diff --git a/.opencode/skills/Remotion/Patterns.md b/.opencode/skills/Remotion/Patterns.md deleted file mode 100644 index e9791858..00000000 --- a/.opencode/skills/Remotion/Patterns.md +++ /dev/null @@ -1,133 +0,0 @@ -# Remotion Patterns - -Common patterns and examples for Remotion video creation. - -## Basic Component Structure - -```typescript -import { useCurrentFrame, useVideoConfig, AbsoluteFill, interpolate } from 'remotion' - -export const MyVideo: React.FC = () => { - const frame = useCurrentFrame() - const { fps, durationInFrames, width, height } = useVideoConfig() - - const opacity = interpolate(frame, [0, 30], [0, 1], { - extrapolateRight: 'clamp' - }) - - return ( - -

Hello World

-
- ) -} -``` - -## Register Composition - -```typescript -// src/Root.tsx -import { Composition } from 'remotion' -import { MyVideo } from './MyVideo' - -export const RemotionRoot: React.FC = () => { - return ( - - ) -} -``` - -## Fade In Text - -```typescript -const frame = useCurrentFrame() -const opacity = interpolate(frame, [0, 30], [0, 1], { extrapolateRight: 'clamp' }) - -

Fade In

-``` - -## Spring Animation - -```typescript -import { spring, useCurrentFrame, useVideoConfig } from 'remotion' - -const frame = useCurrentFrame() -const { fps } = useVideoConfig() - -const scale = spring({ - frame, - fps, - from: 0, - to: 1, - config: { damping: 10, stiffness: 100 } -}) - -
Bounce In
-``` - -## Sequence Multiple Elements - -```typescript -import { Sequence } from 'remotion' - - - -</Sequence> -<Sequence from={60} durationInFrames={90}> - <Content /> -</Sequence> -<Sequence from={150}> - <Outro /> -</Sequence> -``` - -## Audio with Video - -```typescript -import { Audio, Video, staticFile } from 'remotion' - -<Video src={staticFile('video.mp4')} volume={0.5} /> -<Audio src={staticFile('music.mp3')} volume={0.3} startFrom={30} /> -``` - -## Video Size Presets - -```typescript -// YouTube -{ width: 1920, height: 1080 } // 16:9 landscape -{ width: 1080, height: 1920 } // 9:16 Shorts - -// TikTok/Reels -{ width: 1080, height: 1920 } // 9:16 portrait - -// Instagram -{ width: 1080, height: 1080 } // 1:1 square -{ width: 1080, height: 1350 } // 4:5 portrait - -// Twitter/X -{ width: 1280, height: 720 } // 16:9 landscape -``` - -## Critical Rules - -1. **NO CSS animations** - They won't render. Use `useCurrentFrame()` for all animations. -2. **NO third-party animation libraries** - They cause flickering. Drive animations from frame. -3. **Use `staticFile()`** - For assets in `/public` directory. -4. **Extrapolate carefully** - Use `extrapolateRight: 'clamp'` to prevent overflow. -5. **Props with Zod** - Define schemas for type-safe, configurable compositions. - -## Reference Documentation - -For detailed patterns on specific topics, see: -``` -~/.opencode/skills/Remotion/Tools/Reference/ -``` - -Topics include: animations, audio, 3d, charts, captions, fonts, transitions, and more. diff --git a/.opencode/skills/Remotion/SKILL.md b/.opencode/skills/Remotion/SKILL.md deleted file mode 100644 index acc57b31..00000000 --- a/.opencode/skills/Remotion/SKILL.md +++ /dev/null @@ -1,69 +0,0 @@ ---- -name: Remotion -description: Programmatic video creation with React. USE WHEN video, animation, motion graphics, video rendering, React video, intro video, YouTube video, TikTok video, video production, render video. ---- - -## 🚨 MANDATORY: Voice Notification (REQUIRED BEFORE ANY ACTION) - -**You MUST send this notification BEFORE doing anything else when this skill is invoked.** - -1. **Send voice notification**: - ```bash - curl -s -X POST http://localhost:8888/notify \ - -H "Content-Type: application/json" \ - -d '{"message": "Running the WORKFLOWNAME workflow in the Remotion skill to ACTION"}' \ - > /dev/null 2>&1 & - ``` - -2. **Output text notification**: - ``` - Running the **WorkflowName** workflow in the **Remotion** skill to ACTION... - ``` - -**This is not optional. Execute this curl command immediately upon skill invocation.** - -# Remotion - -Create professional videos programmatically with React. - -## Customization - -**Before executing, check for user customizations at:** -`~/.opencode/skills/PAI/USER/SKILLCUSTOMIZATIONS/Remotion/` - -## Workflow Routing - -| Trigger | Workflow | -|---------|----------| -| "animate this", "create animations for", "video overlay" | `Workflows/ContentToAnimation.md` | - -## Quick Reference - -- **Theme:** Always use PAI_THEME from `Tools/Theme.ts` -- **Art Integration:** Load Art preferences before creating content -- **Critical:** NO CSS animations - use `useCurrentFrame()` only -- **Output:** Always to `~/Downloads/` first - -**Render command:** -```bash -npx remotion render {composition-id} ~/Downloads/{name}.mp4 -``` - -## Full Documentation - -- **Art integration:** `ArtIntegration.md` - theme constants, color mapping -- **Common patterns:** `Patterns.md` - code examples, presets -- **Critical rules:** `CriticalRules.md` - what NOT to do -- **Detailed reference:** `Tools/Ref-*.md` - 28 pattern files from Remotion - -## Tools - -| Tool | Purpose | -|------|---------| -| `Tools/Render.ts` | Render, list compositions, create projects | -| `Tools/Theme.ts` | PAI theme constants derived from Art | - -## Links - -- Remotion Docs: https://remotion.dev/docs -- GitHub: https://github.com/remotion-dev/remotion diff --git a/.opencode/skills/Remotion/Tools/Ref-3d.md b/.opencode/skills/Remotion/Tools/Ref-3d.md deleted file mode 100644 index 31fa5c67..00000000 --- a/.opencode/skills/Remotion/Tools/Ref-3d.md +++ /dev/null @@ -1,86 +0,0 @@ ---- -name: 3d -description: 3D content in Remotion using Three.js and React Three Fiber. -metadata: - tags: 3d, three, threejs ---- - -# Using Three.js and React Three Fiber in Remotion - -Follow React Three Fiber and Three.js best practices. -Only the following Remotion-specific rules need to be followed: - -## Prerequisites - -First, the `@remotion/three` package needs to be installed. -If it is not, use the following command: - -```bash -npx remotion add @remotion/three # If project uses npm -bunx remotion add @remotion/three # If project uses bun -yarn remotion add @remotion/three # If project uses yarn -pnpm exec remotion add @remotion/three # If project uses pnpm -``` - -## Using ThreeCanvas - -You MUST wrap 3D content in `<ThreeCanvas>` and include proper lighting. -`<ThreeCanvas>` MUST have a `width` and `height` prop. - -```tsx -import { ThreeCanvas } from "@remotion/three"; -import { useVideoConfig } from "remotion"; - -const { width, height } = useVideoConfig(); - -<ThreeCanvas width={width} height={height}> - <ambientLight intensity={0.4} /> - <directionalLight position={[5, 5, 5]} intensity={0.8} /> - <mesh> - <sphereGeometry args={[1, 32, 32]} /> - <meshStandardMaterial color="red" /> - </mesh> -</ThreeCanvas> -``` - -## No animations not driven by `useCurrentFrame()` - -Shaders, models etc MUST NOT animate by themselves. -No animations are allowed unless they are driven by `useCurrentFrame()`. -Otherwise, it will cause flickering during rendering. - -Using `useFrame()` from `@react-three/fiber` is forbidden. - -## Animate using `useCurrentFrame()` - -Use `useCurrentFrame()` to perform animations. - -```tsx -const frame = useCurrentFrame(); -const rotationY = frame * 0.02; - -<mesh rotation={[0, rotationY, 0]}> - <boxGeometry args={[2, 2, 2]} /> - <meshStandardMaterial color="#4a9eff" /> -</mesh> -``` - -## Using `<Sequence>` inside `<ThreeCanvas>` - -The `layout` prop of any `<Sequence>` inside a `<ThreeCanvas>` must be set to `none`. - -```tsx -import { Sequence } from "remotion"; -import { ThreeCanvas } from "@remotion/three"; - -const { width, height } = useVideoConfig(); - -<ThreeCanvas width={width} height={height}> - <Sequence layout="none"> - <mesh> - <boxGeometry args={[2, 2, 2]} /> - <meshStandardMaterial color="#4a9eff" /> - </mesh> - </Sequence> -</ThreeCanvas> -``` \ No newline at end of file diff --git a/.opencode/skills/Remotion/Tools/Ref-animations.md b/.opencode/skills/Remotion/Tools/Ref-animations.md deleted file mode 100644 index 7e15623f..00000000 --- a/.opencode/skills/Remotion/Tools/Ref-animations.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -name: animations -description: Fundamental animation skills for Remotion -metadata: - tags: animations, transitions, frames, useCurrentFrame ---- - -All animations MUST be driven by the `useCurrentFrame()` hook. -Write animations in seconds and multiply them by the `fps` value from `useVideoConfig()`. - -```tsx -import { useCurrentFrame } from "remotion"; - -export const FadeIn = () => { - const frame = useCurrentFrame(); - const { fps } = useVideoConfig(); - - const opacity = interpolate(frame, [0, 2 * fps], [0, 1], { - extrapolateRight: 'clamp', - }); - - return ( - <div style={{ opacity }}>Hello World!</div> - ); -}; -``` - -CSS transitions or animations are FORBIDDEN - they will not render correctly. -Tailwind animation class names are FORBIDDEN - they will not render correctly. \ No newline at end of file diff --git a/.opencode/skills/Remotion/Tools/Ref-assets.md b/.opencode/skills/Remotion/Tools/Ref-assets.md deleted file mode 100644 index 04c8ad59..00000000 --- a/.opencode/skills/Remotion/Tools/Ref-assets.md +++ /dev/null @@ -1,78 +0,0 @@ ---- -name: assets -description: Importing images, videos, audio, and fonts into Remotion -metadata: - tags: assets, staticFile, images, fonts, public ---- - -# Importing assets in Remotion - -## The public folder - -Place assets in the `public/` folder at your project root. - -## Using staticFile() - -You MUST use `staticFile()` to reference files from the `public/` folder: - -```tsx -import {Img, staticFile} from 'remotion'; - -export const MyComposition = () => { - return <Img src={staticFile('logo.png')} />; -}; -``` - -The function returns an encoded URL that works correctly when deploying to subdirectories. - -## Using with components - -**Images:** - -```tsx -import {Img, staticFile} from 'remotion'; - -<Img src={staticFile('photo.png')} />; -``` - -**Videos:** - -```tsx -import {Video} from '@remotion/media'; -import {staticFile} from 'remotion'; - -<Video src={staticFile('clip.mp4')} />; -``` - -**Audio:** - -```tsx -import {Audio} from '@remotion/media'; -import {staticFile} from 'remotion'; - -<Audio src={staticFile('music.mp3')} />; -``` - -**Fonts:** - -```tsx -import {staticFile} from 'remotion'; - -const fontFamily = new FontFace('MyFont', `url(${staticFile('font.woff2')})`); -await fontFamily.load(); -document.fonts.add(fontFamily); -``` - -## Remote URLs - -Remote URLs can be used directly without `staticFile()`: - -```tsx -<Img src="https://example.com/image.png" /> -<Video src="https://remotion.media/video.mp4" /> -``` - -## Important notes - -- Remotion components (`<Img>`, `<Video>`, `<Audio>`) ensure assets are fully loaded before rendering -- Special characters in filenames (`#`, `?`, `&`) are automatically encoded diff --git a/.opencode/skills/Remotion/Tools/Ref-audio.md b/.opencode/skills/Remotion/Tools/Ref-audio.md deleted file mode 100644 index 48086ec9..00000000 --- a/.opencode/skills/Remotion/Tools/Ref-audio.md +++ /dev/null @@ -1,172 +0,0 @@ ---- -name: audio -description: Using audio and sound in Remotion - importing, trimming, volume, speed, pitch -metadata: - tags: audio, media, trim, volume, speed, loop, pitch, mute, sound, sfx ---- - -# Using audio in Remotion - -## Prerequisites - -First, the @remotion/media package needs to be installed. -If it is not installed, use the following command: - -```bash -npx remotion add @remotion/media # If project uses npm -bunx remotion add @remotion/media # If project uses bun -yarn remotion add @remotion/media # If project uses yarn -pnpm exec remotion add @remotion/media # If project uses pnpm -``` - -## Importing Audio - -Use `<Audio>` from `@remotion/media` to add audio to your composition. - -```tsx -import { Audio } from "@remotion/media"; -import { staticFile } from "remotion"; - -export const MyComposition = () => { - return <Audio src={staticFile("audio.mp3")} />; -}; -``` - -Remote URLs are also supported: - -```tsx -<Audio src="https://remotion.media/audio.mp3" /> -``` - -By default, audio plays from the start, at full volume and full length. -Multiple audio tracks can be layered by adding multiple `<Audio>` components. - -## Trimming - -Use `trimBefore` and `trimAfter` to remove portions of the audio. Values are in frames. - -```tsx -const { fps } = useVideoConfig(); - -return ( - <Audio - src={staticFile("audio.mp3")} - trimBefore={2 * fps} // Skip the first 2 seconds - trimAfter={10 * fps} // End at the 10 second mark - /> -); -``` - -The audio still starts playing at the beginning of the composition - only the specified portion is played. - -## Delaying - -Wrap the audio in a `<Sequence>` to delay when it starts: - -```tsx -import { Sequence, staticFile } from "remotion"; -import { Audio } from "@remotion/media"; - -const { fps } = useVideoConfig(); - -return ( - <Sequence from={1 * fps}> - <Audio src={staticFile("audio.mp3")} /> - </Sequence> -); -``` - -The audio will start playing after 1 second. - -## Volume - -Set a static volume (0 to 1): - -```tsx -<Audio src={staticFile("audio.mp3")} volume={0.5} /> -``` - -Or use a callback for dynamic volume based on the current frame: - -```tsx -import { interpolate } from "remotion"; - -const { fps } = useVideoConfig(); - -return ( - <Audio - src={staticFile("audio.mp3")} - volume={(f) => - interpolate(f, [0, 1 * fps], [0, 1], { extrapolateRight: "clamp" }) - } - /> -); -``` - -The value of `f` starts at 0 when the audio begins to play, not the composition frame. - -## Muting - -Use `muted` to silence the audio. It can be set dynamically: - -```tsx -const frame = useCurrentFrame(); -const { fps } = useVideoConfig(); - -return ( - <Audio - src={staticFile("audio.mp3")} - muted={frame >= 2 * fps && frame <= 4 * fps} // Mute between 2s and 4s - /> -); -``` - -## Speed - -Use `playbackRate` to change the playback speed: - -```tsx -<Audio src={staticFile("audio.mp3")} playbackRate={2} /> {/* 2x speed */} -<Audio src={staticFile("audio.mp3")} playbackRate={0.5} /> {/* Half speed */} -``` - -Reverse playback is not supported. - -## Looping - -Use `loop` to loop the audio indefinitely: - -```tsx -<Audio src={staticFile("audio.mp3")} loop /> -``` - -Use `loopVolumeCurveBehavior` to control how the frame count behaves when looping: - -- `"repeat"`: Frame count resets to 0 each loop (default) -- `"extend"`: Frame count continues incrementing - -```tsx -<Audio - src={staticFile("audio.mp3")} - loop - loopVolumeCurveBehavior="extend" - volume={(f) => interpolate(f, [0, 300], [1, 0])} // Fade out over multiple loops -/> -``` - -## Pitch - -Use `toneFrequency` to adjust the pitch without affecting speed. Values range from 0.01 to 2: - -```tsx -<Audio - src={staticFile("audio.mp3")} - toneFrequency={1.5} // Higher pitch -/> -<Audio - src={staticFile("audio.mp3")} - toneFrequency={0.8} // Lower pitch -/> -``` - -Pitch shifting only works during server-side rendering, not in the Remotion Studio preview or in the `<Player />`. diff --git a/.opencode/skills/Remotion/Tools/Ref-calculate-metadata.md b/.opencode/skills/Remotion/Tools/Ref-calculate-metadata.md deleted file mode 100644 index 06098cad..00000000 --- a/.opencode/skills/Remotion/Tools/Ref-calculate-metadata.md +++ /dev/null @@ -1,104 +0,0 @@ ---- -name: calculate-metadata -description: Dynamically set composition duration, dimensions, and props -metadata: - tags: calculateMetadata, duration, dimensions, props, dynamic ---- - -# Using calculateMetadata - -Use `calculateMetadata` on a `<Composition>` to dynamically set duration, dimensions, and transform props before rendering. - -```tsx -<Composition id="MyComp" component={MyComponent} durationInFrames={300} fps={30} width={1920} height={1080} defaultProps={{videoSrc: 'https://remotion.media/video.mp4'}} calculateMetadata={calculateMetadata} /> -``` - -## Setting duration based on a video - -Use the `getMediaMetadata()` function from the mediabunny/metadata skill to get the video duration: - -```tsx -import {CalculateMetadataFunction} from 'remotion'; -import {getMediaMetadata} from '../get-media-metadata'; - -const calculateMetadata: CalculateMetadataFunction<Props> = async ({props}) => { - const {durationInSeconds} = await getMediaMetadata(props.videoSrc); - - return { - durationInFrames: Math.ceil(durationInSeconds * 30), - }; -}; -``` - -## Matching dimensions of a video - -```tsx -const calculateMetadata: CalculateMetadataFunction<Props> = async ({props}) => { - const {durationInSeconds, dimensions} = await getMediaMetadata(props.videoSrc); - - return { - durationInFrames: Math.ceil(durationInSeconds * 30), - width: dimensions?.width ?? 1920, - height: dimensions?.height ?? 1080, - }; -}; -``` - -## Setting duration based on multiple videos - -```tsx -const calculateMetadata: CalculateMetadataFunction<Props> = async ({props}) => { - const metadataPromises = props.videos.map((video) => getMediaMetadata(video.src)); - const allMetadata = await Promise.all(metadataPromises); - - const totalDuration = allMetadata.reduce((sum, meta) => sum + meta.durationInSeconds, 0); - - return { - durationInFrames: Math.ceil(totalDuration * 30), - }; -}; -``` - -## Setting a default outName - -Set the default output filename based on props: - -```tsx -const calculateMetadata: CalculateMetadataFunction<Props> = async ({props}) => { - return { - defaultOutName: `video-${props.id}.mp4`, - }; -}; -``` - -## Transforming props - -Fetch data or transform props before rendering: - -```tsx -const calculateMetadata: CalculateMetadataFunction<Props> = async ({props, abortSignal}) => { - const response = await fetch(props.dataUrl, {signal: abortSignal}); - const data = await response.json(); - - return { - props: { - ...props, - fetchedData: data, - }, - }; -}; -``` - -The `abortSignal` cancels stale requests when props change in the Studio. - -## Return value - -All fields are optional. Returned values override the `<Composition>` props: - -- `durationInFrames`: Number of frames -- `width`: Composition width in pixels -- `height`: Composition height in pixels -- `fps`: Frames per second -- `props`: Transformed props passed to the component -- `defaultOutName`: Default output filename -- `defaultCodec`: Default codec for rendering diff --git a/.opencode/skills/Remotion/Tools/Ref-can-decode.md b/.opencode/skills/Remotion/Tools/Ref-can-decode.md deleted file mode 100644 index b7146c9c..00000000 --- a/.opencode/skills/Remotion/Tools/Ref-can-decode.md +++ /dev/null @@ -1,75 +0,0 @@ ---- -name: can-decode -description: Check if a video can be decoded by the browser using Mediabunny -metadata: - tags: decode, validation, video, audio, compatibility, browser ---- - -# Checking if a video can be decoded - -Use Mediabunny to check if a video can be decoded by the browser before attempting to play it. - -## The `canDecode()` function - -This function can be copy-pasted into any project. - -```tsx -import { Input, ALL_FORMATS, UrlSource } from "mediabunny"; - -export const canDecode = async (src: string) => { - const input = new Input({ - formats: ALL_FORMATS, - source: new UrlSource(src, { - getRetryDelay: () => null, - }), - }); - - try { - await input.getFormat(); - } catch { - return false; - } - - const videoTrack = await input.getPrimaryVideoTrack(); - if (videoTrack && !(await videoTrack.canDecode())) { - return false; - } - - const audioTrack = await input.getPrimaryAudioTrack(); - if (audioTrack && !(await audioTrack.canDecode())) { - return false; - } - - return true; -}; -``` - -## Usage - -```tsx -const src = "https://remotion.media/video.mp4"; -const isDecodable = await canDecode(src); - -if (isDecodable) { - console.log("Video can be decoded"); -} else { - console.log("Video cannot be decoded by this browser"); -} -``` - -## Using with Blob - -For file uploads or drag-and-drop, use `BlobSource`: - -```tsx -import { Input, ALL_FORMATS, BlobSource } from "mediabunny"; - -export const canDecodeBlob = async (blob: Blob) => { - const input = new Input({ - formats: ALL_FORMATS, - source: new BlobSource(blob), - }); - - // Same validation logic as above -}; -``` diff --git a/.opencode/skills/Remotion/Tools/Ref-charts.md b/.opencode/skills/Remotion/Tools/Ref-charts.md deleted file mode 100644 index a402ed53..00000000 --- a/.opencode/skills/Remotion/Tools/Ref-charts.md +++ /dev/null @@ -1,58 +0,0 @@ ---- -name: charts -description: Chart and data visualization patterns for Remotion. Use when creating bar charts, pie charts, histograms, progress bars, or any data-driven animations. -metadata: - tags: charts, data, visualization, bar-chart, pie-chart, graphs ---- - -# Charts in Remotion - -You can create bar charts in Remotion by using regular React code - HTML and SVG is allowed, as well as D3.js. - -## No animations not powered by `useCurrentFrame()` - -Disable all animations by third party libraries. -They will cause flickering during rendering. -Instead, drive all animations from `useCurrentFrame()`. - -## Bar Chart Animations - -See [Bar Chart Example](assets/charts/bar-chart.tsx) for a basic example implmentation. - -### Staggered Bars - -You can animate the height of the bars and stagger them like this: - -```tsx -const STAGGER_DELAY = 5; -const frame = useCurrentFrame(); -const {fps} = useVideoConfig(); - -const bars = data.map((item, i) => { - const delay = i * STAGGER_DELAY; - const height = spring({ - frame, - fps, - delay, - config: {damping: 200}, - }); - return <div style={{height: height * item.value}} />; -}); -``` - -## Pie Chart Animation - -Animate segments using stroke-dashoffset, starting from 12 o'clock. - -```tsx -const frame = useCurrentFrame(); -const {fps} = useVideoConfig(); - -const progress = interpolate(frame, [0, 100], [0, 1]); - -const circumference = 2 * Math.PI * radius; -const segmentLength = (value / total) * circumference; -const offset = interpolate(progress, [0, 1], [segmentLength, 0]); - -<circle r={radius} cx={center} cy={center} fill="none" stroke={color} strokeWidth={strokeWidth} strokeDasharray={`${segmentLength} ${circumference}`} strokeDashoffset={offset} transform={`rotate(-90 ${center} ${center})`} />; -``` diff --git a/.opencode/skills/Remotion/Tools/Ref-compositions.md b/.opencode/skills/Remotion/Tools/Ref-compositions.md deleted file mode 100644 index 27b61bb1..00000000 --- a/.opencode/skills/Remotion/Tools/Ref-compositions.md +++ /dev/null @@ -1,146 +0,0 @@ ---- -name: compositions -description: Defining compositions, stills, folders, default props and dynamic metadata -metadata: - tags: composition, still, folder, props, metadata ---- - -A `<Composition>` defines the component, width, height, fps and duration of a renderable video. - -It normally is placed in the `src/Root.tsx` file. - -```tsx -import { Composition } from "remotion"; -import { MyComposition } from "./MyComposition"; - -export const RemotionRoot = () => { - return ( - <Composition - id="MyComposition" - component={MyComposition} - durationInFrames={100} - fps={30} - width={1080} - height={1080} - /> - ); -}; -``` - -## Default Props - -Pass `defaultProps` to provide initial values for your component. -Values must be JSON-serializable (`Date`, `Map`, `Set`, and `staticFile()` are supported). - -```tsx -import { Composition } from "remotion"; -import { MyComposition, MyCompositionProps } from "./MyComposition"; - -export const RemotionRoot = () => { - return ( - <Composition - id="MyComposition" - component={MyComposition} - durationInFrames={100} - fps={30} - width={1080} - height={1080} - defaultProps={{ - title: "Hello World", - color: "#ff0000", - } satisfies MyCompositionProps} - /> - ); -}; -``` - -Use `type` declarations for props rather than `interface` to ensure `defaultProps` type safety. - -## Folders - -Use `<Folder>` to organize compositions in the sidebar. -Folder names can only contain letters, numbers, and hyphens. - -```tsx -import { Composition, Folder } from "remotion"; - -export const RemotionRoot = () => { - return ( - <> - <Folder name="Marketing"> - <Composition id="Promo" /* ... */ /> - <Composition id="Ad" /* ... */ /> - </Folder> - <Folder name="Social"> - <Folder name="Instagram"> - <Composition id="Story" /* ... */ /> - <Composition id="Reel" /* ... */ /> - </Folder> - </Folder> - </> - ); -}; -``` - -## Stills - -Use `<Still>` for single-frame images. It does not require `durationInFrames` or `fps`. - -```tsx -import { Still } from "remotion"; -import { Thumbnail } from "./Thumbnail"; - -export const RemotionRoot = () => { - return ( - <Still - id="Thumbnail" - component={Thumbnail} - width={1280} - height={720} - /> - ); -}; -``` - -## Calculate Metadata - -Use `calculateMetadata` to make dimensions, duration, or props dynamic based on data. - -```tsx -import { Composition, CalculateMetadataFunction } from "remotion"; -import { MyComposition, MyCompositionProps } from "./MyComposition"; - -const calculateMetadata: CalculateMetadataFunction<MyCompositionProps> = async ({ - props, - abortSignal, -}) => { - const data = await fetch(`https://api.example.com/video/${props.videoId}`, { - signal: abortSignal, - }).then((res) => res.json()); - - return { - durationInFrames: Math.ceil(data.duration * 30), - props: { - ...props, - videoUrl: data.url, - }, - }; -}; - -export const RemotionRoot = () => { - return ( - <Composition - id="MyComposition" - component={MyComposition} - durationInFrames={100} // Placeholder, will be overridden - fps={30} - width={1080} - height={1080} - defaultProps={{ videoId: "abc123" }} - calculateMetadata={calculateMetadata} - /> - ); -}; -``` - -The function can return `props`, `durationInFrames`, `width`, `height`, `fps`, and codec-related defaults. It runs once before rendering begins. \ No newline at end of file diff --git a/.opencode/skills/Remotion/Tools/Ref-display-captions.md b/.opencode/skills/Remotion/Tools/Ref-display-captions.md deleted file mode 100644 index 1f70b702..00000000 --- a/.opencode/skills/Remotion/Tools/Ref-display-captions.md +++ /dev/null @@ -1,126 +0,0 @@ ---- -name: display-captions -description: Displaying captions in Remotion with TikTok-style pages and word highlighting -metadata: - tags: captions, subtitles, display, tiktok, highlight ---- - -# Displaying captions in Remotion - -This guide explains how to display captions in Remotion, assuming you already have captions in the `Caption` format. - -## Prerequisites - -First, the @remotion/captions package needs to be installed. -If it is not installed, use the following command: - -```bash -npx remotion add @remotion/captions # If project uses npm -bunx remotion add @remotion/captions # If project uses bun -yarn remotion add @remotion/captions # If project uses yarn -pnpm exec remotion add @remotion/captions # If project uses pnpm -``` - -## Creating pages - -Use `createTikTokStyleCaptions()` to group captions into pages. The `combineTokensWithinMilliseconds` option controls how many words appear at once: - -```tsx -import {useMemo} from 'react'; -import {createTikTokStyleCaptions} from '@remotion/captions'; -import type {Caption} from '@remotion/captions'; - -// How often captions should switch (in milliseconds) -// Higher values = more words per page -// Lower values = fewer words (more word-by-word) -const SWITCH_CAPTIONS_EVERY_MS = 1200; - -const {pages} = useMemo(() => { - return createTikTokStyleCaptions({ - captions, - combineTokensWithinMilliseconds: SWITCH_CAPTIONS_EVERY_MS, - }); -}, [captions]); -``` - -## Rendering with Sequences - -Map over the pages and render each one in a `<Sequence>`. Calculate the start frame and duration from the page timing: - -```tsx -import {Sequence, useVideoConfig, AbsoluteFill} from 'remotion'; -import type {TikTokPage} from '@remotion/captions'; - -const CaptionedContent: React.FC = () => { - const {fps} = useVideoConfig(); - - return ( - <AbsoluteFill> - {pages.map((page, index) => { - const nextPage = pages[index + 1] ?? null; - const startFrame = (page.startMs / 1000) * fps; - const endFrame = Math.min( - nextPage ? (nextPage.startMs / 1000) * fps : Infinity, - startFrame + (SWITCH_CAPTIONS_EVERY_MS / 1000) * fps, - ); - const durationInFrames = endFrame - startFrame; - - if (durationInFrames <= 0) { - return null; - } - - return ( - <Sequence - key={index} - from={startFrame} - durationInFrames={durationInFrames} - > - <CaptionPage page={page} /> - </Sequence> - ); - })} - </AbsoluteFill> - ); -}; -``` - -## Word highlighting - -A caption page contains `tokens` which you can use to highlight the currently spoken word: - -```tsx -import {AbsoluteFill, useCurrentFrame, useVideoConfig} from 'remotion'; -import type {TikTokPage} from '@remotion/captions'; - -const HIGHLIGHT_COLOR = '#39E508'; - -const CaptionPage: React.FC<{page: TikTokPage}> = ({page}) => { - const frame = useCurrentFrame(); - const {fps} = useVideoConfig(); - - // Current time relative to the start of the sequence - const currentTimeMs = (frame / fps) * 1000; - // Convert to absolute time by adding the page start - const absoluteTimeMs = page.startMs + currentTimeMs; - - return ( - <AbsoluteFill style={{justifyContent: 'center', alignItems: 'center'}}> - <div style={{fontSize: 80, fontWeight: 'bold', whiteSpace: 'pre'}}> - {page.tokens.map((token) => { - const isActive = - token.fromMs <= absoluteTimeMs && token.toMs > absoluteTimeMs; - - return ( - <span - key={token.fromMs} - style={{color: isActive ? HIGHLIGHT_COLOR : 'white'}} - > - {token.text} - </span> - ); - })} - </div> - </AbsoluteFill> - ); -}; -``` diff --git a/.opencode/skills/Remotion/Tools/Ref-extract-frames.md b/.opencode/skills/Remotion/Tools/Ref-extract-frames.md deleted file mode 100644 index 46e63efc..00000000 --- a/.opencode/skills/Remotion/Tools/Ref-extract-frames.md +++ /dev/null @@ -1,229 +0,0 @@ ---- -name: extract-frames -description: Extract frames from videos at specific timestamps using Mediabunny -metadata: - tags: frames, extract, video, thumbnail, filmstrip, canvas ---- - -# Extracting frames from videos - -Use Mediabunny to extract frames from videos at specific timestamps. This is useful for generating thumbnails, filmstrips, or processing individual frames. - -## The `extractFrames()` function - -This function can be copy-pasted into any project. - -```tsx -import { - ALL_FORMATS, - Input, - UrlSource, - VideoSample, - VideoSampleSink, -} from "mediabunny"; - -type Options = { - track: { width: number; height: number }; - container: string; - durationInSeconds: number | null; -}; - -export type ExtractFramesTimestampsInSecondsFn = ( - options: Options -) => Promise<number[]> | number[]; - -export type ExtractFramesProps = { - src: string; - timestampsInSeconds: number[] | ExtractFramesTimestampsInSecondsFn; - onVideoSample: (sample: VideoSample) => void; - signal?: AbortSignal; -}; - -export async function extractFrames({ - src, - timestampsInSeconds, - onVideoSample, - signal, -}: ExtractFramesProps): Promise<void> { - using input = new Input({ - formats: ALL_FORMATS, - source: new UrlSource(src), - }); - - const [durationInSeconds, format, videoTrack] = await Promise.all([ - input.computeDuration(), - input.getFormat(), - input.getPrimaryVideoTrack(), - ]); - - if (!videoTrack) { - throw new Error("No video track found in the input"); - } - - if (signal?.aborted) { - throw new Error("Aborted"); - } - - const timestamps = - typeof timestampsInSeconds === "function" - ? await timestampsInSeconds({ - track: { - width: videoTrack.displayWidth, - height: videoTrack.displayHeight, - }, - container: format.name, - durationInSeconds, - }) - : timestampsInSeconds; - - if (timestamps.length === 0) { - return; - } - - if (signal?.aborted) { - throw new Error("Aborted"); - } - - const sink = new VideoSampleSink(videoTrack); - - for await (using videoSample of sink.samplesAtTimestamps(timestamps)) { - if (signal?.aborted) { - break; - } - - if (!videoSample) { - continue; - } - - onVideoSample(videoSample); - } -} -``` - -## Basic usage - -Extract frames at specific timestamps: - -```tsx -await extractFrames({ - src: "https://remotion.media/video.mp4", - timestampsInSeconds: [0, 1, 2, 3, 4], - onVideoSample: (sample) => { - const canvas = document.createElement("canvas"); - canvas.width = sample.displayWidth; - canvas.height = sample.displayHeight; - const ctx = canvas.getContext("2d"); - sample.draw(ctx!, 0, 0); - }, -}); -``` - -## Creating a filmstrip - -Use a callback function to dynamically calculate timestamps based on video metadata: - -```tsx -const canvasWidth = 500; -const canvasHeight = 80; -const fromSeconds = 0; -const toSeconds = 10; - -await extractFrames({ - src: "https://remotion.media/video.mp4", - timestampsInSeconds: async ({ track, durationInSeconds }) => { - const aspectRatio = track.width / track.height; - const amountOfFramesFit = Math.ceil( - canvasWidth / (canvasHeight * aspectRatio) - ); - const segmentDuration = toSeconds - fromSeconds; - const timestamps: number[] = []; - - for (let i = 0; i < amountOfFramesFit; i++) { - timestamps.push( - fromSeconds + (segmentDuration / amountOfFramesFit) * (i + 0.5) - ); - } - - return timestamps; - }, - onVideoSample: (sample) => { - console.log(`Frame at ${sample.timestamp}s`); - - const canvas = document.createElement("canvas"); - canvas.width = sample.displayWidth; - canvas.height = sample.displayHeight; - const ctx = canvas.getContext("2d"); - sample.draw(ctx!, 0, 0); - }, -}); -``` - -## Cancellation with AbortSignal - -Cancel frame extraction after a timeout: - -```tsx -const controller = new AbortController(); - -setTimeout(() => controller.abort(), 5000); - -try { - await extractFrames({ - src: "https://remotion.media/video.mp4", - timestampsInSeconds: [0, 1, 2, 3, 4], - onVideoSample: (sample) => { - using frame = sample; - const canvas = document.createElement("canvas"); - canvas.width = frame.displayWidth; - canvas.height = frame.displayHeight; - const ctx = canvas.getContext("2d"); - frame.draw(ctx!, 0, 0); - }, - signal: controller.signal, - }); - - console.log("Frame extraction complete!"); -} catch (error) { - console.error("Frame extraction was aborted or failed:", error); -} -``` - -## Timeout with Promise.race - -```tsx -const controller = new AbortController(); - -const timeoutPromise = new Promise<never>((_, reject) => { - const timeoutId = setTimeout(() => { - controller.abort(); - reject(new Error("Frame extraction timed out after 10 seconds")); - }, 10000); - - controller.signal.addEventListener("abort", () => clearTimeout(timeoutId), { - once: true, - }); -}); - -try { - await Promise.race([ - extractFrames({ - src: "https://remotion.media/video.mp4", - timestampsInSeconds: [0, 1, 2, 3, 4], - onVideoSample: (sample) => { - using frame = sample; - const canvas = document.createElement("canvas"); - canvas.width = frame.displayWidth; - canvas.height = frame.displayHeight; - const ctx = canvas.getContext("2d"); - frame.draw(ctx!, 0, 0); - }, - signal: controller.signal, - }), - timeoutPromise, - ]); - - console.log("Frame extraction complete!"); -} catch (error) { - console.error("Frame extraction was aborted or failed:", error); -} -``` diff --git a/.opencode/skills/Remotion/Tools/Ref-fonts.md b/.opencode/skills/Remotion/Tools/Ref-fonts.md deleted file mode 100644 index c10cd83e..00000000 --- a/.opencode/skills/Remotion/Tools/Ref-fonts.md +++ /dev/null @@ -1,152 +0,0 @@ ---- -name: fonts -description: Loading Google Fonts and local fonts in Remotion -metadata: - tags: fonts, google-fonts, typography, text ---- - -# Using fonts in Remotion - -## Google Fonts with @remotion/google-fonts - -The recommended way to use Google Fonts. It's type-safe and automatically blocks rendering until the font is ready. - -### Prerequisites - -First, the @remotion/google-fonts package needs to be installed. -If it is not installed, use the following command: - -```bash -npx remotion add @remotion/google-fonts # If project uses npm -bunx remotion add @remotion/google-fonts # If project uses bun -yarn remotion add @remotion/google-fonts # If project uses yarn -pnpm exec remotion add @remotion/google-fonts # If project uses pnpm -``` - -```tsx -import { loadFont } from "@remotion/google-fonts/Lobster"; - -const { fontFamily } = loadFont(); - -export const MyComposition = () => { - return <div style={{ fontFamily }}>Hello World</div>; -}; -``` - -Preferrably, specify only needed weights and subsets to reduce file size: - -```tsx -import { loadFont } from "@remotion/google-fonts/Roboto"; - -const { fontFamily } = loadFont("normal", { - weights: ["400", "700"], - subsets: ["latin"], -}); -``` - -### Waiting for font to load - -Use `waitUntilDone()` if you need to know when the font is ready: - -```tsx -import { loadFont } from "@remotion/google-fonts/Lobster"; - -const { fontFamily, waitUntilDone } = loadFont(); - -await waitUntilDone(); -``` - -## Local fonts with @remotion/fonts - -For local font files, use the `@remotion/fonts` package. - -### Prerequisites - -First, install @remotion/fonts: - -```bash -npx remotion add @remotion/fonts # If project uses npm -bunx remotion add @remotion/fonts # If project uses bun -yarn remotion add @remotion/fonts # If project uses yarn -pnpm exec remotion add @remotion/fonts # If project uses pnpm -``` - -### Loading a local font - -Place your font file in the `public/` folder and use `loadFont()`: - -```tsx -import { loadFont } from "@remotion/fonts"; -import { staticFile } from "remotion"; - -await loadFont({ - family: "MyFont", - url: staticFile("MyFont-Regular.woff2"), -}); - -export const MyComposition = () => { - return <div style={{ fontFamily: "MyFont" }}>Hello World</div>; -}; -``` - -### Loading multiple weights - -Load each weight separately with the same family name: - -```tsx -import { loadFont } from "@remotion/fonts"; -import { staticFile } from "remotion"; - -await Promise.all([ - loadFont({ - family: "Inter", - url: staticFile("Inter-Regular.woff2"), - weight: "400", - }), - loadFont({ - family: "Inter", - url: staticFile("Inter-Bold.woff2"), - weight: "700", - }), -]); -``` - -### Available options - -```tsx -loadFont({ - family: "MyFont", // Required: name to use in CSS - url: staticFile("font.woff2"), // Required: font file URL - format: "woff2", // Optional: auto-detected from extension - weight: "400", // Optional: font weight - style: "normal", // Optional: normal or italic - display: "block", // Optional: font-display behavior -}); -``` - -## Using in components - -Call `loadFont()` at the top level of your component or in a separate file that's imported early: - -```tsx -import { loadFont } from "@remotion/google-fonts/Montserrat"; - -const { fontFamily } = loadFont("normal", { - weights: ["400", "700"], - subsets: ["latin"], -}); - -export const Title: React.FC<{ text: string }> = ({ text }) => { - return ( - <h1 - style={{ - fontFamily, - fontSize: 80, - fontWeight: "bold", - }} - > - {text} - </h1> - ); -}; -``` diff --git a/.opencode/skills/Remotion/Tools/Ref-get-audio-duration.md b/.opencode/skills/Remotion/Tools/Ref-get-audio-duration.md deleted file mode 100644 index fc57d914..00000000 --- a/.opencode/skills/Remotion/Tools/Ref-get-audio-duration.md +++ /dev/null @@ -1,58 +0,0 @@ ---- -name: get-audio-duration -description: Getting the duration of an audio file in seconds with Mediabunny -metadata: - tags: duration, audio, length, time, seconds, mp3, wav ---- - -# Getting audio duration with Mediabunny - -Mediabunny can extract the duration of an audio file. It works in browser, Node.js, and Bun environments. - -## Getting audio duration - -```tsx -import { Input, ALL_FORMATS, UrlSource } from "mediabunny"; - -export const getAudioDuration = async (src: string) => { - const input = new Input({ - formats: ALL_FORMATS, - source: new UrlSource(src, { - getRetryDelay: () => null, - }), - }); - - const durationInSeconds = await input.computeDuration(); - return durationInSeconds; -}; -``` - -## Usage - -```tsx -const duration = await getAudioDuration("https://remotion.media/audio.mp3"); -console.log(duration); // e.g. 180.5 (seconds) -``` - -## Using with local files - -For local files, use `FileSource` instead of `UrlSource`: - -```tsx -import { Input, ALL_FORMATS, FileSource } from "mediabunny"; - -const input = new Input({ - formats: ALL_FORMATS, - source: new FileSource(file), // File object from input or drag-drop -}); - -const durationInSeconds = await input.computeDuration(); -``` - -## Using with staticFile in Remotion - -```tsx -import { staticFile } from "remotion"; - -const duration = await getAudioDuration(staticFile("audio.mp3")); -``` diff --git a/.opencode/skills/Remotion/Tools/Ref-get-video-dimensions.md b/.opencode/skills/Remotion/Tools/Ref-get-video-dimensions.md deleted file mode 100644 index b1b212a0..00000000 --- a/.opencode/skills/Remotion/Tools/Ref-get-video-dimensions.md +++ /dev/null @@ -1,68 +0,0 @@ ---- -name: get-video-dimensions -description: Getting the width and height of a video file with Mediabunny -metadata: - tags: dimensions, width, height, resolution, size, video ---- - -# Getting video dimensions with Mediabunny - -Mediabunny can extract the width and height of a video file. It works in browser, Node.js, and Bun environments. - -## Getting video dimensions - -```tsx -import { Input, ALL_FORMATS, UrlSource } from "mediabunny"; - -export const getVideoDimensions = async (src: string) => { - const input = new Input({ - formats: ALL_FORMATS, - source: new UrlSource(src, { - getRetryDelay: () => null, - }), - }); - - const videoTrack = await input.getPrimaryVideoTrack(); - if (!videoTrack) { - throw new Error("No video track found"); - } - - return { - width: videoTrack.displayWidth, - height: videoTrack.displayHeight, - }; -}; -``` - -## Usage - -```tsx -const dimensions = await getVideoDimensions("https://remotion.media/video.mp4"); -console.log(dimensions.width); // e.g. 1920 -console.log(dimensions.height); // e.g. 1080 -``` - -## Using with local files - -For local files, use `FileSource` instead of `UrlSource`: - -```tsx -import { Input, ALL_FORMATS, FileSource } from "mediabunny"; - -const input = new Input({ - formats: ALL_FORMATS, - source: new FileSource(file), // File object from input or drag-drop -}); - -const videoTrack = await input.getPrimaryVideoTrack(); -const width = videoTrack.displayWidth; -const height = videoTrack.displayHeight; -``` - -## Using with staticFile in Remotion - -```tsx -import { staticFile } from "remotion"; - -const dimensions = await getVideoDimensions(staticFile("video.mp4")); -``` diff --git a/.opencode/skills/Remotion/Tools/Ref-get-video-duration.md b/.opencode/skills/Remotion/Tools/Ref-get-video-duration.md deleted file mode 100644 index 92365516..00000000 --- a/.opencode/skills/Remotion/Tools/Ref-get-video-duration.md +++ /dev/null @@ -1,58 +0,0 @@ ---- -name: get-video-duration -description: Getting the duration of a video file in seconds with Mediabunny -metadata: - tags: duration, video, length, time, seconds ---- - -# Getting video duration with Mediabunny - -Mediabunny can extract the duration of a video file. It works in browser, Node.js, and Bun environments. - -## Getting video duration - -```tsx -import { Input, ALL_FORMATS, UrlSource } from "mediabunny"; - -export const getVideoDuration = async (src: string) => { - const input = new Input({ - formats: ALL_FORMATS, - source: new UrlSource(src, { - getRetryDelay: () => null, - }), - }); - - const durationInSeconds = await input.computeDuration(); - return durationInSeconds; -}; -``` - -## Usage - -```tsx -const duration = await getVideoDuration("https://remotion.media/video.mp4"); -console.log(duration); // e.g. 10.5 (seconds) -``` - -## Using with local files - -For local files, use `FileSource` instead of `UrlSource`: - -```tsx -import { Input, ALL_FORMATS, FileSource } from "mediabunny"; - -const input = new Input({ - formats: ALL_FORMATS, - source: new FileSource(file), // File object from input or drag-drop -}); - -const durationInSeconds = await input.computeDuration(); -``` - -## Using with staticFile in Remotion - -```tsx -import { staticFile } from "remotion"; - -const duration = await getVideoDuration(staticFile("video.mp4")); -``` diff --git a/.opencode/skills/Remotion/Tools/Ref-gifs.md b/.opencode/skills/Remotion/Tools/Ref-gifs.md deleted file mode 100644 index d067c759..00000000 --- a/.opencode/skills/Remotion/Tools/Ref-gifs.md +++ /dev/null @@ -1,138 +0,0 @@ ---- -name: gif -description: Displaying GIFs, APNG, AVIF and WebP in Remotion -metadata: - tags: gif, animation, images, animated, apng, avif, webp ---- - -# Using Animated images in Remotion - -## Basic usage - -Use `<AnimatedImage>` to display a GIF, APNG, AVIF or WebP image synchronized with Remotion's timeline: - -```tsx -import {AnimatedImage, staticFile} from 'remotion'; - -export const MyComposition = () => { - return <AnimatedImage src={staticFile('animation.gif')} width={500} height={500} />; -}; -``` - -Remote URLs are also supported (must have CORS enabled): - -```tsx -<AnimatedImage src="https://example.com/animation.gif" width={500} height={500} /> -``` - -## Sizing and fit - -Control how the image fills its container with the `fit` prop: - -```tsx -// Stretch to fill (default) -<AnimatedImage src={staticFile("animation.gif")} width={500} height={300} fit="fill" /> - -// Maintain aspect ratio, fit inside container -<AnimatedImage src={staticFile("animation.gif")} width={500} height={300} fit="contain" /> - -// Fill container, crop if needed -<AnimatedImage src={staticFile("animation.gif")} width={500} height={300} fit="cover" /> -``` - -## Playback speed - -Use `playbackRate` to control the animation speed: - -```tsx -<AnimatedImage src={staticFile("animation.gif")} width={500} height={500} playbackRate={2} /> {/* 2x speed */} -<AnimatedImage src={staticFile("animation.gif")} width={500} height={500} playbackRate={0.5} /> {/* Half speed */} -``` - -## Looping behavior - -Control what happens when the animation finishes: - -```tsx -// Loop indefinitely (default) -<AnimatedImage src={staticFile("animation.gif")} width={500} height={500} loopBehavior="loop" /> - -// Play once, show final frame -<AnimatedImage src={staticFile("animation.gif")} width={500} height={500} loopBehavior="pause-after-finish" /> - -// Play once, then clear canvas -<AnimatedImage src={staticFile("animation.gif")} width={500} height={500} loopBehavior="clear-after-finish" /> -``` - -## Styling - -Use the `style` prop for additional CSS (use `width` and `height` props for sizing): - -```tsx -<AnimatedImage - src={staticFile('animation.gif')} - width={500} - height={500} - style={{ - borderRadius: 20, - position: 'absolute', - top: 100, - left: 50, - }} -/> -``` - -## Getting GIF duration - -Use `getGifDurationInSeconds()` from `@remotion/gif` to get the duration of a GIF. - -```bash -npx remotion add @remotion/gif # If project uses npm -bunx remotion add @remotion/gif # If project uses bun -yarn remotion add @remotion/gif # If project uses yarn -pnpm exec remotion add @remotion/gif # If project uses pnpm -``` - -```tsx -import {getGifDurationInSeconds} from '@remotion/gif'; -import {staticFile} from 'remotion'; - -const duration = await getGifDurationInSeconds(staticFile('animation.gif')); -console.log(duration); // e.g. 2.5 -``` - -This is useful for setting the composition duration to match the GIF: - -```tsx -import {getGifDurationInSeconds} from '@remotion/gif'; -import {staticFile, CalculateMetadataFunction} from 'remotion'; - -const calculateMetadata: CalculateMetadataFunction = async () => { - const duration = await getGifDurationInSeconds(staticFile('animation.gif')); - return { - durationInFrames: Math.ceil(duration * 30), - }; -}; -``` - -## Alternative - -If `<AnimatedImage>` does not work (only supported in Chrome and Firefox), you can use `<Gif>` from `@remotion/gif` instead. - -```bash -npx remotion add @remotion/gif # If project uses npm -bunx remotion add @remotion/gif # If project uses bun -yarn remotion add @remotion/gif # If project uses yarn -pnpm exec remotion add @remotion/gif # If project uses pnpm -``` - -```tsx -import {Gif} from '@remotion/gif'; -import {staticFile} from 'remotion'; - -export const MyComposition = () => { - return <Gif src={staticFile('animation.gif')} width={500} height={500} />; -}; -``` - -The `<Gif>` component has the same props as `<AnimatedImage>` but only supports GIF files. diff --git a/.opencode/skills/Remotion/Tools/Ref-images.md b/.opencode/skills/Remotion/Tools/Ref-images.md deleted file mode 100644 index 262bb57b..00000000 --- a/.opencode/skills/Remotion/Tools/Ref-images.md +++ /dev/null @@ -1,130 +0,0 @@ ---- -name: images -description: Embedding images in Remotion using the <Img> component -metadata: - tags: images, img, staticFile, png, jpg, svg, webp ---- - -# Using images in Remotion - -## The `<Img>` component - -Always use the `<Img>` component from `remotion` to display images: - -```tsx -import { Img, staticFile } from "remotion"; - -export const MyComposition = () => { - return <Img src={staticFile("photo.png")} />; -}; -``` - -## Important restrictions - -**You MUST use the `<Img>` component from `remotion`.** Do not use: - -- Native HTML `<img>` elements -- Next.js `<Image>` component -- CSS `background-image` - -The `<Img>` component ensures images are fully loaded before rendering, preventing flickering and blank frames during video export. - -## Local images with staticFile() - -Place images in the `public/` folder and use `staticFile()` to reference them: - -``` -my-video/ -├─ public/ -│ ├─ logo.png -│ ├─ avatar.jpg -│ └─ icon.svg -├─ src/ -├─ package.json -``` - -```tsx -import { Img, staticFile } from "remotion"; - -<Img src={staticFile("logo.png")} /> -``` - -## Remote images - -Remote URLs can be used directly without `staticFile()`: - -```tsx -<Img src="https://example.com/image.png" /> -``` - -Ensure remote images have CORS enabled. - -For animated GIFs, use the `<Gif>` component from `@remotion/gif` instead. - -## Sizing and positioning - -Use the `style` prop to control size and position: - -```tsx -<Img - src={staticFile("photo.png")} - style={{ - width: 500, - height: 300, - position: "absolute", - top: 100, - left: 50, - objectFit: "cover", - }} -/> -``` - -## Dynamic image paths - -Use template literals for dynamic file references: - -```tsx -import { Img, staticFile, useCurrentFrame } from "remotion"; - -const frame = useCurrentFrame(); - -// Image sequence -<Img src={staticFile(`frames/frame${frame}.png`)} /> - -// Selecting based on props -<Img src={staticFile(`avatars/${props.userId}.png`)} /> - -// Conditional images -<Img src={staticFile(`icons/${isActive ? "active" : "inactive"}.svg`)} /> -``` - -This pattern is useful for: - -- Image sequences (frame-by-frame animations) -- User-specific avatars or profile images -- Theme-based icons -- State-dependent graphics - -## Getting image dimensions - -Use `getImageDimensions()` to get the dimensions of an image: - -```tsx -import { getImageDimensions, staticFile } from "remotion"; - -const { width, height } = await getImageDimensions(staticFile("photo.png")); -``` - -This is useful for calculating aspect ratios or sizing compositions: - -```tsx -import { getImageDimensions, staticFile, CalculateMetadataFunction } from "remotion"; - -const calculateMetadata: CalculateMetadataFunction = async () => { - const { width, height } = await getImageDimensions(staticFile("photo.png")); - return { - width, - height, - }; -}; -``` diff --git a/.opencode/skills/Remotion/Tools/Ref-import-srt-captions.md b/.opencode/skills/Remotion/Tools/Ref-import-srt-captions.md deleted file mode 100644 index 0b9c5bb3..00000000 --- a/.opencode/skills/Remotion/Tools/Ref-import-srt-captions.md +++ /dev/null @@ -1,67 +0,0 @@ ---- -name: import-srt-captions -description: Importing .srt subtitle files into Remotion using @remotion/captions -metadata: - tags: captions, subtitles, srt, import, parse ---- - -# Importing .srt subtitles into Remotion - -If you have an existing `.srt` subtitle file, you can import it into Remotion using `parseSrt()` from `@remotion/captions`. - -## Prerequisites - -First, the @remotion/captions package needs to be installed. -If it is not installed, use the following command: - -```bash -npx remotion add @remotion/captions # If project uses npm -bunx remotion add @remotion/captions # If project uses bun -yarn remotion add @remotion/captions # If project uses yarn -pnpm exec remotion add @remotion/captions # If project uses pnpm -``` - -## Reading an .srt file - -Use `staticFile()` to reference an `.srt` file in your `public` folder, then fetch and parse it: - -```tsx -import {useState, useEffect, useCallback} from 'react'; -import {AbsoluteFill, staticFile, useDelayRender} from 'remotion'; -import {parseSrt} from '@remotion/captions'; -import type {Caption} from '@remotion/captions'; - -export const MyComponent: React.FC = () => { - const [captions, setCaptions] = useState<Caption[] | null>(null); - const {delayRender, continueRender, cancelRender} = useDelayRender(); - const [handle] = useState(() => delayRender()); - - const fetchCaptions = useCallback(async () => { - try { - const response = await fetch(staticFile('subtitles.srt')); - const text = await response.text(); - const {captions: parsed} = parseSrt({input: text}); - setCaptions(parsed); - continueRender(handle); - } catch (e) { - cancelRender(e); - } - }, [continueRender, cancelRender, handle]); - - useEffect(() => { - fetchCaptions(); - }, [fetchCaptions]); - - if (!captions) { - return null; - } - - return <AbsoluteFill>{/* Use captions here */}</AbsoluteFill>; -}; -``` - -Remote URLs are also supported - you can `fetch()` a remote file via URL instead of using `staticFile()`. - -## Using imported captions - -Once parsed, the captions are in the `Caption` format and can be used with all `@remotion/captions` utilities. diff --git a/.opencode/skills/Remotion/Tools/Ref-lottie.md b/.opencode/skills/Remotion/Tools/Ref-lottie.md deleted file mode 100644 index 4d07acde..00000000 --- a/.opencode/skills/Remotion/Tools/Ref-lottie.md +++ /dev/null @@ -1,68 +0,0 @@ ---- -name: lottie -description: Embedding Lottie animations in Remotion. -metadata: - category: Animation ---- - -# Using Lottie Animations in Remotion - -## Prerequisites - -First, the @remotion/lottie package needs to be installed. -If it is not, use the following command: - -```bash -npx remotion add @remotion/lottie # If project uses npm -bunx remotion add @remotion/lottie # If project uses bun -yarn remotion add @remotion/lottie # If project uses yarn -pnpm exec remotion add @remotion/lottie # If project uses pnpm -``` - -## Displaying a Lottie file - -To import a Lottie animation: - -- Fetch the Lottie asset -- Wrap the loading process in `delayRender()` and `continueRender()` -- Save the animation data in a state -- Render the Lottie animation using the `Lottie` component from the `@remotion/lottie` package - -```tsx -import {Lottie, LottieAnimationData} from '@remotion/lottie'; -import {useEffect, useState} from 'react'; -import {cancelRender, continueRender, delayRender} from 'remotion'; - -export const MyAnimation = () => { - const [handle] = useState(() => delayRender('Loading Lottie animation')); - - const [animationData, setAnimationData] = useState<LottieAnimationData | null>(null); - - useEffect(() => { - fetch('https://assets4.lottiefiles.com/packages/lf20_zyquagfl.json') - .then((data) => data.json()) - .then((json) => { - setAnimationData(json); - continueRender(handle); - }) - .catch((err) => { - cancelRender(err); - }); - }, [handle]); - - if (!animationData) { - return null; - } - - return <Lottie animationData={animationData} />; -}; -``` - -## Styling and animating - -Lottie supports the `style` prop to allow styles and animations: - -```tsx -return <Lottie animationData={animationData} style={{width: 400, height: 400}} />; -``` - diff --git a/.opencode/skills/Remotion/Tools/Ref-measuring-dom-nodes.md b/.opencode/skills/Remotion/Tools/Ref-measuring-dom-nodes.md deleted file mode 100644 index 1f9d2bfa..00000000 --- a/.opencode/skills/Remotion/Tools/Ref-measuring-dom-nodes.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -name: measuring-dom-nodes -description: Measuring DOM element dimensions in Remotion -metadata: - tags: measure, layout, dimensions, getBoundingClientRect, scale ---- - -# Measuring DOM nodes in Remotion - -Remotion applies a `scale()` transform to the video container, which affects values from `getBoundingClientRect()`. Use `useCurrentScale()` to get correct measurements. - -## Measuring element dimensions - -```tsx -import { useCurrentScale } from "remotion"; -import { useRef, useEffect, useState } from "react"; - -export const MyComponent = () => { - const ref = useRef<HTMLDivElement>(null); - const scale = useCurrentScale(); - const [dimensions, setDimensions] = useState({ width: 0, height: 0 }); - - useEffect(() => { - if (!ref.current) return; - const rect = ref.current.getBoundingClientRect(); - setDimensions({ - width: rect.width / scale, - height: rect.height / scale, - }); - }, [scale]); - - return <div ref={ref}>Content to measure</div>; -}; -``` - diff --git a/.opencode/skills/Remotion/Tools/Ref-measuring-text.md b/.opencode/skills/Remotion/Tools/Ref-measuring-text.md deleted file mode 100644 index 1bcb33ce..00000000 --- a/.opencode/skills/Remotion/Tools/Ref-measuring-text.md +++ /dev/null @@ -1,143 +0,0 @@ ---- -name: measuring-text -description: Measuring text dimensions, fitting text to containers, and checking overflow -metadata: - tags: measure, text, layout, dimensions, fitText, fillTextBox ---- - -# Measuring text in Remotion - -## Prerequisites - -Install @remotion/layout-utils if it is not already installed: - -```bash -npx remotion add @remotion/layout-utils # If project uses npm -bunx remotion add @remotion/layout-utils # If project uses bun -yarn remotion add @remotion/layout-utils # If project uses yarn -pnpm exec remotion add @remotion/layout-utils # If project uses pnpm -``` - -## Measuring text dimensions - -Use `measureText()` to calculate the width and height of text: - -```tsx -import { measureText } from "@remotion/layout-utils"; - -const { width, height } = measureText({ - text: "Hello World", - fontFamily: "Arial", - fontSize: 32, - fontWeight: "bold", -}); -``` - -Results are cached - duplicate calls return the cached result. - -## Fitting text to a width - -Use `fitText()` to find the optimal font size for a container: - -```tsx -import { fitText } from "@remotion/layout-utils"; - -const { fontSize } = fitText({ - text: "Hello World", - withinWidth: 600, - fontFamily: "Inter", - fontWeight: "bold", -}); - -return ( - <div - style={{ - fontSize: Math.min(fontSize, 80), // Cap at 80px - fontFamily: "Inter", - fontWeight: "bold", - }} - > - Hello World - </div> -); -``` - -## Checking text overflow - -Use `fillTextBox()` to check if text exceeds a box: - -```tsx -import { fillTextBox } from "@remotion/layout-utils"; - -const box = fillTextBox({ maxBoxWidth: 400, maxLines: 3 }); - -const words = ["Hello", "World", "This", "is", "a", "test"]; -for (const word of words) { - const { exceedsBox } = box.add({ - text: word + " ", - fontFamily: "Arial", - fontSize: 24, - }); - if (exceedsBox) { - // Text would overflow, handle accordingly - break; - } -} -``` - -## Best practices - -**Load fonts first:** Only call measurement functions after fonts are loaded. - -```tsx -import { loadFont } from "@remotion/google-fonts/Inter"; - -const { fontFamily, waitUntilDone } = loadFont("normal", { - weights: ["400"], - subsets: ["latin"], -}); - -waitUntilDone().then(() => { - // Now safe to measure - const { width } = measureText({ - text: "Hello", - fontFamily, - fontSize: 32, - }); -}) -``` - -**Use validateFontIsLoaded:** Catch font loading issues early: - -```tsx -measureText({ - text: "Hello", - fontFamily: "MyCustomFont", - fontSize: 32, - validateFontIsLoaded: true, // Throws if font not loaded -}); -``` - -**Match font properties:** Use the same properties for measurement and rendering: - -```tsx -const fontStyle = { - fontFamily: "Inter", - fontSize: 32, - fontWeight: "bold" as const, - letterSpacing: "0.5px", -}; - -const { width } = measureText({ - text: "Hello", - ...fontStyle, -}); - -return <div style={fontStyle}>Hello</div>; -``` - -**Avoid padding and border:** Use `outline` instead of `border` to prevent layout differences: - -```tsx -<div style={{ outline: "2px solid red" }}>Text</div> -``` diff --git a/.opencode/skills/Remotion/Tools/Ref-sequencing.md b/.opencode/skills/Remotion/Tools/Ref-sequencing.md deleted file mode 100644 index 42671376..00000000 --- a/.opencode/skills/Remotion/Tools/Ref-sequencing.md +++ /dev/null @@ -1,106 +0,0 @@ ---- -name: sequencing -description: Sequencing patterns for Remotion - delay, trim, limit duration of items -metadata: - tags: sequence, series, timing, delay, trim ---- - -Use `<Sequence>` to delay when an element appears in the timeline. - -```tsx -import { Sequence } from "remotion"; - -const {fps} = useVideoConfig(); - -<Sequence from={1 * fps} durationInFrames={2 * fps} premountFor={1 * fps}> - <Title /> -</Sequence> -<Sequence from={2 * fps} durationInFrames={2 * fps} premountFor={1 * fps}> - <Subtitle /> -</Sequence> -``` - -This will by default wrap the component in an absolute fill element. -If the items should not be wrapped, use the `layout` prop: - -```tsx -<Sequence layout="none"> - <Title /> -</Sequence> -``` - -## Premounting - -This loads the component in the timeline before it is actually played. -Always premount any `<Sequence>`! - -```tsx -<Sequence premountFor={1 * fps}> - <Title /> -</Sequence> -``` - -## Series - -Use `<Series>` when elements should play one after another without overlap. - -```tsx -import {Series} from 'remotion'; - -<Series> - <Series.Sequence durationInFrames={45}> - <Intro /> - </Series.Sequence> - <Series.Sequence durationInFrames={60}> - <MainContent /> - </Series.Sequence> - <Series.Sequence durationInFrames={30}> - <Outro /> - </Series.Sequence> -</Series>; -``` - -Same as with `<Sequence>`, the items will be wrapped in an absolute fill element by default when using `<Series.Sequence>`, unless the `layout` prop is set to `none`. - -### Series with overlaps - -Use negative offset for overlapping sequences: - -```tsx -<Series> - <Series.Sequence durationInFrames={60}> - <SceneA /> - </Series.Sequence> - <Series.Sequence offset={-15} durationInFrames={60}> - {/* Starts 15 frames before SceneA ends */} - <SceneB /> - </Series.Sequence> -</Series> -``` - -## Frame References Inside Sequences - -Inside a Sequence, `useCurrentFrame()` returns the local frame (starting from 0): - -```tsx -<Sequence from={60} durationInFrames={30}> - <MyComponent /> - {/* Inside MyComponent, useCurrentFrame() returns 0-29, not 60-89 */} -</Sequence> -``` - -## Nested Sequences - -Sequences can be nested for complex timing: - -```tsx -<Sequence from={0} durationInFrames={120}> - <Background /> - <Sequence from={15} durationInFrames={90} layout="none"> - <Title /> - </Sequence> - <Sequence from={45} durationInFrames={60} layout="none"> - <Subtitle /> - </Sequence> -</Sequence> -``` diff --git a/.opencode/skills/Remotion/Tools/Ref-tailwind.md b/.opencode/skills/Remotion/Tools/Ref-tailwind.md deleted file mode 100644 index d2f51952..00000000 --- a/.opencode/skills/Remotion/Tools/Ref-tailwind.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -name: tailwind -description: Using TailwindCSS in Remotion. -metadata: ---- - -You can and should use TailwindCSS in Remotion, if TailwindCSS is installed in the project. - -Don't use `transition-*` or `animate-*` classes - always animate using the `useCurrentFrame()` hook. - -Tailwind must be installed and enabled first in a Remotion project - fetch https://www.remotion.dev/docs/tailwind using WebFetch for instructions. \ No newline at end of file diff --git a/.opencode/skills/Remotion/Tools/Ref-text-animations.md b/.opencode/skills/Remotion/Tools/Ref-text-animations.md deleted file mode 100644 index e38b1c57..00000000 --- a/.opencode/skills/Remotion/Tools/Ref-text-animations.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -name: text-animations -description: Typography and text animation patterns for Remotion. -metadata: - tags: typography, text, typewriter, highlighter ken ---- - -## Text animations - -Based on `useCurrentFrame()`, reduce the string character by character to create a typewriter effect. - -## Typewriter Effect - -See [Typewriter](assets/text-animations-typewriter.tsx) for an advanced example with a blinking cursor and a pause after the first sentence. - -Always use string slicing for typewriter effects. Never use per-character opacity. - -## Word Highlighting - -See [Word Highlight](assets/text-animations-word-highlight.tsx) for an example for how a word highlight is animated, like with a highlighter pen. diff --git a/.opencode/skills/Remotion/Tools/Ref-timing.md b/.opencode/skills/Remotion/Tools/Ref-timing.md deleted file mode 100644 index 464d4e29..00000000 --- a/.opencode/skills/Remotion/Tools/Ref-timing.md +++ /dev/null @@ -1,179 +0,0 @@ ---- -name: timing -description: Interpolation curves in Remotion - linear, easing, spring animations -metadata: - tags: spring, bounce, easing, interpolation ---- - -A simple linear interpolation is done using the `interpolate` function. - -```ts title="Going from 0 to 1 over 100 frames" -import {interpolate} from 'remotion'; - -const opacity = interpolate(frame, [0, 100], [0, 1]); -``` - -By default, the values are not clamped, so the value can go outside the range [0, 1]. -Here is how they can be clamped: - -```ts title="Going from 0 to 1 over 100 frames with extrapolation" -const opacity = interpolate(frame, [0, 100], [0, 1], { - extrapolateRight: 'clamp', - extrapolateLeft: 'clamp', -}); -``` - -## Spring animations - -Spring animations have a more natural motion. -They go from 0 to 1 over time. - -```ts title="Spring animation from 0 to 1 over 100 frames" -import {spring, useCurrentFrame, useVideoConfig} from 'remotion'; - -const frame = useCurrentFrame(); -const {fps} = useVideoConfig(); - -const scale = spring({ - frame, - fps, -}); -``` - -### Physical properties - -The default configuration is: `mass: 1, damping: 10, stiffness: 100`. -This leads to the animation having a bit of bounce before it settles. - -The config can be overwritten like this: - -```ts -const scale = spring({ - frame, - fps, - config: {damping: 200}, -}); -``` - -The recommended configuration for a natural motion without a bounce is: `{ damping: 200 }`. - -Here are some common configurations: - -```tsx -const smooth = {damping: 200}; // Smooth, no bounce (subtle reveals) -const snappy = {damping: 20, stiffness: 200}; // Snappy, minimal bounce (UI elements) -const bouncy = {damping: 8}; // Bouncy entrance (playful animations) -const heavy = {damping: 15, stiffness: 80, mass: 2}; // Heavy, slow, small bounce -``` - -### Delay - -The animation starts immediately by default. -Use the `delay` parameter to delay the animation by a number of frames. - -```tsx -const entrance = spring({ - frame: frame - ENTRANCE_DELAY, - fps, - delay: 20, -}); -``` - -### Duration - -A `spring()` has a natural duration based on the physical properties. -To stretch the animation to a specific duration, use the `durationInFrames` parameter. - -```tsx -const spring = spring({ - frame, - fps, - durationInFrames: 40, -}); -``` - -### Combining spring() with interpolate() - -Map spring output (0-1) to custom ranges: - -```tsx -const springProgress = spring({ - frame, - fps, -}); - -// Map to rotation -const rotation = interpolate(springProgress, [0, 1], [0, 360]); - -<div style={{rotate: rotation + 'deg'}} />; -``` - -### Adding springs - -Springs return just numbers, so math can be performed: - -```tsx -const frame = useCurrentFrame(); -const {fps, durationInFrames} = useVideoConfig(); - -const inAnimation = spring({ - frame, - fps, -}); -const outAnimation = spring({ - frame, - fps, - durationInFrames: 1 * fps, - delay: durationInFrames - 1 * fps, -}); - -const scale = inAnimation - outAnimation; -``` - -## Easing - -Easing can be added to the `interpolate` function: - -```ts -import {interpolate, Easing} from 'remotion'; - -const value1 = interpolate(frame, [0, 100], [0, 1], { - easing: Easing.inOut(Easing.quad), - extrapolateLeft: 'clamp', - extrapolateRight: 'clamp', -}); -``` - -The default easing is `Easing.linear`. -There are various other convexities: - -- `Easing.in` for starting slow and accelerating -- `Easing.out` for starting fast and slowing down -- `Easing.inOut` - -and curves (sorted from most linear to most curved): - -- `Easing.quad` -- `Easing.sin` -- `Easing.exp` -- `Easing.circle` - -Convexities and curves need be combined for an easing function: - -```ts -const value1 = interpolate(frame, [0, 100], [0, 1], { - easing: Easing.inOut(Easing.quad), - extrapolateLeft: 'clamp', - extrapolateRight: 'clamp', -}); -``` - -Cubic bezier curves are also supported: - -```ts -const value1 = interpolate(frame, [0, 100], [0, 1], { - easing: Easing.bezier(0.8, 0.22, 0.96, 0.65), - extrapolateLeft: 'clamp', - extrapolateRight: 'clamp', -}); -``` diff --git a/.opencode/skills/Remotion/Tools/Ref-transcribe-captions.md b/.opencode/skills/Remotion/Tools/Ref-transcribe-captions.md deleted file mode 100644 index b338486b..00000000 --- a/.opencode/skills/Remotion/Tools/Ref-transcribe-captions.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -name: transcribe-captions -description: Transcribing audio to generate captions in Remotion -metadata: - tags: captions, transcribe, whisper, audio, speech-to-text ---- - -# Transcribing audio - -Remotion provides several built-in options for transcribing audio to generate captions: - -- `@remotion/install-whisper-cpp` - Transcribe locally on a server using Whisper.cpp. Fast and free, but requires server infrastructure. - https://remotion.dev/docs/install-whisper-cpp - -- `@remotion/whisper-web` - Transcribe in the browser using WebAssembly. No server needed and free, but slower due to WASM overhead. - https://remotion.dev/docs/whisper-web - -- `@remotion/openai-whisper` - Use OpenAI Whisper API for cloud-based transcription. Fast and no server needed, but requires payment. - https://remotion.dev/docs/openai-whisper/openai-whisper-api-to-captions diff --git a/.opencode/skills/Remotion/Tools/Ref-transitions.md b/.opencode/skills/Remotion/Tools/Ref-transitions.md deleted file mode 100644 index c363cd19..00000000 --- a/.opencode/skills/Remotion/Tools/Ref-transitions.md +++ /dev/null @@ -1,122 +0,0 @@ ---- -name: transitions -description: Fullscreen scene transitions for Remotion. -metadata: - tags: transitions, fade, slide, wipe, scenes ---- - -## Fullscreen transitions - -Using `<TransitionSeries>` to animate between multiple scenes or clips. -This will absolutely position the children. - -## Prerequisites - -First, the @remotion/transitions package needs to be installed. -If it is not, use the following command: - -```bash -npx remotion add @remotion/transitions # If project uses npm -bunx remotion add @remotion/transitions # If project uses bun -yarn remotion add @remotion/transitions # If project uses yarn -pnpm exec remotion add @remotion/transitions # If project uses pnpm -``` - -## Example usage - -```tsx -import {TransitionSeries, linearTiming} from '@remotion/transitions'; -import {fade} from '@remotion/transitions/fade'; - -<TransitionSeries> - <TransitionSeries.Sequence durationInFrames={60}> - <SceneA /> - </TransitionSeries.Sequence> - <TransitionSeries.Transition presentation={fade()} timing={linearTiming({durationInFrames: 15})} /> - <TransitionSeries.Sequence durationInFrames={60}> - <SceneB /> - </TransitionSeries.Sequence> -</TransitionSeries>; -``` - -## Available Transition Types - -Import transitions from their respective modules: - -```tsx -import {fade} from '@remotion/transitions/fade'; -import {slide} from '@remotion/transitions/slide'; -import {wipe} from '@remotion/transitions/wipe'; -import {flip} from '@remotion/transitions/flip'; -import {clockWipe} from '@remotion/transitions/clock-wipe'; -``` - -## Slide Transition with Direction - -Specify slide direction for enter/exit animations. - -```tsx -import {slide} from '@remotion/transitions/slide'; - -<TransitionSeries.Transition presentation={slide({direction: 'from-left'})} timing={linearTiming({durationInFrames: 20})} />; -``` - -Directions: `"from-left"`, `"from-right"`, `"from-top"`, `"from-bottom"` - -## Timing Options - -```tsx -import {linearTiming, springTiming} from '@remotion/transitions'; - -// Linear timing - constant speed -linearTiming({durationInFrames: 20}); - -// Spring timing - organic motion -springTiming({config: {damping: 200}, durationInFrames: 25}); -``` - -## Duration calculation - -Transitions overlap adjacent scenes, so the total composition length is **shorter** than the sum of all sequence durations. - -For example, with two 60-frame sequences and a 15-frame transition: - -- Without transitions: `60 + 60 = 120` frames -- With transition: `60 + 60 - 15 = 105` frames - -The transition duration is subtracted because both scenes play simultaneously during the transition. - -### Getting the duration of a transition - -Use the `getDurationInFrames()` method on the timing object: - -```tsx -import {linearTiming, springTiming} from '@remotion/transitions'; - -const linearDuration = linearTiming({durationInFrames: 20}).getDurationInFrames({fps: 30}); -// Returns 20 - -const springDuration = springTiming({config: {damping: 200}}).getDurationInFrames({fps: 30}); -// Returns calculated duration based on spring physics -``` - -For `springTiming` without an explicit `durationInFrames`, the duration depends on `fps` because it calculates when the spring animation settles. - -### Calculating total composition duration - -```tsx -import {linearTiming} from '@remotion/transitions'; - -const scene1Duration = 60; -const scene2Duration = 60; -const scene3Duration = 60; - -const timing1 = linearTiming({durationInFrames: 15}); -const timing2 = linearTiming({durationInFrames: 20}); - -const transition1Duration = timing1.getDurationInFrames({fps: 30}); -const transition2Duration = timing2.getDurationInFrames({fps: 30}); - -const totalDuration = scene1Duration + scene2Duration + scene3Duration - transition1Duration - transition2Duration; -// 60 + 60 + 60 - 15 - 20 = 145 frames -``` diff --git a/.opencode/skills/Remotion/Tools/Ref-trimming.md b/.opencode/skills/Remotion/Tools/Ref-trimming.md deleted file mode 100644 index f20963a3..00000000 --- a/.opencode/skills/Remotion/Tools/Ref-trimming.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -name: trimming -description: Trimming patterns for Remotion - cut the beginning or end of animations -metadata: - tags: sequence, trim, clip, cut, offset ---- - -Use `<Sequence>` with a negative `from` value to trim the start of an animation. - -## Trim the Beginning - -A negative `from` value shifts time backwards, making the animation start partway through: - -```tsx -import { Sequence, useVideoConfig } from "remotion"; - -const fps = useVideoConfig(); - -<Sequence from={-0.5 * fps}> - <MyAnimation /> -</Sequence> -``` - -The animation appears 15 frames into its progress - the first 15 frames are trimmed off. -Inside `<MyAnimation>`, `useCurrentFrame()` starts at 15 instead of 0. - -## Trim the End - -Use `durationInFrames` to unmount content after a specified duration: - -```tsx - -<Sequence durationInFrames={1.5 * fps}> - <MyAnimation /> -</Sequence> -``` - -The animation plays for 45 frames, then the component unmounts. - -## Trim and Delay - -Nest sequences to both trim the beginning and delay when it appears: - -```tsx -<Sequence from={30}> - <Sequence from={-15}> - <MyAnimation /> - </Sequence> -</Sequence> -``` - -The inner sequence trims 15 frames from the start, and the outer sequence delays the result by 30 frames. - diff --git a/.opencode/skills/Remotion/Tools/Ref-videos.md b/.opencode/skills/Remotion/Tools/Ref-videos.md deleted file mode 100644 index 4d99b31e..00000000 --- a/.opencode/skills/Remotion/Tools/Ref-videos.md +++ /dev/null @@ -1,171 +0,0 @@ ---- -name: videos -description: Embedding videos in Remotion - trimming, volume, speed, looping, pitch -metadata: - tags: video, media, trim, volume, speed, loop, pitch ---- - -# Using videos in Remotion - -## Prerequisites - -First, the @remotion/media package needs to be installed. -If it is not, use the following command: - -```bash -npx remotion add @remotion/media # If project uses npm -bunx remotion add @remotion/media # If project uses bun -yarn remotion add @remotion/media # If project uses yarn -pnpm exec remotion add @remotion/media # If project uses pnpm -``` - -Use `<Video>` from `@remotion/media` to embed videos into your composition. - -```tsx -import { Video } from "@remotion/media"; -import { staticFile } from "remotion"; - -export const MyComposition = () => { - return <Video src={staticFile("video.mp4")} />; -}; -``` - -Remote URLs are also supported: - -```tsx -<Video src="https://remotion.media/video.mp4" /> -``` - -## Trimming - -Use `trimBefore` and `trimAfter` to remove portions of the video. Values are in seconds. - -```tsx -const { fps } = useVideoConfig(); - -return ( - <Video - src={staticFile("video.mp4")} - trimBefore={2 * fps} // Skip the first 2 seconds - trimAfter={10 * fps} // End at the 10 second mark - /> -); -``` - -## Delaying - -Wrap the video in a `<Sequence>` to delay when it appears: - -```tsx -import { Sequence, staticFile } from "remotion"; -import { Video } from "@remotion/media"; - -const { fps } = useVideoConfig(); - -return ( - <Sequence from={1 * fps}> - <Video src={staticFile("video.mp4")} /> - </Sequence> -); -``` - -The video will appear after 1 second. - -## Sizing and Position - -Use the `style` prop to control size and position: - -```tsx -<Video - src={staticFile("video.mp4")} - style={{ - width: 500, - height: 300, - position: "absolute", - top: 100, - left: 50, - objectFit: "cover", - }} -/> -``` - -## Volume - -Set a static volume (0 to 1): - -```tsx -<Video src={staticFile("video.mp4")} volume={0.5} /> -``` - -Or use a callback for dynamic volume based on the current frame: - -```tsx -import { interpolate } from "remotion"; - -const { fps } = useVideoConfig(); - -return ( - <Video - src={staticFile("video.mp4")} - volume={(f) => - interpolate(f, [0, 1 * fps], [0, 1], { extrapolateRight: "clamp" }) - } - /> -); -``` - -Use `muted` to silence the video entirely: - -```tsx -<Video src={staticFile("video.mp4")} muted /> -``` - -## Speed - -Use `playbackRate` to change the playback speed: - -```tsx -<Video src={staticFile("video.mp4")} playbackRate={2} /> {/* 2x speed */} -<Video src={staticFile("video.mp4")} playbackRate={0.5} /> {/* Half speed */} -``` - -Reverse playback is not supported. - -## Looping - -Use `loop` to loop the video indefinitely: - -```tsx -<Video src={staticFile("video.mp4")} loop /> -``` - -Use `loopVolumeCurveBehavior` to control how the frame count behaves when looping: - -- `"repeat"`: Frame count resets to 0 each loop (for `volume` callback) -- `"extend"`: Frame count continues incrementing - -```tsx -<Video - src={staticFile("video.mp4")} - loop - loopVolumeCurveBehavior="extend" - volume={(f) => interpolate(f, [0, 300], [1, 0])} // Fade out over multiple loops -/> -``` - -## Pitch - -Use `toneFrequency` to adjust the pitch without affecting speed. Values range from 0.01 to 2: - -```tsx -<Video - src={staticFile("video.mp4")} - toneFrequency={1.5} // Higher pitch -/> -<Video - src={staticFile("video.mp4")} - toneFrequency={0.8} // Lower pitch -/> -``` - -Pitch shifting only works during server-side rendering, not in the Remotion Studio preview or in the `<Player />`. diff --git a/.opencode/skills/Remotion/Tools/Render.ts b/.opencode/skills/Remotion/Tools/Render.ts deleted file mode 100644 index 75a271d8..00000000 --- a/.opencode/skills/Remotion/Tools/Render.ts +++ /dev/null @@ -1,343 +0,0 @@ -/** - * Remotion Code-First Interface - * - * TypeScript wrappers for Remotion CLI operations. - * Enables programmatic video rendering with full control. - */ - -import { $ } from 'bun' - -export interface RenderOptions { - /** Composition ID to render */ - compositionId: string - /** Output file path */ - outputPath: string - /** Video codec */ - codec?: 'h264' | 'h265' | 'vp8' | 'vp9' | 'prores' | 'gif' - /** Constant Rate Factor (quality, lower = better, 0-51) */ - crf?: number - /** Frames per second */ - fps?: number - /** Video width */ - width?: number - /** Video height */ - height?: number - /** Props to pass to composition */ - inputProps?: Record<string, any> - /** Project directory (defaults to cwd) */ - projectDir?: string - /** Specific frames to render (e.g., "0-100") */ - frames?: string - /** Image sequence output format */ - imageFormat?: 'png' | 'jpeg' - /** JPEG quality (0-100) */ - jpegQuality?: number - /** Scale factor */ - scale?: number - /** Mute audio */ - muted?: boolean - /** Audio codec */ - audioCodec?: 'aac' | 'mp3' | 'opus' | 'wav' | 'pcm' - /** Number of render threads */ - concurrency?: number - /** Verbose output */ - verbose?: boolean -} - -export interface Composition { - id: string - width: number - height: number - fps: number - durationInFrames: number - defaultProps?: Record<string, any> -} - -export interface RenderResult { - success: boolean - outputPath: string - duration?: number - error?: string -} - -/** - * Render a Remotion composition to video file - * - * @param options - Render configuration - * @returns Render result - */ -export async function render(options: RenderOptions): Promise<RenderResult> { - const args: string[] = ['npx', 'remotion', 'render', options.compositionId, options.outputPath] - - if (options.codec) args.push('--codec', options.codec) - if (options.crf !== undefined) args.push('--crf', String(options.crf)) - if (options.fps) args.push('--fps', String(options.fps)) - if (options.width) args.push('--width', String(options.width)) - if (options.height) args.push('--height', String(options.height)) - if (options.frames) args.push('--frames', options.frames) - if (options.imageFormat) args.push('--image-format', options.imageFormat) - if (options.jpegQuality) args.push('--jpeg-quality', String(options.jpegQuality)) - if (options.scale) args.push('--scale', String(options.scale)) - if (options.muted) args.push('--muted') - if (options.audioCodec) args.push('--audio-codec', options.audioCodec) - if (options.concurrency) args.push('--concurrency', String(options.concurrency)) - - if (options.inputProps) { - args.push('--props', JSON.stringify(options.inputProps)) - } - - const startTime = Date.now() - const cwd = options.projectDir || process.cwd() - - try { - const result = await $`${args}`.cwd(cwd).text() - const duration = (Date.now() - startTime) / 1000 - - return { - success: true, - outputPath: options.outputPath, - duration - } - } catch (error: any) { - return { - success: false, - outputPath: options.outputPath, - error: error.message || String(error) - } - } -} - -/** - * Render a still image from a composition - * - * @param options - Still render configuration - * @returns Render result - */ -export async function renderStill(options: { - compositionId: string - outputPath: string - frame?: number - inputProps?: Record<string, any> - projectDir?: string - imageFormat?: 'png' | 'jpeg' - jpegQuality?: number - scale?: number -}): Promise<RenderResult> { - const args: string[] = ['npx', 'remotion', 'still', options.compositionId, options.outputPath] - - if (options.frame !== undefined) args.push('--frame', String(options.frame)) - if (options.imageFormat) args.push('--image-format', options.imageFormat) - if (options.jpegQuality) args.push('--jpeg-quality', String(options.jpegQuality)) - if (options.scale) args.push('--scale', String(options.scale)) - - if (options.inputProps) { - args.push('--props', JSON.stringify(options.inputProps)) - } - - const cwd = options.projectDir || process.cwd() - - try { - await $`${args}`.cwd(cwd).text() - - return { - success: true, - outputPath: options.outputPath - } - } catch (error: any) { - return { - success: false, - outputPath: options.outputPath, - error: error.message || String(error) - } - } -} - -/** - * List all compositions in a Remotion project - * - * @param projectDir - Project directory (defaults to cwd) - * @returns Array of compositions - */ -export async function listCompositions(projectDir?: string): Promise<Composition[]> { - const cwd = projectDir || process.cwd() - - try { - const result = await $`npx remotion compositions --json`.cwd(cwd).text() - return JSON.parse(result) - } catch (error: any) { - console.error('Failed to list compositions:', error.message) - return [] - } -} - -/** - * Start the Remotion studio preview server - * - * @param options - Studio options - */ -export async function startStudio(options?: { - projectDir?: string - port?: number - browserArgs?: string[] -}): Promise<void> { - const args: string[] = ['npx', 'remotion', 'studio'] - - if (options?.port) args.push('--port', String(options.port)) - - const cwd = options?.projectDir || process.cwd() - - // Run in background - studio stays open - $`${args}`.cwd(cwd).nothrow() - - console.log(`Remotion Studio starting at http://localhost:${options?.port || 3000}`) -} - -/** - * Create a new Remotion project - * - * @param options - Project creation options - */ -export async function createProject(options: { - name: string - template?: 'blank' | 'hello-world' | 'three' | 'audiogram' | 'tts' - outputDir?: string -}): Promise<{ success: boolean; path: string; error?: string }> { - const args: string[] = ['npx', 'create-video@latest', options.name] - - if (options.template) { - args.push('--template', options.template) - } - - const cwd = options.outputDir || process.cwd() - - try { - await $`${args}`.cwd(cwd).text() - - return { - success: true, - path: `${cwd}/${options.name}` - } - } catch (error: any) { - return { - success: false, - path: `${cwd}/${options.name}`, - error: error.message || String(error) - } - } -} - -/** - * Upgrade Remotion packages in a project - * - * @param projectDir - Project directory - */ -export async function upgrade(projectDir?: string): Promise<{ success: boolean; error?: string }> { - const cwd = projectDir || process.cwd() - - try { - await $`npx remotion upgrade`.cwd(cwd).text() - return { success: true } - } catch (error: any) { - return { - success: false, - error: error.message || String(error) - } - } -} - -/** - * Get video metadata using Mediabunny - */ -export async function getVideoMetadata(videoPath: string): Promise<{ - width: number - height: number - durationInSeconds: number - fps: number -} | null> { - try { - // This requires @remotion/media-utils in the project - const result = await $`npx remotion parse-video ${videoPath} --json`.text() - return JSON.parse(result) - } catch { - return null - } -} - -/** - * Get audio duration using Mediabunny - */ -export async function getAudioDuration(audioPath: string): Promise<number | null> { - try { - const result = await $`npx remotion parse-audio ${audioPath} --json`.text() - const data = JSON.parse(result) - return data.durationInSeconds - } catch { - return null - } -} - -// CLI entry point -if (import.meta.main) { - const args = process.argv.slice(2) - const command = args[0] - - switch (command) { - case 'render': { - const [_, compositionId, outputPath, ...rest] = args - if (!compositionId || !outputPath) { - console.error('Usage: bun run index.ts render <compositionId> <outputPath> [--crf N] [--fps N]') - process.exit(1) - } - - const options: RenderOptions = { compositionId, outputPath } - - // Parse optional args - for (let i = 0; i < rest.length; i++) { - if (rest[i] === '--crf' && rest[i + 1]) options.crf = parseInt(rest[++i]) - if (rest[i] === '--fps' && rest[i + 1]) options.fps = parseInt(rest[++i]) - if (rest[i] === '--codec' && rest[i + 1]) options.codec = rest[++i] as any - if (rest[i] === '--width' && rest[i + 1]) options.width = parseInt(rest[++i]) - if (rest[i] === '--height' && rest[i + 1]) options.height = parseInt(rest[++i]) - } - - const result = await render(options) - console.log(JSON.stringify(result, null, 2)) - break - } - - case 'list': { - const compositions = await listCompositions(args[1]) - console.log(JSON.stringify(compositions, null, 2)) - break - } - - case 'create': { - const name = args[1] - const template = args[2] as any - - if (!name) { - console.error('Usage: bun run index.ts create <name> [template]') - process.exit(1) - } - - const result = await createProject({ name, template }) - console.log(JSON.stringify(result, null, 2)) - break - } - - default: - console.log(` -Remotion CLI Wrapper - -Commands: - render <compositionId> <outputPath> [--crf N] [--fps N] [--codec TYPE] - list [projectDir] - create <name> [template] - -Examples: - bun run index.ts render my-video out/video.mp4 --crf 18 - bun run index.ts list - bun run index.ts create new-project hello-world -`) - } -} diff --git a/.opencode/skills/Remotion/Tools/Theme.ts b/.opencode/skills/Remotion/Tools/Theme.ts deleted file mode 100644 index 12fe555c..00000000 --- a/.opencode/skills/Remotion/Tools/Theme.ts +++ /dev/null @@ -1,130 +0,0 @@ -/** - * PAI Theme for Remotion - * - * Derived from Art skill preferences at: - * .opencode/skills/PAI/USER/SKILLCUSTOMIZATIONS/Art/PREFERENCES.md - * - * Core aesthetic: Charcoal architectural sketch with purple accents - * Visual feel: Monumental emotional spaces, gestural linework, cool washes - */ - -export const PAI_THEME = { - // Colors (from Art color palette) - colors: { - // Backgrounds (vast architectural space feel) - background: '#0f172a', // Deep slate - backgroundAlt: '#1e293b', // Slightly lighter slate - backgroundDark: '#020617', // Near black - - // Accents (purple/violet from Art prefs) - accent: '#8b5cf6', // Primary purple - accentLight: '#a78bfa', // Lighter purple - accentDark: '#7c3aed', // Darker purple - accentMuted: '#6366f1', // Indigo variant - - // Text (paper ground inspired) - text: '#f1f5f9', // Light text - textMuted: '#94a3b8', // Muted/secondary text - textDark: '#64748b', // De-emphasized text - - // Special - paperGround: '#F5F5F0', // Cream/off-white from Art prefs - coolWash: 'rgba(139, 92, 246, 0.1)', // Purple atmospheric wash - warmWash: 'rgba(251, 191, 36, 0.1)', // Amber contrast wash - - // Utility - success: '#10b981', // Green - warning: '#f59e0b', // Amber - error: '#ef4444', // Red - info: '#3b82f6', // Blue - }, - - // Typography (production design quality) - typography: { - fontFamily: 'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif', - fontFamilyMono: 'ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace', - - // Size scale - title: { fontSize: 72, fontWeight: 'bold' as const, lineHeight: 1.1 }, - subtitle: { fontSize: 48, fontWeight: '600' as const, lineHeight: 1.2 }, - heading: { fontSize: 36, fontWeight: '600' as const, lineHeight: 1.3 }, - body: { fontSize: 24, fontWeight: 'normal' as const, lineHeight: 1.5 }, - caption: { fontSize: 18, fontWeight: 'normal' as const, lineHeight: 1.4 }, - small: { fontSize: 14, fontWeight: 'normal' as const, lineHeight: 1.4 }, - }, - - // Animation feel (gestural, organic - not mechanical) - animation: { - // Spring configs (organic feel like gestural linework) - springFast: { damping: 15, stiffness: 150 }, - springDefault: { damping: 12, stiffness: 100 }, - springSlow: { damping: 10, stiffness: 80 }, - springBouncy: { damping: 8, stiffness: 120 }, - - // Frame durations at 30fps - fadeFrames: 30, // ~1 second fade - quickFade: 15, // ~0.5 second - slowFade: 45, // ~1.5 seconds - - // Stagger delays - staggerDelay: 10, // Frames between sequential elements - staggerFast: 5, // Quick succession - staggerSlow: 15, // Dramatic reveal - }, - - // Spacing (human-scale in vast spaces) - spacing: { - page: 100, // Edge padding for full-screen - section: 60, // Between major sections - element: 30, // Between related elements - tight: 15, // Compact spacing - - // For text blocks - paragraphGap: 24, - listItemGap: 16, - }, - - // Shadows and effects - effects: { - textShadow: '0 2px 4px rgba(0,0,0,0.5)', - boxShadow: '0 4px 6px -1px rgba(0,0,0,0.1), 0 2px 4px -1px rgba(0,0,0,0.06)', - boxShadowLarge: '0 10px 15px -3px rgba(0,0,0,0.1), 0 4px 6px -2px rgba(0,0,0,0.05)', - glow: '0 0 20px rgba(139, 92, 246, 0.5)', - }, - - // Border radius - borderRadius: { - small: 8, - medium: 16, - large: 24, - full: 9999, - }, -} as const - -// Type exports -export type PAITheme = typeof PAI_THEME -export type PAIColors = typeof PAI_THEME.colors -export type PAITypography = typeof PAI_THEME.typography -export type PAIAnimation = typeof PAI_THEME.animation - -// Utility: Get interpolate input/output for fade -export const fadeInterpolation = (startFrame = 0) => ({ - inputRange: [startFrame, startFrame + PAI_THEME.animation.fadeFrames], - outputRange: [0, 1] as [number, number], -}) - -// Utility: Style preset for centered title screen -export const titleScreenStyle = { - backgroundColor: PAI_THEME.colors.background, - display: 'flex' as const, - justifyContent: 'center' as const, - alignItems: 'center' as const, - fontFamily: PAI_THEME.typography.fontFamily, -} - -// Utility: Style preset for content screen -export const contentScreenStyle = { - backgroundColor: PAI_THEME.colors.background, - padding: PAI_THEME.spacing.page, - fontFamily: PAI_THEME.typography.fontFamily, -} diff --git a/.opencode/skills/Remotion/Tools/package.json b/.opencode/skills/Remotion/Tools/package.json deleted file mode 100644 index dc51e4ed..00000000 --- a/.opencode/skills/Remotion/Tools/package.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "name": "@pai/remotion", - "version": "1.0.0", - "description": "PAI Remotion skill - programmatic video creation with React", - "main": "index.ts", - "type": "module", - "scripts": { - "render": "bun run index.ts render", - "list": "bun run index.ts list", - "create": "bun run index.ts create" - }, - "keywords": [ - "remotion", - "video", - "react", - "animation", - "pai", - "skill" - ], - "dependencies": {}, - "peerDependencies": { - "remotion": ">=4.0.0" - }, - "devDependencies": { - "bun-types": "latest", - "typescript": "^5.0.0" - } -} diff --git a/.opencode/skills/Research/MigrationNotes.md b/.opencode/skills/Research/MigrationNotes.md new file mode 100755 index 00000000..523a4191 --- /dev/null +++ b/.opencode/skills/Research/MigrationNotes.md @@ -0,0 +1,121 @@ +# Research Skill Migration - Skills-as-Containers Architecture + +**Date:** 2025-10-31 +**Intern Agent:** Nova +**Architecture:** Skills-as-Containers + +## Migration Summary + +Successfully migrated 4 research commands to the research skill's workflows directory, following the Skills-as-Containers architecture pattern. + +## Files Migrated + +### 1. Claude WebSearch Research +- **Source:** `~/.opencode/commands/perform-claude-research.md` +- **Destination:** `~/.opencode/skills/Research/Workflows/ClaudeResearch.md` +- **Size:** 3.6K +- **Description:** Intelligent query decomposition with Claude's WebSearch tool (free, no API keys) +- **Triggers:** "claude research", "use websearch", "claude only" + +### 2. Perplexity API Research +- **Source:** `~/.opencode/commands/perform-perplexity-research.md` +- **Destination:** `~/.opencode/skills/Research/Workflows/PerplexityResearch.md` +- **Size:** 8.1K +- **Description:** Fast web search with query decomposition via Perplexity API +- **Triggers:** "perplexity research", "use perplexity", "sonar" + +### 3. Interview Preparation +- **Source:** `~/.opencode/commands/perform-interview-research.md` +- **Destination:** `~/.opencode/skills/Research/Workflows/InterviewResearch.md` +- **Size:** 4.4K +- **Description:** Tyler Cowen-style interview prep with Shannon surprise principle +- **Triggers:** "interview research", "prepare interview questions", "sponsored interview" + +### 4. AI Trends Analysis +- **Source:** `~/.opencode/commands/analyze-ai-trends.md` +- **Destination:** `~/.opencode/skills/Research/Workflows/AnalyzeAiTrends.md` +- **Size:** 3.0K +- **Description:** Deep trend analysis across historical AI news logs +- **Triggers:** "analyze ai trends", "trend analysis", "ai industry trends" + +## Workflows Directory Status + +**Location:** `~/.opencode/skills/Research/Workflows/` + +**Note (2026-01):** Conduct.md and PerplexityResearch.md were later removed. Perplexity functionality consolidated into QuickResearch.md (single-agent) and StandardResearch.md (multi-agent). + +**Current Workflows:** 13 +- `AnalyzeAiTrends.md` - AI industry trend analysis +- `ClaudeResearch.md` - Claude WebSearch only +- `Enhance.md` - Content enhancement +- `ExtensiveResearch.md` - 12-agent parallel research +- `ExtractAlpha.md` - Deep insight extraction +- `ExtractKnowledge.md` - Knowledge extraction +- `Fabric.md` - 242+ Fabric patterns +- `InterviewResearch.md` - Tyler Cowen-style prep +- `QuickResearch.md` - 1 Perplexity agent (fast) +- `Retrieve.md` - Content retrieval with anti-bot handling +- `StandardResearch.md` - 3-agent default research +- `WebScraping.md` - Web scraping workflows +- `YoutubeExtraction.md` - YouTube content extraction + +## SKILL.md Updates + +Added comprehensive routing section: + +### Research Workflow Routing + +Based on the type of research request, route to the appropriate workflow: + +1. **Quick Research (Single Perplexity)** - `Workflows/QuickResearch.md` +2. **Standard Research (Default)** - `Workflows/StandardResearch.md` +3. **Extensive Research (12 agents)** - `Workflows/ExtensiveResearch.md` +4. **Claude WebSearch Research** - `Workflows/ClaudeResearch.md` +5. **Interview Preparation** - `Workflows/InterviewResearch.md` +6. **AI Trends Analysis** - `Workflows/AnalyzeAiTrends.md` + +Each workflow has: +- Clear location path +- Trigger phrases for routing +- Brief description of purpose + +## Original Files Status + +✅ **ALL ORIGINALS PRESERVED** + +The original command files remain in `~/.opencode/commands/`: +- `perform-claude-research.md` ✓ +- `perform-perplexity-research.md` ✓ +- `perform-interview-research.md` ✓ +- `analyze-ai-trends.md` ✓ + +## Success Criteria Met + +✅ 4 new commands in Workflows/ (5 total with conduct.md) +✅ SKILL.md routing updated with clear triggers +✅ Originals preserved in commands/ directory +✅ Skills-as-Containers architecture followed + +## Benefits of Migration + +1. **Centralized Research Logic:** All research workflows now live within the research skill +2. **Clear Routing:** SKILL.md provides explicit routing based on user triggers +3. **Skills-as-Containers:** Follows the established architecture pattern +4. **Backwards Compatible:** Original commands preserved for reference/rollback +5. **Scalable:** Easy to add more research workflows in the future + +## Next Steps + +Consider: +1. Adding workflow-specific documentation for each research type +2. Creating example outputs for each workflow +3. Potentially deprecating original command files once migration is validated +4. Adding cross-workflow coordination patterns (e.g., "do both perplexity and claude research") + +## Architecture Pattern + +This migration follows the **Skills-as-Containers** pattern where: +- Skills are self-contained directories +- Workflows live in `Workflows/` subdirectory +- SKILL.md provides routing and documentation +- Original commands can be deprecated after validation diff --git a/.opencode/skills/Research/Templates/MarketResearch.md b/.opencode/skills/Research/Templates/MarketResearch.md new file mode 100644 index 00000000..1e3d8c29 --- /dev/null +++ b/.opencode/skills/Research/Templates/MarketResearch.md @@ -0,0 +1,272 @@ +# Market Research Domain Template + +Domain-specific configuration for the Deep Investigation workflow applied to market analysis. + +--- + +## Entity Categories + +| Category | Description | Target Count | +|----------|-------------|-------------| +| **Companies** | Businesses operating in this market (startups, incumbents, adjacent) | 8-15 | +| **Products** | Key products/services/platforms in the market | 5-10 | +| **People** | Founders, executives, investors, analysts shaping the market | 5-10 | +| **Technologies** | Core technologies, frameworks, standards enabling the market | 3-8 | +| **Trends** | Market movements, shifts, emerging patterns | 3-6 | +| **Investors** | VCs, firms, and funding sources active in this market | 3-8 | + +--- + +## Evaluation Criteria (What Makes Something CRITICAL?) + +**Companies:** +- CRITICAL: Market leaders with >10% share, category creators, companies everyone references +- HIGH: Well-funded challengers, companies with unique approaches, acquisition targets +- MEDIUM: Niche players with specialized focus +- LOW: Early-stage with unproven traction + +**Products:** +- CRITICAL: Category-defining products, industry standards +- HIGH: Strong adoption, innovative approaches, frequently compared +- MEDIUM: Solid but not differentiated +- LOW: New/unproven or declining + +**People:** +- CRITICAL: Founders of CRITICAL companies, top analysts whose opinions move markets +- HIGH: Influential voices, repeat founders, key investors +- MEDIUM: Notable contributors, rising figures +- LOW: Peripheral involvement + +**Technologies:** +- CRITICAL: Foundational tech that enables the entire market +- HIGH: Widely adopted frameworks/standards +- MEDIUM: Emerging tech with growing adoption +- LOW: Experimental, limited adoption + +--- + +## Search Strategies + +**For landscape (Step 1):** +- "[market] market size 2025 2026" +- "[market] competitive landscape analysis" +- "[market] industry report key players" +- "[market] venture funding trends" +- "Gartner|Forrester|IDC [market] analysis" + +**For entity discovery (Step 3):** +- "[market] startups to watch" +- "[market] top companies list" +- "[market] funding rounds recent" +- "[market] key executives leaders" +- "[market] technology stack overview" + +**For deep investigation (Step 4):** +- "[entity name] funding history crunchbase" +- "[entity name] product review comparison" +- "[entity name] CEO interview podcast" +- "[entity name] revenue customers case study" +- "[entity name] competitors alternative" + +--- + +## Profile Templates + +### Company Profile + +```markdown +# {Company Name} + +## Overview +- **Founded:** {year} +- **HQ:** {location} +- **Stage:** {Seed/Series A/B/C/Public/Acquired} +- **Employees:** {count or range} +- **Website:** {url} + +## What They Do +[2-3 sentences: what the company does, who it serves, core value prop] + +## Funding & Financials +- **Total Raised:** {amount} +- **Last Round:** {amount, date, lead investor} +- **Key Investors:** {list} +- **Revenue Indicators:** {public info, estimates, growth signals} + +## Product & Technology +- **Core Product:** {name, description} +- **Technology:** {tech stack, key innovations} +- **Target Market:** {customer segment, use case} +- **Pricing Model:** {pricing approach} + +## Competitive Position +- **Strengths:** {2-3 bullets} +- **Weaknesses:** {2-3 bullets} +- **Key Differentiator:** {what sets them apart} +- **Primary Competitors:** [links to other profiles] + +## Leadership +- **CEO/Founder:** {name, background} +- **Key Executives:** {notable hires} + +## Recent Developments +- {date}: {development} +- {date}: {development} + +## Market Significance +[Why this company matters in the landscape. 2-3 sentences.] + +## Sources +[Verified URLs only] +``` + +### Product Profile + +```markdown +# {Product Name} + +## Overview +- **Company:** [link to company profile] +- **Category:** {product category} +- **Launched:** {year} +- **Pricing:** {model and range} + +## Core Capabilities +- {capability 1} +- {capability 2} +- {capability 3} + +## Target Users +[Who uses this and why] + +## Competitive Comparison +| Feature | {This Product} | {Competitor 1} | {Competitor 2} | +|---------|---------------|----------------|----------------| +| {feature} | {status} | {status} | {status} | + +## Adoption & Traction +- **Users/Customers:** {numbers or indicators} +- **Notable Customers:** {names} +- **Growth Signals:** {evidence} + +## Strengths & Weaknesses +- **Strengths:** {bullets} +- **Weaknesses:** {bullets} + +## Sources +[Verified URLs only] +``` + +### Person Profile + +```markdown +# {Person Name} + +## Overview +- **Current Role:** {title at company} [link to company profile] +- **Background:** {1-sentence career summary} +- **Location:** {city} + +## Career History +- {year-present}: {role at company} +- {year-year}: {previous role} +- {year-year}: {earlier role} + +## Significance +[Why this person matters in the market. What influence do they have?] + +## Thought Leadership +- {topic}: {where they've published/spoken} +- Notable takes: {key positions or predictions} + +## Connections +- Companies: [links to related company profiles] +- Other People: [links to related person profiles] + +## Sources +[Verified URLs only] +``` + +### Technology Profile + +```markdown +# {Technology Name} + +## Overview +- **Type:** {framework/protocol/standard/platform} +- **Created by:** {origin} +- **Maturity:** {experimental/emerging/mainstream/legacy} + +## What It Does +[2-3 sentences explaining the technology] + +## Adoption +- **Key Users:** {companies, products using it} +- **Market Penetration:** {adoption indicators} + +## Significance +[Why this technology matters for the market] + +## Alternatives +- {alternative 1}: {how it compares} +- {alternative 2}: {how it compares} + +## Sources +[Verified URLs only] +``` + +### Trend Profile + +```markdown +# {Trend Name} + +## Overview +[What is this trend? 2-3 sentences] + +## Evidence +- {data point or signal 1} +- {data point or signal 2} +- {data point or signal 3} + +## Drivers +[What's causing this trend?] + +## Impact +- **Winners:** {who benefits} +- **Losers:** {who's disrupted} +- **Timeline:** {when does this play out} + +## Connected Entities +- Companies: [links to related profiles] +- Technologies: [links to related profiles] + +## Sources +[Verified URLs only] +``` + +### Investor Profile + +```markdown +# {Investor/Firm Name} + +## Overview +- **Type:** {VC/PE/Corporate/Angel} +- **AUM:** {assets under management if public} +- **Focus Areas:** {investment thesis areas} + +## Portfolio in This Market +- {company 1}: {round, amount} [link to company profile] +- {company 2}: {round, amount} + +## Investment Thesis +[What do they look for in this market? What's their angle?] + +## Key Partners +- {partner name}: {focus, background} + +## Significance +[Why this investor matters for the market landscape] + +## Sources +[Verified URLs only] +``` diff --git a/.opencode/skills/Research/Templates/ThreatLandscape.md b/.opencode/skills/Research/Templates/ThreatLandscape.md new file mode 100644 index 00000000..c3f90e41 --- /dev/null +++ b/.opencode/skills/Research/Templates/ThreatLandscape.md @@ -0,0 +1,277 @@ +# Threat Landscape Domain Template + +Domain-specific configuration for the Deep Investigation workflow applied to cybersecurity threat analysis. + +--- + +## Entity Categories + +| Category | Description | Target Count | +|----------|-------------|-------------| +| **Threat Actors** | APT groups, cybercrime organizations, hacktivists, nation-state actors | 5-15 | +| **Campaigns** | Named operations, attack waves, ongoing exploitation campaigns | 3-8 | +| **TTPs** | Tactics, techniques, and procedures — MITRE ATT&CK mapped | 5-10 | +| **Vulnerabilities** | CVEs, vulnerability classes, exploit chains being actively used | 5-12 | +| **Tools** | Malware families, C2 frameworks, exploit kits, offensive tools | 5-10 | +| **Defenders** | Security vendors, researchers, CERTs responding to threats | 3-8 | + +--- + +## Evaluation Criteria (What Makes Something CRITICAL?) + +**Threat Actors:** +- CRITICAL: Active APTs targeting your industry, nation-state groups with demonstrated capability +- HIGH: Prolific ransomware groups, actors with recent high-profile breaches +- MEDIUM: Known groups with limited recent activity +- LOW: Low-capability actors, script kiddies, inactive groups + +**Campaigns:** +- CRITICAL: Actively exploiting, widespread targeting, zero-day usage +- HIGH: Recent campaigns with significant impact or novel techniques +- MEDIUM: Historical campaigns with relevant lessons +- LOW: Contained or resolved campaigns + +**TTPs:** +- CRITICAL: Techniques used in active campaigns against your sector +- HIGH: Commonly used techniques with high success rate +- MEDIUM: Known techniques with available mitigations +- LOW: Theoretical or rarely observed techniques + +**Vulnerabilities:** +- CRITICAL: Actively exploited (CISA KEV), network-accessible, no patch available +- HIGH: Actively exploited with patch available, or pre-auth RCE +- MEDIUM: High CVSS but limited exploitation +- LOW: Low CVSS or highly specific preconditions + +--- + +## Search Strategies + +**For landscape (Step 1):** +- "[sector] threat landscape 2025 2026" +- "APT groups targeting [industry]" +- "MITRE ATT&CK [sector] techniques" +- "ransomware trends [year]" +- "CISA advisories [sector] recent" + +**For entity discovery (Step 3):** +- "[threat actor name] IOC report" +- "CVE [year] actively exploited [technology]" +- "[malware family] analysis report" +- "threat intelligence [sector] annual report" + +**For deep investigation (Step 4):** +- "[actor/campaign] MITRE ATT&CK mapping" +- "[actor] mandiant|crowdstrike|recorded future report" +- "[CVE] exploit analysis proof of concept" +- "[malware] reverse engineering analysis" +- "[actor] attribution evidence indicators" + +--- + +## Profile Templates + +### Threat Actor Profile + +```markdown +# {Actor Name / Designation} + +## Overview +- **Also Known As:** {aliases across vendors} +- **Type:** {APT/Cybercrime/Hacktivist/Nation-State} +- **Suspected Origin:** {country/region, confidence level} +- **Active Since:** {year} +- **Current Status:** {Active/Dormant/Disbanded} + +## Attribution +[What evidence supports attribution? Confidence level? Disputed?] + +## Targeting +- **Industries:** {targeted sectors} +- **Geographies:** {targeted regions} +- **Motivation:** {espionage/financial/disruption/ideology} + +## TTPs (MITRE ATT&CK Mapped) +| Tactic | Technique | ID | Notes | +|--------|-----------|-----|-------| +| Initial Access | {technique} | T{XXXX} | {how they use it} | +| Execution | {technique} | T{XXXX} | {details} | + +## Tools & Malware +- {tool/malware 1}: {description} [link to tool profile] +- {tool/malware 2}: {description} + +## Notable Operations +- {date}: {campaign/operation} [link to campaign profile] +- {date}: {campaign/operation} + +## Indicators of Compromise +[Representative IOCs — domains, IPs, hashes, patterns] + +## Defensive Recommendations +- {recommendation 1} +- {recommendation 2} + +## Sources +[Verified URLs — vendor reports, government advisories, academic research] +``` + +### Campaign Profile + +```markdown +# {Campaign Name / Designation} + +## Overview +- **Actor:** [link to actor profile] +- **Timeframe:** {start date — end date or ongoing} +- **Status:** {Active/Contained/Resolved} +- **Impact:** {scope and severity} + +## Targeting +- **Victims:** {who was targeted} +- **Geography:** {where} +- **Scale:** {number of known victims} + +## Attack Chain +1. **Initial Access:** {how they got in} +2. **Execution:** {what they ran} +3. **Persistence:** {how they stayed} +4. **Impact:** {what they achieved} + +## Vulnerabilities Exploited +- {CVE-XXXX-XXXXX}: {description} [link to vuln profile] + +## Tools Used +- {tool}: {role in campaign} [link to tool profile] + +## Detection Opportunities +- {detection 1} +- {detection 2} + +## Lessons Learned +[What can defenders learn from this campaign?] + +## Sources +[Verified URLs] +``` + +### TTP Profile + +```markdown +# {Technique Name} + +## MITRE ATT&CK +- **ID:** T{XXXX} +- **Tactic:** {tactic} +- **Sub-techniques:** {list if applicable} +- **Platforms:** {Windows/Linux/macOS/Cloud} + +## Description +[How this technique works. 2-3 paragraphs.] + +## Real-World Usage +- {Actor 1}: {how they used it} [link to actor profile] +- {Actor 2}: {how they used it} + +## Detection +- **Log Sources:** {what to monitor} +- **Detection Logic:** {sigma rules, KQL, SPL concepts} +- **Difficulty:** {Easy/Medium/Hard to detect} + +## Mitigation +- {mitigation 1} +- {mitigation 2} + +## Sources +[Verified URLs] +``` + +### Vulnerability Profile + +```markdown +# {CVE ID}: {Short Description} + +## Overview +- **CVE:** {CVE-XXXX-XXXXX} +- **CVSS:** {score} ({severity}) +- **Affected:** {product/version} +- **Discovered:** {date} +- **Patch Available:** {yes/no, date} + +## Exploitation Status +- **CISA KEV:** {yes/no} +- **Active Exploitation:** {confirmed/suspected/none} +- **Exploit Availability:** {public PoC/private/none} + +## Technical Details +[How the vulnerability works. What's the root cause?] + +## Impact +[What can an attacker achieve by exploiting this?] + +## Used By +- {Actor/Campaign}: [link to profile] + +## Remediation +- **Patch:** {version/link} +- **Workaround:** {if no patch} +- **Detection:** {how to detect exploitation} + +## Sources +[Verified URLs — NVD, vendor advisory, researcher writeups] +``` + +### Tool / Malware Profile + +```markdown +# {Tool/Malware Name} + +## Overview +- **Type:** {RAT/Ransomware/Loader/C2 Framework/Exploit Kit/Offensive Tool} +- **First Seen:** {date} +- **Current Status:** {Active/Deprecated/Evolving} +- **Availability:** {Open source/Commercial/Private/Leaked} + +## Capabilities +- {capability 1} +- {capability 2} +- {capability 3} + +## Used By +- {Actor 1}: {context} [link to actor profile] +- {Actor 2}: {context} + +## Technical Analysis +[How it works. Key features. Evasion techniques.] + +## Detection +- **Signatures:** {AV detection names} +- **Behavioral:** {what to look for} +- **Network:** {C2 patterns, protocols} + +## Sources +[Verified URLs] +``` + +### Defender Profile + +```markdown +# {Vendor/Team/Researcher Name} + +## Overview +- **Type:** {Security Vendor/CERT/Research Group/Individual Researcher} +- **Focus:** {what they specialize in} + +## Key Contributions +- {contribution 1 — report, tool, disclosure} +- {contribution 2} + +## Threat Coverage +[What threats do they track? What intelligence do they produce?] + +## Notable Reports +- {report title}: {summary} {verified URL} + +## Sources +[Verified URLs] +``` diff --git a/.opencode/skills/System/Workflows/CrossRepoValidation.md b/.opencode/skills/System/Workflows/CrossRepoValidation.md index 39c21a62..93f1ce24 100644 --- a/.opencode/skills/System/Workflows/CrossRepoValidation.md +++ b/.opencode/skills/System/Workflows/CrossRepoValidation.md @@ -521,7 +521,7 @@ Identify which files SHOULD be synced between repos: // Files that should be identical (generic infrastructure) const shouldMatch = [ ".opencode/tools/SkillSearch.ts", - ".opencode/skills/Art/SKILL.md", + ".opencode/skills/Media/Art/SKILL.md", // ... other generic files ]; diff --git a/.opencode/skills/Telos/SKILL.md b/.opencode/skills/Telos/SKILL.md old mode 100755 new mode 100644 index 2b1f3f98..66cb02b6 --- a/.opencode/skills/Telos/SKILL.md +++ b/.opencode/skills/Telos/SKILL.md @@ -1,389 +1,32 @@ --- name: Telos -description: "Life OS and project analysis. USE WHEN TELOS, life goals, projects, dependencies, books, movies. SkillSearch('telos') for docs." +description: Life OS and project management. USE WHEN life goals, projects, dependencies, TELOS, books, movies, tracking. --- -# Telos +# Telos - Life OS and Project Management -**TELOS** (Telic Evolution and Life Operating System) is a comprehensive context-gathering system with two applications: +**Category for skills that manage life goals, projects, and personal tracking.** -1. **Personal TELOS** - {principal.name}'s life context system (beliefs, goals, lessons, wisdom) at `~/.opencode/skills/CORE/USER/TELOS/` -2. **Project TELOS** - Analysis framework for organizations/projects (relationships, dependencies, goals, progress) +## Skills in This Category +| Skill | Purpose | Trigger | +|-------|---------|---------| +| **Telos** | Life OS, goals, projects, books, movies tracking | "life goals", "projects", "TELOS", "tracking" | -## Voice Notification +## When to Use -**When executing a workflow, do BOTH:** +- Managing life goals and long-term planning +- Tracking projects and dependencies +- Recording books read and movies watched +- Personal life organization -1. **Send voice notification**: - ```bash - curl -s -X POST http://localhost:8888/notify \ - -H "Content-Type: application/json" \ - -d '{"message": "Running the WORKFLOWNAME workflow from the Telos skill"}' \ - > /dev/null 2>&1 & - ``` +## Category Philosophy -2. **Output text notification**: - ``` - Running the **WorkflowName** workflow from the **Telos** skill... - ``` +Telos treats life as a system to be managed with intention. It connects daily actions to long-term meaning. -## Workflow Routing +## Customization -**When executing a workflow, output this notification directly:** +**Before executing, check for user customizations at:** +`~/.opencode/skills/PAI/USER/SKILLCUSTOMIZATIONS/Telos/` -``` -Running the **WorkflowName** workflow from the **Telos** skill... -``` - -| Workflow | Trigger | File | -|----------|---------|------| -| **Update** | "add to TELOS", "update my goals", "add book to TELOS" | `Workflows/Update.md` | -| **InterviewExtraction** | "extract content", "extract interviews", "analyze interviews" | `Workflows/InterviewExtraction.md` | -| **CreateNarrativePoints** | "create narrative", "narrative points", "TELOS report", "n=24" | `Workflows/CreateNarrativePoints.md` | -| **WriteReport** | "write report", "McKinsey report", "create TELOS report", "professional report" | `Workflows/WriteReport.md` | - -**Note:** For general project analysis, dashboards, dependency mapping, and executive summaries, the skill handles these directly without a separate workflow file. - -## Examples - -**Example 1: Update personal TELOS** -``` -User: "add Project Hail Mary to my TELOS books" ---> Invokes Update workflow ---> Creates timestamped backup of BOOKS.md ---> Adds book entry with formatted metadata ---> Logs change in updates.md with timestamp -``` - -**Example 2: Analyze project with TELOS** -``` -User: "analyze ~/Projects/MyApp with TELOS" ---> Scans all .md and .csv files in directory ---> Extracts entities, relationships, dependencies ---> Returns analysis with dependency chains and progress metrics -``` - -**Example 3: Build project dashboard** -``` -User: "build a dashboard for TELOSAPP" ---> Launches up to 10 parallel engineers ---> Creates Next.js dashboard with shadcn/ui + Aceternity ---> Returns interactive dashboard with dependency graphs, metrics cards, progress tables -``` - -**Example 4: Generate narrative points** -``` -User: "create TELOS narrative for Acme Corp, n=24" ---> Invokes CreateNarrativePoints workflow ---> Analyzes TELOS context (situation, problems, recommendations) ---> Returns 24 crisp bullet points (8-12 words each) ---> Output is slide-ready for presentations or customer briefings -``` - -**Example 5: Generate McKinsey-style report** -``` -User: "write a TELOS report for Acme Corp" ---> Invokes WriteReport workflow ---> First runs CreateNarrativePoints to generate story content ---> Maps narrative to McKinsey report structure ---> Generates web-based report with professional styling ---> Output at {project_dir}/report - run `bun dev` to view ---> White background, subtle Tokyo Night Storm accents ---> Includes: cover page, executive summary, findings, recommendations, roadmap -``` - ---- - -## Context Detection - -**How {daidentity.name} determines which TELOS context:** - -| User Request | Context | Location | -|--------------|---------|----------| -| "my TELOS", "my goals", "my beliefs", "add to TELOS" | Personal TELOS | `~/.opencode/skills/CORE/USER/TELOS/` | -| "Alma", "TELOSAPP", "analyze [project]", "dashboard for" | Project TELOS | User-specified directory | -| "analyze ~/path/to/project" | Project TELOS | Specified path | - ---- - -# Part 1: Personal TELOS ({principal.name}'s Life) - -## Location - -**CRITICAL PATH:** All personal TELOS files are located at: -``` -~/.opencode/skills/CORE/USER/TELOS/ -``` - -Personal TELOS lives in the CORE USER directory, NOT directly under the Telos skill directory. - -## Personal TELOS Framework - -All files located in `~/.opencode/skills/CORE/USER/TELOS/`: - -### Core Philosophy -- **TELOS.md** - Main framework document -- **MISSION.md** - Life mission statement -- **BELIEFS.md** - Core beliefs and world model -- **WISDOM.md** - Accumulated wisdom - -### Life Data -- **BOOKS.md** - Favorite books -- **MOVIES.md** - Favorite movies -- **LEARNED.md** - Lessons learned over time -- **WRONG.md** - Things {principal.name} was wrong about (growth tracking) - -### Mental Models -- **FRAMES.md** - Mental frames and perspectives -- **MODELS.md** - Mental models used for decision-making -- **NARRATIVES.md** - Personal narratives and self-stories -- **STRATEGIES.md** - Strategies being employed in life - -### Goals & Challenges -- **GOALS.md** - Life goals (short-term and long-term) -- **PROJECTS.md** - Active projects -- **PROBLEMS.md** - Problems to solve -- **CHALLENGES.md** - Current challenges being faced -- **PREDICTIONS.md** - Predictions about the future -- **TRAUMAS.md** - Past traumas (for context and healing) - -### Change Tracking -- **updates.md** - Comprehensive changelog of all TELOS updates - -## Working with Personal TELOS - -### Read Files - -```bash -# View specific file -read ~/.opencode/skills/CORE/USER/TELOS/GOALS.md -read ~/.opencode/skills/CORE/USER/TELOS/BELIEFS.md - -# View recent updates -read ~/.opencode/skills/CORE/USER/TELOS/updates.md -``` - -### Update Personal TELOS - -**CRITICAL:** Never manually edit. Use the Update workflow. - -**Workflow:** `Workflows/Update.md` - -The workflow provides: -- Automatic timestamped backups -- Change logging in updates.md -- Version history preservation -- Proper formatting and structure - -**Valid files for updates:** -BELIEFS.md, BOOKS.md, CHALLENGES.md, FRAMES.md, GOALS.md, LEARNED.md, MISSION.md, MODELS.md, MOVIES.md, NARRATIVES.md, PREDICTIONS.md, PROBLEMS.md, PROJECTS.md, STRATEGIES.md, TELOS.md, TRAUMAS.md, WISDOM.md, WRONG.md - ---- - -# Part 2: Project TELOS (Organizational Analysis) - -## Capabilities - -For any project directory, TELOS provides: - -1. **Relationship Discovery** - Find how files/entities connect -2. **Dependency Mapping** - Identify what depends on what -3. **Goal Extraction** - Discover stated and implied objectives -4. **Progress Analysis** - Track advancement and metrics -5. **Narrative Generation** - Create executive summaries -6. **Visual Dashboards** - Build beautiful UIs with data - -## Target Directory Detection - -**Flexible file discovery - no required structure:** - -```bash -# User specifies directory -"Analyze ~/Cloud/Projects/TELOSAPP" ---> {daidentity.name} scans for .md and .csv files anywhere in tree - -# {daidentity.name} automatically finds all .md and .csv files regardless of structure -``` - -## Analysis Workflow - -### Step 1: Identify Target - -**Auto-detection:** -- User mentions project name (TELOSAPP, Alma, etc.) -- User provides path explicitly -- {daidentity.name} looks for common project locations - -### Step 2: Scan Files - -Discover all markdown and CSV files: -```bash -find $TARGET_DIR -type f \( -name "*.md" -o -name "*.csv" \) -``` - -Index: -- Markdown structure (headings, sections, links) -- CSV schema (columns, data types) -- Cross-references and mentions -- Entities (people, teams, projects, problems) - -### Step 3: Relationship Analysis - -Build relationship graph: -1. **Entity Extraction** - Identify unique entities -2. **Connection Discovery** - Find explicit/implicit links -3. **Dependency Mapping** - Trace dependencies -4. **Network Construction** - Build directed graph - -### Step 4: Generate Insights - -Produce analytics: -- **Dependency Chains**: PROBLEMS --> GOALS --> STRATEGIES --> PROJECTS -- **Bottlenecks**: What blocks progress? -- **Goal Alignment**: Projects aligned with objectives? -- **Progress Metrics**: Completion percentages -- **Risk Areas**: Overdue items, blocked work - -### Step 5: Create Outputs - -**Output Formats:** - -1. **Markdown Report** - Static analysis with Mermaid diagrams -2. **Web Dashboard** - Interactive app with shadcn/ui + Aceternity -3. **JSON Export** - Structured data -4. **Executive Summary** - Narrative overview -5. **Custom Format** - As requested - -## Building Dashboards - -### Parallel Engineer Strategy - -**CRITICAL: When building UIs, use up to 16 parallel engineers.** - -**Launch Strategy:** -Use single message with 10 Task calls in parallel: - -``` -Engineer 1: Project structure + layout + navigation -Engineer 2: Overview page with metrics cards -Engineer 3: Projects page with progress tracking -Engineer 4: Teams page with performance tables -Engineer 5: Vulnerabilities/issues page -Engineer 6: Progress timeline visualization -Engineer 7: Data parsing library (MD/CSV) -Engineer 8: Shared components (cards, badges, tables) -Engineer 9: Design polish and theme -Engineer 10: Integration and testing -``` - -### Dashboard Requirements - -**Tech Stack:** -- Next.js 14 + TypeScript -- shadcn/ui for UI components -- Aceternity UI for layouts -- Tailwind CSS -- Tokyo Night Day theme (professional light) - -**Features:** -- Dependency graphs (Mermaid or D3.js) -- Progress tables (sortable, filterable) -- Metrics cards (KPIs, stats) -- Timeline visualizations -- Relationship networks - -**Design:** -```css ---background: #ffffff ---foreground: #1a1b26 ---primary: #2e7de9 ---accent: #9854f1 ---destructive: #f52a65 ---success: #33b579 ---warning: #f0a020 -``` - -## Common TELOS Files - -**Standard Project TELOS Structure** (auto-detected): - -### Context Files -- **OVERVIEW.md** - Project overview -- **COMPANY.md** - Organization context -- **PROBLEMS.md** - Issues to solve -- **GOALS.md** - Objectives -- **MISSION.md** - Mission statement -- **STRATEGIES.md** - Strategic approaches -- **PROJECTS.md** - Active initiatives - -### Operational Files -- **EMPLOYEES.md** - Team members -- **ENGINEERING_TEAMS.md** - Team structure -- **BUDGET.md** - Financial tracking -- **KPI_TRACKING.md** - Metrics -- **APPLICATIONS.md** - App inventory -- **TOOLS.md** - Tooling -- **VENDORS.md** - Third parties - -### Security Files -- **VULNERABILITIES.md** - Security issues -- **SECURITY_POSTURE.md** - Security state -- **THREAT_MODEL.md** - Threats - -### Data Files (CSV) -- **data/VULNERABILITIES.csv** - Vuln tracking -- **data/INCIDENTS.csv** - Incident log -- **data/VENDORS.csv** - Vendor data - -**Note:** Files are optional. TELOS adapts to whatever exists. - -## Visualization Types - -**Available Visualizations:** - -- **Dependency Graphs** - Mermaid or D3.js network -- **Progress Tables** - shadcn/ui tables with filters -- **Metrics Cards** - Aceternity card layouts -- **Timeline Charts** - Progress over time -- **Status Dashboards** - KPI overviews -- **Relationship Networks** - Force-directed graphs -- **Bar Charts** - Recharts for comparisons -- **Line Charts** - Trend analysis - ---- - -## Security & Privacy - -**Personal TELOS:** -- NEVER commit to public repos -- NEVER share publicly -- Always backup before changes -- Use Update workflow only - -**Project TELOS:** -- May contain sensitive data -- Ask before sharing externally -- Redact sensitive info in examples -- Follow PAI security protocols - ---- - -## Key Principles - -1. **Dual Context** - Handles both personal and project TELOS seamlessly - - Personal TELOS: `~/.opencode/skills/CORE/USER/TELOS/` (in CORE USER directory) - - Project TELOS: User-specified directories -2. **Auto-Detection** - Determines context from user question -3. **Flexible Discovery** - Finds files regardless of structure -4. **TELOS Methodology** - Applies relationships, dependencies, goals, narratives -5. **Parallel Execution** - Up to 10 engineers for dashboard builds -6. **Visual Excellence** - Beautiful outputs with shadcn/ui + Aceternity -7. **Privacy-Aware** - Respects sensitive data -8. **Integrated** - Works with development, research, and other skills - ---- - -**TELOS is {principal.name}'s life operating system AND project analysis framework. One skill, two powerful contexts.** - -**Remember:** Personal TELOS files live at `~/.opencode/skills/CORE/USER/TELOS/` (in the CORE USER directory) +If this directory exists, load and apply any PREFERENCES.md, configurations, or resources found there. diff --git a/.opencode/skills/USMetrics/SKILL.md b/.opencode/skills/USMetrics/SKILL.md old mode 100755 new mode 100644 index f4e85ef8..c7dbffa9 --- a/.opencode/skills/USMetrics/SKILL.md +++ b/.opencode/skills/USMetrics/SKILL.md @@ -1,16 +1,46 @@ --- name: USMetrics -description: US economic indicators. USE WHEN GDP, inflation, unemployment, economic metrics, gas prices. SkillSearch('usmetrics') for docs. +description: US metrics, economic indicators and data tracking. USE WHEN US metrics, American data, statistics, demographics, GDP, inflation, unemployment, economic metrics, gas prices. +triggers: + - "US metrics" + - "American data" + - "statistics" + - "demographics" + - "GDP" + - "inflation" + - "unemployment" + - "economic metrics" + - "gas prices" --- +# USMetrics - US Metrics and Data Tracking + +**Category for skills that track and analyze US-specific metrics and data.** + +## Skills in This Category + +| Skill | Purpose | Trigger | +|-------|---------|---------| +| **USMetrics** | US-specific metrics, economic indicators and data tracking | "US metrics", "American data", "statistics", "GDP", "inflation", "unemployment", "economic metrics", "gas prices", "demographics" | + +## When to Use + +- Tracking US-specific metrics and statistics +- Analyzing American demographic data +- Monitoring US trends and indicators +- Economic analysis (GDP, inflation, unemployment) + +## Category Philosophy + +USMetrics provides focused tracking for US-specific data points and trends. + ## Customization -**Before executing, check for user customizations at:** +**MANDATORY:** Before executing, check for user customizations at: `~/.opencode/skills/PAI/USER/SKILLCUSTOMIZATIONS/USMetrics/` If this directory exists, load and apply any PREFERENCES.md, configurations, or resources found there. These override default behavior. If the directory does not exist, proceed with skill defaults. - ## 🚨 MANDATORY: Voice Notification (REQUIRED BEFORE ANY ACTION) **You MUST send this notification BEFORE doing anything else when this skill is invoked.** @@ -24,30 +54,22 @@ If this directory exists, load and apply any PREFERENCES.md, configurations, or ``` 2. **Output text notification**: - ``` + ```text Running the **WorkflowName** workflow in the **USMetrics** skill to ACTION... ``` **This is not optional. Execute this curl command immediately upon skill invocation.** -# US Metrics - Economic & Social Indicator Analysis - -**Purpose:** Analyze U.S. economic and social metrics using the Substrate US-Common-Metrics dataset. Provides trend analysis, cross-metric correlation, pattern detection, and research recommendations. - -## Data Source - -All metrics sourced from: -- **Location:** Configure your data directory path (e.g., `${PAI_DIR}/data/US-Common-Metrics/`) -- **Master Document:** `US-Common-Metrics.md` (68 metrics across 10 categories) -- **Source Documentation:** `source.md` (full methodology) -- **Underlying APIs:** FRED, EIA, Treasury FiscalData, BLS, Census, CDC, EPA +## OPTIONAL: Additional Setup +- Configure data directory path in `Preferences.md` +- Set API keys in environment variables ## Workflow Routing **When executing a workflow, output this notification directly:** -``` +```text Running the **WorkflowName** workflow in the **USMetrics** skill to ACTION... ``` @@ -124,17 +146,17 @@ For live data fetching: | Tool | Purpose | |------|---------| -| `tools/update-substrate-metrics.ts` | **Primary** - Fetch all metrics, update Substrate files | -| `tools/fetch-fred-series.ts` | Fetch historical data from FRED API | -| `tools/GenerateAnalysis.ts` | Generate analysis report from Substrate data | +| `Tools/update-substrate-metrics.ts` | **Primary** - Fetch all metrics, update Substrate files | +| `Tools/fetch-fred-series.ts` | Fetch historical data from FRED API | +| `Tools/GenerateAnalysis.ts` | Generate analysis report from Substrate data | ## Example Usage -``` +```text User: "How is the US economy doing? Give me a full analysis." +→ Invoke UpdateData workflow (fetch latest data from APIs) → Invoke GetCurrentState workflow -→ Fetch current + historical data for all metrics → Calculate 10y/5y/2y/1y trends → Analyze cross-metric correlations → Identify patterns and anomalies diff --git a/.opencode/skills/skill-index.json b/.opencode/skills/skill-index.json new file mode 100644 index 00000000..7f532052 --- /dev/null +++ b/.opencode/skills/skill-index.json @@ -0,0 +1,1323 @@ +{ + "generated": "2026-03-12T08:28:30.465Z", + "totalSkills": 54, + "categories": 7, + "flatSkills": 19, + "hierarchicalSkills": 35, + "alwaysLoadedCount": 2, + "deferredCount": 52, + "skills": { + "agents": { + "name": "Agents", + "path": "Agents/SKILL.md", + "category": null, + "fullDescription": "Dynamic agent composition. USE WHEN custom agents, agent personalities, traits, voices.", + "triggers": [ + "custom", + "agents", + "agent", + "personalities", + "traits", + "voices" + ], + "workflows": [ + "CREATECUSTOMAGENT", + "CreateCustomAgent", + "LISTTRAITS", + "ListTraits", + "SPAWNPARALLEL", + "SpawnParallelAgents", + "CORE" + ], + "tier": "deferred", + "isHierarchical": false + }, + "annualreports": { + "name": "AnnualReports", + "path": "Security/AnnualReports/SKILL.md", + "category": "Security", + "fullDescription": "Security report aggregation. USE WHEN annual reports, security reports, threat reports.", + "triggers": [ + "annual", + "reports", + "security", + "threat" + ], + "workflows": [ + "UPDATE", + "Update", + "ANALYZE", + "Analyze", + "FETCH", + "Fetch" + ], + "tier": "deferred", + "isHierarchical": true + }, + "aphorisms": { + "name": "Aphorisms", + "path": "Utilities/Aphorisms/SKILL.md", + "category": "Utilities", + "fullDescription": "Aphorism management. USE WHEN aphorism, quote, saying. SkillSearch('aphorisms') for docs.", + "triggers": [ + "aphorism", + "quote", + "saying" + ], + "workflows": [], + "tier": "deferred", + "isHierarchical": true + }, + "apify": { + "name": "Apify", + "path": "Scraping/Apify/SKILL.md", + "category": "Scraping", + "fullDescription": "Social media scraping, business data, e-commerce via Apify actors. USE WHEN Twitter, Instagram, LinkedIn, TikTok, YouTube, Facebook, Google Maps, Amazon scraping.", + "triggers": [ + "twitter", + "instagram", + "linkedin", + "tiktok", + "youtube", + "facebook", + "google", + "maps", + "amazon", + "scraping" + ], + "workflows": [], + "tier": "deferred", + "isHierarchical": true + }, + "art": { + "name": "Art", + "path": "Media/Art/SKILL.md", + "category": "Media", + "fullDescription": "Visual content system. USE WHEN art, illustrations, diagrams, visualizations, mermaid, flowchart.", + "triggers": [ + "art", + "illustrations", + "diagrams", + "visualizations", + "mermaid", + "flowchart", + "visual" + ], + "workflows": [ + "Essay", + "D3Dashboards", + "Visualize", + "Mermaid", + "TechnicalDiagrams", + "Taxonomies", + "Timelines", + "Frameworks", + "Comparisons", + "AnnotatedScreenshots", + "step", + "Aphorisms", + "Maps", + "Stats", + "Comics", + "YouTubeThumbnail", + "AdHocYouTubeThumbnail", + "CreatePAIPackIcon", + "RecipeCards" + ], + "tier": "always", + "isHierarchical": true + }, + "audioeditor": { + "name": "AudioEditor", + "path": "AudioEditor/SKILL.md", + "category": null, + "fullDescription": "AI-powered audio/video editing — transcription, intelligent cut detection, automated editing with crossfades, and optional cloud polish. USE WHEN clean audio, edit audio, remove filler words, clean podcast, remove ums, fix audio, cut dead air, polish audio, clean recording, transcribe and edit.", + "triggers": [ + "clean", + "audio", + "edit", + "remove", + "filler", + "words", + "podcast", + "ums", + "fix", + "cut", + "dead", + "air", + "polish", + "recording", + "transcribe" + ], + "workflows": [ + "Clean" + ], + "tier": "deferred", + "isHierarchical": false + }, + "becreative": { + "name": "BeCreative", + "path": "Thinking/BeCreative/SKILL.md", + "category": "Thinking", + "fullDescription": "Extended thinking mode. USE WHEN be creative, deep thinking, deep thinking, extended reasoning. SkillSearch('becreative') for docs.", + "triggers": [ + "creative", + "deep", + "thinking", + "extended", + "reasoning" + ], + "workflows": [ + "StandardCreativity", + "MaximumCreativity", + "IdeaGeneration", + "TreeOfThoughts", + "DomainSpecific" + ], + "tier": "deferred", + "isHierarchical": true + }, + "brightdata": { + "name": "BrightData", + "path": "Scraping/BrightData/SKILL.md", + "category": "Scraping", + "fullDescription": "\"Progressive URL scraping. USE WHEN Bright Data, scrape URL, web scraping tiers. SkillSearch('brightdata') for docs.\"", + "triggers": [ + "bright", + "data", + "scrape", + "url", + "web", + "scraping", + "tiers" + ], + "workflows": [ + "FourTierScrape" + ], + "tier": "deferred", + "isHierarchical": true + }, + "browser": { + "name": "Browser", + "path": "Utilities/Browser/SKILL.md", + "category": "Utilities", + "fullDescription": "Browser automation with debug visibility. USE WHEN browser, screenshot, debug web, verify UI.", + "triggers": [ + "browser", + "screenshot", + "debug", + "web", + "verify", + "automation" + ], + "workflows": [], + "tier": "deferred", + "isHierarchical": true + }, + "cloudflare": { + "name": "Cloudflare", + "path": "Utilities/Cloudflare/SKILL.md", + "category": "Utilities", + "fullDescription": "Deploy Cloudflare Workers/Pages. USE WHEN Cloudflare, worker, deploy, Pages, MCP server. SkillSearch('cloudflare') for docs.", + "triggers": [ + "cloudflare", + "worker", + "deploy", + "pages", + "mcp", + "server" + ], + "workflows": [ + "Create", + "Troubleshoot" + ], + "tier": "deferred", + "isHierarchical": true + }, + "codereview": { + "name": "CodeReview", + "path": "CodeReview/SKILL.md", + "category": null, + "fullDescription": "AI-powered code review via roborev. USE WHEN review code, check code quality, roborev, audit changes, review before commit, review before PR, code quality check, lint review, architecture review.", + "triggers": [ + "review", + "code", + "check", + "quality", + "roborev", + "audit", + "changes", + "before", + "commit", + "lint", + "architecture" + ], + "workflows": [], + "tier": "deferred", + "isHierarchical": false + }, + "contentanalysis": { + "name": "ContentAnalysis", + "path": "ContentAnalysis/SKILL.md", + "category": null, + "fullDescription": "Content analysis and wisdom extraction. USE WHEN analyze content, extract insights, process media, understand content.", + "triggers": [ + "analyze", + "content", + "extract", + "insights", + "process", + "media", + "understand" + ], + "workflows": [], + "tier": "deferred", + "isHierarchical": false + }, + "council": { + "name": "Council", + "path": "Thinking/Council/SKILL.md", + "category": "Thinking", + "fullDescription": "\"Multi-agent debate system. USE WHEN council, debate, perspectives, agents discuss. SkillSearch('council') for docs.\"", + "triggers": [ + "council", + "debate", + "perspectives", + "agents", + "discuss" + ], + "workflows": [ + "Debate", + "Quick" + ], + "tier": "deferred", + "isHierarchical": true + }, + "createcli": { + "name": "CreateCLI", + "path": "Utilities/CreateCLI/SKILL.md", + "category": "Utilities", + "fullDescription": "\"Generate TypeScript CLIs. USE WHEN create CLI, build CLI, command-line tool. SkillSearch('createcli') for docs.\"", + "triggers": [ + "create", + "cli", + "build", + "command-line", + "tool" + ], + "workflows": [ + "CreateCli", + "AddCommand", + "UpgradeTier" + ], + "tier": "deferred", + "isHierarchical": true + }, + "createskill": { + "name": "CreateSkill", + "path": "Utilities/CreateSkill/SKILL.md", + "category": "Utilities", + "fullDescription": "\"Create and validate skills. USE WHEN create skill, new skill, skill structure, canonicalize. SkillSearch('createskill') for docs.\"", + "triggers": [ + "create", + "skill", + "new", + "structure", + "canonicalize" + ], + "workflows": [ + "Create", + "CompanyDueDiligence", + "WorkflowName", + "CreateSkill", + "ValidateSkill", + "UpdateSkill", + "CanonicalizeSkill" + ], + "tier": "deferred", + "isHierarchical": true + }, + "delegation": { + "name": "Delegation", + "path": "Utilities/Delegation/SKILL.md", + "category": "Utilities", + "fullDescription": "Parallelize work via background/foreground agents, built-in types, custom agents, or agent teams/swarms. USE WHEN 3+ independent workstreams, parallel execution, agent specialization, Extended+ effort, agent team, swarm, create an agent team.", + "triggers": [ + "independent", + "workstreams", + "parallel", + "execution", + "agent", + "specialization", + "extended+", + "effort", + "team", + "swarm", + "create" + ], + "workflows": [], + "tier": "deferred", + "isHierarchical": true + }, + "documents": { + "name": "Documents", + "path": "Utilities/Documents/SKILL.md", + "category": "Utilities", + "fullDescription": "Document processing. USE WHEN document, process file. SkillSearch('documents') for docs.", + "triggers": [ + "document", + "process", + "file" + ], + "workflows": [ + "DOCX", + "PDF", + "PPTX", + "XLSX" + ], + "tier": "deferred", + "isHierarchical": true + }, + "docx": { + "name": "Docx", + "path": "Utilities/Docx/SKILL.md", + "category": "Utilities", + "fullDescription": "Word document processing. USE WHEN docx, Word document. SkillSearch('docx') for docs.", + "triggers": [ + "docx", + "word", + "document" + ], + "workflows": [], + "tier": "deferred", + "isHierarchical": true + }, + "evals": { + "name": "Evals", + "path": "Utilities/Evals/SKILL.md", + "category": "Utilities", + "fullDescription": "Agent evaluation framework. USE WHEN eval, evaluate, test agent, benchmark, verify behavior.", + "triggers": [ + "eval", + "evaluate", + "test", + "agent", + "benchmark", + "verify", + "behavior" + ], + "workflows": [ + "ALGORITHM" + ], + "tier": "deferred", + "isHierarchical": true + }, + "extractwisdom": { + "name": "ExtractWisdom", + "path": "ContentAnalysis/ExtractWisdom/SKILL.md", + "category": "ContentAnalysis", + "fullDescription": "Dynamic wisdom extraction that adapts sections to content. USE WHEN extract wisdom, analyze video, analyze podcast, extract insights, what's interesting, extract from YouTube, what did I miss, key takeaways. Replaces static extract_wisdom with content-adaptive extraction.", + "triggers": [ + "extract", + "wisdom", + "analyze", + "video", + "podcast", + "insights", + "whats", + "interesting", + "youtube", + "what", + "did", + "miss", + "key", + "takeaways" + ], + "workflows": [ + "Extract" + ], + "tier": "deferred", + "isHierarchical": true + }, + "fabric": { + "name": "Fabric", + "path": "Utilities/Fabric/SKILL.md", + "category": "Utilities", + "fullDescription": "240+ prompt patterns for content analysis and transformation. USE WHEN fabric, extract wisdom, summarize, threat model.", + "triggers": [ + "fabric", + "extract", + "wisdom", + "summarize", + "threat", + "model" + ], + "workflows": [ + "ExecutePattern", + "UpdatePatterns" + ], + "tier": "deferred", + "isHierarchical": true + }, + "firstprinciples": { + "name": "FirstPrinciples", + "path": "Thinking/FirstPrinciples/SKILL.md", + "category": "Thinking", + "fullDescription": "\"First principles analysis. USE WHEN first principles, fundamental, root cause, decompose. SkillSearch('firstprinciples') for docs.\"", + "triggers": [ + "first", + "principles", + "fundamental", + "root", + "cause", + "decompose" + ], + "workflows": [ + "Deconstruct", + "Challenge", + "Reconstruct" + ], + "tier": "deferred", + "isHierarchical": true + }, + "investigation": { + "name": "Investigation", + "path": "Investigation/SKILL.md", + "category": null, + "fullDescription": "Investigation and research skills. USE WHEN investigate, research person, company intel, due diligence, OSINT, background check.", + "triggers": [ + "investigate", + "research", + "person", + "company", + "intel", + "due", + "diligence", + "osint", + "background", + "check" + ], + "workflows": [], + "tier": "deferred", + "isHierarchical": false + }, + "iterativedepth": { + "name": "IterativeDepth", + "path": "Thinking/IterativeDepth/SKILL.md", + "category": "Thinking", + "fullDescription": "Multi-angle iterative exploration for deeper ISC extraction. USE WHEN iterative depth, deep exploration, multi-angle analysis, explore deeper, multiple perspectives on problem, examine from angles, OR when the Algorithm's OBSERVE phase needs enhanced ISC extraction.", + "triggers": [ + "iterative", + "depth", + "deep", + "exploration", + "multi-angle", + "analysis", + "explore", + "deeper", + "multiple", + "perspectives", + "problem", + "examine", + "angles", + "when", + "algorithms", + "observe", + "phase", + "needs", + "enhanced", + "isc", + "extraction" + ], + "workflows": [ + "Explore" + ], + "tier": "deferred", + "isHierarchical": true + }, + "media": { + "name": "Media", + "path": "Media/SKILL.md", + "category": null, + "fullDescription": "Media creation and processing skills. USE WHEN create visuals, generate images, video production, thumbnails, art, illustrations.", + "triggers": [ + "create", + "visuals", + "generate", + "images", + "video", + "production", + "thumbnails", + "art", + "illustrations" + ], + "workflows": [], + "tier": "deferred", + "isHierarchical": false + }, + "opencodesystem": { + "name": "OpenCodeSystem", + "path": "OpenCodeSystem/SKILL.md", + "category": null, + "fullDescription": "PAI-OpenCode system self-awareness. USE WHEN asking about tools, config, model routing, plugin handlers, MCP servers, troubleshooting, or operating environment.", + "triggers": [ + "asking", + "tools", + "config", + "model", + "routing", + "plugin", + "handlers", + "mcp", + "servers", + "troubleshooting", + "operating", + "environment" + ], + "workflows": [ + "PAI" + ], + "tier": "deferred", + "isHierarchical": false + }, + "osint": { + "name": "OSINT", + "path": "Investigation/OSINT/SKILL.md", + "category": "Investigation", + "fullDescription": "\"Open source intelligence gathering. USE WHEN OSINT, due diligence, background check, research person, company intel, investigate. SkillSearch('osint') for docs.\"", + "triggers": [ + "osint", + "due", + "diligence", + "background", + "check", + "research", + "person", + "company", + "intel", + "investigate" + ], + "workflows": [ + "PeopleLookup", + "CompanyLookup", + "CompanyDueDiligence", + "EntityLookup" + ], + "tier": "deferred", + "isHierarchical": true + }, + "pai": { + "name": "PAI", + "path": "PAI/SKILL.md", + "category": null, + "fullDescription": "Personal AI Infrastructure core. The authoritative reference for how PAI works.", + "triggers": [], + "workflows": [], + "tier": "deferred", + "isHierarchical": false + }, + "paiupgrade": { + "name": "PAIUpgrade", + "path": "Utilities/PAIUpgrade/SKILL.md", + "category": "Utilities", + "fullDescription": "Extract system improvements and monitor Anthropic ecosystem. USE WHEN upgrade, check Anthropic, new Claude features.", + "triggers": [ + "upgrade", + "check", + "anthropic", + "new", + "claude", + "features", + "extract" + ], + "workflows": [ + "ASPIRATIONAL", + "CheckForUpgrades", + "ResearchUpgrade", + "ReleaseNotesDeepDive", + "FindSources" + ], + "tier": "deferred", + "isHierarchical": true + }, + "parser": { + "name": "Parser", + "path": "Utilities/Parser/SKILL.md", + "category": "Utilities", + "fullDescription": "Parse URLs, files, videos to JSON. USE WHEN parse, extract, URL, transcript, entities, JSON, batch, content, YouTube, PDF, article. SkillSearch('parser') for docs.", + "triggers": [ + "parse", + "extract", + "url", + "transcript", + "entities", + "json", + "batch", + "content", + "youtube", + "pdf", + "article" + ], + "workflows": [ + "ParseContent", + "CollisionDetection", + "DetectContentType", + "ExtractNewsletter", + "ExtractTwitter", + "ExtractArticle", + "ExtractYoutube", + "ExtractPdf", + "ExtractBrowserExtension" + ], + "tier": "deferred", + "isHierarchical": true + }, + "pdf": { + "name": "Pdf", + "path": "Utilities/Pdf/SKILL.md", + "category": "Utilities", + "fullDescription": "PDF processing. USE WHEN pdf, PDF file. SkillSearch('pdf') for docs.", + "triggers": [ + "pdf", + "file" + ], + "workflows": [], + "tier": "deferred", + "isHierarchical": true + }, + "pptx": { + "name": "Pptx", + "path": "Utilities/Pptx/SKILL.md", + "category": "Utilities", + "fullDescription": "PowerPoint processing. USE WHEN pptx, PowerPoint, slides. SkillSearch('pptx') for docs.", + "triggers": [ + "pptx", + "powerpoint", + "slides" + ], + "workflows": [ + "CRITICAL", + "LAYOUT", + "VALIDATION", + "IMPORTANT", + "WARNING" + ], + "tier": "deferred", + "isHierarchical": true + }, + "privateinvestigator": { + "name": "PrivateInvestigator", + "path": "Investigation/PrivateInvestigator/SKILL.md", + "category": "Investigation", + "fullDescription": "\"Ethical people-finding. USE WHEN find person, locate, reconnect, people search, skip trace. SkillSearch('privateinvestigator') for docs.\"", + "triggers": [ + "find", + "person", + "locate", + "reconnect", + "people", + "search", + "skip", + "trace" + ], + "workflows": [], + "tier": "deferred", + "isHierarchical": true + }, + "prompting": { + "name": "Prompting", + "path": "Utilities/Prompting/SKILL.md", + "category": "Utilities", + "fullDescription": "Meta-prompting for prompt generation. USE WHEN meta-prompting, template generation, prompt optimization.", + "triggers": [ + "meta-prompting", + "template", + "generation", + "prompt", + "optimization" + ], + "workflows": [], + "tier": "deferred", + "isHierarchical": true + }, + "promptinjection": { + "name": "PromptInjection", + "path": "Security/PromptInjection/SKILL.md", + "category": "Security", + "fullDescription": "Prompt injection testing. USE WHEN prompt injection, jailbreak, LLM security, AI security assessment, pentest AI application, test chatbot vulnerabilities.", + "triggers": [ + "prompt", + "injection", + "jailbreak", + "llm", + "security", + "assessment", + "pentest", + "application", + "test", + "chatbot", + "vulnerabilities" + ], + "workflows": [ + "CompleteAssessment", + "Reconnaissance", + "DirectInjectionTesting", + "IndirectInjectionTesting", + "MultiStageAttacks" + ], + "tier": "deferred", + "isHierarchical": true + }, + "recon": { + "name": "Recon", + "path": "Security/Recon/SKILL.md", + "category": "Security", + "fullDescription": "\"Security reconnaissance. USE WHEN recon, reconnaissance, bug bounty, attack surface. SkillSearch('recon') for docs.\"", + "triggers": [ + "recon", + "reconnaissance", + "bug", + "bounty", + "attack", + "surface", + "security" + ], + "workflows": [], + "tier": "deferred", + "isHierarchical": true + }, + "redteam": { + "name": "RedTeam", + "path": "Thinking/RedTeam/SKILL.md", + "category": "Thinking", + "fullDescription": "\"Adversarial analysis with 32 agents. USE WHEN red team, attack idea, counterarguments, critique, stress test. SkillSearch('redteam') for docs.\"", + "triggers": [ + "red", + "team", + "attack", + "idea", + "counterarguments", + "critique", + "stress", + "test" + ], + "workflows": [ + "ParallelAnalysis", + "AdversarialValidation" + ], + "tier": "deferred", + "isHierarchical": true + }, + "remotion": { + "name": "Remotion", + "path": "Media/Remotion/SKILL.md", + "category": "Media", + "fullDescription": "Programmatic video creation with React. USE WHEN video, animation, motion graphics, video rendering, React video, intro video, YouTube video, TikTok video, video production, render video.", + "triggers": [ + "video", + "animation", + "motion", + "graphics", + "rendering", + "react", + "intro", + "youtube", + "tiktok", + "production", + "render" + ], + "workflows": [ + "ContentToAnimation" + ], + "tier": "deferred", + "isHierarchical": true + }, + "research": { + "name": "Research", + "path": "Research/SKILL.md", + "category": null, + "fullDescription": "Comprehensive research and content extraction. USE WHEN research, investigate, extract wisdom, analyze content. For OSINT use OSINT skill.", + "triggers": [ + "research", + "investigate", + "extract", + "wisdom", + "analyze", + "content", + "osint" + ], + "workflows": [ + "DEFAULT", + "QuickResearch", + "StandardResearch", + "ExtensiveResearch", + "OSINT", + "ExtractAlpha", + "Retrieve", + "YoutubeExtraction", + "WebScraping", + "ClaudeResearch", + "InterviewResearch", + "AnalyzeAiTrends", + "Fabric", + "Enhance", + "ExtractKnowledge" + ], + "tier": "always", + "isHierarchical": false + }, + "sales": { + "name": "Sales", + "path": "Sales/SKILL.md", + "category": null, + "fullDescription": "Sales workflows. USE WHEN sales, proposal, pricing. SkillSearch('sales') for docs.", + "triggers": [ + "sales", + "proposal", + "pricing" + ], + "workflows": [ + "Create-sales-package", + "Create-narrative", + "Create-visual" + ], + "tier": "deferred", + "isHierarchical": false + }, + "science": { + "name": "Science", + "path": "Thinking/Science/SKILL.md", + "category": "Thinking", + "fullDescription": "Universal thinking and iteration engine based on the scientific method. USE WHEN user says \"think about\", \"figure out\", \"try approaches\", \"experiment with\", \"test this idea\", \"iterate on\", \"improve\", \"optimize\", OR any problem-solving that benefits from structured hypothesis-test-analyze cycles. THE meta-skill that other workflows implement.", + "triggers": [ + "think", + "figure", + "out", + "try", + "approaches", + "experiment", + "test", + "this", + "idea", + "iterate", + "improve", + "optimize", + "any", + "problem-solving", + "that", + "benefits", + "structured", + "hypothesis-test-analyze", + "cycles" + ], + "workflows": [ + "DefineGoal", + "GenerateHypotheses", + "DesignExperiment", + "MeasureResults", + "AnalyzeResults", + "Iterate", + "FullCycle", + "QuickDiagnosis", + "StructuredInvestigation" + ], + "tier": "deferred", + "isHierarchical": true + }, + "scraping": { + "name": "Scraping", + "path": "Scraping/SKILL.md", + "category": null, + "fullDescription": "Web scraping and data extraction. USE WHEN scrape website, extract data, web scraping, Twitter, Instagram, LinkedIn, TikTok, YouTube, Google Maps, Amazon, social media scraping.", + "triggers": [ + "scrape", + "website", + "extract", + "data", + "web", + "scraping", + "twitter", + "instagram", + "linkedin", + "tiktok", + "youtube", + "google", + "maps", + "amazon", + "social", + "media" + ], + "workflows": [], + "tier": "deferred", + "isHierarchical": false + }, + "secupdates": { + "name": "SECUpdates", + "path": "Security/SECUpdates/SKILL.md", + "category": "Security", + "fullDescription": "Security news aggregation. USE WHEN security news, security updates, breaches.", + "triggers": [ + "security", + "news", + "updates", + "breaches" + ], + "workflows": [ + "Update" + ], + "tier": "deferred", + "isHierarchical": true + }, + "security": { + "name": "Security", + "path": "Security/SKILL.md", + "category": null, + "fullDescription": "Security assessment and intelligence. USE WHEN recon, reconnaissance, port scan, subdomain, DNS, WHOIS, web assessment, pentest, vulnerability, security scan, prompt injection, jailbreak, LLM security, security news, breaches, annual reports, threat landscape.", + "triggers": [ + "recon", + "reconnaissance", + "port", + "scan", + "subdomain", + "dns", + "whois", + "web", + "assessment", + "pentest", + "vulnerability", + "security", + "prompt", + "injection", + "jailbreak", + "llm", + "news", + "breaches", + "annual", + "reports", + "threat", + "landscape" + ], + "workflows": [], + "tier": "deferred", + "isHierarchical": false + }, + "system": { + "name": "System", + "path": "System/SKILL.md", + "category": null, + "fullDescription": "System maintenance - integrity check, document session, secret scanning. USE WHEN integrity, audit, document session, secrets, security scan.", + "triggers": [ + "integrity", + "audit", + "document", + "session", + "secrets", + "security", + "scan" + ], + "workflows": [ + "PAI", + "IntegrityCheck", + "DocumentSession", + "DocumentRecent", + "GitPush", + "SecretScanning", + "CrossRepoValidation", + "PrivacyCheck", + "WorkContextRecall" + ], + "tier": "deferred", + "isHierarchical": false + }, + "telos": { + "name": "Telos", + "path": "Telos/SKILL.md", + "category": null, + "fullDescription": "Life OS and project management. USE WHEN life goals, projects, dependencies, TELOS, books, movies, tracking.", + "triggers": [ + "life", + "goals", + "projects", + "dependencies", + "telos", + "books", + "movies", + "tracking" + ], + "workflows": [], + "tier": "deferred", + "isHierarchical": false + }, + "thinking": { + "name": "Thinking", + "path": "Thinking/SKILL.md", + "category": null, + "fullDescription": "Deep thinking and analysis skills. USE WHEN be creative, deep thinking, extended reasoning, first principles, decompose, red team, critique, stress test, council, debate, perspectives, science, research methodology, threat model, world analysis.", + "triggers": [ + "creative", + "deep", + "thinking", + "extended", + "reasoning", + "first", + "principles", + "decompose", + "red", + "team", + "critique", + "stress", + "test", + "council", + "debate", + "perspectives", + "science", + "research", + "methodology", + "threat", + "model", + "world", + "analysis" + ], + "workflows": [], + "tier": "deferred", + "isHierarchical": false + }, + "usmetrics": { + "name": "USMetrics", + "path": "USMetrics/SKILL.md", + "category": null, + "fullDescription": "US metrics, economic indicators and data tracking. USE WHEN US metrics, American data, statistics, demographics, GDP, inflation, unemployment, economic metrics, gas prices.", + "triggers": [ + "metrics", + "american", + "data", + "statistics", + "demographics", + "gdp", + "inflation", + "unemployment", + "economic", + "gas", + "prices" + ], + "workflows": [ + "UpdateData", + "GetCurrentState" + ], + "tier": "deferred", + "isHierarchical": false + }, + "utilities": { + "name": "Utilities", + "path": "Utilities/SKILL.md", + "category": null, + "fullDescription": "Utility and helper skills. USE WHEN aphorisms, quotes, browser automation, Cloudflare, create CLI, build CLI, create skill, process documents, PDF, Word, Excel, evaluations, evals, fabric patterns, PAI upgrade, parser, prompting, templates.", + "triggers": [ + "aphorisms", + "quotes", + "browser", + "automation", + "cloudflare", + "create", + "cli", + "build", + "skill", + "process", + "documents", + "pdf", + "word", + "excel", + "evaluations", + "evals", + "fabric", + "patterns", + "pai", + "upgrade", + "parser", + "prompting", + "templates" + ], + "workflows": [], + "tier": "deferred", + "isHierarchical": false + }, + "voiceserver": { + "name": "VoiceServer", + "path": "VoiceServer/SKILL.md", + "category": null, + "fullDescription": "Voice server management. USE WHEN voice server, TTS server, voice notification, prosody.", + "triggers": [ + "voice", + "server", + "tts", + "notification", + "prosody" + ], + "workflows": [ + "Status" + ], + "tier": "deferred", + "isHierarchical": false + }, + "webassessment": { + "name": "WebAssessment", + "path": "Security/WebAssessment/SKILL.md", + "category": "Security", + "fullDescription": "Web security assessment. USE WHEN web assessment, pentest, security testing, vulnerability scan. SkillSearch('webassessment') for docs.", + "triggers": [ + "web", + "assessment", + "pentest", + "security", + "testing", + "vulnerability", + "scan" + ], + "workflows": [ + "UnderstandApplication", + "CreateThreatModel" + ], + "tier": "deferred", + "isHierarchical": true + }, + "worldthreatmodelharness": { + "name": "WorldThreatModelHarness", + "path": "Thinking/WorldThreatModelHarness/SKILL.md", + "category": "Thinking", + "fullDescription": "Persistent world model system across 11 time horizons (6mo→50yr) for adversarial analysis of ideas, strategies, and investments. USE WHEN threat model, world model, test idea, test strategy, future analysis, test investment, how will this hold up, test against future, update world models, view world models, time horizon analysis, adversarial future test, stress test idea.", + "triggers": [ + "threat", + "model", + "world", + "test", + "idea", + "strategy", + "future", + "analysis", + "investment", + "how", + "will", + "this", + "hold", + "against", + "update", + "models", + "view", + "time", + "horizon", + "adversarial", + "stress" + ], + "workflows": [ + "TestIdea", + "UpdateModels", + "ViewModels" + ], + "tier": "deferred", + "isHierarchical": true + }, + "writestory": { + "name": "WriteStory", + "path": "WriteStory/SKILL.md", + "category": null, + "fullDescription": "Layered fiction writing system using Will Storr's storytelling science and rhetorical figures. USE WHEN write story, fiction, novel, short story, book, chapter, story bible, character arc, plot outline, creative writing, worldbuilding, narrative, mystery writing, dialogue, prose, series planning.", + "triggers": [ + "write", + "story", + "fiction", + "novel", + "short", + "book", + "chapter", + "bible", + "character", + "arc", + "plot", + "outline", + "creative", + "writing", + "worldbuilding", + "narrative", + "mystery", + "dialogue", + "prose", + "series", + "planning" + ], + "workflows": [ + "Interview", + "BuildBible", + "Explore", + "WriteChapter", + "Revise" + ], + "tier": "deferred", + "isHierarchical": false + }, + "xlsx": { + "name": "Xlsx", + "path": "Utilities/Xlsx/SKILL.md", + "category": "Utilities", + "fullDescription": "Excel file processing. USE WHEN xlsx, Excel, spreadsheet. SkillSearch('xlsx') for docs.", + "triggers": [ + "xlsx", + "excel", + "spreadsheet" + ], + "workflows": [], + "tier": "deferred", + "isHierarchical": true + } + }, + "categoryMap": { + "ContentAnalysis": [ + "ExtractWisdom" + ], + "Investigation": [ + "OSINT", + "PrivateInvestigator" + ], + "Media": [ + "Art", + "Remotion" + ], + "Scraping": [ + "Apify", + "BrightData" + ], + "Security": [ + "AnnualReports", + "PromptInjection", + "Recon", + "SECUpdates", + "WebAssessment" + ], + "Thinking": [ + "BeCreative", + "Council", + "FirstPrinciples", + "IterativeDepth", + "RedTeam", + "Science", + "WorldThreatModelHarness" + ], + "Utilities": [ + "Aphorisms", + "Browser", + "Cloudflare", + "CreateCLI", + "CreateSkill", + "Delegation", + "Documents", + "Docx", + "Evals", + "Fabric", + "PAIUpgrade", + "Parser", + "Pdf", + "Pptx", + "Prompting", + "Xlsx" + ] + } +} \ No newline at end of file