Backend isolate now boots in two phases: resolve toolchain on spawn (binary availability only), initialize services on project.open. The dispatcher stays empty until a project activates — IPC requests before that return "No project active". Scheduler ticker only runs while a project is open. Fires an immediate first cycle on ProjectOpened so sidebar panels refresh without waiting for the next interval. Stops on ProjectClosed. Renamed workspace → project throughout backend messages (project.validate, project.open, project.ready), callbacks (onProjectOpen, onValidateProject), and methods (openProject, validateProject, resolveProject). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
56 lines
1.5 KiB
Dart
56 lines
1.5 KiB
Dart
import 'package:clide/clide.dart' show clideVersion;
|
|
import 'package:clide/src/ipc/envelope.dart';
|
|
import 'package:clide/src/ipc/schema_v1.dart';
|
|
|
|
typedef CommandHandler = Future<IpcResponse> Function(IpcRequest req);
|
|
|
|
class DaemonDispatcher {
|
|
DaemonDispatcher() {
|
|
register('ping', _ping);
|
|
register('version', _version);
|
|
}
|
|
|
|
final Map<String, CommandHandler> _handlers = {};
|
|
|
|
void register(String cmd, CommandHandler handler) {
|
|
_handlers[cmd] = handler;
|
|
}
|
|
|
|
/// Remove all registered handlers except ping/version.
|
|
void clear() {
|
|
_handlers.removeWhere((k, _) => k != 'ping' && k != 'version');
|
|
}
|
|
|
|
bool get isEmpty => _handlers.length <= 2; // only ping + version
|
|
|
|
Future<IpcResponse> dispatch(IpcRequest req) async {
|
|
final h = _handlers[req.cmd];
|
|
if (h == null) {
|
|
return IpcResponse.err(
|
|
id: req.id,
|
|
error: IpcError(
|
|
code: IpcExitCode.notFound,
|
|
kind: IpcErrorKind.notFound,
|
|
message: 'unknown command: ${req.cmd}',
|
|
hint: 'run `clide --help` for the surface.',
|
|
),
|
|
);
|
|
}
|
|
return h(req);
|
|
}
|
|
|
|
Future<IpcResponse> _ping(IpcRequest req) async => IpcResponse.ok(
|
|
id: req.id,
|
|
data: {
|
|
'pong': true,
|
|
'ts': DateTime.now().toUtc().toIso8601String(),
|
|
'version': clideVersion,
|
|
},
|
|
);
|
|
|
|
Future<IpcResponse> _version(IpcRequest req) async => IpcResponse.ok(
|
|
id: req.id,
|
|
data: {'version': clideVersion},
|
|
);
|
|
}
|