kiku-agent 1.0.0

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.
Files changed (45) hide show
  1. package/README.md +122 -0
  2. package/package.json +85 -0
  3. package/server/agent/agentCore.js +782 -0
  4. package/server/agent/agentState.js +140 -0
  5. package/server/agent/audioPlayer.js +673 -0
  6. package/server/agent/cli.js +1111 -0
  7. package/server/agent/commandRegistry.js +58 -0
  8. package/server/agent/commands.js +788 -0
  9. package/server/agent/config.js +90 -0
  10. package/server/agent/errors.js +9 -0
  11. package/server/agent/eventBus.js +103 -0
  12. package/server/agent/llmClient.js +200 -0
  13. package/server/agent/memory.js +566 -0
  14. package/server/agent/sanitizer.js +314 -0
  15. package/server/agent/session.js +239 -0
  16. package/server/agent/theme.js +124 -0
  17. package/server/agent/tools.js +1528 -0
  18. package/server/agent/ui.js +469 -0
  19. package/server/agent/webSearch.js +719 -0
  20. package/server/agent/youtubeAuth.js +299 -0
  21. package/server/mcp/claude-desktop-config.example.json +9 -0
  22. package/server/mcp/data/awards.js +14 -0
  23. package/server/mcp/data/brands.js +9 -0
  24. package/server/mcp/data/discography.js +36 -0
  25. package/server/mcp/data/gallery.js +25 -0
  26. package/server/mcp/data/index.js +7 -0
  27. package/server/mcp/data/profile.js +44 -0
  28. package/server/mcp/data/timeline.js +16 -0
  29. package/server/mcp/data/works.js +104 -0
  30. package/server/mcp/handler.js +159 -0
  31. package/server/mcp/prompts.js +143 -0
  32. package/server/mcp/resources.js +54 -0
  33. package/server/mcp/security.js +138 -0
  34. package/server/mcp/server.js +100 -0
  35. package/server/mcp/stdio.js +33 -0
  36. package/server/mcp/tools.js +126 -0
  37. package/src/data/awardsData.js +146 -0
  38. package/src/data/brandsData.js +249 -0
  39. package/src/data/discographyData.js +874 -0
  40. package/src/data/galleryData.js +666 -0
  41. package/src/data/musicVideoData.js +406 -0
  42. package/src/data/profileData.js +156 -0
  43. package/src/data/socialUpdatesData.js +381 -0
  44. package/src/data/timelineData.js +172 -0
  45. package/src/data/worksData.js +516 -0
@@ -0,0 +1,469 @@
1
+ import readline from 'node:readline';
2
+ import { stdin as input, stdout as output } from 'node:process';
3
+ import { eventBus, Events } from './eventBus.js';
4
+ import { AgentStates } from './agentState.js';
5
+ import { ansiBackground, ansiForeground, getThemePalette } from './theme.js';
6
+
7
+
8
+ export const C = Object.freeze({
9
+ reset: '\x1b[0m',
10
+ bold: '\x1b[1m',
11
+ dim: '\x1b[2m',
12
+ italic: '\x1b[3m',
13
+ underline: '\x1b[4m',
14
+
15
+ get sakura() { return ansiForeground(getThemePalette().primary); },
16
+ get roseGlow() { return ansiForeground(getThemePalette().secondary); },
17
+ get gold() { return ansiForeground(getThemePalette().highlight); },
18
+ get amber() { return ansiForeground(getThemePalette().warning); },
19
+ get cyberCyan() { return ansiForeground(getThemePalette().info); },
20
+ get emerald() { return ansiForeground(getThemePalette().success); },
21
+ get lavender() { return ansiForeground(getThemePalette().tertiary); },
22
+ get slate() { return ansiForeground(getThemePalette().muted); },
23
+ get darkGray() { return ansiForeground(getThemePalette().subdued); },
24
+ get white() { return ansiForeground(getThemePalette().text); },
25
+ get red() { return ansiForeground(getThemePalette().error); },
26
+ get bgPanel() { return ansiBackground(getThemePalette().panel); },
27
+ get bgPanelHeader() { return ansiBackground(getThemePalette().panelHeader); },
28
+ get bgDark() { return ansiBackground(getThemePalette().panel); },
29
+ get bgTool() { return ansiBackground(getThemePalette().panel); },
30
+ get bgToolResult() { return ansiBackground(getThemePalette().panel); },
31
+ get bgToolError() { return ansiBackground(getThemePalette().panel); },
32
+ get bgThinking() { return ansiBackground(getThemePalette().panel); },
33
+ get bgResponse() { return ansiBackground(getThemePalette().panel); },
34
+ get bgError() { return ansiBackground(getThemePalette().panel); },
35
+ });
36
+
37
+ const _rawStdoutWrite = process.stdout.write.bind(process.stdout);
38
+ const _rawConsoleLog = console.log.bind(console);
39
+ const _rawConsoleClear = console.clear.bind(console);
40
+
41
+
42
+
43
+ export const spinnerFrames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
44
+ export const processingFrames = spinnerFrames;
45
+ export const thinkingFrames = spinnerFrames;
46
+ export const successFrames = ['OK'];
47
+ export const pulseFrames = ['▓', '▒', '░', '▒', '▓', '█', '▓', '▒'];
48
+ export const INPUT_PLACEHOLDER = 'Ask about Ju Jingyi or type / for commands';
49
+ export const UI_ICONS = Object.freeze({
50
+ help: '📖',
51
+ music: '🎵',
52
+ sponsor: '📢',
53
+ });
54
+
55
+ const fanNames = ['Mìjú / 蜜橘'];
56
+ export function randomFanName() {
57
+ return fanNames[Math.floor(Math.random() * fanNames.length)];
58
+ }
59
+
60
+
61
+
62
+ const graphemeSegmenter = typeof Intl?.Segmenter === 'function'
63
+ ? new Intl.Segmenter(undefined, { granularity: 'grapheme' })
64
+ : null;
65
+
66
+ function fallbackGraphemeSegments(str) {
67
+ const segments = [];
68
+ let index = 0;
69
+
70
+ for (const char of Array.from(str)) {
71
+ const isContinuation = segments.length > 0 && (
72
+ /^\p{Mark}$/u.test(char) ||
73
+ /^\p{Emoji_Modifier}$/u.test(char) ||
74
+ char === '\uFE0F' ||
75
+ char === '\u20E3' ||
76
+ segments.at(-1).segment.endsWith('\u200D') ||
77
+ char === '\u200D'
78
+ );
79
+
80
+ if (isContinuation) {
81
+ segments.at(-1).segment += char;
82
+ segments.at(-1).end += char.length;
83
+ } else {
84
+ segments.push({ segment: char, index, end: index + char.length });
85
+ }
86
+ index += char.length;
87
+ }
88
+
89
+ return segments;
90
+ }
91
+
92
+
93
+ export function getGraphemeSegments(str) {
94
+ if (!str) return [];
95
+ if (!graphemeSegmenter) return fallbackGraphemeSegments(str);
96
+ return Array.from(graphemeSegmenter.segment(str), ({ segment, index }) => ({
97
+ segment,
98
+ index,
99
+ end: index + segment.length,
100
+ }));
101
+ }
102
+
103
+ export function previousGraphemeBoundary(str, cursor) {
104
+ const safeCursor = Math.max(0, Math.min(str.length, cursor));
105
+ let previous = 0;
106
+ for (const item of getGraphemeSegments(str)) {
107
+ if (item.end >= safeCursor) return item.index;
108
+ previous = item.end;
109
+ }
110
+ return previous;
111
+ }
112
+
113
+ export function nextGraphemeBoundary(str, cursor) {
114
+ const safeCursor = Math.max(0, Math.min(str.length, cursor));
115
+ for (const item of getGraphemeSegments(str)) {
116
+ if (item.end > safeCursor) return item.end;
117
+ }
118
+ return str.length;
119
+ }
120
+
121
+ function getGraphemeDisplayWidth(segment) {
122
+ if (/\p{Extended_Pictographic}|\p{Regional_Indicator}/u.test(segment) || /[\uFE0F\u20E3]/u.test(segment)) {
123
+ return 2;
124
+ }
125
+
126
+ let width = 0;
127
+ for (const char of Array.from(segment)) {
128
+ const code = char.codePointAt(0);
129
+ if (/^\p{Mark}$/u.test(char) || code === 0x200D || (code >= 0xFE00 && code <= 0xFE0F)) continue;
130
+ if (
131
+ (code >= 0x1100 && code <= 0x11FF) ||
132
+ (code >= 0x2E80 && code <= 0x9FFF) ||
133
+ (code >= 0xAC00 && code <= 0xD7A3) ||
134
+ (code >= 0xF900 && code <= 0xFAFF) ||
135
+ (code >= 0xFE30 && code <= 0xFE4F)
136
+ ) {
137
+ width += 2;
138
+ } else {
139
+ width += 1;
140
+ }
141
+ }
142
+ return width;
143
+ }
144
+
145
+
146
+ export function getStringDisplayWidth(str) {
147
+ if (!str) return 0;
148
+ const clean = str.replace(/\x1b\[[0-9;]*[a-zA-Z]/g, '');
149
+ return getGraphemeSegments(clean).reduce((width, item) => width + getGraphemeDisplayWidth(item.segment), 0);
150
+ }
151
+
152
+
153
+ export function sliceLineForDisplay(str, cursor, maxWidth) {
154
+ const segments = getGraphemeSegments(str).map(item => ({
155
+ ...item,
156
+ width: getGraphemeDisplayWidth(item.segment),
157
+ }));
158
+ const safeMaxWidth = Math.max(1, maxWidth);
159
+ const totalWidth = segments.reduce((sum, item) => sum + item.width, 0);
160
+ const safeCursor = Math.max(0, Math.min(str.length, cursor));
161
+
162
+ let cursorIndex = segments.findIndex(item => item.index >= safeCursor);
163
+ if (cursorIndex === -1) cursorIndex = segments.length;
164
+
165
+ if (totalWidth <= safeMaxWidth) {
166
+ return {
167
+ displayLine: str,
168
+ cursorVisualOffset: segments.slice(0, cursorIndex).reduce((sum, item) => sum + item.width, 0),
169
+ };
170
+ }
171
+
172
+ let start = cursorIndex;
173
+ let end = cursorIndex;
174
+ let contentWidth = 0;
175
+ let leftWidth = 0;
176
+ let rightWidth = 0;
177
+
178
+ while (true) {
179
+ const candidates = [];
180
+ if (start > 0) {
181
+ const nextStart = start - 1;
182
+ const markerWidth = (nextStart > 0 ? 1 : 0) + (end < segments.length ? 1 : 0);
183
+ const width = segments[nextStart].width;
184
+ if (contentWidth + width + markerWidth <= safeMaxWidth) {
185
+ candidates.push({ side: 'left', width, balance: leftWidth });
186
+ }
187
+ }
188
+ if (end < segments.length) {
189
+ const nextEnd = end + 1;
190
+ const markerWidth = (start > 0 ? 1 : 0) + (nextEnd < segments.length ? 1 : 0);
191
+ const width = segments[end].width;
192
+ if (contentWidth + width + markerWidth <= safeMaxWidth) {
193
+ candidates.push({ side: 'right', width, balance: rightWidth });
194
+ }
195
+ }
196
+ if (candidates.length === 0) break;
197
+
198
+ candidates.sort((a, b) => a.balance - b.balance || a.width - b.width);
199
+ const selected = candidates[0];
200
+ if (selected.side === 'left') {
201
+ start--;
202
+ leftWidth += selected.width;
203
+ } else {
204
+ rightWidth += selected.width;
205
+ end++;
206
+ }
207
+ contentWidth += selected.width;
208
+ }
209
+
210
+ const hasLeftEllipsis = start > 0;
211
+ const hasRightEllipsis = end < segments.length;
212
+ const displayLine = `${hasLeftEllipsis ? '…' : ''}${segments.slice(start, end).map(item => item.segment).join('')}${hasRightEllipsis ? '…' : ''}`;
213
+ const cursorVisualOffset = (hasLeftEllipsis ? 1 : 0) + segments
214
+ .slice(start, cursorIndex)
215
+ .reduce((sum, item) => sum + item.width, 0);
216
+
217
+ return { displayLine, cursorVisualOffset };
218
+ }
219
+
220
+ export function getFullWidth() {
221
+ return process.stdout.columns || 80;
222
+ }
223
+
224
+
225
+
226
+ export function wrapText(text, maxWidth = 72) {
227
+ if (!text) return [];
228
+ const lines = [];
229
+ const rawParagraphs = text.split('\n');
230
+
231
+ for (const para of rawParagraphs) {
232
+ if (!para.trim()) {
233
+ lines.push('');
234
+ continue;
235
+ }
236
+
237
+ const words = para.split(/\s+/);
238
+ let currentLine = '';
239
+
240
+ for (const word of words) {
241
+ if (!word) continue;
242
+ const testLine = currentLine ? (currentLine + ' ' + word) : word;
243
+ const testWidth = getStringDisplayWidth(testLine);
244
+
245
+ if (testWidth <= maxWidth) {
246
+ currentLine = testLine;
247
+ } else {
248
+ if (currentLine) {
249
+ lines.push(currentLine);
250
+ currentLine = word;
251
+ } else {
252
+ let chunk = '';
253
+ for (const ch of word) {
254
+ if (getStringDisplayWidth(chunk + ch) <= maxWidth) {
255
+ chunk += ch;
256
+ } else {
257
+ lines.push(chunk);
258
+ chunk = ch;
259
+ }
260
+ }
261
+ currentLine = chunk;
262
+ }
263
+ }
264
+ }
265
+ if (currentLine) {
266
+ lines.push(currentLine);
267
+ }
268
+ }
269
+ return lines;
270
+ }
271
+
272
+
273
+
274
+ export function stripAnsi(str) {
275
+ return str.replace(/\x1b\[[0-9;]*m/g, '');
276
+ }
277
+
278
+
279
+ export function fitStyledText(styledText, maxWidth) {
280
+ const safeWidth = Math.max(0, maxWidth);
281
+ let result = '';
282
+ let usedWidth = 0;
283
+ const tokens = String(styledText || '').split(/(\x1b\[[0-9;]*[a-zA-Z])/g);
284
+
285
+ for (const token of tokens) {
286
+ if (!token) continue;
287
+ if (/^\x1b\[[0-9;]*[a-zA-Z]$/.test(token)) {
288
+ result += token;
289
+ continue;
290
+ }
291
+ for (const item of getGraphemeSegments(token)) {
292
+ const itemWidth = getGraphemeDisplayWidth(item.segment);
293
+ if (usedWidth + itemWidth > safeWidth) return result;
294
+ result += item.segment;
295
+ usedWidth += itemWidth;
296
+ }
297
+ }
298
+ return result;
299
+ }
300
+
301
+
302
+
303
+ export function printSolidBannerRow(styledText, targetWidth, requestedBg = C.bgPanel, indent = '') {
304
+ const terminalWidth = getFullWidth();
305
+ const rowWidth = Math.max(1, Math.min(targetWidth || terminalWidth, terminalWidth) - 1);
306
+ const contentWidth = Math.max(0, rowWidth - getStringDisplayWidth(indent));
307
+ const fitted = fitStyledText(styledText, contentWidth);
308
+ const background = requestedBg === C.bgPanelHeader ? C.bgPanelHeader : C.bgPanel;
309
+ const fixedStyled = fitted.replace(/\x1b\[0m/g, C.reset + background + C.white);
310
+
311
+ console.log(indent + background + C.white + fixedStyled + '\x1b[0K' + C.reset);
312
+ }
313
+
314
+ export function printSolidPanel({ title, lines, width, indent = '' }) {
315
+ const w = width || getFullWidth();
316
+ if (title) {
317
+ printSolidBannerRow(`${indent} ${C.bold}${C.roseGlow}${title}${C.reset}`, w, C.bgPanelHeader);
318
+ }
319
+ for (const raw of lines) {
320
+ const text = typeof raw === 'string' ? raw : raw.text;
321
+ printSolidBannerRow(`${indent} ${text}`, w, C.bgPanel);
322
+ }
323
+ console.log('');
324
+ }
325
+
326
+
327
+
328
+ export function formatTerminalMarkdown(text) {
329
+ if (!text) return '';
330
+ return text
331
+ .replace(/^###\s*(.+)$/gm, `${C.bold}${C.gold}✦ $1${C.reset}`)
332
+ .replace(/^##\s*(.+)$/gm, `\n${C.bold}${C.roseGlow}$1${C.reset}`)
333
+ .replace(/^#\s*(.+)$/gm, `\n${C.bold}${C.sakura}━━━ $1 ━━━${C.reset}`)
334
+ .replace(/\[([^\]]+)\]\((https?:\/\/[^\s)]+)\)/g, `${C.bold}${C.cyberCyan}$1${C.reset} ➔ ${C.underline}${C.roseGlow}$2${C.reset}`)
335
+ .replace(/\*{3}([^*]+)\*{3}/g, `${C.bold}${C.italic}${C.white}$1${C.reset}`)
336
+ .replace(/\*\*([^*]+)\*\*/g, `${C.bold}${C.white}$1${C.reset}`)
337
+ .replace(/(?<!\*)\*([^\*\n]+)\*(?!\*)/g, `${C.italic}${C.white}$1${C.reset}`)
338
+ .replace(/`([^`]+)`/g, `${C.cyberCyan}$1${C.reset}`)
339
+ .replace(/^(\s*)[*•-]\s+/gm, `$1 ${C.sakura}•${C.reset} `)
340
+ .replace(/^\s*[-*_]{3,}\s*$/gm, ` ${C.slate}${'─'.repeat(Math.max(20, getFullWidth() - 6))}${C.reset}`);
341
+ }
342
+
343
+
344
+ export function parseMarkdownTableRow(text) {
345
+ const trimmed = String(text || '').trim();
346
+ if (!trimmed.includes('|')) return null;
347
+
348
+ const content = trimmed
349
+ .replace(/^\|/, '')
350
+ .replace(/\|$/, '');
351
+ const cells = content
352
+ .split(/(?<!\\)\|/)
353
+ .map(cell => cell.trim().replace(/\\\|/g, '|'));
354
+
355
+ return cells.length >= 2 ? cells : null;
356
+ }
357
+
358
+
359
+ export function isMarkdownTableSeparator(cells) {
360
+ return Array.isArray(cells)
361
+ && cells.length > 0
362
+ && cells.every(cell => /^:?-{3,}:?$/.test(cell.replace(/\s+/g, '')));
363
+ }
364
+
365
+
366
+ export function expandMarkdownLinks(text) {
367
+ return String(text || '').replace(
368
+ /\[([^\]]+)\]\((https?:\/\/[^\s)]+)\)/g,
369
+ '$1: $2'
370
+ );
371
+ }
372
+
373
+
374
+
375
+ export function printWelcomeHero() {
376
+ console.log(`\n${C.sakura} ██╗ ██╗██╗██╗ ██╗██╗ ██╗ █████╗ ██╗${C.reset}\n${C.sakura} ██║ ██╔╝██║██║ ██╔╝██║ ██║ ██╔══██╗██║${C.reset}\n${C.roseGlow} █████═╝ ██║█████═╝ ██║ ██║ ███████║██║${C.reset}\n${C.roseGlow} ██╔═██╗ ██║██╔═██╗ ██║ ██║ ██╔══██║██║${C.reset}\n${C.sakura} ██║ ╚██╗██║██║ ╚██╗╚██████╔╝ ██║ ██║██║${C.reset}\n${C.sakura} ╚═╝ ╚═╝╚═╝╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝╚═╝${C.reset}\n\n${C.bold}${C.roseGlow}Example Questions:${C.reset}\n ${C.dim}•${C.reset} ${C.white}"What are Ju Jingyi's 2026 upcoming drama series?"${C.reset}\n ${C.dim}•${C.reset} ${C.white}"Tell me about her Global Brand Ambassador roles in 2026."${C.reset}\n ${C.dim}•${C.reset} ${C.white}"Search the internet for Ju Jingyi's latest news."${C.reset}\n ${C.dim}•${C.reset} ${C.white}"What OST songs are from The Blooms at Ruyi Pavilion?"${C.reset}\n${C.lavender}Quick Commands:${C.reset} ${C.cyberCyan}/help${C.reset} ${C.dim}•${C.reset} ${C.emerald}/history${C.reset} ${C.dim}•${C.reset} ${C.emerald}/lang${C.reset} ${C.dim}•${C.reset} ${C.emerald}/session${C.reset} ${C.dim}•${C.reset} ${C.emerald}/tool${C.reset} ${C.dim}•${C.reset} ${C.emerald}/mem${C.reset} ${C.dim}•${C.reset} ${C.emerald}/play${C.reset} ${C.dim}•${C.reset} ${C.emerald}/pause${C.reset} ${C.dim}•${C.reset} ${C.emerald}/next${C.reset} ${C.dim}•${C.reset} ${C.emerald}/search${C.reset} ${C.dim}•${C.reset} ${C.emerald}/current${C.reset} ${C.dim}•${C.reset} ${C.emerald}/ads${C.reset} ${C.dim}(Tab or ↑/↓ to navigate / commands)${C.reset}\n`);
377
+ }
378
+
379
+
380
+
381
+
382
+ export function setupOutputInterception(tuiPrompt, _isProcessingFn) {
383
+ let isTuiWriting = false;
384
+ let isReplaying = false;
385
+ let resizeTimer = null;
386
+ const transcript = [];
387
+ const MAX_TRANSCRIPT_ENTRIES = 2500;
388
+
389
+ const remember = (entry) => {
390
+ if (isReplaying) return;
391
+ transcript.push(entry);
392
+ if (transcript.length > MAX_TRANSCRIPT_ENTRIES) {
393
+ transcript.splice(0, transcript.length - MAX_TRANSCRIPT_ENTRIES);
394
+ }
395
+ };
396
+
397
+ process.stdout.write = function (chunk, encoding, callback) {
398
+ if (!isTuiWriting && !isReplaying) remember({ type: 'write', chunk: String(chunk) });
399
+ if (tuiPrompt && tuiPrompt.activeResolve && !isTuiWriting) {
400
+ isTuiWriting = true;
401
+ try {
402
+ tuiPrompt.clearPrompt();
403
+ return _rawStdoutWrite(chunk, encoding, callback);
404
+ } finally {
405
+ tuiPrompt.render();
406
+ isTuiWriting = false;
407
+ }
408
+ }
409
+ return _rawStdoutWrite(chunk, encoding, callback);
410
+ };
411
+
412
+ console.log = function (...args) {
413
+ if (!isReplaying) remember({ type: 'log', args: [...args] });
414
+ if (tuiPrompt && tuiPrompt.activeResolve && !isTuiWriting) {
415
+ isTuiWriting = true;
416
+ try {
417
+ tuiPrompt.clearPrompt();
418
+ _rawConsoleLog(...args);
419
+ } finally {
420
+ tuiPrompt.render();
421
+ isTuiWriting = false;
422
+ }
423
+ } else {
424
+ const wasTuiWriting = isTuiWriting;
425
+ isTuiWriting = true;
426
+ try { _rawConsoleLog(...args); }
427
+ finally { isTuiWriting = wasTuiWriting; }
428
+ }
429
+ };
430
+
431
+ console.clear = function () {
432
+ transcript.length = 0;
433
+ _rawConsoleClear();
434
+ };
435
+
436
+ process.stdout.on('resize', () => {
437
+ if (resizeTimer) clearTimeout(resizeTimer);
438
+ resizeTimer = setTimeout(() => {
439
+ resizeTimer = null;
440
+ if (!tuiPrompt || !tuiPrompt.activeResolve) return;
441
+
442
+ isTuiWriting = true;
443
+ isReplaying = true;
444
+ try {
445
+ tuiPrompt.lastRenderedLines = 0;
446
+ tuiPrompt.hasTopPadding = false;
447
+ _rawStdoutWrite('\x1b[?25l\x1b[2J\x1b[H');
448
+ printWelcomeHero();
449
+ for (const entry of transcript) {
450
+ if (entry.type === 'log') _rawConsoleLog(...entry.args);
451
+ else _rawStdoutWrite(entry.chunk);
452
+ }
453
+ tuiPrompt.render();
454
+ } finally {
455
+ _rawStdoutWrite('\x1b[?25h');
456
+ isReplaying = false;
457
+ isTuiWriting = false;
458
+ }
459
+ }, 120);
460
+ });
461
+ }
462
+
463
+ export function restoreOutput() {
464
+ process.stdout.write = _rawStdoutWrite;
465
+ console.log = _rawConsoleLog;
466
+ console.clear = _rawConsoleClear;
467
+ }
468
+
469
+ export { _rawStdoutWrite as rawWrite, _rawConsoleLog as rawLog };