winter-super-cli 2026.6.24 → 2026.6.27

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 (123) hide show
  1. package/CHANGELOG.md +28 -5
  2. package/README.md +85 -0
  3. package/package.json +5 -1
  4. package/resources/local/gsap-skills/.claude-plugin/marketplace.json +20 -0
  5. package/resources/local/gsap-skills/.claude-plugin/plugin.json +6 -0
  6. package/resources/local/gsap-skills/.cursor-plugin/marketplace.json +13 -0
  7. package/resources/local/gsap-skills/.cursor-plugin/plugin.json +22 -0
  8. package/resources/local/gsap-skills/.github/copilot-instructions.md +17 -0
  9. package/resources/local/gsap-skills/.github/instructions/react.instructions.md +15 -0
  10. package/resources/local/gsap-skills/.github/instructions/scrolltrigger.instructions.md +18 -0
  11. package/resources/local/gsap-skills/AGENTS.md +27 -0
  12. package/resources/local/gsap-skills/CLAUDE.md +1 -0
  13. package/resources/local/gsap-skills/GEMINI.md +1 -0
  14. package/resources/local/gsap-skills/LICENSE +21 -0
  15. package/resources/local/gsap-skills/README.md +163 -0
  16. package/resources/local/gsap-skills/assets/gsap-green.svg +7 -0
  17. package/resources/local/gsap-skills/assets/gsap-icon-inverted.svg +15 -0
  18. package/resources/local/gsap-skills/assets/gsap-icon-square.svg +1 -0
  19. package/resources/local/gsap-skills/assets/gsap-white.svg +7 -0
  20. package/resources/local/gsap-skills/examples/README.md +29 -0
  21. package/resources/local/gsap-skills/examples/nuxt/app/app.vue +3 -0
  22. package/resources/local/gsap-skills/examples/nuxt/app/composables/useGSAP.ts +91 -0
  23. package/resources/local/gsap-skills/examples/nuxt/app/pages/index.vue +55 -0
  24. package/resources/local/gsap-skills/examples/nuxt/nuxt.config.ts +4 -0
  25. package/resources/local/gsap-skills/examples/nuxt/package.json +18 -0
  26. package/resources/local/gsap-skills/examples/react/App.jsx +46 -0
  27. package/resources/local/gsap-skills/examples/react/index.html +12 -0
  28. package/resources/local/gsap-skills/examples/react/main.jsx +9 -0
  29. package/resources/local/gsap-skills/examples/react/package.json +21 -0
  30. package/resources/local/gsap-skills/examples/react/vite.config.js +7 -0
  31. package/resources/local/gsap-skills/examples/vanilla/index.html +33 -0
  32. package/resources/local/gsap-skills/examples/vanilla/main.js +36 -0
  33. package/resources/local/gsap-skills/examples/vue/app.vue +47 -0
  34. package/resources/local/gsap-skills/examples/vue/index.html +15 -0
  35. package/resources/local/gsap-skills/examples/vue/main.js +9 -0
  36. package/resources/local/gsap-skills/examples/vue/package.json +19 -0
  37. package/resources/local/gsap-skills/examples/vue/vite.config.js +7 -0
  38. package/resources/local/gsap-skills/skills/gsap-core/SKILL.md +254 -0
  39. package/resources/local/gsap-skills/skills/gsap-frameworks/SKILL.md +266 -0
  40. package/resources/local/gsap-skills/skills/gsap-performance/SKILL.md +79 -0
  41. package/resources/local/gsap-skills/skills/gsap-plugins/SKILL.md +433 -0
  42. package/resources/local/gsap-skills/skills/gsap-react/SKILL.md +136 -0
  43. package/resources/local/gsap-skills/skills/gsap-scrolltrigger/SKILL.md +296 -0
  44. package/resources/local/gsap-skills/skills/gsap-timeline/SKILL.md +107 -0
  45. package/resources/local/gsap-skills/skills/gsap-utils/SKILL.md +284 -0
  46. package/resources/local/gsap-skills/skills/llms.txt +39 -0
  47. package/resources/local/hermes-agent-core/AGENTS.md +1132 -0
  48. package/resources/local/hermes-agent-core/LICENSE +21 -0
  49. package/resources/local/hermes-agent-core/README.md +215 -0
  50. package/resources/local/hermes-agent-core/docs/2026-05-07-s6-overlay-dynamic-subagent-gateways.md +434 -0
  51. package/resources/local/hermes-agent-core/hermes-already-has-routines.md +160 -0
  52. package/resources/local/hermes-agent-core/skills/autonomous-ai-agents/DESCRIPTION.md +3 -0
  53. package/resources/local/hermes-agent-core/skills/autonomous-ai-agents/claude-code/SKILL.md +745 -0
  54. package/resources/local/hermes-agent-core/skills/autonomous-ai-agents/codex/SKILL.md +130 -0
  55. package/resources/local/hermes-agent-core/skills/autonomous-ai-agents/hermes-agent/SKILL.md +1021 -0
  56. package/resources/local/hermes-agent-core/skills/autonomous-ai-agents/kanban-codex-lane/SKILL.md +277 -0
  57. package/resources/local/hermes-agent-core/skills/autonomous-ai-agents/kanban-codex-lane/templates/pmb-codex-lane-prompt.md +57 -0
  58. package/resources/local/hermes-agent-core/skills/autonomous-ai-agents/opencode/SKILL.md +219 -0
  59. package/resources/local/hermes-agent-core/skills/github/DESCRIPTION.md +3 -0
  60. package/resources/local/hermes-agent-core/skills/github/codebase-inspection/SKILL.md +116 -0
  61. package/resources/local/hermes-agent-core/skills/github/github-auth/SKILL.md +247 -0
  62. package/resources/local/hermes-agent-core/skills/github/github-auth/scripts/gh-env.sh +66 -0
  63. package/resources/local/hermes-agent-core/skills/github/github-code-review/SKILL.md +481 -0
  64. package/resources/local/hermes-agent-core/skills/github/github-code-review/references/review-output-template.md +74 -0
  65. package/resources/local/hermes-agent-core/skills/github/github-issues/SKILL.md +370 -0
  66. package/resources/local/hermes-agent-core/skills/github/github-issues/templates/bug-report.md +35 -0
  67. package/resources/local/hermes-agent-core/skills/github/github-issues/templates/feature-request.md +31 -0
  68. package/resources/local/hermes-agent-core/skills/github/github-pr-workflow/SKILL.md +367 -0
  69. package/resources/local/hermes-agent-core/skills/github/github-pr-workflow/references/ci-troubleshooting.md +183 -0
  70. package/resources/local/hermes-agent-core/skills/github/github-pr-workflow/references/conventional-commits.md +71 -0
  71. package/resources/local/hermes-agent-core/skills/github/github-pr-workflow/templates/pr-body-bugfix.md +35 -0
  72. package/resources/local/hermes-agent-core/skills/github/github-pr-workflow/templates/pr-body-feature.md +33 -0
  73. package/resources/local/hermes-agent-core/skills/github/github-repo-management/SKILL.md +516 -0
  74. package/resources/local/hermes-agent-core/skills/github/github-repo-management/references/github-api-cheatsheet.md +161 -0
  75. package/resources/local/hermes-agent-core/skills/mcp/DESCRIPTION.md +3 -0
  76. package/resources/local/hermes-agent-core/skills/mcp/native-mcp/SKILL.md +357 -0
  77. package/resources/local/hermes-agent-core/skills/software-development/debugging-hermes-tui-commands/SKILL.md +152 -0
  78. package/resources/local/hermes-agent-core/skills/software-development/hermes-agent-skill-authoring/SKILL.md +165 -0
  79. package/resources/local/hermes-agent-core/skills/software-development/hermes-s6-container-supervision/SKILL.md +176 -0
  80. package/resources/local/hermes-agent-core/skills/software-development/node-inspect-debugger/SKILL.md +319 -0
  81. package/resources/local/hermes-agent-core/skills/software-development/plan/SKILL.md +58 -0
  82. package/resources/local/hermes-agent-core/skills/software-development/python-debugpy/SKILL.md +375 -0
  83. package/resources/local/hermes-agent-core/skills/software-development/requesting-code-review/SKILL.md +280 -0
  84. package/resources/local/hermes-agent-core/skills/software-development/spike/SKILL.md +197 -0
  85. package/resources/local/hermes-agent-core/skills/software-development/subagent-driven-development/SKILL.md +352 -0
  86. package/resources/local/hermes-agent-core/skills/software-development/subagent-driven-development/references/context-budget-discipline.md +53 -0
  87. package/resources/local/hermes-agent-core/skills/software-development/subagent-driven-development/references/gates-taxonomy.md +93 -0
  88. package/resources/local/hermes-agent-core/skills/software-development/systematic-debugging/SKILL.md +367 -0
  89. package/resources/local/hermes-agent-core/skills/software-development/test-driven-development/SKILL.md +343 -0
  90. package/resources/local/hermes-agent-core/skills/software-development/writing-plans/SKILL.md +297 -0
  91. package/resources/local/manifest.json +12 -0
  92. package/rule.md +2 -0
  93. package/scripts/audit-pack.js +5 -0
  94. package/scripts/smoke-browser.js +53 -0
  95. package/scripts/smoke-package.js +38 -4
  96. package/skill.md +36 -4
  97. package/skills/gsap.md +26 -0
  98. package/skills/hermes-agent.md +17 -0
  99. package/src/agent/agent-definitions.js +4 -4
  100. package/src/agent/runtime.js +179 -5
  101. package/src/agent/subagent-child.js +44 -0
  102. package/src/ai/capability-scorecard.js +193 -14
  103. package/src/ai/hermes-core.js +77 -0
  104. package/src/ai/model-capabilities.js +42 -2
  105. package/src/ai/prompts/system-prompt.js +18 -2
  106. package/src/ai/small-model-amplifier.js +35 -7
  107. package/src/ai/workflow-selector.js +22 -1
  108. package/src/cli/commands.js +46 -2
  109. package/src/cli/config.js +45 -6
  110. package/src/cli/context-loader.js +253 -9
  111. package/src/cli/conversation-format.js +5 -0
  112. package/src/cli/input-controller.js +79 -10
  113. package/src/cli/prompt-builder.js +47 -8
  114. package/src/cli/repl-commands.js +115 -0
  115. package/src/cli/repl.js +343 -85
  116. package/src/cli/slash-commands.js +4 -2
  117. package/src/cli/tui.js +133 -37
  118. package/src/mcp/client.js +54 -11
  119. package/src/mcp/presets.js +114 -0
  120. package/src/tools/agent.js +316 -25
  121. package/src/tools/executor.js +412 -12
  122. package/src/tools/permission.js +20 -17
  123. package/winter.d.ts +112 -10
@@ -1,56 +1,347 @@
1
- /**
2
- * AGENT TOOL
3
- * Full subagent orchestration tool
4
- */
5
-
1
+ import { AgentDefinitionRegistry } from '../agent/agent-definitions.js';
2
+ import { fork } from 'child_process';
3
+ import { mkdtemp, rm } from 'fs/promises';
4
+ import { tmpdir } from 'os';
6
5
  import path from 'path';
6
+ import { fileURLToPath } from 'url';
7
+
8
+ const DEFAULT_TIMEOUT_MS = 120000;
9
+ const SUBAGENT_CHILD_PATH = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..', 'agent', 'subagent-child.js');
10
+ const WORKSPACE_EXCLUDE_NAMES = new Set([
11
+ '.git',
12
+ '.winter',
13
+ '.codegraph',
14
+ '.claude',
15
+ 'node_modules',
16
+ 'dist',
17
+ 'coverage',
18
+ ]);
19
+ const WORKSPACE_EXCLUDE_PATTERNS = [
20
+ /\.tgz$/i,
21
+ /\.zip$/i,
22
+ /\.rar$/i,
23
+ /\.log$/i,
24
+ ];
25
+
26
+ function clampSteps(value) {
27
+ return Math.min(Math.max(1, parseInt(value, 10) || 10), 25);
28
+ }
29
+
30
+ async function withTimeout(promise, ms, agentId) {
31
+ let timer;
32
+ const timeout = new Promise((_, reject) => {
33
+ timer = setTimeout(() => reject(new Error(`Subagent ${agentId} timed out after ${ms}ms`)), ms);
34
+ });
35
+ try {
36
+ return await Promise.race([promise, timeout]);
37
+ } finally {
38
+ clearTimeout(timer);
39
+ }
40
+ }
7
41
 
8
42
  export class AgentTool {
9
43
  constructor(repl) {
10
44
  this.repl = repl;
11
45
  this.running = new Map();
46
+ this.completed = new Map();
47
+ this.forkProcess = repl?.subagentFork || fork;
12
48
  }
13
49
 
14
50
  async run(task, options = {}) {
15
51
  if (!task || typeof task !== 'string' || task.trim() === '') {
16
52
  return { success: false, error: 'task description is required' };
17
53
  }
54
+ const wantsProcessIsolation = this.shouldUseProcessIsolation(options);
55
+ if ((!wantsProcessIsolation && !this.repl?.runConversation) || !this.repl?.tools || !this.repl?.ai) {
56
+ return {
57
+ success: false,
58
+ error: 'Agent execution requires a live REPL runtime.',
59
+ recovery: 'Run Agent from inside Winter REPL so the subagent can call the model and tools.',
60
+ };
61
+ }
18
62
 
19
63
  const agentId = options.id || `agent-${Date.now()}-${String(Math.random()).slice(2, 6)}`;
20
- const maxSteps = Math.min(Math.max(1, parseInt(options.maxSteps, 10) || 10), 25);
21
- const provider = options.provider || this.repl?.ai?.getActiveProvider?.() || 'ollama';
22
- const cwd = options.cwd || process.cwd();
64
+ const timeoutMs = Math.max(1, parseInt(options.timeoutMs ?? options.timeout_ms, 10) || DEFAULT_TIMEOUT_MS);
65
+ const maxSteps = clampSteps(options.maxSteps ?? options.max_steps);
66
+ const role = String(options.role || options.agent || 'general');
67
+ const startedAt = new Date().toISOString();
68
+ const cwd = options.cwd || this.repl.projectPath || process.cwd();
69
+ const previousProvider = this.repl.ai.getActiveProvider?.();
23
70
 
24
- return {
25
- success: true,
26
- agentId,
27
- status: 'running',
71
+ const state = {
72
+ id: agentId,
28
73
  task: task.trim(),
29
- workflow: [
30
- { phase: 'understand', description: 'Analyze the task and gather initial context' },
31
- { phase: 'inspect', description: 'Read relevant files to understand the codebase' },
32
- { phase: 'decompose', description: 'Break task into subtasks for sequential execution' },
33
- { phase: 'implement', description: 'Execute each subtask implementation' },
34
- { phase: 'verify', description: 'Verify changes and fix any issues' },
35
- { phase: 'report', description: 'Provide final summary of what was done' },
36
- ],
74
+ role,
75
+ status: 'running',
76
+ startedAt,
37
77
  maxSteps,
38
- provider,
39
78
  cwd,
40
- note: 'Agent execution is coordinated by the AI model via tool calls. Use the SWE agent for automated multi-step execution.',
41
79
  };
80
+ this.running.set(agentId, state);
81
+
82
+ try {
83
+ const runOptions = { ...options, agentId, maxSteps, role, cwd, timeoutMs };
84
+ const result = wantsProcessIsolation
85
+ ? await this.executeSubagentInChildProcess(task.trim(), runOptions)
86
+ : await withTimeout(this.executeSubagent(task.trim(), runOptions), timeoutMs, agentId);
87
+ const completed = {
88
+ ...state,
89
+ ...result,
90
+ status: result.success === false ? 'failed' : 'completed',
91
+ completedAt: new Date().toISOString(),
92
+ };
93
+ this.running.delete(agentId);
94
+ this.completed.set(agentId, completed);
95
+ return completed;
96
+ } catch (error) {
97
+ const failed = {
98
+ ...state,
99
+ success: false,
100
+ status: 'failed',
101
+ error: error.message,
102
+ completedAt: new Date().toISOString(),
103
+ };
104
+ this.running.delete(agentId);
105
+ this.completed.set(agentId, failed);
106
+ return failed;
107
+ } finally {
108
+ if (previousProvider && this.repl.ai.setProvider) {
109
+ this.repl.ai.setProvider(previousProvider);
110
+ }
111
+ }
112
+ }
113
+
114
+ shouldUseProcessIsolation(options = {}) {
115
+ if (options.processIsolation === false || options.process_isolation === false) return false;
116
+ if (options.processIsolation === true || options.process_isolation === true) return true;
117
+ if (process.env.NODE_ENV === 'test') return false;
118
+ return this.repl?.constructor?.name === 'WinterREPL';
119
+ }
120
+
121
+ executeSubagentInChildProcess(task, options) {
122
+ return new Promise((resolve, reject) => {
123
+ let workspaceReady = Promise.resolve({ workspacePath: options.cwd, cleanup: async () => {}, isolated: false });
124
+ const child = this.forkProcess(SUBAGENT_CHILD_PATH, [], {
125
+ stdio: ['ignore', 'pipe', 'pipe', 'ipc'],
126
+ env: { ...process.env, WINTER_SUBAGENT_CHILD: '1' },
127
+ });
128
+ const logs = [];
129
+ let settled = false;
130
+ const finish = (fn, value) => {
131
+ if (settled) return;
132
+ settled = true;
133
+ clearTimeout(timer);
134
+ child.kill();
135
+ void workspaceReady
136
+ .then(workspace => workspace.cleanup().catch(() => {}))
137
+ .finally(() => fn(value));
138
+ };
139
+ const timer = setTimeout(() => {
140
+ finish(reject, new Error(`Subagent ${options.agentId} timed out after ${options.timeoutMs}ms`));
141
+ }, options.timeoutMs);
142
+
143
+ child.stdout?.on('data', chunk => logs.push(String(chunk)));
144
+ child.stderr?.on('data', chunk => logs.push(String(chunk)));
145
+ child.on('message', message => {
146
+ if (message?.type === 'result') {
147
+ finish(resolve, {
148
+ ...message.result,
149
+ processIsolated: true,
150
+ workspaceIsolated: message.result?.workspaceIsolated === true || message.result?.workspaceIsolation === true,
151
+ childPid: child.pid,
152
+ childLogs: logs.join('').slice(-4000),
153
+ });
154
+ } else if (message?.type === 'error') {
155
+ finish(reject, new Error(message.error || 'Subagent child failed'));
156
+ }
157
+ });
158
+ child.on('error', error => finish(reject, error));
159
+ child.on('exit', code => {
160
+ if (!settled && code !== 0) {
161
+ finish(reject, new Error(`Subagent child exited with code ${code}: ${logs.join('').slice(-2000)}`));
162
+ }
163
+ });
164
+ workspaceReady = this.prepareSubagentWorkspace(options);
165
+ workspaceReady
166
+ .then(workspace => {
167
+ child.send({
168
+ type: 'run',
169
+ task,
170
+ options: {
171
+ ...options,
172
+ processIsolation: false,
173
+ workspaceIsolation: workspace.isolated,
174
+ parentProjectPath: this.repl.projectPath,
175
+ projectPath: workspace.workspacePath,
176
+ cwd: workspace.workspacePath,
177
+ sessionId: this.repl.sessionId,
178
+ version: this.repl.version,
179
+ },
180
+ });
181
+ })
182
+ .catch(error => finish(reject, error));
183
+ });
184
+ }
185
+
186
+ async prepareSubagentWorkspace(options = {}) {
187
+ if (options.workspaceIsolation === false || options.workspace_isolation === false) {
188
+ return {
189
+ workspacePath: options.cwd || this.repl.projectPath || process.cwd(),
190
+ isolated: false,
191
+ cleanup: async () => {},
192
+ };
193
+ }
194
+
195
+ const source = path.resolve(options.cwd || this.repl.projectPath || process.cwd());
196
+ const workspacePath = await mkdtemp(path.join(tmpdir(), `winter-subagent-${options.agentId || 'agent'}-`));
197
+ await this.copyWorkspaceForSubagent(source, workspacePath);
198
+ return {
199
+ workspacePath,
200
+ isolated: true,
201
+ cleanup: async () => {
202
+ if (options.keepWorkspace === true || options.keep_workspace === true) return;
203
+ await rm(workspacePath, { recursive: true, force: true });
204
+ },
205
+ };
206
+ }
207
+
208
+ async copyWorkspaceForSubagent(source, destination) {
209
+ const fs = await import('fs/promises');
210
+ await fs.cp(source, destination, {
211
+ recursive: true,
212
+ force: false,
213
+ errorOnExist: false,
214
+ filter: (src) => {
215
+ const name = path.basename(src);
216
+ if (WORKSPACE_EXCLUDE_NAMES.has(name)) return false;
217
+ if (WORKSPACE_EXCLUDE_PATTERNS.some(pattern => pattern.test(name))) return false;
218
+ return true;
219
+ },
220
+ });
221
+ }
222
+
223
+ async executeSubagent(task, options) {
224
+ const definition = await this.getAgentDefinition(options.role);
225
+ const requestedTools = Array.isArray(options.tools) ? options.tools.map(String) : null;
226
+ const agentDefinition = requestedTools?.length
227
+ ? { ...definition, tools: definition.tools.filter(tool => requestedTools.includes(tool)) }
228
+ : definition;
229
+ const agentTools = this.repl.getAgentToolsForDefinition
230
+ ? this.repl.getAgentToolsForDefinition(agentDefinition)
231
+ : this.repl.tools.getToolDefinitions().filter(tool => agentDefinition.tools.includes(tool.name));
232
+
233
+ if (agentTools.length === 0) {
234
+ return {
235
+ success: false,
236
+ error: `No tools are allowed for agent role "${agentDefinition.id}".`,
237
+ };
238
+ }
239
+
240
+ if (options.provider && this.repl.ai.setProvider) {
241
+ const switched = this.repl.ai.setProvider(options.provider);
242
+ if (!switched) {
243
+ return {
244
+ success: false,
245
+ error: `Provider is not available for subagent: ${options.provider}`,
246
+ };
247
+ }
248
+ }
249
+
250
+ const context = await this.repl.getProjectContext?.(task);
251
+ const systemPrompt = this.repl.getAgentDefinitionSystemPrompt
252
+ ? this.repl.getAgentDefinitionSystemPrompt(agentDefinition, context || '')
253
+ : this.buildFallbackSystemPrompt(agentDefinition, context || '');
254
+ const messages = [
255
+ { role: 'system', content: systemPrompt },
256
+ {
257
+ role: 'user',
258
+ content: [
259
+ `Subagent task: ${task}`,
260
+ options.context ? `Parent context:\n${options.context}` : '',
261
+ `Constraints: maxSteps=${options.maxSteps}; cwd=${options.cwd}`,
262
+ 'Run independently. Use only your allowed tools. Return summary, changed files, verification, and blockers.',
263
+ ].filter(Boolean).join('\n\n'),
264
+ },
265
+ ];
266
+
267
+ const runtimeResult = await this.repl.runConversation(messages, `Subagent [${agentDefinition.id}]`, agentTools);
268
+ return {
269
+ success: true,
270
+ agentId: options.agentId,
271
+ role: agentDefinition.id,
272
+ provider: this.repl.ai.getActiveProvider?.() || options.provider || 'unknown',
273
+ allowedTools: agentTools.map(tool => tool.name),
274
+ finalContent: runtimeResult.finalContent || '',
275
+ summary: this.summarize(runtimeResult.finalContent),
276
+ changedFiles: runtimeResult.changedFiles || [],
277
+ usedTools: runtimeResult.usedTools === true,
278
+ usedMutatingTools: runtimeResult.usedMutatingTools === true,
279
+ autoVerified: runtimeResult.autoVerified === true,
280
+ autoVerificationPassed: runtimeResult.autoVerificationPassed === true,
281
+ toolSummaries: runtimeResult.toolSummaries || [],
282
+ executedTools: runtimeResult.executedTools || [],
283
+ usage: runtimeResult.usage || {},
284
+ };
285
+ }
286
+
287
+ async runParallel(tasks = [], options = {}) {
288
+ const normalized = Array.isArray(tasks) ? tasks : [];
289
+ if (normalized.length === 0) {
290
+ return { success: false, error: 'tasks array is required' };
291
+ }
292
+ const limit = Math.min(Math.max(1, parseInt(options.concurrency, 10) || normalized.length), 6);
293
+ const results = [];
294
+ let index = 0;
295
+ const workers = Array.from({ length: Math.min(limit, normalized.length) }, async () => {
296
+ while (index < normalized.length) {
297
+ const current = normalized[index++];
298
+ const task = typeof current === 'string' ? current : current.goal || current.task;
299
+ results.push(await this.run(task, { ...options, ...(typeof current === 'object' ? current : {}) }));
300
+ }
301
+ });
302
+ await Promise.all(workers);
303
+ return {
304
+ success: results.every(result => result.success !== false),
305
+ status: 'completed',
306
+ count: results.length,
307
+ results,
308
+ summary: results.map(result => `${result.agentId}: ${result.status} - ${result.summary || result.error || ''}`).join('\n'),
309
+ };
310
+ }
311
+
312
+ async getAgentDefinition(role) {
313
+ if (this.repl?.agentRegistry?.get) return this.repl.agentRegistry.get(role);
314
+ const registry = new AgentDefinitionRegistry({ projectPath: this.repl?.projectPath || process.cwd() });
315
+ return registry.get(role);
316
+ }
317
+
318
+ buildFallbackSystemPrompt(agentDefinition, context) {
319
+ return [
320
+ `You are Winter subagent "${agentDefinition.id}".`,
321
+ agentDefinition.instructionsPrompt || '',
322
+ `Allowed tools: ${(agentDefinition.tools || []).join(', ')}`,
323
+ context ? `Project context:\n${context}` : '',
324
+ ].filter(Boolean).join('\n\n');
325
+ }
326
+
327
+ summarize(text = '') {
328
+ const value = String(text || '').trim().replace(/\s+/g, ' ');
329
+ return value.length > 500 ? `${value.slice(0, 497)}...` : value;
42
330
  }
43
331
 
44
332
  async list() {
333
+ const agents = [...this.running.values(), ...this.completed.values()];
45
334
  return {
46
335
  success: true,
47
- agents: [...this.running.values()].map(a => ({
336
+ agents: agents.map(a => ({
48
337
  id: a.id,
49
338
  task: a.task?.slice(0, 80) || '',
50
339
  status: a.status,
340
+ role: a.role,
51
341
  startedAt: a.startedAt,
342
+ completedAt: a.completedAt,
52
343
  })),
53
- count: this.running.size,
344
+ count: agents.length,
54
345
  };
55
346
  }
56
347
 
@@ -59,7 +350,7 @@ export class AgentTool {
59
350
  return { success: false, error: 'agent_id is required' };
60
351
  }
61
352
 
62
- const agent = this.running.get(agentId);
353
+ const agent = this.running.get(agentId) || this.completed.get(agentId);
63
354
  if (!agent) {
64
355
  return { success: false, error: `Agent not found: ${agentId}` };
65
356
  }