Rename ARIS bridge to go core

This commit is contained in:
Haitao Pan 2026-03-23 20:59:18 +08:00
parent 293278961e
commit bd76a91130
23 changed files with 112 additions and 116 deletions

View File

@ -47,12 +47,12 @@
- Assistant 任务线程升级为持续会话:支持流式回复、继续追问、线程归档和重启恢复。
- 任务列表按 `单机智能体 / 本地 OpenClaw Gateway / 远程 OpenClaw Gateway` 分组,保持极简列表布局。
- Multi-Agent 协作正式升级为 `Architect / Engineer / Tester`,并可选 `ARIS` 作为最强协作框架。
- ARIS bundle 作为只读资产内嵌进 App`skills/` 直接复用 upstream`llm-chat` 与 `claude-review` 切到 Go bridge。
- `Ollama Cloud` 文案与默认地址统一,打包后的 `.app` 会随同分发 `xworkmate-aris-bridge` helper。
- ARIS bundle 作为只读资产内嵌进 App`skills/` 直接复用 upstream`llm-chat` 与 `claude-review` 切到 Go core。
- `Ollama Cloud` 文案与默认地址统一,打包后的 `.app` 会随同分发 `xworkmate-go-core` helper。
### Current Delivery Scope
- 已交付Single Agent streaming threads、OpenClaw 本地/远程任务线程、手动归档与持续会话恢复。
- 已交付Multi-Agent managed runtime、ARIS framework preset、本地优先 Ollama 回退、Go bridge runtime 和打包分发。
- 已交付Multi-Agent managed runtime、ARIS framework preset、本地优先 Ollama 回退、Go core runtime 和打包分发。
- 已交付Settings / Assistant 里的 ARIS 轻量状态展示、任务分组、Ollama Cloud 设置迁移。
- 保持 truth-firstScheduled Tasks 仍是 `cron.list` 只读视图Memory 仍是 `memory/sync` 同步能力,不宣传 CRUD。

View File

@ -8,7 +8,7 @@ DART ?= dart
DEVICE ?= macos
APP_STORE_DART_DEFINE ?= --dart-define=XWORKMATE_APP_STORE=true
.PHONY: help deps analyze test check format run build-linux build-macos build-ios-sim package-deb package-rpm package-linux package-mac install-mac clean build-aris-bridge render-release-docs
.PHONY: help deps analyze test check format run build-linux build-macos build-ios-sim package-deb package-rpm package-linux package-mac install-mac clean build-go-core render-release-docs
help: ## Show available targets
@grep -E '^[a-zA-Z0-9_.-]+:.*?## ' Makefile | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "%-18s %s\n", $$1, $$2}'
@ -42,8 +42,8 @@ build-macos: ## Build the macOS app in release mode
build-ios-sim: ## Build the iOS app for the simulator
$(FLUTTER) build ios --simulator $(APP_STORE_DART_DEFINE)
build-aris-bridge: ## Build the ARIS Go bridge helper
bash scripts/build-aris-bridge.sh
build-go-core: ## Build the Go core helper
bash scripts/build-go-core.sh
package-deb: ## Create the Linux .deb package
bash scripts/package-linux-deb.sh

View File

@ -1,14 +1,14 @@
# XWorkmate
XWorkmate is an AI workspace shell built with Flutter.
`v0.5` ships persistent assistant task threads, optional ARIS-powered multi-agent collaboration, and a bundled Go bridge runtime that travels with the macOS app.
`v0.5` ships persistent assistant task threads, optional ARIS-powered multi-agent collaboration, and a bundled Go core runtime that travels with the macOS app.
## v0.5 Highlights
- Assistant 任务线程支持流式回复、继续追问和手动归档,不再是一问一答即结束。
- 任务列表按 `单机智能体 / 本地 OpenClaw Gateway / 远程 OpenClaw Gateway` 分组显示。
- Multi-Agent 协作支持 `Architect / Engineer / Tester`,并可切换 `Native / ARIS` 框架。
- ARIS `skills/` 直接随 App 内置,`llm-chat` 与 `claude-review` 统一由 Go bridge 驱动。
- ARIS `skills/` 直接随 App 内置,`llm-chat` 与 `claude-review` 统一由 Go core 驱动。
- `Ollama Cloud` 设置、ARIS helper bundling、macOS DMG 打包与安装链路已打通。
## Current Scope
@ -17,7 +17,7 @@ XWorkmate is an AI workspace shell built with Flutter.
- Single Agent streaming assistant threads
- OpenClaw local/remote task threads with persistent context
- Multi-Agent orchestration with optional ARIS preset
- Bundled ARIS skills, Go bridge helper, `llm-chat` reviewer, and `claude-review`
- Bundled ARIS skills, Go core helper, `llm-chat` reviewer, and `claude-review`
- Ollama Cloud settings, task grouping, and macOS packaged delivery
- Flutter Web shell with `Assistant` + `Settings` only, supporting `Single Agent` and `Relay OpenClaw Gateway`

View File

@ -7,7 +7,7 @@
- `远程 OpenClaw Gateway`
- `ARIS + 本地 Ollama`
- `Architect / Engineer / Tester`
- `Go bridge reviewer`
- `Go core reviewer`
- `外部 Agent CLI / JSON-RPC session`
## 推荐验证顺序
@ -29,7 +29,7 @@
- 本地 Ollama 可用时,即便缺失部分云端 CLI也应能退化运行
- 线程应可继续追问,不是一答即结束
- 任务列表仍保持极简,只显示名称、时间、归档
- `llm-chat``claude-review` 由 Go bridge 驱动,不依赖 `go run`
- `llm-chat``claude-review` 由 Go core 驱动,不依赖 `go run`
## 建议记录项

View File

@ -2,13 +2,13 @@
## 目标
验证 `Go bridge` 驱动的 reviewer / CLI 会话是持续的 session而不是一次 prompt 一次退出。
验证 `Go core` 驱动的 reviewer / CLI 会话是持续的 session而不是一次 prompt 一次退出。
## 推荐配置
- 框架:`ARIS`
- 本地 Ollama 可用
- `llm-chat` / `claude-review` 走 Go bridge
- `llm-chat` / `claude-review` 走 Go core
- Assistant 使用现有线程,不切新页面
## 建议任务

View File

@ -1,4 +1,4 @@
module xworkmate/aris_bridge
module xworkmate/go_core
go 1.25.0

View File

@ -203,7 +203,7 @@ func handleToolBridgeRequest(request rpcRequest) map[string]any {
"tools": map[string]any{},
},
"serverInfo": map[string]any{
"name": "xworkmate-aris-bridge",
"name": "xworkmate-go-core",
"version": "0.2.0",
},
},

View File

@ -12,7 +12,7 @@ import '../i18n/app_language.dart';
import '../models/app_models.dart';
import '../runtime/device_identity_store.dart';
import '../runtime/aris_bundle.dart';
import '../runtime/aris_bridge.dart';
import '../runtime/go_core.dart';
import '../runtime/runtime_bootstrap.dart';
import '../runtime/desktop_platform_service.dart';
import '../runtime/gateway_runtime.dart';
@ -151,14 +151,14 @@ class AppController extends ChangeNotifier {
_availableSingleAgentProvidersOverride =
availableSingleAgentProvidersOverride;
_arisBundleRepository = ArisBundleRepository();
_arisBridgeLocator = ArisBridgeLocator();
_goCoreLocator = GoCoreLocator();
_singleAgentRunner =
singleAgentRunner ??
DefaultSingleAgentRunner(appServerClient: _singleAgentAppServerClient);
_multiAgentOrchestrator = MultiAgentOrchestrator(
config: _resolveMultiAgentConfig(_settingsController.snapshot),
arisBundleRepository: _arisBundleRepository,
arisBridgeLocator: _arisBridgeLocator,
goCoreLocator: _goCoreLocator,
);
_attachChildListeners();
@ -189,7 +189,7 @@ class AppController extends ChangeNotifier {
late final DirectSingleAgentAppServerClient _singleAgentAppServerClient;
late final List<SingleAgentProvider>? _availableSingleAgentProvidersOverride;
late final ArisBundleRepository _arisBundleRepository;
late final ArisBridgeLocator _arisBridgeLocator;
late final GoCoreLocator _goCoreLocator;
late final SingleAgentRunner _singleAgentRunner;
late final MultiAgentOrchestrator _multiAgentOrchestrator;
DirectSingleAgentCapabilities _singleAgentCapabilities =

View File

@ -2463,8 +2463,8 @@ class _SettingsPageState extends State<SettingsPage> {
const SizedBox(height: 4),
Text(
appText(
'ARIS 模式会把内嵌 skills 与 Go bridge reviewer 作为本地 Ollama 协作增强层,不会覆盖你原有的 CLI 全局配置。',
'ARIS mode injects embedded skills and the Go bridge reviewer for local Ollama collaboration without overwriting your existing CLI global config.',
'ARIS 模式会把内嵌 skills 与 Go core reviewer 作为本地 Ollama 协作增强层,不会覆盖你原有的 CLI 全局配置。',
'ARIS mode injects embedded skills and the Go core reviewer for local Ollama collaboration without overwriting your existing CLI global config.',
),
style: theme.textTheme.bodySmall,
),

View File

@ -3,7 +3,7 @@ import 'dart:convert';
import 'dart:io';
import '../app/app_store_policy.dart';
import 'aris_bridge.dart';
import 'go_core.dart';
typedef ArisProcessStarter =
Future<Process> Function(
@ -16,7 +16,7 @@ typedef ArisProcessStarter =
class ArisLlmChatClient {
ArisLlmChatClient({
ArisProcessStarter? processStarter,
ArisBridgeLocator? bridgeLocator,
GoCoreLocator? bridgeLocator,
Duration rpcTimeout = const Duration(minutes: 2),
}) : _processStarter =
processStarter ??
@ -28,11 +28,11 @@ class ArisLlmChatClient {
workingDirectory: workingDirectory,
);
}),
_bridgeLocator = bridgeLocator ?? ArisBridgeLocator(),
_bridgeLocator = bridgeLocator ?? GoCoreLocator(),
_rpcTimeout = rpcTimeout;
final ArisProcessStarter _processStarter;
final ArisBridgeLocator _bridgeLocator;
final GoCoreLocator _bridgeLocator;
final Duration _rpcTimeout;
Future<String> chat({
@ -92,12 +92,12 @@ class ArisLlmChatClient {
isAppleHost: Platform.isIOS || Platform.isMacOS,
)) {
throw UnsupportedError(
'App Store builds do not allow launching the bundled ARIS bridge process.',
'App Store builds do not allow launching the bundled Go core process.',
);
}
final launch = await _bridgeLocator.locate();
if (launch == null) {
throw StateError('ARIS Go bridge is unavailable.');
throw StateError('Go core is unavailable.');
}
final process = await _processStarter(
@ -126,7 +126,7 @@ class ArisLlmChatClient {
} catch (error) {
if (!responseCompleter.isCompleted) {
responseCompleter.completeError(
StateError('ARIS bridge returned invalid JSON: $error'),
StateError('Go core returned invalid JSON: $error'),
);
}
return;
@ -149,7 +149,7 @@ class ArisLlmChatClient {
!responseCompleter.isCompleted) {
final error = (message['error'] as Map).cast<String, dynamic>();
responseCompleter.completeError(
StateError(error['message']?.toString() ?? 'ARIS bridge error'),
StateError(error['message']?.toString() ?? 'Go core error'),
);
}
});
@ -168,7 +168,7 @@ class ArisLlmChatClient {
StateError(
stderrText.isNotEmpty
? stderrText
: 'ARIS bridge exited with code $exitCode',
: 'Go core exited with code $exitCode',
),
);
return;
@ -177,7 +177,7 @@ class ArisLlmChatClient {
StateError(
stderrText.isNotEmpty
? stderrText
: 'ARIS bridge closed without returning a tool result.',
: 'Go core closed without returning a tool result.',
),
);
});
@ -209,7 +209,7 @@ class ArisLlmChatClient {
return await responseCompleter.future.timeout(
_rpcTimeout,
onTimeout: () => throw TimeoutException(
'ARIS bridge timed out after ${_rpcTimeout.inSeconds}s',
'Go core timed out after ${_rpcTimeout.inSeconds}s',
_rpcTimeout,
),
);

View File

@ -1,7 +1,7 @@
import 'dart:io';
class ArisBridgeLaunch {
const ArisBridgeLaunch({
class GoCoreLaunch {
const GoCoreLaunch({
required this.executable,
this.arguments = const <String>[],
this.workingDirectory,
@ -12,57 +12,57 @@ class ArisBridgeLaunch {
final String? workingDirectory;
}
typedef ArisBinaryExistsResolver = Future<bool> Function(String command);
typedef GoCoreBinaryExistsResolver = Future<bool> Function(String command);
class ArisBridgeLocator {
ArisBridgeLocator({
ArisBinaryExistsResolver? binaryExistsResolver,
class GoCoreLocator {
GoCoreLocator({
GoCoreBinaryExistsResolver? binaryExistsResolver,
String? workspaceRoot,
String Function()? resolvedExecutableResolver,
}) : _binaryExistsResolver = binaryExistsResolver,
_workspaceRoot = workspaceRoot,
_resolvedExecutableResolver = resolvedExecutableResolver;
final ArisBinaryExistsResolver? _binaryExistsResolver;
final GoCoreBinaryExistsResolver? _binaryExistsResolver;
final String? _workspaceRoot;
final String Function()? _resolvedExecutableResolver;
Future<ArisBridgeLaunch?> locate() async {
Future<GoCoreLaunch?> locate() async {
final bundled = await _bundledHelper();
if (bundled != null) {
return bundled;
}
final override =
(Platform.environment['XWORKMATE_ARIS_BRIDGE_BIN'] ??
Platform.environment['ARIS_BRIDGE_BIN'] ??
(Platform.environment['XWORKMATE_GO_CORE_BIN'] ??
Platform.environment['GO_CORE_BIN'] ??
'')
.trim();
if (override.isNotEmpty && await _binaryExists(override)) {
return ArisBridgeLaunch(executable: override);
return GoCoreLaunch(executable: override);
}
for (final candidate in <String>['xworkmate-aris-bridge', 'aris-bridge']) {
for (final candidate in <String>['xworkmate-go-core', 'go-core']) {
if (await _binaryExists(candidate)) {
return ArisBridgeLaunch(executable: candidate);
return GoCoreLaunch(executable: candidate);
}
}
final root = (_workspaceRoot ?? Directory.current.path).trim();
if (root.isNotEmpty) {
for (final path in <String>[
'$root/go/bin/xworkmate-aris-bridge',
'$root/go/bin/aris-bridge',
'$root/build/bin/xworkmate-aris-bridge',
'$root/go/bin/xworkmate-go-core',
'$root/go/bin/go-core',
'$root/build/bin/xworkmate-go-core',
]) {
if (await File(path).exists()) {
return ArisBridgeLaunch(executable: path);
return GoCoreLaunch(executable: path);
}
}
final packageDirectory = Directory('$root/go/aris_bridge');
final packageDirectory = Directory('$root/go/go_core');
if (await packageDirectory.exists() && await _binaryExists('go')) {
return ArisBridgeLaunch(
return GoCoreLaunch(
executable: 'go',
arguments: const <String>['run', '.'],
workingDirectory: packageDirectory.path,
@ -74,7 +74,7 @@ class ArisBridgeLocator {
Future<bool> isAvailable() async => await locate() != null;
Future<ArisBridgeLaunch?> _bundledHelper() async {
Future<GoCoreLaunch?> _bundledHelper() async {
final resolvedExecutable =
(_resolvedExecutableResolver?.call() ?? Platform.resolvedExecutable)
.trim();
@ -93,10 +93,9 @@ class ArisBridgeLocator {
if (macOsDirectoryName != 'MacOS' || contentsDirectoryName != 'Contents') {
return null;
}
final bundledPath =
'${contentsDirectory.path}/Helpers/xworkmate-aris-bridge';
final bundledPath = '${contentsDirectory.path}/Helpers/xworkmate-go-core';
if (await File(bundledPath).exists()) {
return ArisBridgeLaunch(executable: bundledPath);
return GoCoreLaunch(executable: bundledPath);
}
return null;
}

View File

@ -2,7 +2,7 @@ import 'dart:convert';
import 'dart:io';
import 'aris_bundle.dart';
import 'aris_bridge.dart';
import 'go_core.dart';
import 'codex_config_bridge.dart';
import 'opencode_config_bridge.dart';
import 'runtime_models.dart';
@ -12,11 +12,11 @@ class MultiAgentMountManager {
CodexConfigBridge? codexConfigBridge,
OpencodeConfigBridge? opencodeConfigBridge,
ArisBundleRepository? arisBundleRepository,
ArisBridgeLocator? arisBridgeLocator,
GoCoreLocator? goCoreLocator,
}) : this._(
arisAdapter: ArisMountAdapter(
arisBundleRepository ?? ArisBundleRepository(),
arisBridgeLocator ?? ArisBridgeLocator(),
goCoreLocator ?? GoCoreLocator(),
),
codexConfigBridge: codexConfigBridge ?? CodexConfigBridge(),
opencodeConfigBridge: opencodeConfigBridge ?? OpencodeConfigBridge(),
@ -154,10 +154,10 @@ abstract class CliMountAdapter {
}
class ArisMountAdapter extends CliMountAdapter {
ArisMountAdapter(this._bundleRepository, this._bridgeLocator);
ArisMountAdapter(this._bundleRepository, this._goCoreLocator);
final ArisBundleRepository _bundleRepository;
final ArisBridgeLocator _bridgeLocator;
final GoCoreLocator _goCoreLocator;
String _lastBundleVersion = '';
String get lastBundleVersion => _lastBundleVersion;
@ -197,7 +197,7 @@ class ArisMountAdapter extends CliMountAdapter {
final bundle = await _bundleRepository.ensureReady();
_lastBundleVersion = bundle.manifest.bundleVersion;
final skillCount = await _bundleRepository.countSkillFiles();
final bridgeAvailable = await _bridgeLocator.isAvailable();
final bridgeAvailable = await _goCoreLocator.isAvailable();
final llmChatEntry = bundle.manifest.llmChatServerPath.trim();
final llmChatReady = llmChatEntry.isNotEmpty;
return ManagedMountTargetState.placeholder(
@ -219,8 +219,8 @@ class ArisMountAdapter extends CliMountAdapter {
: 0,
detail: llmChatReady
? bridgeAvailable
? 'Embedded bundle ${bundle.manifest.bundleVersion} ready; XWorkmate Go bridge manages llm-chat and claude-review.'
: 'Embedded bundle is ready, but the XWorkmate Go bridge is not available yet.'
? 'Embedded bundle ${bundle.manifest.bundleVersion} ready; XWorkmate Go core manages llm-chat and claude-review.'
: 'Embedded bundle is ready, but the XWorkmate Go core is not available yet.'
: 'Embedded bundle extracted, but llm-chat metadata is missing.',
);
} catch (error) {

View File

@ -6,7 +6,7 @@ import 'package:flutter/foundation.dart';
import '../app/app_store_policy.dart';
import 'aris_bundle.dart';
import 'aris_bridge.dart';
import 'go_core.dart';
import 'aris_llm_chat_client.dart';
import 'multi_agent_frameworks.dart';
import 'runtime_models.dart';
@ -32,16 +32,16 @@ class MultiAgentOrchestrator extends ChangeNotifier {
MultiAgentOrchestrator({
required MultiAgentConfig config,
ArisBundleRepository? arisBundleRepository,
ArisBridgeLocator? arisBridgeLocator,
GoCoreLocator? goCoreLocator,
Future<bool> Function(String command)? binaryExistsResolver,
HttpClient Function()? httpClientFactory,
ArisLlmChatClient? arisLlmChatClient,
CliProcessStarter? processStarter,
}) : _config = config,
_arisBundleRepository = arisBundleRepository ?? ArisBundleRepository(),
_arisBridgeLocator =
arisBridgeLocator ??
ArisBridgeLocator(binaryExistsResolver: binaryExistsResolver),
_goCoreLocator =
goCoreLocator ??
GoCoreLocator(binaryExistsResolver: binaryExistsResolver),
_binaryExistsResolver = binaryExistsResolver,
_httpClientFactory = httpClientFactory ?? HttpClient.new,
_processStarter =
@ -58,15 +58,15 @@ class MultiAgentOrchestrator extends ChangeNotifier {
arisLlmChatClient ??
ArisLlmChatClient(
bridgeLocator:
arisBridgeLocator ??
ArisBridgeLocator(binaryExistsResolver: binaryExistsResolver),
goCoreLocator ??
GoCoreLocator(binaryExistsResolver: binaryExistsResolver),
);
///
MultiAgentConfig _config;
MultiAgentConfig get config => _config;
final ArisBundleRepository _arisBundleRepository;
final ArisBridgeLocator _arisBridgeLocator;
final GoCoreLocator _goCoreLocator;
final Future<bool> Function(String command)? _binaryExistsResolver;
final HttpClient Function() _httpClientFactory;
final CliProcessStarter _processStarter;
@ -1051,10 +1051,10 @@ ${selectedSkills.isEmpty ? '- 无' : selectedSkills.map((item) => '- $item').joi
required String aiGatewayApiKey,
}) async {
try {
if (!await _arisBridgeLocator.isAvailable()) {
if (!await _goCoreLocator.isAvailable()) {
return const CliResult(
output: '',
error: 'ARIS Go bridge is unavailable for llm-chat',
error: 'Go core is unavailable for llm-chat',
exitCode: -1,
);
}
@ -1081,10 +1081,10 @@ ${selectedSkills.isEmpty ? '- 无' : selectedSkills.map((item) => '- $item').joi
required String prompt,
}) async {
try {
if (!await _arisBridgeLocator.isAvailable()) {
if (!await _goCoreLocator.isAvailable()) {
return const CliResult(
output: '',
error: 'ARIS Go bridge is unavailable for claude-review',
error: 'Go core is unavailable for claude-review',
exitCode: -1,
);
}
@ -1217,10 +1217,7 @@ ${selectedSkills.isEmpty ? '- 无' : selectedSkills.map((item) => '- $item').joi
};
}
bool _prefersOllamaLaunch({
required String tool,
required String model,
}) {
bool _prefersOllamaLaunch({required String tool, required String model}) {
final normalizedTool = tool.trim().toLowerCase();
final normalizedModel = model.trim();
if (normalizedModel.isEmpty) {

View File

@ -11,20 +11,20 @@
- 持续 Assistant 任务线程与流式 AI Gateway 对话
- `单机智能体 / 本地 OpenClaw Gateway / 远程 OpenClaw Gateway` 三模式统一
- `Architect / Engineer / Tester` 多 Agent 协作
- 可选 `ARIS` 框架、内嵌 skills、Go bridge runtime
- 可选 `ARIS` 框架、内嵌 skills、Go core runtime
- `Ollama Cloud` 文案和默认地址统一
## Bundled Runtime
- `assets/aris/skills` 继续直接复用 upstream `skills/`
- `llm-chat``claude-review` 统一由 `xworkmate-aris-bridge` 提供
- macOS `.app` 会把 helper 打进 `Contents/Helpers/xworkmate-aris-bridge`
- `llm-chat``claude-review` 统一由 `xworkmate-go-core` 提供
- macOS `.app` 会把 helper 打进 `Contents/Helpers/xworkmate-go-core`
## Validation
- `flutter analyze`
- `flutter test`
- `cd go/aris_bridge && go test ./...`
- `cd go/go_core && go test ./...`
- `flutter test integration_test/desktop_navigation_flow_test.dart -d macos`
- `flutter test integration_test/desktop_settings_flow_test.dart -d macos`
- `flutter build macos`

View File

@ -2,9 +2,9 @@
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
BRIDGE_DIR="$ROOT_DIR/go/aris_bridge"
BRIDGE_DIR="$ROOT_DIR/go/go_core"
OUTPUT_DIR="${OUTPUT_DIR:-$ROOT_DIR/build/bin}"
OUTPUT_PATH="${OUTPUT_PATH:-$OUTPUT_DIR/xworkmate-aris-bridge}"
OUTPUT_PATH="${OUTPUT_PATH:-$OUTPUT_DIR/xworkmate-go-core}"
if [[ ! -f "$BRIDGE_DIR/go.mod" ]]; then
echo "Missing go.mod in $BRIDGE_DIR" >&2
@ -12,13 +12,13 @@ if [[ ! -f "$BRIDGE_DIR/go.mod" ]]; then
fi
if ! command -v go >/dev/null 2>&1; then
echo "Go toolchain is required to build xworkmate-aris-bridge" >&2
echo "Go toolchain is required to build xworkmate-go-core" >&2
exit 1
fi
mkdir -p "$OUTPUT_DIR"
echo "Building xworkmate-aris-bridge..."
echo "Building xworkmate-go-core..."
(
cd "$BRIDGE_DIR"
GO111MODULE=on go build -o "$OUTPUT_PATH" .

View File

@ -9,7 +9,7 @@ APP_NAME="${APP_NAME:-XWorkmate}"
BUILD_MODE="${BUILD_MODE:-release}"
APP_STORE_DEFINE="${APP_STORE_DEFINE:---dart-define=XWORKMATE_APP_STORE=${XWORKMATE_APP_STORE:-true}}"
PRODUCTS_DIR_NAME="$(tr '[:lower:]' '[:upper:]' <<< "${BUILD_MODE:0:1}")${BUILD_MODE:1}"
BRIDGE_BINARY_NAME="${BRIDGE_BINARY_NAME:-xworkmate-aris-bridge}"
BRIDGE_BINARY_NAME="${BRIDGE_BINARY_NAME:-xworkmate-go-core}"
BRIDGE_BUILD_PATH="${ROOT_DIR}/build/bin/${BRIDGE_BINARY_NAME}"
if [[ ! -f "$PUBSPEC_PATH" ]]; then
@ -37,8 +37,8 @@ HELPER_PATH="$HELPERS_DIR/$BRIDGE_BINARY_NAME"
mkdir -p "$DIST_DIR"
echo "Building bundled ARIS bridge..."
bash "$ROOT_DIR/scripts/build-aris-bridge.sh"
echo "Building bundled Go core..."
bash "$ROOT_DIR/scripts/build-go-core.sh"
echo "Building $APP_NAME $APP_VERSION ($APP_BUILD) for macOS..."
BUILD_ARGS=(

View File

@ -6,7 +6,7 @@ import 'dart:convert';
import 'dart:io';
import 'package:flutter_test/flutter_test.dart';
import 'package:xworkmate/runtime/aris_bridge.dart';
import 'package:xworkmate/runtime/go_core.dart';
import 'package:xworkmate/runtime/aris_llm_chat_client.dart';
void main() {
@ -112,8 +112,8 @@ void main() {
});
}
ArisBridgeLocator _fixedLocator() {
return ArisBridgeLocator(
GoCoreLocator _fixedLocator() {
return GoCoreLocator(
binaryExistsResolver: (_) async => true,
workspaceRoot: Directory.systemTemp.path,
resolvedExecutableResolver: () =>

View File

@ -4,14 +4,14 @@ library;
import 'dart:io';
import 'package:flutter_test/flutter_test.dart';
import 'package:xworkmate/runtime/aris_bridge.dart';
import 'package:xworkmate/runtime/go_core.dart';
void main() {
test(
'ArisBridgeLocator prefers bundled helper inside macOS app bundle',
'GoCoreLocator prefers bundled helper inside macOS app bundle',
() async {
final tempDirectory = await Directory.systemTemp.createTemp(
'xworkmate-aris-bridge-bundle-',
'xworkmate-go-core-bundle-',
);
addTearDown(() async {
if (await tempDirectory.exists()) {
@ -22,11 +22,11 @@ void main() {
'${tempDirectory.path}/XWorkmate.app/Contents/Helpers',
);
await helpersDir.create(recursive: true);
final helperFile = File('${helpersDir.path}/xworkmate-aris-bridge');
final helperFile = File('${helpersDir.path}/xworkmate-go-core');
await helperFile.writeAsString('#!/bin/sh\nexit 0\n');
await Process.run('chmod', <String>['+x', helperFile.path]);
final locator = ArisBridgeLocator(
final locator = GoCoreLocator(
workspaceRoot: tempDirectory.path,
binaryExistsResolver: (_) async => true,
resolvedExecutableResolver: () =>
@ -43,10 +43,10 @@ void main() {
);
test(
'ArisBridgeLocator falls back to go run in the local bridge package',
'GoCoreLocator falls back to go run in the local bridge package',
() async {
final tempDirectory = await Directory.systemTemp.createTemp(
'xworkmate-aris-bridge-',
'xworkmate-go-core-',
);
addTearDown(() async {
if (await tempDirectory.exists()) {
@ -54,10 +54,10 @@ void main() {
}
});
await Directory(
'${tempDirectory.path}/go/aris_bridge',
'${tempDirectory.path}/go/go_core',
).create(recursive: true);
final locator = ArisBridgeLocator(
final locator = GoCoreLocator(
workspaceRoot: tempDirectory.path,
binaryExistsResolver: (command) async => command == 'go',
);
@ -67,7 +67,7 @@ void main() {
expect(launch, isNotNull);
expect(launch!.executable, 'go');
expect(launch.arguments, const <String>['run', '.']);
expect(launch.workingDirectory, '${tempDirectory.path}/go/aris_bridge');
expect(launch.workingDirectory, '${tempDirectory.path}/go/go_core');
},
);
}

View File

@ -1,5 +1,5 @@
import '../test_suite_stub.dart'
if (dart.library.io) 'aris_bridge_suite.dart'
if (dart.library.io) 'go_core_suite.dart'
as suite;
void main() {

View File

@ -5,7 +5,7 @@ import 'dart:io';
import 'package:flutter_test/flutter_test.dart';
import 'package:xworkmate/runtime/aris_bundle.dart';
import 'package:xworkmate/runtime/aris_bridge.dart';
import 'package:xworkmate/runtime/go_core.dart';
import 'package:xworkmate/runtime/codex_config_bridge.dart';
import 'package:xworkmate/runtime/multi_agent_mounts.dart';
import 'package:xworkmate/runtime/runtime_models.dart';
@ -14,7 +14,7 @@ void main() {
test('ArisMountAdapter reports error when bundle is unavailable', () async {
final adapter = ArisMountAdapter(
_ThrowingArisBundleRepository(),
ArisBridgeLocator(binaryExistsResolver: (_) async => false),
GoCoreLocator(binaryExistsResolver: (_) async => false),
);
final state = await adapter.reconcile(
@ -44,7 +44,7 @@ void main() {
final bundle = await _writeFakeBundle(tempDir);
final adapter = ArisMountAdapter(
_FixedArisBundleRepository(bundle),
ArisBridgeLocator(
GoCoreLocator(
workspaceRoot: tempDir.path,
binaryExistsResolver: (_) async => false,
),
@ -63,7 +63,7 @@ void main() {
expect(state.syncState, 'embedded');
expect(state.discoveredMcpCount, 1);
expect(state.managedMcpCount, 0);
expect(state.detail, contains('bridge is not available'));
expect(state.detail, contains('Go core is not available'));
},
);
@ -83,10 +83,10 @@ void main() {
'${tempDir.path}/XWorkmate.app/Contents/Helpers',
);
await helperDir.create(recursive: true);
final helper = File('${helperDir.path}/xworkmate-aris-bridge');
final helper = File('${helperDir.path}/xworkmate-go-core');
await helper.writeAsString('#!/bin/sh\nexit 0\n');
await Process.run('chmod', <String>['+x', helper.path]);
final locator = ArisBridgeLocator(
final locator = GoCoreLocator(
workspaceRoot: tempDir.path,
binaryExistsResolver: (_) async => false,
resolvedExecutableResolver: () =>

View File

@ -13,11 +13,11 @@ import 'package:xworkmate/runtime/runtime_models.dart';
void main() {
test(
'MultiAgentOrchestrator falls back to local Ollama + ARIS Go chat bridge',
'MultiAgentOrchestrator falls back to local Ollama + ARIS Go core chat runtime',
() async {
final fakeOllama = await _FakeOllamaServer.start();
addTearDown(fakeOllama.close);
final bridgeClient = _FakeArisBridgeClient();
final bridgeClient = _FakeGoCoreClient();
final orchestrator = MultiAgentOrchestrator(
config: MultiAgentConfig.defaults().copyWith(
enabled: true,
@ -68,11 +68,11 @@ void main() {
);
test(
'MultiAgentOrchestrator routes tester claude reviews through the same Go bridge',
'MultiAgentOrchestrator routes tester claude reviews through the same Go core runtime',
() async {
final fakeOllama = await _FakeOllamaServer.start();
addTearDown(fakeOllama.close);
final bridgeClient = _FakeArisBridgeClient();
final bridgeClient = _FakeGoCoreClient();
final orchestrator = MultiAgentOrchestrator(
config: MultiAgentConfig.defaults().copyWith(
enabled: true,
@ -117,8 +117,8 @@ void main() {
);
}
class _FakeArisBridgeClient extends ArisLlmChatClient {
_FakeArisBridgeClient();
class _FakeGoCoreClient extends ArisLlmChatClient {
_FakeGoCoreClient();
int chatCallCount = 0;
int claudeReviewCallCount = 0;