winter-super-cli 2026.6.26 → 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 +66 -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 +16 -2
- package/src/ai/small-model-amplifier.js +35 -7
- package/src/ai/workflow-selector.js +22 -1
- package/src/cli/commands.js +21 -1
- package/src/cli/config.js +42 -4
- 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 +45 -8
- package/src/cli/repl-commands.js +115 -0
- package/src/cli/repl.js +147 -86
- package/src/cli/slash-commands.js +3 -1
- package/src/cli/tui.js +133 -37
- package/src/mcp/client.js +46 -5
- package/src/tools/agent.js +316 -25
- package/src/tools/executor.js +310 -9
- package/src/tools/permission.js +20 -17
- package/winter.d.ts +112 -10
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import { existsSync } from 'fs';
|
|
1
|
+
import { existsSync, readFileSync } from 'fs';
|
|
2
|
+
import { mkdtemp, writeFile } from 'fs/promises';
|
|
3
|
+
import { tmpdir } from 'os';
|
|
2
4
|
import path from 'path';
|
|
3
5
|
import { fileURLToPath } from 'url';
|
|
4
6
|
|
|
@@ -73,8 +75,9 @@ export const CAPABILITY_AREAS = [
|
|
|
73
75
|
target: 'Codebuff/Claude-style custom agents with scoped tools',
|
|
74
76
|
probes: [
|
|
75
77
|
{ key: 'agentRegistry', label: 'project agent registry is active' },
|
|
76
|
-
{ key: 'agentTool', label: 'Agent tool
|
|
77
|
-
{ key: 'scopedTools', label: 'role-scoped tools are
|
|
78
|
+
{ key: 'agentTool', label: 'Agent tool runs real subagent conversations' },
|
|
79
|
+
{ key: 'scopedTools', label: 'role-scoped tools are enforced' },
|
|
80
|
+
{ key: 'processIsolation', label: 'subagents can run through child-process isolation' },
|
|
78
81
|
],
|
|
79
82
|
},
|
|
80
83
|
{
|
|
@@ -107,6 +110,7 @@ export const CAPABILITY_AREAS = [
|
|
|
107
110
|
probes: [
|
|
108
111
|
{ key: 'autoDebug', label: '/debug and /auto routes exist' },
|
|
109
112
|
{ key: 'browserDebug', label: 'BrowserDebug tool exists' },
|
|
113
|
+
{ key: 'browserSmoke', label: 'browser smoke covers BrowserDebug and VisibleBrowser' },
|
|
110
114
|
{ key: 'verificationCommands', label: 'verification command inference exists' },
|
|
111
115
|
],
|
|
112
116
|
},
|
|
@@ -139,24 +143,197 @@ function scoreArea(area, probes) {
|
|
|
139
143
|
};
|
|
140
144
|
}
|
|
141
145
|
|
|
146
|
+
async function runBehaviorProbes() {
|
|
147
|
+
const result = {
|
|
148
|
+
agentTool: false,
|
|
149
|
+
scopedTools: false,
|
|
150
|
+
processIsolation: false,
|
|
151
|
+
slashMenu: false,
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
try {
|
|
155
|
+
const { AgentTool } = await import('../tools/agent.js');
|
|
156
|
+
const definitions = [{ name: 'Read' }, { name: 'Write' }];
|
|
157
|
+
const repl = {
|
|
158
|
+
projectPath: PACKAGE_ROOT,
|
|
159
|
+
ai: {
|
|
160
|
+
getActiveProvider: () => 'probe',
|
|
161
|
+
setProvider: () => true,
|
|
162
|
+
},
|
|
163
|
+
tools: {
|
|
164
|
+
getToolDefinitions: () => definitions,
|
|
165
|
+
},
|
|
166
|
+
agentRegistry: {
|
|
167
|
+
async get(id = 'general') {
|
|
168
|
+
return { id, tools: ['Read'], instructionsPrompt: 'probe' };
|
|
169
|
+
},
|
|
170
|
+
},
|
|
171
|
+
getAgentToolsForDefinition(definition) {
|
|
172
|
+
return definitions.filter(tool => definition.tools.includes(tool.name));
|
|
173
|
+
},
|
|
174
|
+
async getProjectContext() {
|
|
175
|
+
return '';
|
|
176
|
+
},
|
|
177
|
+
getAgentDefinitionSystemPrompt() {
|
|
178
|
+
return 'probe';
|
|
179
|
+
},
|
|
180
|
+
async runConversation(_messages, _label, tools) {
|
|
181
|
+
return {
|
|
182
|
+
finalContent: 'probe complete',
|
|
183
|
+
usedTools: true,
|
|
184
|
+
changedFiles: [],
|
|
185
|
+
toolSummaries: [`allowed=${tools.map(tool => tool.name).join(',')}`],
|
|
186
|
+
executedTools: [{ tool: tools[0]?.name, success: true }],
|
|
187
|
+
usage: {},
|
|
188
|
+
};
|
|
189
|
+
},
|
|
190
|
+
};
|
|
191
|
+
const agent = new AgentTool(repl);
|
|
192
|
+
const run = await agent.run('probe real subagent behavior', { role: 'general', tools: ['Read'], processIsolation: false });
|
|
193
|
+
result.agentTool = run.success === true && run.status === 'completed' && run.usedTools === true && run.allowedTools?.includes('Read') && !run.allowedTools?.includes('Write');
|
|
194
|
+
} catch {
|
|
195
|
+
result.agentTool = false;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
try {
|
|
199
|
+
const { EventEmitter } = await import('events');
|
|
200
|
+
const { AgentTool } = await import('../tools/agent.js');
|
|
201
|
+
const projectPath = await mkdtemp(path.join(tmpdir(), 'winter-scorecard-agent-'));
|
|
202
|
+
await writeFile(path.join(projectPath, 'README.md'), 'scorecard workspace', 'utf8');
|
|
203
|
+
const repl = {
|
|
204
|
+
constructor: { name: 'WinterREPL' },
|
|
205
|
+
projectPath,
|
|
206
|
+
sessionId: 'scorecard',
|
|
207
|
+
version: 'scorecard',
|
|
208
|
+
ai: {
|
|
209
|
+
getActiveProvider: () => 'probe',
|
|
210
|
+
setProvider: () => true,
|
|
211
|
+
},
|
|
212
|
+
tools: { getToolDefinitions: () => [] },
|
|
213
|
+
subagentFork: () => {
|
|
214
|
+
const child = new EventEmitter();
|
|
215
|
+
child.pid = 101;
|
|
216
|
+
child.stdout = new EventEmitter();
|
|
217
|
+
child.stderr = new EventEmitter();
|
|
218
|
+
child.kill = () => {};
|
|
219
|
+
child.send = message => {
|
|
220
|
+
queueMicrotask(() => child.emit('message', {
|
|
221
|
+
type: 'result',
|
|
222
|
+
result: {
|
|
223
|
+
success: true,
|
|
224
|
+
agentId: message.options.agentId,
|
|
225
|
+
summary: 'isolated',
|
|
226
|
+
workspaceIsolated: message.options.workspaceIsolation === true,
|
|
227
|
+
workspacePath: message.options.projectPath,
|
|
228
|
+
},
|
|
229
|
+
}));
|
|
230
|
+
};
|
|
231
|
+
return child;
|
|
232
|
+
},
|
|
233
|
+
};
|
|
234
|
+
const agent = new AgentTool(repl);
|
|
235
|
+
const run = await agent.run('probe process isolation', { processIsolation: true });
|
|
236
|
+
result.processIsolation = run.success === true && run.processIsolated === true && run.workspaceIsolated === true && run.childPid === 101;
|
|
237
|
+
} catch {
|
|
238
|
+
result.processIsolation = false;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
try {
|
|
242
|
+
const { AgentRuntime } = await import('../agent/runtime.js');
|
|
243
|
+
let executed = false;
|
|
244
|
+
let turns = 0;
|
|
245
|
+
const repl = {
|
|
246
|
+
hydrateSessionToolPermissions() {},
|
|
247
|
+
isCancelled: false,
|
|
248
|
+
useUnicodeUi: false,
|
|
249
|
+
sessionPermissionGrants: new Set(),
|
|
250
|
+
session: { getContext: () => ({}), updateContext: async () => {} },
|
|
251
|
+
ai: { tools: [], _modelTier: 'medium', setTools() {} },
|
|
252
|
+
tools: {
|
|
253
|
+
normalizeToolName: name => String(name),
|
|
254
|
+
execute: async () => {
|
|
255
|
+
executed = true;
|
|
256
|
+
return { success: true };
|
|
257
|
+
},
|
|
258
|
+
},
|
|
259
|
+
selectExecutionProfile: () => ({ provider: 'probe', model: 'probe' }),
|
|
260
|
+
actionRequiresTools: () => false,
|
|
261
|
+
async requestAssistantTurn() {
|
|
262
|
+
turns += 1;
|
|
263
|
+
if (turns === 1) {
|
|
264
|
+
return { assistantMsg: { content: '' }, toolCalls: [{ id: 'x', toolName: 'Bash', toolArgs: { command: 'echo no' } }] };
|
|
265
|
+
}
|
|
266
|
+
return { assistantMsg: { content: 'done' }, toolCalls: [], finalContent: 'done' };
|
|
267
|
+
},
|
|
268
|
+
buildToolCallSignature: calls => JSON.stringify(calls.map(call => call.toolName)),
|
|
269
|
+
formatToolCallsForMessage: calls => calls,
|
|
270
|
+
buildPromptToolResultForModel: async (_tool, value) => value,
|
|
271
|
+
formatToolResultForConsole: (_tool, value) => value.error || '',
|
|
272
|
+
shouldPromptForToolPermission: async () => false,
|
|
273
|
+
recoverToolArgs: () => null,
|
|
274
|
+
enrichToolArgs: (_tool, args) => args,
|
|
275
|
+
buildToolFallbackAnswer: values => values.join('\n'),
|
|
276
|
+
getLatestUserText: messages => messages.at(-1)?.content || '',
|
|
277
|
+
shouldAutoVerifyAfterTools: () => false,
|
|
278
|
+
};
|
|
279
|
+
const runtime = new AgentRuntime(repl);
|
|
280
|
+
const run = await runtime.runConversation([{ role: 'user', content: 'probe' }], 'probe', [{ name: 'Read' }]);
|
|
281
|
+
result.scopedTools = executed === false && run.toolSummaries?.join('\n').includes('not allowed for this agent');
|
|
282
|
+
} catch {
|
|
283
|
+
result.scopedTools = false;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
try {
|
|
287
|
+
const { WinterInputController } = await import('../cli/input-controller.js');
|
|
288
|
+
const repl = {
|
|
289
|
+
slashMenu: {
|
|
290
|
+
open: true,
|
|
291
|
+
line: '/',
|
|
292
|
+
items: Array.from({ length: 12 }, (_, index) => ({ cmd: `/cmd${index}`, desc: `Command ${index}` })),
|
|
293
|
+
selected: 0,
|
|
294
|
+
offset: 0,
|
|
295
|
+
printedLines: 0,
|
|
296
|
+
},
|
|
297
|
+
rl: { line: '/', prompt() {} },
|
|
298
|
+
getSlashSuggestions: () => [],
|
|
299
|
+
};
|
|
300
|
+
const input = new WinterInputController(repl);
|
|
301
|
+
input.renderSlashMenu = () => {};
|
|
302
|
+
for (let i = 0; i < 8; i++) input.moveSlashSelection(1);
|
|
303
|
+
result.slashMenu = repl.slashMenu.selected === 8 && repl.slashMenu.offset > 0;
|
|
304
|
+
} catch {
|
|
305
|
+
result.slashMenu = false;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
return result;
|
|
309
|
+
}
|
|
310
|
+
|
|
142
311
|
export async function assessWinterCapabilities(repl = {}) {
|
|
143
312
|
const projectPath = repl.projectPath || process.cwd();
|
|
144
313
|
const srcPath = path.join(PACKAGE_ROOT, 'src');
|
|
145
314
|
const resourceRoot = path.join(PACKAGE_ROOT, 'resources');
|
|
146
315
|
const tools = repl.tools?.getToolDefinitions?.() || repl.getAgentTools?.('general') || [];
|
|
147
316
|
const toolNames = new Set(tools.map(tool => tool.name || tool.function?.name).filter(Boolean));
|
|
317
|
+
const hasSourceText = (relativePath, pattern) => {
|
|
318
|
+
try {
|
|
319
|
+
return pattern.test(readFileSync(path.join(srcPath, relativePath), 'utf8'));
|
|
320
|
+
} catch {
|
|
321
|
+
return false;
|
|
322
|
+
}
|
|
323
|
+
};
|
|
148
324
|
|
|
325
|
+
const behavior = await runBehaviorProbes();
|
|
149
326
|
const probes = {
|
|
150
327
|
agentRuntime: Boolean(repl.agentRuntime) || existsSync(path.join(srcPath, 'agent', 'runtime.js')),
|
|
151
328
|
toolEvidenceGuard: existsSync(path.join(srcPath, 'cli', 'repl.test.js')),
|
|
152
|
-
loopProtection: typeof repl.runConversation === 'function',
|
|
329
|
+
loopProtection: typeof repl.runConversation === 'function' || existsSync(path.join(srcPath, 'agent', 'runtime.js')),
|
|
153
330
|
|
|
154
331
|
toolExecutor: Boolean(repl.tools) || existsSync(path.join(srcPath, 'tools', 'executor.js')),
|
|
155
|
-
toolDoctor: typeof repl.runToolDoctor === 'function',
|
|
332
|
+
toolDoctor: typeof repl.runToolDoctor === 'function' || existsSync(path.join(srcPath, 'cli', 'diagnostics.js')),
|
|
156
333
|
fallbackParser: existsSync(path.join(srcPath, 'cli', 'tool-call-adapter.js')),
|
|
157
334
|
|
|
158
335
|
codebaseIndex: typeof repl.ensureCodebaseIndex === 'function' || existsSync(path.join(srcPath, 'codebase-index', 'indexer.js')),
|
|
159
|
-
codebaseContext: typeof repl.buildCodebaseContext === 'function',
|
|
336
|
+
codebaseContext: typeof repl.buildCodebaseContext === 'function' || existsSync(path.join(srcPath, 'codebase-index', 'search.js')),
|
|
160
337
|
atContext: existsSync(path.join(srcPath, 'cli', 'at-context.js')),
|
|
161
338
|
|
|
162
339
|
tokenJuice: Boolean(repl.tokenJuice) || existsSync(path.join(srcPath, 'context', 'token-juice.js')),
|
|
@@ -164,20 +341,22 @@ export async function assessWinterCapabilities(repl = {}) {
|
|
|
164
341
|
sessionCompression: typeof repl.compressSessionContext === 'function' || existsSync(path.join(srcPath, 'context', 'compress.js')),
|
|
165
342
|
|
|
166
343
|
agentRegistry: Boolean(repl.agentRegistry) || existsSync(path.join(srcPath, 'agent', 'agent-definitions.js')),
|
|
167
|
-
agentTool:
|
|
168
|
-
scopedTools:
|
|
344
|
+
agentTool: behavior.agentTool,
|
|
345
|
+
scopedTools: behavior.scopedTools,
|
|
346
|
+
processIsolation: behavior.processIsolation,
|
|
169
347
|
|
|
170
348
|
bottomInput: Boolean(repl.inputController) || existsSync(path.join(srcPath, 'cli', 'input-controller.js')),
|
|
171
|
-
directImagePaste: typeof repl.handleDirectClipboardPaste === 'function',
|
|
172
|
-
slashMenu: Array.isArray(repl.getSlashSuggestions?.('/')) || existsSync(path.join(srcPath, 'cli', 'slash-commands.js')),
|
|
349
|
+
directImagePaste: typeof repl.handleDirectClipboardPaste === 'function' || hasSourceText(path.join('cli', 'input-controller.js'), /handleDirectClipboardPaste|clipboardImage|imageAttachments/),
|
|
350
|
+
slashMenu: behavior.slashMenu && (Array.isArray(repl.getSlashSuggestions?.('/')) || existsSync(path.join(srcPath, 'cli', 'slash-commands.js'))),
|
|
173
351
|
|
|
174
352
|
providerManager: Boolean(repl.ai) || existsSync(path.join(srcPath, 'ai', 'providers.js')),
|
|
175
|
-
providerSwitch: typeof repl.ai?.switchProvider === 'function',
|
|
353
|
+
providerSwitch: typeof repl.ai?.switchProvider === 'function' || hasSourceText(path.join('ai', 'providers.js'), /async\s+switchProvider|switchProvider\s*\(/),
|
|
176
354
|
modelTier: existsSync(path.join(srcPath, 'ai', 'model-capabilities.js')),
|
|
177
355
|
|
|
178
|
-
autoDebug: typeof repl.runAutoHealing === 'function',
|
|
179
|
-
browserDebug: toolNames.has('BrowserDebug'),
|
|
180
|
-
|
|
356
|
+
autoDebug: typeof repl.runAutoHealing === 'function' || hasSourceText(path.join('cli', 'repl.js'), /runAutoHealing|verifyAndHeal/),
|
|
357
|
+
browserDebug: toolNames.has('BrowserDebug') || hasSourceText(path.join('tools', 'executor.js'), /BrowserDebug|OpenBrowser/),
|
|
358
|
+
browserSmoke: hasSourceText(path.join('..', 'scripts', 'smoke-browser.js'), /BrowserDebug[\s\S]*VisibleBrowser|VisibleBrowser[\s\S]*BrowserDebug/),
|
|
359
|
+
verificationCommands: typeof repl.inferVerificationCommands === 'function' || hasSourceText(path.join('cli', 'repl.js'), /inferVerificationCommands/),
|
|
181
360
|
|
|
182
361
|
mcp: existsSync(path.join(srcPath, 'mcp', 'client.js')),
|
|
183
362
|
resources: existsSync(path.join(resourceRoot, 'local', 'manifest.json')),
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
export const HERMES_CORE_RESOURCE = 'hermes-agent-core';
|
|
2
|
+
|
|
3
|
+
export const HERMES_CORE_PATTERNS = [
|
|
4
|
+
{
|
|
5
|
+
key: 'self_improving_loop',
|
|
6
|
+
label: 'Closed learning loop',
|
|
7
|
+
rule: 'After non-trivial work, capture reusable procedures, failure modes, and verification evidence so future turns start smarter.',
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
key: 'skill_lifecycle',
|
|
11
|
+
label: 'Skill lifecycle',
|
|
12
|
+
rule: 'Promote repeated workflows into skills, improve skills when they fail, and keep skill instructions operational rather than decorative.',
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
key: 'session_search',
|
|
16
|
+
label: 'Session search and compression',
|
|
17
|
+
rule: 'Search or summarize prior context before broad guessing; compress long trajectories into high-signal facts and decisions.',
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
key: 'delegation',
|
|
21
|
+
label: 'Subagent delegation',
|
|
22
|
+
rule: 'Split independent workstreams into bounded subagents or parallel tool calls, then merge evidence before finalizing.',
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
key: 'automation_triggers',
|
|
26
|
+
label: 'Automation triggers',
|
|
27
|
+
rule: 'For recurring checks, scheduled work, webhook-like events, or background audits, design a trigger, context injection, verification, and delivery path.',
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
key: 'tui_gateway',
|
|
31
|
+
label: 'TUI gateway separation',
|
|
32
|
+
rule: 'Keep UI rendering, command registry, model loop, tools, and session state as separable surfaces with explicit events and status.',
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
key: 'tool_gateway',
|
|
36
|
+
label: 'Tool gateway discipline',
|
|
37
|
+
rule: 'Treat MCP/tools as a gateway with allowlists, diagnostics, retries, timeouts, and concrete tool-result evidence.',
|
|
38
|
+
},
|
|
39
|
+
];
|
|
40
|
+
|
|
41
|
+
export function detectHermesCoreSignals({ taskText = '', projectSignals = [] } = {}) {
|
|
42
|
+
const text = `${String(taskText || '')}\n${(projectSignals || []).join('\n')}`.toLowerCase();
|
|
43
|
+
const has = (...keywords) => keywords.some(keyword => text.includes(keyword));
|
|
44
|
+
|
|
45
|
+
return {
|
|
46
|
+
agent: has('agent', 'subagent', 'multi-agent', 'multi agent', 'ai assistant', 'coding assistant'),
|
|
47
|
+
skills: has('skill', 'skills', 'procedural memory', 'self-improv', 'self improv', 'learning loop'),
|
|
48
|
+
memory: has('memory', 'memories', 'session search', 'conversation history', 'compress context', 'trajectory'),
|
|
49
|
+
automation: has('cron', 'schedule', 'scheduled', 'webhook', 'routine', 'automation', 'background job'),
|
|
50
|
+
gateway: has('gateway', 'telegram', 'discord', 'slack', 'whatsapp', 'signal', 'messaging'),
|
|
51
|
+
tui: has('tui', 'terminal ui', 'ink', 'composer', 'slash command', 'autocomplete'),
|
|
52
|
+
mcp: has('mcp', 'tool gateway', 'toolset', 'tool registry', 'tool calling'),
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export function shouldApplyHermesCore(input = {}) {
|
|
57
|
+
const signals = detectHermesCoreSignals(input);
|
|
58
|
+
return Object.values(signals).some(Boolean);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export function buildHermesCoreContract({ compact = false } = {}) {
|
|
62
|
+
const selected = compact
|
|
63
|
+
? HERMES_CORE_PATTERNS.filter(pattern => ['self_improving_loop', 'skill_lifecycle', 'delegation', 'tool_gateway'].includes(pattern.key))
|
|
64
|
+
: HERMES_CORE_PATTERNS;
|
|
65
|
+
|
|
66
|
+
const lines = [
|
|
67
|
+
'## Hermes Core Agent Contract',
|
|
68
|
+
'- Apply Hermes-inspired core behavior directly inside Winter: self-improving skills, searchable memory, delegated workstreams, scheduled automation thinking, and tool-gateway discipline.',
|
|
69
|
+
...selected.map(pattern => `- ${pattern.label}: ${pattern.rule}`),
|
|
70
|
+
];
|
|
71
|
+
|
|
72
|
+
if (!compact) {
|
|
73
|
+
lines.push('- UI/TUI work: expose model state, tool progress, interrupts, command discovery, and evidence without fake progress text.');
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return lines.join('\n');
|
|
77
|
+
}
|
|
@@ -18,11 +18,51 @@ const TIER_ORDER = [MODEL_TIERS.TINY, MODEL_TIERS.SMALL, MODEL_TIERS.MEDIUM, MOD
|
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
20
|
* Classify a model name into a capability tier.
|
|
21
|
-
* Winter
|
|
21
|
+
* Winter still pushes maximum reasoning for every model, but the real tier matters
|
|
22
|
+
* for prompt size, tool-result budgets, and small-model guardrails.
|
|
22
23
|
* @returns {string} One of MODEL_TIERS
|
|
23
24
|
*/
|
|
24
25
|
export function classifyModelTier(modelName, provider = '') {
|
|
25
|
-
|
|
26
|
+
const raw = `${provider || ''} ${modelName || ''}`.toLowerCase();
|
|
27
|
+
if (!raw.trim()) return MODEL_TIERS.MEDIUM;
|
|
28
|
+
|
|
29
|
+
if (/\b(tiny|nano|0\.5b|1b|1\.5b|2b|2\.7b)\b/.test(raw)) {
|
|
30
|
+
return MODEL_TIERS.TINY;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const paramMatch = raw.match(/(?:^|[^0-9])(\d+(?:\.\d+)?)\s*b(?:[^a-z]|$)/);
|
|
34
|
+
if (paramMatch) {
|
|
35
|
+
const params = Number(paramMatch[1]);
|
|
36
|
+
if (Number.isFinite(params)) {
|
|
37
|
+
if (params < 3) return MODEL_TIERS.TINY;
|
|
38
|
+
if (params < 15) return MODEL_TIERS.SMALL;
|
|
39
|
+
if (params < 40) return MODEL_TIERS.MEDIUM;
|
|
40
|
+
if (params < 120) return MODEL_TIERS.LARGE;
|
|
41
|
+
return MODEL_TIERS.FLAGSHIP;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (/\b(mini|small|lite|light|fast|flash|haiku|3b|7b|8b|9b|13b|14b)\b/.test(raw)) {
|
|
46
|
+
return MODEL_TIERS.SMALL;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (/\b(sonnet|opus|gpt-5|gpt-4\.1|gpt-4o|o3|o4|gemini-2\.5-pro|minimax-m2|m2\.5|deepseek-r1|kimi-k2)\b/.test(raw)) {
|
|
50
|
+
return MODEL_TIERS.FLAGSHIP;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (/\b(70b|72b|90b|large|pro|command-r|llama3\.1|llama-3\.1)\b/.test(raw)) {
|
|
54
|
+
return MODEL_TIERS.LARGE;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (/\b(32b|34b|medium|codestral|qwen2\.5-coder)\b/.test(raw)) {
|
|
58
|
+
return MODEL_TIERS.MEDIUM;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (/\b(ollama|lmstudio|local|llama|qwen|mistral|gemma|phi|yi-coder|deepseek-coder)\b/.test(raw)) {
|
|
62
|
+
return MODEL_TIERS.SMALL;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return MODEL_TIERS.MEDIUM;
|
|
26
66
|
}
|
|
27
67
|
|
|
28
68
|
/**
|
|
@@ -5,7 +5,9 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import { formatRuntimeEnvironmentSummary, getRuntimeEnvironment } from '../../cli/runtime-env.js';
|
|
8
|
+
import { buildHermesCoreContract } from '../hermes-core.js';
|
|
8
9
|
import { getModelBudgetMultiplier } from '../model-capabilities.js';
|
|
10
|
+
import { buildCodingMasteryContract, buildSmallModelAmplification } from '../small-model-amplifier.js';
|
|
9
11
|
|
|
10
12
|
const BASE_PRINCIPLES = [
|
|
11
13
|
'Execute, don\'t describe - Do the work, don\'t write plans about doing the work',
|
|
@@ -23,7 +25,7 @@ const TOOL_CATEGORIES = {
|
|
|
23
25
|
shell: ['Bash', 'Glob', 'Grep'],
|
|
24
26
|
task: ['TaskCreate', 'TaskUpdate', 'TaskList'],
|
|
25
27
|
web: ['WebFetch', 'WebSearch', 'WebArchive'],
|
|
26
|
-
context: ['LSP', 'MCP', 'Parallel', 'Agent'],
|
|
28
|
+
context: ['LSP', 'MCP', 'Parallel', 'Agent', 'DelegateTask', 'ParallelAgent'],
|
|
27
29
|
plan: ['TodoWrite', 'TodoList', 'ScheduleWakeup'],
|
|
28
30
|
notebook: ['NotebookRead', 'NotebookEdit'],
|
|
29
31
|
};
|
|
@@ -86,8 +88,13 @@ function appendSharedContext(parts, { environment, session, design, resourceCont
|
|
|
86
88
|
}
|
|
87
89
|
|
|
88
90
|
function buildStandardSystemPrompt(options = {}) {
|
|
89
|
-
const { role = 'coding', tools = [], resourceContext, modelTier = '' } = options;
|
|
91
|
+
const { role = 'coding', tools = [], resourceContext, modelTier = '', context } = options;
|
|
90
92
|
const budgets = getPromptBudgets(modelTier);
|
|
93
|
+
const amplifier = buildSmallModelAmplification({
|
|
94
|
+
modelTier,
|
|
95
|
+
workflowProfile: role,
|
|
96
|
+
depth: context?.type || 'standard',
|
|
97
|
+
});
|
|
91
98
|
const projectContextBudget = options.projectContextBudget ?? budgets.projectContextBudget;
|
|
92
99
|
const compactSystemPrompt = options.compactSystemPrompt ?? budgets.compactSystemPrompt;
|
|
93
100
|
const parts = [
|
|
@@ -106,6 +113,13 @@ function buildStandardSystemPrompt(options = {}) {
|
|
|
106
113
|
'For design/UI work, inspect the existing interface and design resources first; avoid generic placeholder layouts.',
|
|
107
114
|
'If the user attaches or pastes an image, analyze it as primary evidence.',
|
|
108
115
|
'',
|
|
116
|
+
'## Winter Strength Amplifier',
|
|
117
|
+
amplifier.hint,
|
|
118
|
+
'',
|
|
119
|
+
buildCodingMasteryContract(),
|
|
120
|
+
'',
|
|
121
|
+
buildHermesCoreContract(),
|
|
122
|
+
'',
|
|
109
123
|
];
|
|
110
124
|
|
|
111
125
|
const toolList = formatToolList(tools);
|
|
@@ -2,18 +2,46 @@ export function isWeakTier(modelTier = '') {
|
|
|
2
2
|
return true;
|
|
3
3
|
}
|
|
4
4
|
|
|
5
|
+
export function buildCodingMasteryContract({ compact = false } = {}) {
|
|
6
|
+
const rules = [
|
|
7
|
+
'Read the code path before editing: entrypoint, caller, callee, config/env, and tests when they exist.',
|
|
8
|
+
'Identify invariants and side effects before changing behavior: data shape, async ordering, permissions, IO, cache, UI state, and provider differences.',
|
|
9
|
+
'Prefer the smallest correct patch, but update adjacent tests/docs/config when the contract changes.',
|
|
10
|
+
'After editing, review the diff mentally for syntax errors, dead code, race conditions, missing imports, wrong paths, and Windows path/shell issues.',
|
|
11
|
+
'Verify with the closest command. If verification is impossible, state the exact blocker and what evidence was still checked.',
|
|
12
|
+
'For mutating work, expect Winter to run verification before the final answer; use failures as the next debugging input instead of claiming success early.',
|
|
13
|
+
'Final answers must name concrete files changed and concrete verification results; no vague "should work" claims.',
|
|
14
|
+
];
|
|
15
|
+
|
|
16
|
+
if (compact) {
|
|
17
|
+
return `## Coding Mastery Contract\n${rules.slice(0, 5).map(rule => `- ${rule}`).join('\n')}`;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return [
|
|
21
|
+
'## Coding Mastery Contract',
|
|
22
|
+
'- Act like a senior maintainer: understand the runtime path, preserve local patterns, and optimize for the user-visible failure.',
|
|
23
|
+
...rules.map(rule => `- ${rule}`),
|
|
24
|
+
'- For reviews, lead with defects and risks. For implementation, finish with a short change summary and verification evidence.',
|
|
25
|
+
].join('\n');
|
|
26
|
+
}
|
|
27
|
+
|
|
5
28
|
export function buildSmallModelAmplification({ modelTier = '', workflowProfile = 'general', depth = 'standard' } = {}) {
|
|
6
29
|
const deepLike = depth === 'deep' || /debug|backend|data|devops|ai/.test(workflowProfile);
|
|
7
|
-
const
|
|
30
|
+
const tier = String(modelTier || 'medium').toLowerCase();
|
|
31
|
+
const smallLike = /tiny|small/.test(tier);
|
|
32
|
+
const maxToolTurns = deepLike ? (smallLike ? 22 : 18) : (smallLike ? 18 : 14);
|
|
8
33
|
|
|
9
34
|
const hint = [
|
|
10
35
|
'[Winter Strength Amplifier]',
|
|
11
|
-
|
|
12
|
-
'- Mandatory
|
|
13
|
-
'-
|
|
14
|
-
'-
|
|
15
|
-
'-
|
|
16
|
-
'- Use CodeGraph/codebase index
|
|
36
|
+
`- Active model tier: ${tier}. Winter must compensate with stricter procedure, not weaker behavior.`,
|
|
37
|
+
'- Mandatory loop for action tasks: restate success criteria privately -> inspect real files/state -> make one concrete tool call -> read result -> continue -> verify -> final.',
|
|
38
|
+
'- If you are uncertain, call Read/Grep/Glob/Bash instead of guessing. Evidence beats reasoning guesses.',
|
|
39
|
+
'- For tool fallback mode, output exactly one tool call and no prose. Do not wrap tool calls in explanation.',
|
|
40
|
+
'- Do not claim files changed, browser checked, tests passed, or commands ran unless tool output in this turn proves it.',
|
|
41
|
+
'- Prefer small, high-signal context reads over broad dumps. Use CodeGraph/codebase index before broad file reads when available.',
|
|
42
|
+
'- Coding standard: follow the Coding Mastery Contract; inspect call sites and tests before edits, then verify the runtime path.',
|
|
43
|
+
'- After a failed tool or test, inspect the new failure and try the next smallest fix. Stop only at max tool turns or a real blocker.',
|
|
44
|
+
'- Before final answer, run a private self-check: requirement met, files touched, verification result, remaining risk. Do not print the self-check.',
|
|
17
45
|
].join('\n');
|
|
18
46
|
|
|
19
47
|
return {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { classifyTask, TASK_CATEGORIES, TASK_TYPES } from './prompts/task-classifier.js';
|
|
2
|
+
import { detectHermesCoreSignals, shouldApplyHermesCore } from './hermes-core.js';
|
|
2
3
|
|
|
3
4
|
function hasAny(text, keywords) {
|
|
4
5
|
return keywords.some(kw => text.includes(kw));
|
|
@@ -20,6 +21,7 @@ function detectTechnology(text, signals) {
|
|
|
20
21
|
devops: hasAny(text, ['devops', 'ci/cd', 'docker', 'kubernetes', 'helm', 'terraform', 'ansible', 'deployment']) || hasSignal(/(docker|k8s|kubernetes|helm|terraform|github-actions|gitlab-ci)/),
|
|
21
22
|
game: hasAny(text, ['game', 'unity', 'unreal', 'godot', 'multiplayer']) || hasSignal(/(unity|unreal|godot)/),
|
|
22
23
|
ai: hasAny(text, ['ai agent', 'llm', 'rag', 'embedding', 'inference', 'model serving', 'mcp']) || hasSignal(/(langchain|llamaindex|embedding|transformer|onnx|mcp)/),
|
|
24
|
+
animation: hasAny(text, ['animation', 'animate', 'motion', 'transition', 'timeline', 'scrolltrigger', 'scroll trigger', 'scroll-driven', 'scroll animation', 'parallax', 'draggable', 'flip animation', 'splittext', 'morphsvg', 'greensock', 'gsap']) || hasSignal(/(gsap|greensock|scrolltrigger|framer-motion|motion|animation)/),
|
|
23
25
|
};
|
|
24
26
|
}
|
|
25
27
|
|
|
@@ -33,12 +35,14 @@ function buildTechnologySuggestions(tech) {
|
|
|
33
35
|
if (tech.devops) suggestions.push('DevOps: Docker + CI/CD + IaC (Terraform), observability/logging');
|
|
34
36
|
if (tech.game) suggestions.push('Game: Unity/Unreal/Godot, profiling, asset pipeline');
|
|
35
37
|
if (tech.ai) suggestions.push('AI: RAG pipeline, vector DB, evals, prompt/version control');
|
|
38
|
+
if (tech.animation) suggestions.push('Animation: GSAP timelines, ScrollTrigger, framework cleanup, transform/opacity performance');
|
|
36
39
|
return suggestions;
|
|
37
40
|
}
|
|
38
41
|
|
|
39
42
|
function buildVerificationStrategy(tech, taskInfo) {
|
|
40
43
|
const checks = ['unit tests'];
|
|
41
44
|
if (tech.web || tech.mobile || tech.desktop) checks.push('UI smoke tests');
|
|
45
|
+
if (tech.animation) checks.push('animation/browser smoke test');
|
|
42
46
|
if (tech.backend) checks.push('API integration tests');
|
|
43
47
|
if (tech.data) checks.push('data quality tests');
|
|
44
48
|
if (tech.devops) checks.push('build + deploy dry-run checks');
|
|
@@ -53,6 +57,7 @@ export function selectWorkflow({ taskText = '', projectSignals = [], skillCatalo
|
|
|
53
57
|
|
|
54
58
|
const taskInfo = classifyTask(text);
|
|
55
59
|
const tech = detectTechnology(text, signals);
|
|
60
|
+
const hermesCore = detectHermesCoreSignals({ taskText, projectSignals });
|
|
56
61
|
|
|
57
62
|
const recommendedSkills = [];
|
|
58
63
|
const recommendedPlugins = [];
|
|
@@ -82,6 +87,14 @@ export function selectWorkflow({ taskText = '', projectSignals = [], skillCatalo
|
|
|
82
87
|
recommendedSkills.push('vercel-react-best-practices');
|
|
83
88
|
}
|
|
84
89
|
|
|
90
|
+
if (tech.animation) {
|
|
91
|
+
recommendedSkills.push('gsap', 'gsap-core', 'gsap-timeline', 'gsap-performance');
|
|
92
|
+
recommendedResources.push('gsap-skills');
|
|
93
|
+
if (tech.web) {
|
|
94
|
+
recommendedSkills.push('gsap-react', 'gsap-scrolltrigger');
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
85
98
|
if (tech.mobile) {
|
|
86
99
|
recommendedSkills.push('debug', 'test', 'performance', 'security');
|
|
87
100
|
}
|
|
@@ -104,6 +117,14 @@ export function selectWorkflow({ taskText = '', projectSignals = [], skillCatalo
|
|
|
104
117
|
recommendedResources.push('ecc');
|
|
105
118
|
}
|
|
106
119
|
|
|
120
|
+
if (shouldApplyHermesCore({ taskText, projectSignals })) {
|
|
121
|
+
recommendedResources.push('hermes-agent-core');
|
|
122
|
+
recommendedSkills.push('hermes-agent', 'subagent-driven-development', 'systematic-debugging');
|
|
123
|
+
if (hermesCore.skills) recommendedSkills.push('hermes-agent-skill-authoring');
|
|
124
|
+
if (hermesCore.mcp) recommendedSkills.push('native-mcp');
|
|
125
|
+
if (hermesCore.automation) recommendedSkills.push('plan', 'test-driven-development');
|
|
126
|
+
}
|
|
127
|
+
|
|
107
128
|
// When user mentions browser automation or interacting with websites, point at page-agent
|
|
108
129
|
if (hasAny(text, ['browser', 'automation', 'crawl', 'scrape', 'form fill', 'e2e', 'playwright', 'selenium', 'page agent'])) {
|
|
109
130
|
recommendedResources.push('page-agent');
|
|
@@ -143,6 +164,7 @@ export function selectWorkflow({ taskText = '', projectSignals = [], skillCatalo
|
|
|
143
164
|
profile,
|
|
144
165
|
depth,
|
|
145
166
|
detectedTechnologies: tech,
|
|
167
|
+
hermesCore,
|
|
146
168
|
technologySuggestions: buildTechnologySuggestions(tech),
|
|
147
169
|
verificationStrategy: buildVerificationStrategy(tech, taskInfo),
|
|
148
170
|
recommendedSkills: filteredSkills,
|
|
@@ -151,4 +173,3 @@ export function selectWorkflow({ taskText = '', projectSignals = [], skillCatalo
|
|
|
151
173
|
recommendedResources: uniq(recommendedResources),
|
|
152
174
|
};
|
|
153
175
|
}
|
|
154
|
-
|
package/src/cli/commands.js
CHANGED
|
@@ -906,6 +906,9 @@ EXECUTION CONTRACT:
|
|
|
906
906
|
case undefined:
|
|
907
907
|
case 'list':
|
|
908
908
|
console.log(`\n${colors.cyan}Permission Allowlist:${colors.reset}`);
|
|
909
|
+
console.log(` Full access: ${config.sandbox?.enabled === false ? 'on' : 'off'}`);
|
|
910
|
+
console.log(` Sandbox enabled: ${config.sandbox?.enabled !== false}`);
|
|
911
|
+
console.log(` Restrict workspace: ${config.sandbox?.restrictToWorkspace !== false}`);
|
|
909
912
|
console.log(` Tools: ${(config.permissions.allowlist.tools || []).join(', ') || 'none'}`);
|
|
910
913
|
console.log(` Commands: ${(config.permissions.allowlist.commands || []).join(', ') || 'none'}`);
|
|
911
914
|
console.log(` MCP Servers: ${(config.permissions.allowlist.mcpServers || []).join(', ') || 'none'}`);
|
|
@@ -934,8 +937,25 @@ EXECUTION CONTRACT:
|
|
|
934
937
|
console.log(`${colors.green}✓ promptByDefault = ${config.permissions.promptByDefault}${colors.reset}`);
|
|
935
938
|
break;
|
|
936
939
|
}
|
|
940
|
+
case 'full': {
|
|
941
|
+
const value = String(rest[0] || 'on').toLowerCase();
|
|
942
|
+
const enabled = !(value === 'off' || value === 'false' || value === '0' || value === 'no');
|
|
943
|
+
if (typeof this.config.setFullAccess === 'function') {
|
|
944
|
+
await this.config.setFullAccess(enabled);
|
|
945
|
+
} else {
|
|
946
|
+
config.sandbox = {
|
|
947
|
+
...(config.sandbox || {}),
|
|
948
|
+
enabled: !enabled,
|
|
949
|
+
restrictToWorkspace: !enabled,
|
|
950
|
+
};
|
|
951
|
+
config.permissions.promptByDefault = !enabled;
|
|
952
|
+
await this.config.save(config);
|
|
953
|
+
}
|
|
954
|
+
console.log(`${colors.green}Full access ${enabled ? 'enabled' : 'disabled'}${colors.reset}`);
|
|
955
|
+
break;
|
|
956
|
+
}
|
|
937
957
|
default:
|
|
938
|
-
console.log(`${colors.yellow}Usage: winter permissions <list|allow|prompt>${colors.reset}`);
|
|
958
|
+
console.log(`${colors.yellow}Usage: winter permissions <list|allow|prompt|full>${colors.reset}`);
|
|
939
959
|
}
|
|
940
960
|
}
|
|
941
961
|
|