refactor: rename app fai_studio -> chain_studio
Some checks are pending
Security / Security check (push) Waiting to run

Studio is the Ch∆In product's GUI, not a F∆I-vendor app. Rename the
Flutter package, all package: imports, and the build identity across
platforms: linux/windows CMake BINARY_NAME + project, Windows Runner.rc
fields, macOS PRODUCT_NAME / bundle id (ai.flemming.chain.chainStudio) /
.app + scheme BuildableName. Update the client-SDK + flow-editor deps to
their renamed chain_* packages (path + git URL). Company/copyright fields
now read Flemming.AI. flutter analyze: clean.

Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
This commit is contained in:
flemming-it 2026-06-16 17:48:11 +02:00
parent c27bb29ba0
commit 68d23ab7dd
25 changed files with 73 additions and 73 deletions

View file

@ -1,6 +1,6 @@
# Changelog
All notable changes to `fai_studio` recorded here. Pubspec
All notable changes to `chain_studio` recorded here. Pubspec
version + `kStudioVersion` in `lib/main.dart` stay in lockstep.
## 0.70.0 — 2026-06-13

View file

@ -24,7 +24,7 @@ These three cover the platform's central properties:
## Stack
- Flutter 3.40+ (Desktop: macOS, Linux, Windows)
- gRPC client via [`fai_client_sdk`](../fai_client_sdk_dart) (sibling
- gRPC client via [`chain_client_sdk`](../fai_chain_client_sdk_dart) (sibling
repo; pinned by relative path during development)
- No external runtime dependencies; bundles its own Dart VM
@ -37,7 +37,7 @@ flutter run -d macos
## Repo placement
Will be published as `fai/studio` on Forgejo (`git.flemming.ws`).
The local directory `fai_studio/` follows the established
The local directory `chain_studio/` follows the established
`fai_platform/` layout convention.
## Why "Studio" and not "Stage"

View file

@ -6,7 +6,7 @@
import 'dart:convert';
import 'dart:typed_data';
import 'package:fai_client_sdk/fai_client_sdk.dart' show Payload;
import 'package:chain_client_sdk/chain_client_sdk.dart' show Payload;
/// One named output of a flow run. Sealed via factory constructors
/// callers pattern-match with `switch` on the runtime type to

View file

@ -13,7 +13,7 @@
import 'dart:async';
import 'dart:typed_data';
import 'package:fai_studio_flow_editor/fai_studio_flow_editor.dart' as editor;
import 'package:chain_studio_flow_editor/chain_studio_flow_editor.dart' as editor;
import 'hub.dart';

View file

@ -34,7 +34,7 @@ class FriendlyError {
FriendlyError friendlyError(Object error, AppLocalizations l) {
// We deliberately don't import package:grpc here so Studio
// doesn't have to add it to its own pubspec — the dependency
// lives one layer down in fai_client_sdk. `GrpcError` has a
// lives one layer down in chain_client_sdk. `GrpcError` has a
// stable `.code` (int) and `.message` (String?) shape; we
// duck-type on those instead of an `is` check.
final code = _intField(error, 'code');

View file

@ -7,7 +7,7 @@
import 'dart:typed_data';
import 'package:fai_client_sdk/fai_client_sdk.dart';
import 'package:chain_client_sdk/chain_client_sdk.dart';
import 'package:flutter/widgets.dart';
import 'package:shared_preferences/shared_preferences.dart';

View file

@ -1,5 +1,5 @@
// FlowsPage Studio's flow surface. Thin host wrapper around
// the swappable fai_studio_flow_editor package: loads the
// the swappable chain_studio_flow_editor package: loads the
// hub's installed capabilities, hands them + a Studio-side
// FlowRunDriver to the editor, and lets the editor own
// everything else (file list, three-tab body, properties
@ -10,7 +10,7 @@
// package so a swap is one pubspec change Studio doesn't
// need to know what's inside the editor any more.
import 'package:fai_studio_flow_editor/fai_studio_flow_editor.dart';
import 'package:chain_studio_flow_editor/chain_studio_flow_editor.dart';
import 'package:flutter/material.dart';
import '../data/flow_run_driver.dart';

View file

@ -2,7 +2,7 @@
// Reads current values from HubService, persists on save via
// HubService.reconnect.
import 'package:fai_client_sdk/fai_client_sdk.dart';
import 'package:chain_client_sdk/chain_client_sdk.dart';
import 'package:flutter/material.dart';
import '../data/error_presentation.dart';

View file

@ -4,10 +4,10 @@ project(runner LANGUAGES CXX)
# The name of the executable created for the application. Change this to change
# the on-disk name of your application.
set(BINARY_NAME "fai_studio")
set(BINARY_NAME "chain_studio")
# The unique GTK application identifier for this application. See:
# https://wiki.gnome.org/HowDoI/ChooseApplicationID
set(APPLICATION_ID "ai.flemming.fai.fai_studio")
set(APPLICATION_ID "ai.flemming.chain.chain_studio")
# Explicitly opt in to modern CMake behaviors to avoid warnings with recent
# versions of CMake.

View file

@ -68,7 +68,7 @@
331C80D7294CF71000263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = "<group>"; };
333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = "<group>"; };
335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = "<group>"; };
33CC10ED2044A3C60003C045 /* fai_studio.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = fai_studio.app; sourceTree = BUILT_PRODUCTS_DIR; };
33CC10ED2044A3C60003C045 /* chain_studio.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = chain_studio.app; sourceTree = BUILT_PRODUCTS_DIR; };
33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = "<group>"; };
33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = "<group>"; };
@ -147,7 +147,7 @@
33CC10EE2044A3C60003C045 /* Products */ = {
isa = PBXGroup;
children = (
33CC10ED2044A3C60003C045 /* fai_studio.app */,
33CC10ED2044A3C60003C045 /* chain_studio.app */,
331C80D5294CF71000263BE5 /* RunnerTests.xctest */,
);
name = Products;
@ -255,7 +255,7 @@
78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */,
);
productName = Runner;
productReference = 33CC10ED2044A3C60003C045 /* fai_studio.app */;
productReference = 33CC10ED2044A3C60003C045 /* chain_studio.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
@ -471,10 +471,10 @@
CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = ai.flemming.fai.faiStudio.RunnerTests;
PRODUCT_BUNDLE_IDENTIFIER = ai.flemming.chain.chainStudio.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/fai_studio.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/fai_studio";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/chain_studio.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/chain_studio";
};
name = Debug;
};
@ -486,10 +486,10 @@
CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = ai.flemming.fai.faiStudio.RunnerTests;
PRODUCT_BUNDLE_IDENTIFIER = ai.flemming.chain.chainStudio.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/fai_studio.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/fai_studio";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/chain_studio.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/chain_studio";
};
name = Release;
};
@ -501,10 +501,10 @@
CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = ai.flemming.fai.faiStudio.RunnerTests;
PRODUCT_BUNDLE_IDENTIFIER = ai.flemming.chain.chainStudio.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/fai_studio.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/fai_studio";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/chain_studio.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/chain_studio";
};
name = Profile;
};

View file

@ -15,7 +15,7 @@
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "33CC10EC2044A3C60003C045"
BuildableName = "fai_studio.app"
BuildableName = "chain_studio.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
@ -33,7 +33,7 @@
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "33CC10EC2044A3C60003C045"
BuildableName = "fai_studio.app"
BuildableName = "chain_studio.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
@ -49,7 +49,7 @@
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "33CC10EC2044A3C60003C045"
BuildableName = "fai_studio.app"
BuildableName = "chain_studio.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
@ -84,7 +84,7 @@
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "33CC10EC2044A3C60003C045"
BuildableName = "fai_studio.app"
BuildableName = "chain_studio.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
@ -101,7 +101,7 @@
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "33CC10EC2044A3C60003C045"
BuildableName = "fai_studio.app"
BuildableName = "chain_studio.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>

View file

@ -5,10 +5,10 @@
// 'flutter create' template.
// The application's name. By default this is also the title of the Flutter window.
PRODUCT_NAME = fai_studio
PRODUCT_NAME = chain_studio
// The application's bundle identifier
PRODUCT_BUNDLE_IDENTIFIER = ai.flemming.fai.faiStudio
PRODUCT_BUNDLE_IDENTIFIER = ai.flemming.chain.chainStudio
// The copyright displayed in application information
PRODUCT_COPYRIGHT = Copyright © 2026 ai.flemming.fai. All rights reserved.
PRODUCT_COPYRIGHT = Copyright © 2026 ai.flemming.chain. All rights reserved.

View file

@ -8,7 +8,7 @@ class MainFlutterWindow: NSWindow {
// Override the window title so the OS task switcher and
// window chrome read "FI Studio" instead of the
// pubspec-derived "fai_studio".
// pubspec-derived "chain_studio".
self.title = "F∆I Studio"
// Pick a comfortable default window size. 1440x900 is the

View file

@ -33,6 +33,20 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.1.2"
chain_client_sdk:
dependency: "direct main"
description:
path: "../fai_chain_client_sdk_dart"
relative: true
source: path
version: "0.18.0"
chain_studio_flow_editor:
dependency: "direct main"
description:
path: "../fai_chain_studio_flow_editor"
relative: true
source: path
version: "0.21.0"
characters:
dependency: transitive
description:
@ -105,20 +119,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.0.8"
fai_client_sdk:
dependency: "direct main"
description:
path: "../fai_client_sdk_dart"
relative: true
source: path
version: "0.18.0"
fai_studio_flow_editor:
dependency: "direct main"
description:
path: "../fai_studio_flow_editor"
relative: true
source: path
version: "0.21.0"
fake_async:
dependency: transitive
description:

View file

@ -1,4 +1,4 @@
name: fai_studio
name: chain_studio
description: "Ch∆In Studio — desktop GUI for the Ch∆In hub"
publish_to: 'none'
version: 0.70.0
@ -17,8 +17,8 @@ dependencies:
meta: any
# Sibling package; will move to Forgejo path once published.
fai_client_sdk:
path: ../fai_client_sdk_dart
chain_client_sdk:
path: ../fai_chain_client_sdk_dart
shared_preferences: ^2.5.5
# Inline README rendering inside the Store detail sheet.
# `flutter_markdown` is discontinued; `flutter_markdown_plus`
@ -39,9 +39,9 @@ dependencies:
# be replaced without touching the rest of Studio. Pin to a
# commit (or branch) here; rebuild Studio to pick up
# editor-side changes.
fai_studio_flow_editor:
chain_studio_flow_editor:
git:
url: https://git.flemming.ai/fai/studio-flow-editor
url: https://git.flemming.ai/fai/chain-studio-flow-editor
ref: main
dev_dependencies:
@ -55,8 +55,8 @@ dev_dependencies:
# + `pub upgrade`. Comment the block out before tagging a Studio
# release so the committed Git ref is what builds on Forgejo CI.
dependency_overrides:
fai_studio_flow_editor:
path: ../fai_studio_flow_editor
chain_studio_flow_editor:
path: ../fai_chain_studio_flow_editor
flutter:
uses-material-design: true

View file

@ -7,7 +7,7 @@
import 'dart:convert';
import 'dart:io';
import 'package:fai_studio/data/fai_log.dart';
import 'package:chain_studio/data/fai_log.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {

View file

@ -6,8 +6,8 @@
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:fai_studio/data/friendly_error.dart';
import 'package:fai_studio/l10n/app_localizations.dart';
import 'package:chain_studio/data/friendly_error.dart';
import 'package:chain_studio/l10n/app_localizations.dart';
class _FakeGrpcError {
final int code;

View file

@ -30,7 +30,7 @@ What's NOT here yet:
## Running
```bash
cd fai_studio
cd chain_studio
flutter test test/integration/
```

View file

@ -25,7 +25,7 @@
import 'dart:async';
import 'dart:io';
import 'package:fai_client_sdk/fai_client_sdk.dart';
import 'package:chain_client_sdk/chain_client_sdk.dart';
import 'package:flutter_test/flutter_test.dart';
class HubFixture {
@ -80,7 +80,7 @@ class HubFixture {
throw StateError('fai binary not found');
}
final tempDir = await Directory.systemTemp.createTemp('fai_studio_test_');
final tempDir = await Directory.systemTemp.createTemp('chain_studio_test_');
final port = await _pickFreePort();
final addr = '127.0.0.1:$port';

View file

@ -3,8 +3,8 @@ import 'package:flutter/services.dart' show rootBundle;
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter_markdown_plus/flutter_markdown_plus.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:fai_studio/l10n/app_localizations.dart';
import 'package:fai_studio/theme/theme.dart';
import 'package:chain_studio/l10n/app_localizations.dart';
import 'package:chain_studio/theme/theme.dart';
/// Recreates the exact DocReaderSheet code path that
/// welcome.dart uses, including FaiTheme.markdownStyle, so a

View file

@ -6,8 +6,8 @@
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:fai_studio/data/hub.dart';
import 'package:fai_studio/main.dart';
import 'package:chain_studio/data/hub.dart';
import 'package:chain_studio/main.dart';
void main() {
testWidgets('Studio shell boots + sidebar shows brand on hover',

View file

@ -25,11 +25,11 @@ ls ~/.fai/today/proposals/
```bash
# Drop a plist that runs propose.sh every morning at 07:30 local time.
# `launchctl load ~/Library/LaunchAgents/ai.flemming.fai.today.plist` to
# `launchctl load ~/Library/LaunchAgents/ai.flemming.chain.today.plist` to
# install. The plist must point at the absolute path of propose.sh.
```
A starter plist lives at `launchd/ai.flemming.fai.today.plist`.
A starter plist lives at `launchd/ai.flemming.chain.today.plist`.
### Linux — systemd timer

View file

@ -11,7 +11,7 @@ set -euo pipefail
SINCE="${FAI_TODAY_SINCE:-24 hours ago}"
# Walk every fai-* directory next to fai_studio so the collector
# Walk every fai-* directory next to chain_studio so the collector
# works from any of the sibling checkouts. Adjust here if the
# layout ever changes.
ROOT="$(cd "$(dirname "$0")/../../.." && pwd)"
@ -55,7 +55,7 @@ if [ -d "$arch_dir" ] && [ -d "$ROOT/fai_platform/.git" ]; then
fi
emit_section "STUDIO RECENT RELEASES"
studio="$ROOT/fai_studio"
studio="$ROOT/chain_studio"
if [ -d "$studio/.git" ]; then
tags=$(git -C "$studio" log --since="$SINCE" --pretty='%h %s' \
--grep='^feat(studio)\|^chore(studio): bump' 2>/dev/null || true)

View file

@ -1,10 +1,10 @@
# Project-level configuration.
cmake_minimum_required(VERSION 3.14)
project(fai_studio LANGUAGES CXX)
project(chain_studio LANGUAGES CXX)
# The name of the executable created for the application. Change this to change
# the on-disk name of your application.
set(BINARY_NAME "fai_studio")
set(BINARY_NAME "chain_studio")
# Explicitly opt in to modern CMake behaviors to avoid warnings with recent
# versions of CMake.

View file

@ -89,13 +89,13 @@ BEGIN
BEGIN
BLOCK "040904e4"
BEGIN
VALUE "CompanyName", "ai.flemming.fai" "\0"
VALUE "FileDescription", "fai_studio" "\0"
VALUE "CompanyName", "Flemming.AI" "\0"
VALUE "FileDescription", "chain_studio" "\0"
VALUE "FileVersion", VERSION_AS_STRING "\0"
VALUE "InternalName", "fai_studio" "\0"
VALUE "LegalCopyright", "Copyright (C) 2026 ai.flemming.fai. All rights reserved." "\0"
VALUE "OriginalFilename", "fai_studio.exe" "\0"
VALUE "ProductName", "fai_studio" "\0"
VALUE "InternalName", "chain_studio" "\0"
VALUE "LegalCopyright", "Copyright (C) 2026 ai.flemming.chain. All rights reserved." "\0"
VALUE "OriginalFilename", "chain_studio.exe" "\0"
VALUE "ProductName", "chain_studio" "\0"
VALUE "ProductVersion", VERSION_AS_STRING "\0"
END
END