Add app source and tests

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
alvocool
2026-10-11 10:15:30 +03:00
parent 7e246255c2
commit 38881d1fe1
135 changed files with 21057 additions and 0 deletions

2221
lib/Peach/comms/Comms.dart Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,223 @@
import 'dart:typed_data';
import '../about/external/data/Docker.dart';
import '../about/external/data/Health.dart';
import '../about/external/data/Kafka.dart';
import '../about/external/data/Redis.dart';
import '../about/internal/application/ServerProfile.dart';
import '../about/internal/application/ServiceConfig.dart';
import '../about/internal/application/StepTracker.dart';
import 'Comms.dart';
/// The transport contract: everything Peach can ask a remote server to do.
/// In the Autoreceptive reference this is the HTTP surface; here the wire is
/// SSH, but the role is identical — one abstract description of every remote
/// call, implemented by exactly one class ([SshService]) and reached only
/// through the [DataManager].
abstract class ConnectComms {
// ── session ───────────────────────────────────────────────────────────────
bool get isConnected;
bool get canRevert;
Stream<LogLine> get logs;
Stream<TransferProgress?> get transferProgress;
Stream<List<DeployStep>> get stepStream;
Future<void> connect(ServerProfile s);
void requestCancel();
void disconnect();
void dispose();
// ── deployment ────────────────────────────────────────────────────────────
Future<DeployResult> deploy({
required ServerProfile server,
required ServiceConfig service,
required Uint8List jarBytes,
required String jarLabel,
});
Future<DeployResult> deployWeb({
required ServerProfile server,
required ServiceConfig service,
required Uint8List archiveBytes,
required int fileCount,
});
Future<DeployResult> restartOnly(ServerProfile server, ServiceConfig service);
Future<DeployResult> revert();
Future<void> discardBackup();
// ── provisioning ──────────────────────────────────────────────────────────
Future<DeployResult> installSystemdUnit({
required ServerProfile server,
required String unitName,
required String unitContent,
bool enable = true,
bool startNow = true,
});
Future<String> detectPackageManager(ServerProfile server);
Future<Map<String, String>> probeEnvironment(
ServerProfile server,
List<String> detectByKey,
);
Future<DeployResult> installEnvironment({
required ServerProfile server,
required String command,
required List<String> units,
});
Future<DeployResult> installPackages({
required ServerProfile server,
required String command,
String? enableUnit,
});
// ── service & health ──────────────────────────────────────────────────────
Future<HealthResult> checkHealth(ServerProfile server, ServiceConfig service);
Future<String> serviceStatus(ServerProfile server, ServiceConfig service);
Future<DeployResult> serviceControl(
ServerProfile server,
ServiceConfig service,
String action,
);
Future<List<String>> nginxRoots(ServerProfile server);
// ── logs ──────────────────────────────────────────────────────────────────
Future<void> fetchLogs(
ServerProfile server,
ServiceConfig service, {
DateTime? since,
DateTime? until,
});
Future<void> followLogs(ServerProfile server, ServiceConfig service);
void stopLogs();
// ── redis ─────────────────────────────────────────────────────────────────
Future<(bool, String)> redisPing(
ServerProfile server, {
String host,
int port,
String pass,
int db,
});
Future<String> redisConfigPassword(ServerProfile server);
Future<int> redisDbSize(
ServerProfile server, {
String host,
int port,
String pass,
int db,
});
Future<(int, Map<int, int>)> redisDatabases(
ServerProfile server, {
String host,
int port,
String pass,
});
Future<List<(String, String)>> redisKeysTyped(
ServerProfile server, {
String pattern,
String filterType,
int limit,
String host,
int port,
String pass,
int db,
});
Future<List<String>> redisKeys(
ServerProfile server, {
String pattern,
int limit,
String host,
int port,
String pass,
int db,
});
Future<RedisEntry> redisGet(
ServerProfile server,
String key, {
String host,
int port,
String pass,
int db,
});
// ── docker ────────────────────────────────────────────────────────────────
Future<DockerStatus> dockerStatus(ServerProfile server);
Future<List<DockerContainer>> dockerPs(ServerProfile server, {bool all});
Future<String> dockerAction(ServerProfile server, String id, String action);
Future<String> dockerLogs(ServerProfile server, String id, {int tail});
Future<String> dockerTest(ServerProfile server);
Future<(bool, String)> dockerRun(ServerProfile server, DockerRunSpec spec);
// ── kafka ─────────────────────────────────────────────────────────────────
Future<KafkaStatus> kafkaDetect(ServerProfile server);
Future<String> kafkaTest(
ServerProfile server, {
required String binDir,
required String suffix,
required String bootstrap,
});
Future<List<KafkaTopic>> kafkaTopics(
ServerProfile server, {
required String binDir,
required String suffix,
required String bootstrap,
bool includeInternal,
});
Future<List<KafkaConsumerGroup>> kafkaGroups(
ServerProfile server, {
required String binDir,
required String suffix,
required String bootstrap,
});
Future<KafkaCluster> kafkaCluster(
ServerProfile server, {
required String binDir,
required String suffix,
required String bootstrap,
});
// ── remote filesystem ─────────────────────────────────────────────────────
Future<List<RemoteEntry>> listDir(ServerProfile server, String path);
Future<String> resolveHome(ServerProfile server);
Future<void> uploadFile(
ServerProfile server,
Uint8List bytes,
String remotePath,
);
Future<Uint8List> downloadFile(ServerProfile server, String remotePath);
Future<void> deleteRemote(
ServerProfile server,
String remotePath,
bool isDir,
);
}