Skip to content

C:/Program Files/Git/loop survives chat restart (replay last loop on resume) #414

@esengine

Description

@esengine

Status: Small, scoped enhancement. Not a daemon. See #410 for the larger always-on / chat-bridge debate.

The gap

/loop <interval> <prompt> schedules a recurring auto-submit inside the current reasonix chat session (src/cli/ui/loop.ts, src/cli/ui/hooks/useLoopMode.ts). It dies the moment the chat exits — Ctrl+C, terminal close, laptop sleep wake-up that drops the SSH pipe, accidental /quit.

Concretely: a user sets /loop 10m check the build, fix anything red, walks to lunch, and comes back to a dead loop because the build itself crashed the terminal at minute 7.

Why it matters

Long-running watch loops (CI babysitting, periodic security scans, scheduled refactor passes) want to survive a session reboot. Today the workaround is "use OS cron + reasonix code -p," which throws away the resume / session continuity that makes Reasonix useful in the first place.

What I'd commit to

Persist active loop config to session state, not a separate daemon.

  • On /loop start, write { intervalMs, prompt, startedAt, iter } into the session's ~/.reasonix/sessions/<name>.json (or alongside, so it survives session compaction).
  • On reasonix chat --resume / SessionPicker → Open: if the session has an active loop entry and the last fire was within intervalMs * 2, prompt the user inline:

    previous loop was `` every 5m, last fired 7m ago — resume? [y/n]

  • y → re-arm the timer with nextFireAt = lastFireAt + intervalMs.
  • n → clear the persisted entry.
  • /loop stop clears the persisted entry too.

This is opt-in on resume — never auto-fires without confirmation, so a sleeping laptop waking up at 3am doesn't quietly burn tokens.

What this is NOT

  • Not a daemon. The CLI process must be running for the loop to fire. We are not detaching, not double-forking, not running on system startup.
  • Not cross-machine. Loop state is per-session and per-machine.
  • Not for >6h intervals. Same MAX_LOOP_INTERVAL_MS = 6h applies — beyond that, OS cron remains the right answer.
  • Not the chat-bridge / OpenClaw shape — see RFC: Chat-platform bridge (Feishu / WeWork / WeChat) #410.

Decision points

  • Persist in the session JSON or in a sidecar <session>.loop.json? Sidecar keeps loop state out of the cache-first transcript hash; session JSON is one fewer file.
  • Resume prompt: inline-in-chat (KeystrokeProvider question) or a flag on launch (--resume-loop / --no-resume-loop)? Inline is the better default; flag is a useful escape hatch for scripts.
  • Window for "stale enough to skip auto-resume" — fixed (e.g. >24h since last fire = always ask) or computed from interval?

Test plan sketch

  • Unit: parse + persist + reload round-trip on session JSON.
  • Integration: /loop 5s ..., Ctrl+C mid-loop, reasonix chat --resume, confirm prompt appears with correct elapsed time.
  • Edge: persisted loop with corrupt entry → drop silently, log warn, do not block resume.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions