mirror of
https://github.com/dtzp555-max/ocp.git
synced 2026-07-21 21:15:09 +00:00
2adea6368d1e159c5c4fa298a9857cb318006058
3
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
2adea6368d |
fix(ocp-connect): rewrite IDE detection + improve hint density (v1.2.0) (#14)
Follow-up to #12 / #13. Fixes the IDE detection failures documented in issue #12 section 9.3 (IDE detection coverage matrix). ## What was broken PR-1 fixed the OpenClaw multi-agent auth bug but left section 9 of the report (IDE detection coverage) unaddressed. Empirical testing showed the script's "Other IDEs detected" section had a 25% effective hit rate: - Cline -> grep pattern was `grep -qi cline` but the actual VSCode extension ID is `saoudrizwan.claude-dev`. Hit rate 0%. - Continue.dev -> checked `~/.continue/config.json` but the directory is not created until the user opens the Continue panel for the first time, AND v1.x uses `config.yaml` not `config.json`. Hit rate 0% on a fresh install. - Cursor -> only checked `command -v cursor` and `~/.cursor`. Both fail when the user installs Cursor.app from the official dmg without enabling the optional shell command and without launching the app. brew cask installs work by side effect (it links the binary). Hit rate 100% via brew, 0% via dmg. - opencode -> not detected at all. opencode (https://opencode.ai) is one of the most popular AI CLI tools, missing entirely from the hint list. The hints themselves were also too sparse. Each one was a single line like `Cursor: Settings -> OpenAI Base URL = ...`, with no API key, no model IDs, no path to the actual settings page. Users had to guess. ## What this commit does ### Detection rewrite (Cline / Continue.dev / Cursor / opencode) Cline: prefer `code --list-extensions`, fall back to ls, match pattern `cline|saoudrizwan\.claude-dev`. Real-world Cline detection goes from 0% to 100%. Continue.dev: three-condition OR -- VSCode extension ID `continue.continue` OR `~/.continue/config.yaml` OR `~/.continue/config.json`. Catches all three real-world install states (extension installed but never opened / config.yaml / legacy config.json). Cursor: add `[[ -d "/Applications/Cursor.app" ]]` as a third fallback alongside `command -v cursor` and `~/.cursor`. Now detects Cursor regardless of how it was installed. opencode: NEW detection branch. Checks `command -v opencode`, `~/.opencode/bin/opencode`, and `~/.local/share/opencode`. Catches the official curl install path and any future package manager installs. ### Hint density improvements Each hint now includes: - The exact base URL to paste - The API key (truncated as `${key:0:8}...${key: -4}` if longer than 16 chars to avoid screenshot leakage; or "(none -- anonymous mode)" message when --key was not provided) - The list of available model IDs, extracted from the actual /v1/models response so the user does not have to guess - The exact menu path or config file location Continue.dev hint specifically shows the YAML snippet under the `models:` top-level key (per reviewer feedback) so the user can paste it directly without schema confusion. opencode hint explicitly says "not yet auto-configured by ocp-connect (PR follow-up)" so users know to use `opencode providers login openai` until a future PR adds direct auth.json writing. opencode does NOT read OPENAI_API_KEY env var (empirically verified) so the existing rc-file export strategy does not help it. ### NOT in scope (deferred) - opencode auto-configure (writing auth.json + opencode.json) -- schema needs more investigation, opencode model whitelist gets in the way of custom claude model IDs - Continue.dev auto-configure -- v1.x config.yaml schema is well enough known but parsing/merging YAML in bash without extra dependencies is awkward - Aider, Cody, Zed, etc. detection -- not in this PR scope These are future work tracked in #12 section 9.6. ### Version bump (per dev iron rule #5) OCP_CONNECT_VERSION 1.1.0 -> 1.2.0. ## Test evidence Offline matrix run on macOS 13 with VSCode 1.115.0, opencode 1.4.3, Cline 3.78.0, Continue.dev 1.2.22, Cursor 3.0.16: - All 4 IDEs installed -> all 4 hints fire with full detail - anonymous mode -> hints fire, key display reads "(none -- anonymous mode...)" instead of blank - HOME=tmpdir mock + only Cline mock dir -> Cline + Cursor (system app) hints fire, others suppressed - HOME=tmpdir mock + nothing -> only Cursor (system app) fires - --version -> "ocp-connect 1.2.0" - --help -> still shows the PR-1 wording for item 5 Hit rate matrix on the test machine (5/5 IDEs installed): | IDE | before PR-2a | after PR-2a | |--------------|--------------|-------------| | OpenClaw | YES (PR-1) | YES | | Cline | NO | YES | | Continue.dev | NO | YES | | Cursor | YES (brew) | YES | | opencode | NO | YES | Effective detection rate: 25% -> ~100%. ## Code review One independent opus reviewer (spec compliance + bash 3.2 compat + UX). Verdict: PASS WITH CONCERNS, 0 blockers. Two non-blocking suggestions both addressed in this commit: 1. Continue.dev YAML hint -- added `models:` top-level key so pasted snippet validates against Continue v1.x schema 2. anonymous mode -- key display now shows "(none -- anonymous mode; most external IDEs require a non-empty API Key)" instead of a blank field B1 (OpenClaw per-agent auth) section is intentionally untouched. Verified by diff line count: all changes fall in lines 347-440 (configure_ides function) + lines 9-13 (version constant). No edits inside the Python heredoc block. Co-authored-by: taodeng <taodeng@Taos-MBP> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
7860f71943 |
fix(ocp-connect): seed per-agent auth-profiles for OpenClaw multi-agent + UX hotfixes (v1.1.0) (#13)
* fix(ocp-connect): seed per-agent auth-profiles for OpenClaw multi-agent + UX hotfixes Fixes #12. ocp-connect bumped to v1.1.0. ## What was broken OpenClaw's per-agent auth loader reads <agentDir>/auth-profiles.json (NOT the root openclaw.json's auth.profiles section, NOT env vars). ocp-connect only wrote the root config, so OpenClaw multi-agent setups - any agent with an explicit or implicit agentDir, including the default `main` agent - silently failed with "No API key found for provider X" on every Telegram/IDE message. The smoke test passed but the user's actual workflow was broken. 3 unrelated UX papercuts compounded the bad experience: * Smoke test only verified OCP direct connectivity, never the IDE/agent -> OCP path, so the script printed "Smoke test passed" while the bot was silently broken. * `read ... </dev/tty 2>/dev/null || fallback` leaked `Device not configured` errors from the parent shell in CI/SSH/no-tty environments. The fallback path worked correctly, but the stderr noise looked like a bug. * Help text claimed `Detects and configures IDEs (OpenClaw, Cline, Continue.dev, Cursor)` while only OpenClaw is actually configured. Full investigation, evidence, and reviewer findings in #12. ## What this commit does ### B1: write per-agent auth-profiles.json (CRITICAL) After writing root openclaw.json, iterate `agents.list[]`. For each agent: derive agentDir from the explicit `agentDir` field, OR fall back to `<openclaw_root>/agents/<id>/agent/` for agents that omit it. This catches the default `main` agent, discovered via end-to-end Telegram testing. Merge into existing auth-profiles.json (preserving other providers' keys), upsert `<provider>:default` with the real key, chmod 0600. Anonymous mode (no --key) explicitly skips agentDir writes (empty keys are dropped by OpenClaw's pi-auth-credentials anyway) and prints a clear warning that OpenClaw multi-agent requires --key. This is the "Path C" decision from #12 section 14. Error handling is split for safety: * `JSONDecodeError` on existing file -> back up to `.bak`, rebuild * `OSError` on read -> skip this agent. Do NOT clobber the user's existing profile, which may hold other providers' real keys. * `OSError` on mkdir/write -> record in `_failed` list, surface in output. Not silently swallowed. Three independent report sections (`_seeded` / `_failed` / `_skipped_anonymous`) so mixed scenarios don't hide warnings behind each other. ### B2: smoke test caveat After "Smoke test passed", append three lines explaining that the test only verifies OCP direct connectivity, and instructing the user to restart OpenClaw and send a real bot message to verify end-to-end. ### B3: suppress /dev/tty stderr Wrap all four `read ... </dev/tty` calls as `{ read ... </dev/tty; } 2>/dev/null || fallback` so the brace group captures the shell's own `Device not configured` error before it reaches the user's terminal. The fallback semantics are unchanged. ### B6: help text wording Change item 5 from old wording mentioning IDE auto-configuration to "Configures OpenClaw automatically; prints setup hints for other IDEs - manual configuration required". Detection logic itself is NOT changed in this commit. That is deferred to a future PR. See #12 section 9 for details. ### Version bump Per dev iron rule #5 (version bump before push): * `OCP_CONNECT_VERSION="1.1.0"` constant * `--version` CLI flag * Banner shows version ## Test evidence End-to-end verified on macOS 13 with the actual OpenClaw 2026.4.11 + Telegram bot setup that exposed #12: 1. cold-install state (clean ~/.openclaw, no agent profiles) 2. run `ocp-connect 172.16.2.30 --key ocp_xxx` -> exit 0 3. verify both `~/.openclaw/agents/main/agent/auth-profiles.json` and `~/.openclaw/agents/macbook_bot/agent/auth-profiles.json` are written with mode 0600 and the real key 4. restart gateway -> `agent model: ocp/claude-sonnet-4-6` loads 5. send a real Telegram message -> bot responds via `ocp/claude-sonnet-4-6`, `[telegram] sendMessage ok`, `auth-state.json` updates `lastUsed` and shows `errorCount: 0, lastGood: ocp:default` 6. zero `No API key found` / 401 / lane-error events anywhere Offline test matrix (also all green): * anonymous mode -> warning prints, no agentDir write * corrupted existing auth-profiles.json -> backed up to .bak, rebuilt * no-tty execution -> 0 `Device not configured` leakage * `--help` -> new B6 wording * `--version` -> `ocp-connect 1.1.0` ## Code review Two independent reviewer subagents (opus, spec compliance + code quality) plus one blind implementer subagent (sonnet, control group). The blind implementer reproduced exactly the two MUST-FIX issues the code-quality reviewer flagged in the first draft (silent data loss on `except Exception`, misleading success on per-agent write failure), validating that the review process caught real non-obvious problems. Both must-fixes are addressed in this commit; re-tested green. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(ocp-connect): drop "with agentDir" from anonymous warning The message previously said "agents with agentDir" but B1.5 now also seeds agents that omit the field (their dir is derived). Reviewer feedback on PR #13. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: taodeng <taodeng@Taos-MBP> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|
|
47434a8ba7 |
fix: security hardening + real streaming (#4)
* Add graceful shutdown handling for SIGTERM and SIGINT On receiving SIGTERM or SIGINT, the server now: 1. Stops accepting new connections (server.close) 2. Clears session cleanup and auth check intervals 3. Sends SIGTERM to all active child processes 4. Waits up to 5s for processes to exit, then SIGKILL + exit(1) 5. Exits cleanly with exit(0) once all processes are gone Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: security hardening — bind localhost, validate models, limit body size - Bind to 127.0.0.1 instead of 0.0.0.0 to prevent network exposure - Restrict CORS Access-Control-Allow-Origin to http://127.0.0.1 - Add 10MB request body size limit (413 on exceed) - Validate model parameter against known MODEL_MAP keys (400 on unknown) - Remove catch-all POST route; only /v1/chat/completions accepted - Use crypto.timingSafeEqual for API key comparison - Sanitize error messages to strip internal file paths Bumps version to 2.4.1. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: replace fake streaming with real stdout-piped SSE streaming Previously, streaming requests waited for the entire claude CLI process to complete, then split the output into artificial 500-char chunks sent as SSE events. This defeated the purpose of streaming and added latency. Now, stdout from the claude child process is piped directly to SSE chunks as data arrives. Each `data` event from the process stdout becomes an immediate SSE delta event, giving clients real incremental output. The shared process setup logic is extracted into spawnClaudeProcess() to avoid duplication between streaming and non-streaming paths. Client disconnect detection kills the child process to free resources. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: tighten CORS to dynamic localhost-only and reduce body limit to 5MB - CORS now dynamically matches localhost/127.0.0.1 origins instead of static http://127.0.0.1, preventing cross-origin abuse while supporting any localhost port - Body size limit reduced from 10MB to 5MB to limit OOM risk Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Oracle Public Cloud User <opc@instance-20230820-1333.subnet07301351.vcn07301351.oraclevcn.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> |