refactor: rename bundle identifiers to com.clawdis
This commit is contained in:
@@ -2,6 +2,9 @@
|
||||
|
||||
## Unreleased
|
||||
|
||||
### Breaking
|
||||
- Identifiers: rename bundle IDs and internal domains to `com.clawdis.*` (macOS: `com.clawdis.mac`, iOS: `com.clawdis.ios`, Android: `com.clawdis.android`) and update the gateway LaunchAgent label to `com.clawdis.gateway`.
|
||||
|
||||
### Features
|
||||
- Gateway: support `gateway.port` + `CLAWDIS_GATEWAY_PORT` across CLI, TUI, and macOS app.
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ plugins {
|
||||
}
|
||||
|
||||
android {
|
||||
namespace = "com.steipete.clawdis.node"
|
||||
namespace = "com.clawdis.android"
|
||||
compileSdk = 36
|
||||
|
||||
sourceSets {
|
||||
@@ -16,7 +16,7 @@ android {
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
applicationId = "com.steipete.clawdis.node"
|
||||
applicationId = "com.clawdis.android"
|
||||
minSdk = 31
|
||||
targetSdk = 36
|
||||
versionCode = 1
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.steipete.clawdis.node
|
||||
package com.clawdis.android
|
||||
|
||||
enum class CameraHudKind {
|
||||
Photo,
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.steipete.clawdis.node
|
||||
package com.clawdis.android
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Build
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.steipete.clawdis.node
|
||||
package com.clawdis.android
|
||||
|
||||
import android.Manifest
|
||||
import android.content.pm.ApplicationInfo
|
||||
@@ -18,8 +18,8 @@ import androidx.core.view.WindowInsetsControllerCompat
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.lifecycle.repeatOnLifecycle
|
||||
import com.steipete.clawdis.node.ui.RootScreen
|
||||
import com.steipete.clawdis.node.ui.ClawdisTheme
|
||||
import com.clawdis.android.ui.RootScreen
|
||||
import com.clawdis.android.ui.ClawdisTheme
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class MainActivity : ComponentActivity() {
|
||||
@@ -1,12 +1,12 @@
|
||||
package com.steipete.clawdis.node
|
||||
package com.clawdis.android
|
||||
|
||||
import android.app.Application
|
||||
import androidx.lifecycle.AndroidViewModel
|
||||
import com.steipete.clawdis.node.bridge.BridgeEndpoint
|
||||
import com.steipete.clawdis.node.chat.OutgoingAttachment
|
||||
import com.steipete.clawdis.node.node.CameraCaptureManager
|
||||
import com.steipete.clawdis.node.node.CanvasController
|
||||
import com.steipete.clawdis.node.node.ScreenRecordManager
|
||||
import com.clawdis.android.bridge.BridgeEndpoint
|
||||
import com.clawdis.android.chat.OutgoingAttachment
|
||||
import com.clawdis.android.node.CameraCaptureManager
|
||||
import com.clawdis.android.node.CanvasController
|
||||
import com.clawdis.android.node.ScreenRecordManager
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
|
||||
class MainViewModel(app: Application) : AndroidViewModel(app) {
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.steipete.clawdis.node
|
||||
package com.clawdis.android
|
||||
|
||||
import android.app.Application
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.steipete.clawdis.node
|
||||
package com.clawdis.android
|
||||
|
||||
import android.app.Notification
|
||||
import android.app.NotificationChannel
|
||||
@@ -146,7 +146,7 @@ class NodeForegroundService : Service() {
|
||||
private const val CHANNEL_ID = "connection"
|
||||
private const val NOTIFICATION_ID = 1
|
||||
|
||||
private const val ACTION_STOP = "com.steipete.clawdis.node.action.STOP"
|
||||
private const val ACTION_STOP = "com.clawdis.android.action.STOP"
|
||||
|
||||
fun start(context: Context) {
|
||||
val intent = Intent(context, NodeForegroundService::class.java)
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.steipete.clawdis.node
|
||||
package com.clawdis.android
|
||||
|
||||
import android.Manifest
|
||||
import android.content.Context
|
||||
@@ -6,27 +6,27 @@ import android.content.pm.PackageManager
|
||||
import android.os.Build
|
||||
import android.os.SystemClock
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.steipete.clawdis.node.chat.ChatController
|
||||
import com.steipete.clawdis.node.chat.ChatMessage
|
||||
import com.steipete.clawdis.node.chat.ChatPendingToolCall
|
||||
import com.steipete.clawdis.node.chat.ChatSessionEntry
|
||||
import com.steipete.clawdis.node.chat.OutgoingAttachment
|
||||
import com.steipete.clawdis.node.bridge.BridgeDiscovery
|
||||
import com.steipete.clawdis.node.bridge.BridgeEndpoint
|
||||
import com.steipete.clawdis.node.bridge.BridgePairingClient
|
||||
import com.steipete.clawdis.node.bridge.BridgeSession
|
||||
import com.steipete.clawdis.node.node.CameraCaptureManager
|
||||
import com.steipete.clawdis.node.BuildConfig
|
||||
import com.steipete.clawdis.node.node.CanvasController
|
||||
import com.steipete.clawdis.node.node.ScreenRecordManager
|
||||
import com.steipete.clawdis.node.protocol.ClawdisCapability
|
||||
import com.steipete.clawdis.node.protocol.ClawdisCameraCommand
|
||||
import com.steipete.clawdis.node.protocol.ClawdisCanvasA2UIAction
|
||||
import com.steipete.clawdis.node.protocol.ClawdisCanvasA2UICommand
|
||||
import com.steipete.clawdis.node.protocol.ClawdisCanvasCommand
|
||||
import com.steipete.clawdis.node.protocol.ClawdisScreenCommand
|
||||
import com.steipete.clawdis.node.voice.TalkModeManager
|
||||
import com.steipete.clawdis.node.voice.VoiceWakeManager
|
||||
import com.clawdis.android.chat.ChatController
|
||||
import com.clawdis.android.chat.ChatMessage
|
||||
import com.clawdis.android.chat.ChatPendingToolCall
|
||||
import com.clawdis.android.chat.ChatSessionEntry
|
||||
import com.clawdis.android.chat.OutgoingAttachment
|
||||
import com.clawdis.android.bridge.BridgeDiscovery
|
||||
import com.clawdis.android.bridge.BridgeEndpoint
|
||||
import com.clawdis.android.bridge.BridgePairingClient
|
||||
import com.clawdis.android.bridge.BridgeSession
|
||||
import com.clawdis.android.node.CameraCaptureManager
|
||||
import com.clawdis.android.BuildConfig
|
||||
import com.clawdis.android.node.CanvasController
|
||||
import com.clawdis.android.node.ScreenRecordManager
|
||||
import com.clawdis.android.protocol.ClawdisCapability
|
||||
import com.clawdis.android.protocol.ClawdisCameraCommand
|
||||
import com.clawdis.android.protocol.ClawdisCanvasA2UIAction
|
||||
import com.clawdis.android.protocol.ClawdisCanvasA2UICommand
|
||||
import com.clawdis.android.protocol.ClawdisCanvasCommand
|
||||
import com.clawdis.android.protocol.ClawdisScreenCommand
|
||||
import com.clawdis.android.voice.TalkModeManager
|
||||
import com.clawdis.android.voice.VoiceWakeManager
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.steipete.clawdis.node
|
||||
package com.clawdis.android
|
||||
|
||||
import android.content.pm.PackageManager
|
||||
import android.content.Intent
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.steipete.clawdis.node
|
||||
package com.clawdis.android
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
@@ -1,6 +1,6 @@
|
||||
@file:Suppress("DEPRECATION")
|
||||
|
||||
package com.steipete.clawdis.node
|
||||
package com.clawdis.android
|
||||
|
||||
import android.content.Context
|
||||
import androidx.core.content.edit
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.steipete.clawdis.node
|
||||
package com.clawdis.android
|
||||
|
||||
enum class VoiceWakeMode(val rawValue: String) {
|
||||
Off("off"),
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.steipete.clawdis.node
|
||||
package com.clawdis.android
|
||||
|
||||
object WakeWords {
|
||||
const val maxWords: Int = 32
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.steipete.clawdis.node.bridge
|
||||
package com.clawdis.android.bridge
|
||||
|
||||
object BonjourEscapes {
|
||||
fun decode(input: String): String {
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.steipete.clawdis.node.bridge
|
||||
package com.clawdis.android.bridge
|
||||
|
||||
import android.content.Context
|
||||
import android.net.ConnectivityManager
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.steipete.clawdis.node.bridge
|
||||
package com.clawdis.android.bridge
|
||||
|
||||
data class BridgeEndpoint(
|
||||
val stableId: String,
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.steipete.clawdis.node.bridge
|
||||
package com.clawdis.android.bridge
|
||||
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.steipete.clawdis.node.bridge
|
||||
package com.clawdis.android.bridge
|
||||
|
||||
import kotlinx.coroutines.CompletableDeferred
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
@@ -11,7 +11,7 @@ import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
import kotlinx.coroutines.sync.withLock
|
||||
import kotlinx.coroutines.withContext
|
||||
import com.steipete.clawdis.node.BuildConfig
|
||||
import com.clawdis.android.BuildConfig
|
||||
import kotlinx.serialization.json.Json
|
||||
import kotlinx.serialization.json.JsonArray
|
||||
import kotlinx.serialization.json.JsonObject
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.steipete.clawdis.node.chat
|
||||
package com.clawdis.android.chat
|
||||
|
||||
import com.steipete.clawdis.node.bridge.BridgeSession
|
||||
import com.clawdis.android.bridge.BridgeSession
|
||||
import java.util.UUID
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.steipete.clawdis.node.chat
|
||||
package com.clawdis.android.chat
|
||||
|
||||
data class ChatMessage(
|
||||
val id: String,
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.steipete.clawdis.node.node
|
||||
package com.clawdis.android.node
|
||||
|
||||
import android.Manifest
|
||||
import android.content.Context
|
||||
@@ -20,7 +20,7 @@ import androidx.camera.video.VideoRecordEvent
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.content.ContextCompat.checkSelfPermission
|
||||
import androidx.core.graphics.scale
|
||||
import com.steipete.clawdis.node.PermissionRequester
|
||||
import com.clawdis.android.PermissionRequester
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.suspendCancellableCoroutine
|
||||
import kotlinx.coroutines.withTimeout
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.steipete.clawdis.node.node
|
||||
package com.clawdis.android.node
|
||||
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.Canvas
|
||||
@@ -17,7 +17,7 @@ import kotlinx.serialization.json.Json
|
||||
import kotlinx.serialization.json.JsonElement
|
||||
import kotlinx.serialization.json.JsonObject
|
||||
import kotlinx.serialization.json.JsonPrimitive
|
||||
import com.steipete.clawdis.node.BuildConfig
|
||||
import com.clawdis.android.BuildConfig
|
||||
import kotlin.coroutines.resume
|
||||
|
||||
class CanvasController {
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.steipete.clawdis.node.node
|
||||
package com.clawdis.android.node
|
||||
|
||||
import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
@@ -1,11 +1,11 @@
|
||||
package com.steipete.clawdis.node.node
|
||||
package com.clawdis.android.node
|
||||
|
||||
import android.content.Context
|
||||
import android.hardware.display.DisplayManager
|
||||
import android.media.MediaRecorder
|
||||
import android.media.projection.MediaProjectionManager
|
||||
import android.util.Base64
|
||||
import com.steipete.clawdis.node.ScreenCaptureRequester
|
||||
import com.clawdis.android.ScreenCaptureRequester
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.withContext
|
||||
@@ -16,13 +16,13 @@ class ScreenRecordManager(private val context: Context) {
|
||||
data class Payload(val payloadJson: String)
|
||||
|
||||
@Volatile private var screenCaptureRequester: ScreenCaptureRequester? = null
|
||||
@Volatile private var permissionRequester: com.steipete.clawdis.node.PermissionRequester? = null
|
||||
@Volatile private var permissionRequester: com.clawdis.android.PermissionRequester? = null
|
||||
|
||||
fun attachScreenCaptureRequester(requester: ScreenCaptureRequester) {
|
||||
screenCaptureRequester = requester
|
||||
}
|
||||
|
||||
fun attachPermissionRequester(requester: com.steipete.clawdis.node.PermissionRequester) {
|
||||
fun attachPermissionRequester(requester: com.clawdis.android.PermissionRequester) {
|
||||
permissionRequester = requester
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.steipete.clawdis.node.protocol
|
||||
package com.clawdis.android.protocol
|
||||
|
||||
import kotlinx.serialization.json.JsonObject
|
||||
import kotlinx.serialization.json.JsonPrimitive
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.steipete.clawdis.node.protocol
|
||||
package com.clawdis.android.protocol
|
||||
|
||||
enum class ClawdisCapability(val rawValue: String) {
|
||||
Canvas("canvas"),
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.steipete.clawdis.node.ui
|
||||
package com.clawdis.android.ui
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Box
|
||||
@@ -1,8 +1,8 @@
|
||||
package com.steipete.clawdis.node.ui
|
||||
package com.clawdis.android.ui
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import com.steipete.clawdis.node.MainViewModel
|
||||
import com.steipete.clawdis.node.ui.chat.ChatSheetContent
|
||||
import com.clawdis.android.MainViewModel
|
||||
import com.clawdis.android.ui.chat.ChatSheetContent
|
||||
|
||||
@Composable
|
||||
fun ChatSheet(viewModel: MainViewModel) {
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.steipete.clawdis.node.ui
|
||||
package com.clawdis.android.ui
|
||||
|
||||
import androidx.compose.foundation.isSystemInDarkTheme
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.steipete.clawdis.node.ui
|
||||
package com.clawdis.android.ui
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.Manifest
|
||||
@@ -65,8 +65,8 @@ import androidx.compose.ui.viewinterop.AndroidView
|
||||
import androidx.compose.ui.window.Popup
|
||||
import androidx.compose.ui.window.PopupProperties
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.steipete.clawdis.node.CameraHudKind
|
||||
import com.steipete.clawdis.node.MainViewModel
|
||||
import com.clawdis.android.CameraHudKind
|
||||
import com.clawdis.android.MainViewModel
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.steipete.clawdis.node.ui
|
||||
package com.clawdis.android.ui
|
||||
|
||||
import android.Manifest
|
||||
import android.content.pm.PackageManager
|
||||
@@ -47,10 +47,10 @@ import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.steipete.clawdis.node.BuildConfig
|
||||
import com.steipete.clawdis.node.MainViewModel
|
||||
import com.steipete.clawdis.node.NodeForegroundService
|
||||
import com.steipete.clawdis.node.VoiceWakeMode
|
||||
import com.clawdis.android.BuildConfig
|
||||
import com.clawdis.android.MainViewModel
|
||||
import com.clawdis.android.NodeForegroundService
|
||||
import com.clawdis.android.VoiceWakeMode
|
||||
|
||||
@Composable
|
||||
fun SettingsSheet(viewModel: MainViewModel) {
|
||||
@@ -381,7 +381,7 @@ fun SettingsSheet(viewModel: MainViewModel) {
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(12.dp)) {
|
||||
Button(
|
||||
onClick = {
|
||||
val parsed = com.steipete.clawdis.node.WakeWords.parseCommaSeparated(wakeWordsText)
|
||||
val parsed = com.clawdis.android.WakeWords.parseCommaSeparated(wakeWordsText)
|
||||
viewModel.setWakeWords(parsed)
|
||||
},
|
||||
enabled = isConnected,
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.steipete.clawdis.node.ui
|
||||
package com.clawdis.android.ui
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Row
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.steipete.clawdis.node.ui
|
||||
package com.clawdis.android.ui
|
||||
|
||||
import androidx.compose.animation.core.LinearEasing
|
||||
import androidx.compose.animation.core.RepeatMode
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.steipete.clawdis.node.ui.chat
|
||||
package com.clawdis.android.ui.chat
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
@@ -38,7 +38,7 @@ import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.steipete.clawdis.node.chat.ChatSessionEntry
|
||||
import com.clawdis.android.chat.ChatSessionEntry
|
||||
|
||||
@Composable
|
||||
fun ChatComposer(
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.steipete.clawdis.node.ui.chat
|
||||
package com.clawdis.android.ui.chat
|
||||
|
||||
import android.graphics.BitmapFactory
|
||||
import android.util.Base64
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.steipete.clawdis.node.ui.chat
|
||||
package com.clawdis.android.ui.chat
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
@@ -20,8 +20,8 @@ import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.alpha
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.steipete.clawdis.node.chat.ChatMessage
|
||||
import com.steipete.clawdis.node.chat.ChatPendingToolCall
|
||||
import com.clawdis.android.chat.ChatMessage
|
||||
import com.clawdis.android.chat.ChatPendingToolCall
|
||||
|
||||
@Composable
|
||||
fun ChatMessageListCard(
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.steipete.clawdis.node.ui.chat
|
||||
package com.clawdis.android.ui.chat
|
||||
|
||||
import android.graphics.BitmapFactory
|
||||
import android.util.Base64
|
||||
@@ -31,9 +31,9 @@ import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.text.font.FontFamily
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.foundation.Image
|
||||
import com.steipete.clawdis.node.chat.ChatMessage
|
||||
import com.steipete.clawdis.node.chat.ChatMessageContent
|
||||
import com.steipete.clawdis.node.chat.ChatPendingToolCall
|
||||
import com.clawdis.android.chat.ChatMessage
|
||||
import com.clawdis.android.chat.ChatMessageContent
|
||||
import com.clawdis.android.chat.ChatPendingToolCall
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.steipete.clawdis.node.ui.chat
|
||||
package com.clawdis.android.ui.chat
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
@@ -20,7 +20,7 @@ import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.steipete.clawdis.node.chat.ChatSessionEntry
|
||||
import com.clawdis.android.chat.ChatSessionEntry
|
||||
|
||||
@Composable
|
||||
fun ChatSessionsDialog(
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.steipete.clawdis.node.ui.chat
|
||||
package com.clawdis.android.ui.chat
|
||||
|
||||
import android.content.ContentResolver
|
||||
import android.net.Uri
|
||||
@@ -19,8 +19,8 @@ import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.steipete.clawdis.node.MainViewModel
|
||||
import com.steipete.clawdis.node.chat.OutgoingAttachment
|
||||
import com.clawdis.android.MainViewModel
|
||||
import com.clawdis.android.chat.OutgoingAttachment
|
||||
import java.io.ByteArrayOutputStream
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.steipete.clawdis.node.ui.chat
|
||||
package com.clawdis.android.ui.chat
|
||||
|
||||
import com.steipete.clawdis.node.chat.ChatSessionEntry
|
||||
import com.clawdis.android.chat.ChatSessionEntry
|
||||
|
||||
private const val MAIN_SESSION_KEY = "main"
|
||||
private const val RECENT_WINDOW_MS = 24 * 60 * 60 * 1000L
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.steipete.clawdis.node.voice
|
||||
package com.clawdis.android.voice
|
||||
|
||||
import android.media.MediaDataSource
|
||||
import kotlin.math.min
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.steipete.clawdis.node.voice
|
||||
package com.clawdis.android.voice
|
||||
|
||||
import kotlinx.serialization.json.Json
|
||||
import kotlinx.serialization.json.JsonElement
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.steipete.clawdis.node.voice
|
||||
package com.clawdis.android.voice
|
||||
|
||||
import android.Manifest
|
||||
import android.content.Context
|
||||
@@ -20,7 +20,7 @@ import android.speech.tts.TextToSpeech
|
||||
import android.speech.tts.UtteranceProgressListener
|
||||
import android.util.Log
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.steipete.clawdis.node.bridge.BridgeSession
|
||||
import com.clawdis.android.bridge.BridgeSession
|
||||
import java.net.HttpURLConnection
|
||||
import java.net.URL
|
||||
import java.util.UUID
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.steipete.clawdis.node.voice
|
||||
package com.clawdis.android.voice
|
||||
|
||||
object VoiceWakeCommandExtractor {
|
||||
fun extractCommand(text: String, triggerWords: List<String>): String? {
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.steipete.clawdis.node.voice
|
||||
package com.clawdis.android.voice
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.steipete.clawdis.node
|
||||
package com.clawdis.android
|
||||
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.steipete.clawdis.node.bridge
|
||||
package com.clawdis.android.bridge
|
||||
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.steipete.clawdis.node.bridge
|
||||
package com.clawdis.android.bridge
|
||||
|
||||
import io.kotest.core.spec.style.StringSpec
|
||||
import io.kotest.matchers.shouldBe
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.steipete.clawdis.node.bridge
|
||||
package com.clawdis.android.bridge
|
||||
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.async
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.steipete.clawdis.node.bridge
|
||||
package com.clawdis.android.bridge
|
||||
|
||||
import kotlinx.coroutines.CompletableDeferred
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.steipete.clawdis.node.node
|
||||
package com.clawdis.android.node
|
||||
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertNull
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.steipete.clawdis.node.node
|
||||
package com.clawdis.android.node
|
||||
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertTrue
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.steipete.clawdis.node.protocol
|
||||
package com.clawdis.android.protocol
|
||||
|
||||
import kotlinx.serialization.json.Json
|
||||
import kotlinx.serialization.json.jsonObject
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.steipete.clawdis.node.protocol
|
||||
package com.clawdis.android.protocol
|
||||
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.steipete.clawdis.node.ui.chat
|
||||
package com.clawdis.android.ui.chat
|
||||
|
||||
import com.steipete.clawdis.node.chat.ChatSessionEntry
|
||||
import com.clawdis.android.chat.ChatSessionEntry
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.steipete.clawdis.node.voice
|
||||
package com.clawdis.android.voice
|
||||
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertNull
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.steipete.clawdis.node.voice
|
||||
package com.clawdis.android.voice
|
||||
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertNull
|
||||
@@ -14,7 +14,7 @@ actor BridgeClient {
|
||||
{
|
||||
self.lineBuffer = Data()
|
||||
let connection = NWConnection(to: endpoint, using: .tcp)
|
||||
let queue = DispatchQueue(label: "com.steipete.clawdis.ios.bridge-client")
|
||||
let queue = DispatchQueue(label: "com.clawdis.ios.bridge-client")
|
||||
defer { connection.cancel() }
|
||||
try await self.withTimeout(seconds: 8, purpose: "connect") {
|
||||
try await self.startAndWaitForReady(connection, queue: queue)
|
||||
|
||||
@@ -99,7 +99,7 @@ final class BridgeConnectionController {
|
||||
guard !instanceId.isEmpty else { return }
|
||||
|
||||
let token = KeychainStore.loadString(
|
||||
service: "com.steipete.clawdis.bridge",
|
||||
service: "com.clawdis.bridge",
|
||||
account: self.keychainAccount(instanceId: instanceId))?
|
||||
.trimmingCharacters(in: .whitespacesAndNewlines) ?? ""
|
||||
guard !token.isEmpty else { return }
|
||||
@@ -189,7 +189,7 @@ final class BridgeConnectionController {
|
||||
if !refreshed.isEmpty, refreshed != token {
|
||||
_ = KeychainStore.saveString(
|
||||
refreshed,
|
||||
service: "com.steipete.clawdis.bridge",
|
||||
service: "com.clawdis.bridge",
|
||||
account: self.keychainAccount(instanceId: instanceId))
|
||||
}
|
||||
appModel.connectToBridge(endpoint: endpoint, hello: self.makeHello(token: resolvedToken))
|
||||
|
||||
@@ -102,7 +102,7 @@ final class BridgeDiscoveryModel {
|
||||
}
|
||||
|
||||
self.browsers[domain] = browser
|
||||
browser.start(queue: DispatchQueue(label: "com.steipete.clawdis.ios.bridge-discovery.\(domain)"))
|
||||
browser.start(queue: DispatchQueue(label: "com.clawdis.ios.bridge-discovery.\(domain)"))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -78,7 +78,7 @@ actor BridgeSession {
|
||||
let params = NWParameters.tcp
|
||||
params.includePeerToPeer = true
|
||||
let connection = NWConnection(to: endpoint, using: params)
|
||||
let queue = DispatchQueue(label: "com.steipete.clawdis.ios.bridge-session")
|
||||
let queue = DispatchQueue(label: "com.clawdis.ios.bridge-session")
|
||||
self.connection = connection
|
||||
self.queue = queue
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import Foundation
|
||||
|
||||
enum BridgeSettingsStore {
|
||||
private static let bridgeService = "com.steipete.clawdis.bridge"
|
||||
private static let nodeService = "com.steipete.clawdis.node"
|
||||
private static let bridgeService = "com.clawdis.bridge"
|
||||
private static let nodeService = "com.clawdis.node"
|
||||
|
||||
private static let instanceIdDefaultsKey = "node.instanceId"
|
||||
private static let preferredBridgeStableIDDefaultsKey = "bridge.preferredStableID"
|
||||
|
||||
@@ -68,7 +68,7 @@ final class ScreenRecordService: @unchecked Sendable {
|
||||
try? FileManager.default.removeItem(at: outURL)
|
||||
|
||||
let state = CaptureState()
|
||||
let recordQueue = DispatchQueue(label: "com.steipete.clawdis.screenrecord")
|
||||
let recordQueue = DispatchQueue(label: "com.clawdis.screenrecord")
|
||||
|
||||
try await withCheckedThrowingContinuation { (cont: CheckedContinuation<Void, Error>) in
|
||||
let handler: @Sendable (CMSampleBuffer, RPSampleBufferType, Error?) -> Void = { sample, type, error in
|
||||
|
||||
@@ -353,7 +353,7 @@ struct SettingsTab: View {
|
||||
do {
|
||||
let statusStore = self.connectStatus
|
||||
let existing = KeychainStore.loadString(
|
||||
service: "com.steipete.clawdis.bridge",
|
||||
service: "com.clawdis.bridge",
|
||||
account: self.keychainAccount())
|
||||
let existingToken = (existing?.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty == false) ?
|
||||
existing :
|
||||
@@ -381,7 +381,7 @@ struct SettingsTab: View {
|
||||
if !token.isEmpty, token != existingToken {
|
||||
_ = KeychainStore.saveString(
|
||||
token,
|
||||
service: "com.steipete.clawdis.bridge",
|
||||
service: "com.clawdis.bridge",
|
||||
account: self.keychainAccount())
|
||||
}
|
||||
|
||||
@@ -427,7 +427,7 @@ struct SettingsTab: View {
|
||||
do {
|
||||
let statusStore = self.connectStatus
|
||||
let existing = KeychainStore.loadString(
|
||||
service: "com.steipete.clawdis.bridge",
|
||||
service: "com.clawdis.bridge",
|
||||
account: self.keychainAccount())
|
||||
let existingToken = (existing?.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty == false) ?
|
||||
existing :
|
||||
@@ -455,7 +455,7 @@ struct SettingsTab: View {
|
||||
if !token.isEmpty, token != existingToken {
|
||||
_ = KeychainStore.saveString(
|
||||
token,
|
||||
service: "com.steipete.clawdis.bridge",
|
||||
service: "com.clawdis.bridge",
|
||||
account: self.keychainAccount())
|
||||
}
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ final class TalkModeManager: NSObject {
|
||||
|
||||
private var chatSubscribedSessionKeys = Set<String>()
|
||||
|
||||
private let logger = Logger(subsystem: "com.steipete.clawdis", category: "TalkMode")
|
||||
private let logger = Logger(subsystem: "com.clawdis", category: "TalkMode")
|
||||
|
||||
func attachBridge(_ bridge: BridgeSession) {
|
||||
self.bridge = bridge
|
||||
|
||||
@@ -6,7 +6,7 @@ import Testing
|
||||
|
||||
@Suite struct BridgeClientTests {
|
||||
private final class LineServer: @unchecked Sendable {
|
||||
private let queue = DispatchQueue(label: "com.steipete.clawdis.tests.bridge-client-server")
|
||||
private let queue = DispatchQueue(label: "com.clawdis.tests.bridge-client-server")
|
||||
private let listener: NWListener
|
||||
private var connection: NWConnection?
|
||||
private var buffer = Data()
|
||||
|
||||
@@ -10,8 +10,8 @@ private struct KeychainEntry: Hashable {
|
||||
let account: String
|
||||
}
|
||||
|
||||
private let bridgeService = "com.steipete.clawdis.bridge"
|
||||
private let nodeService = "com.steipete.clawdis.node"
|
||||
private let bridgeService = "com.clawdis.bridge"
|
||||
private let nodeService = "com.clawdis.node"
|
||||
private let instanceIdEntry = KeychainEntry(service: nodeService, account: "instanceId")
|
||||
private let preferredBridgeEntry = KeychainEntry(service: bridgeService, account: "preferredStableID")
|
||||
private let lastBridgeEntry = KeychainEntry(service: bridgeService, account: "lastDiscoveredStableID")
|
||||
|
||||
@@ -7,8 +7,8 @@ private struct KeychainEntry: Hashable {
|
||||
let account: String
|
||||
}
|
||||
|
||||
private let bridgeService = "com.steipete.clawdis.bridge"
|
||||
private let nodeService = "com.steipete.clawdis.node"
|
||||
private let bridgeService = "com.clawdis.bridge"
|
||||
private let nodeService = "com.clawdis.node"
|
||||
private let instanceIdEntry = KeychainEntry(service: nodeService, account: "instanceId")
|
||||
private let preferredBridgeEntry = KeychainEntry(service: bridgeService, account: "preferredStableID")
|
||||
private let lastBridgeEntry = KeychainEntry(service: bridgeService, account: "lastDiscoveredStableID")
|
||||
|
||||
@@ -4,7 +4,7 @@ import Testing
|
||||
|
||||
@Suite struct KeychainStoreTests {
|
||||
@Test func saveLoadUpdateDeleteRoundTrip() {
|
||||
let service = "com.steipete.clawdis.tests.\(UUID().uuidString)"
|
||||
let service = "com.clawdis.tests.\(UUID().uuidString)"
|
||||
let account = "value"
|
||||
|
||||
#expect(KeychainStore.delete(service: service, account: account))
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
app_identifier("com.steipete.clawdis.ios")
|
||||
app_identifier("com.clawdis.ios")
|
||||
|
||||
# Auth is expected via App Store Connect API key.
|
||||
# Provide either:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
name: Clawdis
|
||||
options:
|
||||
bundleIdPrefix: com.steipete.clawdis
|
||||
bundleIdPrefix: com.clawdis
|
||||
deploymentTarget:
|
||||
iOS: "17.0"
|
||||
xcodeVersion: "16.0"
|
||||
@@ -65,8 +65,8 @@ targets:
|
||||
CODE_SIGN_IDENTITY: "Apple Development"
|
||||
CODE_SIGN_STYLE: Manual
|
||||
DEVELOPMENT_TEAM: Y5PE65HELJ
|
||||
PRODUCT_BUNDLE_IDENTIFIER: com.steipete.clawdis.ios
|
||||
PROVISIONING_PROFILE_SPECIFIER: "com.steipete.clawdis.ios Development"
|
||||
PRODUCT_BUNDLE_IDENTIFIER: com.clawdis.ios
|
||||
PROVISIONING_PROFILE_SPECIFIER: "com.clawdis.ios Development"
|
||||
SWIFT_VERSION: "6.0"
|
||||
info:
|
||||
path: Sources/Info.plist
|
||||
@@ -98,7 +98,7 @@ targets:
|
||||
product: SwabbleKit
|
||||
settings:
|
||||
base:
|
||||
PRODUCT_BUNDLE_IDENTIFIER: com.steipete.clawdis.ios.tests
|
||||
PRODUCT_BUNDLE_IDENTIFIER: com.clawdis.ios.tests
|
||||
SWIFT_VERSION: "6.0"
|
||||
TEST_HOST: "$(BUILT_PRODUCTS_DIR)/Clawdis.app/Clawdis"
|
||||
BUNDLE_LOADER: "$(TEST_HOST)"
|
||||
|
||||
@@ -2,7 +2,7 @@ import Foundation
|
||||
import OSLog
|
||||
|
||||
enum AgentWorkspace {
|
||||
private static let logger = Logger(subsystem: "com.steipete.clawdis", category: "workspace")
|
||||
private static let logger = Logger(subsystem: "com.clawdis", category: "workspace")
|
||||
static let agentsFilename = "AGENTS.md"
|
||||
static let soulFilename = "SOUL.md"
|
||||
static let identityFilename = "IDENTITY.md"
|
||||
|
||||
@@ -58,7 +58,7 @@ enum AnthropicAuthResolver {
|
||||
}
|
||||
|
||||
enum AnthropicOAuth {
|
||||
private static let logger = Logger(subsystem: "com.steipete.clawdis", category: "anthropic-oauth")
|
||||
private static let logger = Logger(subsystem: "com.clawdis", category: "anthropic-oauth")
|
||||
|
||||
private static let clientId = "9d1c250a-e61b-44d9-88ed-5944d1962f5e"
|
||||
private static let authorizeURL = URL(string: "https://claude.ai/oauth/authorize")!
|
||||
|
||||
@@ -19,7 +19,7 @@ actor BridgeConnectionHandler {
|
||||
private let logger: Logger
|
||||
private let decoder = JSONDecoder()
|
||||
private let encoder = JSONEncoder()
|
||||
private let queue = DispatchQueue(label: "com.steipete.clawdis.bridge.connection")
|
||||
private let queue = DispatchQueue(label: "com.clawdis.bridge.connection")
|
||||
|
||||
private var buffer = Data()
|
||||
private var isAuthenticated = false
|
||||
|
||||
@@ -8,7 +8,7 @@ import OSLog
|
||||
actor BridgeServer {
|
||||
static let shared = BridgeServer()
|
||||
|
||||
private let logger = Logger(subsystem: "com.steipete.clawdis", category: "bridge")
|
||||
private let logger = Logger(subsystem: "com.clawdis", category: "bridge")
|
||||
private var listener: NWListener?
|
||||
private var isRunning = false
|
||||
private var store: PairedNodesStore?
|
||||
@@ -42,7 +42,7 @@ actor BridgeServer {
|
||||
Task { await self.handleListenerState(state) }
|
||||
}
|
||||
|
||||
listener.start(queue: DispatchQueue(label: "com.steipete.clawdis.bridge"))
|
||||
listener.start(queue: DispatchQueue(label: "com.clawdis.bridge"))
|
||||
self.listener = listener
|
||||
} catch {
|
||||
self.logger.error("bridge start failed: \(error.localizedDescription, privacy: .public)")
|
||||
|
||||
@@ -36,7 +36,7 @@ actor CameraCaptureService {
|
||||
}
|
||||
}
|
||||
|
||||
private let logger = Logger(subsystem: "com.steipete.clawdis", category: "camera")
|
||||
private let logger = Logger(subsystem: "com.clawdis", category: "camera")
|
||||
|
||||
func listDevices() -> [CameraDeviceInfo] {
|
||||
Self.availableCameras().map { device in
|
||||
|
||||
@@ -10,7 +10,7 @@ final class CanvasFileWatcher: @unchecked Sendable {
|
||||
|
||||
init(url: URL, onChange: @escaping () -> Void) {
|
||||
self.url = url
|
||||
self.queue = DispatchQueue(label: "com.steipete.clawdis.canvaswatcher")
|
||||
self.queue = DispatchQueue(label: "com.clawdis.canvaswatcher")
|
||||
self.onChange = onChange
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import OSLog
|
||||
final class CanvasManager {
|
||||
static let shared = CanvasManager()
|
||||
|
||||
private static let logger = Logger(subsystem: "com.steipete.clawdis", category: "CanvasManager")
|
||||
private static let logger = Logger(subsystem: "com.clawdis", category: "CanvasManager")
|
||||
|
||||
private var panelController: CanvasWindowController?
|
||||
private var panelSessionKey: String?
|
||||
|
||||
@@ -3,7 +3,7 @@ import Foundation
|
||||
import OSLog
|
||||
import WebKit
|
||||
|
||||
private let canvasLogger = Logger(subsystem: "com.steipete.clawdis", category: "Canvas")
|
||||
private let canvasLogger = Logger(subsystem: "com.clawdis", category: "Canvas")
|
||||
|
||||
final class CanvasSchemeHandler: NSObject, WKURLSchemeHandler {
|
||||
private let root: URL
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import AppKit
|
||||
|
||||
let canvasWindowLogger = Logger(subsystem: "com.steipete.clawdis", category: "Canvas")
|
||||
let canvasWindowLogger = Logger(subsystem: "com.clawdis", category: "Canvas")
|
||||
|
||||
enum CanvasLayout {
|
||||
static let panelSize = NSSize(width: 520, height: 680)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import Foundation
|
||||
|
||||
enum ClawdisConfigFile {
|
||||
private static let logger = Logger(subsystem: "com.steipete.clawdis", category: "config")
|
||||
private static let logger = Logger(subsystem: "com.clawdis", category: "config")
|
||||
|
||||
static func url() -> URL {
|
||||
ClawdisPaths.configURL
|
||||
|
||||
@@ -5,7 +5,7 @@ import OSLog
|
||||
final class ConnectionModeCoordinator {
|
||||
static let shared = ConnectionModeCoordinator()
|
||||
|
||||
private let logger = Logger(subsystem: "com.steipete.clawdis", category: "connection")
|
||||
private let logger = Logger(subsystem: "com.clawdis", category: "connection")
|
||||
|
||||
/// Apply the requested connection mode by starting/stopping local gateway,
|
||||
/// managing the control-channel SSH tunnel, and cleaning up chat windows/panels.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import Foundation
|
||||
|
||||
let launchdLabel = "com.steipete.clawdis"
|
||||
let gatewayLaunchdLabel = "com.steipete.clawdis.gateway"
|
||||
let launchdLabel = "com.clawdis.mac"
|
||||
let gatewayLaunchdLabel = "com.clawdis.gateway"
|
||||
let onboardingVersionKey = "clawdis.onboardingVersion"
|
||||
let currentOnboardingVersion = 7
|
||||
let pauseDefaultsKey = "clawdis.pauseEnabled"
|
||||
|
||||
@@ -73,7 +73,7 @@ final class ControlChannel {
|
||||
}
|
||||
private(set) var lastPingMs: Double?
|
||||
|
||||
private let logger = Logger(subsystem: "com.steipete.clawdis", category: "control")
|
||||
private let logger = Logger(subsystem: "com.clawdis", category: "control")
|
||||
|
||||
private var eventTask: Task<Void, Never>?
|
||||
private var recoveryTask: Task<Void, Never>?
|
||||
|
||||
@@ -21,7 +21,7 @@ final class CronJobsStore {
|
||||
var lastError: String?
|
||||
var statusMessage: String?
|
||||
|
||||
private let logger = Logger(subsystem: "com.steipete.clawdis", category: "cron.ui")
|
||||
private let logger = Logger(subsystem: "com.clawdis", category: "cron.ui")
|
||||
private var refreshTask: Task<Void, Never>?
|
||||
private var runsTask: Task<Void, Never>?
|
||||
private var eventTask: Task<Void, Never>?
|
||||
|
||||
@@ -4,7 +4,7 @@ import Foundation
|
||||
import OSLog
|
||||
import Security
|
||||
|
||||
private let deepLinkLogger = Logger(subsystem: "com.steipete.clawdis", category: "DeepLink")
|
||||
private let deepLinkLogger = Logger(subsystem: "com.clawdis", category: "DeepLink")
|
||||
|
||||
@MainActor
|
||||
final class DeepLinkHandler {
|
||||
|
||||
@@ -6,7 +6,7 @@ final class DockIconManager: NSObject, @unchecked Sendable {
|
||||
static let shared = DockIconManager()
|
||||
|
||||
private var windowsObservation: NSKeyValueObservation?
|
||||
private let logger = Logger(subsystem: "com.steipete.clawdis", category: "DockIconManager")
|
||||
private let logger = Logger(subsystem: "com.clawdis", category: "DockIconManager")
|
||||
|
||||
override private init() {
|
||||
super.init()
|
||||
|
||||
@@ -58,7 +58,7 @@ struct WebSocketSessionBox: @unchecked Sendable {
|
||||
private typealias ProtoAnyCodable = ClawdisProtocol.AnyCodable
|
||||
|
||||
actor GatewayChannelActor {
|
||||
private let logger = Logger(subsystem: "com.steipete.clawdis", category: "gateway")
|
||||
private let logger = Logger(subsystem: "com.clawdis", category: "gateway")
|
||||
private var task: WebSocketTaskBox?
|
||||
private var pending: [String: CheckedContinuation<GatewayFrame, Error>] = [:]
|
||||
private var connected = false
|
||||
|
||||
@@ -3,7 +3,7 @@ import ClawdisProtocol
|
||||
import Foundation
|
||||
import OSLog
|
||||
|
||||
private let gatewayConnectionLogger = Logger(subsystem: "com.steipete.clawdis", category: "gateway.connection")
|
||||
private let gatewayConnectionLogger = Logger(subsystem: "com.clawdis", category: "gateway.connection")
|
||||
|
||||
enum GatewayAgentChannel: String, Codable, CaseIterable, Sendable {
|
||||
case last
|
||||
|
||||
@@ -34,7 +34,7 @@ final class GatewayDiscoveryModel {
|
||||
private var localIdentity: LocalIdentity
|
||||
private var resolvedTXTByID: [String: [String: String]] = [:]
|
||||
private var pendingTXTResolvers: [String: GatewayTXTResolver] = [:]
|
||||
private let logger = Logger(subsystem: "com.steipete.clawdis", category: "gateway-discovery")
|
||||
private let logger = Logger(subsystem: "com.clawdis", category: "gateway-discovery")
|
||||
|
||||
init() {
|
||||
self.localIdentity = Self.buildLocalIdentityFast()
|
||||
@@ -69,7 +69,7 @@ final class GatewayDiscoveryModel {
|
||||
}
|
||||
|
||||
self.browsers[domain] = browser
|
||||
browser.start(queue: DispatchQueue(label: "com.steipete.clawdis.macos.gateway-discovery.\(domain)"))
|
||||
browser.start(queue: DispatchQueue(label: "com.clawdis.macos.gateway-discovery.\(domain)"))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -72,7 +72,7 @@ actor GatewayEndpointStore {
|
||||
}
|
||||
|
||||
private let deps: Deps
|
||||
private let logger = Logger(subsystem: "com.steipete.clawdis", category: "gateway-endpoint")
|
||||
private let logger = Logger(subsystem: "com.clawdis", category: "gateway-endpoint")
|
||||
|
||||
private var state: GatewayEndpointState
|
||||
private var subscribers: [UUID: AsyncStream<GatewayEndpointState>.Continuation] = [:]
|
||||
|
||||
@@ -62,7 +62,7 @@ struct GatewayCommandResolution {
|
||||
}
|
||||
|
||||
enum GatewayEnvironment {
|
||||
private static let logger = Logger(subsystem: "com.steipete.clawdis", category: "gateway.env")
|
||||
private static let logger = Logger(subsystem: "com.clawdis", category: "gateway.env")
|
||||
private static let supportedBindModes: Set<String> = ["loopback", "tailnet", "lan", "auto"]
|
||||
|
||||
static func bundledGatewayExecutable() -> String? {
|
||||
|
||||
@@ -1,14 +1,20 @@
|
||||
import Foundation
|
||||
|
||||
enum GatewayLaunchAgentManager {
|
||||
private static let logger = Logger(subsystem: "com.steipete.clawdis", category: "gateway.launchd")
|
||||
private static let logger = Logger(subsystem: "com.clawdis", category: "gateway.launchd")
|
||||
private static let supportedBindModes: Set<String> = ["loopback", "tailnet", "lan", "auto"]
|
||||
private static let legacyGatewayLaunchdLabel = "com.steipete.clawdis.gateway"
|
||||
|
||||
private static var plistURL: URL {
|
||||
FileManager.default.homeDirectoryForCurrentUser
|
||||
.appendingPathComponent("Library/LaunchAgents/\(gatewayLaunchdLabel).plist")
|
||||
}
|
||||
|
||||
private static var legacyPlistURL: URL {
|
||||
FileManager.default.homeDirectoryForCurrentUser
|
||||
.appendingPathComponent("Library/LaunchAgents/\(legacyGatewayLaunchdLabel).plist")
|
||||
}
|
||||
|
||||
private static func gatewayExecutablePath(bundlePath: String) -> String {
|
||||
"\(bundlePath)/Contents/Resources/Relay/clawdis"
|
||||
}
|
||||
@@ -45,6 +51,8 @@ enum GatewayLaunchAgentManager {
|
||||
|
||||
static func set(enabled: Bool, bundlePath: String, port: Int) async -> String? {
|
||||
if enabled {
|
||||
_ = await self.runLaunchctl(["bootout", "gui/\(getuid())/\(legacyGatewayLaunchdLabel)"])
|
||||
try? FileManager.default.removeItem(at: self.legacyPlistURL)
|
||||
let gatewayBin = self.gatewayExecutablePath(bundlePath: bundlePath)
|
||||
guard FileManager.default.isExecutableFile(atPath: gatewayBin) else {
|
||||
self.logger.error("launchd enable failed: gateway missing at \(gatewayBin)")
|
||||
|
||||
@@ -42,7 +42,7 @@ final class GatewayProcessManager {
|
||||
private var environmentRefreshTask: Task<Void, Never>?
|
||||
private var lastEnvironmentRefresh: Date?
|
||||
private var logRefreshTask: Task<Void, Never>?
|
||||
private let logger = Logger(subsystem: "com.steipete.clawdis", category: "gateway.process")
|
||||
private let logger = Logger(subsystem: "com.clawdis", category: "gateway.process")
|
||||
|
||||
private let logLimit = 20000 // characters to keep in-memory
|
||||
private let environmentRefreshMinInterval: TimeInterval = 30
|
||||
|
||||
@@ -77,7 +77,7 @@ enum HealthState: Equatable {
|
||||
final class HealthStore {
|
||||
static let shared = HealthStore()
|
||||
|
||||
private static let logger = Logger(subsystem: "com.steipete.clawdis", category: "health")
|
||||
private static let logger = Logger(subsystem: "com.clawdis", category: "health")
|
||||
|
||||
private(set) var snapshot: HealthSnapshot?
|
||||
private(set) var lastSuccess: Date?
|
||||
|
||||
@@ -2,7 +2,7 @@ import Darwin
|
||||
import Foundation
|
||||
|
||||
enum InstanceIdentity {
|
||||
private static let suiteName = "com.steipete.clawdis.shared"
|
||||
private static let suiteName = "com.clawdis.shared"
|
||||
private static let instanceIdKey = "instanceId"
|
||||
|
||||
private static var defaults: UserDefaults {
|
||||
|
||||
@@ -40,7 +40,7 @@ final class InstancesStore {
|
||||
var statusMessage: String?
|
||||
var isLoading = false
|
||||
|
||||
private let logger = Logger(subsystem: "com.steipete.clawdis", category: "instances")
|
||||
private let logger = Logger(subsystem: "com.clawdis", category: "instances")
|
||||
private var task: Task<Void, Never>?
|
||||
private let interval: TimeInterval = 30
|
||||
private var eventTask: Task<Void, Never>?
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
import Foundation
|
||||
|
||||
enum LaunchAgentManager {
|
||||
private static let legacyLaunchdLabel = "com.steipete.clawdis"
|
||||
private static var plistURL: URL {
|
||||
FileManager.default.homeDirectoryForCurrentUser
|
||||
.appendingPathComponent("Library/LaunchAgents/com.steipete.clawdis.plist")
|
||||
.appendingPathComponent("Library/LaunchAgents/com.clawdis.mac.plist")
|
||||
}
|
||||
private static var legacyPlistURL: URL {
|
||||
FileManager.default.homeDirectoryForCurrentUser
|
||||
.appendingPathComponent("Library/LaunchAgents/\(legacyLaunchdLabel).plist")
|
||||
}
|
||||
|
||||
static func status() async -> Bool {
|
||||
@@ -14,6 +19,8 @@ enum LaunchAgentManager {
|
||||
|
||||
static func set(enabled: Bool, bundlePath: String) async {
|
||||
if enabled {
|
||||
_ = await self.runLaunchctl(["bootout", "gui/\(getuid())/\(legacyLaunchdLabel)"])
|
||||
try? FileManager.default.removeItem(at: self.legacyPlistURL)
|
||||
self.writePlist(bundlePath: bundlePath)
|
||||
_ = await self.runLaunchctl(["bootout", "gui/\(getuid())/\(launchdLabel)"])
|
||||
_ = await self.runLaunchctl(["bootstrap", "gui/\(getuid())", self.plistURL.path])
|
||||
@@ -32,7 +39,7 @@ enum LaunchAgentManager {
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>Label</key>
|
||||
<string>com.steipete.clawdis</string>
|
||||
<string>com.clawdis.mac</string>
|
||||
<key>ProgramArguments</key>
|
||||
<array>
|
||||
<string>\(bundlePath)/Contents/MacOS/Clawdis</string>
|
||||
|
||||
@@ -74,7 +74,7 @@ enum ClawdisLogging {
|
||||
|
||||
static func parseLabel(_ label: String) -> (String, String) {
|
||||
guard let range = label.range(of: Self.labelSeparator) else {
|
||||
return ("com.steipete.clawdis", label)
|
||||
return ("com.clawdis", label)
|
||||
}
|
||||
let subsystem = String(label[..<range.lowerBound])
|
||||
let category = String(label[range.upperBound...])
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user