Skip to content

v0.8.0

Latest

Choose a tag to compare

@github-actions github-actions released this 08 Jul 14:02

Upgrade notes

Breaking changes

email_search now uses a structured DSL instead of a raw Gmail query string

The email_search tool previously accepted a raw Gmail query string via a query parameter. It now requires a structured filter object. If your agents called email_search with a query field, update them to use the new fields.

Before (no longer supported):

email_search({ query: "from:alice@example.com is:unread" })

After (structured DSL):

email_search({ from: "alice@example.com", unread: true })

Available filter fields: from, to, subject, text, unread, sinceDays, folder, limit. text is a free-text match across sender, subject, and body — use it for a content match (an invoice number, an order ID, a phrase from the message) that subject alone can't express. See the email_search tool description in your agent's tool list for the full field reference. The structured DSL is provider-agnostic — the same filters work for both Gmail and the new Microsoft 365 backend.

The tighter agent tool boundary described below also changes runtime behaviour for existing agents, but it only removes built-ins that were never meant to be reachable — see the note under Upgrade notes.

Upgrade notes

The standard flow applies:

cd /opt/pinchy
sed -i 's/PINCHY_VERSION=v0.7.0/PINCHY_VERSION=v0.8.0/' .env
docker compose pull && docker compose up -d && docker image prune -f

Microsoft 365 (Outlook) email

v0.8.0 adds Microsoft 365 (Outlook) email support alongside Gmail. Connect a Microsoft work/school account under Settings → Integrations, and agents get the same email_list, email_read, email_search, email_get_attachment, email_draft, and email_send tools — backed by the Microsoft Graph API and governed by the same per-agent email permissions. Existing Gmail connections are unaffected.

Each email operation (Read, Create drafts, Send) is granted independently in the Permissions tab — checking one does not grant the others. If you're upgrading an agent that relied on Send also implying Read or Draft, re-check the operations it needs.

Legacy permission vocabulary. Agents created before this release may still have their email permissions stored as legacy per-tool rows (search, list) instead of the current read operation. Pinchy treats search and list as aliases of read — they unlock the exact same read-only toolset and never unlock draft or send. The Permissions UI displays these agents' rows as Read messages, and saving the agent's permissions normalizes them to the current read vocabulary. No action needed.

Tamper-evident audit log (hash-chained)

The audit log now binds every row into an HMAC hash-chain: each row's signature includes its predecessor's, so deleting a row from the middle, truncating the tail, or reordering history breaks the chain — not just editing a field. verifyIntegrity checks each link and reports any breaks. Historical rows are never re-signed — existing entries stay verifiable under their original signature, and the chain starts binding from the upgrade onward. Nothing to configure.

Tighter tool boundary for agents

Governed agents now run against a fail-closed allowlist — exactly the audited Pinchy plugin tools plus a few read-only built-ins (memory_search, memory_get, pdf, image, session_status) — instead of a deny-list that left powerful built-ins silently reachable and unaudited. Anything not on the list — cron, gateway, message, nodes, subagents/sessions_*, the tts/image_generate/music_generate/video_generate generators, and any built-in a future OpenClaw version adds — is now denied by default. Existing agents pick this up automatically when their OpenClaw config regenerates on startup; there's no migration and nothing to configure. These built-ins were never an audited Pinchy capability, so no governed agent should notice — and they're denied by design, not re-grantable through agent permissions.

Security hardening

A round of fixes from this cycle that need no action on your part:

  • attachment downloads now enforce per-user ownership (closes an IDOR gap)
  • deactivating a user immediately revokes their active sessions
  • the file-write path resolves symlinks before writing
  • audit and usage CSV exports neutralize spreadsheet formula injection
  • webFetch caps response bodies to bound memory use

Models: self-healing config and smarter vision routing

  • Pinchy now self-heals its OpenClaw config when a dispatch hits a retired model, instead of leaving the agent stuck on an unavailable model.
  • Ollama Cloud vision models resolve against the live catalog, and kimi-k2.7-code joins the curated catalog.
  • Image reads route through the audited pinchy_read tool (with its own resolved vision model) rather than OpenClaw's built-in image tool, and image-turn fallbacks pick the best-vision model while honouring the tools blocklist.

Chat quality-of-life

  • The composer keeps your unsent draft across reloads, scoped per conversation.
  • Selecting an agent reopens your last-viewed conversation.
  • Agents now carry brand-themed avatars.

Telegram conversations from before the upgrade

Telegram conversations that predate Pinchy's own transcript store now render through an OpenClaw history fallback, so upgrading no longer leaves older chats blank. The Telegram channel also shows as a titled icon in the chat list.

Dependencies

  • OpenClaw 2026.6.11 (was 2026.6.8) — picked up via Dockerfile.openclaw, surfaced in GET /api/version. Same protocol train; backward-compatible patch bump.

Database migrations

One additive migration runs automatically on startup — no manual steps:

  • 0043 — adds the nullable prev_hmac column to audit_log, backing the tamper-evident audit hash-chain.

What's Changed

  • docs(release): add post-release deploy + marketing-website steps to the checklist by @clemenshelm in #585
  • ci(links): exclude the private heypinchy/website repo from lychee by @clemenshelm in #586
  • Codebase hardening sweep: audit v3 hash-chain, IDOR & leak fixes (27 commits) by @clemenshelm in #579
  • fix(chat): per-chat composer drafts + reopen last-viewed chat by @clemenshelm in #589
  • docs: de-link the private heypinchy/website repo (fixes the link checker) by @clemenshelm in #591
  • feat(chat): persist composer draft text across reloads by @clemenshelm in #593
  • fix(models): harden ollama-cloud model resolution against upstream retirement + runtime self-heal by @clemenshelm in #588
  • fix(telegram): show pre-existing conversations in the mirror + titled icon in chat list by @clemenshelm in #595
  • feat(pinchy-files): give pinchy_read a dedicated live-resolved vision model by @clemenshelm in #596
  • fix(pinchy-odoo): audit failed tool calls as failures (+ type-check cleanup) by @clemenshelm in #597
  • feat(avatars): brand-themed notionists agent avatars by @clemenshelm in #592
  • fix(chat): honest hint for OpenClaw's generic provider-rejection envelope (#584) by @clemenshelm in #587
  • feat(models): add kimi-k2.7-code to the Ollama Cloud catalog by @clemenshelm in #594
  • fix(chat): apply tools blocklist when picking an image-turn fallback model by @clemenshelm in #598
  • fix(chat): suppress durable error banner when the inline failure is on screen (#583) by @clemenshelm in #590
  • fix(web): fall back to visible text when Readability under-extracts a page by @clemenshelm in #601
  • fix(web): deny OpenClaw group:ui so the native browser tool isn't silently reachable by @clemenshelm in #603
  • refactor(chat): clarify vision-fallback comparator + cover its tiebreak branches by @clemenshelm in #604
  • ci: bump the actions group across 1 directory with 15 updates by @dependabot[bot] in #407
  • fix(web): fail-closed tool allowlist instead of partial deny-list (#605) by @clemenshelm in #606
  • docs(release): v0.8.0 upgrade notes by @clemenshelm in #608
  • ci: align composite action runtimes with workflow group bump (#407) by @clemenshelm in #607
  • fix(chat): last-chat link staleness + context-overflow hint (v0.8.0 staging findings) by @clemenshelm in #612
  • fix(pinchy-odoo): resolve bare _pinchy_ref in m2o fields + scope by company by @clemenshelm in #614
  • fix(chat): tapClientLookup crash recovery + name the model in generic errors by @clemenshelm in #632
  • fix(test): broaden node_modules exclude in vitest.config to cover nested plugin deps by @clemenshelm in #629
  • fix(chat): durable-banner scope + Dismiss + sidebar indicator for any session by @clemenshelm in #634
  • fix(chat): image-attachment note reflects the vision-model offload, not "unsupported" by @clemenshelm in #635
  • chore: bump OpenClaw core to 2026.6.11 + add update-openclaw skill by @clemenshelm in #638
  • fix(chat): preserve the user's message when OpenClaw omits it for size by @clemenshelm in #637
  • feat(diagnostics): include an agent-config snapshot (model, tools, prompt hash) in the bundle by @clemenshelm in #645
  • fix(diagnostics): export any of the user's own chats + graceful degrade (#639) by @clemenshelm in #647
  • feat(diagnostics): enrich depth-truncated tool-call args from the audit log by @clemenshelm in #646
  • chore(deps): update npm dependencies + add update-dependencies skill by @clemenshelm in #648
  • feat(diagnostics): move export into Agent Settings, keep per-message report by @clemenshelm in #644
  • fix(pinchy-odoo): make filters optional on odoo_read/odoo_count/odoo_aggregate by @clemenshelm in #649
  • fix(server): exit on startup failure instead of running as a zombie by @clemenshelm in #652
  • feat(health): surface OpenClaw gateway connectivity in /api/health by @clemenshelm in #653
  • chore(deps): bump openclaw-node to 0.13.1 by @clemenshelm in #654
  • ci(plugins): add TypeScript typecheck gate for pinchy-* plugins by @clemenshelm in #656
  • fix(api): fail loudly with 503 when Google OAuth settings are missing during a required token refresh by @clemenshelm in #658
  • ci: run pinchy plugin vitest unit suites in the quality job by @clemenshelm in #657
  • feat(agent-templates): give bookkeeper & finance-controller read access to Odoo subscriptions by @clemenshelm in #655
  • feat(agent-templates): grant Subscription Manager optional read on sale.subscription.plan by @clemenshelm in #659
  • feat(email): Microsoft 365 email support (OAuth, Graph API, E2E) by @clemenshelm in #328
  • fix(chat): adopt refocus history when a leading greeting hides the landed reply by @clemenshelm in #662
  • ci(links): exclude the stargazers badge from the lychee link check by @clemenshelm in #665
  • fix(integrations): OAuth connect failures as a persistent banner, not a toast by @clemenshelm in #664
  • fix(integrations): actionable message when an agent's connection is gone by @clemenshelm in #667
  • fix(email): emit details.error on failed tool results (#404) by @clemenshelm in #668
  • refactor(models): default ollama-cloud provider default to kimi-k2.6 (#669) by @clemenshelm in #672
  • refactor(models): default balanced-tier agent templates to kimi-k2.6 by @clemenshelm in #671
  • fix(email): resolve message/attachment ids via short handles by @clemenshelm in #673
  • fix(models): emit cost.cacheRead/cacheWrite for openai/google so OpenClaw accepts the catalog by @clemenshelm in #676
  • fix(odoo): validate selection values (move_type) + guard duplicate invoices on create by @clemenshelm in #679
  • fix(models): vision-model fallback chain so an unreachable pdf/image primary degrades gracefully by @clemenshelm in #678
  • docs(release): codify the staging pass as an active test-and-fix loop by @clemenshelm in #682
  • docs: correct v0.8.0 release docs — OpenClaw version, audit hash-chain by @clemenshelm in #683
  • docs: v0.8.0 follow-ups — skills concept page + integration lifecycle/errors by @clemenshelm in #684

New Contributors

Full Changelog: v0.7.0...v0.8.0