Skip to content

The upgrade model

lightcone-cli ships in two parts that upgrade on their own schedules. This page explains how they stay compatible and what to do when they drift.

Two independent channels

The toolchain has two moving parts. They travel on separate channels.

  • The lc CLI upgrades through uv (or pip). You run uv tool upgrade lightcone-cli when you want a newer CLI.
  • The lightcone plugin — the skills, hooks, and the lc-extractor subagent — upgrades through the Claude Code marketplace. Claude Code refreshes it on its own.

Neither channel may assume the other has moved. A machine can carry a new CLI with an old plugin, or an old CLI with a new plugin, in any order. The design target is loose coupling with graceful degradation in both directions. A version gap must degrade, never break.

This is the same principle the report layer already follows. The MyST report references analysis elements by path. When a referenced element is missing, the reference degrades to plain text instead of failing the build. The upgrade model applies that pattern to the CLI/plugin boundary.

Skew is detected, not prevented

The two channels will sometimes drift. We do not try to prevent that. We detect it and tell you how to heal it.

  • The version handshake. The plugin's SessionStart hook runs lc compat. That command prints a small JSON object — the CLI version, the minimum plugin version the CLI expects, and the plugin name. The plugin compares its own version to that floor. On skew it prints one warning line with the exact heal command. The session then continues. Skew warns; it never blocks.

  • The retroactive case. The handshake only helps plugins new enough to run it. Plugins built before the handshake existed cannot warn about themselves. The lc hook stub covers them. Older plugins still call lc hook pretool from a PreToolUse hook. The stub accepts any arguments, exits 0, and prints a one-line deprecation notice to stderr. Without it, the removed subcommand would exit non-zero, which Claude Code reads as "block this tool call" — and every session would wedge. The stub is a bridge, not a fixture. It is kept until the next breaking release, then dropped.

Layout migrations are convergent lc init

Some upgrades change what a project directory should contain — a new config file, a new integration entry, a moved template. These layout migrations are handled by lc init, which is convergent.

  • It is idempotent. Run it as many times as you like.
  • It reports what it added versus what it skipped.
  • It is safe anywhere. In a fresh directory it scaffolds a new project. In an existing ASTRA project it layers on only the missing integration bits and never touches astra.yaml.

The move to the marketplace plugin is the motivating example. Projects created before the plugin existed carry no marketplace registration. To bring one onto the plugin, run lc init once inside it:

cd path/to/existing-project
lc init

It adds the .claude/ marketplace registration, the .lightcone/ state, the results/ directory, and the MyST report — skipping whatever is already there. Run it again and it reports "Nothing to do."