dissolve app/ into repo root (D-056)

Single Flutter package at the repo root. All code, tests, assets,
and platform directories moved from app/ to root. Package renamed
from clide_app to clide — all imports rewritten. Merged pubspec
combines core (ffi) and app (flutter, yaml, xterm) dependencies.
Makefile simplified: no APP_PRESENT conditionals, no cd, no daemon
lifecycle. 317 tests pass.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-23 00:37:20 +02:00
co-authored by Claude Opus 4.6
parent a526c5b9b7
commit 46329700d5
394 changed files with 978 additions and 1090 deletions
+80
View File
@@ -0,0 +1,80 @@
import 'dart:ui';
import 'package:clide/kernel/kernel.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
const loader = ThemeLoader();
group('ThemeLoader.fromYamlString', () {
test('parses palette-only theme', () {
final def = loader.fromYamlString('''
name: summer-night
display_name: Summer Night
dark: true
palette:
primary: "#00a3d2"
background: "#21262F"
foreground: "#E2E8F5"
''');
expect(def.name, 'summer-night');
expect(def.displayName, 'Summer Night');
expect(def.dark, true);
expect(def.palette.lookup('primary'), const Color(0xFF00A3D2));
expect(def.semanticOverride, isNull);
expect(def.surfaceOverride, isNull);
});
test('captures semantic overrides as palette-resolved colors', () {
final def = loader.fromYamlString('''
name: t
palette:
red: "#FF0000"
blue: "#0000FF"
semantic:
mainchrome: red
focus: "#123456"
''');
expect(
def.semanticOverride!.lookup('mainchrome'), const Color(0xFFFF0000));
expect(def.semanticOverride!.lookup('focus'), const Color(0xFF123456));
});
test('captures surface overrides as ref strings', () {
final def = loader.fromYamlString('''
name: t
palette:
red: "#FF0000"
surface:
panel.background: "semantic.mainchrome"
panel.border: red
''');
expect(def.surfaceOverride, {
'panel.background': 'semantic.mainchrome',
'panel.border': 'red',
});
});
test('throws when name is missing and no fallback', () {
expect(
() => loader.fromYamlString('palette: { fg: "#fff" }'),
throwsA(isA<FormatException>()),
);
});
test('throws when palette is missing', () {
expect(
() => loader.fromYamlString('name: t'),
throwsA(isA<FormatException>()),
);
});
test('fallback name is used when name is absent', () {
final def = loader.fromYamlString(
'palette: { fg: "#fff" }',
fallbackName: 'inferred',
);
expect(def.name, 'inferred');
});
});
}