diff --git a/app/src/main/java/app/closer/core/analytics/.gitkeep b/app/src/main/java/app/closer/core/analytics/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/app/src/main/java/app/closer/core/billing/.gitkeep b/app/src/main/java/app/closer/core/billing/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/app/src/main/java/app/closer/core/navigation/.gitkeep b/app/src/main/java/app/closer/core/navigation/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/app/src/main/java/app/closer/core/notifications/.gitkeep b/app/src/main/java/app/closer/core/notifications/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/app/src/main/java/app/closer/core/notifications/NotificationHelper.kt b/app/src/main/java/app/closer/core/notifications/NotificationHelper.kt deleted file mode 100644 index 9dc2babc..00000000 --- a/app/src/main/java/app/closer/core/notifications/NotificationHelper.kt +++ /dev/null @@ -1,70 +0,0 @@ -package app.closer.core.notifications - -import android.app.NotificationChannel -import android.app.NotificationManager -import android.app.PendingIntent -import android.content.Context -import android.content.Intent -import androidx.core.app.NotificationCompat -import androidx.core.app.NotificationManagerCompat -import app.closer.MainActivity -import app.closer.R - -object NotificationHelper { - - const val CHANNEL_REMINDERS = "reminders" - const val CHANNEL_PARTNER = "partner_activity" - const val CHANNEL_GAME_ACTIVITY = "game_activity" - - fun createChannels(context: Context) { - val nm = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager - nm.createNotificationChannel( - NotificationChannel( - CHANNEL_REMINDERS, - "Daily reminders", - NotificationManager.IMPORTANCE_DEFAULT - ).apply { - description = "Gentle nudges for today's question and shared moments" - } - ) - nm.createNotificationChannel( - NotificationChannel( - CHANNEL_PARTNER, - "Partner activity", - NotificationManager.IMPORTANCE_HIGH - ).apply { - description = "When your partner answers, reveals, or opens a conversation" - } - ) - nm.createNotificationChannel( - NotificationChannel( - CHANNEL_GAME_ACTIVITY, - "Games", - NotificationManager.IMPORTANCE_HIGH - ).apply { - description = "When your partner starts or completes a game round" - } - ) - } - - fun show(context: Context, id: Int, channelId: String, title: String, body: String) { - val intent = Intent(context, MainActivity::class.java).apply { - flags = Intent.FLAG_ACTIVITY_SINGLE_TOP - } - val pending = PendingIntent.getActivity( - context, 0, intent, - PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE - ) - val notification = NotificationCompat.Builder(context, channelId) - .setSmallIcon(R.drawable.ic_notification_closer) - .setContentTitle(title) - .setContentText(body) - .setAutoCancel(true) - .setContentIntent(pending) - .build() - - if (NotificationManagerCompat.from(context).areNotificationsEnabled()) { - NotificationManagerCompat.from(context).notify(id, notification) - } - } -} diff --git a/app/src/main/java/app/closer/core/notifications/NotificationPermissionHelper.kt b/app/src/main/java/app/closer/core/notifications/NotificationPermissionHelper.kt deleted file mode 100644 index f56d7462..00000000 --- a/app/src/main/java/app/closer/core/notifications/NotificationPermissionHelper.kt +++ /dev/null @@ -1,69 +0,0 @@ -package app.closer.core.notifications - -import android.Manifest -import android.app.Activity -import android.content.Context -import android.content.pm.PackageManager -import android.os.Build -import androidx.core.app.ActivityCompat -import androidx.core.content.ContextCompat -import javax.inject.Inject -import javax.inject.Singleton - -/** - * Handles Android 13+ (API 33) POST_NOTIFICATIONS permission requests. - * - * Callers should: - * 1. Check [isGranted] before asking. - * 2. If [shouldShowRationale] is true, show an in-app rationale first. - * 3. Invoke [requestPermission] from an Activity context. - */ -@Singleton -class NotificationPermissionHelper @Inject constructor() { - - val permission: String = Manifest.permission.POST_NOTIFICATIONS - - fun isGranted(context: Context): Boolean { - return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { - ContextCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED - } else { - // Pre-Android 13 notifications are granted at install time. - true - } - } - - fun shouldShowRationale(activity: Activity): Boolean { - return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { - ActivityCompat.shouldShowRequestPermissionRationale(activity, permission) - } else { - false - } - } - - fun requestPermission(activity: Activity, requestCode: Int = REQUEST_CODE) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { - ActivityCompat.requestPermissions( - activity, - arrayOf(permission), - requestCode - ) - } - } - - fun onRequestResult( - requestCode: Int, - permissions: Array, - grantResults: IntArray - ): Boolean { - if (requestCode != REQUEST_CODE) return false - - val index = permissions.indexOf(permission) - if (index < 0 || index >= grantResults.size) return false - - return grantResults[index] == PackageManager.PERMISSION_GRANTED - } - - companion object { - const val REQUEST_CODE = 9001 - } -} diff --git a/app/src/main/java/app/closer/data/local/.gitkeep b/app/src/main/java/app/closer/data/local/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/app/src/main/java/app/closer/data/questions/QuestionJsonParser.kt b/app/src/main/java/app/closer/data/questions/QuestionJsonParser.kt deleted file mode 100644 index 49daeb52..00000000 --- a/app/src/main/java/app/closer/data/questions/QuestionJsonParser.kt +++ /dev/null @@ -1,199 +0,0 @@ -package app.closer.data.questions - -import android.util.Log -import app.closer.BuildConfig -import app.closer.domain.model.* -import org.json.JSONArray -import org.json.JSONObject - -/** - * Parses a JSON file containing question data in the v2 schema format. - * - * Expected JSON structure: - * { - * "category": { ... }, - * "questions": [ - * { - * "id": "...", - * "category_id": "...", - * "type": "written|single_choice|multi_choice|scale|this_or_that", - * "text": "...", - * "depth": 1-5, - * "access": "free|premium", - * "tags": [...], - * "answer_config": { ... } - * } - * ] - * } - */ -object QuestionJsonParser { - - private const val TAG = "QuestionJsonParser" - - data class ParsedQuestionBundle( - val category: QuestionCategory, - val questions: List - ) - - fun parseFromFile(jsonFilePath: String): ParsedQuestionBundle? { - val jsonContent = try { - java.io.File(jsonFilePath).readText() - } catch (e: Exception) { - if (BuildConfig.DEBUG) { - Log.e(TAG, "Failed to read JSON file: ${e.message}") - } - return null - } - - return parseFromJsonString(jsonContent) - } - - fun parseFromJsonString(jsonString: String): ParsedQuestionBundle? { - return try { - val root = JSONObject(jsonString) - val categoryObj = root.getJSONObject("category") - val questionsArray = root.getJSONArray("questions") - - val category = parseCategory(categoryObj) - val questions = mutableListOf() - - for (i in 0 until questionsArray.length()) { - val questionObj = questionsArray.getJSONObject(i) - questionObj?.let { q -> - questions.add(parseQuestion(q, category.id)) - } - } - - ParsedQuestionBundle(category, questions) - } catch (e: Exception) { - if (BuildConfig.DEBUG) { - Log.e(TAG, "Failed to parse JSON: ${e.message}") - } - null - } - } - - private fun parseCategory(obj: JSONObject): QuestionCategory { - return QuestionCategory( - id = obj.optString("id", ""), - displayName = obj.optString("display_name", ""), - description = obj.optString("description", ""), - access = obj.optString("access", "free"), - iconName = obj.optString("icon_name", "message") - ) - } - - private fun parseQuestion(obj: JSONObject, categoryId: String): Question { - val type = obj.optString("type", "written") - val tags = obj.optJSONArray("tags")?.let { arr -> - mutableListOf().apply { - for (i in 0 until arr.length()) { - add(arr.optString(i)) - } - }.toList() - } ?: emptyList() - - val answerConfig = parseAnswerConfig(obj, type) - - return Question( - id = obj.optString("id", ""), - text = obj.optString("text", ""), - category = categoryId, - depthLevel = obj.optInt("depth", 1), - isPremium = obj.optString("access", "free") == "premium", - type = type, - tags = tags, - answerConfig = answerConfig - ) - } - - private fun parseAnswerConfig(obj: JSONObject, type: String): AnswerConfig? { - val answerConfigObj = obj.optJSONObject("answer_config") - if (answerConfigObj == null) return null - - return when (type) { - "written" -> { - WrittenAnswerConfigImpl( - config = WrittenAnswerConfig( - minLength = answerConfigObj.optInt("min_length", 1), - maxLength = answerConfigObj.optInt("max_length", 1000), - placeholder = answerConfigObj.optString("placeholder", "Write your answer...") - ) - ) - } - "single_choice" -> { - val options = mutableListOf() - val optionsArray = obj.optJSONArray("options") - if (optionsArray != null) { - for (i in 0 until optionsArray.length()) { - val opt = optionsArray.optJSONObject(i) - opt?.let { o -> - options.add(ChoiceOption( - id = o.optString("id", ""), - text = o.optString("text", "") - )) - } - } - } - ChoiceAnswerConfigImpl( - config = ChoiceAnswerConfig(options = options.toList()) - ) - } - "scale" -> { - ScaleAnswerConfigImpl( - config = ScaleAnswerConfig( - minScale = answerConfigObj.optInt("min_scale", 1), - maxScale = answerConfigObj.optInt("max_scale", 5), - minLabel = answerConfigObj.optString("min_label", ""), - maxLabel = answerConfigObj.optString("max_label", ""), - scaleStep = answerConfigObj.optInt("scale_step", 1) - ) - ) - } - "this_or_that" -> { - val optionsArray = obj.optJSONArray("options") - if (optionsArray?.length() == 2) { - val optA = optionsArray.optJSONObject(0) - val optB = optionsArray.optJSONObject(1) - ThisOrThatAnswerConfigImpl( - config = ThisOrThatAnswerConfig( - optionA = ChoiceOption( - id = optA?.optString("id", "") ?: "", - text = optA?.optString("text", "") ?: "" - ), - optionB = ChoiceOption( - id = optB?.optString("id", "") ?: "", - text = optB?.optString("text", "") ?: "" - ) - ) - ) - } else { - null - } - } - "multi_choice" -> { - val options = mutableListOf() - val optionsArray = obj.optJSONArray("options") - if (optionsArray != null) { - for (i in 0 until optionsArray.length()) { - val opt = optionsArray.optJSONObject(i) - opt?.let { o -> - options.add(ChoiceOption( - id = o.optString("id", ""), - text = o.optString("text", "") - )) - } - } - } - ChoiceAnswerConfigImpl( - type = "multi_choice", - config = ChoiceAnswerConfig( - options = options.toList(), - maxSelections = answerConfigObj.optInt("max_selections", 0) - ) - ) - } - else -> null - } - } -} diff --git a/app/src/main/java/app/closer/data/remote/.gitkeep b/app/src/main/java/app/closer/data/remote/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/app/src/main/java/app/closer/data/repository/.gitkeep b/app/src/main/java/app/closer/data/repository/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/app/src/main/java/app/closer/data/repository/FakeQuestionRepository.kt b/app/src/main/java/app/closer/data/repository/FakeQuestionRepository.kt deleted file mode 100644 index 9fd69c66..00000000 --- a/app/src/main/java/app/closer/data/repository/FakeQuestionRepository.kt +++ /dev/null @@ -1,26 +0,0 @@ -package app.closer.data.repository - -import app.closer.domain.model.Question -import app.closer.domain.model.QuestionCategory -import app.closer.domain.repository.QuestionRepository - -class FakeQuestionRepository : QuestionRepository { - override suspend fun getDailyQuestion(): Question? = null - override suspend fun getDailyQuestionForMode(modeTag: String, isPremium: Boolean): Question? = null - - override suspend fun getQuestionById(id: String): Question? = null - - override suspend fun getQuestionsByCategory(categoryId: String): List = emptyList() - - override suspend fun getCategories(): List = emptyList() - - override suspend fun getCategoryById(id: String): QuestionCategory? = null - - override suspend fun getQuestionCountByCategory(categoryId: String): Int = 0 - - override suspend fun getQuestionsByType(type: String): List = emptyList() - - override suspend fun getQuestionsForPrediction(): List = emptyList() - - override suspend fun getDesireSyncQuestions(sex: String): List = emptyList() -} diff --git a/app/src/main/java/app/closer/domain/model/Entitlement.kt b/app/src/main/java/app/closer/domain/model/Entitlement.kt deleted file mode 100644 index bee2685b..00000000 --- a/app/src/main/java/app/closer/domain/model/Entitlement.kt +++ /dev/null @@ -1,11 +0,0 @@ -package app.closer.domain.model - -data class Entitlement( - val id: String = "", - val userId: String = "", - val source: String = "", - val productId: String = "", - val isActive: Boolean = false, - val expiresAt: Long? = null, - val updatedAt: Long = System.currentTimeMillis() -) diff --git a/app/src/main/java/app/closer/domain/model/InviteStatus.kt b/app/src/main/java/app/closer/domain/model/InviteStatus.kt deleted file mode 100644 index 72db2278..00000000 --- a/app/src/main/java/app/closer/domain/model/InviteStatus.kt +++ /dev/null @@ -1,8 +0,0 @@ -package app.closer.domain.model - -enum class InviteStatus { - PENDING, - ACCEPTED, - EXPIRED, - CANCELLED -} diff --git a/app/src/main/java/app/closer/domain/model/QuestionSessionStatus.kt b/app/src/main/java/app/closer/domain/model/QuestionSessionStatus.kt deleted file mode 100644 index 63e95a84..00000000 --- a/app/src/main/java/app/closer/domain/model/QuestionSessionStatus.kt +++ /dev/null @@ -1,6 +0,0 @@ -package app.closer.domain.model - -enum class QuestionSessionStatus { - ACTIVE, - COMPLETED -} diff --git a/app/src/main/java/app/closer/domain/repository/.gitkeep b/app/src/main/java/app/closer/domain/repository/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/app/src/main/java/app/closer/domain/usecase/.gitkeep b/app/src/main/java/app/closer/domain/usecase/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/app/src/main/java/app/closer/notifications/PartnerNotificationScheduler.kt b/app/src/main/java/app/closer/notifications/PartnerNotificationScheduler.kt deleted file mode 100644 index 626e11ca..00000000 --- a/app/src/main/java/app/closer/notifications/PartnerNotificationScheduler.kt +++ /dev/null @@ -1,81 +0,0 @@ -package app.closer.notifications - -import javax.inject.Inject - -/** - * Schedules partner-trigger notifications in response to partner actions. - * - * This class is intentionally synchronous: it validates quiet hours, opt-outs, - * and rate limits at the moment the event is received. Background deferral is - * handled by the backend FCM delivery schedule and [PartnerNotificationManager]. - */ -class PartnerNotificationScheduler @Inject constructor( - private val notificationManager: PartnerNotificationManager -) { - - /** - * The partner answered today's question; prompt the user to answer too. - */ - suspend fun onPartnerAnswered(coupleId: String, questionId: String? = null) { - notificationManager.show( - PartnerNotificationType.PARTNER_ANSWERED, - coupleId, - PartnerNotificationPayload(questionId = questionId) - ) - } - - /** - * Both partners have answered and the reveal is ready. - */ - suspend fun onRevealReady(coupleId: String, questionId: String) { - notificationManager.show( - PartnerNotificationType.REVEAL_READY, - coupleId, - PartnerNotificationPayload(questionId = questionId) - ) - } - - /** - * The partner started a game for the couple. - */ - suspend fun onPartnerStartedGame(coupleId: String, gameSessionId: String? = null) { - notificationManager.show( - PartnerNotificationType.PARTNER_STARTED_GAME, - coupleId, - PartnerNotificationPayload(gameSessionId = gameSessionId) - ) - } - - /** - * The partner completed their side of a two-player game. - */ - suspend fun onPartnerCompletedPart(coupleId: String, gameSessionId: String? = null) { - notificationManager.show( - PartnerNotificationType.PARTNER_COMPLETED_PART, - coupleId, - PartnerNotificationPayload(gameSessionId = gameSessionId) - ) - } - - /** - * A daily connection challenge is waiting for the couple. - */ - suspend fun onChallengeWaiting(coupleId: String, challengeId: String? = null) { - notificationManager.show( - PartnerNotificationType.CHALLENGE_WAITING, - coupleId, - PartnerNotificationPayload(challengeId = challengeId) - ) - } - - /** - * A previously sealed memory capsule reached its unlock date. - */ - suspend fun onCapsuleUnlocked(coupleId: String, capsuleId: String? = null) { - notificationManager.show( - PartnerNotificationType.CAPSULE_UNLOCKED, - coupleId, - PartnerNotificationPayload(capsuleId = capsuleId) - ) - } -} diff --git a/app/src/main/java/app/closer/ui/answers/.gitkeep b/app/src/main/java/app/closer/ui/answers/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/app/src/main/java/app/closer/ui/auth/.gitkeep b/app/src/main/java/app/closer/ui/auth/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/app/src/main/java/app/closer/ui/components/.gitkeep b/app/src/main/java/app/closer/ui/components/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/app/src/main/java/app/closer/ui/home/.gitkeep b/app/src/main/java/app/closer/ui/home/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/app/src/main/java/app/closer/ui/onboarding/.gitkeep b/app/src/main/java/app/closer/ui/onboarding/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/app/src/main/java/app/closer/ui/pairing/.gitkeep b/app/src/main/java/app/closer/ui/pairing/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/app/src/main/java/app/closer/ui/paywall/.gitkeep b/app/src/main/java/app/closer/ui/paywall/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/app/src/main/java/app/closer/ui/questions/.gitkeep b/app/src/main/java/app/closer/ui/questions/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/app/src/main/java/app/closer/ui/questions/QuestionDetailViewModel.kt b/app/src/main/java/app/closer/ui/questions/QuestionDetailViewModel.kt deleted file mode 100644 index f27c63ef..00000000 --- a/app/src/main/java/app/closer/ui/questions/QuestionDetailViewModel.kt +++ /dev/null @@ -1,104 +0,0 @@ -package app.closer.ui.questions - -import androidx.lifecycle.SavedStateHandle -import androidx.lifecycle.ViewModel -import androidx.lifecycle.viewModelScope -import app.closer.domain.model.ChoiceAnswerConfigImpl -import app.closer.domain.repository.LocalAnswerRepository -import app.closer.domain.repository.QuestionRepository -import app.closer.ui.components.TextInputLimits -import dagger.hilt.android.lifecycle.HiltViewModel -import javax.inject.Inject -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.asStateFlow -import kotlinx.coroutines.flow.update -import kotlinx.coroutines.launch - -@HiltViewModel -class QuestionDetailViewModel @Inject constructor( - private val repository: QuestionRepository, - private val localAnswerRepository: LocalAnswerRepository, - savedStateHandle: SavedStateHandle -) : ViewModel() { - - private val questionId: String = savedStateHandle["questionId"] ?: "" - - private val _uiState = MutableStateFlow(LocalQuestionUiState()) - val uiState: StateFlow = _uiState.asStateFlow() - - init { - loadQuestion() - } - - fun loadQuestion() { - viewModelScope.launch { - _uiState.value = LocalQuestionUiState(isLoading = true) - try { - val question = repository.getQuestionById(questionId) - val answer = question?.let { localAnswerRepository.getAnswer(it.id) } - _uiState.value = LocalQuestionUiState( - isLoading = false, - question = question, - pendingScaleValue = defaultScaleValue(question) - ).withLocalAnswer(answer) - } catch (e: Exception) { - _uiState.value = LocalQuestionUiState( - isLoading = false, - error = e.message ?: "Could not load this question." - ) - } - } - } - - fun updateWrittenText(text: String) { - _uiState.update { it.copy(pendingWrittenText = text.take(MAX_ANSWER_LENGTH), submitted = false) } - } - - fun toggleOption(optionId: String) { - _uiState.update { state -> - val question = state.question ?: return@update state - val updated = if (question.type == "multi_choice") { - val maxSel = (question.answerConfig as? ChoiceAnswerConfigImpl)?.config?.maxSelections ?: 0 - when { - optionId in state.pendingSelectedOptionIds -> state.pendingSelectedOptionIds - optionId - maxSel == 0 || state.pendingSelectedOptionIds.size < maxSel -> state.pendingSelectedOptionIds + optionId - else -> state.pendingSelectedOptionIds - } - } else { - listOf(optionId) - } - state.copy(pendingSelectedOptionIds = updated, submitted = false) - } - } - - fun updateScale(value: Int) { - _uiState.update { it.copy(pendingScaleValue = value, submitted = false) } - } - - fun submitAnswer() { - val state = _uiState.value - val question = state.question ?: return - if (!canSubmit(state)) return - viewModelScope.launch { - localAnswerRepository.saveAnswer(state.toLocalAnswer(question)) - _uiState.update { it.copy(submitted = true) } - } - } - - fun canSubmit(): Boolean = canSubmit(_uiState.value) - - companion object { - const val MAX_ANSWER_LENGTH = TextInputLimits.WRITTEN_ANSWER - } - - private fun canSubmit(state: LocalQuestionUiState): Boolean { - val question = state.question ?: return false - return when (question.type) { - "written" -> state.pendingWrittenText.isNotBlank() - "single_choice", "multi_choice", "this_or_that" -> state.pendingSelectedOptionIds.isNotEmpty() - "scale" -> true - else -> false - } - } -} diff --git a/app/src/main/java/app/closer/ui/settings/.gitkeep b/app/src/main/java/app/closer/ui/settings/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/app/src/main/java/app/closer/ui/wheel/.gitkeep b/app/src/main/java/app/closer/ui/wheel/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/gitleaks-current.json b/gitleaks-current.json deleted file mode 100644 index 35253221..00000000 --- a/gitleaks-current.json +++ /dev/null @@ -1,42 +0,0 @@ -[ - { - "Description": "Generic API Key", - "StartLine": 31, - "EndLine": 31, - "StartColumn": 21, - "EndColumn": 67, - "Match": "key\": \"REDACTED\"", - "Secret": "REDACTED", - "File": "app/google-services.json", - "SymlinkFile": "", - "Commit": "", - "Entropy": 4.7851515, - "Author": "", - "Email": "", - "Date": "", - "Message": "", - "Tags": [], - "RuleID": "generic-api-key", - "Fingerprint": "app/google-services.json:generic-api-key:31" - }, - { - "Description": "Generic API Key", - "StartLine": 68, - "EndLine": 68, - "StartColumn": 21, - "EndColumn": 67, - "Match": "key\": \"REDACTED\"", - "Secret": "REDACTED", - "File": "app/google-services.json", - "SymlinkFile": "", - "Commit": "", - "Entropy": 4.7851515, - "Author": "", - "Email": "", - "Date": "", - "Message": "", - "Tags": [], - "RuleID": "generic-api-key", - "Fingerprint": "app/google-services.json:generic-api-key:68" - } -] diff --git a/gitleaks-history.json b/gitleaks-history.json deleted file mode 100644 index fe51488c..00000000 --- a/gitleaks-history.json +++ /dev/null @@ -1 +0,0 @@ -[]