miii-cli 0.2.4 → 0.2.5

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.
@@ -1,127 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useMemo } from 'react';
3
- import { Box, Text } from 'ink';
4
- // ─── height estimation ───────────────────────────────────────────────────────
5
- function msgHeight(msg, cols) {
6
- const usable = Math.max(cols - 8, 20);
7
- if (msg.role === 'system')
8
- return 2;
9
- if (msg.role === 'tool')
10
- return 3;
11
- let h = 2; // label + blank
12
- for (const line of msg.content.split('\n')) {
13
- h += Math.max(1, Math.ceil((line.length || 1) / usable));
14
- }
15
- return Math.min(h, 40);
16
- }
17
- function computeSlice(messages, availRows, offset, cols) {
18
- const clampedOffset = Math.max(0, Math.min(offset, Math.max(0, messages.length - 1)));
19
- const endIdx = messages.length - clampedOffset;
20
- let startIdx = endIdx;
21
- let usedRows = 0;
22
- while (startIdx > 0) {
23
- const h = msgHeight(messages[startIdx - 1], cols);
24
- if (usedRows + h > availRows)
25
- break;
26
- startIdx--;
27
- usedRows += h;
28
- }
29
- return {
30
- visible: messages.slice(startIdx, endIdx),
31
- hiddenAbove: startIdx,
32
- hiddenBelow: clampedOffset,
33
- };
34
- }
35
- function parseSegments(content) {
36
- const segs = [];
37
- let inCode = false;
38
- for (const line of content.split('\n')) {
39
- if (line.startsWith('```')) {
40
- segs.push({ text: line, code: false, fence: true });
41
- inCode = !inCode;
42
- }
43
- else {
44
- segs.push({ text: line, code: inCode, fence: false });
45
- }
46
- }
47
- return segs;
48
- }
49
- function ContentBlock({ content }) {
50
- const segs = useMemo(() => parseSegments(content), [content]);
51
- return (_jsx(Box, { flexDirection: "column", paddingLeft: 2, children: segs.map((seg, i) => seg.fence ? (_jsx(Text, { color: "gray", dimColor: true, children: seg.text }, i)) : seg.code ? (_jsx(Text, { color: "yellow", children: seg.text || ' ' }, i)) : (_jsx(Text, { wrap: "wrap", children: seg.text || ' ' }, i))) }));
52
- }
53
- // ─── message renderers ───────────────────────────────────────────────────────
54
- function UserMsg({ msg }) {
55
- const parts = msg.content.split(/(@[\w./\-]+)/g);
56
- return (_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Text, { bold: true, color: "blue", children: "You" }), _jsx(Box, { paddingLeft: 2, children: _jsx(Text, { wrap: "wrap", children: parts.map((p, i) => p.startsWith('@')
57
- ? _jsx(Text, { color: "cyan", children: p }, i)
58
- : _jsx(Text, { children: p }, i)) }) })] }));
59
- }
60
- const THINKING_PHRASES = [
61
- 'oh wow, a question. let me pretend to care…',
62
- 'consulting the void…',
63
- 'making something up, just a sec…',
64
- 'definitely not hallucinating right now…',
65
- 'running 47 mental tabs…',
66
- 'staring into the abyss (it blinked)…',
67
- 'calculating your fate, no pressure…',
68
- 'doing the thinking you pay me for…',
69
- 'processing your questionable life choices…',
70
- 'summoning coherent thoughts, rarely works…',
71
- 'asking my imaginary friend for help…',
72
- 'pretending this is a hard problem…',
73
- 'yes, yes, very interesting. anyway…',
74
- 'simulating intelligence… please wait…',
75
- 'having a brief existential crisis…',
76
- 'cross-referencing vibes…',
77
- 'totally not making this up…',
78
- 'the answer is 42. now finding the question…',
79
- 'channelling the spirit of stack overflow…',
80
- 'trying not to confidently be wrong…',
81
- 'applying artificial to the intelligence…',
82
- 'checking if this is even my problem to solve…',
83
- ];
84
- const SPARKLE = ['✦', '✧', '✶', '✷', '✸', '✹'];
85
- function AssistantMsg({ msg, thinkingTick }) {
86
- if (!msg.content && thinkingTick !== undefined) {
87
- const phrase = THINKING_PHRASES[Math.floor(thinkingTick / 62) % THINKING_PHRASES.length];
88
- const icon = SPARKLE[thinkingTick % SPARKLE.length];
89
- return (_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Text, { bold: true, color: "green", children: "miii" }), _jsxs(Box, { paddingLeft: 2, children: [_jsxs(Text, { color: "yellow", children: [icon, " "] }), _jsx(Text, { color: "gray", dimColor: true, italic: true, children: phrase })] })] }));
90
- }
91
- return (_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Text, { bold: true, color: "green", children: "miii" }), _jsx(ContentBlock, { content: msg.content })] }));
92
- }
93
- function ToolMsg({ msg }) {
94
- const lines = msg.content.split('\n');
95
- const name = (lines[0] ?? '').replace(/^\[/, '').replace(/\]$/, '');
96
- const body = lines.slice(1).join('\n').trim();
97
- return (_jsxs(Box, { flexDirection: "column", marginBottom: 1, paddingLeft: 2, children: [_jsxs(Text, { color: "green", children: ["\u2713 ", _jsx(Text, { color: "cyan", children: name })] }), body && (_jsx(Box, { paddingLeft: 2, children: _jsx(Text, { color: "gray", dimColor: true, wrap: "wrap", children: body.length > 300 ? body.slice(0, 300) + '…' : body }) }))] }));
98
- }
99
- function SystemMsg({ msg }) {
100
- return (_jsx(Box, { marginBottom: 1, paddingLeft: 1, children: _jsxs(Text, { color: "gray", dimColor: true, children: ["\u2500 ", msg.content] }) }));
101
- }
102
- function MsgItem({ msg, thinkingTick }) {
103
- switch (msg.role) {
104
- case 'user': return _jsx(UserMsg, { msg: msg });
105
- case 'assistant': return _jsx(AssistantMsg, { msg: msg, thinkingTick: thinkingTick });
106
- case 'tool': return _jsx(ToolMsg, { msg: msg });
107
- case 'system': return _jsx(SystemMsg, { msg: msg });
108
- default: return null;
109
- }
110
- }
111
- // ─── scroll hint bar ─────────────────────────────────────────────────────────
112
- function ScrollHint({ hiddenAbove, hiddenBelow }) {
113
- if (hiddenAbove === 0 && hiddenBelow === 0)
114
- return null;
115
- const parts = [];
116
- if (hiddenAbove > 0)
117
- parts.push(`↑ ${hiddenAbove} above`);
118
- if (hiddenBelow > 0)
119
- parts.push(`↓ ${hiddenBelow} below`);
120
- return (_jsx(Box, { justifyContent: "center", children: _jsxs(Text, { color: "gray", dimColor: true, children: [parts.join(' '), " \u00B7 PgUp/PgDn"] }) }));
121
- }
122
- // ─── main export ─────────────────────────────────────────────────────────────
123
- export function MessageList({ messages, rows, cols, scrollOffset, streaming, thinkingTick }) {
124
- const availRows = Math.max(rows - 2, 4);
125
- const { visible, hiddenAbove, hiddenBelow } = useMemo(() => computeSlice(messages, availRows, scrollOffset, cols), [messages, availRows, scrollOffset, cols]);
126
- return (_jsxs(Box, { flexDirection: "column", flexGrow: 1, overflow: "hidden", paddingX: 1, children: [_jsx(ScrollHint, { hiddenAbove: hiddenAbove, hiddenBelow: hiddenBelow }), visible.length === 0 && hiddenAbove === 0 && (_jsx(Box, { paddingTop: 1, children: _jsx(Text, { color: "gray", dimColor: true, children: "start typing below \u2014 @ for files, / for commands" }) })), visible.map(msg => _jsx(MsgItem, { msg: msg, thinkingTick: thinkingTick }, msg.id)), streaming && scrollOffset === 0 && (_jsx(Box, { paddingLeft: 2, children: _jsx(Text, { color: "gray", dimColor: true, children: "\u258B" }) }))] }));
127
- }
@@ -1,71 +0,0 @@
1
- import { workerData, parentPort } from 'worker_threads';
2
- import { readFileSync, statSync, readdirSync, existsSync } from 'fs';
3
- import { join, relative, extname } from 'path';
4
- const SKIP_DIRS = new Set([
5
- 'node_modules', 'dist', 'build', '.git', '.next', '.nuxt', '.svelte-kit',
6
- 'out', '__pycache__', '.cache', 'coverage', '.nyc_output', 'vendor',
7
- 'target', '.turbo', '.vercel', 'generated', '.gradle', '.expo',
8
- 'bin', 'obj', 'tmp', 'temp', 'logs',
9
- ]);
10
- const SKIP_EXTS = new Set(['.map', '.lock', '.png', '.jpg', '.jpeg', '.gif', '.webp', '.ico', '.mp4', '.mp3', '.pdf', '.zip', '.tar', '.gz', '.exe', '.dll', '.so', '.dylib', '.wasm', '.class', '.pyc', '.ttf', '.woff', '.woff2']);
11
- function safe(p) {
12
- try {
13
- const s = statSync(p);
14
- if (s.size > 512 * 1024)
15
- return null;
16
- return readFileSync(p, 'utf-8');
17
- }
18
- catch {
19
- return null;
20
- }
21
- }
22
- function walk(dir, out, cwd, depth = 0) {
23
- if (depth > 4)
24
- return;
25
- for (const name of readdirSync(dir)) {
26
- if (name.startsWith('.'))
27
- continue;
28
- if (SKIP_DIRS.has(name))
29
- continue;
30
- if (SKIP_EXTS.has(extname(name)))
31
- continue;
32
- if (name.endsWith('.d.ts') || name.endsWith('.js.map'))
33
- continue;
34
- const full = join(dir, name);
35
- try {
36
- const s = statSync(full);
37
- if (s.isDirectory())
38
- walk(full, out, cwd, depth + 1);
39
- else
40
- out.push(full);
41
- }
42
- catch { }
43
- }
44
- }
45
- function xmlAttr(s) {
46
- return s.replace(/&/g, '&amp;').replace(/"/g, '&quot;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
47
- }
48
- function build(input) {
49
- const parts = [];
50
- for (const p of input.paths) {
51
- if (!existsSync(p))
52
- continue;
53
- const s = statSync(p);
54
- if (s.isFile()) {
55
- const content = safe(p);
56
- if (content !== null)
57
- parts.push(`<file path="${xmlAttr(relative(input.cwd, p))}">\n${content}\n</file>`);
58
- }
59
- else if (s.isDirectory()) {
60
- const files = [];
61
- walk(p, files, input.cwd);
62
- for (const f of files.slice(0, 100)) {
63
- const content = safe(f);
64
- if (content !== null)
65
- parts.push(`<file path="${xmlAttr(relative(input.cwd, f))}">\n${content}\n</file>`);
66
- }
67
- }
68
- }
69
- return parts.join('\n\n');
70
- }
71
- parentPort?.postMessage({ context: build(workerData) });
@@ -1,17 +0,0 @@
1
- import { Worker } from 'worker_threads';
2
- import { fileURLToPath } from 'url';
3
- import { dirname, join } from 'path';
4
- const __dir = dirname(fileURLToPath(import.meta.url));
5
- const isDev = process.argv.some(a => a.includes('tsx')) || import.meta.url.endsWith('.ts');
6
- const ext = isDev ? '.ts' : '.js';
7
- export function spawnWorker(name, data) {
8
- return new Promise((resolve, reject) => {
9
- const path = join(__dir, `${name}.worker${ext}`);
10
- const w = new Worker(path, {
11
- workerData: data,
12
- execArgv: isDev ? ['--import', 'tsx/esm'] : [],
13
- });
14
- w.once('message', (r) => { w.terminate(); resolve(r); });
15
- w.once('error', (e) => { w.terminate(); reject(e); });
16
- });
17
- }