Skip to content

v2.2.13

Choose a tag to compare

@github-actions github-actions released this 28 Jul 07:49
e5fbe23
  • Merge pull request #291 from ObjectiveAI/2-2-13
  • fix(release): pin npm and node together so the js publish stops breaking
  • chore(sdk-py): regen for the development tier and mcp.development
  • chore(sdk-go): regen for the development tier and mcp.development
  • chore(sdk-js): regen for the development tier and mcp.development
  • chore(json-schema): regen for the development tier and mcp.development
  • fix(sdk): drop the hoisted variant titles on the development tiers
  • docs(plugin-scaffold): ship a plugin-development skill
  • docs(plugin-scaffold): lead with development mode, declare its caches
  • feat(daemon): development plugin registry and local-host pinning
  • feat(sdk): development plugins mcp command tier
  • feat(laboratory): build a plugin image from a registered directory
  • fix(plugin-scaffold): one subscribe, and let the daemon keep the clock
  • feat(plugin-scaffold): ask a person for a credential over a channel
  • feat(plugin-scaffold): a note written to the database and read back
  • fix(plugin-scaffold): read the switch argument as a strict boolean
  • feat(plugin-scaffold): an argument-gated tool that switches a second on
  • feat(plugin-scaffold): whoami drives the CLI and returns structured JSON
  • refactor(plugin-scaffold): name the example tools to be undeployable
  • fix(plugin-scaffold): the manifest is what a naked plugin needs
  • style(plugin-scaffold): spell the framework out, no oai alias
  • feat(plugin-scaffold): a copyable Rust plugin starting point
  • feat(plugin-framework)!: a plugin declares its own identity
  • feat(plugin-framework): run CLI commands from inside a plugin
  • refactor(plugin-framework)!: drop the Arguments alias
  • refactor(plugin-framework)!: drop the Outcome alias
  • fix(plugin-framework): a caller arriving after a failure starts over
  • feat(plugin-framework)!: connect once, share the attempt, retry on failure
  • feat(plugin-framework)!: swap the tool set while serving, without a lock
  • refactor(plugin-framework)!: serve exposes exactly one item
  • feat(plugin-framework): serve — the one call an importer never returns from
  • feat(plugin-framework): a tool router a plugin can change while serving
  • chore(db): raise the server connection ceiling to 1024
  • feat(plugin-framework): default the pool ceiling to 1024
  • feat(plugin-framework): db::connect hands a plugin its database
  • refactor(plugin-framework)!: Arguments values are any JSON
  • feat(agent)!: plugin arguments are any JSON, canonicalized deeply
  • refactor(plugin-framework)!: three accessors, no Environment struct
  • refactor(plugin-framework)!: Environment::read is private
  • feat(plugin-framework): read the ambient identity once, from the env
  • feat(laboratory): plugin containers get OBJECTIVEAI_ARGUMENTS
  • feat(plugin-framework): depend on rmcp and schemars
  • ci(release): publish the plugin framework to crates.io
  • chore(version): the plugin framework bumps with everything else
  • feat(plugin-framework): scaffold objectiveai-mcp-plugin-framework
  • chore: drop the viewer-plugin-builder reference Containerfile
  • fix(viewer): a dock no longer parks focus in the CEF window
  • refactor(viewer)!: the chrome is two band webviews, not one document
  • feat(viewer): closing a browser tab is instant
  • fix(viewer): a browser tab is not painted over by the chrome
  • feat(viewer): a browser tab reports what its navigation did
  • fix(viewer): browser tabs composite in software, and log by tab title
  • feat(viewer): CEF diagnostics reach the viewer log inbox
  • fix(viewer): a docked browser tab gets keyboard focus too
  • fix(viewer): a browser spawn never blocks the reconciler
  • feat(viewer): browser tabs — a real Chromium surface in the strip
  • refactor(viewer)!: a tab kind is common fields plus a surface
  • feat(viewer): a tab can close the tabs it spawned, by key
  • feat(viewer): tabs message the tabs they spawn
  • fix(laboratory): build chunks ride the binary frame
  • chore(sdk-js): rebuild the dist bundle
  • chore(sdk): regen the plugin manifest bindings
  • chore(sdk): regen the channel-log wire types
  • feat(plugins)!: the manifest splits into optional mcp and viewer halves
  • feat(plugins): tabs declare their stylesheets, the shell injects them
  • fix(laboratory): the export container survives a CMD-less image
  • feat(plugins)!: viewer builds move to the plugin's own Containerfile
  • feat(channels)!: the offer seeds the log as the publish item
  • fix(viewer): the strip scroller rechecks overflow on window resizes
  • feat(viewer): the strip grows Firefox-style overflow chevrons
  • style(viewer): inventory rows stack identity over title like the strip
  • feat(viewer): plugin:// serves installed bundles; import map shares host React
  • fix(daemon)!: the channels identity column follows the rename
  • feat(viewer): the offer tab installs — status-driven verbs
  • refactor(viewer): the model is the only offer registry
  • refactor(viewer)!: the handler tab owns its channel secret
  • docs(viewer): viewer-transport comment follows the client rename
  • refactor(viewer): JS onto daemon.Client.viewer
  • feat(viewer)!: installs download the daemon-built bundle
  • refactor(viewer)!: the shell rides daemon::Client
  • refactor(sdk)!: daemon Client request/open_sse go public; cli-listener alias dies
  • feat(sdk-js)!: the daemon module — dual-mode Client (+ go/py re-key regen)
  • feat(sdk)!: the unified daemon client module
  • refactor(sdk)!: AgentArguments becomes the root-level Identity
  • chore(sdk): per-language baseline regen — drain the pending pile
  • chore(json-schema): baseline regen — the pending channels/manifest pile
  • feat(daemon): GET /plugins/{owner}/{name}/{version}/viewer — streamed extension builds
  • fix(laboratory): temp migration sweeps only uuid leftovers
  • feat(viewer): the plugins tab
  • feat(viewer): uninstall — unload, delete, prune, rescan
  • feat(viewer): the install pipeline + runtime rescan
  • fix(viewer): version dirs are the v-prefixed git tag, byte-for-byte
  • feat(viewer): PluginsDirs + plugins_list + the temp/viewer boot sweep
  • refactor(laboratory): consume the SDK gitrepo; temp/daemon split
  • feat(sdk): the gitrepo module — shared single-tag plugin checkouts
  • fix(viewer): regular plugin tabs dedup on (module, export)
  • fix(viewer): regular plugin tabs are never deduplicated
  • fix(viewer): plugin tab identity is (module, export)
  • feat(plugins): manifest declares the viewer JS root
  • feat(plugins)!: ONE flat manifest schema for the whole objectiveai.json
  • feat(plugins)!: ViewerTab is an enum — channel_key XOR title
  • feat(plugins)!: one tabs ARRAY; channel handlers are tabs with channel_key
  • refactor(api): pipeline MCP re-dials across backoff rounds
  • fix(laboratory): local plugin fetches go full-depth
  • fix(api): re-dial MCP proxy connects across backoff rounds
  • feat(viewer): the accept flow — POST, spawn the handler tab, stamp its secret
  • feat(plugins): manifest channels — key-matched channel-handler components
  • feat(channels)!: flatten the offer identity
  • docs(sdk-js): signature header is fetch-mode only for channels
  • feat(sdk-js): accept returns the secret; channel stream retired
  • feat(channels)!: bare POST accept returns the secret; explicit channels close; per-channel stream retired
  • test(sdk-js): unstale the executor POST test
  • feat(sdk-js): channel accept/observe open the per-channel stream
  • feat(channels)!: the accept IS the channel stream; connection secrets retired
  • style(viewer): pointer cursor + border hover on channel-request buttons
  • feat(viewer): channel requests open as regular tabs, auto-swapped
  • refactor(viewer): drop the capture rate limiter
  • fix(viewer): pre-optimize the channel-request tab's dynamic deps
  • feat(viewer): the channel-request window
  • fix(viewer): break the log-capture feedback storm
  • feat(viewer): response badge on command-log response items
  • feat(viewer): command-log items use the shared JSON formatter; request rides first
  • fix(laboratory): keep the local-source path native off Windows
  • feat(laboratory): local-first plugin source for tag fetches
  • feat(sdk-js): regen + fix broadcast listener task drift
  • chore(sdk-py): regen — channels publish message + pending 2-2-13 wire
  • chore(sdk-go): regen — channels publish message + pending 2-2-13 wire
  • chore(json-schema): regen — channels publish message + pending 2-2-13 wire
  • feat(channels)!: required message on channels publish (≤512 chars)
  • fix(viewer): post-dock first click works — focus parks in the active webview
  • fix(viewer): post-drag click suppression can no longer go stale
  • fix(viewer): strip jitter — tabs now FIT the 40px band; reveal is horizontal-only
  • fix(viewer): strip detach detection reads RAW pointer coords
  • refactor(viewer): tab strip drag on dnd-kit, horizontal-locked
  • fix(viewer): tabs pane drag locked to the vertical axis
  • refactor(viewer): tabs pane drag on dnd-kit
  • feat(viewer): persisted tab ordering + user-controlled mode
  • perf(viewer): toggle persists and applies in parallel
  • fix(viewer): toggle-on appends quietly — no tab switch
  • feat(viewer): the tabs tab — inventory, persisted toggles, boot orchestrator
  • fix(viewer): resize relayout is size-only, inline — the lag is gone
  • fix(viewer): resize relayout takes parked-ness from the MODEL
  • style(viewer): plugin identity as owner/name/version — slashes throughout
  • feat(viewer): plugin identity displays as owner/name@version
  • fix(viewer): park background tabs offscreen instead of hiding them
  • fix(viewer): parallel home-tab seeding; full-bleed window icons
  • feat(viewer): the plugin loader — boot-scan bin/plugins, open declared tabs
  • feat(sdk): the installed-plugin manifest — typed slice with viewer section
  • feat(viewer): IdentityIcon forces uniform icon sizing
  • fix(viewer): crop the strip icon to its glyphs
  • style(viewer): strip icon via plain w/h-3.5
  • style(viewer): strip icon up to text-base
  • style(viewer): white strip icon for objectiveai; icon sized to text-sm
  • feat(viewer): identity icons choose their colors — or inherit
  • style(viewer): tab identity at text-xs, tab name at text-sm
  • feat(viewer): optional per-identity tab icons, left of the identity
  • style(viewer): tab identity one derived step below text-xs
  • style(viewer): tab identity at text-xs
  • style(viewer): tab identity a touch bigger, a touch more breathing room
  • feat(viewer)!: identity-scoped component tabs — Rust knows no tab names
  • chore(sdk-js): rebuild dist (tsup) — picks up openViewerTab
  • feat(sdk-js): openViewerTab — the viewer shell's tab-open helper
  • fix(viewer): show the full machine id on laboratory cards
  • feat(viewer): bottom-tethered scrolling for all three log panes
  • feat(viewer): JsonBlock renders \t escapes in strings as 4 spaces
  • feat(viewer): JsonBlock renders \n escapes in strings as real breaks
  • fix(viewer): inline agent definition renders via the shared JsonBlock
  • fix(viewer): inline agent JSON can't widen the agent box — wraps to it
  • feat(viewer): command-logs — the /listen broadcast captured to disk, per-request drill-down
  • feat(viewer)!: logs live in a per-run logfile — Rust streams, JS rings
  • fix(viewer): friendlier log sources — viewer-container + viewer-logs
  • fix(viewer): logs in plain flow — top-aligned, top-scrolled, oldest first
  • chore: drop clap from the viewer's lockfile entry
  • refactor(viewer)!: drop the --agent-instance-hierarchy debug window
  • fix(viewer): logs read oldest-first, pinned to the bottom
  • feat(viewer): the viewer-logs home tab — zero-cooperation capture from every webview
  • feat(viewer)!: no main window — every window is an equal shell (#284)
  • refactor(viewer): shell polish — ground background_color, drop dead Shell.tsx
  • refactor(viewer)!: one child webview per tab — lossless pop-out/pop-in (#284)
  • refactor(viewer): dormant content entry for per-tab webviews (#284)
  • refactor(viewer): remove the error toast + command palette
  • feat(tasks): tasks delete namespace override (--no-plugin / explicit trio)
  • refactor(tasks): user-chosen namespaced ids; plugin_name rename; consolidate schemas
  • refactor(tasks): drop the unschedulable-command guardrail
  • feat(daemon): the tasks system — durable scheduled commands (#283)
  • feat(sdk): tasks command tier + the task identity component
  • feat(channels): allow optional plugin identity on Reply log entries
  • feat(channels)!: require a plugin on the publisher side; split the log entry by direction
  • feat(viewer): unified draggable tab system — everything is a tab
  • refactor(viewer): remove the plugin surface entirely — no such feature
  • fix(viewer): stub retired plugins-list discovery — unbreak the build
  • chore(sdk-py): regenerate bindings + tests for the 2.2.13 wire
  • chore(sdk-go): regenerate bindings for the 2.2.13 wire
  • chore(sdk-js): regenerate bindings for the 2.2.13 wire
  • chore(json-schema): regenerate for the 2.2.13 wire
  • refactor!: declarative dial list — SetAddresses converge; drop legacy sweep
  • refactor: lifecycle task owns resident children; one unified kill
  • fix: readiness death-watch busy-spin + host pipe-inheritance leak
  • refactor: event-driven laboratories spawn readiness — no polling
  • refactor: drop the laboratories spawn/kill timeouts — no premature caps
  • feat: explicit laboratory host — spawn/kill commands, no auto-spawn
  • perf: run host-pick and plugin DB-credential resolution concurrently
  • fix: daemon must register the pg stream before dialing (dropped startup bytes + leak)
  • refactor: extract the base objectiveai schema to schema.sql
  • feat: per-plugin Postgres tunneled over the /laboratory WebSocket
  • feat: raw TCP Postgres proxy on a random daemon port
  • revert: /mcp auth is X-OBJECTIVEAI-SIGNATURE only
  • feat: /mcp accepts the signature via the standard Authorization header
  • chore: delete the retired objectiveai-mcp crate
  • feat!: the daemon IS the MCP server — standalone objectiveai-mcp retired
  • feat!: no more base64 — transfer chunks ride raw-bytes binary WS frames on both hops
  • perf: one-chunk prefetch in the cross-host transfer splice
  • chore: lab_mcp_client retry budget 600s -> 60s (canonical default)
  • feat: no deadlines on laboratory work — forwards and container MCP calls wait forever
  • fix: close the session half of the channel-death insert race
  • fix: displaced /laboratory connections are killed, not abandoned
  • feat: TCP keepalive (15s/15s/3) on every server accept and WS dial
  • fix: lock ephemeral container lifecycle to its use (findings 2, 3, 4)
  • feat!: remove the daemon's in-process objectiveai-mcp — agents are plugin-only
  • chore: drop the FINDINGS.md gitignore negation
  • chore: un-ignore FINDINGS.md so it shows as untracked (never committed)
  • fix: rename OBJECTIVEAI_PLUGIN_REPOSITORY env var to OBJECTIVEAI_PLUGIN_NAME
  • feat: stamp full identity env on ephemeral containers; reserve the names
  • feat!: daemon routes plugins/agent labs to laboratory hosts; daemon compiles fully
  • feat!: ephemeral agent/plugin laboratories (host + SDK; daemon phase next)
  • feat!: plugin version must be v-prefixed (Go modules exactly); no prepend anywhere
  • feat: plugin laboratories on the laboratory host (host + SDK; daemon dormant)
  • feat: host-initiated CLI command exchange on the /laboratory WS
  • feat!: remove plugins command tree; new agent.Plugin shape (one plugin = one MCP server)
  • refactor!: synthetic client-side MCP URL scheme ws:// -> client://
  • feat!: X-MCP-Plugins marker + proxy->daemon Command streaming
  • feat(sdk-rs): Ack opener frame in the command-response exchange
  • feat(sdk-rs): Last-Event-ID resume in the MCP SSE listener
  • feat(sdk-rs): parallel notification handling in the MCP SSE listener
  • feat(sdk-rs): MCP connection command-execution extension (client side)
  • feat(sdk-rs,mcp-proxy)!: strongly typed MCP JSON-RPC layer
  • feat(sdk-rs): make cli and mcp features mutually inclusive
  • feat(sdk-rs)!: typed Request in McpClientCommandExecutor; mcp feature requires cli
  • refactor(sdk-rs): rename command_execution.rs -> mcp_command_executor.rs
  • refactor(sdk-rs): rename to McpCommandExecutor / UnimplementedMcpCommandExecutor
  • feat(sdk-rs): mcp CommandExecution trait + UnimplementedCommandExecution
  • chore: drop tools from workspace members + build/test scripts
  • feat!: remove the CLI tools feature — plugins only (#272)
  • chore: remove tools test fixtures, e2e, assets, scripts
  • chore(sdk-py): regenerate bindings for channels
  • chore(sdk-go): regenerate bindings for channels
  • chore(sdk-js): regenerate bindings for channels
  • chore(json-schema): regenerate for channels
  • fix(channels): open.rs builds flat identity fields (to_identity was removed)
  • refactor(channels): inline sender + plugin on log entries; MessageKind Go fix
  • feat(sdk-js): ChannelListener replaces UserListener
  • feat(channels)!: retire user requests — channels replaces it (Phase 6)
  • feat(channels): daemon command handlers (Phase 5)
  • feat(channels): SDK command tier (Phase 4)
  • feat(channels): Postgres storage + ChannelHub + routes (Phases 2-3)
  • feat(channels): channel_listener SDK module (Phase 1)
  • feat(user)!: drop the --validate-python reply validator from user requests
  • chore: bump version to 2.2.13