fix: end-to-end working after laptop integration test

Discovered during smoke-testing on hzhang's laptop:

1. `--channels server:X --dangerously-load-development-channels server:X`
   makes Claude Code list the channel twice and the second copy never
   inherits dev-mode, leaving "server: entries need
   --dangerously-load-development-channels" stuck in the status panel.
   Fix: pass channel ONLY via --dangerously-load-development-channels.

2. Without a controlling TTY, Claude Code's dev-mode confirmation dialog
   blocks forever waiting for keystrokes that never arrive. Fix: spawn
   claude wrapped in `script -q -c CMD PTYLOG` so it gets a PTY, then
   write "\r" to stdin at several timeouts (cheap to over-send).

3. process-manager.markReady was matching on PID, but the PID in the
   bridge hello frame is the ClaudePlugin (bun) process's pid, not the
   script-wrapped claude process's pid we tracked. Fix: match on
   openclaw-session-key, which is consistent on both sides.

4. First spawn for a new session can't use --resume (no transcript exists
   yet) — claude errors out. Fix: probe
   ~/.claude/projects/<workspace-slug>/<uuid>.jsonl for existence and use
   --session-id on fresh sessions, --resume after a process restart.

5. Add --debug-file per session so future debugging has the gating logs.

6. Local definePluginEntry shim (no openclaw runtime dependency) so
   `bun index.ts` works standalone for laptop smoke tests.

End-to-end verified twice on laptop: curl POST -> SSE delta with the
exact reply text. Average cold-start ~10s, hot path 2-3s.
This commit is contained in:
zhi
2026-05-14 14:00:32 +00:00
parent 0324a47d13
commit 3229fbd024
3 changed files with 105 additions and 38 deletions

View File

@@ -1,5 +1,12 @@
import { definePluginEntry } from 'openclaw/plugin-sdk/plugin-entry'
import type { OpenClawPluginApi } from 'openclaw/plugin-sdk/core'
// Local `definePluginEntry` shim. The OpenClaw plugin runtime evaluates this
// module and calls .register() on the default export — it doesn't care where
// definePluginEntry came from. Defining it locally lets us run standalone
// (`bun index.ts`) without the `openclaw` package installed.
function definePluginEntry<T extends { id: string; name: string; description?: string; register: (api: any) => void | Promise<void> }>(opts: T): T {
return opts
}
type OpenClawPluginApi = unknown
import fs from 'node:fs'
import path from 'node:path'
import { normalizeConfig, type SynthesisConfig } from './core/config.js'