235 lines
9.7 KiB
Markdown
235 lines
9.7 KiB
Markdown
---
|
|
phase: 42-wallpapers-social-format-conversion-voice
|
|
plan: 01
|
|
type: execute
|
|
wave: 1
|
|
depends_on: []
|
|
files_modified:
|
|
- 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
|
|
autonomous: true
|
|
requirements: [CONV-08]
|
|
must_haves:
|
|
truths:
|
|
- "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"
|
|
artifacts:
|
|
- path: "server/src/services/renderers/types.ts"
|
|
provides: "WallpaperBundle, SocialPostBundle, ConvertBundle type definitions"
|
|
contains: "WallpaperBundle"
|
|
- path: "server/src/services/content-job-runner.ts"
|
|
provides: "wallpaper, social-post, convert cases in renderContent switch"
|
|
contains: "case \"wallpaper\""
|
|
- path: "server/src/services/converter-capabilities.ts"
|
|
provides: "Startup probe for pandoc/libreoffice, cached capability map"
|
|
contains: "converterCapabilitiesService"
|
|
key_links:
|
|
- from: "server/src/services/content-job-runner.ts"
|
|
to: "server/src/services/renderers/wallpaper-renderer.ts"
|
|
via: "dynamic import in case wallpaper"
|
|
pattern: "wallpaper-renderer"
|
|
- from: "server/src/services/content-job-runner.ts"
|
|
to: "server/src/services/renderers/social-renderer.ts"
|
|
via: "dynamic import in case social-post"
|
|
pattern: "social-renderer"
|
|
- from: "server/src/services/content-job-runner.ts"
|
|
to: "server/src/services/renderers/convert-renderer.ts"
|
|
via: "dynamic import in case convert"
|
|
pattern: "convert-renderer"
|
|
---
|
|
|
|
<objective>
|
|
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.
|
|
</objective>
|
|
|
|
<execution_context>
|
|
@$HOME/.claude/get-shit-done/workflows/execute-plan.md
|
|
@$HOME/.claude/get-shit-done/templates/summary.md
|
|
</execution_context>
|
|
|
|
<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
|
|
</context>
|
|
|
|
<interfaces>
|
|
<!-- Key types and contracts the executor needs -->
|
|
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:
|
|
```typescript
|
|
export async function renderContent(jobType: string, input: Record<string, unknown>): Promise<RenderResult> {
|
|
switch (jobType) {
|
|
case "diagram": { ... }
|
|
case "icon-set": { ... }
|
|
case "theme-palette": { ... }
|
|
}
|
|
}
|
|
```
|
|
</interfaces>
|
|
|
|
<tasks>
|
|
|
|
<task type="auto">
|
|
<name>Task 1: Install dependencies and define bundle types</name>
|
|
<files>server/package.json, server/src/services/renderers/types.ts</files>
|
|
<read_first>server/src/services/renderers/types.ts, server/package.json</read_first>
|
|
<action>
|
|
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.
|
|
|
|
2. Add these new bundle types to server/src/services/renderers/types.ts AFTER the existing ThemePaletteBundle:
|
|
|
|
```typescript
|
|
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";
|
|
}
|
|
```
|
|
|
|
3. Update the ContentBundle union type to include the new bundles:
|
|
```typescript
|
|
export type ContentBundle = DiagramBundle | IconSetBundle | ThemePaletteBundle | WallpaperBundle | AppIconBundle | SocialPostBundle | ConvertBundle;
|
|
```
|
|
</action>
|
|
<verify>
|
|
<automated>cd /opt/nexus/server && npx tsc --noEmit 2>&1 | head -20</automated>
|
|
</verify>
|
|
<acceptance_criteria>
|
|
- 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
|
|
</acceptance_criteria>
|
|
<done>All four bundle types exported from types.ts. file-type, xlsx, csv-parse installed in server/package.json.</done>
|
|
</task>
|
|
|
|
<task type="auto">
|
|
<name>Task 2: Wire content-job-runner switch and create converter capabilities service</name>
|
|
<files>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</files>
|
|
<read_first>server/src/services/content-job-runner.ts, server/src/utils/execFileNoThrow.ts</read_first>
|
|
<action>
|
|
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:
|
|
|
|
```typescript
|
|
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);
|
|
}
|
|
```
|
|
|
|
2. 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.
|
|
|
|
3. 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
|
|
</action>
|
|
<verify>
|
|
<automated>cd /opt/nexus/server && npx tsc --noEmit 2>&1 | head -20</automated>
|
|
</verify>
|
|
<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>
|
|
<done>content-job-runner handles wallpaper, social-post, convert job types. Stub renderers satisfy tsc. Converter capabilities service probes and caches binary availability using execFileNoThrow.</done>
|
|
</task>
|
|
|
|
</tasks>
|
|
|
|
<verification>
|
|
- `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
|
|
</verification>
|
|
|
|
<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>
|
|
|
|
<output>
|
|
After completion, create `.planning/phases/42-wallpapers-social-format-conversion-voice/42-01-SUMMARY.md`
|
|
</output>
|