* feat(timer): add one-shot delayed task system (/timer)
Introduces a one-shot timer feature parallel to the existing cron
(recurring) system. Users can schedule delayed tasks via chat command
(/timer add 2h check PR status), CLI (cc-connect timer add --delay 2h),
or agent system prompt.
Core changes:
- core/timer.go: TimerJob, TimerStore, TimerScheduler, ParseDelayOrTime
- core/timer_test.go: 13 unit tests covering store, scheduler, parsing
- cmd/cc-connect/timer.go: CLI subcommands (add/list/del/info)
- core/engine.go: ExecuteTimerJob, cmdTimer, renderTimerCard, shell exec
- core/api.go: /timer/add, /timer/list, /timer/info, /timer/del endpoints
- core/i18n.go: 22 MsgTimer* keys with 5-language translations
- core/hooks.go: HookEventTimerTriggered event
- core/interfaces.go: agent system prompt section for timers
- core/management.go: SetTimerScheduler wiring
- cmd/cc-connect/main.go: timer store/scheduler lifecycle
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* feat(timer): add /timer to help card and improve usage docs
- Add /timer to /help card tools section (all 5 languages)
- Add /timer to text-based /help fallback (all 5 languages)
- Improve MsgTimerAddUsage with both relative and absolute time examples
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* fix(timer): use local timezone for absolute time parsing
When a user specifies an absolute time without timezone (e.g. "9:00"),
it should be interpreted as local time, not UTC. Use time.ParseInLocation
with time.Local for layouts that don't include a timezone component.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* docs(timer): clarify local timezone for absolute time
Absolute times without timezone (e.g. "2026-05-16T09:00") use the
system's local timezone, not UTC. This is now documented in:
- Agent system prompt (core/interfaces.go)
- /timer usage message (MsgTimerUsage, all 5 languages)
- /timer add usage message (MsgTimerAddUsage, all 5 languages)
- CLI --help text (cmd/cc-connect/timer.go)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* fix(timer): use time.Until instead of Sub(time.Now()) for lint
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* fix(timer): sync cron fixes for session_key validation and slash prompt expansion
Reference PR #973: reject empty session_key in validateTimerJob so
management API doesn't persist unrunnable timer jobs.
Reference PR #928: resolve /skill slash prompts through skill registry
in ExecuteTimerJob before constructing the agent message.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* fix: lint - errcheck resp.Body.Close, staticcheck WriteString(fmt.Sprintf)
* fix: two more WriteString(fmt.Sprintf) → fmt.Fprintf
---------
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>