@monoes/monomindcli 2.10.21 → 2.10.23
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/.claude/settings.json +39 -39
- package/dist/src/init/settings-generator.d.ts.map +1 -1
- package/dist/src/init/settings-generator.js +24 -14
- package/dist/src/init/settings-generator.js.map +1 -1
- package/dist/src/orgrt/agent-exec.d.ts.map +1 -1
- package/dist/src/orgrt/agent-exec.js +13 -0
- package/dist/src/orgrt/agent-exec.js.map +1 -1
- package/dist/src/orgrt/agent-runner.d.ts.map +1 -1
- package/dist/src/orgrt/agent-runner.js +78 -2
- package/dist/src/orgrt/agent-runner.js.map +1 -1
- package/dist/src/orgrt/antigravity-runner.d.ts +24 -0
- package/dist/src/orgrt/antigravity-runner.d.ts.map +1 -1
- package/dist/src/orgrt/antigravity-runner.js +162 -37
- package/dist/src/orgrt/antigravity-runner.js.map +1 -1
- package/dist/src/orgrt/opencode-runner.d.ts +47 -15
- package/dist/src/orgrt/opencode-runner.d.ts.map +1 -1
- package/dist/src/orgrt/opencode-runner.js +190 -39
- package/dist/src/orgrt/opencode-runner.js.map +1 -1
- package/dist/src/orgrt/qwen-rpc-runner.d.ts.map +1 -1
- package/dist/src/orgrt/qwen-rpc-runner.js +46 -4
- package/dist/src/orgrt/qwen-rpc-runner.js.map +1 -1
- package/dist/src/orgrt/runner-registry.d.ts +14 -0
- package/dist/src/orgrt/runner-registry.d.ts.map +1 -1
- package/dist/src/orgrt/runner-registry.js +88 -0
- package/dist/src/orgrt/runner-registry.js.map +1 -1
- package/dist/src/ui/routes-org.mjs +143 -5
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
|
@@ -19,6 +19,13 @@ export const RUNNER_SPECS = [
|
|
|
19
19
|
binary: 'claude', // SDK locates its own CLI; PATH probe is best-effort
|
|
20
20
|
installHint: 'npm install -g @anthropic-ai/claude-code',
|
|
21
21
|
loginHint: 'claude login',
|
|
22
|
+
// Real per-token streaming via the SDK's `includePartialMessages`,
|
|
23
|
+
// opted into only for this protocol's own caller (agent-exec.ts) —
|
|
24
|
+
// see agent-runner.ts's `streamPartials` for why it's opt-in rather
|
|
25
|
+
// than always-on. Live-verified against the SDK: content_block_delta
|
|
26
|
+
// events with text_delta arrive per-token, and the complete message
|
|
27
|
+
// still follows with full content/usage.
|
|
28
|
+
streamsIncrementally: true,
|
|
22
29
|
},
|
|
23
30
|
{
|
|
24
31
|
id: 'codex',
|
|
@@ -26,6 +33,11 @@ export const RUNNER_SPECS = [
|
|
|
26
33
|
binEnv: 'CODEX_CLI_BIN',
|
|
27
34
|
installHint: 'npm install -g @openai/codex',
|
|
28
35
|
loginHint: 'codex login',
|
|
36
|
+
// Hard protocol limitation, not a monomind gap: codex's own event set
|
|
37
|
+
// has no delta field at all — confirmed via its documented event enum
|
|
38
|
+
// (codex-runner.ts header) — only whole `item.completed` messages.
|
|
39
|
+
// The runner already yields each one the instant it lands.
|
|
40
|
+
streamsIncrementally: false,
|
|
29
41
|
},
|
|
30
42
|
{
|
|
31
43
|
id: 'kimicode',
|
|
@@ -33,17 +45,38 @@ export const RUNNER_SPECS = [
|
|
|
33
45
|
binEnv: 'KIMI_CLI_BIN',
|
|
34
46
|
installHint: 'install the Kimi Code CLI (kimi) from Moonshot and log in',
|
|
35
47
|
loginHint: 'kimi (interactive first run)',
|
|
48
|
+
// Whole messages only in the version this was verified against
|
|
49
|
+
// (kimicode-runner.ts header, kimi 0.29.2) — moderate confidence, not
|
|
50
|
+
// a live byte-verified spec like codex/qwen/pi below. A newer
|
|
51
|
+
// installed binary hints at an internal "assistant.delta" event of
|
|
52
|
+
// unconfirmed reach into `--output-format stream-json`; worth
|
|
53
|
+
// re-checking before ruling this out permanently.
|
|
54
|
+
streamsIncrementally: false,
|
|
36
55
|
},
|
|
37
56
|
{
|
|
38
57
|
id: 'opencode',
|
|
39
58
|
binary: 'opencode',
|
|
40
59
|
binEnv: 'OPENCODE_BIN',
|
|
41
60
|
installHint: 'npm install -g opencode-ai',
|
|
61
|
+
// Real per-token streaming, switched from a blocking session.prompt()
|
|
62
|
+
// call to session.promptAsync() + client.event.subscribe(). Live-verified
|
|
63
|
+
// against a real opencode server (v1.18.30): the actual per-token event
|
|
64
|
+
// is `message.part.delta` — NOT in the installed SDK's own .d.ts at all
|
|
65
|
+
// (only message.part.updated is, whose own `delta` field was observed
|
|
66
|
+
// to always be undefined live). See opencode-runner.ts's header for the
|
|
67
|
+
// full live-verified event shapes and a real bug this live testing
|
|
68
|
+
// caught (the echoed user prompt leaking out as a fake assistant
|
|
69
|
+
// message) before it could ship.
|
|
70
|
+
streamsIncrementally: true,
|
|
42
71
|
},
|
|
43
72
|
{
|
|
44
73
|
id: 'vercel',
|
|
45
74
|
binary: null, // in-process via the npm `ai` package
|
|
46
75
|
installHint: 'npm install ai (plus the vendor model package)',
|
|
76
|
+
// Real per-token streaming: vercel-runner.ts consumes the `ai` SDK's
|
|
77
|
+
// `result.fullStream` and yields each real `text-delta` part as it
|
|
78
|
+
// arrives (verified against the installed `ai` package's own types).
|
|
79
|
+
streamsIncrementally: true,
|
|
47
80
|
},
|
|
48
81
|
{
|
|
49
82
|
id: 'antigravity',
|
|
@@ -51,6 +84,12 @@ export const RUNNER_SPECS = [
|
|
|
51
84
|
binEnv: 'ANTIGRAVITY_CLI_BIN',
|
|
52
85
|
installHint: 'curl -fsSL https://antigravity.google/cli/install.sh | bash',
|
|
53
86
|
loginHint: 'agy (interactive login)',
|
|
87
|
+
// Real per-token streaming via `agy --output-format stream-json`'s
|
|
88
|
+
// text_delta events, fence-safely buffered by computeSafeChunk/
|
|
89
|
+
// emitVisible/flushText — the reference implementation for a runner
|
|
90
|
+
// whose underlying protocol needs fence-boundary awareness. Live
|
|
91
|
+
// end-to-end verified: multiple incremental NDJSON lines per turn.
|
|
92
|
+
streamsIncrementally: true,
|
|
54
93
|
},
|
|
55
94
|
{
|
|
56
95
|
id: 'grok',
|
|
@@ -58,6 +97,13 @@ export const RUNNER_SPECS = [
|
|
|
58
97
|
binEnv: 'GROK_CLI_BIN',
|
|
59
98
|
installHint: 'install the Grok Build CLI per https://docs.x.ai/build/cli',
|
|
60
99
|
loginHint: 'grok login',
|
|
100
|
+
// Whole messages only with the flag grok-runner.ts currently passes
|
|
101
|
+
// (`--output-format json`) — confirmed via its own event-shape parser,
|
|
102
|
+
// which has no delta field. Its header flags an untested
|
|
103
|
+
// `streaming-messages-json` mode (Anthropic Messages wire format) as a
|
|
104
|
+
// possible source of real deltas — unconfirmed, left `false` until
|
|
105
|
+
// verified live.
|
|
106
|
+
streamsIncrementally: false,
|
|
61
107
|
},
|
|
62
108
|
{
|
|
63
109
|
id: 'qwen',
|
|
@@ -65,6 +111,10 @@ export const RUNNER_SPECS = [
|
|
|
65
111
|
binEnv: 'QWEN_CLI_BIN',
|
|
66
112
|
installHint: 'npm install -g @qwen-code/qwen-code',
|
|
67
113
|
loginHint: 'qwen (interactive first run)',
|
|
114
|
+
// Hard protocol limitation, confirmed live: qwen-runner.ts's own
|
|
115
|
+
// header states directly "qwen's stream-json sends whole messages per
|
|
116
|
+
// event, not per-token deltas — confirmed live, #182".
|
|
117
|
+
streamsIncrementally: false,
|
|
68
118
|
},
|
|
69
119
|
{
|
|
70
120
|
id: 'qwen-rpc',
|
|
@@ -72,12 +122,30 @@ export const RUNNER_SPECS = [
|
|
|
72
122
|
binEnv: 'QWEN_CLI_BIN',
|
|
73
123
|
installHint: 'npm install -g @qwen-code/qwen-code',
|
|
74
124
|
loginHint: 'qwen (interactive first run)',
|
|
125
|
+
// Still false — same whole-message-per-event wire vocabulary as
|
|
126
|
+
// `qwen` above, no per-token/per-chunk delta field to surface. This
|
|
127
|
+
// runner USED TO also buffer every message across the WHOLE round and
|
|
128
|
+
// yield once at the end when `result` fired, instead of yielding per
|
|
129
|
+
// event the way its qwen-runner.ts sibling always did — fixed (each
|
|
130
|
+
// `assistant` event now streams the instant it lands, fence-safely,
|
|
131
|
+
// reusing antigravity-runner.ts's computeSafeChunk). That was a real
|
|
132
|
+
// latency bug (a multi-internal-tool-round turn could sit silent for
|
|
133
|
+
// the WHOLE round instead of showing "working on it" as soon as it
|
|
134
|
+
// arrived) but is orthogonal to this flag: promptness at the wire
|
|
135
|
+
// format's own whole-message granularity isn't per-token streaming —
|
|
136
|
+
// see doc/agent-exec-protocol.md §9 step 3.
|
|
137
|
+
streamsIncrementally: false,
|
|
75
138
|
},
|
|
76
139
|
{
|
|
77
140
|
id: 'crush',
|
|
78
141
|
binary: 'crush',
|
|
79
142
|
binEnv: 'CRUSH_CLI_BIN',
|
|
80
143
|
installHint: 'install Crush per https://github.com/charmbracelet/crush',
|
|
144
|
+
// No structured protocol at all — crush's `run` subcommand has no
|
|
145
|
+
// documented JSON event stream, just plain text (crush-runner.ts
|
|
146
|
+
// header). The runner already streams each line the instant it
|
|
147
|
+
// arrives; there is no finer granularity available to request.
|
|
148
|
+
streamsIncrementally: false,
|
|
81
149
|
},
|
|
82
150
|
{
|
|
83
151
|
id: 'copilot',
|
|
@@ -85,18 +153,37 @@ export const RUNNER_SPECS = [
|
|
|
85
153
|
binEnv: 'COPILOT_CLI_BIN',
|
|
86
154
|
installHint: 'npm install -g @github/copilot',
|
|
87
155
|
loginHint: 'copilot (interactive first run)',
|
|
156
|
+
// Whole-message NDJSON per copilot-runner.ts's own header — but that
|
|
157
|
+
// header also notes the protocol is sourced from public docs, "NOT
|
|
158
|
+
// byte-verified" against the real CLI, so this is lower-confidence
|
|
159
|
+
// than qwen/pi's live-confirmed `false`s. Worth re-checking live
|
|
160
|
+
// before assuming it can never stream.
|
|
161
|
+
streamsIncrementally: false,
|
|
88
162
|
},
|
|
89
163
|
{
|
|
90
164
|
id: 'pi',
|
|
91
165
|
binary: 'pi',
|
|
92
166
|
binEnv: 'PI_CLI_BIN',
|
|
93
167
|
installHint: 'npm install -g @mariozechner/pi-coding-agent',
|
|
168
|
+
// Hard protocol limitation, confirmed live: pi-runner.ts's own header
|
|
169
|
+
// states "pi sends whole messages, not per-token deltas — no
|
|
170
|
+
// accumulation needed, unlike agy", verified against a live 0.73.1
|
|
171
|
+
// binary.
|
|
172
|
+
streamsIncrementally: false,
|
|
94
173
|
},
|
|
95
174
|
{
|
|
96
175
|
id: 'pi-rpc',
|
|
97
176
|
binary: 'pi',
|
|
98
177
|
binEnv: 'PI_CLI_BIN',
|
|
99
178
|
installHint: 'npm install -g @mariozechner/pi-coding-agent',
|
|
179
|
+
// Known-fixable, not a hard limitation: the RPC wire protocol DOES
|
|
180
|
+
// expose progressive `message_start`/`message_update`/`message_end`
|
|
181
|
+
// events per internal turn (a live test showed 4 separate cycles),
|
|
182
|
+
// but pi-rpc-runner.ts drains and discards all of them, waiting only
|
|
183
|
+
// for the terminal `agent_end` to yield one combined message — up to
|
|
184
|
+
// 4 complete assistant messages sit buffered before anything ships.
|
|
185
|
+
// Fix: yield fence-stripped text as each `message_end` lands instead.
|
|
186
|
+
streamsIncrementally: false,
|
|
100
187
|
},
|
|
101
188
|
];
|
|
102
189
|
const SPEC_BY_ID = new Map(RUNNER_SPECS.map((s) => [s.id, s]));
|
|
@@ -198,6 +285,7 @@ export async function scanInstalled(opts = {}) {
|
|
|
198
285
|
? await probeVersion(binPath, opts.versionTimeoutMs)
|
|
199
286
|
: null,
|
|
200
287
|
install_hint: spec.installHint,
|
|
288
|
+
streams_incrementally: spec.streamsIncrementally,
|
|
201
289
|
};
|
|
202
290
|
}));
|
|
203
291
|
return { v: 1, agents: entries };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner-registry.js","sourceRoot":"","sources":["../../../src/orgrt/runner-registry.ts"],"names":[],"mappings":"AAAA,sDAAsD;AACtD;;;;;;;;;GASG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAE5C,OAAO,EAAoB,aAAa,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"runner-registry.js","sourceRoot":"","sources":["../../../src/orgrt/runner-registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,6 +3,13 @@ import fs from 'node:fs';
|
|
|
3
3
|
import os from 'node:os';
|
|
4
4
|
import path from 'node:path';
|
|
5
5
|
import { getMmClientCount } from './sse-manager.mjs';
|
|
6
|
+
// forwarder.js is compiled from orgrt/forwarder.ts (dist/src/orgrt/forwarder.js
|
|
7
|
+
// sits alongside this file's own compiled dist/src/ui/routes-org.mjs after
|
|
8
|
+
// build; under vitest the .js specifier resolves straight to the .ts source,
|
|
9
|
+
// same as every other cross-reference in this codebase). translate()/
|
|
10
|
+
// companionEvents() are pure — no filesystem or process side effects — so
|
|
11
|
+
// importing them here doesn't pull in attachForwarder's spawn/heal logic.
|
|
12
|
+
import { translate, companionEvents } from '../orgrt/forwarder.js';
|
|
6
13
|
|
|
7
14
|
export async function handleOrgRoutes(req, res, url, corsOrigin, ctx) {
|
|
8
15
|
// ------------------------------------------------- Org management
|
|
@@ -2787,9 +2794,70 @@ export async function handleOrgRoutes(req, res, url, corsOrigin, ctx) {
|
|
|
2787
2794
|
return null;
|
|
2788
2795
|
}
|
|
2789
2796
|
};
|
|
2797
|
+
// Org Runtime v2 (#238): each run's raw BusEvents live under a
|
|
2798
|
+
// per-run directory named for the run itself — orgs/<org>/<runId>/bus.jsonl
|
|
2799
|
+
// — never the flat orgs/<org>/runs/<runId>.jsonl layout _parseRun above
|
|
2800
|
+
// expects. Translate through the same translate()/companionEvents()
|
|
2801
|
+
// forwarder.ts uses for the live view, so historical and live event
|
|
2802
|
+
// shapes always match.
|
|
2803
|
+
const _parseV2RunDir = (orgDir, runId) => {
|
|
2804
|
+
try {
|
|
2805
|
+
const busFile = path.join(orgDir, runId, 'bus.jsonl');
|
|
2806
|
+
if (!fs.existsSync(busFile)) return null;
|
|
2807
|
+
const raw = fs
|
|
2808
|
+
.readFileSync(busFile, 'utf8')
|
|
2809
|
+
.split('\n')
|
|
2810
|
+
.filter(Boolean)
|
|
2811
|
+
.map((l) => {
|
|
2812
|
+
try {
|
|
2813
|
+
return JSON.parse(l);
|
|
2814
|
+
} catch {
|
|
2815
|
+
return null;
|
|
2816
|
+
}
|
|
2817
|
+
})
|
|
2818
|
+
.filter(Boolean);
|
|
2819
|
+
if (!raw.length) return null;
|
|
2820
|
+
const translated = raw.flatMap((e) => [...companionEvents(e), translate(e)]);
|
|
2821
|
+
const done = translated.find(
|
|
2822
|
+
(e) => e.type === 'session:complete' || e.type === 'org:complete',
|
|
2823
|
+
);
|
|
2824
|
+
const start = translated.find((e) => e.type === 'org:start');
|
|
2825
|
+
const firstComms = translated.find((e) => e.type === 'org:comms' && e.msg);
|
|
2826
|
+
return {
|
|
2827
|
+
runId,
|
|
2828
|
+
startedAt: raw[0]?.ts || 0,
|
|
2829
|
+
endedAt: done?.ts || 0,
|
|
2830
|
+
status: done ? 'complete' : 'running',
|
|
2831
|
+
eventCount: raw.length,
|
|
2832
|
+
cycleCount: translated.filter((e) => e.type === 'org:checkpoint').length,
|
|
2833
|
+
goal: start?.goal || firstComms?.msg?.slice(0, 80) || '',
|
|
2834
|
+
bossRole: '',
|
|
2835
|
+
};
|
|
2836
|
+
} catch (_) {
|
|
2837
|
+
return null;
|
|
2838
|
+
}
|
|
2839
|
+
};
|
|
2790
2840
|
for (const _rpd of _rProjDirs) {
|
|
2791
2841
|
// Check both .monomind and .git/monomind locations
|
|
2792
2842
|
const _rMonoDir = ctx._getGitMonomindDir(_rpd) || path.join(_rpd, '.monomind');
|
|
2843
|
+
const _rOrgDirs = [path.join(_rMonoDir, 'orgs', _rOrgName)];
|
|
2844
|
+
if (_rMonoDir !== path.join(_rpd, '.monomind'))
|
|
2845
|
+
_rOrgDirs.push(path.join(_rpd, '.monomind', 'orgs', _rOrgName));
|
|
2846
|
+
for (const _rOrgDir of _rOrgDirs) {
|
|
2847
|
+
if (!fs.existsSync(_rOrgDir)) continue;
|
|
2848
|
+
const runDirs = fs
|
|
2849
|
+
.readdirSync(_rOrgDir)
|
|
2850
|
+
.filter((d) => d.startsWith('run-') && fs.statSync(path.join(_rOrgDir, d)).isDirectory())
|
|
2851
|
+
.sort()
|
|
2852
|
+
.reverse();
|
|
2853
|
+
for (const runId of runDirs.slice(0, 50)) {
|
|
2854
|
+
if (_rSeenFiles.has(runId)) continue;
|
|
2855
|
+
const r = _parseV2RunDir(_rOrgDir, runId);
|
|
2856
|
+
if (!r) continue;
|
|
2857
|
+
_rSeenFiles.add(runId);
|
|
2858
|
+
runs.push(r);
|
|
2859
|
+
}
|
|
2860
|
+
}
|
|
2793
2861
|
const _rSearchDirs = [path.join(_rMonoDir, 'orgs', _rOrgName, 'runs')];
|
|
2794
2862
|
if (_rMonoDir !== path.join(_rpd, '.monomind'))
|
|
2795
2863
|
_rSearchDirs.push(path.join(_rpd, '.monomind', 'orgs', _rOrgName, 'runs'));
|
|
@@ -2950,6 +3018,43 @@ export async function handleOrgRoutes(req, res, url, corsOrigin, ctx) {
|
|
|
2950
3018
|
).forEach((p) => _rvProjDirs.add(p));
|
|
2951
3019
|
} catch (_) {}
|
|
2952
3020
|
}
|
|
3021
|
+
// Org Runtime v2 (#238): try the per-run-directory bus.jsonl layout
|
|
3022
|
+
// first — orgs/<org>/<runId>/bus.jsonl — translated to the same
|
|
3023
|
+
// dashboard vocabulary the live view gets from forwarder.ts, before
|
|
3024
|
+
// falling back to the v1 flat orgs/<org>/runs/<runId>.jsonl lookup
|
|
3025
|
+
// below (v1 files are already stored pre-translated).
|
|
3026
|
+
for (const _rvpd of _rvProjDirs) {
|
|
3027
|
+
const _rvMonoDir = ctx._getGitMonomindDir(_rvpd) || path.join(_rvpd, '.monomind');
|
|
3028
|
+
const _v2Candidates = [path.join(_rvMonoDir, 'orgs', _rvOrgName, _rvRunId, 'bus.jsonl')];
|
|
3029
|
+
if (_rvMonoDir !== path.join(_rvpd, '.monomind'))
|
|
3030
|
+
_v2Candidates.push(
|
|
3031
|
+
path.join(_rvpd, '.monomind', 'orgs', _rvOrgName, _rvRunId, 'bus.jsonl'),
|
|
3032
|
+
);
|
|
3033
|
+
for (const _v2File of _v2Candidates) {
|
|
3034
|
+
if (!fs.existsSync(_v2File)) continue;
|
|
3035
|
+
const raw = fs
|
|
3036
|
+
.readFileSync(_v2File, 'utf8')
|
|
3037
|
+
.split('\n')
|
|
3038
|
+
.filter(Boolean)
|
|
3039
|
+
.map((l) => {
|
|
3040
|
+
try {
|
|
3041
|
+
return JSON.parse(l);
|
|
3042
|
+
} catch {
|
|
3043
|
+
return null;
|
|
3044
|
+
}
|
|
3045
|
+
})
|
|
3046
|
+
.filter(Boolean);
|
|
3047
|
+
const events = raw.flatMap((e) => [...companionEvents(e), translate(e)]);
|
|
3048
|
+
events.sort((a, b) => (a.ts || 0) - (b.ts || 0));
|
|
3049
|
+
res.writeHead(200, {
|
|
3050
|
+
'Content-Type': 'application/json',
|
|
3051
|
+
...(corsOrigin ? { 'Access-Control-Allow-Origin': corsOrigin } : {}),
|
|
3052
|
+
'Cache-Control': 'no-cache',
|
|
3053
|
+
});
|
|
3054
|
+
res.end(JSON.stringify(events));
|
|
3055
|
+
return true;
|
|
3056
|
+
}
|
|
3057
|
+
}
|
|
2953
3058
|
let _rvFile = null;
|
|
2954
3059
|
for (const _rvpd of _rvProjDirs) {
|
|
2955
3060
|
const _rvMonoDir = ctx._getGitMonomindDir(_rvpd) || path.join(_rvpd, '.monomind');
|
|
@@ -3452,11 +3557,39 @@ export async function handleOrgRoutes(req, res, url, corsOrigin, ctx) {
|
|
|
3452
3557
|
}
|
|
3453
3558
|
const runId = ctx.activeOrgRuns.get(orgName);
|
|
3454
3559
|
const monoDir = ctx._getGitMonomindDir(root) || path.join(root, '.monomind');
|
|
3455
|
-
// Try active run first, then fall back to most recent run file
|
|
3560
|
+
// Try active run first, then fall back to most recent run file.
|
|
3561
|
+
// Org Runtime v2 (#238): the active run's own events live under
|
|
3562
|
+
// orgs/<org>/<runId>/bus.jsonl, never the v1 flat orgs/<org>/runs/
|
|
3563
|
+
// layout — check that shape (and translate it) before the v1 lookup.
|
|
3456
3564
|
let runFile = null;
|
|
3565
|
+
let isV2 = false;
|
|
3457
3566
|
if (runId) {
|
|
3458
|
-
const
|
|
3459
|
-
if (fs.existsSync(
|
|
3567
|
+
const v2Candidate = path.join(monoDir, 'orgs', orgName, runId, 'bus.jsonl');
|
|
3568
|
+
if (fs.existsSync(v2Candidate)) {
|
|
3569
|
+
runFile = v2Candidate;
|
|
3570
|
+
isV2 = true;
|
|
3571
|
+
} else {
|
|
3572
|
+
const candidate = path.join(monoDir, 'orgs', orgName, 'runs', `${runId}.jsonl`);
|
|
3573
|
+
if (fs.existsSync(candidate)) runFile = candidate;
|
|
3574
|
+
}
|
|
3575
|
+
}
|
|
3576
|
+
if (!runFile) {
|
|
3577
|
+
const orgDir = path.join(monoDir, 'orgs', orgName);
|
|
3578
|
+
const runDirs = fs.existsSync(orgDir)
|
|
3579
|
+
? fs
|
|
3580
|
+
.readdirSync(orgDir)
|
|
3581
|
+
.filter(
|
|
3582
|
+
(d) =>
|
|
3583
|
+
d.startsWith('run-') &&
|
|
3584
|
+
fs.existsSync(path.join(orgDir, d, 'bus.jsonl')),
|
|
3585
|
+
)
|
|
3586
|
+
.sort()
|
|
3587
|
+
.reverse()
|
|
3588
|
+
: [];
|
|
3589
|
+
if (runDirs.length) {
|
|
3590
|
+
runFile = path.join(orgDir, runDirs[0], 'bus.jsonl');
|
|
3591
|
+
isV2 = true;
|
|
3592
|
+
}
|
|
3460
3593
|
}
|
|
3461
3594
|
if (!runFile) {
|
|
3462
3595
|
const runsDir = path.join(monoDir, 'orgs', orgName, 'runs');
|
|
@@ -3475,13 +3608,13 @@ export async function handleOrgRoutes(req, res, url, corsOrigin, ctx) {
|
|
|
3475
3608
|
res.end('{"events":[],"runId":null}');
|
|
3476
3609
|
return true;
|
|
3477
3610
|
}
|
|
3478
|
-
const detectedRunId = path.basename(runFile, '.jsonl');
|
|
3611
|
+
const detectedRunId = isV2 ? path.basename(path.dirname(runFile)) : path.basename(runFile, '.jsonl');
|
|
3479
3612
|
const lines = fs
|
|
3480
3613
|
.readFileSync(runFile, 'utf8')
|
|
3481
3614
|
.split('\n')
|
|
3482
3615
|
.filter((l) => l.trim())
|
|
3483
3616
|
.slice(-100);
|
|
3484
|
-
const
|
|
3617
|
+
const rawEvents = lines
|
|
3485
3618
|
.map((l) => {
|
|
3486
3619
|
try {
|
|
3487
3620
|
return JSON.parse(l);
|
|
@@ -3490,6 +3623,11 @@ export async function handleOrgRoutes(req, res, url, corsOrigin, ctx) {
|
|
|
3490
3623
|
}
|
|
3491
3624
|
})
|
|
3492
3625
|
.filter(Boolean);
|
|
3626
|
+
// v1's stored events are already dashboard-native; v2's raw BusEvents
|
|
3627
|
+
// need the same translate()/companionEvents() pass the live view gets.
|
|
3628
|
+
const events = isV2
|
|
3629
|
+
? rawEvents.flatMap((e) => [...companionEvents(e), translate(e)])
|
|
3630
|
+
: rawEvents;
|
|
3493
3631
|
res.writeHead(200, {
|
|
3494
3632
|
'Content-Type': 'application/json',
|
|
3495
3633
|
...(corsOrigin ? { 'Access-Control-Allow-Origin': corsOrigin } : {}),
|