fix(studio): chain config dir + spawn path + doc URLs
Some checks failed
Security / Security check (push) Failing after 2s

Track the platform rename: the hub spawn path is now ~/.chain/bin/chain
(was ~/.fai/bin/fai.exe on Windows — both dir and binary were stale, so
Studio could not launch the hub after the config-dir rename), the
~/.fai/* help strings become ~/.chain/*, FAI_REGISTRY_TOKEN ->
CHAIN_REGISTRY_TOKEN, and the two in-app doc URLs point at the public
fai/chain repo (fai/platform was renamed to the private fai/chain-private).
The .fai module bundle extension is left unchanged (format phase).
flutter analyze: no issues.

Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
This commit is contained in:
flemming-it 2026-06-16 09:38:30 +02:00
parent 7ff4fda2a3
commit 0f93d90963
18 changed files with 121 additions and 121 deletions

View file

@ -6,7 +6,7 @@
// a copyable, selectable rendition of the message
// a friendly headline (gRPC codes mapped via
// friendlyError) instead of a wall-of-stack-trace
// an automatic append to ~/.fai/logs/studio-errors.log so
// an automatic append to ~/.chain/logs/studio-errors.log so
// the trail survives the dismiss action
//
// Call sites used to scatter `ScaffoldMessenger.of(ctx).showSnackBar(

View file

@ -4,7 +4,7 @@
// went wrong without the operator having to reproduce the
// failure.
//
// Path: `~/.fai/logs/studio-errors.log` (cross-platform via
// Path: `~/.chain/logs/studio-errors.log` (cross-platform via
// HOME / USERPROFILE). One line per event, JSON-shaped so
// `chain doctor` can parse it; humans can still read it because
// the JSON is single-line and short.

View file

@ -55,7 +55,7 @@ class HubService {
}
/// Reconnect to a new endpoint and persist for next launch.
/// [authToken] is read from `~/.fai/hub-auth-token` by
/// [authToken] is read from `~/.chain/hub-auth-token` by
/// default pass `null` to drop a previously-loaded token,
/// or omit the parameter to keep the current value.
Future<void> reconnect(
@ -241,7 +241,7 @@ class HubService {
}
/// Persist a new System-AI configuration. The hub writes back
/// to `~/.fai/config.yaml` and hot-reloads the in-memory copy
/// to `~/.chain/config.yaml` and hot-reloads the in-memory copy
/// in one round-trip; the caller gets the resulting status
/// for an immediate UI refresh.
Future<SystemAiStatus> updateSystemAi({
@ -449,7 +449,7 @@ class HubService {
/// Read the installed module's `MODULE.md` (or
/// `MODULE.<locale>.md`) from disk under
/// `~/.fai/modules/<module>/`. Air-gap friendly, no network.
/// `~/.chain/modules/<module>/`. Air-gap friendly, no network.
///
/// `state` is one of:
/// - `'found'` `text` holds the markdown

View file

@ -3,7 +3,7 @@ import 'package:path/path.dart' as p;
/// Operator-managed gRPC bearer token used to authenticate
/// Studio against a hub that has `auth.tokens:` configured
/// (RBAC Level 2). Stored at `~/.fai/hub-auth-token` (mode
/// (RBAC Level 2). Stored at `~/.chain/hub-auth-token` (mode
/// 0600 on Unix). Sister of [RegistryToken] same on-disk
/// hygiene, different secret.
///
@ -55,7 +55,7 @@ class HubAuthToken {
return content.isEmpty ? null : content;
}
/// Persist [token] to disk, creating `~/.fai/` if needed.
/// Persist [token] to disk, creating `~/.chain/` if needed.
///
/// Atomic write: writes to `<path>.tmp`, chmods 0600 on
/// Unix BEFORE moving into place, then renames. This
@ -63,7 +63,7 @@ class HubAuthToken {
/// `writeAsString` + later `chmod 600` sequence left the
/// file world-readable for the duration of the chmod call.
///
/// Also sets `~/.fai/` itself to 0700 on Unix on first
/// Also sets `~/.chain/` itself to 0700 on Unix on first
/// creation so other users on a shared host can't even
/// enumerate the directory (the 0600 token-file mode is
/// fine in isolation; combining it with a 0755 parent

View file

@ -2,8 +2,8 @@ import 'dart:io';
import 'package:path/path.dart' as p;
/// Operator-managed registry auth token, kept at
/// `~/.fai/registry-token` (mode 0600 on Unix). The hub reads
/// this file at install time when `FAI_REGISTRY_TOKEN` is unset
/// `~/.chain/registry-token` (mode 0600 on Unix). The hub reads
/// this file at install time when `CHAIN_REGISTRY_TOKEN` is unset
/// see `download_to_temp` in `crates/fai_hub/src/lib.rs`.
///
/// Studio writes the file directly so a fresh install never
@ -40,7 +40,7 @@ class RegistryToken {
return trimmed.isEmpty ? null : trimmed.length;
}
/// Persist [token] to disk, creating `~/.fai/` if needed.
/// Persist [token] to disk, creating `~/.chain/` if needed.
/// On Unix the file is chmod-ed to 0600 (owner read/write
/// only). On Windows the default user-ACL is left alone
/// best-effort, no PowerShell handshake.

View file

@ -11,7 +11,7 @@
// call for processes.
//
// The `fai` binary is resolved from PATH first; falls back to
// `~/.fai/bin/chain` (Unix) or `%USERPROFILE%\.fai\bin\chain.exe`
// `~/.chain/bin/chain` (Unix) or `%USERPROFILE%\.chain\bin\chain.exe`
// (Windows). The PowerShell installer puts both in PATH but
// some operators don't restart their shell after install — the
// fallback covers that case.
@ -30,7 +30,7 @@ const String kFaiBinaryNotFound = 'fai-binary-not-found';
/// in the OS browser as the fallback affordance when no `fai`
/// binary can be located on the machine.
const String kFaiInstallDocsUrl =
'https://git.flemming.ai/fai/platform#installation';
'https://git.flemming.ai/fai/chain#installation';
class SystemActions {
SystemActions._();
@ -151,7 +151,7 @@ class SystemActions {
return _runFai(['update', 'apply', '--channel', channel]);
}
/// Switch the active channel pointer at `~/.fai/current-channel`.
/// Switch the active channel pointer at `~/.chain/current-channel`.
/// The CLI also restarts the daemon for the new channel, so the
/// caller does not need a follow-up restart.
static Future<({bool ok, String stdout, String stderr})> faiChannelSwitch(
@ -179,7 +179,7 @@ class SystemActions {
/// Run `chain reset --yes`. Wipes operator state with the same
/// safety net as the CLI: stops every daemon (including off-
/// channel orphans), atomically backs `~/.fai/` up, recreates
/// channel orphans), atomically backs `~/.chain/` up, recreates
/// it with `bin/`, `channels/`, `config.yaml`, `current-channel`,
/// and `registry-token` preserved. The daemon restarts on the
/// active channel before the call returns.
@ -248,8 +248,8 @@ class SystemActions {
final home = Platform.environment[isWindows ? 'USERPROFILE' : 'HOME'];
if (home == null || home.isEmpty) return null;
final fallback = isWindows
? '$home\\.fai\\bin\\fai.exe'
: '$home/.fai/bin/chain';
? '$home\\.chain\\bin\\chain.exe'
: '$home/.chain/bin/chain';
return File(fallback).existsSync() ? fallback : null;
}

View file

@ -1,6 +1,6 @@
// Today-Hero story loader.
//
// Reads ~/.fai/today/active.yaml when present, validates the
// Reads ~/.chain/today/active.yaml when present, validates the
// schema, and hands the parsed bilingual story back to the
// store page. On any failure (file missing, schema mismatch,
// banned-words hit, parse error) the caller falls back to the
@ -73,7 +73,7 @@ class TodayStoryData {
/// store page calls `loadOrFallback` once per fetch and feeds
/// the result into `_StoreTodayHero`.
class TodayStoryLoader {
/// Resolves to `~/.fai/today/active.yaml` on every supported
/// Resolves to `~/.chain/today/active.yaml` on every supported
/// host. The pipeline writes here from [tools/today/accept.sh].
static String activePath() {
final home =