@linkshell/wire 0.2.1 → 0.2.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 CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  The LinkShell v2 wire protocol, shared by the host, the relay and the apps:
4
4
 
5
- - the session model and ACP-shaped session updates,
5
+ - the session model and ACP-shaped session updates, including Claude Workflow phases and Agent progress,
6
6
  - JSON-RPC methods and notifications between devices and a computer,
7
7
  - end-to-end encryption (Ed25519 identities, X25519 channel keys, XChaCha20-Poly1305),
8
8
  - the relay frames and a relay client for Node and React Native.
@@ -0,0 +1,35 @@
1
+ import { z } from "zod";
2
+ export declare const PREVIEW_MAX_BYTES: number;
3
+ export declare const previewFrameSchema: z.ZodObject<{
4
+ id: z.ZodString;
5
+ target: z.ZodString;
6
+ capturedAt: z.ZodNumber;
7
+ width: z.ZodNumber;
8
+ height: z.ZodNumber;
9
+ mimeType: z.ZodLiteral<"image/webp">;
10
+ }, "strip", z.ZodTypeAny, {
11
+ id: string;
12
+ target: string;
13
+ capturedAt: number;
14
+ width: number;
15
+ height: number;
16
+ mimeType: "image/webp";
17
+ }, {
18
+ id: string;
19
+ target: string;
20
+ capturedAt: number;
21
+ width: number;
22
+ height: number;
23
+ mimeType: "image/webp";
24
+ }>;
25
+ export type PreviewFrameInfo = z.infer<typeof previewFrameSchema>;
26
+ export interface PreviewFrame extends PreviewFrameInfo {
27
+ bytes: Uint8Array;
28
+ }
29
+ /** Length-prefixed metadata and image bytes, inside an authenticated proxy stream. */
30
+ export declare function encodePreviewFrame(frame: PreviewFrame): Uint8Array;
31
+ /** Handles split TCP/data-channel chunks without accepting unbounded allocations. */
32
+ export declare class PreviewFrameDecoder {
33
+ private held;
34
+ push(chunk: Uint8Array): PreviewFrame[];
35
+ }
@@ -0,0 +1,51 @@
1
+ import { z } from "zod";
2
+ export const PREVIEW_MAX_BYTES = 48 * 1024;
3
+ export const previewFrameSchema = z.object({
4
+ id: z.string().regex(/^[a-f0-9]{64}$/),
5
+ target: z.string().max(1024),
6
+ capturedAt: z.number().finite().nonnegative(),
7
+ width: z.number().int().positive().max(2048),
8
+ height: z.number().int().positive().max(2048),
9
+ mimeType: z.literal("image/webp"),
10
+ });
11
+ /** Length-prefixed metadata and image bytes, inside an authenticated proxy stream. */
12
+ export function encodePreviewFrame(frame) {
13
+ const { bytes, ...info } = frame;
14
+ const metadata = new TextEncoder().encode(JSON.stringify(previewFrameSchema.parse(info)));
15
+ if (bytes.length > PREVIEW_MAX_BYTES)
16
+ throw new Error("preview image too large");
17
+ const packet = new Uint8Array(8 + metadata.length + bytes.length);
18
+ const header = new DataView(packet.buffer);
19
+ header.setUint32(0, metadata.length);
20
+ header.setUint32(4, bytes.length);
21
+ packet.set(metadata, 8);
22
+ packet.set(bytes, 8 + metadata.length);
23
+ return packet;
24
+ }
25
+ /** Handles split TCP/data-channel chunks without accepting unbounded allocations. */
26
+ export class PreviewFrameDecoder {
27
+ held = new Uint8Array(0);
28
+ push(chunk) {
29
+ if (this.held.length + chunk.length > PREVIEW_MAX_BYTES + 4104)
30
+ throw new Error("preview buffer too large");
31
+ const next = new Uint8Array(this.held.length + chunk.length);
32
+ next.set(this.held);
33
+ next.set(chunk, this.held.length);
34
+ this.held = next;
35
+ const frames = [];
36
+ while (this.held.length >= 8) {
37
+ const header = new DataView(this.held.buffer, this.held.byteOffset);
38
+ const meta = header.getUint32(0), size = header.getUint32(4);
39
+ if (meta > 4096 || size > PREVIEW_MAX_BYTES || !meta || !size)
40
+ throw new Error("invalid preview frame");
41
+ const total = 8 + meta + size;
42
+ if (this.held.length < total)
43
+ break;
44
+ const info = previewFrameSchema.parse(JSON.parse(new TextDecoder().decode(this.held.subarray(8, 8 + meta))));
45
+ frames.push({ ...info, bytes: this.held.slice(8 + meta, total) });
46
+ this.held = this.held.slice(total);
47
+ }
48
+ return frames;
49
+ }
50
+ }
51
+ //# sourceMappingURL=computer-preview.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"computer-preview.js","sourceRoot":"","sources":["../src/computer-preview.ts"],"names":[],"mappings":"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"}
package/dist/goal.d.ts ADDED
@@ -0,0 +1,66 @@
1
+ import { z } from "zod";
2
+ /** Native agent state, not inferred from prose or a completed turn. */
3
+ export declare const sessionGoalSchema: z.ZodObject<{
4
+ objective: z.ZodString;
5
+ status: z.ZodEnum<["active", "paused", "blocked", "usageLimited", "budgetLimited", "complete"]>;
6
+ tokenBudget: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
7
+ tokensUsed: z.ZodOptional<z.ZodNumber>;
8
+ timeUsedSeconds: z.ZodOptional<z.ZodNumber>;
9
+ iterations: z.ZodOptional<z.ZodNumber>;
10
+ lastReason: z.ZodOptional<z.ZodNullable<z.ZodString>>;
11
+ }, "strip", z.ZodTypeAny, {
12
+ status: "active" | "paused" | "blocked" | "usageLimited" | "budgetLimited" | "complete";
13
+ objective: string;
14
+ tokenBudget?: number | null | undefined;
15
+ tokensUsed?: number | undefined;
16
+ timeUsedSeconds?: number | undefined;
17
+ iterations?: number | undefined;
18
+ lastReason?: string | null | undefined;
19
+ }, {
20
+ status: "active" | "paused" | "blocked" | "usageLimited" | "budgetLimited" | "complete";
21
+ objective: string;
22
+ tokenBudget?: number | null | undefined;
23
+ tokensUsed?: number | undefined;
24
+ timeUsedSeconds?: number | undefined;
25
+ iterations?: number | undefined;
26
+ lastReason?: string | null | undefined;
27
+ }>;
28
+ export type SessionGoal = z.infer<typeof sessionGoalSchema>;
29
+ export declare const goalChangeSchema: z.ZodDiscriminatedUnion<"action", [z.ZodObject<{
30
+ action: z.ZodLiteral<"get">;
31
+ }, "strip", z.ZodTypeAny, {
32
+ action: "get";
33
+ }, {
34
+ action: "get";
35
+ }>, z.ZodObject<{
36
+ action: z.ZodLiteral<"set">;
37
+ objective: z.ZodString;
38
+ tokenBudget: z.ZodOptional<z.ZodNumber>;
39
+ }, "strip", z.ZodTypeAny, {
40
+ objective: string;
41
+ action: "set";
42
+ tokenBudget?: number | undefined;
43
+ }, {
44
+ objective: string;
45
+ action: "set";
46
+ tokenBudget?: number | undefined;
47
+ }>, z.ZodObject<{
48
+ action: z.ZodLiteral<"pause">;
49
+ }, "strip", z.ZodTypeAny, {
50
+ action: "pause";
51
+ }, {
52
+ action: "pause";
53
+ }>, z.ZodObject<{
54
+ action: z.ZodLiteral<"resume">;
55
+ }, "strip", z.ZodTypeAny, {
56
+ action: "resume";
57
+ }, {
58
+ action: "resume";
59
+ }>, z.ZodObject<{
60
+ action: z.ZodLiteral<"clear">;
61
+ }, "strip", z.ZodTypeAny, {
62
+ action: "clear";
63
+ }, {
64
+ action: "clear";
65
+ }>]>;
66
+ export type GoalChange = z.infer<typeof goalChangeSchema>;
package/dist/goal.js ADDED
@@ -0,0 +1,19 @@
1
+ import { z } from "zod";
2
+ /** Native agent state, not inferred from prose or a completed turn. */
3
+ export const sessionGoalSchema = z.object({
4
+ objective: z.string(),
5
+ status: z.enum(["active", "paused", "blocked", "usageLimited", "budgetLimited", "complete"]),
6
+ tokenBudget: z.number().nonnegative().nullable().optional(),
7
+ tokensUsed: z.number().nonnegative().optional(),
8
+ timeUsedSeconds: z.number().nonnegative().optional(),
9
+ iterations: z.number().int().nonnegative().optional(),
10
+ lastReason: z.string().nullable().optional(),
11
+ });
12
+ export const goalChangeSchema = z.discriminatedUnion("action", [
13
+ z.object({ action: z.literal("get") }),
14
+ z.object({ action: z.literal("set"), objective: z.string().trim().min(1).max(4000), tokenBudget: z.number().int().positive().max(Number.MAX_SAFE_INTEGER).optional() }),
15
+ z.object({ action: z.literal("pause") }),
16
+ z.object({ action: z.literal("resume") }),
17
+ z.object({ action: z.literal("clear") }),
18
+ ]);
19
+ //# sourceMappingURL=goal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"goal.js","sourceRoot":"","sources":["../src/goal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,uEAAuE;AACvE,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACxC,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;IACrB,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,cAAc,EAAE,eAAe,EAAE,UAAU,CAAC,CAAC;IAC5F,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,WAAW,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IAC3D,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,WAAW,EAAE,CAAC,QAAQ,EAAE;IAC/C,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,WAAW,EAAE,CAAC,QAAQ,EAAE;IACpD,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC,QAAQ,EAAE;IACrD,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;CAC7C,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,kBAAkB,CAAC,QAAQ,EAAE;IAC7D,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;IACtC,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC;IACvK,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;IACxC,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;IACzC,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;CACzC,CAAC,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  export * from "./model.js";
2
+ export * from "./goal.js";
2
3
  export * from "./updates.js";
4
+ export * from "./workflow.js";
3
5
  export * from "./rpc.js";
4
6
  export * from "./peer.js";
5
7
  export * from "./shell.js";
@@ -7,3 +9,4 @@ export * from "./crypto.js";
7
9
  export * from "./relay.js";
8
10
  export * from "./relay-client.js";
9
11
  export * from "./direct.js";
12
+ export * from "./computer-preview.js";
package/dist/index.js CHANGED
@@ -1,5 +1,7 @@
1
1
  export * from "./model.js";
2
+ export * from "./goal.js";
2
3
  export * from "./updates.js";
4
+ export * from "./workflow.js";
3
5
  export * from "./rpc.js";
4
6
  export * from "./peer.js";
5
7
  export * from "./shell.js";
@@ -7,4 +9,5 @@ export * from "./crypto.js";
7
9
  export * from "./relay.js";
8
10
  export * from "./relay-client.js";
9
11
  export * from "./direct.js";
12
+ export * from "./computer-preview.js";
10
13
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC;AAC5B,cAAc,uBAAuB,CAAC"}