kiku-agent 1.0.6 → 1.0.8
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/LICENSE +621 -0
- package/README.md +317 -31
- package/package.json +96 -93
- package/server/agent/agentCore.js +58 -31
- package/server/agent/cli.js +101 -56
- package/server/agent/commandFeatures.js +517 -0
- package/server/agent/commandInput.js +113 -0
- package/server/agent/commandRegistry.js +124 -10
- package/server/agent/commands.js +383 -10
- package/server/agent/config.js +64 -48
- package/server/agent/jobManager.js +96 -0
- package/server/agent/llmClient.js +26 -19
- package/server/agent/mcpClient.js +68 -11
- package/server/agent/memory.js +87 -14
- package/server/agent/modelManager.js +30 -13
- package/server/agent/quizData.js +384 -0
- package/server/agent/terminalImage.js +248 -0
- package/server/agent/tools.js +153 -43
- package/server/agent/ui.js +67 -21
- package/server/agent/youtubeAuth.js +1 -2
- package/src/assets/images/0040jbadgy1id6amcqte3j62c0340qv602.jpg +0 -0
- package/src/assets/images/0040jbadly8icq3if7twwj60qy0qy0uc02.jpg +0 -0
package/server/agent/ui.js
CHANGED
|
@@ -228,13 +228,28 @@ export function wrapText(text, maxWidth = 72) {
|
|
|
228
228
|
const lines = [];
|
|
229
229
|
const rawParagraphs = text.split('\n');
|
|
230
230
|
|
|
231
|
+
const tokenize = para => {
|
|
232
|
+
const raw = para.split(/\s+/).filter(Boolean);
|
|
233
|
+
const tokens = [];
|
|
234
|
+
for (let i = 0; i < raw.length; i++) {
|
|
235
|
+
if (raw[i] === '•' && i + 1 < raw.length) {
|
|
236
|
+
tokens.push('• ' + raw[i + 1]);
|
|
237
|
+
i++;
|
|
238
|
+
} else {
|
|
239
|
+
tokens.push(raw[i]);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
return tokens;
|
|
243
|
+
};
|
|
244
|
+
|
|
231
245
|
for (const para of rawParagraphs) {
|
|
232
246
|
if (!para.trim()) {
|
|
233
247
|
lines.push('');
|
|
234
248
|
continue;
|
|
235
249
|
}
|
|
236
250
|
|
|
237
|
-
const words = para
|
|
251
|
+
const words = tokenize(para);
|
|
252
|
+
const paraLines = [];
|
|
238
253
|
let currentLine = '';
|
|
239
254
|
|
|
240
255
|
for (const word of words) {
|
|
@@ -246,7 +261,7 @@ export function wrapText(text, maxWidth = 72) {
|
|
|
246
261
|
currentLine = testLine;
|
|
247
262
|
} else {
|
|
248
263
|
if (currentLine) {
|
|
249
|
-
|
|
264
|
+
paraLines.push(currentLine);
|
|
250
265
|
currentLine = word;
|
|
251
266
|
} else {
|
|
252
267
|
let chunk = '';
|
|
@@ -254,7 +269,7 @@ export function wrapText(text, maxWidth = 72) {
|
|
|
254
269
|
if (getStringDisplayWidth(chunk + ch) <= maxWidth) {
|
|
255
270
|
chunk += ch;
|
|
256
271
|
} else {
|
|
257
|
-
|
|
272
|
+
paraLines.push(chunk);
|
|
258
273
|
chunk = ch;
|
|
259
274
|
}
|
|
260
275
|
}
|
|
@@ -262,9 +277,19 @@ export function wrapText(text, maxWidth = 72) {
|
|
|
262
277
|
}
|
|
263
278
|
}
|
|
264
279
|
}
|
|
265
|
-
if (currentLine)
|
|
266
|
-
|
|
280
|
+
if (currentLine) paraLines.push(currentLine);
|
|
281
|
+
|
|
282
|
+
if (paraLines.length >= 2 && !/\s/.test(paraLines[paraLines.length - 1].trim())) {
|
|
283
|
+
const last = paraLines[paraLines.length - 1];
|
|
284
|
+
const prev = paraLines[paraLines.length - 2];
|
|
285
|
+
const candidate = prev + ' ' + last;
|
|
286
|
+
if (getStringDisplayWidth(candidate) <= maxWidth) {
|
|
287
|
+
paraLines[paraLines.length - 2] = candidate;
|
|
288
|
+
paraLines.pop();
|
|
289
|
+
}
|
|
267
290
|
}
|
|
291
|
+
|
|
292
|
+
lines.push(...paraLines);
|
|
268
293
|
}
|
|
269
294
|
return lines;
|
|
270
295
|
}
|
|
@@ -829,7 +854,7 @@ export function formatMarkdownLines(text, maxWidth = getFullWidth() - 8) {
|
|
|
829
854
|
return result;
|
|
830
855
|
}
|
|
831
856
|
|
|
832
|
-
export function getWelcomeHeroLines() {
|
|
857
|
+
export function getWelcomeHeroLines() {
|
|
833
858
|
const p = C.sakura;
|
|
834
859
|
const r = C.roseGlow;
|
|
835
860
|
const g = C.gold;
|
|
@@ -841,7 +866,8 @@ export function getWelcomeHeroLines() {
|
|
|
841
866
|
const b = C.bold;
|
|
842
867
|
const d = C.dim;
|
|
843
868
|
const rst = C.reset;
|
|
844
|
-
const boxWidth = Math.min(84, Math.max(50, getFullWidth() - 4));
|
|
869
|
+
const boxWidth = Math.min(84, Math.max(50, getFullWidth() - 4));
|
|
870
|
+
const compact = getFullWidth() < 120;
|
|
845
871
|
const headerTitle = 'Suggested Topics & Queries';
|
|
846
872
|
const topDashCount = Math.max(2, boxWidth - getStringDisplayWidth(headerTitle) - 6);
|
|
847
873
|
const innerWidth = boxWidth - 2;
|
|
@@ -854,14 +880,28 @@ export function getWelcomeHeroLines() {
|
|
|
854
880
|
return ` ${s}│${rst} ${icon} ${tag}${rst}${' '.repeat(Math.max(0, tagWidth - getStringDisplayWidth(tag)))} ${w}${text}${rst}${' '.repeat(pad)}${s}│${rst}`;
|
|
855
881
|
};
|
|
856
882
|
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
` ${p}██╗ ██╗██╗██╗ ██╗██╗ ██╗ █████╗ ██╗${rst}
|
|
860
|
-
` ${
|
|
861
|
-
|
|
862
|
-
` ${
|
|
863
|
-
` ${p}██║
|
|
864
|
-
` ${
|
|
883
|
+
const heroLines = compact ? [
|
|
884
|
+
` ${b}${p}◆ Ju Jingyi • 鞠婧祎 • Mìjú Terminal Portal ◆${rst}`,
|
|
885
|
+
` ${p}██╗ ██╗██╗██╗ ██╗██╗ ██╗ █████╗ ██╗${rst}`,
|
|
886
|
+
` ${r}█████═╝ ██║█████═╝ ██║ ██║ ███████║██║${rst}`,
|
|
887
|
+
] : [
|
|
888
|
+
` ${p}██╗ ██╗██╗██╗ ██╗██╗ ██╗ █████╗ ██╗${rst} ${b}${p}◆ Ju Jingyi • 鞠婧祎 • Mìjú Terminal Portal ◆${rst}`,
|
|
889
|
+
` ${p}██║ ██╔╝██║██║ ██╔╝██║ ██║ ██╔══██╗██║${rst} ${d}${s}Interactive Fan Knowledge Base & Autonomous Agent${rst}`,
|
|
890
|
+
` ${r}█████═╝ ██║█████═╝ ██║ ██║ ███████║██║${rst} ${d}${s}Filmography • Discography • Fashion & Awards${rst}`,
|
|
891
|
+
` ${r}██╔═██╗ ██║██╔═██╗ ██║ ██║ ██╔══██╗██║${rst} ${c}● Live Ready${rst} ${s}• Multilingual (CN / EN / TH)${rst}`,
|
|
892
|
+
` ${p}██║ ╚██╗██║██║ ╚██╗╚██████╔╝ ██║ ██║██║${rst}`,
|
|
893
|
+
` ${p}╚═╝ ╚═╝╚═╝╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝╚═╝${rst}`,
|
|
894
|
+
];
|
|
895
|
+
const shortcutLines = compact ? [
|
|
896
|
+
` ${s}Shortcuts: ${b}${w}[Tab]${rst} ${s}Commands • ${b}${w}[↑/↓]${rst} ${s}History • ${b}${w}[F2]${rst} ${s}Details${rst}`,
|
|
897
|
+
` ${b}${w}[PgUp/PgDn]${rst} ${s}Scroll • ${b}${w}[Ctrl+C]${rst} ${s}Exit${rst}`,
|
|
898
|
+
] : [
|
|
899
|
+
` ${s}Shortcuts: ${b}${w}[Tab]${rst} ${s}Autocomplete • ${b}${w}[↑/↓]${rst} ${s}History • ${b}${w}[PgUp/PgDn]${rst} ${s}Scroll • ${b}${w}[F2]${rst} ${s}Details • ${b}${w}[Ctrl+C]${rst} ${s}Exit${rst}`,
|
|
900
|
+
];
|
|
901
|
+
|
|
902
|
+
return [
|
|
903
|
+
...(compact ? [] : ['']),
|
|
904
|
+
...heroLines,
|
|
865
905
|
'',
|
|
866
906
|
` ${s}╭──${rst} ${b}${g}${headerTitle}${rst} ${s}${'─'.repeat(topDashCount)}╮${rst}`,
|
|
867
907
|
padItem(p + '◆', '2026 Works', '"What are Ju Jingyi\'s 2026 upcoming dramas?"'),
|
|
@@ -870,7 +910,7 @@ export function getWelcomeHeroLines() {
|
|
|
870
910
|
padItem(l + '◆', 'Tools / MCP', '"@search_works 2026, /mcp list, /stats, /help"'),
|
|
871
911
|
` ${s}╰${'─'.repeat(boxWidth)}╯${rst}`,
|
|
872
912
|
'',
|
|
873
|
-
|
|
913
|
+
...shortcutLines,
|
|
874
914
|
'',
|
|
875
915
|
];
|
|
876
916
|
}
|
|
@@ -1040,7 +1080,7 @@ export function exitAlternateScreen() {
|
|
|
1040
1080
|
}
|
|
1041
1081
|
}
|
|
1042
1082
|
|
|
1043
|
-
export function getTuiViewportLayout(termRows = 24) {
|
|
1083
|
+
export function getTuiViewportLayout(termRows = 24) {
|
|
1044
1084
|
const parsedRows = Number(termRows);
|
|
1045
1085
|
const rows = Math.max(10, Number.isFinite(parsedRows) ? Math.floor(parsedRows) : 24);
|
|
1046
1086
|
const viewportStartRow = 1;
|
|
@@ -1055,10 +1095,16 @@ export function getTuiViewportLayout(termRows = 24) {
|
|
|
1055
1095
|
statusBarRow,
|
|
1056
1096
|
promptRow,
|
|
1057
1097
|
separatorRow,
|
|
1058
|
-
};
|
|
1059
|
-
}
|
|
1060
|
-
|
|
1061
|
-
export
|
|
1098
|
+
};
|
|
1099
|
+
}
|
|
1100
|
+
|
|
1101
|
+
export function getNewOutputScrollOffset(addedLineCount, termRows = 24, currentOffset = 0) {
|
|
1102
|
+
const added = Math.max(0, Number.isFinite(Number(addedLineCount)) ? Math.floor(Number(addedLineCount)) : 0);
|
|
1103
|
+
if (currentOffset > 0) return currentOffset + added;
|
|
1104
|
+
return Math.max(0, added - getTuiViewportLayout(termRows).viewportHeight);
|
|
1105
|
+
}
|
|
1106
|
+
|
|
1107
|
+
export class VirtualScreenBuffer {
|
|
1062
1108
|
constructor(width = 80, height = 24, writer = null) {
|
|
1063
1109
|
this.width = Math.max(10, width);
|
|
1064
1110
|
this.height = Math.max(5, height);
|
|
@@ -8,6 +8,7 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
|
8
8
|
const ENV_PATH = path.resolve(__dirname, '..', '..', '.env');
|
|
9
9
|
const AUTH_CONFIG_PATH = path.join(KIKU_DATA_DIR, 'yt_auth.json');
|
|
10
10
|
const SECURE_COOKIE_PATH = path.join(KIKU_DATA_DIR, 'cookies.txt');
|
|
11
|
+
loadEnv();
|
|
11
12
|
const YTDLP_CMD = process.env.KIKU_YTDLP || 'yt-dlp';
|
|
12
13
|
|
|
13
14
|
|
|
@@ -374,5 +375,3 @@ export function getCookieStatus() {
|
|
|
374
375
|
authConfigPath: AUTH_CONFIG_PATH
|
|
375
376
|
};
|
|
376
377
|
}
|
|
377
|
-
|
|
378
|
-
loadEnv();
|
|
Binary file
|
|
Binary file
|