@maidang1/hataraku 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/CLAUDE.md +21 -0
- package/.codex/skills/beautiful-mermaid/SKILL.md +171 -0
- package/.codex/skills/beautiful-mermaid/references/mermaid-syntax.md +235 -0
- package/.codex/skills/beautiful-mermaid/scripts/create-html.ts +177 -0
- package/.codex/skills/beautiful-mermaid/scripts/render.ts +221 -0
- package/.codex/skills/find-skills/SKILL.md +133 -0
- package/.github/workflows/publish-github-packages.yml +58 -0
- package/.github/workflows/publish-npm.yml +46 -0
- package/.vscode/settings.json +2 -0
- package/AGENTS.md +41 -0
- package/LICENSE +21 -0
- package/README.md +119 -0
- package/bun.lock +327 -0
- package/docs/agent/architecture.md +28 -0
- package/docs/agent/development_commands.md +6 -0
- package/docs/plan/agent-plan-2026-02-05.md +136 -0
- package/docs/plan/core-agent-sdk-structure-2026-02-07.md +156 -0
- package/docs/plan/implementation-summary.md +303 -0
- package/docs/plan/mcp-2026-02-05.md +700 -0
- package/docs/plan/op.md +478 -0
- package/docs/plan/skills-2026-02-05.md +352 -0
- package/docs/plan/skills-flow.svg +120 -0
- package/docs/plan/tui-readability-2026-02-06.md +67 -0
- package/package.json +34 -0
- package/src/cli/index.tsx +4 -0
- package/src/cli/main.tsx +98 -0
- package/src/core/README.md +19 -0
- package/src/core/api/agent.ts +1 -0
- package/src/core/api/config.ts +1 -0
- package/src/core/api/index.ts +10 -0
- package/src/core/api/integrations.ts +1 -0
- package/src/core/api/observability.ts +1 -0
- package/src/core/api/policy.ts +1 -0
- package/src/core/api/providers.ts +1 -0
- package/src/core/api/runtime.ts +1 -0
- package/src/core/api/shared.ts +1 -0
- package/src/core/api/tools.ts +1 -0
- package/src/core/api/types.ts +1 -0
- package/src/core/index.ts +1 -0
- package/src/core/internal/config/defaults.ts +8 -0
- package/src/core/internal/config/index.ts +3 -0
- package/src/core/internal/config/loader.ts +97 -0
- package/src/core/internal/config/schema.ts +47 -0
- package/src/core/internal/integrations/index.ts +2 -0
- package/src/core/internal/integrations/mcp/connection-manager.ts +231 -0
- package/src/core/internal/integrations/mcp/health-checker.ts +91 -0
- package/src/core/internal/integrations/mcp/index.ts +197 -0
- package/src/core/internal/integrations/mcp/retry-strategy.ts +111 -0
- package/src/core/internal/integrations/mcp/tool-cache.ts +103 -0
- package/src/core/internal/integrations/mcp/transport.ts +58 -0
- package/src/core/internal/integrations/mcp/types.ts +95 -0
- package/src/core/internal/integrations/mcp/utils.ts +44 -0
- package/src/core/internal/integrations/skills/cache/index.ts +38 -0
- package/src/core/internal/integrations/skills/cache/interface.ts +9 -0
- package/src/core/internal/integrations/skills/cache/memory-cache.ts +118 -0
- package/src/core/internal/integrations/skills/config/defaults.ts +35 -0
- package/src/core/internal/integrations/skills/config/index.ts +71 -0
- package/src/core/internal/integrations/skills/config/schema.ts +31 -0
- package/src/core/internal/integrations/skills/core/errors.ts +36 -0
- package/src/core/internal/integrations/skills/core/events.ts +143 -0
- package/src/core/internal/integrations/skills/core/types.ts +83 -0
- package/src/core/internal/integrations/skills/dependency/conflict-detector.ts +126 -0
- package/src/core/internal/integrations/skills/dependency/graph.ts +91 -0
- package/src/core/internal/integrations/skills/dependency/resolver.ts +128 -0
- package/src/core/internal/integrations/skills/dependency/types.ts +51 -0
- package/src/core/internal/integrations/skills/discovery/index.ts +98 -0
- package/src/core/internal/integrations/skills/discovery/resolver.ts +39 -0
- package/src/core/internal/integrations/skills/discovery/scanner.ts +116 -0
- package/src/core/internal/integrations/skills/discovery/strategies/file-system.ts +16 -0
- package/src/core/internal/integrations/skills/index.ts +3 -0
- package/src/core/internal/integrations/skills/integration/lifecycle.ts +124 -0
- package/src/core/internal/integrations/skills/integration/mcp-loader.ts +100 -0
- package/src/core/internal/integrations/skills/integration/tool-mapper.ts +56 -0
- package/src/core/internal/integrations/skills/loaders/index.ts +5 -0
- package/src/core/internal/integrations/skills/loaders/skill-loader.ts +97 -0
- package/src/core/internal/integrations/skills/manager.ts +200 -0
- package/src/core/internal/integrations/skills/parsers/base.ts +134 -0
- package/src/core/internal/integrations/skills/parsers/factory.ts +42 -0
- package/src/core/internal/integrations/skills/parsers/index.ts +71 -0
- package/src/core/internal/integrations/skills/parsers/markdown.ts +111 -0
- package/src/core/internal/integrations/skills/parsers/yaml-metadata.ts +49 -0
- package/src/core/internal/integrations/skills/types.ts +15 -0
- package/src/core/internal/integrations/skills/utils/fs.ts +59 -0
- package/src/core/internal/integrations/skills/utils/logger.ts +109 -0
- package/src/core/internal/integrations/skills/utils/path.ts +27 -0
- package/src/core/internal/integrations/skills/validation/index.ts +43 -0
- package/src/core/internal/integrations/skills/validation/schema.ts +37 -0
- package/src/core/internal/integrations/skills/validation/skill-validator.ts +56 -0
- package/src/core/internal/observability/index.ts +2 -0
- package/src/core/internal/observability/logging/env.ts +32 -0
- package/src/core/internal/observability/logging/export.ts +55 -0
- package/src/core/internal/observability/logging/index.ts +4 -0
- package/src/core/internal/observability/logging/session-logger.ts +54 -0
- package/src/core/internal/observability/logging/types.ts +53 -0
- package/src/core/internal/policy/index.ts +1 -0
- package/src/core/internal/policy/safety/index.ts +2 -0
- package/src/core/internal/policy/safety/policy.ts +96 -0
- package/src/core/internal/policy/safety/types.ts +24 -0
- package/src/core/internal/providers/anthropic/client.ts +20 -0
- package/src/core/internal/providers/anthropic/index.ts +1 -0
- package/src/core/internal/providers/index.ts +1 -0
- package/src/core/internal/sdk/agent/agent.ts +691 -0
- package/src/core/internal/sdk/agent/index.ts +3 -0
- package/src/core/internal/sdk/agent/session.ts +9 -0
- package/src/core/internal/sdk/agent/tool-loop.ts +10 -0
- package/src/core/internal/sdk/index.ts +3 -0
- package/src/core/internal/sdk/runtime/context.ts +1 -0
- package/src/core/internal/sdk/runtime/errors.ts +9 -0
- package/src/core/internal/sdk/runtime/execution.ts +12 -0
- package/src/core/internal/sdk/runtime/index.ts +3 -0
- package/src/core/internal/sdk/types/api.ts +4 -0
- package/src/core/internal/sdk/types/index.ts +1 -0
- package/src/core/internal/sdk/types/internal.ts +1 -0
- package/src/core/internal/shared/fs.ts +10 -0
- package/src/core/internal/shared/index.ts +3 -0
- package/src/core/internal/shared/message.ts +12 -0
- package/src/core/internal/shared/path.ts +10 -0
- package/src/core/internal/tools/base/errors.ts +6 -0
- package/src/core/internal/tools/base/index.ts +3 -0
- package/src/core/internal/tools/base/schema.ts +1 -0
- package/src/core/internal/tools/base/tool.ts +42 -0
- package/src/core/internal/tools/builtins/architect.ts +45 -0
- package/src/core/internal/tools/builtins/bash.ts +135 -0
- package/src/core/internal/tools/builtins/fetch.ts +62 -0
- package/src/core/internal/tools/builtins/file-edit.ts +134 -0
- package/src/core/internal/tools/builtins/file-read.ts +75 -0
- package/src/core/internal/tools/builtins/fs.ts +254 -0
- package/src/core/internal/tools/builtins/glob.ts +75 -0
- package/src/core/internal/tools/builtins/grep.ts +104 -0
- package/src/core/internal/tools/builtins/index.ts +26 -0
- package/src/core/internal/tools/builtins/list-files.ts +64 -0
- package/src/core/internal/tools/builtins/search.ts +50 -0
- package/src/core/internal/tools/builtins/skills.ts +127 -0
- package/src/core/internal/tools/builtins/todo.ts +121 -0
- package/src/core/internal/tools/guards/file-edit-cache.ts +21 -0
- package/src/core/internal/tools/guards/limits.ts +43 -0
- package/src/core/internal/tools/index.ts +39 -0
- package/src/core/internal/tools/registry/index.ts +2 -0
- package/src/core/internal/tools/registry/presets.ts +28 -0
- package/src/core/internal/tools/registry/registry.ts +21 -0
- package/src/index.ts +3 -0
- package/src/render/commands/index.ts +113 -0
- package/src/render/commands/init.ts +45 -0
- package/src/render/components/ActivityPane.tsx +67 -0
- package/src/render/components/ChatBubble.tsx +58 -0
- package/src/render/components/ConfirmCard.tsx +100 -0
- package/src/render/components/ConfirmSelectMenu.tsx +56 -0
- package/src/render/components/ConversationPane.tsx +65 -0
- package/src/render/components/EventTimeline.tsx +30 -0
- package/src/render/components/MarkdownText.tsx +139 -0
- package/src/render/components/SlashCommandMenu.tsx +68 -0
- package/src/render/components/Spinner.tsx +18 -0
- package/src/render/components/StatusBar.tsx +72 -0
- package/src/render/components/Timeline.tsx +57 -0
- package/src/render/components/TimelineEvent.tsx +313 -0
- package/src/render/components/ToolCard.tsx +126 -0
- package/src/render/components/formatters/confirm.test.ts +34 -0
- package/src/render/components/formatters/confirm.ts +32 -0
- package/src/render/index.tsx +466 -0
- package/src/render/state/events.ts +301 -0
- package/src/render/state/history.ts +5 -0
- package/src/render/state/loading.ts +18 -0
- package/src/render/state/message.tsx +35 -0
- package/src/render/state/store.ts +7 -0
- package/src/render/theme.ts +52 -0
- package/test-e2e.ts +250 -0
- package/tsconfig.json +29 -0
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
# Skills 加载逻辑重构计划
|
|
2
|
+
|
|
3
|
+
## Skills 加载流程图
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+
|
|
7
|
+
上图展示了 Skills 系统的完整加载流程,包括以下关键阶段:
|
|
8
|
+
|
|
9
|
+
1. **缓存检查**:首先检查是否有缓存的结果,避免重复加载
|
|
10
|
+
2. **发现阶段(Discovery)**:
|
|
11
|
+
- 解析根路径(Repo/User/System/Admin 四个作用域)
|
|
12
|
+
- 使用 BFS 算法扫描目录树
|
|
13
|
+
- 将发现的技能文件映射到对应的作用域
|
|
14
|
+
3. **解析阶段(Parse)**:
|
|
15
|
+
- 解析 SKILL.md 文件,提取 YAML frontmatter
|
|
16
|
+
- 解析 agents/openai.yaml 元数据文件
|
|
17
|
+
- 合并两个来源的元数据
|
|
18
|
+
4. **验证阶段(Validate)**:
|
|
19
|
+
- 使用 Zod Schema 验证元数据结构
|
|
20
|
+
- 检查技能是否启用(enabled 字段)
|
|
21
|
+
- 记录验证失败的警告
|
|
22
|
+
5. **结果处理**:
|
|
23
|
+
- 去重和排序(按作用域优先级和名称)
|
|
24
|
+
- 缓存结果以供后续使用
|
|
25
|
+
- 发出 loadComplete 事件
|
|
26
|
+
|
|
27
|
+
## 重构目标
|
|
28
|
+
|
|
29
|
+
将 skills 加载逻辑重构为更加清晰、模块化、可扩展的架构,解决以下问题:
|
|
30
|
+
|
|
31
|
+
1. **配置硬编码**:`.codex`、`SKILL.md`、`agents/openai.yaml` 等都是硬编码常量
|
|
32
|
+
2. **职责混乱**:`loader.ts` 同时负责文件发现、路径解析、内容解析、元数据加载
|
|
33
|
+
3. **缺乏抽象层**:没有将"发现策略"、"解析策略"、"配置源"等抽象出来
|
|
34
|
+
4. **错误处理粗糙**:大量 `try-catch` 且静默失败,错误信息不够详细
|
|
35
|
+
5. **缺乏日志系统**:加载过程不可观测
|
|
36
|
+
6. **类型安全不足**:大量使用 `any` 类型解析 YAML
|
|
37
|
+
7. **扩展性差**:添加新的技能格式或元数据来源需要修改核心逻辑
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## 新的目录结构
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
src/core/skills/
|
|
45
|
+
├── index.ts # 公共 API 导出
|
|
46
|
+
│
|
|
47
|
+
├── core/ # 核心类型定义
|
|
48
|
+
│ ├── types.ts # SkillMetadata、SkillScope 等核心类型
|
|
49
|
+
│ ├── errors.ts # 错误类型定义
|
|
50
|
+
│ └── events.ts # 事件类型定义
|
|
51
|
+
│
|
|
52
|
+
├── config/ # 配置系统
|
|
53
|
+
│ ├── index.ts # 配置管理器
|
|
54
|
+
│ ├── defaults.ts # 默认配置
|
|
55
|
+
│ └── schema.ts # 配置 schema (Zod)
|
|
56
|
+
│
|
|
57
|
+
├── discovery/ # 技能发现层
|
|
58
|
+
│ ├── index.ts # 发现协调器
|
|
59
|
+
│ ├── scanner.ts # 文件系统扫描器
|
|
60
|
+
│ ├── resolver.ts # 根路径解析器
|
|
61
|
+
│ └── strategies/ # 发现策略
|
|
62
|
+
│ └── file-system.ts # 基于文件系统的发现
|
|
63
|
+
│
|
|
64
|
+
├── parsers/ # 解析层
|
|
65
|
+
│ ├── index.ts # 解析器协调器
|
|
66
|
+
│ ├── base.ts # 抽象解析器基类
|
|
67
|
+
│ ├── markdown.ts # Markdown + YAML frontmatter 解析器
|
|
68
|
+
│ ├── yaml-metadata.ts # YAML 元数据解析器
|
|
69
|
+
│ └── factory.ts # 解析器工厂
|
|
70
|
+
│
|
|
71
|
+
├── loaders/ # 加载层
|
|
72
|
+
│ ├── index.ts # 加载器协调器
|
|
73
|
+
│ └── skill-loader.ts # 技能加载器实现
|
|
74
|
+
│
|
|
75
|
+
├── cache/ # 缓存系统
|
|
76
|
+
│ ├── index.ts # 缓存管理器
|
|
77
|
+
│ ├── memory-cache.ts # 内存缓存实现
|
|
78
|
+
│ └── interface.ts # 缓存接口定义
|
|
79
|
+
│
|
|
80
|
+
├── validation/ # 验证系统
|
|
81
|
+
│ ├── index.ts # 验证协调器
|
|
82
|
+
│ ├── skill-validator.ts # 技能数据验证器
|
|
83
|
+
│ └── schema.ts # Zod 验证 schema
|
|
84
|
+
│
|
|
85
|
+
├── utils/ # 工与其他函数
|
|
86
|
+
│ ├── path.ts # 路径处理工具
|
|
87
|
+
│ ├── fs.ts # 文件系统工具
|
|
88
|
+
│ └── logger.ts # 日志工具
|
|
89
|
+
│
|
|
90
|
+
├── manager.ts # SkillsManager(对外主最口)
|
|
91
|
+
└── types.ts # 向后兼容的类型导出
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
## 重构步骤
|
|
97
|
+
|
|
98
|
+
### 阶段 1:基础设施
|
|
99
|
+
|
|
100
|
+
1. 创建新的目录结构
|
|
101
|
+
- `src/core/skills/core/`
|
|
102
|
+
- `src/core/skills/config/`
|
|
103
|
+
- `src/core/skills/discovery/strategies/`
|
|
104
|
+
- `src/core/skills/parsers/`
|
|
105
|
+
- `src/core/skills/loaders/`
|
|
106
|
+
- `src/core/skills/cache/`
|
|
107
|
+
- `src/core/skills/validation/`
|
|
108
|
+
- `src/core/skills/utils/`
|
|
109
|
+
|
|
110
|
+
2. 实现配置系统
|
|
111
|
+
- `config/defaults.ts` - 定义默认配置(保持与现有行为一致)
|
|
112
|
+
- `config/schema.ts` - 定义 Zod 配置 schema
|
|
113
|
+
- `config/index.ts` - 配置管理器类
|
|
114
|
+
|
|
115
|
+
3. 实现日志系统
|
|
116
|
+
- `utils/logger.ts` - Logger 接口和 DefaultLogger 类
|
|
117
|
+
|
|
118
|
+
### 阶段 2:核心类型
|
|
119
|
+
|
|
120
|
+
4. 迁移和增强类型定义
|
|
121
|
+
- `core/types.ts` - 从现有 `types.ts` 迁移,添加新字段(version、author、tags、enabled)
|
|
122
|
+
- `core/errors.ts` - 定义 SkillLoadError、SkillParseError、SkillValidationError
|
|
123
|
+
- `core/events.ts` - 定义事件类型(loadStart、loadComplete、parseComplete 等)
|
|
124
|
+
|
|
125
|
+
### 阶段 3:发现层
|
|
126
|
+
|
|
127
|
+
5. 实现文件系统扫描器
|
|
128
|
+
- `discovery/scanner.ts` - BFS 扫描逻辑(从 `loader.ts:discoverSkillsUnderRoot` 提取)
|
|
129
|
+
|
|
130
|
+
6. 实现根路径解析器
|
|
131
|
+
- `discovery/resolver.ts` - 项目根查找和作用域解析(从 `manager.ts:resolveRoots` 提取)
|
|
132
|
+
|
|
133
|
+
7. 实现发现策略
|
|
134
|
+
- `discovery/strategies/file-system.ts` - 文件系统发现策略
|
|
135
|
+
|
|
136
|
+
8. 创建发现协调器
|
|
137
|
+
- `discovery/index.ts` - DiscoveryCoordinator 类
|
|
138
|
+
|
|
139
|
+
### 阶段 4:解析层
|
|
140
|
+
|
|
141
|
+
9. 实现解析器基类
|
|
142
|
+
- `parsers/base.ts` - 抽象 SkillParser 类
|
|
143
|
+
|
|
144
|
+
10. 实现 Markdown 解析器
|
|
145
|
+
- `parsers/markdown.ts` - 解析 SKILL.md 文件(从 `loader.ts:parseSkillFile` 提取)
|
|
146
|
+
|
|
147
|
+
11. 实现 YAML 元数据解析器
|
|
148
|
+
- `parsers/yaml-metadata.ts` - 解析 agents/openai.yaml(从 `loader.ts:loadSkillMetadata` 提取)
|
|
149
|
+
|
|
150
|
+
12. 创建解析器工厂
|
|
151
|
+
- `parsers/factory.ts` - 根据文件类型选择解析器
|
|
152
|
+
|
|
153
|
+
13. 创建解析器协调器
|
|
154
|
+
- `parsers/index.ts` - ParserCoordinator 类
|
|
155
|
+
|
|
156
|
+
### 阶段 5:验证系统
|
|
157
|
+
|
|
158
|
+
14. 实现 Zod 验证 schema
|
|
159
|
+
- `validation/schema.ts` - 完整的验证规则(使用 zod)
|
|
160
|
+
|
|
161
|
+
15. 实现验证器
|
|
162
|
+
- `validation/skill-validator.ts` - SkillValidator 类
|
|
163
|
+
|
|
164
|
+
16. 创建验证协调器
|
|
165
|
+
- `validation/index.ts` - 导出验证接口
|
|
166
|
+
|
|
167
|
+
### 阶段 6:缓存系统
|
|
168
|
+
|
|
169
|
+
17. 实现缓存接口
|
|
170
|
+
- `cache/interface.ts` - ICache 接口定义
|
|
171
|
+
|
|
172
|
+
18. 实现内存缓存
|
|
173
|
+
- `cache/memory-cache.ts` - MemoryCache 实现(支持 TTL)
|
|
174
|
+
|
|
175
|
+
19. 创建缓存管理器
|
|
176
|
+
- `cache/index.ts` - CacheManager 类
|
|
177
|
+
|
|
178
|
+
### 阶段 7:加载层
|
|
179
|
+
|
|
180
|
+
20. 实现技能加载器
|
|
181
|
+
- `loaders/skill-loader.ts` - 完整的加载流程(编排发现、解析、验证)
|
|
182
|
+
|
|
183
|
+
21. 创建加载器协调器
|
|
184
|
+
- `loaders/index.ts` - 导出加载接口
|
|
185
|
+
|
|
186
|
+
### 阶段 8:管理器重构
|
|
187
|
+
|
|
188
|
+
22. 重构 SkillsManager
|
|
189
|
+
- 保持公共接口不变
|
|
190
|
+
- 内部使用新的模块化组件
|
|
191
|
+
|
|
192
|
+
### 阶段 9:向后兼容
|
|
193
|
+
|
|
194
|
+
23. 更新类型导出
|
|
195
|
+
- 保留 `types.ts` 作为兼容层,从新模块重新导出
|
|
196
|
+
|
|
197
|
+
### 阶段 10:清理
|
|
198
|
+
|
|
199
|
+
24. 删除旧文件
|
|
200
|
+
- 删除 `loader.ts`
|
|
201
|
+
|
|
202
|
+
---
|
|
203
|
+
|
|
204
|
+
## 关键设计要点
|
|
205
|
+
|
|
206
|
+
### 配置化
|
|
207
|
+
|
|
208
|
+
```typescript
|
|
209
|
+
export interface SkillsConfig {
|
|
210
|
+
directories: {
|
|
211
|
+
homeDir: string;
|
|
212
|
+
userSkillsDir: string;
|
|
213
|
+
systemSkillsDir: string;
|
|
214
|
+
projectMarker: string[];
|
|
215
|
+
};
|
|
216
|
+
filenames: {
|
|
217
|
+
skillFile: string;
|
|
218
|
+
metadataDir: string;
|
|
219
|
+
metadataFile: string;
|
|
220
|
+
};
|
|
221
|
+
scanning: {
|
|
222
|
+
maxDepth: number;
|
|
223
|
+
maxDirsPerRoot: number;
|
|
224
|
+
followSymlinks: boolean[];
|
|
225
|
+
};
|
|
226
|
+
cache: {
|
|
227
|
+
enabled: boolean;
|
|
228
|
+
ttl: number;
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### 默认配置(保持向后兼容)
|
|
234
|
+
|
|
235
|
+
```typescript
|
|
236
|
+
export const DEFAULT_CONFIG: SkillsConfig = {
|
|
237
|
+
directories: {
|
|
238
|
+
homeDir: path.join(os.homedir(), '.codex'),
|
|
239
|
+
userSkillsDir: 'skills',
|
|
240
|
+
systemSkillsDir: 'skills/.system',
|
|
241
|
+
projectMarker: ['.git', '.codex', '.agents'],
|
|
242
|
+
},
|
|
243
|
+
filenames: {
|
|
244
|
+
skillFile: 'SKILL.md',
|
|
245
|
+
metadataDir: 'agents',
|
|
246
|
+
metadataFile: 'openai.yaml',
|
|
247
|
+
},
|
|
248
|
+
scanning: {
|
|
249
|
+
maxDepth: 6,
|
|
250
|
+
maxDirsPerRoot: 2000,
|
|
251
|
+
followSymlinks: [true, true, false, true], // Repo, User, System, Admin
|
|
252
|
+
},
|
|
253
|
+
cache: {
|
|
254
|
+
enabled: true,
|
|
255
|
+
ttl: 300000, // 5 分钟 in milliseconds
|
|
256
|
+
},
|
|
257
|
+
};
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
### 公共接口(保持不变)
|
|
261
|
+
|
|
262
|
+
```typescript
|
|
263
|
+
class SkillsManager {
|
|
264
|
+
constructor(codexHome: string);
|
|
265
|
+
getSkillsForCwd(cwd: string, forceReload?: boolean): SkillLoadOutcome;
|
|
266
|
+
clearCache(): void;
|
|
267
|
+
}
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
---
|
|
271
|
+
|
|
272
|
+
## 关键文件清单
|
|
273
|
+
|
|
274
|
+
### 需要创建的文件
|
|
275
|
+
|
|
276
|
+
```
|
|
277
|
+
src/core/skills/core/types.ts
|
|
278
|
+
src/core/skills/core/errors.ts
|
|
279
|
+
src/core/skills/core/events.ts
|
|
280
|
+
src/core/skills/config/index.ts
|
|
281
|
+
src/core/skills/config/defaults.ts
|
|
282
|
+
src/core/skills/config/schema.ts
|
|
283
|
+
src/core/skills/discovery/index.ts
|
|
284
|
+
src/core/skills/discovery/scanner.ts
|
|
285
|
+
src/core/skills/discovery/resolver.ts
|
|
286
|
+
src/core/skills/discovery/strategies/file-system.ts
|
|
287
|
+
src/core/skills/parsers/index.ts
|
|
288
|
+
src/core/skills/parsers/base.ts
|
|
289
|
+
src/core/skills/parsers/markdown.ts
|
|
290
|
+
src/core/skills/parsers/yaml-metadata.ts
|
|
291
|
+
src/core/skills/parsers/factory.ts
|
|
292
|
+
src/core/skills/loaders/index.ts
|
|
293
|
+
src/core/skills/loaders/skill-loader.ts
|
|
294
|
+
src/core/skills/cache/index.ts
|
|
295
|
+
src/core/skills/cache/memory-cache.ts
|
|
296
|
+
src/core/skills/cache/interface.ts
|
|
297
|
+
src/core/skills/validation/index.ts
|
|
298
|
+
src/core/skills/validation/skill-validator.ts
|
|
299
|
+
src/core/skills/validation/schema.ts
|
|
300
|
+
src/core/skills/utils/path.ts
|
|
301
|
+
src/core/skills/utils/fs.ts
|
|
302
|
+
src/core/skills/utils/logger.ts
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
### 需要修改的文件
|
|
306
|
+
|
|
307
|
+
```
|
|
308
|
+
src/core/skills/manager.ts # 重构内部实现
|
|
309
|
+
src/core/skills/types.ts # 改为兼容层
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
### 需要删除的文件
|
|
313
|
+
|
|
314
|
+
```
|
|
315
|
+
src/core/skills/loader.ts # 逻辑拆分到新模块
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
### 集成点
|
|
319
|
+
|
|
320
|
+
```
|
|
321
|
+
src/core/agent/index.ts # 确保 SkillsManager 兼容性
|
|
322
|
+
src/core/tools/skills.ts # 更新类型导入路径
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
---
|
|
326
|
+
|
|
327
|
+
## 验证步骤
|
|
328
|
+
|
|
329
|
+
1. 运行 `bun run src/index.ts` 确保应用正常启动
|
|
330
|
+
2. 验证 skills 能被正确加载(包括 .codex/skills 和项目级 skills)
|
|
331
|
+
3. 测试缓存机制(多次调用 `getSkillsForCwd` 应使用缓存)
|
|
332
|
+
4. 测试 `forceReload` 参数(应强制重新加载)
|
|
333
|
+
5. 验证元数据解析(SKILL.md + agents/openai.yaml)
|
|
334
|
+
6. 验证技能依赖处理(MCP 服务器动态加载)
|
|
335
|
+
|
|
336
|
+
---
|
|
337
|
+
|
|
338
|
+
## 依赖说明
|
|
339
|
+
|
|
340
|
+
- **js-yaml**:已存在,用于 YAML 解析
|
|
341
|
+
- **zod**:可能需要添加,用于运行时类型验证
|
|
342
|
+
|
|
343
|
+
### 检查 zod 是否已安装
|
|
344
|
+
|
|
345
|
+
```bash
|
|
346
|
+
bun pm ls zod
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
如果没有安装,需要运行:
|
|
350
|
+
```bash
|
|
351
|
+
bun add zod
|
|
352
|
+
```
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 696.7125 1317.2" width="696.7125" height="1317.2" style="--bg:#1a1b26;--fg:#a9b1d6;--line:#3d59a1;--accent:#7aa2f7;--muted:#565f89;background:var(--bg)">
|
|
2
|
+
<style>
|
|
3
|
+
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');
|
|
4
|
+
text { font-family: 'Inter', system-ui, sans-serif; }
|
|
5
|
+
svg {
|
|
6
|
+
/* Derived from --bg and --fg (overridable via --line, --accent, etc.) */
|
|
7
|
+
--_text: var(--fg);
|
|
8
|
+
--_text-sec: var(--muted, color-mix(in srgb, var(--fg) 60%, var(--bg)));
|
|
9
|
+
--_text-muted: var(--muted, color-mix(in srgb, var(--fg) 40%, var(--bg)));
|
|
10
|
+
--_text-faint: color-mix(in srgb, var(--fg) 25%, var(--bg));
|
|
11
|
+
--_line: var(--line, color-mix(in srgb, var(--fg) 30%, var(--bg)));
|
|
12
|
+
--_arrow: var(--accent, color-mix(in srgb, var(--fg) 50%, var(--bg)));
|
|
13
|
+
--_node-fill: var(--surface, color-mix(in srgb, var(--fg) 3%, var(--bg)));
|
|
14
|
+
--_node-stroke: var(--border, color-mix(in srgb, var(--fg) 20%, var(--bg)));
|
|
15
|
+
--_group-fill: var(--bg);
|
|
16
|
+
--_group-hdr: color-mix(in srgb, var(--fg) 5%, var(--bg));
|
|
17
|
+
--_inner-stroke: color-mix(in srgb, var(--fg) 12%, var(--bg));
|
|
18
|
+
--_key-badge: color-mix(in srgb, var(--fg) 10%, var(--bg));
|
|
19
|
+
}
|
|
20
|
+
</style>
|
|
21
|
+
<defs>
|
|
22
|
+
<marker id="arrowhead" markerWidth="8" markerHeight="4.8" refX="8" refY="2.4" orient="auto">
|
|
23
|
+
<polygon points="0 0, 8 2.4, 0 4.8" fill="var(--_arrow)" />
|
|
24
|
+
</marker>
|
|
25
|
+
<marker id="arrowhead-start" markerWidth="8" markerHeight="4.8" refX="0" refY="2.4" orient="auto-start-reverse">
|
|
26
|
+
<polygon points="8 0, 0 2.4, 8 4.8" fill="var(--_arrow)" />
|
|
27
|
+
</marker>
|
|
28
|
+
</defs>
|
|
29
|
+
<polyline points="304.42499999999995,76 304.42499999999995,116.00000000000001" fill="none" stroke="var(--_line)" stroke-width="0.75" marker-end="url(#arrowhead)" />
|
|
30
|
+
<polyline points="272.1823923264209,168.35739232642095 272.1823923264209,229.1 77.45,229.1 77.45,1165.2" fill="none" stroke="var(--_line)" stroke-width="0.75" marker-end="url(#arrowhead)" />
|
|
31
|
+
<polyline points="337.5404872345319,167.48451276546808 337.5404872345319,229.1 559.6999999999999,229.1 559.6999999999999,257.6" fill="none" stroke="var(--_line)" stroke-width="0.75" marker-end="url(#arrowhead)" />
|
|
32
|
+
<polyline points="559.6999999999999,293.6 559.6999999999999,375.77500000000003" fill="none" stroke="var(--_line)" stroke-width="0.75" marker-end="url(#arrowhead)" />
|
|
33
|
+
<polyline points="559.6999999999999,411.77500000000003 559.6999999999999,482.45000000000005 516.4575,482.45000000000005 516.4575,556.7" fill="none" stroke="var(--_line)" stroke-width="0.75" marker-end="url(#arrowhead)" />
|
|
34
|
+
<polyline points="516.4575,592.7 516.4575,695.45" fill="none" stroke="var(--_line)" stroke-width="0.75" marker-end="url(#arrowhead)" />
|
|
35
|
+
<polyline points="516.4575,731.45 516.4575,816.325" fill="none" stroke="var(--_line)" stroke-width="0.75" marker-end="url(#arrowhead)" />
|
|
36
|
+
<polyline points="516.4575,852.325 516.4575,955.2 478.13749999999993,955.2" fill="none" stroke="var(--_line)" stroke-width="0.75" marker-end="url(#arrowhead)" />
|
|
37
|
+
<polyline points="529.8874999999999,973.2 529.8874999999999,1013.2" fill="none" stroke="var(--_line)" stroke-width="0.75" marker-end="url(#arrowhead)" />
|
|
38
|
+
<polyline points="529.8874999999999,1049.2 529.8874999999999,1089.2" fill="none" stroke="var(--_line)" stroke-width="0.75" marker-end="url(#arrowhead)" />
|
|
39
|
+
<polyline points="529.8874999999999,1125.2 529.8874999999999,1165.2" fill="none" stroke="var(--_line)" stroke-width="0.75" marker-end="url(#arrowhead)" />
|
|
40
|
+
<polyline points="529.8874999999999,1201.2 529.8874999999999,1259.2 498.3124999999999,1259.2" fill="none" stroke="var(--_line)" stroke-width="0.75" marker-end="url(#arrowhead)" />
|
|
41
|
+
<polyline points="560.7874999999999,1241.2 560.7874999999999,1221.2 680.5,1221.2 680.5,405.61854001009897 366.96395998990107,405.61854001009897" fill="none" stroke="var(--_line)" stroke-width="0.75" marker-end="url(#arrowhead)" />
|
|
42
|
+
<polyline points="278.775899683954,414.09339968395403 278.775899683954,482.45000000000005 144.6875,482.45000000000005 144.6875,695.45" fill="none" stroke="var(--_line)" stroke-width="0.75" marker-end="url(#arrowhead)" />
|
|
43
|
+
<polyline points="302.822647578466,438.14014757846604 302.822647578466,482.45000000000005 287.03249999999997,482.45000000000005 287.03249999999997,510.95000000000005" fill="none" stroke="var(--_line)" stroke-width="0.75" marker-end="url(#arrowhead)" />
|
|
44
|
+
<polyline points="265.31546703296704,616.732967032967 265.31546703296704,666.95 239.37,666.95 239.37,695.45" fill="none" stroke="var(--_line)" stroke-width="0.75" marker-end="url(#arrowhead)" />
|
|
45
|
+
<polyline points="308.74953296703296,616.732967032967 308.74953296703296,666.95 334.695,666.95 334.695,695.45" fill="none" stroke="var(--_line)" stroke-width="0.75" marker-end="url(#arrowhead)" />
|
|
46
|
+
<polyline points="144.6875,731.45 144.6875,817.0689467695031 239.41855323049688,817.0689467695031" fill="none" stroke="var(--_line)" stroke-width="0.75" marker-end="url(#arrowhead)" />
|
|
47
|
+
<polyline points="239.37,731.45 239.37,801.2129042628042 255.2745957371958,801.2129042628042" fill="none" stroke="var(--_line)" stroke-width="0.75" marker-end="url(#arrowhead)" />
|
|
48
|
+
<polyline points="334.695,731.45 334.695,810.1323272118129 289.71982721181286,810.1323272118129" fill="none" stroke="var(--_line)" stroke-width="0.75" marker-end="url(#arrowhead)" />
|
|
49
|
+
<polyline points="305.36113187508613,842.8763681249138 305.36113187508613,908.7 592.6574999999999,908.7 592.6574999999999,955.2 581.6374999999999,955.2" fill="none" stroke="var(--_line)" stroke-width="0.75" marker-end="url(#arrowhead)" />
|
|
50
|
+
<polyline points="268.03749999999997,880.2 268.03749999999997,937.2" fill="none" stroke="var(--_line)" stroke-width="0.75" marker-end="url(#arrowhead)" />
|
|
51
|
+
<polyline points="268.03749999999997,973.2 268.03749999999997,1013.2" fill="none" stroke="var(--_line)" stroke-width="0.75" marker-end="url(#arrowhead)" />
|
|
52
|
+
<polyline points="268.03749999999997,1049.2 268.03749999999997,1089.2" fill="none" stroke="var(--_line)" stroke-width="0.75" marker-end="url(#arrowhead)" />
|
|
53
|
+
<polyline points="268.03749999999997,1125.2 268.03749999999997,1165.2" fill="none" stroke="var(--_line)" stroke-width="0.75" marker-end="url(#arrowhead)" />
|
|
54
|
+
<polyline points="77.45,1201.2 77.45,1259.2 74.03499999999995,1259.2" fill="none" stroke="var(--_line)" stroke-width="0.75" marker-end="url(#arrowhead)" />
|
|
55
|
+
<polyline points="268.03749999999997,1201.2 268.03749999999997,1259.2 134.03499999999997,1259.2" fill="none" stroke="var(--_line)" stroke-width="0.75" marker-end="url(#arrowhead)" />
|
|
56
|
+
<rect x="58.010000000000005" y="746.45" width="38.88" height="27" rx="4" ry="4" fill="var(--bg)" stroke="var(--_inner-stroke)" stroke-width="0.5" />
|
|
57
|
+
<text x="77.45" y="759.95" text-anchor="middle" dy="0.35em" font-size="11" font-weight="400" fill="var(--_text-muted)">缓存命中</text>
|
|
58
|
+
<rect x="537.4" y="215.6" width="44.6" height="27" rx="4" ry="4" fill="var(--bg)" stroke="var(--_inner-stroke)" stroke-width="0.5" />
|
|
59
|
+
<text x="559.6999999999999" y="229.1" text-anchor="middle" dy="0.35em" font-size="11" font-weight="400" fill="var(--_text-muted)">缓存未命中</text>
|
|
60
|
+
<rect x="125.2475" y="561.2" width="38.88" height="27" rx="4" ry="4" fill="var(--bg)" stroke="var(--_inner-stroke)" stroke-width="0.5" />
|
|
61
|
+
<text x="144.6875" y="574.7" text-anchor="middle" dy="0.35em" font-size="11" font-weight="400" fill="var(--_text-muted)">验证失败</text>
|
|
62
|
+
<rect x="267.5925" y="468.95000000000005" width="38.88" height="27" rx="4" ry="4" fill="var(--bg)" stroke="var(--_inner-stroke)" stroke-width="0.5" />
|
|
63
|
+
<text x="287.03249999999997" y="482.45000000000005" text-anchor="middle" dy="0.35em" font-size="11" font-weight="400" fill="var(--_text-muted)">验证通过</text>
|
|
64
|
+
<rect x="208.49" y="653.45" width="61.760000000000005" height="27" rx="4" ry="4" fill="var(--bg)" stroke="var(--_inner-stroke)" stroke-width="0.5" />
|
|
65
|
+
<text x="239.37" y="666.95" text-anchor="middle" dy="0.35em" font-size="11" font-weight="400" fill="var(--_text-muted)">disabled</text>
|
|
66
|
+
<rect x="306.675" y="653.45" width="56.04" height="27" rx="4" ry="4" fill="var(--bg)" stroke="var(--_inner-stroke)" stroke-width="0.5" />
|
|
67
|
+
<text x="334.695" y="666.95" text-anchor="middle" dy="0.35em" font-size="11" font-weight="400" fill="var(--_text-muted)">enabled</text>
|
|
68
|
+
<rect x="581.7974999999999" y="895.2" width="21.72" height="27" rx="4" ry="4" fill="var(--bg)" stroke="var(--_inner-stroke)" stroke-width="0.5" />
|
|
69
|
+
<text x="592.6574999999999" y="908.7" text-anchor="middle" dy="0.35em" font-size="11" font-weight="400" fill="var(--_text-muted)">是</text>
|
|
70
|
+
<rect x="257.17749999999995" y="895.2" width="21.72" height="27" rx="4" ry="4" fill="var(--bg)" stroke="var(--_inner-stroke)" stroke-width="0.5" />
|
|
71
|
+
<text x="268.03749999999997" y="908.7" text-anchor="middle" dy="0.35em" font-size="11" font-weight="400" fill="var(--_text-muted)">否</text>
|
|
72
|
+
<rect x="216.92499999999995" y="40" width="175" height="36" rx="18" ry="18" fill="#e1f5e1" stroke="var(--_node-stroke)" stroke-width="0.75" />
|
|
73
|
+
<polygon points="304.42499999999995,116.00000000000001 346.72499999999997,158.3 304.42499999999995,200.60000000000002 262.12499999999994,158.3" fill="#fff9c4" stroke="var(--_node-stroke)" stroke-width="0.75" />
|
|
74
|
+
<rect x="40" y="1165.2" width="74.9" height="36" rx="0" ry="0" fill="var(--_node-fill)" stroke="var(--_node-stroke)" stroke-width="0.75" />
|
|
75
|
+
<rect x="490.07499999999993" y="257.6" width="139.25" height="36" rx="0" ry="0" fill="var(--_node-fill)" stroke="var(--_node-stroke)" stroke-width="0.75" />
|
|
76
|
+
<rect x="493.6499999999999" y="375.77500000000003" width="132.10000000000002" height="36" rx="0" ry="0" fill="#e3f2fd" stroke="var(--_node-stroke)" stroke-width="0.75" />
|
|
77
|
+
<rect x="386.0575" y="556.7" width="260.8" height="36" rx="0" ry="0" fill="var(--_node-fill)" stroke="var(--_node-stroke)" stroke-width="0.75" />
|
|
78
|
+
<rect x="432.53249999999997" y="695.45" width="167.85000000000002" height="36" rx="0" ry="0" fill="var(--_node-fill)" stroke="var(--_node-stroke)" stroke-width="0.75" />
|
|
79
|
+
<rect x="471.85749999999996" y="816.325" width="89.2" height="36" rx="0" ry="0" fill="var(--_node-fill)" stroke="var(--_node-stroke)" stroke-width="0.75" />
|
|
80
|
+
<rect x="478.13749999999993" y="937.2" width="103.5" height="36" rx="0" ry="0" fill="#fff3e0" stroke="var(--_node-stroke)" stroke-width="0.75" />
|
|
81
|
+
<rect x="406.63749999999993" y="1013.2" width="246.50000000000003" height="36" rx="0" ry="0" fill="var(--_node-fill)" stroke="var(--_node-stroke)" stroke-width="0.75" />
|
|
82
|
+
<rect x="403.06249999999994" y="1089.2" width="253.65" height="36" rx="0" ry="0" fill="var(--_node-fill)" stroke="var(--_node-stroke)" stroke-width="0.75" />
|
|
83
|
+
<rect x="496.01249999999993" y="1165.2" width="67.75" height="36" rx="0" ry="0" fill="var(--_node-fill)" stroke="var(--_node-stroke)" stroke-width="0.75" />
|
|
84
|
+
<rect x="498.3124999999999" y="1241.2" width="124.95" height="36" rx="0" ry="0" fill="#f3e5f5" stroke="var(--_node-stroke)" stroke-width="0.75" />
|
|
85
|
+
<polygon points="318.6325,333.6 378.8075,393.77500000000003 318.6325,453.95000000000005 258.4575,393.77500000000003" fill="#fff9c4" stroke="var(--_node-stroke)" stroke-width="0.75" />
|
|
86
|
+
<rect x="114.3875" y="695.45" width="60.6" height="36" rx="0" ry="0" fill="var(--_node-fill)" stroke="var(--_node-stroke)" stroke-width="0.75" />
|
|
87
|
+
<polygon points="287.03249999999997,510.95000000000005 350.78249999999997,574.7 287.03249999999997,638.45 223.28249999999997,574.7" fill="#fff9c4" stroke="var(--_node-stroke)" stroke-width="0.75" />
|
|
88
|
+
<rect x="205.495" y="695.45" width="67.75" height="36" rx="0" ry="0" fill="var(--_node-fill)" stroke="var(--_node-stroke)" stroke-width="0.75" />
|
|
89
|
+
<rect x="297.245" y="695.45" width="74.9" height="36" rx="0" ry="0" fill="var(--_node-fill)" stroke="var(--_node-stroke)" stroke-width="0.75" />
|
|
90
|
+
<polygon points="268.03749999999997,788.45 313.91249999999997,834.325 268.03749999999997,880.2 222.16249999999997,834.325" fill="var(--_node-fill)" stroke="var(--_node-stroke)" stroke-width="0.75" />
|
|
91
|
+
<rect x="234.16249999999997" y="937.2" width="67.75" height="36" rx="0" ry="0" fill="var(--_node-fill)" stroke="var(--_node-stroke)" stroke-width="0.75" />
|
|
92
|
+
<rect x="237.73749999999995" y="1013.2" width="60.6" height="36" rx="0" ry="0" fill="var(--_node-fill)" stroke="var(--_node-stroke)" stroke-width="0.75" />
|
|
93
|
+
<rect x="187.68749999999994" y="1089.2" width="160.70000000000002" height="36" rx="0" ry="0" fill="var(--_node-fill)" stroke="var(--_node-stroke)" stroke-width="0.75" />
|
|
94
|
+
<rect x="184.11249999999995" y="1165.2" width="167.85000000000002" height="36" rx="0" ry="0" fill="var(--_node-fill)" stroke="var(--_node-stroke)" stroke-width="0.75" />
|
|
95
|
+
<rect x="74.03499999999995" y="1241.2" width="60" height="36" rx="18" ry="18" fill="#ffe1e1" stroke="var(--_node-stroke)" stroke-width="0.75" />
|
|
96
|
+
<text x="304.42499999999995" y="58" text-anchor="middle" dy="0.35em" font-size="13" font-weight="500" fill="var(--_text)">用户调用 getSkillsForCwd</text>
|
|
97
|
+
<text x="304.42499999999995" y="158.3" text-anchor="middle" dy="0.35em" font-size="13" font-weight="500" fill="var(--_text)">检查缓存</text>
|
|
98
|
+
<text x="77.45" y="1183.2" text-anchor="middle" dy="0.35em" font-size="13" font-weight="500" fill="var(--_text)">返回缓存结果</text>
|
|
99
|
+
<text x="559.6999999999999" y="275.6" text-anchor="middle" dy="0.35em" font-size="13" font-weight="500" fill="var(--_text)">发出 loadStart 事件</text>
|
|
100
|
+
<text x="559.6999999999999" y="393.77500000000003" text-anchor="middle" dy="0.35em" font-size="13" font-weight="500" fill="var(--_text)">发现阶段 Discovery</text>
|
|
101
|
+
<text x="516.4575" y="574.7" text-anchor="middle" dy="0.35em" font-size="13" font-weight="500" fill="var(--_text)">解析根路径<br/>Repo/User/System/Admin</text>
|
|
102
|
+
<text x="516.4575" y="713.45" text-anchor="middle" dy="0.35em" font-size="13" font-weight="500" fill="var(--_text)">扫描技能文件<br/>BFS 遍历目录</text>
|
|
103
|
+
<text x="516.4575" y="834.325" text-anchor="middle" dy="0.35em" font-size="13" font-weight="500" fill="var(--_text)">映射文件到作用域</text>
|
|
104
|
+
<text x="529.8874999999999" y="955.2" text-anchor="middle" dy="0.35em" font-size="13" font-weight="500" fill="var(--_text)">解析阶段 Parse</text>
|
|
105
|
+
<text x="529.8874999999999" y="1031.2" text-anchor="middle" dy="0.35em" font-size="13" font-weight="500" fill="var(--_text)">解析 SKILL.md<br/>提取 frontmatter</text>
|
|
106
|
+
<text x="529.8874999999999" y="1107.2" text-anchor="middle" dy="0.35em" font-size="13" font-weight="500" fill="var(--_text)">解析 agents/openai.yaml<br/>加载元数据</text>
|
|
107
|
+
<text x="529.8874999999999" y="1183.2" text-anchor="middle" dy="0.35em" font-size="13" font-weight="500" fill="var(--_text)">合并元数据</text>
|
|
108
|
+
<text x="560.7874999999999" y="1259.2" text-anchor="middle" dy="0.35em" font-size="13" font-weight="500" fill="var(--_text)">验证阶段 Validate</text>
|
|
109
|
+
<text x="318.6325" y="393.77500000000003" text-anchor="middle" dy="0.35em" font-size="13" font-weight="500" fill="var(--_text)">Schema 验证</text>
|
|
110
|
+
<text x="144.6875" y="713.45" text-anchor="middle" dy="0.35em" font-size="13" font-weight="500" fill="var(--_text)">记录警告</text>
|
|
111
|
+
<text x="287.03249999999997" y="574.7" text-anchor="middle" dy="0.35em" font-size="13" font-weight="500" fill="var(--_text)">检查 enabled</text>
|
|
112
|
+
<text x="239.37" y="713.45" text-anchor="middle" dy="0.35em" font-size="13" font-weight="500" fill="var(--_text)">跳过该技能</text>
|
|
113
|
+
<text x="334.695" y="713.45" text-anchor="middle" dy="0.35em" font-size="13" font-weight="500" fill="var(--_text)">添加到结果集</text>
|
|
114
|
+
<text x="268.03749999999997" y="834.325" text-anchor="middle" dy="0.35em" font-size="13" font-weight="500" fill="var(--_text)">还有技能?</text>
|
|
115
|
+
<text x="268.03749999999997" y="955.2" text-anchor="middle" dy="0.35em" font-size="13" font-weight="500" fill="var(--_text)">去重和排序</text>
|
|
116
|
+
<text x="268.03749999999997" y="1031.2" text-anchor="middle" dy="0.35em" font-size="13" font-weight="500" fill="var(--_text)">缓存结果</text>
|
|
117
|
+
<text x="268.03749999999997" y="1107.2" text-anchor="middle" dy="0.35em" font-size="13" font-weight="500" fill="var(--_text)">发出 loadComplete 事件</text>
|
|
118
|
+
<text x="268.03749999999997" y="1183.2" text-anchor="middle" dy="0.35em" font-size="13" font-weight="500" fill="var(--_text)">返回 SkillLoadOutcome</text>
|
|
119
|
+
<text x="104.03499999999995" y="1259.2" text-anchor="middle" dy="0.35em" font-size="13" font-weight="500" fill="var(--_text)">结束</text>
|
|
120
|
+
</svg>
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
## TUI 可读性重构计划(双栏聚焦 + 摘要优先)
|
|
2
|
+
|
|
3
|
+
### Summary
|
|
4
|
+
当前 TUI 的主要问题是“信息层级不清 + 单列堆叠导致阅读路径断裂”。
|
|
5
|
+
我建议将现有时间线改为“双栏聚焦”并采用“摘要优先”策略,保持 Codex 常见交互节奏:右侧主对话连续、左侧工具与系统状态结构化、底部输入始终可用、确认操作始终显眼。
|
|
6
|
+
|
|
7
|
+
### 现状分析(基于代码)
|
|
8
|
+
1. 渲染链路是单列线性堆叠:`/Users/bytedance/codes/ai/hataraku/src/render/index.tsx` + `/Users/bytedance/codes/ai/hataraku/src/render/components/Timeline.tsx`。
|
|
9
|
+
2. 聊天消息默认全量展开,工具和确认事件是卡片/行混排,长会话时“关键状态”容易被冲掉:`/Users/bytedance/codes/ai/hataraku/src/render/components/ChatBubble.tsx`、`/Users/bytedance/codes/ai/hataraku/src/render/components/ToolCard.tsx`。
|
|
10
|
+
3. 输入/浏览模式用 `Esc` 切换,交互状态隐藏在状态栏文本里,认知成本高:`/Users/bytedance/codes/ai/hataraku/src/render/components/StatusBar.tsx`。
|
|
11
|
+
4. 事件模型缺少“展示摘要/严重级别/耗时/最新状态聚合”字段,UI 只能直接渲染原始事件:`/Users/bytedance/codes/ai/hataraku/src/render/state/events.ts`。
|
|
12
|
+
|
|
13
|
+
### 产品决策(已锁定)
|
|
14
|
+
1. 布局:双栏聚焦。
|
|
15
|
+
2. 信息策略:摘要优先,详情按需展开。
|
|
16
|
+
3. 保持当前 Slash 命令集合兼容(`/help /clear /model /session /init`)。
|
|
17
|
+
|
|
18
|
+
### 目标交互规格(Decision Complete)
|
|
19
|
+
1. 主布局改为三段式:顶部状态条 + 中部双栏主体 + 底部输入条。
|
|
20
|
+
2. 中部左栏为 `Activity`(工具、确认、MCP、错误),右栏为 `Conversation`(用户/助手消息流)。
|
|
21
|
+
3. 焦点模式从 `input|timeline` 改为 `composer|activity|conversation`,默认 `composer`。
|
|
22
|
+
4. 键位统一:`Esc` 在 `composer` 与 `activity` 间切换,`Tab` 在 `activity` 与 `conversation` 间切换,`Enter/e` 展开当前项,`i` 回到输入。
|
|
23
|
+
5. 摘要规则:
|
|
24
|
+
- 工具事件默认单行摘要(工具名、状态、预览、耗时)。
|
|
25
|
+
- 确认事件默认高亮且置顶 pin(直到 resolved)。
|
|
26
|
+
- MCP/info 事件合并去噪(同 server 的重复 info 合并为最新)。
|
|
27
|
+
- 错误事件默认展开首行,stack 按需展开。
|
|
28
|
+
6. 对话规则:
|
|
29
|
+
- 用户消息始终全显。
|
|
30
|
+
- 助手消息流式显示,历史消息按块折叠(超过阈值显示“... 展开”)。
|
|
31
|
+
- “Thinking...”从独立行改为顶部/输入区状态标记,减少视觉跳动。
|
|
32
|
+
7. 输入区规则:
|
|
33
|
+
- 始终可见。
|
|
34
|
+
- 若有 pending confirm,输入区上方显示确认 banner,并抢占主提示(`y/n/Esc`)。
|
|
35
|
+
8. 宽度适配:`<100` 列自动退化为单栏分页(先 conversation,按键切换 activity)。
|
|
36
|
+
|
|
37
|
+
### 需要修改的接口/类型(Public APIs / Interfaces)
|
|
38
|
+
1. `UiMode`(`/Users/bytedance/codes/ai/hataraku/src/render/state/events.ts`)调整为 `composer | activity | conversation`。
|
|
39
|
+
2. `UiEvent` 扩展字段:`summary?: string`、`severity?: "info"|"warn"|"error"`、`startedAt?`、`endedAt?`、`pinned?`。
|
|
40
|
+
3. `addToolEvent/completeToolEvent` 增加耗时支持(通过 startedAt/endedAt 计算)。
|
|
41
|
+
4. `StatusBar` props 调整为包含焦点 pane、pending confirm 数、最近工具状态。
|
|
42
|
+
5. `Timeline` 拆分为 `ActivityPane` 和 `ConversationPane`(组件接口独立,避免互相耦合)。
|
|
43
|
+
|
|
44
|
+
### 实施步骤(文件级)
|
|
45
|
+
1. 在 `/Users/bytedance/codes/ai/hataraku/src/render/state/events.ts` 扩展事件模型与派生选择器(最新错误、pending confirm、active tools)。
|
|
46
|
+
2. 在 `/Users/bytedance/codes/ai/hataraku/src/render/index.tsx` 重构主布局和键盘状态机(焦点切换、窄屏降级、banner 插槽)。
|
|
47
|
+
3. 新增 `/Users/bytedance/codes/ai/hataraku/src/render/components/ActivityPane.tsx`,承接 Tool/Confirm/MCP/Error 的摘要列表与详情展开。
|
|
48
|
+
4. 新增 `/Users/bytedance/codes/ai/hataraku/src/render/components/ConversationPane.tsx`,承接 chat 流、历史折叠和流式标记。
|
|
49
|
+
5. 调整 `/Users/bytedance/codes/ai/hataraku/src/render/components/StatusBar.tsx` 为“状态摘要条”而非长提示文本。
|
|
50
|
+
6. 调整 `/Users/bytedance/codes/ai/hataraku/src/render/components/ToolCard.tsx`、`/Users/bytedance/codes/ai/hataraku/src/render/components/ConfirmCard.tsx` 为“摘要行 + 展开详情”双态组件。
|
|
51
|
+
7. 在 `/Users/bytedance/codes/ai/hataraku/src/render/theme.ts` 增加语义色 token(focus/pending/error-muted/surface),统一对比度。
|
|
52
|
+
8. 在 `/Users/bytedance/codes/ai/hataraku/src/render/commands/index.ts` 更新 `/help` 文案,匹配新键位。
|
|
53
|
+
|
|
54
|
+
### 测试与验收
|
|
55
|
+
1. 类型检查:`bunx tsc -p tsconfig.json --noEmit` 必须通过。
|
|
56
|
+
2. 回归脚本:`bun run test-e2e.ts` 必须通过。
|
|
57
|
+
3. 手工场景 A:连续 20+ 条对话,确认右栏对话可连续阅读,左栏不淹没。
|
|
58
|
+
4. 手工场景 B:连续 tool use + confirm,确认 pending banner 始终可见且可快速响应。
|
|
59
|
+
5. 手工场景 C:MCP 重连与错误混合事件,确认错误不会被 info 刷屏覆盖。
|
|
60
|
+
6. 手工场景 D:80 列终端下退化布局可用,键位一致。
|
|
61
|
+
7. 验收标准:用户在 5 秒内能识别“现在在做什么、是否需要确认、最近一次工具结果是什么”。
|
|
62
|
+
|
|
63
|
+
### Assumptions & Defaults
|
|
64
|
+
1. 不引入新 UI 依赖,继续使用 Ink + Jotai。
|
|
65
|
+
2. 不改 Agent 事件源语义,只在渲染层补充展示元数据。
|
|
66
|
+
3. 第一版不做鼠标交互,只优化键盘流。
|
|
67
|
+
4. 历史折叠阈值默认 12 行,可后续配置化。
|
package/package.json
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@maidang1/hataraku",
|
|
3
|
+
"version": "0.0.3",
|
|
4
|
+
"module": "src/index.ts",
|
|
5
|
+
"bin": {
|
|
6
|
+
"hataraku": "./src/index.ts"
|
|
7
|
+
},
|
|
8
|
+
"type": "module",
|
|
9
|
+
"private": false,
|
|
10
|
+
"scripts": {
|
|
11
|
+
"start": "bun run src/index.ts"
|
|
12
|
+
},
|
|
13
|
+
"devDependencies": {
|
|
14
|
+
"@types/bun": "latest",
|
|
15
|
+
"@types/react": "^19.2.10",
|
|
16
|
+
"@types/react-dom": "^19.2.3"
|
|
17
|
+
},
|
|
18
|
+
"peerDependencies": {
|
|
19
|
+
"typescript": "^5"
|
|
20
|
+
},
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"@anthropic-ai/sdk": "^0.72.1",
|
|
23
|
+
"@modelcontextprotocol/sdk": "^1.17.5",
|
|
24
|
+
"@types/js-yaml": "^4.0.9",
|
|
25
|
+
"cac": "^6.7.14",
|
|
26
|
+
"ink": "^6.6.0",
|
|
27
|
+
"ink-text-input": "^6.0.0",
|
|
28
|
+
"jotai": "^2.17.0",
|
|
29
|
+
"js-yaml": "^4.1.1",
|
|
30
|
+
"react": "^19.2.4",
|
|
31
|
+
"zod": "^3.25.0",
|
|
32
|
+
"zustand": "^5.0.11"
|
|
33
|
+
}
|
|
34
|
+
}
|