Releases
v2.2.13
Compare
Sorry, something went wrong.
No results found
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
You can’t perform that action at this time.