@make-u-free/migi 0.5.19 → 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 -18
- package/package.json +1 -1
- package/skills/secretary.md +8 -2
- package/src/agent.js +3 -2
package/bin/migi.js
CHANGED
|
@@ -73,16 +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
|
-
|
|
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
|
+
}
|
|
84
94
|
} catch (err) {
|
|
85
|
-
|
|
95
|
+
if (err.name !== 'AbortError') {
|
|
96
|
+
console.error(chalk.red(' 起動チェック失敗: ' + err.message))
|
|
97
|
+
}
|
|
86
98
|
}
|
|
87
99
|
}
|
|
88
100
|
|
|
@@ -191,11 +203,22 @@ async function readChatInput() {
|
|
|
191
203
|
}
|
|
192
204
|
|
|
193
205
|
if (key.ctrl && key.name === 'c') {
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
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
|
|
199
222
|
}
|
|
200
223
|
|
|
201
224
|
if (key.name === 'return') {
|
|
@@ -338,6 +361,14 @@ async function prompt() {
|
|
|
338
361
|
return prompt()
|
|
339
362
|
}
|
|
340
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
|
+
|
|
341
372
|
// --- スキルルーティング ---
|
|
342
373
|
const parsed = parseSkillInput(input)
|
|
343
374
|
if (parsed) {
|
|
@@ -346,12 +377,15 @@ async function prompt() {
|
|
|
346
377
|
console.log('\n' + sepWithLabel(chalk.bold.cyan(agentName) + chalk.dim(` [スキル: ${parsed.name}]`)))
|
|
347
378
|
const expanded = expandSkill(skill.content, parsed.args)
|
|
348
379
|
try {
|
|
349
|
-
await agent.chat(expanded)
|
|
380
|
+
await agent.chat(expanded, abortController.signal)
|
|
350
381
|
} catch (err) {
|
|
351
|
-
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)
|
|
352
385
|
}
|
|
353
386
|
return prompt()
|
|
354
387
|
} else {
|
|
388
|
+
process.removeListener('SIGINT', sigintHandler)
|
|
355
389
|
console.log(chalk.yellow(`\n スキル「${parsed.name}」が見つかりません。`))
|
|
356
390
|
console.log(chalk.dim(` .migi/skills/${parsed.name}.md を作成してください。`))
|
|
357
391
|
return prompt()
|
|
@@ -361,9 +395,11 @@ async function prompt() {
|
|
|
361
395
|
// --- 通常チャット ---
|
|
362
396
|
console.log('\n' + sepWithLabel(chalk.bold.cyan(agentName)))
|
|
363
397
|
try {
|
|
364
|
-
await agent.chat(input)
|
|
398
|
+
await agent.chat(input, abortController.signal)
|
|
365
399
|
} catch (err) {
|
|
366
|
-
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)
|
|
367
403
|
}
|
|
368
404
|
|
|
369
405
|
prompt()
|
package/package.json
CHANGED
package/skills/secretary.md
CHANGED
|
@@ -29,13 +29,19 @@
|
|
|
29
29
|
|
|
30
30
|
## ダッシュボードを求められたとき
|
|
31
31
|
|
|
32
|
-
今日のTODO
|
|
32
|
+
今日のTODOファイルと .company/ 以下の未完了タスクをまとめて、以下の形式で表示する:
|
|
33
33
|
|
|
34
34
|
```
|
|
35
35
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
36
36
|
ダッシュボード - YYYY-MM-DD
|
|
37
37
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
38
38
|
TODO: X件未完了 / Y件完了
|
|
39
|
-
|
|
39
|
+
1. タスクA
|
|
40
|
+
2. タスクB
|
|
41
|
+
3. タスクC
|
|
40
42
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
41
43
|
```
|
|
44
|
+
|
|
45
|
+
- 未完了タスクは **通し番号(1. 2. 3.)を付けて表示する**(ファイルには書かない)
|
|
46
|
+
- ユーザーが「N番完了」と言ったらその番号のタスクを特定し、ファイルの `[ ]` を `[x]` に書き換える
|
|
47
|
+
- ユーザーが「N番削除」と言ったらその行をファイルから削除する
|
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 = ''
|