nexus/.planning/phases/42-wallpapers-social-format-conversion-voice/42-01-PLAN.md

9.7 KiB

phase plan type wave depends_on files_modified autonomous requirements must_haves
42-wallpapers-social-format-conversion-voice 01 execute 1
server/src/services/renderers/types.ts
server/src/services/content-job-runner.ts
server/src/services/converter-capabilities.ts
server/src/services/renderers/wallpaper-renderer.ts
server/src/services/renderers/social-renderer.ts
server/src/services/renderers/convert-renderer.ts
server/package.json
true
CONV-08
truths artifacts key_links
New npm dependencies (file-type, xlsx, csv-parse) are installed and importable
Bundle types (WallpaperBundle, SocialPostBundle, ConvertBundle) exist with correct shapes
content-job-runner switch handles wallpaper, social-post, and convert job types
Converter capabilities service probes pandoc/libreoffice at startup and caches result
path provides contains
server/src/services/renderers/types.ts WallpaperBundle, SocialPostBundle, ConvertBundle type definitions WallpaperBundle
path provides contains
server/src/services/content-job-runner.ts wallpaper, social-post, convert cases in renderContent switch case "wallpaper"
path provides contains
server/src/services/converter-capabilities.ts Startup probe for pandoc/libreoffice, cached capability map converterCapabilitiesService
from to via pattern
server/src/services/content-job-runner.ts server/src/services/renderers/wallpaper-renderer.ts dynamic import in case wallpaper wallpaper-renderer
from to via pattern
server/src/services/content-job-runner.ts server/src/services/renderers/social-renderer.ts dynamic import in case social-post social-renderer
from to via pattern
server/src/services/content-job-runner.ts server/src/services/renderers/convert-renderer.ts dynamic import in case convert convert-renderer
Install Phase 42 dependencies, define shared bundle types, wire content-job-runner switch for three new job types, and create the converter capabilities probe service.

Purpose: Every subsequent plan depends on these types, job runner cases, and dependency availability. This is the foundation layer. Output: Updated types.ts, content-job-runner.ts, new converter-capabilities.ts, installed packages.

<execution_context> @$HOME/.claude/get-shit-done/workflows/execute-plan.md @$HOME/.claude/get-shit-done/templates/summary.md </execution_context>

@.planning/PROJECT.md @.planning/ROADMAP.md @.planning/STATE.md @.planning/phases/42-wallpapers-social-format-conversion-voice/42-RESEARCH.md

@server/src/services/renderers/types.ts @server/src/services/content-job-runner.ts @server/package.json

From server/src/services/renderers/types.ts: ```typescript export interface RenderResult { filename: string; contentType: string; buffer: Buffer; } export type ContentBundle = DiagramBundle | IconSetBundle | ThemePaletteBundle; ```

From server/src/services/content-job-runner.ts:

export async function renderContent(jobType: string, input: Record<string, unknown>): Promise<RenderResult> {
  switch (jobType) {
    case "diagram": { ... }
    case "icon-set": { ... }
    case "theme-palette": { ... }
  }
}
Task 1: Install dependencies and define bundle types server/package.json, server/src/services/renderers/types.ts server/src/services/renderers/types.ts, server/package.json 1. Install new dependencies in server/: ```bash cd /opt/nexus/server && pnpm add file-type@22.0.0 xlsx@0.18.5 csv-parse@6.2.1 ``` Do NOT install @types/xlsx — xlsx ships its own types.
  1. Add these new bundle types to server/src/services/renderers/types.ts AFTER the existing ThemePaletteBundle:

    export interface WallpaperBundle {
      type: "wallpaper-bundle";
      platform: string;
      width: number;
      height: number;
      pngBase64: string;
      prompt: string;
    }
    
    export interface AppIconBundle {
      type: "app-icon-bundle";
      sizes: Array<{ size: number; pngBase64: string }>;
      prompt: string;
    }
    
    export interface SocialPostBundle {
      type: "social-post-bundle";
      platform: string;
      post: string;
      hashtags: string[];
      slides?: string[];
      charLimit: number;
    }
    
    export interface ConvertBundle {
      type: "convert-bundle";
      outputFilename: string;
      outputMime: string;
      outputBase64: string;
      method: "direct" | "ai-bridge";
    }
    
  2. Update the ContentBundle union type to include the new bundles:

    export type ContentBundle = DiagramBundle | IconSetBundle | ThemePaletteBundle | WallpaperBundle | AppIconBundle | SocialPostBundle | ConvertBundle;
    
cd /opt/nexus/server && npx tsc --noEmit 2>&1 | head -20 - grep "WallpaperBundle" server/src/services/renderers/types.ts - grep "SocialPostBundle" server/src/services/renderers/types.ts - grep "ConvertBundle" server/src/services/renderers/types.ts - grep "AppIconBundle" server/src/services/renderers/types.ts - grep "file-type" server/package.json - grep "xlsx" server/package.json - grep "csv-parse" server/package.json All four bundle types exported from types.ts. file-type, xlsx, csv-parse installed in server/package.json. Task 2: Wire content-job-runner switch and create converter capabilities service server/src/services/content-job-runner.ts, server/src/services/converter-capabilities.ts, server/src/services/renderers/wallpaper-renderer.ts, server/src/services/renderers/social-renderer.ts, server/src/services/renderers/convert-renderer.ts server/src/services/content-job-runner.ts, server/src/utils/execFileNoThrow.ts 1. Add three new cases to the `renderContent` switch in content-job-runner.ts, following the exact existing pattern (dynamic import of renderer, call render function, return result). For now, create stub renderer imports that will be implemented in Plans 02-04:
case "wallpaper": {
  const { renderWallpaper } = await import("./renderers/wallpaper-renderer.js");
  return renderWallpaper(input);
}
case "social-post": {
  const { renderSocialPost } = await import("./renderers/social-renderer.js");
  return renderSocialPost(input);
}
case "convert": {
  const { renderConvert } = await import("./renderers/convert-renderer.js");
  return renderConvert(input);
}
  1. Create stub renderer files so tsc resolves the imports (Plans 02-04 replace with real implementations):

    • server/src/services/renderers/wallpaper-renderer.ts: export async function renderWallpaper that throws "Not implemented"
    • server/src/services/renderers/social-renderer.ts: export async function renderSocialPost that throws "Not implemented"
    • server/src/services/renderers/convert-renderer.ts: export async function renderConvert that throws "Not implemented" Each stub must import and return RenderResult type.
  2. Create server/src/services/converter-capabilities.ts implementing the startup probe pattern:

    • Export interface ConverterCapabilities { imageConverter: boolean; audioVideoConverter: boolean; docConverter: boolean; dataConverter: boolean }
    • Export function converterCapabilitiesService() with a get() method
    • Use execFileNoThrow from src/utils/execFileNoThrow.ts (project standard — do NOT use child_process.exec directly) to probe "pandoc" and "libreoffice" with ["--version"] argument
    • imageConverter, audioVideoConverter, dataConverter always true (npm deps)
    • docConverter true only if pandoc or libreoffice binary responds with status 0
    • Cache result after first probe in module-level variable cd /opt/nexus/server && npx tsc --noEmit 2>&1 | head -20 <acceptance_criteria>
    • grep "case "wallpaper"" server/src/services/content-job-runner.ts
    • grep "case "social-post"" server/src/services/content-job-runner.ts
    • grep "case "convert"" server/src/services/content-job-runner.ts
    • grep "converterCapabilitiesService" server/src/services/converter-capabilities.ts
    • grep "ConverterCapabilities" server/src/services/converter-capabilities.ts
    • grep "execFileNoThrow" server/src/services/converter-capabilities.ts
    • grep "renderWallpaper" server/src/services/renderers/wallpaper-renderer.ts
    • grep "renderSocialPost" server/src/services/renderers/social-renderer.ts
    • grep "renderConvert" server/src/services/renderers/convert-renderer.ts </acceptance_criteria> content-job-runner handles wallpaper, social-post, convert job types. Stub renderers satisfy tsc. Converter capabilities service probes and caches binary availability using execFileNoThrow.
- `cd /opt/nexus/server && npx tsc --noEmit` passes with zero errors - All new types are exported from types.ts - Three new cases exist in content-job-runner switch

<success_criteria>

  • Three new bundle type interfaces exported from types.ts
  • Three new job type cases in content-job-runner.ts switch
  • Stub renderer files exist for wallpaper, social, convert
  • converter-capabilities.ts probes pandoc/libreoffice using execFileNoThrow and caches
  • tsc compiles cleanly </success_criteria>
After completion, create `.planning/phases/42-wallpapers-social-format-conversion-voice/42-01-SUMMARY.md`