@imdeadpool/guardex 7.0.23 → 7.0.25

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 (26) hide show
  1. package/README.md +30 -3
  2. package/package.json +1 -1
  3. package/src/cli/args.js +9 -0
  4. package/src/cli/main.js +7 -2
  5. package/src/context.js +22 -0
  6. package/src/doctor/index.js +158 -5
  7. package/src/finish/index.js +1 -0
  8. package/src/report/session-severity.js +77 -8
  9. package/templates/AGENTS.multiagent-safety.md +3 -0
  10. package/templates/codex/skills/guardex-merge-skills-to-dev/SKILL.md +3 -2
  11. package/templates/scripts/agent-branch-finish.sh +155 -5
  12. package/templates/scripts/agent-branch-start.sh +35 -0
  13. package/templates/scripts/agent-worktree-prune.sh +22 -1
  14. package/templates/vscode/guardex-active-agents/README.md +6 -3
  15. package/templates/vscode/guardex-active-agents/extension.js +1706 -247
  16. package/templates/vscode/guardex-active-agents/fileicons/gitguardex-fileicons.json +54 -0
  17. package/templates/vscode/guardex-active-agents/fileicons/icons/agent.svg +4 -0
  18. package/templates/vscode/guardex-active-agents/fileicons/icons/branch.svg +4 -0
  19. package/templates/vscode/guardex-active-agents/fileicons/icons/config.svg +4 -0
  20. package/templates/vscode/guardex-active-agents/fileicons/icons/hook.svg +3 -0
  21. package/templates/vscode/guardex-active-agents/fileicons/icons/openspec.svg +5 -0
  22. package/templates/vscode/guardex-active-agents/fileicons/icons/plan.svg +4 -0
  23. package/templates/vscode/guardex-active-agents/fileicons/icons/spec.svg +4 -0
  24. package/templates/vscode/guardex-active-agents/media/active-agents-hivemind.svg +14 -0
  25. package/templates/vscode/guardex-active-agents/package.json +39 -11
  26. package/templates/vscode/guardex-active-agents/session-schema.js +226 -8
@@ -15,6 +15,7 @@ CLEANUP_AFTER_MERGE_RAW="${GUARDEX_FINISH_CLEANUP:-false}"
15
15
  WAIT_FOR_MERGE_RAW="${GUARDEX_FINISH_WAIT_FOR_MERGE:-false}"
16
16
  WAIT_TIMEOUT_SECONDS_RAW="${GUARDEX_FINISH_WAIT_TIMEOUT_SECONDS:-1800}"
17
17
  WAIT_POLL_SECONDS_RAW="${GUARDEX_FINISH_WAIT_POLL_SECONDS:-10}"
18
+ PARENT_GITLINK_AUTO_COMMIT_RAW="${GUARDEX_FINISH_PARENT_GITLINK_AUTO_COMMIT:-true}"
18
19
 
19
20
  run_guardex_cli() {
20
21
  if [[ -n "$CLI_ENTRY" ]]; then
@@ -67,6 +68,7 @@ CLEANUP_AFTER_MERGE="$(normalize_bool "$CLEANUP_AFTER_MERGE_RAW" "0")"
67
68
  WAIT_FOR_MERGE="$(normalize_bool "$WAIT_FOR_MERGE_RAW" "0")"
68
69
  WAIT_TIMEOUT_SECONDS="$(normalize_int "$WAIT_TIMEOUT_SECONDS_RAW" "1800" "30")"
69
70
  WAIT_POLL_SECONDS="$(normalize_int "$WAIT_POLL_SECONDS_RAW" "10" "0")"
71
+ PARENT_GITLINK_AUTO_COMMIT="$(normalize_bool "$PARENT_GITLINK_AUTO_COMMIT_RAW" "1")"
70
72
 
71
73
  while [[ $# -gt 0 ]]; do
72
74
  case "$1" in
@@ -117,6 +119,14 @@ while [[ $# -gt 0 ]]; do
117
119
  WAIT_POLL_SECONDS="$(normalize_int "${2:-}" "10" "0")"
118
120
  shift 2
119
121
  ;;
122
+ --parent-gitlink-commit)
123
+ PARENT_GITLINK_AUTO_COMMIT=1
124
+ shift
125
+ ;;
126
+ --no-parent-gitlink-commit)
127
+ PARENT_GITLINK_AUTO_COMMIT=0
128
+ shift
129
+ ;;
120
130
  --mode)
121
131
  MERGE_MODE="${2:-auto}"
122
132
  shift 2
@@ -131,7 +141,7 @@ while [[ $# -gt 0 ]]; do
131
141
  ;;
132
142
  *)
133
143
  echo "[agent-branch-finish] Unknown argument: $1" >&2
134
- echo "Usage: $0 [--base <branch>] [--branch <branch>] [--no-push] [--cleanup|--no-cleanup] [--wait-for-merge|--no-wait-for-merge] [--wait-timeout-seconds <n>] [--wait-poll-seconds <n>] [--keep-remote-branch|--delete-remote-branch] [--mode auto|direct|pr|--via-pr|--direct-only]" >&2
144
+ echo "Usage: $0 [--base <branch>] [--branch <branch>] [--no-push] [--cleanup|--no-cleanup] [--wait-for-merge|--no-wait-for-merge] [--wait-timeout-seconds <n>] [--wait-poll-seconds <n>] [--parent-gitlink-commit|--no-parent-gitlink-commit] [--keep-remote-branch|--delete-remote-branch] [--mode auto|direct|pr|--via-pr|--direct-only]" >&2
135
145
  exit 1
136
146
  ;;
137
147
  esac
@@ -173,6 +183,8 @@ if [[ -z "$stored_worktree_root_rel" ]]; then
173
183
  stored_worktree_root_rel=".omx/agent-worktrees"
174
184
  fi
175
185
  agent_worktree_root="${repo_common_root}/${stored_worktree_root_rel}"
186
+ runtime_state_root_rel="$(dirname "$stored_worktree_root_rel")"
187
+ temp_worktree_root="${repo_common_root}/${runtime_state_root_rel}/.tmp-worktrees"
176
188
 
177
189
  if [[ "$BASE_BRANCH_EXPLICIT" -eq 1 && -z "$BASE_BRANCH" ]]; then
178
190
  echo "[agent-branch-finish] --base requires a non-empty branch name." >&2
@@ -218,7 +230,7 @@ fi
218
230
 
219
231
  get_worktree_for_branch() {
220
232
  local branch="$1"
221
- git -C "$repo_root" worktree list --porcelain | awk -v target="refs/heads/${branch}" -v probe_prefix="${agent_worktree_root}/__source-probe-" '
233
+ git -C "$repo_root" worktree list --porcelain | awk -v target="refs/heads/${branch}" -v probe_prefix="${temp_worktree_root}/__source-probe-" '
222
234
  $1 == "worktree" { wt = $2 }
223
235
  $1 == "branch" && $2 == target {
224
236
  if (index(wt, probe_prefix) != 1) {
@@ -242,7 +254,7 @@ remove_stale_source_probe_worktrees() {
242
254
  git -C "$stale_probe" merge --abort >/dev/null 2>&1 || true
243
255
  git -C "$repo_root" worktree remove "$stale_probe" --force >/dev/null 2>&1 || true
244
256
  done < <(
245
- git -C "$repo_root" worktree list --porcelain | awk -v target="refs/heads/${branch}" -v probe_prefix="${agent_worktree_root}/__source-probe-" '
257
+ git -C "$repo_root" worktree list --porcelain | awk -v target="refs/heads/${branch}" -v probe_prefix="${temp_worktree_root}/__source-probe-" '
246
258
  $1 == "worktree" { wt = $2 }
247
259
  $1 == "branch" && $2 == target {
248
260
  if (index(wt, probe_prefix) == 1) {
@@ -264,11 +276,15 @@ source_worktree="$(get_worktree_for_branch "$SOURCE_BRANCH")"
264
276
  created_source_probe=0
265
277
  source_probe_path=""
266
278
  integration_worktree=""
279
+ integration_branch=""
267
280
 
268
281
  cleanup() {
269
282
  if [[ -n "$integration_worktree" && -d "$integration_worktree" ]]; then
270
283
  git -C "$repo_root" worktree remove "$integration_worktree" --force >/dev/null 2>&1 || true
271
284
  fi
285
+ if [[ -n "${integration_branch:-}" ]]; then
286
+ git -C "$repo_root" branch -D "$integration_branch" >/dev/null 2>&1 || true
287
+ fi
272
288
  if [[ "$created_source_probe" -eq 1 && -n "$source_probe_path" && -d "$source_probe_path" ]]; then
273
289
  # Abort any in-progress git op so `worktree remove --force` succeeds on conflict-stuck probes.
274
290
  git -C "$source_probe_path" rebase --abort >/dev/null 2>&1 || true
@@ -279,7 +295,7 @@ cleanup() {
279
295
  trap cleanup EXIT
280
296
 
281
297
  if [[ -z "$source_worktree" ]]; then
282
- source_probe_path="${agent_worktree_root}/__source-probe-${SOURCE_BRANCH//\//__}-$(date +%Y%m%d-%H%M%S)"
298
+ source_probe_path="${temp_worktree_root}/__source-probe-${SOURCE_BRANCH//\//__}-$(date +%Y%m%d-%H%M%S)"
283
299
  mkdir -p "$(dirname "$source_probe_path")"
284
300
  git -C "$repo_root" worktree add "$source_probe_path" "$SOURCE_BRANCH" >/dev/null
285
301
  source_worktree="$source_probe_path"
@@ -343,7 +359,7 @@ if [[ "$should_require_sync" -eq 1 ]] && git -C "$repo_root" show-ref --verify -
343
359
  fi
344
360
 
345
361
  integration_stamp="$(date +%Y%m%d-%H%M%S)"
346
- integration_worktree_base="${agent_worktree_root}/__integrate-${BASE_BRANCH//\//__}-${integration_stamp}"
362
+ integration_worktree_base="${temp_worktree_root}/__integrate-${BASE_BRANCH//\//__}-${integration_stamp}"
347
363
  integration_branch_base="__agent_integrate_${BASE_BRANCH//\//_}_$(date +%Y%m%d_%H%M%S)"
348
364
  integration_worktree="$integration_worktree_base"
349
365
  integration_branch="$integration_branch_base"
@@ -455,6 +471,128 @@ read_pr_state() {
455
471
  return 0
456
472
  }
457
473
 
474
+ read_merged_pr_for_head() {
475
+ local head_sha="${1:-}"
476
+ local state_line=""
477
+ local parsed_state=""
478
+ local parsed_merged_at=""
479
+ local parsed_url=""
480
+
481
+ if [[ -z "$head_sha" ]]; then
482
+ return 1
483
+ fi
484
+
485
+ state_line="$("$GH_BIN" pr list \
486
+ --state merged \
487
+ --head "$SOURCE_BRANCH" \
488
+ --base "$BASE_BRANCH" \
489
+ --json state,mergedAt,url,headRefOid \
490
+ --jq "map(select(.headRefOid == \"$head_sha\")) | sort_by(.mergedAt // \"\") | reverse | (.[0] // {}) | [(.state // \"\"), (.mergedAt // \"\"), (.url // \"\")] | join(\"\u001f\")" \
491
+ 2>/dev/null || true)"
492
+ if [[ -z "$state_line" ]]; then
493
+ return 1
494
+ fi
495
+
496
+ IFS=$'\x1f' read -r parsed_state parsed_merged_at parsed_url <<< "$state_line"
497
+ if [[ -z "$parsed_state" && -z "$parsed_merged_at" && -z "$parsed_url" ]]; then
498
+ return 1
499
+ fi
500
+ if [[ "$parsed_state" != "MERGED" && -z "$parsed_merged_at" ]]; then
501
+ return 1
502
+ fi
503
+
504
+ PR_STATE="$parsed_state"
505
+ PR_MERGED_AT="$parsed_merged_at"
506
+ if [[ -n "$parsed_url" ]]; then
507
+ pr_url="$parsed_url"
508
+ fi
509
+ return 0
510
+ }
511
+
512
+ maybe_auto_commit_parent_gitlink() {
513
+ local base_wt="${1:-}"
514
+ local base_wt_real=""
515
+ local super_root_raw=""
516
+ local super_root=""
517
+ local subrepo_rel=""
518
+ local gitlink_mode=""
519
+ local gitlink_index_sha=""
520
+ local gitlink_parent_head_sha=""
521
+ local subrepo_head_sha=""
522
+ local update_index_output=""
523
+ local commit_output=""
524
+ local commit_message=""
525
+
526
+ if [[ "$PARENT_GITLINK_AUTO_COMMIT" -ne 1 || "$PUSH_ENABLED" -ne 1 ]]; then
527
+ return 0
528
+ fi
529
+ if [[ -z "$base_wt" ]]; then
530
+ return 0
531
+ fi
532
+ if ! base_wt_real="$(cd "$base_wt" && pwd -P 2>/dev/null)"; then
533
+ return 0
534
+ fi
535
+ if [[ "$base_wt_real" != "$repo_common_root" ]]; then
536
+ return 0
537
+ fi
538
+ if ! is_clean_worktree "$repo_common_root"; then
539
+ echo "[agent-branch-finish] Parent gitlink auto-commit skipped; nested base worktree is dirty: ${repo_common_root}" >&2
540
+ return 0
541
+ fi
542
+
543
+ super_root_raw="$(git -C "$repo_common_root" rev-parse --show-superproject-working-tree 2>/dev/null || true)"
544
+ if [[ -z "$super_root_raw" ]]; then
545
+ return 0
546
+ fi
547
+ if ! super_root="$(cd "$super_root_raw" && pwd -P 2>/dev/null)"; then
548
+ return 0
549
+ fi
550
+
551
+ case "$repo_common_root" in
552
+ "$super_root"/*) subrepo_rel="${repo_common_root#"$super_root"/}" ;;
553
+ *) return 0 ;;
554
+ esac
555
+ if [[ -z "$subrepo_rel" || "$subrepo_rel" == "$repo_common_root" ]]; then
556
+ return 0
557
+ fi
558
+
559
+ gitlink_mode="$(git -C "$super_root" ls-files -s -- "$subrepo_rel" | awk 'NR == 1 { print $1 }')"
560
+ if [[ "$gitlink_mode" != "160000" ]]; then
561
+ return 0
562
+ fi
563
+ gitlink_index_sha="$(git -C "$super_root" ls-files -s -- "$subrepo_rel" | awk 'NR == 1 { print $2 }')"
564
+ gitlink_parent_head_sha="$(git -C "$super_root" ls-tree HEAD -- "$subrepo_rel" | awk 'NR == 1 { print $3 }')"
565
+ subrepo_head_sha="$(git -C "$repo_common_root" rev-parse HEAD 2>/dev/null || true)"
566
+ if [[ -z "$subrepo_head_sha" ]]; then
567
+ return 0
568
+ fi
569
+ if [[ -n "$gitlink_index_sha" && "$gitlink_index_sha" == "$gitlink_parent_head_sha" && "$gitlink_index_sha" == "$subrepo_head_sha" ]]; then
570
+ return 0
571
+ fi
572
+
573
+ if [[ "$gitlink_index_sha" != "$subrepo_head_sha" ]]; then
574
+ if ! update_index_output="$(git -C "$super_root" update-index --cacheinfo 160000 "$subrepo_head_sha" "$subrepo_rel" 2>&1)"; then
575
+ echo "[agent-branch-finish] Warning: parent gitlink staging failed for ${subrepo_rel} in ${super_root}." >&2
576
+ [[ -n "$update_index_output" ]] && echo "$update_index_output" >&2
577
+ return 0
578
+ fi
579
+ gitlink_index_sha="$(git -C "$super_root" ls-files -s -- "$subrepo_rel" | awk 'NR == 1 { print $2 }')"
580
+ fi
581
+ gitlink_parent_head_sha="$(git -C "$super_root" ls-tree HEAD -- "$subrepo_rel" | awk 'NR == 1 { print $3 }')"
582
+ if [[ "$gitlink_index_sha" == "$gitlink_parent_head_sha" ]]; then
583
+ return 0
584
+ fi
585
+
586
+ commit_message="Update ${subrepo_rel} subrepo pointer"
587
+ if ! commit_output="$(git -C "$super_root" commit -m "$commit_message" -- "$subrepo_rel" 2>&1)"; then
588
+ echo "[agent-branch-finish] Warning: parent gitlink auto-commit failed in ${super_root}." >&2
589
+ [[ -n "$commit_output" ]] && echo "$commit_output" >&2
590
+ return 0
591
+ fi
592
+
593
+ echo "[agent-branch-finish] Parent gitlink auto-committed '${subrepo_rel}' in ${super_root}."
594
+ }
595
+
458
596
  wait_for_pr_merge() {
459
597
  local deadline
460
598
  deadline=$(( $(date +%s) + WAIT_TIMEOUT_SECONDS ))
@@ -509,11 +647,22 @@ wait_for_pr_merge() {
509
647
  }
510
648
 
511
649
  run_pr_flow() {
650
+ local source_head_sha=""
651
+
512
652
  if ! command -v "$GH_BIN" >/dev/null 2>&1; then
513
653
  echo "[agent-branch-finish] PR fallback requested but GitHub CLI not found: ${GH_BIN}" >&2
514
654
  return 1
515
655
  fi
516
656
 
657
+ source_head_sha="$(git -C "$repo_root" rev-parse "$SOURCE_BRANCH" 2>/dev/null || true)"
658
+ if read_merged_pr_for_head "$source_head_sha"; then
659
+ echo "[agent-branch-finish] Source branch head already landed in a merged PR; skipping new PR creation and continuing cleanup." >&2
660
+ if [[ -n "$pr_url" ]]; then
661
+ echo "[agent-branch-finish] Merged PR: ${pr_url}" >&2
662
+ fi
663
+ return 0
664
+ fi
665
+
517
666
  git -C "$source_worktree" push -u origin "$SOURCE_BRANCH"
518
667
 
519
668
  pr_title="$(git -C "$repo_root" log -1 --pretty=%s "$SOURCE_BRANCH" 2>/dev/null || true)"
@@ -612,6 +761,7 @@ base_worktree="$(get_worktree_for_branch "$BASE_BRANCH")"
612
761
  if [[ -n "$base_worktree" ]] && is_clean_worktree "$base_worktree" && [[ "$PUSH_ENABLED" -eq 1 ]]; then
613
762
  git -C "$base_worktree" pull --ff-only origin "$BASE_BRANCH" >/dev/null 2>&1 || true
614
763
  fi
764
+ maybe_auto_commit_parent_gitlink "$base_worktree"
615
765
 
616
766
  if [[ "$CLEANUP_AFTER_MERGE" -eq 1 ]]; then
617
767
  if [[ "$source_worktree" == "$repo_root" ]]; then
@@ -155,6 +155,15 @@ env_flag_truthy() {
155
155
  esac
156
156
  }
157
157
 
158
+ maybe_fail_after_auto_transfer_stash() {
159
+ if env_flag_truthy "${GUARDEX_TEST_FAIL_AFTER_AUTO_TRANSFER_STASH:-}"; then
160
+ echo "[agent-branch-start] Simulated failure after capturing auto-transfer stash." >&2
161
+ return 1
162
+ fi
163
+
164
+ return 0
165
+ }
166
+
158
167
  default_worktree_root_rel() {
159
168
  local raw_agent="$1"
160
169
  local override="${GUARDEX_AGENT_TYPE:-}"
@@ -580,6 +589,27 @@ fi
580
589
  auto_transfer_stash_ref=""
581
590
  auto_transfer_message=""
582
591
  auto_transfer_source_branch=""
592
+ auto_transfer_completed=0
593
+
594
+ restore_auto_transfer_stash_on_failure() {
595
+ local exit_code="${1:-0}"
596
+ if [[ "$exit_code" -eq 0 ]] || [[ -z "$auto_transfer_stash_ref" ]] || [[ "$auto_transfer_completed" -eq 1 ]]; then
597
+ return 0
598
+ fi
599
+
600
+ local transfer_label="${auto_transfer_source_branch:-$BASE_BRANCH}"
601
+ if git -C "$repo_root" stash apply "$auto_transfer_stash_ref" >/dev/null 2>&1; then
602
+ git -C "$repo_root" stash drop "$auto_transfer_stash_ref" >/dev/null 2>&1 || true
603
+ auto_transfer_stash_ref=""
604
+ echo "[agent-branch-start] Restored moved changes back to '${transfer_label}' after startup failure." >&2
605
+ else
606
+ echo "[agent-branch-start] Startup failed and auto-restore also failed." >&2
607
+ echo "[agent-branch-start] Changes are preserved in ${auto_transfer_stash_ref} on ${transfer_label}." >&2
608
+ fi
609
+ }
610
+
611
+ trap 'restore_auto_transfer_stash_on_failure "$?"' EXIT
612
+
583
613
  current_branch="$(git -C "$repo_root" rev-parse --abbrev-ref HEAD 2>/dev/null || true)"
584
614
  protected_branches_raw="$(resolve_protected_branches "$repo_root")"
585
615
  if [[ -n "$current_branch" && "$current_branch" != "HEAD" ]] && is_protected_branch_name "$current_branch" "$protected_branches_raw"; then
@@ -593,6 +623,9 @@ if [[ -n "$current_branch" && "$current_branch" != "HEAD" ]] && is_protected_bra
593
623
  if [[ -n "$auto_transfer_stash_ref" ]]; then
594
624
  auto_transfer_source_branch="$current_branch"
595
625
  echo "[agent-branch-start] Detected local changes on protected branch '${current_branch}'. Moving them to '${branch_name}'..."
626
+ if ! maybe_fail_after_auto_transfer_stash; then
627
+ exit 1
628
+ fi
596
629
  fi
597
630
  fi
598
631
  fi
@@ -610,7 +643,9 @@ git -C "$worktree_path" branch --unset-upstream "$branch_name" >/dev/null 2>&1 |
610
643
 
611
644
  if [[ -n "$auto_transfer_stash_ref" ]]; then
612
645
  if git -C "$worktree_path" stash apply "$auto_transfer_stash_ref" >/dev/null 2>&1; then
646
+ auto_transfer_completed=1
613
647
  git -C "$repo_root" stash drop "$auto_transfer_stash_ref" >/dev/null 2>&1 || true
648
+ auto_transfer_stash_ref=""
614
649
  transfer_label="${auto_transfer_source_branch:-$BASE_BRANCH}"
615
650
  echo "[agent-branch-start] Moved local changes from '${transfer_label}' into '${branch_name}'."
616
651
  else
@@ -20,7 +20,9 @@ PR_MERGED_LOOKUP_LOADED=0
20
20
  declare -A MERGED_PR_BRANCHES=()
21
21
  WORKTREE_ROOT_RELS=(
22
22
  ".omx/agent-worktrees"
23
+ ".omx/.tmp-worktrees"
23
24
  ".omc/agent-worktrees"
25
+ ".omc/.tmp-worktrees"
24
26
  )
25
27
 
26
28
  if [[ -n "$BASE_BRANCH" ]]; then
@@ -90,9 +92,15 @@ repo_common_dir="$(cd "$repo_common_dir" && pwd -P)"
90
92
  resolve_worktree_root_rel_for_entry() {
91
93
  local entry="$1"
92
94
  case "$entry" in
95
+ */.omc/.tmp-worktrees/*)
96
+ printf '%s' '.omc/.tmp-worktrees'
97
+ ;;
93
98
  */.omc/agent-worktrees/*)
94
99
  printf '%s' '.omc/agent-worktrees'
95
100
  ;;
101
+ */.omx/.tmp-worktrees/*)
102
+ printf '%s' '.omx/.tmp-worktrees'
103
+ ;;
96
104
  *)
97
105
  printf '%s' '.omx/agent-worktrees'
98
106
  ;;
@@ -538,6 +546,19 @@ if [[ "$DELETE_BRANCHES" -eq 1 ]]; then
538
546
  if branch_has_worktree "$branch"; then
539
547
  continue
540
548
  fi
549
+ if [[ "$branch" == __agent_integrate_* || "$branch" == __source-probe-* ]]; then
550
+ if ! branch_idle_gate "$branch" "" "temporary-worktree"; then
551
+ continue
552
+ fi
553
+ if run_cmd git -C "$repo_root" branch -D "$branch" >/dev/null 2>&1; then
554
+ removed_branches=$((removed_branches + 1))
555
+ echo "[agent-worktree-prune] Deleted stale temporary branch: ${branch}"
556
+ fi
557
+ continue
558
+ fi
559
+ if [[ "$branch" != agent/* ]]; then
560
+ continue
561
+ fi
541
562
  if ! branch_idle_gate "$branch" "" "stale-merged-branch"; then
542
563
  continue
543
564
  fi
@@ -566,7 +587,7 @@ if [[ "$DELETE_BRANCHES" -eq 1 ]]; then
566
587
  fi
567
588
  fi
568
589
  fi
569
- done < <(git -C "$repo_root" for-each-ref --format='%(refname:short)' refs/heads/agent)
590
+ done < <(git -C "$repo_root" for-each-ref --format='%(refname:short)' refs/heads)
570
591
  fi
571
592
 
572
593
  run_cmd git -C "$repo_root" worktree prune
@@ -4,7 +4,7 @@ Local VS Code companion for Guardex-managed repos.
4
4
 
5
5
  ## Quick Start
6
6
 
7
- Use the welcome view in Source Control to create or inspect Guardex sandboxes quickly.
7
+ Use the dedicated Active Agents sidebar icon to create or inspect Guardex sandboxes quickly.
8
8
 
9
9
  1. Install from a Guardex-wired repo:
10
10
 
@@ -13,16 +13,19 @@ node scripts/install-vscode-active-agents-extension.js
13
13
  ```
14
14
 
15
15
  2. Reload the VS Code window.
16
- 3. In Source Control -> `Active Agents`, use `Start agent` to enter a task + agent name and launch the repo Guardex agent runner. The companion prefers `bash scripts/codex-agent.sh` when present, falls back to `npm run agent:codex --`, and only uses `gx branch start` as a last resort.
16
+ 3. In the Activity Bar, open the `Active Agents` hive icon under Source Control. Use `Start agent` to enter a task + agent name and launch the repo Guardex agent runner. The companion prefers `bash scripts/codex-agent.sh` when present, falls back to `npm run agent:codex --`, and only uses `gx branch start` as a last resort.
17
17
 
18
18
  What it does:
19
19
 
20
20
  - Bundles a local GitGuardex icon so repo installs show branded extension metadata inside VS Code.
21
- - Adds an `Active Agents` view to the Source Control container.
21
+ - Bundles the optional `GitGuardex File Icons` theme for OpenSpec, agent worktree, and hook files in Explorer.
22
+ - Adds a dedicated `Active Agents` Activity Bar container with a hive icon and live badge count for active sessions.
22
23
  - Renders one repo node per live Guardex workspace with grouped `ACTIVE AGENTS` and `CHANGES` sections.
23
24
  - Splits live sessions inside `ACTIVE AGENTS` into `BLOCKED`, `WORKING NOW`, `THINKING`, `STALLED`, and `DEAD` groups so stuck, active, and inactive lanes stand out immediately.
24
25
  - Mirrors the same live state in the VS Code status bar so the selected session or active-agent count stays visible outside the tree.
25
26
  - Shows one row per live Guardex sandbox session inside those activity groups, with changed-file rows nested under sessions that are touching files.
27
+ - Labels session rows with provider identity and snapshot context; snapshot-backed rows use a one-letter snapshot badge such as `N` for `nagyviktor@edixa.com`.
28
+ - Shows raw agent branch groups with the `git-branch` icon instead of the generic folder icon.
26
29
  - Shows repo-root git changes in a sibling `CHANGES` section when the guarded repo itself is dirty.
27
30
  - Derives session state from dirty worktree status, git conflict markers, heartbeat freshness, PID liveness, and recent file mtimes, surfaces working/dead/conflict counts in the repo/header summary, and shows changed-file counts for active edits.
28
31
  - Uses distinct VS Code codicons for each session state, including animated `loading~spin` for `WORKING NOW`.