WeFlow - 一个本地的微信聊天记录导出和年度报告应用
This report summarizes scanner evidence for hicccc77/WeFlow, a TypeScript project with 15,671 GitHub stars. SynthScan examined 264,816 lines of code across 415 source files, recording 527 pattern matches distributed across 7 syntactic categories. The legacy adjusted pattern signal is 2.7 (Low pattern signal); it is not an authorship estimate.
Use the findings to ask whether maintainers can explain intent, verify dependencies, simplify unnecessary scaffolding, and focus review effort. Risk Payload v1 adds ownership, supply-chain, over-engineering, and review-effort vectors when available. These are prompts for human verification, not probabilities, security findings, or measured maintenance costs.
Use each vector to guide manual verification of the underlying findings.
Payload schema: 1.0.0 · Engine: 2.0.0 · Scoring: heuristic-density-v1 · Scan date: 2026-10-31.
Can maintainers explain intent, assumptions, and trade-offs? 418 finding(s).
Are imports declared and package/API names verified? 8 finding(s).
Are wrappers, guards, and repeated structures necessary? 506 finding(s).
Which changes need focused human review? 527 finding(s).
This chart tracks the legacy adjusted pattern score across scan runs. Changes can reflect source changes, scan coverage, or detector/scoring versions; they do not measure AI adoption or prove that a team refactored code. Compare runs only when their scoring versions are compatible. The dashed line tracks the raw pattern-hit count.
Groups findings by configured severity weight. Severity is not a confidence estimate, security rating, or proof that a package is missing. Verify imports against the project's manifests and inspect each finding in its local design context.
This horizontal bar chart shows where configured pattern scores accumulate across directories. Treat the bars as locations to inspect, not as evidence of authorship or code quality. Use the file-level findings to decide whether a directory needs a focused ownership, dependency, complexity, or review check.
The scanner identified 527 distinct pattern matches across 7 syntactic categories. Each entry below represents a discrete location in the source code where the engine recorded a detector match to inspect in context. Expand any category row to inspect the individual file paths, line numbers, code snippets, and the lexical context (CODE, COMMENT, or STRING) in which each match was detected.
Reading the findings table: The Severity column indicates the configured finding weight (CRITICAL / HIGH / MEDIUM / LOW). The Context column identifies whether the match occurred inside executable code, an inline comment, or a string literal — legacy comment-context matches receive a ×1.5 score weight. The ⚡ bolt icon marks clustered matches: three or more patterns within a 10-line window, each receiving an additional ×1.5 density multiplier under the legacy scoring model.
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | electron/main.ts | 109 | function agentMemoryConversationRoleText(messages: unknown, role: 'user' | 'assistant'): string { | CODE |
| LOW | electron/main.ts | 120 | function recentAgentMemoryExchanges(limit = 64): AgentMemoryConversationExchange[] { | CODE |
| LOW | electron/main.ts | 1435 | function createErrorReferenceWindow(query?: string, requestedParent?: BrowserWindow | null): BrowserWindow { | CODE |
| LOW | electron/main.ts | 1660 | function createChatHistoryPayloadWindow(payloadId: string) { | CODE |
| LOW | electron/main.ts | 1668 | function createChatHistoryRouteWindow(route: string) { | CODE |
| LOW | electron/main.ts | 1829 | function reloadMainWindowAfterOnboarding() { | CODE |
| LOW | electron/transcribeWorker.ts | 91 | function richTranscribePostProcess(text: string): string { | CODE |
| LOW | electron/windows/notificationWindow.ts | 46 | export function setNotificationNavigateHandler( | CODE |
| LOW | electron/windows/notificationWindow.ts | 184 | export function destroyNotificationWindow() { | CODE |
| LOW | electron/windows/notificationWindow.ts | 381 | async function showViaSystemNotification(data: any) { | CODE |
| LOW | electron/windows/notificationWindow.ts | 419 | function nextNotificationDeliveryId() { | CODE |
| LOW | electron/windows/notificationWindow.ts | 504 | export async function registerNotificationHandlers() { | CODE |
| LOW | electron/assets/wasm/wasm_video_decode.js | 979 | function updateGlobalBufferAndViews(buf) { | CODE |
| LOW | electron/assets/wasm/wasm_video_decode.js | 1268 | function receiveInstantiationResult(result) { | CODE |
| LOW | electron/assets/wasm/wasm_video_decode.js | 1688 | function simpleReadValueFromPointer(pointer) { | CODE |
| LOW | electron/assets/wasm/wasm_video_decode.js | 1751 | function whenDependentTypesAreResolved(myTypes, dependentTypes, getTypeConverters) { | CODE |
| LOW | electron/assets/wasm/wasm_video_decode.js | 1981 | function shallowCopyInternalPointer(o) { | CODE |
| LOW | electron/assets/wasm/wasm_video_decode.js | 1993 | function throwInstanceAlreadyDeleted(obj) { | CODE |
| LOW | electron/assets/wasm/wasm_video_decode.js | 2198 | function constNoSmartPtrRawPointerToWireType(destructors, handle) { | CODE |
| LOW | electron/assets/wasm/wasm_video_decode.js | 2293 | function nonConstNoSmartPtrRawPointerToWireType(destructors, handle) { | CODE |
| LOW | electron/assets/wasm/wasm_video_decode.js | 2349 | function getInheritedInstanceCount() { | CODE |
| LOW | electron/assets/wasm/wasm_video_decode.js | 2353 | function getLiveInheritedInstances() { | CODE |
| LOW | electron/assets/wasm/wasm_video_decode.js | 3258 | function floatReadValueFromPointer(name, shift) { | CODE |
| LOW | electron/assets/wasm/wasm_video_decode.js | 3306 | function integerReadValueFromPointer(name, shift, signed) { | CODE |
| LOW | electron/services/agentModelLedService.ts | 393 | function isAgentVoiceModelRequiredError(error: unknown): boolean { | CODE |
| LOW | electron/services/agentModelLedService.ts | 398 | function agentDirectSessionPageHeader(displayName: string, startAt: string, endAt: string, pageId: string): string { | CODE |
| LOW | electron/services/agentModelLedService.ts | 413 | function compactAgentTimelineEventPreview( | CODE |
| LOW | electron/services/agentModelLedService.ts | 529 | function summarizeAgentActivityRows(rows: AgentActivityDateRow[]) { | CODE |
| LOW | electron/services/agentModelLedService.ts | 641 | function repairSerializedStructuredValue( | CODE |
| LOW | electron/services/agentModelLedService.ts | 858 | function compactToolOutputForStorage(toolName: string, output: unknown): unknown { | CODE |
| LOW | electron/services/agentModelLedService.ts | 862 | function compactToolInputForStorage(toolName: string, input: unknown): unknown { | CODE |
| LOW | electron/services/agentModelLedService.ts | 876 | function compactConversationMessages(messages: unknown): UIMessage[] { | CODE |
| LOW | electron/services/agentModelLedService.ts | 1126 | function compactActivitySummaryForWorkspace(value: unknown): unknown { | CODE |
| LOW | electron/services/agentModelLedService.ts | 1152 | function compactTimelineNavigationForReconnaissance( | CODE |
| LOW | electron/services/agentModelLedService.ts | 1262 | function compactFocusedTimelineNavigation(value: unknown): Array<Record<string, unknown>> { | CODE |
| LOW | electron/services/agentModelLedService.ts | 1307 | function compactReconnaissanceActivitySummary(value: unknown): unknown { | CODE |
| LOW | electron/services/agentModelLedService.ts | 1333 | function summarizeToolOutputForWorkspace(toolName: string, output: unknown): unknown { | CODE |
| LOW | electron/services/agentModelLedService.ts | 1613 | function compactPersistedConversationManifestForWorkspace( | CODE |
| LOW | electron/services/agentModelLedService.ts | 1659 | function compactPersistedTimelineNavigationForWorkspace(output: unknown): unknown { | CODE |
| LOW | electron/services/agentModelLedService.ts | 1692 | function summarizeAcknowledgedToolOutputForWorkspace(toolName: string, output: unknown): unknown { | CODE |
| LOW | electron/services/agentModelLedService.ts | 1744 | function compactExactRawReuseResult(toolName: string, output: unknown): unknown { | CODE |
| LOW | electron/services/agentMemoryRuntimeGuidance.ts | 10 | export function mergeAgentRuntimeMemoryEntries( | CODE |
| LOW | electron/services/agentMemoryRuntimeGuidance.ts | 25 | export function agentRuntimeMemoryGuidance(entries: AgentRuntimeMemoryEntry[]): string { | CODE |
| LOW | electron/services/agentTitleService.ts | 32 | export function normalizeGeneratedAgentTitle(value: unknown): string | null { | CODE |
| LOW | electron/services/openAICompatibleFetch.ts | 33 | function createToolCallStreamState(): ToolCallStreamState { | CODE |
| LOW | electron/services/openAICompatibleFetch.ts | 241 | export function normalizeOpenAICompatibleChunk( | CODE |
| LOW | electron/services/openAICompatibleFetch.ts | 320 | function createTextDecoderTransform(): TransformStream<Uint8Array, string> { | CODE |
| LOW | electron/services/openAICompatibleFetch.ts | 501 | export function createOpenAICompatibleFetch( | CODE |
| LOW | electron/services/agentRetryPolicy.ts | 24 | export function isAgentProviderPoolExhaustedError(error: unknown): boolean { | CODE |
| LOW⚡ | electron/services/agentRetryPolicy.ts | 67 | export function isAgentNetworkRetryExhaustedError(error: unknown): error is AgentNetworkRetryExhaustedError { | CODE |
| LOW⚡ | electron/services/agentRetryPolicy.ts | 72 | export function isAgentRetryExhaustedError(error: unknown): error is AgentNetworkRetryExhaustedError | AgentModelRetryEx | CODE |
| LOW⚡ | electron/services/agentRetryPolicy.ts | 77 | export function isAgentConcurrencyLimitError(error: unknown): boolean { | CODE |
| LOW⚡ | electron/services/agentRetryPolicy.ts | 92 | export function isRetryableAgentTransportError(error: unknown): boolean { | CODE |
| LOW⚡ | electron/services/agentRetryPolicy.ts | 98 | export function agentTransportRetryDelayMs(error: unknown, attempt: number): number { | CODE |
| LOW⚡ | electron/services/agentRetryPolicy.ts | 105 | export async function waitForAgentTransportRetry(delayMs: number, signal?: AbortSignal): Promise<void> { | CODE |
| LOW | electron/services/agentWebSearchPolicy.ts | 9 | export function explicitlyRequestsWebSearch(value: unknown): boolean { | CODE |
| LOW | electron/services/agentWebSearchPolicy.ts | 19 | export function shouldRequireAgentWebSearch( | CODE |
| LOW | electron/services/agentMemoryQuality.ts | 43 | export function inspectAutomaticMemoryEntry(entry: AgentMemoryQualityEntry): AgentMemoryQualityIssue[] { | CODE |
| LOW | electron/services/agentTextRedaction.ts | 33 | export function normalizeAgentSensitiveText(value: string): string { | CODE |
| LOW | electron/services/agentTextRedaction.ts | 76 | export function findChineseMobileCandidates(value: string): AgentSensitiveTextMatch[] { | CODE |
| 345 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | electron/services/insightService.ts | 34 | // ─── 常量 ──────────────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | electron/services/insightService.ts | 88 | // ─── 类型 ──────────────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | electron/services/insightService.ts | 134 | // ─── 日志 ───────────────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | electron/services/insightService.ts | 158 | // ─── 工具函数 ───────────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | electron/services/insightService.ts | 405 | // ─── InsightService 主类 ────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | electron/services/insightService.ts | 457 | // ── 公开 API ──────────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | electron/services/insightService.ts | 1058 | // ── 私有方法 ──────────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | electron/services/insightService.ts | 1371 | // ── 沉默联系人扫描 ────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | electron/services/insightService.ts | 1460 | // ── 活跃会话分析 ──────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | electron/services/insightService.ts | 1580 | // ── 核心见解生成 ──────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | electron/services/insightService.ts | 1611 | // ── 构建 prompt ──────────────────────────────────────────────────────────── | COMMENT |
| MEDIUM | src/stores/exportTaskStore.ts | 13 | // ─── Types ─────────────────────────────────────────────────── | COMMENT |
| MEDIUM | src/stores/exportTaskStore.ts | 51 | // ─── Store ─────────────────────────────────────────────────── | COMMENT |
| MEDIUM | src/pages/ChatPage.scss | 2644 | // ═══════════════════════════════════════════ | COMMENT |
| MEDIUM | src/pages/ChatPage.scss | 2646 | // ═══════════════════════════════════════════ | COMMENT |
| MEDIUM | src/pages/Export/types.ts | 10 | // ─── Tabs & Enums ──────────────────────────────────────────── | COMMENT |
| MEDIUM | src/pages/Export/types.ts | 58 | // ─── Export Options ────────────────────────────────────────── | COMMENT |
| MEDIUM | src/pages/Export/types.ts | 82 | // ─── Session ───────────────────────────────────────────────── | COMMENT |
| MEDIUM | src/pages/Export/types.ts | 94 | // ─── Task Progress ─────────────────────────────────────────── | COMMENT |
| MEDIUM | src/pages/Export/types.ts | 133 | // ─── Export Task ────────────────────────────────────────────── | COMMENT |
| MEDIUM | src/pages/Export/types.ts | 169 | // ─── Export Dialog ──────────────────────────────────────────── | COMMENT |
| MEDIUM | src/pages/Export/types.ts | 181 | // ─── Session Detail ────────────────────────────────────────── | COMMENT |
| MEDIUM | src/pages/Export/types.ts | 211 | // ─── Session Metrics ───────────────────────────────────────── | COMMENT |
| MEDIUM | src/pages/Export/types.ts | 257 | // ─── Session Load Trace ────────────────────────────────────── | COMMENT |
| MEDIUM | src/pages/Export/types.ts | 273 | // ─── Contacts Loading ──────────────────────────────────────── | COMMENT |
| MEDIUM | src/pages/Export/types.ts | 295 | // ─── Automation Draft (for the create/edit form) ───────────── | COMMENT |
| MEDIUM | src/pages/Export/types.ts | 320 | // ─── Re-exports for convenience ────────────────────────────── | COMMENT |
| MEDIUM | src/pages/Export/constants.ts | 18 | // ─── Content type labels ───────────────────────────────────── | COMMENT |
| MEDIUM | src/pages/Export/constants.ts | 32 | // ─── Conversation tab labels ───────────────────────────────── | COMMENT |
| MEDIUM | src/pages/Export/constants.ts | 41 | // ─── Export format options ──────────────────────────────────── | COMMENT |
| MEDIUM | src/pages/Export/constants.ts | 56 | // ─── Display name options ──────────────────────────────────── | COMMENT |
| MEDIUM | src/pages/Export/constants.ts | 70 | // ─── Write layout options ──────────────────────────────────── | COMMENT |
| MEDIUM⚡ | src/pages/Export/constants.ts | 90 | // ─── File size presets ─────────────────────────────────────── | COMMENT |
| MEDIUM⚡ | src/pages/Export/constants.ts | 95 | // ─── Default txt export columns ────────────────────────────── | COMMENT |
| MEDIUM⚡ | src/pages/Export/constants.ts | 99 | // ─── Background task labels ────────────────────────────────── | COMMENT |
| MEDIUM⚡ | src/pages/Export/constants.ts | 121 | // ─── Conversation tab sort priority ────────────────────────── | COMMENT |
| MEDIUM⚡ | src/pages/Export/constants.ts | 130 | // ─── Default sort config ───────────────────────────────────── | COMMENT |
| MEDIUM⚡ | src/pages/Export/constants.ts | 134 | // ─── Timing constants ──────────────────────────────────────── | COMMENT |
| MEDIUM | src/pages/Export/constants.ts | 155 | // ─── Default export options ────────────────────────────────── | COMMENT |
| MEDIUM | src/pages/Export/constants.ts | 182 | // ─── Empty progress factory ────────────────────────────────── | COMMENT |
| MEDIUM | src/pages/Export/ExportPage.scss | 13 | // ─── Top panel ─────────────────────────────────────────────── | COMMENT |
| MEDIUM | src/pages/Export/ExportPage.scss | 20 | // ─── Body (session list + bottom task panel) ───────────────── | COMMENT |
| MEDIUM | src/pages/Export/ExportPage.scss | 49 | // ─── Selection Action Bar ──────────────────────────────────── | COMMENT |
| MEDIUM | src/pages/Export/ExportPage.scss | 108 | // ─── Global Settings Modal ─────────────────────────────────── | COMMENT |
| MEDIUM | src/pages/Export/utils/performance.ts | 10 | // ─── Stage resolution ──────────────────────────────────────── | COMMENT |
| MEDIUM | src/pages/Export/utils/performance.ts | 19 | // ─── Performance object factories ──────────────────────────── | COMMENT |
| MEDIUM | src/pages/Export/utils/performance.ts | 36 | // ─── Session name resolution ───────────────────────────────── | COMMENT |
| MEDIUM | src/pages/Export/utils/performance.ts | 46 | // ─── Apply progress to performance ────────────────────────── | COMMENT |
| MEDIUM | src/pages/Export/utils/performance.ts | 96 | // ─── Finalize performance on task completion ───────────────── | COMMENT |
| MEDIUM | src/pages/Export/utils/performance.ts | 145 | // ─── Top N slowest sessions ────────────────────────────────── | COMMENT |
| MEDIUM | src/pages/Export/utils/progress.ts | 8 | // ─── Progress comparison ───────────────────────────────────── | COMMENT |
| MEDIUM | src/pages/Export/utils/progress.ts | 30 | // ─── Progress normalization ────────────────────────────────── | COMMENT |
| MEDIUM | src/pages/Export/utils/progress.ts | 45 | // ─── Progress payload signature (for dedup) ────────────────── | COMMENT |
| MEDIUM | src/pages/Export/utils/progress.ts | 68 | // ─── Task status helpers ───────────────────────────────────── | COMMENT |
| MEDIUM | src/pages/Export/utils/progress.ts | 107 | // ─── Background task progress parsing ──────────────────────── | COMMENT |
| MEDIUM | src/pages/Export/utils/progress.ts | 128 | // ─── Task scope helpers ────────────────────────────────────── | COMMENT |
| MEDIUM | src/pages/Export/utils/progress.ts | 142 | // ─── Task open directory resolution ────────────────────────── | COMMENT |
| MEDIUM | src/pages/Export/utils/avatar.ts | 10 | // ─── URL normalization ─────────────────────────────────────── | COMMENT |
| MEDIUM | src/pages/Export/utils/avatar.ts | 27 | // ─── Contact map from caches ───────────────────────────────── | COMMENT |
| MEDIUM | src/pages/Export/utils/avatar.ts | 45 | // ─── Avatar cache compaction ───────────────────────────────── | COMMENT |
| 41 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | electron/main.ts | 61 | COMMENT | |
| LOW | electron/windows/notificationWindow.ts | 701 | // Enforce max-height if needed, or trust renderer | COMMENT |
| LOW | electron/assets/wasm/wasm_video_decode.js | 1 | COMMENT | |
| LOW | electron/assets/wasm/wasm_video_decode.js | 781 | str += String.fromCharCode(codeUnit); | COMMENT |
| LOW | electron/assets/wasm/wasm_video_decode.js | 841 | str += String.fromCharCode(utf32); | COMMENT |
| LOW | electron/assets/wasm/wasm_video_decode.js | 1081 | var al = a & 0xffff; | COMMENT |
| LOW | electron/assets/wasm/wasm_video_decode.js | 2941 | // Track whether the return value was handled by any promise handlers. | COMMENT |
| LOW | electron/assets/wasm/wasm_video_decode.js | 3001 | function craftInvokerFunction(humanName, argTypes, classType, cppInvokerFunc, cppTargetFunc) { | COMMENT |
| LOW | electron/assets/wasm/wasm_video_decode.js | 3681 | } | COMMENT |
| LOW | src/components/LiquidGlass/glassStreamRenderer.ts | 1 | // 视频流模式的 WebGL 玻璃渲染器:替代「<video> 元素 + CSS blur/saturate + SVG 位移滤镜」管线。 | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | electron/services/insightService.ts | 656 | return id && !id.endsWith('@chatroom') && !id.toLowerCase().includes('placeholder') && this.isSessionAllowed(id) | CODE |
| LOW | electron/services/insightService.ts | 1429 | if (sessionId.toLowerCase().includes('placeholder')) continue | CODE |
| LOW | electron/services/insightService.ts | 1494 | if (!sessionId || sessionId.toLowerCase().includes('placeholder')) continue | CODE |
| LOW | electron/services/insightService.ts | 1542 | if (!id || id.toLowerCase().includes('placeholder')) return false | CODE |
| LOW | src/pages/ResourcesPage.tsx | 571 | : <div className="placeholder"><ImageIcon size={30} /></div> | CODE |
| LOW | src/pages/ResourcesPage.tsx | 575 | : <div className="placeholder"> | CODE |
| LOW | src/pages/SettingsPage.tsx | 4556 | if (!id || id.toLowerCase().includes('placeholder')) return false | CODE |
| LOW | src/pages/GroupAnalyticsPage.tsx | 1621 | <div className="placeholder"> | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | electron/windows/notificationWindow.ts | 713 | // For now, let's just set the size as requested. | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| MEDIUM | package-lock.json | 18130 | "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.3.tgz", | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | electron/assets/wasm/wasm_video_decode.js | 9 | // We need to check if Module already exists (e.g. case 3 above). | COMMENT |