diff --git a/docs/architecture/task-control-plane-unification.md b/docs/architecture/task-control-plane-unification.md
index ad6769fc..37b89ccd 100644
--- a/docs/architecture/task-control-plane-unification.md
+++ b/docs/architecture/task-control-plane-unification.md
@@ -20,23 +20,8 @@ Last Updated: 2026-04-08
- ACP 是统一控制面
- `single-agent / multi-agent / gateway` 是 ACP 解析后的执行器分支
-## 当前事实
-
-| 客户端 | 非 App Store Desktop | App Store Desktop | Web | Mobile |
-| --- | --- | --- | --- | --- |
-| 启动/入口 | Desktop UI 可桥接到 bundled / build artifact 的 `xworkmate-go-core` | 不启动任何本机 `xworkmate-go-core` / `codex app-server` 进程 | 通过 `GoTaskService.executeTask` 连接本地或远程 ACP `xworkmate-go-core` | 通过 `GoTaskService.executeTask` 连接远程 ACP `xworkmate-go-core` |
-| 执行语义 | 仍然收敛到 ACP Control Plane / `resolvedExecutionTarget` | 只保留 remote ACP / gateway 路由 | local / remote ACP 都是同一执行面 | remote ACP 是唯一允许的执行面 |
-
-补充说明:
-
-- Desktop 非 App Store 构建可以保留本机 go-core 桥接能力。
-- App Store 构建必须把本机 `xworkmate-go-core` / `codex app-server` 启动路径全部关掉。
-- Web 的 `local / remote` 只是 ACP 接入目标的差异,不是另一套执行模型。
-- Mobile 只允许远程 ACP,不能走本机 go-core 进程。
-- `single-agent / multi-agent / gateway` 仍然只是 ACP 解析后的执行器分支,不是 UI 产品线。
## 目标态
-
```mermaid
flowchart TD
A["Desktop / Web / Mobile UI"] --> B["sendMessage
统一 Task Envelope"]
diff --git a/docs/architecture/xworkmate-integrations.md b/docs/architecture/xworkmate-integrations.md
index cea7155e..e18eef37 100644
--- a/docs/architecture/xworkmate-integrations.md
+++ b/docs/architecture/xworkmate-integrations.md
@@ -7,13 +7,6 @@ XWorkmate 现阶段已经不只是“单一 Codex bridge”,但当前实现也
本文件只说明集成能力与 adapter 边界,不承担任务工作流主叙事。
-### 平台入口矩阵
-
-- Desktop 非 App Store:可桥接 bundled / build artifact 的 `xworkmate-go-core`
-- Desktop App Store:不启动任何本机 `xworkmate-go-core` / `codex app-server`
-- Web:可连接本地或远程 ACP `xworkmate-go-core`
-- Mobile:只连接远程 ACP `xworkmate-go-core`
-
任务工作流主叙事统一以
[任务执行链路统一收敛](/Users/shenlan/workspaces/cloud-neutral-toolkit/xworkmate-task-control-plane-unification/docs/architecture/task-control-plane-unification.md)
为准。
diff --git a/docs/cases/core-integration-manual-cases.md b/docs/cases/core-integration-manual-cases.md
index ca992bf0..2ff876bc 100644
--- a/docs/cases/core-integration-manual-cases.md
+++ b/docs/cases/core-integration-manual-cases.md
@@ -63,7 +63,6 @@
### `MANUAL-ACP-003` local ACP / local 模式接入
- 前置条件
- - 非 App Store 桌面构建,或 Web 端 local ACP 验证
- 本机已有 local / loopback ACP 服务
- 确认监听地址与端口
- 操作步骤
@@ -75,8 +74,6 @@
- local / loopback 非 TLS 允许通过
- 页面明确显示当前为本地配置
- 不会把 local endpoint 错误识别为 remote insecure endpoint
-- 备注
- - App Store 桌面构建不执行此 case,只保留 remote ACP 验证。
- 建议记录项
- 当前模式
- loopback endpoint
diff --git a/docs/codex-integration/tasks.md b/docs/codex-integration/tasks.md
index 4c9f77dc..346e4adb 100644
--- a/docs/codex-integration/tasks.md
+++ b/docs/codex-integration/tasks.md
@@ -2,15 +2,13 @@
## 当前结论
-XWorkmate 当前唯一可交付的 Codex 集成路径是 **external CLI**,但只适用于非 App Store 的桌面构建:
+XWorkmate 当前唯一可交付的 Codex 集成路径是 **external CLI**:
- 通过 `CodexRuntime.startStdio()` 拉起外部 `codex app-server`
- 通过 `CodexConfigBridge` 把 AI Gateway 写入 `~/.codex/config.toml`
- 通过 `CodeAgentNodeOrchestrator` 把 XWorkmate 固定为 `app-mediated cooperative node`
- 通过 `RuntimeCoordinator` 保留多外部 Code Agent CLI 的统一 registry surface
-App Store 桌面构建不应再拉起本机 `codex app-server`,而应只保留远程 ACP / gateway 语义。
-
Rust FFI / built-in Codex 仍是 future placeholder,不应宣传为已完成。
## 能力补全清单(按需求项)
@@ -47,7 +45,6 @@ Rust FFI / built-in Codex 仍是 future placeholder,不应宣传为已完成
- `chat.send` 的 app-mediated node metadata
- 本地降级:Gateway 不可用时,外部 Codex 仍可运行
- `CodexConfigBridge` 对 `~/.codex/config.toml` 采用非破坏性写入(仅更新 XWorkmate 托管块,保留原有配置)
-- 仅在非 App Store 的桌面构建中执行外部 Codex CLI 启动
非目标:
diff --git a/docs/reports/codex-integration-status-actual.md b/docs/reports/codex-integration-status-actual.md
index 35151470..3fa76cd9 100644
--- a/docs/reports/codex-integration-status-actual.md
+++ b/docs/reports/codex-integration-status-actual.md
@@ -1,20 +1,20 @@
# XWorkmate Codex 集成实际状态
-更新时间:2026-04-08
+更新时间:2026-03-14
## 当前结论
-XWorkmate 当前唯一可交付的 Codex 集成路径是 **External Codex CLI**。非 App Store 的桌面构建可以拉起本机 `codex app-server`,App Store 桌面构建则不允许这样做。
+XWorkmate 当前唯一可交付的 Codex 集成路径是 **External Codex CLI**。
当前已落地的真实链路:
1. 用户在 `设置 > 集成 > AI Gateway > 工具` 显式启用 Bridge。
2. XWorkmate 通过 `CodexConfigBridge` 写入 `~/.codex/config.toml`,把 AI Gateway 暴露给 Codex。
-3. XWorkmate 在非 App Store 桌面构建中通过 `CodexRuntime.startStdio()` 拉起外部 `codex app-server --listen stdio://`;App Store 桌面构建不会启动这个本机进程。
+3. XWorkmate 通过 `CodexRuntime.startStdio()` 拉起外部 `codex app-server --listen stdio://`。
4. XWorkmate 通过 `CodeAgentNodeOrchestrator` 生成 app-mediated node dispatch metadata,并在 `chat.send` 时发送给 OpenClaw Gateway。
5. 如果 OpenClaw Gateway 已连接,XWorkmate 会执行一次 `agent/register`,把自己注册为协同 `code-agent-bridge`。
-这意味着当前架构是 **app-mediated RPC bridge**,不是 `Codex CLI` 和 `OpenClaw Gateway` 直接互连;App Store 桌面版本则只保留远程 ACP / gateway 路径。
+这意味着当前架构是 **app-mediated RPC bridge**,不是 `Codex CLI` 和 `OpenClaw Gateway` 直接互连。
## 已完成
@@ -25,10 +25,10 @@ XWorkmate 当前唯一可交付的 Codex 集成路径是 **External Codex CLI**
- `AppController.enableCodexBridge()` 已改为显式执行完整链路:
- 校验 AI Gateway 配置
- 导出 Codex bridge 配置
- - 在非 App Store 桌面构建中启动外部 Codex CLI 进程
+ - 启动外部 Codex CLI 进程
- Gateway 已连接时执行 `agent/register`
- `AppController.sendChatMessage()` 已不再直接裸调 Gateway chat,而是先构造 app-mediated node dispatch envelope
-- Gateway 不可用时,Bridge 会在非 App Store 桌面构建中降级为本地运行,外部 Codex 进程不会因为注册失败而被终止
+- Gateway 不可用时,Bridge 会降级为本地运行,外部 Codex 进程不会因为注册失败而被终止
- `AgentRegistry.register()` 已支持真实 `transport` metadata,不再把外部桥接伪装成固定 `in-process`
### 2. 外部 CLI 预留能力
@@ -54,7 +54,6 @@ XWorkmate 当前唯一可交付的 Codex 集成路径是 **External Codex CLI**
- Gateway 协同注册状态
- `builtIn` 仍保留在 enum 中,但 UI 只显示为 `Experimental`
- 若用户选择 `builtIn`,设置会被保留,并以实验态提示风险
-- Desktop UI 继续沿用本地 bridge / external CLI 路径,但 App Store 桌面构建除外
- Scheduled Tasks 页面明确为 `cron.list` 只读展示
- Memory 只表述为 `memory/sync` 同步能力,不宣传 CRUD
- OpenClaw Gateway 看到的是 `XWorkmate App node`,CLI 仍保持在 App 后端 runtime 边界内
@@ -98,7 +97,7 @@ XWorkmate 当前唯一可交付的 Codex 集成路径是 **External Codex CLI**
```mermaid
flowchart LR
- X["XWorkmate App"] --> C["External Codex CLI\n(Non-App Store Desktop only)"]
+ X["XWorkmate App"] --> C["External Codex CLI\n(JSON-RPC over stdio)"]
C --> A["AI Gateway"]
X --> G["OpenClaw Gateway\n(WebSocket RPC)"]
X --> R["agent/register\ncode-agent-bridge"]
diff --git a/integration_test/desktop_navigation_flow_test.dart b/integration_test/desktop_navigation_flow_test.dart
index 085f43a9..d2ff9a4a 100644
--- a/integration_test/desktop_navigation_flow_test.dart
+++ b/integration_test/desktop_navigation_flow_test.dart
@@ -1,40 +1,8 @@
-import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import '../test/helpers/test_keys.dart';
import 'test_support.dart';
-Finder _textEither(String zh, String en) {
- return find.byWidgetPredicate(
- (widget) => widget is Text && (widget.data == zh || widget.data == en),
- );
-}
-
-Future _ensureSettingsFocused(WidgetTester tester) async {
- final activeSettings = find.byKey(
- const ValueKey('assistant-focus-active-title-settings'),
- );
- if (activeSettings.evaluate().isNotEmpty) {
- return;
- }
- final addSettingsChip = find.byKey(
- const ValueKey('assistant-focus-add-settings'),
- );
- if (addSettingsChip.evaluate().isNotEmpty) {
- await tester.tap(addSettingsChip);
- await settleIntegrationUi(tester);
- return;
- }
- final addMenu = find.byKey(const Key('assistant-focus-add-menu'));
- expect(addMenu, findsOneWidget);
- await tester.tap(addMenu);
- await settleIntegrationUi(tester);
- final settingsItem = _textEither('设置', 'Settings');
- expect(settingsItem, findsWidgets);
- await tester.tap(settingsItem.last);
- await settleIntegrationUi(tester);
-}
-
void main() {
initializeIntegrationHarness();
@@ -42,30 +10,37 @@ void main() {
await resetIntegrationPreferences();
});
- testWidgets('desktop shell opens focused navigation surface', (
+ testWidgets('desktop shell can navigate from assistant to settings and back', (
WidgetTester tester,
) async {
await pumpDesktopApp(tester);
- await waitForIntegrationFinder(tester, find.byKey(TestKeys.assistantTaskRail));
-
- expect(_textEither('新对话', 'New conversation'), findsWidgets);
- await tester.tap(
- find.byKey(const Key('assistant-side-pane-tab-navigation')),
+ await waitForIntegrationFinder(
+ tester,
+ find.byKey(TestKeys.assistantConversationShell),
);
+
+ expect(find.byKey(TestKeys.workspaceSidebarNewTaskButton), findsOneWidget);
+ expect(find.byKey(TestKeys.assistantExecutionTargetButton), findsOneWidget);
+
+ await tester.tap(find.byKey(TestKeys.sidebarFooterSettings));
await settleIntegrationUi(tester);
expect(
- find.byKey(const Key('assistant-focus-panel-title')),
+ find.byKey(TestKeys.settingsGatewayTab),
findsOneWidget,
);
- await _ensureSettingsFocused(tester);
expect(
- find.byKey(
- const ValueKey('assistant-focus-active-title-settings'),
- ),
+ find.byKey(TestKeys.settingsIntegrationsTab),
findsOneWidget,
);
- await tester.pumpWidget(const SizedBox.shrink());
+ await tester.tap(find.byKey(const ValueKey('workspace-breadcrumb-0')));
await settleIntegrationUi(tester);
+ await waitForIntegrationFinder(
+ tester,
+ find.byKey(TestKeys.assistantConversationShell),
+ );
+
+ expect(find.byKey(TestKeys.assistantConversationShell), findsOneWidget);
+ expect(find.byKey(TestKeys.assistantComposerInput), findsOneWidget);
});
}
diff --git a/integration_test/desktop_settings_flow_test.dart b/integration_test/desktop_settings_flow_test.dart
index 8ba5168b..485aa395 100644
--- a/integration_test/desktop_settings_flow_test.dart
+++ b/integration_test/desktop_settings_flow_test.dart
@@ -1,40 +1,8 @@
-import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import '../test/helpers/test_keys.dart';
import 'test_support.dart';
-Finder _textEither(String zh, String en) {
- return find.byWidgetPredicate(
- (widget) => widget is Text && (widget.data == zh || widget.data == en),
- );
-}
-
-Future _ensureSettingsFocused(WidgetTester tester) async {
- final activeSettings = find.byKey(
- const ValueKey('assistant-focus-active-title-settings'),
- );
- if (activeSettings.evaluate().isNotEmpty) {
- return;
- }
- final addSettingsChip = find.byKey(
- const ValueKey('assistant-focus-add-settings'),
- );
- if (addSettingsChip.evaluate().isNotEmpty) {
- await tester.tap(addSettingsChip);
- await settleIntegrationUi(tester);
- return;
- }
- final addMenu = find.byKey(const Key('assistant-focus-add-menu'));
- expect(addMenu, findsOneWidget);
- await tester.tap(addMenu);
- await settleIntegrationUi(tester);
- final settingsItem = _textEither('设置', 'Settings');
- expect(settingsItem, findsWidgets);
- await tester.tap(settingsItem.last);
- await settleIntegrationUi(tester);
-}
-
void main() {
initializeIntegrationHarness();
@@ -46,23 +14,25 @@ void main() {
'desktop shell exposes settings entry for gateway configuration',
(WidgetTester tester) async {
await pumpDesktopApp(tester);
- await waitForIntegrationFinder(tester, find.byKey(TestKeys.assistantTaskRail));
-
- await tester.tap(
- find.byKey(const Key('assistant-side-pane-tab-navigation')),
+ await waitForIntegrationFinder(
+ tester,
+ find.byKey(TestKeys.assistantConversationShell),
);
+
+ await tester.tap(find.byKey(TestKeys.sidebarFooterSettings));
await settleIntegrationUi(tester);
expect(
- find.byKey(const Key('assistant-focus-panel-title')),
+ find.byKey(TestKeys.settingsGatewayTab),
findsOneWidget,
);
- await _ensureSettingsFocused(tester);
+ expect(find.byKey(TestKeys.settingsIntegrationsTab), findsOneWidget);
+ await tester.tap(find.byKey(TestKeys.settingsIntegrationsTab));
+ await settleIntegrationUi(tester);
expect(
- find.byKey(
- const ValueKey('assistant-focus-active-title-settings'),
- ),
+ find.byKey(TestKeys.settingsExternalAcpProvider),
findsOneWidget,
);
+ expect(find.byKey(TestKeys.settingsExternalAcpEndpoint), findsOneWidget);
await tester.pumpWidget(const SizedBox.shrink());
await settleIntegrationUi(tester);
diff --git a/integration_test/home_flow_test.dart b/integration_test/home_flow_test.dart
index fc0cc7ec..f2b9217e 100644
--- a/integration_test/home_flow_test.dart
+++ b/integration_test/home_flow_test.dart
@@ -1,4 +1,3 @@
-import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import '../test/helpers/test_keys.dart';
@@ -12,13 +11,16 @@ void main() {
) async {
await resetIntegrationPreferences();
await pumpDesktopApp(tester);
- await waitForIntegrationFinder(tester, find.byKey(TestKeys.assistantTaskRail));
+ await waitForIntegrationFinder(
+ tester,
+ find.byKey(TestKeys.assistantConversationShell),
+ );
- expect(find.byKey(TestKeys.assistantTaskRail), findsOneWidget);
- expect(find.byKey(TestKeys.assistantNewTaskButton), findsOneWidget);
+ expect(find.byKey(TestKeys.assistantConversationShell), findsOneWidget);
+ expect(find.byKey(TestKeys.workspaceSidebarNewTaskButton), findsOneWidget);
expect(find.byKey(TestKeys.assistantExecutionTargetButton), findsOneWidget);
expect(find.byKey(TestKeys.assistantComposerInput), findsOneWidget);
- expect(find.byKey(TestKeys.assistantSubmitButton), findsOneWidget);
+ expect(find.byKey(TestKeys.assistantSendButton), findsOneWidget);
expect(
find.byKey(TestKeys.assistantExecutionTargetMenuItemSingleAgent),
@@ -34,49 +36,18 @@ void main() {
find.byKey(TestKeys.assistantSingleAgentProviderButton),
findsOneWidget,
);
- expect(find.text('ACP Server'), findsOneWidget);
+ expect(find.text('ACP Server Local'), findsOneWidget);
});
- testWidgets(
- 'core flow 02 can submit a prompt in single agent mode',
- (WidgetTester tester) async {
- await resetIntegrationPreferences();
- await pumpDesktopApp(tester);
- await waitForIntegrationFinder(
- tester,
- find.byKey(TestKeys.assistantTaskRail),
- );
-
- await switchNewConversationExecutionTargetForIntegration(
- tester,
- find.byKey(TestKeys.assistantExecutionTargetMenuItemSingleAgent),
- );
-
- final prompt = '请回复:单机智能体提交成功';
- final composerInput = find.descendant(
- of: find.byKey(TestKeys.assistantComposerInput),
- matching: find.byType(TextField),
- );
-
- expect(composerInput, findsOneWidget);
-
- await tester.enterText(composerInput, prompt);
- await tester.tap(find.byKey(TestKeys.assistantSubmitButton));
- await settleIntegrationUi(tester);
-
- await waitForIntegrationFinder(tester, find.textContaining(prompt));
-
- expect(find.textContaining(prompt), findsWidgets);
- expect(tester.widget(composerInput).controller?.text, isEmpty);
- },
- );
-
- testWidgets('core flow 03 can switch a new conversation to local openclaw gateway', (
+ testWidgets('core flow 02 can switch a new conversation to local openclaw gateway', (
WidgetTester tester,
) async {
await resetIntegrationPreferences();
await pumpDesktopApp(tester);
- await waitForIntegrationFinder(tester, find.byKey(TestKeys.assistantTaskRail));
+ await waitForIntegrationFinder(
+ tester,
+ find.byKey(TestKeys.assistantConversationShell),
+ );
await switchNewConversationExecutionTargetForIntegration(
tester,
@@ -86,12 +57,15 @@ void main() {
expect(find.textContaining('127.0.0.1:4317'), findsWidgets);
});
- testWidgets('core flow 04 can switch a new conversation to remote openclaw gateway', (
+ testWidgets('core flow 03 can switch a new conversation to remote openclaw gateway', (
WidgetTester tester,
) async {
await resetIntegrationPreferences();
await pumpDesktopApp(tester);
- await waitForIntegrationFinder(tester, find.byKey(TestKeys.assistantTaskRail));
+ await waitForIntegrationFinder(
+ tester,
+ find.byKey(TestKeys.assistantConversationShell),
+ );
await switchNewConversationExecutionTargetForIntegration(
tester,
diff --git a/integration_test/test_support.dart b/integration_test/test_support.dart
index 42a7fdde..01130da9 100644
--- a/integration_test/test_support.dart
+++ b/integration_test/test_support.dart
@@ -109,7 +109,14 @@ Future switchNewConversationExecutionTargetForIntegration(
WidgetTester tester,
Finder menuItemFinder,
) async {
- await tester.tap(find.byKey(const Key('assistant-new-task-button')));
+ final desktopNewTaskButton = find.byKey(
+ const Key('workspace-sidebar-new-task-button'),
+ );
+ if (desktopNewTaskButton.evaluate().isNotEmpty) {
+ await tester.tap(desktopNewTaskButton);
+ } else {
+ await tester.tap(find.byKey(const Key('assistant-new-task-button')));
+ }
await settleIntegrationUi(tester);
await tester.tap(find.byKey(const Key('assistant-execution-target-button')));
await settleIntegrationUi(tester);
diff --git a/lib/app/app_controller_desktop_thread_sessions.dart b/lib/app/app_controller_desktop_thread_sessions.dart
index 570e5441..ad90f712 100644
--- a/lib/app/app_controller_desktop_thread_sessions.dart
+++ b/lib/app/app_controller_desktop_thread_sessions.dart
@@ -387,7 +387,7 @@ extension AppControllerDesktopThreadSessions on AppController {
);
final target = assistantExecutionTargetForSession(normalizedSessionKey);
if (target == AssistantExecutionTarget.singleAgent) {
- final primaryLabel = appText('ACP Server', 'ACP Server');
+ final primaryLabel = appText('ACP Server Local', 'ACP Server Local');
final provider = singleAgentProviderForSession(normalizedSessionKey);
final resolvedProvider = singleAgentResolvedProviderForSession(
normalizedSessionKey,
diff --git a/lib/app/app_controller_desktop_thread_storage.dart b/lib/app/app_controller_desktop_thread_storage.dart
index b3cfc244..aacd9fec 100644
--- a/lib/app/app_controller_desktop_thread_storage.dart
+++ b/lib/app/app_controller_desktop_thread_storage.dart
@@ -446,7 +446,7 @@ extension AppControllerDesktopThreadStorage on AppController {
path: resolvedRootPath,
bookmark: rootSpec.bookmark,
),
- );
+ );
if (accessHandle == null) {
continue;
}
@@ -544,6 +544,7 @@ extension AppControllerDesktopThreadStorage on AppController {
Future>
scanSingleAgentWorkspaceSkillEntriesInternal(String sessionKey) {
+ final workspacePath = assistantWorkspacePathForSession(sessionKey);
if (assistantWorkspaceKindForSession(sessionKey) !=
WorkspaceRefKind.localPath) {
return Future>.value(
@@ -552,7 +553,7 @@ extension AppControllerDesktopThreadStorage on AppController {
}
return scanSingleAgentSkillEntriesInternal(
AppController.defaultSingleAgentWorkspaceSkillScanRootsInternal,
- workspacePath: assistantWorkspacePathForSession(sessionKey),
+ workspacePath: workspacePath,
);
}
diff --git a/lib/runtime/aris_llm_chat_client.dart b/lib/runtime/aris_llm_chat_client.dart
index a91435b2..ef1673ae 100644
--- a/lib/runtime/aris_llm_chat_client.dart
+++ b/lib/runtime/aris_llm_chat_client.dart
@@ -97,7 +97,7 @@ class ArisLlmChatClient {
isAppleHost: Platform.isIOS || Platform.isMacOS,
)) {
throw UnsupportedError(
- 'App Store builds do not allow launching local Go core processes.',
+ 'App Store builds only allow the bundled Go core helper inside the app bundle.',
);
}
diff --git a/lib/runtime/embedded_agent_launch_policy.dart b/lib/runtime/embedded_agent_launch_policy.dart
index 8c4668db..b587df97 100644
--- a/lib/runtime/embedded_agent_launch_policy.dart
+++ b/lib/runtime/embedded_agent_launch_policy.dart
@@ -16,8 +16,11 @@ bool shouldBlockGoCoreLaunch(
required bool isAppleHost,
bool? enabled,
}) {
- return shouldApplyAppleAppStorePolicy(
+ if (!shouldApplyAppleAppStorePolicy(
isAppleHost: isAppleHost,
enabled: enabled,
- );
+ )) {
+ return false;
+ }
+ return launch.source != GoCoreLaunchSource.bundledHelper;
}
diff --git a/lib/runtime/runtime_bootstrap.dart b/lib/runtime/runtime_bootstrap.dart
index 732aaf2d..7db7a23d 100644
--- a/lib/runtime/runtime_bootstrap.dart
+++ b/lib/runtime/runtime_bootstrap.dart
@@ -26,7 +26,7 @@ class RuntimeBootstrapConfig {
workspaceRoot,
cliPathHint: cliPathHint,
);
- final env = await _loadEnvFile(
+ final env = _loadEnvFile(
workspacePathHint: workspacePathHint,
cliPathHint: cliPathHint,
workspaceRoot: workspaceRoot,
@@ -176,12 +176,12 @@ class GatewayBootstrapTarget {
}
}
-Future