skimpyclaw 0.3.14 โ†’ 0.4.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 (222) hide show
  1. package/README.md +47 -37
  2. package/dist/__tests__/adapter-types.test.d.ts +4 -0
  3. package/dist/__tests__/adapter-types.test.js +63 -0
  4. package/dist/__tests__/anthropic-adapter.test.d.ts +4 -0
  5. package/dist/__tests__/anthropic-adapter.test.js +264 -0
  6. package/dist/__tests__/api.test.js +0 -1
  7. package/dist/__tests__/cli.integration.test.js +2 -4
  8. package/dist/__tests__/cli.test.js +0 -1
  9. package/dist/__tests__/code-agents-notifications.test.js +137 -0
  10. package/dist/__tests__/code-agents-parser.test.js +19 -1
  11. package/dist/__tests__/code-agents-preflight.test.js +3 -28
  12. package/dist/__tests__/code-agents-utils.test.js +34 -9
  13. package/dist/__tests__/code-agents-worktrees.test.js +116 -0
  14. package/dist/__tests__/codex-adapter.test.js +184 -0
  15. package/dist/__tests__/codex-auth.test.js +66 -0
  16. package/dist/__tests__/codex-provider-gating.test.js +35 -0
  17. package/dist/__tests__/codex-unified-loop.test.js +111 -0
  18. package/dist/__tests__/config-security.test.js +127 -0
  19. package/dist/__tests__/config.test.js +23 -0
  20. package/dist/__tests__/context-manager.test.js +243 -164
  21. package/dist/__tests__/cron-run.test.js +250 -0
  22. package/dist/__tests__/cron.test.js +12 -38
  23. package/dist/__tests__/digests.test.js +67 -0
  24. package/dist/__tests__/discord-attachments.test.js +211 -0
  25. package/dist/__tests__/discord-docs.test.d.ts +1 -0
  26. package/dist/__tests__/discord-docs.test.js +27 -0
  27. package/dist/__tests__/discord-thread-agents.test.d.ts +1 -0
  28. package/dist/__tests__/discord-thread-agents.test.js +115 -0
  29. package/dist/__tests__/discord-thread-context.test.d.ts +1 -0
  30. package/dist/__tests__/discord-thread-context.test.js +42 -0
  31. package/dist/__tests__/doctor.formatters.test.js +4 -4
  32. package/dist/__tests__/doctor.index.test.js +1 -1
  33. package/dist/__tests__/doctor.runner.test.js +3 -15
  34. package/dist/__tests__/env-sanitizer.test.d.ts +1 -0
  35. package/dist/__tests__/env-sanitizer.test.js +45 -0
  36. package/dist/__tests__/exec-approval.test.js +61 -0
  37. package/dist/__tests__/fetch-tool.test.d.ts +1 -0
  38. package/dist/__tests__/fetch-tool.test.js +85 -0
  39. package/dist/__tests__/gateway-status-auth.test.d.ts +1 -0
  40. package/dist/__tests__/gateway-status-auth.test.js +72 -0
  41. package/dist/__tests__/heartbeat.test.js +3 -3
  42. package/dist/__tests__/interactive-sessions.test.d.ts +1 -0
  43. package/dist/__tests__/interactive-sessions.test.js +96 -0
  44. package/dist/__tests__/langfuse.test.js +6 -18
  45. package/dist/__tests__/model-selection.test.js +3 -4
  46. package/dist/__tests__/providers-init.test.js +2 -8
  47. package/dist/__tests__/providers-routing.test.js +1 -1
  48. package/dist/__tests__/providers-utils.test.js +13 -3
  49. package/dist/__tests__/sessions.test.js +14 -10
  50. package/dist/__tests__/setup.test.js +12 -29
  51. package/dist/__tests__/skills.test.js +10 -7
  52. package/dist/__tests__/stream-formatter.test.d.ts +1 -0
  53. package/dist/__tests__/stream-formatter.test.js +114 -0
  54. package/dist/__tests__/token-efficiency.test.js +131 -15
  55. package/dist/__tests__/tool-loop.test.d.ts +4 -0
  56. package/dist/__tests__/tool-loop.test.js +505 -0
  57. package/dist/__tests__/tools.test.js +101 -276
  58. package/dist/__tests__/utils.test.d.ts +1 -0
  59. package/dist/__tests__/utils.test.js +14 -0
  60. package/dist/__tests__/voice.test.js +21 -0
  61. package/dist/agent.js +35 -4
  62. package/dist/api.js +113 -37
  63. package/dist/channels/discord/attachments.d.ts +50 -0
  64. package/dist/channels/discord/attachments.js +137 -0
  65. package/dist/channels/discord/delegation.d.ts +5 -0
  66. package/dist/channels/discord/delegation.js +136 -0
  67. package/dist/channels/discord/handlers.js +694 -7
  68. package/dist/channels/discord/index.d.ts +16 -1
  69. package/dist/channels/discord/index.js +64 -1
  70. package/dist/channels/discord/thread-agents.d.ts +54 -0
  71. package/dist/channels/discord/thread-agents.js +323 -0
  72. package/dist/channels/discord/threads.d.ts +58 -0
  73. package/dist/channels/discord/threads.js +192 -0
  74. package/dist/channels/discord/types.js +4 -2
  75. package/dist/channels/discord/utils.d.ts +16 -0
  76. package/dist/channels/discord/utils.js +86 -6
  77. package/dist/channels/telegram/index.d.ts +1 -1
  78. package/dist/channels/telegram/types.js +1 -1
  79. package/dist/channels/telegram/utils.js +9 -3
  80. package/dist/channels.d.ts +1 -1
  81. package/dist/cli.js +20 -400
  82. package/dist/code-agents/executor.d.ts +1 -1
  83. package/dist/code-agents/executor.js +101 -45
  84. package/dist/code-agents/index.d.ts +2 -7
  85. package/dist/code-agents/index.js +111 -80
  86. package/dist/code-agents/interactive-resume.d.ts +6 -0
  87. package/dist/code-agents/interactive-resume.js +98 -0
  88. package/dist/code-agents/interactive-sessions.d.ts +20 -0
  89. package/dist/code-agents/interactive-sessions.js +132 -0
  90. package/dist/code-agents/parser.js +5 -1
  91. package/dist/code-agents/registry.d.ts +7 -1
  92. package/dist/code-agents/registry.js +11 -23
  93. package/dist/code-agents/stream-formatter.d.ts +8 -0
  94. package/dist/code-agents/stream-formatter.js +92 -0
  95. package/dist/code-agents/types.d.ts +16 -24
  96. package/dist/code-agents/utils.d.ts +35 -11
  97. package/dist/code-agents/utils.js +349 -95
  98. package/dist/code-agents/worktrees.d.ts +37 -0
  99. package/dist/code-agents/worktrees.js +116 -0
  100. package/dist/config.d.ts +2 -4
  101. package/dist/config.js +123 -23
  102. package/dist/cron.d.ts +1 -6
  103. package/dist/cron.js +175 -82
  104. package/dist/dashboard/assets/index-B345aOO-.js +65 -0
  105. package/dist/dashboard/assets/index-ZWK4dalJ.css +1 -0
  106. package/dist/dashboard/index.html +2 -2
  107. package/dist/digests.d.ts +1 -0
  108. package/dist/digests.js +132 -42
  109. package/dist/doctor/checks.d.ts +0 -3
  110. package/dist/doctor/checks.js +1 -108
  111. package/dist/doctor/runner.js +1 -4
  112. package/dist/env-sanitizer.d.ts +2 -0
  113. package/dist/env-sanitizer.js +61 -0
  114. package/dist/exec-approval.d.ts +11 -1
  115. package/dist/exec-approval.js +17 -4
  116. package/dist/gateway.d.ts +3 -1
  117. package/dist/gateway.js +17 -7
  118. package/dist/heartbeat.js +1 -6
  119. package/dist/langfuse.js +3 -29
  120. package/dist/model-selection.js +3 -1
  121. package/dist/providers/adapter.d.ts +118 -0
  122. package/dist/providers/adapter.js +6 -0
  123. package/dist/providers/adapters/anthropic-adapter.d.ts +22 -0
  124. package/dist/providers/adapters/anthropic-adapter.js +204 -0
  125. package/dist/providers/adapters/codex-adapter.d.ts +26 -0
  126. package/dist/providers/adapters/codex-adapter.js +203 -0
  127. package/dist/providers/anthropic.d.ts +1 -0
  128. package/dist/providers/anthropic.js +10 -272
  129. package/dist/providers/codex.d.ts +21 -0
  130. package/dist/providers/codex.js +149 -330
  131. package/dist/providers/content.d.ts +1 -1
  132. package/dist/providers/content.js +2 -2
  133. package/dist/providers/context-manager.d.ts +18 -6
  134. package/dist/providers/context-manager.js +199 -223
  135. package/dist/providers/index.d.ts +9 -1
  136. package/dist/providers/index.js +73 -64
  137. package/dist/providers/loop-utils.d.ts +20 -0
  138. package/dist/providers/loop-utils.js +30 -0
  139. package/dist/providers/tool-loop.d.ts +12 -0
  140. package/dist/providers/tool-loop.js +251 -0
  141. package/dist/providers/utils.d.ts +19 -3
  142. package/dist/providers/utils.js +100 -29
  143. package/dist/secure-store.d.ts +8 -0
  144. package/dist/secure-store.js +80 -0
  145. package/dist/service.js +3 -28
  146. package/dist/sessions.d.ts +3 -0
  147. package/dist/sessions.js +147 -18
  148. package/dist/setup-templates.js +13 -25
  149. package/dist/setup.d.ts +10 -6
  150. package/dist/setup.js +84 -292
  151. package/dist/skills.js +3 -11
  152. package/dist/tools/agent-delegation.d.ts +19 -0
  153. package/dist/tools/agent-delegation.js +49 -0
  154. package/dist/tools/bash-tool.js +89 -34
  155. package/dist/tools/definitions.d.ts +199 -302
  156. package/dist/tools/definitions.js +70 -123
  157. package/dist/tools/execute-context.d.ts +13 -4
  158. package/dist/tools/fetch-tool.js +109 -13
  159. package/dist/tools/file-tools.js +7 -1
  160. package/dist/tools.d.ts +7 -7
  161. package/dist/tools.js +133 -151
  162. package/dist/types.d.ts +37 -30
  163. package/dist/utils.js +4 -6
  164. package/dist/voice.d.ts +1 -1
  165. package/dist/voice.js +17 -4
  166. package/package.json +33 -23
  167. package/templates/TOOLS.md +0 -27
  168. package/dist/__tests__/audit.test.js +0 -122
  169. package/dist/__tests__/code-agents-orchestrator.test.js +0 -216
  170. package/dist/__tests__/code-agents-sandbox.test.js +0 -163
  171. package/dist/__tests__/orchestrator.test.js +0 -425
  172. package/dist/__tests__/sandbox-bridge.test.js +0 -116
  173. package/dist/__tests__/sandbox-manager.test.js +0 -144
  174. package/dist/__tests__/sandbox-mount-security.test.js +0 -139
  175. package/dist/__tests__/sandbox-runtime.test.js +0 -176
  176. package/dist/__tests__/subagent.test.js +0 -240
  177. package/dist/__tests__/telegram.test.js +0 -42
  178. package/dist/code-agents/orchestrator.d.ts +0 -29
  179. package/dist/code-agents/orchestrator.js +0 -694
  180. package/dist/code-agents/worktree.d.ts +0 -40
  181. package/dist/code-agents/worktree.js +0 -215
  182. package/dist/dashboard/assets/index-BoTHPby4.js +0 -65
  183. package/dist/dashboard/assets/index-D4mufvBg.css +0 -1
  184. package/dist/dashboard.d.ts +0 -8
  185. package/dist/dashboard.js +0 -4071
  186. package/dist/discord.d.ts +0 -8
  187. package/dist/discord.js +0 -792
  188. package/dist/mcp-context-a8c.d.ts +0 -13
  189. package/dist/mcp-context-a8c.js +0 -34
  190. package/dist/orchestrator.d.ts +0 -15
  191. package/dist/orchestrator.js +0 -676
  192. package/dist/providers/openai.d.ts +0 -10
  193. package/dist/providers/openai.js +0 -355
  194. package/dist/sandbox/bridge.d.ts +0 -5
  195. package/dist/sandbox/bridge.js +0 -63
  196. package/dist/sandbox/index.d.ts +0 -5
  197. package/dist/sandbox/index.js +0 -4
  198. package/dist/sandbox/manager.d.ts +0 -7
  199. package/dist/sandbox/manager.js +0 -100
  200. package/dist/sandbox/mount-security.d.ts +0 -12
  201. package/dist/sandbox/mount-security.js +0 -122
  202. package/dist/sandbox/runtime.d.ts +0 -39
  203. package/dist/sandbox/runtime.js +0 -192
  204. package/dist/sandbox-utils.d.ts +0 -6
  205. package/dist/sandbox-utils.js +0 -36
  206. package/dist/subagent.d.ts +0 -19
  207. package/dist/subagent.js +0 -407
  208. package/dist/telegram.d.ts +0 -2
  209. package/dist/telegram.js +0 -11
  210. package/dist/tools/browser-tool.d.ts +0 -3
  211. package/dist/tools/browser-tool.js +0 -266
  212. package/sandbox/Dockerfile +0 -40
  213. /package/dist/__tests__/{audit.test.d.ts โ†’ code-agents-notifications.test.d.ts} +0 -0
  214. /package/dist/__tests__/{code-agents-orchestrator.test.d.ts โ†’ code-agents-worktrees.test.d.ts} +0 -0
  215. /package/dist/__tests__/{code-agents-sandbox.test.d.ts โ†’ codex-adapter.test.d.ts} +0 -0
  216. /package/dist/__tests__/{orchestrator.test.d.ts โ†’ codex-auth.test.d.ts} +0 -0
  217. /package/dist/__tests__/{sandbox-bridge.test.d.ts โ†’ codex-provider-gating.test.d.ts} +0 -0
  218. /package/dist/__tests__/{sandbox-manager.test.d.ts โ†’ codex-unified-loop.test.d.ts} +0 -0
  219. /package/dist/__tests__/{sandbox-mount-security.test.d.ts โ†’ config-security.test.d.ts} +0 -0
  220. /package/dist/__tests__/{sandbox-runtime.test.d.ts โ†’ cron-run.test.d.ts} +0 -0
  221. /package/dist/__tests__/{subagent.test.d.ts โ†’ digests.test.d.ts} +0 -0
  222. /package/dist/__tests__/{telegram.test.d.ts โ†’ discord-attachments.test.d.ts} +0 -0
@@ -1,240 +0,0 @@
1
- import { describe, it, expect, beforeEach, vi } from 'vitest';
2
- import { existsSync, mkdirSync, writeFileSync } from 'fs';
3
- import { join } from 'path';
4
- import { homedir } from 'os';
5
- import { initSubagentSystem, dispatchSubagent, cancelTask, getActiveTasks, getRecentTasks, getTask, getPresetDescriptions, resetForTesting, ensureAgentSetup, } from '../subagent.js';
6
- // Mock runAgentTurn
7
- vi.mock('../agent.js', () => ({
8
- runAgentTurn: vi.fn().mockResolvedValue('mock agent response'),
9
- }));
10
- // Mock getCurrentModel
11
- vi.mock('../gateway.js', () => ({
12
- getCurrentModel: vi.fn().mockReturnValue('anthropic/claude-sonnet-4-5'),
13
- }));
14
- // Mock fs operations for ensureAgentSetup tests
15
- vi.mock('fs', async () => {
16
- const actual = await vi.importActual('fs');
17
- return {
18
- ...actual,
19
- existsSync: vi.fn(actual.existsSync),
20
- mkdirSync: vi.fn(),
21
- writeFileSync: vi.fn(),
22
- };
23
- });
24
- function createMockConfig() {
25
- return {
26
- gateway: { port: 18790, mode: 'local' },
27
- agents: {
28
- default: 'main',
29
- list: {
30
- main: {
31
- identity: { name: 'Test', emoji: '๐Ÿฆž' },
32
- model: 'anthropic/claude-sonnet-4-5',
33
- },
34
- },
35
- },
36
- models: {
37
- providers: {},
38
- aliases: {
39
- 'claude-think': 'anthropic/claude-sonnet-4-5',
40
- 'claude-opus': 'anthropic/claude-opus-4-6',
41
- },
42
- },
43
- channels: {
44
- telegram: {
45
- enabled: false,
46
- token: '',
47
- allowFrom: [],
48
- },
49
- },
50
- cron: { jobs: [] },
51
- heartbeat: {
52
- intervalMs: 300000,
53
- prompt: 'test',
54
- },
55
- };
56
- }
57
- describe('subagent', () => {
58
- let deliveredMessages;
59
- let mockConfig;
60
- beforeEach(() => {
61
- resetForTesting();
62
- mockConfig = createMockConfig();
63
- deliveredMessages = [];
64
- initSubagentSystem(async (chatId, message) => {
65
- deliveredMessages.push({ chatId, message });
66
- });
67
- });
68
- describe('initSubagentSystem', () => {
69
- it('initializes without error', () => {
70
- expect(() => initSubagentSystem(async () => { })).not.toThrow();
71
- });
72
- });
73
- describe('getPresetDescriptions', () => {
74
- it('returns descriptions for all agent types', () => {
75
- const desc = getPresetDescriptions();
76
- expect(desc).toContain('coding');
77
- expect(desc).toContain('research');
78
- });
79
- });
80
- describe('dispatchSubagent', () => {
81
- it('creates a task with correct fields', () => {
82
- const task = dispatchSubagent('coding', 'list TODOs', 123, mockConfig);
83
- expect(task.id).toBe('t1');
84
- expect(task.type).toBe('coding');
85
- expect(task.prompt).toBe('list TODOs');
86
- expect(task.chatId).toBe(123);
87
- expect(task.model).toBe('anthropic/claude-opus-4-6');
88
- expect(task.createdAt).toBeInstanceOf(Date);
89
- });
90
- it('increments task IDs', () => {
91
- const t1 = dispatchSubagent('coding', 'task 1', 123, mockConfig);
92
- const t2 = dispatchSubagent('research', 'task 2', 123, mockConfig);
93
- expect(t1.id).toBe('t1');
94
- expect(t2.id).toBe('t2');
95
- });
96
- it('uses model override when provided', () => {
97
- const task = dispatchSubagent('coding', 'test', 123, mockConfig, 'anthropic/claude-opus-4');
98
- expect(task.model).toBe('anthropic/claude-opus-4-6');
99
- });
100
- it('resolves model override aliases to canonical model ids', () => {
101
- const task = dispatchSubagent('coding', 'test', 123, mockConfig, 'claude-think');
102
- expect(task.model).toBe('anthropic/claude-sonnet-4-5');
103
- });
104
- it('rejects when max concurrent reached', () => {
105
- // Set max concurrent to 3 to test the limit
106
- const configWithLimit = { ...mockConfig, subagents: { maxConcurrent: 3 } };
107
- dispatchSubagent('coding', 'task 1', 123, configWithLimit);
108
- dispatchSubagent('coding', 'task 2', 123, configWithLimit);
109
- dispatchSubagent('coding', 'task 3', 123, configWithLimit);
110
- expect(() => dispatchSubagent('coding', 'task 4', 123, configWithLimit)).toThrow('Max concurrent');
111
- });
112
- it('delivers result on completion', async () => {
113
- dispatchSubagent('coding', 'test prompt', 456, mockConfig);
114
- // Wait for async execution
115
- await new Promise(r => setTimeout(r, 100));
116
- expect(deliveredMessages.length).toBe(1);
117
- expect(deliveredMessages[0].chatId).toBe(456);
118
- expect(deliveredMessages[0].message).toContain('mock agent response');
119
- expect(deliveredMessages[0].message).toContain('completed');
120
- });
121
- });
122
- describe('cancelTask', () => {
123
- it('cancels a running task', async () => {
124
- const task = dispatchSubagent('coding', 'test', 123, mockConfig);
125
- const result = cancelTask(task.id);
126
- expect(result?.status).toBe('cancelled');
127
- });
128
- it('returns null for unknown task', () => {
129
- expect(cancelTask('t999')).toBeNull();
130
- });
131
- it('returns task unchanged if already completed', async () => {
132
- const task = dispatchSubagent('coding', 'test', 123, mockConfig);
133
- await new Promise(r => setTimeout(r, 100));
134
- const result = cancelTask(task.id);
135
- expect(result?.status).toBe('completed');
136
- });
137
- });
138
- describe('getActiveTasks', () => {
139
- it('returns empty when no tasks', () => {
140
- expect(getActiveTasks()).toHaveLength(0);
141
- });
142
- it('returns pending/running tasks', () => {
143
- dispatchSubagent('coding', 'test', 123, mockConfig);
144
- // Task starts as pending/running immediately
145
- const active = getActiveTasks();
146
- expect(active.length).toBeGreaterThanOrEqual(0); // may already be running
147
- });
148
- });
149
- describe('getRecentTasks', () => {
150
- it('returns tasks sorted newest first', async () => {
151
- dispatchSubagent('coding', 'first', 123, mockConfig);
152
- // Small delay to ensure different timestamps
153
- await new Promise(r => setTimeout(r, 5));
154
- dispatchSubagent('research', 'second', 123, mockConfig);
155
- const recent = getRecentTasks(10);
156
- expect(recent).toHaveLength(2);
157
- expect(recent[0].prompt).toBe('second');
158
- expect(recent[1].prompt).toBe('first');
159
- });
160
- it('limits results', () => {
161
- dispatchSubagent('coding', 'a', 123, mockConfig);
162
- dispatchSubagent('coding', 'b', 123, mockConfig);
163
- dispatchSubagent('coding', 'c', 123, mockConfig);
164
- const recent = getRecentTasks(2);
165
- expect(recent).toHaveLength(2);
166
- });
167
- });
168
- describe('getTask', () => {
169
- it('returns task by id', () => {
170
- const task = dispatchSubagent('coding', 'test', 123, mockConfig);
171
- expect(getTask(task.id)).toBe(task);
172
- });
173
- it('returns null for unknown id', () => {
174
- expect(getTask('t999')).toBeNull();
175
- });
176
- });
177
- describe('ensureAgentSetup', () => {
178
- const mockedExistsSync = vi.mocked(existsSync);
179
- const mockedMkdirSync = vi.mocked(mkdirSync);
180
- const mockedWriteFileSync = vi.mocked(writeFileSync);
181
- beforeEach(() => {
182
- mockedExistsSync.mockReset();
183
- mockedMkdirSync.mockReset();
184
- mockedWriteFileSync.mockReset();
185
- });
186
- it('creates agent dir and templates when dir does not exist', () => {
187
- mockedExistsSync.mockReturnValue(false);
188
- const config = createMockConfig();
189
- ensureAgentSetup('coding', config);
190
- const expectedDir = join(homedir(), '.skimpyclaw', 'agents', 'coding');
191
- expect(mockedMkdirSync).toHaveBeenCalledWith(expectedDir, { recursive: true });
192
- expect(mockedWriteFileSync).toHaveBeenCalledTimes(2);
193
- // Check IDENTITY.md was written
194
- const identityCall = mockedWriteFileSync.mock.calls.find((c) => String(c[0]).endsWith('IDENTITY.md'));
195
- expect(identityCall).toBeTruthy();
196
- expect(identityCall[1]).toContain('Coding Agent');
197
- // Check TOOLS.md was written
198
- const toolsCall = mockedWriteFileSync.mock.calls.find((c) => String(c[0]).endsWith('TOOLS.md'));
199
- expect(toolsCall).toBeTruthy();
200
- expect(toolsCall[1]).toContain('Act, Don\'t Narrate');
201
- });
202
- it('does not create dir when it already exists', () => {
203
- mockedExistsSync.mockReturnValue(true);
204
- const config = createMockConfig();
205
- ensureAgentSetup('coding', config);
206
- expect(mockedMkdirSync).not.toHaveBeenCalled();
207
- expect(mockedWriteFileSync).not.toHaveBeenCalled();
208
- });
209
- it('registers agent in config.agents.list in-memory', () => {
210
- mockedExistsSync.mockReturnValue(true);
211
- const config = createMockConfig();
212
- expect(config.agents.list['coding']).toBeUndefined();
213
- ensureAgentSetup('coding', config);
214
- expect(config.agents.list['coding']).toBeDefined();
215
- expect(config.agents.list['coding'].identity.name).toBe('Coding Agent');
216
- expect(config.agents.list['coding'].identity.emoji).toBe('๐Ÿ”ง');
217
- expect(config.agents.list['coding'].thinking).toBe('medium');
218
- });
219
- it('does not overwrite existing agent registration', () => {
220
- mockedExistsSync.mockReturnValue(true);
221
- const config = createMockConfig();
222
- config.agents.list['research'] = {
223
- identity: { name: 'Custom Research', emoji: '๐Ÿงช' },
224
- model: 'custom-model',
225
- };
226
- ensureAgentSetup('research', config);
227
- // Should keep the existing registration
228
- expect(config.agents.list['research'].identity.name).toBe('Custom Research');
229
- expect(config.agents.list['research'].identity.emoji).toBe('๐Ÿงช');
230
- });
231
- it('creates correct templates for research type', () => {
232
- mockedExistsSync.mockReturnValue(false);
233
- const config = createMockConfig();
234
- ensureAgentSetup('research', config);
235
- const identityCall = mockedWriteFileSync.mock.calls.find((c) => String(c[0]).endsWith('IDENTITY.md'));
236
- expect(identityCall[1]).toContain('Research Agent');
237
- expect(identityCall[1]).toContain('research subagent dispatched');
238
- });
239
- });
240
- });
@@ -1,42 +0,0 @@
1
- import { describe, it, expect, beforeEach, afterEach } from 'vitest';
2
- import { mkdirSync, writeFileSync, rmSync } from 'fs';
3
- import { join } from 'path';
4
- import { tmpdir } from 'os';
5
- import { getRecentMemoryFiles } from '../telegram.js';
6
- const TEST_ROOT = join(tmpdir(), `skimpyclaw-telegram-test-${Date.now()}`);
7
- function seedMemory(agentId, name, content) {
8
- const dir = join(TEST_ROOT, 'agents', agentId, 'memory');
9
- mkdirSync(dir, { recursive: true });
10
- writeFileSync(join(dir, name), content, 'utf-8');
11
- }
12
- describe('getRecentMemoryFiles', () => {
13
- beforeEach(() => {
14
- mkdirSync(TEST_ROOT, { recursive: true });
15
- });
16
- afterEach(() => {
17
- rmSync(TEST_ROOT, { recursive: true, force: true });
18
- });
19
- it('returns files sorted newest first', () => {
20
- seedMemory('main', '2026-02-05.md', 'older');
21
- seedMemory('main', '2026-02-07.md', 'newer');
22
- seedMemory('main', '2026-02-06.md', 'middle');
23
- const files = getRecentMemoryFiles('main', 10, TEST_ROOT);
24
- expect(files.map(f => f.name)).toEqual([
25
- '2026-02-07.md',
26
- '2026-02-06.md',
27
- '2026-02-05.md',
28
- ]);
29
- });
30
- it('limits to requested count', () => {
31
- seedMemory('main', '2026-02-01.md', '1');
32
- seedMemory('main', '2026-02-02.md', '2');
33
- seedMemory('main', '2026-02-03.md', '3');
34
- const files = getRecentMemoryFiles('main', 2, TEST_ROOT);
35
- expect(files).toHaveLength(2);
36
- expect(files.map(f => f.name)).toEqual(['2026-02-03.md', '2026-02-02.md']);
37
- });
38
- it('returns empty for unknown agent memory dir', () => {
39
- const files = getRecentMemoryFiles('does-not-exist', 5, TEST_ROOT);
40
- expect(files).toEqual([]);
41
- });
42
- });
@@ -1,29 +0,0 @@
1
- import type { Config } from '../types.js';
2
- import type { ExecuteToolContext } from '../tools/execute-context.js';
3
- import type { DecomposedSubtask, ChildResult } from './types.js';
4
- /**
5
- * Compute execution waves from dependency info.
6
- * Returns an array of waves, where each wave is an array of subtask indices that can run in parallel.
7
- * Throws if there's a cycle in the dependency graph.
8
- */
9
- export declare function computeWaves(subtasks: DecomposedSubtask[]): number[][];
10
- /**
11
- * Gather lightweight codebase context to improve task decomposition.
12
- * Returns a short summary of the project structure (file tree, package.json scripts).
13
- * Capped at ~2000 chars to keep the decomposition prompt small.
14
- */
15
- export declare function gatherCodebaseContext(workdir: string): string;
16
- /**
17
- * Use a quick model call to decompose a complex task into N subtasks with optional dependency info.
18
- * Falls back to numbered subtask splitting on parse error.
19
- * Falls back to all-independent if dependency info is missing or invalid.
20
- */
21
- export declare function decomposeTask(task: string, teamSize: number, config: Config, workdir?: string): Promise<DecomposedSubtask[]>;
22
- /**
23
- * Use a quick model call to synthesize results from multiple subtask completions.
24
- */
25
- export declare function synthesizeResults(originalTask: string, results: ChildResult[], config: Config, workdir?: string): Promise<string>;
26
- /**
27
- * Team orchestrator โ€” decomposes task, spawns parallel agents, monitors, synthesizes.
28
- */
29
- export declare function runTeamOrchestrator(parentId: string, task: string, teamSize: number, workdir: string, validate: boolean, agent: string, model: string | undefined, startedAt: Date, context?: ExecuteToolContext): Promise<void>;