@kurokeita/add-skill 2.6.1 → 2.6.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/dist/bin/cli.js CHANGED
@@ -1690,7 +1690,7 @@ async function remove(type, options) {
1690
1690
  }
1691
1691
 
1692
1692
  // package.json
1693
- var version = "2.6.1";
1693
+ var version = "2.6.2";
1694
1694
 
1695
1695
  // bin/cli.ts
1696
1696
  var program = new Command();
@@ -58,6 +58,8 @@ The box is left out entirely when it has no rows: detached HEAD, a remote that i
58
58
 
59
59
  Build **two parallel arrays** per box: one holding the plain text, one holding the same text wrapped in color escapes. Measure padding from the plain array only — measuring the colored string counts the escape bytes and destroys alignment.
60
60
 
61
+ Widths are **terminal columns**, not characters. Emoji and CJK take two columns, so a commit subject with `šŸ“` pushes its row one column past the border when measured with `${#str}`. The bash variant measures every plain row in one `perl -CS` call: per grapheme cluster (`\X`), 2 columns when it holds an East Asian Wide or Fullwidth character or `U+FE0F`, else 1. Without perl it falls back to character counts.
62
+
61
63
  ### UTF-8 locale guard (bash only)
62
64
 
63
65
  `${#str}` counts **bytes**, not characters, unless the shell is in a UTF-8 locale. The rows contain `↑`, `↓` and `…`, so under `LC_ALL=C` every such row is padded 2 characters short. Guard at the top of the script with a subprocess-free probe:
@@ -255,7 +257,7 @@ The input schema depends on the platform:
255
257
 
256
258
  ## Linux / macOS Implementation
257
259
 
258
- Write `statusline-command.sh` (chmod +x) to the targeted platform directory. Pure bash + `jq` — no Python. `jq` must be installed; if missing, the script prints a one-line hint and exits 0.
260
+ Write `statusline-command.sh` (chmod +x) to the targeted platform directory. Pure bash + `jq` — no Python. `jq` must be installed; if missing, the script prints a one-line hint and exits 0. `perl`, which macOS and most Linux systems ship, measures row widths; without it the boxes still render but misalign on emoji.
259
261
 
260
262
  JSON parsing rules:
261
263
 
@@ -711,18 +713,30 @@ if (( work_rows )); then
711
713
  fi
712
714
 
713
715
  # Width comes from the plain rows; the parallel colored rows carry ANSI escapes
714
- # that would otherwise be counted as visible characters. Arrays are passed
715
- # positionally because bash 3.2 (macOS) has no `local -n` nameref.
716
+ # that would otherwise be counted as visible characters. ${#s} counts characters,
717
+ # but emoji and CJK take two terminal columns, so one perl call measures every
718
+ # row by grapheme. Each box holds `rows` rows, so box N's widths start at N*rows.
719
+ all=("${repo_plain[@]}" "${sess_plain[@]}")
720
+ # An empty array trips `set -u` on bash 3.2, so only expand it when it has rows.
721
+ (( work_rows )) && all+=("${work_plain[@]}")
722
+ cols=()
723
+ while IFS= read -r n; do cols+=("$n"); done < <(printf '%s\n' "${all[@]}" \
724
+ | perl -CS -ne 'chomp; my $w = 0; $w += /[\p{Ea=W}\p{Ea=F}\x{FE0F}]/ ? 2 : 1 for /\X/g; print "$w\n"' 2>/dev/null)
725
+ # Without perl (or its Unicode tables) fall back to character counts.
726
+ if (( ${#cols[@]} != ${#all[@]} )); then
727
+ cols=(); for s in "${all[@]}"; do cols+=("${#s}"); done
728
+ fi
729
+
730
+ # Widths are passed positionally because bash 3.2 (macOS) has no `local -n` nameref.
716
731
  box_width() {
717
732
  local title="$1"; shift
718
- local w=$(( ${#title} + 2 )) s
719
- for s in "$@"; do (( ${#s} > w )) && w=${#s}; done
733
+ local w=$(( ${#title} + 2 )) n
734
+ for n in "$@"; do (( n > w )) && w=$n; done
720
735
  printf '%d' "$w"
721
736
  }
722
- rw=$(box_width "repo" "${repo_plain[@]}")
723
- sw=$(box_width "session" "${sess_plain[@]}")
724
- # An empty array trips `set -u` on bash 3.2, so only expand it when it has rows.
725
- (( work_rows )) && ww=$(box_width "work" "${work_plain[@]}")
737
+ rw=$(box_width "repo" "${cols[@]:0:rows}")
738
+ sw=$(box_width "session" "${cols[@]:rows:rows}")
739
+ (( work_rows )) && ww=$(box_width "work" "${cols[@]:2*rows:rows}")
726
740
 
727
741
  box_top() {
728
742
  local title="$1" w="$2"
@@ -733,18 +747,18 @@ box_bottom() {
733
747
  printf '%sā•°%s╯%s' "$C_BOX" "$(repeat_char '─' $(( $1 + 2 )))" "$RESET"
734
748
  }
735
749
  box_row() {
736
- local colored="$1" w="$2" plain="$3"
750
+ local colored="$1" w="$2" used="$3"
737
751
  printf '%s│%s %s%s %s│%s' "$C_BOX" "$RESET" "$colored" \
738
- "$(repeat_char ' ' $(( w - ${#plain} )))" "$C_BOX" "$RESET"
752
+ "$(repeat_char ' ' $(( w - used )))" "$C_BOX" "$RESET"
739
753
  }
740
754
 
741
755
  out="$(box_top repo "$rw") $(box_top session "$sw")"
742
756
  (( work_rows )) && out+=" $(box_top work "$ww")"
743
757
  for (( i = 0; i < rows; i++ )); do
744
758
  out+=$'\n'
745
- out+="$(box_row "${repo_color[$i]}" "$rw" "${repo_plain[$i]}")"
746
- out+=" $(box_row "${sess_color[$i]}" "$sw" "${sess_plain[$i]}")"
747
- (( work_rows )) && out+=" $(box_row "${work_color[$i]}" "$ww" "${work_plain[$i]}")"
759
+ out+="$(box_row "${repo_color[$i]}" "$rw" "${cols[$i]}")"
760
+ out+=" $(box_row "${sess_color[$i]}" "$sw" "${cols[rows + i]}")"
761
+ (( work_rows )) && out+=" $(box_row "${work_color[$i]}" "$ww" "${cols[2 * rows + i]}")"
748
762
  done
749
763
  out+=$'\n'"$(box_bottom "$rw") $(box_bottom "$sw")"
750
764
  (( work_rows )) && out+=" $(box_bottom "$ww")"
@@ -1271,7 +1285,8 @@ It needs the same `gh` or `az` login as the work box. It fetches by itself and d
1271
1285
 
1272
1286
  After installing, pipe a fake payload into the script and confirm:
1273
1287
 
1274
- - **Every rendered line has the same character count** — this is the alignment check, and it fails first when width is measured off a colored string or the locale is not UTF-8.
1288
+ - **Every rendered line has the same width in terminal columns** — this is the alignment check, and it fails first when width is measured off a colored string, by characters instead of columns, or the locale is not UTF-8.
1289
+ - A last commit whose subject holds an emoji such as `šŸ“` or `ā™»ļø` still passes the width check.
1275
1290
  - Both boxes show the same number of rows, framed top and bottom on the same lines.
1276
1291
  - Inside a repo the repo box shows 4 rows: full cwd, branch, working-tree state, last commit.
1277
1292
  - Staging a deletion (`git rm`) renders `-N`, not `+N`.
@@ -1309,12 +1324,12 @@ Assert equal line widths mechanically:
1309
1324
  ```bash
1310
1325
  printf '{"cwd":"%s","transcript_path":"/tmp/statusline-smoke/transcript.jsonl","model":{"display_name":"Opus 4.7"},"context_window":{"used_percentage":42}}' "$PWD" \
1311
1326
  | bash ~/.claude/statusline-command.sh \
1312
- | perl -CSD -pe 's/\e\[[0-9;]*m//g' \
1313
- | perl -CSD -ne 'chomp; print length($_), "\n"' \
1327
+ | perl -CSD -pe 's/\e\[[0-9;]*m//g; s/\e\]8;;[^\a]*\a//g' \
1328
+ | perl -CSD -ne 'chomp; my $w = 0; $w += /[\p{Ea=W}\p{Ea=F}\x{FE0F}]/ ? 2 : 1 for /\X/g; print "$w\n"' \
1314
1329
  | sort -u
1315
1330
  ```
1316
1331
 
1317
- That must print exactly one number. Re-run the same pipeline wrapped in `env -i PATH="$PATH" HOME="$HOME" bash -c '...'` to confirm the locale guard holds with no `LANG` set.
1332
+ That must print exactly one number. Counting with `length` instead would pass on a row an emoji pushes out of line. Re-run the same pipeline wrapped in `env -i PATH="$PATH" HOME="$HOME" bash -c '...'` to confirm the locale guard holds with no `LANG` set.
1318
1333
 
1319
1334
  Work box from a fixture cache, run inside a GitHub or Azure DevOps repo. The fresh `.at` stamp stops a network refresh, so this stays offline:
1320
1335
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kurokeita/add-skill",
3
- "version": "2.6.1",
3
+ "version": "2.6.2",
4
4
  "description": "CLI to install AI agent skills to various platforms",
5
5
  "type": "module",
6
6
  "bin": {