-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinstall.sh
More file actions
executable file
·106 lines (95 loc) · 5.48 KB
/
Copy pathinstall.sh
File metadata and controls
executable file
·106 lines (95 loc) · 5.48 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#!/usr/bin/env bash
set -euo pipefail
# install.sh — generate the /yshifu Claude Code command from this repo.
#
# Reproducibly writes ~/.claude/commands/yshifu.md from templates/yshifu-command.md,
# substituting the control-plane repo's own location for the {{YSTACK_ROOT}}
# placeholder — so the command never hardcodes ~/git/ystack and works from
# wherever this clone lives. Idempotent: re-running yields the same file; if an
# existing yshifu.md differs, it is backed up to yshifu.md.bak before overwriting.
# Resolve the repo root from this script's own location, following symlinks so
# the derived path is the real clone directory even if install.sh is symlinked.
script_path="$0"
while [ -L "$script_path" ]; do
link_target="$(readlink "$script_path")"
case "$link_target" in
/*) script_path="$link_target" ;;
*) script_path="$(dirname "$script_path")/$link_target" ;;
esac
done
repo_root="$(cd "$(dirname "$script_path")/.." && pwd -P)"
template="$repo_root/templates/yshifu-command.md"
commands_dir="$HOME/.claude/commands"
target="$commands_dir/yshifu.md"
legacy_faber_target="$commands_dir/faber.md" # legacy retired command; never mutate here
if [ ! -f "$template" ]; then
echo "error: template not found: $template" >&2
exit 1
fi
# Render the template with the resolved repo path. Build the content first so we
# can compare against any existing file before touching it (idempotency + backup).
# Use bash literal string replacement (not sed) so paths containing sed
# metacharacters (&, #, /, spaces) substitute correctly — bash ${var//pat/repl}
# treats the replacement literally.
template_contents="$(cat "$template")"
rendered="${template_contents//'{{YSTACK_ROOT}}'/$repo_root}"
mkdir -p "$commands_dir"
if [ -f "$target" ]; then
if [ "$rendered" = "$(cat "$target")" ]; then
echo "Already up to date: $target"
action="unchanged"
else
cp "$target" "$target.bak"
printf '%s\n' "$rendered" >"$target"
echo "Updated (backed up old version to $target.bak): $target"
action="updated"
fi
else
printf '%s\n' "$rendered" >"$target"
echo "Created: $target"
action="created"
fi
# Retirement is deliberately non-destructive. Warn about the exact old entrypoint,
# including a dangling symlink, but never read, back up, overwrite, or delete it.
if [ -e "$legacy_faber_target" ] || [ -L "$legacy_faber_target" ]; then # legacy residual
echo "WARNING: retired legacy /faber command remains at $legacy_faber_target" >&2
echo " /yshifu was updated; inspect and move the retired file explicitly" >&2
echo " using RESTORE.md's rollback-safe cleanup. This installer leaves it untouched." >&2
fi
cat <<EOF
/yshifu command ${action}.
command file: $target
repo path: $repo_root (derived from this script's location)
Next steps:
1. Make sure your target repo has CI that runs on PRs (the hard merge gate) — the one real
precondition. You no longer have to wire it yourself: if the repo has no PR CI, yshifu can
BOOTSTRAP it for you at first contact (it scaffolds a pull_request workflow from your
toolchain as the first 'add PR CI' issue). That CI-bootstrap PR is HUMAN-MERGE-ONLY: yshifu
classifies it as such and does NOT run merge-pr.sh on it at all — a same-repo bootstrap PR
that adds the workflow can run it on its own PR and self-report green, so the human, not the
tooling, is the gate — YOU approve and merge it by hand. Or wire it yourself. The loop
labels + readiness pre-flight are handled by yshifu on first use (see step 3), so you do NOT
need to run setup-target-repo.sh / doctor.sh by hand — they remain available as an
optional/advanced pre-flight. A target CLAUDE.md is OPTIONAL: the coder auto-discovers the
install/lint/build/test commands from the repo's CI workflows and standard manifests
(see the discovery order in $repo_root/routines/coder.md). A filled-in CLAUDE.md
"Stack & commands" ($repo_root/templates/target-CLAUDE.md) is an OPTIONAL override —
add one only to pin or disambiguate a non-standard toolchain.
2. Set your own north star PER TARGET — in each target repo, CREATE + commit + approve
.ystack/north-star.md yourself: copy $repo_root/templates/.ystack/north-star.md into
the target as .ystack/north-star.md, replace the placeholder, remove the
'<!-- ystack-shipped-default -->' marker, then commit it (the gate reads the target's
COMMITTED north star; an uncommitted local edit does not authorize proactive work, and
setup-target-repo.sh only creates the loop labels — it does NOT seed this file). The
shipped approval note is the prior owner's history, not a token that approves the goal
for you. (ystack-self is its own target: when you run against this control-plane repo
it uses its own root $repo_root/NORTH_STAR.md.)
3. Open Claude Code in a target repo and run /yshifu to summon the manager. On its first
loop action this session, yshifu auto-bootstraps the repo — derives <owner>/<repo> from
the cwd, creates/reconciles the loop labels, and runs the read-only readiness self-check
— so adoption is 'cd repo -> /yshifu -> go'. Then, in that session, explicitly approve
your north star to yshifu — this is the root authorization that unlocks proactive
autonomous mode (approve it with yshifu, not by editing the file). Until it's set +
approved, yshifu acts only on issues you direct (one-liner -> approved intake -> G1 intent
-> G2 spec-with-risk -> plan gate -> ready -> claimed -> coder).
EOF