Files
js-sdk/package.json
zeekayandHanzo Dev d8b09a274d feat: budget, policy, audit, search, kb and graph, over the generated client
Every Hanzo SDK offers the same six capabilities in the same six words. Go and
Python hang them off a client that already existed; TypeScript had none, so it
gains one — `Client`, holding an IAM client id and secret and minting its own
access token (client_secret_basic, RFC 8707 `resource`, held until 60s before
expiry, re-minted once on a 401). It takes no bearer and reads no
HANZO_API_KEY: a credential the SDK is handed is one nobody rotates and one
that says nothing about who is calling.

A refused budget and a refused policy are ANSWERS. `Answer<T>` is a union
discriminated on a literal tag — ok{value} | denied{code, reason, product?,
cures[]} | held{id, clause, reason}, all three carrying the x-request-id that
joins a call to its audit row — so `a.value` does not typecheck until the union
is narrowed and a switch that forgets an arm does not compile. The mapping from
HTTP to arm lives in one function; no capability can grow a rule of its own.
Exceptions stay for outcomes with no decision in them.

The layer is hand-written because the routes it needs are the ones the document
states as an address and not as a shape: /v1/authz/check declares neither a
request body nor a response, /v1/billing/balance and /usage declare no
response. Those three are modelled from what the served handlers read and
write, measured. It sits in src/ beside the generated tree because .generated
is the driver's manifest of what it owns — a file it does not name is this
repo's own and a regeneration never touches it — and the package entry moves to
src/hanzo.ts, which re-exports the generated src/index.ts and adds the client
beside it. Capability types are namespaced (budget.Allowance, search.Hit,
audit.Event, graph.Fact) because thirteen of the contract's names already
belong to generated models.

policy.check sends {subject, verb, path}, which is what
hanzoai/[email protected] serve/use.go reads, not the {sub, obj, act} the route's
own openapi.Describe prose states. The caller still says (sub, act, obj). The
prose and the handler are one fact and should be made to agree upstream.

Gates: `npm run wire` runs the six against a scripted fetch, asserting the
exact request each sends and decoding a realistic answer including both of
cloud's 402 bodies, a 202 hold and a 403 that is not a refusal. examples/six
drives all six in one pass against the live API and is type-checked with the
rest. The agent and tools flows are repaired for the tag names the current
document singularized (AgentsApi -> AgentApi, getTools -> getTool).

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-10 14:56:16 -07:00

47 lines
1.1 KiB
JSON

{
"name": "hanzoai",
"version": "8.5.158",
"description": "The official TypeScript library for the Hanzo API",
"author": "Hanzo <[email protected]>",
"license": "Apache-2.0",
"repository": "github:hanzoai/js-sdk",
"type": "commonjs",
"main": "dist/hanzo.js",
"module": "dist/esm/hanzo.js",
"types": "dist/hanzo.d.ts",
"files": [
"dist",
"src",
"README.md",
"LICENSE"
],
"private": false,
"publishConfig": {
"access": "public"
},
"scripts": {
"build": "tsc && tsc -p tsconfig.esm.json",
"typecheck": "tsc --noEmit",
"examples": "tsc -p examples/tsconfig.json",
"smoke": "node scripts/smoke.mjs",
"wire": "node --test test/*.test.mjs",
"test": "npm run build && npm run smoke && npm run wire && npm run examples",
"generate": "./scripts/generate.sh",
"prepublishOnly": "npm run build"
},
"dependencies": {
"axios": "1.18.1"
},
"devDependencies": {
"@types/node": "26.4.0",
"typescript": "7.0.2"
},
"exports": {
".": {
"types": "./dist/hanzo.d.ts",
"import": "./dist/hanzo.js",
"require": "./dist/hanzo.js"
}
}
}