@linkshell/wire 0.2.22 → 0.2.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,14 +1,35 @@
1
1
  import { z } from "zod";
2
- export declare const workflowStateSchema: z.ZodEnum<["running", "paused", "completed", "failed", "stopped"]>;
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<["pending", "running", "paused", "completed", "failed", "stopped", "unknown"]>;
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<["pending", "running", "paused", "completed", "failed", "stopped", "unknown"]>;
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
- }, "strip", z.ZodTypeAny, {
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
- }, "strip", z.ZodTypeAny, {
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<["running", "paused", "completed", "failed", "stopped"]>>;
67
- /** Observed counts: a dynamic script may start more agents later. */
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
- }, "strip", z.ZodTypeAny, {
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<["pending", "running", "paused", "completed", "failed", "stopped", "unknown"]>;
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
- }, "strip", z.ZodTypeAny, {
102
- id: string;
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.22",
3
+ "version": "0.2.23",
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": "^3.24.3"
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.string().url(), headers: env.default({}) }),
7
- z.object({ type: z.literal("sse"), name: z.string().min(1), url: z.string().url(), headers: env.default({}) }),
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.string().url().optional(),
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.default({}),
29
+ settings: acpAgentSettingsSchema.prefault({}),
30
30
  });
31
31
  export type AcpRemoteAgent = z.infer<typeof acpRemoteAgentSchema>;
32
32
 
@@ -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().finite().nonnegative(),
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.object({ audience: z.array(z.enum(["user", "assistant"])).nullish().transform((value) => value ?? undefined), priority: z.number().nullish().transform((value) => value ?? undefined), lastModified: optionalString }).passthrough().nullish().transform((value) => value ?? undefined),
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, z.ZodTypeDef, unknown> = contentVariants;
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 "&#x20;": 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).replace(ANSI, "").replace(/\n+$/, "")) || undefined;
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"));
@@ -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.string().url().max(256),
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),
package/src/relay.ts CHANGED
@@ -74,7 +74,7 @@ export const serverFrameSchema = z.discriminatedUnion("t", [
74
74
  result: z.unknown().optional(),
75
75
  error: z.object({ code: z.string(), message: z.string() }).optional(),
76
76
  }),
77
- z.object({ t: z.literal("event"), name: z.string(), data: z.unknown() }),
77
+ z.object({ t: z.literal("event"), name: z.string(), data: z.unknown().optional() }),
78
78
  /** An encrypted frame from a peer, with the keys the gateway verified it holds. */
79
79
  z.object({ t: z.literal("from"), from: publicIdentitySchema, via: z.enum(["paired", "account"]), d: z.string() }),
80
80
  /** A frame couldn't be delivered: the peer is offline or not reachable. */
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
@@ -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.object({}).passthrough();
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.string().url().optional(), headers: z.record(z.string()).optional() }).optional() }),
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": {
@@ -434,12 +434,12 @@ const coreMethods = {
434
434
  args: z.array(z.string()).default([]),
435
435
  /** The terminal's working directory and environment. */
436
436
  cwd: z.string().optional(),
437
- env: z.record(z.string()).optional(),
437
+ env: z.record(z.string(), z.string()).optional(),
438
438
  }),
439
439
  result: z.object({
440
440
  command: z.string(),
441
441
  args: z.array(z.string()),
442
- env: z.record(z.string()).optional(),
442
+ env: z.record(z.string(), z.string()).optional(),
443
443
  /** Set for handoff agents: the session this terminal now drives. */
444
444
  sessionId: z.string().optional(),
445
445
  }),
@@ -455,7 +455,7 @@ const coreMethods = {
455
455
  result: z.object({
456
456
  command: z.string(),
457
457
  args: z.array(z.string()),
458
- env: z.record(z.string()).optional(),
458
+ env: z.record(z.string(), z.string()).optional(),
459
459
  }),
460
460
  },
461
461
  // ── Gateway: reach this computer from anywhere ──