winter-super-cli 2026.6.8 → 2026.6.9
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/package.json +1 -1
- package/src/agent/runtime.js +4 -2
- package/src/ai/benchmark.js +5 -5
- package/src/ai/model-capabilities.js +1 -1
- package/src/ai/orchestrator.js +6 -6
- package/src/ai/providers.js +20 -8
- package/src/cache/system.js +1 -1
- package/src/cli/at-context.js +1 -1
- package/src/cli/commands.js +1 -1
- package/src/cli/composer.js +2 -2
- package/src/cli/config.js +1 -1
- package/src/cli/diff-view.js +2 -2
- package/src/cli/ecc.js +2 -2
- package/src/cli/input-controller.js +6 -0
- package/src/cli/repl-commands.js +44 -4
- package/src/cli/repl.js +16 -0
- package/src/cli/slash-commands.js +1 -0
- package/src/cli/spinner.js +7 -1
- package/src/cli/tui.js +3 -1
- package/src/codebase-index/indexer.js +1 -1
- package/src/codebase-index/search.js +1 -1
- package/src/codebase-index/watcher.js +1 -1
- package/src/design/commands.js +2 -2
- package/src/mcp/inline-complete.js +6 -6
- package/src/plugins/manager.js +5 -5
- package/src/session/manager.js +1 -1
- package/src/skills/manager.js +8 -8
- package/src/tools/agent.js +1 -1
- package/src/tools/executor.js +1 -1
- package/src/tools/insert-text.js +1 -1
- package/src/tools/interactive.js +1 -1
- package/src/tools/notebook.js +1 -1
- package/src/tools/scheduler.js +1 -1
- package/src/tools/str-replace-all.js +1 -1
- package/src/tools/todo.js +1 -1
- package/src/tools/web-archive.js +1 -1
package/package.json
CHANGED
package/src/agent/runtime.js
CHANGED
|
@@ -140,7 +140,7 @@ export class AgentRuntime {
|
|
|
140
140
|
const enrichedArgs = argParseError && !canUseRecoveredArgs ? {} : repl.enrichToolArgs(canonicalToolName, normalizedArgs, messages);
|
|
141
141
|
|
|
142
142
|
const icon = repl.useUnicodeUi
|
|
143
|
-
? (canonicalToolName === 'Bash' ? '
|
|
143
|
+
? (canonicalToolName === 'Bash' ? '$' : canonicalToolName === 'Read' ? '≡' : canonicalToolName === 'Write' ? '±' : canonicalToolName === 'Edit' ? '$' : canonicalToolName === 'Grep' ? '⌕' : canonicalToolName === 'Glob' ? '►' : '▶')
|
|
144
144
|
: `[${canonicalToolName}]`;
|
|
145
145
|
|
|
146
146
|
let proceed = true;
|
|
@@ -200,7 +200,9 @@ export class AgentRuntime {
|
|
|
200
200
|
}));
|
|
201
201
|
}
|
|
202
202
|
}
|
|
203
|
-
|
|
203
|
+
if (toolSummaries.length > 0) {
|
|
204
|
+
console.log(`\n${colors.dim}💡 Tip: Gõ /tool để xem lại toàn bộ dữ liệu (data) của các tool calls vừa chạy.${colors.reset}\n`);
|
|
205
|
+
}
|
|
204
206
|
}
|
|
205
207
|
|
|
206
208
|
if (usedTools && !finalContent) {
|
package/src/ai/benchmark.js
CHANGED
|
@@ -275,17 +275,17 @@ export class BenchmarkRunner {
|
|
|
275
275
|
|
|
276
276
|
const lines = [];
|
|
277
277
|
lines.push(`\n${colors.cyan}${'═'.repeat(60)}${colors.reset}`);
|
|
278
|
-
lines.push(`${colors.bright}${colors.cyan}
|
|
278
|
+
lines.push(`${colors.bright}${colors.cyan} ◆ WINTER MODEL BENCHMARK${colors.reset}`);
|
|
279
279
|
lines.push(`${colors.cyan}${'═'.repeat(60)}${colors.reset}`);
|
|
280
280
|
lines.push(` ${colors.dim}${benchmarkResult.timestamp}${colors.reset}`);
|
|
281
281
|
lines.push(` ${colors.dim}Total time: ${(benchmarkResult.totalElapsed / 1000).toFixed(1)}s${colors.reset}`);
|
|
282
282
|
lines.push('');
|
|
283
283
|
|
|
284
284
|
// Ranking
|
|
285
|
-
lines.push(`${colors.bright}
|
|
285
|
+
lines.push(`${colors.bright}★ RANKING${colors.reset}`);
|
|
286
286
|
lines.push(`${'─'.repeat(40)}`);
|
|
287
287
|
benchmarkResult.ranking.forEach((r, i) => {
|
|
288
|
-
const medal = i === 0 ? '
|
|
288
|
+
const medal = i === 0 ? '1.' : i === 1 ? '2.' : i === 2 ? '3.' : ` ${i + 1}.`;
|
|
289
289
|
const bar = this._scoreBar(r.score, 20);
|
|
290
290
|
lines.push(` ${medal} ${colors.bright}${r.name}${colors.reset} ${bar} ${r.score}%`);
|
|
291
291
|
lines.push(` ${colors.dim}Model: ${r.model} | Time: ${(r.elapsed / 1000).toFixed(1)}s${colors.reset}`);
|
|
@@ -295,7 +295,7 @@ export class BenchmarkRunner {
|
|
|
295
295
|
// Detail per provider
|
|
296
296
|
for (const [name, data] of Object.entries(benchmarkResult.providers)) {
|
|
297
297
|
lines.push(`${colors.bright}${'─'.repeat(50)}${colors.reset}`);
|
|
298
|
-
lines.push(`${colors.bright}
|
|
298
|
+
lines.push(`${colors.bright}≡ ${name}${colors.reset} ${colors.dim}(${data.model})${colors.reset}`);
|
|
299
299
|
lines.push(`${'─'.repeat(50)}`);
|
|
300
300
|
|
|
301
301
|
const categories = {};
|
|
@@ -316,7 +316,7 @@ export class BenchmarkRunner {
|
|
|
316
316
|
|
|
317
317
|
// Per-item breakdown
|
|
318
318
|
for (const r of data.results) {
|
|
319
|
-
const icon = r.score >= 0.8 ? '✅' : r.score >= 0.5 ? '
|
|
319
|
+
const icon = r.score >= 0.8 ? '✅' : r.score >= 0.5 ? '○' : r.score >= 0.2 ? '●' : '❌';
|
|
320
320
|
const label = r.type === 'question' ? r.id : r.title;
|
|
321
321
|
lines.push(` ${icon} ${colors.dim}${label}:${colors.reset} ${Math.round(r.score * 100)}% (${(r.elapsed / 1000).toFixed(1)}s)`);
|
|
322
322
|
// Show preview of answer
|
package/src/ai/orchestrator.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* ❄ MULTI-MODEL ORCHESTRATOR ❄
|
|
3
3
|
* Run multiple AI models in parallel, compare results, vote, and merge.
|
|
4
4
|
*/
|
|
5
5
|
|
|
@@ -69,7 +69,7 @@ Respond with the NUMBER of the best solution only, no explanation.
|
|
|
69
69
|
{ role: 'user', content: prompt },
|
|
70
70
|
];
|
|
71
71
|
|
|
72
|
-
console.log(`\n${colors.cyan}
|
|
72
|
+
console.log(`\n${colors.cyan}◆ Ensemble: running ${providers.length} providers in parallel...${colors.reset}`);
|
|
73
73
|
|
|
74
74
|
const results = await Promise.allSettled(
|
|
75
75
|
providers.map(async ([name, provider]) => {
|
|
@@ -160,7 +160,7 @@ Respond with the NUMBER of the best solution only, no explanation.
|
|
|
160
160
|
.join('\n\n---\n\n');
|
|
161
161
|
const votePrompt = template.replace('{solutions}', solutionBlocks);
|
|
162
162
|
|
|
163
|
-
console.log(`\n${colors.cyan}
|
|
163
|
+
console.log(`\n${colors.cyan}✓ Voting: comparing ${entries.length} solutions...${colors.reset}`);
|
|
164
164
|
|
|
165
165
|
// Choose judge — prefer best available model
|
|
166
166
|
const judgeProvider = options.judge || this._pickBestJudge(entries.map(([n]) => n));
|
|
@@ -185,7 +185,7 @@ Respond with the NUMBER of the best solution only, no explanation.
|
|
|
185
185
|
}
|
|
186
186
|
|
|
187
187
|
const [winnerName] = entries[winnerIndex];
|
|
188
|
-
console.log(` ${colors.green}
|
|
188
|
+
console.log(` ${colors.green}★ Winner: ${winnerName}${colors.reset}`);
|
|
189
189
|
|
|
190
190
|
return {
|
|
191
191
|
...ensembleResults,
|
|
@@ -202,7 +202,7 @@ Respond with the NUMBER of the best solution only, no explanation.
|
|
|
202
202
|
*/
|
|
203
203
|
async orchestrate(task, options = {}) {
|
|
204
204
|
const startTime = measureTime();
|
|
205
|
-
console.log(`\n${colors.cyan}
|
|
205
|
+
console.log(`\n${colors.cyan}» Pipeline orchestration starting...${colors.reset}`);
|
|
206
206
|
|
|
207
207
|
// Step 1: Classify task
|
|
208
208
|
const taskInfo = this._classifyTask(task);
|
|
@@ -293,7 +293,7 @@ Respond with the NUMBER of the best solution only, no explanation.
|
|
|
293
293
|
const requiredTier = complexity === 'deep' || complexity === 'complex'
|
|
294
294
|
? 'large' : complexity === 'moderate' ? 'medium' : 'small';
|
|
295
295
|
|
|
296
|
-
console.log(`\n${colors.cyan}
|
|
296
|
+
console.log(`\n${colors.cyan}◆ Smart route: required tier=${requiredTier}, task=${complexity}${colors.reset}`);
|
|
297
297
|
|
|
298
298
|
const messages = [
|
|
299
299
|
{ role: 'system', content: options.system || this.ai.getSystemPrompt() },
|
package/src/ai/providers.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* ❄ WINTER AI PROVIDER ❄
|
|
3
3
|
* Full Claude Code / Codex compatible AI integration
|
|
4
4
|
*/
|
|
5
5
|
|
|
@@ -25,7 +25,7 @@ const RESERVED_CONFIG_SECTIONS = new Set([
|
|
|
25
25
|
'ui',
|
|
26
26
|
]);
|
|
27
27
|
|
|
28
|
-
const DEFAULT_REQUEST_TIMEOUT_MS =
|
|
28
|
+
const DEFAULT_REQUEST_TIMEOUT_MS = 600000;
|
|
29
29
|
|
|
30
30
|
function isAuthError(error) {
|
|
31
31
|
const msg = String(error?.message || error || '');
|
|
@@ -47,6 +47,8 @@ function getRequestTimeoutMs(options = {}) {
|
|
|
47
47
|
function createTimeoutSignal(timeoutMs, externalSignal = null) {
|
|
48
48
|
const controller = new AbortController();
|
|
49
49
|
let timedOut = false;
|
|
50
|
+
let timer;
|
|
51
|
+
|
|
50
52
|
const onAbort = () => {
|
|
51
53
|
controller.abort(externalSignal?.reason || new DOMException('The operation was aborted.', 'AbortError'));
|
|
52
54
|
};
|
|
@@ -55,16 +57,24 @@ function createTimeoutSignal(timeoutMs, externalSignal = null) {
|
|
|
55
57
|
} else if (externalSignal) {
|
|
56
58
|
externalSignal.addEventListener('abort', onAbort, { once: true });
|
|
57
59
|
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
60
|
+
|
|
61
|
+
const startTimer = () => {
|
|
62
|
+
if (timer) clearTimeout(timer);
|
|
63
|
+
timer = setTimeout(() => {
|
|
64
|
+
timedOut = true;
|
|
65
|
+
controller.abort(new Error(`Winter request timed out after ${timeoutMs}ms`));
|
|
66
|
+
}, timeoutMs);
|
|
67
|
+
if (typeof timer.unref === 'function') timer.unref();
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
startTimer();
|
|
71
|
+
|
|
63
72
|
return {
|
|
64
73
|
signal: controller.signal,
|
|
65
74
|
timedOut: () => timedOut,
|
|
75
|
+
resetTimer: startTimer,
|
|
66
76
|
cleanup: () => {
|
|
67
|
-
clearTimeout(timer);
|
|
77
|
+
if (timer) clearTimeout(timer);
|
|
68
78
|
if (externalSignal) externalSignal.removeEventListener('abort', onAbort);
|
|
69
79
|
},
|
|
70
80
|
};
|
|
@@ -606,6 +616,8 @@ export class AIProviderManager {
|
|
|
606
616
|
let buffer = '';
|
|
607
617
|
|
|
608
618
|
for await (const chunk of response.body) {
|
|
619
|
+
if (timeout.resetTimer) timeout.resetTimer();
|
|
620
|
+
|
|
609
621
|
buffer += decoder.decode(chunk, { stream: true });
|
|
610
622
|
const lines = buffer.split(/\r?\n/);
|
|
611
623
|
buffer = lines.pop() || '';
|
package/src/cache/system.js
CHANGED
package/src/cli/at-context.js
CHANGED
package/src/cli/commands.js
CHANGED
package/src/cli/composer.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* ❄ COMPOSER MODE ❄
|
|
3
3
|
* Multi-file editing orchestration with batch apply/reject.
|
|
4
4
|
* Inspired by Cursor Composer.
|
|
5
5
|
*
|
|
@@ -78,7 +78,7 @@ export class Composer {
|
|
|
78
78
|
});
|
|
79
79
|
|
|
80
80
|
console.log(`\n${renderBox({
|
|
81
|
-
title: `
|
|
81
|
+
title: ` ≡ Composer: ${this.pendingChanges.length} file(s) `,
|
|
82
82
|
width,
|
|
83
83
|
borderColor: colors.magenta,
|
|
84
84
|
titleColor: colors.bright,
|
package/src/cli/config.js
CHANGED
package/src/cli/diff-view.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* ❄ DIFF VIEW — APPLY/REJECT UI ❄
|
|
3
3
|
* Provides diff preview and interactive accept/reject/edit workflow.
|
|
4
4
|
* Inspired by Cursor's apply/reject UI.
|
|
5
5
|
*/
|
|
@@ -297,7 +297,7 @@ export class DiffView {
|
|
|
297
297
|
` ${colors.red}[r]${colors.reset} Reject — Discard these changes\n` +
|
|
298
298
|
` ${colors.yellow}[m]${colors.reset} Manual — Open file in $EDITOR to manually resolve\n` +
|
|
299
299
|
` ${colors.dim}[s]${colors.reset} Skip — Skip for now\n` +
|
|
300
|
-
`${colors.yellow}
|
|
300
|
+
`${colors.yellow}→ Choose [a/r/m/s]: ${colors.reset}`,
|
|
301
301
|
onAnswer
|
|
302
302
|
);
|
|
303
303
|
|
package/src/cli/ecc.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* ❄ ECC Integration ❄
|
|
3
3
|
* Everything Claude Code — agent harness performance optimization system
|
|
4
4
|
* Browsing, searching, syncing ECC resources inside Winter
|
|
5
5
|
*/
|
|
@@ -246,7 +246,7 @@ export class ECCManager {
|
|
|
246
246
|
for (const section of sections) {
|
|
247
247
|
const entries = await this._listDir(section.path);
|
|
248
248
|
const count = entries ? entries.length : 0;
|
|
249
|
-
const icon = entries ? (count > 0 ? '
|
|
249
|
+
const icon = entries ? (count > 0 ? '►' : '►') : '⛔';
|
|
250
250
|
console.log(` ${icon} ${colors.green}${section.name}${colors.reset} ${colors.dim}(${count} items)${colors.reset}`);
|
|
251
251
|
console.log(` ${colors.dim}${section.desc}${colors.reset}`);
|
|
252
252
|
}
|
|
@@ -86,6 +86,12 @@ export class WinterInputController {
|
|
|
86
86
|
void this.handleDirectClipboardPaste();
|
|
87
87
|
return;
|
|
88
88
|
}
|
|
89
|
+
|
|
90
|
+
if (key.name === 'return' && (key.shift || key.meta)) {
|
|
91
|
+
repl.rl.write('\\\n');
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
|
|
89
95
|
if (key.ctrl || key.meta) return;
|
|
90
96
|
|
|
91
97
|
if (typeof str === 'string' && str.length > 1) {
|
package/src/cli/repl-commands.js
CHANGED
|
@@ -103,7 +103,7 @@ export async function handleSlashCommand(repl, input) {
|
|
|
103
103
|
console.log(`\n${colors.cyan}ECC ${result.section}:${colors.reset} ${result.description}`);
|
|
104
104
|
if (result.entries) {
|
|
105
105
|
result.entries.forEach(e => {
|
|
106
|
-
const icon = e.isDirectory ? '
|
|
106
|
+
const icon = e.isDirectory ? '►' : '📄';
|
|
107
107
|
console.log(` ${icon} ${e.name}`);
|
|
108
108
|
});
|
|
109
109
|
}
|
|
@@ -120,7 +120,7 @@ export async function handleSlashCommand(repl, input) {
|
|
|
120
120
|
console.log(` ${colors.dim}No results${colors.reset}`);
|
|
121
121
|
} else {
|
|
122
122
|
searchResult.matches.forEach(m => {
|
|
123
|
-
const icon = m.isDirectory ? '
|
|
123
|
+
const icon = m.isDirectory ? '►' : '📄';
|
|
124
124
|
console.log(` ${icon} [${m.section}] ${m.name}`);
|
|
125
125
|
});
|
|
126
126
|
}
|
|
@@ -174,7 +174,7 @@ export async function handleSlashCommand(repl, input) {
|
|
|
174
174
|
console.log(`\n${colors.cyan}=== Vote Results ===${colors.reset}`);
|
|
175
175
|
if (result.winner) {
|
|
176
176
|
const winner = result.results[result.winner];
|
|
177
|
-
console.log(`\n${colors.green}
|
|
177
|
+
console.log(`\n${colors.green}★ Winner: ${result.winner} (${winner.model})${colors.reset}`);
|
|
178
178
|
console.log(`${colors.dim}${'─'.repeat(50)}${colors.reset}`);
|
|
179
179
|
console.log(winner.content.slice(0, 2000));
|
|
180
180
|
if (winner.content.length > 2000) console.log(`${colors.dim}... (${winner.content.length - 2000} more chars)${colors.reset}`);
|
|
@@ -219,7 +219,7 @@ export async function handleSlashCommand(repl, input) {
|
|
|
219
219
|
}
|
|
220
220
|
{
|
|
221
221
|
const url = args[0].replace(/^['"]|['"]$/g, '');
|
|
222
|
-
console.log(`${colors.cyan}
|
|
222
|
+
console.log(`${colors.cyan}@ Đang mở: ${url}${colors.reset}`);
|
|
223
223
|
try {
|
|
224
224
|
// Thử WebFetch trước (nhanh, lấy text)
|
|
225
225
|
const result = await repl.tools.execute('WebFetch', { url });
|
|
@@ -289,6 +289,46 @@ export async function handleSlashCommand(repl, input) {
|
|
|
289
289
|
case '/history':
|
|
290
290
|
repl.showReplay(args[0] ? parseInt(args[0], 10) : 20);
|
|
291
291
|
return;
|
|
292
|
+
case '/tool':
|
|
293
|
+
const toolCalls = [];
|
|
294
|
+
const history = repl.session.getHistory(30);
|
|
295
|
+
let idxCounter = 1;
|
|
296
|
+
for (const msg of history) {
|
|
297
|
+
if (msg.tool_calls && Array.isArray(msg.tool_calls)) {
|
|
298
|
+
for (const tc of msg.tool_calls) {
|
|
299
|
+
toolCalls.push({ index: idxCounter++, call: tc });
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
if (args.length === 0) {
|
|
304
|
+
if (toolCalls.length === 0) {
|
|
305
|
+
console.log(`${colors.dim}No recent tool calls found.${colors.reset}`);
|
|
306
|
+
} else {
|
|
307
|
+
console.log(`${colors.cyan}Recent Tool Calls:${colors.reset}`);
|
|
308
|
+
for (const tc of toolCalls.slice(-10)) {
|
|
309
|
+
const funcName = tc.call.function?.name || tc.call.toolName || 'Unknown';
|
|
310
|
+
console.log(` ${colors.green}[${tc.index}]${colors.reset} ${funcName}`);
|
|
311
|
+
}
|
|
312
|
+
console.log(`${colors.dim}Use /tool <index> to view arguments.${colors.reset}`);
|
|
313
|
+
}
|
|
314
|
+
} else {
|
|
315
|
+
const targetIndex = parseInt(args[0], 10);
|
|
316
|
+
const target = toolCalls.find(tc => tc.index === targetIndex);
|
|
317
|
+
if (!target) {
|
|
318
|
+
console.log(`${colors.red}Tool call [${targetIndex}] not found.${colors.reset}`);
|
|
319
|
+
} else {
|
|
320
|
+
const funcName = target.call.function?.name || target.call.toolName || 'Unknown';
|
|
321
|
+
const argsStr = target.call.function?.arguments || target.call.toolArgs || '{}';
|
|
322
|
+
console.log(`\n${colors.cyan}=== Tool Call [${targetIndex}]: ${funcName} ===${colors.reset}`);
|
|
323
|
+
try {
|
|
324
|
+
const parsed = typeof argsStr === 'string' ? JSON.parse(argsStr) : argsStr;
|
|
325
|
+
console.log(JSON.stringify(parsed, null, 2));
|
|
326
|
+
} catch (e) {
|
|
327
|
+
console.log(argsStr);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
return;
|
|
292
332
|
case '/new':
|
|
293
333
|
await repl.session.newSession({ project: repl.projectPath });
|
|
294
334
|
repl.history = [];
|
package/src/cli/repl.js
CHANGED
|
@@ -1847,6 +1847,22 @@ ${colors.reset}
|
|
|
1847
1847
|
if (chunk.content) {
|
|
1848
1848
|
content += chunk.content;
|
|
1849
1849
|
}
|
|
1850
|
+
|
|
1851
|
+
if (this.spinner && printed === false) {
|
|
1852
|
+
if (toolCallParts.length > 0) {
|
|
1853
|
+
const lastCall = toolCallParts[toolCallParts.length - 1];
|
|
1854
|
+
if (lastCall.function?.name) {
|
|
1855
|
+
const args = lastCall.function.arguments || '';
|
|
1856
|
+
let summary = args.replace(/\s+/g, ' ');
|
|
1857
|
+
if (summary.length > 60) summary = '...' + summary.slice(-60);
|
|
1858
|
+
this.spinner.update(`Calling ${lastCall.function.name}... ${summary}`);
|
|
1859
|
+
}
|
|
1860
|
+
} else if (content.length > 0 && bufferToolModeContent) {
|
|
1861
|
+
let summary = content.replace(/\s+/g, ' ');
|
|
1862
|
+
if (summary.length > 60) summary = '...' + summary.slice(-60);
|
|
1863
|
+
this.spinner.update(`Generating... ${summary}`);
|
|
1864
|
+
}
|
|
1865
|
+
}
|
|
1850
1866
|
}
|
|
1851
1867
|
|
|
1852
1868
|
if (this.spinner) this.spinner.stop();
|
|
@@ -9,6 +9,7 @@ export const SLASH_COMMANDS = [
|
|
|
9
9
|
{ cmd: '/session', desc: 'Session management' },
|
|
10
10
|
{ cmd: '/sessions', desc: 'List all sessions' },
|
|
11
11
|
{ cmd: '/history', desc: 'Browse recent chat and tool history', usage: '/history [count]' },
|
|
12
|
+
{ cmd: '/tool', desc: 'Inspect recent tool calls and their raw data', usage: '/tool [index]' },
|
|
12
13
|
{ cmd: '/new', desc: 'Start a new conversation' },
|
|
13
14
|
{ cmd: '/clear', desc: 'Clear screen' },
|
|
14
15
|
{ cmd: '/remember', desc: 'Store in memory', usage: '/remember <text>' },
|
package/src/cli/spinner.js
CHANGED
|
@@ -13,8 +13,14 @@ export class Spinner {
|
|
|
13
13
|
const cyan = this.colors.cyan || '';
|
|
14
14
|
const reset = this.colors.reset || '';
|
|
15
15
|
const dim = this.colors.dim || '';
|
|
16
|
+
this.startTime = Date.now();
|
|
16
17
|
this.interval = setInterval(() => {
|
|
17
|
-
|
|
18
|
+
const elapsed = Math.floor((Date.now() - this.startTime) / 1000);
|
|
19
|
+
let timeStr = '';
|
|
20
|
+
if (elapsed >= 5) {
|
|
21
|
+
timeStr = ` (still thinking... ${elapsed}s)`;
|
|
22
|
+
}
|
|
23
|
+
process.stdout.write(`\r\x1b[K${cyan}${this.frames[this.frameIndex]}${reset} ${dim}${this.text}${timeStr}${reset}`);
|
|
18
24
|
this.frameIndex = (this.frameIndex + 1) % this.frames.length;
|
|
19
25
|
}, 80);
|
|
20
26
|
}
|
package/src/cli/tui.js
CHANGED
|
@@ -191,5 +191,7 @@ export function renderToolPanel({ toolName = 'Tool', summary = '', success = tru
|
|
|
191
191
|
return ` ${c.dim}${line}${c.reset}`;
|
|
192
192
|
}).join('\n');
|
|
193
193
|
|
|
194
|
-
|
|
194
|
+
let output = `${status} ${c.bright}${c.cyan}${toolName}${c.reset} ${c.dim}· ${firstLine}${c.reset}`;
|
|
195
|
+
if (formattedRest) output += `\n${formattedRest}`;
|
|
196
|
+
return output;
|
|
195
197
|
}
|
package/src/design/commands.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* ❄ DESIGN COMMANDS ❄
|
|
3
3
|
* Design system integration with brand guidelines
|
|
4
4
|
*/
|
|
5
5
|
|
|
@@ -163,7 +163,7 @@ export class DesignCommands {
|
|
|
163
163
|
}
|
|
164
164
|
|
|
165
165
|
console.log(`\n${'='.repeat(60)}`);
|
|
166
|
-
console.log(`${colors.cyan}
|
|
166
|
+
console.log(`${colors.cyan}≡ ${brand} - ${fileName}${colors.reset}`);
|
|
167
167
|
console.log('='.repeat(60));
|
|
168
168
|
console.log('');
|
|
169
169
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* ❄ INLINE COMPLETION — /complete command ❄
|
|
3
3
|
* Provides code completion suggestions based on context.
|
|
4
4
|
* Integrates the existing CompletionProvider into the REPL.
|
|
5
5
|
*/
|
|
@@ -76,15 +76,15 @@ export class InlineComplete {
|
|
|
76
76
|
const width = terminalWidth(76, 116, 92);
|
|
77
77
|
const body = result.completions.map((c, i) => {
|
|
78
78
|
const typeIcon = c.type === 'block-close' ? '}' :
|
|
79
|
-
c.type === 'import' ? '
|
|
79
|
+
c.type === 'import' ? '■' :
|
|
80
80
|
c.type === 'function' ? 'ƒ' :
|
|
81
81
|
c.type === 'method' ? '.' :
|
|
82
82
|
c.type === 'arrow-function' ? '=>' :
|
|
83
83
|
c.type === 'variable' ? '✕' :
|
|
84
|
-
c.type === 'keyword' ? '
|
|
85
|
-
c.type === 'export' ? '
|
|
86
|
-
c.type === 'import-path' ? '
|
|
87
|
-
c.type === 'cached' ? '
|
|
84
|
+
c.type === 'keyword' ? '#' :
|
|
85
|
+
c.type === 'export' ? '^' :
|
|
86
|
+
c.type === 'import-path' ? '►' :
|
|
87
|
+
c.type === 'cached' ? 'v' : '•';
|
|
88
88
|
const confidence = (c.confidence * 100).toFixed(0);
|
|
89
89
|
return ` ${colors.cyan}#${i + 1}${colors.reset} ${typeIcon} ${colors.green}${c.text}${colors.reset}` +
|
|
90
90
|
`\n ${colors.dim}type: ${c.type}, confidence: ${confidence}%${colors.reset}`;
|
package/src/plugins/manager.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* ❄ PLUGIN MANAGER ❄
|
|
3
3
|
* Manage Winter CLI plugins
|
|
4
4
|
*/
|
|
5
5
|
|
|
@@ -21,7 +21,7 @@ export class PluginManager {
|
|
|
21
21
|
{
|
|
22
22
|
name: 'winter-core',
|
|
23
23
|
version: '1.0.0',
|
|
24
|
-
icon: '
|
|
24
|
+
icon: '❄',
|
|
25
25
|
description: 'Core Winter CLI functionality',
|
|
26
26
|
hooks: {},
|
|
27
27
|
commands: {},
|
|
@@ -30,7 +30,7 @@ export class PluginManager {
|
|
|
30
30
|
{
|
|
31
31
|
name: 'winter-design',
|
|
32
32
|
version: '1.0.0',
|
|
33
|
-
icon: '
|
|
33
|
+
icon: '*',
|
|
34
34
|
description: 'Design system integration',
|
|
35
35
|
hooks: {},
|
|
36
36
|
commands: {},
|
|
@@ -39,7 +39,7 @@ export class PluginManager {
|
|
|
39
39
|
{
|
|
40
40
|
name: 'winter-coding',
|
|
41
41
|
version: '1.0.0',
|
|
42
|
-
icon: '
|
|
42
|
+
icon: '■',
|
|
43
43
|
description: 'Coding assistance tools',
|
|
44
44
|
hooks: {},
|
|
45
45
|
commands: {},
|
|
@@ -67,7 +67,7 @@ export class PluginManager {
|
|
|
67
67
|
plugins.push({
|
|
68
68
|
name: plugin.default?.name || file.replace('.js', ''),
|
|
69
69
|
version: plugin.default?.version || '1.0.0',
|
|
70
|
-
icon: plugin.default?.icon || '
|
|
70
|
+
icon: plugin.default?.icon || '+',
|
|
71
71
|
description: plugin.default?.description || 'Plugin',
|
|
72
72
|
hooks: plugin.default?.hooks || {},
|
|
73
73
|
commands: plugin.default?.commands || {},
|
package/src/session/manager.js
CHANGED
package/src/skills/manager.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* ❄ SKILL MANAGER ❄
|
|
3
3
|
* Manage Winter CLI skills
|
|
4
4
|
*/
|
|
5
5
|
|
|
@@ -19,7 +19,7 @@ export class SkillManager {
|
|
|
19
19
|
return [
|
|
20
20
|
{
|
|
21
21
|
name: 'coding',
|
|
22
|
-
icon: '
|
|
22
|
+
icon: '■',
|
|
23
23
|
description: 'Code analysis, generation, and review',
|
|
24
24
|
prompts: [
|
|
25
25
|
'Analyze this code for issues',
|
|
@@ -29,7 +29,7 @@ export class SkillManager {
|
|
|
29
29
|
},
|
|
30
30
|
{
|
|
31
31
|
name: 'design',
|
|
32
|
-
icon: '
|
|
32
|
+
icon: '*',
|
|
33
33
|
description: 'Design system and brand guidelines',
|
|
34
34
|
prompts: [
|
|
35
35
|
'Apply {brand} design patterns',
|
|
@@ -39,7 +39,7 @@ export class SkillManager {
|
|
|
39
39
|
},
|
|
40
40
|
{
|
|
41
41
|
name: 'debug',
|
|
42
|
-
icon: '
|
|
42
|
+
icon: '$',
|
|
43
43
|
description: 'Debugging and error analysis',
|
|
44
44
|
prompts: [
|
|
45
45
|
'Find the root cause of this error',
|
|
@@ -49,7 +49,7 @@ export class SkillManager {
|
|
|
49
49
|
},
|
|
50
50
|
{
|
|
51
51
|
name: 'refactor',
|
|
52
|
-
icon: '
|
|
52
|
+
icon: '♻',
|
|
53
53
|
description: 'Code refactoring and improvements',
|
|
54
54
|
prompts: [
|
|
55
55
|
'Simplify this function',
|
|
@@ -69,7 +69,7 @@ export class SkillManager {
|
|
|
69
69
|
},
|
|
70
70
|
{
|
|
71
71
|
name: 'security',
|
|
72
|
-
icon: '
|
|
72
|
+
icon: '#',
|
|
73
73
|
description: 'Security analysis and best practices',
|
|
74
74
|
prompts: [
|
|
75
75
|
'Find potential security vulnerabilities',
|
|
@@ -79,7 +79,7 @@ export class SkillManager {
|
|
|
79
79
|
},
|
|
80
80
|
{
|
|
81
81
|
name: 'performance',
|
|
82
|
-
icon: '
|
|
82
|
+
icon: '▶',
|
|
83
83
|
description: 'Performance optimization',
|
|
84
84
|
prompts: [
|
|
85
85
|
'Identify performance bottlenecks',
|
|
@@ -107,7 +107,7 @@ export class SkillManager {
|
|
|
107
107
|
const name = file.replace('.md', '');
|
|
108
108
|
skills.push({
|
|
109
109
|
name,
|
|
110
|
-
icon: '
|
|
110
|
+
icon: '$',
|
|
111
111
|
description: this.extractDescription(content),
|
|
112
112
|
isCustom: true,
|
|
113
113
|
});
|
package/src/tools/agent.js
CHANGED
package/src/tools/executor.js
CHANGED
package/src/tools/insert-text.js
CHANGED
package/src/tools/interactive.js
CHANGED
package/src/tools/notebook.js
CHANGED
package/src/tools/scheduler.js
CHANGED
package/src/tools/todo.js
CHANGED
package/src/tools/web-archive.js
CHANGED