@g3nomaly/mods 0.1.0 → 0.1.2
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 +13 -12
- package/dist/cli/commands/add.d.ts +11 -2
- package/dist/cli/commands/add.d.ts.map +1 -1
- package/dist/cli/commands/add.js +7 -4
- package/dist/cli/commands/add.js.map +1 -1
- package/dist/cli/commands/init.d.ts +15 -4
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +8 -4
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/ls.d.ts +13 -3
- package/dist/cli/commands/ls.d.ts.map +1 -1
- package/dist/cli/commands/ls.js +6 -1
- package/dist/cli/commands/ls.js.map +1 -1
- package/dist/cli/commands/remove.d.ts +10 -1
- package/dist/cli/commands/remove.d.ts.map +1 -1
- package/dist/cli/commands/remove.js +11 -2
- package/dist/cli/commands/remove.js.map +1 -1
- package/dist/cli/commands/source.d.ts +37 -6
- package/dist/cli/commands/source.d.ts.map +1 -1
- package/dist/cli/commands/source.js +23 -4
- package/dist/cli/commands/source.js.map +1 -1
- package/dist/cli/commands/update.d.ts +10 -1
- package/dist/cli/commands/update.d.ts.map +1 -1
- package/dist/cli/commands/update.js +5 -1
- package/dist/cli/commands/update.js.map +1 -1
- package/dist/cli/index.js +10 -4
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/project.d.ts +34 -11
- package/dist/cli/project.d.ts.map +1 -1
- package/dist/cli/project.js +19 -5
- package/dist/cli/project.js.map +1 -1
- package/dist/cli/viewer.d.ts +17 -5
- package/dist/cli/viewer.d.ts.map +1 -1
- package/dist/cli/viewer.js +77 -18
- package/dist/cli/viewer.js.map +1 -1
- package/dist/registry/locate.d.ts +9 -4
- package/dist/registry/locate.d.ts.map +1 -1
- package/dist/registry/locate.js +4 -3
- package/dist/registry/locate.js.map +1 -1
- package/dist/registry/manifest.d.ts +2 -2
- package/dist/registry/manifest.js +2 -2
- package/dist/registry/readModDir.d.ts +2 -2
- package/dist/registry/readModDir.d.ts.map +1 -1
- package/dist/registry/readModDir.js +8 -3
- package/dist/registry/readModDir.js.map +1 -1
- package/dist/registry/readSource.d.ts +1 -1
- package/dist/registry/readSource.js +1 -1
- package/dist/registry/types.d.ts +15 -0
- package/dist/registry/types.d.ts.map +1 -1
- package/dist/registry/types.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/extension.d.ts +16 -6
- package/dist/viewer/extension.d.ts.map +1 -1
- package/dist/viewer/extension.js +10 -4
- package/dist/viewer/extension.js.map +1 -1
- 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/settings.d.ts +13 -7
- package/dist/viewer/settings.d.ts.map +1 -1
- package/dist/viewer/settings.js +10 -3
- package/dist/viewer/settings.js.map +1 -1
- 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,35 @@
|
|
|
1
|
+
// packages/mods/src/relay/lines.ts
|
|
2
|
+
/**
|
|
3
|
+
* Cuts a byte stream into whole lines. Holds the unfinished tail of each
|
|
4
|
+
* chunk until its newline arrives, so a writer can put its own lines between
|
|
5
|
+
* the stream's lines without splitting one.
|
|
6
|
+
*
|
|
7
|
+
* Created once per stream by `runRelay`, which feeds it every chunk the
|
|
8
|
+
* extension or Claude writes and acts on each line it returns.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* const lines = new LineSplitter();
|
|
12
|
+
* for (const line of lines.push(chunk)) forward(line);
|
|
13
|
+
*/
|
|
14
|
+
export class LineSplitter {
|
|
15
|
+
tail = "";
|
|
16
|
+
decoder = new TextDecoder();
|
|
17
|
+
/**
|
|
18
|
+
* Adds a chunk and returns the lines it completed, each without its newline.
|
|
19
|
+
*
|
|
20
|
+
* @returns the completed lines; empty while the chunk ends mid-line
|
|
21
|
+
*/
|
|
22
|
+
push(chunk) {
|
|
23
|
+
const text = typeof chunk === "string" ? chunk : this.decoder.decode(chunk, { stream: true });
|
|
24
|
+
const parts = (this.tail + text).split("\n");
|
|
25
|
+
this.tail = parts.pop() ?? "";
|
|
26
|
+
return parts;
|
|
27
|
+
}
|
|
28
|
+
/** Returns what is left when the stream ends, or `undefined` when it ended on a newline. */
|
|
29
|
+
flush() {
|
|
30
|
+
const rest = this.tail + this.decoder.decode();
|
|
31
|
+
this.tail = "";
|
|
32
|
+
return rest === "" ? undefined : rest;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=lines.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lines.js","sourceRoot":"","sources":["../../src/relay/lines.ts"],"names":[],"mappings":"AAAA,mCAAmC;AAEnC;;;;;;;;;;;GAWG;AACH,MAAM,OAAO,YAAY;IACf,IAAI,GAAG,EAAE,CAAC;IACD,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;IAE7C;;;;OAIG;IACH,IAAI,CAAC,KAA0B;QAC7B,MAAM,IAAI,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QAC9F,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC7C,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC;QAC9B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,4FAA4F;IAC5F,KAAK;QACH,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;QAC/C,IAAI,CAAC,IAAI,GAAG,EAAE,CAAC;QACf,OAAO,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC;IACxC,CAAC;CACF"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { SessionInfo } from "./sessions";
|
|
3
|
+
/** The surface the viewer draws as, and the client id it attaches under. */
|
|
4
|
+
export declare const VIEWER_SURFACE = "vscode";
|
|
5
|
+
export declare 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 declare const RELAY_REQUEST_PREFIX = "g3nv:";
|
|
8
|
+
/** The engine's UI requests a viewer may send; the relay refuses every other subtype. */
|
|
9
|
+
export declare const ViewerRequestSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
10
|
+
subtype: z.ZodLiteral<"ui_render">;
|
|
11
|
+
component: z.ZodString;
|
|
12
|
+
instance_id: z.ZodString;
|
|
13
|
+
props: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
14
|
+
viewport: z.ZodOptional<z.ZodObject<{
|
|
15
|
+
columns: z.ZodNumber;
|
|
16
|
+
rows: z.ZodNumber;
|
|
17
|
+
}, z.core.$strip>>;
|
|
18
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
19
|
+
subtype: z.ZodLiteral<"ui_press">;
|
|
20
|
+
plugin: z.ZodString;
|
|
21
|
+
handle: z.ZodNumber;
|
|
22
|
+
key: z.ZodOptional<z.ZodString>;
|
|
23
|
+
href: z.ZodOptional<z.ZodString>;
|
|
24
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
25
|
+
subtype: z.ZodLiteral<"ui_input">;
|
|
26
|
+
plugin: z.ZodString;
|
|
27
|
+
handle: z.ZodNumber;
|
|
28
|
+
kind: z.ZodEnum<{
|
|
29
|
+
change: "change";
|
|
30
|
+
submit: "submit";
|
|
31
|
+
}>;
|
|
32
|
+
value: z.ZodString;
|
|
33
|
+
key: z.ZodOptional<z.ZodString>;
|
|
34
|
+
component: z.ZodOptional<z.ZodString>;
|
|
35
|
+
instance_id: z.ZodOptional<z.ZodString>;
|
|
36
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
37
|
+
subtype: z.ZodLiteral<"ui_select">;
|
|
38
|
+
plugin: z.ZodString;
|
|
39
|
+
handle: z.ZodNumber;
|
|
40
|
+
value: z.ZodString;
|
|
41
|
+
key: z.ZodOptional<z.ZodString>;
|
|
42
|
+
component: z.ZodOptional<z.ZodString>;
|
|
43
|
+
instance_id: z.ZodOptional<z.ZodString>;
|
|
44
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
45
|
+
subtype: z.ZodLiteral<"ui_panes">;
|
|
46
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
47
|
+
subtype: z.ZodLiteral<"ui_close">;
|
|
48
|
+
id: z.ZodString;
|
|
49
|
+
}, z.core.$strip>], "subtype">;
|
|
50
|
+
export type ViewerRequest = z.infer<typeof ViewerRequestSchema>;
|
|
51
|
+
/** One line a viewer sends the relay: a UI request it numbers itself. */
|
|
52
|
+
export declare const ViewerMessageSchema: z.ZodObject<{
|
|
53
|
+
id: z.ZodString;
|
|
54
|
+
request: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
55
|
+
subtype: z.ZodLiteral<"ui_render">;
|
|
56
|
+
component: z.ZodString;
|
|
57
|
+
instance_id: z.ZodString;
|
|
58
|
+
props: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
59
|
+
viewport: z.ZodOptional<z.ZodObject<{
|
|
60
|
+
columns: z.ZodNumber;
|
|
61
|
+
rows: z.ZodNumber;
|
|
62
|
+
}, z.core.$strip>>;
|
|
63
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
64
|
+
subtype: z.ZodLiteral<"ui_press">;
|
|
65
|
+
plugin: z.ZodString;
|
|
66
|
+
handle: z.ZodNumber;
|
|
67
|
+
key: z.ZodOptional<z.ZodString>;
|
|
68
|
+
href: z.ZodOptional<z.ZodString>;
|
|
69
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
70
|
+
subtype: z.ZodLiteral<"ui_input">;
|
|
71
|
+
plugin: z.ZodString;
|
|
72
|
+
handle: z.ZodNumber;
|
|
73
|
+
kind: z.ZodEnum<{
|
|
74
|
+
change: "change";
|
|
75
|
+
submit: "submit";
|
|
76
|
+
}>;
|
|
77
|
+
value: z.ZodString;
|
|
78
|
+
key: z.ZodOptional<z.ZodString>;
|
|
79
|
+
component: z.ZodOptional<z.ZodString>;
|
|
80
|
+
instance_id: z.ZodOptional<z.ZodString>;
|
|
81
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
82
|
+
subtype: z.ZodLiteral<"ui_select">;
|
|
83
|
+
plugin: z.ZodString;
|
|
84
|
+
handle: z.ZodNumber;
|
|
85
|
+
value: z.ZodString;
|
|
86
|
+
key: z.ZodOptional<z.ZodString>;
|
|
87
|
+
component: z.ZodOptional<z.ZodString>;
|
|
88
|
+
instance_id: z.ZodOptional<z.ZodString>;
|
|
89
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
90
|
+
subtype: z.ZodLiteral<"ui_panes">;
|
|
91
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
92
|
+
subtype: z.ZodLiteral<"ui_close">;
|
|
93
|
+
id: z.ZodString;
|
|
94
|
+
}, z.core.$strip>], "subtype">;
|
|
95
|
+
}, z.core.$strip>;
|
|
96
|
+
export type ViewerMessage = z.infer<typeof ViewerMessageSchema>;
|
|
97
|
+
/** One line the relay sends a viewer. */
|
|
98
|
+
export type RelayMessage =
|
|
99
|
+
/** The session the relay runs, on connect and whenever it learns more */
|
|
100
|
+
{
|
|
101
|
+
type: "session";
|
|
102
|
+
session: SessionInfo;
|
|
103
|
+
}
|
|
104
|
+
/** The engine's answer to a viewer request, or why it failed */
|
|
105
|
+
| {
|
|
106
|
+
type: "response";
|
|
107
|
+
id: string;
|
|
108
|
+
response?: unknown;
|
|
109
|
+
error?: string;
|
|
110
|
+
}
|
|
111
|
+
/** An engine push a viewer acts on: `ui_panes` (the pane roster) or `ui_invalidate` (redraw) */
|
|
112
|
+
| {
|
|
113
|
+
type: "push";
|
|
114
|
+
push: Record<string, unknown>;
|
|
115
|
+
};
|
|
116
|
+
/** Subtypes of the engine's `system` messages the relay copies to every viewer. */
|
|
117
|
+
export declare const RELAYED_PUSHES: Set<string>;
|
|
118
|
+
/**
|
|
119
|
+
* The control request a viewer request becomes on Claude's stdin: the
|
|
120
|
+
* viewer's surface and client id are filled in where the engine takes them.
|
|
121
|
+
*/
|
|
122
|
+
export declare function toControlRequest(request: ViewerRequest): Record<string, unknown>;
|
|
123
|
+
//# sourceMappingURL=protocol.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../src/relay/protocol.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,4EAA4E;AAC5E,eAAO,MAAM,cAAc,WAAa,CAAC;AACzC,eAAO,MAAM,gBAAgB,eAAe,CAAC;AAE7C,4FAA4F;AAC5F,eAAO,MAAM,oBAAoB,UAAU,CAAC;AAE5C,yFAAyF;AACzF,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8BAoC9B,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEhE,yEAAyE;AACzE,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAG9B,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEhE,yCAAyC;AACzC,MAAM,MAAM,YAAY;AACtB,yEAAyE;AACvE;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,WAAW,CAAA;CAAE;AAC3C,gEAAgE;GAC9D;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE;AACtE,gGAAgG;GAC9F;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,CAAC;AAEpD,mFAAmF;AACnF,eAAO,MAAM,cAAc,aAAyC,CAAC;AAErE;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAYhF"}
|
|
@@ -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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"}
|