Skip to content

Releases: Lifecycle-Innovations-Limited/claude-ops

claude-ops v2.17.0

31 May 01:49
4f2c449

Choose a tag to compare

Release v2.17.0. See CHANGELOG.md for details.

claude-ops v2.16.0

31 May 01:48

Choose a tag to compare

Release v2.16.0. See CHANGELOG.md for details.

claude-ops v2.15.0

29 May 18:30

Choose a tag to compare

Added

  • Triage decision-log hookops-pocket-triage.py now records each triage decision (event type, confidence, reasoning) via /opt/pocket-mcp/pipeline/ops-pocket-decisions.py when present (try/except-guarded, no-op if absent), building an audit trail for downstream reporting.

Changed

  • ops-message-listener.sh input hardening — defense-in-depth on the dispatch path: env-var isolation for QUEUE_FILE (no shell interpolation), JSON load guarded by try/except + isinstance, per-message bounds (MAX_LEN=4000, sender ≤64), control-char stripping, and NUL-delimited dispatch output so newlines in message text can't smuggle extra dispatch lines. Merged on top of origin's existing stdin-piping fix; keeps the || true call-site resilience.

(Ports two patches that had been applied directly on the deploy box into the repo, so the live checkout can track main cleanly.)

claude-ops v2.14.1

29 May 18:23

Choose a tag to compare

Fixed

  • ops-pocket-notify wrapper resolves symlinks. The bin/ops-pocket-notify bash wrapper computed the Python script path from dirname "$0", which resolves relative to a PATH symlink's directory rather than the real file — so invoking it via a ~/.local/bin symlink failed to find ../scripts/ops-pocket-notify.py. Now readlink -fs itself first. Also syncs package.json (had drifted to 2.13.0) to the plugin version.

claude-ops v2.14.0

29 May 18:04

Choose a tag to compare

Release v2.14.0. See CHANGELOG.md for details.

claude-ops v2.13.0

29 May 17:49

Choose a tag to compare

Added

  • Config-driven pocket notifications (ops-pocket-notify) — interactive setup of which events, which channels, when. Pocket components emit an event id; the new bin/ops-pocket-notify dispatcher decides routing from preferences.json → pocket.notifications: per-event channels (telegram/email/whatsapp/slack via the existing senders + out-queue), plus a full per-event schedule — cooldown, quiet-hours, active-days, and severity escalation (high bypasses windows). New events are off by default. /ops:ops-settings → Configure notifications walks each event interactively (channels + schedule + dry-run test-send) and writes the prefs; docs/pocket-notifications.md documents the schema + event taxonomy. The executor emits worker.spawned / worker.failed, and the env-broker's notify hook points at the dispatcher. --dry-run --json resolves routing without sending (used by setup + tests).

claude-ops v2.12.0

29 May 17:35

Choose a tag to compare

Added

  • pocket-env-broker — peer-authenticated secrets broker for restricted pocket workers. Restricted background workers (which no longer inherit the orchestrator's secret env, per 2.11.9) can now request a specific allowlisted secret at runtime via the pocket-env <VAR> client, instead of all-or-nothing. The broker (scripts/pocket-env-broker.py, runs as the privileged orchestrator user) listens on a unix socket, authenticates the caller with SO_PEERCRED (must be the worker uid), checks a default-deny allowlist (env-broker-policy.json), returns the value over the socket only (never to disk), and audits every grant/deny. Ships with the client, policy + systemd templates, docs, and tests; the pocket executor forwards the broker socket path + task/worker ids to workers.
  • Env-broker observability. The broker keeps a metrics snapshot (env-broker-health.json: request/grant/deny/uid-rejection counters, recent denials, anomaly flag), exposes pocket-env-broker --status [--json], and surfaces an Env-broker line in /ops:ops-status that raises a anomaly on any uid rejection (a prompt-injection probing signal).
  • Env-broker push notifications (opt-in). Set POCKET_ENV_BROKER_NOTIFY_CMD (+ POCKET_ENV_BROKER_NOTIFY_COOLDOWN, default 300s) and the broker fires that command with an alert on uid rejections / not-allowed denials — rate-limited, best-effort, never blocking request handling. Wired to the operator's own chat it is a self-notification (outbound-comms-gate exempt).

claude-ops v2.11.9

29 May 14:55

Choose a tag to compare

Security

  • Pocket executor: optional least-privilege worker isolation (POCKET_WORKER_USER). ops-cron-pocket-executor.py can now launch each claude --bg worker as a restricted unix user via sudo -n -H -u <user> instead of inheriting the executor user's full privileges, capping the blast radius of a prompt-injected or auto-promoted task. Opt-in: set POCKET_WORKER_USER (and optionally POCKET_WORKER_CLAUDE_CONFIG_DIR to point the worker at a readable Claude config). Default unset = unchanged behaviour. --dangerously-skip-permissions is retained (required for unattended --bg workers) but is now bounded by the worker user's FS/network grants rather than running with the executor's full access.

claude-ops v2.11.8

29 May 14:35

Choose a tag to compare

Security

  • Account-rotation config: stop tracking config.json; readers prefer the gitignored override. rotate.mjs and kapture-claim-credits.mjs now resolve the rotation config from $CLAUDE_PLUGIN_DATA_DIR/account-rotation-config.json (where setup-account.mjs already writes real accounts), falling back to a local gitignored config.json and then the shipped empty config.example.json. config.json is git rm --cached'd so real emails can never land in a tracked file (it was already in .gitignore but remained tracked). No data was ever leaked to the remote — the committed config.json was always the empty default; this closes the accidental-commit footgun.

claude-ops v2.11.7

29 May 13:25

Choose a tag to compare

Added

  • WhatsApp bridge: Linux (systemd-user) install path. scripts/install-whatsapp-bridge-linux.sh clones lharries/whatsapp-mcp, applies the in-repo claude-ops patches (scripts/whatsapp/apply-patches.py), drops three systemd-user units (whatsapp-bridge.service, whatsapp-backfill.service, whatsapp-backfill.timer), and pairs via the bridge's pairing-code flow. Idempotent — re-running is safe and only applies missing patches.
  • POST /api/backfill REST endpoint on the bridge (patch). Lets the claude-ops daemon, a 2h systemd timer, or curl trigger a fresh history backfill without restarting the bridge. Returns {"success":true,"message":"backfill requested"} when connected; 503 otherwise.
  • Auto-backfill on events.Connected (patch). Every reconnect fires requestHistorySync 5s after Connected — replaces the previous "manual backfill only" behaviour. Idempotent; whatsmeow dedups by message ID.
  • Cross-platform whatsapp-bridge daemon entry in scripts/daemon-services.default.json via scripts/lib/whatsapp-bridge-up.sh wrapper that branches launchctl (macOS) / systemctl --user (Linux). Replaces the previous launchctl-only command.
  • whatsapp-backfill daemon entry (cron 0 */2 * * *) — fallback trigger for hosts without the systemd timer.
  • Python MCP server (whatsapp.py) LID/contact resolver (patch). get_sender_name now resolves via whatsmeow_contacts.full_name/push_name/business_name and whatsmeow_lid_map from the bridge's whatsapp.db, instead of relying on the macOS-only contacts table populated by Contacts.app. Group senders in @lid form now resolve to their real names on Linux.

Fixed

  • PairPhone silent hang in lharries/whatsapp-mcp (patch). Two fixes per the upstream whatsmeow godoc: (Fix A) time.Sleep(3 * time.Second) between client.Connect() and client.PairPhone(...) so the noise handshake completes; (Fix B) context.WithTimeout(..., 3*time.Minute) on PairPhone so an internal hang is recoverable instead of leaving the process zombied with no PairSuccess and no Timeout error.
  • requestHistorySync SIGSEGV (patch). whatsmeow's BuildHistorySyncRequest(nil, count) panics because it dereferences .Chat/.ID/.Timestamp on the nil first arg (send.go:572). Rewritten to open messages.db read-only, pick the 50 most-recently-active chats, and anchor against each chat's oldest stored message — also more efficient than a global request.

Changed

  • /ops-inbox multi-channel scan is now a parallel Workflow fan-out — the scan/classify phase spawns one read-only scanner agent per available channel concurrently (via the Workflow tool), each returning structured classified results (NEEDS_REPLY / WAITING / HANDLED / FYI + the chatId needed to reply), then a synthesizer merges them into prioritized buckets. Wall-clock collapses from sum-of-channels to slowest-single-channel. Rule 6 is preserved end-to-end: scanners are explicitly read-only (never send/archive/mutate) and all reply drafting, approval, and sending stay in the main session under the one-draft→one-approval→one-send gate; channels are availability-detected first so no scanner is spawned for an unconfigured channel. Agent Teams and sequential scan are retained as documented fallbacks for older harnesses under the same constraints.