@granica/myelin-beam-client 0.1.0-alpha.0
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/LICENSE +202 -0
- package/README.md +44 -0
- package/dist/auth.d.ts +17 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +286 -0
- package/dist/auth.js.map +1 -0
- package/dist/beamUp.d.ts +14 -0
- package/dist/beamUp.d.ts.map +1 -0
- package/dist/beamUp.js +252 -0
- package/dist/beamUp.js.map +1 -0
- package/dist/harnessSync.d.ts +22 -0
- package/dist/harnessSync.d.ts.map +1 -0
- package/dist/harnessSync.js +199 -0
- package/dist/harnessSync.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/rollout.d.ts +14 -0
- package/dist/rollout.d.ts.map +1 -0
- package/dist/rollout.js +319 -0
- package/dist/rollout.js.map +1 -0
- package/dist/types.d.ts +8 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +55 -0
package/dist/rollout.js
ADDED
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
import { promises as fs } from "node:fs";
|
|
2
|
+
import { homedir } from "node:os";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { createHash } from "node:crypto";
|
|
5
|
+
/// Encode a cwd the way Claude Code does. Absolute path only; relative
|
|
6
|
+
/// or `~`-prefixed paths won't match a real project directory.
|
|
7
|
+
export function encodeCwdForClaude(cwd) {
|
|
8
|
+
// Claude replaces every `/` with `-`, keeping the leading `/`'s dash.
|
|
9
|
+
// We do the same, then strip control chars for safety.
|
|
10
|
+
return cwd.replace(/\//g, "-").replace(/[\r\n\t]/g, "");
|
|
11
|
+
}
|
|
12
|
+
/// Locate the newest-mtime rollout under the current cwd. Returns null
|
|
13
|
+
/// when the directory doesn't exist (fresh cwd, no prior session) or
|
|
14
|
+
/// when no jsonl files match.
|
|
15
|
+
export async function findCurrentClaudeRollout(cwd) {
|
|
16
|
+
const projectCwd = cwd || process.cwd();
|
|
17
|
+
const encoded = encodeCwdForClaude(projectCwd);
|
|
18
|
+
const dir = join(homedir(), ".claude", "projects", encoded);
|
|
19
|
+
let entries;
|
|
20
|
+
try {
|
|
21
|
+
entries = await fs.readdir(dir);
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
const jsonls = entries.filter((e) => e.endsWith(".jsonl"));
|
|
27
|
+
if (jsonls.length === 0)
|
|
28
|
+
return null;
|
|
29
|
+
let newest = null;
|
|
30
|
+
for (const name of jsonls) {
|
|
31
|
+
const path = join(dir, name);
|
|
32
|
+
try {
|
|
33
|
+
const st = await fs.stat(path);
|
|
34
|
+
const mtime = st.mtimeMs;
|
|
35
|
+
if (!newest || mtime > newest.mtime) {
|
|
36
|
+
newest = { path, mtime, name };
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
// Ignore unreadable entries.
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
if (!newest)
|
|
44
|
+
return null;
|
|
45
|
+
return {
|
|
46
|
+
agent: "claude",
|
|
47
|
+
path: newest.path,
|
|
48
|
+
session_uuid: newest.name.replace(/\.jsonl$/, ""),
|
|
49
|
+
project_cwd: projectCwd,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
/// Locate the current Codex rollout under `~/.codex/sessions/`.
|
|
53
|
+
///
|
|
54
|
+
/// Codex layout: `~/.codex/sessions/<YYYY>/<MM>/<DD>/rollout-<ts>-<uuid>.jsonl`.
|
|
55
|
+
/// Unlike Claude, the tree is date-partitioned rather than cwd-encoded;
|
|
56
|
+
/// each rollout embeds its own `cwd` inside a session_meta header:
|
|
57
|
+
/// {"type":"session_meta","payload":{"id":"<uuid>","cwd":"<abs-path>",...}}
|
|
58
|
+
///
|
|
59
|
+
/// Strategy: pick the newest rollout by mtime. Header cwd is used to
|
|
60
|
+
/// populate project_cwd (so the router gets the user's ACTUAL cwd, not
|
|
61
|
+
/// the MCP subprocess's spawned cwd — which may differ). We do NOT
|
|
62
|
+
/// filter by matching process.cwd() to the header cwd — Codex has been
|
|
63
|
+
/// observed to spawn MCP subprocesses with a different working directory
|
|
64
|
+
/// than the user's session cwd, and a strict match would silently drop
|
|
65
|
+
/// the intended rollout. The docs already flag "concurrent sessions →
|
|
66
|
+
/// newest wins" as the ambiguity the user has to manage.
|
|
67
|
+
export async function findCurrentCodexRollout(cwd) {
|
|
68
|
+
const root = join(homedir(), ".codex", "sessions");
|
|
69
|
+
const files = await walkJsonlFiles(root, 4);
|
|
70
|
+
if (files.length === 0)
|
|
71
|
+
return null;
|
|
72
|
+
// Prefer newest mtime globally. Bounded walk (year/month/day/file).
|
|
73
|
+
let best = null;
|
|
74
|
+
for (const path of files) {
|
|
75
|
+
if (!/rollout-.*\.jsonl$/.test(path))
|
|
76
|
+
continue;
|
|
77
|
+
let st;
|
|
78
|
+
try {
|
|
79
|
+
st = await fs.stat(path);
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
if (!best || st.mtimeMs > best.mtime) {
|
|
85
|
+
best = { path, mtime: st.mtimeMs };
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
if (!best)
|
|
89
|
+
return null;
|
|
90
|
+
const header = await readFirstJsonlLine(best.path);
|
|
91
|
+
const parsed = header ? safeParseHeader(header) : null;
|
|
92
|
+
if (!parsed)
|
|
93
|
+
return null;
|
|
94
|
+
// If the caller passed an explicit cwd, honor it (test hook).
|
|
95
|
+
// Otherwise use the rollout's own recorded cwd — that's the path
|
|
96
|
+
// the user actually cd'd into and it must be what the router
|
|
97
|
+
// receives so agent-launcher.sh's workspace slug resolves correctly.
|
|
98
|
+
const projectCwd = cwd || parsed.cwd;
|
|
99
|
+
return {
|
|
100
|
+
agent: "codex",
|
|
101
|
+
path: best.path,
|
|
102
|
+
session_uuid: parsed.id,
|
|
103
|
+
project_cwd: projectCwd,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
async function walkJsonlFiles(root, maxDepth) {
|
|
107
|
+
const out = [];
|
|
108
|
+
async function visit(dir, depth) {
|
|
109
|
+
if (depth > maxDepth)
|
|
110
|
+
return;
|
|
111
|
+
let entries;
|
|
112
|
+
try {
|
|
113
|
+
entries = await fs.readdir(dir, { withFileTypes: true });
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
for (const e of entries) {
|
|
119
|
+
const full = join(dir, e.name);
|
|
120
|
+
if (e.isDirectory()) {
|
|
121
|
+
await visit(full, depth + 1);
|
|
122
|
+
}
|
|
123
|
+
else if (e.isFile() && e.name.endsWith(".jsonl")) {
|
|
124
|
+
out.push(full);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
await visit(root, 0);
|
|
129
|
+
return out;
|
|
130
|
+
}
|
|
131
|
+
async function readFirstJsonlLine(path) {
|
|
132
|
+
// Codex session_meta headers embed the full system prompt in
|
|
133
|
+
// payload.base_instructions.text (observed at 8+ KiB, 2026-07).
|
|
134
|
+
// A single-shot 8 KiB read truncated the JSON and the whole locator
|
|
135
|
+
// silently returned null. Stream chunks until we hit a newline;
|
|
136
|
+
// cap at 1 MiB defensively so a pathological file (missing newline)
|
|
137
|
+
// doesn't OOM us.
|
|
138
|
+
const CHUNK = 65536;
|
|
139
|
+
const MAX = 1024 * 1024;
|
|
140
|
+
let handle;
|
|
141
|
+
try {
|
|
142
|
+
handle = await fs.open(path, "r");
|
|
143
|
+
let offset = 0;
|
|
144
|
+
let acc = "";
|
|
145
|
+
while (offset < MAX) {
|
|
146
|
+
const buf = Buffer.alloc(CHUNK);
|
|
147
|
+
const { bytesRead } = await handle.read(buf, 0, buf.length, offset);
|
|
148
|
+
if (bytesRead === 0)
|
|
149
|
+
break;
|
|
150
|
+
const text = buf.slice(0, bytesRead).toString("utf8");
|
|
151
|
+
const nl = text.indexOf("\n");
|
|
152
|
+
if (nl >= 0)
|
|
153
|
+
return acc + text.slice(0, nl);
|
|
154
|
+
acc += text;
|
|
155
|
+
offset += bytesRead;
|
|
156
|
+
}
|
|
157
|
+
// Hit the cap without seeing a newline — treat as unparseable.
|
|
158
|
+
return null;
|
|
159
|
+
}
|
|
160
|
+
catch {
|
|
161
|
+
return null;
|
|
162
|
+
}
|
|
163
|
+
finally {
|
|
164
|
+
await handle?.close().catch(() => { });
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
function safeParseHeader(line) {
|
|
168
|
+
try {
|
|
169
|
+
const obj = JSON.parse(line);
|
|
170
|
+
// Codex writes session_meta as the first line. Some builds nest
|
|
171
|
+
// under `payload`, others put fields at the top level — accept
|
|
172
|
+
// both shapes rather than pinning to one version.
|
|
173
|
+
const payload = obj?.payload ?? obj;
|
|
174
|
+
const id = typeof payload?.id === "string" ? payload.id :
|
|
175
|
+
typeof payload?.session_id === "string" ? payload.session_id :
|
|
176
|
+
null;
|
|
177
|
+
const cwd = typeof payload?.cwd === "string" ? payload.cwd : null;
|
|
178
|
+
if (!id || !cwd)
|
|
179
|
+
return null;
|
|
180
|
+
return { id, cwd };
|
|
181
|
+
}
|
|
182
|
+
catch {
|
|
183
|
+
return null;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
/// Read the rollout bytes for upload. Returns raw bytes; caller PUTs to
|
|
187
|
+
/// the transcript signed URL as-is (no re-encoding).
|
|
188
|
+
export async function readRolloutBytes(hit) {
|
|
189
|
+
return fs.readFile(hit.path);
|
|
190
|
+
}
|
|
191
|
+
/// Drop any incomplete trailing turn from a rollout before uploading.
|
|
192
|
+
///
|
|
193
|
+
/// Beam-up-from-local runs INSIDE a turn: the last event the local agent
|
|
194
|
+
/// wrote is the `beam_up` tool call itself, and the matching tool result
|
|
195
|
+
/// hasn't happened yet (it can't — `beam_up` returning IS the upload
|
|
196
|
+
/// finishing). Uploading the raw rollout leaves a dangling tool call in
|
|
197
|
+
/// the beam's transcript, which Codex renders as "Conversation
|
|
198
|
+
/// interrupted" and Claude silently drops.
|
|
199
|
+
///
|
|
200
|
+
/// Trim to the last COMPLETE turn — the between-turn snapshot state
|
|
201
|
+
/// that fork already benefits from naturally (fork happens on a button
|
|
202
|
+
/// click, always between turns).
|
|
203
|
+
///
|
|
204
|
+
/// Conservative: on any parse trouble, returns the input unchanged.
|
|
205
|
+
/// The only failure mode is "we uploaded slightly too much" which is
|
|
206
|
+
/// the same UX as before this fix — never worse.
|
|
207
|
+
export function trimIncompleteTail(bytes, agentKind) {
|
|
208
|
+
const text = bytes.toString("utf8");
|
|
209
|
+
const trimmed = agentKind === "codex" ? trimCodexTail(text) : trimClaudeTail(text);
|
|
210
|
+
return Buffer.from(trimmed, "utf8");
|
|
211
|
+
}
|
|
212
|
+
/// Codex: trim to the last `event_msg / task_complete` marker.
|
|
213
|
+
///
|
|
214
|
+
/// Codex emits an explicit `task_complete` event when a turn (user
|
|
215
|
+
/// message + assistant reply + any tool_calls) is done. Anything after
|
|
216
|
+
/// the last `task_complete` is by definition mid-turn — including
|
|
217
|
+
/// dangling function_calls, in-flight assistant messages, or pending
|
|
218
|
+
/// tool_call_output events. Truncating at the last `task_complete`
|
|
219
|
+
/// gives a guaranteed clean state that codex's `resume --last` renders
|
|
220
|
+
/// without the "Conversation interrupted" banner.
|
|
221
|
+
///
|
|
222
|
+
/// Prior version of this trim only dropped dangling function_calls
|
|
223
|
+
/// (call_id with no matching function_call_output). That still left
|
|
224
|
+
/// the transcript ending on a `token_count` or `mcp_tool_call_end`
|
|
225
|
+
/// event inside the same turn, so codex still saw an open turn and
|
|
226
|
+
/// showed the banner. This tighter boundary is unambiguous.
|
|
227
|
+
///
|
|
228
|
+
/// Trade-off (approved by design): the last user turn — the one that
|
|
229
|
+
/// contained the `beam_up` tool_call — is dropped from the resumed
|
|
230
|
+
/// session. Users see prior completed turns cleanly; the beam-up
|
|
231
|
+
/// action itself doesn't render in the beam (they already see the
|
|
232
|
+
/// URL locally, so no user-facing loss).
|
|
233
|
+
///
|
|
234
|
+
/// If no `task_complete` exists at all (fresh session with no
|
|
235
|
+
/// completed turns yet), returns just the session_meta header so the
|
|
236
|
+
/// pod's `codex resume --last` still finds a syntactically-valid
|
|
237
|
+
/// rollout to pick up as "recent session" — the transcript will be
|
|
238
|
+
/// empty but the sentinel + agent boot won't error.
|
|
239
|
+
function trimCodexTail(text) {
|
|
240
|
+
const lines = text.split("\n");
|
|
241
|
+
let lastTaskCompleteLine = -1;
|
|
242
|
+
for (let i = 0; i < lines.length; i++) {
|
|
243
|
+
const line = lines[i];
|
|
244
|
+
if (!line)
|
|
245
|
+
continue;
|
|
246
|
+
let obj;
|
|
247
|
+
try {
|
|
248
|
+
obj = JSON.parse(line);
|
|
249
|
+
}
|
|
250
|
+
catch {
|
|
251
|
+
continue;
|
|
252
|
+
}
|
|
253
|
+
const p = obj?.payload;
|
|
254
|
+
if (p?.type === "task_complete") {
|
|
255
|
+
lastTaskCompleteLine = i;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
if (lastTaskCompleteLine === -1) {
|
|
259
|
+
// No completed turn on record. Keep only the session_meta
|
|
260
|
+
// header (line 0) so the file remains a valid codex rollout.
|
|
261
|
+
// Everything past that is by definition mid-turn.
|
|
262
|
+
const headerLine = lines.find((l) => l.length > 0);
|
|
263
|
+
return headerLine ? headerLine + "\n" : "";
|
|
264
|
+
}
|
|
265
|
+
const kept = lines.slice(0, lastTaskCompleteLine + 1);
|
|
266
|
+
return kept.join("\n") + "\n";
|
|
267
|
+
}
|
|
268
|
+
/// Claude: trim to the last `assistant` message with `stop_reason:
|
|
269
|
+
/// "end_turn"` — Claude's explicit turn-closed marker.
|
|
270
|
+
///
|
|
271
|
+
/// Symmetric to codex's task_complete boundary. `end_turn` is the
|
|
272
|
+
/// only stop_reason that means "the assistant fully responded and
|
|
273
|
+
/// isn't waiting on anything." Other values (`tool_use`,
|
|
274
|
+
/// `max_tokens`, `stop_sequence`, `pause_turn`) all leave the turn
|
|
275
|
+
/// mid-flight from the resume perspective — the model is either
|
|
276
|
+
/// awaiting a tool result or was cut off before finishing.
|
|
277
|
+
///
|
|
278
|
+
/// Same trade-off as codex: the user's mid-turn "beam this up"
|
|
279
|
+
/// question gets dropped from the resumed session. Users see the
|
|
280
|
+
/// beam URL locally so no user-facing loss; the resumed session
|
|
281
|
+
/// ends on a coherent last assistant reply.
|
|
282
|
+
///
|
|
283
|
+
/// If no `end_turn` line exists, returns empty — Claude Code
|
|
284
|
+
/// tolerates an empty transcript and fresh-boots the session.
|
|
285
|
+
function trimClaudeTail(text) {
|
|
286
|
+
const lines = text.split("\n");
|
|
287
|
+
let lastEndTurnLine = -1;
|
|
288
|
+
for (let i = 0; i < lines.length; i++) {
|
|
289
|
+
const line = lines[i];
|
|
290
|
+
if (!line)
|
|
291
|
+
continue;
|
|
292
|
+
let obj;
|
|
293
|
+
try {
|
|
294
|
+
obj = JSON.parse(line);
|
|
295
|
+
}
|
|
296
|
+
catch {
|
|
297
|
+
continue;
|
|
298
|
+
}
|
|
299
|
+
if (obj?.type === "assistant" &&
|
|
300
|
+
obj?.message?.stop_reason === "end_turn") {
|
|
301
|
+
lastEndTurnLine = i;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
if (lastEndTurnLine === -1) {
|
|
305
|
+
return "";
|
|
306
|
+
}
|
|
307
|
+
const kept = lines.slice(0, lastEndTurnLine + 1);
|
|
308
|
+
return kept.join("\n") + "\n";
|
|
309
|
+
}
|
|
310
|
+
/// SHA-256 hash of a file's bytes. Used for harness manifest entries.
|
|
311
|
+
/// Small files only (allowlist covers ~KB-to-MB). Caller enforces size
|
|
312
|
+
/// caps before hashing.
|
|
313
|
+
export async function sha256File(path) {
|
|
314
|
+
const bytes = await fs.readFile(path);
|
|
315
|
+
const h = createHash("sha256");
|
|
316
|
+
h.update(bytes);
|
|
317
|
+
return h.digest("hex");
|
|
318
|
+
}
|
|
319
|
+
//# sourceMappingURL=rollout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rollout.js","sourceRoot":"","sources":["../src/rollout.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,SAAS;IAGxB,cAAc,EAAE,MAAM,CAAC;IAEvB,KAAK,EAAE,MAAM,CAAC;IAGd,KAAK,EAAE,MAAM,CAAC;IAId,YAAY,EAAE,MAAM,CAAC;CACtB;AAMD,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAC"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@granica/myelin-beam-client",
|
|
3
|
+
"version": "0.1.0-alpha.0",
|
|
4
|
+
"description": "Shared Node client for Myelin beam-up/down endpoints. Consumed by @granica/myelin-beam-mcp (and future CLI). No agent-specific code.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"myelin",
|
|
7
|
+
"beam",
|
|
8
|
+
"client"
|
|
9
|
+
],
|
|
10
|
+
"homepage": "https://myelin.granica.ai",
|
|
11
|
+
"bugs": {
|
|
12
|
+
"url": "https://github.com/granica-ai/myelin/issues",
|
|
13
|
+
"email": "security@granica.ai"
|
|
14
|
+
},
|
|
15
|
+
"license": "Apache-2.0",
|
|
16
|
+
"author": "Granica <team@granica.ai>",
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "git+https://github.com/granica-ai/myelin.git",
|
|
20
|
+
"directory": "packages/beam-client"
|
|
21
|
+
},
|
|
22
|
+
"type": "module",
|
|
23
|
+
"main": "dist/index.js",
|
|
24
|
+
"types": "dist/index.d.ts",
|
|
25
|
+
"exports": {
|
|
26
|
+
".": {
|
|
27
|
+
"import": "./dist/index.js",
|
|
28
|
+
"types": "./dist/index.d.ts"
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"files": [
|
|
32
|
+
"dist",
|
|
33
|
+
"LICENSE",
|
|
34
|
+
"README.md"
|
|
35
|
+
],
|
|
36
|
+
"publishConfig": {
|
|
37
|
+
"access": "public",
|
|
38
|
+
"provenance": true,
|
|
39
|
+
"tag": "alpha"
|
|
40
|
+
},
|
|
41
|
+
"scripts": {
|
|
42
|
+
"build": "tsc -p tsconfig.json",
|
|
43
|
+
"clean": "rm -rf dist"
|
|
44
|
+
},
|
|
45
|
+
"engines": {
|
|
46
|
+
"node": ">=20.0.0"
|
|
47
|
+
},
|
|
48
|
+
"dependencies": {
|
|
49
|
+
"undici": "6.21.1"
|
|
50
|
+
},
|
|
51
|
+
"devDependencies": {
|
|
52
|
+
"@types/node": "20.19.9",
|
|
53
|
+
"typescript": "5.6.3"
|
|
54
|
+
}
|
|
55
|
+
}
|