@imdeadpool/guardex 7.0.26 → 7.0.27

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/README.md CHANGED
@@ -111,6 +111,16 @@ gx setup
111
111
 
112
112
  That's it. Install and update via `@imdeadpool/guardex`. Setup installs the minimal repo footprint: managed hook shims, repo-local state, AGENTS wiring, OpenSpec/caveman/OMX scaffolding, and a small set of repo-local helper assets. Aliases: `gx` (preferred), `gitguardex` (full), `guardex` (legacy compatibility).
113
113
 
114
+ ### Install surfaces at a glance
115
+
116
+ | Goal | Command | Installs |
117
+ | --- | --- | --- |
118
+ | Global Guardex CLI | `npm i -g @imdeadpool/guardex` | `gx`, `gitguardex`, `guardex`, and the CLI runtime |
119
+ | User-level Codex/Claude companions | `gx install-agent-skills` | `~/.codex/skills/gitguardex/SKILL.md`, `~/.codex/skills/guardex-merge-skills-to-dev/SKILL.md`, and `~/.claude/commands/gitguardex.md` |
120
+ | Generic repo skill catalog | `npx skills add recodee/` or `npx skills add recodee/gitguardex` | the repo-root `skills/` catalog for agents that support the generic installer |
121
+
122
+ These paths are complementary, not chained together. `npm i -g @imdeadpool/guardex` does not auto-run `npx skills add ...`.
123
+
114
124
  ---
115
125
 
116
126
  ## How `AGENTS.md` and `CLAUDE.md` are handled
@@ -140,7 +150,14 @@ That's it. Install and update via `@imdeadpool/guardex`. Setup installs the mini
140
150
  </div>
141
151
 
142
152
  > [!NOTE]
143
- > In this repo, `CLAUDE.md` is a symlink to `AGENTS.md`, so Claude reads the same contract. Optional Codex/Claude companion files still install at the user level with `gx install-agent-skills`, while the generic repo skill catalog is available through `npx skills add recodeee/` or directly via `npx skills add recodeee/gitguardex`.
153
+ > In this repo, `CLAUDE.md` is a symlink to `AGENTS.md`, so Claude reads the same contract as Codex.
154
+ >
155
+ > Keep the install paths separate:
156
+ > - `npm i -g @imdeadpool/guardex` installs the Guardex CLI.
157
+ > - `gx install-agent-skills` installs the user-level Codex/Claude companion files.
158
+ > - `npx skills add recodee/` or `npx skills add recodee/gitguardex` installs the generic repo skill catalog.
159
+ >
160
+ > The global npm install does not auto-run the generic `npx skills add ...` flow.
144
161
 
145
162
  ### Decision flow
146
163
 
@@ -461,17 +478,19 @@ Repo: <https://github.com/Yeachan-Heo/oh-my-claudecode>
461
478
 
462
479
  ### GitGuardex skills - install the repo skill catalog through `npx skills`
463
480
 
464
- For agents that already support the generic `skills` installer flow, GitGuardex now exposes its repo skill catalog directly. You can start from the broader `recodeee` source or jump straight into this repo's catalog.
481
+ For agents that already support the generic `skills` installer flow, GitGuardex exposes its repo skill catalog directly. Use it as a separate install path after the CLI install. You can start from the broader `recodee` source or jump straight into this repo's catalog.
465
482
 
466
483
  ```sh
467
- npx skills add recodeee/
484
+ npx skills add recodee/
468
485
  ```
469
486
 
470
487
  ```sh
471
- npx skills add recodeee/gitguardex
488
+ npx skills add recodee/gitguardex
472
489
  ```
473
490
 
474
- This repo currently exposes `gitguardex` and `guardex-merge-skills-to-dev` through that flow. If the picker does not show a separate `guardex` skill, that is expected: `guardex` remains the legacy CLI alias, while the repo skill itself is named `gitguardex`. Use `gx install-agent-skills` when you want the Codex/Claude user-home startup files instead of the generic `skills` catalog.
491
+ This repo currently exposes `gitguardex` and `guardex-merge-skills-to-dev` through that flow. If the picker does not show a separate `guardex` skill, that is expected: `guardex` remains the legacy CLI alias, while the repo skill itself is named `gitguardex`.
492
+
493
+ Need the Codex/Claude user-home startup files instead? Run `gx install-agent-skills`. Need the generic repo catalog? Run `npx skills add ...`. They solve different setup surfaces.
475
494
 
476
495
  Repo: <https://github.com/recodeee/gitguardex>
477
496
  [![GitHub stars](https://img.shields.io/github/stars/recodeee/gitguardex?style=social)](https://github.com/recodeee/gitguardex)
@@ -626,7 +645,7 @@ vscode/guardex-active-agents/README.md
626
645
 
627
646
  Legacy compatibility note: older repos may still contain repo-local workflow scripts under `scripts/`. Direct `gx branch ...`, `gx locks ...`, `gx finish`, `gx cleanup`, `gx merge`, and `gx migrate` do not require them. `gx migrate` removes those leftover workflow shims by default. The CLI still honors repo-local `scripts/review-bot-watch.sh` and `scripts/codex-agent.sh` when they are already present so older repos can keep working during migration.
628
647
 
629
- Optional Codex/Claude user-level companions still install with `gx install-agent-skills`; the generic repo skill catalog is available with `npx skills add recodeee/` or directly via `npx skills add recodeee/gitguardex`. Neither path copies those user-home files into each repo.
648
+ Optional Codex/Claude user-level companions still install with `gx install-agent-skills`; the generic repo skill catalog is available with `npx skills add recodee/` or directly via `npx skills add recodee/gitguardex`. Neither path copies those user-home files into each repo, and the global Guardex npm install does not trigger the `npx skills add ...` path for you.
630
649
 
631
650
  ---
632
651
 
@@ -689,9 +708,15 @@ npm pack --dry-run
689
708
  <details>
690
709
  <summary><strong>v7.x</strong></summary>
691
710
 
711
+ ### v7.0.27
712
+ - Bumped `@imdeadpool/guardex` from `7.0.26` to `7.0.27` so npm can publish a fresh version after `7.0.26` was already taken on the registry.
713
+ - The shipped `agent-branch-start.sh` copies now keep the startup auto-transfer path alive under `set -o pipefail`, so Guardex can still restore moved changes back to the protected checkout when branch startup hits a later failure.
714
+ - The shipped `agent-branch-finish.sh` copies now keep PR-only finish runs from opening temporary integration repos, so maintainers can finish directly through the existing PR lane without extra temp-repo churn.
715
+ - Keep the release scoped to version metadata for the already-merged `main` payload; no additional runtime behavior changes are introduced in this release lane.
716
+
692
717
  ### v7.0.26
693
718
  - Bumped `@imdeadpool/guardex` from `7.0.25` to `7.0.26` so npm can publish a fresh version after `v7.0.25` reached GitHub Releases while the registry stayed on `7.0.24`.
694
- - README now documents both `npx skills add recodeee/` and `npx skills add recodeee/gitguardex`, and explains why the picker shows `gitguardex` instead of a separate `guardex` skill.
719
+ - README now documents both `npx skills add recodee/` and `npx skills add recodee/gitguardex`, clarifies that the global Guardex npm install does not auto-run the generic skills installer, and explains why the picker shows `gitguardex` instead of a separate `guardex` skill.
695
720
  - Keep the release scoped to version metadata plus the already-merged README installer guidance on `main`; no additional CLI/runtime behavior changed in this lane.
696
721
 
697
722
  ### v7.0.25
package/SECURITY.md CHANGED
@@ -8,7 +8,7 @@ Only the latest published GitGuardex CLI build is supported for security fixes.
8
8
 
9
9
  Please report security issues privately by opening a GitHub security advisory:
10
10
 
11
- - https://github.com/recodeecom/multiagent-safety/security/advisories/new
11
+ - https://github.com/recodeee/gitguardex/security/advisories/new
12
12
 
13
13
  If advisories are unavailable, open a private report via GitHub issue contact details and avoid posting exploit details publicly.
14
14
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@imdeadpool/guardex",
3
- "version": "7.0.26",
3
+ "version": "7.0.27",
4
4
  "description": "Guardian T-Rex for your multi-agent repo. Isolated worktrees, file locks, and PR-only merges stop parallel Codex & Claude agents from overwriting each other's work. Auto-wires Oh My Codex, Oh My Claude, OpenSpec, and Caveman.",
5
5
  "license": "MIT",
6
6
  "preferGlobal": true,
@@ -68,10 +68,10 @@
68
68
  "access": "public"
69
69
  },
70
70
  "devDependencies": {
71
- "fast-check": "^3.23.2"
71
+ "fast-check": "3.23.2"
72
72
  },
73
73
  "dependencies": {
74
- "jsonc-parser": "^3.3.1",
75
- "semver": "^7.7.4"
74
+ "jsonc-parser": "3.3.1",
75
+ "semver": "7.7.4"
76
76
  }
77
77
  }
@@ -277,6 +277,10 @@ created_source_probe=0
277
277
  source_probe_path=""
278
278
  integration_worktree=""
279
279
  integration_branch=""
280
+ merge_completed=0
281
+ merge_status="pr"
282
+ direct_push_error=""
283
+ pr_url=""
280
284
 
281
285
  cleanup() {
282
286
  if [[ -n "$integration_worktree" && -d "$integration_worktree" ]]; then
@@ -358,22 +362,6 @@ if [[ "$should_require_sync" -eq 1 ]] && git -C "$repo_root" show-ref --verify -
358
362
  fi
359
363
  fi
360
364
 
361
- integration_stamp="$(date +%Y%m%d-%H%M%S)"
362
- integration_worktree_base="${temp_worktree_root}/__integrate-${BASE_BRANCH//\//__}-${integration_stamp}"
363
- integration_branch_base="__agent_integrate_${BASE_BRANCH//\//_}_$(date +%Y%m%d_%H%M%S)"
364
- integration_worktree="$integration_worktree_base"
365
- integration_branch="$integration_branch_base"
366
- integration_suffix=1
367
- while [[ -e "$integration_worktree" ]] || git -C "$repo_root" show-ref --verify --quiet "refs/heads/${integration_branch}"; do
368
- integration_worktree="${integration_worktree_base}-${integration_suffix}"
369
- integration_branch="${integration_branch_base}_${integration_suffix}"
370
- integration_suffix=$((integration_suffix + 1))
371
- done
372
- mkdir -p "$(dirname "$integration_worktree")"
373
-
374
- git -C "$repo_root" worktree add "$integration_worktree" "$start_ref" >/dev/null
375
- git -C "$integration_worktree" checkout -b "$integration_branch" >/dev/null
376
-
377
365
  if git -C "$repo_root" show-ref --verify --quiet "refs/remotes/origin/${BASE_BRANCH}"; then
378
366
  git -C "$source_worktree" fetch origin "$BASE_BRANCH" --quiet
379
367
 
@@ -395,16 +383,37 @@ if git -C "$repo_root" show-ref --verify --quiet "refs/remotes/origin/${BASE_BRA
395
383
  git -C "$source_worktree" merge --abort >/dev/null 2>&1 || true
396
384
  fi
397
385
 
398
- if ! git -C "$integration_worktree" merge --no-ff --no-edit "$SOURCE_BRANCH"; then
399
- echo "[agent-branch-finish] Merge conflict detected while merging '${SOURCE_BRANCH}' into '${BASE_BRANCH}'." >&2
400
- git -C "$integration_worktree" merge --abort >/dev/null 2>&1 || true
401
- exit 1
386
+ should_create_integration_helper=1
387
+ if [[ "$MERGE_MODE" == "pr" && "$PUSH_ENABLED" -eq 1 ]]; then
388
+ should_create_integration_helper=0
402
389
  fi
403
390
 
404
- merge_completed=1
405
- merge_status="direct"
406
- direct_push_error=""
407
- pr_url=""
391
+ if [[ "$should_create_integration_helper" -eq 1 ]]; then
392
+ integration_stamp="$(date +%Y%m%d-%H%M%S)"
393
+ integration_worktree_base="${temp_worktree_root}/__integrate-${BASE_BRANCH//\//__}-${integration_stamp}"
394
+ integration_branch_base="__agent_integrate_${BASE_BRANCH//\//_}_$(date +%Y%m%d_%H%M%S)"
395
+ integration_worktree="$integration_worktree_base"
396
+ integration_branch="$integration_branch_base"
397
+ integration_suffix=1
398
+ while [[ -e "$integration_worktree" ]] || git -C "$repo_root" show-ref --verify --quiet "refs/heads/${integration_branch}"; do
399
+ integration_worktree="${integration_worktree_base}-${integration_suffix}"
400
+ integration_branch="${integration_branch_base}_${integration_suffix}"
401
+ integration_suffix=$((integration_suffix + 1))
402
+ done
403
+ mkdir -p "$(dirname "$integration_worktree")"
404
+
405
+ git -C "$repo_root" worktree add "$integration_worktree" "$start_ref" >/dev/null
406
+ git -C "$integration_worktree" checkout -b "$integration_branch" >/dev/null
407
+
408
+ if ! git -C "$integration_worktree" merge --no-ff --no-edit "$SOURCE_BRANCH"; then
409
+ echo "[agent-branch-finish] Merge conflict detected while merging '${SOURCE_BRANCH}' into '${BASE_BRANCH}'." >&2
410
+ git -C "$integration_worktree" merge --abort >/dev/null 2>&1 || true
411
+ exit 1
412
+ fi
413
+
414
+ merge_completed=1
415
+ merge_status="direct"
416
+ fi
408
417
 
409
418
  is_local_branch_delete_error() {
410
419
  local output="$1"
@@ -370,6 +370,19 @@ has_local_changes() {
370
370
  return 1
371
371
  }
372
372
 
373
+ resolve_stash_ref_by_message() {
374
+ local root="$1"
375
+ local message="$2"
376
+ local stash_list
377
+ stash_list="$(git -C "$root" stash list 2>/dev/null || true)"
378
+ if [[ -z "$stash_list" ]]; then
379
+ printf ''
380
+ return 0
381
+ fi
382
+
383
+ awk -v msg="$message" '$0 ~ msg { ref=$1; sub(/:$/, "", ref); print ref; exit }' <<<"$stash_list"
384
+ }
385
+
373
386
  resolve_protected_branches() {
374
387
  local root="$1"
375
388
  local raw
@@ -616,10 +629,7 @@ if [[ -n "$current_branch" && "$current_branch" != "HEAD" ]] && is_protected_bra
616
629
  if has_local_changes "$repo_root"; then
617
630
  auto_transfer_message="guardex-auto-transfer-${timestamp}-${agent_slug}-${task_slug}"
618
631
  if git -C "$repo_root" stash push --include-untracked --message "$auto_transfer_message" >/dev/null 2>&1; then
619
- auto_transfer_stash_ref="$(
620
- git -C "$repo_root" stash list \
621
- | awk -v msg="$auto_transfer_message" '$0 ~ msg { ref=$1; sub(/:$/, "", ref); print ref; exit }'
622
- )"
632
+ auto_transfer_stash_ref="$(resolve_stash_ref_by_message "$repo_root" "$auto_transfer_message")"
623
633
  if [[ -n "$auto_transfer_stash_ref" ]]; then
624
634
  auto_transfer_source_branch="$current_branch"
625
635
  echo "[agent-branch-start] Detected local changes on protected branch '${current_branch}'. Moving them to '${branch_name}'..."
@@ -3,11 +3,13 @@ const path = require('node:path');
3
3
  const cp = require('node:child_process');
4
4
  const vscode = require('vscode');
5
5
  const {
6
+ clearWorktreeActivityCache,
6
7
  formatElapsedFrom,
7
8
  readActiveSessions,
8
9
  readRepoChanges,
9
10
  readSessionInspectData,
10
11
  sanitizeBranchForFile,
12
+ sessionFilePathForBranch,
11
13
  } = require('./session-schema.js');
12
14
 
13
15
  const SESSION_DECORATION_SCHEME = 'gitguardex-agent';
@@ -65,6 +67,7 @@ const SESSION_ACTIVITY_ICON_IDS = {
65
67
  stalled: 'clock',
66
68
  dead: 'error',
67
69
  };
70
+ const DISMISSABLE_SESSION_ACTIVITY_KINDS = new Set(['stalled', 'dead']);
68
71
  const SESSION_PROVIDER_BRANDS = {
69
72
  openai: {
70
73
  id: 'openai',
@@ -693,6 +696,14 @@ function changeRiskBadges(change) {
693
696
  ].filter(Boolean));
694
697
  }
695
698
 
699
+ function changeNeedsWarningIcon(change) {
700
+ return Boolean(
701
+ change?.protectedBranch
702
+ || change?.hasForeignLock
703
+ || (!change?.hasForeignLock && change?.lockOwnerBranch),
704
+ );
705
+ }
706
+
696
707
  function buildSessionCardDescription(session) {
697
708
  const provider = resolveSessionProvider(session);
698
709
  const statusAgentLabel = `${sessionStatusLabel(session)}: ${session.agentName || 'agent'}`;
@@ -1289,7 +1300,7 @@ class SessionItem extends vscode.TreeItem {
1289
1300
  : buildSessionCardDescription(session);
1290
1301
  this.tooltip = buildSessionTooltip(session, this.description);
1291
1302
  this.iconPath = themeIcon(resolveSessionActivityIconId(session.activityKind));
1292
- this.contextValue = 'gitguardex.session';
1303
+ this.contextValue = sessionContextValue(session);
1293
1304
  this.command = {
1294
1305
  command: 'gitguardex.activeAgents.openWorktree',
1295
1306
  title: 'Open Agent Worktree',
@@ -1298,6 +1309,35 @@ class SessionItem extends vscode.TreeItem {
1298
1309
  }
1299
1310
  }
1300
1311
 
1312
+ function sessionContextValue(session) {
1313
+ const activityKind = typeof session?.activityKind === 'string' ? session.activityKind.trim() : '';
1314
+ return activityKind
1315
+ ? `gitguardex.session.${activityKind}`
1316
+ : 'gitguardex.session';
1317
+ }
1318
+
1319
+ function canDismissSession(session) {
1320
+ return DISMISSABLE_SESSION_ACTIVITY_KINDS.has(session?.activityKind);
1321
+ }
1322
+
1323
+ function buildDismissSessionDetail(session, statePath) {
1324
+ const repoRoot = typeof session?.repoRoot === 'string' ? session.repoRoot.trim() : '';
1325
+ const relativeStatePath = repoRoot
1326
+ ? path.relative(repoRoot, statePath) || path.basename(statePath)
1327
+ : path.basename(statePath);
1328
+ const detailParts = [
1329
+ `Remove ${relativeStatePath} and hide this session from Active Agents.`,
1330
+ ];
1331
+
1332
+ if (session?.activityKind === 'stalled') {
1333
+ detailParts.push('This dismisses the stale sidebar row only; use Stop if you want to interrupt a live agent.');
1334
+ } else {
1335
+ detailParts.push('This clears the stale session record from the sidebar.');
1336
+ }
1337
+
1338
+ return detailParts.join(' ');
1339
+ }
1340
+
1301
1341
  class FolderItem extends vscode.TreeItem {
1302
1342
  constructor(label, relativePath, items, options = {}) {
1303
1343
  super(
@@ -1845,6 +1885,51 @@ async function stopSession(session, refresh) {
1845
1885
  }
1846
1886
  }
1847
1887
 
1888
+ async function dismissSession(session, refresh) {
1889
+ if (!canDismissSession(session)) {
1890
+ showSessionMessage('Only stalled or dead sessions can be dismissed.');
1891
+ return;
1892
+ }
1893
+
1894
+ const repoRoot = typeof session?.repoRoot === 'string' ? session.repoRoot.trim() : '';
1895
+ if (!repoRoot) {
1896
+ showSessionMessage('Cannot dismiss session: missing repo root.');
1897
+ return;
1898
+ }
1899
+ if (!session?.branch) {
1900
+ showSessionMessage('Cannot dismiss session: missing branch name.');
1901
+ return;
1902
+ }
1903
+
1904
+ const statePath = sessionFilePathForBranch(repoRoot, session.branch);
1905
+ if (!fs.existsSync(statePath)) {
1906
+ clearWorktreeActivityCache(session.worktreePath);
1907
+ refresh();
1908
+ showSessionMessage(`Session record already gone for ${sessionDisplayLabel(session)}.`);
1909
+ return;
1910
+ }
1911
+
1912
+ const confirmed = await vscode.window.showWarningMessage(
1913
+ `Dismiss ${sessionDisplayLabel(session)}?`,
1914
+ {
1915
+ modal: true,
1916
+ detail: buildDismissSessionDetail(session, statePath),
1917
+ },
1918
+ 'Dismiss',
1919
+ );
1920
+ if (confirmed !== 'Dismiss') {
1921
+ return;
1922
+ }
1923
+
1924
+ try {
1925
+ fs.unlinkSync(statePath);
1926
+ clearWorktreeActivityCache(session.worktreePath);
1927
+ refresh();
1928
+ } catch (error) {
1929
+ showSessionMessage(`Failed to dismiss session ${sessionDisplayLabel(session)}: ${error.message}`);
1930
+ }
1931
+ }
1932
+
1848
1933
  function readGitDirPath(targetPath) {
1849
1934
  const normalizedTargetPath = typeof targetPath === 'string' ? targetPath.trim() : '';
1850
1935
  if (!normalizedTargetPath) {
@@ -2719,7 +2804,7 @@ function buildUnassignedChangeNodes(changes) {
2719
2804
  return sortUnassignedChanges(changes).map((change) => new ChangeItem(change, {
2720
2805
  label: compactRelativePath(change.relativePath),
2721
2806
  description: buildUnassignedChangeDescription(change),
2722
- iconId: changeRiskBadges(change).length > 0 ? 'warning' : undefined,
2807
+ iconId: changeNeedsWarningIcon(change) ? 'warning' : undefined,
2723
2808
  }));
2724
2809
  }
2725
2810
 
@@ -3358,6 +3443,7 @@ function activate(context) {
3358
3443
  vscode.commands.registerCommand('gitguardex.activeAgents.finishSession', finishSession),
3359
3444
  vscode.commands.registerCommand('gitguardex.activeAgents.syncSession', syncSession),
3360
3445
  vscode.commands.registerCommand('gitguardex.activeAgents.stopSession', (session) => stopSession(session, refresh)),
3446
+ vscode.commands.registerCommand('gitguardex.activeAgents.dismissSession', (session) => dismissSession(session, refresh)),
3361
3447
  vscode.workspace.onDidChangeWorkspaceFolders(handleWorkspaceFoldersChanged),
3362
3448
  activeSessionsWatcher,
3363
3449
  lockWatcher,
@@ -3,7 +3,7 @@
3
3
  "displayName": "GitGuardex Active Agents",
4
4
  "description": "Shows live Guardex sandbox sessions and repo changes in a dedicated VS Code Active Agents sidebar.",
5
5
  "publisher": "recodeee",
6
- "version": "0.0.17",
6
+ "version": "0.0.18",
7
7
  "license": "MIT",
8
8
  "icon": "icon.png",
9
9
  "engines": {
@@ -65,6 +65,11 @@
65
65
  "title": "Stop",
66
66
  "icon": "$(debug-stop)"
67
67
  },
68
+ {
69
+ "command": "gitguardex.activeAgents.dismissSession",
70
+ "title": "Dismiss",
71
+ "icon": "$(trash)"
72
+ },
68
73
  {
69
74
  "command": "gitguardex.activeAgents.showSessionTerminal",
70
75
  "title": "Show Terminal",
@@ -125,32 +130,37 @@
125
130
  "view/item/context": [
126
131
  {
127
132
  "command": "gitguardex.activeAgents.openWorktree",
128
- "when": "view == gitguardex.activeAgents && viewItem == gitguardex.session",
133
+ "when": "view == gitguardex.activeAgents && viewItem =~ /^gitguardex\\.session(\\.|$)/",
129
134
  "group": "inline"
130
135
  },
131
136
  {
132
137
  "command": "gitguardex.activeAgents.inspect",
133
- "when": "view == gitguardex.activeAgents && viewItem == gitguardex.session",
138
+ "when": "view == gitguardex.activeAgents && viewItem =~ /^gitguardex\\.session(\\.|$)/",
134
139
  "group": "inline"
135
140
  },
136
141
  {
137
142
  "command": "gitguardex.activeAgents.showSessionTerminal",
138
- "when": "view == gitguardex.activeAgents && viewItem == gitguardex.session",
143
+ "when": "view == gitguardex.activeAgents && viewItem =~ /^gitguardex\\.session(\\.|$)/",
139
144
  "group": "inline"
140
145
  },
141
146
  {
142
147
  "command": "gitguardex.activeAgents.finishSession",
143
- "when": "view == gitguardex.activeAgents && viewItem == gitguardex.session",
148
+ "when": "view == gitguardex.activeAgents && viewItem =~ /^gitguardex\\.session(\\.|$)/",
144
149
  "group": "inline"
145
150
  },
146
151
  {
147
152
  "command": "gitguardex.activeAgents.syncSession",
148
- "when": "view == gitguardex.activeAgents && viewItem == gitguardex.session",
153
+ "when": "view == gitguardex.activeAgents && viewItem =~ /^gitguardex\\.session(\\.|$)/",
149
154
  "group": "inline"
150
155
  },
151
156
  {
152
157
  "command": "gitguardex.activeAgents.stopSession",
153
- "when": "view == gitguardex.activeAgents && viewItem == gitguardex.session",
158
+ "when": "view == gitguardex.activeAgents && viewItem =~ /^gitguardex\\.session(\\.|$)/",
159
+ "group": "inline"
160
+ },
161
+ {
162
+ "command": "gitguardex.activeAgents.dismissSession",
163
+ "when": "view == gitguardex.activeAgents && viewItem =~ /^gitguardex\\.session\\.(stalled|dead)$/",
154
164
  "group": "inline"
155
165
  }
156
166
  ]