chore: clean up documentation and refine onboarding UI

- Remove 25 outdated documentation files from completed refactoring efforts
- Reorder placement options to prioritize inline mode in onboarding
- Fix task item CSS class naming for consistency
- Remove unused content area showcase from fluent components
- Correct sideleaves configuration logic in placement step
- Update onboarding component styles for better visual hierarchy

These changes streamline the codebase by removing completed migration
documentation and improve the onboarding experience with better defaults
and cleaner UI presentation.
This commit is contained in:
Boninall 2025-10-03 22:02:54 +08:00
parent 055ba03772
commit 962623b3e8
31 changed files with 37 additions and 6257 deletions

View file

@ -1,172 +0,0 @@
## 目标
- 在 Task 视图src/pages/TaskView.ts为每个任务的右键菜单新增“删除任务”按钮。
- 当目标任务存在子任务时,弹出二次确认,允许选择“仅删除该任务”或“删除该任务及所有子任务”。
- 完成后数据流Dataflow中缓存/索引即时更新WriteAPI 支持级联删除并发出明确的事件Canvas 任务同样支持。
## 涉及范围
- UITaskView 右键菜单、用户确认弹窗
- 应用层:调用 WriteAPI 的删除接口(新增 deleteChildren 支持)
- Dataflow/事件:明确发出 TASK_DELETED含批量删除信息监听方执行增量删除更新
- Markdown/Canvas 文件写入单行删除与“子树”删除Canvas 文本节点的删除逻辑
- i18n新增菜单与确认文案
## 交互与用户体验
- 右键菜单新增“删除任务”项:
- 无子任务:点击后直接删除,删除成功后在 UI 中移除toast/notice 简短提示
- 有子任务:点击后弹确认对话框,内容包含:
- 选项 A仅删除该任务保留子任务子任务提升为同级或根据设计保留缩进见“边界与策略”
- 选项 B删除该任务及其所有子任务
- 删除完成后,列表立即更新,无需刷新;如失败显示错误提示
建议文案(以 t(key) 引用):
- t("Delete Task")t("Delete")t("Delete task only")t("Delete task and all subtasks")t("This task has N subtasks. How would you like to proceed?")
## 数据流与事件
- WriteAPI 删除成功后显式发出:
- Events.TASK_DELETEDpayload 建议:
- taskId: string
- filePath: string
- deletedTaskIds: string[](若级联删除,包含所有被删节点;仅删除自己则数组长度为 1
- mode: "single" | "subtree"
- 继续保留现有 WRITE_OPERATION_START/COMPLETE 事件(兼容已有 Orchestrator
- Dataflow 监听 TASK_DELETED做增量更新
- 从任务缓存/索引移除对应 taskId 与其 descendants
- 调整同文件中被删行下方任务的行号(如你的索引维护行号)
- 发出 TASK_CACHE_UPDATED 或对应局部更新事件(当前架构已有 TASK_CACHE_UPDATED
说明:现有 Events.ts 已定义 TASK_DELETED 常量,但 WriteAPI.deleteTask 尚未发出;此次补齐并优先级采用 TASK_DELETED 进行 UI 直达更新,减少“全量重扫”开销。
## WriteAPI 方案Markdown + Canvas
在 src/dataflow/api/WriteAPI.ts
1) DeleteTaskArgs 增加 deleteChildren?: boolean
- interface DeleteTaskArgs { taskId: string; deleteChildren?: boolean }
2) deleteTask(args) 行为扩展
- 读取目标任务getTaskById
- 分支:
- Canvas 任务:调用 deleteCanvasTask并新增支持级联删除的实现见下
- Markdown 任务:
- 无级联(默认):按现有逻辑,删除该行
- 级联deleteChildren=true
- 方式 A优先依赖任务索引拿到 descendants 列表,按行号聚合并自底向上批量删除
- 方式 B回退基于 Markdown 缩进扫描“子树”范围(见算法)
- 发出 WRITE_OPERATION_START → vault.modify → WRITE_OPERATION_COMPLETE
- 新增emit(Events.TASK_DELETED, { taskId, filePath, deletedTaskIds, mode })
3) CanvasTaskUpdatersrc/parsers/canvas-task-updater.ts
- 现有 deleteCanvasTask 仅删除单条。扩展:
- 解析文本节点后,按“子树”算法在纯文本中删除对应行和被嵌套的子任务行
- 返回 updatedContent
- WriteAPI.deleteTask 在 Canvas 分支拿到 descendants 时同样构造 deletedTaskIds 并 emit TASK_DELETED
### Markdown “子树”删除算法(回退策略)
- 读取文件并 split 为行数组
- 定位父任务行 parentLine 与其前导空白长度 parentIndent空格数/制表符长度)
- 从 parentLine + 1 开始向下扫描,直到:
- 遇到同级或上级的任务项(识别条件:以空白+[-*+] [ ] 或 [x] 开头,且当前行的前导空白长度 <= parentIndent停止
- 中间所有“子任务行”记录进删除列表(建议仅删除带复选框的“任务行”,不删除纯文本说明行,以避免误删注释;如需同时删除说明行,需与产品确认)
- 删除集合 = {parentLine} {子任务行集合}
- 自底向上 splice 删除,防止行号位移
注意:你们当前已有 insertSubtask 等方法,说明对缩进/父子关系已有约定,上述算法应与解析器保持一致。首选用索引的 descendants 做删除集合,回退才用缩进扫描。
## Task 索引/缓存配合
- 如果当前索引已维护 parent/children 关系,建议新增一个工具:
- getDescendants(taskId): string[],返回所有后代 ID含子、孙…
- Dataflow 监听 TASK_DELETED 后:
- 从 Map/Index 移除 taskId 与这些 descendants
- 如果仅删除父节点且保留子节点,需决定“提升子节点为同级”还是“保留缩进但无父”(推荐与产品/设计确定,见“边界与策略”)
- 对于同文件更靠下的任务,若你们缓存了 line执行行号偏移修正根据删除的行数
## UI 改动src/pages/TaskView.ts
在 handleTaskContextMenu 内新增一项:
- “删除任务”菜单项
- onClick:
- 查索引判断是否存在子任务(优先索引;没有则可只弹一次确认“是否删除”,简单版)
- 无子任务:直接调用 this.plugin.writeApi.deleteTask({ taskId: task.id })
- 有子任务:弹窗:
- 仅删除该任务deleteChildren=false
- 删除任务及所有子任务deleteChildren=true
- 删除成功后:可显式从本地列表移除项(或依赖 TASK_DELETED 事件驱动刷新)
- 失败:显示 Notice 提示
确认弹窗可以使用 ConfirmModal.ts
## Canvas 支持
- CanvasTaskUpdater.deleteTaskFromTextNode 目前只处理单行任务删除,需扩展为支持“子树”:
- 与 Markdown 回退算法类似,在 Canvas 文本节点的 Markdown 中计算子树范围
- 修改 Canvas JSON 后写回
- WriteAPI.deleteTask 对 Canvas 分支传递 deleteChildren 参数,并组装 deletedTaskIds索引可提供 descendants若无则按文本子树扫描推导
## i18n
新增 keys示例
- "Delete Task", "Delete", "Delete task only", "Delete task and all subtasks", "This task has {n} subtasks. How would you like to proceed?", "Deleted", "Failed to delete task"
## 边界与策略待确认
- 仅删除父节点时子节点的处理策略:
- 选项 1子任务整体提升为父节点的同级需要在 WriteAPI 中调整这些行的缩进,较复杂)
- 选项 2保留原缩进但无父可能导致“悬空子任务”
- 选项 3UI 层不提供“仅删除父节点”,统一为“删除父及所有子节点”以避免歧义(最简单)
- 是否删除带说明的非任务行(不带复选框的列表项/文本):
- 默认只删除“任务行”(有复选框)
- 若确需一并删除说明行,需明确说明行的识别规则(例如直到下一个同级任务或空行)
- FileSource 任务metadata.source === "file-source")的删除语义:
- 若支持删除,是否需要发出 FILE_TASK_REMOVED 之类事件(项目中已有 FILE_TASK_REMOVED 常量)
- 撤销/回滚:依赖 Obsidian 本身文件级撤销还是需要插件内提供 Undo建议先依赖 Obsidian
## 验收标准
- 右键菜单出现“删除任务”,符合 i18n
- 无子任务点击后文件内容更新、缓存更新、UI 移除该任务
- 有子任务:
- 仅删除父:父行被删、子任务处理符合策略(见上)
- 删除父及所有子对应行全部删除deletedTaskIds 包含所有被删任务
- Markdown/Canvas 两种来源都支持
- 事件序列正确:
- WRITE_OPERATION_START → 文件修改 → WRITE_OPERATION_COMPLETE
- 以及 TASK_DELETED包含 deletedTaskIds
- 删除后不出现“幽灵任务”(索引和 UI 无残留)
- 无控制台报错,异常可见错误提示
## 分工与实施清单(按文件)
1) src/pages/TaskView.ts
- 在 handleTaskContextMenu 添加“删除任务”菜单项
- 新增 confirmAndDeleteTask(task)
- 读取 descendants 数(索引或简单判断)
- 显示确认对话框(存在子任务时)
- 调用 this.plugin.writeApi.deleteTask({ taskId: task.id, deleteChildren })
- 成功后依赖 TASK_DELETED 刷新或局部移除
2) src/dataflow/api/WriteAPI.ts
- 扩展 DeleteTaskArgsdeleteChildren?: boolean
- deleteTask
- 读取任务,分 Canvas/Markdown
- Markdown
- deleteChildren=true 时按索引 descendants 或缩进扫描删除集合;自底向上删除
- Canvas调用扩展后的 deleteCanvasTask支持子树
- 发出 WRITE_OPERATION_START/COMPLETE 和 TASK_DELETED带 deletedTaskIds
- 如需,针对 file-source 任务发 FILE_TASK_REMOVED
3) src/parsers/canvas-task-updater.ts
- 扩展 deleteCanvasTask 支持 deleteChildren 或新增 deleteCanvasTaskSubtree
- 在文本节点里按缩进/层级识别子树并删除
4) Dataflow 监听与缓存
- 监听 TASK_DELETED移除缓存中任务及 descendants修正行号偏移最后 emit TASK_CACHE_UPDATED
- 若当前已有 Orchestrator 依赖 WRITE_OPERATION_COMPLETE 触发全量更新,可在过渡期两者都保留
5) i18n
- 增加相关键(中英)

View file

@ -1,220 +0,0 @@
# Canvas Task API Guide
## Overview
The WriteAPI now provides comprehensive support for Canvas tasks, allowing you to create, update, delete, and manipulate tasks within Obsidian Canvas files (.canvas).
## Architecture
Canvas task support is implemented through:
- **CanvasTaskUpdater**: Core utility class handling Canvas-specific operations
- **WriteAPI Integration**: Automatic detection and routing of Canvas tasks
- **Event System**: Proper event emission for dataflow updates
## API Methods
### Automatic Detection
The following methods automatically detect Canvas tasks and route them appropriately:
```typescript
// These methods work for both regular and Canvas tasks
writeAPI.updateTask(args)
writeAPI.deleteTask(args)
writeAPI.updateTaskStatus(args)
```
### Canvas-Specific Methods
#### Update Canvas Task
```typescript
await writeAPI.updateCanvasTask({
taskId: "task-123",
updates: {
content: "Updated task content",
completed: true,
metadata: {
priority: 3,
dueDate: new Date().getTime()
}
}
})
```
#### Delete Canvas Task
```typescript
await writeAPI.deleteCanvasTask({
taskId: "task-123"
})
```
#### Move Canvas Task
```typescript
await writeAPI.moveCanvasTask({
taskId: "task-123",
targetFilePath: "another-canvas.canvas",
targetNodeId: "node-456", // Optional: specific node
targetSection: "## Tasks" // Optional: section within node
})
```
#### Duplicate Canvas Task
```typescript
await writeAPI.duplicateCanvasTask({
taskId: "task-123",
targetFilePath: "target.canvas", // Optional: defaults to same file
targetNodeId: "node-789", // Optional: specific node
targetSection: "## Duplicates", // Optional: section within node
preserveMetadata: false // Optional: whether to keep completion data
})
```
#### Add Task to Canvas Node
```typescript
await writeAPI.addTaskToCanvasNode({
filePath: "my-canvas.canvas",
content: "New task content",
targetNodeId: "node-123", // Optional: creates new node if not specified
targetSection: "## New Tasks", // Optional: section within node
completed: false,
metadata: {
project: "MyProject",
priority: 2,
tags: ["important", "review"]
}
})
```
### Utility Methods
#### Check if Task is Canvas Task
```typescript
const isCanvas = writeAPI.isCanvasTask(task);
```
#### Get Canvas Task Updater Instance
```typescript
const canvasUpdater = writeAPI.getCanvasTaskUpdater();
// Use for advanced Canvas operations
```
## Task Detection
Canvas tasks are identified by:
- File extension: `.canvas`
- Metadata property: `sourceType === "canvas"`
- Canvas node ID: `metadata.canvasNodeId`
## Event Flow
When Canvas tasks are updated:
1. WriteAPI detects Canvas task type
2. Routes to CanvasTaskUpdater
3. Updates Canvas JSON structure
4. Emits `WRITE_OPERATION_START` event
5. Writes to vault
6. Emits `TASK_UPDATED` event for dataflow
7. Emits `WRITE_OPERATION_COMPLETE` event
## Error Handling
All Canvas operations return a result object:
```typescript
interface Result {
success: boolean;
error?: string;
task?: Task; // For update operations
updatedContent?: string; // For debugging
}
```
Example error handling:
```typescript
const result = await writeAPI.updateCanvasTask({
taskId: "task-123",
updates: { completed: true }
});
if (!result.success) {
console.error("Failed to update Canvas task:", result.error);
// Handle error appropriately
}
```
## Canvas Task Metadata
Canvas tasks include special metadata:
```typescript
interface CanvasTaskMetadata extends StandardTaskMetadata {
sourceType: "canvas";
canvasNodeId: string; // ID of the Canvas text node
canvasNodeX?: number; // Node position
canvasNodeY?: number;
canvasNodeWidth?: number; // Node dimensions
canvasNodeHeight?: number;
}
```
## Implementation Details
### Task Matching
Canvas tasks are matched within nodes using:
1. Original markdown content
2. Core content extraction (removing metadata)
3. Line-by-line comparison
### Metadata Preservation
When updating Canvas tasks, the system:
- Preserves task indentation
- Maintains metadata format preferences (emoji vs dataview)
- Handles project/context tags correctly
- Updates completion dates automatically
### Node Management
- New nodes are automatically positioned to avoid overlaps
- Empty nodes are handled gracefully
- Multi-task nodes are supported
## Best Practices
1. **Always check task type** before performing Canvas-specific operations
2. **Use automatic detection** when possible (updateTask, deleteTask, updateTaskStatus)
3. **Handle errors gracefully** - Canvas operations can fail due to JSON parsing or node issues
4. **Emit proper events** to ensure dataflow stays synchronized
5. **Preserve metadata format** according to user preferences
## Migration from TaskManager
If migrating from the old TaskManager system:
| TaskManager Method | WriteAPI Equivalent |
|-------------------|-------------------|
| `canvasTaskUpdater.updateCanvasTask()` | `writeAPI.updateCanvasTask()` |
| `canvasTaskUpdater.deleteCanvasTask()` | `writeAPI.deleteCanvasTask()` |
| `canvasTaskUpdater.moveCanvasTask()` | `writeAPI.moveCanvasTask()` |
| `canvasTaskUpdater.duplicateCanvasTask()` | `writeAPI.duplicateCanvasTask()` |
| Direct CanvasTaskUpdater usage | `writeAPI.getCanvasTaskUpdater()` |
## Testing
Canvas task operations are tested in:
- `/src/__tests__/CanvasTaskUpdater.test.ts`
- `/src/__tests__/CanvasIntegration.test.ts`
- `/src/__tests__/CanvasTaskMatching.integration.test.ts`
## Limitations
- Canvas files must be valid JSON
- Node IDs must be unique within a Canvas
- Task line matching may fail if content is heavily modified outside the system
- Bulk operations on Canvas tasks may be slower than regular tasks due to JSON parsing
## Future Enhancements
Potential improvements:
- Batch Canvas operations for better performance
- Canvas-specific query methods in QueryAPI
- Visual task positioning helpers
- Canvas template support

View file

@ -1,568 +0,0 @@
# src/components 目录重构与迁移方案(最终执行版)
本方案用于将当前过于分散且命名不一致的前端 UI 组件进行系统性重构,目标是:
- 建立“共享 UI 库ui/+ 业务功能模块features/)”的稳定结构
- 统一命名规则,便于检索、复用与增量演进
- 分阶段稳妥迁移,保证任意阶段都可编译运行
不在本次范围API/数据流重构、视觉设计改造、依赖升级。
---
## 1. 目标目录结构(提案)
- src/components/
- ui/(共享可复用的通用组件与行为)
- modals/
- popovers/
- menus/
- inputs/
- date-picker/
- renderers/
- feedback/
- behavior/
- widgets/
- suggest/
- tree/
- features/(按业务域分组)
- calendar/algorithm、rendering、views
- gantt/
- kanban/
- quadrant/
- habit/
- onboarding/
- quick-capture/
- workflow/
- settings/
- tabs/
- components/
- core/
- task/
- edit/
- view/
- filter/
- timeline-sidebar/
- read-mode/
- table/
- on-completion/
说明:每个二级/三级目录都添加 index.ts 作为 barrel 出口(统一导出)。
---
## 2. 命名规则
- 目录kebab-case如 on-completion、habit-card
- 文件:导出“类/组件”的文件使用 PascalCaseConfirmModal.ts、TaskList.ts
- 后缀统一Modal/Popover/Dialog/View/Component/Renderer/Manager/Service/Widget/Suggest/Tab
- 设置页签统一为 XxxxSettingsTab.ts注意复数 Settings
- 文件名与主要导出保持一致
---
## 3. 分阶段迁移计划
建议每阶段单独提交一次,采用 git mv 保留历史;阶段结束进行编译与关键 UI 冒烟检查。
### Phase 0准备
- 决定目录命名统一为 kebab-case
- (可选)是否引入路径别名,如:
- @ui/* -> src/components/ui/*
- @features/* -> src/components/features/*
### Phase 1抽取共享 UIui/
- 新建src/components/ui/{modals,popovers,menus,inputs,date-picker,renderers,feedback,behavior,widgets,suggest,tree}
- 移动与重命名(示例):
- AutoComplete.ts → ui/inputs/AutoComplete.ts
- ConfirmModal.ts → ui/modals/ConfirmModal.ts
- IframeModal.ts → ui/modals/IframeModal.ts
- IconMenu.ts → ui/menus/IconMenu.ts
- MarkdownRenderer.ts → ui/renderers/MarkdownRenderer.ts
- StatusComponent.ts → ui/feedback/StatusIndicator.ts建议改名更贴近语义
- DragManager.ts → ui/behavior/DragManager.ts
- ViewComponentManager.ts → ui/behavior/ViewComponentManager.ts
- date-picker/ → ui/date-picker/
- common/TreeComponent.ts → ui/tree/TreeComponent.ts
- common/TreeItemRenderer.ts → ui/tree/TreeItemRenderer.ts
- suggest/ → ui/suggest/
- 为 ui/ 及其子目录添加 index.ts 出口
- 过渡策略:
- 方案 A一次性修正所有 import 到新路径
- 方案 B原位置保留同名文件仅 re-export 新路径(逐步替换后再删除)
### Phase 2合并业务功能模块features/
- 新建src/components/features/
- 迁移(示例):
- calendar/ → features/calendar/algorithm.ts、rendering/、views/ 原样保留)
- gantt/ → features/gantt/
- kanban/ → features/kanban/
- quadrant/ → features/quadrant/
- onboarding/ → features/onboarding/
- timeline-sidebar/ → features/timeline-sidebar/
- readModeProgressbarWidget.ts → features/read-mode/ReadModeProgressBarWidget.ts规范大小写与单词分割
- readModeTextMark.ts → features/read-mode/ReadModeTextMark.ts
- habit/ → features/habit/
- habit/habitcard/ → features/habit/components/habit-card/
- HabitEditDialog.ts → features/habit/components/HabitEditDialog.ts
- RewardModal.ts → (二选一)
- A. features/habit/modals/RewardModal.ts
- B. features/reward/modals/RewardModal.ts与 RewardSettingsTab 形成一组)
- quick-capture/
- MinimalQuickCaptureModal.ts → features/quick-capture/modals/MinimalQuickCaptureModal.ts
- QuickCaptureModal.ts → features/quick-capture/modals/QuickCaptureModal.ts
- MinimalQuickCaptureSuggest.ts → features/quick-capture/suggest/MinimalQuickCaptureSuggest.ts或 MinimalQuickCaptureSuggester.ts
- workflow/
- QuickWorkflowModal.ts → features/workflow/modals/QuickWorkflowModal.ts
- StageEditModal.ts → features/workflow/modals/StageEditModal.ts
- WorkflowDefinitionModal.ts → features/workflow/modals/WorkflowDefinitionModal.ts
- WorkflowProgressIndicator.ts → (二选一)
- A. features/workflow/widgets/WorkflowProgressIndicator.ts
- B. ui/widgets/WorkflowProgressIndicator.ts视作通用
- task/
- task-edit/ → features/task/edit/
- task-view/ → features/task/view/
- task-filter/ → features/task/filter/
- inview-filter/ → features/task/filter/in-view/(或保留为 features/in-view-filter/
- table/ → features/table/
- onCompletion/ → features/on-completion/
- 为 features/* 添加 index.ts 出口
### Phase 3标准化设置settings/
- settings/ → features/settings/
- tabs/:将所有 *SettingsTab.ts 移至此处并统一命名(保持 *SettingsTab
- TaskTimerSettingTab.ts → TaskTimerSettingsTab.ts修正为复数 Settings
- components/
- FileSourceSettings.ts → components/FileSourceSettingsSection.ts增加 Section 后缀更贴合)
- SettingsSearchComponent.ts → components/SettingsSearchComponent.ts
- core/
- SettingsIndexer.ts → core/SettingsIndexer.ts
- 更新 features/settings/index.ts统一导出 tabs/components/core
### Phase 4统一导入与过渡清理
- 在 ui/ 与各 features/* 目录添加 index.tsbarrel 模式)
- 采用路径别名或相对路径统一 import
- import { ConfirmModal } from '@ui/modals'
- import { TaskList } from '@features/task/view'
- 若采用过渡 re-export
- 原路径文件仅保留export * from '新路径'
- 扫描替换存量 import 后,最终删除过渡文件
### Phase 5收尾
- 删除所有过渡 re-export 文件
- 搜索并清理旧路径残留引用
- 全量构建 + 核心 UI 冒烟
---
## 4. 详细映射清单(代表性)
- 顶层散落组件 → ui/ 或特性模块
- AutoComplete.ts → ui/inputs/AutoComplete.ts
- ConfirmModal.ts → ui/modals/ConfirmModal.ts
- IframeModal.ts → ui/modals/IframeModal.ts
- IconMenu.ts → ui/menus/IconMenu.ts
- MarkdownRenderer.ts → ui/renderers/MarkdownRenderer.ts
- StatusComponent.ts → ui/feedback/StatusIndicator.ts
- DragManager.ts → ui/behavior/DragManager.ts
- ViewComponentManager.ts → ui/behavior/ViewComponentManager.ts
- ViewConfigModal.ts → features/task/view/modals/ViewConfigModal.ts
- QuickWorkflowModal.ts → features/workflow/modals/QuickWorkflowModal.ts
- WorkflowProgressIndicator.ts → features/workflow/widgets/WorkflowProgressIndicator.ts或 ui/widgets/…)
- readModeProgressbarWidget.ts → features/read-mode/ReadModeProgressBarWidget.ts
- readModeTextMark.ts → features/read-mode/ReadModeTextMark.ts
- 目录整体迁移
- calendar → features/calendaralgorithm.ts、rendering/、views/
- date-picker → ui/date-picker
- suggest → ui/suggest
- common/Tree* → ui/tree
- gantt/、kanban/、quadrant/、onboarding/ → 对应 features/*
- task-edit/、task-filter/、task-view/ → features/task 下分 edit/filter/view
- inview-filter/ → features/task/filter/in-view或 features/in-view-filter
- onboarding/、timeline-sidebar/、table/、onCompletion/ → 对应 features/*
- habit/ + habitcard/ + HabitEditDialog.ts + RewardModal.ts → 归入 features/habit或 RewardModal 放 features/reward
- settings 专项
- 全部 *SettingsTab.ts → features/settings/tabs/
- FileSourceSettings.ts → features/settings/components/FileSourceSettingsSection.ts
- SettingsIndexer.ts → features/settings/core/SettingsIndexer.ts
- SettingsSearchComponent.ts → features/settings/components/SettingsSearchComponent.ts
---
## 5. 过渡 re-export 示例(可选策略 B
- 原文件 src/components/ConfirmModal.ts仅保留
```ts
export * from './ui/modals/ConfirmModal'
```
- 原目录 src/components/suggest/index.ts仅保留
```ts
export * from '../ui/suggest'
```
后续逐步把业务代码的 import 改为新路径,再删除这些过渡文件。
---
## 6. (可选)路径别名建议
- 若采用 tsconfig 路径:
```json
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@ui/*": ["src/components/ui/*"],
"@features/*": ["src/components/features/*"]
}
}
}
```
- import 示例:
```ts
import { ConfirmModal } from '@ui/modals'
import { TaskList } from '@features/task/view'
```
---
## 7. 验证清单
- 每阶段完成后:
- 构建通过,无 TS 路径错误
- 搜索旧路径是否仍有引用
- 核心 UI如任务视图、设置页、日历打开不报错
- 最终阶段:清除过渡 re-export所有 import 指向新结构
---
## 8. 未决项(待确认)
- inview-filter
- A. 收敛到 features/task/filter/in-view/
- B. 独立 features/in-view-filter/
- RewardModal
- A. 放 features/habit/
- B. 放 features/reward/(与 RewardSettingsTab 配对)
- WorkflowProgressIndicator
- A. 放 features/workflow/widgets/
- B. 放 ui/widgets/(若确认为通用)
- 是否启用 @ui / @features 路径别名
---
## 9. 执行建议
- 使用 git mv按阶段提交commit message 清晰指明范围
- 优先迁移“共享 UI”减少后续重复
- 大范围修改 import 前,优先采用过渡 re-export降低一次性影响
- 阶段结束进行构建与冒烟,确保安全可回滚
---
## 10. 详细执行步骤(可直接复制运行)
以下步骤假设你在仓库根目录执行,使用 git mv 确保历史保留。若路径别名未启用,请保持相对路径;若启用,请在 Phase 4 统一替换 import。
### Phase 1抽取共享 UIui/
1) 创建目录
```bash
mkdir -p src/components/ui/{modals,popovers,menus,inputs,date-picker,renderers,feedback,behavior,widgets,suggest,tree}
```
2) 移动文件(命令清单)
```bash
# 顶层散落文件 → ui
git mv src/components/AutoComplete.ts src/components/ui/inputs/AutoComplete.ts
git mv src/components/ConfirmModal.ts src/components/ui/modals/ConfirmModal.ts
git mv src/components/IframeModal.ts src/components/ui/modals/IframeModal.ts
git mv src/components/IconMenu.ts src/components/ui/menus/IconMenu.ts
git mv src/components/MarkdownRenderer.ts src/components/ui/renderers/MarkdownRenderer.ts
git mv src/components/DragManager.ts src/components/ui/behavior/DragManager.ts
git mv src/components/ViewComponentManager.ts src/components/ui/behavior/ViewComponentManager.ts
# 状态指示重命名(建议)
# 如需保留原名,可跳过,后续统一改名
# 方案 A直接重命名
git mv src/components/StatusComponent.ts src/components/ui/feedback/StatusIndicator.ts
# Date Picker 整体
git mv src/components/date-picker src/components/ui/date-picker
# Tree 相关
mkdir -p src/components/ui/tree
git mv src/components/common/TreeComponent.ts src/components/ui/tree/TreeComponent.ts
git mv src/components/common/TreeItemRenderer.ts src/components/ui/tree/TreeItemRenderer.ts
# Suggest 整体
git mv src/components/suggest src/components/ui/suggest
```
3) (可选)在旧位置添加过渡 re-export若暂不批量改 import
```bash
# 示例:创建 src/components/ConfirmModal.ts 并仅导出新路径(如果前一步已移动,可新建同名文件)
# echo "export * from './ui/modals/ConfirmModal'" > src/components/ConfirmModal.ts
# 其他类似文件按需添加
```
4) 添加 barrel 出口index.ts
```bash
# 示例:为 ui/ 及子目录创建 index.ts根据实际导出补充
# echo "export * from './modals'" > src/components/ui/index.ts
# echo "export * from './ConfirmModal'" > src/components/ui/modals/index.ts
```
提交:
```bash
git add -A
git commit -m "refactor(components): extract shared UI into src/components/ui/* (phase 1)"
```
---
### Phase 2合并业务功能模块features/
1) 创建目录
```bash
mkdir -p src/components/features/{calendar,gantt,kanban,quadrant,habit,onboarding,quick-capture,workflow,settings,task/{edit,view,filter},timeline-sidebar,read-mode,table,on-completion}
```
2) 迁移与重命名(命令清单)
```bash
# Calendar
git mv src/components/calendar src/components/features/calendar
# Gantt / Kanban / Quadrant / Onboarding
git mv src/components/gantt src/components/features/gantt
git mv src/components/kanban src/components/features/kanban
git mv src/components/quadrant src/components/features/quadrant
git mv src/components/onboarding src/components/features/onboarding
# Timeline Sidebar
git mv src/components/timeline-sidebar src/components/features/timeline-sidebar
# Read Mode并统一大小写
mkdir -p src/components/features/read-mode
git mv src/components/readModeProgressbarWidget.ts src/components/features/read-mode/ReadModeProgressBarWidget.ts
git mv src/components/readModeTextMark.ts src/components/features/read-mode/ReadModeTextMark.ts
# Habit
git mv src/components/habit src/components/features/habit
mkdir -p src/components/features/habit/components/habit-card
git mv src/components/habit/habitcard src/components/features/habit/components/habit-card
git mv src/components/HabitEditDialog.ts src/components/features/habit/components/HabitEditDialog.ts
# Reward依你选择若归入 habit 则移动到 habit 下)
# git mv src/components/RewardModal.ts src/components/features/habit/modals/RewardModal.ts
# 或:
# mkdir -p src/components/features/reward/modals
# git mv src/components/RewardModal.ts src/components/features/reward/modals/RewardModal.ts
# Quick Capture
mkdir -p src/components/features/quick-capture/{modals,suggest}
git mv src/components/MinimalQuickCaptureModal.ts src/components/features/quick-capture/modals/MinimalQuickCaptureModal.ts
git mv src/components/QuickCaptureModal.ts src/components/features/quick-capture/modals/QuickCaptureModal.ts
git mv src/components/MinimalQuickCaptureSuggest.ts src/components/features/quick-capture/suggest/MinimalQuickCaptureSuggest.ts
# Workflow
mkdir -p src/components/features/workflow/{modals,widgets}
git mv src/components/QuickWorkflowModal.ts src/components/features/workflow/modals/QuickWorkflowModal.ts
git mv src/components/StageEditModal.ts src/components/features/workflow/modals/StageEditModal.ts
git mv src/components/WorkflowDefinitionModal.ts src/components/features/workflow/modals/WorkflowDefinitionModal.ts
git mv src/components/WorkflowProgressIndicator.ts src/components/features/workflow/widgets/WorkflowProgressIndicator.ts
# Taskedit/view/filter
mkdir -p src/components/features/task/{edit,view,filter}
git mv src/components/task-edit src/components/features/task/edit
git mv src/components/task-view src/components/features/task/view
git mv src/components/task-filter src/components/features/task/filter
# In-view Filter两种放置方式其一
# 方案 A
mkdir -p src/components/features/task/filter/in-view
git mv src/components/inview-filter src/components/features/task/filter/in-view
# 方案 B
# mkdir -p src/components/features/in-view-filter
# git mv src/components/inview-filter src/components/features/in-view-filter
# Table
git mv src/components/table src/components/features/table
# On Completion目录名统一为 kebab-case
git mv src/components/onCompletion src/components/features/on-completion
```
3) 为各 features/* 添加 index.ts按需并提交
```bash
git add -A
git commit -m "refactor(components): consolidate feature modules under src/components/features/* (phase 2)"
```
---
### Phase 3标准化设置settings/
```bash
# 将 settings 迁移到 features/settings
mkdir -p src/components/features/settings/{tabs,components,core}
git mv src/components/settings/AboutSettingsTab.ts src/components/features/settings/tabs/AboutSettingsTab.ts
git mv src/components/settings/BasesSettingsTab.ts src/components/features/settings/tabs/BasesSettingsTab.ts
git mv src/components/settings/BetaTestSettingsTab.ts src/components/features/settings/tabs/BetaTestSettingsTab.ts
git mv src/components/settings/DatePrioritySettingsTab.ts src/components/features/settings/tabs/DatePrioritySettingsTab.ts
git mv src/components/settings/FileFilterSettingsTab.ts src/components/features/settings/tabs/FileFilterSettingsTab.ts
git mv src/components/settings/HabitSettingsTab.ts src/components/features/settings/tabs/HabitSettingsTab.ts
git mv src/components/settings/IcsSettingsTab.ts src/components/features/settings/tabs/IcsSettingsTab.ts
git mv src/components/settings/IndexSettingsTab.ts src/components/features/settings/tabs/IndexSettingsTab.ts
git mv src/components/settings/McpIntegrationSettingsTab.ts src/components/features/settings/tabs/McpIntegrationSettingsTab.ts
git mv src/components/settings/ProgressSettingsTab.ts src/components/features/settings/tabs/ProgressSettingsTab.ts
git mv src/components/settings/ProjectSettingsTab.ts src/components/features/settings/tabs/ProjectSettingsTab.ts
git mv src/components/settings/QuickCaptureSettingsTab.ts src/components/features/settings/tabs/QuickCaptureSettingsTab.ts
git mv src/components/settings/RewardSettingsTab.ts src/components/features/settings/tabs/RewardSettingsTab.ts
git mv src/components/settings/TaskFilterSettingsTab.ts src/components/features/settings/tabs/TaskFilterSettingsTab.ts
git mv src/components/settings/TaskHandlerSettingsTab.ts src/components/features/settings/tabs/TaskHandlerSettingsTab.ts
git mv src/components/settings/TaskStatusSettingsTab.ts src/components/features/settings/tabs/TaskStatusSettingsTab.ts
git mv src/components/settings/TimeParsingSettingsTab.ts src/components/features/settings/tabs/TimeParsingSettingsTab.ts
git mv src/components/settings/TimelineSidebarSettingsTab.ts src/components/features/settings/tabs/TimelineSidebarSettingsTab.ts
git mv src/components/settings/ViewSettingsTab.ts src/components/features/settings/tabs/ViewSettingsTab.ts
git mv src/components/settings/WorkflowSettingsTab.ts src/components/features/settings/tabs/WorkflowSettingsTab.ts
# 修正单复数TaskTimerSettingTab.ts -> TaskTimerSettingsTab.ts
git mv src/components/settings/TaskTimerSettingTab.ts src/components/features/settings/tabs/TaskTimerSettingsTab.ts
# 其他设置相关组件
git mv src/components/settings/FileSourceSettings.ts src/components/features/settings/components/FileSourceSettingsSection.ts
git mv src/components/settings/SettingsIndexer.ts src/components/features/settings/core/SettingsIndexer.ts
git mv src/components/settings/SettingsSearchComponent.ts src/components/features/settings/components/SettingsSearchComponent.ts
# index.ts 移至新位置(如需要保留,可改为 re-export
# git mv src/components/settings/index.ts src/components/features/settings/index.ts
```
提交:
```bash
git add -A
git commit -m "refactor(settings): standardize settings under features/settings with tabs/components/core (phase 3)"
```
---
### Phase 4barrels、import 与过渡清理
1) 添加/完善 index.ts示例
```bash
# ui/index.ts → 按子目录导出
# features/*/index.ts → 导出每个模块公共 API
```
2) (可选)启用路径别名并批量替换 import示例
```bash
# tsconfig.json 中添加 paths见上文第 6 节)
# 然后批量替换 import
# from 'src/components/ui/...' → from '@ui/...'
# from 'src/components/features/...' → from '@features/...'
```
3) 若采用过渡 re-export逐步替换后删除旧文件
提交:
```bash
git add -A
git commit -m "refactor(components): add barrels and update imports; remove transitional re-exports (phase 4)"
```
---
### Phase 5收尾
```bash
# 搜索旧路径残留
rg -n "src/components/(?!ui|features)/" src | cat
# 最终清理与提交
git add -A
git commit -m "refactor(components): finalize directory migration and clean up (phase 5)"
```
> 注:若未安装 ripgrep(rg),可使用 grep -R -n 进行搜索。

View file

@ -1,380 +0,0 @@
# Dataflow Architecture Documentation
## Overview
The Dataflow architecture is a modern, modular task management system that replaces the legacy TaskManager-based approach. It provides better separation of concerns, improved performance, and a more maintainable codebase. The architecture now supports both file-based tasks and external data sources (like ICS calendar events) through a unified event-driven pipeline.
## Architecture Components
### Core Directory Structure
```
src/dataflow/
├── api/ # Public API interfaces
│ └── QueryAPI.ts # Unified query interface for all views
├── augment/ # Task enhancement logic
│ └── Augmentor.ts # Centralized task augmentation
├── core/ # Core parsing logic
│ ├── CanvasParser.ts
│ ├── ConfigurableTaskParser.ts
│ └── CoreTaskParser.ts
├── events/ # Event system
│ └── Events.ts # Centralized event management
├── indexer/ # Task indexing
│ └── Repository.ts # Task repository with indexing & ICS integration
├── parsers/ # High-level parsing entries
│ ├── CanvasEntry.ts
│ ├── FileMetaEntry.ts
│ └── MarkdownEntry.ts
├── persistence/ # Data persistence
│ └── Storage.ts # Unified storage layer (tasks + ICS events)
├── project/ # Project management
│ └── Resolver.ts # Project resolution logic
├── sources/ # Data sources
│ ├── ObsidianSource.ts # File system monitoring
│ ├── IcsSource.ts # ICS calendar events source
│ ├── FileSource.ts # File-based task recognition system
│ └── FileSourceConfig.ts # FileSource configuration management
├── workers/ # Background processing
│ ├── ProjectData.worker.ts
│ ├── ProjectDataWorkerManager.ts
│ ├── TaskIndex.worker.ts
│ ├── TaskWorkerManager.ts
│ └── WorkerOrchestrator.ts
├── Orchestrator.ts # Main coordination component
├── createDataflow.ts # Factory function
└── index.ts # Module exports
```
## Key Principles
### 1. Separation of Concerns
- **Parsers**: Only extract raw task data, no enhancement
- **Augmentor**: All task enhancement logic in one place
- **Repository**: Centralized indexing, querying, and data merging
- **Storage**: Unified persistence layer for all data types
- **Sources**: Independent data providers (files, ICS, etc.)
### 2. Event-Driven Architecture
- Centralized event system through `Events.ts`
- Consistent event naming and payload structure
- Decoupled components communicate via events
- Event sequence tracking prevents circular updates
### 3. Production Ready
- Core setting (`dataflowEnabled`) enabled by default
- Full backward compatibility maintained
- Complete feature parity achieved
### 4. Unified Data Pipeline
- All data sources flow through the same architecture
- File-based tasks and external events (ICS) are merged seamlessly
- Consistent querying interface regardless of data source
## Component Responsibilities
### Orchestrator
- Coordinates all dataflow components
- Manages initialization and lifecycle
- Routes events between components
- Handles multiple data sources (ObsidianSource, IcsSource)
- Implements sequence-based loop prevention
### Data Sources
#### ObsidianSource
- Monitors file system changes
- Emits FILE_UPDATED events
- Handles Markdown and Canvas files
- Tracks file modifications, creations, deletions
#### IcsSource (New)
- Integrates external calendar events
- Emits ICS_EVENTS_UPDATED events
- Syncs with IcsManager
- Converts calendar events to task format
#### FileSource (Integrated - Bug Fixed)
- Recognizes files as tasks based on configurable strategies
- Supports metadata, tag, template, and path-based recognition
- Emits file-task-updated events for file-level tasks
- Manages file task caching and deduplication
- Integrates with status mapping for flexible task states
- **Status**: Fully integrated with configuration path fix applied
### QueryAPI
- Public interface for all data queries
- Abstracts internal repository complexity
- Provides consistent API for views
- Returns merged data from all sources
### Repository
- Maintains task index for file-based tasks
- Stores ICS events separately
- Merges data from multiple sources in queries
- Handles snapshot persistence
- Emits update events with source tracking
### Augmentor
- Applies task enhancement strategies
- Handles inheritance and deduplication
- Manages project references
### Storage
- Wraps LocalStorageCache
- Manages versioning and invalidation
- Provides namespace isolation
- Persists:
- Raw tasks (file-based)
- Augmented tasks
- Project data
- ICS events
- Consolidated index
## Event Flow & Loop Prevention
### Event Types
```typescript
Events = {
CACHE_READY: "task-genius:cache-ready",
TASK_CACHE_UPDATED: "task-genius:task-cache-updated",
FILE_UPDATED: "task-genius:file-updated",
ICS_EVENTS_UPDATED: "task-genius:ics-events-updated",
FILE_TASK_UPDATED: "task-genius:file-task-updated", // FileSource events
FILE_TASK_REMOVED: "task-genius:file-task-removed", // FileSource removal
// ... other events
}
```
### Loop Prevention Mechanism
1. **Source Sequence Tracking**: Each operation generates a unique sequence number
2. **Event Tagging**: Events include `sourceSeq` to identify their origin
3. **Filtering**: Components ignore events they originated
4. **Clean Event Flow**: Prevents infinite update loops
### Typical Event Flow
```
1. File Change → ObsidianSource → FILE_UPDATED event
2. Orchestrator processes → Repository.updateFile()
3. Repository → TASK_CACHE_UPDATED event (with sourceSeq)
4. Views update → UI refreshes
OR
1. Calendar Sync → IcsSource → ICS_EVENTS_UPDATED event
2. Orchestrator processes → Repository.updateIcsEvents()
3. Repository → TASK_CACHE_UPDATED event (with sourceSeq)
4. Views update → UI refreshes
OR (pending integration)
1. File Recognition → FileSource → FILE_TASK_UPDATED event
2. Orchestrator processes → Repository.updateFileTasks()
3. Repository → TASK_CACHE_UPDATED event (with sourceSeq)
4. Views update → UI refreshes
```
## Data Flow
### Initialization
1. **Repository.initialize()**: Load consolidated index and ICS events
2. **ObsidianSource.initialize()**: Start file monitoring
3. **IcsSource.initialize()**: Start calendar sync
4. **FileSource.initialize()** (pending): Start file recognition
5. **Initial Scan**: Process all files if no cache exists
### Runtime Updates
1. **File Changes**: ObsidianSource → Orchestrator → Repository → Views
2. **ICS Updates**: IcsSource → Orchestrator → Repository → Views
3. **File Task Updates** (pending): FileSource → Orchestrator → Repository → Views
4. **Manual Refresh**: Views → QueryAPI → Repository (cached data)
### Data Persistence
- **Continuous**: Augmented tasks stored on each update
- **ICS Events**: Persisted separately for fast recovery
- **File Tasks** (pending): Cached with recognition metadata
- **Consolidated Index**: Saved periodically and on shutdown
- **Version Control**: Schema versioning for migration support
## Migration Status
### Completed Phases
- ✅ Phase A: Parallel initialization with feature flag
- ✅ Phase B: View migration to QueryAPI
- ✅ Phase C: Parser and enhancement separation
- ✅ Phase D: Unified persistence layer
- ✅ Phase E: Default enablement and cleanup
- ✅ Phase F: ICS integration through dataflow
### Current Architecture State
- **Default Mode**: Dataflow is now the default (enabled by default)
- **Legacy Support**: TaskManager fully replaced by Dataflow
- **External Data**: ICS events integrated seamlessly
- **File Recognition**: FileSource fully integrated and operational
- **Performance**: Optimized with caching and workers
- **Stability**: Loop prevention and error handling
## Usage
### Enabling Dataflow
```typescript
// In settings (now default)
dataflowEnabled: true
```
### Querying Tasks
```typescript
// Using QueryAPI - returns both file tasks and ICS events
const allTasks = await queryAPI.getAllTasks();
const projectTasks = await queryAPI.getTasksByProject("MyProject");
const taggedTasks = await queryAPI.getTasksByTags(["important"]);
```
### Event Subscription
```typescript
// Subscribe to all task updates (files + ICS)
Events.on(Events.TASK_CACHE_UPDATED, (payload) => {
const { changedFiles, stats } = payload;
// Handle updated tasks
});
// Subscribe to ICS-specific updates
Events.on(Events.ICS_EVENTS_UPDATED, (payload) => {
const { events } = payload;
// Handle ICS events
});
```
## Performance Characteristics
### Optimizations
1. **Snapshot Loading**: Fast startup from persisted state (~100ms for 1000 tasks)
2. **Worker Orchestration**: Parallel processing for large vaults
3. **Batch Operations**: Reduced I/O overhead
4. **Event Deduplication**: Sequence-based loop prevention
5. **Incremental Updates**: Only changed files processed
6. **Separate ICS Storage**: Calendar events don't impact file indexing
### Cache Strategy
- **Multi-tier**: Raw → Augmented → Consolidated
- **Content Hashing**: Detect actual changes
- **Modification Time**: Quick staleness check
- **Lazy Loading**: Load data only when needed
## Troubleshooting
### Common Issues
#### Infinite Loop Detection
- **Symptom**: Repeated "Batch update" logs
- **Cause**: Missing sourceSeq in events
- **Solution**: Ensure all TASK_CACHE_UPDATED events include sourceSeq
#### Missing ICS Events
- **Symptom**: Calendar events not showing in views
- **Cause**: IcsSource not initialized or IcsManager unavailable
- **Solution**: Check IcsManager configuration and initialization
#### Stale Data
- **Symptom**: Changes not reflected in views
- **Cause**: Cache not invalidated properly
- **Solution**: Clear cache or trigger manual rebuild
### Debug Commands
```javascript
// In console
app.plugins.plugins['task-genius'].dataflowOrchestrator.getStats()
app.plugins.plugins['task-genius'].dataflowOrchestrator.rebuild()
```
## Development Guidelines
### Adding New Data Sources
1. Create source in `src/dataflow/sources/`
2. Implement event emission pattern
3. Add event type to `Events.ts`
4. Update Orchestrator to subscribe
5. Extend Repository if needed
6. Update Storage for persistence
### FileSource Integration (Completed)
The FileSource component has been fully integrated into the Orchestrator:
1. ✅ Initialize FileSource in Orchestrator constructor
2. ✅ Subscribe to FILE_TASK_UPDATED and FILE_TASK_REMOVED events
3. ✅ Extend Repository to handle file tasks separately from regular tasks
4. ✅ Update QueryAPI to merge file tasks in query results
5. ✅ Implement caching strategy to avoid redundant project resolution
6. ✅ Complete template and path recognition strategies
7. ✅ Add removeFileTask method to Repository
**Bug Fixes Applied**:
- Fixed configuration path mismatch where Orchestrator was checking `fileSourceConfig` instead of `fileSource` in settings
- Added missing removeFileTask method to Repository for proper file task cleanup
- Completed template recognition strategy implementation
### Adding New Features
1. Implement in dataflow architecture first
2. Add conditional logic for backward compatibility
3. Include sourceSeq in any TASK_CACHE_UPDATED events
4. Test both dataflow and legacy modes
5. Update this documentation
### Best Practices
- Always use QueryAPI for data access
- Never bypass Repository for updates
- Include proper event metadata
- Handle errors gracefully
- Log with component prefix: `[ComponentName]`
## Future Enhancements
### Planned
1. **Write Operations**: Extend dataflow for task creation/updates
2. **Advanced Querying**: GraphQL-like query capabilities
3. **Real-time Sync**: Multi-device synchronization
4. **Plugin API**: External plugin support
### Under Consideration
- WebSocket support for real-time collaboration
- Database backend option for large vaults
- Incremental parsing for huge files
- Custom data source plugins
## Architecture Decisions
### Why Separate ICS Storage?
- **Independence**: ICS events have different lifecycle than file tasks
- **Performance**: Avoid re-parsing files when only calendar changes
- **Flexibility**: Easy to add/remove external sources
- **Clarity**: Clear separation of concerns
### Why Source Sequences?
- **Simplicity**: Single number comparison prevents loops
- **Performance**: Minimal overhead
- **Debugging**: Easy to trace event origins
- **Compatibility**: Works with existing event system
### Why Keep Legacy Support?
- **Safety**: Fallback for critical issues
- **Migration**: Gradual transition for large vaults
- **Testing**: A/B comparison capability
- **Confidence**: Users can always revert
## Bug Fixes and Updates
### FileSource Configuration Path Fix (2025-08-22)
**Problem**: FileSource was not initializing despite being enabled in settings.
- **Root Cause**: Configuration path mismatch between settings structure (`fileSource`) and Orchestrator code (`fileSourceConfig`)
- **Files Modified**: `src/dataflow/Orchestrator.ts` (lines 88-91)
- **Resolution**: Updated Orchestrator to use correct settings path `plugin.settings.fileSource`
- **Impact**: FileSource now properly initializes when enabled and can recognize files as tasks
## Conclusion
The Dataflow architecture has evolved from a file-centric system to a unified data pipeline supporting multiple sources. Its event-driven, modular design enables:
- Clean integration of new data sources
- Robust loop prevention
- Excellent performance characteristics
- Maintainable and testable codebase
The architecture is production-ready and serves as the foundation for future task management enhancements.

View file

@ -1,208 +0,0 @@
# Dataflow 事件系统架构
## 概述
Dataflow 架构通过事件驱动的方式处理任务的增删改查操作,确保 UI 和数据层的同步更新。
## 核心组件
### 1. ObsidianSource
- **作用**: 监听 Obsidian 文件系统事件
- **事件**:
- 文件创建/修改/删除/重命名
- 元数据变更
- **特性**:
- 自动去抖动300ms
- 批量处理
- 跳过 WriteAPI 触发的修改
### 2. DataflowOrchestrator
- **作用**: 协调所有数据流组件
- **监听事件**:
- `FILE_UPDATED`: 处理文件变更
- `TASK_CACHE_UPDATED`: 处理批量更新
- `WRITE_OPERATION_COMPLETE`: 处理 WriteAPI 完成的操作
- **处理流程**:
1. 接收事件
2. 解析文件内容
3. 增强任务数据
4. 更新 Repository
5. 触发 UI 更新
### 3. Repository
- **作用**: 中央数据仓库
- **功能**:
- 维护任务索引
- 持久化存储
- 触发 `TASK_CACHE_UPDATED` 事件通知 UI
### 4. WriteAPI
- **作用**: 处理所有写操作
- **事件流程**:
1. 发送 `WRITE_OPERATION_START` 事件
2. 修改文件
3. 发送 `WRITE_OPERATION_COMPLETE` 事件
4. Orchestrator 接收事件并重新处理文件
## 数据流路径
### 场景 1: UI 更新任务
```
UI操作 → WriteAPI → 发送 WRITE_OPERATION_START
→ 修改文件
→ 发送 WRITE_OPERATION_COMPLETE
→ Orchestrator 处理文件
→ Repository 更新
→ 发送 TASK_CACHE_UPDATED
→ UI 更新
```
### 场景 2: 直接编辑文件
```
文件编辑 → ObsidianSource 检测变化
→ 发送 FILE_UPDATED 事件
→ Orchestrator 处理文件
→ Repository 更新
→ 发送 TASK_CACHE_UPDATED
→ UI 更新
```
### 场景 3: Canvas 任务更新
```
Canvas 任务编辑 → CanvasTaskUpdater
→ 发送 WRITE_OPERATION_START
→ 修改 Canvas JSON
→ 发送 WRITE_OPERATION_COMPLETE
→ Orchestrator 处理
→ UI 更新
```
## 关键事件
### Events 定义
```typescript
export const Events = {
CACHE_READY: "task-genius:cache-ready",
TASK_CACHE_UPDATED: "task-genius:task-cache-updated",
FILE_UPDATED: "task-genius:file-updated",
WRITE_OPERATION_START: "task-genius:write-operation-start",
WRITE_OPERATION_COMPLETE: "task-genius:write-operation-complete",
// ...
}
```
### 事件协作
1. **ObsidianSource 与 WriteAPI 协作**:
- WriteAPI 发送 `WRITE_OPERATION_START`ObsidianSource 标记该文件
- ObsidianSource 跳过被标记文件的 modify 事件
- 避免重复处理
2. **Orchestrator 事件处理**:
- 监听多个事件源
- 对 WriteAPI 操作立即处理(无去抖)
- 对文件系统事件进行去抖处理
3. **Repository 事件发送**:
- 每次更新后发送 `TASK_CACHE_UPDATED`
- 包含变更文件列表和统计信息
- UI 组件监听此事件进行更新
## 实现细节
### 去抖动机制
- ObsidianSource: 300ms 去抖
- Orchestrator: 300ms 去抖(除 WriteAPI 操作外)
- 批量操作: 150ms 批处理延迟
### 事件跳过机制
```typescript
// ObsidianSource
if (this.skipNextModify.has(file.path)) {
this.skipNextModify.delete(file.path);
console.log(`Skipping modify event (handled by WriteAPI)`);
return;
}
```
### 立即处理机制
```typescript
// Orchestrator - WriteAPI 操作立即处理
on(Events.WRITE_OPERATION_COMPLETE, async (payload) => {
const file = this.vault.getAbstractFileByPath(payload.path);
if (file) {
await this.processFileImmediate(file); // 无去抖
}
});
```
## 测试要点
1. **UI 更新测试**:
- 通过 UI 修改任务状态
- 验证文件被更新
- 验证 UI 自动刷新
2. **文件编辑测试**:
- 直接在 Obsidian 中编辑任务
- 验证 UI 在 300ms 后更新
3. **Canvas 任务测试**:
- 在 Canvas 中修改任务
- 验证 Canvas 文件更新
- 验证任务列表刷新
4. **批量操作测试**:
- 同时修改多个文件
- 验证批处理机制工作
- 验证性能优化效果
## 调试技巧
### 启用日志
```typescript
// 在 Orchestrator 中
console.log(`[DataflowOrchestrator] FILE_UPDATED: ${path}`);
console.log(`[DataflowOrchestrator] WRITE_OPERATION_COMPLETE: ${path}`);
// 在 ObsidianSource 中
console.log(`ObsidianSource: File modified - ${file.path}`);
console.log(`ObsidianSource: Skipping modify event (handled by WriteAPI)`);
```
### 事件流追踪
1. 打开控制台
2. 执行操作
3. 观察事件序列:
- WRITE_OPERATION_START
- File modification (可能被跳过)
- WRITE_OPERATION_COMPLETE
- TASK_CACHE_UPDATED
### 常见问题
1. **UI 不更新**:
- 检查 TASK_CACHE_UPDATED 事件是否触发
- 验证 UI 组件是否正确监听事件
2. **重复处理**:
- 检查 skipNextModify 机制
- 验证去抖动时间设置
3. **Canvas 更新失败**:
- 检查 CanvasTaskUpdater 事件发送
- 验证 Canvas JSON 格式正确
## 未来改进
1. **性能优化**:
- 实现更智能的增量更新
- 优化大文件处理
2. **错误处理**:
- 添加重试机制
- 改进错误报告
3. **监控**:
- 添加性能指标
- 实现事件追踪系统

View file

@ -1,99 +0,0 @@
# Dataflow Migration - Phase A Complete
## Summary
Phase A of the dataflow migration has been successfully implemented. This phase enables parallel initialization of both the traditional TaskManager and the new dataflow architecture, with experimental user control.
## Completed Tasks
### A1: Experimental Settings Switch ✅
- **Location**: `src/common/setting-definition.ts`, `src/setting.ts`
- **Changes**:
- Added `experimental.dataflowEnabled` setting with default `false`
- Created new "Experimental" tab in settings UI
- Added warning messages and user-friendly descriptions
- Added CSS styles for experimental settings
### A2: Parallel Initialization ✅
- **Location**: `src/index.ts`, `src/dataflow/createDataflow.ts`
- **Changes**:
- Created `createDataflow()` factory function
- Added `isDataflowEnabled()` utility function
- Modified plugin `onload()` to conditionally initialize dataflow
- Added proper cleanup in `onunload()`
- Both systems run in parallel when dataflow is enabled
### A3: TaskView Data Source Selection ✅
- **Location**: `src/pages/TaskView.ts`
- **Changes**:
- Modified `loadTasks()` method to check dataflow availability
- Modified `loadTasksFast()` method with same logic
- Added fallback mechanism to TaskManager if dataflow fails
- Maintained backward compatibility
## Key Features
### Safe Experimentation
- Users can enable/disable dataflow through settings
- Automatic fallback to TaskManager on any dataflow errors
- Both systems can run simultaneously for comparison
### Non-Breaking Changes
- All existing functionality preserved
- No changes to default behavior (dataflow disabled by default)
- Graceful error handling
### Ready for Testing
- TaskView now conditionally uses QueryAPI when dataflow is enabled
- Console logging for debugging and verification
- Clean separation between old and new systems
## Testing Instructions
1. **Enable Dataflow**:
- Go to Settings → Advanced → Experimental
- Toggle "Enable Dataflow Architecture"
- Restart plugin (recommended)
2. **Verify Operation**:
- Open Task Genius view
- Check console for messages:
- "Loading tasks from dataflow orchestrator..." (dataflow enabled)
- "TaskView loaded X tasks from dataflow" (success)
- "Loading tasks from TaskManager" (fallback/disabled)
3. **Test Fallback**:
- If dataflow fails, should automatically fall back to TaskManager
- No user-visible errors should occur
## Next Phase Recommendations
**Phase B: View Migration**
- Migrate remaining views (Projects, Tags, Forecast)
- Add more sophisticated error handling
- Implement data consistency checks
**Phase C: Feature Parity**
- Ensure all TaskManager features work with dataflow
- Performance comparison and optimization
- User feedback collection
## Code Locations
```
src/common/setting-definition.ts # Settings definition
src/setting.ts # Settings UI
src/styles/setting.css # Experimental settings styles
src/index.ts # Plugin initialization
src/dataflow/createDataflow.ts # Dataflow factory
src/pages/TaskView.ts # Main view with conditional data source
```
## Architecture Notes
The implementation maintains clean separation:
- **Settings Layer**: Controls experimental features
- **Initialization Layer**: Manages parallel system startup
- **Data Layer**: Provides conditional data source selection
- **UI Layer**: Unchanged, works with both systems
This approach allows for gradual migration with minimal risk and easy rollback capabilities.

View file

@ -1,136 +0,0 @@
# Dataflow Architecture - Production Ready
## Overview
The Dataflow architecture has been promoted from experimental status to production ready. This document outlines the changes made to reflect this milestone.
## Changes Made
### 1. Settings Structure Update
**Before (Experimental)**:
```typescript
interface TaskProgressBarSettings {
experimental?: {
dataflowEnabled: boolean;
};
}
// Default
experimental: {
dataflowEnabled: true
}
```
**After (Production)**:
```typescript
interface TaskProgressBarSettings {
// Core Architecture Settings
dataflowEnabled: boolean;
}
// Default
dataflowEnabled: true
```
### 2. Settings UI Migration
- **Moved from**: Experimental tab → Index & Sources tab
- **New location**: Core Architecture section in Index & Sources
- **Updated description**: Removed experimental warnings, emphasized as recommended setting
### 3. Code References Updated
All references to `settings.experimental.dataflowEnabled` have been updated to `settings.dataflowEnabled`:
- `src/dataflow/createDataflow.ts` - `isDataflowEnabled()` function
- `src/index.ts` - Command handlers
- `src/mcp/McpServer.ts` - MCP integration
- `src/components/settings/IndexSettingsTab.ts` - Settings UI
### 4. Default Behavior
- **Default value**: `true` (Dataflow enabled by default)
- **Fallback behavior**: If setting is undefined, defaults to `true`
- **Migration**: Existing users with `experimental.dataflowEnabled: false` will need to manually update
## Migration Guide
### For Plugin Users
1. **Automatic Migration**: New installations will use Dataflow by default
2. **Existing Users**:
- If you had Dataflow enabled: No action needed
- If you had Dataflow disabled: Check "Index & Sources" → "Enable Dataflow Architecture"
3. **Settings Location**: Find Dataflow settings in "Index & Sources" tab instead of "Experimental"
### For Developers
1. **API Changes**: Use `plugin.settings.dataflowEnabled` instead of `plugin.settings.experimental?.dataflowEnabled`
2. **Default Assumption**: Code should assume Dataflow is enabled unless explicitly disabled
3. **Backward Compatibility**: Old experimental setting is ignored
## Benefits of Production Status
### 1. User Confidence
- No longer marked as experimental
- Clear indication that the feature is stable and recommended
- Reduced barrier to adoption
### 2. Simplified Settings
- Cleaner settings structure
- More logical organization (Core Architecture vs Experimental)
- Better user experience
### 3. Development Focus
- Experimental tab reserved for truly experimental features
- Core architecture decisions are clearly separated
- Easier maintenance and documentation
## Architecture Maturity Indicators
### ✅ Completed Milestones
1. **Feature Parity**: All TaskManager functionality replicated
2. **Performance**: Optimized with caching and workers
3. **Stability**: Comprehensive error handling and recovery
4. **Testing**: Extensive test coverage
5. **Documentation**: Complete architecture documentation
6. **User Feedback**: Positive feedback from beta users
### ✅ Production Readiness Criteria
1. **Zero Data Loss**: Safe migration from legacy system
2. **Performance**: Equal or better performance than legacy
3. **Reliability**: Stable operation under various conditions
4. **Maintainability**: Clean, well-documented codebase
5. **Extensibility**: Easy to add new features
## Future Roadmap
### Short Term
- Monitor user adoption and feedback
- Performance optimizations based on real usage
- Bug fixes and stability improvements
### Medium Term
- Advanced query capabilities
- Additional data source integrations
- Enhanced caching strategies
### Long Term
- Plugin ecosystem support
- Advanced analytics and insights
- Multi-vault synchronization
## Conclusion
The promotion of Dataflow architecture to production status represents a significant milestone in the Task Genius plugin's evolution. The architecture has proven itself through extensive testing and real-world usage, providing a solid foundation for future enhancements.
Users can now confidently use the Dataflow architecture as the primary task processing system, enjoying improved performance, reliability, and feature richness compared to the legacy TaskManager system.
---
**Document Version**: 1.0
**Last Updated**: 2025-01-23
**Status**: Production Ready ✅

View file

@ -1,351 +0,0 @@
# Directory Structure Refactoring Plan
## Overview
This document outlines the comprehensive refactoring plan for reorganizing the `src/utils` directory and establishing a clearer, more maintainable directory structure for the Task Genius plugin.
## Current Issues
### Problem Analysis
1. **Mixed Responsibilities**: The `src/utils/` directory contains managers, services, parsers, utilities, and executors all mixed together
2. **Inconsistent Naming**: Files have inconsistent naming conventions (e.g., `TaskManager.ts` vs `taskUtil.ts`)
3. **Poor Organization**: Related functionality is scattered across different locations
4. **Overly Large Files**: `TaskManager.ts` is over 27,000 tokens and should be split
5. **Unclear Dependencies**: Hard to understand relationships between components
## Existing Structures to Preserve
### Keep As-Is
- **`src/dataflow/`** - Already well-organized with:
- `api/` - QueryAPI, WriteAPI for dataflow operations
- `parsers/` - Dataflow-specific parsers (MarkdownEntry, FileMetaEntry, CanvasEntry)
- `workers/` - Dataflow-specific workers
- `core/`, `events/`, `sources/`, etc.
- **`src/mcp/`** - MCP server implementation with:
- `auth/` - Authentication middleware
- `bridge/` - Bridge implementations (DataflowBridge, TaskManagerBridge)
- `types/` - Type definitions
## New Directory Structure
```
src/
├── cache/ # Caching and storage utilities
│ ├── local-storage-cache.ts (from utils/persister.ts)
│ └── project-data-cache.ts (from utils/ProjectDataCache.ts)
├── core/ # Core business logic
│ ├── goal/ # Goal-related functionality (moved from utils/goal/)
│ │ ├── edit-mode.ts
│ │ ├── read-mode.ts
│ │ └── regex-goal.ts
│ ├── project-filter.ts (from utils/projectFilter.ts)
│ ├── project-tree-builder.ts (from utils/projectTreeBuilder.ts)
│ ├── task-indexer.ts (from utils/import/TaskIndexer.ts)
│ └── workflow-converter.ts (from utils/workflowConversion.ts)
├── dataflow/ # [EXISTING - NO CHANGES]
│ └── workers/ # Add worker-related utilities here
│ ├── [existing files]
│ ├── task-index-message.ts (from utils/workers/TaskIndexWorkerMessage.ts)
│ └── deferred-promise.ts (from utils/workers/deferred.ts)
├── executors/ # Action executors
│ └── completion/ # Task completion actions
│ ├── base-executor.ts (from utils/onCompletion/BaseActionExecutor.ts)
│ ├── archive-executor.ts (from utils/onCompletion/ArchiveActionExecutor.ts)
│ ├── complete-executor.ts (from utils/onCompletion/CompleteActionExecutor.ts)
│ ├── delete-executor.ts (from utils/onCompletion/DeleteActionExecutor.ts)
│ ├── duplicate-executor.ts (from utils/onCompletion/DuplicateActionExecutor.ts)
│ ├── keep-executor.ts (from utils/onCompletion/KeepActionExecutor.ts)
│ ├── move-executor.ts (from utils/onCompletion/MoveActionExecutor.ts)
│ └── canvas-operation-utils.ts (from utils/onCompletion/CanvasTaskOperationUtils.ts)
├── managers/ # Feature-specific managers
│ ├── completion-manager.ts (from utils/OnCompletionManager.ts)
│ ├── file-filter-manager.ts (from utils/FileFilterManager.ts)
│ ├── file-task-manager.ts (from utils/FileTaskManager.ts)
│ ├── habit-manager.ts (from utils/HabitManager.ts)
│ ├── icon-manager.ts (from utils/TaskGeniusIconManager.ts)
│ ├── ics-manager.ts (from utils/ics/IcsManager.ts)
│ ├── onboarding-manager.ts (from utils/OnboardingConfigManager.ts)
│ ├── project-config-manager.ts (from utils/ProjectConfigManager.ts)
│ ├── rebuild-progress-manager.ts (from utils/RebuildProgressManager.ts)
│ ├── reward-manager.ts (from utils/RewardManager.ts)
│ ├── task-manager.ts (from utils/TaskManager.ts)
│ ├── timer-manager.ts (from utils/TaskTimerManager.ts)
│ └── version-manager.ts (from utils/VersionManager.ts)
├── mcp/ # [EXISTING - NO CHANGES]
├── parsers/ # General-purpose parsers (non-dataflow)
│ ├── canvas-parser.ts (from utils/parsing/CanvasParser.ts)
│ ├── canvas-task-updater.ts (from utils/parsing/CanvasTaskUpdater.ts)
│ ├── configurable-task-parser.ts (from utils/workers/ConfigurableTaskParser.ts)
│ ├── context-detector.ts (from utils/workers/ContextDetector.ts)
│ ├── file-metadata-parser.ts (from utils/workers/FileMetadataTaskParser.ts)
│ ├── file-metadata-updater.ts (from utils/workers/FileMetadataTaskUpdater.ts)
│ ├── holiday-detector.ts (from utils/ics/HolidayDetector.ts)
│ ├── ics-parser.ts (from utils/ics/IcsParser.ts)
│ ├── ics-status-mapper.ts (from utils/ics/StatusMapper.ts)
│ └── webcal-converter.ts (from utils/ics/WebcalUrlConverter.ts)
├── services/ # Service classes
│ ├── settings-change-detector.ts (from utils/SettingsChangeDetector.ts)
│ ├── task-parsing-service.ts (from utils/TaskParsingService.ts)
│ ├── time-parsing-service.ts (from utils/TimeParsingService.ts)
│ ├── timer-export-service.ts (from utils/TaskTimerExporter.ts)
│ ├── timer-format-service.ts (from utils/TaskTimerFormatter.ts)
│ └── timer-metadata-service.ts (from utils/TaskTimerMetadataDetector.ts)
└── utils/ # Pure utility functions only
├── date/ # Date utilities
│ ├── date-formatter.ts (from utils/dateUtil.ts)
│ └── date-helper.ts (from utils/DateHelper.ts)
├── file/ # File utilities
│ ├── file-operations.ts (from utils/fileUtils.ts)
│ └── file-type-detector.ts (from utils/fileTypeUtils.ts)
├── task/ # Task utilities
│ ├── filter-compatibility.ts (from utils/filterUtils.ts)
│ ├── priority-utils.ts (from utils/priorityUtils.ts)
│ ├── task-filter-utils.ts (from utils/TaskFilterUtils.ts)
│ ├── task-migration.ts (from utils/taskMigrationUtils.ts)
│ └── task-operations.ts (from utils/taskUtil.ts - if not deprecated)
├── ui/ # UI utilities
│ ├── tree-view-utils.ts (from utils/treeViewUtil.ts)
│ └── view-mode-utils.ts (from utils/viewModeUtils.ts)
└── id-generator.ts (from utils/common.ts)
```
## Implementation Phases
### Phase 1: Directory Creation
Create all new directories before moving any files:
- `src/managers/`
- `src/services/`
- `src/executors/completion/`
- `src/parsers/`
- `src/cache/`
- `src/core/goal/`
- `src/utils/date/`
- `src/utils/file/`
- `src/utils/task/`
- `src/utils/ui/`
### Phase 2: Manager Migration
Move all manager classes from `src/utils/` to `src/managers/`:
| Original File | New Location | Rename Reason |
|--------------|--------------|---------------|
| `FileTaskManager.ts` | `managers/file-task-manager.ts` | Kebab-case consistency |
| `HabitManager.ts` | `managers/habit-manager.ts` | Kebab-case consistency |
| `TaskManager.ts` | `managers/task-manager.ts` | Kebab-case consistency |
| `OnCompletionManager.ts` | `managers/completion-manager.ts` | Clearer naming + kebab-case |
| `OnboardingConfigManager.ts` | `managers/onboarding-manager.ts` | Simpler name + kebab-case |
| `ProjectConfigManager.ts` | `managers/project-config-manager.ts` | Kebab-case consistency |
| `RebuildProgressManager.ts` | `managers/rebuild-progress-manager.ts` | Kebab-case consistency |
| `RewardManager.ts` | `managers/reward-manager.ts` | Kebab-case consistency |
| `TaskGeniusIconManager.ts` | `managers/icon-manager.ts` | Simpler name + kebab-case |
| `TaskTimerManager.ts` | `managers/timer-manager.ts` | Simpler name + kebab-case |
| `VersionManager.ts` | `managers/version-manager.ts` | Kebab-case consistency |
| `FileFilterManager.ts` | `managers/file-filter-manager.ts` | Kebab-case consistency |
| `ics/IcsManager.ts` | `managers/ics-manager.ts` | Flatten structure + kebab-case |
### Phase 3: Service Migration
Move service classes from `src/utils/` to `src/services/`:
| Original File | New Location | Rename Reason |
|--------------|--------------|---------------|
| `TaskParsingService.ts` | `services/task-parsing-service.ts` | Kebab-case consistency |
| `TimeParsingService.ts` | `services/time-parsing-service.ts` | Kebab-case consistency |
| `SettingsChangeDetector.ts` | `services/settings-change-detector.ts` | Kebab-case consistency |
| `TaskTimerExporter.ts` | `services/timer-export-service.ts` | Clearer naming + kebab-case |
| `TaskTimerFormatter.ts` | `services/timer-format-service.ts` | Clearer naming + kebab-case |
| `TaskTimerMetadataDetector.ts` | `services/timer-metadata-service.ts` | Clearer naming + kebab-case |
### Phase 4: Executor Migration
Move executors from `src/utils/onCompletion/` to `src/executors/completion/`:
| Original File | New Location | Rename Reason |
|--------------|--------------|---------------|
| `onCompletion/BaseActionExecutor.ts` | `executors/completion/base-executor.ts` | Simpler name + kebab-case |
| `onCompletion/ArchiveActionExecutor.ts` | `executors/completion/archive-executor.ts` | Simpler name + kebab-case |
| `onCompletion/CompleteActionExecutor.ts` | `executors/completion/complete-executor.ts` | Simpler name + kebab-case |
| `onCompletion/DeleteActionExecutor.ts` | `executors/completion/delete-executor.ts` | Simpler name + kebab-case |
| `onCompletion/DuplicateActionExecutor.ts` | `executors/completion/duplicate-executor.ts` | Simpler name + kebab-case |
| `onCompletion/KeepActionExecutor.ts` | `executors/completion/keep-executor.ts` | Simpler name + kebab-case |
| `onCompletion/MoveActionExecutor.ts` | `executors/completion/move-executor.ts` | Simpler name + kebab-case |
| `onCompletion/CanvasTaskOperationUtils.ts` | `executors/completion/canvas-operation-utils.ts` | Clearer naming + kebab-case |
### Phase 5: Parser Migration
Move parsers from various locations to appropriate directories:
| Original File | New Location | Rename Reason |
|--------------|--------------|---------------|
| `parsing/CanvasParser.ts` | `parsers/canvas-parser.ts` | Kebab-case consistency |
| `parsing/CanvasTaskUpdater.ts` | `parsers/canvas-task-updater.ts` | Kebab-case consistency |
| `ics/IcsParser.ts` | `parsers/ics-parser.ts` | Flatten structure + kebab-case |
| `ics/HolidayDetector.ts` | `parsers/holiday-detector.ts` | Flatten structure + kebab-case |
| `ics/StatusMapper.ts` | `parsers/ics-status-mapper.ts` | Clearer naming + kebab-case |
| `ics/WebcalUrlConverter.ts` | `parsers/webcal-converter.ts` | Simpler name + kebab-case |
| `workers/ConfigurableTaskParser.ts` | `parsers/configurable-task-parser.ts` | Kebab-case consistency |
| `workers/ContextDetector.ts` | `parsers/context-detector.ts` | Kebab-case consistency |
| `workers/FileMetadataTaskParser.ts` | `parsers/file-metadata-parser.ts` | Simpler name + kebab-case |
| `workers/FileMetadataTaskUpdater.ts` | `parsers/file-metadata-updater.ts` | Simpler name + kebab-case |
### Phase 6: Cache Migration
Move caching utilities to `src/cache/`:
| Original File | New Location | Rename Reason |
|--------------|--------------|---------------|
| `persister.ts` | `cache/local-storage-cache.ts` | Descriptive name + kebab-case |
| `ProjectDataCache.ts` | `cache/project-data-cache.ts` | Kebab-case consistency |
### Phase 7: Core Business Logic Migration
Move core business logic to `src/core/`:
| Original File | New Location | Rename Reason |
|--------------|--------------|---------------|
| `projectFilter.ts` | `core/project-filter.ts` | Kebab-case consistency |
| `projectTreeBuilder.ts` | `core/project-tree-builder.ts` | Kebab-case consistency |
| `workflowConversion.ts` | `core/workflow-converter.ts` | Clearer naming + kebab-case |
| `goal/` (entire directory) | `core/goal/` | Preserve structure |
| `import/TaskIndexer.ts` | `core/task-indexer.ts` | Flatten structure + kebab-case |
### Phase 8: Worker Migration to Dataflow
Move worker utilities to existing `src/dataflow/workers/`:
| Original File | New Location | Rename Reason |
|--------------|--------------|---------------|
| `workers/TaskIndexWorkerMessage.ts` | `dataflow/workers/task-index-message.ts` | Simpler name + kebab-case |
| `workers/deferred.ts` | `dataflow/workers/deferred-promise.ts` | Descriptive name + kebab-case |
### Phase 9: Utility Reorganization
Reorganize remaining utilities into categorized subdirectories:
| Original File | New Location | Rename Reason |
|--------------|--------------|---------------|
| `DateHelper.ts` | `utils/date/date-helper.ts` | Kebab-case consistency |
| `dateUtil.ts` | `utils/date/date-formatter.ts` | Descriptive name + kebab-case |
| `fileTypeUtils.ts` | `utils/file/file-type-detector.ts` | Descriptive name + kebab-case |
| `fileUtils.ts` | `utils/file/file-operations.ts` | Descriptive name + kebab-case |
| `priorityUtils.ts` | `utils/task/priority-utils.ts` | Kebab-case consistency |
| `taskUtil.ts` | `utils/task/task-operations.ts` | Descriptive name + kebab-case |
| `TaskFilterUtils.ts` | `utils/task/task-filter-utils.ts` | Kebab-case consistency |
| `filterUtils.ts` | `utils/task/filter-compatibility.ts` | Descriptive name + kebab-case |
| `taskMigrationUtils.ts` | `utils/task/task-migration.ts` | Simpler name + kebab-case |
| `treeViewUtil.ts` | `utils/ui/tree-view-utils.ts` | Kebab-case consistency |
| `viewModeUtils.ts` | `utils/ui/view-mode-utils.ts` | Kebab-case consistency |
| `common.ts` | `utils/id-generator.ts` | Descriptive name + kebab-case |
### Phase 10: Import Path Updates
After all files are moved, update all import statements throughout the codebase:
1. Use automated refactoring tools where possible
2. Run TypeScript compiler to identify broken imports
3. Update test file imports
4. Update barrel exports (index.ts files)
5. Verify no circular dependencies were introduced
### Phase 11: Cleanup
1. Remove empty directories
2. Delete or update `src/utils/README.md`
3. Update any documentation that references old file paths
4. Run full test suite to ensure nothing broke
## Validation Checklist
- [ ] All directories created successfully
- [ ] All files moved to new locations
- [ ] All files renamed to kebab-case
- [ ] All import paths updated
- [ ] TypeScript compilation succeeds
- [ ] All tests pass
- [ ] No circular dependencies introduced
- [ ] Documentation updated
- [ ] Commit with detailed message explaining the refactoring
## Commit Message Template
```
refactor: reorganize directory structure for better maintainability
BREAKING CHANGE: Major directory restructuring - all import paths updated
Motivation:
- Mixed responsibilities in utils/ directory causing confusion
- Inconsistent naming conventions across files
- Poor organization making code discovery difficult
- Need for clearer separation of concerns
Changes by category:
Managers (utils/ → managers/):
- Renamed to kebab-case for consistency
- FileTaskManager → file-task-manager
- TaskGeniusIconManager → icon-manager (simplified)
- OnCompletionManager → completion-manager (clarified)
Services (utils/ → services/):
- Separated service classes from utilities
- TaskTimerExporter → timer-export-service (clarified purpose)
- TaskTimerFormatter → timer-format-service (clarified purpose)
Executors (utils/onCompletion/ → executors/completion/):
- Grouped action executors together
- Simplified names (e.g., BaseActionExecutor → base-executor)
Parsers (various → parsers/):
- Consolidated general-purpose parsers
- Kept dataflow-specific parsers in dataflow/parsers/
Core Logic (utils/ → core/):
- Moved business logic out of utils
- Created goal/ subdirectory for goal-related features
Cache (utils/ → cache/):
- Separated caching utilities
- persister → local-storage-cache (descriptive rename)
Pure Utilities (reorganized in utils/):
- Created subdirectories: date/, file/, task/, ui/
- Renamed for clarity and consistency
- common.ts → id-generator.ts (specific purpose)
Worker Integration:
- Moved worker utilities to dataflow/workers/
- Maintains consistency with dataflow architecture
Benefits:
- Clear separation of concerns
- Easier code discovery
- Consistent naming conventions
- Better maintainability
- Reduced cognitive load for developers
```
## Notes
1. **Naming Convention**: All files use kebab-case for consistency
2. **Dataflow Preservation**: The existing dataflow architecture is preserved
3. **MCP Preservation**: The MCP server structure remains unchanged
4. **Gradual Migration**: Can be implemented in phases to minimize disruption
5. **Future Consideration**: TaskManager.ts should be split into smaller, focused modules
## Risk Mitigation
1. **Create a branch**: `refactor/directory-structure`
2. **Implement in small commits**: One phase per commit for easy rollback
3. **Run tests after each phase**: Ensure nothing breaks
4. **Use automated tools**: VSCode's "Move file" and "Rename Symbol" features
5. **Review imports carefully**: Some imports might need manual adjustment
6. **Document changes**: Update README and other docs as needed
## Future Improvements
After this refactoring:
1. Consider splitting `TaskManager.ts` into smaller modules
2. Create barrel exports (index.ts) for each major directory
3. Add JSDoc comments to clarify module purposes
4. Consider dependency injection for better testability
5. Evaluate if any managers should become services or vice versa

View file

@ -1,118 +0,0 @@
# Editor Extensions Refactoring Plan
## Overview
This document outlines the refactoring of the `editor-ext` directory to improve organization, consistency, and maintainability of editor extension code.
## Completed on: 2025-01-19
## Changes Implemented
### Directory Renaming
- **Old**: `src/editor-ext/`
- **New**: `src/editor-extensions/`
- **Reason**: More complete and professional naming
### New Directory Structure
```
src/editor-extensions/
├── autocomplete/ # Auto-completion and suggestion features
│ ├── task-metadata-suggest.ts
│ └── parent-task-updater.ts
├── task-operations/ # Task operations (status, cleanup, monitoring)
│ ├── status-cycler.ts
│ ├── status-switcher.ts
│ ├── completion-monitor.ts
│ ├── mark-cleanup.ts
│ └── gutter-marker.ts
├── date-time/ # Date and time features
│ ├── date-picker.ts
│ ├── date-manager.ts
│ └── task-timer.ts
├── ui-widgets/ # UI decorations and widgets
│ ├── progress-bar-widget.ts
│ ├── priority-picker.ts
│ └── workflow-decorator.ts
├── workflow/ # Workflow features
│ ├── workflow-handler.ts
│ └── workflow-enter-handler.ts
└── core/ # Core editor functionality
├── markdown-editor.ts
├── extended-gutter.ts
├── regex-cursor.ts
├── task-filter-panel.ts
└── quick-capture-panel.ts
```
## File Renaming Details
### Autocomplete
| Original | New | Reason |
|----------|-----|--------|
| QuickCaptureSuggest.ts | task-metadata-suggest.ts | More accurate description of task metadata suggestions |
| autoCompleteParent.ts | parent-task-updater.ts | Clearly indicates parent task update functionality |
### Task Operations
| Original | New | Reason |
|----------|-----|--------|
| cycleCompleteStatus.ts | status-cycler.ts | Simplified name, kebab-case |
| taskStatusSwitcher.ts | status-switcher.ts | Kebab-case consistency |
| monitorTaskCompleted.ts | completion-monitor.ts | Simplified and clearer |
| taskMarkCleanup.ts | mark-cleanup.ts | Simplified name |
| TaskGutterHandler.ts | gutter-marker.ts | More accurate description |
### Date-Time
| Original | New | Reason |
|----------|-----|--------|
| datePicker.ts | date-picker.ts | Kebab-case consistency |
| autoDateManager.ts | date-manager.ts | Simplified name |
| taskTimer.ts | task-timer.ts | Kebab-case consistency |
### UI Widgets
| Original | New | Reason |
|----------|-----|--------|
| progressBarWidget.ts | progress-bar-widget.ts | Kebab-case consistency |
| priorityPicker.ts | priority-picker.ts | Kebab-case consistency |
| workflowDecorator.ts | workflow-decorator.ts | Kebab-case consistency |
### Workflow
| Original | New | Reason |
|----------|-----|--------|
| workflow.ts | workflow-handler.ts | More explicit name |
| workflowRootEnterHandler.ts | workflow-enter-handler.ts | Simplified name |
### Core
| Original | New | Reason |
|----------|-----|--------|
| markdownEditor.ts | markdown-editor.ts | Kebab-case consistency |
| patchedGutter.ts | extended-gutter.ts | More professional name |
| regexp-cursor.ts | regex-cursor.ts | Common abbreviation |
| filterTasks.ts | task-filter-panel.ts | More explicit name |
| quickCapture.ts | quick-capture-panel.ts | More explicit name |
## Benefits Achieved
1. **Clear Separation of Concerns**: Each subdirectory now has a specific, well-defined purpose
2. **Consistent Naming**: All files use kebab-case naming convention
3. **Improved Discoverability**: Developers can easily find functionality based on category
4. **Better Maintainability**: Related code is grouped together
5. **Professional Structure**: The naming and organization follows modern best practices
## Migration Impact
- All import paths have been updated throughout the codebase
- No functionality changes, only organizational improvements
- Build succeeds with no errors
- All tests continue to pass
## Future Considerations
1. Consider creating barrel exports (index.ts) for each subdirectory
2. Add README files in each subdirectory explaining the purpose and contents
3. Consider further splitting large files if they contain multiple responsibilities
4. Add JSDoc comments to exported functions for better documentation

View file

@ -1,734 +0,0 @@
# Enhanced Time Parsing API Documentation
## Overview
The Enhanced Time Parsing API extends Task Genius's existing time parsing capabilities to support granular time recognition including single times, time ranges, and intelligent date inheritance. This document provides comprehensive developer guidance for working with the enhanced time parsing system.
## Core Interfaces
### TimeComponent
The `TimeComponent` interface represents a parsed time value with validation and range support.
```typescript
interface TimeComponent {
/** Hour (0-23) */
hour: number;
/** Minute (0-59) */
minute: number;
/** Second (0-59, optional) */
second?: number;
/** Original text that was parsed */
originalText: string;
/** Whether this is part of a time range */
isRange: boolean;
/** Range partner (for start/end time pairs) */
rangePartner?: TimeComponent;
}
```
#### Usage Example
```typescript
// Creating a TimeComponent for 2:30 PM
const timeComponent: TimeComponent = {
hour: 14,
minute: 30,
originalText: "2:30 PM",
isRange: false
};
// Creating a time range (9:00-17:00)
const startTime: TimeComponent = {
hour: 9,
minute: 0,
originalText: "9:00-17:00",
isRange: true,
rangePartner: endTime
};
const endTime: TimeComponent = {
hour: 17,
minute: 0,
originalText: "9:00-17:00",
isRange: true,
rangePartner: startTime
};
```
### EnhancedParsedTimeResult
Extends the existing `ParsedTimeResult` to include time component information.
```typescript
interface EnhancedParsedTimeResult extends ParsedTimeResult {
// Time-specific components
timeComponents: {
startTime?: TimeComponent;
endTime?: TimeComponent;
dueTime?: TimeComponent;
scheduledTime?: TimeComponent;
};
// Enhanced expressions with time information
parsedExpressions: Array<EnhancedTimeExpression>;
}
```
#### Usage Example
```typescript
import { TimeParsingService } from '../services/time-parsing-service';
const timeParser = new TimeParsingService();
const result: EnhancedParsedTimeResult = await timeParser.parseTimeExpressions(
"Meeting tomorrow 2:30 PM - 4:00 PM"
);
// Access parsed time components
if (result.timeComponents.startTime) {
console.log(`Start: ${result.timeComponents.startTime.hour}:${result.timeComponents.startTime.minute}`);
}
if (result.timeComponents.endTime) {
console.log(`End: ${result.timeComponents.endTime.hour}:${result.timeComponents.endTime.minute}`);
}
```
### EnhancedTimeExpression
Represents a parsed time expression with enhanced metadata.
```typescript
interface EnhancedTimeExpression {
text: string;
date: Date;
type: "start" | "due" | "scheduled";
index: number;
length: number;
// New time-specific fields
timeComponent?: TimeComponent;
isTimeRange: boolean;
rangeStart?: TimeComponent;
rangeEnd?: TimeComponent;
}
```
### EnhancedStandardTaskMetadata
Extends task metadata to include time components alongside existing timestamp fields.
```typescript
interface EnhancedStandardTaskMetadata extends StandardTaskMetadata {
// Time-specific metadata (separate from date timestamps)
timeComponents?: {
/** Start time component */
startTime?: TimeComponent;
/** End time component (for time ranges) */
endTime?: TimeComponent;
/** Due time component */
dueTime?: TimeComponent;
/** Scheduled time component */
scheduledTime?: TimeComponent;
};
// Enhanced date fields that combine date + time
enhancedDates?: {
/** Full datetime for start (combines startDate + startTime) */
startDateTime?: Date;
/** Full datetime for end (combines date + endTime) */
endDateTime?: Date;
/** Full datetime for due (combines dueDate + dueTime) */
dueDateTime?: Date;
/** Full datetime for scheduled (combines scheduledDate + scheduledTime) */
scheduledDateTime?: Date;
};
}
```
## TimeParsingService API
### Core Methods
#### parseTimeComponents(text: string): Promise<TimeComponent[]>
Extracts time components from text without processing dates.
```typescript
const timeParser = new TimeParsingService();
// Parse single time
const singleTime = await timeParser.parseTimeComponents("Meeting at 2:30 PM");
// Returns: [{ hour: 14, minute: 30, originalText: "2:30 PM", isRange: false }]
// Parse time range
const timeRange = await timeParser.parseTimeComponents("Workshop 9:00-17:00");
// Returns: [
// { hour: 9, minute: 0, originalText: "9:00-17:00", isRange: true, rangePartner: endTime },
// { hour: 17, minute: 0, originalText: "9:00-17:00", isRange: true, rangePartner: startTime }
// ]
```
#### parseTimeExpressions(text: string): Promise<EnhancedParsedTimeResult>
Enhanced version of the existing method that includes time component parsing.
```typescript
const result = await timeParser.parseTimeExpressions("Project due tomorrow 5:00 PM");
// Access both date and time information
console.log(result.parsedExpressions[0].date); // Date object for tomorrow
console.log(result.timeComponents.dueTime?.hour); // 17
console.log(result.timeComponents.dueTime?.minute); // 0
```
#### combineDateTime(date: Date, timeComponent: TimeComponent): Date
Utility method to combine date and time components into a full datetime object.
```typescript
const date = new Date('2024-12-25');
const timeComponent: TimeComponent = { hour: 14, minute: 30, originalText: "2:30 PM", isRange: false };
const combinedDateTime = timeParser.combineDateTime(date, timeComponent);
// Returns: Date object for 2024-12-25 14:30:00
```
### Configuration
#### EnhancedTimeParsingConfig
Configure time parsing behavior through the enhanced configuration interface.
```typescript
interface EnhancedTimeParsingConfig extends TimeParsingConfig {
timePatterns: {
/** Single time patterns (12:00, 12:00:00, 1:30 PM) */
singleTime: RegExp[];
/** Time range patterns (12:00-13:00, 12:00 - 13:00, 12:00~13:00) */
timeRange: RegExp[];
/** Time separators for ranges */
rangeSeparators: string[];
};
timeDefaults: {
/** Default format preference (12-hour vs 24-hour) */
preferredFormat: "12h" | "24h";
/** Default AM/PM when ambiguous */
defaultPeriod: "AM" | "PM";
/** How to handle midnight crossing ranges */
midnightCrossing: "next-day" | "same-day" | "error";
};
}
```
#### Usage Example
```typescript
const config: EnhancedTimeParsingConfig = {
// ... existing config
timeDefaults: {
preferredFormat: "24h",
defaultPeriod: "AM",
midnightCrossing: "next-day"
}
};
const timeParser = new TimeParsingService(config);
```
## Date Inheritance API
### DateInheritanceService
Handles intelligent date resolution for time-only expressions.
```typescript
interface DateInheritanceService {
/** Resolve date for time-only expressions using priority logic */
resolveDateForTimeOnly(
task: Task,
timeComponent: TimeComponent,
context: DateResolutionContext
): Promise<DateResolutionResult>;
/** Get file-based date information with caching */
getFileDateInfo(filePath: string): Promise<FileDateInfo>;
/** Extract daily note date from file path/title */
extractDailyNoteDate(filePath: string): Date | null;
}
```
#### Usage Example
```typescript
import { DateInheritanceService } from '../services/date-inheritance-service';
const dateService = new DateInheritanceService();
const context: DateResolutionContext = {
currentLine: "- [ ] Meeting 📅 14:30",
filePath: "Daily Notes/2024-12-25.md",
parentTask: undefined,
fileMetadataCache: new Map()
};
const timeComponent: TimeComponent = {
hour: 14,
minute: 30,
originalText: "14:30",
isRange: false
};
const result = await dateService.resolveDateForTimeOnly(task, timeComponent, context);
console.log(result.resolvedDate); // Date for 2024-12-25 14:30
console.log(result.source); // "daily-note-date"
console.log(result.confidence); // "high"
```
### DateResolutionContext
Provides context information for date resolution.
```typescript
interface DateResolutionContext {
/** Current line being parsed */
currentLine: string;
/** File path of the task */
filePath: string;
/** Parent task information for inheritance */
parentTask?: Task;
/** File metadata cache */
fileMetadataCache?: Map<string, FileDateInfo>;
}
```
### DateResolutionResult
Result of date resolution with metadata about the source and confidence.
```typescript
interface DateResolutionResult {
/** Resolved date */
resolvedDate: Date;
/** Source of the date */
source: "line-date" | "metadata-date" | "daily-note-date" | "file-ctime" | "parent-task";
/** Confidence level of the resolution */
confidence: "high" | "medium" | "low";
/** Whether fallback was used */
usedFallback: boolean;
}
```
## Timeline Integration
### EnhancedTimelineEvent
Extended timeline event interface with time information.
```typescript
interface EnhancedTimelineEvent extends TimelineEvent {
// Enhanced time information
timeInfo?: {
/** Primary time for display and sorting */
primaryTime: Date;
/** End time for ranges */
endTime?: Date;
/** Whether this is a time range */
isRange: boolean;
/** Original time component from parsing */
timeComponent?: TimeComponent;
/** Display format preference */
displayFormat: "time-only" | "date-time" | "range";
};
}
```
#### Usage Example
```typescript
// Creating an enhanced timeline event
const timelineEvent: EnhancedTimelineEvent = {
// ... existing TimelineEvent properties
timeInfo: {
primaryTime: new Date('2024-12-25T14:30:00'),
endTime: new Date('2024-12-25T16:00:00'),
isRange: true,
timeComponent: startTimeComponent,
displayFormat: "range"
}
};
```
## Error Handling
### TimeParsingError
Structured error information for time parsing failures.
```typescript
interface TimeParsingError {
type: "invalid-format" | "midnight-crossing" | "ambiguous-time" | "range-error";
originalText: string;
position: number;
message: string;
fallbackUsed: boolean;
fallbackValue?: TimeComponent;
}
```
### EnhancedParseResult
Comprehensive result structure with error handling.
```typescript
interface EnhancedParseResult {
success: boolean;
result?: EnhancedParsedTimeResult;
errors: TimeParsingError[];
warnings: string[];
}
```
#### Usage Example
```typescript
const parseResult: EnhancedParseResult = await timeParser.parseWithErrorHandling(
"Invalid time format 25:70"
);
if (!parseResult.success) {
parseResult.errors.forEach(error => {
console.error(`Time parsing error: ${error.message}`);
if (error.fallbackUsed && error.fallbackValue) {
console.log(`Using fallback: ${error.fallbackValue.hour}:${error.fallbackValue.minute}`);
}
});
}
```
## Migration Strategies
### Automatic Task Enhancement
Existing tasks are automatically enhanced when accessed through the new API:
```typescript
import { TaskMigrationService } from '../services/task-migration-service';
const migrationService = new TaskMigrationService();
// Migrate existing task to enhanced format
const enhancedTask = migrationService.migrateTaskToEnhanced(existingTask);
// Check if task has enhanced metadata
if (enhancedTask.metadata.timeComponents) {
console.log("Task has enhanced time information");
}
```
### Backward Compatibility
The enhanced API maintains full backward compatibility:
```typescript
// Existing code continues to work
const oldResult = await timeParser.parseTimeExpressions("tomorrow 5pm");
console.log(oldResult.parsedExpressions[0].date); // Still works
// New features are additive
if (oldResult.timeComponents?.dueTime) {
console.log("Enhanced time info available");
}
```
### Gradual Migration
For large codebases, migrate incrementally:
```typescript
// 1. Update type annotations to enhanced interfaces
function processTask(task: Task<EnhancedStandardTaskMetadata>) {
// Enhanced functionality available
if (task.metadata.timeComponents?.startTime) {
// Use enhanced time information
} else {
// Fall back to existing timestamp-based logic
}
}
// 2. Update parsing calls to use enhanced methods
const result = await timeParser.parseTimeExpressions(text);
// Enhanced result includes both old and new fields
// 3. Update UI components to display enhanced information
if (result.timeComponents?.startTime) {
displayEnhancedTime(result.timeComponents.startTime);
} else {
displayBasicTime(result.parsedExpressions[0].date);
}
```
## Performance Considerations
### Caching Strategies
The enhanced time parsing system includes several performance optimizations:
```typescript
// File metadata caching
const fileCache = new Map<string, FileDateInfo>();
const context: DateResolutionContext = {
// ... other properties
fileMetadataCache: fileCache
};
// Reuse cache across multiple parsing operations
const result1 = await dateService.resolveDateForTimeOnly(task1, time1, context);
const result2 = await dateService.resolveDateForTimeOnly(task2, time2, context);
```
### Batch Processing
For processing multiple tasks efficiently:
```typescript
// Batch process tasks with shared context
const tasks = await getAllTasks();
const batchContext = await createBatchContext(tasks);
const enhancedTasks = await Promise.all(
tasks.map(task => enhanceTaskWithTimeInfo(task, batchContext))
);
```
### Memory Management
Time components are lightweight objects, but for large datasets:
```typescript
// Use weak references for temporary time components
const timeComponentCache = new WeakMap<Task, TimeComponent[]>();
// Clean up enhanced metadata when not needed
function cleanupEnhancedMetadata(task: Task) {
if (task.metadata.enhancedDates) {
delete task.metadata.enhancedDates;
}
}
```
## Testing Utilities
### Mock Time Components
```typescript
// Test utilities for creating mock time components
export function createMockTimeComponent(
hour: number,
minute: number,
options: Partial<TimeComponent> = {}
): TimeComponent {
return {
hour,
minute,
originalText: `${hour}:${minute.toString().padStart(2, '0')}`,
isRange: false,
...options
};
}
// Create mock time ranges
export function createMockTimeRange(
startHour: number,
startMinute: number,
endHour: number,
endMinute: number
): [TimeComponent, TimeComponent] {
const originalText = `${startHour}:${startMinute}-${endHour}:${endMinute}`;
const startTime: TimeComponent = {
hour: startHour,
minute: startMinute,
originalText,
isRange: true,
rangePartner: undefined // Will be set below
};
const endTime: TimeComponent = {
hour: endHour,
minute: endMinute,
originalText,
isRange: true,
rangePartner: startTime
};
startTime.rangePartner = endTime;
return [startTime, endTime];
}
```
### Test Examples
```typescript
describe('Enhanced Time Parsing', () => {
let timeParser: TimeParsingService;
beforeEach(() => {
timeParser = new TimeParsingService();
});
test('should parse single time correctly', async () => {
const result = await timeParser.parseTimeComponents("Meeting at 2:30 PM");
expect(result).toHaveLength(1);
expect(result[0].hour).toBe(14);
expect(result[0].minute).toBe(30);
expect(result[0].isRange).toBe(false);
});
test('should parse time range correctly', async () => {
const result = await timeParser.parseTimeComponents("Workshop 9:00-17:00");
expect(result).toHaveLength(2);
expect(result[0].hour).toBe(9);
expect(result[1].hour).toBe(17);
expect(result[0].isRange).toBe(true);
expect(result[1].isRange).toBe(true);
expect(result[0].rangePartner).toBe(result[1]);
});
});
```
## Best Practices
### API Usage
1. **Always check for enhanced metadata availability**:
```typescript
if (task.metadata.timeComponents?.startTime) {
// Use enhanced time information
} else {
// Fall back to timestamp-based logic
}
```
2. **Use type guards for enhanced interfaces**:
```typescript
function isEnhancedTask(task: Task): task is Task<EnhancedStandardTaskMetadata> {
return 'timeComponents' in task.metadata;
}
```
3. **Handle errors gracefully**:
```typescript
try {
const result = await timeParser.parseTimeExpressions(text);
// Process result
} catch (error) {
// Fall back to basic date parsing
const basicResult = await timeParser.parseBasicDates(text);
}
```
### Performance Optimization
1. **Cache file metadata for batch operations**
2. **Use lazy loading for enhanced metadata**
3. **Implement proper cleanup for temporary objects**
4. **Consider memory usage in large datasets**
### Integration Guidelines
1. **Maintain backward compatibility in all public APIs**
2. **Provide migration utilities for existing integrations**
3. **Document breaking changes clearly**
4. **Use feature flags for gradual rollout**
## Examples and Recipes
### Common Integration Patterns
#### Task Creation with Enhanced Time Parsing
```typescript
async function createTaskWithTime(text: string, filePath: string): Promise<Task> {
const timeParser = new TimeParsingService();
const dateService = new DateInheritanceService();
// Parse time expressions
const parseResult = await timeParser.parseTimeExpressions(text);
// Create base task
const task: Task = {
// ... basic task properties
metadata: {
// ... basic metadata
}
};
// Add enhanced time information if available
if (parseResult.timeComponents) {
const enhancedMetadata: EnhancedStandardTaskMetadata = {
...task.metadata,
timeComponents: parseResult.timeComponents
};
// Resolve dates for time-only expressions
if (parseResult.timeComponents.startTime && !parseResult.parsedExpressions[0]?.date) {
const context: DateResolutionContext = {
currentLine: text,
filePath,
parentTask: undefined
};
const dateResult = await dateService.resolveDateForTimeOnly(
task,
parseResult.timeComponents.startTime,
context
);
enhancedMetadata.enhancedDates = {
startDateTime: timeParser.combineDateTime(
dateResult.resolvedDate,
parseResult.timeComponents.startTime
)
};
}
task.metadata = enhancedMetadata;
}
return task;
}
```
#### Timeline Event Enhancement
```typescript
function createEnhancedTimelineEvent(task: Task): EnhancedTimelineEvent {
const baseEvent: TimelineEvent = {
// ... create base timeline event
};
if (isEnhancedTask(task) && task.metadata.timeComponents?.startTime) {
const timeComponent = task.metadata.timeComponents.startTime;
const enhancedEvent: EnhancedTimelineEvent = {
...baseEvent,
timeInfo: {
primaryTime: task.metadata.enhancedDates?.startDateTime || baseEvent.date,
endTime: task.metadata.enhancedDates?.endDateTime,
isRange: timeComponent.isRange,
timeComponent,
displayFormat: timeComponent.isRange ? "range" : "time-only"
}
};
return enhancedEvent;
}
return baseEvent;
}
```
This comprehensive API documentation provides developers with all the necessary information to integrate with and extend the enhanced time parsing system while maintaining backward compatibility and following best practices.

View file

@ -1,487 +0,0 @@
# FileSource Implementation Tracking
## Overview
This document tracks the implementation progress of the FileSource feature, which enables files to be recognized as tasks based on their metadata properties. The implementation follows the dataflow architecture patterns and integrates seamlessly with existing functionality.
## Task Breakdown
### Phase 1: Core Infrastructure (Week 1-2)
#### TypeScript Definitions
- [x] Create `src/types/file-source.d.ts`
- [x] `FileSourceTaskMetadata` interface
- [x] `FileSourceConfiguration` interface
- [x] `RecognitionStrategy` interface
- [x] `FileSourceStats` interface
- [x] Recognition strategy type definitions
#### Configuration Management
- [x] Create `src/dataflow/sources/FileSourceConfig.ts`
- [x] Configuration validation logic
- [x] Default configuration constants
- [x] Configuration update handlers
- [x] Strategy-specific configuration management
#### Basic FileSource Implementation
- [x] Create `src/dataflow/sources/FileSource.ts`
- [x] Basic source initialization
- [x] Event subscription to FILE_UPDATED
- [ ] Granular event subscriptions (FILE_METADATA_CHANGED, FILE_CONTENT_CHANGED)
- [x] Basic file task detection
- [x] Smart update detection integration (basic implementation)
- [x] Selective property updates (updateFileTaskProperties)
- [x] Selective children updates (updateFileTaskChildren)
- [x] Event emission for file task updates
- [x] Basic cleanup and destroy methods
#### Settings Integration
- [x] Update `src/common/setting-definition.ts`
- [x] Add FileSourceConfiguration to TaskProgressBarSettings
- [x] Update DEFAULT_SETTINGS with FileSource defaults
- [x] Add validation for FileSource settings
- [x] Create settings UI components
- [x] `src/components/settings/FileSourceSettings.ts`
- [x] Recognition strategy configuration panels
- [x] File task properties configuration
- [x] Performance settings interface
#### Unit Tests
- [x] Create `src/__tests__/file-source/`
- [x] `FileSourceConfig.test.ts` - Configuration validation tests
- [x] `FileSource.basic.test.ts` - Basic functionality tests
- [ ] `FileSourceUpdateDetector.test.ts` - Update detection logic tests (Phase 2)
- [ ] Test metadata change detection
- [ ] Test content change detection
- [ ] Test children structure detection
- [ ] Test hash comparison logic
- [ ] `RecognitionStrategies.test.ts` - Strategy testing framework (Phase 2)
### Phase 2: Recognition Strategies (Week 3-4)
#### Update Detection System
- [ ] Create `src/dataflow/sources/FileSourceUpdateDetector.ts`
- [ ] Update decision logic implementation
- [ ] Change type analysis (metadata vs content)
- [ ] Children structure change detection
- [ ] Previous state caching mechanism
- [ ] Hash-based property comparison
- [ ] Performance metrics collection
#### Core Parser Implementation
- [ ] Create `src/dataflow/parsers/FileSourceParser.ts`
- [ ] Base recognition strategy framework
- [ ] Metadata extraction utilities
- [ ] File content analysis helpers
- [ ] Strategy result aggregation
- [ ] Selective parsing for updates
#### Metadata-Based Recognition
- [ ] Implement metadata recognition strategy
- [ ] Frontmatter field checking
- [ ] Required vs optional field logic
- [ ] Metadata validation and parsing
- [ ] Default value assignment
#### Tag-Based Recognition
- [ ] Implement tag recognition strategy
- [ ] Tag pattern matching (exact, prefix, contains)
- [ ] Tag extraction from file cache
- [ ] Multiple tag requirement logic
- [ ] Tag-based metadata extraction
#### Template-Based Recognition
- [ ] Implement template recognition strategy
- [ ] Template path matching
- [ ] Template metadata inheritance
- [ ] Template instance detection
- [ ] Template-specific configuration
#### Path-Based Recognition
- [ ] Implement path recognition strategy
- [ ] Path pattern matching (prefix, regex, glob)
- [ ] Path-based metadata assignment
- [ ] Exclude pattern handling
- [ ] Path hierarchy analysis
#### Parser Entry Point
- [ ] Create `src/dataflow/parsers/FileSourceEntry.ts`
- [ ] Integration with existing parser architecture
- [ ] Strategy orchestration
- [ ] Result merging and conflict resolution
- [ ] Performance optimization
#### Strategy Testing
- [ ] Comprehensive strategy tests
- [ ] `MetadataStrategy.test.ts`
- [ ] `TagStrategy.test.ts`
- [ ] `TemplateStrategy.test.ts`
- [ ] `PathStrategy.test.ts`
- [ ] Strategy integration tests
### Phase 3: Integration & Augmentation (Week 5-6)
#### File Task Augmentation
- [ ] Create `src/dataflow/augment/FileSourceAugmentor.ts`
- [ ] File task metadata enhancement
- [ ] Child task relationship building
- [ ] Metadata inheritance implementation
- [ ] Project data integration
#### Repository Integration
- [ ] Update `src/dataflow/indexer/Repository.ts`
- [ ] File task storage and indexing
- [ ] File task query methods
- [ ] Integration with existing task cache
- [ ] Event handling for file task updates
#### Event System Integration
- [ ] Update `src/dataflow/events/Events.ts`
- [ ] Add FileSource event types
- [ ] Add granular update events (FILE_METADATA_CHANGED, FILE_CONTENT_CHANGED)
- [ ] Add specific file task events (FILE_TASK_PROPERTY_CHANGED, FILE_TASK_CHILDREN_CHANGED)
- [ ] Add INLINE_TASK_CONTENT_CHANGED event
- [ ] Event payload definitions
- [ ] Sequence tracking for file tasks
- [ ] Update `src/dataflow/Orchestrator.ts`
- [ ] FileSource initialization
- [ ] Event routing for file tasks
- [ ] Integration with existing sources
- [ ] Granular event handling logic
#### Child Task Relationships
- [ ] Implement child task management
- [ ] Parent-child relationship tracking
- [ ] Child task discovery within files
- [ ] Relationship updates on file changes
- [ ] Orphaned task cleanup
#### Metadata Inheritance System
- [ ] Implement inheritance logic
- [ ] Configurable inheritance fields
- [ ] Inheritance priority resolution
- [ ] Update propagation to child tasks
- [ ] Inheritance conflict resolution
#### Integration Tests
- [ ] End-to-end integration testing
- [ ] `FileSourceDataflow.test.ts`
- [ ] `FileTaskRelationships.test.ts`
- [ ] `MetadataInheritance.test.ts`
- [ ] `EventFlow.test.ts`
### Phase 4: Performance & Polish (Week 7-8)
#### Specialized Indexing
- [ ] Create `src/dataflow/indexer/FileSourceIndex.ts`
- [ ] Optimized file task indexing
- [ ] Fast lookup structures
- [ ] Batch update operations
- [ ] Memory-efficient storage
#### Worker Integration
- [ ] Update worker system for file tasks
- [ ] `src/dataflow/workers/FileSourceWorker.ts`
- [ ] Background file task processing
- [ ] Worker message protocol
- [ ] Performance monitoring
#### Caching Implementation
- [ ] Create `src/dataflow/indexer/FileTaskCache.ts`
- [ ] File task state caching structure
- [ ] Frontmatter hash implementation
- [ ] Children ID set management
- [ ] Recognition result caching
- [ ] TTL-based cache invalidation
- [ ] Memory usage optimization
- [ ] Cache performance metrics
- [ ] State comparison utilities
#### Settings UI Enhancement
- [ ] Advanced settings components
- [ ] Strategy priority configuration
- [ ] Custom recognition function editor
- [ ] Performance tuning interface
- [ ] Diagnostic tools
#### Performance Testing
- [ ] Performance benchmark suite
- [ ] Large vault testing (1000+ files)
- [ ] Recognition performance metrics
- [ ] Memory usage profiling
- [ ] Worker performance validation
- [ ] Update detection performance tests
- [ ] Rapid file changes scenario
- [ ] Large file with many tasks
- [ ] Metadata-only updates
- [ ] Content-only updates
- [ ] Mixed update patterns
- [ ] `PerformanceOptimization.test.ts`
- [ ] Test early exit patterns
- [ ] Test selective processing
- [ ] Test cache hit rates
- [ ] Test event deduplication
#### Documentation
- [ ] User documentation
- [ ] Feature overview guide
- [ ] Configuration examples
- [ ] Troubleshooting guide
- [ ] Best practices document
### Phase 5: Advanced Features (Week 9-10)
#### Custom Recognition Functions
- [ ] Implement custom function support
- [ ] JavaScript function parsing
- [ ] Sandboxed execution environment
- [ ] Function validation and testing
- [ ] Error handling and logging
#### Advanced Conflict Resolution
- [ ] Sophisticated conflict handling
- [ ] Dual role (project/task) management
- [ ] Metadata priority rules
- [ ] User-defined resolution strategies
- [ ] Conflict notification system
#### Bulk Operations
- [ ] Bulk file task operations
- [ ] Batch file task creation
- [ ] Bulk metadata updates
- [ ] Batch recognition re-evaluation
- [ ] Progress reporting for bulk ops
#### Export/Import Functionality
- [ ] File task data portability
- [ ] Export file task configurations
- [ ] Import recognition strategies
- [ ] Backup and restore functionality
- [ ] Migration tools
#### Advanced Filtering
- [ ] Enhanced query capabilities
- [ ] File task specific filters
- [ ] Recognition strategy filtering
- [ ] Child task aggregation filters
- [ ] Custom filter expressions
## File Structure and Components
### New Files to Create
```
src/
├── types/
│ └── file-source.d.ts # Core type definitions
├── dataflow/
│ ├── sources/
│ │ ├── FileSource.ts # Main FileSource implementation
│ │ ├── FileSourceConfig.ts # Configuration management
│ │ └── FileSourceUpdateDetector.ts # Update detection logic
│ ├── parsers/
│ │ ├── FileSourceEntry.ts # Parser entry point
│ │ └── FileSourceParser.ts # Recognition strategies
│ ├── augment/
│ │ └── FileSourceAugmentor.ts # File task augmentation
│ ├── indexer/
│ │ ├── FileSourceIndex.ts # Specialized indexing
│ │ └── FileTaskCache.ts # File task state caching
│ └── workers/
│ └── FileSourceWorker.ts # Background processing
├── components/
│ └── settings/
│ └── FileSourceSettings.ts # Settings UI
└── __tests__/
└── file-source/
├── FileSourceConfig.test.ts
├── FileSource.basic.test.ts
├── FileSourceUpdateDetector.test.ts
├── RecognitionStrategies.test.ts
├── MetadataStrategy.test.ts
├── TagStrategy.test.ts
├── TemplateStrategy.test.ts
├── PathStrategy.test.ts
├── FileSourceDataflow.test.ts
├── FileTaskRelationships.test.ts
├── MetadataInheritance.test.ts
├── EventFlow.test.ts
└── PerformanceOptimization.test.ts
```
### Files to Modify
```
src/
├── common/
│ └── setting-definition.ts # Add FileSource configuration
├── dataflow/
│ ├── events/
│ │ └── Events.ts # Add FileSource events and granular update events
│ ├── sources/
│ │ └── ObsidianSource.ts # Emit granular events (FILE_METADATA_CHANGED, FILE_CONTENT_CHANGED)
│ ├── indexer/
│ │ └── Repository.ts # File task integration
│ ├── Orchestrator.ts # FileSource initialization
│ └── createDataflow.ts # Factory updates
├── components/
│ └── settings/
│ └── TaskProgressBarSettingTab.ts # Settings integration
└── index.ts # Plugin initialization
```
## Dependencies and Integration Points
### Internal Dependencies
- **Dataflow Architecture**: Core event system, repository, orchestrator
- **Project System**: Resolver, ProjectConfigManager, ProjectDataCache
- **Task System**: Task types, metadata, parsing infrastructure
- **Settings System**: Setting definitions, UI components, validation
- **Worker System**: TaskWorkerManager, worker orchestration
### External Dependencies
- **Obsidian API**: Vault, MetadataCache, TFile, FileSystemAdapter
- **File System**: Path manipulation, file watching, metadata extraction
- **Performance**: Worker threads, caching, batch processing
### Integration Points
1. **Event System**: FILE_UPDATED → FileSource → FILE_TASK_UPDATED
2. **Repository**: File task storage alongside regular tasks
3. **QueryAPI**: Extended queries for file tasks
4. **Views**: File tasks displayed in all task views
5. **Project System**: Dual role management and conflict resolution
## Progress Tracking Sections
### Week 1-2: Core Infrastructure
**Status**: ✅ Completed
**Target Completion**: 2025-08-20
**Completion**: 20/25 tasks (80% - Core functionality complete)
**Priority Tasks**:
- [x] Core type definitions
- [x] Basic FileSource implementation
- [x] Settings integration
- [x] Initial unit tests
**Implementation Notes**:
- Core FileSource infrastructure is fully functional
- Metadata and tag-based recognition strategies implemented
- Comprehensive configuration system with validation
- Full test coverage for core components
- TypeScript compilation passing without errors
- Ready for Phase 2 implementation
### Week 3-4: Recognition Strategies
**Status**: ⏳ Not Started
**Target Completion**: [Date]
**Completion**: 0/18 tasks
**Priority Tasks**:
- [ ] Metadata-based recognition
- [ ] Tag-based recognition
- [ ] Strategy testing framework
- [ ] Parser entry point
### Week 5-6: Integration & Augmentation
**Status**: ⏳ Not Started
**Target Completion**: [Date]
**Completion**: 0/22 tasks
**Priority Tasks**:
- [ ] Repository integration
- [ ] Event system integration
- [ ] Child task relationships
- [ ] Metadata inheritance
### Week 7-8: Performance & Polish
**Status**: ⏳ Not Started
**Target Completion**: [Date]
**Completion**: 0/18 tasks
**Priority Tasks**:
- [ ] Worker integration
- [ ] Caching implementation
- [ ] Performance testing
- [ ] User documentation
### Week 9-10: Advanced Features
**Status**: ⏳ Not Started
**Target Completion**: [Date]
**Completion**: 0/15 tasks
**Priority Tasks**:
- [ ] Custom recognition functions
- [ ] Bulk operations
- [ ] Advanced filtering
- [ ] Export/import functionality
## Risk Assessment
### High Risk Items
- **Performance Impact**: Large vaults with many files could impact startup time
- *Mitigation*: Worker-based processing, selective file scanning, caching
- **Memory Usage**: File tasks add to memory footprint
- *Mitigation*: Efficient indexing, lazy loading, configurable limits
- **Conflict Resolution**: Dual role files may create complex scenarios
- *Mitigation*: Clear precedence rules, user configuration options
### Medium Risk Items
- **Configuration Complexity**: Many options may overwhelm users
- *Mitigation*: Sensible defaults, configuration wizard, presets
- **Event Loop Performance**: Additional event processing overhead
- *Mitigation*: Debounced events, batch processing, sequence optimization
### Low Risk Items
- **Backward Compatibility**: New feature shouldn't break existing functionality
- *Mitigation*: Feature flag, disabled by default, comprehensive testing
## Success Metrics
### Functional Metrics
- [ ] All recognition strategies working correctly
- [ ] File tasks appear in all relevant views
- [ ] Child task relationships functioning
- [ ] Metadata inheritance working
- [ ] Settings interface complete and intuitive
### Performance Metrics
- [ ] File task detection under 100ms for typical files
- [ ] Memory usage increase under 10% for equivalent functionality
- [ ] No noticeable impact on plugin startup time
- [ ] Worker processing provides measurable performance benefits
### Quality Metrics
- [ ] 90%+ test coverage for FileSource components
- [ ] Zero regression in existing functionality
- [ ] User documentation complete and clear
- [ ] Configuration examples working as documented
## Notes and Decisions
### Architecture Decisions
- **FileSource as separate source**: Maintains clean separation from ObsidianSource
- **Event-driven integration**: Leverages existing event system for consistency
- **Strategy pattern**: Allows flexible recognition approaches
- **Metadata extension**: Extends existing task metadata rather than creating new types
### Configuration Decisions
- **Disabled by default**: Conservative rollout approach
- **Multiple strategies**: Accommodates different user workflows
- **Extensive configuration**: Provides flexibility while maintaining usability
### Performance Decisions
- **Worker integration**: Maintains UI responsiveness
- **Caching strategy**: Balances memory usage with performance
- **Selective processing**: Avoid processing irrelevant files
---
**Last Updated**: [Current Date]
**Document Version**: 1.0
**Next Review**: [Date]

View file

@ -1,613 +0,0 @@
# FileSource Feature Specification
## Overview
The FileSource feature extends the dataflow architecture to recognize files themselves as tasks based on their metadata properties. This enables a dual-role model where a file can simultaneously serve as both a Project (container for tasks) and a FileSource Task (a task with its own properties like due dates, status, etc.).
## Architecture Alignment
### Dataflow Integration
FileSource integrates seamlessly into the existing dataflow architecture following established patterns:
- **Source Pattern**: Follows the same pattern as `ObsidianSource` and `IcsSource`
- **Event-Driven**: Uses the centralized event system with proper sequence tracking
- **Separation of Concerns**: Maintains clear boundaries between parsing, augmentation, repository, and storage
- **Performance**: Leverages existing worker orchestration and caching mechanisms
### Key Design Principles
1. **Non-Intrusive**: Builds on existing file metadata parsing without breaking current functionality
2. **Dual Role Support**: A file can be both a Project and a Task without conflicts
3. **Flexible Recognition**: Multiple strategies for identifying files as tasks
4. **Configuration-Driven**: Extensive configuration options for different use cases
## Core Concepts
### File as Task
A file becomes a FileSource Task when it meets configured recognition criteria:
- **Metadata-Based**: File has specific frontmatter properties (e.g., `dueDate`, `status`, `priority`)
- **Tag-Based**: File contains specific tags (e.g., `#task`, `#project-task`, `#actionable`)
- **Template-Based**: File is created from or matches specific templates
- **Path-Based**: File location matches configured patterns
### Dual Role Model
Files can simultaneously serve as:
1. **Project**: Container for child tasks within the file
2. **FileSource Task**: A task entity with its own metadata and lifecycle
This dual role is managed through:
- **Namespace Separation**: Project data vs. task data are kept distinct
- **Hierarchical Relationships**: File-tasks can contain child tasks from within the file
- **Status Independence**: File status is separate from contained task statuses
### Relationship with Projects
FileSource integrates with the existing Project system:
- **Project Enhancement**: Files that are Projects can also be tasks
- **Hierarchy Preservation**: Existing project hierarchies remain intact
- **Metadata Inheritance**: Child tasks can inherit metadata from file-tasks
- **Conflict Resolution**: Clear rules for handling conflicts between project and task metadata
## Technical Design
### Architecture Components
```
src/dataflow/sources/
├── FileSource.ts # Main FileSource implementation
└── FileSourceConfig.ts # Configuration management
src/dataflow/parsers/
├── FileSourceEntry.ts # File-to-task parsing entry point
└── FileSourceParser.ts # Core file metadata → task conversion
src/dataflow/augment/
└── FileSourceAugmentor.ts # File task augmentation logic
src/dataflow/indexer/
└── FileSourceIndex.ts # Specialized indexing for file tasks
src/types/
└── file-source.d.ts # TypeScript definitions
```
### Data Flow
```
1. File Change → ObsidianSource → FILE_UPDATED event
2. FileSource subscribes to FILE_UPDATED events
3. FileSource evaluates recognition criteria
4. If match: FileSource → FILE_TASK_UPDATED event
5. Orchestrator → Repository.updateFileTasks()
6. Repository → TASK_CACHE_UPDATED event (with sourceSeq)
7. Views update with merged file tasks + regular tasks
```
### Event System
New events added to the centralized event system:
```typescript
Events = {
// ... existing events
FILE_TASK_DETECTED: "task-genius:file-task-detected",
FILE_TASK_UPDATED: "task-genius:file-task-updated",
FILE_TASK_REMOVED: "task-genius:file-task-removed",
}
```
### Task Metadata Extension
File tasks use extended metadata:
```typescript
interface FileSourceTaskMetadata extends StandardTaskMetadata {
/** Task source */
source: "file-source";
/** Recognition strategy that identified this file as a task */
recognitionStrategy: "metadata" | "tag" | "template" | "path";
/** Recognition criteria that matched */
recognitionCriteria: string;
/** File creation/modification timestamps */
fileTimestamps: {
created: number;
modified: number;
};
/** Child task relationships */
childTasks: string[]; // IDs of tasks within this file
/** Project relationship (if file is also a project) */
projectData?: {
isProject: boolean;
projectName?: string;
projectType?: string;
};
}
```
## Configuration Schema
### FileSource Configuration
```typescript
interface FileSourceConfiguration {
/** Enable FileSource feature */
enabled: boolean;
/** Recognition strategies */
recognitionStrategies: {
/** Metadata-based recognition */
metadata: {
enabled: boolean;
/** Metadata fields that make a file a task */
taskFields: string[]; // Default: ["dueDate", "status", "priority", "assigned"]
/** Require all fields or any field */
requireAllFields: boolean; // Default: false
};
/** Tag-based recognition */
tags: {
enabled: boolean;
/** Tags that make a file a task */
taskTags: string[]; // Default: ["#task", "#actionable", "#todo"]
/** Tag matching mode */
matchMode: "exact" | "prefix" | "contains"; // Default: "exact"
};
/** Template-based recognition */
templates: {
enabled: boolean;
/** Template files or patterns */
templatePaths: string[]; // Default: ["Templates/Task Template.md"]
/** Check template metadata */
checkTemplateMetadata: boolean; // Default: true
};
/** Path-based recognition */
paths: {
enabled: boolean;
/** Path patterns that contain file tasks */
taskPaths: string[]; // Default: ["Projects/", "Tasks/"]
/** Pattern matching mode */
matchMode: "prefix" | "regex" | "glob"; // Default: "prefix"
};
};
/** File task properties */
fileTaskProperties: {
/** Default task content source */
contentSource: "filename" | "title" | "h1" | "custom"; // Default: "filename"
/** Custom content field (if contentSource is "custom") */
customContentField?: string;
/** Strip file extension from content */
stripExtension: boolean; // Default: true
/** Default status for new file tasks */
defaultStatus: string; // Default: " "
/** Default priority for new file tasks */
defaultPriority?: number;
};
/** Relationship configuration */
relationships: {
/** Enable file-task to child-task relationships */
enableChildRelationships: boolean; // Default: true
/** Inherit metadata from file to child tasks */
enableMetadataInheritance: boolean; // Default: true
/** Metadata fields to inherit */
inheritanceFields: string[]; // Default: ["project", "priority", "context"]
};
/** Performance configuration */
performance: {
/** Enable worker processing for file tasks */
enableWorkerProcessing: boolean; // Default: true
/** Cache file task results */
enableCaching: boolean; // Default: true
/** Cache TTL in milliseconds */
cacheTTL: number; // Default: 300000 (5 minutes)
};
}
```
### Default Configuration
```typescript
const DEFAULT_FILE_SOURCE_CONFIG: FileSourceConfiguration = {
enabled: false,
recognitionStrategies: {
metadata: {
enabled: true,
taskFields: ["dueDate", "status", "priority", "assigned"],
requireAllFields: false
},
tags: {
enabled: true,
taskTags: ["#task", "#actionable", "#todo"],
matchMode: "exact"
},
templates: {
enabled: false,
templatePaths: ["Templates/Task Template.md"],
checkTemplateMetadata: true
},
paths: {
enabled: false,
taskPaths: ["Projects/", "Tasks/"],
matchMode: "prefix"
}
},
fileTaskProperties: {
contentSource: "filename",
stripExtension: true,
defaultStatus: " ",
defaultPriority: undefined
},
relationships: {
enableChildRelationships: true,
enableMetadataInheritance: true,
inheritanceFields: ["project", "priority", "context"]
},
performance: {
enableWorkerProcessing: true,
enableCaching: true,
cacheTTL: 300000
},
};
```
## Implementation Roadmap
### Phase 1: Core Infrastructure (Week 1-2)
**Components to Implement:**
- [ ] `src/types/file-source.d.ts` - Core type definitions
- [ ] `src/dataflow/sources/FileSourceConfig.ts` - Configuration management
- [ ] `src/dataflow/sources/FileSource.ts` - Basic source implementation
- [ ] Settings integration for FileSource configuration
- [ ] Unit tests for core components
**Deliverables:**
- Basic FileSource that can detect metadata-based file tasks
- Configuration system fully integrated
- Test coverage for core functionality
### Phase 2: Recognition Strategies (Week 3-4)
**Components to Implement:**
- [ ] `src/dataflow/parsers/FileSourceParser.ts` - Recognition strategy implementations
- [ ] `src/dataflow/parsers/FileSourceEntry.ts` - Parser entry point
- [ ] Tag-based recognition
- [ ] Template-based recognition
- [ ] Path-based recognition
- [ ] Integration tests for all strategies
**Deliverables:**
- All recognition strategies functional
- Comprehensive strategy testing
- Performance benchmarks
### Phase 3: Integration & Augmentation (Week 5-6)
**Components to Implement:**
- [ ] `src/dataflow/augment/FileSourceAugmentor.ts` - File task augmentation
- [ ] Repository integration for file tasks
- [ ] Event system integration
- [ ] Child task relationship management
- [ ] Metadata inheritance system
**Deliverables:**
- Full dataflow integration
- File-task to child-task relationships
- Metadata inheritance working
### Phase 4: Performance & Polish (Week 7-8)
**Components to Implement:**
- [ ] `src/dataflow/indexer/FileSourceIndex.ts` - Specialized indexing
- [ ] Worker integration for performance
- [ ] Caching implementation
- [ ] Settings UI components
- [ ] Documentation and examples
**Deliverables:**
- Optimized performance for large vaults
- Complete settings interface
- User documentation
- Migration guide
### Phase 5: Advanced Features (Week 9-10)
**Components to Implement:**
- [ ] Custom recognition function support
- [ ] Advanced conflict resolution
- [ ] Bulk operations for file tasks
- [ ] Export/import functionality
- [ ] Advanced filtering for file tasks
**Deliverables:**
- Advanced user customization options
- Bulk management capabilities
- Integration with existing tools
## API Specifications
### FileSource Class
```typescript
export class FileSource {
constructor(
private app: App,
private config: FileSourceConfiguration
);
/** Initialize the FileSource */
initialize(): void;
/** Check if a file should be treated as a task */
shouldCreateFileTask(filePath: string): Promise<boolean>;
/** Convert a file to a FileSource task */
createFileTask(filePath: string): Promise<Task<FileSourceTaskMetadata> | null>;
/** Update an existing file task */
updateFileTask(filePath: string): Promise<Task<FileSourceTaskMetadata> | null>;
/** Remove a file task */
removeFileTask(filePath: string): Promise<void>;
/** Get all file tasks */
getAllFileTasks(): Promise<Task<FileSourceTaskMetadata>[]>;
/** Update configuration */
updateConfiguration(config: Partial<FileSourceConfiguration>): void;
/** Get statistics */
getStats(): FileSourceStats;
/** Cleanup and destroy */
destroy(): void;
}
```
### Recognition Strategy Interface
```typescript
interface RecognitionStrategy {
/** Strategy name */
name: string;
/** Check if file matches this strategy */
matches(filePath: string, fileContent: string, fileCache: CachedMetadata): boolean;
/** Extract task metadata from file */
extractMetadata(filePath: string, fileContent: string, fileCache: CachedMetadata): Partial<FileSourceTaskMetadata>;
/** Get strategy configuration */
getConfig(): any;
/** Update strategy configuration */
updateConfig(config: any): void;
}
```
### Query API Extensions
```typescript
// Extensions to existing QueryAPI
interface QueryAPI {
/** Get all file tasks */
getFileTasks(): Promise<Task<FileSourceTaskMetadata>[]>;
/** Get file tasks by criteria */
getFileTasksByStrategy(strategy: string): Promise<Task<FileSourceTaskMetadata>[]>;
/** Get child tasks for a file task */
getChildTasks(fileTaskId: string): Promise<Task[]>;
/** Get file task for a specific file */
getFileTaskByPath(filePath: string): Promise<Task<FileSourceTaskMetadata> | null>;
}
```
## Testing Strategy
### Unit Tests
- **Recognition Strategy Tests**: Each strategy with various file configurations
- **FileSource Core Tests**: Basic functionality, event handling, configuration
- **Metadata Extraction Tests**: Parsing different file types and frontmatter formats
- **Configuration Validation Tests**: Ensure configuration changes are properly handled
### Integration Tests
- **Dataflow Integration**: End-to-end file task creation and updates
- **Event Flow Tests**: Verify proper event emission and handling
- **Repository Integration**: File task storage and retrieval
- **View Integration**: File tasks appearing in various views
### Performance Tests
- **Large Vault Tests**: 1000+ files with mixed file tasks
- **Recognition Performance**: Speed of strategy evaluation
- **Memory Usage**: Memory consumption with large numbers of file tasks
- **Worker Performance**: Performance gains from worker processing
### Edge Case Tests
- **Dual Role Conflicts**: Files that are both projects and tasks
- **Circular Dependencies**: File tasks with circular child relationships
- **Invalid Configurations**: Handling of malformed recognition criteria
- **File System Events**: Rapid file changes, renames, deletions
## Migration Considerations
### Backward Compatibility
- **Existing Functionality**: All current features remain unchanged
- **Configuration**: FileSource disabled by default
- **Data Integrity**: No changes to existing task data
- **Performance**: No impact when FileSource is disabled
### Migration Path
1. **Incremental Rollout**: Feature flag for gradual enablement
2. **Configuration Wizard**: Guided setup for common use cases
3. **Data Migration**: Tools to convert existing project files to file tasks
4. **Documentation**: Clear migration guides and examples
### Rollback Strategy
- **Clean Disable**: FileSource can be completely disabled without data loss
- **Data Preservation**: File task data stored separately, can be ignored
- **Event Cleanup**: Clean removal of FileSource events and handlers
## Performance Optimization
### Update Detection Strategy
FileSource implements intelligent update detection to minimize unnecessary processing:
#### Metadata Changes
- **Detection**: Uses Obsidian's MetadataCache for efficient frontmatter monitoring
- **Processing**: Only updates file task properties, not entire file
- **Events**: FILE_METADATA_CHANGED → FILE_TASK_PROPERTY_CHANGED
- **Optimization**: Diff-based property updates avoid full re-parsing
#### Content Changes
- **Detection**: Analyzes change type to determine impact
- **Processing**:
- File not a task: Skip FileSource update entirely
- File is a task: Check if children structure changed
- Only task content: Trigger INLINE_TASK_CONTENT_CHANGED
- **Events**: FILE_CONTENT_CHANGED → conditional processing
#### Children Structure Detection
- **Optimization**: Only checks task IDs, not content
- **Caching**: Maintains previous state for comparison
- **Threshold**: Only updates on add/remove, not content changes
- **Performance**: O(n) comparison using Set operations
### Event Granularity
Fine-grained events prevent cascading updates:
```typescript
Events = {
// Granular file events
FILE_METADATA_CHANGED: "task-genius:file-metadata-changed",
FILE_CONTENT_CHANGED: "task-genius:file-content-changed",
// Specific file task events
FILE_TASK_PROPERTY_CHANGED: "task-genius:file-task-property-changed",
FILE_TASK_CHILDREN_CHANGED: "task-genius:file-task-children-changed",
// Inline task events
INLINE_TASK_CONTENT_CHANGED: "task-genius:inline-task-content-changed"
}
```
### Update Decision Logic
```typescript
interface UpdateDecision {
update: boolean;
reason: 'not-a-file-task' | 'task-status-changed' |
'task-properties-changed' | 'children-structure-changed' |
'no-relevant-changes';
details?: any;
}
class FileSourceUpdateDetector {
async shouldUpdateFileTask(
filePath: string,
changeReason: 'metadata' | 'content' | 'create' | 'delete'
): Promise<UpdateDecision> {
// Smart detection logic based on change type
// Minimizes false positives and unnecessary updates
}
}
```
### Performance Characteristics
#### Typical Operations
- **Metadata update**: < 10ms (property extraction only)
- **Children structure check**: < 20ms (ID comparison only)
- **Full file task update**: < 50ms (includes augmentation)
- **Inline task update (no file task)**: 0ms FileSource overhead
#### Memory Optimization
- **State caching**: ~100 bytes per file task
- **Children ID cache**: ~20 bytes per child task
- **Total overhead**: < 1MB for 1000 file tasks
#### Batch Processing
- **Debounced updates**: 300ms delay for rapid changes
- **Batch merging**: Multiple file updates processed together
- **Worker offloading**: Heavy processing in background threads
### Cache Strategy
```typescript
interface FileTaskCache {
// Minimal cache for change detection
fileTaskExists: boolean;
frontmatterHash: string; // Quick property change detection
childTaskIds: Set<string>; // Structure tracking only
lastUpdated: number;
}
```
### Optimization Techniques
1. **Early Exit Patterns**
- Non-task files skip processing immediately
- Known unchanged files use cached results
- Quick hash comparisons before deep analysis
2. **Selective Processing**
- Only parse changed sections
- Reuse unchanged metadata
- Incremental children updates
3. **Smart Caching**
- TTL-based cache invalidation
- Content hash validation
- Memory-bounded cache size
4. **Event Deduplication**
- Sequence-based duplicate detection
- Merge rapid sequential updates
- Coalesce related events
## Security Considerations
### File Access
- **Read-Only Operations**: FileSource only reads file metadata
- **Path Validation**: All file paths validated and sanitized
- **Permission Checks**: Respect Obsidian's file access permissions
### Configuration Security
- **Input Validation**: All configuration inputs validated
- **Custom Functions**: Custom recognition functions sandboxed
- **Path Traversal**: Protection against path traversal attacks
## Conclusion
The FileSource feature represents a natural evolution of the Task Genius plugin, extending the powerful dataflow architecture to support files as first-class task entities. The design maintains backward compatibility while providing flexible, performant, and user-friendly file task management.
The dual-role model allows users to organize their work hierarchically (files as projects containing tasks) while also treating files themselves as actionable items with due dates, priorities, and status tracking. This bridges the gap between project management and task management within Obsidian.
The implementation follows established architectural patterns, ensuring maintainability and consistency with the existing codebase. The extensive configuration options provide flexibility for various user workflows while maintaining simplicity for basic use cases.

View file

@ -1,144 +0,0 @@
# FileSource 架构审查报告
## 概述
FileSource 是一个新实现的数据源组件,用于将文件识别为任务并集成到 dataflow 架构中。本报告审查了 FileSource 的设计实现,并评估了其与现有 dataflow 架构的集成情况。
## 当前状态
### 已实现功能
1. **文件识别策略**
- 基于元数据frontmatter的识别
- 基于标签的识别
- 模板和路径策略(预留接口)
- 灵活的状态映射系统
2. **事件处理**
- 订阅 FILE_UPDATED 事件
- 发射 file-task-updated 和 file-task-removed 事件
- 防抖机制300ms避免频繁更新
3. **缓存管理**
- FileTaskCache 跟踪文件任务状态
- FrontmatterHash 用于变更检测
- 统计信息跟踪
### 待集成部分
FileSource 已完全实现但尚未集成到 DataflowOrchestrator 中。需要的集成步骤包括:
1. 在 Orchestrator 构造函数中初始化 FileSource
2. 订阅 FILE_TASK_UPDATED 和 FILE_TASK_REMOVED 事件
3. 扩展 Repository 以处理文件任务
4. 更新 QueryAPI 以合并文件任务到查询结果
## 架构设计评估
### 优点
1. **模块化设计**FileSource 完全独立,遵循 dataflow 的数据源模式
2. **配置灵活性**:通过 FileSourceConfig 提供丰富的配置选项
3. **性能优化**:实现了防抖、缓存和增量更新机制
4. **事件驱动**:与现有事件系统良好集成
### 潜在问题与建议
#### 1. 重复计算问题
**问题**FileSource 在处理文件时需要获取项目数据,这可能与 Orchestrator 的处理产生重复。
**分析**
- FileSource 独立获取项目数据(通过 project/Resolver
- Orchestrator 也会为同一文件获取项目数据
- 但由于 ProjectDataCache 的存在,实际不会产生重复计算
**建议**
- 当前设计可接受,缓存机制有效避免了重复计算
- 未来可考虑通过事件传递项目数据,进一步优化
#### 2. 事件循环风险
**问题**FileSource 订阅 FILE_UPDATED 事件,可能与 ObsidianSource 产生冲突。
**分析**
- FileSource 监听 FILE_UPDATED 来识别文件任务
- ObsidianSource 发射 FILE_UPDATED 事件
- 存在潜在的事件循环风险
**建议**
- 使用序列号Seq机制防止循环
- FileSource 应忽略自己触发的更新
- 考虑使用不同的事件通道避免冲突
#### 3. 数据合并策略
**问题**:文件任务与普通任务如何在 Repository 中合并?
**当前设计缺陷**
- Repository 当前只处理文件内的任务和 ICS 事件
- 没有专门处理文件级任务的机制
- QueryAPI 需要扩展以合并三种数据源
**建议**
```typescript
// Repository 扩展建议
class Repository {
private fileTasks: Map<string, Task> = new Map(); // 新增:文件任务存储
async updateFileTask(filePath: string, task: Task): Promise<void> {
this.fileTasks.set(filePath, task);
// 发射更新事件
}
async all(): Promise<Task[]> {
const regularTasks = await this.indexer.getAllTasks();
const fileTaskArray = Array.from(this.fileTasks.values());
return [...regularTasks, ...this.icsEvents, ...fileTaskArray];
}
}
```
#### 4. 性能考虑
**问题**:初始扫描可能处理大量文件。
**当前实现**
- 同步处理所有文件
- 没有批处理或并行处理
**建议**
- 实现批处理机制
- 考虑使用 Worker 进行并行处理
- 添加进度报告机制
## 集成路线图
### 第一阶段:基础集成
1. 在 Orchestrator 中初始化 FileSource
2. 添加事件监听器
3. 扩展 Repository 支持文件任务
4. 更新 QueryAPI 合并逻辑
### 第二阶段:优化
1. 实现批处理和并行扫描
2. 优化项目数据传递
3. 添加更多识别策略(模板、路径)
4. 实现智能更新检测
### 第三阶段:高级功能
1. 支持文件任务的子任务
2. 实现文件任务的双向同步
3. 添加文件任务的特殊视图
4. 支持文件任务的批量操作
## 结论
FileSource 的实现质量良好,遵循了 dataflow 架构的设计原则。主要需要关注的是:
1. **集成工作**:需要将 FileSource 正式集成到 Orchestrator 中
2. **数据合并**Repository 需要扩展以正确处理三种数据源
3. **性能优化**:大规模文件扫描需要优化
4. **避免冲突**:确保与现有系统的事件处理不产生冲突
通过 ProjectDataCache 的缓存机制重复计算的担忧已得到有效解决。FileSource 的设计是合理的,只需完成集成工作即可投入使用。
## 建议的下一步行动
1. 完成 FileSource 与 Orchestrator 的集成
2. 扩展 Repository 以支持文件任务存储
3. 更新 QueryAPI 的查询逻辑
4. 添加集成测试确保三种数据源正确合并
5. 优化初始扫描性能
6. 更新用户文档说明新功能

View file

@ -1,276 +0,0 @@
# Onboarding Intro Step 修复文档
## 问题描述
在引导流程Onboarding的 Intro 步骤中第四条消息intro-line-4在显示后立即被清除用户无法阅读完整内容。
**问题消息内容:**
> "In the current version, Task Genius provides a brand new visual and interactive experience: Fluent; while also providing the option to return to the previous interface. Which one do you prefer?"
## 根本原因
### 错误的实现逻辑
在重构后的代码中commit 8f5daebd`IntroStep.ts` 的实现逻辑是:
```typescript
// 错误的实现
new TypingAnimation(typingContainer, messages, () => {
// 打字完成后立即切换步骤
footerEl.style.display = "";
controller.setStep(OnboardingStep.MODE_SELECT); // ❌ 这里切换步骤
});
```
`controller.setStep(OnboardingStep.MODE_SELECT)` 被调用时:
1. `ModeSelectionStep.render()` 被触发
2. 该方法首先调用 `contentEl.empty()` 清空内容
3. `intro-line-4` 消息被立即清除
4. 用户几乎看不到消息内容
### 原始的正确逻辑
在旧版本中commit 491e2a6`IntroTyping` 组件的实现是:
```typescript
// 正确的实现
this.introTyping.render(this.onboardingContentEl, () => {
// 打字完成后,在同一容器中添加模式选择
const modeContainer = this.onboardingContentEl.createDiv({
cls: "intro-mode-selection-container"
});
this.modeSelection.render(modeContainer, this.state.uiMode, (mode) => {
this.state.uiMode = mode;
// 用户选择后才显示 footer
this.footerEl.style.display = '';
this.updateButtonStates();
});
});
```
**关键区别:**
- ✅ 不切换步骤,保持在 INTRO 步骤
- ✅ 在同一个 `contentEl` 中追加模式选择 UI
- ✅ `intro-line-4` 消息保留在页面上
- ✅ 用户可以完整阅读消息后再选择模式
## 解决方案
### 修改的文件
1. **`src/components/features/onboarding/steps/IntroStep.ts`**
- 修改 `TypingAnimation``onComplete` 回调
- 不再切换到 MODE_SELECT 步骤
- 而是在同一容器中渲染模式选择 UI
2. **`src/components/features/onboarding/steps/ModeSelectionStep.ts`**
- 添加新方法 `renderInline()`
- 该方法不清空容器,直接在给定容器中渲染
- 接受自定义的 `onSelect` 回调
### 具体实现
#### IntroStep.ts 修改
```typescript
// Start typing animation
new TypingAnimation(typingContainer, messages, () => {
// After typing completes, show mode selection in same container
const modeContainer = introWrapper.createDiv({
cls: "intro-mode-selection-container"
});
// Render mode selection inline (without clearing intro-line-4)
ModeSelectionStep.renderInline(
modeContainer,
controller,
(mode: UIMode) => {
// User selected a mode, show footer with Next button
controller.setUIMode(mode);
footerEl.style.display = "";
}
);
});
```
#### ModeSelectionStep.ts 新增方法
```typescript
/**
* Render mode selection inline (for intro step)
* This version doesn't clear the container and calls a custom callback
*/
static renderInline(
containerEl: HTMLElement,
controller: OnboardingController,
onSelect: (mode: UIMode) => void
) {
// Get current state
const currentMode = controller.getState().uiMode;
// Create cards configuration
const cardConfigs: SelectableCardConfig<UIMode>[] = [
// ... 卡片配置
];
// Render selectable cards
const card = new SelectableCard<UIMode>(
containerEl,
cardConfigs,
{
containerClass: "selectable-cards-container",
cardClass: "selectable-card",
showPreview: true,
},
(mode) => {
onSelect(mode); // 调用自定义回调
}
);
// Set initial selection
if (currentMode) {
card.setSelected(currentMode);
}
// Add info alert
Alert.create(
containerEl,
t("You can change this option later in settings"),
{
variant: "info",
className: "mode-selection-tip",
}
);
}
```
## 用户体验流程
修复后的用户体验流程:
1. **打字动画阶段**
- 显示 "Hi,"
- 显示 "Thank you for using Task Genius"
- 显示长文本,然后淡出前三条消息
- 显示 `intro-line-4` 消息(关键消息)
2. **模式选择阶段**
- `intro-line-4` 消息**保留在页面上**
- 在消息下方显示模式选择卡片Fluent vs Legacy
- 用户可以完整阅读消息内容
- 用户选择模式后,显示 Next 按钮
3. **下一步**
- 用户点击 Next 按钮
- 才清除内容并进入下一个步骤
## CSS 样式支持
相关的 CSS 样式已经存在于 `src/styles/onboarding.css`
```css
/* Mode selection container that appears after intro typing */
.intro-mode-selection-container {
animation: fadeInFromBottom 0.6s ease-out;
animation-fill-mode: both;
width: 100%;
margin-top: var(--size-4-10);
}
.intro-line-4 {
font-size: clamp(1rem, 2vw, 1.4rem);
color: var(--text-muted);
line-height: 1.8;
margin-bottom: var(--size-4-5);
}
```
## 测试验证
构建成功,无错误:
```bash
npm run build
# ✅ Build successful
# dist\main.js 3.7mb
# dist\main.css 345.1kb
```
## 导航逻辑修复
### 问题
修复 intro 消息显示后,发现了新的导航问题:
当用户在 INTRO 步骤中选择模式后点击 Next会经过以下流程
1. INTRO → MODE_SELECT因为 handleNext 中 INTRO 的下一步是 MODE_SELECT
2. MODE_SELECT 被渲染(但用户已经选择过了)
3. 用户再次点击 Next
4. MODE_SELECT → FLUENT_COMPONENTS**跳过了 FLUENT_PLACEMENT**
### 解决方案
修改 `OnboardingController.ts` 中的 `handleNext()` 逻辑:
```typescript
case OnboardingStep.INTRO:
// Mode selection is now inline in INTRO step
// So we skip MODE_SELECT and go directly based on selected mode
if (this.state.uiMode === 'fluent') {
nextStep = OnboardingStep.FLUENT_PLACEMENT; // ✅ 正确跳转
} else {
// Legacy mode: check for existing changes
if (this.state.userHasChanges) {
nextStep = OnboardingStep.SETTINGS_CHECK;
} else {
nextStep = OnboardingStep.USER_LEVEL_SELECT;
}
}
break;
case OnboardingStep.MODE_SELECT:
// This step is now integrated into INTRO, but keep for backward compatibility
if (this.state.uiMode === 'fluent') {
nextStep = OnboardingStep.FLUENT_PLACEMENT; // ✅ 修复:不再跳过
} else {
// Legacy mode: check for existing changes
if (this.state.userHasChanges) {
nextStep = OnboardingStep.SETTINGS_CHECK;
} else {
nextStep = OnboardingStep.USER_LEVEL_SELECT;
}
}
break;
```
### 修复后的流程
**Fluent 模式:**
1. INTRO包含模式选择
2. FLUENT_PLACEMENT选择 Sideleaves 或 Inline
3. FLUENT_COMPONENTS组件预览
4. SETTINGS_CHECK 或 USER_LEVEL_SELECT根据是否有更改
**Legacy 模式:**
1. INTRO包含模式选择
2. SETTINGS_CHECK如果有更改或 USER_LEVEL_SELECT如果没有更改
## 总结
通过恢复原始的实现逻辑并修复导航逻辑,现在:
**消息显示:**
- ✅ `intro-line-4` 消息完整显示在页面上
- ✅ 在模式选择卡片上方保留
- ✅ 用户有充足时间阅读
- ✅ 只有在点击 Next 后才被清除
**导航流程:**
- ✅ INTRO 步骤包含模式选择(内联)
- ✅ 选择 Fluent 后正确进入 FLUENT_PLACEMENT
- ✅ 选择 Legacy 后根据配置进入相应步骤
- ✅ 不会跳过任何必要的步骤
这符合原始设计意图,提供了更好的用户体验。

View file

@ -1,237 +0,0 @@
# OnCompletion Feature Guide
## Overview
The OnCompletion feature allows you to define automatic actions that occur when a task is marked as completed. This is useful for workflows like archiving completed tasks, triggering dependent tasks, or moving tasks to different locations.
## Architecture
The OnCompletion system consists of:
- **OnCompletionManager**: Core manager that listens for task completion events
- **Action Executors**: Individual executors for each action type (delete, move, archive, etc.)
- **Event System**: Integration with `task-genius:task-completed` event
- **WriteAPI Integration**: Automatic triggering when tasks are completed via API
## Setup
The OnCompletion feature is automatically initialized when the plugin loads with indexer enabled. No additional configuration is required.
## Usage
### Task Metadata Format
Add an `onCompletion` property to your task metadata:
#### Simple Format (Emoji)
```markdown
- [ ] Task content 🏁 delete
- [ ] Task content 🏁 keep
- [ ] Task content 🏁 archive
- [ ] Task content 🏁 move:Projects/Archive.md
- [ ] Task content 🏁 complete:task-id-1,task-id-2
- [ ] Task content 🏁 duplicate:Projects/Templates.md
```
#### Dataview Format
```markdown
- [ ] Task content [onCompletion:: delete]
- [ ] Task content [onCompletion:: keep]
- [ ] Task content [onCompletion:: archive]
- [ ] Task content [onCompletion:: move:Projects/Archive.md]
- [ ] Task content [onCompletion:: complete:task-id-1,task-id-2]
- [ ] Task content [onCompletion:: duplicate:Projects/Templates.md]
```
#### JSON Format (Advanced)
```markdown
- [ ] Task content 🏁 {"type":"move","targetFile":"Archive.md","section":"## Completed"}
- [ ] Task content 🏁 {"type":"complete","taskIds":["id1","id2"],"cascade":true}
- [ ] Task content 🏁 {"type":"archive","archiveFile":"2024-Archive.md","preserveMetadata":true}
```
## Action Types
### DELETE
Removes the task from the file when completed.
```markdown
- [ ] Temporary task 🏁 delete
```
### KEEP
Keeps the task as completed (default behavior, useful for overriding).
```markdown
- [ ] Important task 🏁 keep
```
### ARCHIVE
Moves the task to an archive file (default: "Archive.md" in same folder).
```markdown
- [ ] Task to archive 🏁 archive
- [ ] Custom archive 🏁 archive:Completed/2024.md
```
### MOVE
Moves the task to a different file or section.
```markdown
- [ ] Task to move 🏁 move:Another File.md
- [ ] Move to section 🏁 {"type":"move","targetFile":"File.md","section":"## Done"}
```
### COMPLETE
Automatically completes other tasks when this task is completed.
```markdown
- [ ] Parent task 🏁 complete:child-task-id-1,child-task-id-2
- [ ] Cascade completion 🏁 {"type":"complete","taskIds":["id1"],"cascade":true}
```
### DUPLICATE
Creates a copy of the task in another location when completed.
```markdown
- [ ] Template task 🏁 duplicate:Templates/Recurring.md
- [ ] Duplicate and reset 🏁 {"type":"duplicate","targetFile":"Tomorrow.md","resetStatus":true}
```
## Event Flow
1. User marks task as completed (via UI, command, or API)
2. WriteAPI detects completion and triggers `task-genius:task-completed` event
3. OnCompletionManager receives the event
4. Manager parses the `onCompletion` metadata
5. Appropriate executor is invoked
6. Action is performed (delete, move, archive, etc.)
7. Result is logged
## Integration Points
### WriteAPI
The WriteAPI automatically triggers the completion event:
- `updateTask()` - When `completed: true` is set
- `updateTaskStatus()` - When task is marked complete
- `updateCanvasTask()` - Canvas tasks also trigger events
### Editor Extensions
- `monitorTaskCompletedExtension` - Monitors inline completions
- `status-switcher` - Triggers on status changes
- `status-cycler` - Triggers on cycle operations
### Canvas Support
Canvas tasks fully support OnCompletion:
```javascript
// Canvas task with onCompletion
{
"type": "text",
"text": "- [ ] Canvas task 🏁 delete",
...
}
```
## Error Handling
If an OnCompletion action fails:
1. Error is logged to console
2. Task remains completed
3. No rollback occurs
4. User is not notified (silent failure)
To debug issues:
1. Open Developer Console (Ctrl+Shift+I)
2. Look for "OnCompletionManager" logs
3. Check for parsing or execution errors
## Best Practices
1. **Use simple format** for basic actions (delete, keep, archive)
2. **Use JSON format** for complex configurations
3. **Test actions** on non-critical tasks first
4. **Validate file paths** exist before using move/archive
5. **Use task IDs** carefully with complete action
## Examples
### Daily Task Cleanup
```markdown
## Daily Tasks
- [ ] Review emails 🏁 delete
- [ ] Update status report 🏁 move:Completed/2024-08.md
- [ ] Team standup 🏁 delete
```
### Project Dependencies
```markdown
## Project Steps
- [ ] Design mockups 🆔 design-001
- [ ] Implement frontend 🆔 frontend-001 🏁 complete:testing-001
- [ ] Write tests 🆔 testing-001 🏁 complete:deploy-001
- [ ] Deploy to production 🆔 deploy-001
```
### Recurring Task Template
```markdown
## Templates
- [ ] Weekly review 🏁 duplicate:Next Week.md
- [ ] Monthly report 🏁 {"type":"duplicate","targetFile":"Next Month.md","resetStatus":true}
```
## Configuration
Currently, OnCompletion actions are defined per-task via metadata. Global configuration options may be added in future versions.
## Limitations
- Actions are not undoable
- Circular dependencies in `complete` action may cause issues
- File operations may fail if target doesn't exist
- No UI for configuring actions (metadata only)
## Migration from TaskManager
The OnCompletion feature is fully compatible with the new Dataflow architecture:
| Component | Old (TaskManager) | New (Dataflow) |
|-----------|------------------|----------------|
| Manager | Part of TaskManager | Standalone OnCompletionManager |
| Events | Manual triggering | Automatic via WriteAPI |
| Canvas | Limited support | Full support |
| Performance | Synchronous | Asynchronous |
## Testing OnCompletion
To test if OnCompletion is working:
1. Create a test task:
```markdown
- [ ] Test task 🏁 delete
```
2. Mark it complete using:
- Click the checkbox
- Use keyboard shortcut
- Use WriteAPI
3. Check that the task is deleted
4. Check console for logs:
```
[Plugin] OnCompletionManager initialized
handleTaskCompleted {task object}
parseResult {config object}
```
## Troubleshooting
### OnCompletion not triggering
- Ensure indexer is enabled in settings
- Check that task has valid onCompletion metadata
- Verify task-completed event is firing (check console)
- Ensure OnCompletionManager is loaded
### Action failing
- Check file paths are correct
- Ensure target files exist for move/archive
- Verify task IDs exist for complete action
- Check console for specific error messages
### Performance issues
- Large batch operations may be slow
- Consider using delete instead of archive for many tasks
- Avoid deep cascade chains in complete action

View file

@ -1,262 +0,0 @@
# Parser Refactoring Plan
## Current State Analysis
### 1. Parser Duplication Issues
#### Canvas Parser Chain (3 layers)
```
src/parsers/canvas-parser.ts (redirect)
→ src/dataflow/core/CanvasParser.ts (implementation)
→ src/dataflow/parsers/CanvasEntry.ts (entry point)
```
**Current Usage:**
- Tests import from `src/parsers/canvas-parser.ts` (2 test files)
- Worker imports directly from `src/dataflow/core/CanvasParser.ts`
- Orchestrator uses `parseCanvas()` from `CanvasEntry.ts`
#### TaskParserConfig Duplication
- **Old**: `src/types/task.d.ts:267` - Simple interface with regex patterns
- **New**: `src/types/TaskParserConfig.ts:12` - Comprehensive with 60+ fields
- **Active Usage**: All 13 imports use the new TaskParserConfig.ts
#### Parser Implementation Overlap
- **MarkdownTaskParser**: Core implementation (1700+ lines)
- **ConfigurableTaskParser**: Extends MarkdownTaskParser with time parsing
- **FileMetadataTaskParser**: Separate implementation for metadata
- **TaskParsingService**: High-level orchestrator
### 2. Dependency Analysis
```mermaid
graph TD
A[Orchestrator] --> B[CanvasEntry::parseCanvas]
B --> C[CanvasParser::parseCanvasFile]
C --> D[ConfigurableTaskParser]
E[Tests] --> F[canvas-parser.ts redirect]
F --> C
G[Worker] --> C
H[TaskParsingService] --> D
H --> I[FileMetadataTaskParser]
```
## Refactoring Steps
### Phase 1: Immediate Cleanup (Low Risk)
#### 1.1 Remove Canvas Parser Redirect
**Files to modify:**
- Delete: `src/parsers/canvas-parser.ts`
- Update imports in:
- `src/__tests__/CanvasParser.test.ts`
- `src/__tests__/CanvasIntegration.test.ts`
**Change:**
```typescript
// Before
import { CanvasParser } from '../parsers/canvas-parser';
// After
import { CanvasParser } from '../dataflow/core/CanvasParser';
```
#### 1.2 Remove Old TaskParserConfig
**Files to modify:**
- Remove interface from `src/types/task.d.ts:267-284`
- No import changes needed (all use the new one)
### Phase 2: Consolidate Canvas Parsing (Medium Risk)
#### 2.1 Merge CanvasEntry into CanvasParser
**Goal:** Single entry point for Canvas parsing
**New structure:**
```typescript
// src/dataflow/core/CanvasParser.ts
export class CanvasParser {
// Existing implementation
// Add entry function from CanvasEntry
static async parseCanvas(
filePath: string,
fileContent: string,
plugin: TaskProgressBarPlugin
): Promise<TaskResult> {
// Merge logic from CanvasEntry
}
}
```
#### 2.2 Update Canvas Updater
**Goal:** Share parsing logic with CanvasParser
**Files to modify:**
- `src/parsers/canvas-task-updater.ts`
- Import Canvas types from CanvasParser
- Reuse node parsing logic
### Phase 3: Unified Parser Architecture (High Impact)
#### 3.1 Create Unified Parser Registry
```typescript
// src/parsing/ParserRegistry.ts
export class ParserRegistry {
private parsers: Map<string, BaseParser>;
register(extension: string, parser: BaseParser) { }
parse(file: TFile, config: TaskParserConfig): Promise<TaskResult> { }
}
```
#### 3.2 Standardize Parser Interface
```typescript
// src/parsing/BaseParser.ts
export interface BaseParser {
parse(content: string, config: TaskParserConfig): Promise<ParseResult>;
update(content: string, updates: TaskUpdate[]): Promise<string>;
supports(file: TFile): boolean;
}
```
#### 3.3 Implement Specific Parsers
```
src/parsing/
├── BaseParser.ts
├── ParserRegistry.ts
├── parsers/
│ ├── MarkdownParser.ts
│ ├── CanvasParser.ts
│ └── ICSParser.ts
└── updaters/
├── MarkdownUpdater.ts
└── CanvasUpdater.ts
```
## Migration Strategy
### Step-by-Step Execution
1. **Week 1**: Phase 1 - Immediate Cleanup
- Remove redirects and duplicates
- Run full test suite
- Monitor for issues
2. **Week 2**: Phase 2.1 - Canvas Consolidation
- Merge CanvasEntry into CanvasParser
- Update Orchestrator imports
- Test Canvas functionality
3. **Week 3**: Phase 2.2 - Updater Integration
- Refactor Canvas updater
- Share parsing logic
- Test update operations
4. **Week 4+**: Phase 3 - Architecture (Optional)
- Implement if needed for new features
- Gradual migration
- Maintain backward compatibility
## Testing Requirements
### Unit Tests
- [ ] Canvas parsing tests pass
- [ ] Markdown parsing tests pass
- [ ] Task parsing service tests pass
- [ ] Worker tests pass
### Integration Tests
- [ ] Canvas file operations
- [ ] Task updates in Canvas
- [ ] Cross-file task references
- [ ] Performance benchmarks
### Manual Testing
- [ ] Create tasks in Canvas
- [ ] Update task status in Canvas
- [ ] Parse complex Canvas files
- [ ] Verify no UI regressions
## Risk Assessment
### Low Risk Changes
- Removing redirect files
- Removing unused interfaces
- Import path updates
### Medium Risk Changes
- Merging CanvasEntry logic
- Sharing parsing code between parser/updater
### High Risk Changes
- Full architecture refactor
- Parser registry implementation
- Breaking API changes
## Success Metrics
1. **Code Reduction**: ~200 lines removed from duplicates
2. **Performance**: No regression in parsing speed
3. **Maintainability**: Single source of truth for each parser
4. **Test Coverage**: All tests passing
5. **Bug Count**: No new parsing issues reported
## Rollback Plan
If issues arise:
1. Revert commits in reverse order
2. Restore redirect files temporarily
3. Document specific failure points
4. Create targeted fixes
## Implementation Status
### Phase 1: Immediate Cleanup ✅ COMPLETED
- ✅ Removed canvas-parser.ts redirect file
- ✅ Updated test imports to use dataflow/core/CanvasParser
- ✅ Removed old TaskParserConfig from task.d.ts
- ✅ All tests passing
- ✅ TypeScript compilation clean
- ✅ Build successful
### Phase 2.1: Canvas Consolidation ✅ COMPLETED
- ✅ Added static parseCanvas method to CanvasParser
- ✅ Removed CanvasEntry.ts file
- ✅ Updated Orchestrator to use CanvasParser.parseCanvas()
- ✅ Updated WorkerOrchestrator dynamic imports
- ✅ Reduced Canvas parsing layers from 3 to 2
### Phase 2.2: Canvas Updater Integration ✅ COMPLETED
- ✅ Added utility methods to CanvasParser:
- parseCanvasJSON() - Safe JSON parsing
- findTextNode() - Find node by ID
- getTextNodes() - Get all text nodes
- ✅ Refactored canvas-task-updater to use shared utilities
- ✅ Eliminated duplicate Canvas JSON parsing logic
- ✅ All Canvas functionality tested and working
## Results Summary
### Code Improvements
- **Lines Removed**: ~60 lines (redundant code)
- **Files Deleted**: 2 (canvas-parser.ts, CanvasEntry.ts)
- **Architecture**: Simplified from 3-layer to 2-layer Canvas parsing
- **Code Reuse**: Shared utilities between parser and updater
### Quality Metrics
- ✅ **TypeScript**: No compilation errors
- ✅ **Build**: Successful (3.3MB bundle)
- ✅ **Tests**: Canvas-specific tests passing
- ✅ **Backward Compatibility**: Maintained through static methods
## Next Actions
1. ✅ Document current state
2. ✅ Remove canvas-parser.ts redirect
3. ✅ Remove old TaskParserConfig interface
4. ✅ Test changes
5. ✅ Proceed with Phase 2
6. ⬜ Consider Phase 3 (Unified Parser Architecture) for future major refactor

View file

@ -1,74 +0,0 @@
# Review: 待修复 Bugs 列表2025-09-04
说明:以下清单基于当前代码与已知反馈整理。已确认不纳入本次修复范围的项:
- [已修复] 任务在 Task View 中编辑后不更新(原问题 #2
- [暂不考虑] List View 渲染卡顿(原问题 #4
- [已在新架构修复] 启动时任务重建漏项(原问题 #7
以下为仍需修复的问题与建议方案:
## 1) 过滤器输入导致实时加载Task View 打开时性能大幅下降(原问题 #1
- 现象:在“视图过滤器”输入每个字符时就触发刷新,造成频繁过滤与重渲染。
- 涉及模块:
- 过滤器组件事件广播:`src/components/features/task/filter/ViewTaskFilter.ts`saveStateToLocalStorage → 触发 `task-genius:filter-changed`
- TaskView 处理防抖:`src/pages/TaskView.ts``debouncedApplyFilter` 当前延时较短)
- 文本搜索即时刷新:`src/components/features/task/view/content.ts``filterTasks`
- 修复建议:
- 提高 TaskView 内 `debouncedApplyFilter` 延迟(建议 300500ms
- 在 ViewTaskFilter 中对输入框 `input` 事件增加本地防抖;或编辑时 `saveStateToLocalStorage(triggerRealtimeUpdate=false)`,提交/失焦时再广播。
- ContentComponent 的文本搜索同样使用防抖(约 300ms
- 验收:连续输入时渲染频率显著下降;大型数据集输入体验流畅,无明显掉帧。
## 2) 视图顺序在设置中调整后Task View 侧边栏未按顺序展示(原问题 #3
- 现象Views & Index 页中上下移动视图后,侧边栏排序不一致。
- 涉及模块:
- 设置页顺序变更:`src/components/features/settings/tabs/ViewSettingsTab.ts`
- 侧边栏渲染:`src/components/features/task/view/sidebar.ts`(当前将视图分为默认/自定义/底部组,改变了原始顺序)
- 修复建议:
- 侧边栏按 `settings.viewConfiguration` 原始顺序渲染(仅过滤 `visible`),不要再额外分组打乱顺序。
- 若需“底部固定组”habit/calendar/gantt/kanban可在设置层面赋予“区域”属性或在数据层维护顺序一致性。
- 验收:在设置中调整顺序后,侧边栏显示顺序与设置数组一致。
## 3) 编辑包含任务的文件时Task View 展示的文本出现偏差,需关闭重开才正确(原问题 #5
- 现象:外部编辑器或 Obsidian 编辑某文件中的任务时Task View 中对应条目短时间显示不一致内容。
- 涉及模块:
- 任务缓存更新与视图刷新:`src/pages/TaskView.ts`(监听 `TASK_CACHE_UPDATED``debouncedViewUpdate` 刷新)
- 列表项 Markdown 渲染:`src/components/features/task/view/listItem.ts``renderMarkdown` 使用 `task.originalMarkdown`
- 修复建议:
- 稳定事件节奏:适度加大 `debouncedViewUpdate` 延迟或合并短时间内的多次更新,避免“半成品”快照进入 UI。
- 确保外部写入后再触发一次最终刷新Orchestrator rebuild/快照完成时统一触发视图更新)。
- 列表项渲染前确保完全清理旧内容(已 empty并使用最新 `originalMarkdown` 渲染。
- 验收编辑文件后无需关闭重开Task View 即可稳定显示最终内容,无中间错乱。
## 4) 自定义任务视图从分栏split模式无法切回单列模式原问题 #6
- 现象:编辑自定义视图时,无法从“两列视图”回到“单列视图”。
- 涉及模块:
- 两列视图基类与切换:`src/components/features/task/view/TwoColumnViewBase.ts`
- 视图创建/切换:`src/pages/TaskView.ts`(根据 `viewConfig.specificConfig.viewType === "twocolumn"` 决定)
- 视图配置弹窗:`src/components/features/task/view/modals/ViewConfigModal.ts`
- 修复建议:
- 在 ViewConfigModal 中暴露“视图布局类型”single/twocolumn切换保存后更新 `viewConfiguration`
- TaskView 在 `onSettingsUpdate` 时销毁/隐藏旧的 TwoColumn 组件,恢复常规 ContentComponent并刷新当前视图。
- 验收:用户可在配置中自由切换布局,保存后侧边栏对应视图正确切换模式。
## 5) 勾选一个习惯时,偶发地所有习惯都被勾选(原问题 #8
- 现象:点击单个 Habit 打勾,偶发地其它 Habit 也被更新。
- 涉及模块:
- Habit 勾选入口:`src/components/features/habit/habitcard/habitcard.ts``toggleHabitCompletion`
- 写回与索引:`src/managers/habit-manager.ts``updateHabitInObsidian` 与后续 habit 索引更新)
- 修复建议:
- 校验 Habit `id` 的唯一性与全链路使用一致;仅更新目标 habit 的 `completions[today]`
- 写回模板/标记仅定位目标 habit 片段,避免通配批量替换。
- 索引更新map 遍历)中保持纯函数式修改,仅对目标 habit 变动,防止共享引用导致联动。
- 验收:反复勾选单一 Habit不会影响其它 Habit 的状态。
## 6) Ctrl+K 未能聚焦设置菜单的搜索框(原问题 #9
- 现象:提示文案包含 “(Ctrl+K)”,但快捷键无法聚焦搜索输入。
- 涉及模块:
- 设置搜索组件:`src/components/features/settings/components/SettingsSearchComponent.ts`
- 设置页入口:`src/setting.ts`(创建搜索组件)
- 修复建议:
- 在 SettingsSearchComponent 内注册全局键盘监听:在 macOS 使用 `metaKey + K`Windows/Linux 使用 `ctrlKey + K`,触发 `searchInputEl.focus()` 与结果弹出。
- 或通过 SettingTab 的 Scope 定义快捷键绑定到聚焦行为。
- 验收:在设置页按下 Ctrl/Cmd+K输入框获得焦点并可立即搜索。

View file

@ -1,78 +0,0 @@
# Storage API 修复记录
## 完成的修复
### 1. API 不匹配问题
- **问题**: Storage.ts 使用了 LocalStorageCache 不存在的方法 `clearFile()``getKeys()`
- **修复**:
- 将所有 `clearFile()` 调用替换为 `removeFile()`
- 将所有 `getKeys()` 调用替换为 `allFiles()``allKeys()`
### 2. 哈希校验逻辑不一致
- **问题**:
- `storeRaw()` 使用任务数组计算哈希
- `isRawValid()` 使用文件内容计算哈希
- 导致校验失真
- **修复**:
- 修改 `storeRaw()` 签名,增加可选的 `fileContent` 参数
- 使用文件内容(如果提供)计算哈希,保持语义一致
- 更新 Orchestrator.processFileImmediate() 调用,传入 fileContent
### 3. clearNamespace 实现修正
- **问题**: 原实现使用底层的完整键,而非路径化键
- **修复**:
- 改为使用 `allFiles()` 获取路径化键
- 按正确的前缀模式匹配和删除
- 为每个命名空间定义明确的前缀映射
### 4. consolidated 快照 API 统一
- **问题**: 混用了 `loadFile()` 和专用的 consolidated API
- **修复**:
- `loadConsolidated()` 改用 `loadConsolidatedCache()`
- `storeConsolidated()` 改用 `storeConsolidatedCache()`
- 保持与 LocalStorageCache 的设计一致
### 5. getStats() 统计方法修正
- **问题**: 使用底层键统计,计数不准确
- **修复**:
- 改用 `allFiles()` 获取路径化键
- 按正确的前缀模式统计各命名空间的文件数
## 影响范围
### 修改的文件
1. `/src/dataflow/persistence/Storage.ts` - 主要修复
2. `/src/dataflow/Orchestrator.ts` - 更新 storeRaw() 调用参数
### 行为改进
- ✅ 冷启动优先从快照加载,无需等待索引
- ✅ 单文件内容校验准确可靠
- ✅ 命名空间清理功能正常工作
- ✅ 统计数据准确反映实际存储状态
- ✅ 版本不兼容时正确清理过期缓存
## 后续建议
### 短期优化
1. 考虑将 Keys 命名空间管理抽象为独立的 helper 类
2. 添加单元测试覆盖所有存储操作
3. 增加缓存命中率的监控指标
### 长期改进
1. 实现渐进式 schema 迁移器,而非简单的版本检查删除
2. 考虑添加缓存压缩机制以减少存储空间占用
3. 实现更智能的缓存淘汰策略LRU/LFU
## 验证清单
- [x] removeFile() 方法调用正常
- [x] allFiles() 返回正确的路径化键
- [x] clearNamespace 按前缀正确删除
- [x] consolidated API 使用统一
- [x] 哈希校验逻辑一致
- [x] getStats() 统计准确
- [x] Orchestrator 传参更新
## 相关文档
- [TaskIndexer 迁移计划](./taskindexer-migration-plan.md)
- [Dataflow 架构文档](./dataflow-architecture.md)

View file

@ -1,232 +0,0 @@
## Task Genius 数据流全面重构计划Refactor Plan
### 目的Goals
- 去重与统一:消除项目识别、文件级元数据解析、任务解析、增强/继承、索引、缓存、持久化、事件传递在多处重复实现与分散入口的问题。
- 稳定与持久:建立单一数据源与可验证的数据流,降低未来演进/扩展成本。
- 一致与同步:保证视图数据与底层缓存/索引严格一致,避免“视图数据不同步”。
- 快速冷启动:最大程度复用持久化数据,避免用户反复 reindex。
- 事件驱动:所有上行/下行数据变更通过 Obsidian 事件系统传播,而不是上级组件直接 setTasks。
- 增量更新:跟随 Obsidian 的 vault/metadataCache/设置事件做最小代价的增量更新。
### 非目标Non-goals
- 不改变用户可见的功能语义与现有配置的含义(除非标注为改进项)。
- 不一次性大爆炸替换;采用阶段性迁移确保回退路径。
---
## 设计原则
- 单一职责与单一真相源Single Source of Truth
- 项目识别只在 ProjectResolver统一接口进行解析器与增强器不再分散探测。
- 继承/增强只在 TaskAugmentor 进行;解析器仅负责“从文本抽取”。
- 事件优于回调:统一使用 Obsidian workspace 事件分发数据变更,视图通过事件 + 查询 API 获取数据。
- 可重放、可回退Worker 与主线程遵循相同协议;主线程兜底。
- 可持久与可验证:内容哈希 + 版本/架构版本管理;命名空间化缓存;精细化失效与一致性校验。
- 增量优先:文件内容变动仅重解析该文件;项目配置变动仅重跑增强;设置变动按 scope 精准失效。
- 向后兼容:提供 Adapter 兼容旧 setTasks 调用路径,逐步下线。
---
## 数据拥有权与边界Ownership
- 源事件File eventsObsidianSource 拥有,统一发出内部文件事件。
- 项目识别ProjectProjectResolver 拥有,对外只暴露“文件 → {tgProject, enhancedMetadata}”。
- 解析器ParsersMarkdown/Canvas/FileLevel 仅负责“抽取任务/文件级任务”,不写入项目或其他增强信息。
- 增强/继承AugmentTaskAugmentor 拥有“task > file > project”的可配置优先级合并。
- 索引IndexingTaskIndexer 拥有内存索引与查询,不做解析与增强。
- 持久化PersistenceStorageAdapter基于 LocalStorageCache拥有命名空间与 hash/版本校验。
- 事件与查询Events & QueryEvents 模块拥有事件契约QueryAPI 对外只读查询。
---
## 目标数据流(高层)
1) Obsidian 事件 → Sources 标准化为 FileChanged/FileDeleted/Renamed 等内部事件。
2) ParsersEntry根据文件类型抽取
- FileLevelTaskParser从 frontmatter/tags 形成“文件级任务”。
- MarkdownTaskParserEntry / CanvasTaskParserEntry从正文生成“基础任务”。
3) ProjectResolver 计算项目 + 项目增强元数据(可并行)。
4) TaskAugmentor将“文件级 + 正文任务”与“文件元数据 + 项目增强元数据”按策略合并到任务对象。
5) TaskIndexer.updateIndexWithTasks(filePath, tasksEnhanced)。
6) Persistence写入命名空间缓存见下必要时更新 consolidated 索引快照。
7) 事件广播 task-genius:task-cache-updated { changedFiles }。
8) 视图订阅事件 → QueryAPI 拉取 → 渲染。
---
## 组件与目录结构(建议新增 src/dataflow/*
- sources/ObsidianSource.ts
- 订阅 vault/metadataCache/设置事件;统一去抖与批量合并;发出内部文件事件。
- project/ProjectResolver.ts
- 合并现有 ProjectConfigManager + ProjectDataCache/Worker 的“对外接口”。
- 输入filePath输出{ tgProject?, enhancedMetadata, timestamp }。
- 统一“frontmatter 指定项目、目录 config、tag/link 提示”的优先级;可配置。
- parsers/
- MarkdownTaskParserEntry.ts包装 ConfigurableTaskParser.parseLegacy
- CanvasTaskParserEntry.ts包装 CanvasParser
- FileLevelTaskParser.ts包装 FileMetadataTaskParser禁用内部项目探测
- augment/TaskAugmentor.ts
- 单一继承/增强实现:
- 标量task 显式 > file > project > 默认
- 数组:合并去重(保持稳定次序)
- 状态/完成:只取 task 行级
- 复发task 显式优先
- 子任务继承:按 FileMetadataInheritance/设置 per-key 控制
- workers/WorkerOrchestrator.ts
- 统一任务/项目命令parseFileTasks、batchParse、computeProjectData、batchCompute
- 并发控制、重试、回退、指标
- indexer/TaskRepository.ts
- 组合 TaskIndexer + Persistence提供查询 API 的后端依赖
- persistence/StorageAdapter.ts
- 命名空间 + hash内容+ 版本/架构版本 + 粒度化失效
- Keyspace
- tasks.raw:<filePath>
- project.data:<filePath>
- tasks.augmented:<filePath>
- consolidated:taskIndex
- meta:version / meta:schemaVersion
- events/Events.ts
- 事件常量/载荷类型/帮助方法emit/subscribe。与 obsidian-ex.d.ts 契约一致。
- api/QueryAPI.ts
- 为视图提供只读查询(按项目/标签/状态/时间窗口等),屏蔽内部实现细节。
---
## 最大化避免与现有功能重复的策略
1) 单一入口与关停重复:
- FileMetadataTaskParser关闭其内部项目探测统一由 ProjectResolver 提供 project 值后在 Augmentor 注入。
- ConfigurableTaskParser/CanvasParser不处理项目/继承,仅返回“基础任务”。
- TaskManager 内的解析/增强/持久化逻辑收敛到新模块TaskManager 变为编排薄层。
2) 功能所有权迁移表(旧 → 新):
- 项目识别FileMetadataTaskParser.detectProjectFromFile / ProjectData* → ProjectResolver
- 继承/增强ConfigurableTaskParser 内部继承 / FileMetadataInheritance 分散 → TaskAugmentor
- 数据广播:上层 setTasks → Events + QueryAPI
- Worker 管理TaskWorkerManager/ProjectDataWorkerManager → WorkerOrchestrator内部保留原 Worker
- 持久化LocalStorageCache 直接使用 → StorageAdapter 管理命名空间/版本/hash
3) Adapter 与 Deprecation
- ViewComponentManager.setTasks 标记 deprecated提供兼容 AdaptersetTasks 内部转为发事件 + 触发查询,避免一次性改动所有视图。
- FileMetadataTaskParser 暴露“允许/禁止项目探测”开关;重构期禁用。
---
## 视图同步与一致性保证
- 事件驱动 + 拉取查询:视图统一订阅 task-genius:task-cache-updated / filter-changed随后调用 QueryAPI 拉取。彻底替代上级 setTasks 链接。
- 原子性:单文件变更导出单批次“增强后任务”提交到 Indexer再触发事件视图永远看到同一版本。
- 序号/时间戳:在广播载荷中携带 sequence/timestamp视图可丢弃过期更新。
- 去抖/批量Sources 对频繁变动进行批处理,减少 UI 抖动。
- 兼容策略:在迁移期间,旧视图通过 Adapter 仍可工作。
---
## 持久化与缓存策略
- 命名空间:
- tasks.raw:<filePath> → 基础解析结果
- project.data:<filePath> → {tgProject, enhancedMetadata}
- tasks.augmented:<filePath> → Augmentor 合成产物(可选,提升冷启动)
- consolidated:taskIndex → 全量索引快照(可选)
- 版本与架构版本:
- meta:version插件版本 + meta:schemaVersion缓存结构版本不兼容时精准清理对应命名空间。
- 内容哈希:
- tasks.raw 基于文件内容 hashproject.data 基于“有效配置 + frontmatter + tags/links”等来源 hash。
- 仅当 hash 改变时重算mtime 仅用于快速预判。
- 失效矩阵:
- 文件正文变动:重算 tasks.raw → augment → 更新 index → 事件。
- 文件 frontmatter/tags 变动:重做 file→task 继承与 augment若正文未变可跳过正文解析
- 项目配置变动:仅失效 project.data 与 tasks.augmented重做 augment跳过正文解析。
- 设置变动:按 scope解析/增强/索引)精准失效。
---
## 失败与回退
- Worker 异常:自动回退主线程解析;熔断/退避重试;错误事件与日志。
- 缓存损坏:校验失败则清理对应命名空间并重建;保留其余命名空间。
- 事件风暴:限流与批处理;视图侧忽略过期序号。
---
## 性能与 SLO
- 冷启动:优先使用 consolidated:taskIndex 或 tasks.augmented目标 P50 < 300ms视库大小微调
- 增量更新:单文件保存到视图更新 P95 < 150ms含解析 + augment + index + 事件
- 内存:索引结构保持与现有相当;新增缓存命名空间带来可控增量。
---
## 向后兼容与迁移
- Adapter
- 视图 setTasks 调用 → 转为发事件并触发 QueryAPI从而兼容旧代码逐视图切换到纯事件。
- 逐步替换:
- ProjectResolver 接管后,禁用 FileMetadataTaskParser 的项目探测。
- Augmentor 接管继承后,解析器不再做继承。
- 配置兼容:沿用原设置字段并提供合理默认;新增 per-key 策略作为高级选项。
---
## 阶段性实施与检查清单
Phase A事件封装 + 查询 API2 天)
- [ ] 新增 events/Events.ts封装现有触发点保持事件名兼容
- [ ] 新增 api/QueryAPI.ts提供最小查询全部任务/按项目/按标签)。
- [ ] TaskManager 触发统一走 Events.ts。
Phase B解析入口收敛 + Augmentor3 天)
- [ ] 新建 parsers/*Entry.ts主线程路径先打通。
- [ ] 新建 augment/TaskAugmentor.ts落地继承策略task>file>project
- [ ] 修改 FileMetadataTaskParser允许禁用项目探测默认禁用
Phase C持久化命名空间 + hash2 天)
- [ ] StorageAdapter.ts命名空间 + 版本/架构版本 + hash。
- [ ] 冷启动优先加载 consolidated 或 tasks.augmented兼容旧数据。
Phase DWorkerOrchestrator3 天)
- [ ] 合并任务/项目 worker 调度;统一命令协议与回退策略。
- [ ] 指标与日志:成功率、延迟、退避情况。
Phase E视图去 setTasks试点 2 个视图3 天)
- [ ] 视图订阅事件 + QueryAPI 拉取;移除直接 setTasks。
- [ ] 保留 Adapter 以兼容未迁移视图。
Phase F项目配置变更仅增强重算2 天)
- [ ] 变更监听 → 失效 project.data 与 tasks.augmented → augment → 事件。
Phase G全面测试与性能调优2 天)
- [ ] 单测/集成测补齐SLO 校验;回归修复。
---
## 测试计划(重点)
- 冷启动:无修改 → 不 reindex版本兼容 → 直接用。
- 文件增量正文变更、frontmatter/tags 变更、重命名/删除;仅影响对应文件。
- 项目配置变更:仅增强重算;正文不解析。
- 设置变更:按 scope 精准失效。
- 事件一致性:视图通过事件 + 查询看到一致数据;序号去重验证。
- 兼容回归:
- 空/Null 排序规则:空值永远排在非空之后(双向排序)。
- 中文标签重复历史问题:复发任务创建链路校验不重复,解析层不二次注入。
- 性能P50/P95 指标达标;压力下稳定。
---
## 回退计划
- 任意阶段可切回旧路径:
- 解析:保留旧 TaskWorkerManager/TaskManager 主路径开关。
- 事件:保留 setTasks Adapter。
- 缓存:清空新命名空间后回退旧 consolidated 流程。
---
## 开放问题(需确认)
- 事件载荷是否需要强制携带 diff新增/删除/修改的 taskIds以优化大视图刷新
- 默认继承策略中是否存在“项目优先于文件”的字段(例如 SLA 类字段)?
- consolidated:taskIndex 是否纳入默认启用,还是作为可选以节省空间?
---
## 附:事件契约(建议)
- task-genius:cache-ready { initial: boolean, timestamp, seq }
- task-genius:task-cache-updated { changedFiles?: string[], stats?, timestamp, seq }
- task-genius:file-updated { path, reason, timestamp }
- task-genius:project-data-updated { affectedFiles: string[], timestamp }
- task-genius:settings-changed { scopes: string[], timestamp }
说明:保持与现有 obsidian-ex.d.ts 的兼容命名(如 task-cache-updated
---
## 结束语
本方案以“单一真相源 + 事件驱动 + 命名空间缓存 + 可回退”为核心,最大化复用现有解析/索引能力,在不破坏现有功能的前提下,消除重复与耦合点,确保视图数据与缓存/索引一致。分阶段推进、可测可回退,可支撑后续长期演进。

View file

@ -1,164 +0,0 @@
## Task Genius 数据流重构实施规范Implementation Spec
本规范补充《task-genius-refactor-plan.md》面向执行同学提供可直接落地的事件载荷类型、QueryAPI 函数签名、StorageAdapter 的 Key 规则,以及示例代码与任务清单。
---
### 1. 事件载荷类型(建议)
事件名称与 obsidian-ex.d.ts 兼容,并统一通过 Events.ts 导出常量与帮助方法。
- task-genius:cache-ready
- payload: { initial: boolean; timestamp: number; seq: number }
- task-genius:task-cache-updated
- payload: { changedFiles?: string[]; stats?: { total: number; changed: number }; timestamp: number; seq: number }
- task-genius:file-updated
- payload: { path: string; reason: "modify" | "frontmatter" | "rename" | "delete"; timestamp: number }
- task-genius:project-data-updated
- payload: { affectedFiles: string[]; reason?: string; timestamp: number }
- task-genius:settings-changed
- payload: { scopes: ("parser" | "augment" | "index" | "view")[]; timestamp: number }
- 保留task-genius:task-completed/task-added/task-updated/task-deleted按现有类型
辅助:
- seq 为单调递增序号TaskRepository 维护)
- timestamp 为事件生成时间
---
### 2. QueryAPI 函数签名(草案)
文件src/dataflow/api/QueryAPI.ts
- getAllTasks(): Promise<Task[]>
- getTasksByProject(projectName: string): Promise<Task[]>
- getTasksByTags(tags: string[]): Promise<Task[]>
- getTasksByStatus(completed: boolean): Promise<Task[]>
- getTasksByDateRange(opts: { from?: number; to?: number; field?: "due" | "start" | "scheduled" }): Promise<Task[]>
- getTaskById(id: string): Promise<Task | null>
- getIndexSummary(): Promise<{ total: number; byProject: Record<string, number>; byTag: Record<string, number> }>
实现要点:
- 背后依赖 TaskRepository组合 TaskIndexer + Persistence严禁直接访问内部索引结构于视图层。
- 函数返回的 Task 均为“增强后任务”。
---
### 3. StorageAdapter Key 规则与版本
文件src/dataflow/persistence/StorageAdapter.ts
- 命名空间规范namespace:key
- tasks.raw:<filePath>
- project.data:<filePath>
- tasks.augmented:<filePath>
- consolidated:taskIndex
- meta:version插件版本
- meta:schemaVersion缓存架构版本
- 哈希与版本
- tasks.raw 记录:{ hash: string; time: number; version: string; schema: number; data: Task[] }
- project.data 记录:{ hash: string; time: number; version: string; schema: number; data: { tgProject?: TgProject; enhancedMetadata: Record<string, any> } }
- tasks.augmented 记录:{ hash: string; time: number; version: string; schema: number; data: Task[] }
- consolidated:taskIndex 记录:{ time: number; version: string; schema: number; data: TaskCacheSnapshot }
- 兼容策略
- 版本或 schema 不兼容时仅清理受影响命名空间。
- hash 优先判定是否需要重算mtime 仅作为辅助。
---
### 4. 代码示例2 段)
示例 A视图订阅事件 + QueryAPI 拉取(替代 setTasks
```ts
// 在某视图 onOpen 内
import { subscribeTaskCacheUpdated } from "src/dataflow/events/Events";
import { QueryAPI } from "src/dataflow/api/QueryAPI";
let unsub: () => void;
this.registerEvent(
(unsub = subscribeTaskCacheUpdated(async (payload) => {
const tasks = await QueryAPI.getTasksByProject(this.currentProject ?? "");
this.renderer.render(tasks); // 视图自身的渲染方法
}))
);
// onClose 时
if (unsub) unsub();
```
示例 B单文件变更 → 解析 + 增强 + 索引 + 事件
```ts
import { ParsersEntry } from "src/dataflow/parsers";
import { ProjectResolver } from "src/dataflow/project/ProjectResolver";
import { TaskAugmentor } from "src/dataflow/augment/TaskAugmentor";
import { TaskRepository } from "src/dataflow/indexer/TaskRepository";
import { emitTaskCacheUpdated } from "src/dataflow/events/Events";
import { StorageAdapter } from "src/dataflow/persistence/StorageAdapter";
async function handleFileChanged(filePath: string) {
// 1. 尝试读取 tasks.rawhash 命中则跳过正文解析)
const raw = await StorageAdapter.loadRaw(filePath);
const needsParse = !(raw && StorageAdapter.isRawValid(filePath, raw));
const rawTasks = needsParse
? await ParsersEntry.parseFile(filePath) // Markdown/Canvas/FileLevel 分流
: raw.data;
if (needsParse) await StorageAdapter.storeRaw(filePath, rawTasks);
// 2. 读取/计算项目数据(可并行)
const proj = await ProjectResolver.getProjectData(filePath);
await StorageAdapter.storeProjectData(filePath, proj);
// 3. 增强合并
const augmented = await TaskAugmentor.merge({ filePath, rawTasks, project: proj });
await StorageAdapter.storeAugmented(filePath, augmented);
// 4. 更新索引
await TaskRepository.updateFile(filePath, augmented);
// 5. 广播事件
emitTaskCacheUpdated({ changedFiles: [filePath], timestamp: Date.now() });
}
```
---
### 5. 执行清单(给贡献者)
1) 新增骨架文件
- src/dataflow/events/Events.ts事件常量与 emit/subscribe内部维护 seq。
- src/dataflow/api/QueryAPI.ts空壳方法先返回现有 TaskManager 数据(过渡)。
- src/dataflow/parsers/MarkdownTaskParserEntry.ts包装现有 ConfigurableTaskParser.parseLegacy。
- src/dataflow/parsers/CanvasTaskParserEntry.ts包装现有 CanvasParser。
- src/dataflow/parsers/FileLevelTaskParser.ts包装现有 FileMetadataTaskParser并添加“禁用项目探测”配置默认禁用
- src/dataflow/augment/TaskAugmentor.ts实现继承策略task>file>project支持子任务控制。
- src/dataflow/project/ProjectResolver.ts统一项目识别接口内部复用 ProjectConfigManager/ProjectDataCache。
- src/dataflow/persistence/StorageAdapter.ts命名空间 + 版本/schema + hash 校验;读写 helpers。
- src/dataflow/indexer/TaskRepository.ts组合 TaskIndexer 与 StorageAdapter对外提供查询。
2) TaskManager 接入
- 触发事件统一改为 Events.ts 的封装。
- 冷启动改为优先读取 consolidated 或 tasks.augmented失败再回落旧流程。
- 单文件变更路径替换为“解析入口 + Augmentor + Repository”的新流水线逐步灰度
3) 视图迁移(首批 1-2 个)
- 去除直接 setTasks 调用,改成订阅 task-cache-updated + QueryAPI 拉取。
- 保留 Adapter 以兼容未迁移视图。
4) 持久化与失效策略
- 引入命名空间 key 规则与 hash 计算;对项目配置变更只失效 project.data 与 tasks.augmented。
5) 测试
- 单测ParsersEntry、TaskAugmentor继承策略、StorageAdapterhash/版本/失效、ProjectResolver优先级
- 集成:单文件改动/重命名/删除、项目配置变更、冷启动、事件序号。
6) 文档
- 在 README 或开发文档中标注 setTasks 已废弃(迁移至事件 + QueryAPI
---
如需我补充具体类型定义TypeScript 接口)或更详细的函数注释,请告知要优先完善的模块。

View file

@ -1,82 +0,0 @@
# TaskIndexer 迁移动计划
## 1. 目标
- 将 TaskIndexer 从 `src/utils/import/TaskIndexer.ts` 迁移至 `src/dataflow/indexer/TaskIndexer.ts`
- 统一“索引层”的所有权到 dataflow 命名空间,减少新旧架构交叉依赖。
- 保持功能零回归、提供兼容过渡re-export并具备可快速回滚能力。
## 2. 现状与依赖
- 现有引用(至少):
- dataflow: `src/dataflow/indexer/Repository.ts``../../utils/import/TaskIndexer`
- legacy: `src/utils/TaskManager.ts``./import/TaskIndexer`
- 说明Repository 属于 dataflow却反向引用 utils 的 TaskIndexer迁移后应改为本地引用 `./TaskIndexer`
## 3. 分阶段迁移步骤
### 阶段 A平滑迁移与适配兼容期
1) 移动实现
- 将 `src/utils/import/TaskIndexer.ts` 的实现移动到 `src/dataflow/indexer/TaskIndexer.ts`
- 修正文件内部的相对导入路径(若有)。
2) 更新 dataflow 内部引用
- 修改 `src/dataflow/indexer/Repository.ts` 导入:
- `import { TaskIndexer } from "./TaskIndexer";`
3) 旧路径提供 re-export保持旧架构可用
- 将 `src/utils/import/TaskIndexer.ts` 改为仅转发:
```ts
export { TaskIndexer } from "../../dataflow/indexer/TaskIndexer";
```
4) (可选)在 `src/dataflow/index.ts` 导出 TaskIndexer仅当需要对外暴露
### 阶段 B去耦旧架构依赖
5) 旧 TaskManager 改用新路径
- 在 `src/utils/TaskManager.ts` 将导入改为:
- `import { TaskIndexer } from "../dataflow/indexer/TaskIndexer";`(或继续依赖上一步 re-export推荐直接走 dataflow
6) 全仓替换引用
- 搜索引用旧路径的地方(包含相对路径与别名路径),替换为 dataflow 新路径或保留通过 re-export 过渡。
7) 校验环依赖
- 确认 utils → dataflow 的依赖不会引入 dataflow ↔ utils 的循环(若存在,则保持 TaskManager 通过 re-export 访问)。
### 阶段 C收尾与清理
8) 文档更新
- 更新架构文档中 TaskIndexer 所有权,归属 `src/dataflow/indexer`
9) 清理 re-export下个版本周期
- 保留 `src/utils/import/TaskIndexer.ts` re-export 一个版本周期后,删除该文件。
10) 守护措施(可选)
- 在 `src/utils/import/` 目录添加 README 或 lint 规则,禁止新增 dataflow 相关实现,仅允许过渡性 re-export。
## 4. 任务清单(派工用)
- A1 移动实现并修正内部导入
- A2 更新 Repository 导入路径
- A3 添加 re-export 兼容层
- B1 更新 TaskManager 导入为 dataflow 新路径
- B2 全仓替换其他引用(如有)
- B3 编译/类型检查 + 本地运行验证
- C1 更新 docsdataflow-architecture 等)
- C2 移除 re-export一个版本周期后
## 5. 验收标准DoD
- 构建与类型检查通过,无循环依赖警告
- dataflow 默认路径正常:
- 冷启动从 Storage 快照恢复成功Repository.initialize
- 事件广播与视图刷新正常CACHE_READY/TASK_CACHE_UPDATED
- 旧 TaskManager 路径仍可回退使用(过渡期)
- 全仓再无对 `utils/import/TaskIndexer` 的直接实现引用(仅允许 re-export 在过渡期存在)
## 6. 风险与回滚
- 风险:隐性引用遗漏
- 缓解grep 全仓 `from "./import/TaskIndexer"``from "../../utils/import/TaskIndexer"`
- 风险:环依赖
- 缓解TaskManager 如引入环,则继续通过 re-export 访问;确认后再做进一步解耦。
- 回滚:保留 re-export 不删即可回滚Repository 可临时指回旧路径)。
## 7. 预估工作量
- AB0.51 天(含全仓引用更新与验证)
- C合并后 1 个版本周期内清理0.5 天)

View file

@ -1,169 +0,0 @@
# TaskManager → Dataflow 架构迁移计划
本计划用于逐步替换仓库内对 TaskManager 的依赖,全面切换到 Dataflow 架构QueryAPI + Repository + Events + WorkerOrchestrator + WriteAPI
---
## 1. 现存 TaskManager 依赖清单(待迁移点)
以下为当前明确依赖 TaskManager 的文件与使用方式(以本仓库为范围):
- src/index.ts
- 持有实例:`taskManager: TaskManager`
- 初始化:在 onload 时 `new TaskManager(...)``this.addChild(this.taskManager)`
- 与版本管理耦合VersionManager 检测版本变化后调用 `taskManager.initialize()` 触发重建
- 数据查询/回退WriteAPI 的 `getTaskById` 优先 dataflow失败则回退 `this.taskManager.getTaskById`
- 其它:`setProgressManager()`、`initialize()`、`getAllTasks()` 等调用路径
- src/pages/TaskView.ts
- 读取:`this.plugin.taskManager.getAllTasksWithSync()` / `this.plugin.taskManager.getAllTasks()`
- 用于初始化与后续刷新
- src/mcp/McpServer.ts
- 判断/桥接:在 dataflow 未启用时检查 `this.plugin.taskManager` 存在性
- 绑定桥:`this.taskBridge = new TaskManagerBridge(this.plugin, this.plugin.taskManager)`
- src/mcp/bridge/TaskManagerBridge.ts
- 广泛使用 TaskManager查询/索引/更新/获取文件任务等(`getAllTasks`、`indexFile`、`getTasksForFile`、`updateTask` 等)
- 文档说明(需更新):
- src/utils/README.md 描述了 TaskManager 是“Primary orchestrator”迁移后将以 Dataflow 架构为主
> 备注:可能仍有零散依赖 `this.taskManager` 的地方,迁移期需通过全仓检索“`taskManager`”“`TaskManager`”逐步清理。
---
## 2. 迁移目标与原则
- 目标:所有读取、写入、索引、事件广播、缓存持久化均通过 Dataflow。
- 原则:
- 渐进式切换:在开关/灰度下替换调用者,优先完成“读取路径”迁移,随后完成“写入路径”与“初始化/重建路径”迁移。
- 兼容性:在切换窗口期保留 TaskManager 适配器与回退路径,直到完成验证。
- 稳定性优先:每一阶段完成后提供可回退的 feature flag。
---
## 3. 分阶段实施计划(建议顺序)
### Phase 0开关与基础
- 确认并使用既有 `settings.experimental.dataflowEnabled` 开关门控。
- 在该开关打开时:严禁新的调用者再接入 TaskManager新功能只接入 Dataflow。
### Phase 1读取路径迁移Views/MCP 查询)
- 目标:所有“读”都从 Dataflow 的 QueryAPI/Repository 取数,而非 TaskManager。
- 任务:
1. 视图层(以 TaskView 为起点)
- 改造 `TaskView`
- 将 `loadTasksFromTaskManager()` 替换为基于 Dataflow 的查询:
- 订阅 Dataflow 事件 `CACHE_READY`initial/非 initial`TASK_CACHE_UPDATED`
- 初次加载:`dataflowOrchestrator.queryAPI.getAllTasks()` 或基于筛选的查询
- 去除对 `this.plugin.taskManager` 的直接读取
2. MCP 查询层
- 用 `DataflowBridge` 取代 `TaskManagerBridge`
- 若缺功能(如按条件查询/搜索/按日期范围等),扩展 `DataflowBridge`,通过 `QueryAPI`/`Repository` 实现
- 在 `McpServer` 中:当 dataflowEnabled 时,优先创建并使用 `DataflowBridge`,不再依赖 `TaskManagerBridge`
- 验收:关闭 TaskManager 后,视图和 MCP 查询仍能完整工作(仅依赖 Dataflow
### Phase 2写入路径统一创建/更新/删除)
- 目标:所有写操作通过 Dataflow 的 WriteAPI + 事件回流(而非 TaskManager 的更新方法)。
- 任务:
- 统一写入口:确保 UI/MCP 写操作均使用 `WriteAPI`(已存在)
- 监听 `WRITE_OPERATION_*``FILE_UPDATED`,由 Orchestrator 触发增量解析与索引
- 从 `TaskManagerBridge` 中迁移写逻辑至 `DataflowBridge`(或直接调用 `WriteAPI`
- 验收:关闭 TaskManager 后,写入与后续实时更新(事件/视图刷新)正常。
### Phase 3初始化/重建路径迁移
- 目标:去除对 TaskManager 初始化与 VersionManager-重建的耦合,改由 Dataflow 主导冷启动与重建。
- 任务:
- 在 `src/index.ts`
- 若 dataflowEnabled跳过 `new TaskManager(...)` 与其 `initialize()`、`setProgressManager()`、版本重建流程;以 Dataflow 的 `Repository.initialize()` + `Orchestrator.initialize()` 为唯一路径
- 若需要版本驱动重建(兼容策略),在 Dataflow 中实现对应的重建触发(调用 `DataflowOrchestrator.rebuild()`
- 验收dataflowEnabled 下,重启不再触发 TaskManager 重建路径;缓存与增量解析由 Dataflow 自洽。
### Phase 4适配器/回退清理
- 目标:在默认启用 Dataflow 后,移除大部分 TaskManager 依赖,保留最小回退。
- 任务:
- 在配置中隐藏或标注 TaskManager 已废弃
- 将 `TaskManagerBridge` 标记 deprecated并在代码注释中引导迁移到 `DataflowBridge`
- 清理 src/utils/README.md 等文档中对 TaskManager 的“Primary orchestrator”描述改为 Dataflow
### Phase 5彻底移除 TaskManager最终
- 前置条件:稳定运行一段时间(至少 1-2 个版本周期),无回退需求
- 任务:移除 `src/managers/task-manager.ts` 与相关桥接/引用、设置项
---
## 4. 详细改动清单(按文件)
- src/index.ts
- [Phase 3] dataflowEnabled 时:不实例化 TaskManager不进入 VersionManager→TaskManager 的重建流程
- [Phase 1/2] WriteAPI 只走 Dataflow`getTaskById` 的 fallback 去除(或仅在禁用 dataflow 时保留)
- src/pages/TaskView.ts
- [Phase 1] 替换为订阅 Dataflow 事件 + `QueryAPI` 拉取
- 移除 `loadTasksFromTaskManager` / `this.plugin.taskManager` 依赖
- src/mcp/McpServer.ts
- [Phase 1] dataflowEnabled 时绑定 `DataflowBridge`(扩展其查询接口)
- 移除/降级 `TaskManagerBridge` 使用
- src/mcp/bridge/TaskManagerBridge.ts
- [Phase 2/4] 将功能迁移至 `DataflowBridge`,并标记 deprecated最终删除
- 文档
- src/utils/README.md更新“核心架构图/职责”,以 Dataflow 为准
- (全仓)
- 检索与替换:`this.taskManager` / `TaskManager` 的 import/方法调用
---
## 5. 事件/查询对齐(供视图迁移参照)
- 事件:
- 使用 Dataflow 事件中心src/dataflow/events/Events.ts
- `CACHE_READY`initial 与非 initial
- `TASK_CACHE_UPDATED`(批量或单文件更新)
- 查询:
- 使用 Dataflow `QueryAPI`
- `getAllTasks()`、`getTasksByProject(project)`、`getTasksByTags(tags)`、`byDateRange({from,to,field})` 等(可按需扩展)
---
## 6. 风险与回滚
- 风险:
- 视图或 MCP 仍有隐藏依赖 `TaskManager`
- 写入后事件链路与增量索引在部分场景不同步
- 缓解:
- 阶段性灰度与双写/双读对比(仅限调试)
- 增强日志与 metricsWorkerOrchestrator.metrics、Repository.persist 频率等)
- 回滚策略:
- 保留设置开关:关闭 dataflow 时恢复 TaskManager 初始化/路径
---
## 7. 建议的实施顺序与 PR 拆分
1) PR#1视图读取改造TaskView → Dataflow不改写入与初始化
2) PR#2MCP 查询改造TaskManagerBridge → DataflowBridge 扩展)
3) PR#3写入统一全面使用 WriteAPI + Dataflow 事件)
4) PR#4启动/重建路径切换dataflowEnabled 时禁用 TaskManager 初始化及其重建)
5) PR#5清理与文档deprecated 标记、README 更新)
6) PR#6移除 TaskManager最终
---
## 8. 待办检查清单(简版)
- [ ] 全仓检索并列出所有 `taskManager`/`TaskManager` 引用
- [ ] TaskView 读取改为 Dataflow + 事件订阅
- [ ] MCP 查询改为 DataflowBridge + QueryAPI
- [ ] 写入统一走 WriteAPIDataflow确认事件与索引链路
- [ ] dataflowEnabled 下禁用 TaskManager 初始化与重建
- [ ] 文档更新与 deprecated 标记
- [ ] 最终删除 TaskManager 代码

View file

@ -1,229 +0,0 @@
# TaskManager 与 WriteAPI/QueryAPI 功能差异分析报告
## 功能覆盖状态总览
### ✅ 已完全覆盖的功能
#### 写入操作 (WriteAPI 已实现)
- `updateTask` - 更新任务属性
- `createTask` - 创建新任务
- `deleteTask` - 删除任务
- `updateTaskStatus` - 更新任务状态/完成标记
- `batchUpdateTaskStatus` - 批量更新任务状态
- `postponeTasks` - 推迟任务到新日期
- `batchUpdateText` - 批量文本查找替换
- `batchCreateSubtasks` - 批量创建子任务
- `createTaskInDailyNote` - 在日记中创建任务
- `addProjectTaskToQuickCapture` - 添加项目任务到快速捕获
#### 查询操作 (QueryAPI 已实现)
- `getAllTasks` / `getAllTasksSync` - 获取所有任务
- `getTaskById` / `getTaskByIdSync` - 按ID获取任务
- `getTasksByProject` - 按项目筛选任务
- `getTasksByTags` - 按标签筛选任务
- `getTasksByStatus` - 按完成状态筛选任务
- `getTasksByDateRange` - 按日期范围筛选任务
- `query` - 通用查询接口 (支持 TaskFilter 和 SortingCriteria)
### ⚠️ 需要补充的功能
#### 1. 便捷查询方法 (需要在 QueryAPI 中添加)
```typescript
// 需要添加到 QueryAPI 的方法:
// 获取特定文件的任务
async getTasksForFile(filePath: string): Promise<Task[]> {
const allTasks = await this.getAllTasks();
return allTasks.filter(task => task.filePath === filePath);
}
// 获取今天到期的任务
async getTasksDueToday(): Promise<Task[]> {
const today = new Date();
today.setHours(0, 0, 0, 0);
const tomorrow = new Date(today);
tomorrow.setDate(tomorrow.getDate() + 1);
return this.getTasksByDateRange({
from: today,
to: tomorrow,
field: 'due'
});
}
// 获取过期任务
async getOverdueTasks(): Promise<Task[]> {
const now = new Date();
const allTasks = await this.getAllTasks();
return allTasks.filter(task =>
!task.completed &&
task.metadata?.dueDate &&
task.metadata.dueDate < now.getTime()
);
}
// 获取所有可用的上下文和项目
async getAvailableContextsAndProjects(): Promise<{
contexts: string[];
projects: string[];
}> {
const allTasks = await this.getAllTasks();
const contexts = new Set<string>();
const projects = new Set<string>();
allTasks.forEach(task => {
if (task.metadata?.context) contexts.add(task.metadata.context);
if (task.metadata?.project) projects.add(task.metadata.project);
// 兼容旧格式
const tgProject = (task.metadata as any)?.tgProject;
if (tgProject?.name) projects.add(tgProject.name);
});
return {
contexts: Array.from(contexts).sort(),
projects: Array.from(projects).sort()
};
}
// 获取未完成任务 (便捷方法)
async getIncompleteTasks(): Promise<Task[]> {
return this.getTasksByStatus(false);
}
// 获取已完成任务 (便捷方法)
async getCompletedTasks(): Promise<Task[]> {
return this.getTasksByStatus(true);
}
```
#### 2. 同步查询方法 (需要添加到 QueryAPI)
```typescript
// 基于缓存的同步方法:
getTasksForFileSync(filePath: string): Task[] {
const allTasks = this.getAllTasksSync();
return allTasks.filter(task => task.filePath === filePath);
}
getIncompleteTasksSync(): Task[] {
const allTasks = this.getAllTasksSync();
return allTasks.filter(task => !task.completed);
}
getCompletedTasksSync(): Task[] {
const allTasks = this.getAllTasksSync();
return allTasks.filter(task => task.completed);
}
```
### 🏗️ 架构差异说明
#### 管理器功能迁移
原 TaskManager 中的管理器功能在 Dataflow 架构中有不同的实现位置:
| TaskManager 功能 | Dataflow 架构对应 |
|-----------------|------------------|
| `FileFilterManager` | 集成在 `ObsidianSource``ConfigurableTaskParser` |
| `OnCompletionManager` | 需要在 `WriteAPI` 或独立模块中实现 |
| `RebuildProgressManager` | 集成在 `Orchestrator``rebuild()` 方法 |
| `forceReindex()` | `DataflowOrchestrator.rebuild()` |
| `updateParsingConfiguration()` | 配置直接更新Orchestrator 监听配置变化 |
| `updateFileFilterConfiguration()` | 配置直接更新ObsidianSource 响应变化 |
#### Canvas 和元数据支持
- `CanvasTaskUpdater` - 应该作为 WriteAPI 的扩展方法
- `FileMetadataTaskUpdater` - 已集成在 `ConfigurableTaskParser`
### 📋 实施建议
#### 优先级 1补充常用查询方法 ✅ 已完成
`src/dataflow/api/QueryAPI.ts` 中添加:
- [x] `getTasksForFile()` - ✅ 已实现
- [x] `getTasksDueToday()` - ✅ 已实现
- [x] `getOverdueTasks()` - ✅ 已实现
- [x] `getAvailableContextsAndProjects()` - ✅ 已实现
- [x] 对应的同步版本 (基于缓存) - ✅ 已实现
- [x] `getIncompleteTasks()` / `getCompletedTasks()` - ✅ 已实现
#### 优先级 2OnCompletion 支持
- [ ] 创建 `src/dataflow/managers/OnCompletionManager.ts`
- [ ] 在 WriteAPI 中集成 OnCompletion 触发逻辑
- [ ] 支持任务完成后的自动操作
#### 优先级 3Canvas 支持增强
- [ ] 在 WriteAPI 中添加 `updateCanvasTask()` 方法
- [ ] 确保 Canvas 文件的任务更新正确触发事件
#### 优先级 4清理和文档
- [ ] 更新 API 文档说明新增方法
- [ ] 在迁移指南中标注功能对应关系
- [ ] 清理遗留的 TaskManager 引用
### 📊 影响评估
#### 低风险补充
- 查询便捷方法 - 仅是现有功能的封装
- 同步查询方法 - 基于已有缓存机制
#### 中等风险功能
- OnCompletionManager - 需要与事件系统深度集成
- Canvas 任务更新 - 需要处理特殊文件格式
#### 已解决的风险
- 批量操作 - WriteAPI 已完整实现
- 日记集成 - createTaskInDailyNote 已实现
- 快速捕获 - addProjectTaskToQuickCapture 已实现
## 结论
WriteAPI 和 QueryAPI 已经覆盖了 TaskManager 的核心功能(约 **98%**)。
### 已完成的补充功能2025-08-22
**QueryAPI 便捷查询方法** - 全部实现:
- `getTasksForFile()` / `getTasksForFileSync()` - 获取文件任务
- `getTasksDueToday()` / `getTasksDueTodaySync()` - 今日到期任务
- `getOverdueTasks()` / `getOverdueTasksSync()` - 过期任务
- `getIncompleteTasks()` / `getIncompleteTasksSync()` - 未完成任务
- `getCompletedTasks()` / `getCompletedTasksSync()` - 已完成任务
- `getAvailableContextsAndProjects()` / `getAvailableContextsAndProjectsSync()` - 可用项目/上下文
**WriteAPI Canvas 支持** - 全部实现:
- `updateCanvasTask()` - 更新 Canvas 任务
- `deleteCanvasTask()` - 删除 Canvas 任务
- `moveCanvasTask()` - 移动 Canvas 任务
- `duplicateCanvasTask()` - 复制 Canvas 任务
- `addTaskToCanvasNode()` - 添加任务到 Canvas 节点
- `isCanvasTask()` - 检查是否为 Canvas 任务
- `getCanvasTaskUpdater()` - 获取 CanvasTaskUpdater 实例
- **自动检测**`updateTask()`, `deleteTask()`, `updateTaskStatus()` 会自动检测并处理 Canvas 任务
**OnCompletion 管理器** - 全部实现:
- OnCompletionManager 已集成到主插件
- WriteAPI 自动触发 task-completed 事件
- 支持所有 OnCompletion 操作delete, keep, archive, move, complete, duplicate
- Canvas 任务也完全支持 OnCompletion
- 完整的错误处理和日志记录
## 最终成果
### 功能覆盖率
WriteAPI 和 QueryAPI 现已覆盖 TaskManager **100%** 的功能!
### 已完成的所有工作
1. ✅ 所有 QueryAPI 便捷查询方法
2. ✅ 完整的 Canvas 任务支持
3. ✅ OnCompletion 管理器集成
4. ✅ 事件系统完整集成
5. ✅ 同步和异步方法支持
### 架构优势
- **模块化设计**:各组件职责清晰
- **事件驱动**:松耦合的组件通信
- **性能优化**:缓存机制和请求去重
- **向后兼容**:自动检测任务类型
- **可扩展性**:易于添加新功能
迁移已完全完成,系统现已成功切换到 Dataflow 架构!

View file

@ -1,126 +0,0 @@
# obsidian:// deep link rollout plan for Task Genius settings
This plan documents the exact deep-link formats supported by the plugin and where to add "Open Settings" buttons across the docs-site so users can jump directly to the right configuration screens in Obsidian.
## Supported URI formats
Primary scheme (recommended):
- Open plugin settings root
- obsidian://task-genius/settings
- Open a specific tab
- obsidian://task-genius/settings?tab=<tabId>
- Open tab and scroll to a section (where supported)
- obsidian://task-genius/settings?tab=<tabId>&section=<sectionId>
- Open tab and focus the search box with a query
- obsidian://task-genius/settings?tab=<tabId>&search=<text>
- Trigger tab-specific actions (currently on MCP tab):
- Enable MCP server: obsidian://task-genius/settings?tab=mcp-integration&action=enable
- Test MCP connection: obsidian://task-genius/settings?tab=mcp-integration&action=test
- Regenerate auth token: obsidian://task-genius/settings?tab=mcp-integration&action=regenerate-token
Alternative legacy form (also supported):
- obsidian://task-genius?action=settings (less explicit; prefer the path-based form above)
Notes
- Use ASCII punctuation exactly as shown: obsidian:// (not fullwidth colon).
- MCP Integration tab exists on desktop only; on mobile, deep links will land on the General tab.
## Tab IDs you can link to
- general
- index
- view-settings
- file-filter
- progress-bar
- task-status
- task-handler
- task-filter
- project
- workflow
- date-priority
- quick-capture
- task-timer
- time-parsing
- timeline-sidebar
- reward
- habit
- ics-integration
- mcp-integration (desktop only)
- beta-test
- experimental
- about
Special sections
- On the MCP Integration tab, section=cursor expands and scrolls to the Cursor client configuration section when present:
- obsidian://task-genius/settings?tab=mcp-integration&section=cursor
## Placement plan in docs-site
Add a small call-to-action button near the top of each pages Configuration or Getting Started section. Use consistent labels and the recommended links below.
Already good
- MCP Integration index: Includes Enable/Test deep links. Keep as is.
- MCP Clients (Cursor, Claude Desktop, Claude Code): Include “Open MCP Settings” deep links. Keep/expand with regenerate-token link in troubleshooting where helpful.
Add/update these pages
- /docs/getting-started
- Add an “Open Task Genius Settings” button: obsidian://task-genius/settings
- /docs/installation/index, /docs/installation/community, /docs/installation/manual
- After “Enable the plugin”, add: “Open Task Genius Settings”: obsidian://task-genius/settings
- /docs/quick-capture
- Add: “Open Quick Capture Settings”: obsidian://task-genius/settings?tab=quick-capture
- /docs/habit
- Add: “Open Habit Settings”: obsidian://task-genius/settings?tab=habit
- /docs/task-view/habit-view
- Add: “Open Habit Settings”: obsidian://task-genius/settings?tab=habit
- /docs/ics-support
- Add: “Open ICS Integration Settings”: obsidian://task-genius/settings?tab=ics-integration
- /docs/progress-bars
- Add: “Open Progress Display Settings”: obsidian://task-genius/settings?tab=progress-bar
- /docs/task-status
- Add: “Open Checkbox Status Settings”: obsidian://task-genius/settings?tab=task-status
- /docs/filtering
- Add: “Open Task Filter Settings”: obsidian://task-genius/settings?tab=task-filter
- /docs/date-priority
- Add: “Open Dates & Priority Settings”: obsidian://task-genius/settings?tab=date-priority
- /docs/task-view/timeline-sidebar-view
- Add: “Open Timeline Sidebar Settings”: obsidian://task-genius/settings?tab=timeline-sidebar
- /docs/workflows
- Add: “Open Workflows Settings”: obsidian://task-genius/settings?tab=workflow
- /docs/reward
- Add: “Open Rewards Settings”: obsidian://task-genius/settings?tab=reward
Optional advanced links
- MCP quick actions (place in troubleshooting sections):
- Enable server: obsidian://task-genius/settings?tab=mcp-integration&action=enable
- Test connection: obsidian://task-genius/settings?tab=mcp-integration&action=test
- Regenerate token: obsidian://task-genius/settings?tab=mcp-integration&action=regenerate-token
- Jump straight to Cursor section (MCP Integration):
- obsidian://task-genius/settings?tab=mcp-integration§ion=cursor
## Copy and style guidelines
- Button label conventions
- Primary: “Open … Settings” (e.g., “Open MCP Settings”).
- Keep labels short; avoid sentence case after the first word.
- Use a styled anchor tag in MDX pages for visual prominence, e.g.:
- <a href="obsidian://task-genius/settings?tab=habit" className="btn btn-primary">Open Habit Settings</a>
- Place the button right after the first paragraph of the Configuration section, or at the end of the Installation steps.
- Include a one-line fallback for users whose environment blocks deeplinks: “If the button doesnt work, open Obsidian → Settings → Community Plugins → Task Genius → [Tab Name].”
## Consistency notes for client docs
- Server name in examples
- Our server name auto-derives from the vault (e.g., my-vault-tasks) with a fallback obsidian-tasks. For simplicity, standardize docs examples to obsidian-tasks unless showing multi-vault setups.
- Auth header format
- Always show: Authorization: Bearer TOKEN+APP_ID
- Ports
- Default port 7777. Use 7778, 7779 in multi-vault examples.
## Validation checklist
- All new links use ASCII obsidian:// and correct tab IDs.
- MCP action links validated on desktop (enable, test, regenerate-token).
- Mobile gracefully shows General tab when MCP tab not available.
- Pages render with a single primary button per configuration area to reduce clutter.

View file

@ -1,61 +0,0 @@
# Worker Processing Control Implementation
## Overview
Implemented complete control for background worker processing in Task Genius plugin, allowing users to enable/disable worker threads for file parsing performance optimization.
## Changes Made
### 1. Settings UI Integration (`IndexSettingsTab.ts`)
- Updated the "Enable worker processing" toggle to use the new `fileSource.performance.enableWorkerProcessing` setting path
- Added backward compatibility with legacy `fileParsingConfig.enableWorkerProcessing` setting
- Ensures proper initialization of setting structure when needed
### 2. WorkerOrchestrator Enhancement (`WorkerOrchestrator.ts`)
- Added `enableWorkerProcessing` configuration option to constructor
- Implemented `setWorkerProcessingEnabled()` method for dynamic control
- Added `isWorkerProcessingEnabled()` status check method
- Enhanced `getMetrics()` to provide comprehensive performance statistics
- Circuit breaker automatically resets when re-enabling workers
### 3. DataflowOrchestrator Integration (`Orchestrator.ts`)
- Reads worker processing setting from both new and legacy paths
- Passes configuration to WorkerOrchestrator during initialization
- Added `updateSettings()` method to propagate setting changes
- Added `getWorkerStatus()` for monitoring worker state and metrics
### 4. Settings Update Flow (`setting.ts`)
- Modified `applySettingsUpdate()` to call `dataflowOrchestrator.updateSettings()`
- Ensures worker processing changes take effect immediately without restart
### 5. FileSource Management (`FileSource.ts`)
- Added `cleanup()` method for proper resource cleanup
- Added `updateConfig()` alias for configuration updates
- Properly handles initialization and cleanup based on settings
## How It Works
1. **User toggles setting**: User changes "Enable worker processing" in Index Settings
2. **Setting saved**: New value stored in `fileSource.performance.enableWorkerProcessing`
3. **Update propagated**: `applySettingsUpdate()` calls `dataflowOrchestrator.updateSettings()`
4. **Worker control**: `WorkerOrchestrator.setWorkerProcessingEnabled()` updates worker state
5. **Processing mode**: Tasks are processed either by workers or main thread based on setting
## Benefits
- **Performance Control**: Users can disable workers if experiencing issues
- **Dynamic Updates**: Changes take effect immediately without plugin restart
- **Backward Compatibility**: Works with both old and new setting paths
- **Circuit Breaker**: Automatic recovery when re-enabling workers
- **Monitoring**: Comprehensive metrics for debugging and optimization
## Testing
Created comprehensive test suite (`worker-processing-control.test.ts`) that verifies:
- Default enabled state
- Configuration respect on initialization
- Dynamic enabling/disabling
- Circuit breaker reset behavior
- Metrics availability
- Settings path fallback logic
All tests pass successfully, confirming proper implementation.

View file

@ -52,17 +52,19 @@ export class FluentPlacement {
el.addClass("clickable-icon");
};
makeCard(
"inline",
t("Inline (Single-Page Immersion)"),
t("All content in one page, focusing on the main view and reducing interface distractions.")
);
makeCard(
"sideleaves",
t("Sideleaves (Multi-Column Collaboration)"),
t("Left navigation and right details as separate workspace sidebars, ideal for simultaneous browsing and editing.")
);
makeCard(
"inline",
t("Inline (Single-Page Immersion)"),
t("All content in one page, focusing on the main view and reducing interface distractions.")
);
const tips = section.createDiv({ cls: "placement-tips" });
tips.createEl("p", {

View file

@ -229,7 +229,7 @@ export class ComponentPreviewFactory {
];
mockTasks.forEach(task => {
const taskItem = taskList.createDiv({ cls: "task-list-item" });
const taskItem = taskList.createDiv({ cls: "task-item" });
const checkbox = taskItem.createDiv({ cls: "task-checkbox" });
setIcon(checkbox, "circle");

View file

@ -41,7 +41,7 @@ export class FluentComponentsStep {
}> = [
{ id: "sidebar", label: t("Sidebar") },
{ id: "topnav", label: t("Top Navigation") },
{ id: "content", label: t("Content Area") },
// { id: "content", label: t("Content Area") },
{ id: "project", label: t("Project Management") },
];
@ -92,9 +92,9 @@ export class FluentComponentsStep {
case "topnav":
this.renderTopNavShowcase(previewSection, descSection);
break;
case "content":
this.renderContentShowcase(previewSection, descSection);
break;
// case "content":
// this.renderContentShowcase(previewSection, descSection);
// break;
case "project":
this.renderProjectShowcase(previewSection, descSection);
break;

View file

@ -68,7 +68,7 @@ export class PlacementStep {
showPreview: true,
},
(placement) => {
controller.setUseSideLeaves(placement === "sideleaves");
controller.setUseSideLeaves(placement === "inline");
}
);

View file

@ -4,6 +4,19 @@
overflow-y: hidden;
}
.component-preview .v2-nav-left {
display: none;
}
.onboarding-view:has(.component-showcase) .onboarding-header {
padding: calc(var(--onboarding-spacing) * 2) var(--onboarding-spacing) var(--size-4-2) var(--onboarding-spacing);
}
.v2-top-navigation.component-preview {
overflow-x: auto;
padding: 0;
}
/* Component showcase container */
.component-showcase {
display: flex;
@ -68,7 +81,6 @@
.component-preview {
pointer-events: none;
user-select: none;
transform-origin: top left;
}
/* Scale down previews to fit */
@ -76,17 +88,8 @@
max-width: 300px;
}
.component-preview-topnav {
transform: scale(0.9);
}
.component-preview-content {
transform: scale(0.9);
}
.component-preview-popover {
max-width: 350px;
transform: scale(0.9);
}
/* Disable interactions in previews */
@ -141,10 +144,6 @@
.component-showcase-preview {
min-height: 300px;
}
.component-preview {
transform: scale(0.75);
}
}
/* File filter preview styles */

File diff suppressed because one or more lines are too long