9.7 KiB
| phase | plan | type | wave | depends_on | files_modified | autonomous | requirements | must_haves | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 42-wallpapers-social-format-conversion-voice | 01 | execute | 1 |
|
true |
|
|
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.
-
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"; } -
Update the ContentBundle union type to include the new bundles:
export type ContentBundle = DiagramBundle | IconSetBundle | ThemePaletteBundle | WallpaperBundle | AppIconBundle | SocialPostBundle | ConvertBundle;
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);
}
-
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.
-
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.
<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>