typescript 7.0.2 is the native compiler and exports no JavaScript API, so
ts-jest, tsup's dts build and typescript-eslint cannot read it. It comes in
aliased as tsgo and does the typechecking through new typecheck scripts;
typescript stays on the 6 line for the tools.
shell-tool-mcp asked for moduleResolution "Node", which TS7 removed, so it
moves to node16 alongside its module; the node and jest globals it uncovers
are now declared rather than swept in. 30 diagnostics before, 29 after, the
same on both compilers.
Co-authored-by: Hanzo Dev <[email protected]>
A version written into a manifest is written into every manifest that wants it,
which is how eslint came to exist in a hundred and four forms across this estate
and how a package came to resolve twice at run time. The catalog moves the number
out of the manifest: a manifest names the package, the workspace names the
version.
Four are held below their latest because the newer release cannot be used, and
the reason is recorded rather than the version alone: @noble/hashes 2 renamed
every subpath the web3 stack imports, @splinetool/runtime 2 depends on a package
that was never published, @dynamic-labs 5.4.1 the same, and react-resizable-panels
3 points its types condition at the bundle.
457 sites carried an upstream prefix into every surface a user reaches — shell
exports, docs, CI, the SDK. CODEX_ is not our name and it was never going to
stop arriving on its own: it is what upstream writes, and every sync brings more.
Two namespaces, because they answer different questions.
DEV_* the app's own configuration — DEV_HOME, DEV_PROFILE, the rest
HANZO_API_KEY a credential for the Hanzo stack, which is not app config
CODEX_API_KEY held the literal string "CODEX_API_KEY", so the rename moves the
value and not just the constant. It becomes HANZO_API_KEY, which is what
create_hanzo_provider already reads through HANZO_MACHINE_ENV_KEYS — one name
for one credential instead of two spellings of it.
vendor/ is untouched, which is the point of vendor/: upstream code keeps
upstream names, and the boundary is a path rather than a habit.
Three things the last pass left flagged. Two are done; the third turned out to
belong somewhere else and is reported rather than forced in.
## exec --json emits the schema instead of the SDK guessing it
`exec_events.rs` and `experimental_event_processor_with_json_output.rs` had no
`mod` declaration, so 683 lines defining the `thread.*`/`item.*` schema never
compiled. `sdk/typescript/src/events.ts` says "based on event types from
code-rs/exec/src/exec_events.rs" and then rebuilt those events client-side from
raw core events — the contract existed only in TypeScript, and nothing checked
the two halves agreed.
Declared the modules and fixed what drifted while dead: TaskStarted became a
unit variant, WebSearchEnd became WebSearchComplete, StreamError folded into
Error, ExecCommandEndEvent lost `aggregated_output`, print_config_summary lost a
parameter. `--json` now uses it (`--experimental-json` is an alias, matching
upstream), and the old raw-event processor is deleted rather than left as a
second way to do this. thread.started needed a route because exec consumes
SessionConfigured before the event loop, so EventProcessor grew a defaulted
`on_session_configured`.
Making it real immediately found a lie: the SDK's `Usage` declares five fields
and we emitted three. core::TokenUsage had `cache_write_input_tokens` and
`reasoning_output_tokens` all along; the processor dropped them. Against a mock
model:
{"type":"thread.started","thread_id":"2bd35c77-..."}
{"type":"turn.started"}
{"type":"item.completed","item":{"id":"item_0","type":"agent_message","text":"Hello from the model."}}
{"type":"turn.completed","usage":{"input_tokens":11,"cached_input_tokens":2,
"cache_write_input_tokens":0,"output_tokens":5,"reasoning_output_tokens":1}}
The SDK now passes those through instead of reconstructing them. Its test suite
did not compile — at HEAD and in just-every upstream: runStreamed.test.ts uses
`path` and `createMockClient` without importing either, testCodex.ts passes
`config` to a type declaring `configOverrides`, and findCodexPath() referenced
four names (`moduleRequire`, `CODEX_NPM_NAME`, `createRequire`,
`PLATFORM_PACKAGE_BY_TARGET`) that were never declared anywhere. Declared them
against @hanzo/dev, added `env` to CodexOptions, pointed the harness at
code-rs/target/debug/dev instead of codex-rs/target/debug/codex.
pnpm exec jest tests/runStreamed.test.ts --testTimeout=120000
3 passed (asserts thread.started, turn.started, item.completed, turn.completed
and item.type === "agent_message" against the real binary)
## queueUserMessage: steer a turn instead of tearing it
`sendUserMessage` submits Op::UserInput, and core/src/codex/streaming.rs:998
calls `sess.abort()` before spawning a new turn — over app-server you could
interrupt a turn, never redirect one. Op::QueueUserInput folds items into the
running task instead, and only the TUI used it. It is now an app-server method.
Separate method, not a flag: interrupting and steering are different acts and a
caller should not pick the destructive one by accident.
→ {"method":"queueUserMessage","id":3,"params":{"conversationId":"999222eb-…",
"items":[{"type":"text","data":{"text":"steer me"}}]}}
← {"id":3,"jsonrpc":"2.0","result":{}}
← {"error":{"code":-32600,"message":"conversation not found: 00000000-…"},"id":4}
## zrok: not ours to build
Assessed and deliberately not implemented here. `hanzo link` already composes
ttyd + share::start + publish_terminal into exactly this feature, and
cli/src/commands/share.rs calls itself "the ONE implementation of 'publish a
local port on the fabric'". `dev` has no framable surface anyway — app-server is
raw JSON-RPC — and no IAM identity to reach POST /v1/share/enable. The gap is in
cloud/cmd/boxd, which already execs `dev`. Details in the report.
Also: git.hanzo.ai release migration precondition written into LLM.md (four
call sites, forge serves /v1/ not /api/v1/, publish to both for a cycle before
moving the updater). SDK package was @openai/codex-sdk; now @hanzo/dev-sdk.
cargo test -p {code-core,code-protocol,code-cli,code-app-server,
code-exec,code-mcp-server,code-tui} -- --test-threads=1
1311 passed; 1 failed
The failure is git_info::test_collect_git_info_with_remote, still environmental:
the new narrower insteadOf rule only covers hanzoai/*, and the test's URL is
github.com/example/repo, which the broad rule still rewrites.
Version 0.2.189 -> 0.2.190.
Co-authored-by: Hanzo Dev <[email protected]>
Our history is just-every's with author emails rewritten, so the graphs are
disjoint and git finds no merge base. Supplied one by hand: d1f1f51a41, the
just-every commit matching our Oct-2025 fork point (22 files apart). 9618
upstream commits, 7004 files, +1.81M/-159k, 37 conflicts.
Resolution:
- Upstream code where our side was the Oct-2025 prototype of a feature they
have since reimplemented 3-5x larger (agent_runs, browser_sessions,
history_cell/{agent,browser}, the vt100 harness and its snapshots).
- Upstream's config.rs module split (builder/defaults/sources/validation)
kept; zen5-coder and the provider-follows-model rule re-applied on top.
- Ours where the file IS the identity: README, package.json, postinstall,
release notes pipeline, integration-zed.
- Hybrid where upstream improved a file we had branded: updates.rs (their
release-repo migration, our hanzoai/dev), release.yml (their fail-fast npm
auth check, our package name), chatwidget.rs (their turn handling, our
HANZO_USER_KEY hint), exec human output (their 237 lines, our banner).
Superseded and dropped deliberately: our resume_command_name() coder-alias
hack — upstream's derive_resume_command_name() reads the invocation basename
generically, which yields "dev" for us.
LLM.md now records the real topology and the sync point; AGENTS.md and
CLAUDE.md are symlinks to it again. Single parent on purpose: adopting
jecode/main as a second parent would re-import 13,742 commits carrying the
upstream author emails a prior rewrite deliberately removed.
Version 0.2.188 -> 0.2.189.
Co-authored-by: Hanzo Dev <[email protected]>
## Summary
- expand the TypeScript SDK README with streaming, architecture, and API
docs
- refresh quick start examples and clarify thread management options
## Testing
- Not Run (docs only)
---------
Co-authored-by: Hanzo Dev <[email protected]>
There was a bit of copypasta I put up with when were publishing two
packages to npm, but now that it's three, I created some more scripts to
consolidate things.
With this change, I ran:
```shell
./scripts/stage_npm_packages.py --release-version 0.43.0-alpha.8 --package codex --package codex-responses-api-proxy --package codex-sdk
```
Indeed when it finished, I ended up with:
```shell
$ tree dist
dist
└── npm
├── codex-npm-0.43.0-alpha.8.tgz
├── codex-responses-api-proxy-npm-0.43.0-alpha.8.tgz
└── codex-sdk-npm-0.43.0-alpha.8.tgz
$ tar tzvf dist/npm/codex-sdk-npm-0.43.0-alpha.8.tgz
-rwxr-xr-x 0 0 0 25476720 Oct 26 1985 package/vendor/aarch64-apple-darwin/codex/codex
-rwxr-xr-x 0 0 0 29871400 Oct 26 1985 package/vendor/aarch64-unknown-linux-musl/codex/codex
-rwxr-xr-x 0 0 0 28368096 Oct 26 1985 package/vendor/x86_64-apple-darwin/codex/codex
-rwxr-xr-x 0 0 0 36029472 Oct 26 1985 package/vendor/x86_64-unknown-linux-musl/codex/codex
-rw-r--r-- 0 0 0 10926 Oct 26 1985 package/LICENSE
-rw-r--r-- 0 0 0 30187520 Oct 26 1985 package/vendor/aarch64-pc-windows-msvc/codex/codex.exe
-rw-r--r-- 0 0 0 35277824 Oct 26 1985 package/vendor/x86_64-pc-windows-msvc/codex/codex.exe
-rw-r--r-- 0 0 0 4842 Oct 26 1985 package/dist/index.js
-rw-r--r-- 0 0 0 1347 Oct 26 1985 package/package.json
-rw-r--r-- 0 0 0 9867 Oct 26 1985 package/dist/index.js.map
-rw-r--r-- 0 0 0 12 Oct 26 1985 package/README.md
-rw-r--r-- 0 0 0 4287 Oct 26 1985 package/dist/index.d.ts
```