Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Q
qjclaw-dmg
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
AI-甘富林
qjclaw-dmg
Commits
782eb235
Commit
782eb235
authored
May 21, 2026
by
edy
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix(desktop): inject workspace path into workspace entry env
parent
94996437
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
56 additions
and
6 deletions
+56
-6
ipc.ts
apps/desktop/src/main/ipc.ts
+18
-4
workspace-entry-lobster-env.ts
.../desktop/src/main/services/workspace-entry-lobster-env.ts
+12
-0
workspace-entry-lobster-env-smoke.ts
build/scripts/workspace-entry-lobster-env-smoke.ts
+26
-2
No files found.
apps/desktop/src/main/ipc.ts
View file @
782eb235
...
...
@@ -69,7 +69,10 @@ import {
buildProjectModelRuntime
,
materializeProjectModelRuntime
}
from
"./services/project-model-runtime.js"
;
import
{
buildWorkspaceEntryLobsterEnv
}
from
"./services/workspace-entry-lobster-env.js"
;
import
{
buildWorkspaceEntryLobsterEnv
,
buildWorkspaceEntryWorkspacePathEnv
}
from
"./services/workspace-entry-lobster-env.js"
;
import
{
refreshProjectContextAfterExecution
,
shouldRefreshProjectContextAfterExecution
...
...
@@ -832,6 +835,11 @@ export function registerDesktopIpc(services: MainServices): RegisteredDesktopIpc
return buildWorkspaceEntryLobsterEnv(await secretManager.getApiKey());
};
const prepareWorkspaceEntryWorkspacePathEnv = async (): Promise<Record<string, string>> => {
const config = await configService.load();
return buildWorkspaceEntryWorkspacePathEnv(config.workspacePath);
};
const resolveConfiguredChatModel = async (config?: AppConfig) => {
const nextConfig = config ?? await getEffectiveConfig();
const baseUrl = nextConfig.expertModelConfig.copywriting.baseUrl.trim();
...
...
@@ -1998,6 +2006,7 @@ export function registerDesktopIpc(services: MainServices): RegisteredDesktopIpc
try {
if (preparedExecution.decision.kind === "
workspace
-
entry
") {
const lobsterEnv = await prepareWorkspaceEntryLobsterEnv();
const workspacePathEnv = await prepareWorkspaceEntryWorkspacePathEnv();
const projectModelEnv = await prepareProjectModelRuntime(
preparedExecution.sessionState.projectId,
preparedExecution.sessionState.projectRoot
...
...
@@ -2010,7 +2019,8 @@ export function registerDesktopIpc(services: MainServices): RegisteredDesktopIpc
attachments: preparedExecution.attachments,
extraEnv: {
...projectModelEnv,
...lobsterEnv
...lobsterEnv,
...workspacePathEnv
}
});
if ("
handoff
" in result) {
...
...
@@ -2142,6 +2152,7 @@ export function registerDesktopIpc(services: MainServices): RegisteredDesktopIpc
try {
if (decision.kind === "
workspace
-
entry
") {
const lobsterEnv = await prepareWorkspaceEntryLobsterEnv();
const workspacePathEnv = await prepareWorkspaceEntryWorkspacePathEnv();
const projectModelEnv = await prepareProjectModelRuntime(project.id, projectRoot);
const result = await projectWorkspaceExecutor.execute({
sessionId,
...
...
@@ -2151,7 +2162,8 @@ export function registerDesktopIpc(services: MainServices): RegisteredDesktopIpc
attachments: [],
extraEnv: {
...projectModelEnv,
...lobsterEnv
...lobsterEnv,
...workspacePathEnv
}
});
if ("
handoff
" in result) {
...
...
@@ -2473,6 +2485,7 @@ export function registerDesktopIpc(services: MainServices): RegisteredDesktopIpc
void (async () => {
try {
const lobsterEnv = await prepareWorkspaceEntryLobsterEnv();
const workspacePathEnv = await prepareWorkspaceEntryWorkspacePathEnv();
const projectModelEnv = await prepareProjectModelRuntime(
preparedExecution.sessionState.projectId,
preparedExecution.sessionState.projectRoot
...
...
@@ -2485,7 +2498,8 @@ export function registerDesktopIpc(services: MainServices): RegisteredDesktopIpc
attachments: preparedExecution.attachments,
extraEnv: {
...projectModelEnv,
...lobsterEnv
...lobsterEnv,
...workspacePathEnv
}
}, {
onStarted: (runId) => {
...
...
apps/desktop/src/main/services/workspace-entry-lobster-env.ts
View file @
782eb235
const
LOBSTER_KEY_REQUIRED_MESSAGE
=
"请先绑定龙虾密钥"
;
const
WORKSPACE_PATH_REQUIRED_MESSAGE
=
"请先设置工作目录"
;
export
function
buildWorkspaceEntryLobsterEnv
(
apiKey
:
string
|
undefined
):
Record
<
string
,
string
>
{
const
lobsterKey
=
apiKey
?.
trim
();
...
...
@@ -11,3 +12,14 @@ export function buildWorkspaceEntryLobsterEnv(apiKey: string | undefined): Recor
OPENCLAW_EMPLOYEE_API_KEY
:
lobsterKey
};
}
export
function
buildWorkspaceEntryWorkspacePathEnv
(
workspacePathInput
:
string
|
undefined
):
Record
<
string
,
string
>
{
const
workspacePath
=
workspacePathInput
?.
trim
();
if
(
!
workspacePath
)
{
throw
new
Error
(
WORKSPACE_PATH_REQUIRED_MESSAGE
);
}
return
{
QJCLAW_WORKSPACE_PATH
:
workspacePath
};
}
build/scripts/workspace-entry-lobster-env-smoke.ts
View file @
782eb235
import
{
mkdir
,
rm
,
writeFile
}
from
"node:fs/promises"
;
import
path
from
"node:path"
;
import
{
fileURLToPath
}
from
"node:url"
;
import
{
buildWorkspaceEntryLobsterEnv
}
from
"../../apps/desktop/src/main/services/workspace-entry-lobster-env.js"
;
import
{
buildWorkspaceEntryLobsterEnv
,
buildWorkspaceEntryWorkspacePathEnv
}
from
"../../apps/desktop/src/main/services/workspace-entry-lobster-env.js"
;
function
assert
(
condition
:
unknown
,
message
:
string
):
asserts
condition
{
if
(
!
condition
)
{
...
...
@@ -21,6 +24,18 @@ function assertThrowsMissingKey(input: string | undefined): void {
throw
new
Error
(
"Missing-key path did not throw."
);
}
function
assertThrowsMissingWorkspacePath
(
input
:
string
|
undefined
):
void
{
try
{
buildWorkspaceEntryWorkspacePathEnv
(
input
);
}
catch
(
error
)
{
assert
(
error
instanceof
Error
,
"Missing-workspace-path path should throw an Error."
);
assert
(
error
.
message
===
"请先设置工作目录"
,
"Missing-workspace-path error message changed."
);
return
;
}
throw
new
Error
(
"Missing-workspace-path path did not throw."
);
}
async
function
main
():
Promise
<
void
>
{
const
__filename
=
fileURLToPath
(
import
.
meta
.
url
);
const
__dirname
=
path
.
dirname
(
__filename
);
...
...
@@ -36,13 +51,22 @@ async function main(): Promise<void> {
assert
(
env
.
OPENCLAW_EMPLOYEE_API_KEY
===
"lobster-secret"
,
"Compatibility env var should use the trimmed key."
);
assert
(
Object
.
keys
(
env
).
length
===
2
,
"Workspace-entry lobster env should expose only the two expected variables."
);
const
workspacePathEnv
=
buildWorkspaceEntryWorkspacePathEnv
(
" /tmp/qjc-workspace "
);
assert
(
workspacePathEnv
.
QJCLAW_WORKSPACE_PATH
===
"/tmp/qjc-workspace"
,
"Workspace path env var should use the trimmed path."
);
assert
(
Object
.
keys
(
workspacePathEnv
).
length
===
1
,
"Workspace-entry workspace path env should expose only the expected variable."
);
assertThrowsMissingKey
(
undefined
);
assertThrowsMissingKey
(
""
);
assertThrowsMissingKey
(
" "
);
assertThrowsMissingWorkspacePath
(
undefined
);
assertThrowsMissingWorkspacePath
(
""
);
assertThrowsMissingWorkspacePath
(
" "
);
await
writeFile
(
resultPath
,
JSON
.
stringify
({
ok
:
true
,
envKeys
:
Object
.
keys
(
env
)
envKeys
:
Object
.
keys
(
env
),
workspacePathEnvKeys
:
Object
.
keys
(
workspacePathEnv
),
workspacePath
:
workspacePathEnv
.
QJCLAW_WORKSPACE_PATH
},
null
,
2
),
"utf8"
);
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment