From 68d23ab7dde23d5ed5515954be20bd8aa73228ad Mon Sep 17 00:00:00 2001 From: flemming-it Date: Tue, 16 Jun 2026 17:48:11 +0200 Subject: [PATCH] refactor: rename app fai_studio -> chain_studio MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- CHANGELOG.md | 2 +- README.md | 4 +-- lib/data/flow_output.dart | 2 +- lib/data/flow_run_driver.dart | 2 +- lib/data/friendly_error.dart | 2 +- lib/data/hub.dart | 2 +- lib/pages/flows.dart | 4 +-- lib/widgets/fai_settings_dialog.dart | 2 +- linux/CMakeLists.txt | 4 +-- macos/Runner.xcodeproj/project.pbxproj | 18 ++++++------ .../xcshareddata/xcschemes/Runner.xcscheme | 10 +++---- macos/Runner/Configs/AppInfo.xcconfig | 6 ++-- macos/Runner/MainFlutterWindow.swift | 2 +- pubspec.lock | 28 +++++++++---------- pubspec.yaml | 14 +++++----- test/fai_log_test.dart | 2 +- test/friendly_error_test.dart | 4 +-- test/integration/README.md | 2 +- test/integration/hub_fixture.dart | 4 +-- test/load_docs_test.dart | 4 +-- test/widget_test.dart | 4 +-- tools/today/README.md | 4 +-- tools/today/collect.sh | 4 +-- windows/CMakeLists.txt | 4 +-- windows/runner/Runner.rc | 12 ++++---- 25 files changed, 73 insertions(+), 73 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f74b4ea..6c35b76 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/README.md b/README.md index 7793600..c2d2355 100644 --- a/README.md +++ b/README.md @@ -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" diff --git a/lib/data/flow_output.dart b/lib/data/flow_output.dart index 5ae466b..4000d52 100644 --- a/lib/data/flow_output.dart +++ b/lib/data/flow_output.dart @@ -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 diff --git a/lib/data/flow_run_driver.dart b/lib/data/flow_run_driver.dart index 34af0b7..1864f15 100644 --- a/lib/data/flow_run_driver.dart +++ b/lib/data/flow_run_driver.dart @@ -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'; diff --git a/lib/data/friendly_error.dart b/lib/data/friendly_error.dart index 5cb17ad..ba2416f 100644 --- a/lib/data/friendly_error.dart +++ b/lib/data/friendly_error.dart @@ -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'); diff --git a/lib/data/hub.dart b/lib/data/hub.dart index 93abcf4..da95297 100644 --- a/lib/data/hub.dart +++ b/lib/data/hub.dart @@ -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'; diff --git a/lib/pages/flows.dart b/lib/pages/flows.dart index 396d4c3..4120bf1 100644 --- a/lib/pages/flows.dart +++ b/lib/pages/flows.dart @@ -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'; diff --git a/lib/widgets/fai_settings_dialog.dart b/lib/widgets/fai_settings_dialog.dart index 8fee21e..3910507 100644 --- a/lib/widgets/fai_settings_dialog.dart +++ b/lib/widgets/fai_settings_dialog.dart @@ -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'; diff --git a/linux/CMakeLists.txt b/linux/CMakeLists.txt index 2d30c2b..ce3e955 100644 --- a/linux/CMakeLists.txt +++ b/linux/CMakeLists.txt @@ -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. diff --git a/macos/Runner.xcodeproj/project.pbxproj b/macos/Runner.xcodeproj/project.pbxproj index 7260522..b6babe3 100644 --- a/macos/Runner.xcodeproj/project.pbxproj +++ b/macos/Runner.xcodeproj/project.pbxproj @@ -68,7 +68,7 @@ 331C80D7294CF71000263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; }; 333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = ""; }; 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = ""; }; - 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 = ""; }; 33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = ""; }; 33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; @@ -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; }; diff --git a/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index 19a2983..ceb4444 100644 --- a/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -15,7 +15,7 @@ @@ -33,7 +33,7 @@ @@ -49,7 +49,7 @@ @@ -84,7 +84,7 @@ @@ -101,7 +101,7 @@ diff --git a/macos/Runner/Configs/AppInfo.xcconfig b/macos/Runner/Configs/AppInfo.xcconfig index 37e6a9c..737cc16 100644 --- a/macos/Runner/Configs/AppInfo.xcconfig +++ b/macos/Runner/Configs/AppInfo.xcconfig @@ -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. diff --git a/macos/Runner/MainFlutterWindow.swift b/macos/Runner/MainFlutterWindow.swift index 1ab6ff6..a856fe1 100644 --- a/macos/Runner/MainFlutterWindow.swift +++ b/macos/Runner/MainFlutterWindow.swift @@ -8,7 +8,7 @@ class MainFlutterWindow: NSWindow { // Override the window title so the OS task switcher and // window chrome read "F∆I 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 diff --git a/pubspec.lock b/pubspec.lock index 21128e8..279d399 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -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: diff --git a/pubspec.yaml b/pubspec.yaml index b941b3e..942b452 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -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 diff --git a/test/fai_log_test.dart b/test/fai_log_test.dart index 195d093..0dae9d0 100644 --- a/test/fai_log_test.dart +++ b/test/fai_log_test.dart @@ -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() { diff --git a/test/friendly_error_test.dart b/test/friendly_error_test.dart index e8ef45f..2577e79 100644 --- a/test/friendly_error_test.dart +++ b/test/friendly_error_test.dart @@ -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; diff --git a/test/integration/README.md b/test/integration/README.md index edbed8b..e2f71f4 100644 --- a/test/integration/README.md +++ b/test/integration/README.md @@ -30,7 +30,7 @@ What's NOT here yet: ## Running ```bash -cd fai_studio +cd chain_studio flutter test test/integration/ ``` diff --git a/test/integration/hub_fixture.dart b/test/integration/hub_fixture.dart index 429ba72..d0c5836 100644 --- a/test/integration/hub_fixture.dart +++ b/test/integration/hub_fixture.dart @@ -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'; diff --git a/test/load_docs_test.dart b/test/load_docs_test.dart index f822544..3960cde 100644 --- a/test/load_docs_test.dart +++ b/test/load_docs_test.dart @@ -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 diff --git a/test/widget_test.dart b/test/widget_test.dart index dd936bb..421c7e0 100644 --- a/test/widget_test.dart +++ b/test/widget_test.dart @@ -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', diff --git a/tools/today/README.md b/tools/today/README.md index a25ac3e..a386e6b 100644 --- a/tools/today/README.md +++ b/tools/today/README.md @@ -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 diff --git a/tools/today/collect.sh b/tools/today/collect.sh index fc51d9e..4d0430b 100755 --- a/tools/today/collect.sh +++ b/tools/today/collect.sh @@ -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) diff --git a/windows/CMakeLists.txt b/windows/CMakeLists.txt index 1acb775..8c58452 100644 --- a/windows/CMakeLists.txt +++ b/windows/CMakeLists.txt @@ -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. diff --git a/windows/runner/Runner.rc b/windows/runner/Runner.rc index d1ffbe9..3b7eba1 100644 --- a/windows/runner/Runner.rc +++ b/windows/runner/Runner.rc @@ -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