Files
agent-radar 2ed3415fb7
Publish Claude Code Binaries / Stage and publish binaries (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-arm64 (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build linux-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build windows-amd64 (push) Canceled after 0s
Sync Tutti Agent Skills / sync (push) Canceled after 0s
Windows Agent Adapters / Test Windows agent adapters (push) Canceled after 0s
Windows Daemon Adapters / Test Windows daemon adapters (push) Canceled after 0s
Publish Tutti App Runtime / Publish runtime catalog (push) Canceled after 0s
源码快照 @ 2026-09-01 (source-only, 剔除非源码素材)
2026-09-01 20:17:27 +08:00

371 lines
13 KiB
Go

package workspace
import (
"strings"
tuttigenerated "github.com/tutti-os/tutti/services/tuttid/api/generated"
workspacebiz "github.com/tutti-os/tutti/services/tuttid/biz/workspace"
)
func GeneratedAppFromBiz(app workspacebiz.WorkspaceApp) tuttigenerated.WorkspaceApp {
return tuttigenerated.WorkspaceApp{
AppId: app.Package.AppID,
DisplayName: app.Package.DisplayName(),
Version: app.Package.Version,
Description: app.Package.Description(),
Authors: generatedAppAuthorsFromBiz(app.Package.Manifest),
Repository: generatedAppRepositoryFromBiz(app.Package.Manifest),
CreatedAtUnixMs: app.Package.CreatedAtUnixMs,
IconUrl: app.ResolvedIconURL(),
AvailableVersion: app.AvailableVersion,
AvailableIconUrl: app.AvailableIconURL,
UpdateAvailable: app.UpdateAvailable,
Installed: app.Installation != nil,
Enabled: app.Installation != nil && app.Installation.Enabled,
Status: generatedAppRuntimeStatus(app.Runtime.Status),
StateRevision: app.StateRevision,
LaunchUrl: app.Runtime.LaunchURL,
Port: app.Runtime.Port,
FailurePhase: generatedAppFailurePhase(app.Runtime.FailurePhase),
FailureReason: app.Runtime.FailureReason,
LastError: app.Runtime.LastError,
StartedAtUnixMs: app.Runtime.StartedAtUnixMs,
UpdatedAtUnixMs: app.Runtime.UpdatedAtUnixMs,
Source: generatedAppSource(app.Package.Source),
Exportable: app.Package.Source == workspacebiz.AppPackageSourceGenerated || app.Package.Source == workspacebiz.AppPackageSourceImported,
LocalPackageDir: generatedAppLocalPackageDir(app.Package),
Tags: nonNilStrings(app.Package.Manifest.Tags),
Localizations: GeneratedAppLocalizationsFromBiz(app.Package.Localizations()),
MinimizeBehavior: tuttigenerated.WorkspaceAppMinimizeBehavior(app.Package.MinimizeBehavior()),
WindowMinWidth: app.Package.WindowMinWidth(),
WindowMinHeight: app.Package.WindowMinHeight(),
Cli: generatedAppCLIState(app.CLI),
References: generatedAppReferencesStateFromBiz(app),
InstallProgress: generatedAppInstallProgressFromBiz(app.InstallProgress),
}
}
func generatedAppFailurePhase(value *workspacebiz.AppFailurePhase) *tuttigenerated.WorkspaceAppFailurePhase {
if value == nil {
return nil
}
result := tuttigenerated.WorkspaceAppFailurePhase(*value)
return &result
}
func generatedAppAuthorsFromBiz(manifest workspacebiz.AppManifest) []tuttigenerated.WorkspaceAppAuthor {
authors := manifest.Authors
if len(authors) == 0 && manifest.Author != nil {
authors = []workspacebiz.AppManifestAuthor{*manifest.Author}
}
result := make([]tuttigenerated.WorkspaceAppAuthor, 0, len(authors))
for _, author := range authors {
name := trimString(author.Name)
if name == "" {
continue
}
result = append(result, tuttigenerated.WorkspaceAppAuthor{
Name: name,
AvatarUrl: nullableString(trimString(author.AvatarURL)),
Url: nullableString(trimString(author.URL)),
})
}
return result
}
func generatedAppRepositoryFromBiz(manifest workspacebiz.AppManifest) *tuttigenerated.WorkspaceAppRepository {
if manifest.Source == nil {
return nil
}
repositoryType := trimString(manifest.Source.Type)
repositoryURL := trimString(manifest.Source.URL)
if repositoryType != "github" || repositoryURL == "" {
return nil
}
return &tuttigenerated.WorkspaceAppRepository{
Type: tuttigenerated.Github,
Url: repositoryURL,
}
}
func generatedAppInstallProgressFromBiz(progress *workspacebiz.AppInstallProgress) *tuttigenerated.WorkspaceAppInstallProgress {
if progress == nil {
return nil
}
return &tuttigenerated.WorkspaceAppInstallProgress{
UserPhase: generatedAppInstallUserPhase(progress.UserPhase),
OverallPercent: float32(progress.OverallPercent),
DownloadedBytes: progress.DownloadedBytes,
TotalBytes: progress.TotalBytes,
Indeterminate: progress.Indeterminate,
}
}
func generatedAppInstallUserPhase(phase workspacebiz.AppInstallUserPhase) tuttigenerated.WorkspaceAppInstallUserPhase {
switch phase {
case workspacebiz.AppInstallUserPhaseInstalling:
return tuttigenerated.WorkspaceAppInstallUserPhaseInstalling
case workspacebiz.AppInstallUserPhaseStarting:
return tuttigenerated.WorkspaceAppInstallUserPhaseStarting
default:
return tuttigenerated.WorkspaceAppInstallUserPhaseDownloading
}
}
func GeneratedAppsFromBiz(apps []workspacebiz.WorkspaceApp) []tuttigenerated.WorkspaceApp {
result := make([]tuttigenerated.WorkspaceApp, 0, len(apps))
for _, app := range apps {
result = append(result, GeneratedAppFromBiz(app))
}
return result
}
func GeneratedAppReferenceListResultFromBiz(workspaceID string, appID string, result workspacebiz.AppReferenceListResult) tuttigenerated.AppReferenceListResponse {
return tuttigenerated.AppReferenceListResponse{
WorkspaceId: workspaceID,
AppId: appID,
Items: generatedAppReferenceListItemsFromBiz(result.Items),
NextCursor: result.NextCursor,
}
}
func GeneratedAppReferenceSearchResultFromBiz(workspaceID string, appID string, result workspacebiz.AppReferenceListResult) tuttigenerated.AppReferenceSearchResponse {
return tuttigenerated.AppReferenceSearchResponse{
WorkspaceId: workspaceID,
AppId: appID,
Items: generatedAppReferenceSearchItemsFromBiz(result.Items),
NextCursor: result.NextCursor,
}
}
func generatedAppReferenceSearchItemsFromBiz(items []workspacebiz.AppReferenceListItem) []tuttigenerated.AppReferenceListReferenceItem {
result := make([]tuttigenerated.AppReferenceListReferenceItem, 0, len(items))
for _, item := range items {
referenceItem, ok := item.(workspacebiz.AppReferenceListReferenceItem)
if !ok {
continue
}
reference, ok := generatedAppReferenceFromBiz(referenceItem.Reference)
if !ok {
continue
}
result = append(result, tuttigenerated.AppReferenceListReferenceItem{
Type: tuttigenerated.AppReferenceListReferenceItemTypeReference,
Reference: reference,
})
}
return result
}
func GeneratedAppLocalizationsFromBiz(localizations []workspacebiz.AppManifestLocalization) []tuttigenerated.WorkspaceAppLocalization {
result := make([]tuttigenerated.WorkspaceAppLocalization, 0, len(localizations))
for _, localization := range localizations {
result = append(result, tuttigenerated.WorkspaceAppLocalization{
Locale: localization.Locale,
DisplayName: nullableString(localization.Name),
Description: nullableString(localization.Description),
Tags: nonNilStrings(localization.Tags),
})
}
return result
}
func GeneratedAppCatalogLoadStateFromBiz(state workspacebiz.AppCatalogLoadState) tuttigenerated.WorkspaceAppCatalogLoadState {
return tuttigenerated.WorkspaceAppCatalogLoadState{
Status: generatedAppCatalogLoadStatus(state.Status),
LastError: state.LastError,
UpdatedAtUnixMs: state.UpdatedAtUnixMs,
}
}
func generatedAppReferencesStateFromBiz(app workspacebiz.WorkspaceApp) tuttigenerated.WorkspaceAppReferencesState {
return tuttigenerated.WorkspaceAppReferencesState{
ListSupported: app.Package.ReferenceListSupported(),
SearchSupported: app.Package.ReferenceSearchSupported(),
}
}
func generatedAppReferenceListItemsFromBiz(items []workspacebiz.AppReferenceListItem) []tuttigenerated.AppReferenceListItem {
result := make([]tuttigenerated.AppReferenceListItem, 0, len(items))
for _, item := range items {
generated, ok := generatedAppReferenceListItemFromBiz(item)
if ok {
result = append(result, generated)
}
}
return result
}
func generatedAppReferenceListItemFromBiz(item workspacebiz.AppReferenceListItem) (tuttigenerated.AppReferenceListItem, bool) {
switch typed := item.(type) {
case workspacebiz.AppReferenceGroup:
var generated tuttigenerated.AppReferenceListItem
if err := generated.FromAppReferenceGroup(tuttigenerated.AppReferenceGroup{
Type: tuttigenerated.AppReferenceGroupTypeGroup,
Id: typed.ID,
DisplayName: typed.DisplayName,
Description: nullableString(typed.Description),
ReferenceCount: typed.ReferenceCount,
}); err != nil {
return tuttigenerated.AppReferenceListItem{}, false
}
return generated, true
case workspacebiz.AppReferenceListReferenceItem:
reference, ok := generatedAppReferenceFromBiz(typed.Reference)
if !ok {
return tuttigenerated.AppReferenceListItem{}, false
}
var generated tuttigenerated.AppReferenceListItem
if err := generated.FromAppReferenceListReferenceItem(tuttigenerated.AppReferenceListReferenceItem{
Type: tuttigenerated.AppReferenceListReferenceItemTypeReference,
Reference: reference,
}); err != nil {
return tuttigenerated.AppReferenceListItem{}, false
}
return generated, true
default:
return tuttigenerated.AppReferenceListItem{}, false
}
}
func generatedAppReferenceFromBiz(reference workspacebiz.AppReference) (tuttigenerated.AppReference, bool) {
switch typed := reference.(type) {
case workspacebiz.AppFileReference:
var generated tuttigenerated.AppReference
if err := generated.FromAppFileReference(generatedAppFileReferenceFromBiz(typed)); err != nil {
return tuttigenerated.AppReference{}, false
}
return generated, true
default:
return tuttigenerated.AppReference{}, false
}
}
func generatedAppFileReferenceFromBiz(reference workspacebiz.AppFileReference) tuttigenerated.AppFileReference {
return tuttigenerated.AppFileReference{
Kind: tuttigenerated.AppFileReferenceKindFile,
DisplayName: nullableString(reference.DisplayName),
Description: nullableString(reference.Description),
Path: reference.Path,
SizeBytes: reference.SizeBytes,
MtimeMs: reference.MtimeMs,
MimeType: nullableString(reference.MimeType),
Score: nullableFloat32(reference.Score),
ParentGroupLabel: nullableString(reference.ParentGroupLabel),
}
}
func nullableString(value string) *string {
if value == "" {
return nil
}
return &value
}
func trimString(value string) string {
return strings.TrimSpace(value)
}
func nullableFloat32(value *float64) *float32 {
if value == nil {
return nil
}
converted := float32(*value)
return &converted
}
func nonNilStrings(values []string) []string {
if values == nil {
return []string{}
}
return values
}
func generatedAppSource(source workspacebiz.AppPackageSource) tuttigenerated.WorkspaceAppSource {
switch source {
case workspacebiz.AppPackageSourceGenerated:
return tuttigenerated.WorkspaceAppSourceGenerated
case workspacebiz.AppPackageSourceImported:
return tuttigenerated.WorkspaceAppSourceImported
case workspacebiz.AppPackageSourceLocalDev:
return tuttigenerated.WorkspaceAppSourceLocalDev
default:
return tuttigenerated.WorkspaceAppSourceBuiltin
}
}
func generatedAppLocalPackageDir(appPackage workspacebiz.AppPackage) *string {
if appPackage.Source != workspacebiz.AppPackageSourceLocalDev {
return nil
}
return nullableString(appPackage.PackageDir)
}
func generatedAppCatalogLoadStatus(status workspacebiz.AppCatalogLoadStatus) tuttigenerated.WorkspaceAppCatalogLoadStatus {
switch status {
case workspacebiz.AppCatalogLoadStatusLoading:
return tuttigenerated.WorkspaceAppCatalogLoadStatusLoading
case workspacebiz.AppCatalogLoadStatusReady:
return tuttigenerated.WorkspaceAppCatalogLoadStatusReady
case workspacebiz.AppCatalogLoadStatusFailed:
return tuttigenerated.WorkspaceAppCatalogLoadStatusFailed
default:
return tuttigenerated.WorkspaceAppCatalogLoadStatusDisabled
}
}
func generatedAppRuntimeStatus(status workspacebiz.AppRuntimeStatus) tuttigenerated.WorkspaceAppRuntimeStatus {
switch status {
case workspacebiz.AppRuntimeStatusRunning:
return tuttigenerated.WorkspaceAppRuntimeStatusRunning
case workspacebiz.AppRuntimeStatusInstalledPendingRestart:
return tuttigenerated.WorkspaceAppRuntimeStatusInstalledPendingRestart
case workspacebiz.AppRuntimeStatusPreparing:
return tuttigenerated.WorkspaceAppRuntimeStatusPreparing
case workspacebiz.AppRuntimeStatusStarting:
return tuttigenerated.WorkspaceAppRuntimeStatusStarting
case workspacebiz.AppRuntimeStatusFailed:
return tuttigenerated.WorkspaceAppRuntimeStatusFailed
case workspacebiz.AppRuntimeStatusStopping:
return tuttigenerated.WorkspaceAppRuntimeStatusStopping
default:
return tuttigenerated.WorkspaceAppRuntimeStatusIdle
}
}
func generatedAppCLIState(state workspacebiz.AppCLIState) tuttigenerated.WorkspaceAppCliState {
return tuttigenerated.WorkspaceAppCliState{
Status: generatedAppCLIStatus(state.Status),
Scope: nullableString(state.Scope),
Active: state.Active,
Issues: generatedAppCLIIssues(state.Issues),
}
}
func generatedAppCLIIssues(issues []workspacebiz.AppCLIIssue) []tuttigenerated.WorkspaceAppCliIssue {
result := make([]tuttigenerated.WorkspaceAppCliIssue, 0, len(issues))
for _, issue := range issues {
result = append(result, tuttigenerated.WorkspaceAppCliIssue{
Code: issue.Code,
Message: issue.Message,
Path: nullableString(issue.Path),
})
}
return result
}
func generatedAppCLIStatus(status workspacebiz.AppCLIStatus) tuttigenerated.WorkspaceAppCliStatus {
switch status {
case workspacebiz.AppCLIStatusPending:
return tuttigenerated.WorkspaceAppCliStatusPending
case workspacebiz.AppCLIStatusActive:
return tuttigenerated.WorkspaceAppCliStatusActive
case workspacebiz.AppCLIStatusWarning:
return tuttigenerated.WorkspaceAppCliStatusWarning
case workspacebiz.AppCLIStatusError:
return tuttigenerated.WorkspaceAppCliStatusError
default:
return tuttigenerated.WorkspaceAppCliStatusNone
}
}