Initial TrueGrowth source import
This commit is contained in:
59
openspec/specs/agent-image-understanding/spec.md
Normal file
59
openspec/specs/agent-image-understanding/spec.md
Normal file
@@ -0,0 +1,59 @@
|
||||
# agent-image-understanding Specification
|
||||
|
||||
## Purpose
|
||||
TBD - created by archiving change add-agent-image-understanding. Update Purpose after archive.
|
||||
## Requirements
|
||||
### Requirement: Text Bindings Declare Image Understanding Capability
|
||||
|
||||
The system SHALL determine whether a text invocation can accept image input from the resolved text binding, instead of assuming every text model supports multimodal input.
|
||||
|
||||
#### Scenario: Supported text binding accepts image input
|
||||
|
||||
- **GIVEN** a text invocation resolves to a binding whose protocol supports image input
|
||||
- **WHEN** the user sends a text request with one or more images
|
||||
- **THEN** the system SHALL allow those images to be included in the outbound text request
|
||||
|
||||
#### Scenario: Unsupported text binding stays text-only
|
||||
|
||||
- **GIVEN** a text invocation resolves to a binding that does not support image input
|
||||
- **WHEN** the user sends a text request with one or more images
|
||||
- **THEN** the system SHALL NOT include image parts in the outbound request
|
||||
- **AND** SHALL preserve the existing text-only behavior for that invocation
|
||||
|
||||
### Requirement: Chat Messages Can Carry Attached Images To Supported Text Models
|
||||
|
||||
The system SHALL allow chat messages to include attached images when the resolved text binding supports image understanding.
|
||||
|
||||
#### Scenario: Chat drawer sends attached image to OpenAI-compatible text protocol
|
||||
|
||||
- **GIVEN** the user attaches an image in the chat drawer
|
||||
- **AND** the selected text binding resolves to `openai.chat.completions`
|
||||
- **WHEN** the user sends the message
|
||||
- **THEN** the outbound message SHALL include the user text and the attached image as multimodal message parts
|
||||
|
||||
#### Scenario: Chat drawer sends attached image to Google text protocol
|
||||
|
||||
- **GIVEN** the user attaches an image in the chat drawer
|
||||
- **AND** the selected text binding resolves to `google.generateContent`
|
||||
- **WHEN** the user sends the message
|
||||
- **THEN** the outbound request SHALL include the user text and image content
|
||||
- **AND** the image SHALL be converted into the Google-compatible payload shape before submission
|
||||
|
||||
### Requirement: Agent And AI Analyze Requests Preserve Real Reference Images
|
||||
|
||||
The system SHALL preserve real image inputs for Agent and AI analyze requests instead of reducing them to placeholder text only.
|
||||
|
||||
#### Scenario: Default Agent execution sends reference images
|
||||
|
||||
- **GIVEN** the Agent context contains one or more selected images
|
||||
- **WHEN** the Agent builds the default user request
|
||||
- **THEN** the request SHALL include the structured text prompt
|
||||
- **AND** SHALL also include the selected images as message parts when the resolved text binding supports image input
|
||||
|
||||
#### Scenario: AI analyze workflow keeps image content across conversion
|
||||
|
||||
- **GIVEN** an `ai_analyze` workflow step is created from a request containing reference images
|
||||
- **WHEN** that step is executed later
|
||||
- **THEN** the workflow path SHALL preserve the reference image content needed for text-model image understanding
|
||||
- **AND** SHALL not rely only on placeholder text to represent those images
|
||||
|
||||
85
openspec/specs/ai-input-generation/spec.md
Normal file
85
openspec/specs/ai-input-generation/spec.md
Normal file
@@ -0,0 +1,85 @@
|
||||
# ai-input-generation Specification
|
||||
|
||||
## Purpose
|
||||
TBD - created by archiving change add-agent-skill-media-model-selectors. Update Purpose after archive.
|
||||
## Requirements
|
||||
### Requirement: Agent Skill Media Model Selectors
|
||||
|
||||
The AI input bar SHALL show additional media model selectors when Agent mode has an explicitly selected Skill that is known to invoke media generation.
|
||||
|
||||
#### Scenario: Image or PPT Skill selected
|
||||
- **GIVEN** the user is in Agent mode
|
||||
- **AND** the selected Skill is classified as image or PPT output
|
||||
- **WHEN** the input bar renders
|
||||
- **THEN** it SHALL keep the text model selector for Agent analysis
|
||||
- **AND** it SHALL show an image model selector for the Skill's media generation
|
||||
|
||||
#### Scenario: Video Skill selected
|
||||
- **GIVEN** the user is in Agent mode
|
||||
- **AND** the selected Skill is classified as video output
|
||||
- **WHEN** the input bar renders
|
||||
- **THEN** it SHALL keep the text model selector for Agent analysis
|
||||
- **AND** it SHALL show a video model selector for the Skill's media generation
|
||||
|
||||
#### Scenario: Audio Skill selected
|
||||
- **GIVEN** the user is in Agent mode
|
||||
- **AND** the selected Skill is classified as audio output
|
||||
- **WHEN** the input bar renders
|
||||
- **THEN** it SHALL keep the text model selector for Agent analysis
|
||||
- **AND** it SHALL show an audio model selector for the Skill's media generation
|
||||
|
||||
#### Scenario: Auto Skill selected
|
||||
- **GIVEN** the user is in Agent mode
|
||||
- **AND** the selected Skill is Auto
|
||||
- **WHEN** the input bar renders
|
||||
- **THEN** it SHALL NOT show additional media model selectors
|
||||
|
||||
### Requirement: Agent Skill Media Model Routing
|
||||
|
||||
Agent and Skill workflows SHALL pass selected media model IDs and model references to downstream media generation tools.
|
||||
|
||||
#### Scenario: Dynamic media tool call
|
||||
- **GIVEN** Agent analysis emits a media generation tool call without a model
|
||||
- **WHEN** the execution context contains a selected model for that media type
|
||||
- **THEN** the generated workflow step SHALL include that selected model
|
||||
- **AND** it SHALL include the matching `modelRef` when available
|
||||
|
||||
#### Scenario: Parsed Skill workflow step
|
||||
- **GIVEN** a Skill DSL resolves directly to a media generation workflow step
|
||||
- **WHEN** the execution context contains a selected model for that media type
|
||||
- **THEN** the workflow step SHALL use the selected media model
|
||||
- **AND** it SHALL include the matching `modelRef` when available
|
||||
|
||||
### Requirement: AI Input Bar SHALL Distinguish Agent And Text Generation
|
||||
|
||||
The system SHALL expose `agent` and `text` as separate generation types in the AI input bar.
|
||||
|
||||
#### Scenario: User selects text generation
|
||||
- **WHEN** the user switches the generation type to `text`
|
||||
- **THEN** the AI input bar SHALL show text models
|
||||
- **AND** SHALL hide Skill selection
|
||||
- **AND** SHALL treat the request as direct text generation
|
||||
|
||||
#### Scenario: User selects agent generation
|
||||
- **WHEN** the user switches the generation type to `agent`
|
||||
- **THEN** the AI input bar SHALL show Skill selection
|
||||
- **AND** SHALL route the request through the existing Agent analysis flow
|
||||
|
||||
### Requirement: Text Generation SHALL Insert Results Into Canvas
|
||||
|
||||
The system SHALL insert direct text generation results into the canvas after the text model returns content.
|
||||
|
||||
#### Scenario: Text model returns markdown-like content
|
||||
- **WHEN** a direct text generation request completes
|
||||
- **THEN** the system SHALL insert the text result through the existing canvas insertion flow
|
||||
- **AND** MAY parse markdown cards before falling back to plain text insertion
|
||||
|
||||
### Requirement: Text Generation SHALL Support Scoped Model Parameters
|
||||
|
||||
The system SHALL persist text-generation model parameters independently from agent mode.
|
||||
|
||||
#### Scenario: User switches between text models
|
||||
- **WHEN** the user changes text models in direct text mode
|
||||
- **THEN** the system SHALL restore the last compatible parameters for the selected text model
|
||||
- **AND** SHALL NOT reuse agent-only state such as selected Skill
|
||||
|
||||
71
openspec/specs/audio-generation/spec.md
Normal file
71
openspec/specs/audio-generation/spec.md
Normal file
@@ -0,0 +1,71 @@
|
||||
# audio-generation Specification
|
||||
|
||||
## Purpose
|
||||
TBD - created by archiving change add-music-analyzer-suno-edit-actions. Update Purpose after archive.
|
||||
## Requirements
|
||||
### Requirement: Support Unified Suno Music Edit Actions In The Music Analyzer
|
||||
|
||||
The system SHALL expose Suno music generation, continuation, and infill as action variants within one unified music creation flow.
|
||||
|
||||
#### Scenario: User switches from generate to continue in one unified form
|
||||
|
||||
- **GIVEN** the user is editing music in the music analyzer generation page
|
||||
- **WHEN** the user changes the action from `generate` to `continue`
|
||||
- **THEN** the UI SHALL keep the user in the same unified form
|
||||
- **AND** SHALL reveal only the continuation parameters relevant to the selected action
|
||||
|
||||
#### Scenario: User switches from continue to infill in one unified form
|
||||
|
||||
- **GIVEN** the user is editing music in the music analyzer generation page
|
||||
- **WHEN** the user changes the action from `continue` to `infill`
|
||||
- **THEN** the UI SHALL remain in the same unified form
|
||||
- **AND** SHALL reveal `infill_start_s` and `infill_end_s`
|
||||
- **AND** SHALL preserve any compatible shared fields such as `prompt`, `title`, `tags`, and `mv`
|
||||
|
||||
### Requirement: Use clip_id As The Source Of Truth For Continuation Targets
|
||||
|
||||
The system SHALL use the Suno polling result field `clip_id` as the source-of-truth identifier for continuation and infill requests.
|
||||
|
||||
#### Scenario: Polling response discovers continuation clip ids before audio is ready
|
||||
|
||||
- **GIVEN** `/suno/fetch/{task_id}` returns generated items that already include `clip_id`
|
||||
- **WHEN** playable audio URLs are not yet fully available
|
||||
- **THEN** the system SHALL still remember those `clip_id` values
|
||||
- **AND** SHALL reuse them in later normalized results for continuation actions
|
||||
|
||||
#### Scenario: User launches continuation from a generated clip card
|
||||
|
||||
- **GIVEN** the music analyzer displays generated clips
|
||||
- **WHEN** the user chooses to continue or infill a clip
|
||||
- **THEN** the system SHALL use that clip's remembered `clip_id`
|
||||
- **AND** SHALL not substitute the list row `id` in place of `clip_id`
|
||||
|
||||
### Requirement: Scope Suno Music Parameters By Edit Action
|
||||
|
||||
The system SHALL validate and submit Suno music parameters according to the selected unified edit action.
|
||||
|
||||
#### Scenario: Basic generation omits continuation parameters
|
||||
|
||||
- **GIVEN** the selected action is `generate`
|
||||
- **WHEN** the user submits the request
|
||||
- **THEN** the system SHALL send `prompt`, `mv`, `title`, and `tags` when provided
|
||||
- **AND** SHALL omit `continue_clip_id`, `continue_at`, `infill_start_s`, and `infill_end_s`
|
||||
|
||||
#### Scenario: Continuation requires clip id and continue time
|
||||
|
||||
- **GIVEN** the selected action is `continue`
|
||||
- **WHEN** the user submits the request
|
||||
- **THEN** the system SHALL require `continue_clip_id`
|
||||
- **AND** SHALL require `continue_at`
|
||||
- **AND** SHALL submit both fields to `/suno/submit/music`
|
||||
|
||||
#### Scenario: Infill requires continuation anchor and infill window
|
||||
|
||||
- **GIVEN** the selected action is `infill`
|
||||
- **WHEN** the user submits the request
|
||||
- **THEN** the system SHALL require `continue_clip_id`
|
||||
- **AND** SHALL require `continue_at`
|
||||
- **AND** SHALL require `infill_start_s`
|
||||
- **AND** SHALL require `infill_end_s`
|
||||
- **AND** SHALL ensure `infill_start_s` is less than `infill_end_s`
|
||||
|
||||
85
openspec/specs/backup-restore/spec.md
Normal file
85
openspec/specs/backup-restore/spec.md
Normal file
@@ -0,0 +1,85 @@
|
||||
# backup-restore Specification
|
||||
|
||||
## Purpose
|
||||
TBD - created by archiving change add-complete-environment-backup-restore. Update Purpose after archive.
|
||||
## Requirements
|
||||
### Requirement: Complete Environment Backup
|
||||
The system SHALL support a complete backup mode that captures all durable user-facing environment data needed to restore the app to the backed-up state.
|
||||
|
||||
#### Scenario: Complete backup includes durable domains
|
||||
- **GIVEN** the user has projects, assets, tasks, workflows, prompts, knowledge base content, chats, playlists, skills, model preferences, and UI preferences
|
||||
- **WHEN** the user creates a complete backup
|
||||
- **THEN** the backup SHALL include every selected durable domain
|
||||
- **AND** the manifest SHALL record v4 schema metadata, selected domains, per-domain stats, and backup mode
|
||||
|
||||
### Requirement: Replace Restore
|
||||
The system SHALL support replace restore for complete backups by clearing selected local domains before importing backup data.
|
||||
|
||||
#### Scenario: Replace restore mirrors the backup
|
||||
- **GIVEN** the current browser has existing local data
|
||||
- **AND** the user selects replace restore for a complete backup
|
||||
- **WHEN** restore completes
|
||||
- **THEN** selected domains SHALL match the backup content instead of being merged with previous local content
|
||||
- **AND** the workspace SHALL reload and restore the backed-up current board when available
|
||||
|
||||
### Requirement: Encrypted Secrets
|
||||
The system SHALL export sensitive configuration only when the user explicitly includes secrets and provides a backup password.
|
||||
|
||||
#### Scenario: Secrets require password
|
||||
- **GIVEN** settings contain API keys, provider profiles, or sync credentials
|
||||
- **WHEN** the user creates a backup without enabling secrets
|
||||
- **THEN** sensitive values SHALL NOT be written to normal backup JSON
|
||||
- **WHEN** the user enables secrets and provides a password
|
||||
- **THEN** sensitive values SHALL be written only to an encrypted secrets payload
|
||||
|
||||
### Requirement: Full Task and Prompt Fidelity
|
||||
The system SHALL include full terminal and archived generation history required by prompt history, media library, PPT, audio, and task queue views.
|
||||
|
||||
#### Scenario: Task and prompt data survives restore
|
||||
- **GIVEN** completed or archived image, video, audio, PPT, text, and agent tasks exist
|
||||
- **WHEN** the user backs up and restores data
|
||||
- **THEN** restored task records SHALL be persisted to IndexedDB
|
||||
- **AND** prompt preset settings SHALL include all supported prompt types, deleted prompt contents, and prompt overrides
|
||||
|
||||
### Requirement: Backward Compatibility
|
||||
The system SHALL continue importing existing v2 and v3 backups.
|
||||
|
||||
#### Scenario: Legacy backups import incrementally
|
||||
- **GIVEN** a valid v2 or v3 backup without environment files
|
||||
- **WHEN** the user imports it
|
||||
- **THEN** existing prompt, project, asset, task, and knowledge base import behavior SHALL continue to work
|
||||
- **AND** missing v4 environment data SHALL be reported as skipped, not as a fatal error
|
||||
|
||||
### Requirement: Shared Backup Restore Core
|
||||
系统 SHALL 提供一套由主应用与 `sw-debug` 共用的备份恢复核心逻辑,用于统一备份格式、导出筛选、导入恢复顺序与去重规则。
|
||||
|
||||
#### Scenario: Main App and sw-debug export the same data semantics
|
||||
- **GIVEN** 主应用与 `sw-debug` 访问的是同一份项目、素材、任务、提示词与知识库数据
|
||||
- **WHEN** 用户分别从主应用与 `sw-debug` 执行备份
|
||||
- **THEN** 两边都必须产出兼容的 manifest 与 ZIP 目录结构
|
||||
- **AND** 音频、任务结果、知识库、项目目录和素材元数据的导出语义必须一致
|
||||
|
||||
#### Scenario: Shared core fixes apply to both environments
|
||||
- **GIVEN** 共享备份恢复核心修复了素材命名冲突或音频任务筛选问题
|
||||
- **WHEN** 主应用或 `sw-debug` 执行备份恢复
|
||||
- **THEN** 两边都必须同时继承同一修复行为
|
||||
- **AND** 不允许再出现仅一端生效、另一端仍保留旧逻辑的情况
|
||||
|
||||
### Requirement: Environment Adapter Boundary
|
||||
系统 SHALL 将备份恢复中的环境相关能力限制在适配层,以隔离核心逻辑与平台依赖。
|
||||
|
||||
#### Scenario: Core stays independent from app-specific services
|
||||
- **GIVEN** 共享备份恢复核心需要读取或写入数据
|
||||
- **WHEN** 核心执行导出或导入
|
||||
- **THEN** 核心只能通过适配接口访问项目、素材、任务、提示词、知识库与缓存能力
|
||||
- **AND** 核心不得直接依赖主应用 UI、React 状态或 `sw-debug` DOM 节点
|
||||
|
||||
### Requirement: Knowledge Base Parity
|
||||
系统 SHALL 保证主应用与 `sw-debug` 在共享内核接入后,对知识库备份与恢复采用同一数据结构与导入顺序。
|
||||
|
||||
#### Scenario: Knowledge base backup is available in both environments
|
||||
- **GIVEN** 知识库中存在目录、笔记、标签和图片
|
||||
- **WHEN** 用户从主应用或 `sw-debug` 执行备份恢复
|
||||
- **THEN** 两边都必须使用同一份知识库序列化结构
|
||||
- **AND** 导入后笔记数量、目录映射和标签关联必须保持一致
|
||||
|
||||
201
openspec/specs/canvas-audio-playback/spec.md
Normal file
201
openspec/specs/canvas-audio-playback/spec.md
Normal file
@@ -0,0 +1,201 @@
|
||||
# canvas-audio-playback Specification
|
||||
|
||||
## Purpose
|
||||
TBD - created by archiving change add-audio-playback-modes. Update Purpose after archive.
|
||||
## Requirements
|
||||
### Requirement: Shared playback modes for audio players
|
||||
The system SHALL provide shared playback controls for the global floating audio player and the music player tool.
|
||||
|
||||
#### Scenario: Switch playback speed from the floating player
|
||||
- **GIVEN** an audio or reading queue is active
|
||||
- **WHEN** the user changes playback speed from the floating player dropdown
|
||||
- **THEN** the system SHALL update the shared playback speed state
|
||||
- **AND** the music player tool SHALL reflect the same selected speed
|
||||
|
||||
#### Scenario: Switch playback speed from the music player tool
|
||||
- **GIVEN** an audio or reading queue is active
|
||||
- **WHEN** the user changes playback speed from the music player tool dropdown
|
||||
- **THEN** the system SHALL update the shared playback speed state
|
||||
- **AND** the floating player SHALL reflect the same selected speed
|
||||
|
||||
#### Scenario: Sync reading speed with TTS settings
|
||||
- **GIVEN** the active queue is a reading queue
|
||||
- **WHEN** the user changes playback speed from either player entry
|
||||
- **THEN** the system SHALL update the current reading playback speed
|
||||
- **AND** SHALL sync the same value to `tts.rate`
|
||||
|
||||
#### Scenario: Reflect external TTS speed changes during reading
|
||||
- **GIVEN** a reading queue is active
|
||||
- **WHEN** `tts.rate` changes from the settings panel
|
||||
- **THEN** the shared reading playback speed SHALL update
|
||||
- **AND** both player entries SHALL reflect the latest reading speed
|
||||
|
||||
### Requirement: Continue playback according to the selected mode
|
||||
The system SHALL determine queue continuation behavior according to the selected playback mode.
|
||||
|
||||
#### Scenario: Stop at the end in sequential mode
|
||||
- **GIVEN** the current playback mode is `顺序播放`
|
||||
- **WHEN** the last item in the active queue finishes
|
||||
- **THEN** the system SHALL stop playback on the current item
|
||||
|
||||
#### Scenario: Restart queue in list-loop mode
|
||||
- **GIVEN** the current playback mode is `列表循环`
|
||||
- **WHEN** the last item in the active queue finishes
|
||||
- **THEN** the system SHALL continue playback from the first item in the same queue
|
||||
|
||||
#### Scenario: Replay current item in single-loop mode
|
||||
- **GIVEN** the current playback mode is `单曲循环`
|
||||
- **WHEN** the active queue item finishes
|
||||
- **THEN** the system SHALL restart the same queue item from the beginning
|
||||
|
||||
#### Scenario: Pick another item in shuffle mode
|
||||
- **GIVEN** the current playback mode is `随机播放`
|
||||
- **WHEN** the active queue item finishes and the queue contains multiple items
|
||||
- **THEN** the system SHALL continue playback with a different queue item when possible
|
||||
|
||||
### Requirement: Persistent audio playlists
|
||||
The system SHALL provide persistent audio playlists for audio assets, including a default favorites playlist.
|
||||
|
||||
#### Scenario: Initialize default favorites playlist
|
||||
- **WHEN** the audio playlist feature is initialized
|
||||
- **THEN** the system SHALL ensure a system playlist named `收藏` exists
|
||||
- **AND** the playlist SHALL be available without requiring user creation
|
||||
|
||||
#### Scenario: Create a custom playlist
|
||||
- **WHEN** the user creates a new playlist with a valid name
|
||||
- **THEN** the system SHALL persist the playlist
|
||||
- **AND** the playlist SHALL appear in the music player and media library playlist selectors
|
||||
|
||||
### Requirement: Manage playlist membership from audio asset cards
|
||||
The system SHALL allow users to manage playlist membership from audio asset cards.
|
||||
|
||||
#### Scenario: Toggle favorites from an audio card
|
||||
- **GIVEN** an audio asset card is visible in the media library
|
||||
- **WHEN** the user activates the favorite heart control
|
||||
- **THEN** the system SHALL add or remove the asset from the favorites playlist
|
||||
- **AND** the card SHALL reflect the updated favorite state
|
||||
|
||||
#### Scenario: Add audio to a selected playlist from context menu
|
||||
- **GIVEN** an audio asset card is visible in the media library
|
||||
- **WHEN** the user opens the context menu and selects a target playlist
|
||||
- **THEN** the system SHALL add the audio asset to that playlist without duplicating the same asset within the playlist
|
||||
|
||||
### Requirement: Preserve separate canvas and playlist playback queues
|
||||
The system SHALL preserve canvas playback behavior while supporting playlist-based playback.
|
||||
|
||||
#### Scenario: Keep canvas playback queue unchanged
|
||||
- **GIVEN** the user starts playback from a canvas audio node
|
||||
- **WHEN** the global player is used to navigate previous or next tracks
|
||||
- **THEN** the player SHALL continue using the current canvas audio queue
|
||||
|
||||
#### Scenario: Use playlist queue for music player playback
|
||||
- **GIVEN** the user starts playback from a music playlist
|
||||
- **WHEN** the global player is used to navigate previous or next tracks
|
||||
- **THEN** the player SHALL use the active playlist queue
|
||||
- **AND** the player SHALL expose the active playlist name in its UI
|
||||
|
||||
### Requirement: Play Canvas Audio Assets In Place
|
||||
|
||||
The system SHALL allow audio assets inserted onto the canvas to be played and paused directly within the workspace.
|
||||
|
||||
#### Scenario: Play an inserted audio node on the canvas
|
||||
|
||||
- **GIVEN** an audio task has completed and its result has been inserted onto the canvas
|
||||
- **WHEN** the user activates the audio node
|
||||
- **THEN** the system SHALL begin playback for that node inside the workspace
|
||||
- **AND** SHALL not require opening the audio URL in a separate browser tab
|
||||
|
||||
#### Scenario: Pause the currently playing audio node
|
||||
|
||||
- **GIVEN** a canvas audio node is currently playing
|
||||
- **WHEN** the user activates the same node again
|
||||
- **THEN** the system SHALL pause playback
|
||||
- **AND** SHALL update the node's active playback state accordingly
|
||||
|
||||
### Requirement: Render Audio As A First-Class Canvas Component
|
||||
|
||||
The system SHALL render newly inserted audio assets as dedicated audio components instead of static SVG image cards.
|
||||
|
||||
#### Scenario: Insert a generated audio result as a component node
|
||||
|
||||
- **GIVEN** an audio generation result includes a playable URL and metadata
|
||||
- **WHEN** the result is inserted onto the canvas
|
||||
- **THEN** the canvas SHALL create an audio-specific element
|
||||
- **AND** the element SHALL render structured UI such as title, cover, waveform, or play state feedback
|
||||
|
||||
#### Scenario: Show playback feedback inside the audio node
|
||||
|
||||
- **GIVEN** a canvas audio node is active or currently playing
|
||||
- **WHEN** the node re-renders
|
||||
- **THEN** the node SHALL visually reflect the current playback state
|
||||
- **AND** SHALL not appear as a plain static image thumbnail
|
||||
|
||||
#### Scenario: Drive waveform rhythm from the active audio signal when available
|
||||
|
||||
- **GIVEN** a canvas audio node is currently playing
|
||||
- **WHEN** browser audio analysis is available for the active media source
|
||||
- **THEN** the node waveform and rhythm feedback SHALL respond to the live audio signal instead of only using static decorative animation
|
||||
- **AND** inactive nodes SHALL not require the same high-frequency visual updates
|
||||
|
||||
#### Scenario: Gracefully fall back when audio analysis is unavailable
|
||||
|
||||
- **GIVEN** a canvas audio node is currently playing
|
||||
- **WHEN** browser capabilities or media origin rules prevent live audio analysis
|
||||
- **THEN** playback SHALL continue
|
||||
- **AND** the node SHALL fall back to a non-reactive waveform presentation without crashing the workspace
|
||||
|
||||
#### Scenario: Keep audio node composition stable while resizing
|
||||
|
||||
- **GIVEN** a canvas audio node is selected
|
||||
- **WHEN** the user resizes the node
|
||||
- **THEN** the node SHALL preserve its intended component proportions
|
||||
- **AND** SHALL avoid arbitrary stretching that distorts the cover, waveform, and timing layout
|
||||
|
||||
#### Scenario: Hide technical provider details from the main node surface
|
||||
|
||||
- **GIVEN** a canvas audio node retains provider metadata for follow-up actions
|
||||
- **WHEN** the node is rendered in the workspace
|
||||
- **THEN** the visible node UI SHALL prioritize title, playback state, and user-facing semantic information
|
||||
- **AND** SHALL not expose technical model or provider identifiers as a primary badge
|
||||
|
||||
### Requirement: Provide A Global Canvas Audio Player Overlay
|
||||
|
||||
The system SHALL expose a lightweight global playback overlay while canvas audio is active.
|
||||
|
||||
#### Scenario: Show the top player while audio is playing
|
||||
|
||||
- **GIVEN** a canvas audio asset is currently playing
|
||||
- **WHEN** playback is active
|
||||
- **THEN** the workspace SHALL display a compact playback overlay near the top center of the canvas
|
||||
- **AND** SHALL show at least the current title, play state, and progress
|
||||
|
||||
#### Scenario: Control playback queue and volume from the overlay
|
||||
|
||||
- **GIVEN** the global playback overlay is visible for a canvas audio asset
|
||||
- **WHEN** the user uses the overlay controls
|
||||
- **THEN** the overlay SHALL support previous and next track navigation within the current canvas audio queue
|
||||
- **AND** SHALL support adjusting playback volume without leaving the workspace
|
||||
|
||||
#### Scenario: Close the overlay and stop playback
|
||||
|
||||
- **GIVEN** the global playback overlay is visible
|
||||
- **WHEN** the user closes the overlay
|
||||
- **THEN** the system SHALL stop the active playback
|
||||
- **AND** SHALL clear the current active audio state
|
||||
|
||||
### Requirement: Preserve Audio Provider Metadata For Follow-Up Actions
|
||||
|
||||
The system SHALL preserve provider-level audio identifiers from generation results through task storage and canvas insertion.
|
||||
|
||||
#### Scenario: Keep clip identifiers on inserted audio nodes
|
||||
|
||||
- **GIVEN** an audio generation result includes provider task and clip identifiers
|
||||
- **WHEN** that result is inserted onto the canvas
|
||||
- **THEN** the inserted audio element SHALL retain the corresponding provider task identifier and clip identifier metadata
|
||||
|
||||
#### Scenario: Reuse stored provider metadata after task restoration
|
||||
|
||||
- **GIVEN** an audio task has been persisted and later restored from storage or sync
|
||||
- **WHEN** the restored result is inserted or inspected
|
||||
- **THEN** the restored task result SHALL still expose the provider task identifier and clip identifiers needed for follow-up actions
|
||||
|
||||
49
openspec/specs/canvas-markdown-toolbar/spec.md
Normal file
49
openspec/specs/canvas-markdown-toolbar/spec.md
Normal file
@@ -0,0 +1,49 @@
|
||||
# canvas-markdown-toolbar Specification
|
||||
|
||||
## Purpose
|
||||
TBD - created by archiving change add-canvas-markdown-kb-actions. Update Purpose after archive.
|
||||
## Requirements
|
||||
### Requirement: Canvas Markdown 卡片知识库保存入口
|
||||
The system SHALL expose a save-to-knowledge-base action in the canvas popup toolbar when the current selection is a single Markdown card that has not been linked to a knowledge-base note.
|
||||
|
||||
#### Scenario: Save an unlinked card to the knowledge base
|
||||
- **GIVEN** the user selects a single Markdown card on the canvas
|
||||
- **AND** the card does not have a `noteId`
|
||||
- **WHEN** the popup toolbar is shown
|
||||
- **THEN** the toolbar SHALL display a save-to-knowledge-base action
|
||||
- **AND** activating the action SHALL create a knowledge-base note from the card content
|
||||
- **AND** the created note id SHALL be written back to the card
|
||||
|
||||
### Requirement: Markdown 卡片 duplicate 必须克隆元素
|
||||
The system SHALL duplicate a selected Markdown card as a new canvas card element instead of copying its text content to the clipboard.
|
||||
|
||||
#### Scenario: Duplicate a linked Markdown card
|
||||
- **GIVEN** the user selects a single Markdown card on the canvas
|
||||
- **AND** the card may already be linked to a knowledge-base note
|
||||
- **WHEN** the user activates the duplicate action in the popup toolbar
|
||||
- **THEN** the system SHALL create a new Markdown card element with the same visible content
|
||||
- **AND** the new card SHALL not reuse the original card's knowledge-base note id
|
||||
|
||||
### Requirement: Markdown 卡片与文本元素内容合并
|
||||
The system SHALL expose a merge-content action in the canvas popup toolbar when the current multi-selection contains only Markdown cards and plain text elements.
|
||||
|
||||
#### Scenario: Merge selected Markdown cards and text elements
|
||||
- **GIVEN** the user selects multiple canvas elements
|
||||
- **AND** every selected element is either a Markdown card or a plain text element
|
||||
- **WHEN** the popup toolbar is shown
|
||||
- **THEN** the toolbar SHALL display a merge-content action
|
||||
- **AND** activating the action SHALL merge all selected content into a single Markdown card
|
||||
- **AND** the merge order SHALL follow the canvas position rule of right into left and bottom into top
|
||||
- **AND** all merged-away elements SHALL be removed from the canvas
|
||||
|
||||
### Requirement: 合并时收敛知识库关联
|
||||
The system SHALL preserve at most one knowledge-base note binding after a content merge and delete any extra linked notes.
|
||||
|
||||
#### Scenario: Merge selection with multiple linked notes
|
||||
- **GIVEN** the user merges multiple selected Markdown cards or text elements
|
||||
- **AND** more than one selected card is linked to a different knowledge-base note
|
||||
- **WHEN** the merge completes
|
||||
- **THEN** the merged Markdown card SHALL keep exactly one knowledge-base note id
|
||||
- **AND** the preserved knowledge-base note SHALL be updated with the merged content
|
||||
- **AND** every other linked knowledge-base note from the merged selection SHALL be deleted
|
||||
|
||||
26
openspec/specs/canvas-text-to-speech-toolbar/spec.md
Normal file
26
openspec/specs/canvas-text-to-speech-toolbar/spec.md
Normal file
@@ -0,0 +1,26 @@
|
||||
# canvas-text-to-speech-toolbar Specification
|
||||
|
||||
## Purpose
|
||||
TBD - created by archiving change add-canvas-text-to-speech-toolbar. Update Purpose after archive.
|
||||
## Requirements
|
||||
### Requirement: Canvas popup toolbar text-to-speech
|
||||
The system SHALL expose a text-to-speech action in the canvas popup toolbar when the current selection contains readable text or markdown content.
|
||||
|
||||
#### Scenario: Read a selected text element
|
||||
- **GIVEN** the user has selected a text-bearing canvas element
|
||||
- **WHEN** the popup toolbar is shown
|
||||
- **THEN** the toolbar SHALL display a text-to-speech action
|
||||
- **AND** activating the action SHALL read the selected element content aloud
|
||||
|
||||
#### Scenario: Prefer card text selection over full card content
|
||||
- **GIVEN** the user has selected a card element with markdown content
|
||||
- **AND** the user has highlighted a portion of text inside the card body
|
||||
- **WHEN** the text-to-speech action is activated
|
||||
- **THEN** the system SHALL read the highlighted text instead of the full card content
|
||||
|
||||
#### Scenario: Toggle pause and resume while speaking
|
||||
- **GIVEN** the canvas text-to-speech action is currently reading content aloud
|
||||
- **WHEN** the user activates the same action again
|
||||
- **THEN** the system SHALL pause the current reading
|
||||
- **AND** a subsequent activation SHALL resume the same reading session
|
||||
|
||||
35
openspec/specs/canvas-text-to-speech/spec.md
Normal file
35
openspec/specs/canvas-text-to-speech/spec.md
Normal file
@@ -0,0 +1,35 @@
|
||||
# canvas-text-to-speech Specification
|
||||
|
||||
## Purpose
|
||||
TBD - created by archiving change add-canvas-text-to-speech-toolbar. Update Purpose after archive.
|
||||
## Requirements
|
||||
### Requirement: Read selected canvas text aloud
|
||||
The system SHALL expose a text-to-speech action in the popup toolbar when the current canvas selection contains readable text content.
|
||||
|
||||
#### Scenario: Read a selected text element
|
||||
- **GIVEN** the user selects a canvas text element with non-empty text
|
||||
- **WHEN** the popup toolbar is shown
|
||||
- **THEN** the toolbar SHALL display a speech action
|
||||
- **AND** activating the action SHALL read the text content aloud
|
||||
|
||||
#### Scenario: Pause and resume active speech
|
||||
- **GIVEN** canvas text-to-speech is currently speaking
|
||||
- **WHEN** the user activates the same speech action again
|
||||
- **THEN** the system SHALL pause playback
|
||||
- **AND** activating it once more SHALL resume playback
|
||||
|
||||
### Requirement: Prefer explicit Card text selection
|
||||
The system SHALL prefer a concrete text selection inside a selected Card or Markdown container over the full element content.
|
||||
|
||||
#### Scenario: Read selected text inside a Card
|
||||
- **GIVEN** the user has selected a Card on the canvas
|
||||
- **AND** the user has highlighted a text range inside the Card body
|
||||
- **WHEN** the speech action is activated
|
||||
- **THEN** the system SHALL read only the highlighted text range
|
||||
|
||||
#### Scenario: Fall back to the whole Card content
|
||||
- **GIVEN** the user has selected a Card on the canvas
|
||||
- **AND** there is no active text range inside the Card body
|
||||
- **WHEN** the speech action is activated
|
||||
- **THEN** the system SHALL read the Card title and body content
|
||||
|
||||
82
openspec/specs/image-generation-feedback/spec.md
Normal file
82
openspec/specs/image-generation-feedback/spec.md
Normal file
@@ -0,0 +1,82 @@
|
||||
# image-generation-feedback Specification
|
||||
|
||||
## Purpose
|
||||
TBD - created by archiving change update-image-generation-anchor-feedback. Update Purpose after archive.
|
||||
## Requirements
|
||||
### Requirement: Image Generation SHALL Use Canvas Anchors Instead Of Default Progress Cards
|
||||
|
||||
The system SHALL represent image-generation progress in the canvas through lightweight generation anchors instead of default large workflow cards.
|
||||
|
||||
#### Scenario: User submits a single image generation request
|
||||
- **WHEN** the user submits an `image` generation request from the AI input bar
|
||||
- **THEN** the canvas SHALL show a lightweight generation anchor near the expected insertion location
|
||||
- **AND** SHALL NOT default to a large progress card for that image request
|
||||
|
||||
#### Scenario: Non-image tasks keep existing feedback behavior
|
||||
- **WHEN** the user submits a non-image generation request
|
||||
- **THEN** the system MAY continue to use the existing task feedback behavior
|
||||
- **AND** SHALL NOT be forced into the image anchor presentation model
|
||||
|
||||
### Requirement: Image Generation Anchors SHALL Derive Geometry From Submission-Time Signals
|
||||
|
||||
The system SHALL determine the image anchor geometry from the strongest available submission-time signals before the final image result is returned.
|
||||
|
||||
#### Scenario: Anchor inherits frame geometry
|
||||
- **GIVEN** the user submits image generation while a target frame is selected
|
||||
- **AND** the request contains `targetFrameId` and `targetFrameDimensions`
|
||||
- **WHEN** the anchor is created
|
||||
- **THEN** the anchor SHALL use the frame geometry as its primary outer shell
|
||||
|
||||
#### Scenario: Anchor inherits requested aspect ratio
|
||||
- **GIVEN** the request has no target frame
|
||||
- **AND** the request contains a valid `size` ratio
|
||||
- **WHEN** the anchor is created
|
||||
- **THEN** the anchor SHALL derive its aspect ratio from that requested size
|
||||
|
||||
#### Scenario: Anchor falls back to a ghost anchor
|
||||
- **GIVEN** the request has no target frame
|
||||
- **AND** the request has no stable ratio signal
|
||||
- **WHEN** the anchor is created
|
||||
- **THEN** the system SHALL create a lightweight ghost anchor instead of a full image frame placeholder
|
||||
|
||||
### Requirement: Image Generation SHALL Expose User-Centered Lifecycle States
|
||||
|
||||
The system SHALL map image generation into user-centered lifecycle states that prioritize creation continuity over raw workflow details.
|
||||
|
||||
#### Scenario: User sees lifecycle progression
|
||||
- **WHEN** an image generation task progresses from submission to insertion
|
||||
- **THEN** the UI SHALL express the lifecycle using user-facing states such as `submitted`, `queued`, `generating`, `developing`, `inserting`, `completed`, and `failed`
|
||||
- **AND** SHALL allow those states to be rendered without exposing the full internal workflow step list in the canvas by default
|
||||
|
||||
### Requirement: Completed Images SHALL Replace Anchors With Spatial Continuity
|
||||
|
||||
The system SHALL transition from anchor to final image with spatial continuity so the result appears to emerge from the same canvas location.
|
||||
|
||||
#### Scenario: Image result is inserted into the canvas
|
||||
- **WHEN** the image generation result is ready and the insertion flow begins
|
||||
- **THEN** the final image SHALL take over the anchor location with a continuous visual transition
|
||||
- **AND** the anchor SHALL fade out after the image is stably inserted
|
||||
|
||||
### Requirement: Failed Image Generation SHALL Preserve Contextual Recovery
|
||||
|
||||
The system SHALL preserve a contextual recovery point when image generation fails.
|
||||
|
||||
#### Scenario: Image generation fails before insertion
|
||||
- **WHEN** an image generation task fails
|
||||
- **THEN** the anchor SHALL remain in place as a failure node
|
||||
- **AND** SHALL expose a retry path without requiring the user to rediscover the original insertion context
|
||||
|
||||
### Requirement: Image Generation Anchors SHALL Defer Detailed Execution History To Task Details
|
||||
|
||||
The system SHALL keep canvas anchors lightweight and defer detailed execution history to the task detail layer.
|
||||
|
||||
#### Scenario: Canvas anchor shows only concise progress context
|
||||
- **WHEN** an image generation anchor is rendered in the canvas
|
||||
- **THEN** it SHALL prioritize stage, lightweight progress, and direct recovery actions
|
||||
- **AND** SHALL NOT default to rendering the full workflow step list inside the canvas object
|
||||
|
||||
#### Scenario: Users need detailed failure or history information
|
||||
- **WHEN** the user requests more detail about an image generation task
|
||||
- **THEN** the system SHALL provide that information through the task detail layer
|
||||
- **AND** the anchor MAY offer a navigation affordance without becoming the primary detail container
|
||||
|
||||
48
openspec/specs/image-generation/spec.md
Normal file
48
openspec/specs/image-generation/spec.md
Normal file
@@ -0,0 +1,48 @@
|
||||
# image-generation Specification
|
||||
|
||||
## Purpose
|
||||
TBD - created by archiving change add-gpt-image-edit-support. Update Purpose after archive.
|
||||
## Requirements
|
||||
### Requirement: Support Official GPT Image Edit Requests
|
||||
|
||||
The system SHALL send official GPT Image edit requests to `/images/edits` when an official GPT Image profile is selected and the image request includes edit inputs.
|
||||
|
||||
#### Scenario: Reference-image request uses edit endpoint
|
||||
|
||||
- **GIVEN** a provider profile resolves image API compatibility to `openai-gpt-image`
|
||||
- **AND** the selected model is a GPT Image model
|
||||
- **AND** the image request includes at least one reference image
|
||||
- **WHEN** the image task is executed
|
||||
- **THEN** the GPT Image adapter SHALL send the request to `/images/edits`
|
||||
- **AND** include input images as multipart `image[]` file fields
|
||||
- **AND** SHALL NOT include `response_format`
|
||||
|
||||
#### Scenario: Text-only request remains generation
|
||||
|
||||
- **GIVEN** a provider profile resolves image API compatibility to `openai-gpt-image`
|
||||
- **AND** the selected model is a GPT Image model
|
||||
- **AND** the image request has no reference images or edit inputs
|
||||
- **WHEN** the image task is executed
|
||||
- **THEN** the GPT Image adapter SHALL send the request to `/images/generations`
|
||||
|
||||
### Requirement: Route Tuzi GPT Image Through Dedicated Adapter
|
||||
|
||||
The system SHALL route Tuzi GPT Image generation and edit requests through the dedicated Tuzi GPT Image adapter when the selected profile resolves to Tuzi GPT Image compatibility.
|
||||
|
||||
#### Scenario: Tuzi GPT request uses Tuzi adapter
|
||||
|
||||
- **GIVEN** a provider profile resolves image API compatibility to `tuzi-gpt-image`
|
||||
- **AND** the selected model is a GPT Image model
|
||||
- **WHEN** the image task is executed
|
||||
- **THEN** the request SHALL be handled by the dedicated Tuzi GPT Image adapter
|
||||
- **AND** SHALL NOT rely on GPT-specific translation logic inside the generic default adapter
|
||||
|
||||
### Requirement: Preserve Generic Basic Compatibility
|
||||
|
||||
The system SHALL preserve the default adapter behavior only for generic OpenAI-compatible image gateways that resolve to the basic compatibility mode.
|
||||
|
||||
#### Scenario: Generic compatibility stays basic
|
||||
|
||||
- **GIVEN** a provider profile resolves image API compatibility to `openai-compatible-basic`
|
||||
- **WHEN** the image task is executed
|
||||
- **THEN** the request SHALL remain eligible for the default adapter
|
||||
43
openspec/specs/markdown-media-embeds/spec.md
Normal file
43
openspec/specs/markdown-media-embeds/spec.md
Normal file
@@ -0,0 +1,43 @@
|
||||
# markdown-media-embeds Specification
|
||||
|
||||
## Purpose
|
||||
TBD - created by archiving change add-kb-asset-embeds-and-markdown-card-rendering. Update Purpose after archive.
|
||||
## Requirements
|
||||
### Requirement: 知识库 Markdown 编辑器必须支持素材库引用
|
||||
The system SHALL allow users to insert media-library assets into knowledge-base markdown notes without duplicating media content into the note body.
|
||||
|
||||
#### Scenario: Insert an asset into a note
|
||||
- **GIVEN** the user is editing a knowledge-base note
|
||||
- **WHEN** the user opens the media library and selects an asset
|
||||
- **THEN** the editor SHALL insert a markdown asset reference into the note content
|
||||
- **AND** the inserted content SHALL preserve the referenced asset id
|
||||
|
||||
### Requirement: Markdown 渲染必须支持图片、视频、音频素材引用
|
||||
The system SHALL resolve markdown asset references and render the referenced media inline in markdown preview surfaces.
|
||||
|
||||
#### Scenario: Render an image asset reference
|
||||
- **GIVEN** a markdown body contains an `asset://` reference to an image asset
|
||||
- **WHEN** the markdown is rendered in preview
|
||||
- **THEN** the system SHALL display the referenced image inline
|
||||
|
||||
#### Scenario: Render a video or audio asset reference
|
||||
- **GIVEN** a markdown body contains an `asset://` reference to a video or audio asset
|
||||
- **WHEN** the markdown is rendered in preview
|
||||
- **THEN** the system SHALL display an inline player for the referenced media
|
||||
|
||||
### Requirement: 画布 Markdown 卡片必须复用同一套素材渲染
|
||||
The system SHALL render markdown asset references consistently in canvas markdown cards and in the knowledge-base editor preview.
|
||||
|
||||
#### Scenario: Display the same note content in a canvas card
|
||||
- **GIVEN** a markdown body with media-library asset references is shown inside a canvas markdown card
|
||||
- **WHEN** the card is rendered
|
||||
- **THEN** the card SHALL display the same inline media presentation as the knowledge-base preview
|
||||
|
||||
### Requirement: 缺失素材必须有安全降级
|
||||
The system SHALL replace unresolved markdown asset references with a visible placeholder instead of failing the render.
|
||||
|
||||
#### Scenario: Referenced asset has been deleted
|
||||
- **GIVEN** a markdown body references an asset id that no longer exists
|
||||
- **WHEN** the markdown is rendered
|
||||
- **THEN** the system SHALL show a missing-asset placeholder in place of the media
|
||||
|
||||
60
openspec/specs/media-cache-warnings/spec.md
Normal file
60
openspec/specs/media-cache-warnings/spec.md
Normal file
@@ -0,0 +1,60 @@
|
||||
# media-cache-warnings Specification
|
||||
|
||||
## Purpose
|
||||
TBD - created by archiving change add-cache-failure-download-badges. Update Purpose after archive.
|
||||
## Requirements
|
||||
### Requirement: 缓存失败媒体必须携带下载提醒状态
|
||||
系统 SHALL 为浏览器缓存失败或已知不可缓存的远程图片/视频结果记录可选警告状态,用于提示用户尽快下载保存。
|
||||
|
||||
#### Scenario: 远程媒体缓存失败
|
||||
- **GIVEN** 图片或视频任务结果已生成远程 URL
|
||||
- **AND** 浏览器缓存流程因跨域、网络或响应不可读而失败
|
||||
- **WHEN** 系统更新任务结果或保存素材
|
||||
- **THEN** 该媒体应携带缓存警告状态
|
||||
- **AND** 警告状态应包含可展示原因和检测时间
|
||||
|
||||
### Requirement: 素材库必须展示缓存失败角标
|
||||
系统 SHALL 在素材库中为携带缓存警告或缓存状态明确为失败的图片/视频素材显示可见角标。
|
||||
|
||||
#### Scenario: 用户浏览缓存失败素材
|
||||
- **GIVEN** 素材库中某图片或视频未能缓存到浏览器
|
||||
- **WHEN** 用户打开素材库并看到该素材卡片
|
||||
- **THEN** 卡片应显示“需下载”或等价语义角标
|
||||
- **AND** 用户 hover 角标时应看到无法缓存与链接可能过期的说明
|
||||
|
||||
### Requirement: 任务队列必须展示缓存失败角标
|
||||
系统 SHALL 在任务队列完成态媒体结果中为缓存失败或缓存状态明确为错误的图片/视频显示可见角标。
|
||||
|
||||
#### Scenario: 用户查看刚完成且缓存失败的视频任务
|
||||
- **GIVEN** 视频任务已完成并返回可预览远程 URL
|
||||
- **AND** 该 URL 未能缓存到浏览器
|
||||
- **WHEN** 用户查看任务队列结果卡片
|
||||
- **THEN** 结果卡片应显示下载提醒角标
|
||||
- **AND** hover 角标时应提示用户尽快下载保存
|
||||
|
||||
### Requirement: 提醒判断必须与模型无关
|
||||
系统 SHALL 只根据缓存结果、缓存状态或媒体对象上的缓存警告决定是否展示下载提醒,不得根据模型名、供应商名或 URL 域名硬编码判断。
|
||||
|
||||
#### Scenario: 不同模型产生相同缓存失败结果
|
||||
- **GIVEN** 两个不同模型生成的媒体都发生浏览器缓存失败
|
||||
- **WHEN** 用户在素材库或任务队列查看这些媒体
|
||||
- **THEN** 两个媒体都应显示缓存失败下载提醒
|
||||
- **AND** 提醒文案不应依赖具体模型名称
|
||||
|
||||
### Requirement: 提醒判断不得主动批量探测跨域资源
|
||||
系统 SHALL 使用已有缓存状态和任务结果元数据来决定是否展示提醒,不得在列表渲染期间对每个远程资源发起额外跨域探测请求。
|
||||
|
||||
#### Scenario: 用户打开包含大量远程素材的素材库
|
||||
- **GIVEN** 素材库中存在大量远程图片和视频
|
||||
- **WHEN** UI 渲染素材列表
|
||||
- **THEN** 系统不应为了判断角标而批量 fetch 远程资源
|
||||
- **AND** 列表渲染不应被缓存检测阻塞
|
||||
|
||||
### Requirement: 已成功缓存的媒体不得显示缓存失败角标
|
||||
系统 SHALL 对已确认缓存成功的图片/视频隐藏缓存失败下载提醒,避免误导用户。
|
||||
|
||||
#### Scenario: 用户浏览已离线缓存的素材
|
||||
- **GIVEN** 某图片或视频已成功写入浏览器缓存
|
||||
- **WHEN** 用户在素材库或任务队列查看该媒体
|
||||
- **THEN** 系统不应显示缓存失败或尽快下载角标
|
||||
|
||||
33
openspec/specs/media-preview/spec.md
Normal file
33
openspec/specs/media-preview/spec.md
Normal file
@@ -0,0 +1,33 @@
|
||||
# media-preview Specification
|
||||
|
||||
## Purpose
|
||||
TBD - created by archiving change update-video-poster-preview-fallback. Update Purpose after archive.
|
||||
## Requirements
|
||||
### Requirement: 视频展示必须优先使用海报预览
|
||||
系统 SHALL 在列表、网格、缩略图等非必须即时播放的视频展示场景中优先使用图片海报,而不是首次直接渲染视频内容。
|
||||
|
||||
#### Scenario: 缓存视频首次出现在素材库列表
|
||||
- **GIVEN** 视频资源已缓存到本地虚拟路径
|
||||
- **WHEN** 用户首次打开素材库或滚动到该素材
|
||||
- **THEN** 界面应优先请求该视频对应的海报图
|
||||
- **AND** 不应依赖首次解码 `<video>` 作为默认展示路径
|
||||
|
||||
### Requirement: 海报失败时必须回退到视频预览
|
||||
系统 SHALL 在视频海报不可用或加载失败时自动回退到原生视频预览,避免出现“完全不可预览”的状态。
|
||||
|
||||
#### Scenario: 跨域视频无法生成首帧
|
||||
- **GIVEN** 视频资源因跨域限制无法提取首帧或海报图加载失败
|
||||
- **WHEN** 页面尝试展示该视频
|
||||
- **THEN** 系统应自动改用 `<video>` 进行预览
|
||||
- **AND** 用户仍可看到该视频内容或继续播放
|
||||
|
||||
### Requirement: 可点击播放场景必须支持先海报后播放
|
||||
系统 SHALL 在允许用户直接播放视频的详情或预览场景中支持先显示海报,再在用户触发后切换为原生视频播放器。
|
||||
|
||||
#### Scenario: 详情面板中的视频点击播放
|
||||
- **GIVEN** 某视频展示场景支持用户直接点击播放
|
||||
- **WHEN** 海报图已成功展示
|
||||
- **AND** 用户点击该海报
|
||||
- **THEN** 系统应切换为原生 `<video controls>`
|
||||
- **AND** 用户可正常播放该视频
|
||||
|
||||
112
openspec/specs/ppt-editing/spec.md
Normal file
112
openspec/specs/ppt-editing/spec.md
Normal file
@@ -0,0 +1,112 @@
|
||||
# ppt-editing Specification
|
||||
|
||||
## Purpose
|
||||
TBD - created by archiving change add-ppt-slide-transitions. Update Purpose after archive.
|
||||
## Requirements
|
||||
### Requirement: PPT Page Transition Menu
|
||||
|
||||
The system SHALL provide a per-page PPT transition menu from the single-page PPT right-click menu.
|
||||
|
||||
#### Scenario: Hover transition submenu
|
||||
|
||||
- **GIVEN** the PPT editing panel shows slide page cards
|
||||
- **WHEN** the user right-clicks a single PPT page card and hovers the animation menu
|
||||
- **THEN** the system SHALL show supported slide transition choices
|
||||
- **AND** the currently selected transition SHALL be indicated
|
||||
|
||||
#### Scenario: Select transition
|
||||
|
||||
- **GIVEN** the user opens the PPT page transition submenu
|
||||
- **WHEN** the user selects a transition
|
||||
- **THEN** the system SHALL store the transition on that page's PPT metadata
|
||||
- **AND** subsequent editor renders SHALL show the selected transition as current
|
||||
|
||||
### Requirement: PPT Slideshow Transition Playback
|
||||
|
||||
The system SHALL apply the selected per-page transition during in-app PPT slideshow playback.
|
||||
|
||||
#### Scenario: Navigate to page with transition
|
||||
|
||||
- **GIVEN** a PPT page has a supported transition configured
|
||||
- **WHEN** slideshow playback navigates to that page
|
||||
- **THEN** the visible page change SHALL use the configured transition effect
|
||||
|
||||
#### Scenario: Reduced motion
|
||||
|
||||
- **GIVEN** the user environment prefers reduced motion
|
||||
- **WHEN** slideshow playback navigates between PPT pages
|
||||
- **THEN** the system SHALL avoid animated transition effects
|
||||
|
||||
### Requirement: PPTX Transition Export
|
||||
|
||||
The system SHALL include supported per-page slide transitions in downloaded PPTX files.
|
||||
|
||||
#### Scenario: Export configured transitions
|
||||
|
||||
- **GIVEN** PPT pages have supported transitions configured
|
||||
- **WHEN** the user downloads the PPT deck
|
||||
- **THEN** the generated PPTX SHALL include slide transition metadata for those pages
|
||||
- **AND** pages without configured transitions SHALL keep the existing no-transition behavior
|
||||
|
||||
#### Scenario: Ignore invalid transition metadata
|
||||
|
||||
- **GIVEN** a PPT page contains missing or invalid transition metadata
|
||||
- **WHEN** the user downloads the PPT deck or plays the slideshow
|
||||
- **THEN** the system SHALL treat that page as having no transition
|
||||
|
||||
### Requirement: Image-First PPT Generation
|
||||
The system SHALL generate PPT pages as slide Frames whose primary visual content is a complete 16:9 generated image containing the page text, layout, background, and visual design.
|
||||
|
||||
#### Scenario: Generate PPT pages from content
|
||||
- **GIVEN** the user invokes PPT generation from a topic or mindmap
|
||||
- **WHEN** the system creates the PPT pages
|
||||
- **THEN** it SHALL create one Frame per page
|
||||
- **AND** it SHALL associate each Frame with the whole-slide generation prompt
|
||||
- **AND** it SHALL generate or enqueue one full-slide image for each page
|
||||
- **AND** it SHALL insert the resulting image into the corresponding Frame as the primary slide image
|
||||
|
||||
#### Scenario: Page image generation fails
|
||||
- **GIVEN** a PPT page image generation task fails
|
||||
- **WHEN** the PPT editing panel shows the page
|
||||
- **THEN** the page SHALL remain available with its original generation prompt
|
||||
- **AND** the user SHALL be able to regenerate that page without recreating the whole PPT
|
||||
|
||||
### Requirement: PPT Editing Panel
|
||||
The system SHALL present Frame-based PPT pages through a PPT editing panel that previews and manages pages in deck order.
|
||||
|
||||
#### Scenario: Preview PPT pages
|
||||
- **GIVEN** the current canvas contains PPT Frames
|
||||
- **WHEN** the user opens the PPT editing panel
|
||||
- **THEN** each PPT page SHALL show a page card with its index, name, dimensions, and preview image when available
|
||||
- **AND** clicking a page card SHALL focus/select the corresponding Frame on the canvas
|
||||
|
||||
#### Scenario: Hide obsolete PPT actions
|
||||
- **GIVEN** the current canvas contains PPT Frames
|
||||
- **WHEN** the PPT editing panel renders actions
|
||||
- **THEN** it SHALL NOT show PPT background image controls
|
||||
- **AND** it SHALL NOT show single-page PPT export actions
|
||||
- **AND** it SHALL keep full-deck PPT export available
|
||||
|
||||
### Requirement: PPT Page Regeneration
|
||||
The system SHALL replace single-page PPT export with page regeneration that uses the existing page image as a reference.
|
||||
|
||||
#### Scenario: Open regeneration dialog
|
||||
- **GIVEN** a PPT page has a stored generation prompt
|
||||
- **WHEN** the user clicks “重新生成” for that page
|
||||
- **THEN** the AI image generation dialog SHALL open with the stored prompt prefilled
|
||||
- **AND** the current primary slide image SHALL be attached as a reference image when available
|
||||
- **AND** the target Frame id and dimensions SHALL be passed for automatic回填
|
||||
|
||||
#### Scenario: Regeneration succeeds
|
||||
- **GIVEN** a PPT page regeneration task completes successfully
|
||||
- **WHEN** the generated image is inserted back into the target Frame
|
||||
- **THEN** the previous primary slide image SHALL be replaced by the new image
|
||||
- **AND** the page preview SHALL show the new image
|
||||
- **AND** the Frame SHALL remain in the same deck order
|
||||
|
||||
#### Scenario: Regeneration fails or is cancelled
|
||||
- **GIVEN** a PPT page regeneration task fails or is cancelled
|
||||
- **WHEN** the task finishes without a usable image
|
||||
- **THEN** the previous primary slide image SHALL remain unchanged
|
||||
- **AND** the page SHALL remain available for another regeneration attempt
|
||||
|
||||
36
openspec/specs/ppt-outline-generation/spec.md
Normal file
36
openspec/specs/ppt-outline-generation/spec.md
Normal file
@@ -0,0 +1,36 @@
|
||||
# ppt-outline-generation Specification
|
||||
|
||||
## Purpose
|
||||
TBD - created by archiving change update-ppt-outline-generation-flow. Update Purpose after archive.
|
||||
## Requirements
|
||||
### Requirement: PPT Outline Mode
|
||||
The system SHALL provide a PPT editor outline mode that shows a shared prompt field and editable per-slide prompt fields.
|
||||
|
||||
#### Scenario: User reviews generated prompts
|
||||
- **WHEN** a generated PPT contains placeholder slide frames
|
||||
- **THEN** the PPT editor can switch between slide thumbnail mode and outline mode
|
||||
- **AND** outline mode shows one shared prompt field above all slide prompt fields
|
||||
- **AND** every slide prompt row includes a checkbox for generation selection
|
||||
|
||||
### Requirement: Outline-First PPT Skill
|
||||
The system SHALL make the built-in complete PPT Skill generate prompts and placeholder slides before image generation.
|
||||
|
||||
#### Scenario: User runs the complete PPT Skill
|
||||
- **WHEN** the user runs `generate_ppt`
|
||||
- **THEN** the tool creates PPT frames containing shared style metadata and per-slide prompts
|
||||
- **AND** no slide image task is submitted automatically
|
||||
- **AND** the project drawer opens to PPT editor outline mode
|
||||
|
||||
### Requirement: Controlled PPT Slide Generation
|
||||
The system SHALL generate only selected PPT slides from outline mode using either serial or parallel execution.
|
||||
|
||||
#### Scenario: Serial selected-slide generation
|
||||
- **WHEN** the user selects serial generation
|
||||
- **THEN** slides generate one at a time in page order
|
||||
- **AND** each slide after the first uses the previous successfully generated slide image as a reference image
|
||||
|
||||
#### Scenario: Parallel selected-slide generation
|
||||
- **WHEN** the user selects parallel generation
|
||||
- **THEN** slides generate without reference images
|
||||
- **AND** at most five slide image tasks are in flight at once
|
||||
|
||||
31
openspec/specs/prompt-history/spec.md
Normal file
31
openspec/specs/prompt-history/spec.md
Normal file
@@ -0,0 +1,31 @@
|
||||
# prompt-history Specification
|
||||
|
||||
## Purpose
|
||||
TBD - created by archiving change add-prompt-history-tool. Update Purpose after archive.
|
||||
## Requirements
|
||||
### Requirement: Prompt Lineage History
|
||||
The system SHALL derive prompt history records from task queue data and connect initial prompt, sent prompt, tags, and generated result preview.
|
||||
|
||||
#### Scenario: New task has prompt metadata
|
||||
- **WHEN** a generation task is created from AI input
|
||||
- **THEN** the task stores lightweight prompt metadata with initial prompt, sent prompt, category, and optional Skill identifiers
|
||||
|
||||
#### Scenario: Old task has no prompt metadata
|
||||
- **WHEN** an older task is shown in prompt history
|
||||
- **THEN** the initial prompt falls back to `sourcePrompt`, then `rawInput`, then `prompt`
|
||||
- **AND** the sent prompt falls back to `prompt`
|
||||
|
||||
### Requirement: Prompt History Filtering
|
||||
The prompt history tool SHALL support filtering by image, video, audio, text, and Agent categories, with optional Skill tag filtering.
|
||||
|
||||
#### Scenario: User filters prompt records
|
||||
- **WHEN** the user selects a category, Skill tag, or search query
|
||||
- **THEN** the tool shows only matching prompt history records in reverse chronological order
|
||||
|
||||
### Requirement: Prompt Hover Details
|
||||
Prompt list items SHALL optionally show prompt titles in the list while keeping sent prompt as the selectable content.
|
||||
|
||||
#### Scenario: User hovers a prompt history item
|
||||
- **WHEN** the prompt history item has sent prompt, tags, or result preview data
|
||||
- **THEN** the hover tip shows the sent prompt, tags, and a lightweight result preview
|
||||
|
||||
37
openspec/specs/prompt-optimization/spec.md
Normal file
37
openspec/specs/prompt-optimization/spec.md
Normal file
@@ -0,0 +1,37 @@
|
||||
# prompt-optimization Specification
|
||||
|
||||
## Purpose
|
||||
TBD - created by archiving change refactor-prompt-optimization-public-capability. Update Purpose after archive.
|
||||
## Requirements
|
||||
### Requirement: Scenario-Based Prompt Optimization
|
||||
The system SHALL route prompt optimization through a shared scenario registry that defines the optimization type, default mode, history bucket, display name, and built-in template for each supported entrypoint.
|
||||
|
||||
#### Scenario: Existing entrypoints use distinct scenarios
|
||||
- **WHEN** a user opens prompt optimization from AI input, image/video tools, PPT outline prompts, or music creation
|
||||
- **THEN** the optimizer uses the scenario assigned to that entrypoint rather than only the broad generation type
|
||||
|
||||
### Requirement: Knowledge Base Template Overrides
|
||||
The system SHALL store prompt optimization templates as editable Knowledge Base notes in a "提示词优化" directory and prefer those note contents over built-in templates.
|
||||
|
||||
#### Scenario: User edits a template note
|
||||
- **WHEN** the template note for a scenario has non-empty user-edited content
|
||||
- **THEN** future optimizations for that scenario use the edited content
|
||||
|
||||
#### Scenario: Template note is missing or empty
|
||||
- **WHEN** the directory or scenario note is missing, or the note content is empty
|
||||
- **THEN** the system restores the built-in default template and continues optimization
|
||||
|
||||
### Requirement: Required Runtime Inputs
|
||||
The system SHALL append the original prompt and supplemental requirements to every optimization request outside of the editable template content.
|
||||
|
||||
#### Scenario: Template omits variables
|
||||
- **WHEN** a user-edited template does not include `{{originalPrompt}}` or `{{requirements}}`
|
||||
- **THEN** the optimization request still contains the original prompt and requirements in a system-controlled input block
|
||||
|
||||
### Requirement: Shared Prompt Optimization UI
|
||||
The system SHALL provide a shared prompt optimization button that opens the shared dialog, supports tooltip placement and styling overrides, and fills optimized prompts back to the caller.
|
||||
|
||||
#### Scenario: Caller applies optimized prompt
|
||||
- **WHEN** the user applies an optimized draft from the dialog
|
||||
- **THEN** the caller receives the optimized prompt through its existing fill-back handler
|
||||
|
||||
34
openspec/specs/provider-routing/spec.md
Normal file
34
openspec/specs/provider-routing/spec.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# provider-routing Specification
|
||||
|
||||
## Purpose
|
||||
TBD - created by archiving change add-gpt-image-edit-support. Update Purpose after archive.
|
||||
## Requirements
|
||||
### Requirement: Prefer Image Request Schema Per Invocation
|
||||
|
||||
The system SHALL allow an image invocation to prefer a request schema when multiple bindings exist for the same provider profile and model.
|
||||
|
||||
#### Scenario: Prefer GPT Image edit schema
|
||||
|
||||
- **GIVEN** a provider profile exposes both `openai.image.gpt-generation-json` and `openai.image.gpt-edit-form` for the same GPT Image model
|
||||
- **WHEN** the invocation asks for preferred request schema `openai.image.gpt-edit-form`
|
||||
- **THEN** the invocation plan SHALL select the edit binding
|
||||
|
||||
#### Scenario: Fall back when preferred schema is unavailable
|
||||
|
||||
- **GIVEN** a provider profile has only `openai.image.basic-json` for a GPT Image model
|
||||
- **WHEN** the invocation asks for preferred request schema `openai.image.gpt-edit-form`
|
||||
- **THEN** the invocation plan SHALL fall back to the available basic binding
|
||||
|
||||
### Requirement: Add Official GPT Image Edit Binding
|
||||
|
||||
The system SHALL infer an official GPT Image edit binding for provider profiles that resolve to official GPT Image compatibility.
|
||||
|
||||
#### Scenario: Official GPT Image profile exposes edit binding
|
||||
|
||||
- **GIVEN** a provider profile resolves image API compatibility to `openai-gpt-image`
|
||||
- **AND** the selected model is a GPT Image model
|
||||
- **WHEN** image bindings are inferred
|
||||
- **THEN** one binding SHALL use request schema `openai.image.gpt-edit-form`
|
||||
- **AND** submit path `/images/edits`
|
||||
- **AND** protocol `openai.images.edits`
|
||||
|
||||
33
openspec/specs/release-safe-static-loading/spec.md
Normal file
33
openspec/specs/release-safe-static-loading/spec.md
Normal file
@@ -0,0 +1,33 @@
|
||||
# release-safe-static-loading Specification
|
||||
|
||||
## Purpose
|
||||
TBD - created by archiving change update-release-safe-static-loading. Update Purpose after archive.
|
||||
## Requirements
|
||||
### Requirement: 运行时只使用可用的 CDN 源
|
||||
系统 SHALL 仅让可在浏览器与 Service Worker 中稳定访问的 CDN 源参与运行时静态资源加载。
|
||||
|
||||
#### Scenario: 不可用 CDN 不进入运行时候选集
|
||||
- **WHEN** Service Worker 选择当前版本静态资源的远程源
|
||||
- **THEN** 仅返回运行时可用的 CDN 源
|
||||
- **AND** 不会尝试已知会被浏览器或 Worker 拦截的 CDN 源
|
||||
|
||||
### Requirement: 服务器部署必须等待关键 CDN 资产就绪
|
||||
系统 SHALL 在部署服务器 HTML 前,确认当前版本关键静态资源已能从运行时 CDN 访问。
|
||||
|
||||
#### Scenario: CDN 未就绪时阻塞服务器部署
|
||||
- **WHEN** npm 发布已完成,但关键 JS/CSS 资产仍未能从运行时 CDN 成功获取
|
||||
- **THEN** 发布流程持续等待
|
||||
- **AND** 不继续部署服务器 HTML
|
||||
|
||||
#### Scenario: CDN 就绪后继续部署
|
||||
- **WHEN** 当前版本关键入口静态资源均已从运行时 CDN 返回成功
|
||||
- **THEN** 发布流程继续执行服务器部署
|
||||
|
||||
### Requirement: 启动边界依赖链必须稳定
|
||||
系统 SHALL 为高频延后模块产出稳定 chunk 分组,并阻止它们重新回流到入口依赖链。
|
||||
|
||||
#### Scenario: 构建校验入口依赖链
|
||||
- **WHEN** 运行启动边界校验脚本
|
||||
- **THEN** 脚本检查入口 HTML 及静态依赖图
|
||||
- **AND** 若发现高频延后模块分组重新进入入口依赖链则返回失败
|
||||
|
||||
29
openspec/specs/runtime-model-discovery/spec.md
Normal file
29
openspec/specs/runtime-model-discovery/spec.md
Normal file
@@ -0,0 +1,29 @@
|
||||
# runtime-model-discovery Specification
|
||||
|
||||
## Purpose
|
||||
TBD - created by archiving change update-model-recommendation-sorting. Update Purpose after archive.
|
||||
## Requirements
|
||||
### Requirement: Built-in Model Recommendation Metadata
|
||||
The system SHALL allow built-in model definitions to carry a static recommendation score used for display prioritization.
|
||||
|
||||
#### Scenario: Built-in model has curated recommendation score
|
||||
- **GIVEN** a built-in model definition is maintained in the static model catalog
|
||||
- **WHEN** the model config is exposed to selectors or settings views
|
||||
- **THEN** the model MAY include a recommendation score as part of its metadata
|
||||
- **AND** the score SHALL be treated as curated display metadata rather than runtime benchmark history
|
||||
|
||||
### Requirement: Unified Model Display Ordering
|
||||
The system SHALL apply one shared ordering strategy across model selectors, settings model lists, and runtime selectable model collections.
|
||||
|
||||
#### Scenario: Order models within the same family
|
||||
- **GIVEN** multiple models belong to the same normalized model family
|
||||
- **WHEN** the system sorts them for display
|
||||
- **THEN** it SHALL prioritize newer versions first
|
||||
- **AND** for equal version priority it SHALL sort by recommendation score in descending order
|
||||
|
||||
#### Scenario: Reuse the same ordering in runtime-discovered selector flows
|
||||
- **GIVEN** a model selector consumes runtime selectable models that combine static and discovered entries
|
||||
- **WHEN** the selector renders the model list
|
||||
- **THEN** it SHALL use the same shared ordering strategy as other model display surfaces
|
||||
- **AND** the ordering SHALL not depend on a selector-specific local sort implementation
|
||||
|
||||
31
openspec/specs/seo-homepage/spec.md
Normal file
31
openspec/specs/seo-homepage/spec.md
Normal file
@@ -0,0 +1,31 @@
|
||||
# seo-homepage Specification
|
||||
|
||||
## Purpose
|
||||
TBD - created by archiving change add-english-home-seo-page. Update Purpose after archive.
|
||||
## Requirements
|
||||
### Requirement: Localized SEO homepage
|
||||
The site SHALL provide an English SEO homepage with localized visible content, metadata, structured data, and a self-referencing canonical URL.
|
||||
|
||||
#### Scenario: English homepage is crawlable
|
||||
- **WHEN** a crawler requests `/en/home.html`
|
||||
- **THEN** the response contains an English HTML document
|
||||
- **AND** the document declares `lang="en"`
|
||||
- **AND** the document includes indexable metadata and structured data for OpenTu
|
||||
- **AND** the canonical URL points to `https://opentu.ai/en/home.html`
|
||||
|
||||
### Requirement: Localized homepage alternates
|
||||
The localized SEO homepages SHALL expose reciprocal alternate-language links.
|
||||
|
||||
#### Scenario: Chinese and English homepages declare alternates
|
||||
- **WHEN** a crawler reads either `/home.html` or `/en/home.html`
|
||||
- **THEN** the document declares alternates for `zh-CN`, `en`, and `x-default`
|
||||
- **AND** each localized document keeps its own self-referencing canonical URL
|
||||
|
||||
### Requirement: Localized homepage discovery
|
||||
The XML sitemap SHALL include the English homepage and its localized alternate relationship.
|
||||
|
||||
#### Scenario: Sitemap lists localized homepages
|
||||
- **WHEN** a crawler reads `/sitemap.xml`
|
||||
- **THEN** the sitemap includes `https://opentu.ai/en/home.html`
|
||||
- **AND** the Chinese and English homepage entries include reciprocal localized alternates
|
||||
|
||||
49
openspec/specs/smart-cdn-loading/spec.md
Normal file
49
openspec/specs/smart-cdn-loading/spec.md
Normal file
@@ -0,0 +1,49 @@
|
||||
# smart-cdn-loading Specification
|
||||
|
||||
## Purpose
|
||||
TBD - created by archiving change update-smart-cdn-loading. Update Purpose after archive.
|
||||
## Requirements
|
||||
### Requirement: 智能 CDN 优先静态资源加载
|
||||
系统 SHALL 对版本化静态资源采用 `Cache First -> 智能 CDN 优先 -> 源站快速兜底` 的加载顺序,同时对入口链路保持同源优先。
|
||||
|
||||
#### Scenario: 版本化静态资源优先走 CDN
|
||||
- **WHEN** Service Worker 处理未命中缓存的脚本、样式、字体、图片、图标或其他版本化静态 JSON 请求
|
||||
- **THEN** 系统优先尝试健康且匹配当前版本的 CDN
|
||||
- **AND** CDN 成功返回后将结果写入静态缓存
|
||||
|
||||
#### Scenario: 入口链路保持同源优先
|
||||
- **WHEN** 请求资源为 `index.html`、导航文档、`version.json`、`manifest.json`、`sw.js` 或 `precache-manifest.json`
|
||||
- **THEN** 系统优先从当前服务器获取资源
|
||||
- **AND** 不因 CDN 偏好而改写该优先级
|
||||
|
||||
#### Scenario: CDN 在发版窗口不可用时快速回源
|
||||
- **WHEN** CDN 对当前版本静态资源返回超时、404/5xx、错误 HTML 或明显异常内容
|
||||
- **THEN** 系统快速回退到当前服务器
|
||||
- **AND** 失败的 CDN 在短时间内被降级,避免同一页面重复优先命中该 CDN
|
||||
|
||||
### Requirement: CDN 偏好同步与持久化
|
||||
系统 SHALL 将主线程探测到的 CDN 偏好同步给 Service Worker,并允许后续刷新在主线程尚未启动前复用该偏好。
|
||||
|
||||
#### Scenario: 主线程同步 CDN 偏好
|
||||
- **WHEN** 主线程已得到 CDN 探测结果
|
||||
- **THEN** 主线程发送 `SW_CDN_SET_PREFERENCE`
|
||||
- **AND** 消息体包含 `cdn`、`latency`、`timestamp`、`version`
|
||||
|
||||
#### Scenario: Service Worker 复用持久化偏好
|
||||
- **WHEN** 用户刷新页面且主线程尚未重新完成 CDN 探测
|
||||
- **THEN** Service Worker 可读取上次持久化的偏好
|
||||
- **AND** 仅在偏好版本与当前应用版本一致时作为排序依据
|
||||
|
||||
### Requirement: 已校验 CDN 缓存可复用
|
||||
系统 SHALL 允许复用已校验的 CDN 静态缓存响应,而不是将所有非源站缓存一律视为异常。
|
||||
|
||||
#### Scenario: 合法 CDN 缓存直接命中
|
||||
- **WHEN** 静态缓存项包含有效的 `x-sw-source`、`x-sw-revision`、`x-sw-app-version`
|
||||
- **AND** `x-sw-app-version` 与当前应用版本一致
|
||||
- **THEN** Service Worker 直接返回该缓存项
|
||||
|
||||
#### Scenario: 异常缓存项被清理
|
||||
- **WHEN** 缓存项缺少必需元数据、版本不匹配,或静态资源缓存实际返回 HTML 错页
|
||||
- **THEN** Service Worker 删除该缓存项
|
||||
- **AND** 重新按智能加载策略获取资源
|
||||
|
||||
41
openspec/specs/toolbox-plugin-runtime/spec.md
Normal file
41
openspec/specs/toolbox-plugin-runtime/spec.md
Normal file
@@ -0,0 +1,41 @@
|
||||
# toolbox-plugin-runtime Specification
|
||||
|
||||
## Purpose
|
||||
Define the shared runtime contract for toolbox iframe tools and internal React tools.
|
||||
|
||||
## Requirements
|
||||
### Requirement: iframe 与内部工具必须共享统一运行时协议
|
||||
系统 SHALL 允许 `iframe` 工具和内部 React 工具通过同一工具定义模型被打开、最小化和嵌入画布,并允许支持多实例的工具打开多个独立窗口实例,以及通过工具定义声明默认窗口行为。
|
||||
|
||||
#### Scenario: 打开内部工具
|
||||
- **WHEN** 用户从工具箱打开内部工具
|
||||
- **THEN** 系统根据注册中心解析对应内部组件
|
||||
|
||||
#### Scenario: 打开 iframe 工具
|
||||
- **WHEN** 用户从工具箱打开 URL 工具
|
||||
- **THEN** 系统根据工具定义渲染 iframe
|
||||
|
||||
#### Scenario: 多实例工具新开窗口
|
||||
- **GIVEN** 某工具被标记为支持多实例
|
||||
- **WHEN** 用户从工具栏图标右键选择“新窗口打开”
|
||||
- **THEN** 系统为该工具创建新的窗口实例
|
||||
- **AND** 新旧实例各自维护独立的位置、尺寸和最小化状态
|
||||
- **AND** 工具栏分别显示对应实例图标
|
||||
|
||||
#### Scenario: 单实例工具保持兼容
|
||||
- **GIVEN** 某工具尚未标记为支持多实例
|
||||
- **WHEN** 用户通过已有入口再次打开该工具
|
||||
- **THEN** 系统继续复用或聚焦现有窗口行为
|
||||
- **AND** 不暴露可点击的“新窗口打开”入口
|
||||
|
||||
#### Scenario: 工具定义声明默认自动常驻
|
||||
- **GIVEN** 某工具定义声明 `defaultWindowBehavior.autoPinOnOpen = true`
|
||||
- **AND** 用户尚未手动取消该工具的常驻状态
|
||||
- **WHEN** 系统通过常规入口首次打开该工具
|
||||
- **THEN** 工具窗口服务 SHALL 将该工具加入常驻工具栏
|
||||
|
||||
#### Scenario: 调用方显式覆盖默认窗口行为
|
||||
- **GIVEN** 某工具定义声明 `defaultWindowBehavior.autoPinOnOpen = true`
|
||||
- **WHEN** 调用方以显式 `autoPin: false` 打开该工具
|
||||
- **THEN** 系统 SHALL 以调用方显式选项为准
|
||||
- **AND** 不因为工具默认行为再次自动常驻
|
||||
60
openspec/specs/toolbox/spec.md
Normal file
60
openspec/specs/toolbox/spec.md
Normal file
@@ -0,0 +1,60 @@
|
||||
# toolbox Specification
|
||||
|
||||
## Purpose
|
||||
TBD - created by archiving change add-prompt-history-tool. Update Purpose after archive.
|
||||
## Requirements
|
||||
### Requirement: Prompt History Toolbox Tool
|
||||
The system SHALL provide a built-in toolbox tool named "提示词历史" that opens as an internal React tool.
|
||||
|
||||
#### Scenario: User opens prompt history from toolbox
|
||||
- **WHEN** the user opens the toolbox
|
||||
- **THEN** the "提示词历史" tool is available as a content tool
|
||||
- **AND** opening it shows local prompt history records derived from generation tasks
|
||||
|
||||
### Requirement: Prompt History Tool Uses Lightweight Records
|
||||
The prompt history tool SHALL read only lightweight task summaries for list rendering and result previews.
|
||||
|
||||
#### Scenario: Large media tasks exist
|
||||
- **WHEN** prompt history records are loaded
|
||||
- **THEN** the list data excludes large uploaded media, analysis payloads, tool call arrays, and full generated media blobs
|
||||
- **AND** media previews reference existing URLs or thumbnails
|
||||
|
||||
### Requirement: 工具栏必须展示同工具的多个窗口实例
|
||||
系统 SHALL 在左侧工具栏中将同一工具的多个已打开或最小化实例显示为多个独立图标,并在图标上提供实例序号标识。
|
||||
|
||||
#### Scenario: 多个实例并列显示
|
||||
- **GIVEN** 用户已为同一个工具打开两个窗口实例
|
||||
- **WHEN** 左侧工具栏渲染工具实例
|
||||
- **THEN** 工具栏显示两个独立图标
|
||||
- **AND** 两个图标使用相同工具图标并带有不同的实例序号角标
|
||||
|
||||
#### Scenario: 常驻工具无实例时回退为启动图标
|
||||
- **GIVEN** 某工具被常驻到工具栏且当前没有打开实例
|
||||
- **WHEN** 左侧工具栏渲染该工具
|
||||
- **THEN** 工具栏仅显示一个关闭态启动图标
|
||||
- **AND** 用户点击该图标时系统新建一个窗口实例
|
||||
|
||||
### Requirement: 工具栏右键菜单必须支持新窗口打开
|
||||
系统 SHALL 在支持多实例的工具图标右键菜单中提供“新窗口打开”操作,用于从当前工具直接新建窗口实例。
|
||||
|
||||
#### Scenario: 从工具图标右键新开实例
|
||||
- **GIVEN** 某工具支持多实例并已在工具栏显示
|
||||
- **WHEN** 用户右键该工具图标并选择“新窗口打开”
|
||||
- **THEN** 系统新建一个该工具的窗口实例
|
||||
- **AND** 新实例默认以级联偏移方式打开,避免与已有实例完全重叠
|
||||
|
||||
### Requirement: 特定工具可声明默认常驻工具栏
|
||||
系统 SHALL 允许工具通过定义元数据声明“打开后默认常驻工具栏”行为,并在所有常规打开入口中保持一致。
|
||||
|
||||
#### Scenario: 爆款工具打开后自动常驻
|
||||
- **GIVEN** 用户打开“爆款视频生成”或“爆款音乐生成”
|
||||
- **WHEN** 工具窗口成功创建
|
||||
- **THEN** 左侧最小化工具栏 SHALL 显示该工具的常驻图标
|
||||
- **AND** 用户关闭窗口后仍可通过 launcher 图标再次打开
|
||||
|
||||
#### Scenario: 用户手动取消常驻后保持用户选择
|
||||
- **GIVEN** 某工具具备默认自动常驻规则
|
||||
- **AND** 用户已在工具栏中手动取消该工具常驻
|
||||
- **WHEN** 用户后续再次打开该工具
|
||||
- **THEN** 系统 SHALL 优先保留用户当前常驻选择
|
||||
|
||||
67
openspec/specs/video-analyzer/spec.md
Normal file
67
openspec/specs/video-analyzer/spec.md
Normal file
@@ -0,0 +1,67 @@
|
||||
# video-analyzer Specification
|
||||
|
||||
## Purpose
|
||||
TBD - created by archiving change update-video-analyzer-task-queue. Update Purpose after archive.
|
||||
## Requirements
|
||||
### Requirement: 视频分析必须进入统一任务队列
|
||||
|
||||
爆款视频生成工具在用户提交视频分析时,系统 SHALL 创建一个可追踪的队列任务,而不是仅在组件内直接等待异步结果。
|
||||
|
||||
#### Scenario: YouTube 视频分析入队
|
||||
|
||||
- **WHEN** 用户在爆款视频生成工具第 1 步输入 YouTube URL 并开始分析
|
||||
- **THEN** 系统创建一个视频分析任务并出现在任务队列中
|
||||
- **AND** 任务完成后将结构化分析结果写回对应的分析记录
|
||||
|
||||
#### Scenario: 本地上传视频分析入队
|
||||
|
||||
- **WHEN** 用户在爆款视频生成工具第 1 步上传本地视频并开始分析
|
||||
- **THEN** 系统创建一个视频分析任务并出现在任务队列中
|
||||
- **AND** 任务完成后将结构化分析结果写回对应的分析记录
|
||||
|
||||
### Requirement: 脚本改编必须进入统一任务队列
|
||||
|
||||
爆款视频生成工具在用户执行 AI 脚本改编时,系统 SHALL 创建一个可追踪的队列任务,并在完成后回写镜头脚本。
|
||||
|
||||
#### Scenario: 脚本改编任务完成后回写
|
||||
|
||||
- **WHEN** 用户在第 2 步提交 AI 改编脚本
|
||||
- **THEN** 系统创建一个脚本改编任务并出现在任务队列中
|
||||
- **AND** 任务完成后将改编后的镜头数据写回当前分析记录
|
||||
|
||||
### Requirement: 历史分析记录必须保存可恢复输入源
|
||||
|
||||
爆款视频生成工具保存分析历史时,系统 SHALL 同时保存足以恢复再次分析的输入源快照。
|
||||
|
||||
#### Scenario: 保存 YouTube 输入源
|
||||
|
||||
- **WHEN** 用户使用 YouTube URL 完成一次分析
|
||||
- **THEN** 历史记录保存原始 `youtubeUrl`
|
||||
|
||||
#### Scenario: 保存本地上传输入源
|
||||
|
||||
- **WHEN** 用户使用本地视频完成一次分析
|
||||
- **THEN** 系统将本地视频缓存到本地存储
|
||||
- **AND** 历史记录保存恢复该视频所需的缓存引用与文件元数据
|
||||
|
||||
### Requirement: 从历史记录重新进入分析页时必须回填输入源
|
||||
|
||||
用户从爆款视频生成工具的历史记录重新进入分析页时,系统 SHALL 尝试恢复原始输入源,而不是只展示历史结果。
|
||||
|
||||
#### Scenario: 回填 YouTube URL
|
||||
|
||||
- **WHEN** 用户打开一条来自 YouTube 的历史分析记录
|
||||
- **THEN** 分析页自动回填对应的 YouTube URL
|
||||
|
||||
#### Scenario: 恢复本地上传视频
|
||||
|
||||
- **WHEN** 用户打开一条来自本地上传的历史分析记录且本地缓存仍可用
|
||||
- **THEN** 分析页自动恢复视频预览
|
||||
- **AND** 用户可以直接重新提交分析
|
||||
|
||||
#### Scenario: 本地视频缓存不可恢复时安全降级
|
||||
|
||||
- **WHEN** 用户打开一条来自本地上传的历史分析记录但原视频缓存已丢失
|
||||
- **THEN** 系统保留原有分析结果展示
|
||||
- **AND** 明确提示该历史记录无法恢复原视频输入
|
||||
|
||||
71
openspec/specs/video-batch-generation/spec.md
Normal file
71
openspec/specs/video-batch-generation/spec.md
Normal file
@@ -0,0 +1,71 @@
|
||||
# video-batch-generation Specification
|
||||
|
||||
## Purpose
|
||||
TBD - created by archiving change update-batch-video-chaining. Update Purpose after archive.
|
||||
## Requirements
|
||||
### Requirement: 批量视频生成必须按镜头顺序串行执行
|
||||
|
||||
爆款 MV 与爆款视频生成工具在用户执行“全部→生成视频”时,系统 SHALL 按镜头顺序逐段生成视频,而不是一次性并发提交全部片段。
|
||||
|
||||
#### Scenario: 串行生成下一段
|
||||
|
||||
- **WHEN** 用户在生成页点击“全部→生成视频”
|
||||
- **THEN** 系统只创建当前镜头的视频任务
|
||||
- **AND** 当前镜头成功后才开始下一镜头的视频生成
|
||||
|
||||
### Requirement: 片段之间必须自动传递尾帧到下一段首帧
|
||||
|
||||
系统 SHALL 在串行批量生成时自动提取上一段视频尾帧,并将其作为下一段的首帧输入。
|
||||
|
||||
#### Scenario: 首段使用参考图启动
|
||||
|
||||
- **WHEN** 用户已上传参考图并开始批量生成
|
||||
- **THEN** 第 1 段使用参考图作为首帧输入
|
||||
|
||||
#### Scenario: 后续段使用上一段尾帧
|
||||
|
||||
- **WHEN** 第 N 段视频生成成功且存在第 N+1 段
|
||||
- **THEN** 系统提取第 N 段视频尾帧
|
||||
- **AND** 将该尾帧写入第 N+1 段的首帧输入
|
||||
|
||||
#### Scenario: 已生成片段跳过并继续传帧
|
||||
|
||||
- **WHEN** 某一镜头已经存在已生成视频
|
||||
- **THEN** 系统跳过该镜头的新任务创建
|
||||
- **AND** 直接从已有视频提取尾帧并继续驱动下一镜头
|
||||
|
||||
### Requirement: 批量串行生成失败后必须自动重试
|
||||
|
||||
系统 SHALL 在批量串行生成的当前镜头失败后立即自动重试,直到成功或用户主动停止本轮批量生成。
|
||||
|
||||
#### Scenario: 当前镜头失败后立即重试
|
||||
|
||||
- **WHEN** 批量生成中的某个镜头任务失败
|
||||
- **THEN** 系统立即重新提交或重试该镜头任务
|
||||
- **AND** 不推进到下一镜头
|
||||
|
||||
#### Scenario: 用户主动停止批量生成
|
||||
|
||||
- **WHEN** 用户在批量串行生成过程中执行停止
|
||||
- **THEN** 系统停止当前批量编排
|
||||
- **AND** 不再创建后续镜头任务
|
||||
|
||||
### Requirement: 生成页必须提供统一的视频尺寸参数
|
||||
|
||||
爆款 MV 与爆款视频生成工具的生成页 SHALL 在视频模型下方提供尺寸选择,并统一作用于单镜头生成与批量生成。
|
||||
|
||||
#### Scenario: 单镜头与批量入口共享尺寸
|
||||
|
||||
- **WHEN** 用户在生成页选择某个视频尺寸
|
||||
- **THEN** 单镜头“生成视频”与“全部→生成视频”都使用该尺寸参数
|
||||
|
||||
#### Scenario: 模型切换时回退到有效尺寸
|
||||
|
||||
- **WHEN** 用户切换视频模型且当前已选尺寸不被新模型支持
|
||||
- **THEN** 系统自动回退到新模型的默认尺寸
|
||||
|
||||
#### Scenario: 旧记录缺少尺寸字段
|
||||
|
||||
- **WHEN** 用户打开一条旧历史记录且其中未保存视频尺寸
|
||||
- **THEN** 系统使用当前视频模型的默认尺寸作为兼容回退
|
||||
|
||||
39
openspec/specs/video-mv-workflow-parity/spec.md
Normal file
39
openspec/specs/video-mv-workflow-parity/spec.md
Normal file
@@ -0,0 +1,39 @@
|
||||
# video-mv-workflow-parity Specification
|
||||
|
||||
## Purpose
|
||||
TBD - created by archiving change update-video-mv-workflow-parity. Update Purpose after archive.
|
||||
## Requirements
|
||||
### Requirement: Script Page Character Editing Parity
|
||||
The system SHALL let users edit detected character descriptions in the video analyzer script page, using the same interaction pattern as the MV creator.
|
||||
|
||||
#### Scenario: Edit character descriptions in video analyzer
|
||||
- **GIVEN** a video analyzer record contains detected characters
|
||||
- **WHEN** the user edits a character description on the script page
|
||||
- **THEN** the updated description is persisted on the record
|
||||
- **AND** subsequent generation uses the updated character description
|
||||
|
||||
### Requirement: Shared Generation Reset
|
||||
The system SHALL provide a consistent "reset generated assets" action for both video analyzer and MV creator generation pages.
|
||||
|
||||
#### Scenario: Reset generation assets
|
||||
- **GIVEN** a record has generated first frames, last frames, videos, or character reference images
|
||||
- **WHEN** the user clicks the reset action
|
||||
- **THEN** generated asset URLs and suppressed generated URLs are cleared
|
||||
- **AND** character reference images are cleared
|
||||
- **AND** script content, selected models, and workflow versions remain unchanged
|
||||
|
||||
### Requirement: Shared ZIP Export Contract
|
||||
The system SHALL export generated workflow assets from both video analyzer and MV creator using the same ZIP manifest contract.
|
||||
|
||||
#### Scenario: Export video analyzer assets
|
||||
- **GIVEN** a video analyzer record has generated assets
|
||||
- **WHEN** the user exports the workflow assets
|
||||
- **THEN** the ZIP contains the script markdown, manifest file, download helper script, and generated shot assets
|
||||
- **AND** the manifest keeps the shared structure used by MV creator
|
||||
- **AND** music-related fields are empty when no music asset exists
|
||||
|
||||
#### Scenario: Export MV creator assets
|
||||
- **GIVEN** an MV creator record has generated assets and optionally a selected music clip
|
||||
- **WHEN** the user exports the workflow assets
|
||||
- **THEN** the ZIP contains the shared manifest structure plus the selected music asset when available
|
||||
|
||||
Reference in New Issue
Block a user