Skip to content

Commit 14397a7

Browse files
pandemicsynjrf0110
authored andcommitted
feat(kiloclaw): add unexpected stop recovery (#1993)
* feat(kiloclaw): add stop recovery admin tooling * fix(kiloclaw): trigger recovery on first stopped alarm * fix(kiloclaw): hand off recovery startup timeouts
1 parent 8cb9b94 commit 14397a7

22 files changed

Lines changed: 1720 additions & 67 deletions

File tree

apps/web/src/app/(app)/claw/components/InstanceControls.tsx

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ export function InstanceControls({
6767
const isProvisioned = status.status === 'provisioned';
6868
const isStarting = status.status === 'starting';
6969
const isRestarting = status.status === 'restarting';
70+
const isRecovering = status.status === 'recovering';
7071
const isStopped = status.status === 'stopped';
7172
const isStartable = isStopped || isProvisioned;
7273
const isDestroying = status.status === 'destroying';
@@ -249,7 +250,8 @@ export function InstanceControls({
249250
isAutoStarting ||
250251
isDestroying ||
251252
isStarting ||
252-
isRestarting
253+
isRestarting ||
254+
isRecovering
253255
}
254256
onClick={() => {
255257
posthog?.capture('claw_start_instance_clicked', { instance_status: status.status });
@@ -277,7 +279,8 @@ export function InstanceControls({
277279
mutations.restartOpenClaw.isPending ||
278280
isDestroying ||
279281
isStarting ||
280-
isRestarting
282+
isRestarting ||
283+
isRecovering
281284
}
282285
onClick={() => {
283286
posthog?.capture('claw_restart_openclaw_prompted', {
@@ -299,7 +302,8 @@ export function InstanceControls({
299302
mutations.restartMachine.isPending ||
300303
isDestroying ||
301304
isStarting ||
302-
isRestarting
305+
isRestarting ||
306+
isRecovering
303307
}
304308
onClick={() => {
305309
posthog?.capture('claw_redeploy_prompted', { instance_status: status.status });
@@ -319,7 +323,8 @@ export function InstanceControls({
319323
mutations.runDoctor.isPending ||
320324
isDestroying ||
321325
isStarting ||
322-
isRestarting
326+
isRestarting ||
327+
isRecovering
323328
}
324329
onClick={() => {
325330
posthog?.capture('claw_doctor_clicked', { instance_status: status.status });
@@ -333,7 +338,7 @@ export function InstanceControls({
333338
size="sm"
334339
variant="outline"
335340
className="border-emerald-500/30 text-emerald-400 hover:bg-emerald-500/10 hover:text-emerald-300"
336-
disabled={!isRunning || isDestroying || isStarting || isRestarting}
341+
disabled={!isRunning || isDestroying || isStarting || isRestarting || isRecovering}
337342
onClick={() => {
338343
posthog?.capture('claw_kilo_run_clicked', { instance_status: status.status });
339344
setKiloRunOpen(true);
@@ -439,16 +444,16 @@ export function InstanceControls({
439444
onError: err => toast.error(err.message, { duration: 10000 }),
440445
});
441446
}}
442-
disabled={mutations.restartMachine.isPending || isRestarting}
447+
disabled={mutations.restartMachine.isPending || isRestarting || isRecovering}
443448
>
444449
{mutations.restartMachine.isPending ? (
445450
<>
446451
{redeployMode === 'redeploy' ? 'Redeploying' : 'Upgrading'}
447452
<AnimatedDots />
448453
</>
449-
) : isRestarting ? (
454+
) : isRestarting || isRecovering ? (
450455
<>
451-
Restarting
456+
{isRecovering ? 'Recovering' : 'Restarting'}
452457
<AnimatedDots />
453458
</>
454459
) : (

apps/web/src/app/(app)/claw/components/SettingsTab.tsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -590,6 +590,7 @@ export function SettingsTab({
590590
const isSaving = mutations.patchConfig.isPending;
591591
const isStarting = status.status === 'starting';
592592
const isRestarting = status.status === 'restarting';
593+
const isRecovering = status.status === 'recovering';
593594
const isDestroying = status.status === 'destroying';
594595
const supportsConfigRestore = calverAtLeast(
595596
cleanVersion(controllerVersion?.version),
@@ -978,7 +979,8 @@ export function SettingsTab({
978979
!isRunning ||
979980
mutations.restoreConfig.isPending ||
980981
isDestroying ||
981-
isRestarting
982+
isRestarting ||
983+
isRecovering
982984
}
983985
onClick={() => {
984986
posthog?.capture('claw_restore_config_clicked', {
@@ -1000,7 +1002,7 @@ export function SettingsTab({
10001002
<Button
10011003
variant="outline"
10021004
size="sm"
1003-
disabled={!isRunning || isDestroying || isRestarting}
1005+
disabled={!isRunning || isDestroying || isRestarting || isRecovering}
10041006
onClick={() => setEditConfigOpen(true)}
10051007
>
10061008
<FileCode className="h-4 w-4" />
@@ -1015,7 +1017,8 @@ export function SettingsTab({
10151017
mutations.stop.isPending ||
10161018
isDestroying ||
10171019
isStarting ||
1018-
isRestarting
1020+
isRestarting ||
1021+
isRecovering
10191022
}
10201023
onClick={() => {
10211024
posthog?.capture('claw_stop_instance_clicked', {

apps/web/src/app/(app)/claw/components/claw.types.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,10 @@ export const CLAW_STATUS_BADGE: Record<
8888
label: 'Restarting',
8989
className: 'border-amber-500/30 bg-amber-500/15 text-amber-400 animate-pulse',
9090
},
91+
recovering: {
92+
label: 'Recovering',
93+
className: 'border-orange-500/30 bg-orange-500/15 text-orange-400 animate-pulse',
94+
},
9195
stopped: {
9296
label: 'Machine Stopped',
9397
className: 'border-red-500/30 bg-red-500/15 text-red-400',

0 commit comments

Comments
 (0)