Skip to content

feat(install): user-level symlink install — stop copying the engine into projects - #15

Merged
kostua16 merged 3 commits into
mainfrom
claude/setup-command-org-37b6c9
Jul 15, 2026
Merged

feat(install): user-level symlink install — stop copying the engine into projects#15
kostua16 merged 3 commits into
mainfrom
claude/setup-command-org-37b6c9

Conversation

@kostua16

Copy link
Copy Markdown
Owner

What

Replaces the per-project engine install with a user-level symlink install. The pipeline commands now auto-create (and self-repair) symlinks in ~/.claude/workflows/ pointing at the plugin's ${CLAUDE_PLUGIN_ROOT}/workflows/… files — nothing is copied into consuming projects anymore, plugin updates propagate instantly through the link, and engine-version drift becomes structurally impossible. Where symlinks are unavailable (e.g. Windows without developer mode) the same preflight falls back to a user-level copy that auto-re-syncs on version drift.

Why

The old /setup flow copied the 340KB generated engine bundle (+2 docs) into every project's .claude/workflows/, required a manual re-run after every plugin update, and polluted consumer repos with derived files. The Workflow tool also resolves user-level ~/.claude/workflows/ (see docs/dynamic-workflows.md), which makes the per-project copy unnecessary.

Changes

  • commands/setup.md → doctor/repair command: diagnoses each managed target (SYMLINK-OK / STALE / DANGLING / PLAIN-COPY / MISSING), recreates the links (ln -sfn, cp fallback), ESM-validates the plugin engine (no delete-on-failure anymore), reports versions, and interactively removes legacy pre-1.5.0 project copies — which shadow the user-level engine.
  • All 7 pipeline commands carry one byte-identical self-repairing preflight (silent ln||cp repair; the old STOP + AskUserQuestion drift flow is deleted; pipeline-status's soft variant folded in). The only remaining STOP is a legacy project copy whose engine-version: differs from the plugin's.
  • Resume safety net: flushPipelineState stamps engineVersion into pipeline-state.json; the resume path logs a non-blocking skew warning and sets result._resumeEngineSkew when a newer engine hydrates older state. Pre-1.5.0 state files (no field) stay silently resumable.
  • Docs: QUICKSTART ("No project setup" + "Upgrading from ≤1.4.x" + new troubleshooting rows), both READMEs ("Why a doctor command"), engine reference docs, dist banner scriptPath, plugin.json description.
  • Tests: new tests/command-preflight.test.mjs — asserts preflight byte-identity across all 7 commands, user-level/repair markers, no project-path references outside legacy-detection lines, required Bash permissions, and setup-is-a-doctor invariants. config-and-state extended for the engineVersion stamp (and its backward-compat absence).

190 tests green; validate:build, validate:versions, validate:agents, and the ESM check all pass.

Reviewer notes

  • Spike gate before release: the design assumes the Workflow tool resolves ~/.claude/workflows/ by name and follows symlinks. This needs a one-time manual verification in a live session (3-step spike: user-level plain file → symlink → project-vs-user precedence). If symlinks turn out not to be followed, the copy fallback already wired into the preflight becomes the primary path (drop the readlink/target lines) — still zero project files.
  • Version is intentionally still 1.4.2. The bump to 1.5.0 goes through npm run release -- 1.5.0 (single bump site, rebuilds + re-pins the marketplace) after the spike passes — the dist and marketplace pin are never hand-edited.
  • The command-file rewrite was scripted against exact-match blocks to guarantee the byte-identity the new test asserts.

… symlinks

Stop copying the engine into consuming projects. The Workflow tool also
resolves user-level ~/.claude/workflows/, so the pipeline commands now
auto-create (and self-repair) symlinks there pointing at the plugin's
engine; plugin updates propagate through the link and version drift
becomes impossible. Where symlinks are unavailable the preflight falls
back to a user-level copy that re-syncs on engine-version drift.

- rewrite /setup as a doctor/repair command: diagnose links (ok/stale/
  dangling/copy/missing), recreate them, ESM-validate the plugin engine,
  and interactively remove legacy per-project copies (which shadow the
  user-level engine)
- give all 7 pipeline commands one byte-identical self-repairing
  preflight; drop the drift AskUserQuestion flow; only a stale legacy
  project copy still stops a command
- stamp engineVersion into pipeline-state.json and warn (non-blocking)
  when a resume runs a newer engine than the one that wrote the state
- update banner scriptPath, plugin description, QUICKSTART (upgrade
  note, troubleshooting), both READMEs, and the engine reference docs
- add tests/command-preflight.test.mjs (preflight byte-identity, user-
  level markers, no project-path refs outside legacy detection) and
  extend config-and-state tests for the engineVersion stamp
Comment thread plugins/feature-workflows/commands/setup.md Outdated
@kilo-code-bot

kilo-code-bot Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Files Reviewed (8 files — incremental)
  • plugins/feature-workflows/commands/design-feature.md
  • plugins/feature-workflows/commands/extract-design.md
  • plugins/feature-workflows/commands/feature-pipeline.md
  • plugins/feature-workflows/commands/implement-feature.md
  • plugins/feature-workflows/commands/pipeline-status.md
  • plugins/feature-workflows/commands/review-design.md
  • plugins/feature-workflows/commands/tune-feature.md
  • tests/command-preflight.test.mjs

Resolved: The SUGGESTION about Bash(mktemp:*) missing from allowed-tools has been addressed in 705bb75 — all 7 pipeline commands now grant both Bash(mktemp:*) and Bash(rm:*), and the test asserts both.

Previous Review Summaries (2 snapshots, latest commit 12619ca)

Current summary above is authoritative. Previous snapshots are kept for context only.

Previous review (commit 12619ca)

Status: 1 Issue Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 0
SUGGESTION 1
Issue Details (click to expand)

SUGGESTION

File Line Issue
plugins/feature-workflows/commands/design-feature.md 4 Bash(mktemp:*) missing from allowed-tools in all 7 pipeline commands — symlink capability preflight check uses mktemp -d but the permission is not granted
Files Reviewed (11 files — incremental)
  • docs/QUICKSTART.md
  • plugins/feature-workflows/README.md
  • plugins/feature-workflows/commands/design-feature.md - 1 issue
  • plugins/feature-workflows/commands/extract-design.md
  • plugins/feature-workflows/commands/feature-pipeline.md
  • plugins/feature-workflows/commands/implement-feature.md
  • plugins/feature-workflows/commands/pipeline-status.md
  • plugins/feature-workflows/commands/review-design.md
  • plugins/feature-workflows/commands/setup.md
  • plugins/feature-workflows/commands/tune-feature.md
  • tests/command-preflight.test.mjs

Previous issue resolved: The WARNING about bare ln -sfn in setup.md lacking a || cp fallback has been fully addressed in commit 12619ca — setup.md now carries the same byte-identical three-tier (ln → powershell → cp) repair block as the pipeline preflights.

Fix these issues in Kilo Cloud

Previous review (commit ee93964)

Status: 1 Issue Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 1
SUGGESTION 0
Issue Details (click to expand)

WARNING

File Line Issue
plugins/feature-workflows/commands/setup.md 30 Repair ln -sfn commands lack `
Files Reviewed (23 files)
  • .remember/remember.md
  • README.md
  • docs/QUICKSTART.md
  • plugins/feature-workflows/.claude-plugin/plugin.json
  • plugins/feature-workflows/README.md
  • plugins/feature-workflows/commands/design-feature.md
  • plugins/feature-workflows/commands/extract-design.md
  • plugins/feature-workflows/commands/feature-pipeline.md
  • plugins/feature-workflows/commands/implement-feature.md
  • plugins/feature-workflows/commands/pipeline-status.md
  • plugins/feature-workflows/commands/review-design.md
  • plugins/feature-workflows/commands/setup.md - 1 issue
  • plugins/feature-workflows/commands/tune-feature.md
  • plugins/feature-workflows/workflows/docs/feature-pipeline-documentation.md
  • plugins/feature-workflows/workflows/feature-pipeline.js
  • plugins/feature-workflows/workflows/feature-pipeline.md
  • plugins/feature-workflows/workflows/src/main.mjs
  • plugins/feature-workflows/workflows/src/state.mjs
  • scripts/build-workflows.mjs
  • scripts/validate-plugin-versions.mjs
  • tests/command-preflight.test.mjs
  • tests/config-and-state.test.mjs
  • tests/harness.mjs

Fix these issues in Kilo Cloud


Reviewed by deepseek-v4-pro · Input: 28.7K · Output: 5.6K · Cached: 180.5K

Review guidance: REVIEW.md from base branch main

…S detection and three-tier symlink/copy fallback

The setup command and all 7 pipeline-command preflights now support Windows
alongside Linux/macOS. Previously the repair block used a bare 'ln -sfn' with the
cp fallback described only in prose — an agent executing the block literally
failed on Windows without symlink privilege (the exact issue raised in the PR #15
review), and there was no OS or symlink-capability detection on the install
surface.

The auto-repair is now a three-tier cascade applied byte-identically across all
seven pipeline commands (the byte-identity test stays green):

  1. ln -sfn           — Linux/macOS + Git-Bash on Windows with Developer Mode
  2. powershell New-Item -ItemType SymbolicLink — native Windows attempt, tried
     only where ln fails but symlink privilege exists; $ErrorActionPreference='Stop'
     makes any failure fall through to the copy tier
  3. cp                — universal fallback (Windows without Developer Mode),
     auto-resyncs on engine-version drift

setup.md becomes a cross-platform doctor: it reports the OS (uname -s) and
symlink capability up front, runs the same three-tier repair, re-checks which
mode took effect, and gives explicit Windows Developer-Mode guidance.

- preflight adds OS + symlink-capability probes; all 7 commands gain
  Bash(uname:*) and Bash(powershell:*) permissions
- setup.md: bare ln block replaced with the inline three-tier block (closes the
  review thread on setup.md:30) + OS/symlink diagnostics + Windows guidance
- command-preflight.test.mjs: new markers (uname/powershell/New-Item), two new
  required permissions, and setup-doctor assertions that the powershell + cp
  fallback tiers are inline (regression guard for the review fix); the
  project-path filter now also treats $USERPROFILE/.claude/workflows as user-level
- QUICKSTART troubleshooting + plugin README note the three-tier repair

Validated on a Windows Git Bash host without Developer Mode: both the ln and
powershell tiers are rejected and the cp fallback lands cleanly (exit 0).
189 tests green across 12 files; validate:versions OK. (The pre-existing
build-drift.test.mjs failure in schemas.mjs is unrelated and reproduces on clean
main.)
Comment thread plugins/feature-workflows/commands/design-feature.md Outdated
…ability probe

The symlink-capability preflight added in 12619ca runs
'd=$(mktemp -d); ln -s "$d" "$d/t" ...; rm -rf "$d"', but mktemp and rm were
not in the 7 pipeline commands' allowed-tools — only ln was (already granted). If
Claude Code enforces allowed-tools against inline !-preflight executions, the probe
would fail on every invocation. setup.md is unaffected (unrestricted Bash).

- all 7 pipeline commands: append Bash(mktemp:*) and Bash(rm:*)
- command-preflight.test.mjs: add both to the required-permission set (regression guard)

Addresses the review thread on design-feature.md:4. 189 tests green.
@kostua16
kostua16 merged commit 0ca968e into main Jul 15, 2026
3 checks passed
@kostua16
kostua16 deleted the claude/setup-command-org-37b6c9 branch July 15, 2026 22:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant