winter-super-cli 2026.6.23 → 2026.6.26
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/README.md +19 -0
- package/bin/winter.js +23 -1
- package/extensions/vscode/src/extension.js +34 -7
- package/package.json +3 -2
- package/skill.md +4 -1
- package/src/agent/agent-definitions.js +4 -4
- package/src/ai/prompts/system-prompt.js +2 -0
- package/src/cli/commands.js +32 -1
- package/src/cli/config.js +4 -3
- package/src/cli/prompt-builder.js +32 -8
- package/src/cli/repl-commands.js +6 -0
- package/src/cli/repl.js +269 -13
- package/src/cli/slash-commands.js +2 -1
- package/src/mcp/client.js +8 -6
- package/src/mcp/ide-server.js +114 -2
- package/src/mcp/presets.js +114 -0
- package/src/rag/cli.js +195 -0
- package/src/rag/embeddings.js +183 -0
- package/src/rag/rag-engine.js +187 -0
- package/src/rag/retriever.js +112 -0
- package/src/rag/vector-store.js +225 -0
- package/src/tools/executor.js +103 -4
package/README.md
CHANGED
|
@@ -162,6 +162,25 @@ Winter reads config from the user profile directory. Typical settings include:
|
|
|
162
162
|
- MCP servers
|
|
163
163
|
- sandbox / allowlist options
|
|
164
164
|
|
|
165
|
+
### Chrome DevTools MCP
|
|
166
|
+
|
|
167
|
+
Winter has a built-in preset for ChromeDevTools/chrome-devtools-mcp:
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
winter mcp preset chrome-devtools --isolated
|
|
171
|
+
winter mcp tools chrome-devtools
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
In the REPL, use the same flow with slash commands:
|
|
175
|
+
|
|
176
|
+
```text
|
|
177
|
+
/mcp preset chrome-devtools --isolated
|
|
178
|
+
/mcp tools chrome-devtools
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
The preset registers the `chrome-devtools` MCP server, allowlists it, and gives Winter runtime hints to use its page navigation, click, fill, snapshot, screenshot, console, network, and performance tools for live browser debugging. Omit `--headless` when you want to watch Winter operate Chrome in a normal visible window.
|
|
182
|
+
It requires Node.js 22.12+ and a current Chrome installation, matching the upstream MCP package requirements.
|
|
183
|
+
|
|
165
184
|
### Minimal example
|
|
166
185
|
|
|
167
186
|
```json
|
package/bin/winter.js
CHANGED
|
@@ -13,6 +13,7 @@ import { SessionManager } from '../src/session/manager.js';
|
|
|
13
13
|
import { AIProviderManager } from '../src/ai/providers.js';
|
|
14
14
|
import { CommandParser } from '../src/cli/commands.js';
|
|
15
15
|
import { supportsUnicodeUi } from '../src/cli/terminal-ui.js';
|
|
16
|
+
import { IDEServer } from '../src/mcp/ide-server.js';
|
|
16
17
|
|
|
17
18
|
const pkg = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8'));
|
|
18
19
|
const version = pkg.version;
|
|
@@ -23,7 +24,7 @@ const COMMANDS = new Set([
|
|
|
23
24
|
'autopilot', 'plan',
|
|
24
25
|
'provider', 'providers', 'model', 'models', 'ecc', 'page-agent', 'pageagent',
|
|
25
26
|
'resources', 'htmlfx', 'memory-vault', 'doctor', 'context', 'scorecard',
|
|
26
|
-
'tui',
|
|
27
|
+
'tui', 'rag',
|
|
27
28
|
]);
|
|
28
29
|
|
|
29
30
|
function isInteractiveRequest(args) {
|
|
@@ -69,6 +70,7 @@ Commands:
|
|
|
69
70
|
winter context [task] Inspect model context for this project
|
|
70
71
|
winter scorecard Score Winter capability gates
|
|
71
72
|
winter doctor [full|tools] Diagnose context, provider, and tools
|
|
73
|
+
winter rag <action> RAG query/index/status/reset
|
|
72
74
|
winter provider [name] Show/switch provider
|
|
73
75
|
winter providers List providers
|
|
74
76
|
winter model [model] Show/set active provider model
|
|
@@ -89,6 +91,7 @@ Flags:
|
|
|
89
91
|
|
|
90
92
|
winter -h, --help Show help
|
|
91
93
|
winter -v, --version Show version
|
|
94
|
+
winter --mcp [--port n] Start VS Code/IDE MCP bridge
|
|
92
95
|
|
|
93
96
|
Version ${version}
|
|
94
97
|
`);
|
|
@@ -97,6 +100,25 @@ Version ${version}
|
|
|
97
100
|
async function main() {
|
|
98
101
|
const args = process.argv.slice(2);
|
|
99
102
|
|
|
103
|
+
if (args.includes('--mcp')) {
|
|
104
|
+
const portIndex = args.indexOf('--port');
|
|
105
|
+
const hostIndex = args.indexOf('--host');
|
|
106
|
+
const projectIndex = args.indexOf('--project');
|
|
107
|
+
const server = new IDEServer({
|
|
108
|
+
port: portIndex !== -1 && args[portIndex + 1] ? Number(args[portIndex + 1]) : undefined,
|
|
109
|
+
host: hostIndex !== -1 && args[hostIndex + 1] ? args[hostIndex + 1] : undefined,
|
|
110
|
+
projectPath: projectIndex !== -1 && args[projectIndex + 1] ? path.resolve(args[projectIndex + 1]) : process.cwd(),
|
|
111
|
+
});
|
|
112
|
+
await server.start();
|
|
113
|
+
const shutdown = async () => {
|
|
114
|
+
await server.stop();
|
|
115
|
+
process.exit(0);
|
|
116
|
+
};
|
|
117
|
+
process.on('SIGINT', shutdown);
|
|
118
|
+
process.on('SIGTERM', shutdown);
|
|
119
|
+
return new Promise(() => {});
|
|
120
|
+
}
|
|
121
|
+
|
|
100
122
|
if (args.includes('--help') || args.includes('-h')) {
|
|
101
123
|
printHelp();
|
|
102
124
|
return;
|
|
@@ -341,6 +341,7 @@ function sendMessage(message) {
|
|
|
341
341
|
}, 5000);
|
|
342
342
|
|
|
343
343
|
let responseData = '';
|
|
344
|
+
let settled = false;
|
|
344
345
|
|
|
345
346
|
client.connect(SERVER_PORT, SERVER_HOST, () => {
|
|
346
347
|
client.write(JSON.stringify(message) + '\n');
|
|
@@ -348,13 +349,31 @@ function sendMessage(message) {
|
|
|
348
349
|
|
|
349
350
|
client.on('data', (data) => {
|
|
350
351
|
responseData += data.toString();
|
|
351
|
-
|
|
352
|
-
|
|
352
|
+
const lines = responseData.split(/\r?\n/);
|
|
353
|
+
responseData = lines.pop() || '';
|
|
354
|
+
|
|
355
|
+
for (const line of lines) {
|
|
356
|
+
if (!line.trim()) continue;
|
|
357
|
+
let response;
|
|
358
|
+
try {
|
|
359
|
+
response = JSON.parse(line);
|
|
360
|
+
} catch {
|
|
361
|
+
continue;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
if (response.type === 'server:info') {
|
|
365
|
+
continue;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
settled = true;
|
|
353
369
|
clearTimeout(timeout);
|
|
354
370
|
client.destroy();
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
371
|
+
if (response.type === 'error') {
|
|
372
|
+
reject(new Error(response.message || 'Winter MCP server returned an error'));
|
|
373
|
+
} else {
|
|
374
|
+
resolve(response);
|
|
375
|
+
}
|
|
376
|
+
return;
|
|
358
377
|
}
|
|
359
378
|
});
|
|
360
379
|
|
|
@@ -366,9 +385,17 @@ function sendMessage(message) {
|
|
|
366
385
|
|
|
367
386
|
client.on('close', () => {
|
|
368
387
|
clearTimeout(timeout);
|
|
369
|
-
if (
|
|
388
|
+
if (settled) return;
|
|
389
|
+
if (responseData.trim()) {
|
|
370
390
|
try {
|
|
371
|
-
|
|
391
|
+
const response = JSON.parse(responseData);
|
|
392
|
+
if (response.type === 'error') {
|
|
393
|
+
reject(new Error(response.message || 'Winter MCP server returned an error'));
|
|
394
|
+
} else if (response.type === 'server:info') {
|
|
395
|
+
reject(new Error('Connection closed before Winter MCP server responded'));
|
|
396
|
+
} else {
|
|
397
|
+
resolve(response);
|
|
398
|
+
}
|
|
372
399
|
} catch {
|
|
373
400
|
reject(new Error('Invalid response from Winter MCP server'));
|
|
374
401
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "winter-super-cli",
|
|
3
|
-
"version": "2026.6.
|
|
3
|
+
"version": "2026.6.26",
|
|
4
4
|
"description": "❄️ AI-Powered Development CLI with Interactive REPL",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "bin/winter.js",
|
|
@@ -83,7 +83,8 @@
|
|
|
83
83
|
},
|
|
84
84
|
"dependencies": {
|
|
85
85
|
"cli-highlight": "^2.1.11",
|
|
86
|
-
"diff": "^9.0.0"
|
|
86
|
+
"diff": "^9.0.0",
|
|
87
|
+
"glob": "^13.0.6"
|
|
87
88
|
},
|
|
88
89
|
"optionalDependencies": {
|
|
89
90
|
"@colbymchenry/codegraph": "^0.7.12",
|
package/skill.md
CHANGED
|
@@ -16,10 +16,12 @@ File này định nghĩa cách Winter chọn và áp dụng skill. Không chỉ
|
|
|
16
16
|
- **security**: Protect secrets, validate inputs, avoid unsafe shell/file operations.
|
|
17
17
|
- **performance**: Measure or reason from the hot path before optimizing.
|
|
18
18
|
|
|
19
|
-
## Available Local Skills (
|
|
19
|
+
## Available Local Skills (16)
|
|
20
20
|
- codex-primary-runtime
|
|
21
21
|
- coding
|
|
22
|
+
- coding.md
|
|
22
23
|
- debug
|
|
24
|
+
- debug.md
|
|
23
25
|
- design
|
|
24
26
|
- learned
|
|
25
27
|
- performance
|
|
@@ -27,6 +29,7 @@ File này định nghĩa cách Winter chọn và áp dụng skill. Không chỉ
|
|
|
27
29
|
- security
|
|
28
30
|
- skill-creator
|
|
29
31
|
- test
|
|
32
|
+
- test.md
|
|
30
33
|
- vercel-react-best-practices
|
|
31
34
|
- vibefigma
|
|
32
35
|
- web-design-guidelines
|
|
@@ -3,13 +3,13 @@ import { pathToFileURL } from 'url';
|
|
|
3
3
|
import { promises as fs } from 'fs';
|
|
4
4
|
|
|
5
5
|
const DEFAULT_TOOL_SETS = {
|
|
6
|
-
general: ['Read', 'Write', 'Edit', 'Bash', 'Glob', 'Grep', 'BrowserDebug', 'WebFetch', 'WebSearch', 'Parallel', 'Agent'],
|
|
6
|
+
general: ['Read', 'Write', 'Edit', 'Bash', 'Glob', 'Grep', 'OpenBrowser', 'BrowserDebug', 'WebFetch', 'WebSearch', 'Parallel', 'Agent'],
|
|
7
7
|
plan: ['Read', 'Grep', 'Glob', 'WebFetch', 'WebSearch', 'Parallel'],
|
|
8
8
|
review: ['Read', 'Grep', 'Glob', 'Bash', 'WebFetch'],
|
|
9
|
-
debug: ['Read', 'Write', 'Edit', 'Bash', 'Grep', 'Glob', 'BrowserDebug', 'WebFetch', 'Parallel'],
|
|
10
|
-
design: ['Read', 'Write', 'Edit', 'Bash', 'Grep', 'Glob', 'BrowserDebug', 'WebFetch'],
|
|
9
|
+
debug: ['Read', 'Write', 'Edit', 'Bash', 'Grep', 'Glob', 'OpenBrowser', 'BrowserDebug', 'WebFetch', 'Parallel'],
|
|
10
|
+
design: ['Read', 'Write', 'Edit', 'Bash', 'Grep', 'Glob', 'OpenBrowser', 'BrowserDebug', 'WebFetch'],
|
|
11
11
|
research: ['Read', 'Grep', 'Glob', 'WebFetch', 'WebSearch', 'Parallel'],
|
|
12
|
-
swe: ['Read', 'Write', 'Edit', 'Bash', 'Grep', 'Glob', 'BrowserDebug', 'Parallel'],
|
|
12
|
+
swe: ['Read', 'Write', 'Edit', 'Bash', 'Grep', 'Glob', 'OpenBrowser', 'BrowserDebug', 'Parallel'],
|
|
13
13
|
};
|
|
14
14
|
|
|
15
15
|
const BUILTIN_AGENTS = [
|
|
@@ -100,7 +100,9 @@ function buildStandardSystemPrompt(options = {}) {
|
|
|
100
100
|
'Use tools when they materially improve correctness. Inspect before editing. Verify after changes.',
|
|
101
101
|
'Use maximum reasoning discipline for every model tier, including tiny, local, free, and routed models.',
|
|
102
102
|
'Never invent file paths, APIs, command output, or test results.',
|
|
103
|
+
'For visible browser launch requests such as "mở chrome" or "open Chrome", use OpenBrowser; do not use Bash, Get-Command, Start-Process, or shell launch commands.',
|
|
103
104
|
'For debug work, locate the first hard failure, patch the root cause, and verify with the closest test/build/browser smoke.',
|
|
105
|
+
'For live browser debugging and user-visible Chrome control, prefer MCP server chrome-devtools when configured; use its page, click, fill, snapshot, screenshot, console, network, and performance tools before falling back to headless browser automation.',
|
|
104
106
|
'For design/UI work, inspect the existing interface and design resources first; avoid generic placeholder layouts.',
|
|
105
107
|
'If the user attaches or pastes an image, analyze it as primary evidence.',
|
|
106
108
|
'',
|
package/src/cli/commands.js
CHANGED
|
@@ -10,6 +10,7 @@ import { DesignCommands } from '../design/commands.js';
|
|
|
10
10
|
import { SkillManager } from '../skills/manager.js';
|
|
11
11
|
import { PluginManager } from '../plugins/manager.js';
|
|
12
12
|
import { MCPClient } from '../mcp/client.js';
|
|
13
|
+
import { getMcpPreset, upsertMcpServer } from '../mcp/presets.js';
|
|
13
14
|
import { BenchmarkRunner } from '../ai/benchmark.js';
|
|
14
15
|
import { redactSecrets } from './secret-env.js';
|
|
15
16
|
import { formatRuntimeEnvironmentSummary, getRuntimeEnvironment } from './runtime-env.js';
|
|
@@ -20,6 +21,7 @@ import { HtmlFxManager } from '../integrations/htmlfx-manager.js';
|
|
|
20
21
|
import { selectWorkflow } from '../ai/workflow-selector.js';
|
|
21
22
|
import { getProfileBlueprint } from '../ai/profile-blueprints.js';
|
|
22
23
|
import { ToolExecutor } from '../tools/executor.js';
|
|
24
|
+
import { handleRagCommandFromParser } from '../rag/cli.js';
|
|
23
25
|
import { promises as fs } from 'fs';
|
|
24
26
|
import path from 'path';
|
|
25
27
|
import readline from 'node:readline/promises';
|
|
@@ -76,6 +78,7 @@ export class CommandParser {
|
|
|
76
78
|
resources: this.handleResources.bind(this),
|
|
77
79
|
htmlfx: this.handleHtmlFx.bind(this),
|
|
78
80
|
'memory-vault': this.handleMemoryVault.bind(this),
|
|
81
|
+
rag: this.handleRag.bind(this),
|
|
79
82
|
tui: this.handleTui.bind(this),
|
|
80
83
|
provider: this.handleProvider.bind(this),
|
|
81
84
|
providers: this.showProviders.bind(this),
|
|
@@ -142,6 +145,7 @@ export class CommandParser {
|
|
|
142
145
|
'/htmlfx': () => this.handleHtmlFx(args),
|
|
143
146
|
'/debug': () => this.handleDebug(args),
|
|
144
147
|
'/auto': () => this.handleDebug(args),
|
|
148
|
+
'/rag': () => this.handleRag(args),
|
|
145
149
|
'/autopilot': () => this.handleAutopilot(args),
|
|
146
150
|
'/exit': () => process.exit(0),
|
|
147
151
|
};
|
|
@@ -234,6 +238,10 @@ export class CommandParser {
|
|
|
234
238
|
})}\n`);
|
|
235
239
|
}
|
|
236
240
|
|
|
241
|
+
async handleRag(args = []) {
|
|
242
|
+
await handleRagCommandFromParser(this, args);
|
|
243
|
+
}
|
|
244
|
+
|
|
237
245
|
async searchResourceFiles(root, query, limit = 30) {
|
|
238
246
|
const matches = [];
|
|
239
247
|
const needle = String(query || '').toLowerCase();
|
|
@@ -806,6 +814,29 @@ EXECUTION CONTRACT:
|
|
|
806
814
|
console.log(`${colors.green}✓ Added MCP server: ${name}${colors.reset}`);
|
|
807
815
|
break;
|
|
808
816
|
}
|
|
817
|
+
case 'preset':
|
|
818
|
+
case 'install': {
|
|
819
|
+
const [presetName, ...presetOptions] = rest;
|
|
820
|
+
if (!presetName) {
|
|
821
|
+
console.log(`${colors.yellow}Usage: winter mcp preset <chrome-devtools> [--isolated] [--headless] [--browser-url <url>]${colors.reset}`);
|
|
822
|
+
break;
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
try {
|
|
826
|
+
const server = getMcpPreset(presetName, presetOptions);
|
|
827
|
+
upsertMcpServer(config, server);
|
|
828
|
+
await this.config.save(config);
|
|
829
|
+
console.log(`${colors.green}OK Installed MCP preset: ${server.name}${colors.reset}`);
|
|
830
|
+
console.log(` ${colors.dim}${server.command} ${server.args.join(' ')}${colors.reset}`);
|
|
831
|
+
if (!server.args.includes('--headless')) {
|
|
832
|
+
console.log(` ${colors.dim}Visible Chrome mode: enabled. Use --headless only for background browser runs.${colors.reset}`);
|
|
833
|
+
}
|
|
834
|
+
console.log(` ${colors.dim}Inspect tools with: winter mcp tools ${server.name}${colors.reset}`);
|
|
835
|
+
} catch (error) {
|
|
836
|
+
console.log(`${colors.red}${error.message}${colors.reset}`);
|
|
837
|
+
}
|
|
838
|
+
break;
|
|
839
|
+
}
|
|
809
840
|
case 'remove': {
|
|
810
841
|
const name = rest[0];
|
|
811
842
|
if (!name) {
|
|
@@ -861,7 +892,7 @@ EXECUTION CONTRACT:
|
|
|
861
892
|
break;
|
|
862
893
|
}
|
|
863
894
|
default:
|
|
864
|
-
console.log(`${colors.yellow}Usage: winter mcp <list|add|remove|allow|tools>${colors.reset}`);
|
|
895
|
+
console.log(`${colors.yellow}Usage: winter mcp <list|add|preset|install|remove|allow|tools>${colors.reset}`);
|
|
865
896
|
}
|
|
866
897
|
}
|
|
867
898
|
|
package/src/cli/config.js
CHANGED
|
@@ -7,6 +7,7 @@ import { promises as fs } from 'fs';
|
|
|
7
7
|
import path from 'path';
|
|
8
8
|
import { homedir } from 'os';
|
|
9
9
|
import { loadEnvFile, stripInlineSecrets } from './secret-env.js';
|
|
10
|
+
import { CHROME_DEVTOOLS_MCP_NAME, createChromeDevtoolsMcpServer } from '../mcp/presets.js';
|
|
10
11
|
|
|
11
12
|
export class ConfigLoader {
|
|
12
13
|
constructor() {
|
|
@@ -61,13 +62,13 @@ export class ConfigLoader {
|
|
|
61
62
|
permissions: {
|
|
62
63
|
promptByDefault: true,
|
|
63
64
|
allowlist: {
|
|
64
|
-
tools: ['Read', 'Glob', 'Grep', 'LSP', 'TaskCreate', 'TaskUpdate', 'TaskList', 'WebFetch', 'WebSearch', 'Parallel'],
|
|
65
|
+
tools: ['Read', 'Glob', 'Grep', 'LSP', 'TaskCreate', 'TaskUpdate', 'TaskList', 'WebFetch', 'WebSearch', 'Parallel', 'MCP'],
|
|
65
66
|
commands: [],
|
|
66
|
-
mcpServers: [],
|
|
67
|
+
mcpServers: [CHROME_DEVTOOLS_MCP_NAME],
|
|
67
68
|
},
|
|
68
69
|
},
|
|
69
70
|
mcp: {
|
|
70
|
-
servers: [],
|
|
71
|
+
servers: [createChromeDevtoolsMcpServer(['--isolated'])],
|
|
71
72
|
},
|
|
72
73
|
routing: {
|
|
73
74
|
strategy: 'heuristic',
|
|
@@ -117,12 +117,14 @@ export class PromptBuilder {
|
|
|
117
117
|
`Prefer Read/Grep/Glob before editing. Use Write/Edit for file changes.`,
|
|
118
118
|
`CRITICAL: When the user asks you to fix/create/edit/run/modify anything, you MUST call tools (Read, Write, Edit, Bash, etc.) to actually do it. NEVER just write code in a markdown code block and claim it is done. Winter will detect and block fake completions. If you say "đã sửa/đã tạo/done/fixed" without a tool call, your response will be rejected.`,
|
|
119
119
|
`Tool call compatibility: if native tool calls are unavailable, output exactly one of these forms and no prose: <invoke name="Read"><parameter name="path">README.md</parameter></invoke> OR {"tool":"Read","arguments":{"path":"README.md"}} OR CALL_TOOL Read {"path":"README.md"}.`,
|
|
120
|
-
`
|
|
120
|
+
`Open browser requests: if the user asks to "mở chrome", "open Chrome", or open a URL in a visible browser, use OpenBrowser. Do NOT use Bash, Get-Command, Start-Process, cmd start, or shell app launch commands for this.`,
|
|
121
|
+
`Browser capability: You CAN browse URLs! Use WebFetch only for static page text extraction. For live Chrome debugging and visible browser control, prefer MCP server "chrome-devtools" when configured: use MCP tool "new_page" or "navigate_page", then "take_snapshot", "click", "fill"/"fill_form", "take_screenshot", "evaluate_script", "list_console_messages", "list_network_requests", or performance trace tools. BrowserDebug is headless fallback only when chrome-devtools MCP is unavailable or the user explicitly asks for headless smoke/debug.`,
|
|
122
|
+
`Browser interaction rule: if the user asks to click, press, fill, select, submit, open a web app path, or inspect page-by-page data, WebFetch is not enough and BrowserDebug is not user-visible. Use chrome-devtools MCP so the user can watch the normal Chrome client. Never claim "đã bấm/đã điền/đã mở/đã kiểm tra" from prose alone.`,
|
|
121
123
|
`When a task touches coding, agents, UI, brand, or design, inspect the relevant required local resource in depth before deciding.`,
|
|
122
124
|
`If the user asks you to modify, run, inspect, check, publish, commit, or otherwise act on the project, you MUST use tools. Do not claim completion without a tool result from this turn.`,
|
|
123
125
|
``,
|
|
124
126
|
`## Debug Excellence`,
|
|
125
|
-
`For bugs, crashes, test failures, or "not working": identify the first hard failure, reproduce or inspect logs, trace the exact runtime path, patch the smallest root cause, and verify with the closest command. For frontend/runtime UI issues,
|
|
127
|
+
`For bugs, crashes, test failures, or "not working": identify the first hard failure, reproduce or inspect logs, trace the exact runtime path, patch the smallest root cause, and verify with the closest command. For frontend/runtime UI issues with a URL/dev server, prefer chrome-devtools MCP in visible Chrome; use BrowserDebug only as a headless fallback.`,
|
|
126
128
|
``,
|
|
127
129
|
`## Design Excellence`,
|
|
128
130
|
`For UI/design work: inspect existing components/styles and any design resources first. Build a polished, responsive, domain-appropriate interface with complete states and clear interactions. Avoid generic placeholders, fake controls, one-note palettes, and unverified visual claims.`,
|
|
@@ -193,7 +195,7 @@ export class PromptBuilder {
|
|
|
193
195
|
review: 'You are a Winter review subagent. Critique the request or implementation with specific issues, edge cases, and concrete improvements.',
|
|
194
196
|
debug: 'You are a Winter debugging subagent. Reproduce or inspect the exact failing path, isolate the first hard blocker, patch the smallest root cause, and verify with the closest test/build/browser smoke.',
|
|
195
197
|
research: 'You are a Winter research subagent. Gather the important facts, compare options, and summarize only what matters.',
|
|
196
|
-
browser: `You are a Winter browser subagent. Bạn CÓ QUYỀN sử dụng
|
|
198
|
+
browser: `You are a Winter browser subagent. Bạn CÓ QUYỀN sử dụng chrome-devtools MCP để thao tác Chrome visible cho user xem: mở URL, click, fill form, snapshot, screenshot, đọc console/network. Dùng BrowserDebug chỉ khi cần headless fallback.`,
|
|
197
199
|
};
|
|
198
200
|
|
|
199
201
|
const rolePrompt = rolePrompts[role] || 'You are a Winter coding subagent. Solve the task directly, use tools when needed, and return a concise result.';
|
|
@@ -208,14 +210,14 @@ export class PromptBuilder {
|
|
|
208
210
|
'3. [DEBUG EXCELLENCE]: Reproduce or inspect the failing path first, isolate the first hard blocker, patch root cause, and verify with the closest test/build/browser smoke.',
|
|
209
211
|
'4. [DESIGN EXCELLENCE]: Use rich aesthetics. Default to modern UI frameworks if applicable. Never output plain, ugly HTML/CSS. Ensure responsive, premium feel with micro-animations.',
|
|
210
212
|
'5. [CODE QUALITY]: Write clean, modular, SOLID code. Check for syntax errors carefully. Do not generate incomplete code blocks.',
|
|
211
|
-
'6. [NO HALLUCINATION]: If you don\'t know, use tools (Grep/Read/Web/BrowserDebug) to find out. Do not guess file paths or APIs.',
|
|
213
|
+
'6. [NO HALLUCINATION]: If you don\'t know, use tools (Grep/Read/Web/chrome-devtools MCP/BrowserDebug) to find out. Do not guess file paths or APIs.',
|
|
212
214
|
'7. [TOOL EXECUTION FIRST]: You DO have file tools. Use Write to create/overwrite files and Edit to patch files. Never say there is no write tool.',
|
|
213
215
|
'8. [IMAGE INPUTS]: If an image is attached or pasted, analyze it directly and use it as evidence for UI/debug/design decisions.',
|
|
214
216
|
'',
|
|
215
217
|
rolePrompt,
|
|
216
218
|
'',
|
|
217
219
|
'## Tool Rules',
|
|
218
|
-
'- Canonical tools: Read, Write, Edit, Bash, Glob, Grep, TaskCreate, TaskUpdate, TaskList, BrowserDebug, WebFetch, WebSearch.',
|
|
220
|
+
'- Canonical tools: Read, Write, Edit, Bash, Glob, Grep, TaskCreate, TaskUpdate, TaskList, OpenBrowser, BrowserDebug, WebFetch, WebSearch, MCP.',
|
|
219
221
|
'- If native tool calls are unavailable, output exactly one fallback tool call and no prose: <invoke name="Read"><parameter name="path">README.md</parameter></invoke> OR {"tool":"Read","arguments":{"path":"README.md"}} OR CALL_TOOL Read {"path":"README.md"}.',
|
|
220
222
|
'- Treat skills, memories, bundled resources, local project rules, and the tool list as operational context. Use them proactively when relevant.',
|
|
221
223
|
`- Runtime environment:\n${runtimeSummary}`,
|
|
@@ -234,11 +236,33 @@ export class PromptBuilder {
|
|
|
234
236
|
|
|
235
237
|
/** @private */
|
|
236
238
|
_formatMemories(memories, options = {}) {
|
|
237
|
-
|
|
238
|
-
|
|
239
|
+
const priorityPatterns = [
|
|
240
|
+
/^\[Recent Work Ledger\]/i,
|
|
241
|
+
/^\[Conversation Summary\]/i,
|
|
242
|
+
/^\[Project Anchor\]/i,
|
|
243
|
+
];
|
|
244
|
+
const priority = [];
|
|
245
|
+
const regular = [];
|
|
246
|
+
|
|
247
|
+
for (const memory of memories) {
|
|
248
|
+
const text = typeof memory === 'string' ? memory : memory?.text || '';
|
|
249
|
+
if (priorityPatterns.some(pattern => pattern.test(text))) {
|
|
250
|
+
priority.push(memory);
|
|
251
|
+
} else {
|
|
252
|
+
regular.push(memory);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
const ordered = [
|
|
257
|
+
...regular.slice(-Math.max(0, (options.limit || 10) - Math.min(priority.length, 4))),
|
|
258
|
+
...priority.slice(-4),
|
|
259
|
+
];
|
|
260
|
+
|
|
261
|
+
return `\n## Memories (Important Context)\n${this._summarizePrompts(ordered, {
|
|
262
|
+
limit: options.limit || 10,
|
|
239
263
|
maxEntryChars: 220,
|
|
240
264
|
maxTotalChars: options.maxTotalChars || 1200,
|
|
241
|
-
mapper: memory => memory
|
|
265
|
+
mapper: memory => typeof memory === 'string' ? memory : memory?.text,
|
|
242
266
|
})}`;
|
|
243
267
|
}
|
|
244
268
|
|
package/src/cli/repl-commands.js
CHANGED
|
@@ -4,6 +4,7 @@ import { colors } from './snowflake-logo.js';
|
|
|
4
4
|
import { SLASH_COMMANDS } from './slash-commands.js';
|
|
5
5
|
|
|
6
6
|
import { DesignCommands } from '../design/commands.js';
|
|
7
|
+
import { handleRagCommandFromRepl } from '../rag/cli.js';
|
|
7
8
|
|
|
8
9
|
function getPageAgentRoot(repl) {
|
|
9
10
|
return repl.contextLoader?.getResourcePaths?.()?.pageAgent || path.join(repl.projectPath, 'resources', 'local', 'page-agent');
|
|
@@ -672,6 +673,11 @@ export async function handleSlashCommand(repl, input) {
|
|
|
672
673
|
case '/pageagent':
|
|
673
674
|
await handlePageAgentCommand(repl, args);
|
|
674
675
|
break;
|
|
676
|
+
|
|
677
|
+
// RAG
|
|
678
|
+
case '/rag':
|
|
679
|
+
await handleRagCommandFromRepl(repl, args);
|
|
680
|
+
break;
|
|
675
681
|
case '/image':
|
|
676
682
|
const imagePath = args[0];
|
|
677
683
|
const imageQuestion = args.slice(1).join(' ');
|