feat(core): add LARKSUITE_CLI_FORCE_LOCAL to bypass workspace auto-detection
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 17.3k
- Forks
- 1.4k
- Avg merge
- 2d 4h
- Merged PRs (30d)
- 105
Description
问题
DetectWorkspaceFromEnv(internal/core/workspace.go:102-124)把 OPENCLAW_HOME/OPENCLAW_STATE_DIR/OPENCLAW_CONFIG_PATH/OPENCLAW_GATEWAY_PORT 等 env 当作 workspace 信号,但这些 env 的本意是 OpenClaw 宿主做 state 目录隔离和 gateway 自身运行所需——并非"我在 OpenClaw workspace 里"的声明。这造成 state-relocation / gateway 运行与 workspace 路由的语义错位。
源码注释(workspace.go:83-89)说明 OPENCLAW_CLI=1 是"现代 build 用的精确 subprocess marker",OPENCLAW_HOME/STATE_DIR/CONFIG_PATH 等是 legacy fallback 信号。但两者都触发 WorkspaceOpenClaw——OPENCLAW_CLI=1 不是"绕过检测",是"显式干净地进入 openclaw 模式"。下游目前没有一个"显式说不"的入口,只能靠"枚举并剥光所有 OPENCLAW_* env"来规避误判,但这不可靠。
设计层面的两个问题
-
fallback 信号语义错位:
OPENCLAW_HOME/STATE_DIR/CONFIG_PATH是 state-relocation 入口,OPENCLAW_GATEWAY_PORT是 gateway 运行必需(gateway 进程必须知道自己的监听端口)——把它们当作 workspace 信号是把"宿主应用做 state 隔离 / gateway 自身运行"误读为"声明进入 openclaw workspace"。下游即使未设OPENCLAW_CLI=1(即未声明进入 openclaw 模式),仍会被 fallback 检测误判。 -
OPENCLAW_GATEWAY_PORT不可剥:作为 gateway 运行的必然产物,下游无法通过剥 env 规避误判——这使"剥 env"路径在机制上不可行,下游没有干净的 opt-out 入口。
后果
任何 OpenClaw 宿主应用只要做 state 隔离(设 OPENCLAW_HOME 等)或启动 gateway(必然设 OPENCLAW_GATEWAY_PORT),其调用的 lark-cli 就会被路由到 <base>/openclaw/ 子目录,而不是 <base>/。这迫使下游维护一系列 workaround:
- 在不同调用入口手动注入
OPENCLAW_*env 对齐路径(避免 split-brain) - 用 direct-write mirror 把独立模式配置镜像到 openclaw 子目录
- 直接写
bind.json,绕过cmd/auth/login.go的 identity policy enforcement——安全降级 - 反向工程
DetectWorkspaceFromEnv的信号列表做 env 剥离,且无法应对OPENCLAW_GATEWAY_PORT这类剥不掉的信号
修复建议
新增 LARKSUITE_CLI_FORCE_LOCAL=1 env,在 DetectWorkspaceFromEnv 入口短路:
--- a/internal/core/workspace.go
+++ b/internal/core/workspace.go
@@ -102,6 +102,11 @@ func DetectWorkspaceFromEnv(getenv func(string) string) Workspace {
+ // LARKSUITE_CLI_FORCE_LOCAL lets OpenClaw host apps explicitly opt out
+ // of workspace auto-detection. These apps set OPENCLAW_HOME for state
+ // relocation and OPENCLAW_GATEWAY_PORT for gateway operation (not as
+ // workspace markers); auto-detection routes lark-cli into OpenClaw
+ // mode as a side effect. This env is the explicit "no" override,
+ // complementing OPENCLAW_CLI=1 (the explicit "yes" signal).
+ if getenv("LARKSUITE_CLI_FORCE_LOCAL") == "1" {
+ return WorkspaceLocal
+ }
+
if getenv("OPENCLAW_CLI") == "1" ||
getenv("OPENCLAW_HOME") != "" ||
理由:
- 延续 LARKSUITE_CLI_* 命名空间(已有 LARKSUITE_CLI_CONFIG_DIR、LARKSUITE_CLI_NO_UPDATE_NOTIFIER 等),下游自然对接。
- 与 OPENCLAW_CLI=1(显式"是")形成对偶——LARKSUITE_CLI_FORCE_LOCAL=1 是显式"否",覆盖所有 fallback 检测。
- 下游设一个 env 即可,无需反向工程检测信号列表;lark-cli 上游加新 OPENCLAW_* 信号也不影响。
- 解决 OPENCLAW_GATEWAY_PORT 这类"剥不掉"的 env 触发误判的问题——FORCE_LOCAL 短路在最前面,覆盖所有信号。
- 纯新增,100% 向后兼容。
兼容性
纯新增 env,不设此 env 的用户/应用行为不变。OPENCLAW_CLI=1、HOME fallback 等既有检测逻辑全部保留。
落地后下游可拆除的 workaround
- 各调用入口手动注入 OPENCLAW_* 对齐路径的逻辑
- independent → openclaw 的 direct-write mirror
- config init 前 env 剥离逻辑
- 直接写 bind.json(恢复走原生 config bind,回归 identity policy enforcement)
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at internal/core/workspace.go:102-124 and inspect DetectWorkspaceFromEnv, including the existing OPENCLAW_CLI=1 and fallback checks. Add the documented LARKSUITE_CLI_FORCE_LOCAL=1 early override, then verify that it returns WorkspaceLocal despite the OpenClaw environment signals while existing detection remains unchanged.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- cli
- Issue type
- Feature
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100