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.
- package/CHANGELOG.md +28 -5
- package/README.md +85 -0
- package/package.json +5 -1
- package/resources/local/gsap-skills/.claude-plugin/marketplace.json +20 -0
- package/resources/local/gsap-skills/.claude-plugin/plugin.json +6 -0
- package/resources/local/gsap-skills/.cursor-plugin/marketplace.json +13 -0
- package/resources/local/gsap-skills/.cursor-plugin/plugin.json +22 -0
- package/resources/local/gsap-skills/.github/copilot-instructions.md +17 -0
- package/resources/local/gsap-skills/.github/instructions/react.instructions.md +15 -0
- package/resources/local/gsap-skills/.github/instructions/scrolltrigger.instructions.md +18 -0
- package/resources/local/gsap-skills/AGENTS.md +27 -0
- package/resources/local/gsap-skills/CLAUDE.md +1 -0
- package/resources/local/gsap-skills/GEMINI.md +1 -0
- package/resources/local/gsap-skills/LICENSE +21 -0
- package/resources/local/gsap-skills/README.md +163 -0
- package/resources/local/gsap-skills/assets/gsap-green.svg +7 -0
- package/resources/local/gsap-skills/assets/gsap-icon-inverted.svg +15 -0
- package/resources/local/gsap-skills/assets/gsap-icon-square.svg +1 -0
- package/resources/local/gsap-skills/assets/gsap-white.svg +7 -0
- package/resources/local/gsap-skills/examples/README.md +29 -0
- package/resources/local/gsap-skills/examples/nuxt/app/app.vue +3 -0
- package/resources/local/gsap-skills/examples/nuxt/app/composables/useGSAP.ts +91 -0
- package/resources/local/gsap-skills/examples/nuxt/app/pages/index.vue +55 -0
- package/resources/local/gsap-skills/examples/nuxt/nuxt.config.ts +4 -0
- package/resources/local/gsap-skills/examples/nuxt/package.json +18 -0
- package/resources/local/gsap-skills/examples/react/App.jsx +46 -0
- package/resources/local/gsap-skills/examples/react/index.html +12 -0
- package/resources/local/gsap-skills/examples/react/main.jsx +9 -0
- package/resources/local/gsap-skills/examples/react/package.json +21 -0
- package/resources/local/gsap-skills/examples/react/vite.config.js +7 -0
- package/resources/local/gsap-skills/examples/vanilla/index.html +33 -0
- package/resources/local/gsap-skills/examples/vanilla/main.js +36 -0
- package/resources/local/gsap-skills/examples/vue/app.vue +47 -0
- package/resources/local/gsap-skills/examples/vue/index.html +15 -0
- package/resources/local/gsap-skills/examples/vue/main.js +9 -0
- package/resources/local/gsap-skills/examples/vue/package.json +19 -0
- package/resources/local/gsap-skills/examples/vue/vite.config.js +7 -0
- package/resources/local/gsap-skills/skills/gsap-core/SKILL.md +254 -0
- package/resources/local/gsap-skills/skills/gsap-frameworks/SKILL.md +266 -0
- package/resources/local/gsap-skills/skills/gsap-performance/SKILL.md +79 -0
- package/resources/local/gsap-skills/skills/gsap-plugins/SKILL.md +433 -0
- package/resources/local/gsap-skills/skills/gsap-react/SKILL.md +136 -0
- package/resources/local/gsap-skills/skills/gsap-scrolltrigger/SKILL.md +296 -0
- package/resources/local/gsap-skills/skills/gsap-timeline/SKILL.md +107 -0
- package/resources/local/gsap-skills/skills/gsap-utils/SKILL.md +284 -0
- package/resources/local/gsap-skills/skills/llms.txt +39 -0
- package/resources/local/hermes-agent-core/AGENTS.md +1132 -0
- package/resources/local/hermes-agent-core/LICENSE +21 -0
- package/resources/local/hermes-agent-core/README.md +215 -0
- package/resources/local/hermes-agent-core/docs/2026-05-07-s6-overlay-dynamic-subagent-gateways.md +434 -0
- package/resources/local/hermes-agent-core/hermes-already-has-routines.md +160 -0
- package/resources/local/hermes-agent-core/skills/autonomous-ai-agents/DESCRIPTION.md +3 -0
- package/resources/local/hermes-agent-core/skills/autonomous-ai-agents/claude-code/SKILL.md +745 -0
- package/resources/local/hermes-agent-core/skills/autonomous-ai-agents/codex/SKILL.md +130 -0
- package/resources/local/hermes-agent-core/skills/autonomous-ai-agents/hermes-agent/SKILL.md +1021 -0
- package/resources/local/hermes-agent-core/skills/autonomous-ai-agents/kanban-codex-lane/SKILL.md +277 -0
- package/resources/local/hermes-agent-core/skills/autonomous-ai-agents/kanban-codex-lane/templates/pmb-codex-lane-prompt.md +57 -0
- package/resources/local/hermes-agent-core/skills/autonomous-ai-agents/opencode/SKILL.md +219 -0
- package/resources/local/hermes-agent-core/skills/github/DESCRIPTION.md +3 -0
- package/resources/local/hermes-agent-core/skills/github/codebase-inspection/SKILL.md +116 -0
- package/resources/local/hermes-agent-core/skills/github/github-auth/SKILL.md +247 -0
- package/resources/local/hermes-agent-core/skills/github/github-auth/scripts/gh-env.sh +66 -0
- package/resources/local/hermes-agent-core/skills/github/github-code-review/SKILL.md +481 -0
- package/resources/local/hermes-agent-core/skills/github/github-code-review/references/review-output-template.md +74 -0
- package/resources/local/hermes-agent-core/skills/github/github-issues/SKILL.md +370 -0
- package/resources/local/hermes-agent-core/skills/github/github-issues/templates/bug-report.md +35 -0
- package/resources/local/hermes-agent-core/skills/github/github-issues/templates/feature-request.md +31 -0
- package/resources/local/hermes-agent-core/skills/github/github-pr-workflow/SKILL.md +367 -0
- package/resources/local/hermes-agent-core/skills/github/github-pr-workflow/references/ci-troubleshooting.md +183 -0
- package/resources/local/hermes-agent-core/skills/github/github-pr-workflow/references/conventional-commits.md +71 -0
- package/resources/local/hermes-agent-core/skills/github/github-pr-workflow/templates/pr-body-bugfix.md +35 -0
- package/resources/local/hermes-agent-core/skills/github/github-pr-workflow/templates/pr-body-feature.md +33 -0
- package/resources/local/hermes-agent-core/skills/github/github-repo-management/SKILL.md +516 -0
- package/resources/local/hermes-agent-core/skills/github/github-repo-management/references/github-api-cheatsheet.md +161 -0
- package/resources/local/hermes-agent-core/skills/mcp/DESCRIPTION.md +3 -0
- package/resources/local/hermes-agent-core/skills/mcp/native-mcp/SKILL.md +357 -0
- package/resources/local/hermes-agent-core/skills/software-development/debugging-hermes-tui-commands/SKILL.md +152 -0
- package/resources/local/hermes-agent-core/skills/software-development/hermes-agent-skill-authoring/SKILL.md +165 -0
- package/resources/local/hermes-agent-core/skills/software-development/hermes-s6-container-supervision/SKILL.md +176 -0
- package/resources/local/hermes-agent-core/skills/software-development/node-inspect-debugger/SKILL.md +319 -0
- package/resources/local/hermes-agent-core/skills/software-development/plan/SKILL.md +58 -0
- package/resources/local/hermes-agent-core/skills/software-development/python-debugpy/SKILL.md +375 -0
- package/resources/local/hermes-agent-core/skills/software-development/requesting-code-review/SKILL.md +280 -0
- package/resources/local/hermes-agent-core/skills/software-development/spike/SKILL.md +197 -0
- package/resources/local/hermes-agent-core/skills/software-development/subagent-driven-development/SKILL.md +352 -0
- package/resources/local/hermes-agent-core/skills/software-development/subagent-driven-development/references/context-budget-discipline.md +53 -0
- package/resources/local/hermes-agent-core/skills/software-development/subagent-driven-development/references/gates-taxonomy.md +93 -0
- package/resources/local/hermes-agent-core/skills/software-development/systematic-debugging/SKILL.md +367 -0
- package/resources/local/hermes-agent-core/skills/software-development/test-driven-development/SKILL.md +343 -0
- package/resources/local/hermes-agent-core/skills/software-development/writing-plans/SKILL.md +297 -0
- package/resources/local/manifest.json +12 -0
- package/rule.md +2 -0
- package/scripts/audit-pack.js +5 -0
- package/scripts/smoke-browser.js +53 -0
- package/scripts/smoke-package.js +38 -4
- package/skill.md +36 -4
- package/skills/gsap.md +26 -0
- package/skills/hermes-agent.md +17 -0
- package/src/agent/agent-definitions.js +4 -4
- package/src/agent/runtime.js +179 -5
- package/src/agent/subagent-child.js +44 -0
- package/src/ai/capability-scorecard.js +193 -14
- package/src/ai/hermes-core.js +77 -0
- package/src/ai/model-capabilities.js +42 -2
- package/src/ai/prompts/system-prompt.js +18 -2
- package/src/ai/small-model-amplifier.js +35 -7
- package/src/ai/workflow-selector.js +22 -1
- package/src/cli/commands.js +46 -2
- package/src/cli/config.js +45 -6
- package/src/cli/context-loader.js +253 -9
- package/src/cli/conversation-format.js +5 -0
- package/src/cli/input-controller.js +79 -10
- package/src/cli/prompt-builder.js +47 -8
- package/src/cli/repl-commands.js +115 -0
- package/src/cli/repl.js +343 -85
- package/src/cli/slash-commands.js +4 -2
- package/src/cli/tui.js +133 -37
- package/src/mcp/client.js +54 -11
- package/src/mcp/presets.js +114 -0
- package/src/tools/agent.js +316 -25
- package/src/tools/executor.js +412 -12
- package/src/tools/permission.js +20 -17
- package/winter.d.ts +112 -10
package/src/tools/agent.js
CHANGED
|
@@ -1,56 +1,347 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
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
|
|
21
|
-
const
|
|
22
|
-
const
|
|
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
|
-
|
|
25
|
-
|
|
26
|
-
agentId,
|
|
27
|
-
status: 'running',
|
|
71
|
+
const state = {
|
|
72
|
+
id: agentId,
|
|
28
73
|
task: task.trim(),
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
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:
|
|
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:
|
|
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
|
}
|