Skip to content
Development
Command

/update

Sync this project with the current LETS release - a self-driving one-step loop; self-heals .env + project rules (rules deferred while the plugin is behind), reports the hook-maintained global rules, installs the binary and refreshes the plugin in-session on approval, and points

From plugin
lets-workflow
1726 skills15 agents26 commands
> /plugin marketplace add restarter/lets-workflow
> /plugin install lets@lets-workflow

Command definition

update.md
description: Sync this project with the current LETS release - a self-driving one-step loop; self-heals .env + project rules (rules deferred while the plugin is behind), reports the hook-maintained global rules, installs the binary and refreshes the plugin in-session on approval, and points at the single next action until everything is on the same version

Update LETS

Sync the drift-able LETS artifacts (four core + two optional: the user-scope global rules and the active `tracker-<name>.md` adapter) with the current release. Bridges to `lets update --json` (Go binary): auto-syncs `.lets/.env` (header refresh when `LETS_ENV_VERSION` is stale), `.claude/rules/lets-rules.md` (re-copy when outdated/missing - but **deferred** when the plugin is behind, so rules never sync to a stale plugin), and reports `~/.claude/rules/lets-rules.md` (the global rules - maintained by the session hook as a cache of the running plugin, only reported here, never written; the `user-rules` row appears only when that file exists). It then computes a single ordered `next_action` (the self-driving loop): the binary and plugin steps can be run in-session (approval-gated), and a fully-synced machine prints `✓ Everything on vX.Y.Z`.

> **MANDATORY:** Execute every Step's bash block **literally as written**. Do not substitute output from earlier `ls`/`cat` in this conversation - `.env` and other dotfiles are invisible to plain `ls`. The `test -f` checks below ARE the contract.

Difference from `/lets:init`: `/lets:init` is first-time setup (it also asks config questions and sets up the statusline + beads). `/lets:update` only syncs what a new release changes - it asks no project-configuration questions and never touches `settings.json` or beads; the binary install and the on-disk plugin refresh each run only after an approval prompt.

Step 1: Pre-checks

command -v lets >/dev/null 2>&1 || { echo "NO_LETS_BINARY"; exit 0; }
LETS_PROJECT_ROOT=$(git rev-parse --show-toplevel 2>/dev/null) || { echo "NOT_GIT_REPO"; exit 0; }
test -f "$LETS_PROJECT_ROOT/.lets/.env" && echo "ENV_EXISTS" || echo "ENV_ABSENT"

Branch on output:

  • `NO_LETS_BINARY` → tell user: "`lets` binary not found on `$PATH`. Install it — `! curl -fsSL https://raw.githubusercontent.com/restarter/lets-workflow/main/scripts/install.sh | bash` (the leading `!` runs it in this session; or the same command without `!` in a terminal). See the README → Quick Start." NO LETS box. STOP.
  • `NOT_GIT_REPO` → tell user: "Not a git repository. `/lets:update` runs inside a LETS project." NO LETS box. STOP.
  • `ENV_ABSENT` → not initialized. Tell user: "This project hasn't been set up - run `/lets:init` first." Then still run Step 2 (it reports `.env: not-initialized` plus the binary/plugin status, which is useful). In Step 4 show the LETS box pointing at `/lets:init` instead of `/lets:start`.
  • `ENV_EXISTS` → normal path. Continue to Step 2.

(No bash worktree pre-check here - `lets update` detects a worktree itself: the project rows (`.env`, `rules`, `tracker-rules`) come back `skipped` naming the main checkout, the binary / plugin / global-rules rows are checked as usual, and `next_action` names the main checkout.)

Step 2: Exec

LETS_PROJECT_ROOT=$(git rev-parse --show-toplevel)
lets update --json --plugin-root="${CLAUDE_PLUGIN_ROOT}"

Capture stdout (single JSON object). On network trouble the binary degrades gracefully: `binary`/`plugin` come back `unknown` with an explanatory `detail`; it never fails the run for that. In a git worktree the run succeeds: project rows are `skipped` (`.claude/` isn't shared into worktrees) and `next_action.kind == "main-checkout"` names the main checkout (`main_checkout`).

Step 3: Render

Parse JSON.

`lets update` is a **self-driving loop**: each run advances ONE step and tells you the single next thing to do. Do that one thing, re-run `/lets:update`, repeat until it prints `✓ Everything on vX.Y.Z`. NEVER suggest a re-run for `reload` (a newer plugin already installed), `new-session` or `user-rules` - a re-run before that step reports the same.

1. **Artifact table** - one line per `artifacts[]` entry: `<name> v<current_version> <status> (latest v<latest_version>) - <detail>` Omit `(latest …)` / `- <detail>` when those fields are empty; print `?` for an empty `current_version` (`dev` prints as-is, not `vdev`). **When `next_action.kind == "done"`, SKIP the table entirely** - print only the `✓ Everything on v<next_action.version>` line (no status matrix on a fully-synced machine). Status vocabulary: `.env`/`rules` report `in-sync` - they track a *local* source (the `lets` binary for `.env`, the plugin for `rules`), not the latest release. `binary`/`plugin` report `up-to-date`/`outdated` against the *latest release*. So `.env` and `rules` can sit at different versions and both be `in-sync` - expected, not a contradiction; their `detail` names what they track and flags "itself behind latest v…" when that source is itself stale. `rules`/`tracker-rules` may report `deferred` - the plugin is behind, so syncing the rules now would write a stale lower version; the row's `detail` explains it and `next_action` steers you to the plugin step. Not an error, not a contradiction. `user-rules` (only present when `~/.claude/rules/lets-rules.md` exists) is informational - the session hook owns that file, update never writes it: `delegated` = verified cache of the installed plugin (healthy); `unknown` = not recorded yet / edited / stale / not verified - relay the `detail`. `skipped` (worktree run) = the project row was not checked here; its `detail` names the main checkout - not up to date, not an error. `rules` may also report `delegated` (`LETS_RULES_SCOPE=user`): the project deliberately has no own copy and lives on the global rules - a healthy state, not an error. `tracker-rules` (present when `LETS_TRACKER` names a shipped adapter, OR a user-authored/unshipped adapter with an installed `.clau

Read more
@restarter
Ships withlets-workflow

A development workflow plugin for Claude Code Stop babysitting your AI. Start shipping with it.

1725 skills15 agents
Get the whole plugin

Stars on GitHub

Momentum

stars in total
17
Star history of restarter/lets-workflow on GitHub, a chart by star-history.com

Other commands on lets-workflow.

backlog

backlog

Command

Backlog review and cleanup - multi-agent backlog review, quick no-agent pulse (--fast), or interactive triage cleanup

end

end

Command

End a work session - a settlement pass that reconciles uncommitted / unpushed work + session context into git, the tracker, and a…

execute

execute

Command

Execute implementation plan from /lets:plan - inline in native plan mode, or delegated to named implementer subagents you review…

More commands from other plugins.

build
Auto-invoked

build

Command

Implement tasks incrementally — build, test, verify, commit. Add "auto" to run the whole plan in one approved pass.

@addyosmani@addyosmaniInstall Command