forge-cw 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/cw/cw CHANGED
@@ -155,6 +155,29 @@ _link_account_skills() {
155
155
  done
156
156
  }
157
157
 
158
+ # links global and account skills into the config dir the harness reads, since CLAUDE_CONFIG_DIR hides ~/.claude/skills
159
+ _link_shared_skills() {
160
+ local harness_dir="${1:?Usage: _link_shared_skills <harness_dir> <acct_root>}" acct_root="${2:?}"
161
+ harness_supports skills || return 0
162
+ local target_dir="$harness_dir/skills" link src name
163
+ mkdir -p "$target_dir" 2>/dev/null || return 0
164
+ # drops links whose skill was removed from its source
165
+ for link in "$target_dir"/*; do
166
+ [[ -L "$link" && ! -e "$link" ]] && rm -f "$link"
167
+ done
168
+ local sources=("$HOME/.claude/skills")
169
+ [[ "$acct_root/skills" != "$target_dir" ]] && sources=("$acct_root/skills" "${sources[@]}")
170
+ for src in "${sources[@]}"; do
171
+ [[ -d "$src" && "$src" != "$target_dir" ]] || continue
172
+ for link in "$src"/*/; do
173
+ [[ -f "$link/SKILL.md" ]] || continue
174
+ name=$(basename "$link")
175
+ case "$name" in acct--*) continue ;; esac
176
+ [[ -e "$target_dir/$name" || -L "$target_dir/$name" ]] || ln -s "${link%/}" "$target_dir/$name"
177
+ done
178
+ done
179
+ }
180
+
158
181
  _get_project() {
159
182
  CW_REG="$CW_REGISTRY" CW_NAME="$1" python3 -c "
160
183
  import json, os, sys
@@ -559,10 +582,17 @@ _harness_provider_applies() {
559
582
  return 1
560
583
  }
561
584
 
585
+ # every launch sees the global skills and its account's skills
586
+ _link_harness_skills() {
587
+ [[ -n "${CW_HARNESS_DIR:-}" && -n "${CW_ACCOUNT:-}" ]] || return 0
588
+ _link_shared_skills "$CW_HARNESS_DIR" "$(_account_root "$CW_ACCOUNT")"
589
+ }
590
+
562
591
  # a driver that refuses to build a launch sets _CW_LAUNCH_REFUSED so callers can fail
563
592
  _harness_launch() {
564
593
  HARNESS_ARGV=(); HARNESS_ENV=()
565
594
  _harness_provider_applies || { _CW_LAUNCH_REFUSED=1; return 1; }
595
+ _link_harness_skills
566
596
  harness_launch || { _CW_LAUNCH_REFUSED=1; return 1; }
567
597
  _harness_exec
568
598
  }
@@ -571,6 +601,7 @@ _harness_launch() {
571
601
  _harness_resume() {
572
602
  local attempt=1 rc=1
573
603
  _harness_provider_applies || { _CW_LAUNCH_REFUSED=1; return 1; }
604
+ _link_harness_skills
574
605
  while :; do
575
606
  HARNESS_ARGV=(); HARNESS_ENV=()
576
607
  harness_resume "$attempt" || break
@@ -965,6 +996,15 @@ _account_migrate_split() {
965
996
  _account_migrate_undo() {
966
997
  local account="$1" root="$2" dry="$3"
967
998
  [[ -d "$root/claude" ]] || { _warn "Account '$account' is already flat."; return 0; }
999
+ # launches link skills into claude/skills; the skills themselves live elsewhere
1000
+ if [[ -d "$root/claude/skills" ]]; then
1001
+ if $dry; then
1002
+ _dim " would drop the skill links in claude/skills"
1003
+ else
1004
+ find "$root/claude/skills" -maxdepth 1 -type l -delete
1005
+ rmdir "$root/claude/skills" 2>/dev/null || true
1006
+ fi
1007
+ fi
968
1008
  _account_scan_dir "$root/claude"
969
1009
  local entries=(${CW_ACCOUNT_ENTRIES[@]+"${CW_ACCOUNT_ENTRIES[@]}"})
970
1010
  local entry base blocked=0