Skip to content

v0.0.3

Choose a tag to compare

@github-actions github-actions released this 14 Nov 10:00
· 32 commits to master since this release
98b914f

[0.0.3] - 2026-11-13

Added

  • The jelly settings declare their choices: access is drawn as Allowed, Ask before changes or Read only, with Jelly's own line for each (needs a jelly that includes app#1301).

  • The uiActions option, empty (off) by default, and Jelly's commit action: a person can approve a Sheets value update (sheets.spreadsheets.values.update, the only value the option takes) from a UI an agent made in Jelly. The action is plan-shaped: its input is a gws plan request, its preview, the new read-only method plan.preview (permission gws.plan), is gws's own dry run of that exact request with every cell it writes (the spreadsheet, range and cells quoted, and control, line-separator and bidi characters shown as escapes, so no field can fake or reorder a line; it needs no grant and writes no audit record), and Jelly asks every time (confirm: "always") from an owner device only (class: "local"). The plugin checks Jelly's single-use action grant (its key, this plugin and action, the digest of exactly this input, at most a minute old, never used before, an owner device's class), then refuses when the option does not list the operation (UI_ACTION_OFF), when access is read-only, for any other operation, for USER_ENTERED values, extra fields or more than 100 rows of 26 cells, and for a preview over Jelly's 4,000 characters (UI_ACTION_REFUSED); a bad grant is UI_GRANT_REFUSED. It then plans and commits the change as the person through the normal plan and commit path, so access, policy and the admin gate apply (the person's OpenCode permission rules for agents are not consulted: no agent makes the call), and answers what Google says changed. Each call writes a ui.act audit record with caller: "person", the Jelly member and the grant's id, as do the plan and commit records. The declaration adds the action (tool: "gws.write"), the preview method and a minimal settings page, views/ui-changes.html, which Jelly's schema needs until it relaxes its rule for agent-UI actions (In Jelly).

  • images.read, a read-only method for Jelly on the RPC named after the package, so a Google Drive or Workspace picture an agent puts in a UI is drawn. It takes { url } and answers { mime, base64 }: a PNG, JPEG, GIF or WebP of at most 1 MB, its type judged from its first bytes, never SVG. A Drive file link is read through gws as the account (drive.files.get, then its bytes with alt=media in a private directory removed at once, or else its thumbnail); any other address must be https on one of Google's own image servers (lh3 to lh7, lh7-rt, lh7-us under googleusercontent.com), with no user name, port or IP address, and is fetched with no redirect followed and the size checked while it streams; every other googleusercontent.com name, which anyone can hold, is refused before any fetch. The account's token goes only for an address Google returned to that account in this process, in a field Google fills itself (thumbnailLink, contentUri and the like, never text people write); any other image-server address is fetched without credentials. The account is the one Google returned the address to, or else the only account that enables drive, or else default; otherwise IMAGE_ACCOUNT_AMBIGUOUS. New codes IMAGE_HOST_REFUSED, IMAGE_TYPE_REFUSED, IMAGE_TOO_LARGE and IMAGE_UNAVAILABLE, an images.read audit record, and the declaration's imageHosts (exactly drive.google.com and those image servers) and imageRead (In Jelly). Jelly's host currently refuses any RPC answer over 64 KB, so until Jelly lifts that only pictures up to about 47 KB show there.

Known limits

  • Platforms. macOS (arm64, x64) and Linux (glibc, arm64, x64) only. Windows and musl have no release binary, so the tools refuse with GWS_UNAVAILABLE unless binary.path names a gws 0.22.5 executable.
  • Operations. The tools are the operations in the manifest generated from the pinned gws 0.22.5. A method that a later gws adds arrives with a plugin release, and gws_catalog lists only the manifest.
  • Services the default sign-in leaves out. Keep needs domain-wide delegation that a Workspace admin sets up, admin reports need a Workspace admin account, and Model Armor cannot run. A method that only a Chat app or a Classroom add-on can run (appOnly) fails with AUTH_SCOPE_MISSING under a Google sign-in.
  • Unverified OAuth apps. An External client left in Testing shows unverified-app warnings, and its refresh tokens expire after 7 days, so each account signs in again weekly.
  • A cancelled commit may have been applied. CANCELLED means the call stopped while gws ran. Check the state with gws_read before planning the change again.
  • Asks need an answerer. At access: "ask-changes", opencode run and scripts cannot answer a prompt, so a commit there needs an allow rule for it, or access: "all".
  • Output and time limits. A result that is too large stops with OUTPUT_LIMIT, and a slow call with TIMEOUT. Narrow the request with fields, a smaller page size, maxPages or maxItems.
  • Changes from an agent's UI in Jelly. Off by default, and only Sheets value updates: RAW values (never formulas), at most 100 rows of 26 cells, with a preview that fits Jelly's 4,000-character confirmation. The preview shows the new values, not the cells' current ones. It works only in Jelly, which holds the key its grants are signed with; Jelly's grant does not yet say how Jelly asked, so the plugin relies on Jelly for asking every time. /gws-status does not show the option yet.
  • Pictures in Jelly over about 47 KB. images.read answers pictures up to 1 MB, as Jelly's picture contract allows, but Jelly's host currently refuses any plugin RPC answer over 64 KB of JSON (VIEW_DATA_MAX_BYTES), so a picture over about 47 KB shows no picture in Jelly until Jelly lifts that limit for pictures. That limit is Jelly's, not the plugin's.
  • Jelly. The access setting declares its choices, which only a Jelly that includes app#1301 reads; an older Jelly refuses the plugin's declaration.
  • Tested hosts. Tested on OpenCode 2.2.3, 2.2.4, 2.2.5 and 2.2.6. A later 2.2 release loads, and /gws-status marks it untested.
  • Audit lines can drop. The audit log is written off the call path, with a 100 ms budget per line. A write that stalls past it is abandoned: its line and any queued behind it are lost. The call's result is not affected. The sink then stops writing until the plugin reloads, and /gws-status shows that some audit records could not be saved.
  • Updates are not automatic for a Git install, and opencode plugin update and opencode plugin check do not work on one: to move to a newer release, remove the old entry and add the new tag.