@g3nomaly/mods 0.1.1 → 0.1.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/README.md +16 -21
- package/dist/cli/commands/add.d.ts.map +1 -1
- package/dist/cli/commands/add.js +2 -3
- package/dist/cli/commands/add.js.map +1 -1
- package/dist/cli/commands/init.d.ts +7 -4
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +6 -5
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/index.js +4 -3
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/viewer.d.ts +16 -5
- package/dist/cli/viewer.d.ts.map +1 -1
- package/dist/cli/viewer.js +76 -18
- package/dist/cli/viewer.js.map +1 -1
- package/dist/relay/index.d.ts +2 -0
- package/dist/relay/index.d.ts.map +1 -0
- package/dist/relay/index.js +9 -0
- package/dist/relay/index.js.map +1 -0
- package/dist/relay/lines.d.ts +25 -0
- package/dist/relay/lines.d.ts.map +1 -0
- package/dist/relay/lines.js +35 -0
- package/dist/relay/lines.js.map +1 -0
- package/dist/relay/protocol.d.ts +123 -0
- package/dist/relay/protocol.d.ts.map +1 -0
- package/dist/relay/protocol.js +70 -0
- package/dist/relay/protocol.js.map +1 -0
- package/dist/relay/relay.d.ts +16 -0
- package/dist/relay/relay.d.ts.map +1 -0
- package/dist/relay/relay.js +213 -0
- package/dist/relay/relay.js.map +1 -0
- package/dist/relay/sessions.d.ts +28 -0
- package/dist/relay/sessions.d.ts.map +1 -0
- package/dist/relay/sessions.js +86 -0
- package/dist/relay/sessions.js.map +1 -0
- package/dist/viewer/index.d.ts +6 -0
- package/dist/viewer/index.d.ts.map +1 -1
- package/dist/viewer/index.js +3 -0
- package/dist/viewer/index.js.map +1 -1
- package/dist/viewer/machine.d.ts +37 -0
- package/dist/viewer/machine.d.ts.map +1 -0
- package/dist/viewer/machine.js +55 -0
- package/dist/viewer/machine.js.map +1 -0
- package/dist/viewer/relay.d.ts +23 -0
- package/dist/viewer/relay.d.ts.map +1 -0
- package/dist/viewer/relay.js +51 -0
- package/dist/viewer/relay.js.map +1 -0
- package/dist/viewer/viewerExtension.d.ts +27 -0
- package/dist/viewer/viewerExtension.d.ts.map +1 -0
- package/dist/viewer/viewerExtension.js +48 -0
- package/dist/viewer/viewerExtension.js.map +1 -0
- package/dist/vscode/g3n-mods-viewer.vsix +0 -0
- package/package.json +9 -5
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
// packages/mods/src/relay/protocol.ts
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
/** The surface the viewer draws as, and the client id it attaches under. */
|
|
4
|
+
export const VIEWER_SURFACE = "vscode";
|
|
5
|
+
export const VIEWER_CLIENT_ID = "g3n-viewer";
|
|
6
|
+
/** Prefix of the request ids the relay gives the control requests it sends for a viewer. */
|
|
7
|
+
export const RELAY_REQUEST_PREFIX = "g3nv:";
|
|
8
|
+
/** The engine's UI requests a viewer may send; the relay refuses every other subtype. */
|
|
9
|
+
export const ViewerRequestSchema = z.discriminatedUnion("subtype", [
|
|
10
|
+
z.object({
|
|
11
|
+
subtype: z.literal("ui_render"),
|
|
12
|
+
component: z.string().min(1),
|
|
13
|
+
instance_id: z.string().min(1),
|
|
14
|
+
props: z.record(z.string(), z.unknown()),
|
|
15
|
+
viewport: z.object({ columns: z.number().int().positive(), rows: z.number().int().positive() }).optional(),
|
|
16
|
+
}),
|
|
17
|
+
z.object({
|
|
18
|
+
subtype: z.literal("ui_press"),
|
|
19
|
+
plugin: z.string(),
|
|
20
|
+
handle: z.number().int(),
|
|
21
|
+
key: z.string().optional(),
|
|
22
|
+
href: z.string().max(2048).optional(),
|
|
23
|
+
}),
|
|
24
|
+
z.object({
|
|
25
|
+
subtype: z.literal("ui_input"),
|
|
26
|
+
plugin: z.string(),
|
|
27
|
+
handle: z.number().int(),
|
|
28
|
+
kind: z.enum(["change", "submit"]),
|
|
29
|
+
value: z.string().max(16384),
|
|
30
|
+
key: z.string().optional(),
|
|
31
|
+
component: z.string().optional(),
|
|
32
|
+
instance_id: z.string().optional(),
|
|
33
|
+
}),
|
|
34
|
+
z.object({
|
|
35
|
+
subtype: z.literal("ui_select"),
|
|
36
|
+
plugin: z.string(),
|
|
37
|
+
handle: z.number().int(),
|
|
38
|
+
value: z.string().max(16384),
|
|
39
|
+
key: z.string().optional(),
|
|
40
|
+
component: z.string().optional(),
|
|
41
|
+
instance_id: z.string().optional(),
|
|
42
|
+
}),
|
|
43
|
+
z.object({ subtype: z.literal("ui_panes") }),
|
|
44
|
+
z.object({ subtype: z.literal("ui_close"), id: z.string().min(1) }),
|
|
45
|
+
]);
|
|
46
|
+
/** One line a viewer sends the relay: a UI request it numbers itself. */
|
|
47
|
+
export const ViewerMessageSchema = z.object({
|
|
48
|
+
id: z.string().min(1).max(64),
|
|
49
|
+
request: ViewerRequestSchema,
|
|
50
|
+
});
|
|
51
|
+
/** Subtypes of the engine's `system` messages the relay copies to every viewer. */
|
|
52
|
+
export const RELAYED_PUSHES = new Set(["ui_panes", "ui_invalidate"]);
|
|
53
|
+
/**
|
|
54
|
+
* The control request a viewer request becomes on Claude's stdin: the
|
|
55
|
+
* viewer's surface and client id are filled in where the engine takes them.
|
|
56
|
+
*/
|
|
57
|
+
export function toControlRequest(request) {
|
|
58
|
+
switch (request.subtype) {
|
|
59
|
+
case "ui_render":
|
|
60
|
+
return { ...request, surface: VIEWER_SURFACE, client_id: VIEWER_CLIENT_ID };
|
|
61
|
+
case "ui_press":
|
|
62
|
+
case "ui_input":
|
|
63
|
+
case "ui_select":
|
|
64
|
+
return { ...request, surface: VIEWER_SURFACE };
|
|
65
|
+
case "ui_panes":
|
|
66
|
+
case "ui_close":
|
|
67
|
+
return { ...request, client_id: VIEWER_CLIENT_ID };
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=protocol.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protocol.js","sourceRoot":"","sources":["../../src/relay/protocol.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runs Claude Code as a child and stands on its stdio pipe: everything the
|
|
3
|
+
* extension writes reaches Claude and everything Claude writes reaches the
|
|
4
|
+
* extension, line for line and unchanged. Beside that it serves viewers on a
|
|
5
|
+
* local socket, attaches to the session as the `vscode` surface while one is
|
|
6
|
+
* connected, sends their UI requests as control requests of its own, and
|
|
7
|
+
* keeps the answers and the pane pushes they need away from the extension.
|
|
8
|
+
* A launch that is no stream-json session (`--version`, a subcommand) runs
|
|
9
|
+
* straight through, with no socket.
|
|
10
|
+
*
|
|
11
|
+
* @param claudePath - Absolute path of the Claude Code executable the extension wanted to launch
|
|
12
|
+
* @param args - Claude Code's arguments, passed on as given
|
|
13
|
+
* @returns Claude's exit code, once it has ended and the socket is closed
|
|
14
|
+
*/
|
|
15
|
+
export declare function runRelay(claudePath: string, args: readonly string[]): Promise<number>;
|
|
16
|
+
//# sourceMappingURL=relay.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relay.d.ts","sourceRoot":"","sources":["../../src/relay/relay.ts"],"names":[],"mappings":"AAsDA;;;;;;;;;;;;;GAaG;AACH,wBAAsB,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CA4I3F"}
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
// packages/mods/src/relay/relay.ts
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import net from "node:net";
|
|
4
|
+
import { LineSplitter } from "./lines";
|
|
5
|
+
import { RELAYED_PUSHES, RELAY_REQUEST_PREFIX, VIEWER_CLIENT_ID, VIEWER_SURFACE, ViewerMessageSchema, toControlRequest, } from "./protocol";
|
|
6
|
+
import { removeSession, socketPath, writeSessionInfo } from "./sessions";
|
|
7
|
+
/** Writes one relay message to a viewer as a JSON line; a closed socket is skipped. */
|
|
8
|
+
function send(socket, message) {
|
|
9
|
+
if (!socket.destroyed)
|
|
10
|
+
socket.write(JSON.stringify(message) + "\n");
|
|
11
|
+
}
|
|
12
|
+
/** Parses a line as a JSON object, or `undefined` when it is not one. */
|
|
13
|
+
function parseObject(line) {
|
|
14
|
+
try {
|
|
15
|
+
const value = JSON.parse(line);
|
|
16
|
+
return typeof value === "object" && value !== null ? value : undefined;
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
return undefined;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
/** The text of the first prompt in a `user` line from the extension, or `undefined` for any other line. */
|
|
23
|
+
function promptText(line) {
|
|
24
|
+
if (!line.includes('"type":"user"'))
|
|
25
|
+
return undefined;
|
|
26
|
+
const message = parseObject(line)?.message;
|
|
27
|
+
const content = message?.content;
|
|
28
|
+
const text = typeof content === "string"
|
|
29
|
+
? content
|
|
30
|
+
: Array.isArray(content)
|
|
31
|
+
? content.map((block) => (typeof block === "object" && block !== null && block.type === "text" ? String(block.text ?? "") : "")).join(" ")
|
|
32
|
+
: "";
|
|
33
|
+
const title = text.replace(/\s+/g, " ").trim();
|
|
34
|
+
return title === "" ? undefined : title.slice(0, 80);
|
|
35
|
+
}
|
|
36
|
+
/** Runs Claude Code with the relay's own stdio, for the one-off commands the extension runs that are no session. */
|
|
37
|
+
async function passThrough(claudePath, args) {
|
|
38
|
+
const child = Bun.spawn([claudePath, ...args], { stdin: "inherit", stdout: "inherit", stderr: "inherit", env: process.env });
|
|
39
|
+
for (const signal of ["SIGINT", "SIGTERM", "SIGHUP"])
|
|
40
|
+
process.on(signal, () => child.kill(signal));
|
|
41
|
+
return child.exited;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Runs Claude Code as a child and stands on its stdio pipe: everything the
|
|
45
|
+
* extension writes reaches Claude and everything Claude writes reaches the
|
|
46
|
+
* extension, line for line and unchanged. Beside that it serves viewers on a
|
|
47
|
+
* local socket, attaches to the session as the `vscode` surface while one is
|
|
48
|
+
* connected, sends their UI requests as control requests of its own, and
|
|
49
|
+
* keeps the answers and the pane pushes they need away from the extension.
|
|
50
|
+
* A launch that is no stream-json session (`--version`, a subcommand) runs
|
|
51
|
+
* straight through, with no socket.
|
|
52
|
+
*
|
|
53
|
+
* @param claudePath - Absolute path of the Claude Code executable the extension wanted to launch
|
|
54
|
+
* @param args - Claude Code's arguments, passed on as given
|
|
55
|
+
* @returns Claude's exit code, once it has ended and the socket is closed
|
|
56
|
+
*/
|
|
57
|
+
export async function runRelay(claudePath, args) {
|
|
58
|
+
if (!args.includes("stream-json"))
|
|
59
|
+
return passThrough(claudePath, args);
|
|
60
|
+
const child = Bun.spawn([claudePath, ...args], { stdin: "pipe", stdout: "pipe", stderr: "inherit", env: process.env });
|
|
61
|
+
const info = { pid: process.pid, socket: socketPath(process.pid), cwd: process.cwd(), startedAt: Date.now() };
|
|
62
|
+
const viewers = new Set();
|
|
63
|
+
const pending = new Map();
|
|
64
|
+
const queued = [];
|
|
65
|
+
let isReady = false;
|
|
66
|
+
let nextConnection = 0;
|
|
67
|
+
const writeToClaude = (line) => {
|
|
68
|
+
child.stdin.write(line + "\n");
|
|
69
|
+
child.stdin.flush();
|
|
70
|
+
};
|
|
71
|
+
/** Sends a control request of the relay's own, holding it until Claude has answered its first message. */
|
|
72
|
+
const inject = (requestId, request) => {
|
|
73
|
+
const line = JSON.stringify({ type: "control_request", request_id: requestId, request });
|
|
74
|
+
if (isReady)
|
|
75
|
+
writeToClaude(line);
|
|
76
|
+
else
|
|
77
|
+
queued.push(line);
|
|
78
|
+
};
|
|
79
|
+
const markReady = () => {
|
|
80
|
+
if (isReady)
|
|
81
|
+
return;
|
|
82
|
+
isReady = true;
|
|
83
|
+
for (const line of queued.splice(0))
|
|
84
|
+
writeToClaude(line);
|
|
85
|
+
};
|
|
86
|
+
const publish = () => {
|
|
87
|
+
try {
|
|
88
|
+
writeSessionInfo(info);
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
// A viewer cannot find this session without the file; the session itself runs on.
|
|
92
|
+
}
|
|
93
|
+
for (const viewer of viewers)
|
|
94
|
+
send(viewer, { type: "session", session: info });
|
|
95
|
+
};
|
|
96
|
+
fs.rmSync(info.socket, { force: true });
|
|
97
|
+
const server = net.createServer((socket) => {
|
|
98
|
+
const connection = ++nextConnection;
|
|
99
|
+
const lines = new LineSplitter();
|
|
100
|
+
viewers.add(socket);
|
|
101
|
+
if (viewers.size === 1)
|
|
102
|
+
inject(`${RELAY_REQUEST_PREFIX}attach`, { subtype: "ui_attach", surface: VIEWER_SURFACE, client_id: VIEWER_CLIENT_ID });
|
|
103
|
+
send(socket, { type: "session", session: info });
|
|
104
|
+
socket.on("data", (chunk) => {
|
|
105
|
+
for (const line of lines.push(chunk)) {
|
|
106
|
+
if (line.trim() === "")
|
|
107
|
+
continue;
|
|
108
|
+
const parsed = ViewerMessageSchema.safeParse(parseObject(line));
|
|
109
|
+
if (!parsed.success) {
|
|
110
|
+
const id = typeof parseObject(line)?.id === "string" ? String(parseObject(line)?.id) : "";
|
|
111
|
+
send(socket, { type: "response", id, error: `not a viewer request: ${parsed.error.issues[0]?.message ?? "invalid"}` });
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
const requestId = `${RELAY_REQUEST_PREFIX}${connection}:${parsed.data.id}`;
|
|
115
|
+
pending.set(requestId, { socket, id: parsed.data.id });
|
|
116
|
+
inject(requestId, toControlRequest(parsed.data.request));
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
const drop = () => {
|
|
120
|
+
if (!viewers.delete(socket))
|
|
121
|
+
return;
|
|
122
|
+
for (const [requestId, request] of pending)
|
|
123
|
+
if (request.socket === socket)
|
|
124
|
+
pending.delete(requestId);
|
|
125
|
+
if (viewers.size === 0)
|
|
126
|
+
inject(`${RELAY_REQUEST_PREFIX}detach`, { subtype: "ui_detach", client_id: VIEWER_CLIENT_ID });
|
|
127
|
+
};
|
|
128
|
+
socket.on("close", drop);
|
|
129
|
+
socket.on("error", drop);
|
|
130
|
+
});
|
|
131
|
+
server.on("error", () => {
|
|
132
|
+
// Without the socket no viewer can attach; the session itself runs on.
|
|
133
|
+
});
|
|
134
|
+
server.listen(info.socket, () => {
|
|
135
|
+
fs.chmodSync(info.socket, 0o600);
|
|
136
|
+
publish();
|
|
137
|
+
});
|
|
138
|
+
/** Routes a line from Claude: the relay's own answers go to their viewer, everything else to the extension. */
|
|
139
|
+
const fromClaude = (line) => {
|
|
140
|
+
if (line.includes('"control_response"')) {
|
|
141
|
+
markReady();
|
|
142
|
+
if (line.includes(RELAY_REQUEST_PREFIX)) {
|
|
143
|
+
const response = parseObject(line)?.response;
|
|
144
|
+
const requestId = typeof response?.request_id === "string" ? response.request_id : "";
|
|
145
|
+
if (requestId.startsWith(RELAY_REQUEST_PREFIX)) {
|
|
146
|
+
const request = pending.get(requestId);
|
|
147
|
+
pending.delete(requestId);
|
|
148
|
+
if (request !== undefined) {
|
|
149
|
+
send(request.socket, response?.subtype === "error"
|
|
150
|
+
? { type: "response", id: request.id, error: String(response.error ?? "the engine refused the request") }
|
|
151
|
+
: { type: "response", id: request.id, response: response?.response });
|
|
152
|
+
}
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
else if (line.includes('"subtype":"init"') || line.includes('"subtype":"ui_')) {
|
|
158
|
+
const message = parseObject(line);
|
|
159
|
+
if (message?.type === "system" && message.subtype === "init") {
|
|
160
|
+
markReady();
|
|
161
|
+
if (typeof message.session_id === "string")
|
|
162
|
+
info.sessionId = message.session_id;
|
|
163
|
+
if (typeof message.cwd === "string")
|
|
164
|
+
info.cwd = message.cwd;
|
|
165
|
+
publish();
|
|
166
|
+
}
|
|
167
|
+
else if (message?.type === "system" && RELAYED_PUSHES.has(String(message.subtype))) {
|
|
168
|
+
for (const viewer of viewers)
|
|
169
|
+
send(viewer, { type: "push", push: message });
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
process.stdout.write(line + "\n");
|
|
173
|
+
};
|
|
174
|
+
const forwardStdin = (async () => {
|
|
175
|
+
const lines = new LineSplitter();
|
|
176
|
+
for await (const chunk of process.stdin) {
|
|
177
|
+
for (const line of lines.push(chunk)) {
|
|
178
|
+
writeToClaude(line);
|
|
179
|
+
if (info.title === undefined) {
|
|
180
|
+
const title = promptText(line);
|
|
181
|
+
if (title !== undefined) {
|
|
182
|
+
info.title = title;
|
|
183
|
+
publish();
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
const rest = lines.flush();
|
|
189
|
+
if (rest !== undefined)
|
|
190
|
+
child.stdin.write(rest);
|
|
191
|
+
await child.stdin.end();
|
|
192
|
+
})().catch(() => undefined);
|
|
193
|
+
const forwardStdout = (async () => {
|
|
194
|
+
const lines = new LineSplitter();
|
|
195
|
+
for await (const chunk of child.stdout)
|
|
196
|
+
for (const line of lines.push(chunk))
|
|
197
|
+
fromClaude(line);
|
|
198
|
+
const rest = lines.flush();
|
|
199
|
+
if (rest !== undefined)
|
|
200
|
+
process.stdout.write(rest);
|
|
201
|
+
})();
|
|
202
|
+
for (const signal of ["SIGINT", "SIGTERM", "SIGHUP"])
|
|
203
|
+
process.on(signal, () => child.kill(signal));
|
|
204
|
+
const exitCode = await child.exited;
|
|
205
|
+
await forwardStdout;
|
|
206
|
+
void forwardStdin;
|
|
207
|
+
for (const viewer of viewers)
|
|
208
|
+
viewer.destroy();
|
|
209
|
+
server.close();
|
|
210
|
+
removeSession(info.pid);
|
|
211
|
+
return exitCode;
|
|
212
|
+
}
|
|
213
|
+
//# sourceMappingURL=relay.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relay.js","sourceRoot":"","sources":["../../src/relay/relay.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/** What a relay says about the session it runs, written beside its socket as `<pid>.json`. */
|
|
3
|
+
export declare const SessionInfoSchema: z.ZodObject<{
|
|
4
|
+
pid: z.ZodNumber;
|
|
5
|
+
socket: z.ZodString;
|
|
6
|
+
cwd: z.ZodString;
|
|
7
|
+
startedAt: z.ZodNumber;
|
|
8
|
+
sessionId: z.ZodOptional<z.ZodString>;
|
|
9
|
+
title: z.ZodOptional<z.ZodString>;
|
|
10
|
+
}, z.core.$strip>;
|
|
11
|
+
export type SessionInfo = z.infer<typeof SessionInfoSchema>;
|
|
12
|
+
/**
|
|
13
|
+
* Folder the relays of this user put their sockets and session files in:
|
|
14
|
+
* `$XDG_RUNTIME_DIR/g3n-mods`, else `<tmp>/g3n-mods-<uid>`.
|
|
15
|
+
*/
|
|
16
|
+
export declare function sessionsDir(): string;
|
|
17
|
+
/** Socket path of the relay with this process id. */
|
|
18
|
+
export declare function socketPath(pid: number): string;
|
|
19
|
+
/** Writes or replaces a relay's session file. */
|
|
20
|
+
export declare function writeSessionInfo(info: SessionInfo): void;
|
|
21
|
+
/** Removes a relay's session file and socket; missing files are ignored. */
|
|
22
|
+
export declare function removeSession(pid: number): void;
|
|
23
|
+
/**
|
|
24
|
+
* The sessions whose relay still runs, newest first. Files of relays that
|
|
25
|
+
* ended without cleaning up are removed on the way.
|
|
26
|
+
*/
|
|
27
|
+
export declare function listSessions(): SessionInfo[];
|
|
28
|
+
//# sourceMappingURL=sessions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessions.d.ts","sourceRoot":"","sources":["../../src/relay/sessions.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,8FAA8F;AAC9F,eAAO,MAAM,iBAAiB;;;;;;;iBAa5B,CAAC;AAEH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAE5D;;;GAGG;AACH,wBAAgB,WAAW,IAAI,MAAM,CAKpC;AAED,qDAAqD;AACrD,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE9C;AAMD,iDAAiD;AACjD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,CAKxD;AAED,4EAA4E;AAC5E,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAE/C;AAWD;;;GAGG;AACH,wBAAgB,YAAY,IAAI,WAAW,EAAE,CAgB5C"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
// packages/mods/src/relay/sessions.ts
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import os from "node:os";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import { z } from "zod";
|
|
6
|
+
/** What a relay says about the session it runs, written beside its socket as `<pid>.json`. */
|
|
7
|
+
export const SessionInfoSchema = z.object({
|
|
8
|
+
/** Process id of the relay */
|
|
9
|
+
pid: z.number().int(),
|
|
10
|
+
/** Absolute path of the relay's socket */
|
|
11
|
+
socket: z.string().min(1),
|
|
12
|
+
/** Absolute working directory of the session */
|
|
13
|
+
cwd: z.string(),
|
|
14
|
+
/** Milliseconds since the epoch */
|
|
15
|
+
startedAt: z.number(),
|
|
16
|
+
/** Claude Code's session id, once the session has reported it */
|
|
17
|
+
sessionId: z.string().optional(),
|
|
18
|
+
/** The first prompt of the session, cut to 80 characters */
|
|
19
|
+
title: z.string().optional(),
|
|
20
|
+
});
|
|
21
|
+
/**
|
|
22
|
+
* Folder the relays of this user put their sockets and session files in:
|
|
23
|
+
* `$XDG_RUNTIME_DIR/g3n-mods`, else `<tmp>/g3n-mods-<uid>`.
|
|
24
|
+
*/
|
|
25
|
+
export function sessionsDir() {
|
|
26
|
+
const runtime = process.env.XDG_RUNTIME_DIR;
|
|
27
|
+
if (runtime !== undefined && runtime !== "")
|
|
28
|
+
return path.join(runtime, "g3n-mods");
|
|
29
|
+
const uid = typeof process.getuid === "function" ? process.getuid() : os.userInfo().username;
|
|
30
|
+
return path.join(os.tmpdir(), `g3n-mods-${uid}`);
|
|
31
|
+
}
|
|
32
|
+
/** Socket path of the relay with this process id. */
|
|
33
|
+
export function socketPath(pid) {
|
|
34
|
+
return path.join(sessionsDir(), `${pid}.sock`);
|
|
35
|
+
}
|
|
36
|
+
function infoPath(pid) {
|
|
37
|
+
return path.join(sessionsDir(), `${pid}.json`);
|
|
38
|
+
}
|
|
39
|
+
/** Writes or replaces a relay's session file. */
|
|
40
|
+
export function writeSessionInfo(info) {
|
|
41
|
+
fs.mkdirSync(sessionsDir(), { recursive: true, mode: 0o700 });
|
|
42
|
+
const file = infoPath(info.pid);
|
|
43
|
+
fs.writeFileSync(`${file}.tmp`, JSON.stringify(info));
|
|
44
|
+
fs.renameSync(`${file}.tmp`, file);
|
|
45
|
+
}
|
|
46
|
+
/** Removes a relay's session file and socket; missing files are ignored. */
|
|
47
|
+
export function removeSession(pid) {
|
|
48
|
+
for (const file of [infoPath(pid), socketPath(pid)])
|
|
49
|
+
fs.rmSync(file, { force: true });
|
|
50
|
+
}
|
|
51
|
+
function isAlive(pid) {
|
|
52
|
+
try {
|
|
53
|
+
process.kill(pid, 0);
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
return error.code === "EPERM";
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* The sessions whose relay still runs, newest first. Files of relays that
|
|
62
|
+
* ended without cleaning up are removed on the way.
|
|
63
|
+
*/
|
|
64
|
+
export function listSessions() {
|
|
65
|
+
const dir = sessionsDir();
|
|
66
|
+
if (!fs.existsSync(dir))
|
|
67
|
+
return [];
|
|
68
|
+
const sessions = [];
|
|
69
|
+
for (const name of fs.readdirSync(dir)) {
|
|
70
|
+
if (!name.endsWith(".json"))
|
|
71
|
+
continue;
|
|
72
|
+
let info;
|
|
73
|
+
try {
|
|
74
|
+
info = SessionInfoSchema.parse(JSON.parse(fs.readFileSync(path.join(dir, name), "utf8")));
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
if (isAlive(info.pid) && fs.existsSync(info.socket))
|
|
80
|
+
sessions.push(info);
|
|
81
|
+
else
|
|
82
|
+
removeSession(info.pid);
|
|
83
|
+
}
|
|
84
|
+
return sessions.sort((a, b) => b.startedAt - a.startedAt);
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=sessions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessions.js","sourceRoot":"","sources":["../../src/relay/sessions.ts"],"names":[],"mappings":"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"}
|
package/dist/viewer/index.d.ts
CHANGED
|
@@ -2,4 +2,10 @@ export { MIN_ENGINE_VERSION, compareVersions, findClaudeExtension } from "./exte
|
|
|
2
2
|
export type { ClaudeExtension } from "./extension";
|
|
3
3
|
export { ViewerLocationSchema, configureViewer } from "./settings";
|
|
4
4
|
export type { ViewerLocation, ViewerSettingsResult } from "./settings";
|
|
5
|
+
export { installRelay, relayBinaryPath } from "./relay";
|
|
6
|
+
export type { RelayInstallResult } from "./relay";
|
|
7
|
+
export { machineSettingsPath, setProcessWrapper } from "./machine";
|
|
8
|
+
export type { WrapperResult } from "./machine";
|
|
9
|
+
export { VIEWER_EXTENSION_ID, installViewer, viewerPackagePath } from "./viewerExtension";
|
|
10
|
+
export type { ViewerInstallResult } from "./viewerExtension";
|
|
5
11
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/viewer/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACvF,YAAY,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AACnE,YAAY,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/viewer/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACvF,YAAY,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AACnE,YAAY,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AACvE,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AACxD,YAAY,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAClD,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AACnE,YAAY,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,EAAE,mBAAmB,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAC1F,YAAY,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC"}
|
package/dist/viewer/index.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
// packages/mods/src/viewer/index.ts
|
|
2
2
|
export { MIN_ENGINE_VERSION, compareVersions, findClaudeExtension } from "./extension";
|
|
3
3
|
export { ViewerLocationSchema, configureViewer } from "./settings";
|
|
4
|
+
export { installRelay, relayBinaryPath } from "./relay";
|
|
5
|
+
export { machineSettingsPath, setProcessWrapper } from "./machine";
|
|
6
|
+
export { VIEWER_EXTENSION_ID, installViewer, viewerPackagePath } from "./viewerExtension";
|
|
4
7
|
//# sourceMappingURL=index.js.map
|
package/dist/viewer/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/viewer/index.ts"],"names":[],"mappings":"AAAA,oCAAoC;AACpC,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAEvF,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/viewer/index.ts"],"names":[],"mappings":"AAAA,oCAAoC;AACpC,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAEvF,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAEnE,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAExD,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAEnE,OAAO,EAAE,mBAAmB,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The settings file VS Code reads machine-scoped settings from on this
|
|
3
|
+
* machine: the server's `Machine/settings.json` under a remote (WSL, SSH),
|
|
4
|
+
* else the desktop's user settings.
|
|
5
|
+
*/
|
|
6
|
+
export declare function machineSettingsPath(home?: string): string;
|
|
7
|
+
/** What `setProcessWrapper` did. */
|
|
8
|
+
export type WrapperResult = {
|
|
9
|
+
kind: "written";
|
|
10
|
+
file: string;
|
|
11
|
+
} | {
|
|
12
|
+
kind: "unchanged";
|
|
13
|
+
file: string;
|
|
14
|
+
}
|
|
15
|
+
/** Another wrapper is set; it was left in place */
|
|
16
|
+
| {
|
|
17
|
+
kind: "taken";
|
|
18
|
+
file: string;
|
|
19
|
+
current: string;
|
|
20
|
+
}
|
|
21
|
+
/** The file is not plain JSON (comments, trailing commas); nothing was written */
|
|
22
|
+
| {
|
|
23
|
+
kind: "unreadable";
|
|
24
|
+
file: string;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Sets `claudeCode.claudeProcessWrapper` to the relay, so the Claude Code
|
|
28
|
+
* extension launches every session through it. A different wrapper already
|
|
29
|
+
* set is kept unless `force` is passed; the file's other settings are kept.
|
|
30
|
+
*
|
|
31
|
+
* @param relay - Absolute path of the relay executable
|
|
32
|
+
*/
|
|
33
|
+
export declare function setProcessWrapper(relay: string, options?: {
|
|
34
|
+
force?: boolean;
|
|
35
|
+
home?: string;
|
|
36
|
+
}): WrapperResult;
|
|
37
|
+
//# sourceMappingURL=machine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"machine.d.ts","sourceRoot":"","sources":["../../src/viewer/machine.ts"],"names":[],"mappings":"AAUA;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,GAAE,MAAqB,GAAG,MAAM,CAKvE;AAED,oCAAoC;AACpC,MAAM,MAAM,aAAa,GACrB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACjC;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE;AACrC,mDAAmD;GACjD;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE;AAClD,kFAAkF;GAChF;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzC;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,aAAa,CAuBhH"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
// packages/mods/src/viewer/machine.ts
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import os from "node:os";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import { z } from "zod";
|
|
6
|
+
const WRAPPER_KEY = "claudeCode.claudeProcessWrapper";
|
|
7
|
+
const SettingsSchema = z.record(z.string(), z.unknown());
|
|
8
|
+
/**
|
|
9
|
+
* The settings file VS Code reads machine-scoped settings from on this
|
|
10
|
+
* machine: the server's `Machine/settings.json` under a remote (WSL, SSH),
|
|
11
|
+
* else the desktop's user settings.
|
|
12
|
+
*/
|
|
13
|
+
export function machineSettingsPath(home = os.homedir()) {
|
|
14
|
+
if (fs.existsSync(path.join(home, ".vscode-server")))
|
|
15
|
+
return path.join(home, ".vscode-server", "data", "Machine", "settings.json");
|
|
16
|
+
if (process.platform === "darwin")
|
|
17
|
+
return path.join(home, "Library", "Application Support", "Code", "User", "settings.json");
|
|
18
|
+
if (process.platform === "win32")
|
|
19
|
+
return path.join(process.env.APPDATA ?? path.join(home, "AppData", "Roaming"), "Code", "User", "settings.json");
|
|
20
|
+
return path.join(home, ".config", "Code", "User", "settings.json");
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Sets `claudeCode.claudeProcessWrapper` to the relay, so the Claude Code
|
|
24
|
+
* extension launches every session through it. A different wrapper already
|
|
25
|
+
* set is kept unless `force` is passed; the file's other settings are kept.
|
|
26
|
+
*
|
|
27
|
+
* @param relay - Absolute path of the relay executable
|
|
28
|
+
*/
|
|
29
|
+
export function setProcessWrapper(relay, options = {}) {
|
|
30
|
+
const file = machineSettingsPath(options.home);
|
|
31
|
+
let current = {};
|
|
32
|
+
if (fs.existsSync(file)) {
|
|
33
|
+
const text = fs.readFileSync(file, "utf8");
|
|
34
|
+
let parsed;
|
|
35
|
+
try {
|
|
36
|
+
parsed = text.trim() === "" ? {} : JSON.parse(text);
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
return { kind: "unreadable", file };
|
|
40
|
+
}
|
|
41
|
+
const settings = SettingsSchema.safeParse(parsed);
|
|
42
|
+
if (!settings.success)
|
|
43
|
+
return { kind: "unreadable", file };
|
|
44
|
+
current = settings.data;
|
|
45
|
+
}
|
|
46
|
+
const existing = current[WRAPPER_KEY];
|
|
47
|
+
if (existing === relay)
|
|
48
|
+
return { kind: "unchanged", file };
|
|
49
|
+
if (typeof existing === "string" && existing !== "" && options.force !== true)
|
|
50
|
+
return { kind: "taken", file, current: existing };
|
|
51
|
+
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
52
|
+
fs.writeFileSync(file, JSON.stringify({ ...current, [WRAPPER_KEY]: relay }, null, 2) + "\n");
|
|
53
|
+
return { kind: "written", file };
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=machine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"machine.js","sourceRoot":"","sources":["../../src/viewer/machine.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/** Where `init` builds the relay: one executable per machine, since VS Code sets the wrapper per machine. */
|
|
2
|
+
export declare function relayBinaryPath(home?: string): string;
|
|
3
|
+
/** What `installRelay` did. */
|
|
4
|
+
export type RelayInstallResult = {
|
|
5
|
+
kind: "built";
|
|
6
|
+
binary: string;
|
|
7
|
+
} | {
|
|
8
|
+
kind: "current";
|
|
9
|
+
binary: string;
|
|
10
|
+
} | {
|
|
11
|
+
kind: "failed";
|
|
12
|
+
binary: string;
|
|
13
|
+
reason: string;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Builds the relay into a standalone executable with `bun build --compile`,
|
|
17
|
+
* unless the one already there was built from the same sources. A stamp
|
|
18
|
+
* file beside it holds the hash of those sources.
|
|
19
|
+
*
|
|
20
|
+
* @param home - Home directory the executable goes under; the current user's by default
|
|
21
|
+
*/
|
|
22
|
+
export declare function installRelay(home?: string): Promise<RelayInstallResult>;
|
|
23
|
+
//# sourceMappingURL=relay.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relay.d.ts","sourceRoot":"","sources":["../../src/viewer/relay.ts"],"names":[],"mappings":"AAOA,6GAA6G;AAC7G,wBAAgB,eAAe,CAAC,IAAI,GAAE,MAAqB,GAAG,MAAM,CAEnE;AAED,+BAA+B;AAC/B,MAAM,MAAM,kBAAkB,GAC1B;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACjC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACnC;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAevD;;;;;;GAMG;AACH,wBAAsB,YAAY,CAAC,IAAI,GAAE,MAAqB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAmB3F"}
|