@agent-sh/computer-use-linux 0.7.12 → 0.7.14

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
@@ -330,6 +330,16 @@ You can also search by capability:
330
330
  computer_use_linux_tools({ query: "observe a window and click a control" })
331
331
  ```
332
332
 
333
+ Codemode scripts receive `{ text, images, isError }`. Each image is an MCP image
334
+ block that can be passed directly to `image()`:
335
+
336
+ ```js
337
+ const result = await tools.computer_use_linux_screenshot({});
338
+ if (result.isError) throw new Error(result.text);
339
+ text(result.text);
340
+ for (const block of result.images) image(block);
341
+ ```
342
+
333
343
  No separate MCP adapter or manual MCP configuration is required. Pi starts one
334
344
  computer-use-linux process lazily on the first real tool call, reuses it for the
335
345
  session so accessibility snapshots remain valid, serializes desktop actions,
package/npm/README.md CHANGED
@@ -88,6 +88,10 @@ When installed through Pi, the package supplies native, dynamically loaded
88
88
  configuration is required. Native tools require Pi 0.84.4 or newer; the
89
89
  standalone CLI wrapper retains Node.js 18 support.
90
90
 
91
+ In Pi codemode, native tools return `{ text, images, isError }`. Pass image
92
+ blocks directly to `image(result.images[0])` and check `isError` before using
93
+ a result.
94
+
91
95
  If you already built or installed the binary yourself, set
92
96
  `COMPUTER_USE_LINUX_BIN=/path/to/computer-use-linux` to make the wrapper use
93
97
  that executable instead.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-sh/computer-use-linux",
3
- "version": "0.7.12",
3
+ "version": "0.7.14",
4
4
  "description": "Linux desktop-control MCP server: AT-SPI accessibility trees, Wayland/X11 input, screenshots, and compositor window targeting.",
5
5
  "license": "MIT",
6
6
  "type": "commonjs",
@@ -7,7 +7,7 @@ export interface GeneratedMcpToolDefinition {
7
7
  annotations: Record<string, unknown>;
8
8
  }
9
9
 
10
- export const GENERATED_SERVER_VERSION = "0.7.12";
10
+ export const GENERATED_SERVER_VERSION = "0.7.14";
11
11
  export const GENERATED_TOOL_CATALOG_HASH = "666f4649084b7c1a240e6a0eacc01a55379b64a579355f50071211437e91229c";
12
12
  export const GENERATED_SHELL_TOOL_CATALOG_HASH = "554322e70886f5c1e1a3ad06869c5be91c140103f71350ad635160e128c1563d";
13
13
  export const GENERATED_MCP_TOOLS =
@@ -483,6 +483,46 @@ function convertMcpResult(result: McpCallToolResult): PiContent[] {
483
483
  return converted;
484
484
  }
485
485
 
486
+ /**
487
+ * Machine-readable result for codemode scripts.
488
+ *
489
+ * Pi's codemode sandbox only passes `structuredContent` to nested calls from
490
+ * tools that declare `outputSchema`; otherwise scripts receive text only and
491
+ * image blocks are dropped. Mirror the `read` tool pattern so screenshots and
492
+ * other image results stay reachable via `image()`.
493
+ */
494
+ const NativeToolOutputSchema = Type.Object({
495
+ text: Type.String({
496
+ description: "Joined text blocks of the converted MCP result.",
497
+ }),
498
+ images: Type.Array(
499
+ Type.Object({
500
+ type: Type.Literal("image"),
501
+ data: Type.String({ description: "Base64 image data." }),
502
+ mimeType: Type.String({ description: "Image MIME type." }),
503
+ }),
504
+ { description: "Image blocks of the converted MCP result." },
505
+ ),
506
+ isError: Type.Boolean({ description: "Whether the MCP tool reported a failure." }),
507
+ });
508
+
509
+ function toNativeToolStructuredContent(content: PiContent[], isError: boolean): {
510
+ text: string;
511
+ images: Array<{ type: "image"; data: string; mimeType: string }>;
512
+ isError: boolean;
513
+ } {
514
+ const texts: string[] = [];
515
+ const images: Array<{ type: "image"; data: string; mimeType: string }> = [];
516
+ for (const block of content) {
517
+ if (block.type === "text") {
518
+ texts.push(block.text);
519
+ } else if (block.type === "image") {
520
+ images.push({ type: "image", data: block.data, mimeType: block.mimeType });
521
+ }
522
+ }
523
+ return { text: texts.join("\n"), images, isError };
524
+ }
525
+
486
526
  function legacyConfigPath(): string {
487
527
  const agentDir =
488
528
  process.env.PI_CODING_AGENT_DIR?.trim() || join(homedir(), ".pi", "agent");
@@ -585,6 +625,7 @@ export function createComputerUseLinuxExtension(
585
625
  label: `Computer Use: ${tool.name}`,
586
626
  description: nativeToolDescription(tool),
587
627
  parameters: toolParameters(tool.inputSchema),
628
+ outputSchema: NativeToolOutputSchema,
588
629
  executionMode: "sequential",
589
630
  async execute(_toolCallId, params, signal) {
590
631
  const result = await getClient().callTool(
@@ -592,13 +633,15 @@ export function createComputerUseLinuxExtension(
592
633
  params as Record<string, unknown>,
593
634
  signal,
594
635
  );
636
+ const content = convertMcpResult(result);
595
637
  return {
596
- content: convertMcpResult(result),
638
+ content,
597
639
  details: {
598
640
  computerUseLinux: true,
599
641
  mcpIsError: result.isError === true,
600
642
  tool: tool.name,
601
643
  },
644
+ structuredContent: toNativeToolStructuredContent(content, result.isError === true),
602
645
  };
603
646
  },
604
647
  });
@@ -59,6 +59,16 @@ Pi does not start the desktop process when the loader runs. The first real tool
59
59
  call starts one computer-use-linux process, and the package reuses it for the
60
60
  session so `get_app_state` element indices and portal sessions remain valid.
61
61
 
62
+ Codemode scripts receive `{ text, images, isError }`. Each image is an MCP image
63
+ block that can be passed directly to `image()`:
64
+
65
+ ```js
66
+ const result = await tools.computer_use_linux_screenshot({});
67
+ if (result.isError) throw new Error(result.text);
68
+ text(result.text);
69
+ for (const block of result.images) image(block);
70
+ ```
71
+
62
72
  ## Safe operating loop
63
73
 
64
74
  1. Enable `get_app_state`, `list_windows`, and any likely action tools.