@make-u-free/migi 0.5.17 → 0.5.19
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/bin/migi.js +66 -21
- package/package.json +1 -1
package/bin/migi.js
CHANGED
|
@@ -75,9 +75,10 @@ const agent = new MigiAgent({ context, promptFn, apiKey, model, name: agentName,
|
|
|
75
75
|
try {
|
|
76
76
|
await agent.chat(
|
|
77
77
|
`起動した。以下の手順で今日の状況を確認して、簡潔にダッシュボードを表示してから、今一番優先すべきことを1つだけ提案して:\n` +
|
|
78
|
-
`1. todos/${today}.md を read_file
|
|
79
|
-
`2. .
|
|
80
|
-
`3.
|
|
78
|
+
`1. todos/${today}.md を read_file で読んで未完了タスクを確認(ファイルがなければスキップ)\n` +
|
|
79
|
+
`2. search_content で「- \\[ \\]」を .company/ ディレクトリ全体から検索して、部署ごとの未完了タスクも集約する\n` +
|
|
80
|
+
`3. .migi/memory/next-actions.md があれば読む\n` +
|
|
81
|
+
`4. todos/ と .company/ の両方を合わせたダッシュボード(未完了の件数サマリー、ソース別)をコンパクトに出して、一言で「今日はこれから」と提案する\n` +
|
|
81
82
|
`(詳細な説明はいらない。テンポよく)`
|
|
82
83
|
)
|
|
83
84
|
} catch (err) {
|
|
@@ -127,14 +128,14 @@ async function readChatInput() {
|
|
|
127
128
|
const PCONT = ' '
|
|
128
129
|
const lines = ['']
|
|
129
130
|
let curLine = 0
|
|
131
|
+
let cursorPos = 0 // 行内のカーソル位置(文字インデックス)
|
|
130
132
|
let drawnLines = 0
|
|
131
|
-
let cursorLine = 0
|
|
133
|
+
let cursorLine = 0 // カーソルの物理行(drawn area 先頭からの offset)
|
|
132
134
|
let drawPending = false
|
|
133
135
|
|
|
134
136
|
emitKeypressEvents(process.stdin)
|
|
135
137
|
if (process.stdin.isTTY) process.stdin.setRawMode(true)
|
|
136
138
|
|
|
137
|
-
// ペースト等の連続入力をまとめて1回の描画にするためのデバウンス
|
|
138
139
|
function scheduleDraw() {
|
|
139
140
|
if (drawPending) return
|
|
140
141
|
drawPending = true
|
|
@@ -145,7 +146,7 @@ async function readChatInput() {
|
|
|
145
146
|
const w = process.stdout.columns || 80
|
|
146
147
|
const newLines = [
|
|
147
148
|
...lines.map((l, i) => chalk.cyan(i === 0 ? PFIRST : PCONT) + l),
|
|
148
|
-
chalk.dim('─'.repeat(w - 1)),
|
|
149
|
+
chalk.dim('─'.repeat(w - 1)),
|
|
149
150
|
chalk.dim(` ✦ ${model} · Alt+Enterで改行 / Enterで送信`)
|
|
150
151
|
]
|
|
151
152
|
const oldDrawnLines = drawnLines
|
|
@@ -153,30 +154,25 @@ async function readChatInput() {
|
|
|
153
154
|
|
|
154
155
|
let buf = ''
|
|
155
156
|
|
|
156
|
-
// ① drawn area 先頭まで戻る(cursorLine = カーソルが今いる物理行)
|
|
157
157
|
if (cursorLine > 0) buf += `\x1b[${cursorLine}A`
|
|
158
158
|
buf += '\r'
|
|
159
159
|
|
|
160
|
-
// ② 各行を上書き。「先クリア→描画」ではなく「描画→行末クリア」でちらつき防止
|
|
161
160
|
for (let i = 0; i < newLines.length; i++) {
|
|
162
161
|
buf += newLines[i] + '\x1b[K'
|
|
163
162
|
if (i < newLines.length - 1) buf += '\r\n'
|
|
164
163
|
}
|
|
165
164
|
|
|
166
|
-
// ③ 行数が減った場合、余分な古い行をクリア
|
|
167
165
|
for (let i = newLines.length; i < oldDrawnLines; i++) {
|
|
168
166
|
buf += '\r\n\x1b[2K'
|
|
169
167
|
}
|
|
170
168
|
|
|
171
|
-
// ④ curLine の行まで戻る
|
|
172
|
-
// step②+③後のカーソル位置は max(新行数, 旧行数)-1 行目
|
|
173
169
|
const linesFromBottom = Math.max(drawnLines, oldDrawnLines) - 1 - curLine
|
|
174
170
|
if (linesFromBottom > 0) buf += `\x1b[${linesFromBottom}A`
|
|
175
171
|
buf += '\r'
|
|
176
172
|
|
|
177
|
-
//
|
|
173
|
+
// カーソルをcursorPosの位置へ(末尾ではなく現在位置)
|
|
178
174
|
const prefix = curLine === 0 ? PFIRST : PCONT
|
|
179
|
-
buf += `\x1b[${prefix.length + displayWidth(lines[curLine]) + 1}G`
|
|
175
|
+
buf += `\x1b[${prefix.length + displayWidth(lines[curLine].slice(0, cursorPos)) + 1}G`
|
|
180
176
|
|
|
181
177
|
cursorLine = curLine
|
|
182
178
|
process.stdout.write(buf)
|
|
@@ -186,7 +182,11 @@ async function readChatInput() {
|
|
|
186
182
|
|
|
187
183
|
const onKey = (str, key) => {
|
|
188
184
|
if (!key) {
|
|
189
|
-
if (str) {
|
|
185
|
+
if (str) {
|
|
186
|
+
lines[curLine] = lines[curLine].slice(0, cursorPos) + str + lines[curLine].slice(cursorPos)
|
|
187
|
+
cursorPos += str.length
|
|
188
|
+
scheduleDraw()
|
|
189
|
+
}
|
|
190
190
|
return
|
|
191
191
|
}
|
|
192
192
|
|
|
@@ -195,17 +195,19 @@ async function readChatInput() {
|
|
|
195
195
|
process.stdout.write(`\x1b[${drawnLines - 1 - curLine}B\n`)
|
|
196
196
|
process.stdin.removeListener('keypress', onKey)
|
|
197
197
|
if (process.stdin.isTTY) process.stdin.setRawMode(false)
|
|
198
|
-
resolve(null)
|
|
198
|
+
resolve(null)
|
|
199
199
|
}
|
|
200
200
|
|
|
201
201
|
if (key.name === 'return') {
|
|
202
|
-
// Alt+Enter(macOS: Option+Enter)または Shift+Enter → 改行
|
|
203
202
|
if (key.meta || key.shift) {
|
|
204
|
-
|
|
203
|
+
// カーソル位置で行を分割して改行
|
|
204
|
+
const rest = lines[curLine].slice(cursorPos)
|
|
205
|
+
lines[curLine] = lines[curLine].slice(0, cursorPos)
|
|
206
|
+
lines.splice(curLine + 1, 0, rest)
|
|
205
207
|
curLine++
|
|
208
|
+
cursorPos = 0
|
|
206
209
|
scheduleDraw()
|
|
207
210
|
} else {
|
|
208
|
-
// Enter → 送信(保留中の描画があれば先に確定)
|
|
209
211
|
if (drawPending) { drawPending = false; draw() }
|
|
210
212
|
const content = lines.join('\n').trim()
|
|
211
213
|
if (!content) return
|
|
@@ -218,10 +220,15 @@ async function readChatInput() {
|
|
|
218
220
|
}
|
|
219
221
|
|
|
220
222
|
if (key.name === 'backspace') {
|
|
221
|
-
if (
|
|
222
|
-
lines[curLine] = lines[curLine].slice(0, -1)
|
|
223
|
+
if (cursorPos > 0) {
|
|
224
|
+
lines[curLine] = lines[curLine].slice(0, cursorPos - 1) + lines[curLine].slice(cursorPos)
|
|
225
|
+
cursorPos--
|
|
223
226
|
scheduleDraw()
|
|
224
227
|
} else if (curLine > 0) {
|
|
228
|
+
// 行頭でbackspace → 前の行に結合
|
|
229
|
+
const prev = lines[curLine - 1]
|
|
230
|
+
cursorPos = prev.length
|
|
231
|
+
lines[curLine - 1] = prev + lines[curLine]
|
|
225
232
|
lines.splice(curLine, 1)
|
|
226
233
|
curLine--
|
|
227
234
|
scheduleDraw()
|
|
@@ -229,8 +236,46 @@ async function readChatInput() {
|
|
|
229
236
|
return
|
|
230
237
|
}
|
|
231
238
|
|
|
239
|
+
if (key.name === 'delete') {
|
|
240
|
+
if (cursorPos < lines[curLine].length) {
|
|
241
|
+
lines[curLine] = lines[curLine].slice(0, cursorPos) + lines[curLine].slice(cursorPos + 1)
|
|
242
|
+
scheduleDraw()
|
|
243
|
+
}
|
|
244
|
+
return
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
if (key.name === 'left') {
|
|
248
|
+
if (cursorPos > 0) { cursorPos--; scheduleDraw() }
|
|
249
|
+
else if (curLine > 0) { curLine--; cursorPos = lines[curLine].length; scheduleDraw() }
|
|
250
|
+
return
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
if (key.name === 'right') {
|
|
254
|
+
if (cursorPos < lines[curLine].length) { cursorPos++; scheduleDraw() }
|
|
255
|
+
else if (curLine < lines.length - 1) { curLine++; cursorPos = 0; scheduleDraw() }
|
|
256
|
+
return
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
if (key.name === 'up' && curLine > 0) {
|
|
260
|
+
curLine--
|
|
261
|
+
cursorPos = Math.min(cursorPos, lines[curLine].length)
|
|
262
|
+
scheduleDraw()
|
|
263
|
+
return
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
if (key.name === 'down' && curLine < lines.length - 1) {
|
|
267
|
+
curLine++
|
|
268
|
+
cursorPos = Math.min(cursorPos, lines[curLine].length)
|
|
269
|
+
scheduleDraw()
|
|
270
|
+
return
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
if (key.name === 'home') { cursorPos = 0; scheduleDraw(); return }
|
|
274
|
+
if (key.name === 'end') { cursorPos = lines[curLine].length; scheduleDraw(); return }
|
|
275
|
+
|
|
232
276
|
if (str && !key.ctrl && !key.meta) {
|
|
233
|
-
lines[curLine]
|
|
277
|
+
lines[curLine] = lines[curLine].slice(0, cursorPos) + str + lines[curLine].slice(cursorPos)
|
|
278
|
+
cursorPos += str.length
|
|
234
279
|
scheduleDraw()
|
|
235
280
|
}
|
|
236
281
|
}
|