The @hanzo/usage sibling-path alias pointed at /…/usage that doesn't exist on
CI, breaking every release build. Both are now published deps resolved from
node_modules — CI build works. Bump 1.9.33→1.9.34 (1.9.33 store build failed here).
iManage Work OAuth2 + Work API (workspaces/documents/search) + content extraction,
AI actions (summarize doc / extract clauses-dates-parties / search-synthesize);
server-side tokens, never logs content, grounded extraction, 'not legal advice'.
121 tests. On published @hanzo/ai@0.2.0.
All 6 Wave 5 verticals now on main: epic(109) procore(102) quickbooks(91)
canvas-lms(119) workday(113) imanage(121). CI step added.
Read+assist clinical copilot embedded in the EHR via SMART on FHIR. Loads the
launched patient's chart over FHIR R4 (problems, meds, allergies, labs/vitals,
notes) and runs four actions — summarize patient, draft SOAP note, extract
problems & meds, ask — through the api.hanzo.ai gateway via @hanzo/ai@^0.2.0.
PHI posture: the FHIR/PHI access token is confined server-side (server.ts);
the browser holds only an opaque HttpOnly session cookie and a Hanzo gateway
key. No PHI is ever logged; SMART is auth-code + PKCE (S256) with the
confidential secret read from the environment; the proxy is scoped to the six
read resources and the session's own FHIR base (SSRF/cross-tenant guards).
Read + assist only — no clinical write-back, no *.write scope.
Tests: 109 vitest across config/smart-oauth/fhir-client/chart/hanzo/auth/server.
Workspace-wired like every sibling: test/ dir, root pnpm-lock importer, no
package-level lock.
The extension's packages/ai was a duplicate 'AgentKit with MCP' (canonical home:
hanzoai/ai) that squatted the @hanzo/ai name and collided with the published AI
client. Nothing consumes it anymore (all 16 adapters resolve @hanzo/ai to the
published 0.2.0 client from npm; no @hanzo/ai/server|react subpath imports; not
in the release publish). Removing it makes @hanzo/ai in the workspace
unambiguously the AI client.
Taxonomy (per direction): @hanzo/ai = AI client · @hanzo/agent = Agent SDK ·
@hanzo/ui = all v8 components (hanzoai/ui, agent UI → @hanzo/ui/agent) ·
@hanzo/gui = v8 framework (hanzoai/gui, Tauri+Tamagui unified). Removed the
@hanzo/ai CI test step. github 84 + slack 68 still green.
5 early adapters (docusign/meetings/notion/slack/teams) pinned @hanzo/ai@^0.1.1,
which resolved to the LOCAL packages/ai AgentKit (no createAiClient) — the reason
they carry stand-in client.ts files. Bump them to ^0.2.0 so every adapter's
declared dep points at the real published headless client. Tests unchanged and
green (docusign 103, meetings 70, notion 104, slack 68, teams 69).
Remaining SDK cleanup (separate pass): rename the extension's own @hanzo/ai
AgentKit → @hanzo/agentkit to end the name collision, then replace each adapter's
stand-in client.ts with a one-line re-export of @hanzo/ai.
- @hanzo/github — GitHub App: auto PR review (diff windowed), issue triage
(labels intersected with real repo labels), @hanzo mentions; HMAC-verified
webhooks; all via @hanzo/ai (84 tests).
- hanzo-ai (Raycast) — command bar: Ask (streaming) + Summarize/Explain/Rewrite/
Translate/Fix-grammar over selection/clipboard, paste-back (51 tests).
Both on published @hanzo/ai@0.2.0 + @hanzo/iam. CI steps added.
A side-panel Canva app over the published @hanzo/ai: generate copy, rewrite
the selected text in place, translate, brainstorm content ideas, and ask.
- design-core.ts (PURE): the five-action catalog, prompt builders, design-
context assembly + budget truncation, and response parsing (fence/quote/
list-marker stripping). Mirrors @hanzo/figma's design-core. Fully unit-tested.
- hanzo.ts: thin over @hanzo/ai (createAiClient) — the only model-gateway path.
- canva.ts: thin over @canva/design — observe the plaintext selection, replace
it via a fresh draft, insert a new text element at the cursor.
- app.tsx: the @canva/app-ui-kit panel (model picker, action picker, output,
ideas). index.tsx mounts it under AppUiProvider.
- config.ts: api.hanzo.ai /v1 gateway, default zen5, hk- key guard.
40 vitest tests green, tsc --noEmit clean, esbuild build succeeds. Registered
in pnpm-workspace.yaml.
ZAFv2 ticket_sidebar Support app on the published @hanzo/ai@0.2.0: summarize
ticket, draft reply (agent voice), suggest macro/next-steps, ask; write-back via
ticket.comment.appendText (public reply / internal note). Hanzo key is a secure
ZAF setting, proxied server-side so it never reaches the browser (49 tests). CI step added.
@hanzo/teams — bot (1:1/channel) + message extensions, Adaptive Cards via
@hanzo/cards, Action.Submit/Execute dispatch, packaged Teams app zip (69 tests).
CI: add teams test step. Wave 1 (Slack · Teams · Zoom/Meet) all on main.
Wave 1 comms hubs land:
- @hanzo/slack — /hanzo slash command, App Home, message shortcuts, thread-context
quick actions, OAuth install; UI 100% @hanzo/cards Block Kit (68 tests).
- @hanzo/meetings — Zoom App + Google Meet add-on panels + Zoom webhook
transcript→summary (signature-verified); web panels over @hanzo/ai (70 tests).
CI: build @hanzo/cards before dependent tests (consumers resolve its built dist/),
and add slack + meetings test steps.
Note: the headless @hanzo/ai client isn't published under 'latest' yet (npm
@hanzo/ai@0.1.1 is the React <HanzoAI/> UI); each adapter ships a client to the
exact createAiClient /v1 contract as an interim, to become a one-line re-export
once the headless client publishes.
The shared card-builder — one canonical PanelSpec → Slack Block Kit / Teams
Adaptive Cards / Google CardService with stable action ids. The missing
foundation piece for card-host adapters (Slack/Teams/Google); pairs with the
existing @hanzo/ai (headless client) + @hanzo/iam (identity) SDKs. Pure, zero
runtime deps, 66 tests.
Clio practice-management integration — OAuth2 + Clio API v4, AI actions over
matters/documents with write-back to matter notes/activities, and Custom Actions
to embed AI buttons inside Clio. A hosted web app + token-exchange service
(clio.hanzo.ai; client_secret server-only, KMS), so CI-tested — no sideload
binary. Completes the daily-lawyer surface set (iManage/NetDocuments deferred).
The Hanzo AI PDF workspace (PDF.js viewer + AI side panel — summarize, extract
parties/dates/obligations, find risky clauses over filings/contracts). A hosted
static surface (pdf.hanzo.ai over hanzoai/static), so CI-tested like the Google
Workspace add-on — no sideload binary.
Wire the two new productivity surfaces into CI/CD:
- ci.yml: test @hanzo/outlook-addin (39) + @hanzo/gworkspace-addon (29).
- publish.yml: new 'outlook' job builds @hanzo/outlook-addin → hanzo-ai-outlook-v<ver>.zip,
added to release needs/files + an Outlook row in the download table.
(Google Workspace deploys via clasp to Google, not a sideload binary — CI-tested
only, no release zip.)
- pnpm-lock: workspace now includes packages/outlook + packages/gworkspace.
Five surfaces (browser, office, vscode, cli, mcp) each hand-rolled the SAME
IAM OAuth2+PKCE flow — and one drifted and broke: vscode built
hanzo.id/oauth/authorize and iam.hanzo.ai/oauth/token, both MISSING the
/v1/iam prefix (a 404 — the same class of bug as the browser login fix),
plus it POSTed JSON where IAM requires form-urlencoded and sent a
client_secret on a public PKCE client. That is the opposite of one way.
Decomplected into ONE core — packages/auth (@hanzo/auth):
- config.ts canonical HIP-0111 endpoints (authorize/token/userinfo ALL
carry /v1/iam) + the one-client-per-surface registry
(hanzo-browser/office/vscode/cli). URL assembly lives once.
- pkce.ts the one PKCE (S256), platform-CSPRNG + WebCrypto.
- oauth.ts buildAuthorizeURL / exchangeCode / refreshTokens / userinfo —
pure fetch, form-encoded per RFC 6749.
- flow.ts login / getValidToken (transparent refresh) / logout /
currentUser, written ONCE against TokenStore + Opener. A
surface supplies only those two thin adapters — no surface
re-implements the flow.
23 tests: the drift guard (every path has /v1/iam), client registry, PKCE
RFC-7636 vector, wire shapes, and the full flow with fake adapters.
Migrate office onto it: roamingSettings TokenStore + Dialog-API Opener;
delete office's duplicate pkce.ts + IAM config (now the core's). API-key
path kept. 22 tests; the core bundles into the task pane.
Fix vscode standalone-auth: all three endpoints → ${host}/v1/iam/oauth/*,
token calls form-urlencoded, OIDC scopes, drop the secret on the public
PKCE client. Compiles clean.
CI now gates @hanzo/auth. Browser/mcp/tools already use canonical paths;
migrating them to import the core is the tracked next step (each needs its
own bundler wiring) — the ONE way now exists and has two consumers.
The surface a non-developer actually uses — a Microsoft Office task-pane
add-in that puts Hanzo AI inside the document. Select text or a range,
ask, insert. Distinct from the browser extension and the IDE extensions;
same backend as everything else: model calls through api.hanzo.ai/v1
(OpenAI-compatible), sign-in via Hanzo IAM (hanzo.id, auth-code + PKCE,
HIP-0111). No new API surface.
Decomplected so the logic is pure and unit-tested (26 tests), Office.js
glue kept thin:
- chat.ts — request/response shaping (buildMessages fences the selection
as data; extractContent tolerates the gateway's response shapes)
- pkce.ts — PKCE + authorize URL, verified against the RFC 7636 S256 test
vector
- host.ts — per-host read/insert; Excel range↔text helpers tested
- config.ts — canonical endpoints pinned (api.hanzo.ai, /v1/iam/oauth/*)
- taskpane/auth/commands — the Office.js + Dialog-API glue
manifest.xml passes `office-addin-manifest validate` ("The manifest is
valid" — Word/Excel/PowerPoint on web, Windows, Mac). build.js stamps the
hosting base URL (office.hanzo.ai, override for localhost dev) into a
sideloadable/AppSource-submittable dist/manifest.xml.
CI runs the tests and builds+zips a sideloadable artifact. Publishing to
AppSource needs the dist hosted at office.hanzo.ai + a hanzo-office IAM
client + a Partner Center submission (documented in the README).
The package's `npm test` has been broken-by-construction for years:
tsconfig excluded src/test entirely (out/test/runTest.js never existed),
tsconfig.test.json inherited the exclude that negated its include, the
runner pointed at a ./suite/index path that never existed, two suites used
BDD describe/it under the tdd-configured mocha, a vitest file sat in the
mocha glob, `ws` was never declared (it resolved only cross-package), and
154 eslint errors blocked pretest.
Lint 154 → 0 with real fixes: the ban-types autofix damage reverted
properly (the local `Symbol` interface shadowing the ES built-in — the
actual footgun — is now `CodeSymbol` everywhere), case bodies braced via
AST codemod, empty catches annotated, `Function` types replaced with real
signatures, hasOwnProperty via Object.prototype, and
@typescript-eslint/no-var-requires off — CJS lazy requires are the
intentional activation-perf idiom (the rule is retired to stylistic in
typescript-eslint v8).
Harness: tests compile via tsconfig.test.json in pretest; runner path
fixed; BDD→TDD; glob v10 promise API; esModuleInterop default imports.
Two harnesses, one directory each: vitest owns src/test/vitest/ (scoped
vitest.config, excluded from the mocha compile), mocha owns the rest;
posttest runs the vitest side so `npm test` is the whole gate.
Suites modernized against current tool contracts (34 passing / 64 failing
→ 152 passing / 0 failing / 12 pending): web-fetch rewritten against the
real http(s) path via loopback server, mode against list/activate/show/
current, mcp-tools against config-driven getAllTools filtering, extension
pins the shipped manifest contract, shell/process/git-search/filesystem/
config/bash/mcp-runner exercise real commands, files, repos and spawns.
Dead-subject suites removed; network-dependent integration tests gated on
HANZO_E2E_LIVE with visible skip reasons (12 pending). Tests-only — the
one suspected product bug was an unfaithful Memento mock, and a real
cross-suite settings leak was fixed by making suites hermetic.
CI: cli-tools and vscode test steps lose continue-on-error and become
hard gates (vscode under xvfb-run, same as the E2E job).
The first pass pinned each override to its advisory-snapshot floor, but
several packages carry stacked advisories — a pin at one advisory's floor
sits inside the next one's vulnerable range (protobufjs 7.5.5 vs 7.6.3,
tar 7.5.16, tmp 0.2.7, flatted 3.4.2, vite 6.4.3, file-type 21.3.2,
qs 6.15.2, js-yaml 4.2.0). One within-major floor per package now, at the
highest first-patched. Suites: browser 243, ai 31, aci 29, cli-tools 87.
- pnpm overrides pin every vulnerable transitive to its advisory's exact
first-patched version, scoped to the advisory's own vulnerable range so
no dependency is dragged across a major it didn't need (criticals:
form-data 4.0.6, handlebars 4.7.9, protobufjs 7.5.5).
- vitest < 3.2.6 is a critical (CVE fix floor) with no 0.x/1.x backport —
forced major to ^3.2.6 in every package. Test scripts unify on
`vitest run` (aci/ai ran bare watch mode). tools' vscode mock alias
becomes absolute (vitest 3 dropped relative alias resolution).
- packages/ai otel family 1.x → 2.x (core <2.8.0 advisory covers all 1.x):
resourceFromAttributes, ATTR_* semconv, constructor spanProcessors. The
previously-uncollectable telemetry suite now runs: ai 31 tests (was 16).
- direct bumps: vite ^6.4.3 (site), esbuild ^0.25.8 (mcp), uuid ^11.1.1
(tools). packages/ai/package-lock.json deleted — stray npm lockfile in a
pnpm workspace, carried 24 of the alerts.
- ci: test step filtered @hanzo/tools but the package is @hanzo/cli-tools —
the suite never ran in CI. Fixed; 87 tests now gate (behind the existing
continue-on-error). pnpm 9 reads onlyBuiltDependencies from package.json,
not pnpm-workspace.yaml — mirrored so native build scripts stay allowlisted.
Verified: browser 243/243 + e2e 30/30 + build; aci 29/29; ai 31/31;
cli-tools 87/87; site builds on vite 6; mcp builds on esbuild 0.25.
Decomplected three orthogonal layers:
L3: hanzo.* ergonomic aliases
L2: CDP-shape canonical primitives (Page.* DOM.* Input.* ...)
L1: runFunc(tabId, fn, args) → scripting.executeScript({world: MAIN, func: ref})
Every DOM op now passes a real function reference to scripting.executeScript
instead of constructing Function(codeStr)(). The Function() path is blocked
by strict page CSP on sec.gov / github.com / any default-src 'self' SPA.
Direct function refs are exempt from page CSP per the WebExtension spec, so
the new path works everywhere.
Added (all CSP-safe):
• hanzo.clickByText fillByLabel findByText listForm submitForm
• hanzo.press scroll waitForText waitForMutation
• hanzo.uploadFile dialogAccept observe/observeRead/observeStop
• Input.dispatchMouseEvent Input.scrollWheel
• DOM.querySelector DOM.scrollIntoView DOM.focus
• Page.printToPDF
Rewrote with runFunc (CSP-safe):
• hanzo.click fill check uncheck clear getText getHTML
• hanzo.querySelectorAll
Capabilities handshake bumped to advertise the new method names.
Driver-side mapping in hanzo-tools-browser/browser_tool.py updated with
~100 snake_case action → wire-method entries (Python MCP surface).
API reference: dist/browser-extension/firefox/API.md
- Replace red (#FF6B6B) accent with monochrome white palette
- Replace hallucinated shield SVG with real Hanzo geometric H logo
- Copy real icon PNGs from hanzo/logo for extension icons
- Add Playwright E2E test suite (16 tests: popup + sidebar)
- Fix CI: remove continue-on-error from test job
- Gate releases on all tests (unit + E2E) passing
- Release only on tag push, not nightly
- Add vitest.config.ts to exclude e2e from unit tests
- Add comprehensive test suites for ACI and MCP packages
- Fix ACI TypeScript build errors (Region type conflicts, Key enum conversion)
- Rename palette system to mode presets throughout codebase
- Add all 100 historic programmer modes from Python dev tool
- Add 13 mode presets from Python MCP (unix, modern, web, scripting, etc.)
- Fix circular dependency in MCP by creating tool-registry.ts
- All tests passing: AI (31), ACI (29), MCP (33)
- Reorganized directory structure: pkg/ -> packages/, app/ -> apps/
- Added @hanzo/ai package with Vercel AI SDK patterns
- Implemented AgentKit concepts (agents, networks, state, routers)
- Added MCP (Model Context Protocol) integration
- Integrated telemetry with Hanzo Cloud observability
- Fixed all failing tests across all packages
- Updated Makefile with comprehensive commands for development and release
- Added support for Gemini, Codex, and Grok CLI tools
- Fixed import paths and build configuration for new structure
- Add --swarm <count> capability to launch up to 100 agents in parallel
- Support multiple providers: --claude, --openai, --gemini, --grok, --local
- Implement lazy agent spawning for efficient resource usage
- Add automatic authentication for all providers
- Create parallel file processing with progress tracking
- Migrate all tests from Jest to Vitest
- Add comprehensive test coverage for swarm functionality
- Support idiomatic usage: dev --claude --swarm 5 -p 'edit files...'
- Version bump to 2.1.0
- Implement feature parity between Python and TypeScript MCP versions
- Add comprehensive test coverage for all orthogonal tools
- Consolidate tools to follow single-tool-multiple-actions pattern
- Add bash, git-search, critic, and mode tools
- Create multi-platform build system for VS Code, Claude Desktop, and DXT
- Add test files for filesystem, search, shell, process, web-fetch, mode, and git-search tools
- Fix TypeScript compilation issues and update build scripts
- Update package.json with hanzo-ai publisher ID
- Successfully build all distribution formats:
- VS Code Extension (.vsix)
- Claude Desktop MCP package
- Claude Code DXT file
- Standalone MCP server