@make-u-free/migi 0.5.20 → 0.5.21
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 +54 -20
- package/package.json +1 -1
- package/src/agent.js +3 -2
package/bin/migi.js
CHANGED
|
@@ -73,18 +73,28 @@ const agent = new MigiAgent({ context, promptFn, apiKey, model, name: agentName,
|
|
|
73
73
|
const today = new Date().toISOString().split('T')[0]
|
|
74
74
|
console.log('\n' + chalk.bold.cyan(`─── ${agentName} `) + chalk.dim('─'.repeat(Math.max(0, (process.stdout.columns || 80) - agentName.length - 5))))
|
|
75
75
|
try {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
76
|
+
const _abort = new AbortController()
|
|
77
|
+
const _sigint = () => { process.stdout.write(chalk.yellow('\n キャンセルしました\n')); _abort.abort() }
|
|
78
|
+
process.once('SIGINT', _sigint)
|
|
79
|
+
try {
|
|
80
|
+
await agent.chat(
|
|
81
|
+
`起動した。以下の手順で今日の状況を確認して、簡潔にダッシュボードを表示してから、今一番優先すべきことを1つだけ提案して:\n` +
|
|
82
|
+
`1. todos/${today}.md を read_file で読んで未完了タスクを確認(ファイルがなければスキップ)\n` +
|
|
83
|
+
`2. search_content で「- \\[ \\]」を .company/ ディレクトリ全体から検索して、部署ごとの未完了タスクも集約する\n` +
|
|
84
|
+
`3. .migi/memory/next-actions.md があれば読む\n` +
|
|
85
|
+
`4. todos/ と .company/ の両方を合わせたダッシュボード(未完了の件数サマリー、ソース別)をコンパクトに出して、一言で「今日はこれから」と提案する\n` +
|
|
86
|
+
` - 未完了タスクは 1. 2. 3. と通し番号を付けて表示する(ファイルには書かない、表示だけ)\n` +
|
|
87
|
+
` - ユーザーが「N番完了」と言ったら、その番号のタスクを特定してファイルの [ ] を [x] に書き換える\n` +
|
|
88
|
+
`(詳細な説明はいらない。テンポよく)`,
|
|
89
|
+
_abort.signal
|
|
90
|
+
)
|
|
91
|
+
} finally {
|
|
92
|
+
process.removeListener('SIGINT', _sigint)
|
|
93
|
+
}
|
|
86
94
|
} catch (err) {
|
|
87
|
-
|
|
95
|
+
if (err.name !== 'AbortError') {
|
|
96
|
+
console.error(chalk.red(' 起動チェック失敗: ' + err.message))
|
|
97
|
+
}
|
|
88
98
|
}
|
|
89
99
|
}
|
|
90
100
|
|
|
@@ -193,11 +203,22 @@ async function readChatInput() {
|
|
|
193
203
|
}
|
|
194
204
|
|
|
195
205
|
if (key.ctrl && key.name === 'c') {
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
206
|
+
const isEmpty = lines.every(l => l.length === 0)
|
|
207
|
+
if (!isEmpty) {
|
|
208
|
+
// バッファをクリアして再描画(終了しない)
|
|
209
|
+
lines.splice(0, lines.length, '')
|
|
210
|
+
curLine = 0
|
|
211
|
+
cursorPos = 0
|
|
212
|
+
scheduleDraw()
|
|
213
|
+
} else {
|
|
214
|
+
// 空の状態で Ctrl+C → ヒントだけ出してそのまま
|
|
215
|
+
process.stdout.write(`\x1b[${drawnLines - 1 - curLine}B\r\n`)
|
|
216
|
+
process.stdout.write(chalk.dim(' 終了するには /exit を入力してください') + '\r\n')
|
|
217
|
+
drawnLines = 0
|
|
218
|
+
cursorLine = 0
|
|
219
|
+
draw()
|
|
220
|
+
}
|
|
221
|
+
return
|
|
201
222
|
}
|
|
202
223
|
|
|
203
224
|
if (key.name === 'return') {
|
|
@@ -340,6 +361,14 @@ async function prompt() {
|
|
|
340
361
|
return prompt()
|
|
341
362
|
}
|
|
342
363
|
|
|
364
|
+
// --- Ctrl+C で処理キャンセル(アプリ継続)---
|
|
365
|
+
const abortController = new AbortController()
|
|
366
|
+
const sigintHandler = () => {
|
|
367
|
+
process.stdout.write(chalk.yellow('\n キャンセルしました\n'))
|
|
368
|
+
abortController.abort()
|
|
369
|
+
}
|
|
370
|
+
process.once('SIGINT', sigintHandler)
|
|
371
|
+
|
|
343
372
|
// --- スキルルーティング ---
|
|
344
373
|
const parsed = parseSkillInput(input)
|
|
345
374
|
if (parsed) {
|
|
@@ -348,12 +377,15 @@ async function prompt() {
|
|
|
348
377
|
console.log('\n' + sepWithLabel(chalk.bold.cyan(agentName) + chalk.dim(` [スキル: ${parsed.name}]`)))
|
|
349
378
|
const expanded = expandSkill(skill.content, parsed.args)
|
|
350
379
|
try {
|
|
351
|
-
await agent.chat(expanded)
|
|
380
|
+
await agent.chat(expanded, abortController.signal)
|
|
352
381
|
} catch (err) {
|
|
353
|
-
console.error(chalk.red('\n エラー: ' + err.message + '\n'))
|
|
382
|
+
if (err.name !== 'AbortError') console.error(chalk.red('\n エラー: ' + err.message + '\n'))
|
|
383
|
+
} finally {
|
|
384
|
+
process.removeListener('SIGINT', sigintHandler)
|
|
354
385
|
}
|
|
355
386
|
return prompt()
|
|
356
387
|
} else {
|
|
388
|
+
process.removeListener('SIGINT', sigintHandler)
|
|
357
389
|
console.log(chalk.yellow(`\n スキル「${parsed.name}」が見つかりません。`))
|
|
358
390
|
console.log(chalk.dim(` .migi/skills/${parsed.name}.md を作成してください。`))
|
|
359
391
|
return prompt()
|
|
@@ -363,9 +395,11 @@ async function prompt() {
|
|
|
363
395
|
// --- 通常チャット ---
|
|
364
396
|
console.log('\n' + sepWithLabel(chalk.bold.cyan(agentName)))
|
|
365
397
|
try {
|
|
366
|
-
await agent.chat(input)
|
|
398
|
+
await agent.chat(input, abortController.signal)
|
|
367
399
|
} catch (err) {
|
|
368
|
-
console.error(chalk.red('\n エラー: ' + err.message + '\n'))
|
|
400
|
+
if (err.name !== 'AbortError') console.error(chalk.red('\n エラー: ' + err.message + '\n'))
|
|
401
|
+
} finally {
|
|
402
|
+
process.removeListener('SIGINT', sigintHandler)
|
|
369
403
|
}
|
|
370
404
|
|
|
371
405
|
prompt()
|
package/package.json
CHANGED
package/src/agent.js
CHANGED
|
@@ -206,7 +206,7 @@ JSON形式のみで返答(他のテキスト不要):
|
|
|
206
206
|
this.history = cleaned
|
|
207
207
|
}
|
|
208
208
|
|
|
209
|
-
async chat(userMessage) {
|
|
209
|
+
async chat(userMessage, signal = null) {
|
|
210
210
|
this._sanitizeHistory()
|
|
211
211
|
this.history.push({ role: 'user', content: userMessage })
|
|
212
212
|
|
|
@@ -225,7 +225,8 @@ JSON形式のみで返答(他のテキスト不要):
|
|
|
225
225
|
messages,
|
|
226
226
|
tools: this.tools,
|
|
227
227
|
tool_choice: 'auto',
|
|
228
|
-
stream: true
|
|
228
|
+
stream: true,
|
|
229
|
+
...(signal ? { signal } : {})
|
|
229
230
|
})
|
|
230
231
|
|
|
231
232
|
let content = ''
|