When sessions were started from ~ as working directory, the writer
produced ~/CLAUDE.md which Claude Code doesn't read. Now redirects
to ~/.claude/CLAUDE.md (the global location Claude Code reads for
all sessions).
Fixes#96
- M8: Fix null prompt_tokens_details in streaming.py (2 more instances)
- Issue 2: requests_compressed now counts by tokens_saved > 0 only,
not savings_percent > 0 (which could be negative from pipeline overhead)
- H3: Initialize original_tokens=0 before try block in Google batch handler
so error handler has a valid value
- L4: Google batch handler now looks up model context limit via
openai_provider.get_context_limit() instead of hardcoding 128000
Image compression inflated savings metrics by 3-4x because the tokenizer
counted base64 data as text tokens (330K per 1MB image). The compressor
itself works, but reported metrics were wrong.
TODO: re-enable once tokenizer extracts image dimensions and uses
Anthropic's formula (width*height/750) for accurate counting.
From deep code review of the refactoring:
- H3: Fix potential NameError in Google batch error handler (original_tokens
unbound if pipeline fails before producing result)
- M8: Fix null prompt_tokens_details from OpenAI (use `or {}` not default)
- L3: Add input_audio/audio/input_image to tokenizer (prevent json.dumps fallback)
- L6: _read_request_json now validates result is a dict (not list/string)
- H1/L2: Remove stale _HEADROOM_LOG_DIR and unused MAX_RATE_LIMITER_BUCKETS
- Extract shared defaultLogger constant, use in both ProxyManager and
HeadroomContextEngine (was duplicated inline in both constructors)
- Extract parseProxyUrl() helper, reused by normalizeAndValidateProxyUrl
and withDefaultPort (eliminates redundant URL parsing)
- Add test helpers: stubProbeSuccess/NonHeadroom/Unreachable to replace
6 identical inline fetch mock constructions
- Remove duplicate probe tests from engine.test.ts (already covered in
proxy-manager.test.ts)
- Clean up unused probeHeadroomProxy import from engine.test.ts
Net: -26 lines, same coverage (28 tests)
- proxyPort default (8787) now only applied to local URLs; remote URLs
use their protocol default (80/443) as expected
- Remove redundant localhost-only entries from network capabilities
(covered by http://*:* and https://*:* wildcards)
- Sync package.json capabilities with openclaw.plugin.json
- Export isLocalProxyUrl from barrel index
- Fix JSDoc indentation in start() method
- Rename "Required Proxy Setup" to "Manual Proxy Setup" with accurate
description for remote proxy users
- Clarify autoStart description: local-only, ignored for remote
- Add test: remote URL does not get proxyPort applied
Build: tsc clean, 30 tests passed
Remove localhost-only restriction from proxyUrl validation. Remote URLs
are connect-only: the plugin probes and uses them but never attempts to
spawn a subprocess. Auto-start remains available for local addresses
(127.0.0.1/localhost) only.
- Accept http:// and https:// URLs for any hostname
- Add isLocalProxyUrl() helper to gate auto-start on local addresses
- Remote URLs that fail probe get a clear "Remote proxy not reachable"
error instead of falling through to auto-start
- Update plugin.json schema, network capabilities, and UI hints
- Update plugin README with local vs remote proxy sections
- Add tests: remote connect, remote fail-fast, isLocalProxyUrl
Build: tsc --noEmit clean
Tests: 29 passed (0 skipped)
Add dedicated OpenClaw plugin section with install instructions,
explanation of --dangerously-force-unsafe-install requirement (proxy
subprocess spawning), and quick config example. Links to plugin README
for full details. Update integration tables to reference new section.
Also fix proxy port handling: apply default proxyPort when explicit
proxyUrl omits port, and allow trailing slash in proxyUrl validation
pattern. Add test coverage for port defaulting behavior.