feat: cron job editor dialog (closes #150)

Implements a full-screen cron job editor dialog following the skills editor pattern:
- Create/edit/delete cron jobs with all backend fields
- CronJobRepeat data class matching backend object shape
- Fixed Gson crash on cron tab load
This commit is contained in:
M57 authored and GitHub committed 2026-06-29 18:48:45 +03:00
1 parent 4849f4c1c6
commit 4c075be026
6 files changed
+608 -10

No files matched your search

@@ -1,5 +1,10 @@
package com.m57.hermescontrol.data.model
data class CronJobRepeat(
val times: Int? = null,
val completed: Int = 0,
)
data class CronJob(
val id: String,
val name: String,
@@ -10,6 +15,20 @@ data class CronJob(
val schedule_display: String? = null,
val last_status: String? = null,
val next_run_at: String? = null,
// Full editor fields — all optional with defaults for backward compat
val enabled: Boolean? = null,
val prompt: String? = null,
val deliver: String? = null,
val skills: List<String>? = null,
val model: String? = null,
val provider: String? = null,
val base_url: String? = null,
val script: String? = null,
val context_from: List<String>? = null,
val enabled_toolsets: List<String>? = null,
val workdir: String? = null,
val no_agent: Boolean? = null,
val repeat: CronJobRepeat? = null,
) {
val scheduleText: String
get() =
@@ -0,0 +1,22 @@
package com.m57.hermescontrol.data.model
data class CreateCronJobRequest(
val name: String = "",
val schedule: String,
val prompt: String = "",
val deliver: String = "local",
val skills: List<String>? = null,
val model: String? = null,
val provider: String? = null,
val base_url: String? = null,
val script: String? = null,
val context_from: List<String>? = null,
val enabled_toolsets: List<String>? = null,
val workdir: String? = null,
val no_agent: Boolean = false,
val repeat: Int? = null,
)
data class UpdateCronJobRequest(
val updates: Map<String, Any?>,
)
@@ -3,6 +3,7 @@ package com.m57.hermescontrol.data.remote
import com.m57.hermescontrol.data.model.AchievementsResponse
import com.m57.hermescontrol.data.model.ActiveProfileResponse
import com.m57.hermescontrol.data.model.AgentPluginInstallBody
import com.m57.hermescontrol.data.model.CreateCronJobRequest
import com.m57.hermescontrol.data.model.CreateTaskBody
import com.m57.hermescontrol.data.model.CronJob
import com.m57.hermescontrol.data.model.DoctorResponse
@@ -38,6 +39,7 @@ import com.m57.hermescontrol.data.model.SystemStatsResponse
import com.m57.hermescontrol.data.model.ToggleSkillRequest
import com.m57.hermescontrol.data.model.Toolset
import com.m57.hermescontrol.data.model.ToolsetToggleRequest
import com.m57.hermescontrol.data.model.UpdateCronJobRequest
import com.m57.hermescontrol.data.model.UpdateProfileModelRequest
import com.m57.hermescontrol.data.model.UpdateProfileSoulRequest
import com.m57.hermescontrol.data.model.UpdateRawConfigRequest
@@ -103,6 +105,22 @@ interface HermesApiService {
@Path("id") id: String,
): Response<Unit>
@GET("api/cron/jobs/{id}")
suspend fun getCronJob(
@Path("id") id: String,
): Response<CronJob>
@POST("api/cron/jobs")
suspend fun createCronJob(
@Body body: CreateCronJobRequest,
): Response<CronJob>
@PUT("api/cron/jobs/{id}")
suspend fun updateCronJob(
@Path("id") id: String,
@Body body: UpdateCronJobRequest,
): Response<CronJob>
@POST("api/cron/jobs/{id}/trigger")
suspend fun triggerCronJob(
@Path("id") id: String,