Self-Update
Overview
Check for available KiroCrew updates, apply them, and optionally set up automatic update checking via cron.
kirocrew update behaves differently on three install layouts, and which one the
user is on decides everything below:
- git checkout — fetch, then
reset --hardto the upstream tip. Only a fast-forwardable checkout is updated; a DIVERGED checkout (local commits both ahead and behind) is refused, because the reset would discard them. - wheel / cli.sh — fetch the release feed, compare versions, re-run the installer.
- externally managed (desktop app, Docker) — prints guidance and returns without updating. The desktop app updates itself over its own OTA channel.
There is no separate "check" subcommand.
A policy-defined update provider, when one is configured, owns updating this host:
it runs before any layout dispatch, the built-in mechanism never runs, and there is
no fallback — kirocrew update exits 1 on provider failure. Report the provider's
failure; do not try to route around it.
Core Concepts
Checking for Updates
Non-destructive — safe to run anytime. Report the installed version:
kirocrew --version
Then compare it against that layout's own source of truth: upstream for a git checkout, the release feed for a wheel install, the app's own updater for desktop. Comparing against the public repository's tags is right only for a git install.
Applying Updates
To apply an available update:
kirocrew update
The gateway must be restarted afterward for the new version to take effect.
Two more verbs:
kirocrew update approve # approve a pending in-app update armed from the dashboard
kirocrew update --force # git installs only
--force is the destructive one: on a diverged git checkout it lets the hard reset
discard local commits, recoverable only from git reflog. Never run it without
saying that first.
Automatic Update Checking
If the user asks for automatic updates, create a cron job that checks periodically and notifies.
Scheduling rules:
- Pick a random weekday and business hour — don't hardcode Monday 9am. Suggest something like "I'll check on Wednesdays around 2pm" and let the user approve or adjust.
- Add a random minute (0-59) to the cron expression to avoid a thundering herd of all KiroCrew instances checking simultaneously.
- Use the user's local timezone — get it from their Slack profile via
read_slack_profile. Thecron_addtool accepts atimezoneparameter. Never schedule in UTC unless the user is actually in UTC. - For auto-apply mode, some users prefer updates outside business hours (e.g. "update overnight"). Ask the user's preference.
Determining the user's timezone:
Check the system timezone first (fastest). If it's UTC, it may be an unconfigured cloud desktop rather than the user's actual timezone — verify with a second source.
# System timezone (fast, local)
cat /etc/timezone # or: timedatectl show -p Timezone --value
Resolution order:
- System timezone is non-UTC — use it (reliably reflects user's locale)
- System timezone is UTC — could be correct or could be an unconfigured server. Check Slack profile via
read_slack_profile(user="<user_id>")for the user's configured timezone, or ask the user to confirm - If
read_slack_profileunavailable — ask the user directly
Example — notify-only cron:
cron_add(
name="kirocrew-update-check",
cron_expr="37 14 * * 3", # Wednesday at 2:37pm (random minute)
timezone="America/Los_Angeles", # from user's Slack profile
command="kirocrew --version",
message="Report the installed KiroCrew version and check whether a newer one is available",
)
A notify-only cron must NOT run kirocrew update (that applies the update). Use
kirocrew --version to report the installed version, and have the LLM-mode job
compare it against the public repo and tell the user if an update is available.
Present the schedule to the user for confirmation, always including the timezone: "I'll check for updates on Wednesdays around 2:37pm Pacific (America/Los_Angeles). Sound good?"
For fully automatic updates (apply + restart), first check the layout: only a git or wheel install has a self-update path to automate. On a desktop install point the user at the app's own OTA updater instead of a cron, and on Docker there is no self-update at all. Where a cron does fit, use an LLM-mode one so it can follow the gateway-restart skill for a safe restart:
cron_add(
name="kirocrew-auto-update",
cron_expr="42 2 * * 4", # Thursday at 2:42am (off-hours, random minute)
timezone="America/Los_Angeles",
message="Apply a KiroCrew update by scheduling it server-side, then follow the gateway-restart skill to restart the gateway. If already up to date, report briefly.",
)
An explicit kirocrew update is the supported way a source install updates; a
boot-time automatic apply is not part of the update architecture, so do not
reintroduce one by cron on a layout that has no self-update engine.
Limitations
- BOTH
kirocrew restartANDkirocrew updateare blocked when run directly from an agent session, by the self-protection argv floor (it reads the command's argv, so mentioning the words in a path or a grep pattern is not blocked, and there is no opt-out). - A policy-defined update provider, where configured, owns updating the host and there is no fallback:
kirocrew updateexits 1 if it fails. Report that failure rather than working around it. - Because the agent shell cannot run them, an update must be applied either by the user manually, or scheduled server-side (a cron job runs outside the shell-tool filter). After an update, restart via the gateway-restart skill.
- After an update + restart, the resuming session runs the new code.
Usage
User asks "am I up to date?" or "check for updates"
- Run
kirocrew --versionto show the current version - Compare it against that layout's own source of truth (upstream for a git checkout, the release feed for a wheel install, the app's updater for desktop)
- Report findings
- If an update is available, offer to apply it and offer to set up automatic updates
User asks "update yourself"
- Check the current version first
- If an update is available, apply it (the agent shell cannot run
kirocrew updatedirectly — schedule it server-side via cron, or ask the user to run it) - Inform the user that a gateway restart is needed for the new version to take effect
- Offer to schedule the restart via a cron (per the gateway-restart skill) or ask the user to run it manually
User asks "keep yourself updated" or "auto-update"
- Look up the user's timezone from their Slack profile (
read_slack_profile) - Pick a random weekday and business-hour time; present for approval
- Create a recurring cron with the user's timezone
- Offer two modes:
- Notify only — check and report during business hours, user applies manually
- Auto-apply — apply and restart automatically (suggest off-hours for this mode)