@linkshell/wire 0.2.22 → 0.2.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/acp.d.ts +68 -430
- package/dist/acp.js +5 -5
- package/dist/acp.js.map +1 -1
- package/dist/async-questions.d.ts +2 -10
- package/dist/computer-preview.d.ts +1 -15
- package/dist/computer-preview.js +1 -1
- package/dist/computer-preview.js.map +1 -1
- package/dist/content.d.ts +211 -376
- package/dist/content.js +4 -4
- package/dist/content.js.map +1 -1
- package/dist/editor.d.ts +48 -592
- package/dist/envelopes.js +13 -1
- package/dist/envelopes.js.map +1 -1
- package/dist/goal.d.ts +15 -48
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/live-activity.d.ts +83 -212
- package/dist/live-activity.js +1 -1
- package/dist/live-activity.js.map +1 -1
- package/dist/model-name.d.ts +2 -0
- package/dist/model-name.js +9 -0
- package/dist/model-name.js.map +1 -0
- package/dist/model.d.ts +467 -2317
- package/dist/model.js +2 -0
- package/dist/model.js.map +1 -1
- package/dist/relay-client.d.ts +2 -1
- package/dist/relay-client.js +10 -5
- package/dist/relay-client.js.map +1 -1
- package/dist/relay.d.ts +51 -267
- package/dist/relay.js +4 -1
- package/dist/relay.js.map +1 -1
- package/dist/rpc-mcp.d.ts +21 -136
- package/dist/rpc-mcp.js +1 -1
- package/dist/rpc-mcp.js.map +1 -1
- package/dist/rpc.d.ts +7272 -31804
- package/dist/rpc.js +18 -6
- package/dist/rpc.js.map +1 -1
- package/dist/side.d.ts +13 -61
- package/dist/updates.d.ts +1812 -6932
- package/dist/usage.d.ts +17 -195
- package/dist/watch.d.ts +223 -1141
- package/dist/workflow.d.ts +46 -139
- package/package.json +2 -2
- package/src/acp.ts +5 -5
- package/src/computer-preview.ts +1 -1
- package/src/content.ts +5 -5
- package/src/envelopes.ts +11 -1
- package/src/index.ts +1 -0
- package/src/live-activity.ts +1 -1
- package/src/model-name.ts +7 -0
- package/src/model.ts +2 -0
- package/src/relay-client.ts +10 -5
- package/src/relay.ts +6 -1
- package/src/rpc-mcp.ts +1 -1
- package/src/rpc.ts +18 -6
package/dist/workflow.d.ts
CHANGED
|
@@ -1,14 +1,35 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
export declare const workflowStateSchema: z.ZodEnum<
|
|
2
|
+
export declare const workflowStateSchema: z.ZodEnum<{
|
|
3
|
+
paused: "paused";
|
|
4
|
+
running: "running";
|
|
5
|
+
completed: "completed";
|
|
6
|
+
failed: "failed";
|
|
7
|
+
stopped: "stopped";
|
|
8
|
+
}>;
|
|
3
9
|
export type WorkflowState = z.infer<typeof workflowStateSchema>;
|
|
4
|
-
export declare const workflowAgentStateSchema: z.ZodEnum<
|
|
10
|
+
export declare const workflowAgentStateSchema: z.ZodEnum<{
|
|
11
|
+
unknown: "unknown";
|
|
12
|
+
paused: "paused";
|
|
13
|
+
running: "running";
|
|
14
|
+
completed: "completed";
|
|
15
|
+
failed: "failed";
|
|
16
|
+
stopped: "stopped";
|
|
17
|
+
pending: "pending";
|
|
18
|
+
}>;
|
|
5
19
|
export type WorkflowAgentState = z.infer<typeof workflowAgentStateSchema>;
|
|
6
20
|
export declare const workflowAgentSchema: z.ZodObject<{
|
|
7
21
|
id: z.ZodString;
|
|
8
|
-
/** Present only after the host has imported this agent's transcript. */
|
|
9
22
|
toolCallId: z.ZodOptional<z.ZodString>;
|
|
10
23
|
title: z.ZodString;
|
|
11
|
-
state: z.ZodEnum<
|
|
24
|
+
state: z.ZodEnum<{
|
|
25
|
+
unknown: "unknown";
|
|
26
|
+
paused: "paused";
|
|
27
|
+
running: "running";
|
|
28
|
+
completed: "completed";
|
|
29
|
+
failed: "failed";
|
|
30
|
+
stopped: "stopped";
|
|
31
|
+
pending: "pending";
|
|
32
|
+
}>;
|
|
12
33
|
phaseId: z.ZodOptional<z.ZodString>;
|
|
13
34
|
model: z.ZodOptional<z.ZodString>;
|
|
14
35
|
tokens: z.ZodOptional<z.ZodNumber>;
|
|
@@ -17,54 +38,25 @@ export declare const workflowAgentSchema: z.ZodObject<{
|
|
|
17
38
|
startedAt: z.ZodOptional<z.ZodNumber>;
|
|
18
39
|
endedAt: z.ZodOptional<z.ZodNumber>;
|
|
19
40
|
result: z.ZodOptional<z.ZodString>;
|
|
20
|
-
},
|
|
21
|
-
id: string;
|
|
22
|
-
title: string;
|
|
23
|
-
state: "unknown" | "paused" | "running" | "completed" | "failed" | "stopped" | "pending";
|
|
24
|
-
toolCallId?: string | undefined;
|
|
25
|
-
phaseId?: string | undefined;
|
|
26
|
-
model?: string | undefined;
|
|
27
|
-
tokens?: number | undefined;
|
|
28
|
-
toolCalls?: number | undefined;
|
|
29
|
-
durationMs?: number | undefined;
|
|
30
|
-
startedAt?: number | undefined;
|
|
31
|
-
endedAt?: number | undefined;
|
|
32
|
-
result?: string | undefined;
|
|
33
|
-
}, {
|
|
34
|
-
id: string;
|
|
35
|
-
title: string;
|
|
36
|
-
state: "unknown" | "paused" | "running" | "completed" | "failed" | "stopped" | "pending";
|
|
37
|
-
toolCallId?: string | undefined;
|
|
38
|
-
phaseId?: string | undefined;
|
|
39
|
-
model?: string | undefined;
|
|
40
|
-
tokens?: number | undefined;
|
|
41
|
-
toolCalls?: number | undefined;
|
|
42
|
-
durationMs?: number | undefined;
|
|
43
|
-
startedAt?: number | undefined;
|
|
44
|
-
endedAt?: number | undefined;
|
|
45
|
-
result?: string | undefined;
|
|
46
|
-
}>;
|
|
41
|
+
}, z.core.$strip>;
|
|
47
42
|
export type WorkflowAgent = z.infer<typeof workflowAgentSchema>;
|
|
48
43
|
export declare const workflowPhaseSchema: z.ZodObject<{
|
|
49
44
|
id: z.ZodString;
|
|
50
45
|
title: z.ZodString;
|
|
51
46
|
order: z.ZodNumber;
|
|
52
|
-
},
|
|
53
|
-
id: string;
|
|
54
|
-
title: string;
|
|
55
|
-
order: number;
|
|
56
|
-
}, {
|
|
57
|
-
id: string;
|
|
58
|
-
title: string;
|
|
59
|
-
order: number;
|
|
60
|
-
}>;
|
|
47
|
+
}, z.core.$strip>;
|
|
61
48
|
export type WorkflowPhase = z.infer<typeof workflowPhaseSchema>;
|
|
62
49
|
/** A complete run snapshot, independent of the loaded conversation window. */
|
|
63
50
|
export declare const workflowSchema: z.ZodObject<{
|
|
64
51
|
runId: z.ZodOptional<z.ZodString>;
|
|
65
52
|
name: z.ZodOptional<z.ZodString>;
|
|
66
|
-
state: z.ZodOptional<z.ZodEnum<
|
|
67
|
-
|
|
53
|
+
state: z.ZodOptional<z.ZodEnum<{
|
|
54
|
+
paused: "paused";
|
|
55
|
+
running: "running";
|
|
56
|
+
completed: "completed";
|
|
57
|
+
failed: "failed";
|
|
58
|
+
stopped: "stopped";
|
|
59
|
+
}>>;
|
|
68
60
|
started: z.ZodOptional<z.ZodNumber>;
|
|
69
61
|
completed: z.ZodOptional<z.ZodNumber>;
|
|
70
62
|
tokens: z.ZodOptional<z.ZodNumber>;
|
|
@@ -75,21 +67,20 @@ export declare const workflowSchema: z.ZodObject<{
|
|
|
75
67
|
id: z.ZodString;
|
|
76
68
|
title: z.ZodString;
|
|
77
69
|
order: z.ZodNumber;
|
|
78
|
-
},
|
|
79
|
-
id: string;
|
|
80
|
-
title: string;
|
|
81
|
-
order: number;
|
|
82
|
-
}, {
|
|
83
|
-
id: string;
|
|
84
|
-
title: string;
|
|
85
|
-
order: number;
|
|
86
|
-
}>, "many">>;
|
|
70
|
+
}, z.core.$strip>>>;
|
|
87
71
|
agents: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
88
72
|
id: z.ZodString;
|
|
89
|
-
/** Present only after the host has imported this agent's transcript. */
|
|
90
73
|
toolCallId: z.ZodOptional<z.ZodString>;
|
|
91
74
|
title: z.ZodString;
|
|
92
|
-
state: z.ZodEnum<
|
|
75
|
+
state: z.ZodEnum<{
|
|
76
|
+
unknown: "unknown";
|
|
77
|
+
paused: "paused";
|
|
78
|
+
running: "running";
|
|
79
|
+
completed: "completed";
|
|
80
|
+
failed: "failed";
|
|
81
|
+
stopped: "stopped";
|
|
82
|
+
pending: "pending";
|
|
83
|
+
}>;
|
|
93
84
|
phaseId: z.ZodOptional<z.ZodString>;
|
|
94
85
|
model: z.ZodOptional<z.ZodString>;
|
|
95
86
|
tokens: z.ZodOptional<z.ZodNumber>;
|
|
@@ -98,90 +89,6 @@ export declare const workflowSchema: z.ZodObject<{
|
|
|
98
89
|
startedAt: z.ZodOptional<z.ZodNumber>;
|
|
99
90
|
endedAt: z.ZodOptional<z.ZodNumber>;
|
|
100
91
|
result: z.ZodOptional<z.ZodString>;
|
|
101
|
-
},
|
|
102
|
-
|
|
103
|
-
title: string;
|
|
104
|
-
state: "unknown" | "paused" | "running" | "completed" | "failed" | "stopped" | "pending";
|
|
105
|
-
toolCallId?: string | undefined;
|
|
106
|
-
phaseId?: string | undefined;
|
|
107
|
-
model?: string | undefined;
|
|
108
|
-
tokens?: number | undefined;
|
|
109
|
-
toolCalls?: number | undefined;
|
|
110
|
-
durationMs?: number | undefined;
|
|
111
|
-
startedAt?: number | undefined;
|
|
112
|
-
endedAt?: number | undefined;
|
|
113
|
-
result?: string | undefined;
|
|
114
|
-
}, {
|
|
115
|
-
id: string;
|
|
116
|
-
title: string;
|
|
117
|
-
state: "unknown" | "paused" | "running" | "completed" | "failed" | "stopped" | "pending";
|
|
118
|
-
toolCallId?: string | undefined;
|
|
119
|
-
phaseId?: string | undefined;
|
|
120
|
-
model?: string | undefined;
|
|
121
|
-
tokens?: number | undefined;
|
|
122
|
-
toolCalls?: number | undefined;
|
|
123
|
-
durationMs?: number | undefined;
|
|
124
|
-
startedAt?: number | undefined;
|
|
125
|
-
endedAt?: number | undefined;
|
|
126
|
-
result?: string | undefined;
|
|
127
|
-
}>, "many">>;
|
|
128
|
-
}, "strip", z.ZodTypeAny, {
|
|
129
|
-
name?: string | undefined;
|
|
130
|
-
completed?: number | undefined;
|
|
131
|
-
state?: "paused" | "running" | "completed" | "failed" | "stopped" | undefined;
|
|
132
|
-
tokens?: number | undefined;
|
|
133
|
-
durationMs?: number | undefined;
|
|
134
|
-
startedAt?: number | undefined;
|
|
135
|
-
endedAt?: number | undefined;
|
|
136
|
-
runId?: string | undefined;
|
|
137
|
-
started?: number | undefined;
|
|
138
|
-
phases?: {
|
|
139
|
-
id: string;
|
|
140
|
-
title: string;
|
|
141
|
-
order: number;
|
|
142
|
-
}[] | undefined;
|
|
143
|
-
agents?: {
|
|
144
|
-
id: string;
|
|
145
|
-
title: string;
|
|
146
|
-
state: "unknown" | "paused" | "running" | "completed" | "failed" | "stopped" | "pending";
|
|
147
|
-
toolCallId?: string | undefined;
|
|
148
|
-
phaseId?: string | undefined;
|
|
149
|
-
model?: string | undefined;
|
|
150
|
-
tokens?: number | undefined;
|
|
151
|
-
toolCalls?: number | undefined;
|
|
152
|
-
durationMs?: number | undefined;
|
|
153
|
-
startedAt?: number | undefined;
|
|
154
|
-
endedAt?: number | undefined;
|
|
155
|
-
result?: string | undefined;
|
|
156
|
-
}[] | undefined;
|
|
157
|
-
}, {
|
|
158
|
-
name?: string | undefined;
|
|
159
|
-
completed?: number | undefined;
|
|
160
|
-
state?: "paused" | "running" | "completed" | "failed" | "stopped" | undefined;
|
|
161
|
-
tokens?: number | undefined;
|
|
162
|
-
durationMs?: number | undefined;
|
|
163
|
-
startedAt?: number | undefined;
|
|
164
|
-
endedAt?: number | undefined;
|
|
165
|
-
runId?: string | undefined;
|
|
166
|
-
started?: number | undefined;
|
|
167
|
-
phases?: {
|
|
168
|
-
id: string;
|
|
169
|
-
title: string;
|
|
170
|
-
order: number;
|
|
171
|
-
}[] | undefined;
|
|
172
|
-
agents?: {
|
|
173
|
-
id: string;
|
|
174
|
-
title: string;
|
|
175
|
-
state: "unknown" | "paused" | "running" | "completed" | "failed" | "stopped" | "pending";
|
|
176
|
-
toolCallId?: string | undefined;
|
|
177
|
-
phaseId?: string | undefined;
|
|
178
|
-
model?: string | undefined;
|
|
179
|
-
tokens?: number | undefined;
|
|
180
|
-
toolCalls?: number | undefined;
|
|
181
|
-
durationMs?: number | undefined;
|
|
182
|
-
startedAt?: number | undefined;
|
|
183
|
-
endedAt?: number | undefined;
|
|
184
|
-
result?: string | undefined;
|
|
185
|
-
}[] | undefined;
|
|
186
|
-
}>;
|
|
92
|
+
}, z.core.$strip>>>;
|
|
93
|
+
}, z.core.$strip>;
|
|
187
94
|
export type Workflow = z.infer<typeof workflowSchema>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@linkshell/wire",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.24",
|
|
4
4
|
"description": "Wire protocol for LinkShell v2: session model, JSON-RPC methods, end-to-end encryption and the relay client.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"@noble/ciphers": "^2.4.0",
|
|
30
30
|
"@noble/curves": "^1.9.7",
|
|
31
31
|
"@noble/hashes": "^1.8.0",
|
|
32
|
-
"zod": "^
|
|
32
|
+
"zod": "^4.6.7"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"vitest": "^3.2.1"
|
package/src/acp.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
|
|
3
|
-
const env = z.record(z.string());
|
|
3
|
+
const env = z.record(z.string(), z.string());
|
|
4
4
|
export const mcpServerSchema = z.discriminatedUnion("type", [
|
|
5
5
|
z.object({ type: z.literal("stdio"), name: z.string().min(1), command: z.string().min(1), args: z.array(z.string()).default([]), env: env.default({}) }),
|
|
6
|
-
z.object({ type: z.literal("http"), name: z.string().min(1), url: z.
|
|
7
|
-
z.object({ type: z.literal("sse"), name: z.string().min(1), url: z.
|
|
6
|
+
z.object({ type: z.literal("http"), name: z.string().min(1), url: z.url(), headers: env.default({}) }),
|
|
7
|
+
z.object({ type: z.literal("sse"), name: z.string().min(1), url: z.url(), headers: env.default({}) }),
|
|
8
8
|
z.object({ type: z.literal("acp"), name: z.string().min(1), command: z.string().min(1), args: z.array(z.string()).default([]), env: env.default({}) }),
|
|
9
9
|
]);
|
|
10
10
|
export type AcpMcpServer = z.infer<typeof mcpServerSchema>;
|
|
@@ -23,10 +23,10 @@ export const acpRemoteAgentSchema = z.object({
|
|
|
23
23
|
label: z.string().min(1).max(80),
|
|
24
24
|
transport: z.enum(["stdio", "http", "websocket"]),
|
|
25
25
|
command: z.string().optional(), args: z.array(z.string()).default([]),
|
|
26
|
-
url: z.
|
|
26
|
+
url: z.url().optional(),
|
|
27
27
|
/** Header name to environment-variable name. The UI does not store secrets. */
|
|
28
28
|
headerEnv: env.default({}),
|
|
29
|
-
settings: acpAgentSettingsSchema.
|
|
29
|
+
settings: acpAgentSettingsSchema.prefault({}),
|
|
30
30
|
});
|
|
31
31
|
export type AcpRemoteAgent = z.infer<typeof acpRemoteAgentSchema>;
|
|
32
32
|
|
package/src/computer-preview.ts
CHANGED
|
@@ -4,7 +4,7 @@ export const PREVIEW_MAX_BYTES = 48 * 1024;
|
|
|
4
4
|
export const previewFrameSchema = z.object({
|
|
5
5
|
id: z.string().regex(/^[a-f0-9]{64}$/),
|
|
6
6
|
target: z.string().max(1024),
|
|
7
|
-
capturedAt: z.number().
|
|
7
|
+
capturedAt: z.number().nonnegative(),
|
|
8
8
|
width: z.number().int().positive().max(2048),
|
|
9
9
|
height: z.number().int().positive().max(2048),
|
|
10
10
|
mimeType: z.literal("image/webp"),
|
package/src/content.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
|
|
3
|
-
const optionalString = z.string().nullish().transform((value) => value ?? undefined);
|
|
4
|
-
const optionalMeta = z.record(z.unknown()).nullish().transform((value) => value ?? undefined);
|
|
3
|
+
const optionalString = z.string().nullish().transform((value) => value ?? undefined).optional();
|
|
4
|
+
const optionalMeta = z.record(z.string(), z.unknown()).nullish().transform((value) => value ?? undefined).optional();
|
|
5
5
|
const contentMetadata = {
|
|
6
|
-
annotations: z.
|
|
6
|
+
annotations: z.looseObject({ audience: z.array(z.enum(["user", "assistant"])).nullish().transform((value) => value ?? undefined).optional(), priority: z.number().nullish().transform((value) => value ?? undefined).optional(), lastModified: optionalString }).nullish().transform((value) => value ?? undefined).optional(),
|
|
7
7
|
_meta: optionalMeta,
|
|
8
8
|
};
|
|
9
9
|
const contentVariants = z.discriminatedUnion("type", [
|
|
@@ -28,7 +28,7 @@ const contentVariants = z.discriminatedUnion("type", [
|
|
|
28
28
|
title: optionalString,
|
|
29
29
|
description: optionalString,
|
|
30
30
|
mimeType: optionalString,
|
|
31
|
-
size: z.number().nullish().transform((value) => value ?? undefined),
|
|
31
|
+
size: z.number().nullish().transform((value) => value ?? undefined).optional(),
|
|
32
32
|
...contentMetadata,
|
|
33
33
|
/** What the link names: a file (default), a skill the user invoked, or another agent. */
|
|
34
34
|
kind: z.enum(["file", "skill", "agent"]).optional(),
|
|
@@ -36,7 +36,7 @@ const contentVariants = z.discriminatedUnion("type", [
|
|
|
36
36
|
]);
|
|
37
37
|
export type ContentBlock = z.infer<typeof contentVariants>;
|
|
38
38
|
// Hide the nested validator implementation from every exported RPC declaration.
|
|
39
|
-
export const contentBlockSchema: z.ZodType<ContentBlock,
|
|
39
|
+
export const contentBlockSchema: z.ZodType<ContentBlock, unknown> = contentVariants;
|
|
40
40
|
|
|
41
41
|
export const toolCallStatusSchema = z.enum(["pending", "in_progress", "completed", "failed"]);
|
|
42
42
|
export type ToolCallStatus = z.infer<typeof toolCallStatusSchema>;
|
package/src/envelopes.ts
CHANGED
|
@@ -95,6 +95,7 @@ export function stripHiddenContext(text: string, { keepPeers = false }: { keepPe
|
|
|
95
95
|
.trim();
|
|
96
96
|
}
|
|
97
97
|
|
|
98
|
+
// eslint-disable-next-line no-control-regex -- terminal colour codes start with ESC.
|
|
98
99
|
const ANSI = /\u001b\[[\d;?]*[ -/]*[@-~]/g;
|
|
99
100
|
|
|
100
101
|
function tagText(source: string, tag: string): string | undefined {
|
|
@@ -206,6 +207,15 @@ function unescapeHtml(value: string): string {
|
|
|
206
207
|
});
|
|
207
208
|
}
|
|
208
209
|
|
|
210
|
+
/** Output as a terminal shows it: no colour codes, a backspace takes back the character before it, other controls are not drawn. */
|
|
211
|
+
function printed(value: string): string {
|
|
212
|
+
let text = value.replace(ANSI, "");
|
|
213
|
+
// eslint-disable-next-line no-control-regex -- a backspace is the character being handled.
|
|
214
|
+
for (let previous = ""; previous !== text; ) { previous = text; text = text.replace(/[^\n\x08]\x08/g, ""); }
|
|
215
|
+
// eslint-disable-next-line no-control-regex -- what a terminal doesn't draw.
|
|
216
|
+
return text.replace(/[\x00-\x08\x0b-\x1f\x7f]/g, "");
|
|
217
|
+
}
|
|
218
|
+
|
|
209
219
|
/**
|
|
210
220
|
* Codex Desktop writes a mention of another of its threads as a Markdown link to
|
|
211
221
|
* codex://threads/<id>, with the space before it as " ": read as the thread's title.
|
|
@@ -249,7 +259,7 @@ export function readUserText(raw: string, { images = 0 }: { images?: number } =
|
|
|
249
259
|
}
|
|
250
260
|
|
|
251
261
|
if (/^<bash-(?:input|stdout|stderr)>/.test(text)) {
|
|
252
|
-
const clean = (value?: string) => (value === undefined ? undefined : unescapeHtml(value)
|
|
262
|
+
const clean = (value?: string) => (value === undefined ? undefined : printed(unescapeHtml(value)).replace(/\n+$/, "")) || undefined;
|
|
253
263
|
const command = clean(tagText(text, "bash-input"))?.trim();
|
|
254
264
|
const stdout = clean(tagText(text, "bash-stdout"));
|
|
255
265
|
const stderr = clean(tagText(text, "bash-stderr"));
|
package/src/index.ts
CHANGED
package/src/live-activity.ts
CHANGED
|
@@ -42,7 +42,7 @@ export interface LiveActivityPayload extends Partial<LiveActivityContentState> {
|
|
|
42
42
|
export const liveActivityIdSchema = z.string().min(1).max(128).regex(/^[a-zA-Z0-9-]+$/);
|
|
43
43
|
export const liveActivitySubscriptionSchema = z.object({
|
|
44
44
|
activityId: liveActivityIdSchema,
|
|
45
|
-
serviceUrl: z.
|
|
45
|
+
serviceUrl: z.url().max(256),
|
|
46
46
|
grant: z.string().regex(/^[a-f0-9]{64}$/),
|
|
47
47
|
expiresAt: z.number().int().positive(),
|
|
48
48
|
computerKey: z.string().min(1).max(512),
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** Format a raw GPT model ID for display without changing the value sent to the agent. */
|
|
2
|
+
export function displayModelName(name: string): string {
|
|
3
|
+
const match = /^gpt-(\d+(?:\.\d+)*)(?:-([a-z][a-z0-9-]*))?$/i.exec(name.trim());
|
|
4
|
+
if (!match) return name;
|
|
5
|
+
const suffix = match[2]?.split("-").map((word) => word[0]!.toUpperCase() + word.slice(1).toLowerCase()).join(" ");
|
|
6
|
+
return `GPT-${match[1]}${suffix ? ` ${suffix}` : ""}`;
|
|
7
|
+
}
|
package/src/model.ts
CHANGED
|
@@ -333,6 +333,8 @@ export type ProjectSummary = z.infer<typeof projectSummarySchema>;
|
|
|
333
333
|
export const machineInfoSchema = z.object({
|
|
334
334
|
machineId: z.string().min(1),
|
|
335
335
|
hostname: z.string(),
|
|
336
|
+
/** Host-owned display name; its presence also advertises `machine.rename`. */
|
|
337
|
+
naming: z.object({ defaultName: z.string(), customName: z.string().optional(), configured: z.boolean() }).optional(),
|
|
336
338
|
platform: z.string(),
|
|
337
339
|
hostVersion: z.string(),
|
|
338
340
|
/** The host's RPC revision (`HOST_PROTOCOL`); absent from hosts older than it. */
|
package/src/relay-client.ts
CHANGED
|
@@ -30,7 +30,8 @@ export interface RelayClientOptions {
|
|
|
30
30
|
url: string;
|
|
31
31
|
identity: Identity;
|
|
32
32
|
role: PeerRole;
|
|
33
|
-
name: string;
|
|
33
|
+
name: string | (() => string);
|
|
34
|
+
namingConfigured?: () => boolean;
|
|
34
35
|
platform?: string;
|
|
35
36
|
/** Account token, fetched fresh for each connection. */
|
|
36
37
|
token?: () => Promise<string | undefined> | string | undefined;
|
|
@@ -240,7 +241,8 @@ export class RelayClient {
|
|
|
240
241
|
this.heardAt = Date.now();
|
|
241
242
|
let fatal: { code: string; message: string } | undefined;
|
|
242
243
|
socket.onmessage = (event) => {
|
|
243
|
-
if (this.socket
|
|
244
|
+
if (this.socket !== socket) return;
|
|
245
|
+
this.heardAt = Date.now();
|
|
244
246
|
let frame;
|
|
245
247
|
try {
|
|
246
248
|
const parsed = serverFrameSchema.safeParse(JSON.parse(String(event.data)));
|
|
@@ -251,7 +253,7 @@ export class RelayClient {
|
|
|
251
253
|
}
|
|
252
254
|
switch (frame.t) {
|
|
253
255
|
case "challenge":
|
|
254
|
-
void this.authenticate(frame.nonce);
|
|
256
|
+
void this.authenticate(frame.nonce, socket);
|
|
255
257
|
return;
|
|
256
258
|
case "ready":
|
|
257
259
|
this.attempt = 0;
|
|
@@ -362,19 +364,22 @@ export class RelayClient {
|
|
|
362
364
|
this.scheduleReconnect({ code: "disconnected", message });
|
|
363
365
|
}
|
|
364
366
|
|
|
365
|
-
private async authenticate(nonce: string): Promise<void> {
|
|
367
|
+
private async authenticate(nonce: string, socket: RelaySocket): Promise<void> {
|
|
366
368
|
let token: string | undefined;
|
|
367
369
|
try {
|
|
368
370
|
token = (await this.options.token?.()) ?? undefined;
|
|
369
371
|
} catch {
|
|
370
372
|
token = undefined;
|
|
371
373
|
}
|
|
374
|
+
// A token refresh may outlive reauthentication; its nonce belongs to the socket that asked.
|
|
375
|
+
if (this.socket !== socket) return;
|
|
372
376
|
this.sendFrame({
|
|
373
377
|
t: "auth",
|
|
374
378
|
role: this.options.role,
|
|
375
379
|
identity: publicIdentity(this.options.identity),
|
|
376
380
|
signature: sign(this.options.identity, gatewayChallengeMessage(nonce)),
|
|
377
|
-
name: this.options.name.slice(0, 120),
|
|
381
|
+
name: (typeof this.options.name === "function" ? this.options.name() : this.options.name).slice(0, 120),
|
|
382
|
+
...(this.options.namingConfigured?.() ? { namingConfigured: true } : {}),
|
|
378
383
|
platform: this.options.platform,
|
|
379
384
|
token,
|
|
380
385
|
...(this.options.locked?.() ? { locked: true } : {}),
|
package/src/relay.ts
CHANGED
|
@@ -24,6 +24,8 @@ export type PeerRole = z.infer<typeof peerRoleSchema>;
|
|
|
24
24
|
/** A machine as a device sees it in the gateway's list. */
|
|
25
25
|
export const machineEntrySchema = publicIdentitySchema.extend({
|
|
26
26
|
name: z.string(),
|
|
27
|
+
/** An explicit host-owned name/reset supersedes older device-local aliases. */
|
|
28
|
+
namingConfigured: z.boolean().optional(),
|
|
27
29
|
platform: z.string().optional(),
|
|
28
30
|
online: z.boolean(),
|
|
29
31
|
/** How this device may reach it: it paired, or both belong to the same account. */
|
|
@@ -50,6 +52,7 @@ export const clientFrameSchema = z.discriminatedUnion("t", [
|
|
|
50
52
|
identity: publicIdentitySchema,
|
|
51
53
|
signature: z.string(),
|
|
52
54
|
name: z.string().max(120),
|
|
55
|
+
namingConfigured: z.boolean().optional(),
|
|
53
56
|
platform: z.string().max(40).optional(),
|
|
54
57
|
/** Account access token, when signed in. */
|
|
55
58
|
token: z.string().optional(),
|
|
@@ -74,7 +77,7 @@ export const serverFrameSchema = z.discriminatedUnion("t", [
|
|
|
74
77
|
result: z.unknown().optional(),
|
|
75
78
|
error: z.object({ code: z.string(), message: z.string() }).optional(),
|
|
76
79
|
}),
|
|
77
|
-
z.object({ t: z.literal("event"), name: z.string(), data: z.unknown() }),
|
|
80
|
+
z.object({ t: z.literal("event"), name: z.string(), data: z.unknown().optional() }),
|
|
78
81
|
/** An encrypted frame from a peer, with the keys the gateway verified it holds. */
|
|
79
82
|
z.object({ t: z.literal("from"), from: publicIdentitySchema, via: z.enum(["paired", "account"]), d: z.string() }),
|
|
80
83
|
/** A frame couldn't be delivered: the peer is offline or not reachable. */
|
|
@@ -96,6 +99,8 @@ export interface RelayMethods {
|
|
|
96
99
|
result: { machine: MachineEntry };
|
|
97
100
|
};
|
|
98
101
|
"machines.list": { params: Record<string, never>; result: { machines: MachineEntry[] } };
|
|
102
|
+
/** Machine: refresh its display metadata without replacing its authenticated connection. */
|
|
103
|
+
"machines.update": { params: { name: string; namingConfigured?: boolean }; result: Record<string, never> };
|
|
99
104
|
"machines.forget": { params: { machineId: string }; result: Record<string, never> };
|
|
100
105
|
"devices.list": { params: Record<string, never>; result: { devices: DeviceEntry[] } };
|
|
101
106
|
"devices.revoke": { params: { deviceId: string }; result: Record<string, never> };
|
package/src/rpc-mcp.ts
CHANGED
|
@@ -68,7 +68,7 @@ export const mcpMethods = {
|
|
|
68
68
|
sessionId: z.string().min(1),
|
|
69
69
|
server: z.string().min(1),
|
|
70
70
|
tool: z.string().min(1),
|
|
71
|
-
arguments: z.record(z.unknown()).optional(),
|
|
71
|
+
arguments: z.record(z.string(), z.unknown()).optional(),
|
|
72
72
|
connector: z.string().optional(),
|
|
73
73
|
}),
|
|
74
74
|
result: z.object({
|
package/src/rpc.ts
CHANGED
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
questionAnswerSchema,
|
|
21
21
|
pendingPermissionSchema,
|
|
22
22
|
} from "./model.js";
|
|
23
|
-
import { contentBlockSchema, sessionEventSchema, sessionNoticeSchema } from "./updates.js";
|
|
23
|
+
import { contentBlockSchema, sessionConfigOptionSchema, sessionEventSchema, sessionNoticeSchema } from "./updates.js";
|
|
24
24
|
import { sideChatSchema } from "./side.js";
|
|
25
25
|
import { mcpMethods } from "./rpc-mcp.js";
|
|
26
26
|
|
|
@@ -78,7 +78,7 @@ export const RPC_APP_ERROR = -32000;
|
|
|
78
78
|
*/
|
|
79
79
|
export const HOST_PROTOCOL = 2;
|
|
80
80
|
|
|
81
|
-
const empty = z.
|
|
81
|
+
const empty = z.looseObject({});
|
|
82
82
|
|
|
83
83
|
export const directoryEntrySchema = z.object({
|
|
84
84
|
name: z.string(),
|
|
@@ -111,7 +111,7 @@ const acpMethods = {
|
|
|
111
111
|
result: empty,
|
|
112
112
|
},
|
|
113
113
|
"agents.providers": {
|
|
114
|
-
params: z.object({ agent: z.string().min(1), operation: z.enum(["list", "set", "disable"]), config: z.object({ providerId: z.string(), apiType: z.string().optional(), baseUrl: z.
|
|
114
|
+
params: z.object({ agent: z.string().min(1), operation: z.enum(["list", "set", "disable"]), config: z.object({ providerId: z.string(), apiType: z.string().optional(), baseUrl: z.url().optional(), headers: z.record(z.string(), z.string()).optional() }).optional() }),
|
|
115
115
|
result: z.object({ providers: z.array(acpProviderSchema) }),
|
|
116
116
|
},
|
|
117
117
|
"agents.custom": {
|
|
@@ -135,6 +135,11 @@ const coreMethods = {
|
|
|
135
135
|
params: empty,
|
|
136
136
|
result: machineInfoSchema,
|
|
137
137
|
},
|
|
138
|
+
"machine.rename": {
|
|
139
|
+
/** Empty restores the configured default; names never change peer identities. */
|
|
140
|
+
params: z.object({ name: z.string().trim().max(40) }),
|
|
141
|
+
result: machineInfoSchema,
|
|
142
|
+
},
|
|
138
143
|
"projects.list": {
|
|
139
144
|
params: z.object({ limit: z.number().int().positive().max(200).optional() }),
|
|
140
145
|
result: z.object({ projects: z.array(projectSummarySchema) }),
|
|
@@ -167,11 +172,15 @@ const coreMethods = {
|
|
|
167
172
|
agent: z.string().min(1),
|
|
168
173
|
/** Where the session will work: an agent's project settings can choose another model. */
|
|
169
174
|
cwd: z.string().optional(),
|
|
175
|
+
/** Preview settings supported by a selected model without changing the agent's default. */
|
|
176
|
+
model: z.string().optional(),
|
|
170
177
|
}),
|
|
171
178
|
result: z.object({
|
|
172
179
|
/** As a session's model option lists them (`group`: the heading some agents put models under). */
|
|
173
180
|
models: z.array(z.object({ value: z.string(), name: z.string(), description: z.string().optional(), group: z.string().optional() })),
|
|
174
181
|
current: z.string().optional(),
|
|
182
|
+
/** Settings available before the first prompt; omitted by older hosts or agents without a template. */
|
|
183
|
+
config: z.array(sessionConfigOptionSchema).optional(),
|
|
175
184
|
}),
|
|
176
185
|
},
|
|
177
186
|
"sessions.create": {
|
|
@@ -182,6 +191,8 @@ const coreMethods = {
|
|
|
182
191
|
clientMessageId: z.string().optional(),
|
|
183
192
|
/** One of `agents.models`' values; absent: the agent's own default. */
|
|
184
193
|
model: z.string().optional(),
|
|
194
|
+
/** Explicit choices from agents.models.config, applied before the first prompt. */
|
|
195
|
+
config: z.record(z.string(), z.string()).optional(),
|
|
185
196
|
/**
|
|
186
197
|
* Start in a new git worktree of `cwd`'s repository (its own branch, from
|
|
187
198
|
* the last commit) instead of in `cwd` itself. Refused with `not_a_repo`
|
|
@@ -434,12 +445,12 @@ const coreMethods = {
|
|
|
434
445
|
args: z.array(z.string()).default([]),
|
|
435
446
|
/** The terminal's working directory and environment. */
|
|
436
447
|
cwd: z.string().optional(),
|
|
437
|
-
env: z.record(z.string()).optional(),
|
|
448
|
+
env: z.record(z.string(), z.string()).optional(),
|
|
438
449
|
}),
|
|
439
450
|
result: z.object({
|
|
440
451
|
command: z.string(),
|
|
441
452
|
args: z.array(z.string()),
|
|
442
|
-
env: z.record(z.string()).optional(),
|
|
453
|
+
env: z.record(z.string(), z.string()).optional(),
|
|
443
454
|
/** Set for handoff agents: the session this terminal now drives. */
|
|
444
455
|
sessionId: z.string().optional(),
|
|
445
456
|
}),
|
|
@@ -455,7 +466,7 @@ const coreMethods = {
|
|
|
455
466
|
result: z.object({
|
|
456
467
|
command: z.string(),
|
|
457
468
|
args: z.array(z.string()),
|
|
458
|
-
env: z.record(z.string()).optional(),
|
|
469
|
+
env: z.record(z.string(), z.string()).optional(),
|
|
459
470
|
}),
|
|
460
471
|
},
|
|
461
472
|
// ── Gateway: reach this computer from anywhere ──
|
|
@@ -741,6 +752,7 @@ export function isMethodName(name: string): name is MethodName {
|
|
|
741
752
|
// ── Notifications (host → client) ────────────────────────────────────
|
|
742
753
|
|
|
743
754
|
export const notifications = {
|
|
755
|
+
"machine.changed": machineInfoSchema,
|
|
744
756
|
"agent.changed": z.object({ agent: agentInfoSchema }),
|
|
745
757
|
"agent.interaction": z.object({ agent: z.string(), request: z.union([pendingPermissionSchema, z.object({ requestId: z.string(), resolved: z.literal(true) })]) }),
|
|
746
758
|
"session.notice": z.object({ sessionId: z.string(), notice: sessionNoticeSchema }),
|