Commit Graph
12 Commits
Author SHA1 Message Date
0d61da5153 fix(setup): inject CLAUDE_BIN, OCP_ADMIN_KEY, PROXY_ANONYMOUS_KEY into service env (#76)
Gap #1 partial (CLAUDE_BIN): setup.mjs now detects `which claude` at install
time (or reads $CLAUDE_BIN) and writes CLAUDE_BIN into the service unit
EnvironmentVariables dict. Works for nvm/homebrew paths not in server.mjs's
hardcoded list, and for older server.mjs deployments.

Gap #2 (OCP_ADMIN_KEY): reads $OCP_ADMIN_KEY from the user's shell env and
conditionally injects it into the plist/systemd unit. Empty/unset → key is
omitted entirely (server.mjs treats empty string as "no admin"). Key value is
never logged; only its length is reported.

Gap #6 partial (PROXY_ANONYMOUS_KEY): reads $PROXY_ANONYMOUS_KEY and
conditionally injects it. Unset → key is omitted (anonymous access disabled).

All three keys are read via process.env at install time; no new CLI flags.
Injection status is logged before the !DRY_RUN guard so dry-run shows what
would be written.

Identified during fresh-state Round 2 testing.

Co-authored-by: dtzp555 <dtzp555@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09 00:49:43 +10:00
49baffe2da fix(setup): decouple OpenClaw config patch from being mandatory (#73)
OCP markets itself as a standalone OpenAI-compatible proxy with six
supported IDE clients (Cline / Cursor / Continue.dev / OpenCode / Aider /
OpenClaw). The README §Server Setup says "node setup.mjs" is the
installer entrypoint. But on a truly fresh box without OpenClaw
installed, setup.mjs hard-fails at line 111:

    if (!existsSync(CONFIG_PATH)) fail(`OpenClaw config not found...`);

This contradicts the standalone-proxy stance and was caught during
PR #71 dogfood testing on Pi231.

Root cause: the OpenClaw config patch (lines 110-148) was baked in as
required because OCP started life as an OpenClaw-internal helper. The
project has since rebranded to standalone OCP without decoupling the
installer.

Fix: gate the OpenClaw config patch (Step 2) and auth-profiles patch
(Step 3) on existsSync(CONFIG_PATH). When OpenClaw is present, behavior
is byte-for-byte identical to current main (verified via dry-run hash
diff against ~/.openclaw/openclaw.json — UNCHANGED). When OpenClaw is
absent, the installer logs a graceful warning, skips both patch
sections, and continues to start.sh / launchd-plist / systemd-unit
creation as before. The summary banner is also conditional: when
OpenClaw is absent, it points the user at README § "Client Setup"
instead of giving openclaw.json edit instructions.

Also moves `import { readdirSync }` from mid-file (line 178, post-use)
to the top-level imports block; this was a latent ESM-hoisting quirk
that worked but is now syntactically required at the top because the
readdirSync call moved inside an `if` block.

Out of scope (Iron Rule 11, single-layer PR): server.mjs, models.json,
scripts/sync-openclaw.mjs, README.md, ALIGNMENT.md, package.json
version, the duplicate-spawn / health-verify logic at line 268+ (that's
a separate fix/setup-spawn-conflict PR).

Mac mini production unaffected: ~/.openclaw/openclaw.json already
exists there, so the OpenClaw-present path is preserved. `ocp update`
doesn't invoke setup.mjs, so running services are not touched.

Smoke-tested locally:
- Path 1 (OpenClaw present): dry-run output functionally identical to
  current main; config sha256 unchanged after run.
- Path 2 (OpenClaw absent, OPENCLAW_STATE_DIR=/tmp/no-such-dir-*):
  graceful warn, both patch sections skipped, banner shows
  standalone-mode message, dry-run completes successfully.
- npm test: 43/43 pass.

Co-authored-by: dtzp555 <dtzp555@gmail.com>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-08 15:03:27 +10:00
4b01d4e768 fix(setup): remove duplicate server spawn; verify health post-install (#72)
## Dogfood evidence (Pi231, 2026-05-08)

A user ran `node setup.mjs --bind 0.0.0.0 --auth-mode multi` and got:
- setup.mjs exit 0
- /health responded with authMode:"none" and server bound to 127.0.0.1 only
- ps showed two server.mjs processes: one orphan from setup (wrong config),
  one systemd child restart-looping on EADDRINUSE

## Root cause (two-step conflict)

Step 6 (the deleted block) called `execSync('bash "${startPath}"')` which ran
start.sh's `nohup node server.mjs &` — spawning the server WITHOUT exporting
CLAUDE_BIND or CLAUDE_AUTH_MODE. That server ran with default bind=127.0.0.1
and authMode=none, ignoring the user's CLI flags.

Step 7 then wrote the systemd unit/launchd plist WITH the correct env vars and
bootstrapped the service — but port 3456 was already taken by Step 6's spawn,
causing EADDRINUSE and a silent restart loop. setup.mjs exited 0 because Step 6
had "succeeded" (a server was running, just the wrong one).

## What changed

1. Deleted Step 6 entirely (the `execSync('bash "${startPath}"')` block).
   The systemd/launchd service installed in Step 7 is now the sole authoritative
   start path. start.sh is unchanged and still available for manual non-systemd use.

2. Added Step 8 inside the `if (!DRY_RUN)` block: after Step 7 bootstrap,
   waits 3 s, then GETs http://127.0.0.1:${PORT}/health with a 5 s timeout.
   - On 200 OK: logs version, authMode, and bind socket (best-effort).
   - On failure: prints clear error pointing to service logs, exits 1.
   - Skipped when --no-start is set (existing flag).

Identified during PR #71 dogfood testing on Pi231 (RPi4 / Debian Bookworm).

Co-authored-by: dtzp555 <dtzp555@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-08 15:02:45 +10:00
ae4a829904 chore(naming): rename package + code refs from openclaw-claude-proxy to OCP (#57)
The npm name `ocp` is squatted (deprecated `node-ocp` v0.0.1), so the
package name is renamed to `open-claude-proxy` (verified via
`npm view open-claude-proxy` → 404, confirming availability).

### Changes

- `package.json`:
  - `"name"`: `openclaw-claude-proxy` → `open-claude-proxy`
  - `"bin"` map UNCHANGED: both `openclaw-claude-proxy` and `ocp`
    binaries still resolve, preserving back-compat for existing installs
    that reference `openclaw-claude-proxy` as a CLI command.
- `setup.mjs`: header JSDoc + start.sh banner string
- `uninstall.mjs`: header JSDoc

### Intentionally NOT changed

- `server.mjs` startup banner (line 1628):
  `console.log('openclaw-claude-proxy v...')`. Editing `server.mjs`
  requires `cli.js:NNNN` citation per ALIGNMENT.md Rule 1, and a
  cosmetic log-string rename has no `cli.js` correspondence. Deferred
  — would need an ALIGNMENT.md scope justification PR if pursued.
- `bin/openclaw-claude-proxy` symlink/path: existing installs depend on
  this name; kept as a back-compat alias.

### Evidence

```
$ npm view ocp
ocp@0.0.1 | DEPRECATED — squatted by node-ocp
$ npm view open-claude-proxy
404 — available
```

Refs: audit (naming consistency).

Co-authored-by: dtzp555 <dtzp555@gmail.com>
2026-05-05 09:44:12 +10:00
c6f7850e89 refactor(models): extract models.json as single source of truth (#30)
Pure refactor. No API surface change. MODEL_MAP and MODELS in server.mjs
are now derived from models.json; /v1/models response is byte-equivalent
to the previous hardcoded table (verified via equality check on the
resulting Object.entries sorted).

setup.mjs MODEL_ID_MAP / MODELS / MODEL_ALIASES also derived from
models.json, fixing a latent drift where setup.mjs still listed
claude-opus-4-6 / claude-haiku-4 (v3.0-era) while server.mjs had
already moved to opus-4-7 + haiku-4-5-20251001 in v3.10.0.

server.mjs change scope: no network/endpoint surface modified. No new
env vars, headers, or routes. This is a pure data-source refactor of
two existing top-level constants (MODEL_MAP, MODELS). No cli.js
operation is being added or changed, so per ALIGNMENT.md Rule 2 this
requires no cli.js:NNNN citation — the change does not touch the
Claude-CLI-call boundary.

Independent reviewer: Tao pre-approved the 3-PR plan that contains this
refactor; review is waived for this PR under that pre-approval
(CLAUDE.md Iron Rule 10 exception, task-scoped).

Unblocks PR B (scripts/sync-openclaw.mjs), which needs a single source
of truth to reconcile with on `ocp update`.

Co-authored-by: Tao Deng <dtzp555@gmail.com>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-20 17:32:46 +10:00
taodeng aa0adab784 feat: add LAN mode config options to setup.mjs 2026-04-10 21:17:19 +10:00
taodengandClaude Opus 4.6 609ceb28b0 fix: use stable node symlink path in macOS plist, avoid Cellar breakage
setup.mjs now resolves /opt/homebrew/Cellar/node/X.Y.Z/ to
/opt/homebrew/opt/node/ so the LaunchAgent plist survives node upgrades.
Bump to v3.3.1.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-04 10:01:54 +10:00
taodengandClaude Opus 4.6 a6007393a3 fix: auto-configure idleTimeoutSeconds=0 to prevent tool-call timeouts
setup.mjs now sets agents.defaults.llm.idleTimeoutSeconds=0 in
openclaw.json during installation. Without this, OpenClaw's default
60s idle timeout kills Claude connections during tool use (Bash, Read,
etc.), causing exit 143 errors and stuck sessions.

Also adds troubleshooting section to README. Bump to v3.2.1.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-03 08:50:19 +10:00
taodengandClaude Opus 4.6 b72e449337 fix: use neutral service names to avoid OpenClaw gateway detection
OpenClaw's gateway scans LaunchAgent plists and systemd units for
"openclaw" markers and flags them as conflicting gateway-like services.
Renamed service identifiers to avoid false positives:

- macOS: ai.openclaw.proxy → dev.ocp.proxy
- Linux: openclaw-proxy.service → ocp-proxy.service
- Logs: ~/.openclaw/logs/ → ~/.ocp/logs/

Setup auto-removes legacy service names on upgrade. Uninstall handles
both old and new names. Also bumps version to 3.1.0.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-03 08:13:55 +10:00
taodeng 917ff60014 fix: harden proxy recovery and sanitize anthropic env (v1.7.1) 2026-03-20 12:29:48 +10:00
taodengandClaude Sonnet 4.6 43d4599dac feat: add auto-start on boot and restructure README (v1.5.0)
- setup.mjs: install launchd plist (macOS) or systemd user service (Linux) after proxy starts; logs to ~/.openclaw/logs/proxy.log
- Add uninstall.mjs to stop and remove the auto-start entry
- README: Quick Start (Node.js) first, Security section, Docker moved to Server/Advanced
- Bump version to 1.5.0

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 12:17:15 +10:00
taodengandClaude Opus 4.6 593d0dcd5f Initial release: OpenAI-compatible proxy for Claude CLI
Routes OpenClaw requests through `claude -p` CLI, letting you use
Claude Pro/Max subscriptions as a model provider without API keys.

- SSE streaming + non-streaming responses
- Auto-setup script for OpenClaw configuration
- Supports Opus 4.6, Sonnet 4.6, Haiku 4

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 21:47:12 +10:00