diff --git a/lib/src/generated/fai/v1/hub.pb.dart b/lib/src/generated/fai/v1/hub.pb.dart index e413fb9..038242d 100644 --- a/lib/src/generated/fai/v1/hub.pb.dart +++ b/lib/src/generated/fai/v1/hub.pb.dart @@ -1627,6 +1627,111 @@ class InstallModuleResponse extends $pb.GeneratedMessage { void clearCapabilityCount() => $_clearField(3); } +class UninstallModuleRequest extends $pb.GeneratedMessage { + factory UninstallModuleRequest({ + $core.String? name, + }) { + final $result = create(); + if (name != null) { + $result.name = name; + } + return $result; + } + UninstallModuleRequest._() : super(); + factory UninstallModuleRequest.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory UninstallModuleRequest.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + + static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'UninstallModuleRequest', package: const $pb.PackageName(_omitMessageNames ? '' : 'fai.v1'), createEmptyInstance: create) + ..aOS(1, _omitFieldNames ? '' : 'name') + ..hasRequiredFields = false + ; + + @$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.') + UninstallModuleRequest clone() => UninstallModuleRequest()..mergeFromMessage(this); + @$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.') + UninstallModuleRequest copyWith(void Function(UninstallModuleRequest) updates) => super.copyWith((message) => updates(message as UninstallModuleRequest)) as UninstallModuleRequest; + + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static UninstallModuleRequest create() => UninstallModuleRequest._(); + UninstallModuleRequest createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static UninstallModuleRequest getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static UninstallModuleRequest? _defaultInstance; + + /// Module name as the registry knows it. Empty → InvalidArgument. + @$pb.TagNumber(1) + $core.String get name => $_getSZ(0); + @$pb.TagNumber(1) + set name($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasName() => $_has(0); + @$pb.TagNumber(1) + void clearName() => $_clearField(1); +} + +class UninstallModuleResponse extends $pb.GeneratedMessage { + factory UninstallModuleResponse({ + $core.String? name, + $core.String? version, + }) { + final $result = create(); + if (name != null) { + $result.name = name; + } + if (version != null) { + $result.version = version; + } + return $result; + } + UninstallModuleResponse._() : super(); + factory UninstallModuleResponse.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory UninstallModuleResponse.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + + static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'UninstallModuleResponse', package: const $pb.PackageName(_omitMessageNames ? '' : 'fai.v1'), createEmptyInstance: create) + ..aOS(1, _omitFieldNames ? '' : 'name') + ..aOS(2, _omitFieldNames ? '' : 'version') + ..hasRequiredFields = false + ; + + @$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.') + UninstallModuleResponse clone() => UninstallModuleResponse()..mergeFromMessage(this); + @$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.') + UninstallModuleResponse copyWith(void Function(UninstallModuleResponse) updates) => super.copyWith((message) => updates(message as UninstallModuleResponse)) as UninstallModuleResponse; + + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static UninstallModuleResponse create() => UninstallModuleResponse._(); + UninstallModuleResponse createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static UninstallModuleResponse getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static UninstallModuleResponse? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get name => $_getSZ(0); + @$pb.TagNumber(1) + set name($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasName() => $_has(0); + @$pb.TagNumber(1) + void clearName() => $_clearField(1); + + /// Version that was removed; "unknown" when the manifest was + /// unreadable for some reason but the directory still got wiped. + @$pb.TagNumber(2) + $core.String get version => $_getSZ(1); + @$pb.TagNumber(2) + set version($core.String v) { $_setString(1, v); } + @$pb.TagNumber(2) + $core.bool hasVersion() => $_has(1); + @$pb.TagNumber(2) + void clearVersion() => $_clearField(2); +} + class ListApprovalsRequest extends $pb.GeneratedMessage { factory ListApprovalsRequest({ $core.Iterable<$core.String>? statuses, @@ -2618,6 +2723,128 @@ class ChannelEntry extends $pb.GeneratedMessage { void clearEndpoint() => $_clearField(4); } +class DaemonPathsResponse extends $pb.GeneratedMessage { + factory DaemonPathsResponse({ + $core.String? logPath, + $core.String? dbPath, + $core.String? modulesDir, + $core.String? flowsDir, + $core.String? configPath, + $core.String? pidPath, + }) { + final $result = create(); + if (logPath != null) { + $result.logPath = logPath; + } + if (dbPath != null) { + $result.dbPath = dbPath; + } + if (modulesDir != null) { + $result.modulesDir = modulesDir; + } + if (flowsDir != null) { + $result.flowsDir = flowsDir; + } + if (configPath != null) { + $result.configPath = configPath; + } + if (pidPath != null) { + $result.pidPath = pidPath; + } + return $result; + } + DaemonPathsResponse._() : super(); + factory DaemonPathsResponse.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory DaemonPathsResponse.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + + static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'DaemonPathsResponse', package: const $pb.PackageName(_omitMessageNames ? '' : 'fai.v1'), createEmptyInstance: create) + ..aOS(1, _omitFieldNames ? '' : 'logPath') + ..aOS(2, _omitFieldNames ? '' : 'dbPath') + ..aOS(3, _omitFieldNames ? '' : 'modulesDir') + ..aOS(4, _omitFieldNames ? '' : 'flowsDir') + ..aOS(5, _omitFieldNames ? '' : 'configPath') + ..aOS(6, _omitFieldNames ? '' : 'pidPath') + ..hasRequiredFields = false + ; + + @$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.') + DaemonPathsResponse clone() => DaemonPathsResponse()..mergeFromMessage(this); + @$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.') + DaemonPathsResponse copyWith(void Function(DaemonPathsResponse) updates) => super.copyWith((message) => updates(message as DaemonPathsResponse)) as DaemonPathsResponse; + + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static DaemonPathsResponse create() => DaemonPathsResponse._(); + DaemonPathsResponse createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static DaemonPathsResponse getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static DaemonPathsResponse? _defaultInstance; + + /// Channel-scoped log file path (empty if Studio cannot + /// resolve one — e.g. older daemon writes only to stderr). + @$pb.TagNumber(1) + $core.String get logPath => $_getSZ(0); + @$pb.TagNumber(1) + set logPath($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasLogPath() => $_has(0); + @$pb.TagNumber(1) + void clearLogPath() => $_clearField(1); + + /// SQLite audit-log database path. + @$pb.TagNumber(2) + $core.String get dbPath => $_getSZ(1); + @$pb.TagNumber(2) + set dbPath($core.String v) { $_setString(1, v); } + @$pb.TagNumber(2) + $core.bool hasDbPath() => $_has(1); + @$pb.TagNumber(2) + void clearDbPath() => $_clearField(2); + + /// Modules directory the registry scans. + @$pb.TagNumber(3) + $core.String get modulesDir => $_getSZ(2); + @$pb.TagNumber(3) + set modulesDir($core.String v) { $_setString(2, v); } + @$pb.TagNumber(3) + $core.bool hasModulesDir() => $_has(2); + @$pb.TagNumber(3) + void clearModulesDir() => $_clearField(3); + + /// Saved flows directory. + @$pb.TagNumber(4) + $core.String get flowsDir => $_getSZ(3); + @$pb.TagNumber(4) + set flowsDir($core.String v) { $_setString(3, v); } + @$pb.TagNumber(4) + $core.bool hasFlowsDir() => $_has(3); + @$pb.TagNumber(4) + void clearFlowsDir() => $_clearField(4); + + /// Operator config file (~/.fai/config.yaml). + @$pb.TagNumber(5) + $core.String get configPath => $_getSZ(4); + @$pb.TagNumber(5) + set configPath($core.String v) { $_setString(4, v); } + @$pb.TagNumber(5) + $core.bool hasConfigPath() => $_has(4); + @$pb.TagNumber(5) + void clearConfigPath() => $_clearField(5); + + /// PID file the daemon supervisor writes (for the active + /// channel). + @$pb.TagNumber(6) + $core.String get pidPath => $_getSZ(5); + @$pb.TagNumber(6) + set pidPath($core.String v) { $_setString(5, v); } + @$pb.TagNumber(6) + $core.bool hasPidPath() => $_has(5); + @$pb.TagNumber(6) + void clearPidPath() => $_clearField(6); +} + class CheckUpdateResponse extends $pb.GeneratedMessage { factory CheckUpdateResponse({ $core.String? channel, diff --git a/lib/src/generated/fai/v1/hub.pbgrpc.dart b/lib/src/generated/fai/v1/hub.pbgrpc.dart index ae53106..b42649f 100644 --- a/lib/src/generated/fai/v1/hub.pbgrpc.dart +++ b/lib/src/generated/fai/v1/hub.pbgrpc.dart @@ -163,6 +163,10 @@ class HubAdminClient extends $grpc.Client { '/fai.v1.HubAdmin/InstallModule', ($0.InstallModuleRequest value) => value.writeToBuffer(), ($core.List<$core.int> value) => $0.InstallModuleResponse.fromBuffer(value)); + static final _$uninstallModule = $grpc.ClientMethod<$0.UninstallModuleRequest, $0.UninstallModuleResponse>( + '/fai.v1.HubAdmin/UninstallModule', + ($0.UninstallModuleRequest value) => value.writeToBuffer(), + ($core.List<$core.int> value) => $0.UninstallModuleResponse.fromBuffer(value)); static final _$listApprovals = $grpc.ClientMethod<$0.ListApprovalsRequest, $0.ApprovalList>( '/fai.v1.HubAdmin/ListApprovals', ($0.ListApprovalsRequest value) => value.writeToBuffer(), @@ -191,6 +195,10 @@ class HubAdminClient extends $grpc.Client { '/fai.v1.HubAdmin/ChannelStatus', ($1.Empty value) => value.writeToBuffer(), ($core.List<$core.int> value) => $0.ChannelStatusResponse.fromBuffer(value)); + static final _$daemonPaths = $grpc.ClientMethod<$1.Empty, $0.DaemonPathsResponse>( + '/fai.v1.HubAdmin/DaemonPaths', + ($1.Empty value) => value.writeToBuffer(), + ($core.List<$core.int> value) => $0.DaemonPathsResponse.fromBuffer(value)); static final _$systemAiStatus = $grpc.ClientMethod<$1.Empty, $0.SystemAiStatusResponse>( '/fai.v1.HubAdmin/SystemAiStatus', ($1.Empty value) => value.writeToBuffer(), @@ -284,6 +292,14 @@ class HubAdminClient extends $grpc.Client { return $createUnaryCall(_$installModule, request, options: options); } + /// Remove an installed module by name. Wipes the module + /// directory and re-scans the registry; writes a + /// `module.uninstalled` audit event. Surfaced by the Studio + /// module sheet's "Uninstall" affordance. + $grpc.ResponseFuture<$0.UninstallModuleResponse> uninstallModule($0.UninstallModuleRequest request, {$grpc.CallOptions? options}) { + return $createUnaryCall(_$uninstallModule, request, options: options); + } + /// List system.approval@^0 entries, optionally filtered by status. $grpc.ResponseFuture<$0.ApprovalList> listApprovals($0.ListApprovalsRequest request, {$grpc.CallOptions? options}) { return $createUnaryCall(_$listApprovals, request, options: options); @@ -336,6 +352,14 @@ class HubAdminClient extends $grpc.Client { return $createUnaryCall(_$channelStatus, request, options: options); } + /// Filesystem locations the daemon owns: log file, db file, + /// modules dir, flows dir, config file. Studio's Doctor page + /// surfaces these so operators on Windows (who never touch + /// a shell) can open them via the OS file manager. + $grpc.ResponseFuture<$0.DaemonPathsResponse> daemonPaths($1.Empty request, {$grpc.CallOptions? options}) { + return $createUnaryCall(_$daemonPaths, request, options: options); + } + /// Read-only system-AI status. Lets Studio render the /// "configure in Settings" affordance when the feature is /// off, and the privacy-mode badge when it is on. @@ -490,6 +514,13 @@ abstract class HubAdminServiceBase extends $grpc.Service { false, ($core.List<$core.int> value) => $0.InstallModuleRequest.fromBuffer(value), ($0.InstallModuleResponse value) => value.writeToBuffer())); + $addMethod($grpc.ServiceMethod<$0.UninstallModuleRequest, $0.UninstallModuleResponse>( + 'UninstallModule', + uninstallModule_Pre, + false, + false, + ($core.List<$core.int> value) => $0.UninstallModuleRequest.fromBuffer(value), + ($0.UninstallModuleResponse value) => value.writeToBuffer())); $addMethod($grpc.ServiceMethod<$0.ListApprovalsRequest, $0.ApprovalList>( 'ListApprovals', listApprovals_Pre, @@ -539,6 +570,13 @@ abstract class HubAdminServiceBase extends $grpc.Service { false, ($core.List<$core.int> value) => $1.Empty.fromBuffer(value), ($0.ChannelStatusResponse value) => value.writeToBuffer())); + $addMethod($grpc.ServiceMethod<$1.Empty, $0.DaemonPathsResponse>( + 'DaemonPaths', + daemonPaths_Pre, + false, + false, + ($core.List<$core.int> value) => $1.Empty.fromBuffer(value), + ($0.DaemonPathsResponse value) => value.writeToBuffer())); $addMethod($grpc.ServiceMethod<$1.Empty, $0.SystemAiStatusResponse>( 'SystemAiStatus', systemAiStatus_Pre, @@ -651,6 +689,10 @@ abstract class HubAdminServiceBase extends $grpc.Service { return installModule($call, await $request); } + $async.Future<$0.UninstallModuleResponse> uninstallModule_Pre($grpc.ServiceCall $call, $async.Future<$0.UninstallModuleRequest> $request) async { + return uninstallModule($call, await $request); + } + $async.Future<$0.ApprovalList> listApprovals_Pre($grpc.ServiceCall $call, $async.Future<$0.ListApprovalsRequest> $request) async { return listApprovals($call, await $request); } @@ -679,6 +721,10 @@ abstract class HubAdminServiceBase extends $grpc.Service { return channelStatus($call, await $request); } + $async.Future<$0.DaemonPathsResponse> daemonPaths_Pre($grpc.ServiceCall $call, $async.Future<$1.Empty> $request) async { + return daemonPaths($call, await $request); + } + $async.Future<$0.SystemAiStatusResponse> systemAiStatus_Pre($grpc.ServiceCall $call, $async.Future<$1.Empty> $request) async { return systemAiStatus($call, await $request); } @@ -729,6 +775,7 @@ abstract class HubAdminServiceBase extends $grpc.Service { $async.Future<$0.SubmitResponse> runSavedFlow($grpc.ServiceCall call, $0.RunSavedFlowRequest request); $async.Future<$0.StoreSearchResponse> searchStore($grpc.ServiceCall call, $0.SearchStoreRequest request); $async.Future<$0.InstallModuleResponse> installModule($grpc.ServiceCall call, $0.InstallModuleRequest request); + $async.Future<$0.UninstallModuleResponse> uninstallModule($grpc.ServiceCall call, $0.UninstallModuleRequest request); $async.Future<$0.ApprovalList> listApprovals($grpc.ServiceCall call, $0.ListApprovalsRequest request); $async.Future<$0.DecideApprovalResponse> decideApproval($grpc.ServiceCall call, $0.DecideApprovalRequest request); $async.Future<$0.VerifyEventChainResponse> verifyEventChain($grpc.ServiceCall call, $1.Empty request); @@ -736,6 +783,7 @@ abstract class HubAdminServiceBase extends $grpc.Service { $async.Future<$0.ServiceList> listServices($grpc.ServiceCall call, $1.Empty request); $async.Future<$0.CheckUpdateResponse> checkUpdate($grpc.ServiceCall call, $1.Empty request); $async.Future<$0.ChannelStatusResponse> channelStatus($grpc.ServiceCall call, $1.Empty request); + $async.Future<$0.DaemonPathsResponse> daemonPaths($grpc.ServiceCall call, $1.Empty request); $async.Future<$0.SystemAiStatusResponse> systemAiStatus($grpc.ServiceCall call, $1.Empty request); $async.Future<$0.AskAiResponse> askAi($grpc.ServiceCall call, $0.AskAiRequest request); $async.Future<$0.SystemAiStatusResponse> updateSystemAi($grpc.ServiceCall call, $0.UpdateSystemAiRequest request); diff --git a/lib/src/generated/fai/v1/hub.pbjson.dart b/lib/src/generated/fai/v1/hub.pbjson.dart index cc347fb..4806391 100644 --- a/lib/src/generated/fai/v1/hub.pbjson.dart +++ b/lib/src/generated/fai/v1/hub.pbjson.dart @@ -435,6 +435,32 @@ final $typed_data.Uint8List installModuleResponseDescriptor = $convert.base64Dec 'IgASgJUgd2ZXJzaW9uEikKEGNhcGFiaWxpdHlfY291bnQYAyABKAVSD2NhcGFiaWxpdHlDb3Vu' 'dA=='); +@$core.Deprecated('Use uninstallModuleRequestDescriptor instead') +const UninstallModuleRequest$json = { + '1': 'UninstallModuleRequest', + '2': [ + {'1': 'name', '3': 1, '4': 1, '5': 9, '10': 'name'}, + ], +}; + +/// Descriptor for `UninstallModuleRequest`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List uninstallModuleRequestDescriptor = $convert.base64Decode( + 'ChZVbmluc3RhbGxNb2R1bGVSZXF1ZXN0EhIKBG5hbWUYASABKAlSBG5hbWU='); + +@$core.Deprecated('Use uninstallModuleResponseDescriptor instead') +const UninstallModuleResponse$json = { + '1': 'UninstallModuleResponse', + '2': [ + {'1': 'name', '3': 1, '4': 1, '5': 9, '10': 'name'}, + {'1': 'version', '3': 2, '4': 1, '5': 9, '10': 'version'}, + ], +}; + +/// Descriptor for `UninstallModuleResponse`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List uninstallModuleResponseDescriptor = $convert.base64Decode( + 'ChdVbmluc3RhbGxNb2R1bGVSZXNwb25zZRISCgRuYW1lGAEgASgJUgRuYW1lEhgKB3ZlcnNpb2' + '4YAiABKAlSB3ZlcnNpb24='); + @$core.Deprecated('Use listApprovalsRequestDescriptor instead') const ListApprovalsRequest$json = { '1': 'ListApprovalsRequest', @@ -643,6 +669,26 @@ final $typed_data.Uint8List channelEntryDescriptor = $convert.base64Decode( 'CgxDaGFubmVsRW50cnkSEgoEbmFtZRgBIAEoCVIEbmFtZRISCgRwb3J0GAIgASgNUgRwb3J0Eh' 'gKB3J1bm5pbmcYAyABKAhSB3J1bm5pbmcSGgoIZW5kcG9pbnQYBCABKAlSCGVuZHBvaW50'); +@$core.Deprecated('Use daemonPathsResponseDescriptor instead') +const DaemonPathsResponse$json = { + '1': 'DaemonPathsResponse', + '2': [ + {'1': 'log_path', '3': 1, '4': 1, '5': 9, '10': 'logPath'}, + {'1': 'db_path', '3': 2, '4': 1, '5': 9, '10': 'dbPath'}, + {'1': 'modules_dir', '3': 3, '4': 1, '5': 9, '10': 'modulesDir'}, + {'1': 'flows_dir', '3': 4, '4': 1, '5': 9, '10': 'flowsDir'}, + {'1': 'config_path', '3': 5, '4': 1, '5': 9, '10': 'configPath'}, + {'1': 'pid_path', '3': 6, '4': 1, '5': 9, '10': 'pidPath'}, + ], +}; + +/// Descriptor for `DaemonPathsResponse`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List daemonPathsResponseDescriptor = $convert.base64Decode( + 'ChNEYWVtb25QYXRoc1Jlc3BvbnNlEhkKCGxvZ19wYXRoGAEgASgJUgdsb2dQYXRoEhcKB2RiX3' + 'BhdGgYAiABKAlSBmRiUGF0aBIfCgttb2R1bGVzX2RpchgDIAEoCVIKbW9kdWxlc0RpchIbCglm' + 'bG93c19kaXIYBCABKAlSCGZsb3dzRGlyEh8KC2NvbmZpZ19wYXRoGAUgASgJUgpjb25maWdQYX' + 'RoEhkKCHBpZF9wYXRoGAYgASgJUgdwaWRQYXRo'); + @$core.Deprecated('Use checkUpdateResponseDescriptor instead') const CheckUpdateResponse$json = { '1': 'CheckUpdateResponse', diff --git a/lib/src/hub_client.dart b/lib/src/hub_client.dart index a0dd4ac..8b3c44f 100644 --- a/lib/src/hub_client.dart +++ b/lib/src/hub_client.dart @@ -54,6 +54,8 @@ typedef ListSystemAiCuratedModelsResponse = pb.ListSystemAiCuratedModelsResponse; typedef CuratedModel = pb.CuratedModel; typedef ClearEventLogResponse = pb.ClearEventLogResponse; +typedef DaemonPathsResponse = pb.DaemonPathsResponse; +typedef UninstallModuleResponse = pb.UninstallModuleResponse; typedef ModuleInfoResponse = pb.ModuleInfoResponse; typedef FlowSummary = pb.FlowSummary; typedef StoreEntry = pb.StoreEntry; @@ -208,6 +210,22 @@ class HubClient { return _admin.channelStatus(Empty()); } + /// Filesystem paths the daemon owns (log file, db, config, + /// flows, modules, pid). Studio's Doctor page surfaces these + /// as "Open in file manager" buttons so Windows operators can + /// inspect everything without a shell. + Future daemonPaths() { + return _admin.daemonPaths(Empty()); + } + + /// Remove an installed module by name. Wipes the module + /// directory + re-scans the registry; writes a + /// `module.uninstalled` audit event. Returned response carries + /// the version that was removed. + Future uninstallModule(String name) { + return _admin.uninstallModule(pb.UninstallModuleRequest(name: name)); + } + /// Read-only system-AI status. `enabled=false` lets Studio /// render "configure in Settings" without making a request. Future systemAiStatus() { diff --git a/pubspec.yaml b/pubspec.yaml index 54458fe..345461e 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: fai_dart_sdk description: gRPC client SDK for the F∆I Platform hub. Used by F∆I Studio and Tier-3 domain apps. -version: 0.8.0 +version: 0.9.0 publish_to: 'none' repository: https://git.flemming.ws/fai/dart-sdk