Feature/ai post suggestions (#40)

* feat: first cut on ai suggestion system for title and summary

* feat: completion of titling/excerpt/slug-suggestion AI quick action

* feat: feeds use existing excerpts. also documentation.

---------

Co-authored-by: hugo <hugoms@me.com>
This commit is contained in:
Georg Bauer
2026-03-07 09:54:13 +01:00
committed by GitHub
parent 72b21ddba7
commit 9871cb827f
30 changed files with 1270 additions and 245 deletions

102
TODO.md
View File

@@ -125,108 +125,6 @@ In `PageRenderer` and `BlogGenerationEngine`:
---
## 2. AI Post Summary, Title & Slug Suggestions
### Goal
The post editor has AI buttons that generate summaries (excerpts), improved
titles, and better slugs — so the user can focus on writing content and let AI
handle the metadata.
### Current State
- `analyzeMediaImage()` in `OpenCodeManager` already implements the exact
pattern: one-shot AI call, JSON response, language-aware.
- `AISuggestionsModal` already provides the UI: loading state, field-by-field
checkboxes, current vs. suggested comparison, apply/cancel.
- The media editor has an "Analyze with AI" button in a quick-actions menu.
- The post editor metadata area has title, tags, author, slug, and categories
fields but no AI buttons.
- The `excerpt` field exists on `PostData` and can serve as the summary.
- Slug is read-only in the UI after first publish (auto-generated from title).
### Implementation Plan
#### 2.1 Backend — `analyzePost()` in OpenCodeManager
Add a new method following the `analyzeMediaImage()` pattern:
**Input:** `postId: string, language: string`
**Process:**
1. Load post content, title, excerpt, and slug via `PostEngine`.
2. Build a system prompt:
```
You are a blog editor assistant. Analyze the following blog post and suggest
improvements. Return a JSON object with:
- "title": a clear, engaging title for this post
- "excerpt": a 2-3 sentence summary suitable for overview pages
- "slug": a concise, SEO-friendly URL slug (lowercase, hyphens only)
Respond in {language}. Return only the JSON object.
```
3. Send post content as user message to OpenCode Zen API.
4. Parse JSON response.
5. Return `{ success, title?, excerpt?, slug?, error? }`.
Register IPC handler: `chat:analyzePost`.
#### 2.2 Frontend — Post Editor AI Button
In the post editor metadata area (`Editor.tsx`, around line 720):
- Add a "Quick Actions" dropdown button (same pattern as media editor at
line 1242).
- Menu item: "Suggest Title, Summary & Slug" with a robot icon.
- On click: call `window.electronAPI.chat.analyzePost(postId, projectLanguage)`.
- Show `AISuggestionsModal` with the results.
#### 2.3 Extend AISuggestionsModal
The modal currently supports `title`, `alt`, `caption` fields. Adapt it to
also support a post mode with `title`, `excerpt`, `slug` fields:
- Add a `mode` prop (`'media'` | `'post'`) or make field configuration
dynamic.
- For post mode, show title, excerpt, and slug fields.
- Slug field should show a warning that it only applies to unpublished posts.
Alternatively, keep the modal generic and pass field definitions as props:
```typescript
interface SuggestionField {
key: string;
label: string; // i18n key
currentValue: string;
suggestedValue?: string;
warning?: string; // e.g., "slug is locked after first publish"
}
```
#### 2.4 Applying Suggestions
On "Apply Selected":
- Title: update via existing `onTitleChange` handler.
- Excerpt: update via `onExcerptChange` (may need to add this handler if not
present — excerpt editing may need a field in the metadata area).
- Slug: only apply if post has never been published. Show a warning and disable
the checkbox if the post has `publishedAt` set.
#### 2.5 i18n
Add keys to all 5 locale files:
- `aiSuggestions.postTitle`, `aiSuggestions.excerptField`,
`aiSuggestions.slugField`
- `aiSuggestions.analyzingPost`
- `aiSuggestions.slugLockedWarning`
- `postEditor.quickActions`, `postEditor.analyzeWithAI`
#### 2.6 Excerpt Field in Editor
If the excerpt/summary is not currently editable in the post metadata area,
add a multi-line text field for it between title and tags. This is needed both
for manual editing and for applying AI suggestions.
---
## 3. Drag-and-Drop Image Insertion