@windyroad/architect 0.21.4-preview.1104 → 0.21.4-preview.1105

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@windyroad/architect",
3
- "version": "0.21.4-preview.1104",
3
+ "version": "0.21.4-preview.1105",
4
4
  "description": "Architecture decision enforcement for AI coding agents",
5
5
  "bin": {
6
6
  "windyroad-architect": "./bin/install.mjs"
@@ -147,15 +147,18 @@ get_section() {
147
147
  ' "$file"
148
148
  }
149
149
 
150
- # Extract the "Chosen option:" line from the Decision Outcome section.
150
+ # Extract the first "Chosen option:" paragraph from the Decision Outcome section.
151
151
  # Matches the common MADR shapes:
152
152
  # Chosen option: **"X"**, because Y.
153
153
  # Chosen option: X, because Y.
154
154
  # Chosen: X.
155
155
  get_chosen() {
156
156
  get_section "$1" "Decision Outcome" \
157
- | awk '/^Chosen/ { print; exit }' \
158
- | head -1
157
+ | awk '
158
+ /^Chosen/ { in_chosen = 1 }
159
+ in_chosen && NF == 0 { exit }
160
+ in_chosen { print }
161
+ '
159
162
  }
160
163
 
161
164
  # Extract top-level bullet lines (`- ...`) from a section. Skips nested
@@ -229,16 +232,27 @@ oneline() {
229
232
  tr '\n\r' ' ' | tr -s ' ' | sed 's/^ *//; s/ *$//'
230
233
  }
231
234
 
232
- # Truncate a string to N chars + ellipsis if longer. Avoids slicing inside
233
- # a markdown emphasis pair (e.g. `**text**`) if the truncation would land
234
- # inside `**...**`, round back to before the opening pair.
235
+ # Truncate a string to N chars + ellipsis if longer. Avoids slicing a `**`
236
+ # marker in half and closes emphasis when truncation lands inside it.
235
237
  truncate_with_ellipsis() {
236
- local s="$1" n="$2"
238
+ local s="$1" n="$2" truncated remainder pairs=0
237
239
  if [ "${#s}" -le "$n" ]; then
238
240
  printf '%s' "$s"
239
241
  return
240
242
  fi
241
- printf '%s' "${s:0:n}..."
243
+ truncated="${s:0:n}"
244
+ if [[ "$truncated" == *\* && "${s:n:1}" == "*" ]]; then
245
+ truncated="${truncated%?}"
246
+ fi
247
+ remainder="$truncated"
248
+ while [[ "$remainder" == *"**"* ]]; do
249
+ remainder="${remainder#*"**"}"
250
+ pairs=$((pairs + 1))
251
+ done
252
+ if [ $((pairs % 2)) -ne 0 ]; then
253
+ truncated="${truncated}**"
254
+ fi
255
+ printf '%s' "${truncated}..."
242
256
  }
243
257
 
244
258
  # --- Per-ADR entry emitter -------------------------------------------------
@@ -264,8 +278,7 @@ emit_entry() {
264
278
 
265
279
  # Chosen-option line — truncate to a comfortable summary length.
266
280
  chosen=$(get_chosen "$file" | strip_links | oneline)
267
- if ! chosen=$(printf '%s' "$chosen" \
268
- | awk -v n=240 '{ if (length($0) > n) print substr($0,1,n) "..."; else print }' \
281
+ if ! chosen=$(truncate_with_ellipsis "$chosen" 240 \
269
282
  | iconv -f UTF-8 -t UTF-8 -c); then
270
283
  echo "generate-decisions-compendium: failed to truncate chosen text safely for $file" >&2
271
284
  return 1