foliko 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/.claude/settings.local.json +30 -0
  2. package/22.txt +10 -0
  3. package/README.md +218 -0
  4. package/SPEC.md +452 -0
  5. package/cli/bin/foliko.js +12 -0
  6. package/cli/src/commands/chat.js +75 -0
  7. package/cli/src/index.js +64 -0
  8. package/cli/src/ui/chat-ui.js +272 -0
  9. package/cli/src/utils/ansi.js +40 -0
  10. package/cli/src/utils/markdown.js +296 -0
  11. package/docs/quick-reference.md +131 -0
  12. package/docs/user-manual.md +1205 -0
  13. package/examples/basic.js +110 -0
  14. package/examples/bootstrap.js +93 -0
  15. package/examples/mcp-example.js +53 -0
  16. package/examples/skill-example.js +49 -0
  17. package/examples/workflow.js +158 -0
  18. package/package.json +36 -0
  19. package/plugins/ai-plugin.js +89 -0
  20. package/plugins/audit-plugin.js +187 -0
  21. package/plugins/default-plugins.js +412 -0
  22. package/plugins/file-system-plugin.js +344 -0
  23. package/plugins/install-plugin.js +93 -0
  24. package/plugins/python-executor-plugin.js +331 -0
  25. package/plugins/rules-plugin.js +292 -0
  26. package/plugins/scheduler-plugin.js +426 -0
  27. package/plugins/session-plugin.js +343 -0
  28. package/plugins/shell-executor-plugin.js +196 -0
  29. package/plugins/storage-plugin.js +237 -0
  30. package/plugins/subagent-plugin.js +395 -0
  31. package/plugins/think-plugin.js +329 -0
  32. package/plugins/tools-plugin.js +114 -0
  33. package/skills/mcp-usage/SKILL.md +198 -0
  34. package/skills/vb-agent-dev/AGENTS.md +162 -0
  35. package/skills/vb-agent-dev/SKILL.md +370 -0
  36. package/src/capabilities/index.js +11 -0
  37. package/src/capabilities/skill-manager.js +319 -0
  38. package/src/capabilities/workflow-engine.js +401 -0
  39. package/src/core/agent-chat.js +311 -0
  40. package/src/core/agent.js +573 -0
  41. package/src/core/framework.js +255 -0
  42. package/src/core/index.js +19 -0
  43. package/src/core/plugin-base.js +205 -0
  44. package/src/core/plugin-manager.js +392 -0
  45. package/src/core/provider.js +108 -0
  46. package/src/core/tool-registry.js +134 -0
  47. package/src/core/tool-router.js +216 -0
  48. package/src/executors/executor-base.js +58 -0
  49. package/src/executors/mcp-executor.js +728 -0
  50. package/src/index.js +37 -0
  51. package/src/utils/event-emitter.js +97 -0
  52. package/test-chat.js +129 -0
  53. package/test-mcp.js +79 -0
  54. package/test-reload.js +61 -0
@@ -0,0 +1,30 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(grep -r \"dotenv\" \"D:/Code/vb-agent/\" --include=\"*.json\" 2>/dev/null | head -20)",
5
+ "Bash(cd \"D:/Code/vb-agent\" && pnpm add dotenv)",
6
+ "Bash(cd \"D:/Code/vb-agent\" && node -e \"const ai = require\\('ai'\\); console.log\\(Object.keys\\(ai\\).filter\\(k => k.toLowerCase\\(\\).includes\\('reason'\\) || k.toLowerCase\\(\\).includes\\('split'\\) || k.toLowerCase\\(\\).includes\\('think'\\)\\)\\)\")",
7
+ "Bash(cd \"D:/Code/vb-agent\" && node -e \"const ai = require\\('ai'\\); console.log\\(typeof ai.extractReasoningMiddleware, ai.extractReasoningMiddleware.toString\\(\\).substring\\(0, 500\\)\\)\")",
8
+ "Bash(cd \"D:/Code/vb-agent\" && node -e \"\nconst ai = require\\('ai'\\);\nconsole.log\\('=== extractReasoningMiddleware ==='\\);\nconsole.log\\(ai.extractReasoningMiddleware.toString\\(\\)\\);\nconsole.log\\('\\\\n=== isReasoningUIPart ==='\\);\nconsole.log\\(typeof ai.isReasoningUIPart\\);\n\")",
9
+ "Bash(cd \"D:/Code/vb-agent\" && node -e \"const ai = require\\('ai'\\); console.log\\(Object.keys\\(ai\\).filter\\(k => k.toLowerCase\\(\\).includes\\('split'\\)\\)\\)\")",
10
+ "Bash(cd \"D:/Code/vb-agent\" && pnpm add ink react)",
11
+ "Bash(cd \"D:/Code/vb-agent\" && node cli/bin/foliko.js --help)",
12
+ "Bash(cd \"D:/Code/vb-agent\" && timeout 2 node cli/bin/foliko.js chat 2>&1 || true)",
13
+ "Bash(cd \"D:/Code/vb-agent\" && node -e \"const mt = require\\('marked-terminal'\\); console.log\\(typeof mt, Object.keys\\(mt\\)\\)\")",
14
+ "Bash(cd \"D:/Code/vb-agent\" && timeout 3 node cli/bin/foliko.js chat 2>&1 || true)",
15
+ "Bash(echo \"你好\" | node cli/bin/foliko.js chat 2>&1 | head -50)",
16
+ "Bash(printf '思考一下1+1等于几\\\\n' | node cli/bin/foliko.js chat 2>&1 | head -100)",
17
+ "Bash(printf '1+1等于几\\\\n' | node cli/bin/foliko.js chat 2>&1)",
18
+ "Bash(node -e \"\nconst { renderLine } = require\\('./cli/src/utils/markdown'\\)\nconsole.log\\(renderLine\\('🎉 这是一个 emoji'\\)\\)\nconsole.log\\(renderLine\\('**粗体** 和 🎉'\\)\\)\n\")",
19
+ "Bash(node -e \"\nconst { render } = require\\('./cli/src/utils/markdown'\\)\nconst text = '🎉 今天是个好日子\\\\n## 标题\\\\n- 列表项1\\\\n- 列表项2'\nconsole.log\\(render\\(text\\)\\)\n\")",
20
+ "Bash(node -e \"\nconst { renderLine } = require\\('./cli/src/utils/markdown'\\)\n\n// 模拟emoji被截断的情况\nconst emoji = '🎉'\nconsole.log\\('完整的 emoji:', renderLine\\(emoji\\)\\)\n\n// 模拟截断 - emoji的UTF-8字节是 \\\\xF0\\\\x9F\\\\x8E\\\\x89\nconst partial = '\\\\xF0\\\\x9F' // 不完整的emoji\nconsole.log\\('截断的 emoji:', renderLine\\(partial\\)\\)\n\")",
21
+ "Bash(node -e \"\nconst isIncompleteUTF8 = \\(str\\) => {\n if \\(!str || str.length === 0\\) return false\n const lastChar = str.charCodeAt\\(str.length - 1\\)\n if \\(lastChar >= 0x80 && lastChar < 0xC0\\) return true\n return false\n}\n\n// 测试各种emoji\nconst tests = ['🎉', '📁', '⚡', '🛠️', '🔑', '💾', '📝', '⏰', '🔌', '📋']\ntests.forEach\\(e => {\n console.log\\(e, '完整:', !isIncompleteUTF8\\(e\\)\\)\n}\\)\n\n// 测试被截断的emoji \\(只保留第一字节\\)\nconst broken = '🎉'.slice\\(0, 1\\)\nconsole.log\\('截断emoji:', broken, '检测:', isIncompleteUTF8\\(broken\\)\\)\n\")",
22
+ "Bash(node -e \"\nconst { renderLine } = require\\('./cli/src/utils/markdown'\\)\nconsole.log\\('测试:', renderLine\\('📁 文件操作:读取、创建'\\)\\)\n\")",
23
+ "Bash(node -e \"\nconst hasIncompleteSurrogate = \\(str\\) => {\n if \\(!str || str.length === 0\\) return false\n const lastChar = str.charCodeAt\\(str.length - 1\\)\n console.log\\('检查:', str, 'lastChar:', lastChar.toString\\(16\\), '范围:', \\(lastChar >= 0xD800 && lastChar <= 0xDBFF\\)\\)\n return lastChar >= 0xD800 && lastChar <= 0xDBFF\n}\n\nconst chunk1 = '\\\\xD83C'\nconsole.log\\('结果:', hasIncompleteSurrogate\\(chunk1\\)\\)\n\")",
24
+ "Bash(cd D:/Code/vb-agent && node test-stream-emoji.js 2>&1)",
25
+ "Read(//d/Date/20260321/app/**)",
26
+ "Bash(node -e \":*)",
27
+ "Bash(node -e \"\nconst { loadAgentConfig } = require\\('./plugins/default-plugins'\\);\nconst config = loadAgentConfig\\('D:/Date/20260321/app/.agent'\\);\nconsole.log\\('skillsDirs:', config.skillsDirs\\);\n\")"
28
+ ]
29
+ }
30
+ }
package/22.txt ADDED
@@ -0,0 +1,10 @@
1
+ {
2
+ "mcpServers": {
3
+ "fetch": {
4
+ "args": [
5
+ "mcp-server-fetch"
6
+ ],
7
+ "command": "uvx"
8
+ }
9
+ }
10
+ }
package/README.md ADDED
@@ -0,0 +1,218 @@
1
+ # JavaScript 测试代码示例
2
+
3
+ 这个项目展示了现代 JavaScript 测试的最佳实践,使用 Jest 作为测试框架。
4
+
5
+ ## 文件结构
6
+
7
+ - `test-example.js` - 完整的测试示例,包含多种测试类型
8
+ - `simple-test-example.js` - 简洁的测试示例,适合初学者
9
+ - `package.json` - 项目配置和 Jest 设置
10
+
11
+ ## 包含的测试类型
12
+
13
+ ### 1. 单元测试
14
+ - 函数测试
15
+ - 类方法测试
16
+ - 边界情况测试
17
+ - 异常测试
18
+
19
+ ### 2. 异步测试
20
+ - Promise 测试
21
+ - async/await 测试
22
+ - 超时处理
23
+
24
+ ### 3. 集成测试
25
+ - 多个类的组合测试
26
+ - 完整流程测试
27
+
28
+ ### 4. Mock 和 Spy
29
+ - 模拟函数
30
+ - 模拟 API 调用
31
+ - 验证函数调用
32
+
33
+ ### 5. 参数化测试
34
+ - 使用 `test.each` 测试多组数据
35
+
36
+ ### 6. 快照测试
37
+ - 对象结构验证
38
+
39
+ ## 最佳实践展示
40
+
41
+ ### 1. AAA 模式 (Arrange-Act-Assert)
42
+ ```javascript
43
+ test('应该正确计算两个数的和', () => {
44
+ // Arrange: 准备测试数据
45
+ const a = 5;
46
+ const b = 3;
47
+ const expected = 8;
48
+
49
+ // Act: 执行被测试的方法
50
+ const result = calculator.add(a, b);
51
+
52
+ // Assert: 验证结果
53
+ expect(result).toBe(expected);
54
+ });
55
+ ```
56
+
57
+ ### 2. 描述性测试名称
58
+ - 使用 "should" 描述预期行为
59
+ - 包含测试条件
60
+ - 清晰表达测试目的
61
+
62
+ ### 3. 测试隔离
63
+ - 每个测试独立运行
64
+ - 使用 `beforeEach` 重置状态
65
+ - 避免测试间的依赖
66
+
67
+ ### 4. 恰当的断言
68
+ - 使用合适的匹配器
69
+ - 验证异常
70
+ - 检查异步结果
71
+
72
+ ### 5. 测试覆盖率
73
+ - 行覆盖率
74
+ - 分支覆盖率
75
+ - 函数覆盖率
76
+ - 语句覆盖率
77
+
78
+ ## 安装和运行
79
+
80
+ ### 1. 安装依赖
81
+ ```bash
82
+ npm install
83
+ ```
84
+
85
+ ### 2. 运行测试
86
+ ```bash
87
+ # 运行所有测试
88
+ npm test
89
+
90
+ # 监视模式(文件变化时自动运行)
91
+ npm run test:watch
92
+
93
+ # 生成覆盖率报告
94
+ npm run test:coverage
95
+
96
+ # 详细输出
97
+ npm run test:verbose
98
+
99
+ # 更新快照
100
+ npm run test:update
101
+ ```
102
+
103
+ ### 3. 查看覆盖率报告
104
+ 运行 `npm run test:coverage` 后,打开 `coverage/index.html` 查看详细的覆盖率报告。
105
+
106
+ ## Jest 配置说明
107
+
108
+ 在 `package.json` 中的 Jest 配置:
109
+
110
+ ```json
111
+ {
112
+ "jest": {
113
+ "testEnvironment": "node", // 测试环境
114
+ "verbose": true, // 详细输出
115
+ "collectCoverage": true, // 收集覆盖率
116
+ "coverageDirectory": "coverage", // 覆盖率输出目录
117
+ "coverageReporters": ["text", "lcov", "html"], // 报告格式
118
+ "coverageThreshold": { // 覆盖率阈值
119
+ "global": {
120
+ "branches": 80,
121
+ "functions": 80,
122
+ "lines": 80,
123
+ "statements": 80
124
+ }
125
+ },
126
+ "testMatch": [ // 测试文件匹配模式
127
+ "**/__tests__/**/*.js",
128
+ "**/?(*.)+(spec|test).js"
129
+ ],
130
+ "testTimeout": 10000, // 测试超时时间
131
+ "clearMocks": true, // 自动清理 mock
132
+ "resetMocks": true, // 重置 mock
133
+ "restoreMocks": true // 恢复原始实现
134
+ }
135
+ }
136
+ ```
137
+
138
+ ## 测试技巧
139
+
140
+ ### 1. 测试异步代码
141
+ ```javascript
142
+ // 使用 async/await
143
+ test('应该异步返回数据', async () => {
144
+ const result = await fetchData();
145
+ expect(result).toEqual({ data: '测试数据' });
146
+ });
147
+
148
+ // 测试异步异常
149
+ test('应该抛出异步错误', async () => {
150
+ await expect(asyncFunction()).rejects.toThrow('错误信息');
151
+ });
152
+ ```
153
+
154
+ ### 2. Mock 函数
155
+ ```javascript
156
+ // 创建 mock 函数
157
+ const mockFn = jest.fn();
158
+
159
+ // 设置返回值
160
+ mockFn.mockReturnValue('返回值');
161
+
162
+ // 验证调用
163
+ expect(mockFn).toHaveBeenCalledTimes(1);
164
+ expect(mockFn).toHaveBeenCalledWith('参数');
165
+ ```
166
+
167
+ ### 3. 参数化测试
168
+ ```javascript
169
+ test.each([
170
+ [1, 1, 2],
171
+ [1, 2, 3],
172
+ [2, 1, 3],
173
+ ])('add(%i, %i) should equal %i', (a, b, expected) => {
174
+ expect(a + b).toBe(expected);
175
+ });
176
+ ```
177
+
178
+ ### 4. 快照测试
179
+ ```javascript
180
+ test('对象应该匹配快照', () => {
181
+ const obj = {
182
+ id: 1,
183
+ name: '测试',
184
+ date: new Date('2024-01-01')
185
+ };
186
+
187
+ expect(obj).toMatchSnapshot({
188
+ date: expect.any(Date) // 忽略具体日期值
189
+ });
190
+ });
191
+ ```
192
+
193
+ ## 常见问题
194
+
195
+ ### 1. 测试运行太慢
196
+ - 减少不必要的异步等待
197
+ - 使用 `jest.useFakeTimers()` 模拟时间
198
+ - 避免在测试中执行真实 API 调用
199
+
200
+ ### 2. 测试不稳定(Flaky Tests)
201
+ - 确保测试独立
202
+ - 避免依赖外部状态
203
+ - 使用固定的测试数据
204
+
205
+ ### 3. 覆盖率不足
206
+ - 添加边界情况测试
207
+ - 测试错误处理路径
208
+ - 验证所有分支条件
209
+
210
+ ## 扩展阅读
211
+
212
+ - [Jest 官方文档](https://jestjs.io/)
213
+ - [测试金字塔原则](https://martinfowler.com/bliki/TestPyramid.html)
214
+ - [AAA 测试模式](https://medium.com/@pjbgf/title-testing-code-ocd-and-the-aaa-pattern-df453975ab80)
215
+
216
+ ## 许可证
217
+
218
+ MIT