@agent-sh/computer-use-linux 0.7.13 → 0.7.15

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
@@ -78,7 +78,9 @@ and measure from its clipped screenshot crop origin. Divide preview `x` and
78
78
  GDK surface or widget-local coordinates; decorations and clipping can change
79
79
  the origin. A missing window target is rejected.
80
80
 
81
- Targeted `press_key`/`type_text` results append focused-element feedback from AT-SPI (role, name, editable) and warn when no editable element holds focus. Click/screenshot/input results warn when the target window or coordinate is partially or fully off-screen. `get_app_state` returns a compact readiness block by default; pass `verbose: true` for the full diagnostics report. It also reports `tree_scoped` (false when no app target narrowed the AT-SPI tree, with a warning in `message`) and `accessibility_tree_truncated` (true when the node, depth, or read budget stopped traversal with unread elements left).
81
+ Targeted `press_key`/`type_text` results append focused-element feedback from AT-SPI (role, name, editable) and warn when a concrete non-terminal focus is not editable. Terminals accept keyboard input without an EditableText interface; re-observe the contents to confirm input. Click/screenshot/input results warn when the target window or coordinate is partially or fully off-screen. `get_app_state` returns a compact readiness block by default; pass `verbose: true` for the full diagnostics report. It also reports `tree_scoped` (false when no app target narrowed the AT-SPI tree, with a warning in `message`) and `accessibility_tree_truncated` (true when the node, depth, or read budget stopped traversal with unread elements left).
82
+
83
+ On X11, text input sends LF and CRLF line endings as Return, with one newline per CRLF pair.
82
84
 
83
85
  On GNOME, a read-only keymap preflight rejects the whole string before input if a character is absent or requires a modifier level Mutter cannot synthesize. The background reader cannot establish the active layout group, so every configured group must support the text. This can reject text that works in one of several groups; use `set_value` on an editable field instead. The check requires `libxkbcommon.so.0` at runtime and stops after a two-second keymap read deadline. It does not cover held modifiers or a keymap changed concurrently with typing.
84
86
 
@@ -330,6 +332,16 @@ You can also search by capability:
330
332
  computer_use_linux_tools({ query: "observe a window and click a control" })
331
333
  ```
332
334
 
335
+ Codemode scripts receive `{ text, images, isError }`. Each image is an MCP image
336
+ block that can be passed directly to `image()`:
337
+
338
+ ```js
339
+ const result = await tools.computer_use_linux_screenshot({});
340
+ if (result.isError) throw new Error(result.text);
341
+ text(result.text);
342
+ for (const block of result.images) image(block);
343
+ ```
344
+
333
345
  No separate MCP adapter or manual MCP configuration is required. Pi starts one
334
346
  computer-use-linux process lazily on the first real tool call, reuses it for the
335
347
  session so accessibility snapshots remain valid, serializes desktop actions,
package/npm/README.md CHANGED
@@ -88,6 +88,14 @@ 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.
98
+
99
+ X11 text input sends LF and CRLF line endings as Return. Focused terminals
100
+ accept keyboard input even when AT-SPI does not expose EditableText. Focus
101
+ feedback describes the target; re-observe its contents to confirm input.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-sh/computer-use-linux",
3
- "version": "0.7.13",
3
+ "version": "0.7.15",
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.13";
10
+ export const GENERATED_SERVER_VERSION = "0.7.15";
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.