@make-u-free/migi 0.3.7 → 0.3.9
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 +71 -28
- package/package.json +1 -1
package/bin/migi.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import '../src/tls.js' // 企業CA(Zscaler等)を起動直後に読み込む
|
|
3
|
-
import readline from 'readline'
|
|
3
|
+
import readline, { emitKeypressEvents } from 'readline'
|
|
4
4
|
import chalk from 'chalk'
|
|
5
5
|
import dotenv from 'dotenv'
|
|
6
6
|
import { MigiAgent } from '../src/agent.js'
|
|
@@ -66,37 +66,84 @@ console.log(chalk.dim(' /exit 終了\n'))
|
|
|
66
66
|
|
|
67
67
|
const agent = new MigiAgent({ context, promptFn, apiKey, model, name: agentName, userName, teamsWebhookUrl })
|
|
68
68
|
|
|
69
|
-
function sep() {
|
|
69
|
+
function sep() {
|
|
70
|
+
const w = process.stdout.columns || 80
|
|
71
|
+
return chalk.dim('─'.repeat(w))
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function sepWithLabel(label) {
|
|
75
|
+
const w = process.stdout.columns || 80
|
|
76
|
+
const left = '── ' + label + ' '
|
|
77
|
+
const right = '─'.repeat(Math.max(0, w - left.length))
|
|
78
|
+
return chalk.dim(left + right)
|
|
79
|
+
}
|
|
70
80
|
|
|
71
|
-
// ----
|
|
72
|
-
async function
|
|
73
|
-
const lines = []
|
|
81
|
+
// ---- チャット入力(Enter送信 / Shift+Enter改行)----
|
|
82
|
+
async function readChatInput() {
|
|
74
83
|
return new Promise((resolve) => {
|
|
75
|
-
const
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
process.stdout.write(
|
|
84
|
+
const lines = ['']
|
|
85
|
+
|
|
86
|
+
emitKeypressEvents(process.stdin)
|
|
87
|
+
if (process.stdin.isTTY) process.stdin.setRawMode(true)
|
|
88
|
+
process.stdout.write(chalk.cyan(' '))
|
|
89
|
+
|
|
90
|
+
const onKey = (str, key) => {
|
|
91
|
+
if (!key) {
|
|
92
|
+
// IME確定などの複合文字
|
|
93
|
+
if (str) { lines[lines.length - 1] += str; process.stdout.write(str) }
|
|
94
|
+
return
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Ctrl+C
|
|
98
|
+
if (key.ctrl && key.name === 'c') {
|
|
99
|
+
console.log(chalk.cyan('\n\n お疲れ様でした!またね。\n'))
|
|
100
|
+
process.exit(0)
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (key.name === 'return') {
|
|
104
|
+
if (key.shift) {
|
|
105
|
+
// Shift+Enter → 改行
|
|
106
|
+
lines.push('')
|
|
107
|
+
process.stdout.write('\n ')
|
|
108
|
+
} else {
|
|
109
|
+
// Enter → 送信
|
|
110
|
+
const content = lines.join('\n').trim()
|
|
111
|
+
if (!content) return // 空は無視
|
|
112
|
+
process.stdin.removeListener('keypress', onKey)
|
|
113
|
+
if (process.stdin.isTTY) process.stdin.setRawMode(false)
|
|
114
|
+
process.stdout.write('\n')
|
|
115
|
+
console.log(sep())
|
|
116
|
+
console.log(chalk.dim(` ✦ ${model} · Shift+Enterで改行 / Enterで送信`))
|
|
117
|
+
resolve(content)
|
|
118
|
+
}
|
|
119
|
+
return
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
if (key.name === 'backspace') {
|
|
123
|
+
const cur = lines[lines.length - 1]
|
|
124
|
+
if (cur.length > 0) {
|
|
125
|
+
lines[lines.length - 1] = cur.slice(0, -1)
|
|
126
|
+
process.stdout.write('\b \b')
|
|
127
|
+
}
|
|
128
|
+
return
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if (str && !key.ctrl && !key.meta) {
|
|
132
|
+
lines[lines.length - 1] += str
|
|
133
|
+
process.stdout.write(str)
|
|
85
134
|
}
|
|
86
135
|
}
|
|
87
|
-
|
|
88
|
-
|
|
136
|
+
|
|
137
|
+
process.stdin.on('keypress', onKey)
|
|
89
138
|
})
|
|
90
139
|
}
|
|
91
140
|
|
|
92
141
|
// ---- メインループ ----
|
|
93
142
|
async function prompt() {
|
|
94
|
-
//
|
|
95
|
-
console.log('\n' +
|
|
96
|
-
console.log(chalk.bold.cyan(` ${userName || 'あなた'}`))
|
|
97
|
-
console.log(sep())
|
|
143
|
+
// 入力ボックス上辺(ユーザー名をセパレーターに埋め込む)
|
|
144
|
+
console.log('\n' + sepWithLabel(chalk.bold.cyan(userName || 'あなた')))
|
|
98
145
|
|
|
99
|
-
const input = (await
|
|
146
|
+
const input = (await readChatInput()).trim()
|
|
100
147
|
if (!input) return prompt()
|
|
101
148
|
|
|
102
149
|
// --- ビルトインコマンド ---
|
|
@@ -139,9 +186,7 @@ async function prompt() {
|
|
|
139
186
|
if (parsed) {
|
|
140
187
|
const skill = resolveSkill(parsed.name, process.cwd())
|
|
141
188
|
if (skill) {
|
|
142
|
-
console.log('\n' +
|
|
143
|
-
console.log(chalk.bold.cyan(` ${agentName}`) + chalk.dim(` [スキル: ${parsed.name}]`))
|
|
144
|
-
console.log(sep())
|
|
189
|
+
console.log('\n' + sepWithLabel(chalk.bold.cyan(agentName) + chalk.dim(` [スキル: ${parsed.name}]`)))
|
|
145
190
|
const expanded = expandSkill(skill.content, parsed.args)
|
|
146
191
|
try {
|
|
147
192
|
const reply = await agent.chat(expanded)
|
|
@@ -158,9 +203,7 @@ async function prompt() {
|
|
|
158
203
|
}
|
|
159
204
|
|
|
160
205
|
// --- 通常チャット ---
|
|
161
|
-
console.log('\n' +
|
|
162
|
-
console.log(chalk.bold.cyan(` ${agentName}`))
|
|
163
|
-
console.log(sep())
|
|
206
|
+
console.log('\n' + sepWithLabel(chalk.bold.cyan(agentName)))
|
|
164
207
|
try {
|
|
165
208
|
const reply = await agent.chat(input)
|
|
166
209
|
console.log('\n' + reply + '\n')
|