aidevops 3.8.83 → 3.8.84

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.
Files changed (4) hide show
  1. package/VERSION +1 -1
  2. package/aidevops.sh +114 -56
  3. package/package.json +1 -1
  4. package/setup.sh +1 -1
package/VERSION CHANGED
@@ -1 +1 @@
1
- 3.8.83
1
+ 3.8.84
package/aidevops.sh CHANGED
@@ -5,7 +5,7 @@
5
5
  # AI DevOps Framework CLI
6
6
  # Usage: aidevops <command> [options]
7
7
  #
8
- # Version: 3.8.83
8
+ # Version: 3.8.84
9
9
 
10
10
  set -euo pipefail
11
11
 
@@ -2592,44 +2592,118 @@ _upgrade_check_version() {
2592
2592
  fi
2593
2593
  }
2594
2594
 
2595
+ # t2434: Extract lines under "## <section>" until the next "## " header.
2596
+ # Skips ## Format block entirely (its content is documentation, not tasks).
2597
+ # Skips fenced code blocks.
2598
+ # Exact-match on the section header — no regex escaping concerns.
2599
+ _extract_todo_section() {
2600
+ local file="$1" section="$2"
2601
+ awk -v target="## $section" '
2602
+ /^## Format/ { in_format=1; next }
2603
+ in_format && /^## / { in_format=0 }
2604
+ in_format { next }
2605
+ /^```/ { in_codeblock = !in_codeblock; next }
2606
+ in_codeblock { next }
2607
+ $0 == target { found=1; next }
2608
+ found && /^## / { exit }
2609
+ found
2610
+ ' "$file" 2>/dev/null || echo ""
2611
+ }
2612
+
2613
+ # t2434: Filter stdin, removing only the literal Format-block placeholder IDs
2614
+ # (tXXX, tYYY, tZZZ). Real-world repos have historic IDs that don't follow the
2615
+ # strict t<digits> shape (e.g. "t059b", "t043-merge" from awardsapp) — we must
2616
+ # preserve those. A blocklist is safer than an allowlist here: extraction
2617
+ # already skips the Format section, so the filter is a secondary guard rather
2618
+ # than primary validation.
2619
+ _filter_todo_placeholders() {
2620
+ awk '
2621
+ !/^- \[[ x-]\] t/ { print; next }
2622
+ {
2623
+ id = $0
2624
+ sub(/^- \[[ x-]\] /, "", id)
2625
+ sub(/ .*/, "", id)
2626
+ if (id == "tXXX" || id == "tYYY" || id == "tZZZ") next
2627
+ print
2628
+ }
2629
+ '
2630
+ }
2631
+
2632
+ # t2434: Insert content_file into target_file immediately after the closing
2633
+ # "-->" of the named TOON marker block (<!--TOON:<tag>...-->).
2634
+ # Idempotent only in the sense that each call inserts once per marker; repeated
2635
+ # calls would stack insertions. Intended to be called once per tag per upgrade.
2636
+ _insert_after_toon_marker() {
2637
+ local target_file="$1" toon_tag="$2" content_file="$3"
2638
+ local temp_file="${target_file}.insert"
2639
+ local marker_open="<!--TOON:${toon_tag}"
2640
+ local in_marker=false
2641
+ while IFS= read -r line || [[ -n "$line" ]]; do
2642
+ [[ "$line" == *"$marker_open"* ]] && in_marker=true
2643
+ if [[ "$in_marker" == true && "$line" == "-->" ]]; then
2644
+ echo "$line"
2645
+ echo ""
2646
+ cat "$content_file"
2647
+ in_marker=false
2648
+ continue
2649
+ fi
2650
+ echo "$line"
2651
+ done <"$target_file" >"$temp_file"
2652
+ mv "$temp_file" "$target_file"
2653
+ }
2654
+
2655
+ # t2434: Preserve each of the 6 task sections into $workdir/<tag>.txt for
2656
+ # later re-insertion after the template is applied. Placeholder filter runs
2657
+ # per section so Format-block tXXX-style examples never reach the new file.
2658
+ _upgrade_todo_preserve_sections() {
2659
+ local todo_file="$1" workdir="$2"
2660
+ local sections=("Ready" "Backlog" "In Progress" "In Review" "Done" "Declined")
2661
+ local tags=("ready" "backlog" "in_progress" "in_review" "done" "declined")
2662
+ local i=0
2663
+ while [[ $i -lt ${#sections[@]} ]]; do
2664
+ local section="${sections[$i]}" tag="${tags[$i]}"
2665
+ local content
2666
+ content=$(_extract_todo_section "$todo_file" "$section")
2667
+ if [[ -n "$content" ]]; then
2668
+ content=$(printf '%s\n' "$content" | _filter_todo_placeholders)
2669
+ [[ -n "$content" ]] && printf '%s\n' "$content" >"$workdir/${tag}.txt"
2670
+ fi
2671
+ i=$((i + 1))
2672
+ done
2673
+ return 0
2674
+ }
2675
+
2676
+ # t2434: Re-insert preserved section content after its matching TOON marker
2677
+ # in the freshly-applied new template. Caller is responsible for counting
2678
+ # merged tasks from the final file — keeping count out of the hot loop avoids
2679
+ # subshell/arithmetic edge cases under `set -u` when content contains `GH#`-
2680
+ # style IDs that don't match a naive `t[0-9]` count pattern.
2681
+ _upgrade_todo_reinsert_sections() {
2682
+ local todo_file="$1" workdir="$2"
2683
+ local tags=("ready" "backlog" "in_progress" "in_review" "done" "declined")
2684
+ local tag content_file
2685
+ for tag in "${tags[@]}"; do
2686
+ content_file="$workdir/${tag}.txt"
2687
+ [[ -f "$content_file" && -s "$content_file" ]] || continue
2688
+ grep -q "<!--TOON:${tag}" "$todo_file" || continue
2689
+ _insert_after_toon_marker "$todo_file" "$tag" "$content_file"
2690
+ done
2691
+ return 0
2692
+ }
2693
+
2694
+ # t2434: Upgrade TODO.md to the latest TOON-enhanced template, preserving
2695
+ # tasks from all 6 sections (Ready, Backlog, In Progress, In Review, Done,
2696
+ # Declined). Prior behaviour (GH#20077) only preserved Backlog and silently
2697
+ # dropped the other 5 sections into TODO.md.bak, losing audit-trail data.
2595
2698
  _upgrade_todo() {
2596
2699
  local todo_file="$1" todo_template="$2" backup="$3"
2597
2700
  print_info "Upgrading TODO.md..."
2598
- local existing_tasks=""
2701
+ local workdir=""
2702
+ workdir=$(mktemp -d)
2703
+ # shellcheck disable=SC2064 # intentional $workdir expansion at trap-set time
2704
+ trap "rm -rf \"${workdir}\"" RETURN
2599
2705
  if [[ -f "$todo_file" ]]; then
2600
- # Extract everything under ## Backlog (tasks AND ### subsection headers)
2601
- # until the next ## header or EOF — preserves semantic grouping.
2602
- # GH#17804: Skip ## Format section and filter out template placeholder IDs
2603
- # (tXXX, tYYY, tZZZ) that are documentation examples, not real tasks.
2604
- existing_tasks=$(awk '
2605
- # Section-aware: track when inside ## Format to skip its content
2606
- /^## Format/ { in_format=1; next }
2607
- in_format && /^## / { in_format=0 }
2608
- in_format { next }
2609
- # Also skip content inside markdown code blocks (``` fenced blocks)
2610
- /^```/ { in_codeblock = !in_codeblock; next }
2611
- in_codeblock { next }
2612
- # Extract from ## Backlog to next ## header
2613
- /^## Backlog/ { found=1; next }
2614
- found && /^## / { exit }
2615
- found
2616
- ' "$todo_file" 2>/dev/null || echo "")
2617
- # GH#17804: Filter out lines with non-numeric task IDs (template placeholders
2618
- # like tXXX, tYYY, tZZZ). Real task IDs match t<digits> or t<digits>.<digits>.
2619
- if [[ -n "$existing_tasks" ]]; then
2620
- existing_tasks=$(printf '%s\n' "$existing_tasks" | awk '
2621
- # Keep non-task lines (subsection headers, comments, blank lines)
2622
- !/^- \[[ x-]\] t/ { print; next }
2623
- # For task lines: extract the ID and validate it is numeric
2624
- {
2625
- id = $0
2626
- sub(/^- \[[ x-]\] /, "", id)
2627
- sub(/ .*/, "", id)
2628
- # Valid IDs: t followed by digits, optionally .digits (subtasks)
2629
- if (id ~ /^t[0-9]+(\.[0-9]+)*$/) print
2630
- }
2631
- ')
2632
- fi
2706
+ _upgrade_todo_preserve_sections "$todo_file" "$workdir"
2633
2707
  [[ "$backup" == "true" ]] && {
2634
2708
  cp "$todo_file" "${todo_file}.bak"
2635
2709
  print_success "Backup created: TODO.md.bak"
@@ -2643,27 +2717,11 @@ _upgrade_todo() {
2643
2717
  cp "$todo_template" "$todo_file"
2644
2718
  fi
2645
2719
  sed_inplace "s/{{DATE}}/$(date +%Y-%m-%d)/" "$todo_file" 2>/dev/null || true
2646
- if [[ -n "$existing_tasks" ]] && grep -q "<!--TOON:backlog" "$todo_file"; then
2647
- local temp_file="${todo_file}.merge" tasks_file
2648
- tasks_file=$(mktemp)
2649
- trap 'rm -f "${tasks_file:-}"' RETURN
2650
- printf '%s\n' "$existing_tasks" >"$tasks_file"
2651
- local in_backlog=false
2652
- while IFS= read -r line || [[ -n "$line" ]]; do
2653
- [[ "$line" == *"<!--TOON:backlog"* ]] && in_backlog=true
2654
- if [[ "$in_backlog" == true && "$line" == "-->" ]]; then
2655
- echo "$line"
2656
- echo ""
2657
- cat "$tasks_file"
2658
- in_backlog=false
2659
- continue
2660
- fi
2661
- echo "$line"
2662
- done <"$todo_file" >"$temp_file"
2663
- rm -f "$tasks_file"
2664
- mv "$temp_file" "$todo_file"
2665
- print_success "Merged existing tasks into Backlog"
2666
- fi
2720
+ _upgrade_todo_reinsert_sections "$todo_file" "$workdir"
2721
+ local merged=0
2722
+ merged=$(grep -cE '^- \[[ x-]\] (t[0-9]|GH#[0-9])' "$todo_file" 2>/dev/null || true)
2723
+ merged="${merged:-0}"
2724
+ [[ "$merged" -gt 0 ]] && print_success "Merged $merged existing task(s) across sections"
2667
2725
  print_success "TODO.md upgraded to TOON-enhanced template"
2668
2726
  return 0
2669
2727
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aidevops",
3
- "version": "3.8.83",
3
+ "version": "3.8.84",
4
4
  "description": "AI DevOps Framework - AI-assisted development workflows, code quality, and deployment automation",
5
5
  "type": "module",
6
6
  "bin": {
package/setup.sh CHANGED
@@ -12,7 +12,7 @@ shopt -s inherit_errexit 2>/dev/null || true
12
12
  # AI Assistant Server Access Framework Setup Script
13
13
  # Helps developers set up the framework for their infrastructure
14
14
  #
15
- # Version: 3.8.83
15
+ # Version: 3.8.84
16
16
  #
17
17
  # Quick Install:
18
18
  # npm install -g aidevops && aidevops update (recommended)