54 Commits
Author SHA1 Message Date
zeekay a158e0165c release(hanzo-tools-browser): 0.5.10 — zapd connect-or-spawn auto-start 2026-07-08 08:50:48 -07:00
zeekayandGitHub 2d964c305d feat(browser): auto-start zapd when absent (connect-or-spawn) (#47)
The browser MCP tool no longer requires a human to have started zapd.
ZapdConsumer.connect() now dials the router and, on failure, auto-starts
the shared singleton (locate the zapd binary, spawn it detached, wait for
the socket) then dials once more — mirroring zapd's own host-mode
connect-or-spawn. No consumer-side lock: the singleton invariant lives in
zapd (advisory-lock bind), so concurrent spawns are safe. The OS unit is
the primary starter; this is the bare-machine fallback so the tool just
works.
2026-07-08 08:49:21 -07:00
zeekay 4991923b67 fix(browser): route MCP register through _result_to_mcp — ToolImage→ImageContent
The browser tool's bespoke register() returned execute()'s dict RAW, so FastMCP
flat-JSON-serialized a screenshot's ToolImage (base64 inline, 250K chars) →
overflowed the agent context and wedged the run — the SAME bug main's
ImageContent converter (711eb498) fixed for every OTHER tool via
BaseTool.register→_result_to_mcp, but the browser tool bypassed that path.
Now both registration paths share the one converter: nested ToolImage anywhere
in the result becomes a native MCP ImageContent block the client SEES. One way.
2026-07-05 04:29:07 -07:00
zeekay 9155b4ccf3 Merge branch 'chore/ui-rag-v1-paths'
# Conflicts:
#	pkg/hanzo-tools-browser/hanzo_tools/browser/browser_tool.py
2026-07-04 13:59:42 -07:00
zeekay af29483757 fix(browser): screenshots/pdf save-to-disk + return path, never inline huge base64
A full-page PNG returned as inline base64 (100K+ chars) overflows an agent's
context window and wedges the whole run — the #1 cause of 'the browser tool
hangs' (two mobile-QA agents died on 6.6MB transcripts). Both capture paths
(native-zap _extension_command + the playwright fallback) now persist to
~/.hanzo/screenshots (or a caller path) and return a compact {path,size};
base64 is inlined ONLY for a small PNG (<=40KB). Adds _save_capture + _extract_b64.
2026-07-04 12:33:52 -07:00
zeekayandHanzo Dev d70222ccce browser/zapd_consumer: self-heal a dead cached socket
connect() trusted a cached ZapClient forever; if the router restarted, every
call raised BrokenPipeError and the consumer stayed wedged. list_providers/route
now drop the dead client and reconnect once.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-03 12:31:09 -07:00
zeekay 85bf05c796 feat(mcp): native MCP ImageContent — tools return images the client can SEE
HIP-0300 tools serialize results to JSON text, which flattened images into
useless base64-in-text. Add a ToolImage value type + one converter in
BaseTool.register: any ToolImage anywhere in a result becomes a real
mcp.types.ImageContent block; text-only results stay byte-for-byte JSON.
Emitters wired: fs read of image files, browser screenshots (bidi+playwright).
This gives hanzo-mcp vision parity with zai-mcp — an agent with native vision
(Claude) sees pixels directly, no per-task vision tool needed.

Also decomplect the core-package collision that caused this class of bug:
hanzo-tools-core shipped a DUPLICATE hanzo_tools/core/ that nondeterministically
shadowed canonical hanzo-tools (dropping ToolImage, the sophisticated register,
etc. — same shadow class as the 0.3.0 error-reexport gap). Finish the
'merge core into hanzo-tools' refactor: move id_tool into hanzo-tools, make
hanzo-tools-core a pure empty metapackage. Now ONE package owns hanzo_tools.core.

Versions: hanzo-tools 0.3.2, -core 0.3.1 (shim), -browser 0.5.9, -fs 0.3.4,
hanzo-mcp 0.15.12 (floors bumped). Verified: fs read PNG -> [text, image];
fs stat -> [text]; 29 tools intact; 9 tests pass.
2026-07-03 00:45:49 -07:00
zeekay ce23c4e4ad refactor(zap): consume canonical zap-proto, drop hand-rolled wire
hanzo-tools-browser: the zapd router envelope (frame.rs mirror) is no
longer reimplemented — zapd_consumer now uses zap.frame + zap.ZapClient
(dep zap-proto>=1.2.0). The end-to-end browser command codec stays local
and untagged to match the extension's decodeCmd (frame.encode_cmd is
tagged and would corrupt it); a new test proves the byte layout.

hanzo-zap: wire.py now delegates the zero-copy codec (Message/Builder/
ObjectBuilder/object readers) to canonical zap.wire instead of a 3rd
hand-rolled copy; the hanzo cloud-service schema + handshake + frame I/O
remain as a thin layer. dep zap-proto>=1.2.0. 114 tests pass.
2026-06-21 01:29:06 -07:00
zeekay 418fda81b2 feat(browser): route Firefox actions through BiDi fast-path
When the firefox backend is targeted and Firefox exposes a WebDriver BiDi remote agent (--remote-debugging-port=9222), drive it directly via bidi_client (real navigation + trusted input) instead of the half-implemented extension path or a dead headless Playwright. Additive + gated: only fires for target firefox with live BiDi and a BiDi-mapped action; otherwise falls through to the existing extension/Playwright routing unchanged. Takes effect after the MCP server reloads.
2026-06-20 13:04:39 -07:00
zeekay 6503f017a6 fix(browser/bidi): drive Firefox 153 (BiDi-only) seamlessly
Firefox 129+ runs WebDriver BiDi-only by default (CDP off), so /json/version 404s and the socket is served directly at /session. Four fixes make the BiDi client actually work against it:

- probe(): fall back to a TCP check + ws://host:port/session when /json/version isn't advertised (don't open a probe WebSocket — that establishes session state and conflicts with session.new).

- websockets>=13 compat: ClientConnection dropped .closed; _ws_open() reads .state/.close_code across versions.

- session lifecycle: session.end on close() so a session never orphans (Firefox keeps one at a time, and an orphan blocks every later session.new); retry session.new once after ending.

- add create_context/close_context/get_url so automation runs in a fresh tab without disturbing the user's tabs.
2026-06-20 13:04:39 -07:00
248e5e0ea9 fix(browser-mcp): migrate CDP bridge → zapd consumer; disk authoritative (#35)
* fix(browser-mcp): migrate CDP bridge -> zapd consumer; make disk authoritative

The MCP runtime kept pulling the buggy published wheel (hanzo-tools-browser
0.5.7) from PyPI instead of the migrated on-disk source, so every restart
re-broke the `cdp` tool. Reinstate `cdp` as a zapd-native tool, finish the
bridge->zapd migration (delete dead bridge/server modules + their tests), bump
to 0.5.8 and pin hanzo-mcp >=0.5.8, add the package to the uv workspace/sources
so disk is authoritative. 9/9 browser tests pass.

Pairs with the hanzoai/extension bridge->zapd migration (separate, still
uncommitted). The ~/.claude.json MCP invocation was also pointed at the local
editable source (machine config, not in this repo).

(cherry picked from commit 11b4d4ea8a5570d6fb0e51079fa445dba3713f71)

* fix(browser): drop dead lifecycle.py (in-process zap_server/cdp_bridge are gone)

lifecycle.py only wrapped the removed in-process ZAP server + CDP bridge; nothing
imports it under the zapd-consumer model. One way: transport is zapd_consumer,
tools are browser/cdp/playwright.

---------

Co-authored-by: hanzo-dev <[email protected]>

Co-authored-by: Antje Worring <[email protected]>

Co-authored-by: Hanzo Dev <[email protected]>
2026-06-16 22:12:07 -07:00
zeekay b025d1e9b7 corona→corona: academic Corona now only in lp-220-p3q-corona 2026-06-11 10:26:04 -07:00
zeekay f6b516dbb8 hanzo-tools-browser: scaffold WebDriver BiDi client (v1.10.0 foundation)
Adds bidi_client.py — a WebDriver BiDi client over WebSocket to
Firefox 129+ / Chrome 124+ at --remote-debugging-port=9222.

This is the "trusted input" backend that complements the existing
WebExtension scripting backend (the cdp_bridge_server WS to the
extension). The extension produces synthetic events with
isTrusted=false, which strict frameworks (Drupal AJAX, certain React
libraries, security-aware sites) reject. BiDi via input.performActions
produces real browser input with isTrusted=true that ALL frameworks
honor because they ARE the real browser events.

Methods implemented:
  - probe()                    auto-detect at /json/version
  - connect() / close()        WebSocket session lifecycle
  - list_contexts()            browsingContext.getTree
  - find_context_by_url()      locate tab by URL substring
  - navigate(ctx, url)         browsingContext.navigate
  - capture_screenshot(ctx)    browsingContext.captureScreenshot
  - script_evaluate(ctx, js)   script.evaluate in page context
  - input_mouse_click(ctx,x,y) input.performActions — TRUSTED click
  - input_double_click         double-click composite
  - input_key_press            input.performActions key
  - input_insert_text          trusted keyboard typing
  - click_selector(ctx, sel)   composite: eval rect + trusted click

Architecture: decomplected, three layers. Layer 1 = wire transport
(WebSocket JSON-RPC). Layer 2 = canonical primitives
(input.performActions / browsingContext.* / script.evaluate). Layer 3
= ergonomic aliases (click_selector composite).

Integration into cdp_bridge_server.py — auto-detect on startup, route
BiDi.* methods, optionally route Input.dispatchMouseEvent and
hanzo.click to BiDi backend when available — is the next step.

To enable BiDi in a Firefox session:
  open -a "Firefox Developer Edition" --args --remote-debugging-port=9222
The bridge will probe http://localhost:9222/json/version on startup;
if BiDi is available it advertises BiDi.* in its capabilities.
2026-06-10 13:20:10 -07:00
zeekay aec6638a69 hanzo-tools-browser 0.5.7: fix CdpTool — implement register() (0.5.6 was DOA)
0.5.6 shipped CdpTool inheriting BaseTool but missing the required
`register()` abstract method, so any host that registered the tool
crashed with `TypeError: Can't instantiate abstract class CdpTool`.
The browser package never reached MCP startup, taking the whole hanzo
MCP server with it.

This commit adds CdpTool.register() with the cdp-specific param surface
(action / method / params / tab_id / target_browser / client_id / timeout)
matching the BrowserTool registration pattern.

Yanking 0.5.6 from PyPI alongside this release; 0.5.7 is the canonical
0.5.x for the three-tool surface.
2026-06-10 10:24:33 -07:00
zeekay a1022c257e hanzo-tools-browser 0.5.6: three orthogonal tools (browser / cdp / playwright)
Decomplects the browser surface. Previously: BrowserTool with three
braided transports (ZAP, CDP bridge, Playwright) plus a CdpTool alias
that was just a name change. Now: three peer tools, one transport
strategy each, env-gated registration.

Tools (each default-on, each disable-able):
- `browser`    — high-level action surface, auto-routes transport.
                 Disable: HANZO_BROWSER_TOOL_DISABLED=1
- `cdp`        — raw Chrome DevTools Protocol method dispatch
                 (`method=`, `params=`). No Playwright fallback.
                 Disable: HANZO_CDP_TOOL_DISABLED=1
- `playwright` — same action surface as `browser` but pinned to
                 backend=playwright (no extension / CDP-bridge).
                 Disable: HANZO_PLAYWRIGHT_TOOL_DISABLED=1

Transport knobs stay orthogonal to tool selection:
- HANZO_ZAP_DISABLED=1        — don't auto-start the in-process ZAP server
- HANZO_CDP_BRIDGE_ENABLED=1  — opt back into the legacy HTTP bridge
- BROWSER_TRANSPORT=zap|http|auto
- BROWSER_BACKEND=firefox|chrome|extension|playwright|auto

Lifecycle (ZAP server + CDP bridge background threads) moved out of
__init__.py into lifecycle.py. __init__.py is now a pure re-export
surface that resolves TOOLS at import time based on env flags.

CdpTool is now a genuine peer of BrowserTool — method-oriented, not
action-oriented — replacing the alias-subclass from 0.5.5.
2026-06-10 08:41:13 -07:00
zeekay a20bb00177 hanzo-tools-browser 0.5.5: surface CdpTool alias under cdp name
Adds CdpTool — a subclass of BrowserTool with `name = "cdp"` — so MCP
clients can reach the same browser control surface under both
`mcp__hanzo__browser` and `mcp__hanzo__cdp`. One implementation
(BrowserTool.execute is shared), two registered names. ZAP server,
CDP-bridge fallback, and Playwright transport stack are all shared.
2026-06-10 08:12:58 -07:00
zooqueenandHanzo Dev 2c26efdb84 hanzo-tools-browser: vendor ZAP wire constants, advertise on bind host
Two fixes for the canonical ZAP server:

1. Vendor the wire format (ZAP_MAGIC, MSG_*, MAX_MESSAGE_SIZE,
   encode/decode) inside hanzo_tools/browser/zap_server.py instead of
   importing from the external ``zap.protocol`` module — the published
   ``zap-protocol`` package on PyPI is now a ``zap-schema`` stub that
   doesn't expose those symbols, so the import chain breaks for any
   fresh install. Inlining ~40 lines keeps the spec self-contained and
   matches the TS reference at extension/packages/browser/src/shared/zap.ts.

2. Pass ``host=self.host`` to ``zap_mdns.publish`` so the advertised
   address matches the bound address. Default behaviour advertised the
   outbound LAN IP via ``_local_ip()`` while the WebSocket was bound to
   127.0.0.1; clients dialled the LAN IP and got ECONNREFUSED.

Drops the broken ``zap-protocol>=0.2.1`` dependency from both
hanzo-mcp and hanzo-tools-browser pyprojects — no longer needed.

Co-authored-by: Hanzo Dev <[email protected]>
2026-05-18 22:24:47 -07:00
zeekay 2ecbd28aa5 style: black --target-version py312 (CI format-check fix)
No semantic changes — pure black reformat across the four files touched
in 55b55146 (hanzo-mcp 0.15.3 + hanzo-tools-browser 0.5.4).
2026-05-10 17:22:07 -07:00
zeekay c1da01a98b hanzo-mcp 0.15.3 + hanzo-tools-browser 0.5.4: ZAP TextContent normalization, mDNS-only discovery
hanzo-mcp (0.15.1 -> 0.15.3):
- _normalize_mcp_result() collapses FastMCP list[TextContent] to parsed JSON
  for ZAP MSG_RESPONSE serialization
- Closes the "TextContent not JSON serializable" bug surfaced when driving
  the Hanzo extension from agent via tools/call
- Bump hanzo-tools-browser[playwright] floor to 0.5.4

hanzo-tools-browser (0.5.2 -> 0.5.4):
- mDNS-only ZAP discovery via _hanzo._tcp.local. (HIP-0069); no port pool,
  no lockfile, OS-assigned ports advertised by hanzo-zap-mdns
- zap_server.py: refactor for unique server_id + retract on stop
- Test suite trimmed to the new wire contract

Patch-bump both packages.
2026-05-10 17:17:13 -07:00
zeekay a3bc5f5bcf fix(hanzo-tools-browser): 0.5.2 — import wire format from zap-protocol
The custom encode/decode and message-type constants in zap_server.py
were a byte-identical duplicate of zap-protocol (~/work/zap/zap-py).
Drop the duplicates, import from canonical:

  from zap.protocol import (
      ZAP_MAGIC, HEADER_SIZE, MAX_MESSAGE_SIZE,
      MSG_HANDSHAKE, MSG_HANDSHAKE_OK,
      MSG_REQUEST, MSG_RESPONSE,
      MSG_PING, MSG_PONG,
      ZAP_PORTS as DEFAULT_ZAP_PORTS,
      encode, decode,
  )

Single source of truth for the wire — any change (MSG_STREAM, frame
versioning, future Cap'n Proto migration) lands once and propagates.

zap-protocol added as a dependency. Verified at install:
  ZAP encode unified: True
  ZAP decode unified: True
2026-05-09 14:48:36 -07:00
zeekay 65cb749fa6 feat(zap-server): auto-publish via hanzo-zap-mdns + retract on stop
Every ZapServer.start() now publishes its bound port + agent_label as a
`_hanzo-zap._tcp.local.` mDNS record (best-effort — silently skipped
when `hanzo-zap-mdns` isn't installed). Browser extensions and any
LAN-wide agent can discover the server via `hanzo_zap_mdns.browse()`
without hard-coded ports or fragile lockfile registries.

Publish runs on a worker thread (asyncio.to_thread) so zeroconf's
internal multicast-socket setup doesn't block our event loop and
trigger EventLoopBlocked on zeroconf >= 0.140.

stop() retracts the announcement before closing the WS.
2026-05-08 12:10:26 -07:00
zeekay 41bdfa3644 fix(zap-server): race-free client cleanup when client_id is reused
When an extension reuses its client_id across consecutive ZAP connections
(probe followed by connectZap, both with mgr.state.extensionId), the
older websocket's finally clause was unconditionally popping the
client_id from _clients — deleting the new connection's freshly-installed
registration. The extension would then immediately disconnect because the
server-side state no longer had it, hammering reconnect loops.

Now the finally clause only removes the entry when it still points at
the closing websocket. Verified end-to-end: Firefox 1.9.x ZAP-native
connection holds steady; tabs/screenshot/evaluate round-trip in
11/73/5 ms.
2026-05-08 09:54:12 -07:00
zeekay 90e6e4f0d9 feat(tools-browser): ZAP-native 2-process architecture (0.5.0)
Each hanzo-mcp now hosts a ZAP server directly on the lowest free port
from [9999..9995], using a POSIX flock for cross-MCP arbitration. The
browser extension discovers and connects to this server without any
node-side bridge in the critical path.

- New hanzo_tools/browser/zap_server.py: wire format, server, lifecycle,
  client registry, leases, cluster-visibility config registry.
- _extension_command tries ZAP first (sub-1ms median round-trip on
  loopback), falls back to legacy HTTP bridge on :9224 only when no
  ZAP-connected client matches. Pinnable via BROWSER_TRANSPORT.
- New tool actions: list_mcp_instances, claim_browser, release_browser
  for sub-agent coordination across multiple parallel MCPs.
- Legacy CDP HTTP bridge no longer auto-starts (opt in with
  HANZO_CDP_BRIDGE_ENABLED=1). It remains available for non-ZAP MCP
  clients.

Tests: 30 new unit tests cover wire format, port arbitration,
multi-MCP coexistence, lease semantics, and cluster registry.
Bench shows 0.35ms median round-trip on local loopback.

Total tests: 4 baseline -> 35 passing (30 zap_server + 1 bench + 4 imports).
2026-05-07 21:32:43 -07:00
zeekay 00b8c911ea feat(tools-browser): set_default_browser / use_browser actions for v1.9.0 bridge
The extension's bridge server (cdp-bridge-server.ts v1.9.0) added two
new actions for dynamic browser switching:

  set_default_browser — persist a default-target browser
  use_browser        — alias of set_default_browser

Both accept the browser name (firefox / chrome / safari / edge or a
specific instance ID like 'firefox-2') as the 'browser' field. The
bridge writes the choice to ~/.hanzo/extension/config.json so it
survives bridge restarts.

This commit:
- Adds the two action names to the Action Literal so the MCP tool
  accepts them.
- Adds them to extension_actions so they route through the bridge
  rather than falling to Playwright.
- The 'target_browser' parameter (already exposed) carries the
  browser name through to the bridge as 'browser', which is exactly
  what set_default_browser expects.

Bumps hanzo-tools-browser 0.4.5 → 0.4.6.
2026-05-07 21:07:22 -07:00
zeekay 9df3941de5 feat(tools-browser): add tab_id / client_id / target_browser params
Mirror the v1.8.3 extension bridge fix on the python side. The MCP
'browser' tool now exposes:

- tab_id — accepts the targetId returned by 'tabs' (e.g. "tab-1888868904")
  or a numeric tab id. Forwards as tabId so every action operates on the
  specified tab instead of the OS-active tab. Critical when the user has
  many windows open and the wrong one is in focus.
- client_id — pin to a specific connected extension instance (returned
  in 'status'). Use with 'list_browsers' to address one Chrome instance
  vs another Firefox instance bridged to the same hanzo bridge.
- target_browser — 'chrome' | 'firefox' per call. Per-call override of
  the global backend so a single MCP session can address Chrome and
  Firefox at different moments.

Also expose two action names that the bridge already supports:
  select_tab — bring a specific tab to focus (Target.activateTarget)
  list_browsers — enumerate every connected provider with details

The "tab-NNN" prefix from getTargets is automatically stripped and the
numeric id forwarded; the bridge's parseTabId() handles both formats.

Tested against extension v1.8.3 which lands the matching bridge changes.
2026-05-07 14:20:54 -07:00
zeekay c9e279855f fix(browser): unwrap CDP Runtime.evaluate results for consistency
The CDP bridge server now unwraps Runtime.evaluate results from the
nested CDP format {result: {type, value}} to just the value, matching
Playwright's evaluate return format.

Also bumps hanzo-tools-browser to 0.4.5 and hanzo-mcp to 0.12.9.
2026-03-10 10:38:31 -07:00
zeekay 5d03527549 bump: hanzo-tools-browser 0.4.4 2026-03-10 09:50:00 -07:00
zeekay 45674599f3 fix(browser): add missing action-to-method mappings in CDP bridge
url, title, reload, go_back, go_forward, tab_info were not mapped
to their hanzo.* / Page.* CDP equivalents, causing "Unknown method"
errors when routed through the extension.
2026-03-10 09:45:15 -07:00
zeekay 259d437061 fix: ruff lint errors across hanzo-tools-* packages (I001, F401, F541)
Fix 21 auto-fixable errors: import sorting (I001), unused import (F401),
and empty f-strings (F541) in 13 files across tool packages.
2026-03-06 23:44:10 -08:00
zeekay a10852c523 feat(browser): add wait_for_selector, query_selector_all to extension actions 2026-03-06 03:49:20 -08:00
zeekay 9ad7dba847 feat(browser): add navigation/fetch/history to extension actions 2026-03-06 03:43:55 -08:00
zeekay 833dbd715e fix(browser): fix extension result passthrough, add DOM actions
- Fix result normalization: non-dict values no longer crash with **spread
- Add 20+ DOM actions to extension_actions set (get/set HTML/text,
  attributes, styles, classes, mutations, localStorage, cookies, etc.)
- Bump hanzo-tools-browser 0.4.3, hanzo-mcp 0.12.6
2026-03-06 03:33:33 -08:00
zeekay c69a39146a bump: hanzo-tools-browser 0.4.2, hanzo-mcp 0.12.4
- browser: auto-start CDP bridge on BrowserTool init (extension-first routing)
- mcp: pin hanzo-tools-browser>=0.4.2
2026-03-06 00:55:37 -08:00
zeekay 237c801a7b fix(browser): auto-start CDP bridge on BrowserTool init
The CDP bridge server (ws://localhost:9223 + http://localhost:9224)
was never starting because the entrypoint loader instantiates
BrowserTool directly, bypassing the package-level register_tools()
which called start_cdp_bridge().

Now BrowserTool.__init__() auto-starts the bridge when backend is
not "playwright", ensuring the browser extension can connect and
be used as the preferred backend over headless Playwright.
2026-03-06 00:32:42 -08:00
zeekay d2c6d50557 feat(browser): configurable backend + fix CDP bridge for websockets >= 13
- Add BROWSER_BACKEND env var: firefox | chrome | extension | playwright | auto
- Config persists to ~/.hanzo/extension/config.json
- Fix CDP bridge WebSocket handler signature for websockets >= 13 (new API)
- Add browser-based client resolution in CDP bridge
- Add /config GET/POST endpoints for extension preference sync
- Backend-aware routing: explicit backends don't fall back to Playwright
2026-03-04 19:35:00 -08:00
zeekay e35be26f75 fix(test-hanzo-tools): align tool expectations and modernize websockets import 2026-03-04 12:52:05 -08:00
zeekay 8c05bf99d6 fix(ci): pin black <26.1 to avoid internal error, lower requires-python to 3.12
Black 26.1.0 crashes on multiple exception types in parentheses.
The requires-python bump to 3.14 broke CI which runs Python 3.12.
2026-03-01 16:01:16 -08:00
zeekay 6c376a4d13 [chore] bump all packages to Python 3.14+
Update requires-python to >=3.14 in all 46 pkg/ pyproject.toml files
and the root pyproject.toml (47 files total).
2026-02-28 12:43:10 -08:00
zeekay 4455f09a67 Update hanzo-mcp config and browser tool 2026-02-26 20:56:54 -08:00
zooqueenandHanzo Dev b144973bfc fix(lint): resolve all ruff + black errors across all packages
Fix 35 ruff errors (E722, F841, B904, B905, B007, E741, S202, S310,
S306, S110, TID251, UP042, F401) and run black on 526 files.

Co-authored-by: Hanzo Dev <[email protected]>
2026-02-21 23:32:32 -08:00
zooqueenandHanzo Dev 920f767417 style: auto-fix ruff lint and format for Python 3.12
Run ruff check --fix and ruff format across the repo to fix ~495
auto-fixable lint errors (mostly I001 import sorting) and reformat
225 files to match the py312 target.

Co-authored-by: Hanzo Dev <[email protected]>
2026-02-20 21:29:31 -08:00
zeekay 73fbba8141 feat: add hanzo-kms package, MCP proxy tools, and agent reflexion
- Add hanzo-kms v1.0.0: Secret management SDK compatible with Infisical API
  - Sync and async clients with multiple auth methods (Universal, AWS IAM, Azure, GCP, K8s)
  - Full CRUD operations for secrets with environment injection

- Add MCP proxy system for lazy-loading external MCP servers
  - mcp_proxy.py: Dynamic MCP server connection and tool discovery
  - proxy_tool.py: Tool for managing external MCP server proxies
  - platform_auth.py: Hanzo Platform authentication utilities
  - Built-in servers: platform, github, cloudflare, postgres, sqlite, docker, k8s

- Add agent reflexion module for self-correction and rule management
  - ReflexionEngine for reflection and rule-based behavior updates
  - Integration with hanzo-memory for persistent rules

- Add self_learning_agent example demonstrating reflexion capabilities

- Update ps_tool with improved process management and log handling
- Update browser tools with enhanced CDP bridge and automation
- Bump dependency versions across all tool packages

All tests pass (3156 passed)
2026-02-04 10:55:08 -08:00
zeekay 86c2cdcc0d feat: add new tool packages and install command
- Add hanzo-tools-code: code analysis and transformation tools
- Add hanzo-tools-net: network and HTTP tools
- Add hanzo-tools-plan: planning and task management tools
- Add hanzo-tools-test: testing tools
- Add hanzo-tools-vcs: version control tools
- Add install command for dependency management
- Improve CDP bridge server with better error handling
- Add ui_tool for computer tools
- Add unified tool loading and id_tool
- Add HIP documentation (HIP-0300, HIP-0301)
2026-01-24 13:21:16 -08:00
zeekay fd21a7d995 feat(browser): add CDP bridge server for extension integration
- Add cdp_bridge_server.py with WebSocket bridge
- CDPBridgeServer routes commands to browser extension
- CDPBridgeClient for programmatic browser control
- Export bridge classes from browser package
- Update vscode.md with extension integration docs
2026-01-05 18:46:13 -08:00
zeekay 6998188dea style: format test files with black 2025-12-27 15:00:11 -08:00
zeekay ec7eabd9fc test: add basic test suites for all 18 hanzo-tools-* packages 2025-12-27 14:57:15 -08:00
zeekay 058fffc218 docs: add READMEs for all 18 hanzo-tools-* packages 2025-12-27 14:55:13 -08:00
zeekay a9769ebb28 refactor: merge hanzo-tools-core into hanzo-tools
- hanzo-tools now contains core infrastructure (BaseTool, ToolRegistry, etc.)
- hanzo-tools-core becomes a thin backwards-compat wrapper
- All tool packages now depend on hanzo-tools>=0.3.0
- Reduces package count and simplifies dependency tree
2025-12-26 16:53:58 -08:00
zeekay 303a05a616 feat(agent): agentic proxy with agent integration
Enhanced agent tool architecture:
- 8 CLI agents: claude, codex, gemini, grok, qwen, vibe, code, dev
- Auto-detects agent environment for seamless auth
- Shares hanzo-mcp config with spawned agents
- Lightweight - no heavy litellm dependency

Essential tools reorganization:
- Added agent, think, critic to essential tools
- Removed llm/consensus from essential (heavy deps, opt-in)
- HEAVY_TOOLS constant for tracking opt-in tools

Config sharing:
- HANZO_AGENT_PARENT=true passed to child agents
- MCP config env vars propagated
- API keys shared when appropriate
2025-12-26 12:25:16 -08:00
zeekay 23b8a161a9 chore: bump hanzo-tools-* to 0.2.0, hanzo-mcp to 0.10.17
Published all packages to PyPI:
- hanzo-tools-core 0.2.0
- hanzo-tools-filesystem 0.2.0
- hanzo-tools-shell 0.2.0
- hanzo-tools-browser 0.2.0
- hanzo-tools-memory 0.2.0
- hanzo-tools-todo 0.2.0
- hanzo-tools-reasoning 0.2.0
- hanzo-tools-lsp 0.2.0
- hanzo-tools-refactor 0.2.0
- hanzo-tools-database 0.2.0
- hanzo-tools-agent 0.2.0
- hanzo-tools-jupyter 0.2.0
- hanzo-tools-editor 0.2.0
- hanzo-tools-computer 0.2.0
- hanzo-mcp 0.10.17
2025-12-26 06:49:24 -08:00