@monoes/monomindcli 2.9.19 → 2.9.20
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/src/ui/server.mjs +30 -63
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
package/dist/src/ui/server.mjs
CHANGED
|
@@ -5298,71 +5298,38 @@ export async function startServer({
|
|
|
5298
5298
|
|
|
5299
5299
|
// ── Gap-fill ordering (ADR Issue 7): rebuild activeOrgRuns BEFORE the server
|
|
5300
5300
|
// starts accepting connections so the first incoming event already has runId context.
|
|
5301
|
-
// Uses SQLite when available; falls back to JSONL scan.
|
|
5302
5301
|
await _initRunDb(MONOMIND_HOME);
|
|
5302
|
+
// #155 follow-up: the original gap-fill scanned run_events (SQLite) / a
|
|
5303
|
+
// run's bus.jsonl for a terminal event — but run_events is populated by
|
|
5304
|
+
// LIVE forwarding while a dashboard is connected, not backfilled from a
|
|
5305
|
+
// run's actual history. A dashboard that starts after a run has already
|
|
5306
|
+
// stopped never saw most (or any) of that run's events, including its
|
|
5307
|
+
// terminal one, so there was nothing for the corrected #155 query to
|
|
5308
|
+
// match against even once the query itself was fixed. runtime.json's own
|
|
5309
|
+
// top-level `status` field is authoritative regardless of dashboard
|
|
5310
|
+
// uptime — it's the exact thing `monomind org status` reads — so check
|
|
5311
|
+
// that directly instead of reconstructing "done" from an event log that
|
|
5312
|
+
// may simply never have recorded it.
|
|
5303
5313
|
try {
|
|
5304
|
-
|
|
5305
|
-
|
|
5306
|
-
const
|
|
5307
|
-
|
|
5308
|
-
|
|
5309
|
-
|
|
5310
|
-
|
|
5311
|
-
|
|
5312
|
-
|
|
5313
|
-
|
|
5314
|
-
|
|
5315
|
-
|
|
5316
|
-
|
|
5317
|
-
|
|
5318
|
-
|
|
5319
|
-
|
|
5320
|
-
|
|
5321
|
-
|
|
5322
|
-
|
|
5323
|
-
// (org_complete tool). Both land in the JSON-stringified `raw`
|
|
5324
|
-
// column, not a dedicated type string, so match on that instead.
|
|
5325
|
-
const _gfRunStmt = _runDb.prepare(
|
|
5326
|
-
"SELECT type FROM run_events WHERE org=? AND run_id=? AND type='status' AND (raw LIKE '%\"msg\":\"org stopped\"%' OR raw LIKE '%\"reason\":\"org-complete\"%') LIMIT 1",
|
|
5327
|
-
);
|
|
5328
|
-
_gfRunStmt.bind([_gfOrg, _gfLatestRun]);
|
|
5329
|
-
if (_gfRunStmt.step()) _gfDone = true;
|
|
5330
|
-
_gfRunStmt.free();
|
|
5331
|
-
}
|
|
5332
|
-
if (_gfLatestRun && !_gfDone) activeOrgRuns.set(_gfOrg, _gfLatestRun);
|
|
5333
|
-
}
|
|
5334
|
-
_gfOrgsStmt.free();
|
|
5335
|
-
} else {
|
|
5336
|
-
// JSONL fallback (sql.js unavailable). #155: Org Runtime v2 never
|
|
5337
|
-
// writes <org>/runs/*.jsonl — the actual event log per run is
|
|
5338
|
-
// <org>/<runId>/bus.jsonl (OrgBus, bus.ts). runtime.json's `run` field
|
|
5339
|
-
// names the current/latest run id, matching the #138 fix already
|
|
5340
|
-
// shipped for statusline.cjs's getActiveOrgs().
|
|
5341
|
-
const _gfOrgsDir = path.join(MONOMIND_HOME, '.monomind', 'orgs');
|
|
5342
|
-
if (fs.existsSync(_gfOrgsDir)) {
|
|
5343
|
-
for (const _gfOrg of fs.readdirSync(_gfOrgsDir)) {
|
|
5344
|
-
if (!_gfOrg || _gfOrg.startsWith('.') || !/^[a-z0-9][a-z0-9_-]*$/i.test(_gfOrg)) continue;
|
|
5345
|
-
try {
|
|
5346
|
-
const _gfRuntimePath = path.join(_gfOrgsDir, _gfOrg, 'runtime.json');
|
|
5347
|
-
if (!fs.existsSync(_gfRuntimePath)) continue;
|
|
5348
|
-
const _gfRt = JSON.parse(fs.readFileSync(_gfRuntimePath, 'utf8'));
|
|
5349
|
-
const _gfId = typeof _gfRt?.run === 'string' ? _gfRt.run : null;
|
|
5350
|
-
if (!_gfId) continue;
|
|
5351
|
-
const _gfBusPath = path.join(_gfOrgsDir, _gfOrg, _gfId, 'bus.jsonl');
|
|
5352
|
-
if (!fs.existsSync(_gfBusPath)) continue;
|
|
5353
|
-
const _gfContent = fs.readFileSync(_gfBusPath, 'utf8');
|
|
5354
|
-
const _gfLast = _gfContent.trim().split('\n').filter(Boolean).slice(-10);
|
|
5355
|
-
const _gfDone = _gfLast.some((l) => {
|
|
5356
|
-
try {
|
|
5357
|
-
const e = JSON.parse(l);
|
|
5358
|
-
return e.type === 'status' && (e.msg === 'org stopped' || e.reason === 'org-complete');
|
|
5359
|
-
} catch {
|
|
5360
|
-
return false;
|
|
5361
|
-
}
|
|
5362
|
-
});
|
|
5363
|
-
if (!_gfDone) activeOrgRuns.set(_gfOrg, _gfId);
|
|
5364
|
-
} catch (_) {}
|
|
5365
|
-
}
|
|
5314
|
+
const _gfOrgsDir = path.join(MONOMIND_HOME, '.monomind', 'orgs');
|
|
5315
|
+
if (fs.existsSync(_gfOrgsDir)) {
|
|
5316
|
+
for (const _gfOrg of fs.readdirSync(_gfOrgsDir)) {
|
|
5317
|
+
if (!_gfOrg || _gfOrg.startsWith('.') || !/^[a-z0-9][a-z0-9_-]*$/i.test(_gfOrg)) continue;
|
|
5318
|
+
try {
|
|
5319
|
+
const _gfRuntimePath = path.join(_gfOrgsDir, _gfOrg, 'runtime.json');
|
|
5320
|
+
if (!fs.existsSync(_gfRuntimePath)) continue;
|
|
5321
|
+
const _gfRt = JSON.parse(fs.readFileSync(_gfRuntimePath, 'utf8'));
|
|
5322
|
+
const _gfId = typeof _gfRt?.run === 'string' ? _gfRt.run : null;
|
|
5323
|
+
if (!_gfId) continue;
|
|
5324
|
+
// Mirrors org.ts's statusAction: a "running" record whose pid is
|
|
5325
|
+
// gone means the daemon died without its stopOrg cleanup — treat
|
|
5326
|
+
// that as not-active too, not just a literal status !== 'running'.
|
|
5327
|
+
let _gfActive = _gfRt.status === 'running';
|
|
5328
|
+
if (_gfActive && typeof _gfRt.pid === 'number') {
|
|
5329
|
+
try { process.kill(_gfRt.pid, 0); } catch { _gfActive = false; }
|
|
5330
|
+
}
|
|
5331
|
+
if (_gfActive) activeOrgRuns.set(_gfOrg, _gfId);
|
|
5332
|
+
} catch (_) {}
|
|
5366
5333
|
}
|
|
5367
5334
|
}
|
|
5368
5335
|
} catch (_) {}
|