@team-semicolon/semo-cli 4.4.1 → 4.4.3
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/dist/commands/bots.js +37 -2
- package/dist/index.js +6 -0
- package/package.json +2 -1
package/dist/commands/bots.js
CHANGED
|
@@ -50,6 +50,7 @@ const chalk_1 = __importDefault(require("chalk"));
|
|
|
50
50
|
const ora_1 = __importDefault(require("ora"));
|
|
51
51
|
const fs = __importStar(require("fs"));
|
|
52
52
|
const path = __importStar(require("path"));
|
|
53
|
+
const os = __importStar(require("os"));
|
|
53
54
|
const database_1 = require("../database");
|
|
54
55
|
const sessions_1 = require("./sessions");
|
|
55
56
|
const audit_1 = require("./audit");
|
|
@@ -140,6 +141,27 @@ function getAllFileMtimes(dir, depth = 0) {
|
|
|
140
141
|
return times;
|
|
141
142
|
}
|
|
142
143
|
// ============================================================
|
|
144
|
+
// Gateway status detection
|
|
145
|
+
// ============================================================
|
|
146
|
+
async function detectGatewayStatus(botId) {
|
|
147
|
+
const configPath = path.join(os.homedir(), `.openclaw-${botId}`, 'openclaw.json');
|
|
148
|
+
if (!fs.existsSync(configPath))
|
|
149
|
+
return 'offline';
|
|
150
|
+
try {
|
|
151
|
+
const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
|
|
152
|
+
const port = config?.gateway?.port;
|
|
153
|
+
if (!port)
|
|
154
|
+
return 'offline';
|
|
155
|
+
const res = await fetch(`http://127.0.0.1:${port}/`, {
|
|
156
|
+
signal: AbortSignal.timeout(1000),
|
|
157
|
+
});
|
|
158
|
+
return res.ok ? 'online' : 'offline';
|
|
159
|
+
}
|
|
160
|
+
catch {
|
|
161
|
+
return 'offline';
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
// ============================================================
|
|
143
165
|
// Command registration
|
|
144
166
|
// ============================================================
|
|
145
167
|
function registerBotsCommands(program) {
|
|
@@ -324,16 +346,28 @@ function registerBotsCommands(program) {
|
|
|
324
346
|
const errors = [];
|
|
325
347
|
try {
|
|
326
348
|
await client.query("BEGIN");
|
|
349
|
+
// Detect gateway status for all bots in parallel
|
|
350
|
+
const statusMap = new Map();
|
|
351
|
+
const statusResults = await Promise.all(bots.map(async (bot) => ({
|
|
352
|
+
botId: bot.botId,
|
|
353
|
+
status: await detectGatewayStatus(bot.botId),
|
|
354
|
+
})));
|
|
355
|
+
for (const { botId, status } of statusResults) {
|
|
356
|
+
statusMap.set(botId, status);
|
|
357
|
+
}
|
|
358
|
+
const onlineCount = statusResults.filter(r => r.status === 'online').length;
|
|
359
|
+
spinner.text = `${bots.length}개 봇 DB 반영 중... (게이트웨이: ${onlineCount}개 online)`;
|
|
327
360
|
for (const bot of bots) {
|
|
328
361
|
try {
|
|
362
|
+
const detectedStatus = statusMap.get(bot.botId) || 'offline';
|
|
329
363
|
await client.query(`INSERT INTO semo.bot_status
|
|
330
364
|
(bot_id, name, emoji, role, status, last_active, workspace_path, synced_at)
|
|
331
|
-
VALUES ($1, $2, $3, $4,
|
|
365
|
+
VALUES ($1, $2, $3, $4, $7, $5, $6, NOW())
|
|
332
366
|
ON CONFLICT (bot_id) DO UPDATE SET
|
|
333
367
|
name = COALESCE(EXCLUDED.name, semo.bot_status.name),
|
|
334
368
|
emoji = COALESCE(EXCLUDED.emoji, semo.bot_status.emoji),
|
|
335
369
|
role = COALESCE(EXCLUDED.role, semo.bot_status.role),
|
|
336
|
-
status =
|
|
370
|
+
status = EXCLUDED.status,
|
|
337
371
|
last_active = CASE
|
|
338
372
|
WHEN EXCLUDED.last_active IS NOT NULL
|
|
339
373
|
AND (semo.bot_status.last_active IS NULL
|
|
@@ -349,6 +383,7 @@ function registerBotsCommands(program) {
|
|
|
349
383
|
bot.role,
|
|
350
384
|
bot.lastActive?.toISOString() || null,
|
|
351
385
|
bot.workspacePath,
|
|
386
|
+
detectedStatus,
|
|
352
387
|
]);
|
|
353
388
|
upserted++;
|
|
354
389
|
}
|
package/dist/index.js
CHANGED
|
@@ -1412,6 +1412,12 @@ async function buildKbFirstBlock() {
|
|
|
1412
1412
|
}
|
|
1413
1413
|
domainGuide += `- 서비스 KPI → \`domain: {서비스명}\`, key: \`kpi/current\`\n`;
|
|
1414
1414
|
domainGuide += `- 서비스 마일스톤 → \`domain: {서비스명}\`, key: \`milestone/{slug}\`\n`;
|
|
1415
|
+
domainGuide += `\n**정확한 경로를 모를 때:**\n`;
|
|
1416
|
+
domainGuide += `1. \`semo kb search "검색어"\` → 결과의 \`[domain] key/sub_key\` 경로 확인\n`;
|
|
1417
|
+
domainGuide += `2. \`semo kb get <domain> <key> <sub_key>\` 실행\n`;
|
|
1418
|
+
domainGuide += `\n**도메인 자체를 모를 때:**\n`;
|
|
1419
|
+
domainGuide += `- \`semo kb ontology --action instances\` — 서비스 도메인 목록\n`;
|
|
1420
|
+
domainGuide += `- \`semo kb ontology --action routing-table\` — 전체 domain→key 매핑\n`;
|
|
1415
1421
|
}
|
|
1416
1422
|
catch {
|
|
1417
1423
|
// DB 연결 실패 시 최소한의 가이드
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@team-semicolon/semo-cli",
|
|
3
|
-
"version": "4.4.
|
|
3
|
+
"version": "4.4.3",
|
|
4
4
|
"description": "SEMO CLI - AI Agent Orchestration Framework Installer",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
},
|
|
10
10
|
"scripts": {
|
|
11
11
|
"build": "tsc",
|
|
12
|
+
"postbuild": "xattr -cr dist/ 2>/dev/null || true",
|
|
12
13
|
"start": "node dist/index.js",
|
|
13
14
|
"dev": "ts-node src/index.ts"
|
|
14
15
|
},
|