@make-u-free/migi 0.4.3 → 0.4.4

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 (2) hide show
  1. package/bin/migi.js +31 -32
  2. package/package.json +1 -1
package/bin/migi.js CHANGED
@@ -86,47 +86,46 @@ async function readChatInput() {
86
86
  const lines = ['']
87
87
  let curLine = 0
88
88
  let drawnLines = 0
89
- let lastLineCount = 0
90
- let cursorLine = 0 // カーソルが実際にいる物理行(drawn area 先頭からの offset)
89
+ let cursorLine = 0 // カーソルの物理行(drawn area 先頭からの offset)
91
90
 
92
91
  emitKeypressEvents(process.stdin)
93
92
  if (process.stdin.isTTY) process.stdin.setRawMode(true)
94
93
 
95
94
  function draw() {
96
95
  const w = process.stdout.columns || 80
97
-
98
- // 行数が変わっていない(通常の文字入力)→ 現在行だけ上書き。セパレーター・ガイドは触らない
99
- if (lines.length === lastLineCount && drawnLines > 0) {
100
- const prefix = curLine === 0 ? PFIRST : PCONT
101
- process.stdout.write('\r\x1b[K' + chalk.cyan(prefix) + lines[curLine])
102
- cursorLine = curLine
103
- return
104
- }
105
-
106
- // 行数変化 or 初回 → 全体を再描画
107
- lastLineCount = lines.length
108
- const allLines = [
96
+ const newLines = [
109
97
  ...lines.map((l, i) => chalk.cyan(i === 0 ? PFIRST : PCONT) + l),
110
- chalk.dim('─'.repeat(w)),
111
- chalk.dim(` ✦ ${model} · Shift+Enterで改行 / Enterで送信`)
98
+ chalk.dim('─'.repeat(w - 1)), // w-1: 行末での自動折り返し防止
99
+ chalk.dim(` ✦ ${model} · Alt+Enterで改行 / Enterで送信`)
112
100
  ]
101
+ const oldDrawnLines = drawnLines
102
+ drawnLines = newLines.length
113
103
 
114
104
  let buf = ''
115
- if (drawnLines > 0) {
116
- // cursorLine = カーソルの現在位置。先頭行まで戻ってから全行クリア
117
- if (cursorLine > 0) buf += `\x1b[${cursorLine}A`
118
- buf += `\x1b[1G`
119
- for (let i = 0; i < drawnLines; i++) buf += '\x1b[2K\n'
120
- buf += `\x1b[${drawnLines}A\x1b[1G`
105
+
106
+ // ① drawn area 先頭まで戻る(cursorLine = カーソルが今いる物理行)
107
+ if (cursorLine > 0) buf += `\x1b[${cursorLine}A`
108
+ buf += '\r'
109
+
110
+ // 各行を上書き。「先クリア→描画」ではなく「描画→行末クリア」でちらつき防止
111
+ for (let i = 0; i < newLines.length; i++) {
112
+ buf += newLines[i] + '\x1b[K'
113
+ if (i < newLines.length - 1) buf += '\r\n'
114
+ }
115
+
116
+ // ③ 行数が減った場合、余分な古い行をクリア
117
+ for (let i = newLines.length; i < oldDrawnLines; i++) {
118
+ buf += '\r\n\x1b[2K'
121
119
  }
122
120
 
123
- drawnLines = allLines.length
124
- buf += allLines.join('\n') + '\n'
121
+ // curLine の行まで戻る
122
+ const linesFromBottom = drawnLines - 1 - curLine
123
+ if (linesFromBottom > 0) buf += `\x1b[${linesFromBottom}A`
124
+ buf += '\r'
125
125
 
126
- const linesBelow = drawnLines - curLine
127
- if (linesBelow > 0) buf += `\x1b[${linesBelow}A`
128
- const col = (curLine === 0 ? PFIRST : PCONT).length + lines[curLine].length + 1
129
- buf += `\x1b[${col}G`
126
+ // カーソルを入力内容の末尾へ
127
+ const prefix = curLine === 0 ? PFIRST : PCONT
128
+ buf += `\x1b[${prefix.length + lines[curLine].length + 1}G`
130
129
 
131
130
  cursorLine = curLine
132
131
  process.stdout.write(buf)
@@ -141,7 +140,7 @@ async function readChatInput() {
141
140
  }
142
141
 
143
142
  if (key.ctrl && key.name === 'c') {
144
- process.stdout.write(`\x1b[${drawnLines - curLine}B\n`)
143
+ process.stdout.write(`\x1b[${drawnLines - 1 - curLine}B\n`)
145
144
  process.stdin.removeListener('keypress', onKey)
146
145
  if (process.stdin.isTTY) process.stdin.setRawMode(false)
147
146
  console.log(chalk.cyan('\n お疲れ様でした!またね。\n'))
@@ -149,8 +148,8 @@ async function readChatInput() {
149
148
  }
150
149
 
151
150
  if (key.name === 'return') {
152
- if (key.shift) {
153
- // Shift+Enter 改行
151
+ // Alt+Enter(macOS: Option+Enter)または Shift+Enter → 改行
152
+ if (key.meta || key.shift) {
154
153
  lines.splice(curLine + 1, 0, '')
155
154
  curLine++
156
155
  draw()
@@ -158,7 +157,7 @@ async function readChatInput() {
158
157
  // Enter → 送信
159
158
  const content = lines.join('\n').trim()
160
159
  if (!content) return
161
- process.stdout.write(`\x1b[${drawnLines - curLine}B\n`)
160
+ process.stdout.write(`\x1b[${drawnLines - 1 - curLine}B\n`)
162
161
  process.stdin.removeListener('keypress', onKey)
163
162
  if (process.stdin.isTTY) process.stdin.setRawMode(false)
164
163
  resolve(content)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@make-u-free/migi",
3
- "version": "0.4.3",
3
+ "version": "0.4.4",
4
4
  "description": "Your AI right-hand agent. Works anywhere, with any LLM API.",
5
5
  "type": "module",
6
6
  "bin": {