All checks were successful
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 1m22s
110 lines
3.5 KiB
Markdown
110 lines
3.5 KiB
Markdown
# Upload And Extract Episodes Implementation Plan
|
|
|
|
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
|
|
|
|
**Goal:** Add file upload for `.docx`, `.txt`, `.pdf`, and `.md` in conversion mode, stream a Doubao-based episode extraction result into the source textarea, and preserve the existing conversion workflow.
|
|
|
|
**Architecture:** Extend the conversion UI in `src/App.tsx` with upload controls and extraction state, add browser-side file parsing helpers for the four formats, and create a new streaming Doubao extraction method in `src/services/ai.ts`. The extraction result should progressively replace `sourceText`, then hand control back to the user for the existing conversion step.
|
|
|
|
**Tech Stack:** React 19, TypeScript, Vite, OpenAI SDK, browser file APIs, PDF/docx parsing libraries
|
|
|
|
---
|
|
|
|
### Task 1: Add dependency and extraction API surface
|
|
|
|
**Files:**
|
|
- Modify: `package.json`
|
|
- Modify: `src/services/ai.ts`
|
|
|
|
**Step 1: Write the failing test surrogate**
|
|
|
|
Use TypeScript as the first guard by adding a new extraction function signature and references from `App.tsx` before implementation is complete.
|
|
|
|
**Step 2: Run verification to confirm the break**
|
|
|
|
Run: `npm run lint`
|
|
Expected: FAIL because the new extraction path is not fully wired.
|
|
|
|
**Step 3: Write minimal implementation**
|
|
|
|
- Add any needed client-side parsing dependencies.
|
|
- Add `extractEpisodesFromSource` in `src/services/ai.ts`.
|
|
- Use model `doubao-seed-1-6-flash-250828`.
|
|
- Stream chunks through a callback similar to the existing conversion flow.
|
|
- Build a strict prompt requiring 1:1 episode/script extraction with no edits.
|
|
|
|
**Step 4: Re-run verification**
|
|
|
|
Run: `npm run lint`
|
|
Expected: still failing until UI wiring is complete.
|
|
|
|
### Task 2: Add browser-side file parsing helpers
|
|
|
|
**Files:**
|
|
- Create: `src/services/fileParsing.ts`
|
|
- Modify: `src/App.tsx`
|
|
|
|
**Step 1: Write the failing test surrogate**
|
|
|
|
Reference helper APIs from `App.tsx` before the helper module is complete.
|
|
|
|
**Step 2: Implement minimal parsing**
|
|
|
|
- Support `.txt` and `.md` via plain text reads.
|
|
- Support `.docx` via browser text extraction.
|
|
- Support `.pdf` via browser PDF text extraction.
|
|
- Return normalized raw text for LLM input without attempting episode splitting locally.
|
|
|
|
**Step 3: Handle unsupported files**
|
|
|
|
- Reject anything outside the four allowed extensions.
|
|
- Return actionable error messages.
|
|
|
|
### Task 3: Wire upload UX into conversion mode
|
|
|
|
**Files:**
|
|
- Modify: `src/App.tsx`
|
|
|
|
**Step 1: Add state**
|
|
|
|
- Add extraction progress/loading/error state.
|
|
- Keep `sourceText` persistence unchanged.
|
|
|
|
**Step 2: Add UI**
|
|
|
|
- Add file upload control near the source textarea.
|
|
- Show supported formats.
|
|
- Show extraction-in-progress feedback distinct from the existing conversion action.
|
|
|
|
**Step 3: Add upload flow**
|
|
|
|
- On file select, parse the file.
|
|
- Start the streaming extraction call immediately.
|
|
- Replace `sourceText` incrementally with streamed content.
|
|
- Preserve manual editing after completion.
|
|
|
|
### Task 4: Verify behavior and guardrails
|
|
|
|
**Files:**
|
|
- Modify: `src/App.tsx`
|
|
- Modify: `src/services/ai.ts`
|
|
- Modify: `package.json`
|
|
|
|
**Step 1: Run type check**
|
|
|
|
Run: `npm run lint`
|
|
Expected: PASS
|
|
|
|
**Step 2: Run build**
|
|
|
|
Run: `npm run build`
|
|
Expected: PASS
|
|
|
|
**Step 3: Manual review checklist**
|
|
|
|
- Upload accepts only `.docx`, `.txt`, `.pdf`, `.md`.
|
|
- Upload starts extraction immediately.
|
|
- Left source textarea updates in streaming fashion.
|
|
- Extraction uses the raw-output contract and does not intentionally rewrite content.
|
|
- Existing `立即转换成剧本` button still works after extraction.
|