speccrew 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.speccrew/agents/speccrew-feature-designer.md +142 -0
- package/.speccrew/agents/speccrew-product-manager.md +61 -0
- package/.speccrew/agents/speccrew-system-designer.md +200 -0
- package/.speccrew/agents/speccrew-system-developer.md +238 -0
- package/.speccrew/agents/speccrew-task-worker.md +80 -0
- package/.speccrew/agents/speccrew-team-leader.md +92 -0
- package/.speccrew/agents/speccrew-test-manager.md +313 -0
- package/.speccrew/skills/speccrew-create-agents/SKILL.md +98 -0
- package/.speccrew/skills/speccrew-create-agents/templates/agents/designer-agent.md +54 -0
- package/.speccrew/skills/speccrew-create-agents/templates/agents/dev-agent.md +79 -0
- package/.speccrew/skills/speccrew-create-agents/templates/agents/test-agent.md +80 -0
- package/.speccrew/skills/speccrew-dev-backend/SKILL.md +205 -0
- package/.speccrew/skills/speccrew-dev-backend/templates/TASK-RECORD-TEMPLATE.md +118 -0
- package/.speccrew/skills/speccrew-dev-desktop/SKILL.md +258 -0
- package/.speccrew/skills/speccrew-dev-desktop/templates/TASK-RECORD-TEMPLATE.md +161 -0
- package/.speccrew/skills/speccrew-dev-frontend/SKILL.md +202 -0
- package/.speccrew/skills/speccrew-dev-frontend/templates/TASK-RECORD-TEMPLATE.md +115 -0
- package/.speccrew/skills/speccrew-dev-mobile/SKILL.md +200 -0
- package/.speccrew/skills/speccrew-dev-mobile/templates/TASK-RECORD-TEMPLATE.md +125 -0
- package/.speccrew/skills/speccrew-fd-api-contract/SKILL.md +73 -0
- package/.speccrew/skills/speccrew-fd-api-contract/templates/API-CONTRACT-TEMPLATE.md +96 -0
- package/.speccrew/skills/speccrew-fd-feature-design/SKILL.md +395 -0
- package/.speccrew/skills/speccrew-fd-feature-design/templates/FEATURE-SPEC-TEMPLATE.md +387 -0
- package/.speccrew/skills/speccrew-get-timestamp/SKILL.md +80 -0
- package/.speccrew/skills/speccrew-get-timestamp/scripts/get-timestamp.js +35 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-api-analyze/SKILL.md +1116 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-api-analyze/templates/FEATURE-DETAIL-TEMPLATE-FASTAPI.md +462 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-api-analyze/templates/FEATURE-DETAIL-TEMPLATE-JAVA.md +480 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-api-analyze/templates/FEATURE-DETAIL-TEMPLATE-NET.md +464 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-api-analyze/templates/FEATURE-DETAIL-TEMPLATE.md +480 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-api-analyze/templates/MODULE-OVERVIEW-TEMPLATE.md +367 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-dispatch/SKILL.md +667 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-dispatch/STATUS-FORMATS.md +74 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-dispatch/scripts/batch-orchestrator.js +176 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-dispatch/scripts/get-next-batch.js +150 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-dispatch/scripts/get-pending-features.js +106 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-dispatch/scripts/mark-stale.js +249 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-dispatch/scripts/process-batch-results.js +848 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-dispatch/scripts/update-feature-status.js +226 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-init-features/SKILL.md +264 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-init-features/examples/features.json +34 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-init-features/scripts/generate-inventory.js +867 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-init-features/scripts/test-inventory.js +26 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-module-classify/SKILL.md +165 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-module-classify/scripts/apply-module-mapping.js +208 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-module-classify/scripts/extract-module-summary.js +180 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-module-classify/scripts/reindex-modules.js +358 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-ui-analyze/SKILL.md +1055 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-ui-analyze/templates/FEATURE-DETAIL-TEMPLATE-UI-DESKTOP.md +303 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-ui-analyze/templates/FEATURE-DETAIL-TEMPLATE-UI-ELECTRON.md +327 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-ui-analyze/templates/FEATURE-DETAIL-TEMPLATE-UI-MINIAPP.md +292 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-ui-analyze/templates/FEATURE-DETAIL-TEMPLATE-UI-MOBILE.md +281 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-ui-analyze/templates/FEATURE-DETAIL-TEMPLATE-UI.md +324 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-ui-style-extract/SKILL.md +270 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-ui-style-extract/templates/COMPONENT-PATTERN-TEMPLATE.md +33 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-ui-style-extract/templates/LAYOUT-PATTERN-TEMPLATE.md +33 -0
- package/.speccrew/skills/speccrew-knowledge-bizs-ui-style-extract/templates/PAGE-TYPE-TEMPLATE.md +33 -0
- package/.speccrew/skills/speccrew-knowledge-graph-query/SKILL.md +229 -0
- package/.speccrew/skills/speccrew-knowledge-graph-query/scripts/graph-query.js +549 -0
- package/.speccrew/skills/speccrew-knowledge-graph-write/SKILL.md +181 -0
- package/.speccrew/skills/speccrew-knowledge-graph-write/scripts/graph-write.js +651 -0
- package/.speccrew/skills/speccrew-knowledge-module-summarize/SKILL.md +305 -0
- package/.speccrew/skills/speccrew-knowledge-module-summarize/templates/MODULE-OVERVIEW-TEMPLATE.md +400 -0
- package/.speccrew/skills/speccrew-knowledge-system-summarize/SKILL.md +351 -0
- package/.speccrew/skills/speccrew-knowledge-system-summarize/templates/SYSTEM-OVERVIEW-TEMPLATE.md +294 -0
- package/.speccrew/skills/speccrew-knowledge-techs-dispatch/SKILL.md +683 -0
- package/.speccrew/skills/speccrew-knowledge-techs-dispatch/STATUS-FORMATS.md +550 -0
- package/.speccrew/skills/speccrew-knowledge-techs-dispatch/templates/techs-manifest-EXAMPLE.json +35 -0
- package/.speccrew/skills/speccrew-knowledge-techs-generate/SKILL.md +1087 -0
- package/.speccrew/skills/speccrew-knowledge-techs-generate/templates/ARCHITECTURE-TEMPLATE.md +240 -0
- package/.speccrew/skills/speccrew-knowledge-techs-generate/templates/COLOR-SYSTEM-TEMPLATE.md +68 -0
- package/.speccrew/skills/speccrew-knowledge-techs-generate/templates/COMPONENT-LIBRARY-TEMPLATE.md +86 -0
- package/.speccrew/skills/speccrew-knowledge-techs-generate/templates/CONVENTIONS-BUILD-TEMPLATE.md +466 -0
- package/.speccrew/skills/speccrew-knowledge-techs-generate/templates/CONVENTIONS-DATA-TEMPLATE.md +432 -0
- package/.speccrew/skills/speccrew-knowledge-techs-generate/templates/CONVENTIONS-DESIGN-TEMPLATE.md +1209 -0
- package/.speccrew/skills/speccrew-knowledge-techs-generate/templates/CONVENTIONS-DEV-TEMPLATE.md +1433 -0
- package/.speccrew/skills/speccrew-knowledge-techs-generate/templates/CONVENTIONS-SYSTEM-TEST-TEMPLATE.md +1052 -0
- package/.speccrew/skills/speccrew-knowledge-techs-generate/templates/CONVENTIONS-UNIT-TEST-TEMPLATE.md +946 -0
- package/.speccrew/skills/speccrew-knowledge-techs-generate/templates/INDEX-TEMPLATE.md +29 -0
- package/.speccrew/skills/speccrew-knowledge-techs-generate/templates/PAGE-LAYOUTS-TEMPLATE.md +69 -0
- package/.speccrew/skills/speccrew-knowledge-techs-generate/templates/PAGE-TYPE-SUMMARY-TEMPLATE.md +74 -0
- package/.speccrew/skills/speccrew-knowledge-techs-generate/templates/TECH-STACK-TEMPLATE.md +232 -0
- package/.speccrew/skills/speccrew-knowledge-techs-generate-conventions/SKILL.md +628 -0
- package/.speccrew/skills/speccrew-knowledge-techs-generate-ui-style/SKILL.md +392 -0
- package/.speccrew/skills/speccrew-knowledge-techs-index/SKILL.md +489 -0
- package/.speccrew/skills/speccrew-knowledge-techs-index/templates/INDEX-TEMPLATE.md +243 -0
- package/.speccrew/skills/speccrew-knowledge-techs-init/SKILL.md +269 -0
- package/.speccrew/skills/speccrew-knowledge-techs-ui-analyze/SKILL.md +562 -0
- package/.speccrew/skills/speccrew-knowledge-techs-ui-analyze/templates/BUSINESS-COMPONENTS-TEMPLATE.md +171 -0
- package/.speccrew/skills/speccrew-knowledge-techs-ui-analyze/templates/COMMON-COMPONENTS-TEMPLATE.md +177 -0
- package/.speccrew/skills/speccrew-knowledge-techs-ui-analyze/templates/COMPONENT-INDIVIDUAL-TEMPLATE.md +80 -0
- package/.speccrew/skills/speccrew-knowledge-techs-ui-analyze/templates/COMPONENT-LIBRARY-TEMPLATE.md +118 -0
- package/.speccrew/skills/speccrew-knowledge-techs-ui-analyze/templates/LAYOUT-INDIVIDUAL-TEMPLATE.md +97 -0
- package/.speccrew/skills/speccrew-knowledge-techs-ui-analyze/templates/LAYOUT-PATTERNS-TEMPLATE.md +208 -0
- package/.speccrew/skills/speccrew-knowledge-techs-ui-analyze/templates/NAVIGATION-PATTERNS-TEMPLATE.md +157 -0
- package/.speccrew/skills/speccrew-knowledge-techs-ui-analyze/templates/PAGE-TYPE-INDIVIDUAL-TEMPLATE.md +123 -0
- package/.speccrew/skills/speccrew-knowledge-techs-ui-analyze/templates/PAGE-TYPE-SUMMARY-TEMPLATE.md +58 -0
- package/.speccrew/skills/speccrew-knowledge-techs-ui-analyze/templates/SPACING-TEMPLATE.md +119 -0
- package/.speccrew/skills/speccrew-knowledge-techs-ui-analyze/templates/STYLE-SYSTEM-TEMPLATE.md +117 -0
- package/.speccrew/skills/speccrew-knowledge-techs-ui-analyze/templates/TYPOGRAPHY-TEMPLATE.md +107 -0
- package/.speccrew/skills/speccrew-knowledge-techs-ui-analyze/templates/UI-STYLE-GUIDE-TEMPLATE.md +171 -0
- package/.speccrew/skills/speccrew-pm-requirement-analysis/SKILL.md +434 -0
- package/.speccrew/skills/speccrew-pm-requirement-analysis/templates/BIZS-MODELING-TEMPLATE.md +332 -0
- package/.speccrew/skills/speccrew-pm-requirement-analysis/templates/PRD-TEMPLATE.md +200 -0
- package/.speccrew/skills/speccrew-pm-requirement-assess/SKILL.md +195 -0
- package/.speccrew/skills/speccrew-project-diagnosis/SKILL.md +208 -0
- package/.speccrew/skills/speccrew-project-diagnosis/templates/DIAGNOSIS-REPORT-TEMPLATE.md +202 -0
- package/.speccrew/skills/speccrew-sd-backend/SKILL.md +188 -0
- package/.speccrew/skills/speccrew-sd-backend/templates/INDEX-TEMPLATE.md +85 -0
- package/.speccrew/skills/speccrew-sd-backend/templates/SD-BACKEND-TEMPLATE.md +269 -0
- package/.speccrew/skills/speccrew-sd-desktop/SKILL.md +192 -0
- package/.speccrew/skills/speccrew-sd-desktop/templates/INDEX-TEMPLATE.md +271 -0
- package/.speccrew/skills/speccrew-sd-desktop/templates/SD-DESKTOP-TEMPLATE.md +673 -0
- package/.speccrew/skills/speccrew-sd-frontend/SKILL.md +176 -0
- package/.speccrew/skills/speccrew-sd-frontend/templates/INDEX-TEMPLATE.md +184 -0
- package/.speccrew/skills/speccrew-sd-frontend/templates/SD-FRONTEND-TEMPLATE.md +382 -0
- package/.speccrew/skills/speccrew-sd-mobile/SKILL.md +189 -0
- package/.speccrew/skills/speccrew-sd-mobile/templates/INDEX-TEMPLATE.md +219 -0
- package/.speccrew/skills/speccrew-sd-mobile/templates/SD-MOBILE-TEMPLATE.md +534 -0
- package/.speccrew/skills/speccrew-test-case-design/SKILL.md +284 -0
- package/.speccrew/skills/speccrew-test-case-design/templates/TEST-CASE-DESIGN-TEMPLATE.md +263 -0
- package/.speccrew/skills/speccrew-test-code-gen/SKILL.md +313 -0
- package/.speccrew/skills/speccrew-test-code-gen/templates/TEST-CODE-PLAN-TEMPLATE.md +180 -0
- package/.speccrew/skills/speccrew-test-execute/SKILL.md +283 -0
- package/.speccrew/skills/speccrew-test-execute/templates/BUG-REPORT-TEMPLATE.md +50 -0
- package/.speccrew/skills/speccrew-test-execute/templates/TEST-REPORT-TEMPLATE.md +57 -0
- package/.speccrew/skills/speccrew-workflow-diagnose/SKILL.md +155 -0
- package/LICENSE +21 -0
- package/README.ar.md +318 -0
- package/README.en.md +318 -0
- package/README.es.md +318 -0
- package/README.md +340 -0
- package/bin/cli.js +62 -0
- package/lib/commands/doctor.js +138 -0
- package/lib/commands/init.js +231 -0
- package/lib/commands/list.js +114 -0
- package/lib/commands/uninstall.js +117 -0
- package/lib/commands/update.js +351 -0
- package/lib/ide-adapters.js +73 -0
- package/lib/utils.js +104 -0
- package/package.json +28 -0
- package/workspace-template/docs/configs/document-templates.json +667 -0
- package/workspace-template/docs/configs/platform-mapping.json +194 -0
- package/workspace-template/docs/configs/tech-stack-mappings.json +313 -0
- package/workspace-template/docs/configs/validation-rules.json +87 -0
- package/workspace-template/docs/rules/mermaid-rule.md +114 -0
- package/workspace-template/docs/solutions/Agent/346/212/200/350/203/275/345/256/232/344/271/211+/351/234/200/346/261/202/346/226/207/346/241/243+UML/344/275/277/347/224/250/346/250/241/346/235/277/357/274/210ISA-95/345/205/255/346/256/265/345/274/217/350/236/215/345/220/210/347/211/210/357/274/211.md +586 -0
- package/workspace-template/docs/solutions/agent-knowledge-map.md +238 -0
- package/workspace-template/docs/solutions/bizs-knowledge-pipeline.md +678 -0
- package/workspace-template/docs/solutions/harness.md +410 -0
- package/workspace-template/docs/solutions/knowledge-incremental-sync-spec.md +943 -0
- package/workspace-template/docs/solutions/techs-knowledge-pipeline.md +803 -0
- package/workspace-template/docs/solutions/workspace-structure.md +318 -0
|
@@ -0,0 +1,673 @@
|
|
|
1
|
+
# Desktop System Design - {ModuleName}
|
|
2
|
+
|
|
3
|
+
> Feature Spec Reference: {FeatureSpecPath}
|
|
4
|
+
> API Contract Reference: {ApiContractPath}
|
|
5
|
+
> Platform: {PlatformId} | Framework: {Framework} | Language: {Language}
|
|
6
|
+
|
|
7
|
+
## 1. Design Goal
|
|
8
|
+
|
|
9
|
+
{Brief description of what this module implements, referencing Feature Spec function}
|
|
10
|
+
|
|
11
|
+
## 2. Process Architecture
|
|
12
|
+
|
|
13
|
+
### 2.1 Process Model
|
|
14
|
+
|
|
15
|
+
<!-- AI-NOTE: Describe Main Process vs Renderer Process for Electron; or Rust Core vs WebView for Tauri -->
|
|
16
|
+
|
|
17
|
+
{Description of process model and responsibilities}
|
|
18
|
+
|
|
19
|
+
### 2.2 Process Responsibility Table
|
|
20
|
+
|
|
21
|
+
| Process | Type | Responsibility | Has UI |
|
|
22
|
+
|---------|------|----------------|--------|
|
|
23
|
+
| Main Process | Node.js/Rust | {responsibilities: window management, native APIs, background tasks} | No |
|
|
24
|
+
| Renderer Process | Chromium/WebView | {responsibilities: UI rendering, user interaction} | Yes |
|
|
25
|
+
|
|
26
|
+
### 2.3 Architecture Diagram
|
|
27
|
+
|
|
28
|
+
<!-- AI-NOTE: Use Mermaid graph TD with basic syntax only. No style definitions, no HTML tags, no nested subgraph, no direction keyword. -->
|
|
29
|
+
|
|
30
|
+
```mermaid
|
|
31
|
+
graph TD
|
|
32
|
+
A[Main Process] --> B[Window Manager]
|
|
33
|
+
A --> C[IPC Handlers]
|
|
34
|
+
A --> D[Native Modules]
|
|
35
|
+
B --> E[Renderer Process]
|
|
36
|
+
C --> E
|
|
37
|
+
E --> F[UI Components]
|
|
38
|
+
E --> G[Renderer State]
|
|
39
|
+
D --> H[File System]
|
|
40
|
+
D --> I[System APIs]
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## 3. Window Design
|
|
44
|
+
|
|
45
|
+
### 3.1 Window Configuration
|
|
46
|
+
|
|
47
|
+
| Window | Type | Size | Resizable | Frame | Purpose |
|
|
48
|
+
|--------|------|------|-----------|-------|---------|
|
|
49
|
+
| {MainWindow} | BrowserWindow/Window | 1200x800 | Yes | Yes | Main application window |
|
|
50
|
+
| {ModalWindow} | BrowserWindow/Window | 600x400 | No | No | Dialog/modal content |
|
|
51
|
+
|
|
52
|
+
### 3.2 Window Lifecycle
|
|
53
|
+
|
|
54
|
+
<!-- AI-NOTE: Describe create, show, hide, close, restore behaviors -->
|
|
55
|
+
|
|
56
|
+
| Stage | Action | Description |
|
|
57
|
+
|-------|--------|-------------|
|
|
58
|
+
| Create | {create logic} | {when and how window is created} |
|
|
59
|
+
| Show | {show logic} | {when window becomes visible} |
|
|
60
|
+
| Hide | {hide logic} | {when window is hidden but not closed} |
|
|
61
|
+
| Close | {close logic} | {cleanup and event handling} |
|
|
62
|
+
| Restore | {restore logic} | {window state restoration} |
|
|
63
|
+
|
|
64
|
+
### 3.3 Multi-Window Communication
|
|
65
|
+
|
|
66
|
+
<!-- AI-NOTE: Describe how multiple windows communicate if applicable -->
|
|
67
|
+
|
|
68
|
+
{Description of inter-window communication strategy}
|
|
69
|
+
|
|
70
|
+
## 4. IPC Communication Design
|
|
71
|
+
|
|
72
|
+
### 4.1 IPC Channel Registry
|
|
73
|
+
|
|
74
|
+
| Channel | Direction | Payload Type | Handler | Description |
|
|
75
|
+
|---------|-----------|--------------|---------|-------------|
|
|
76
|
+
| {channel-name} | Renderer→Main | {type} | {handler} | {description} |
|
|
77
|
+
| {channel-name} | Main→Renderer | {type} | {handler} | {description} |
|
|
78
|
+
| {channel-name} | Bidirectional | {type} | {handler} | {description} |
|
|
79
|
+
|
|
80
|
+
### 4.2 IPC Flow Diagrams
|
|
81
|
+
|
|
82
|
+
<!-- AI-NOTE: Use Mermaid sequenceDiagram for IPC flows -->
|
|
83
|
+
|
|
84
|
+
```mermaid
|
|
85
|
+
sequenceDiagram
|
|
86
|
+
participant R as Renderer
|
|
87
|
+
participant M as Main
|
|
88
|
+
participant N as Native API
|
|
89
|
+
|
|
90
|
+
R->>M: invoke('channel-name', payload)
|
|
91
|
+
M->>N: call native API
|
|
92
|
+
N-->>M: return result
|
|
93
|
+
M-->>R: return response
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### 4.3 IPC Pseudo-code
|
|
97
|
+
|
|
98
|
+
<!-- AI-NOTE: Use actual IPC syntax from techs knowledge -->
|
|
99
|
+
|
|
100
|
+
**Main Process Handler:**
|
|
101
|
+
|
|
102
|
+
```{framework-language}
|
|
103
|
+
// AI-NOTE: Electron example - use actual syntax from techs knowledge
|
|
104
|
+
// File: src/main/ipc/{module}.ts
|
|
105
|
+
|
|
106
|
+
import { ipcMain, BrowserWindow } from 'electron'
|
|
107
|
+
import { {Service} } from '../services/{service}'
|
|
108
|
+
|
|
109
|
+
// AI-NOTE: Use actual handler pattern from conventions
|
|
110
|
+
ipcMain.handle('{channel-name}', async (event, payload: {PayloadType}) => {
|
|
111
|
+
try {
|
|
112
|
+
const result = await {Service}.{method}(payload)
|
|
113
|
+
return { success: true, data: result }
|
|
114
|
+
} catch (error) {
|
|
115
|
+
return { success: false, error: error.message }
|
|
116
|
+
}
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
// AI-NOTE: For Tauri, use:
|
|
120
|
+
// #[tauri::command]
|
|
121
|
+
// async fn handler_name(payload: PayloadType) -> Result<ResponseType, Error> {
|
|
122
|
+
// // handler logic
|
|
123
|
+
// }
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
**Renderer Process Invocation:**
|
|
127
|
+
|
|
128
|
+
```{framework-language}
|
|
129
|
+
// AI-NOTE: Electron example - use actual syntax from techs knowledge
|
|
130
|
+
// File: src/renderer/apis/{module}.ts
|
|
131
|
+
|
|
132
|
+
import { ipcRenderer } from 'electron'
|
|
133
|
+
import type { {PayloadType}, {ResponseType} } from '@/types/{module}'
|
|
134
|
+
|
|
135
|
+
export const {apiFunction} = async (payload: {PayloadType}): Promise<{ResponseType}> => {
|
|
136
|
+
const result = await ipcRenderer.invoke('{channel-name}', payload)
|
|
137
|
+
if (!result.success) {
|
|
138
|
+
throw new Error(result.error)
|
|
139
|
+
}
|
|
140
|
+
return result.data
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// AI-NOTE: For Tauri, use:
|
|
144
|
+
// import { invoke } from '@tauri-apps/api/tauri'
|
|
145
|
+
// export const apiFunction = async (payload: PayloadType) => {
|
|
146
|
+
// return await invoke<ResponseType>('handler_name', payload)
|
|
147
|
+
// }
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### 4.4 IPC Error Recovery & Retry
|
|
151
|
+
|
|
152
|
+
<!-- AI-NOTE: IPC timeout, retry logic, and error classification patterns -->
|
|
153
|
+
|
|
154
|
+
```typescript
|
|
155
|
+
// IPC call with timeout and retry
|
|
156
|
+
const ipcCallWithRetry = async <T>(
|
|
157
|
+
channel: string,
|
|
158
|
+
payload: unknown,
|
|
159
|
+
options: { timeout?: number; maxRetries?: number } = {}
|
|
160
|
+
): Promise<T> => {
|
|
161
|
+
const { timeout = 10000, maxRetries = 3 } = options;
|
|
162
|
+
|
|
163
|
+
for (let attempt = 0; attempt < maxRetries; attempt++) {
|
|
164
|
+
try {
|
|
165
|
+
const result = await Promise.race([
|
|
166
|
+
window.electronAPI[channel](payload),
|
|
167
|
+
new Promise((_, reject) =>
|
|
168
|
+
setTimeout(() => reject(new Error('IPC_TIMEOUT')), timeout)
|
|
169
|
+
),
|
|
170
|
+
]);
|
|
171
|
+
return result as T;
|
|
172
|
+
} catch (error) {
|
|
173
|
+
if (error.message === 'IPC_TIMEOUT' && attempt < maxRetries - 1) {
|
|
174
|
+
await new Promise(r => setTimeout(r, 1000 * (attempt + 1)));
|
|
175
|
+
continue;
|
|
176
|
+
}
|
|
177
|
+
throw error;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
throw new Error('IPC_MAX_RETRIES_EXCEEDED');
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
// IPC error classification and handling
|
|
184
|
+
const handleIpcError = (error: Error, channel: string) => {
|
|
185
|
+
if (error.message === 'IPC_TIMEOUT') {
|
|
186
|
+
// Main process may be busy - show non-blocking notification
|
|
187
|
+
showNotification('Operation is taking longer than expected...');
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
if (error.message?.includes('ENOENT')) {
|
|
191
|
+
// File not found
|
|
192
|
+
showError(`File not found: ${error.message}`);
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
if (error.message?.includes('EPERM') || error.message?.includes('EACCES')) {
|
|
196
|
+
// Permission denied
|
|
197
|
+
showError('Permission denied. Please check file permissions.');
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
// Unknown error - log and show generic message
|
|
201
|
+
console.error(`IPC error on channel ${channel}:`, error);
|
|
202
|
+
showError('An unexpected error occurred. Please try again.');
|
|
203
|
+
};
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
## 5. UI Component Design
|
|
207
|
+
|
|
208
|
+
### 5.1 Component Tree
|
|
209
|
+
|
|
210
|
+
<!-- AI-NOTE: ASCII component tree showing UI structure in renderer process -->
|
|
211
|
+
|
|
212
|
+
```
|
|
213
|
+
MainWindow
|
|
214
|
+
├── TitleBar
|
|
215
|
+
│ ├── WindowControls
|
|
216
|
+
│ └── MenuButton
|
|
217
|
+
├── Sidebar
|
|
218
|
+
│ ├── NavigationItems
|
|
219
|
+
│ └── UserProfile
|
|
220
|
+
├── ContentArea
|
|
221
|
+
│ ├── Toolbar
|
|
222
|
+
│ │ ├── SearchBox
|
|
223
|
+
│ │ └── ActionButtons
|
|
224
|
+
│ └── DataView
|
|
225
|
+
│ ├── ListView
|
|
226
|
+
│ └── DetailPanel
|
|
227
|
+
└── StatusBar
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
### 5.2 Component Summary Table
|
|
231
|
+
|
|
232
|
+
| Component | Path | Type | Status | Description |
|
|
233
|
+
|-----------|------|------|--------|-------------|
|
|
234
|
+
| {Name} | `{directory}/{FileName}` | Page | [NEW]/[MODIFIED]/[EXISTING] | {Purpose} |
|
|
235
|
+
| {Name} | `{directory}/{FileName}` | Component | [NEW]/[MODIFIED]/[EXISTING] | {Purpose} |
|
|
236
|
+
|
|
237
|
+
### 5.3 Component Detail
|
|
238
|
+
|
|
239
|
+
<!-- AI-NOTE: Repeat Section 5.3.N for each component. Focus on [NEW] or [MODIFIED] status. -->
|
|
240
|
+
|
|
241
|
+
#### 5.3.1 {ComponentName}
|
|
242
|
+
|
|
243
|
+
**Purpose**: {What this component does}
|
|
244
|
+
|
|
245
|
+
**Props**:
|
|
246
|
+
|
|
247
|
+
| Prop | Type | Required | Default | Description |
|
|
248
|
+
|------|------|----------|---------|-------------|
|
|
249
|
+
| {prop} | {TypeScript type} | Yes/No | {value} | {description} |
|
|
250
|
+
|
|
251
|
+
**Emits/Callbacks**:
|
|
252
|
+
|
|
253
|
+
| Event | Payload Type | Description |
|
|
254
|
+
|-------|-------------|-------------|
|
|
255
|
+
| {event} | {TypeScript type} | {description} |
|
|
256
|
+
|
|
257
|
+
**Internal State**:
|
|
258
|
+
|
|
259
|
+
| State | Type | Initial Value | Description |
|
|
260
|
+
|-------|------|--------------|-------------|
|
|
261
|
+
| {state} | {type} | {value} | {description} |
|
|
262
|
+
|
|
263
|
+
**Pseudo-code**:
|
|
264
|
+
|
|
265
|
+
```{framework-language}
|
|
266
|
+
// AI-NOTE: Use actual framework API syntax from techs knowledge
|
|
267
|
+
// Example for React with TypeScript:
|
|
268
|
+
|
|
269
|
+
import React, { useState, useEffect } from 'react'
|
|
270
|
+
import { use{StoreName}Store } from '@/stores/{store-name}'
|
|
271
|
+
import { {apiFunction} } from '@/apis/{module}'
|
|
272
|
+
|
|
273
|
+
interface {ComponentName}Props {
|
|
274
|
+
{propName}: {Type}
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
export const {ComponentName}: React.FC<{ComponentName}Props> = ({ {propName} }) => {
|
|
278
|
+
const [{state}, set{State}] = useState<{Type}>({initialValue})
|
|
279
|
+
const {store} = use{StoreName}Store()
|
|
280
|
+
|
|
281
|
+
const handle{Action} = async () => {
|
|
282
|
+
try {
|
|
283
|
+
const result = await {apiFunction}(params)
|
|
284
|
+
// handle result
|
|
285
|
+
} catch (error) {
|
|
286
|
+
// handle error
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
useEffect(() => {
|
|
291
|
+
// initialization
|
|
292
|
+
}, [])
|
|
293
|
+
|
|
294
|
+
return (
|
|
295
|
+
// JSX structure
|
|
296
|
+
)
|
|
297
|
+
}
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
**Referenced IPC Calls**:
|
|
301
|
+
|
|
302
|
+
| IPC Channel | Usage Context |
|
|
303
|
+
|-------------|---------------|
|
|
304
|
+
| {channel} | {when and why called} |
|
|
305
|
+
|
|
306
|
+
---
|
|
307
|
+
|
|
308
|
+
### 5.4 Component Error Boundary & Loading States
|
|
309
|
+
|
|
310
|
+
<!-- AI-NOTE: Error handling and async data loading patterns for desktop apps -->
|
|
311
|
+
|
|
312
|
+
```typescript
|
|
313
|
+
// Error boundary wrapper for desktop app sections
|
|
314
|
+
const SectionErrorBoundary: React.FC<{
|
|
315
|
+
fallback: React.ReactNode;
|
|
316
|
+
onError?: (error: Error) => void;
|
|
317
|
+
children: React.ReactNode;
|
|
318
|
+
}> = ({ fallback, onError, children }) => {
|
|
319
|
+
const [hasError, setHasError] = useState(false);
|
|
320
|
+
|
|
321
|
+
// Note: Use React ErrorBoundary class component in actual implementation
|
|
322
|
+
// This shows the pattern for the design document
|
|
323
|
+
if (hasError) return <>{fallback}</>;
|
|
324
|
+
return <>{children}</>;
|
|
325
|
+
};
|
|
326
|
+
|
|
327
|
+
// Loading state management pattern
|
|
328
|
+
const useAsyncData = <T>(fetcher: () => Promise<T>) => {
|
|
329
|
+
const [data, setData] = useState<T | null>(null);
|
|
330
|
+
const [isLoading, setIsLoading] = useState(true);
|
|
331
|
+
const [error, setError] = useState<Error | null>(null);
|
|
332
|
+
|
|
333
|
+
const load = useCallback(async () => {
|
|
334
|
+
setIsLoading(true);
|
|
335
|
+
setError(null);
|
|
336
|
+
try {
|
|
337
|
+
const result = await fetcher();
|
|
338
|
+
setData(result);
|
|
339
|
+
} catch (e) {
|
|
340
|
+
setError(e instanceof Error ? e : new Error(String(e)));
|
|
341
|
+
} finally {
|
|
342
|
+
setIsLoading(false);
|
|
343
|
+
}
|
|
344
|
+
}, [fetcher]);
|
|
345
|
+
|
|
346
|
+
useEffect(() => { load(); }, [load]);
|
|
347
|
+
|
|
348
|
+
return { data, isLoading, error, reload: load };
|
|
349
|
+
};
|
|
350
|
+
|
|
351
|
+
// Usage in component
|
|
352
|
+
const FileManager: React.FC = () => {
|
|
353
|
+
const { data: files, isLoading, error, reload } = useAsyncData(
|
|
354
|
+
() => window.electronAPI.listFiles(currentDir)
|
|
355
|
+
);
|
|
356
|
+
|
|
357
|
+
if (isLoading) return <LoadingSpinner />;
|
|
358
|
+
if (error) return <ErrorPanel message={error.message} onRetry={reload} />;
|
|
359
|
+
if (!files?.length) return <EmptyState message="No files in this directory" />;
|
|
360
|
+
|
|
361
|
+
return (
|
|
362
|
+
<FileGrid files={files} onFileClick={handleFileClick} />
|
|
363
|
+
);
|
|
364
|
+
};
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
## 6. State Management
|
|
368
|
+
|
|
369
|
+
### 6.1 Main Process State
|
|
370
|
+
|
|
371
|
+
<!-- AI-NOTE: Describe state managed in main process (window states, native resources) -->
|
|
372
|
+
|
|
373
|
+
| State | Type | Scope | Description |
|
|
374
|
+
|-------|------|-------|-------------|
|
|
375
|
+
| {state} | {type} | {scope} | {description} |
|
|
376
|
+
|
|
377
|
+
### 6.2 Renderer Process State
|
|
378
|
+
|
|
379
|
+
<!-- AI-NOTE: Describe state managed in renderer process (UI state, user data) -->
|
|
380
|
+
|
|
381
|
+
| State | Type | Scope | Description |
|
|
382
|
+
|-------|------|-------|-------------|
|
|
383
|
+
| {state} | {type} | {scope} | {description} |
|
|
384
|
+
|
|
385
|
+
**Store Module**: `{store-path}/{store-name}`
|
|
386
|
+
**Status**: [NEW]/[MODIFIED]/[EXISTING]
|
|
387
|
+
|
|
388
|
+
```{framework-language}
|
|
389
|
+
// AI-NOTE: Use actual store pattern from techs knowledge
|
|
390
|
+
// Example for Zustand:
|
|
391
|
+
|
|
392
|
+
import { create } from 'zustand'
|
|
393
|
+
import type { {TypeName} } from '@/types/{module}'
|
|
394
|
+
|
|
395
|
+
interface {StoreName}State {
|
|
396
|
+
{stateField}: {Type}
|
|
397
|
+
{action}: (params: {Type}) => void
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
export const use{StoreName}Store = create<{StoreName}State>((set, get) => ({
|
|
401
|
+
{stateField}: {initialValue},
|
|
402
|
+
|
|
403
|
+
{action}: (params) => {
|
|
404
|
+
// action implementation
|
|
405
|
+
set({ {stateField}: newValue })
|
|
406
|
+
}
|
|
407
|
+
}))
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
### 6.3 State Synchronization
|
|
411
|
+
|
|
412
|
+
<!-- AI-NOTE: Describe how state is synchronized between main and renderer processes -->
|
|
413
|
+
|
|
414
|
+
| Direction | Mechanism | Trigger | Description |
|
|
415
|
+
|-----------|-----------|---------|-------------|
|
|
416
|
+
| Main→Renderer | IPC event | {trigger} | {description} |
|
|
417
|
+
| Renderer→Main | IPC invoke | {trigger} | {description} |
|
|
418
|
+
|
|
419
|
+
## 7. API Layer
|
|
420
|
+
|
|
421
|
+
### 7.1 Remote API Functions
|
|
422
|
+
|
|
423
|
+
<!-- AI-NOTE: HTTP calls to backend server -->
|
|
424
|
+
|
|
425
|
+
```{framework-language}
|
|
426
|
+
// AI-NOTE: File path follows conventions from techs knowledge
|
|
427
|
+
// File: src/renderer/apis/remote/{module}.ts
|
|
428
|
+
|
|
429
|
+
import { request } from '@/utils/request'
|
|
430
|
+
import type { {RequestType}, {ResponseType} } from '@/types/{module}'
|
|
431
|
+
|
|
432
|
+
export const {remoteApiFunction} = (params: {RequestType}): Promise<{ResponseType}> => {
|
|
433
|
+
return request.{method}('{path}', params)
|
|
434
|
+
}
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
### 7.2 Local API Functions
|
|
438
|
+
|
|
439
|
+
<!-- AI-NOTE: IPC calls to main process -->
|
|
440
|
+
|
|
441
|
+
See Section 4.3 for IPC pseudo-code.
|
|
442
|
+
|
|
443
|
+
### 7.3 Error Handling
|
|
444
|
+
|
|
445
|
+
| Error Source | Error Type | Handling | User Feedback |
|
|
446
|
+
|--------------|------------|----------|---------------|
|
|
447
|
+
| Remote API | HTTP Error | {handling logic} | {message/dialog} |
|
|
448
|
+
| Local IPC | IPC Error | {handling logic} | {message/dialog} |
|
|
449
|
+
| Native API | Native Error | {handling logic} | {message/dialog} |
|
|
450
|
+
|
|
451
|
+
## 8. Native Integration
|
|
452
|
+
|
|
453
|
+
### 8.1 File System Access
|
|
454
|
+
|
|
455
|
+
| Operation | API | Scope | Security |
|
|
456
|
+
|-----------|-----|-------|----------|
|
|
457
|
+
| Read File | {API} | {allowed paths} | {security measure} |
|
|
458
|
+
| Write File | {API} | {allowed paths} | {security measure} |
|
|
459
|
+
| Open Dialog | {API} | {scope} | {security measure} |
|
|
460
|
+
| Save Dialog | {API} | {scope} | {security measure} |
|
|
461
|
+
|
|
462
|
+
### 8.2 File System Safety Patterns
|
|
463
|
+
|
|
464
|
+
<!-- AI-NOTE: Path validation, size limits, and safe file operations -->
|
|
465
|
+
|
|
466
|
+
```typescript
|
|
467
|
+
// Main process: Safe file operations with path validation
|
|
468
|
+
const ALLOWED_BASE_PATHS = [
|
|
469
|
+
app.getPath('documents'),
|
|
470
|
+
app.getPath('downloads'),
|
|
471
|
+
app.getPath('userData'),
|
|
472
|
+
];
|
|
473
|
+
|
|
474
|
+
ipcMain.handle('file:read', async (_event, filePath: string) => {
|
|
475
|
+
// Path traversal prevention
|
|
476
|
+
const resolvedPath = path.resolve(filePath);
|
|
477
|
+
const isAllowed = ALLOWED_BASE_PATHS.some(base =>
|
|
478
|
+
resolvedPath.startsWith(path.resolve(base))
|
|
479
|
+
);
|
|
480
|
+
if (!isAllowed) {
|
|
481
|
+
throw new Error('ACCESS_DENIED: Path outside allowed directories');
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
// Check existence before reading
|
|
485
|
+
try {
|
|
486
|
+
await fs.promises.access(resolvedPath, fs.constants.R_OK);
|
|
487
|
+
} catch {
|
|
488
|
+
throw new Error(`FILE_NOT_FOUND: ${path.basename(resolvedPath)}`);
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
// Read with size limit (prevent memory issues)
|
|
492
|
+
const stats = await fs.promises.stat(resolvedPath);
|
|
493
|
+
if (stats.size > 100 * 1024 * 1024) { // 100MB limit
|
|
494
|
+
throw new Error('FILE_TOO_LARGE: Max 100MB');
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
return await fs.promises.readFile(resolvedPath, 'utf-8');
|
|
498
|
+
});
|
|
499
|
+
|
|
500
|
+
// Renderer process: File operation with user feedback
|
|
501
|
+
const openAndReadFile = async (): Promise<string | null> => {
|
|
502
|
+
try {
|
|
503
|
+
setIsLoading(true);
|
|
504
|
+
const filePath = await window.electronAPI.showOpenDialog({
|
|
505
|
+
filters: [{ name: 'Documents', extensions: ['json', 'csv', 'txt'] }],
|
|
506
|
+
});
|
|
507
|
+
if (!filePath) return null; // User cancelled
|
|
508
|
+
|
|
509
|
+
return await ipcCallWithRetry<string>('file:read', filePath, { timeout: 30000 });
|
|
510
|
+
} catch (error) {
|
|
511
|
+
handleIpcError(error, 'file:read');
|
|
512
|
+
return null;
|
|
513
|
+
} finally {
|
|
514
|
+
setIsLoading(false);
|
|
515
|
+
}
|
|
516
|
+
};
|
|
517
|
+
```
|
|
518
|
+
|
|
519
|
+
### 8.3 System Tray Design
|
|
520
|
+
|
|
521
|
+
- **Icon**: {icon path or generation method}
|
|
522
|
+
- **Context Menu Items**:
|
|
523
|
+
| Item | Action | Handler |
|
|
524
|
+
|------|--------|---------|
|
|
525
|
+
| {item} | {action} | {handler} |
|
|
526
|
+
- **Click Behavior**: {single click / double click behavior}
|
|
527
|
+
|
|
528
|
+
### 8.4 Menu Bar Design
|
|
529
|
+
|
|
530
|
+
| Menu | Items | Shortcuts | Handler |
|
|
531
|
+
|------|-------|-----------|---------|
|
|
532
|
+
| File | {items} | {shortcuts} | {handlers} |
|
|
533
|
+
| Edit | {items} | {shortcuts} | {handlers} |
|
|
534
|
+
| View | {items} | {shortcuts} | {handlers} |
|
|
535
|
+
|
|
536
|
+
### 8.5 OS Notifications
|
|
537
|
+
|
|
538
|
+
<!-- AI-NOTE: Describe notification usage -->
|
|
539
|
+
|
|
540
|
+
| Scenario | Title | Body | Actions |
|
|
541
|
+
|----------|-------|------|---------|
|
|
542
|
+
| {scenario} | {title} | {body} | {actions} |
|
|
543
|
+
|
|
544
|
+
### 8.6 Protocol Handlers & File Associations
|
|
545
|
+
|
|
546
|
+
| Protocol/Extension | Handler | Description |
|
|
547
|
+
|-------------------|---------|-------------|
|
|
548
|
+
| {protocol} | {handler} | {description} |
|
|
549
|
+
| {.ext} | {handler} | {description} |
|
|
550
|
+
|
|
551
|
+
### 8.7 Keyboard Shortcuts
|
|
552
|
+
|
|
553
|
+
| Shortcut | Scope | Action |
|
|
554
|
+
|----------|-------|--------|
|
|
555
|
+
| {Ctrl/Cmd}+N | Global/Window | {action} |
|
|
556
|
+
| {Ctrl/Cmd}+S | Window | {action} |
|
|
557
|
+
|
|
558
|
+
## 9. Local Data Storage
|
|
559
|
+
|
|
560
|
+
### 9.1 Storage Strategy
|
|
561
|
+
|
|
562
|
+
<!-- AI-NOTE: Choose from SQLite/LevelDB/JSON files/electron-store/tauri-store -->
|
|
563
|
+
|
|
564
|
+
| Data Type | Storage | Location | Encryption |
|
|
565
|
+
|-----------|---------|----------|------------|
|
|
566
|
+
| {data type} | {SQLite/LevelDB/etc} | {path} | {Yes/No} |
|
|
567
|
+
|
|
568
|
+
### 9.2 Data Schema
|
|
569
|
+
|
|
570
|
+
| Table/Key | Fields | Description |
|
|
571
|
+
|-----------|--------|-------------|
|
|
572
|
+
| {table/key} | {fields} | {description} |
|
|
573
|
+
|
|
574
|
+
### 9.3 Migration Strategy
|
|
575
|
+
|
|
576
|
+
<!-- AI-NOTE: Describe how data migrations are handled -->
|
|
577
|
+
|
|
578
|
+
{Description of migration approach}
|
|
579
|
+
|
|
580
|
+
## 10. Security Design
|
|
581
|
+
|
|
582
|
+
### 10.1 Context Isolation Configuration
|
|
583
|
+
|
|
584
|
+
<!-- AI-NOTE: Electron-specific: describe contextIsolation, nodeIntegration settings -->
|
|
585
|
+
|
|
586
|
+
| Setting | Value | Purpose |
|
|
587
|
+
|---------|-------|---------|
|
|
588
|
+
| contextIsolation | true/false | {purpose} |
|
|
589
|
+
| nodeIntegration | true/false | {purpose} |
|
|
590
|
+
| enableRemoteModule | true/false | {purpose} |
|
|
591
|
+
|
|
592
|
+
### 10.2 Preload Script Design
|
|
593
|
+
|
|
594
|
+
```{framework-language}
|
|
595
|
+
// AI-NOTE: Electron preload script example
|
|
596
|
+
// File: src/preload/{module}.ts
|
|
597
|
+
|
|
598
|
+
import { contextBridge, ipcRenderer } from 'electron'
|
|
599
|
+
import type { {PayloadType}, {ResponseType} } from '@/types/{module}'
|
|
600
|
+
|
|
601
|
+
// AI-NOTE: Expose safe APIs to renderer
|
|
602
|
+
contextBridge.exposeInMainWorld('{apiName}', {
|
|
603
|
+
{functionName}: (payload: {PayloadType}): Promise<{ResponseType}> => {
|
|
604
|
+
return ipcRenderer.invoke('{channel-name}', payload)
|
|
605
|
+
}
|
|
606
|
+
})
|
|
607
|
+
```
|
|
608
|
+
|
|
609
|
+
### 10.3 Content Security Policy
|
|
610
|
+
|
|
611
|
+
<!-- AI-NOTE: Describe CSP configuration -->
|
|
612
|
+
|
|
613
|
+
```
|
|
614
|
+
{ CSP policy string }
|
|
615
|
+
```
|
|
616
|
+
|
|
617
|
+
### 10.4 Permission Scoping
|
|
618
|
+
|
|
619
|
+
| Permission | Scope | Justification |
|
|
620
|
+
|------------|-------|---------------|
|
|
621
|
+
| {permission} | {scope} | {justification} |
|
|
622
|
+
|
|
623
|
+
## 11. Auto-Update Mechanism
|
|
624
|
+
|
|
625
|
+
### 11.1 Update Check Strategy
|
|
626
|
+
|
|
627
|
+
<!-- AI-NOTE: Describe when and how update checks are performed -->
|
|
628
|
+
|
|
629
|
+
| Trigger | Frequency | Method |
|
|
630
|
+
|---------|-----------|--------|
|
|
631
|
+
| {trigger} | {frequency} | {method} |
|
|
632
|
+
|
|
633
|
+
### 11.2 Download and Install Flow
|
|
634
|
+
|
|
635
|
+
```mermaid
|
|
636
|
+
sequenceDiagram
|
|
637
|
+
participant A as App
|
|
638
|
+
participant U as Updater
|
|
639
|
+
participant S as Update Server
|
|
640
|
+
|
|
641
|
+
A->>U: checkForUpdates()
|
|
642
|
+
U->>S: fetch latest version
|
|
643
|
+
S-->>U: version info
|
|
644
|
+
U-->>A: update-available event
|
|
645
|
+
A->>U: downloadUpdate()
|
|
646
|
+
U->>S: download package
|
|
647
|
+
S-->>U: package data
|
|
648
|
+
U-->>A: download-progress events
|
|
649
|
+
U-->>A: update-downloaded event
|
|
650
|
+
A->>U: quitAndInstall()
|
|
651
|
+
```
|
|
652
|
+
|
|
653
|
+
### 11.3 Rollback Mechanism
|
|
654
|
+
|
|
655
|
+
<!-- AI-NOTE: Describe rollback strategy if update fails -->
|
|
656
|
+
|
|
657
|
+
{Description of rollback approach}
|
|
658
|
+
|
|
659
|
+
## 12. Unit Test Points
|
|
660
|
+
|
|
661
|
+
| Test Target | Test Scenario | Expected Behavior |
|
|
662
|
+
|-------------|--------------|-------------------|
|
|
663
|
+
| {IPC handler} | {scenario} | {expected result} |
|
|
664
|
+
| {Window manager} | {scenario} | {expected result} |
|
|
665
|
+
| {Native API wrapper} | {scenario} | {expected result} |
|
|
666
|
+
| {Component} | {scenario} | {expected result} |
|
|
667
|
+
| {Store action} | {scenario} | {expected result} |
|
|
668
|
+
|
|
669
|
+
---
|
|
670
|
+
|
|
671
|
+
**Document Status**: Draft / In Review / Published
|
|
672
|
+
**Last Updated**: {Date}
|
|
673
|
+
**Related Feature Spec**: [{Feature Name}]({FeatureSpecPath})
|