skyloom 1.5.1 → 1.5.2
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/dist/cli/main.js +218 -592
- package/dist/cli/main.js.map +1 -1
- package/dist/core/llm.d.ts +8 -9
- package/dist/core/llm.d.ts.map +1 -1
- package/dist/core/llm.js +162 -35
- package/dist/core/llm.js.map +1 -1
- package/package.json +1 -1
package/dist/cli/main.js
CHANGED
|
@@ -39,7 +39,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
39
39
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
40
|
/**
|
|
41
41
|
* 天空织机 CLI — Skyloom Terminal Interface
|
|
42
|
-
* Raw-mode input + slash command popup + streaming display
|
|
43
42
|
*/
|
|
44
43
|
const commander_1 = require("commander");
|
|
45
44
|
const fs = __importStar(require("fs"));
|
|
@@ -47,663 +46,292 @@ const readline = __importStar(require("readline"));
|
|
|
47
46
|
const chalk_1 = __importDefault(require("chalk"));
|
|
48
47
|
const factory_1 = require("../core/factory");
|
|
49
48
|
const config_1 = require("../core/config");
|
|
50
|
-
const router_1 = require("../core/router");
|
|
51
49
|
const mode_1 = require("./mode");
|
|
52
50
|
const MODE = new mode_1.ModeController();
|
|
53
|
-
const VERSION = "1.4.
|
|
54
|
-
/* ── Agent colors ── */
|
|
55
|
-
const AGENT_COLORS = {
|
|
56
|
-
fog: "#b8c6db", rain: "#4a90d9", frost: "#2cd4d4",
|
|
57
|
-
snow: "#e8ecf1", dew: "#7bed9f", fair: "#f7b733",
|
|
58
|
-
};
|
|
51
|
+
const VERSION = "1.4.4";
|
|
59
52
|
const AGENT_DISPLAY = {
|
|
60
53
|
fog: "≋ 雾 Fog", rain: "⸽ 雨 Rain", frost: "✱ 霜 Frost",
|
|
61
54
|
snow: "❉ 雪 Snow", dew: "∘ 露 Dew", fair: "☼ 晴 Fair",
|
|
62
55
|
};
|
|
63
56
|
const AGENT_NAMES = ["fog", "rain", "frost", "snow", "dew", "fair"];
|
|
64
57
|
/* ═══════════════════════════════════════
|
|
65
|
-
|
|
66
|
-
═══════════════════════════════════════ */
|
|
67
|
-
const program = new commander_1.Command()
|
|
68
|
-
.name("sky").description("天空织机 Skyloom — 6 weather-themed AI agents").version(VERSION);
|
|
69
|
-
program.command("chat").description("Start interactive chat")
|
|
70
|
-
.argument("[agent]", "agent name", "fog")
|
|
71
|
-
.option("-m,--model <model>", "Model override")
|
|
72
|
-
.action(async (a, o) => { await chat(a, o.model); });
|
|
73
|
-
program.command("task").description("Multi-agent orchestration")
|
|
74
|
-
.argument("[goal]", "task goal")
|
|
75
|
-
.option("-r,--resume", "resume from checkpoint")
|
|
76
|
-
.action(async (g, o) => { if (g)
|
|
77
|
-
await runTask(g, o?.resume); });
|
|
78
|
-
program.command("web").description("Start web server")
|
|
79
|
-
.option("-p,--port <port>", "port", "3000")
|
|
80
|
-
.action(async (o) => { const { startWebServer } = await Promise.resolve().then(() => __importStar(require("../web/server"))); await startWebServer(parseInt(o.port || "3000", 10)); });
|
|
81
|
-
program.command("mcp").description("Start MCP server")
|
|
82
|
-
.action(async () => { const { startMCPServer } = await Promise.resolve().then(() => __importStar(require("../core/mcp_server"))); await startMCPServer(); });
|
|
83
|
-
program.command("config").description("Show configuration")
|
|
84
|
-
.action(() => { const c = (0, config_1.loadConfig)(); logLine(chalk_1.default.cyan("Config dir: ") + config_1.USER_CONFIG_DIR); logLine(chalk_1.default.cyan("Agent models:")); for (const [n, a] of Object.entries(c.agents || {}))
|
|
85
|
-
logLine(` ${chalk_1.default.bold(n)}: ${a.model || "default"}`); });
|
|
86
|
-
program.command("init").description("Initialize config directory")
|
|
87
|
-
.action(() => { const d = config_1.USER_CONFIG_DIR; if (!fs.existsSync(d))
|
|
88
|
-
fs.mkdirSync(d, { recursive: true }); logLine(chalk_1.default.green("✓ ") + d); });
|
|
89
|
-
program.command("version").description("Show version")
|
|
90
|
-
.action(() => logLine(`Skyloom v${VERSION}`));
|
|
91
|
-
/* ═══════════════════════════════════════
|
|
92
|
-
Interactive Chat — raw-mode input + popup
|
|
58
|
+
Slash commands registry
|
|
93
59
|
═══════════════════════════════════════ */
|
|
94
60
|
const SLASH_CMDS = [
|
|
95
|
-
["/help", "Show all commands"
|
|
96
|
-
["/clear", "Clear screen"
|
|
97
|
-
["/status", "Agent overview"
|
|
98
|
-
["/cost", "Usage & cost"
|
|
99
|
-
["/cost reset", "Reset usage stats"
|
|
100
|
-
["/compact", "Compress context"
|
|
101
|
-
["/retry", "Resend last
|
|
102
|
-
["/
|
|
103
|
-
["/memory", "
|
|
104
|
-
["/sessions", "Session list"
|
|
105
|
-
["/workspace", "Workspace info"
|
|
106
|
-
["/model", "Model info"
|
|
107
|
-
["/
|
|
108
|
-
["/
|
|
109
|
-
["/
|
|
110
|
-
["/fog", "≋ Fog — research
|
|
111
|
-
["/rain", "⸽ Rain — codegen"
|
|
112
|
-
["/frost", "✱ Frost — review
|
|
113
|
-
["/snow", "❉ Snow — planning
|
|
114
|
-
["/dew", "∘ Dew — devops
|
|
115
|
-
["/fair", "☼ Fair — companion
|
|
116
|
-
["/quit", "Exit chat"
|
|
117
|
-
["/exit", "Exit chat"
|
|
61
|
+
["/help", "Show all commands"],
|
|
62
|
+
["/clear", "Clear screen"],
|
|
63
|
+
["/status", "Agent overview"],
|
|
64
|
+
["/cost", "Usage & cost"],
|
|
65
|
+
["/cost reset", "Reset usage stats"],
|
|
66
|
+
["/compact", "Compress context"],
|
|
67
|
+
["/retry", "Resend last msg"],
|
|
68
|
+
["/memory", "Memory stats"],
|
|
69
|
+
["/memory clear", "Clear short-term memory"],
|
|
70
|
+
["/sessions", "Session list"],
|
|
71
|
+
["/workspace", "Workspace info"],
|
|
72
|
+
["/model", "Model info"],
|
|
73
|
+
["/mcp", "MCP server status"],
|
|
74
|
+
["/version", "Version info"],
|
|
75
|
+
["/task <goal>", "Multi-agent orchestrate"],
|
|
76
|
+
["/fog", "≋ Fog — research insight"],
|
|
77
|
+
["/rain", "⸽ Rain — creation codegen"],
|
|
78
|
+
["/frost", "✱ Frost — review quality"],
|
|
79
|
+
["/snow", "❉ Snow — planning architect"],
|
|
80
|
+
["/dew", "∘ Dew — devops reliability"],
|
|
81
|
+
["/fair", "☼ Fair — companion warmth"],
|
|
82
|
+
["/quit", "Exit chat"],
|
|
83
|
+
["/exit", "Exit chat"],
|
|
118
84
|
];
|
|
119
|
-
function
|
|
120
|
-
/* ── Stream response with spinner ── */
|
|
121
|
-
async function chatWithSpinner(agent, ctx, message) {
|
|
122
|
-
let frame = 0;
|
|
123
|
-
const frames = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
|
|
124
|
-
const spinner = setInterval(() => {
|
|
125
|
-
readline.cursorTo(process.stdout, 0);
|
|
126
|
-
process.stdout.write(chalk_1.default.cyan(` ${frames[frame % frames.length]} ${agent.displayName} thinking...`));
|
|
127
|
-
frame++;
|
|
128
|
-
}, 80);
|
|
129
|
-
try {
|
|
130
|
-
const response = await agent.chat(message);
|
|
131
|
-
clearInterval(spinner);
|
|
132
|
-
readline.cursorTo(process.stdout, 0);
|
|
133
|
-
process.stdout.write(" ".repeat(50) + "\r");
|
|
134
|
-
return response;
|
|
135
|
-
}
|
|
136
|
-
catch (e) {
|
|
137
|
-
clearInterval(spinner);
|
|
138
|
-
throw e;
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
/* ── Render response ── */
|
|
142
|
-
function renderResponse(text) {
|
|
143
|
-
const lines = [];
|
|
85
|
+
function showPopup(cmds, selIdx) {
|
|
144
86
|
const w = process.stdout.columns || 80;
|
|
145
|
-
const
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
const codeLines = trimmed.split("\n");
|
|
153
|
-
lines.push(chalk_1.default.dim(" ┌─ code ──────────────"));
|
|
154
|
-
for (let i = 1; i < codeLines.length - 1; i++) {
|
|
155
|
-
const cl = codeLines[i];
|
|
156
|
-
lines.push(` ${chalk_1.default.dim("│")} ${chalk_1.default.white(cl.slice(0, maxW - 4))}`);
|
|
157
|
-
}
|
|
158
|
-
lines.push(chalk_1.default.dim(" └────────────────────"));
|
|
159
|
-
continue;
|
|
160
|
-
}
|
|
161
|
-
// Wrap long lines
|
|
162
|
-
for (const line of trimmed.split("\n")) {
|
|
163
|
-
if (line.startsWith("#")) {
|
|
164
|
-
lines.push(" " + chalk_1.default.bold(line));
|
|
165
|
-
}
|
|
166
|
-
else if (line.startsWith("- ") || line.startsWith("* ")) {
|
|
167
|
-
lines.push(" " + chalk_1.default.dim("• ") + line.slice(2));
|
|
168
|
-
}
|
|
169
|
-
else {
|
|
170
|
-
let remaining = line;
|
|
171
|
-
while (remaining.length > maxW) {
|
|
172
|
-
const cut = remaining.lastIndexOf(" ", maxW);
|
|
173
|
-
const idx = cut > 0 ? cut : maxW;
|
|
174
|
-
lines.push(" " + remaining.slice(0, idx));
|
|
175
|
-
remaining = remaining.slice(idx).trimStart();
|
|
176
|
-
}
|
|
177
|
-
if (remaining)
|
|
178
|
-
lines.push(" " + remaining);
|
|
179
|
-
}
|
|
180
|
-
}
|
|
87
|
+
const start = Math.max(0, Math.min(selIdx - 4, cmds.length - 8));
|
|
88
|
+
const end = Math.min(cmds.length, start + 8);
|
|
89
|
+
process.stdout.write(chalk_1.default.dim(" ┌─ commands (↑↓ pick · type letter to filter · tab/enter select) ─┐\n"));
|
|
90
|
+
for (let i = start; i < end; i++) {
|
|
91
|
+
const [cmd, desc] = cmds[i];
|
|
92
|
+
const marker = i === selIdx ? chalk_1.default.cyan(" ▶ ") : " ";
|
|
93
|
+
process.stdout.write(` │${marker}${chalk_1.default.cyan(cmd.padEnd(24))}${chalk_1.default.dim(desc)}${" ".repeat(Math.max(0, 50 - desc.length))}│\n`);
|
|
181
94
|
}
|
|
182
|
-
|
|
95
|
+
process.stdout.write(chalk_1.default.dim(` └${"─".repeat(60)}┘\n`));
|
|
183
96
|
}
|
|
184
|
-
/*
|
|
185
|
-
|
|
97
|
+
/* ═══════════════════════════════════════
|
|
98
|
+
Commander
|
|
99
|
+
═══════════════════════════════════════ */
|
|
100
|
+
const program = new commander_1.Command()
|
|
101
|
+
.name("sky").description("天空织机 Skyloom").version(VERSION);
|
|
102
|
+
program.command("chat").argument("[agent]", "agent name", "fog")
|
|
103
|
+
.option("-m,--model <m>", "model").action(async (a, o) => { await chat(a, o.model); });
|
|
104
|
+
program.command("task").argument("[goal]", "task goal")
|
|
105
|
+
.action(async (g) => { if (g)
|
|
106
|
+
await runTask(g); });
|
|
107
|
+
program.command("web").option("-p,--port <p>", "port", "3000")
|
|
108
|
+
.action((o) => { Promise.resolve().then(() => __importStar(require("../web/server"))).then(m => m.startWebServer(parseInt(o.port || "3000"))); });
|
|
109
|
+
program.command("mcp").action(() => { Promise.resolve().then(() => __importStar(require("../core/mcp_server"))).then(m => m.startMCPServer()); });
|
|
110
|
+
program.command("config").action(() => { const c = (0, config_1.loadConfig)(); process.stdout.write(chalk_1.default.cyan("\nConfig: ") + config_1.USER_CONFIG_DIR + "\n"); for (const [n, a] of Object.entries(c.agents || {}))
|
|
111
|
+
process.stdout.write(` ${chalk_1.default.bold(n)}: ${a.model || "default"}\n`); });
|
|
112
|
+
program.command("init").action(() => { if (!fs.existsSync(config_1.USER_CONFIG_DIR))
|
|
113
|
+
fs.mkdirSync(config_1.USER_CONFIG_DIR, { recursive: true }); process.stdout.write(chalk_1.default.green("✓ ") + config_1.USER_CONFIG_DIR + "\n"); });
|
|
114
|
+
program.command("version").action(() => { process.stdout.write(`Skyloom v${VERSION}\n`); });
|
|
115
|
+
/* ═══════════════════════════════════════
|
|
116
|
+
Welcome
|
|
117
|
+
═══════════════════════════════════════ */
|
|
118
|
+
function welcome(agent) {
|
|
186
119
|
const w = process.stdout.columns || 80;
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
const
|
|
192
|
-
|
|
193
|
-
const
|
|
194
|
-
|
|
195
|
-
agentLine.push(prefix);
|
|
120
|
+
const pad = " ".repeat(Math.max(0, Math.floor((w - 34) / 2)));
|
|
121
|
+
process.stdout.write("\n" + pad + chalk_1.default.cyan("✦ 天 空 织 机 ✦\n"));
|
|
122
|
+
process.stdout.write(pad + chalk_1.default.dim("S K Y L O O M\n\n"));
|
|
123
|
+
const parts = [];
|
|
124
|
+
for (const n of AGENT_NAMES) {
|
|
125
|
+
const a = n === agent.name;
|
|
126
|
+
const s = `${AGENT_DISPLAY[n].split(" ")[0]} ${AGENT_DISPLAY[n].split(" ")[1]}`;
|
|
127
|
+
parts.push(a ? chalk_1.default.bold.cyan(s) : chalk_1.default.dim(s));
|
|
196
128
|
}
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
logLine(chalk_1.default.dim(` Model: ${model} · /help for commands · /quit to exit`));
|
|
200
|
-
logLine("");
|
|
129
|
+
process.stdout.write(" " + parts.join(chalk_1.default.dim(" · ")) + "\n\n");
|
|
130
|
+
process.stdout.write(chalk_1.default.dim(" /help for commands · /quit to exit\n\n"));
|
|
201
131
|
}
|
|
202
|
-
/* ── Status bar ── */
|
|
203
132
|
function statusBar(agent, ctx) {
|
|
204
|
-
let ctxStr = "";
|
|
205
|
-
let costStr = "$0";
|
|
206
|
-
let modelStr = "default";
|
|
207
133
|
try {
|
|
208
134
|
const cu = agent.contextUsage();
|
|
209
|
-
modelStr = cu.model || "?";
|
|
210
135
|
const pct = cu.pct || 0;
|
|
211
|
-
const
|
|
212
|
-
const
|
|
213
|
-
|
|
214
|
-
|
|
136
|
+
const bar = pct < 50 ? chalk_1.default.green : pct < 80 ? chalk_1.default.yellow : chalk_1.default.red;
|
|
137
|
+
const filled = Math.round(pct / 10);
|
|
138
|
+
const ctxBar = `${bar("█".repeat(filled) + "░".repeat(10 - filled))} ${pct}%`;
|
|
139
|
+
const cost = formatCost(ctx.llm.getTotalCost());
|
|
140
|
+
return chalk_1.default.dim(`${ctxBar} · ${cost} · ${cu.model || "?"}`);
|
|
141
|
+
}
|
|
142
|
+
catch {
|
|
143
|
+
return "";
|
|
215
144
|
}
|
|
216
|
-
catch { /* ignore */ }
|
|
217
|
-
const w = process.stdout.columns || 80;
|
|
218
|
-
return chalk_1.default.dim(`┤ ${ctxStr} · ${costStr} · ${modelStr} ├${"─".repeat(Math.max(0, w - 60))}`);
|
|
219
145
|
}
|
|
220
|
-
function formatCost(
|
|
221
|
-
if (
|
|
222
|
-
return chalk_1.default.yellow(`$${
|
|
223
|
-
if (
|
|
224
|
-
return chalk_1.default.yellow(`$${
|
|
225
|
-
if (
|
|
226
|
-
return chalk_1.default.green(`${(
|
|
146
|
+
function formatCost(c) {
|
|
147
|
+
if (c >= 1)
|
|
148
|
+
return chalk_1.default.yellow(`$${c.toFixed(2)}`);
|
|
149
|
+
if (c >= 0.01)
|
|
150
|
+
return chalk_1.default.yellow(`$${c.toFixed(4)}`);
|
|
151
|
+
if (c > 0)
|
|
152
|
+
return chalk_1.default.green(`${(c * 100).toFixed(2)}¢`);
|
|
227
153
|
return "$0";
|
|
228
154
|
}
|
|
229
|
-
/*
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
let buf = "";
|
|
245
|
-
let cursor = 0;
|
|
246
|
-
let popup = false;
|
|
247
|
-
let selIdx = 0;
|
|
248
|
-
const _history = readWithPopup._popupHistory || [];
|
|
249
|
-
let histIdx = _history.length;
|
|
250
|
-
function render() {
|
|
251
|
-
const w = process.stdout.columns || 80;
|
|
252
|
-
readline.cursorTo(process.stdout, 0);
|
|
253
|
-
// Clear current line area
|
|
254
|
-
const promptLine = ` ${chalk_1.default.cyan(agent.displayName)} ${chalk_1.default.dim("❯")} `;
|
|
255
|
-
// Build filtered commands
|
|
256
|
-
const filtered = popup ? SLASH_CMDS.filter(c => c[0].toLowerCase().includes(buf.toLowerCase())) : [];
|
|
257
|
-
if (filtered.length && selIdx >= filtered.length)
|
|
258
|
-
selIdx = filtered.length - 1;
|
|
259
|
-
const popupH = Math.min(filtered.length, 10);
|
|
260
|
-
const totalH = popup ? popupH + 3 : 1;
|
|
261
|
-
// Move cursor up
|
|
262
|
-
if (popup) {
|
|
263
|
-
for (let i = 0; i < popupH + 2; i++)
|
|
264
|
-
process.stdout.write("\x1b[1A\x1b[2K");
|
|
265
|
-
}
|
|
266
|
-
else {
|
|
267
|
-
process.stdout.write("\x1b[2K\r");
|
|
268
|
-
}
|
|
269
|
-
// Input line
|
|
270
|
-
const before = buf.slice(0, cursor);
|
|
271
|
-
const after = buf.slice(cursor);
|
|
272
|
-
const cursorChar = after[0] || " ";
|
|
273
|
-
process.stdout.write(promptLine + before + chalk_1.default.inverse(cursorChar) + after.slice(1) + "\n");
|
|
274
|
-
// Popup
|
|
275
|
-
if (popup && filtered.length) {
|
|
276
|
-
const maxW = Math.min(w - 4, 60);
|
|
277
|
-
const start = Math.max(0, Math.min(selIdx - 4, filtered.length - 8));
|
|
278
|
-
const end = Math.min(filtered.length, start + 8);
|
|
279
|
-
process.stdout.write(chalk_1.default.dim(` ┌─ commands (↑↓ pick · type to filter · tab/enter select · esc close)${"─".repeat(Math.max(0, maxW - 58))}┐\n`));
|
|
280
|
-
for (let i = start; i < end; i++) {
|
|
281
|
-
const [cmd, desc] = filtered[i];
|
|
282
|
-
const marker = i === selIdx ? chalk_1.default.cyan(" ▶ ") : " ";
|
|
283
|
-
const cmdColored = i === selIdx ? chalk_1.default.bold(cmd) : chalk_1.default.cyan(cmd);
|
|
284
|
-
const line = ` │${marker}${cmdColored.padEnd(24)}${chalk_1.default.dim(desc)}`;
|
|
285
|
-
process.stdout.write(line + " ".repeat(Math.max(0, maxW - line.length + 6)) + "│\n");
|
|
286
|
-
}
|
|
287
|
-
process.stdout.write(chalk_1.default.dim(` └${"─".repeat(maxW + 1)}┘\n`));
|
|
288
|
-
}
|
|
289
|
-
// Status bar
|
|
290
|
-
process.stdout.write(statusBar(agent, ctx) + (popup ? "" : "\n"));
|
|
155
|
+
/* ═══════════════════════════════════════
|
|
156
|
+
Response render
|
|
157
|
+
═══════════════════════════════════════ */
|
|
158
|
+
function render(text) {
|
|
159
|
+
const out = [];
|
|
160
|
+
for (const para of text.split("\n\n")) {
|
|
161
|
+
const t = para.trim();
|
|
162
|
+
if (!t)
|
|
163
|
+
continue;
|
|
164
|
+
if (t.startsWith("```")) {
|
|
165
|
+
const lines = t.split("\n");
|
|
166
|
+
out.push(chalk_1.default.dim(" ╭─ code ──"));
|
|
167
|
+
for (let i = 1; i < lines.length - 1; i++)
|
|
168
|
+
out.push(` ${chalk_1.default.dim("│")} ${chalk_1.default.gray(lines[i].slice(0, 72))}`);
|
|
169
|
+
out.push(chalk_1.default.dim(" ╰────────"));
|
|
291
170
|
}
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
171
|
+
else {
|
|
172
|
+
for (const line of t.split("\n")) {
|
|
173
|
+
if (line.startsWith("# "))
|
|
174
|
+
out.push(" " + chalk_1.default.bold(line));
|
|
175
|
+
else if (line.startsWith("- ") || line.startsWith("* "))
|
|
176
|
+
out.push(" " + chalk_1.default.dim("• ") + line.slice(2));
|
|
177
|
+
else
|
|
178
|
+
out.push(" " + line);
|
|
295
179
|
}
|
|
296
|
-
catch { }
|
|
297
|
-
stdin.pause();
|
|
298
|
-
resolve(line);
|
|
299
180
|
}
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
for (const ch of seq) {
|
|
303
|
-
// Esc
|
|
304
|
-
if (ch === "\x1b") {
|
|
305
|
-
if (popup) {
|
|
306
|
-
popup = false;
|
|
307
|
-
render();
|
|
308
|
-
return;
|
|
309
|
-
}
|
|
310
|
-
accept("");
|
|
311
|
-
return;
|
|
312
|
-
}
|
|
313
|
-
// Enter
|
|
314
|
-
if (ch === "\r" || ch === "\n") {
|
|
315
|
-
if (popup && SLASH_CMDS.filter(c => c[0].toLowerCase().includes(buf.toLowerCase())).length) {
|
|
316
|
-
const filtered = SLASH_CMDS.filter(c => c[0].toLowerCase().includes(buf.toLowerCase()));
|
|
317
|
-
buf = filtered[selIdx]?.[0] || buf;
|
|
318
|
-
popup = false;
|
|
319
|
-
}
|
|
320
|
-
accept(buf.trim());
|
|
321
|
-
return;
|
|
322
|
-
}
|
|
323
|
-
// Tab
|
|
324
|
-
if (ch === "\t") {
|
|
325
|
-
if (popup && SLASH_CMDS.filter(c => c[0].toLowerCase().includes(buf.toLowerCase())).length) {
|
|
326
|
-
const filtered = SLASH_CMDS.filter(c => c[0].toLowerCase().includes(buf.toLowerCase()));
|
|
327
|
-
buf = filtered[selIdx]?.[0] || buf;
|
|
328
|
-
cursor = buf.length;
|
|
329
|
-
popup = false;
|
|
330
|
-
render();
|
|
331
|
-
return;
|
|
332
|
-
}
|
|
333
|
-
// Insert 2 spaces
|
|
334
|
-
buf = buf.slice(0, cursor) + " " + buf.slice(cursor);
|
|
335
|
-
cursor += 2;
|
|
336
|
-
render();
|
|
337
|
-
return;
|
|
338
|
-
}
|
|
339
|
-
// Backspace
|
|
340
|
-
if (ch === "\x7f" || ch === "\b") {
|
|
341
|
-
if (cursor > 0) {
|
|
342
|
-
buf = buf.slice(0, cursor - 1) + buf.slice(cursor);
|
|
343
|
-
cursor--;
|
|
344
|
-
}
|
|
345
|
-
if (!buf) {
|
|
346
|
-
popup = false;
|
|
347
|
-
}
|
|
348
|
-
render();
|
|
349
|
-
return;
|
|
350
|
-
}
|
|
351
|
-
// Ctrl+C
|
|
352
|
-
if (ch === "\x03") {
|
|
353
|
-
accept("/quit");
|
|
354
|
-
return;
|
|
355
|
-
}
|
|
356
|
-
// Printable
|
|
357
|
-
if (ch >= " ") {
|
|
358
|
-
buf = buf.slice(0, cursor) + ch + buf.slice(cursor);
|
|
359
|
-
cursor++;
|
|
360
|
-
if (buf === "/") {
|
|
361
|
-
popup = true;
|
|
362
|
-
selIdx = 0;
|
|
363
|
-
}
|
|
364
|
-
else if (popup) {
|
|
365
|
-
selIdx = 0;
|
|
366
|
-
}
|
|
367
|
-
render();
|
|
368
|
-
return;
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
});
|
|
372
|
-
// Arrow keys come as escape sequences — handle via process.stdin
|
|
373
|
-
// For simplicity, arrow keys in raw mode are: \x1b[A (up), \x1b[B (down), \x1b[C (right), \x1b[D (left)
|
|
374
|
-
// We handle them in the data handler above by checking for escape sequences
|
|
375
|
-
// Actually the raw mode data comes byte by byte — let me use a state machine approach
|
|
376
|
-
// For now, let me handle the common case: the full escape sequence arrives in one data event
|
|
377
|
-
// Note: Arrow keys are 3 bytes: \x1b [ A/B/C/D. They may arrive in one or multiple data events.
|
|
378
|
-
// In practice on Windows they arrive as one event. Let me add a simple buffered approach.
|
|
379
|
-
stdin.removeAllListeners("data");
|
|
380
|
-
let escBuf = "";
|
|
381
|
-
stdin.on("data", (data) => {
|
|
382
|
-
const str = data.toString();
|
|
383
|
-
escBuf += str;
|
|
384
|
-
// If we have an escape sequence, process it
|
|
385
|
-
if (escBuf.startsWith("\x1b[")) {
|
|
386
|
-
if (escBuf.length >= 3) {
|
|
387
|
-
const code = escBuf[2];
|
|
388
|
-
escBuf = "";
|
|
389
|
-
if (code === "A") {
|
|
390
|
-
if (popup) {
|
|
391
|
-
selIdx = Math.max(0, selIdx - 1);
|
|
392
|
-
}
|
|
393
|
-
else if (_history.length) {
|
|
394
|
-
histIdx = Math.max(0, histIdx - 1);
|
|
395
|
-
buf = _history[histIdx] || "";
|
|
396
|
-
cursor = buf.length;
|
|
397
|
-
}
|
|
398
|
-
render();
|
|
399
|
-
return;
|
|
400
|
-
}
|
|
401
|
-
if (code === "B") {
|
|
402
|
-
if (popup) {
|
|
403
|
-
const f = SLASH_CMDS.filter(c => c[0].toLowerCase().includes(buf.toLowerCase()));
|
|
404
|
-
selIdx = Math.min(f.length - 1, selIdx + 1);
|
|
405
|
-
}
|
|
406
|
-
else if (_history.length && histIdx < _history.length) {
|
|
407
|
-
histIdx++;
|
|
408
|
-
buf = _history[histIdx] || "";
|
|
409
|
-
cursor = buf.length;
|
|
410
|
-
}
|
|
411
|
-
render();
|
|
412
|
-
return;
|
|
413
|
-
}
|
|
414
|
-
if (code === "C") {
|
|
415
|
-
if (cursor < buf.length)
|
|
416
|
-
cursor++;
|
|
417
|
-
if (popup)
|
|
418
|
-
popup = false;
|
|
419
|
-
render();
|
|
420
|
-
return;
|
|
421
|
-
}
|
|
422
|
-
if (code === "D") {
|
|
423
|
-
if (cursor > 0)
|
|
424
|
-
cursor--;
|
|
425
|
-
if (popup)
|
|
426
|
-
popup = false;
|
|
427
|
-
render();
|
|
428
|
-
return;
|
|
429
|
-
}
|
|
430
|
-
}
|
|
431
|
-
else {
|
|
432
|
-
return; /* wait for more bytes */
|
|
433
|
-
}
|
|
434
|
-
}
|
|
435
|
-
// Not an escape sequence — process normally
|
|
436
|
-
for (const ch of escBuf) {
|
|
437
|
-
escBuf = "";
|
|
438
|
-
if (ch === "\x1b") {
|
|
439
|
-
if (popup) {
|
|
440
|
-
popup = false;
|
|
441
|
-
render();
|
|
442
|
-
}
|
|
443
|
-
return;
|
|
444
|
-
}
|
|
445
|
-
if (ch === "\r" || ch === "\n") {
|
|
446
|
-
if (popup && SLASH_CMDS.filter(c => c[0].toLowerCase().includes(buf.toLowerCase())).length) {
|
|
447
|
-
buf = SLASH_CMDS.filter(c => c[0].toLowerCase().includes(buf.toLowerCase()))[selIdx]?.[0] || buf;
|
|
448
|
-
popup = false;
|
|
449
|
-
}
|
|
450
|
-
accept(buf.trim());
|
|
451
|
-
return;
|
|
452
|
-
}
|
|
453
|
-
if (ch === "\t") {
|
|
454
|
-
if (popup && SLASH_CMDS.filter(c => c[0].toLowerCase().includes(buf.toLowerCase())).length) {
|
|
455
|
-
const filtered = SLASH_CMDS.filter(c => c[0].toLowerCase().includes(buf.toLowerCase()));
|
|
456
|
-
buf = filtered[selIdx]?.[0] || buf;
|
|
457
|
-
cursor = buf.length;
|
|
458
|
-
popup = false;
|
|
459
|
-
render();
|
|
460
|
-
return;
|
|
461
|
-
}
|
|
462
|
-
buf = buf.slice(0, cursor) + " " + buf.slice(cursor);
|
|
463
|
-
cursor += 2;
|
|
464
|
-
render();
|
|
465
|
-
return;
|
|
466
|
-
}
|
|
467
|
-
if (ch === "\x7f" || ch === "\b") {
|
|
468
|
-
if (cursor > 0) {
|
|
469
|
-
buf = buf.slice(0, cursor - 1) + buf.slice(cursor);
|
|
470
|
-
cursor--;
|
|
471
|
-
}
|
|
472
|
-
if (!buf)
|
|
473
|
-
popup = false;
|
|
474
|
-
render();
|
|
475
|
-
return;
|
|
476
|
-
}
|
|
477
|
-
if (ch === "\x03") {
|
|
478
|
-
accept("/quit");
|
|
479
|
-
return;
|
|
480
|
-
}
|
|
481
|
-
if (ch >= " ") {
|
|
482
|
-
buf = buf.slice(0, cursor) + ch + buf.slice(cursor);
|
|
483
|
-
cursor++;
|
|
484
|
-
if (buf === "/") {
|
|
485
|
-
popup = true;
|
|
486
|
-
selIdx = 0;
|
|
487
|
-
}
|
|
488
|
-
else if (popup)
|
|
489
|
-
selIdx = 0;
|
|
490
|
-
render();
|
|
491
|
-
return;
|
|
492
|
-
}
|
|
493
|
-
}
|
|
494
|
-
});
|
|
495
|
-
render();
|
|
496
|
-
});
|
|
181
|
+
}
|
|
182
|
+
return out;
|
|
497
183
|
}
|
|
498
184
|
/* ═══════════════════════════════════════
|
|
499
|
-
|
|
185
|
+
Chat loop
|
|
500
186
|
═══════════════════════════════════════ */
|
|
187
|
+
/* Check for API key availability */
|
|
188
|
+
function checkApiKeys() {
|
|
189
|
+
const keys = ["DEEPSEEK_API_KEY", "OPENAI_API_KEY", "ANTHROPIC_API_KEY", "GROQ_API_KEY", "OPENROUTER_API_KEY"];
|
|
190
|
+
for (const k of keys) {
|
|
191
|
+
if (process.env[k])
|
|
192
|
+
return k;
|
|
193
|
+
}
|
|
194
|
+
return null;
|
|
195
|
+
}
|
|
501
196
|
async function chat(agentName, modelOverride) {
|
|
197
|
+
const haveKey = checkApiKeys();
|
|
198
|
+
if (!haveKey) {
|
|
199
|
+
process.stdout.write("\n" + chalk_1.default.yellow(" ⚠ No API key configured.\n"));
|
|
200
|
+
process.stdout.write(chalk_1.default.dim(" Set one: $env:DEEPSEEK_API_KEY = \"sk-your-key\" (PowerShell)\n"));
|
|
201
|
+
process.stdout.write(chalk_1.default.dim(" export DEEPSEEK_API_KEY=sk-your-key (Bash)\n\n"));
|
|
202
|
+
process.stdout.write(chalk_1.default.dim(" Then run: sky\n\n"));
|
|
203
|
+
process.exit(1);
|
|
204
|
+
}
|
|
502
205
|
const ctx = (0, factory_1.createSystemContext)();
|
|
503
206
|
let agent = ctx.agentMap.get(agentName);
|
|
504
207
|
if (!agent) {
|
|
505
|
-
|
|
208
|
+
process.stdout.write(chalk_1.default.red("Unknown agent: " + agentName) + "\n");
|
|
506
209
|
return;
|
|
507
210
|
}
|
|
508
211
|
await agent.init();
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
212
|
+
// eslint-disable-next-line prefer-const
|
|
213
|
+
let currentAgent = agent; // mutable for agent switching
|
|
214
|
+
welcome(agent);
|
|
215
|
+
process.stdout.write(chalk_1.default.dim(" Key: " + haveKey + "\n\n"));
|
|
216
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
217
|
+
function ask() { rl.question(chalk_1.default.cyan(" " + currentAgent.displayName + " ❯ "), handler); }
|
|
218
|
+
async function handler(inp) {
|
|
219
|
+
inp = inp.trim();
|
|
515
220
|
if (!inp) {
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
}
|
|
519
|
-
// Save to history
|
|
520
|
-
if (!inputHistory[inputHistory.length - 1] || inputHistory[inputHistory.length - 1] !== inp) {
|
|
521
|
-
inputHistory.push(inp);
|
|
522
|
-
if (inputHistory.length > 50)
|
|
523
|
-
inputHistory.shift();
|
|
221
|
+
ask();
|
|
222
|
+
return;
|
|
524
223
|
}
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
const cmdLower = cmd.toLowerCase();
|
|
528
|
-
/* ── Slash commands ── */
|
|
529
|
-
let handled = false;
|
|
530
|
-
// Agent switching
|
|
224
|
+
const cmdL = inp.toLowerCase();
|
|
225
|
+
// Agent switch
|
|
531
226
|
for (const n of AGENT_NAMES) {
|
|
532
|
-
if (
|
|
533
|
-
const
|
|
534
|
-
if (
|
|
535
|
-
await
|
|
536
|
-
|
|
537
|
-
logLine(chalk_1.default.dim(`\n ⟳ ${AGENT_DISPLAY[n]}\n`));
|
|
538
|
-
// We can't reassign the outer `agent` const, so use a workaround
|
|
539
|
-
chat._currentAgent = newAgent;
|
|
540
|
-
chat._currentCtx = ctx;
|
|
541
|
-
// Actually, let me handle this differently — replace the agent in the closure
|
|
542
|
-
agent = newAgent;
|
|
227
|
+
if (cmdL === "/" + n) {
|
|
228
|
+
const a = ctx.agentMap.get(n);
|
|
229
|
+
if (a) {
|
|
230
|
+
await a.init();
|
|
231
|
+
currentAgent = a;
|
|
543
232
|
}
|
|
544
|
-
|
|
545
|
-
|
|
233
|
+
process.stdout.write(chalk_1.default.dim(" ⟳ " + AGENT_DISPLAY[n] + "\n"));
|
|
234
|
+
ask();
|
|
235
|
+
return;
|
|
546
236
|
}
|
|
547
237
|
}
|
|
548
|
-
if (
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
if (cmdLower === "/clear") {
|
|
555
|
-
console.clear();
|
|
556
|
-
handled = true;
|
|
557
|
-
}
|
|
558
|
-
if (cmdLower === "/version") {
|
|
559
|
-
logLine(` Skyloom v${VERSION}`);
|
|
560
|
-
handled = true;
|
|
238
|
+
if (cmdL === "/quit" || cmdL === "/exit") {
|
|
239
|
+
process.stdout.write(chalk_1.default.dim("\n Session ended\n"));
|
|
240
|
+
rl.close();
|
|
241
|
+
await ctx.closeAll();
|
|
242
|
+
process.exit(0);
|
|
243
|
+
return;
|
|
561
244
|
}
|
|
562
|
-
if (
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
handled = true;
|
|
245
|
+
if (cmdL === "/help") {
|
|
246
|
+
process.stdout.write(helpText());
|
|
247
|
+
ask();
|
|
248
|
+
return;
|
|
567
249
|
}
|
|
568
|
-
if (
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
if (cmdLower === "/cost reset") {
|
|
575
|
-
ctx.llm.resetUsageStats?.();
|
|
576
|
-
logLine(chalk_1.default.dim(" Stats reset"));
|
|
577
|
-
handled = true;
|
|
578
|
-
}
|
|
579
|
-
if (cmdLower === "/compact") {
|
|
580
|
-
logLine(chalk_1.default.dim(" Compacting..."));
|
|
581
|
-
const r = await agent.compact();
|
|
582
|
-
logLine(chalk_1.default.green(` ✓ ${r}`));
|
|
583
|
-
handled = true;
|
|
584
|
-
}
|
|
585
|
-
if (cmdLower === "/memory") {
|
|
586
|
-
logLine(chalk_1.default.bold("\n Memory"));
|
|
587
|
-
logLine(chalk_1.default.dim(` Short-term: ${agent.memory.shortTerm.length} msgs · Working: ${Object.keys(agent.memory.working).length} keys`));
|
|
588
|
-
handled = true;
|
|
250
|
+
if (cmdL === "/clear") {
|
|
251
|
+
console.clear();
|
|
252
|
+
welcome(agent);
|
|
253
|
+
process.stdout.write(chalk_1.default.dim(" Key: " + haveKey + "\n\n"));
|
|
254
|
+
ask();
|
|
255
|
+
return;
|
|
589
256
|
}
|
|
590
|
-
if (
|
|
591
|
-
|
|
592
|
-
|
|
257
|
+
if (cmdL === "/status") {
|
|
258
|
+
process.stdout.write(chalk_1.default.bold("\n " + currentAgent.displayName + " (" + currentAgent.name + ")\n") + chalk_1.default.dim(" State: " + currentAgent.state + " · Memory: " + currentAgent.memory.shortTerm.length + " msgs\n\n"));
|
|
259
|
+
ask();
|
|
260
|
+
return;
|
|
593
261
|
}
|
|
594
|
-
if (
|
|
595
|
-
|
|
596
|
-
|
|
262
|
+
if (cmdL === "/cost") {
|
|
263
|
+
process.stdout.write(chalk_1.default.bold("\n Total: " + formatCost(ctx.llm.getTotalCost()) + "\n\n"));
|
|
264
|
+
ask();
|
|
265
|
+
return;
|
|
597
266
|
}
|
|
598
|
-
if (
|
|
599
|
-
const
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
logLine(chalk_1.default.dim(` ${s.id?.slice(0, 10)}... ${s.preview || ""} (${s.messageCount || 0} msgs)`));
|
|
604
|
-
}
|
|
605
|
-
}
|
|
606
|
-
else {
|
|
607
|
-
logLine(chalk_1.default.dim(" No saved sessions"));
|
|
608
|
-
}
|
|
609
|
-
handled = true;
|
|
267
|
+
if (cmdL === "/compact") {
|
|
268
|
+
const r = await currentAgent.compact();
|
|
269
|
+
process.stdout.write(chalk_1.default.green(" ✓ " + r + "\n\n"));
|
|
270
|
+
ask();
|
|
271
|
+
return;
|
|
610
272
|
}
|
|
611
|
-
if (
|
|
612
|
-
|
|
613
|
-
|
|
273
|
+
if (cmdL === "/version") {
|
|
274
|
+
process.stdout.write(" Skyloom v" + VERSION + "\n");
|
|
275
|
+
ask();
|
|
276
|
+
return;
|
|
614
277
|
}
|
|
615
|
-
if (
|
|
616
|
-
const
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
handled = true;
|
|
278
|
+
if (cmdL.startsWith("/task ")) {
|
|
279
|
+
const g = inp.slice(6);
|
|
280
|
+
process.stdout.write(chalk_1.default.cyan("\n ✦ " + g + "\n\n"));
|
|
281
|
+
await runTask(g);
|
|
282
|
+
ask();
|
|
283
|
+
return;
|
|
622
284
|
}
|
|
623
|
-
if (
|
|
624
|
-
|
|
625
|
-
|
|
285
|
+
if (inp.startsWith("/")) {
|
|
286
|
+
process.stdout.write(helpText());
|
|
287
|
+
ask();
|
|
288
|
+
return;
|
|
626
289
|
}
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
if (mode === mode_1.InteractiveMode.PLAN) {
|
|
630
|
-
await runTask(cmd);
|
|
631
|
-
logLine("");
|
|
632
|
-
continue;
|
|
633
|
-
}
|
|
634
|
-
const cls = (0, router_1.classify)(cmd);
|
|
635
|
-
if (cls === "orchestrate" && mode !== mode_1.InteractiveMode.AUTO) {
|
|
636
|
-
await runTask(cmd);
|
|
637
|
-
logLine("");
|
|
638
|
-
continue;
|
|
639
|
-
}
|
|
640
|
-
/* ── Chat ── */
|
|
290
|
+
// ── Chat ──
|
|
291
|
+
process.stdout.write(chalk_1.default.dim(" " + currentAgent.displayName + " thinking...\r"));
|
|
641
292
|
try {
|
|
642
|
-
const response = await
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
// Auto-continue
|
|
649
|
-
if (mode === mode_1.InteractiveMode.AUTO) {
|
|
650
|
-
const tail = response.split("\n").slice(-6).join("\n");
|
|
651
|
-
if (/(?:接下来|下一步|继续|next|let me|I'[vl]l)/i.test(tail) && !/(?:完成了|全部完成|all done)/i.test(tail)) {
|
|
652
|
-
logLine(chalk_1.default.yellow(" [auto-continue]\n"));
|
|
653
|
-
try {
|
|
654
|
-
const r2 = await chatWithSpinner(agent, ctx, "请继续完成");
|
|
655
|
-
logLine("");
|
|
656
|
-
for (const line of renderResponse(r2))
|
|
657
|
-
logLine(line);
|
|
658
|
-
logLine("");
|
|
659
|
-
}
|
|
660
|
-
catch { /* ignore */ }
|
|
661
|
-
}
|
|
662
|
-
}
|
|
293
|
+
const response = await currentAgent.chat(inp);
|
|
294
|
+
process.stdout.write("\r" + " ".repeat(40) + "\r\n");
|
|
295
|
+
const lines = render(response);
|
|
296
|
+
for (const l of lines)
|
|
297
|
+
process.stdout.write(l + "\n");
|
|
298
|
+
process.stdout.write("\n");
|
|
663
299
|
}
|
|
664
300
|
catch (e) {
|
|
665
|
-
|
|
301
|
+
process.stdout.write("\r" + " ".repeat(40) + "\r");
|
|
302
|
+
process.stdout.write(chalk_1.default.red(" ✗ " + (e.message || e) + "\n\n"));
|
|
666
303
|
}
|
|
304
|
+
ask();
|
|
667
305
|
}
|
|
668
|
-
|
|
669
|
-
await ctx.closeAll();
|
|
670
|
-
process.exit(0);
|
|
306
|
+
ask();
|
|
671
307
|
}
|
|
672
308
|
/* ═══════════════════════════════════════
|
|
673
|
-
Task
|
|
309
|
+
Task
|
|
674
310
|
═══════════════════════════════════════ */
|
|
675
|
-
async function runTask(goal
|
|
311
|
+
async function runTask(goal) {
|
|
676
312
|
const ctx = (0, factory_1.createSystemContext)();
|
|
677
313
|
await ctx.initAll();
|
|
678
|
-
const [, results, summary] = await (0, factory_1.orchestrateTask)(goal, ctx.agentMap
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
logLine(chalk_1.default.dim(" ─".repeat(30)));
|
|
683
|
-
for (const r of results) {
|
|
684
|
-
logLine(` ${r.success ? chalk_1.default.green("✓") : chalk_1.default.red("✗")} ${chalk_1.default.cyan(r.agent)}: ${r.description.slice(0, 60)}`);
|
|
685
|
-
}
|
|
686
|
-
logLine(chalk_1.default.bold("\n Summary"));
|
|
687
|
-
logLine(chalk_1.default.dim(" ─".repeat(30)));
|
|
688
|
-
logLine(` ${summary.slice(0, 1000)}`);
|
|
689
|
-
logLine("");
|
|
314
|
+
const [, results, summary] = await (0, factory_1.orchestrateTask)(goal, ctx.agentMap);
|
|
315
|
+
for (const r of results)
|
|
316
|
+
process.stdout.write(` ${r.success ? chalk_1.default.green("✓") : chalk_1.default.red("✗")} ${chalk_1.default.cyan(r.agent)}: ${r.description.slice(0, 60)}\n`);
|
|
317
|
+
process.stdout.write(chalk_1.default.bold("\n " + summary.slice(0, 800) + "\n\n"));
|
|
690
318
|
await ctx.closeAll();
|
|
691
319
|
}
|
|
692
|
-
function
|
|
693
|
-
logLine(chalk_1.default.bold("\n Slash Commands"));
|
|
694
|
-
logLine(chalk_1.default.dim(" ─".repeat(40)));
|
|
320
|
+
function helpText() {
|
|
695
321
|
const groups = [
|
|
696
322
|
["Agent", [["/fog /rain /frost", "Switch agents"], ["/snow /dew /fair", "Switch agents"]]],
|
|
697
|
-
["Chat", [["/help", "
|
|
698
|
-
["Info", [["/status", "
|
|
699
|
-
["Orch.", [["/task <goal>", "Multi-agent
|
|
323
|
+
["Chat", [["/help", "Commands"], ["/clear", "Clear"], ["/compact", "Compress"], ["/retry", "Resend"]]],
|
|
324
|
+
["Info", [["/status", "Status"], ["/cost", "Cost"], ["/memory", "Memory"], ["/sessions", "Sessions"], ["/workspace", "Workspace"], ["/version", "Version"]]],
|
|
325
|
+
["Orch.", [["/task <goal>", "Multi-agent"]]],
|
|
700
326
|
];
|
|
327
|
+
let s = "";
|
|
701
328
|
for (const [title, cmds] of groups) {
|
|
702
|
-
|
|
329
|
+
s += chalk_1.default.cyan(` ${title}\n`);
|
|
703
330
|
for (const [c, d] of cmds)
|
|
704
|
-
|
|
331
|
+
s += ` ${chalk_1.default.cyan(c.padEnd(18))}${chalk_1.default.dim(d)}\n`;
|
|
705
332
|
}
|
|
706
|
-
|
|
333
|
+
s += "\n";
|
|
334
|
+
return s;
|
|
707
335
|
}
|
|
708
336
|
/* ═══════════════════════════════════════
|
|
709
337
|
Entry
|
|
@@ -716,19 +344,17 @@ async function main() {
|
|
|
716
344
|
}
|
|
717
345
|
if (AGENT_NAMES.includes(args[0])) {
|
|
718
346
|
let m;
|
|
719
|
-
for (let i = 1; i < args.length; i++)
|
|
347
|
+
for (let i = 1; i < args.length; i++)
|
|
720
348
|
if ((args[i] === "-m" || args[i] === "--model") && i + 1 < args.length)
|
|
721
349
|
m = args[++i];
|
|
722
|
-
}
|
|
723
350
|
await chat(args[0], m);
|
|
724
351
|
return;
|
|
725
352
|
}
|
|
726
|
-
|
|
727
|
-
if (!subCmds.includes(args[0]) && !args[0].startsWith("-")) {
|
|
353
|
+
if (!["chat", "task", "web", "config", "init", "version", "mcp", "help"].includes(args[0]) && !args[0].startsWith("-")) {
|
|
728
354
|
await chat("fog");
|
|
729
355
|
return;
|
|
730
356
|
}
|
|
731
357
|
program.parse(process.argv);
|
|
732
358
|
}
|
|
733
|
-
main().catch(e => {
|
|
359
|
+
main().catch(e => { process.stderr.write(chalk_1.default.red(`Fatal: ${e.message}\n`)); process.exit(1); });
|
|
734
360
|
//# sourceMappingURL=main.js.map
|